documentation updates
This commit is contained in:
parent
21d52eabba
commit
63548f5664
28 changed files with 758 additions and 384 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -8,6 +8,8 @@ Netlink Core Library
|
|||
====================
|
||||
Thomas Graf <tgraf@suug.ch>
|
||||
3.0, March 30 2011:
|
||||
:toc:
|
||||
:numbered:
|
||||
|
||||
== Introduction
|
||||
|
||||
|
|
16
doc/index.txt
Normal file
16
doc/index.txt
Normal file
|
@ -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
|
720
doc/route.txt
Normal file
720
doc/route.txt
Normal file
|
@ -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
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
|
@ -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));
|
|
@ -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 */
|
|
@ -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 */
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
};
|
|
@ -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]);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
#include <netlink/msg.h>
|
||||
|
||||
struct nlmsghdr *hdr;
|
||||
|
||||
nlmsg_for_each(hdr, stream, length) {
|
||||
/* do something with message */
|
||||
}
|
|
@ -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]));
|
||||
}
|
||||
}
|
|
@ -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 |
|
||||
* +--------+---------+
|
||||
*/
|
|
@ -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);
|
|
@ -1,10 +0,0 @@
|
|||
/**
|
||||
* \cond skip
|
||||
* vim:syntax=doxygen
|
||||
* \endcond
|
||||
|
||||
\page genl_doc Generic Netlink Library (-lnl-genl)
|
||||
|
||||
\section genl_intro Introduction
|
||||
|
||||
*/
|
10
doc/src/nf.c
10
doc/src/nf.c
|
@ -1,10 +0,0 @@
|
|||
/**
|
||||
* \cond skip
|
||||
* vim:syntax=doxygen
|
||||
* \endcond
|
||||
|
||||
\page nf_doc Netfilter Netlink Library (-lnl-nf)
|
||||
|
||||
\section nf_intro Introduction
|
||||
|
||||
*/
|
|
@ -1,10 +0,0 @@
|
|||
/**
|
||||
* \cond skip
|
||||
* vim:syntax=doxygen
|
||||
* \endcond
|
||||
|
||||
\page route_doc Routing Netlink Library (-lnl-route)
|
||||
|
||||
\section route_intro Introduction
|
||||
|
||||
*/
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue