]> granicus.if.org Git - libnl/commitdiff
documentation updates
authorThomas Graf <tgraf@suug.ch>
Thu, 14 Jul 2011 10:48:00 +0000 (12:48 +0200)
committerThomas Graf <tgraf@suug.ch>
Thu, 14 Jul 2011 10:48:00 +0000 (12:48 +0200)
28 files changed:
doc/Doxyfile.in
doc/Makefile.am
doc/core.txt
doc/index.txt [new file with mode: 0644]
doc/route.txt [new file with mode: 0644]
doc/src/examples/NLA_PUT.c [deleted file]
doc/src/examples/msg_constr_attr.c [deleted file]
doc/src/examples/msg_parse_attr.c [deleted file]
doc/src/examples/my_parse.c [deleted file]
doc/src/examples/nl_cb_set.c [deleted file]
doc/src/examples/nl_send_simple.c [deleted file]
doc/src/examples/nla_flag.c [deleted file]
doc/src/examples/nla_for_each_attr.c [deleted file]
doc/src/examples/nla_nest_start.c [deleted file]
doc/src/examples/nla_ok.c [deleted file]
doc/src/examples/nla_parse_nested.c [deleted file]
doc/src/examples/nla_put.c [deleted file]
doc/src/examples/nlmsg_for_each.c [deleted file]
doc/src/examples/nlmsg_parse.c [deleted file]
doc/src/examples/nlmsg_put.c [deleted file]
doc/src/examples/sk_group_example.c [deleted file]
doc/src/genl.c [deleted file]
doc/src/nf.c [deleted file]
doc/src/route.c [deleted file]
doc/src/toc.c
lib/msg.c
lib/route/cls.c
lib/route/tc.c

index 9bfb7111eb2e986af8bed42a4b918d25aeaed281..ed78bfe7522a9058601a7bc1f2b0765a41a9405b 100644 (file)
@@ -642,7 +642,7 @@ EXCLUDE_SYMBOLS        =
 # directories that contain example code fragments that are included (see
 # the \include command).
 
-EXAMPLE_PATH           = src/examples
+EXAMPLE_PATH           = src
 
 # If the value of the EXAMPLE_PATH tag contains directories, you can use the
 # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
index 0dd044b235f9c59d7e3b5d68de42fff3ae02f447..dc521633f2b57b3e564e7156634df411439f56e3 100644 (file)
@@ -1,17 +1,25 @@
 # -*- Makefile -*-
 
-.PHONY: gendoc
+.PHONY: gendoc api_refs asciidoc
 
-ASCIIDOCOPTS=-n -a pygments -a toc -a language=c -a icons \
+ASCIIDOCOPTS=-a pygments -a language=c -a icons \
             -a imagesdir="images/" \
             -a stylesdir="${abs_srcdir}/stylesheets/"
 
-gendoc:
+%.html: %.txt
+       asciidoc $(ASCIIDOCOPTS) $<
+       ./doxygen-link.py libnl.dict $@ > doxygen-link.tmp
+       mv doxygen-link.tmp $@
+
+asciidoc: core.html route.html index.html link.html
+
+api_ref:
        doxygen Doxyfile;
        ./gen-tags.sh | ./tags2dict.sh > libnl.dict
-       asciidoc $(ASCIIDOCOPTS) core.txt
-       ./doxygen-link.py libnl.dict core.html > core.tmp.html
-       mv core.tmp.html core.html
 
-distclean-local:
-       rm -f api/* libnl.tags *.html;
+gendoc:
+       $(MAKE) api_ref
+       $(MAKE) asciidoc
+
+clean-local:
+       rm -f api/* libnl.dict *.html;
index 7ae30819fa4cd61a9d084be9f7a6b901c21ebaca..22b0e1c3f6cac845c6c38c443b24b8bcbcb0ca19 100644 (file)
@@ -8,6 +8,8 @@ Netlink Core Library
 ====================
 Thomas Graf <tgraf@suug.ch>
 3.0, March 30 2011:
+:toc:
+:numbered:
 
 == Introduction
 
diff --git a/doc/index.txt b/doc/index.txt
new file mode 100644 (file)
index 0000000..c59be0e
--- /dev/null
@@ -0,0 +1,16 @@
+libnl
+=====
+Thomas Graf <tgraf@suug.ch>
+3.0, April 12 2011:
+
+== Table of Contents
+=== Libraries
+ - link:core.html[Core Library]
+ - link:route.html[Routing Family]
+
+=== Tools
+ - link:link.html[Link Utility]
+
+=== Python Packages
+ - netlink.core
+ - netlink.route.link
diff --git a/doc/route.txt b/doc/route.txt
new file mode 100644 (file)
index 0000000..4c184e9
--- /dev/null
@@ -0,0 +1,720 @@
+////
+       vim.syntax: asciidoc
+
+       Copyright (c) 2011 Thomas Graf <tgraf@suug.ch>
+////
+
+Netlink Routing Library
+=======================
+Thomas Graf <tgraf@suug.ch>
+3.0, March 23 2011:
+:toc:
+:icons:
+:numbered:
+
+
+== Introduction
+
+== Introduction to the Library
+
+== Addresses
+
+== Links / Interfaces
+
+== Neighbouring
+
+== Routing
+
+== Traffic Control
+
+The traffic control architecture allows the queueing and
+prioritization of packets before they are enqueued to the network
+driver. To a limited degree it is also possible to take control of
+network traffic as it enters the network stack.
+
+The architecture consists of three different types of modules:
+
+- *Queueing disciplines (qdisc)* provide a mechanism to enqueue packets
+  in different forms. They may be used to implement fair queueing,
+  prioritization of differentiated services, enforce bandwidth
+  limitations, or even to simulate network behaviour such as packet
+  loss and packet delay. Qdiscs can be classful in which case they
+  allow traffic classes described in the next paragraph to be attached
+  to them.
+
+- *Traffic classes (class)* are supported by several qdiscs to build
+  a tree structure for different types of traffic. Each class may be
+  assigned its own set of attributes such as bandwidth limits or
+  queueing priorities. Some qdiscs even allow borrowing of bandwidth
+  between classes.
+
+- *Classifiers (cls)* are used to decide which qdisc/class the packet
+  should be enqueued to. Different types of classifiers exists,
+  ranging from classification based on protocol header values to
+  classification based on packet priority or firewall marks.
+  Additionally most classifiers support *extended matches (ematch)*
+  which allow extending classifiers by a set of matcher modules, and
+  *actions* which allow classifiers to take actions such as mangling,
+  mirroring, or even rerouting of packets.
+
+.Default Qdisc
+
+The default qdisc used on all network devices is `pfifo_fast`.
+Network devices which do not require a transmit queue such as the
+loopback device do not have a default qdisc attached. The `pfifo_fast`
+qdisc provides three bands to prioritize interactive traffic over bulk
+traffic. Classification is based on the packet priority (diffserv).
+
+image:qdisc_default.png["Default Qdisc"]
+
+.Multiqueue Default Qdisc
+
+If the network device provides multiple transmit queues the `mq`
+qdisc is used by default. It will automatically create a separate
+class for each transmit queue available and will also replace
+the single per device tx lock with a per queue lock.
+
+image:qdisc_mq.png["Multiqueue default Qdisc"]
+
+.Example of a customized classful qdisc setup
+
+The following figure illustrates a possible combination of different
+queueing and classification modules to implement quality of service
+needs.
+
+image:tc_overview.png["Classful Qdisc diagram"]
+
+=== Traffic Control Object
+
+Each type traffic control module (qdisc, class, classifier) is
+represented by its own structure. All of them are based on the traffic
+control object represented by `struct rtnl_tc` which itself is based
+on the generic object `struct nl_object` to make it cacheable. The
+traffic control object contains all attributes, implementation details
+and statistics that are shared by all of the traffic control object
+types.
+
+image:tc_obj.png["struct rtnl_tc hierarchy"]
+
+It is not possible to allocate a `struct rtnl_tc` object, instead the
+actual tc object types must be allocated directly using
+`rtnl_qdisc_alloc()`, `rtnl_class_alloc()`, `rtnl_cls_alloc()` and
+then casted to `struct rtnl_tc` using the `TC_CAST()` macro.
+
+.Usage Example: Allocation, Casting, Freeing
+[source,c]
+-----
+#include <netlink/route/tc.h>
+#include <netlink/route/qdisc.h>
+
+struct rtnl_qdisc *qdisc;
+
+/* Allocation of a qdisc object */
+qdisc = rtnl_qdisc_alloc();
+
+/* Cast the qdisc to a tc object using TC_CAST() to use rtnl_tc_ functions. */
+rtnl_tc_set_mpu(TC_CAST(qdisc), 64);
+
+/* Free the qdisc object */
+rtnl_qdisc_put(qdisc);
+-----
+
+[[tc_attr]]
+==== Attributes
+
+[cols="a,a", options="header", frame="topbot"]
+|====================================================================
+| Attribute | C Interface
+|
+Handle::
+The handle uniquely identifies a tc object and is used to refer
+to other tc objects when constructing tc trees.
+|
+[source,c]
+-----
+void rtnl_tc_set_handle(struct rtnl_tc *tc, uint32_t handle);
+uint32_t rtnl_tc_get_handle(struct rtnl_tc *tc);
+-----
+|
+IfIndex::
+The interface index specifies the network device the traffic object
+is attached to. The function `rtnl_tc_set_link()` should be preferred
+when setting the interface index. It stores the reference to the link
+object in the tc object and allows retrieving the `mtu` and `linktype`
+automatically.
+|
+[source,c]
+-----
+void rtnl_tc_set_ifindex(struct rtnl_tc *tc, int ifindex);
+void rtnl_tc_set_link(struct rtnl_tc *tc, struct rtnl_link *link);
+int rtnl_tc_get_ifindex(struct rtnl_tc *tc);
+-----
+|
+LinkType::
+The link type specifies the kind of link that is used by the network
+device (e.g. ethernet, ATM, ...). It is derived automatically when
+the network device is specified with `rtnl_tc_set_link()`.
+The default fallback is `ARPHRD_ETHER` (ethernet).
+|
+[source,c]
+-----
+void rtnl_tc_set_linktype(struct rtnl_tc *tc, uint32_t type);
+uint32_t rtnl_tc_get_linktype(struct rtnl_tc *tc);
+-----
+|
+Kind::
+The kind character string specifies the type of qdisc, class,
+classifier. Setting the kind results in the module specific
+structure being allocated. Therefore it is imperative to call 
+`rtnl_tc_set_kind()` before using any type specific API functions
+such as `rtnl_htb_set_rate()`.
+|
+[source,c]
+-----
+int rtnl_tc_set_kind(struct rtnl_tc *tc, const char *kind);
+char *rtnl_tc_get_kind(struct rtnl_tc *tc);
+-----
+|
+MPU::
+The Minimum Packet Unit specifies the minimum packet size which will
+be transmitted
+ever be seen by this traffic control object. This value is used for
+rate calculations. Not all object implementations will make use of
+this value. The default value is 0.
+|
+[source,c]
+-----
+void rtnl_tc_set_mpu(struct rtnl_tc *tc, uint32_t mpu);
+uint32_t rtnl_tc_get_mpu(struct rtnl_tc *tc);
+-----
+|
+MTU::
+The Maximum Transmission Unit specifies the maximum packet size which
+will be transmitted. The value is derived from the link specified
+with `rtnl_tc_set_link()` if not overwritten with `rtnl_tc_set_mtu()`.
+If no link and MTU is specified, the value defaults to 1500
+(ethernet).
+|
+[source,c]
+-----
+void rtnl_tc_set_mtu(struct rtnl_tc *tc, uint32_t mtu);
+uint32_t rtnl_tc_get_mtu(struct rtnl_tc *tc);
+-----
+|
+Overhead::
+The overhead specifies the additional overhead per packet caused by
+the network layer. This value can be used to correct packet size
+calculations if the packet size on the wire does not match the packet
+size seen by the kernel. The default value is 0.
+|
+[source,c]
+-----
+void rtnl_tc_set_overhead(struct rtnl_tc *tc, uint32_t overhead);
+uint32_t rtnl_tc_get_overhead(struct rtnl_tc *tc);
+-----
+|
+Parent::
+Specifies the parent traffic control object. The parent is identifier
+by its handle. Special values are:
+- `TC_H_ROOT`: attach tc object directly to network device (root
+  qdisc, root classifier)
+- `TC_H_INGRESS`: same as `TC_H_ROOT` but on the ingress side of the
+  network stack.
+|
+[source,c]
+-----
+void rtnl_tc_set_parent(struct rtnl_tc *tc, uint32_t parent);
+uint32_t rtnl_tc_get_parent(struct rtnl_tc *tc);
+-----
+|
+Statistics::
+Generic statistics, see <<tc_stats, Accessing Statistics>> for
+additional information.
+|
+[source,c]
+-----
+uint64_t rtnl_tc_get_stat(struct rtnl_tc *tc, enum rtnl_tc_stat id);
+-----
+|====================================================================
+
+[[tc_stats]]
+==== Accessing Statistics
+
+The traffic control object holds a set of generic statistics. Not all
+traffic control modules will make use of all of these statistics. Some
+modules may provide additional statistics via their own APIs.
+
+.Statistic identifiers `(enum rtnl_tc_stat)`
+[cols="m,,", options="header", frame="topbot"]
+|====================================================================
+| ID                 | Type    | Description
+| RTNL_TC_PACKETS    | Counter | Total # of packets transmitted
+| RTNL_TC_BYTES      | Counter | Total # of bytes transmitted
+| RTNL_TC_RATE_BPS   | Rate    | Current bytes/s rate
+| RTNL_TC_RATE_PPS   | Rate    | Current packets/s rate
+| RTNL_TC_QLEN       | Rate    | Current length of the queue
+| RTNL_TC_BACKLOG    | Rate    | # of packets currently backloged
+| RTNL_TC_DROPS      | Counter | # of packets dropped
+| RTNL_TC_REQUEUES   | Counter | # of packets requeued
+| RTNL_TC_OVERLIMITS | Counter | # of packets that exceeded the limit
+|====================================================================
+
+NOTE: `RTNL_TC_RATE_BPS` and `RTNL_TC_RATE_PPS` only return meaningful
+      values if a rate estimator has been configured.
+
+.Usage Example: Retrieving tc statistics
+[source,c]
+-------
+#include <netlink/route/tc.h>
+
+uint64_t drops, qlen;
+
+drops = rtnl_tc_get_stat(TC_CAST(qdisc), RTNL_TC_DROPS);
+qlen  = rtnl_tc_get_stat(TC_CAST(qdisc), RTNL_TC_QLEN);
+-------
+
+==== Rate Table Calculations
+
+[[tc_qdisc]]
+=== Queueing Discipline (qdisc)
+
+.Classless Qdisc
+
+The queueing discipline (qdisc) is used to implement fair queueing,
+priorization or rate control. It provides a _enqueue()_ and
+_dequeue()_ operation. Whenever a network packet leaves the networking
+stack over a network device, be it a physical or virtual device, it
+will be enqueued to a qdisc unless the device is queueless. The
+_enqueue()_ operation is followed by an immediate call to _dequeue()_
+for the same qdisc to eventually retrieve a packet which can be
+scheduled for transmission by the driver. Additionally, the networking
+stack runs a watchdog which polls the qdisc regularly to dequeue and
+send packets even if no new packets are being enqueued.
+
+This additional watchdog is required due to the fact that qdiscs may
+hold on to packets and not return any packets upon _dequeue()_ in
+order to enforce bandwidth restrictions.
+
+image:classless_qdisc_nbands.png[alt="Multiband Qdisc", float="right"]
+
+The figure illustrates a trivial example of a classless qdisc
+consisting of three bands (queues). Use of multiple bands is a common
+technique in qdiscs to implement fair queueing between flows or
+prioritize differentiated services.
+
+Classless qdiscs can be regarded as a blackbox, their inner workings
+can only be steered using the configuration parameters provided by the
+qdisc. There is no way of taking influence on the structure of its
+internal queues itself.
+
+.Classful Qdisc
+
+Classful qdiscs allow for the queueing structure and classification
+process to be created by the user. 
+
+image:classful_qdisc.png["Classful Qdisc"]
+
+The figure above shows a classful qdisc with a classifier attached to
+it which will make the decision whether to enqueue a packet to traffic
+class +1:1+ or +1:2+. Unlike with classless qdiscs, classful qdiscs
+allow the classification process and the structure of the queues to be
+defined by the user. This allows for complex traffic class rules to
+be applied.
+
+.List of Qdisc Implementations
+[options="header", frame="topbot", cols="2,1^,8"]
+|======================================================================
+| Qdisc     | Classful | Description
+| ATM       | Yes      | FIXME
+| Blackhole | No       | This qdisc will drop all packets passed to it.
+| CBQ       | Yes      |
+The CBQ (Class Based Queueing) is a classful qdisc which allows
+creating traffic classes and enforce bandwidth limitations for each
+class.
+| DRR       | Yes      |
+The DRR (Deficit Round Robin) scheduler is a classful qdisc
+impelemting fair queueing. Each class is assigned a quantum specyfing
+the maximum number of bytes that can be served per round.  Unused
+quantum at the end of the round is carried over to the next round.
+| DSMARK   | Yes       | FIXME
+| FIFO     | No        | FIXME
+| GRED     | No        | FIXME
+| HFSC     | Yes       | FIXME
+| HTB      | Yes       | FIXME
+| mq       | Yes       | FIXME
+| multiq   | Yes       | FIXME
+| netem    | No        | FIXME
+| Prio     | Yes       | FIXME
+| RED      | Yes       | FIXME
+| SFQ      | Yes       | FIXME
+| TBF      | Yes       | FIXME
+| teql     | No        | FIXME
+|======================================================================
+
+
+.QDisc API Overview
+[cols="a,a", options="header", frame="topbot"]
+|====================================================================
+| Attribute | C Interface
+|
+Allocation / Freeing::
+|
+[source,c]
+-----
+struct rtnl_qdisc *rtnl_qdisc_alloc(void);
+void rtnl_qdisc_put(struct rtnl_qdisc *qdisc);
+-----
+|
+Addition::
+|
+[source,c]
+-----
+int rtnl_qdisc_build_add_request(struct rtnl_qdisc *qdisc, int flags,
+                                struct nl_msg **result);
+int rtnl_qdisc_add(struct nl_sock *sock, struct rtnl_qdisc *qdisc,
+                   int flags);
+-----
+|
+Modification::
+|
+[source,c]
+-----
+int rtnl_qdisc_build_change_request(struct rtnl_qdisc *old,
+                                   struct rtnl_qdisc *new,
+                                   struct nl_msg **result);
+int rtnl_qdisc_change(struct nl_sock *sock, struct rtnl_qdisc *old,
+                     struct rtnl_qdisc *new);
+-----
+|
+Deletion::
+|
+[source,c]
+-----
+int rtnl_qdisc_build_delete_request(struct rtnl_qdisc *qdisc,
+                                   struct nl_msg **result);
+int rtnl_qdisc_delete(struct nl_sock *sock, struct rtnl_qdisc *qdisc);
+-----
+|
+Cache::
+|
+[source,c]
+-----
+int rtnl_qdisc_alloc_cache(struct nl_sock *sock,
+                          struct nl_cache **cache);
+struct rtnl_qdisc *rtnl_qdisc_get(struct nl_cache *cache, int, uint32_t);
+
+struct rtnl_qdisc *rtnl_qdisc_get_by_parent(struct nl_cache *, int, uint32_t);
+-----
+|====================================================================
+
+[[qdisc_get]]
+==== Retrieving Qdisc Configuration
+
+The function rtnl_qdisc_alloc_cache() is used to retrieve the current
+qdisc configuration in the kernel. It will construct a +RTM_GETQDISC+
+netlink message, requesting the complete list of qdiscs configured in
+the kernel.
+
+[source,c]
+-------
+#include <netlink/route/qdisc.h>
+
+struct nl_cache *all_qdiscs;
+
+if (rtnl_link_alloc_cache(sock, &all_qdiscs) < 0)
+       /* error while retrieving qdisc cfg */
+-------
+
+The cache can be accessed using the following functions:
+
+- Search qdisc with matching ifindex and handle:
++
+[source,c]
+--------
+struct rtnl_qdisc *rtnl_qdisc_get(struct nl_cache *cache, int ifindex, uint32_t handle);
+--------
+- Search qdisc with matching ifindex and parent:
++
+[source,c]
+--------
+struct rtnl_qdisc *rtnl_qdisc_get_by_parent(struct nl_cache *cache, int ifindex , uint32_t parent);
+--------
+- Or any of the generic cache functions (e.g. nl_cache_search(), nl_cache_dump(), etc.)
+
+.Example: Search and print qdisc
+[source,c]
+-------
+struct rtnl_qdisc *qdisc;
+int ifindex;
+
+ifindex = rtnl_link_get_ifindex(eth0_obj);
+
+/* search for qdisc on eth0 with handle 1:0 */
+if (!(qdisc = rtnl_qdisc_get(all_qdiscs, ifindex, TC_HANDLE(1, 0))))
+       /* no such qdisc found */
+
+nl_object_dump(OBJ_CAST(qdisc), NULL);
+
+rtnl_qdisc_put(qdisc);
+-------
+
+[[qdisc_add]]
+==== Adding a Qdisc
+
+In order to add a new qdisc to the kernel, a qdisc object needs to be
+allocated. It will hold all attributes of the new qdisc.
+
+[source,c]
+-----
+#include <netlink/route/qdisc.h>
+
+struct rtnl_qdisc *qdisc;
+
+if (!(qdisc = rtnl_qdisc_alloc()))
+       /* OOM error */
+-----
+
+The next step is to specify all generic qdisc attributes using the tc
+object interface described in the section <<tc_attr, traffic control
+object attributes>>.
+
+The following attributes must be specified:
+- IfIndex
+- Parent
+- Kind
+
+[source,c]
+-----
+/* Attach qdisc to device eth0 */
+rtnl_tc_set_link(TC_CAST(qdisc), eth0_obj);
+
+/* Make this the root qdisc */
+rtnl_tc_set_parent(TC_CAST(qdisc), TC_H_ROOT);
+
+/* Set qdisc identifier to 1:0, if left unspecified, a handle will be generated by the kernel. */
+rtnl_tc_set_handle(TC_CAST(qdisc), TC_HANDLE(1, 0));
+
+/* Make this a HTB qdisc */
+rtnl_tc_set_kind(TC_CAST(qdisc), "htb");
+-----
+
+After specyfing the qdisc kind (rtnl_tc_set_kind()) the qdisc type
+specific interface can be used to set attributes which are specific
+to the respective qdisc implementations:
+
+[source,c]
+------
+/* HTB feature: Make unclassified packets go to traffic class 1:5 */
+rtnl_htb_set_defcls(qdisc, TC_HANDLE(1, 5));
+------
+
+Finally, the qdisc is ready to be added and can be passed on to the
+function rntl_qdisc_add() which takes care of constructing a netlink
+message requesting the addition of the new qdisc, sends the message to
+the kernel and waits for the response by the kernel. The function
+returns 0 if the qdisc has been added or updated successfully or a
+negative error code if an error occured.
+
+CAUTION: The kernel operation for updating and adding a qdisc is the
+         same. Therefore when calling rtnl_qdisc_add() any existing
+         qdisc with matching handle will be updated unless the flag
+         NLM_F_EXCL is specified.
+
+The following flags may be specified:
+[horizontal]
+NLM_F_CREATE::  Create qdisc if it does not exist, otherwise
+                -NLE_OBJ_NOTFOUND is returned.
+NLM_F_REPLACE:: If another qdisc is already attached to the same
+                parent and their handles mismatch, replace the qdisc
+                instead of returning -EEXIST.
+NLM_F_EXCL::    Return -NLE_EXISTS if a qdisc with matching handles
+                exists already.
+
+WARNING: The function rtnl_qdisc_add() requires administrator
+         privileges.
+
+[source,c]
+------
+/* Submit request to kernel and wait for response */
+err = rtnl_qdisc_add(sock, qdisc, NLM_F_CREATE);
+
+/* Return the qdisc object to free memory resources */
+rtnl_qdisc_put(qdisc);
+
+if (err < 0) {
+       fprintf(stderr, "Unable to add qdisc: %s\n", nl_geterror(err));
+       return err;
+}
+------
+
+==== Deleting a qdisc
+
+[source,c]
+------
+#include <netlink/route/qdisc.h>
+
+struct rtnl_qdisc *qdisc;
+
+qdisc = rtnl_qdisc_alloc();
+
+rtnl_tc_set_link(TC_CAST(qdisc), eth0_obj);
+rtnl_tc_set_parent(TC_CAST(qdisc), TC_H_ROOT);
+
+rtnl_qdisc_delete(sock, qdisc)
+
+rtnl_qdisc_put(qdisc);
+------
+
+WARNING: The function rtnl_qdisc_delete() requires administrator
+         privileges.
+
+
+[[qdisc_htb]]
+==== HTB - Hierarchical Token Bucket
+
+.HTB Qdisc Attributes
+
+[cols="a,a", options="header", frame="topbot"]
+|====================================================================
+| Attribute | C Interface
+|
+Default Class::
+The default class is the fallback class to which all traffic which
+remained unclassified is directed to. If no default class or an
+invalid default class is specified, packets are transmitted directly
+to the next layer (direct transmissions).
+|
+[source,c]
+-----
+uint32_t rtnl_htb_get_defcls(struct rtnl_qdisc *qdisc);
+int rtnl_htb_set_defcls(struct rtnl_qdisc *qdisc, uint32_t defcls);
+-----
+|
+Rate to Quantum (r2q)::
+TODO
+|
+[source,c]
+-----
+uint32_t rtnl_htb_get_rate2quantum(struct rtnl_qdisc *qdisc);
+int rtnl_htb_set_rate2quantum(struct rtnl_qdisc *qdisc, uint32_t rate2quantum);
+-----
+|====================================================================
+
+
+.HTB Class Attributes
+
+[cols="a,a", options="header", frame="topbot"]
+|====================================================================
+| Attribute | C Interface
+|
+Priority::
+|
+[source,c]
+-----
+uint32_t rtnl_htb_get_prio(struct rtnl_class *class);
+int rtnl_htb_set_prio(struct rtnl_class *class, uint32_t prio);
+-----
+|
+Rate::
+The rate (bytes/s) specifies the maximum bandwidth an invidivual class
+can use without borrowing. The rate of a class should always be greater
+or erqual than the rate of its children.
+|
+[source,c]
+-----
+uint32_t rtnl_htb_get_rate(struct rtnl_class *class);
+int rtnl_htb_set_rate(struct rtnl_class *class, uint32_t ceil);
+-----
+|
+Ceil Rate::
+The ceil rate specifies the maximum bandwidth an invidivual class
+can use. This includes bandwidth that is being borrowed from other
+classes. Ceil defaults to the class rate implying that by default
+the class will not borrow. The ceil rate of a class should always
+be greater or erqual than the ceil rate of its children.
+|
+[source,c]
+-----
+uint32_t rtnl_htb_get_ceil(struct rtnl_class *class);
+int rtnl_htb_set_ceil(struct rtnl_class *class, uint32_t ceil);
+-----
+|
+Burst::
+TODO
+|
+[source,c]
+-----
+uint32_t rtnl_htb_get_rbuffer(struct rtnl_class *class);
+int rtnl_htb_set_rbuffer(struct rtnl_class *class, uint32_t burst);
+-----
+|
+Ceil Burst::
+TODO
+|
+[source,c]
+-----
+uint32_t rtnl_htb_get_bbuffer(struct rtnl_class *class);
+int rtnl_htb_set_bbuffer(struct rtnl_class *class, uint32_t burst);
+-----
+|
+Quantum::
+TODO
+|
+[source,c]
+-----
+int rtnl_htb_set_quantum(struct rtnl_class *class, uint32_t quantum);
+-----
+|====================================================================
+
+extern int     rtnl_htb_set_cbuffer(struct rtnl_class *, uint32_t);
+
+
+
+
+[[tc_class]]
+=== Class
+
+[options="header", cols="s,a,a,a,a"]
+|=======================================================================
+|        | UNSPEC             | TC_H_ROOT          | 0:pY  | pX:pY
+| UNSPEC 3+^|
+[horizontal]
+qdisc =:: root-qdisc
+class =:: root-qdisc:0
+|
+[horizontal]
+qdisc =:: pX:0
+class =:: pX:0
+| 0:hY 3+^|
+[horizontal]
+qdisc =:: root-qdisc
+class =:: root-qdisc:hY
+|
+[horizontal]
+qdisc =:: pX:0
+class =:: pX:hY
+| hX:hY 3+^|
+[horizontal]
+qdisc =:: hX:
+class =:: hX:hY
+|
+if pX != hX
+    return -EINVAL
+[horizontal]
+qdisc =:: hX:
+class =:: hX:hY
+|=======================================================================
+
+[[tc_cls]]
+=== Classifier (cls)
+
+[[tc_classid_mngt]]
+=== ClassID Management
+
+[[tc_pktloc]]
+=== Packet Location Aliasing (pktloc)
+
+[[tc_api]]
+=== Traffic Control Module API
+
+
diff --git a/doc/src/examples/NLA_PUT.c b/doc/src/examples/NLA_PUT.c
deleted file mode 100644 (file)
index c3afb47..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#include <netlink/msg.h>
-#include <netlink/attr.h>
-
-void construct_attrs(struct nl_msg *msg)
-{
-       NLA_PUT_STRING(msg, MY_ATTR_FOO1, "some text");
-       NLA_PUT_U32(msg, MY_ATTR_FOO1, 0x1010);
-       NLA_PUT_FLAG(msg, MY_ATTR_FOO3, 1);
-
-       return 0;
-
-nla_put_failure:
-       /* NLA_PUT* macros jump here in case of an error */
-       return -EMSGSIZE;
-}
diff --git a/doc/src/examples/msg_constr_attr.c b/doc/src/examples/msg_constr_attr.c
deleted file mode 100644 (file)
index bfa00fe..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-struct nl_msg *build_msg(int ifindex, struct nl_addr *lladdr, int mtu)
-{
-       struct nl_msg *msg;
-       struct nlattr *info, *vlan;
-       struct ifinfomsg ifi = {
-               .ifi_family = AF_INET,
-               .ifi_index = ifindex,
-       };
-
-       /* Allocate a default sized netlink message */
-       if (!(msg = nlmsg_alloc_simple(RTM_SETLINK, 0)))
-               return NULL;
-
-       /* Append the protocol specific header (struct ifinfomsg)*/
-       if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0)
-               goto nla_put_failure
-
-       /* Append a 32 bit integer attribute to carry the MTU */
-       NLA_PUT_U32(msg, IFLA_MTU, mtu);
-
-       /* Append a unspecific attribute to carry the link layer address */
-       NLA_PUT_ADDR(msg, IFLA_ADDRESS, lladdr);
-
-       /* Append a container for nested attributes to carry link information */
-       if (!(info = nla_nest_start(msg, IFLA_LINKINFO)))
-               goto nla_put_failure;
-
-       /* Put a string attribute into the container */
-       NLA_PUT_STRING(msg, IFLA_INFO_KIND, "vlan");
-
-       /*
-        * Append another container inside the open container to carry
-        * vlan specific attributes
-        */
-       if (!(vlan = nla_nest_start(msg, IFLA_INFO_DATA)))
-               goto nla_put_failure;
-
-       /* add vlan specific info attributes here... */
-
-       /* Finish nesting the vlan attributes and close the second container. */
-       nla_nest_end(msg, vlan);
-
-       /* Finish nesting the link info attribute and close the first container. */
-       nla_nest_end(msg, info);
-
-       return msg;
-
-nla_put_failure:
-       nlmsg_free(msg);
-       return NULL;
-}
diff --git a/doc/src/examples/msg_parse_attr.c b/doc/src/examples/msg_parse_attr.c
deleted file mode 100644 (file)
index 6e275e9..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-int parse_message(struct nlmsghdr *hdr)
-{
-       /*
-        * The policy defines two attributes: a 32 bit integer and a container
-        * for nested attributes.
-        */
-       struct nla_policy attr_policy[] = {
-               [ATTR_FOO] = { .type = NLA_U32 },
-               [ATTR_BAR] = { .type = NLA_NESTED },
-       };
-       struct nlattr *attrs[ATTR_MAX+1];
-       int err;
-
-       /*
-        * The nlmsg_parse() function will make sure that the message contains
-        * enough payload to hold the header (struct my_hdr), validates any
-        * attributes attached to the messages and stores a pointer to each
-        * attribute in the attrs[] array accessable by attribute type.
-        */
-       if ((err = nlmsg_parse(hdr, sizeof(struct my_hdr), attrs, ATTR_MAX,
-                              attr_policy)) < 0)
-               goto errout;
-
-       if (attrs[ATTR_FOO]) {
-               /*
-                * It is safe to directly access the attribute payload without
-                * any further checks since nlmsg_parse() enforced the policy.
-                */
-               uint32_t foo = nla_get_u32(attrs[ATTR_FOO]);
-       }
-
-       if (attrs[ATTR_BAR]) {
-               struct *nested[NESTED_MAX+1];
-
-               /*
-                * Attributes nested in a container can be parsed the same way
-                * as top level attributes.
-                */
-               err = nla_parse_nested(nested, NESTED_MAX, attrs[ATTR_BAR],
-                                      nested_policy);
-               if (err < 0)
-                       goto errout;
-
-               // Process nested attributes here.
-       }
-
-       err = 0;
-errout:
-       return err;
-}
diff --git a/doc/src/examples/my_parse.c b/doc/src/examples/my_parse.c
deleted file mode 100644 (file)
index c1ff637..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#include <netlink/msg.h>
-
-void my_parse(void *stream, int length)
-{
-       struct nlmsghdr *hdr = stream;
-
-       while (nlmsg_ok(hdr, length)) {
-               // Parse message here
-               hdr = nlmsg_next(hdr, &length);
-       }
-}
diff --git a/doc/src/examples/nl_cb_set.c b/doc/src/examples/nl_cb_set.c
deleted file mode 100644 (file)
index 4fbaefc..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#include <netlink/handlers.h>
-
-/* Allocate a callback set and initialize it to the verbose default set */
-struct nl_cb *cb = nl_cb_alloc(NL_CB_VERBOSE);
-
-/* Modify the set to call my_func() for all valid messages */
-nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, my_func, NULL);
-
-/*
- * Set the error message handler to the verbose default implementation
- * and direct it to print all errors to the given file descriptor.
- */
-FILE *file = fopen(...);
-nl_cb_err(cb, NL_CB_VERBOSE, NULL, file);
diff --git a/doc/src/examples/nl_send_simple.c b/doc/src/examples/nl_send_simple.c
deleted file mode 100644 (file)
index afbed7a..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#include <netlink/netlink.h>
-
-struct nl_sock *sk;
-struct rtgenmsg rt_hdr = {
-       .rtgen_family = AF_UNSPEC,
-};
-
-sk = nl_socket_alloc();
-nl_connect(sk, NETLINK_ROUTE);
-
-nl_send_simple(sock, RTM_GETLINK, NLM_F_DUMP, &rt_hdr, sizeof(rt_hdr));
diff --git a/doc/src/examples/nla_flag.c b/doc/src/examples/nla_flag.c
deleted file mode 100644 (file)
index dc3d0f9..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-/* nla_put_flag() appends a zero sized attribute to the message. */
-nla_put_flag(msg, ATTR_FLAG);
-
-
-/* There is no need for a receival function, the presence is the value. */
-if (attrs[ATTR_FLAG])
-       /* flag is present */
diff --git a/doc/src/examples/nla_for_each_attr.c b/doc/src/examples/nla_for_each_attr.c
deleted file mode 100644 (file)
index 9d81835..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#include <netlink/attr.h>
-
-struct nalttr *nla;
-int rem;
-
-nla_for_each_attr(nla, attrstream, streamlen, rem) {
-       /* validate & parse attribute */
-}
-
-if (rem > 0)
-       /* unparsed attribute data */
diff --git a/doc/src/examples/nla_nest_start.c b/doc/src/examples/nla_nest_start.c
deleted file mode 100644 (file)
index 51cd616..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-int put_opts(struct nl_msg *msg)
-{
-       struct nlattr *opts;
-
-       if (!(opts = nla_nest_start(msg, ATTR_OPTS)))
-               goto nla_put_failure;
-
-       NLA_PUT_U32(msg, NESTED_FOO, 123);
-       NLA_PUT_STRING(msg, NESTED_BAR, "some text");
-
-       nla_nest_end(msg, opts);
-       return 0;
-
-nla_put_failure:
-       return -EMSGSIZE;
-}
diff --git a/doc/src/examples/nla_ok.c b/doc/src/examples/nla_ok.c
deleted file mode 100644 (file)
index 4485a96..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#include <netlink/msg.h>
-#include <netlink/attr.h>
-
-struct nlattr *hdr = nlmsg_attrdata(msg, 0);
-int remaining = nlmsg_attrlen(msg, 0);
-
-while (nla_ok(hdr, remaining)) {
-       /* parse attribute here */
-       hdr = nla_next(hdr, &remaining);
-};
diff --git a/doc/src/examples/nla_parse_nested.c b/doc/src/examples/nla_parse_nested.c
deleted file mode 100644 (file)
index 563bfc8..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-if (attrs[ATTR_OPTS]) {
-       struct nlattr *nested[NESTED_MAX+1];
-       struct nla_policy nested_policy[] = {
-               [NESTED_FOO] = { .type = NLA_U32 },
-       };
-
-       if (nla_parse_nested(nested, NESTED_MAX, attrs[ATTR_OPTS], nested_policy) < 0)
-               /* error */
-       
-       if (nested[NESTED_FOO])
-               uint32_t val = nla_get_u32(nested[NESTED_FOO]);
-}
diff --git a/doc/src/examples/nla_put.c b/doc/src/examples/nla_put.c
deleted file mode 100644 (file)
index 0683fa5..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-struct my_attr_struct {
-       uint32_t a;
-       uint32_t b;
-};
-
-int my_put(struct nl_msg *msg)
-{
-       struct my_attr_struct obj = {
-               .a = 10,
-               .b = 20,
-       };
-
-       return nla_put(msg, ATTR_MY_STRUCT, sizeof(obj), &obj);
-}
diff --git a/doc/src/examples/nlmsg_for_each.c b/doc/src/examples/nlmsg_for_each.c
deleted file mode 100644 (file)
index ae2ee66..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <netlink/msg.h>
-
-struct nlmsghdr *hdr;
-
-nlmsg_for_each(hdr, stream, length) {
-       /* do something with message */
-}
diff --git a/doc/src/examples/nlmsg_parse.c b/doc/src/examples/nlmsg_parse.c
deleted file mode 100644 (file)
index ac6acb3..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#include <netlink/msg.h>
-#include <netlink/attr.h>
-
-enum {
-       MY_ATTR_FOO = 1,
-       MY_ATTR_BAR,
-       __MY_ATTR_MAX,
-};
-
-#define MY_ATTR_MAX (__MY_ATTR_MAX - 1)
-
-static struct nla_policy my_policy[MY_ATTR_MAX+1] = {
-       [MY_ATTR_FOO] = { .type = NLA_U32 },
-       [MY_ATTR_BAR] = { .type = NLA_STRING,
-                         .maxlen = 16 },
-};
-
-void parse_msg(struct nlmsghdr *nlh)
-{
-       struct nlattr *attrs[MY_ATTR_MAX+1];
-
-       if (nlmsg_parse(nlh, 0, attrs, MY_ATTR_MAX, my_policy) < 0)
-               /* error */
-
-       if (attrs[MY_ATTR_FOO]) {
-               /* MY_ATTR_FOO is present in message */
-               printf("value: %u\n", nla_get_u32(attrs[MY_ATTR_FOO]));
-       }
-}
diff --git a/doc/src/examples/nlmsg_put.c b/doc/src/examples/nlmsg_put.c
deleted file mode 100644 (file)
index 5e609c6..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-#include <netlink/msg.h>
-
-struct nlmsghdr *hdr;
-struct nl_msg *msg;
-struct myhdr {
-       uint32_t foo1, foo2;
-} hdr = { 10, 20 };
-
-/* Allocate a message with the default maximum message size */
-msg = nlmsg_alloc();
-
-/*
- * Add header with message type MY_MSGTYPE, the flag NLM_F_CREATE,
- * let library fill port and sequence number, and reserve room for
- * struct myhdr
- */
-hdr = nlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, MY_MSGTYPE, sizeof(hdr), NLM_F_CREATE);
-
-/* Copy own header into newly reserved payload section */
-memcpy(nlmsg_data(hdr), &hdr, sizeof(hdr));
-
-/*
- * The message will now look like this:
- *     +-------------------+- - -+----------------+- - -+
- *     |  struct nlmsghdr  | Pad |  struct myhdr  | Pad |
- *     +-------------------+-----+----------------+- - -+
- * nlh -^                        /                \
- *                              +--------+---------+
- *                              |  foo1  |  foo2   |
- *                              +--------+---------+
- */
diff --git a/doc/src/examples/sk_group_example.c b/doc/src/examples/sk_group_example.c
deleted file mode 100644 (file)
index f948e18..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-#include <netlink/netlink.h>
-#include <netlink/socket.h>
-#include <netlink/msg.h>
-
-/*
- * This function will be called for each valid netlink message received
- * in nl_recvmsgs_default()
- */
-static int my_func(struct nl_msg *msg, void *arg)
-{
-       return 0;
-}
-
-struct nl_sock *sk;
-
-/* Allocate a new socket */
-sk = nl_socket_alloc();
-
-/*
- * Notifications do not use sequence numbers, disable sequence number
- * checking.
- */
-nl_socket_disable_seq_check(sk);
-
-/*
- * Define a callback function, which will be called for each notification
- * received
- */
-nl_socket_modify_cb(sk, NL_CB_VALID, NL_CB_CUSTOM, my_func, NULL);
-
-/* Connect to routing netlink protocol */
-nl_connect(sk, NETLINK_ROUTE);
-
-/* Subscribe to link notifications group */
-nl_socket_add_memberships(sk, RTNLGRP_LINK);
-
-/*
- * Start receiving messages. The function nl_recvmsgs_default() will block
- * until one or more netlink messages (notification) are received which
- * will be passed on to my_func().
- */
-while (1)
-       nl_recvmsgs_default(sock);
diff --git a/doc/src/genl.c b/doc/src/genl.c
deleted file mode 100644 (file)
index 8585c62..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
- * \cond skip
- * vim:syntax=doxygen
- * \endcond
-
-\page genl_doc Generic Netlink Library (-lnl-genl)
-
-\section genl_intro Introduction
-
-*/
diff --git a/doc/src/nf.c b/doc/src/nf.c
deleted file mode 100644 (file)
index 006500d..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
- * \cond skip
- * vim:syntax=doxygen
- * \endcond
-
-\page nf_doc Netfilter Netlink Library (-lnl-nf)
-
-\section nf_intro Introduction
-
-*/
diff --git a/doc/src/route.c b/doc/src/route.c
deleted file mode 100644 (file)
index 2c042db..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
- * \cond skip
- * vim:syntax=doxygen
- * \endcond
-
-\page route_doc Routing Netlink Library (-lnl-route)
-
-\section route_intro Introduction
-
-*/
index c33727cf2bc0cf7b83d51db6f7893cb5e473203e..ba7e07a4a04f51bf95967d86e7156757dbb423ec 100644 (file)
@@ -13,7 +13,7 @@ provide APIs on different levels of abstraction. The core library libnl.so
 provides a fundamental set of functions to deal with sockets, construct
 messages, and send/receive those messages. Additional high level interfaces
 for several individual netlink protocols are provided in separate
-libraries (e.g. \ref route_doc "nl-route.so", \ref genl_doc "nl-genl.so", ...).
+libraries (e.g. "nl-route.so", "nl-genl.so", ...).
 
 The library is designed to ensure that all components are optional, i.e.
 even though the core library provides a caching system which allows to
@@ -28,11 +28,6 @@ version is used with a considerably older kernel.
 
 \section main_toc Table of Contents
 
-- \subpage core_doc "1. Netlink Core Library (-lnl)"
-- \subpage route_doc "2. Routing Netlink Library (-lnl-route)"
-- \subpage genl_doc "3. Generic Netlink Library (-lnl-genl)"
-- \subpage nf_doc "4. Netfilter Netlink Library (-lnl-nf)"
-
 \section main_trees GIT Trees
 
 \subsection tree_dev Development Tree
index 62f0911be5f21488542a1c97b824fa0e525d3ece..ee2922cb6416659e7a3211af8ce8e2bb316d43eb 100644 (file)
--- a/lib/msg.c
+++ b/lib/msg.c
@@ -181,8 +181,6 @@ static void __init init_msg_size(void)
  * Calculates size of netlink message based on payload length.
  * @arg payload                Length of payload
  *
- * See \ref core_msg_fmt_align for more information on alignment.
- *
  * @return size of netlink message without padding.
  */
 int nlmsg_size(int payload)
@@ -201,8 +199,6 @@ int nlmsg_msg_size(int payload)
  *
  * This function is idential to nlmsg_size() + nlmsg_padlen().
  *
- * See \ref core_msg_fmt_align for more information on alignment.
- *
  * @return Size of netlink message including padding.
  */
 int nlmsg_total_size(int payload)
@@ -218,8 +214,6 @@ int nlmsg_total_size(int payload)
  * the end of the message to ensure that the next netlink message header begins
  * properly aligned to NLMSG_ALIGNTO.
  *
- * See \ref core_msg_fmt_align for more information on alignment.
- *
  * @return Number of bytes of padding needed.
  */
 int nlmsg_padlen(int payload)
index aa79b095b07ca8cfca724d657f308a29d9875e50..fb2e9bef0e3642309aaa550b138ea7175ad3f77b 100644 (file)
@@ -237,6 +237,7 @@ int rtnl_cls_change(struct nl_sock *sk, struct rtnl_cls *cls, int flags)
 /**
  * Build netlink message requesting the deletion of a classifier
  * @arg cls            Classifier to delete
+ * @arg flags          Additional netlink message flags
  * @arg result         Pointer to store resulting netlink message
  *
  * The behaviour of this function is identical to rtnl_cls_delete() with
@@ -264,6 +265,7 @@ int rtnl_cls_build_delete_request(struct rtnl_cls *cls, int flags,
  * Delete classifier
  * @arg sk             Netlink socket
  * @arg cls            Classifier to delete
+ * @arg flags          Additional netlink message flags
  *
  * Builds a \c RTM_DELTFILTER netlink message requesting the deletion
  * of a classifier and sends the message to the kernel.
index 7bd47283d18d01b98889e95ffa4cda3e01ffe48a..6826a05ef874c7e059bcef2c227bea314c39c4a6 100644 (file)
@@ -307,7 +307,6 @@ void rtnl_tc_set_link(struct rtnl_tc *tc, struct rtnl_link *link)
 /**
  * Get link of traffic control object
  * @arg tc             traffic control object
- * @arg link           link object
  *
  * Returns the link of a traffic control object. The link is only
  * returned if it has been set before via rtnl_tc_set_link() or