more documentation updates

- improved stylesheets for both doxygen and asciidoc
 - use of xml doxygen layout
 - python script to resolve <<foo>> asciidoc references to
   <<foo, title>> based on the target caption
 - graphics for netlink and netlink error headers
 - more link documentation
This commit is contained in:
Thomas Graf 2011-07-21 16:24:31 +02:00
parent dea6de42f6
commit 50074732af
14 changed files with 998 additions and 235 deletions

View File

@ -519,7 +519,7 @@ FILE_VERSION_FILTER =
# You can optionally specify a file name after the option, if omitted
# DoxygenLayout.xml will be used as the name of the layout file.
LAYOUT_FILE =
LAYOUT_FILE = DoxygenLayout.xml
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages

185
doc/DoxygenLayout.xml Normal file
View File

@ -0,0 +1,185 @@
<doxygenlayout version="1.0">
<!-- Navigation index tabs for HTML output -->
<navindex>
<tab type="mainpage" visible="yes" title=""/>
<tab type="pages" visible="yes" title="" intro=""/>
<tab type="modules" visible="yes" title="" intro=""/>
<tab type="namespaces" visible="no" title="">
<tab type="namespaces" visible="yes" title="" intro=""/>
<tab type="namespacemembers" visible="yes" title="" intro=""/>
</tab>
<tab type="classes" visible="no" title="">
<tab type="classes" visible="yes" title="" intro=""/>
<tab type="classindex" visible="$ALPHABETICAL_INDEX" title=""/>
<tab type="hierarchy" visible="yes" title="" intro=""/>
<tab type="classmembers" visible="yes" title="" intro=""/>
</tab>
<tab type="files" visible="yes" title="">
<tab type="files" visible="yes" title="" intro=""/>
<tab type="globals" visible="yes" title="" intro=""/>
</tab>
<tab type="dirs" visible="yes" title="" intro=""/>
<tab type="examples" visible="yes" title="" intro=""/>
</navindex>
<!-- Layout definition for a class page -->
<class>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<inheritancegraph visible="$CLASS_GRAPH"/>
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
<allmemberslink visible="yes"/>
<memberdecl>
<nestedclasses visible="yes" title=""/>
<publictypes title=""/>
<publicslots title=""/>
<signals title=""/>
<publicmethods title=""/>
<publicstaticmethods title=""/>
<publicattributes title=""/>
<publicstaticattributes title=""/>
<protectedtypes title=""/>
<protectedslots title=""/>
<protectedmethods title=""/>
<protectedstaticmethods title=""/>
<protectedattributes title=""/>
<protectedstaticattributes title=""/>
<packagetypes title=""/>
<packagemethods title=""/>
<packagestaticmethods title=""/>
<packageattributes title=""/>
<packagestaticattributes title=""/>
<properties title=""/>
<events title=""/>
<privatetypes title=""/>
<privateslots title=""/>
<privatemethods title=""/>
<privatestaticmethods title=""/>
<privateattributes title=""/>
<privatestaticattributes title=""/>
<friends title=""/>
<related title="" subtitle=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<typedefs title=""/>
<enums title=""/>
<constructors title=""/>
<functions title=""/>
<related title=""/>
<variables title=""/>
<properties title=""/>
<events title=""/>
</memberdef>
<usedfiles visible="$SHOW_USED_FILES"/>
<authorsection visible="yes"/>
</class>
<!-- Layout definition for a namespace page -->
<namespace>
<briefdescription visible="yes"/>
<memberdecl>
<nestednamespaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection visible="yes"/>
</namespace>
<!-- Layout definition for a file page -->
<file>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<includegraph visible="$INCLUDE_GRAPH"/>
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
<sourcelink visible="yes"/>
<memberdecl>
<classes visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
<memberdef>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection/>
</file>
<!-- Layout definition for a group page -->
<group>
<briefdescription visible="yes"/>
<groupgraph visible="$GROUP_GRAPHS"/>
<detaileddescription title=""/>
<memberdecl>
<classes visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<dirs visible="yes" title=""/>
<nestedgroups visible="yes" title=""/>
<files visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<pagedocs/>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
</memberdef>
<authorsection visible="yes"/>
</group>
<!-- Layout definition for a directory page -->
<directory>
<briefdescription visible="yes"/>
<directorygraph visible="yes"/>
<memberdecl>
<dirs visible="yes"/>
<files visible="yes"/>
</memberdecl>
<detaileddescription title=""/>
</directory>
</doxygenlayout>

View File

@ -4,14 +4,16 @@
ASCIIDOCOPTS=-a pygments -a language=c -a icons \
-a toc2 \
-a numbered \
-a imagesdir="./images/" \
-a iconsdir="./images/icons" \
-a stylesdir="${abs_srcdir}/stylesheets/"
%.html: %.txt
asciidoc $(ASCIIDOCOPTS) $<
./doxygen-link.py libnl.dict $@ > doxygen-link.tmp
mv doxygen-link.tmp $@
./resolve-asciidoc-refs.py $< > asciidoc.tmp
asciidoc $(ASCIIDOCOPTS) -o $@ asciidoc.tmp
./doxygen-link.py libnl.dict $@ > asciidoc.tmp
mv asciidoc.tmp $@
asciidoc: core.html route.html index.html

View File

@ -20,25 +20,42 @@ provides a abstract data type framework which eases the implementation
of object based netlink protocols where objects are added, removed, or
modified using a netlink based protocol.
.Sub Libraries
.Library Hierarchy
Several sub libraries exist which provide APIs to several netlink
protocols:
The suite is split into multiple libraries:
- link:route.html[libnl-route] Adresses, Links, Neighbours, Routing & Traffic Control
- Netfilter
- Generic Netlink
image:library_overview.png["Library Hierarchy"]
+FIXME+: Add links
link:core.html[Netlink Library] (libnl)::
Socket handling, sending and receiving, message construction and parsing, ...
link:route.html[Routing Family Library] (libnl-route)::
Adresses, links, neighbours, routing, traffic control, neighbour tables, ...
Netfilter Library (libnl-nf)::
Connection tracking, logging, queueing
Generic Netlink Library (libnl-genl)::
Controller API, family and command registration
=== How To Read This Documentation
The documentation consists of this manual and the API reference pages.
Both contain references to each other and as many examples as
possible.
The libraries provide a broad set of APIs of which most applications only
require a small subset of it. Depending on the type of application, some
users may only be interested in the low level netlink messaging API while
others wish to make heavy use of the high level API.
In any case it is recommended to get familiar with the netlink protocol
first.
- <<core_netlink_fundamentals>>
The low level APIs are described in:
- <<core_sockets>>
- <<core_send_recv>>
+FIXME+
=== Linking to this Library
@ -48,9 +65,10 @@ The main header is `<netlink/netlink.h>`. Additional headers need to
be included in your sources depending on the subsystems your program
makes use of.
.Version Checking
[source,c]
-----
#include <netlink/netlink.h>
#include <netlink/version.h>
#if LIBNL_VER_NUM >= LIBNL_VER(3,0)
/* include code if compiled with libnl version >= 3.0 */
@ -64,8 +82,9 @@ $ gcc myprogram.c -o myprogram -lnl
=== Debugging
The library contains debugging statements which are printed to
+stderr+ if the environment variable +NLDBG+ is set to > 0.
The library has been compiled with debugging statements enabled it will
print debug information to +stderr+ if the environment variable +NLDBG+
is set to > 0.
-----
$ NLDBG=2 ./myprogram
@ -130,7 +149,7 @@ $ NLCB=debug ./myprogram
-----
[[core_prot_fund]]
[[core_netlink_fundamentals]]
== Netlink Protocol Fundamentals
The netlink protocol is a socket based IPC mechanism used for
@ -147,19 +166,36 @@ each peer.
A netlink protocol is typically based on messages and consists of the
netlink message header (+struct nlmsghdr+) plus the payload attached
to it. The payload can consist of arbitary data but usually contains
to it. The payload can consist of arbitrary data but usually contains
a fixed size protocol specific header followed by a stream of
attributes.
.Netlink message header (+struct nlmsghdr+)
[cols="^s,^s", width="40%", align="center"]
|==============================================================
2+| Length
| Type | Flags
2+| Sequence Number
2+| Port (Address)
|==============================================================
.Netlink message header (struct nlmsghdr)
image:nlmsghdr.png[align="center", alt="Netlink Message Header"]
Total Length (32bit)::
Total length of the message in bytes including the netlink message header.
Message Type (16bit)::
The message type specifies the type of payload the message is carrying.
Several standard message types are defined by the netlink protocol.
Additional message types may be defined by each protocol family. See
<<core_msg_types>> for additional information.
Message Flags (16bit)::
The message flags may be used to modify the behaviour of a message type.
See section <<core_msg_flags>> for a list of standard message flags.
Sequence Number (32bit)::
The sequence number is optional and may be used to allow referring to
a previous message, e.g. an error message can refer to the original
request causing the error.
Port Number (32bit)::
The port number specifies the peer to which the message should be delivered
to. If not specified, the message will be delivered to the first matching
kernel side socket of the same protocol family.
[[core_msg_types]]
=== Message Types
@ -193,10 +229,9 @@ The type of message is primarly identified by its 16 bit message type set
in the message header. The following standard message types are defined:
- +NLMSG_NOOP+ - No operation, message must be discarded
- +NLMSG_ERROR+ - Error message or ACK, see <<core_errmsg, Error
Messages>>, respectively <<core_msg_ack, ACK Messages>>
- +NLMSG_DONE+ - End of multipart sequence, see <<core_multipart,
Multipart Messages>>
- +NLMSG_ERROR+ - Error message or ACK, see <<core_errmsg>>
respectively <<core_msg_ack>>
- +NLMSG_DONE+ - End of multipart sequence, see <<core_multipart>>
- +NLMSG_OVERRUN+ - Overrun notification (Error)
Every netlink protocol is free to define own message types. Note that
@ -231,8 +266,8 @@ msc {
--------
The configuration may be changed by sending a +MSG_SETCFG+ which will
be responded to with either a ACK (see <<core_msg_ack, ACK Messages>>)
or a error message (see <<core_errmsg, Error Messages>>).
be responded to with either a ACK (see <<core_msg_ack>>)
or a error message (see <<core_errmsg>>).
["mscgen"]
--------
@ -294,16 +329,7 @@ Error messages can be sent in response to a request. Error messages must
use the standard message type +NLMSG_ERROR+. The payload consists of a
error code and the original netlink mesage header of the request.
.Netlink Error Message Header (+struct nlmsggerr+)
[cols="^,^", width="50%"]
|==============================================================
2+| Length
|.nlmsg_type = NLMSG_ERROR | .nlmsg_flags = 0
2+| Sequence number of the orig request
2+| Port number of the orig request
2+| Error Code (e.g. EINVAL)
2+| Netlink Message Header of orig. request
|==============================================================
image:nlmsgerr.png["Netlink Errror Message header"]
Error messages should set the sequence number to the sequence number
of the request which caused the error.
@ -337,6 +363,7 @@ msc {
ACK messages also use the message type +NLMSG_ERROR+ and payload
format but the error code is set to 0.
[[core_msg_flags]]
==== Message Flags
The following standard flags are defined
@ -349,19 +376,16 @@ The following standard flags are defined
#define NLM_F_ECHO 8
--------
- `NLM_F_REQUEST` - Message is a request, see <<core_msg_type, Message
Types>>.
- `NLM_F_MULTI` - Multipart message, see <<core_multipart, Multipart
Messages>>
- `NLM_F_ACK` - ACK message requested, see <<core_msg_ack, ACK
Messages>>.
- `NLM_F_REQUEST` - Message is a request, see <<core_msg_type>>.
- `NLM_F_MULTI` - Multipart message, see <<core_multipart>>
- `NLM_F_ACK` - ACK message requested, see <<core_msg_ack>>.
- `NLM_F_ECHO` - Request to echo the request.
The flag +NLM_F_ECHO+ is similar to the `NLM_F_ACK` flag. It can be
used in combination with `NLM_F_REQUEST` and causes a notification
which is sent as a result of a request to also be sent to the sender
regardless of whether the sender has subscribed to the corresponding
multicast group or not. See <<core_multicast, Multicast Groups>>
multicast group or not. See <<core_multicast>>
Additional universal message flags are defined which only apply for
+GET+ requests:
@ -383,8 +407,7 @@ Additional universal message flags are defined which only apply for
Use of these flags is completely optional and many netlink protocols only
make use of the `NLM_F_DUMP` flag which typically requests the receiver
to send a list of all objects in the context of the message type as a
sequence of multipart messages (see <<core_multipart, Multipart
Messages>>).
sequence of multipart messages (see <<core_multipart>>).
Another set of flags exist related to `NEW` or `SET` requests. These
flags are mutually exclusive to the `GET` flags:
@ -411,20 +434,19 @@ Netlink allows the use of sequence numbers to help relate replies to
requests. It should be noted that unlike in protocols such as TCP
there is no strict enforcment of the sequence number. The sole purpose
of sequence numbers is to assist a sender in relating replies to the
corresponding requests. See <<core_msg_type, Message Types>> for more
information.
corresponding requests. See <<core_msg_type>> for more information.
Sequence numbers are managed on a per socket basis, see
<<core_sk_seq_num, Socket Sequence Numbers>> for more information on
how to use sequence numbers.
<<core_sk_seq_num>> for more information on how to use sequence numbers.
[[core_multicast]]
=== Multicast Groups
TODO
See <<core_sk_multicast, Multicast Group Socket Interface>>
See <<core_sk_multicast>>
[[core_sockets]]
== Netlink Sockets
In order to use the netlink protocol, a netlink socket is required.
@ -434,10 +456,10 @@ same netlink protocol, e.g. one socket to send requests and receive
replies and another socket subscribed to a multicast group to receive
notifications.
=== Socket Allocation & Freeing
=== Allocation & Freeing
The netlink socket and all its related attributes are represented by
=struct nl_sock=.
+struct nl_sock+.
[source,c]
--------
@ -470,8 +492,7 @@ unsigned int nl_socket_use_seq(struct nl_sock *sk);
Most applications will not want to deal with sequence number handling
themselves though. When using nl_send_auto() the sequence number is
filled out automatically and matched again on the receiving side. See
<<core_send_recv, Sending and Receiving of Messages / Data>> for more
information.
<<core_send_recv>> for more information.
This behaviour can and must be disabled if the netlink protocol
implemented does not use a request/reply model, e.g. when a socket is
@ -567,7 +588,7 @@ while (1)
[[core_sk_cb]]
=== Modifiying Socket Callback Configuration
See <<core_cb, Callback Configuration>> for more information on
See <<core_cb>> for more information on
callback hooks and overwriting capabilities.
Each socket is assigned a callback configuration which controls the
@ -696,9 +717,9 @@ int nl_socket_set_passcred(struct nl_sock *sk, int state);
.Enable/Disable Auto-ACK Mode
The following functions allow to enable/disable Auto-ACK mode on a
socket. See <<core_auto_ack, Auto-ACK Mode>> for more information on
what implications that has. Auto-ACK mode is enabled by default.
The following functions allow to enable/disable Auto-ACK mode on a socket.
See <<core_auto_ack>> for more information on what implications that has.
Auto-ACK mode is enabled by default.
[source,c]
--------
@ -742,7 +763,7 @@ NOTE: Processing of NETLINK_PKTINFO has not been implemented yet.
== Sending and Receiving of Messages / Data
[[core_send]]
=== Sending Netlink Messages
=== Sending Messages
The standard method of sending a netlink message over a netlink socket
is to use the function nl_send_auto(). It will automatically complete
@ -800,7 +821,7 @@ it will try to fall back to the peer address specified in the socket
unaddressed and it is left to the kernel to find the correct peer.
nl_send_iovec() also adds credentials if present and enabled
(see <<core_sk_cred, Socket Credentials>>).
(see <<core_sk_cred>>).
The message is then passed on to nl_sendmsg().
@ -838,8 +859,8 @@ may inspect or modify the message and return an error code. If this
error code is NL_OK the message is sent using sendmsg() resulting in
the number of bytes written being returned. Otherwise the message
sending process is aborted and the error code specified by the
callback function is returned. See <<core_sk_cb, Socket Callback
Configuration>> for more information on how to set callbacks.
callback function is returned. See <<core_sk_cb>> for more information
on how to set callbacks.
.Sending Raw Data with nl_sendto()
@ -889,7 +910,7 @@ nl_send_simple(sock, RTM_GETLINK, NLM_F_DUMP, &rt_hdr, sizeof(rt_hdr));
--------
[[core_recv]]
=== Receiving Netlink Messages
=== Receiving Messages
The easiest method to receive netlink messages is to call nl_recvmsgs_default().
It will receive messages based on the semantics defined in the socket. The
@ -917,12 +938,11 @@ nl_recvmsgs() implements the actual receiving loop, it blocks until a
netlink message has been received unless the socket has been put into
non-blocking mode.
For the unlikely scenario that certain required receive
characteristics can not be achieved by fine tuning the internal
recvmsgs function using the callback configuration (see <<core_sk_cb,
Socket Callback Configuration>>) the application may provide a
complete own implementation of it and overwrite all calls to
nl_recvmsgs() with the function nl_cb_overwrite_recvmsgs().
For the unlikely scenario that certain required receive characteristics
can not be achieved by fine tuning the internal recvmsgs function using
the callback configuration (see <<core_sk_cb>>) the application may provide
a complete own implementation of it and overwrite all calls to nl_recvmsgs()
with the function nl_cb_overwrite_recvmsgs().
[source,c]
--------
@ -972,21 +992,21 @@ will be done repeately until the parser returns NL_STOP, an error was
returned or all data has been parsed.
In case the last message parsed successfully was a multipart message
(see <<core_multipart, Multipart Messages>>) and the parser did not
(see <<core_multipart>>) and the parser did not
quit due to either an error or NL_STOP nl_recv() respectively the
applications own implementation will be called again and the parser
starts all over.
See <<core_parse_character, Parse Characteristics>> for information on
how to extract valid netlink messages from the parser and on how to
control the behaviour of it.
See <<core_parse_character>> for information on how to extract valid
netlink messages from the parser and on how to control the behaviour
of it.
[[core_parse_character]]
.Parsing Characteristics
The internal parser is invoked for each netlink message received from
a netlink socket. It is typically fed by nl_recv() (see
<<core_recv_character, Receive Characteristics>>).
<<core_recv_character>>).
The parser will first ensure that the length of the data stream
provided is sufficient to contain a netlink message header and that
@ -1010,8 +1030,7 @@ always returns NL_OK.
Another callback hook NL_CB_SEND_ACK exists which is called if the
message has the NLM_F_ACK flag set. Although I am not aware of any
userspace netlink socket doing this, the application may want to send
an ACK message back to the sender (see <<core_msg_ack, ACK
Messages>>).
an ACK message back to the sender (see <<core_msg_ack>>).
[source,c]
--------
@ -1041,12 +1060,12 @@ Messages>>).
TODO
== Netlink Message Parsing & Construction
== Message Parsing & Construction
=== Message Format
See <<core_prot_fund, Protocol Fundamentals>> for an introduction to
the netlink protocol and its message format.
See <<core_netlink_fundamentals>> for an introduction to the netlink
protocol and its message format.
.Alignment
@ -1097,8 +1116,7 @@ the parsing manually. This method is described below. Alternatively
the library also offers an interface to implement a parser as part of
a cache operations set which is especially useful when your protocol
deals with objects of any sort such as network links, routes, etc.
This high level interface is described in <<core_cache, Caching
System>>
This high level interface is described in <<core_cache>>.
.Splitting a byte stream into separate messages
@ -1234,8 +1252,7 @@ struct nlattr *nlmsg_attrdata(const struct nlmsghdr *hdr, int hdrlen);
int nlmsg_attrlen(const struct nlmsghdr *hdr, int hdrlen);
--------
See <<core_attr, Attributes>> for more information on how to use netlink
attributes.
See <<core_attr>> for more information on how to use netlink attributes.
.Parsing a Message the Easy Way
@ -1244,8 +1261,7 @@ step. If +hdrlen > 0+ it will first call nlmsg_valid_hdr() to check
if the protocol header fits into the message. If there is more payload
to parse, it will assume it to be attributes and parse the payload
accordingly. The function behaves exactly like nla_parse() when
parsing attributes, see <<core_attr_nla_parse, Parsing Attributes the
Easy Way>>.
parsing attributes, see <<core_attr_parse_easy>>.
[source,c]
--------
@ -1263,13 +1279,13 @@ int nlmsg_validate(struct nlmsghdr *hdr, int hdrlen, intmaxtype,
struct nla_policy *policy);
--------
See <<core_attr_nla_parse, Parsing Attributes the Easy Way>> for an
example and more information on attribute parsing.
See <<core_attr_parse_easy>> for an example and more information on
attribute parsing.
=== Construction of a Message
See <<core_msg_format, Message Format>> for information on the netlink
message format and alignment requirements.
See <<core_msg_format>> for information on the netlink message format
and alignment requirements.
Message construction is based on struct nl_msg which uses an internal
buffer to store the actual netlink message. struct nl_msg +does not+
@ -1374,14 +1390,13 @@ To use this feature, the message must be sent using the function
nl_send_auto(). Like +port+, the argument +seqnr+ can be set to
+NL_AUTO_PORT+ indicating that the local port assigned to the socket
should be used as source port. This is generally a good idea unless
you are replying to a request. See <<core_prot_fund, Netlink Protocol
Fundamentals>> for more information on how to fill the header.
you are replying to a request. See <<core_netlink_fundamentals>>
for more information on how to fill the header.
NOTE: The argument +payload+ can be used by the application to reserve
room for additional data after the header. A value of > 0 is
equivalent to calling +nlmsg_reserve(msg, payload,
NLMSG_ALIGNTO)+. See <<core_msg_reserve, Reserving room at the
end of the message>> for more information on reserving room for
equivalent to calling +nlmsg_reserve(msg, payload, NLMSG_ALIGNTO)+.
See <<core_msg_reserve>> for more information on reserving room for
data.
.Example
@ -1477,10 +1492,10 @@ NOTE: `nlmsg_append()` will *not* align the start of the data. Any
.Adding attribtues to a message
Construction of attributes and addition of attribtues to the message is
covereted in section <<core_attr, Attributes>>.
covereted in section <<core_attr>>.
[[core_attr]]
== Netlink Attributes
== Attributes
Any form of payload should be encoded as netlink attributes whenever
possible. Use of attributes allows to extend any netlink protocol in
@ -1510,9 +1525,8 @@ the message format will never ever change in the future.
=== Attribute Format
Netlink attributes allow for any number of data chunks of arbitary
length to be attached to a netlink message. See <<core_msg_attr,
Messages Attributes>> for more information on where attributes are
stored in the message.
length to be attached to a netlink message. See <<core_msg_attr>>
for more information on where attributes are stored in the message.
The format of the attributes data returned by nlmsg_attrdata() is as
follows:
@ -1532,17 +1546,7 @@ Every attribute must start at an offset which is a multiple of
to be padded at the end, the function nla_padlen() returns the number
of padding bytes that will or need to be added.
--------
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-------------------------------------------------------------+
| Length | Type |
+------------------------------+------------------------------+
| Attribute Payload |
. .
. .
+-------------------------------------------------------------+
--------
image:attribute_hdr.png["Netlink Attribute Header"]
Every attribute is encoded with a type and length field, both 16 bits,
stored in the attribute header (struct nlattr) preceding the attribute
@ -1556,16 +1560,14 @@ the next attribute.
.Splitting an Attributes Stream into Attributes
Although most applications will use one of the functions from the
nlmsg_parse() family (See <<core_attr_nla_parse, Parsing Attributes
the Easy Way>>) an interface exists to split the attributes stream
manually.
nlmsg_parse() family (See <<core_attr_parse_easy>>) an interface exists
to split the attributes stream manually.
As described in <<core_attr_format, Attribute Format>> the attributes
section contains a infinite sequence or stream of attributes. The
pointer returned by nlmsg_attrdata() (See <<core_msg_attr, Message
Attributes>>) points to the first attribute header. Any subsequent
attribute is accessed with the function nla_next() based on the
previous header.
As described in <<core_attr_format>> the attributes section contains a
infinite sequence or stream of attributes. The pointer returned by
nlmsg_attrdata() (See <<core_msg_attr>>) points to the first attribute
header. Any subsequent attribute is accessed with the function nla_next()
based on the previous header.
[source,c]
--------
@ -1654,7 +1656,7 @@ void *nla_data(const struct nlattr *hdr);
[NOTE]
Never rely on the size of a payload being what you expect it to be.
_Always_ verify the payload size and make sure that it matches your
expectations. See <<core_attr_validation, Attribute Validation>>.
expectations. See <<core_attr_validation>>
[[core_attr_validation]]
.Attribute Validation
@ -1702,8 +1704,7 @@ introduced attributes to continue functioning.
--------
#include <netlink/attr.h>
int nla_validate(struct nlattr *head, int len, int maxtype,
struct nla_policy *policy);
int nla_validate(struct nlattr *head, int len, int maxtype, struct nla_policy *policy);
--------
The function nla_validate() returns 0 if all attributes are valid,
@ -1712,26 +1713,24 @@ otherwise a validation failure specific error code is returned.
Most applications will rarely use nla_validate() directly but use
nla_parse() instead which takes care of validation in the same way but
also parses the the attributes in the same step. See
<<core_attr_nla_parse, Parsing Attributes the Easy Way>> for an
example and more information.
<<core_attr_parse_easy>> for an example and more information.
The validation process in detail:
-# If attribute type is 0 or exceeds +maxtype+ attribute is
considered valid, 0 is returned.
-# If payload length is < +minlen+, +-NLE_ERANGE+ is returned.
-# If +maxlen+ is defined and payload exceeds it, +-NLE_ERANGE+
is returned.
-# Datatype specific requirements rules, see
<<core_attr_types, Attribute Types>>
-# If all is ok, 0 is returned.
[[core_attr_nla_parse]]
. If attribute type is 0 or exceeds +maxtype+ attribute is
considered valid, 0 is returned.
. If payload length is < +minlen+, +-NLE_ERANGE+ is returned.
. If +maxlen+ is defined and payload exceeds it, +-NLE_ERANGE+
is returned.
. Datatype specific requirements rules, see <<core_attr_types>>
. If all is ok, 0 is returned.
[[core_attr_parse_easy]]
.Parsing Attributes the Easy Way
Most applications will not want to deal with splitting attribute
streams themselves as described in <<core_attr_parse_split, Splitting
an Attributes Stream into Attributes>>. A much easier method is to use
nla_parse().
streams themselves as described in <<core_attr_parse_split>>
A much easier method is to use nla_parse().
[source,c]
--------
@ -1742,15 +1741,13 @@ int nla_parse(struct nlattr **attrs, int maxtype, struct nlattr *head,
--------
The function nla_parse() will iterate over a stream of attributes,
validate each attribute as described in <<core_attr_validation,
Attribute Validation>>. If the validation of all attributes succeeds,
a pointer to each attribute is stored in the +attrs+ array at
`attrs[nla_type(attr)]`.
validate each attribute as described in <<core_attr_validation>>
If the validation of all attributes succeeds, a pointer to each attribute
is stored in the +attrs+ array at `attrs[nla_type(attr)]`.
As an alernative to nla_parse() the function nlmsg_parse() can be used
to parse the message and its attributes in one step. See
<<core_attr_nla_parse, Parsing Attributes the Easy Way>> for
information on how to use these functions.
<<core_attr_parse_easy>> for information on how to use these functions.
.Example:
@ -1815,8 +1812,7 @@ struct nlattr *nlmsg_find_attr(struct nlmsghdr *hdr, int hdrlen, int attrtype);
--------
NOTE: `nla_find()` and `nlmsg_find_attr()` will *not* search in nested
attributes recursively, see <<core_attr_nested, Nested
Attributes>>.
attributes recursively, see <<core_attr_nested>>.
==== Iterating over a Stream of Attributes
@ -1901,8 +1897,8 @@ int my_put(struct nl_msg *msg)
}
--------
See <<core_attr_types, Attribute Types>> for datatype specific
attribute construction functions.
See <<core_attr_types>> for datatype specific attribute construction
functions.
.Exception Based Attribute Construction
@ -1931,8 +1927,8 @@ nla_put_failure:
}
--------
See <<core_attr_types, Attribute Types>> for more information on the
datatype specific exception based variants.
See <<core_attr_types>> for more information on the datatype specific
exception based variants.
[[core_attr_types]]
=== Attribute Data Types
@ -2114,11 +2110,10 @@ if (attrs[ATTR_FLAG])
[[core_attr_nested]]
==== Nested Attributes
As described in <<core_attr, Netlink Attributes>>, attributes can be
nested allowing for complex tree structures of attributes. It is
commonly used to delegate the responsibility of a subsection of the
message to a subsystem. Nested attributes are also commonly used for
transmitting list of objects.
As described in <<core_attr>>, attributes can be nested allowing for
complex tree structures of attributes. It is commonly used to delegate
the responsibility of a subsection of the message to a subsystem.
Nested attributes are also commonly used for transmitting list of objects.
When nesting attributes, the nested attributes are included as payload
of a container attribute.

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
doc/images/ifinfomsg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
doc/images/nlmsgerr.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

BIN
doc/images/nlmsghdr.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -1,16 +1,22 @@
libnl
=====
Thomas Graf <tgraf@suug.ch>
3.0, April 12 2011:
Documentation Overview - libnl Suite
====================================
== Table of Contents
=== Libraries
- link:core.html[Core Library]
- link:route.html[Routing Family]
== Libraries
=== Tools
- link:link.html[Link Utility]
image:library_overview.png["Library Hierarchy"]
=== Python Packages
link:core.html[Netlink Library] (libnl)::
Socket handling, sending and receiving, message construction and parsing, ...
link:route.html[Routing Family Library] (libnl-route)::
Adresses, links, neighbours, routing, traffic control, neighbour tables, ...
Netfilter Library (libnl-nf)::
Connection tracking, logging, queueing
Generic Netlink Library (libnl-genl)::
Controller API, family and command registration
== Python Packages
- netlink.core
- netlink.route.link

View File

@ -2,21 +2,31 @@
body, table, div, p, dl {
font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif;
font-size: 12px;
font-size: 13px;
}
/* @group Heading Levels */
h1, h2, h3 {
color: #990000;
}
h1 {
font-size: 180%;
font-size: 150%;
}
.title {
font-size: 150%;
font-weight: bold;
margin: 10px 2px;
}
h2 {
font-size: 140%;
font-size: 120%;
}
h3 {
font-size: 120%;
font-size: 100%;
}
dt {
@ -82,13 +92,15 @@ div.navtab {
/* @group Link Styling */
a {
color: #3D578C;
/* color: #3D578C; */
color: #990000;
font-weight: normal;
text-decoration: none;
}
.contents a:visited {
color: #4665A2;
/* color: #4665A2; */
color: #990000;
}
a:hover {
@ -118,7 +130,8 @@ a.elRef {
}
a.code {
color: #4665A2;
/* color: #4665A2; */
color: #990000;
}
a.codeRef {
@ -158,6 +171,7 @@ div.ah {
border-radius: 0.5em;
-webkit-border-radius: .5em;
-moz-border-radius: .5em;
box-shadow: 2px 2px 3px #999;
-webkit-box-shadow: 2px 2px 3px #999;
-moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444));
@ -167,7 +181,6 @@ div.ah {
div.groupHeader {
margin-left: 16px;
margin-top: 12px;
margin-bottom: 6px;
font-weight: bold;
}
@ -185,16 +198,7 @@ body {
div.contents {
margin-top: 10px;
margin-left: 10px;
margin-right: 10px;
}
div.contents p {
margin-left: 30px;
}
div.contents .fragment {
margin-left: 30px;
margin-right: 20px;
margin-right: 5px;
}
td.indexkey {
@ -370,8 +374,13 @@ table.memberdecls {
white-space: nowrap;
}
.memItemRight {
width: 100%;
}
.memTemplParams {
color: #4665A2;
/* color: #4665A2; */
color: #990000;
white-space: nowrap;
}
@ -382,10 +391,11 @@ table.memberdecls {
/* Styles for detailed member documentation */
.memtemplate {
font-size: 100%;
color: #4665A2;
font-size: 80%;
/* color: #4665A2; */
color: #990000;
font-weight: normal;
margin-left: 3px;
margin-left: 9px;
}
.memnav {
@ -397,10 +407,14 @@ table.memberdecls {
padding: 2px;
}
.mempage {
width: 100%;
}
.memitem {
padding: 0;
border: 1px solid #C4CFE5;
margin-bottom: 30px;
margin-bottom: 10px;
margin-right: 5px;
}
.memname {
@ -410,17 +424,53 @@ table.memberdecls {
}
.memproto {
background-color: #F9FAFC;
border-bottom: 1px solid #A3B4D7;
border-top: 1px solid #A8B8D9;
border-left: 1px solid #A8B8D9;
border-right: 1px solid #A8B8D9;
border-bottom: 1px solid #A8B8D9;
padding: 6px 0px 6px 0px;
color: #000000;
color: #253555;
font-weight: bold;
/* text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); */
/* opera specific markup */
box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
border-top-right-radius: 8px;
border-top-left-radius: 8px;
/* firefox specific markup */
-moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
-moz-border-radius-topright: 8px;
-moz-border-radius-topleft: 8px;
/* webkit specific markup */
-webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
-webkit-border-top-right-radius: 8px;
-webkit-border-top-left-radius: 8px;
background-image:url('nav_f.png');
background-repeat:repeat-x;
background-color: #E2E8F2;
}
.memdoc {
border-bottom: 1px solid #A8B8D9;
border-left: 1px solid #A8B8D9;
border-right: 1px solid #A8B8D9;
padding: 2px 5px;
margin-left: 30px;
background-color: #FBFCFD;
border-top-width: 0;
/* opera specific markup */
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
/* firefox specific markup */
-moz-border-radius-bottomleft: 8px;
-moz-border-radius-bottomright: 8px;
-moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
background-image: -moz-linear-gradient(center top, #FFFFFF 0%, #FFFFFF 60%, #F7F8FB 95%, #EEF1F7);
/* webkit specific markup */
-webkit-border-bottom-left-radius: 8px;
-webkit-border-bottom-right-radius: 8px;
-webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
background-image: -webkit-gradient(linear,center top,center bottom,from(#FFFFFF), color-stop(0.6,#FFFFFF), color-stop(0.60,#FFFFFF), color-stop(0.95,#F7F8FB), to(#EEF1F7));
}
.paramkey {
@ -432,13 +482,36 @@ table.memberdecls {
}
.paramname {
color: #602020;
/* color: #602020; */
color: black;
white-space: nowrap;
}
.paramname em {
font-style: normal;
}
.params, .retval, .exception, .tparams {
border-spacing: 6px 2px;
}
.params .paramname, .retval .paramname {
font-weight: bold;
vertical-align: top;
}
.params .paramtype {
font-style: italic;
vertical-align: top;
}
.params .paramdir {
font-family: "courier new",courier,monospace;
vertical-align: top;
}
/* @end */
/* @group Directory (tree) */
@ -589,14 +662,14 @@ table.doxtable th {
list-style-type:none;
float:left;
padding-left:10px;
padding-right: 15px;
padding-right:15px;
background-image:url('bc_s.png');
background-repeat:no-repeat;
background-position:right;
color:#364D7C;
}
.navpath a
.navpath li.navelem a
{
height:32px;
display:block;
@ -604,11 +677,25 @@ table.doxtable th {
outline: none;
}
.navpath a:hover
.navpath li.navelem a:hover
{
color:#6884BD;
}
.navpath li.footer
{
list-style-type:none;
float:right;
padding-left:10px;
padding-right:15px;
background-image:none;
background-repeat:no-repeat;
background-position:right;
color:#364D7C;
font-size: 8pt;
}
div.summary
{
float: right;
@ -623,6 +710,19 @@ div.summary a
white-space: nowrap;
}
div.ingroups
{
font-size: 8pt;
padding-left: 5px;
width: 50%;
text-align: left;
}
div.ingroups a
{
white-space: nowrap;
}
div.header
{
background-image:url('nav_h.png');
@ -637,3 +737,110 @@ div.headertitle
padding: 5px 5px 5px 10px;
}
dl
{
padding: 0 0 0 10px;
}
dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug
{
border-left:4px solid;
padding: 0 0 0 6px;
}
dl.note
{
border-color: #D0C000;
}
dl.warning, dl.attention
{
border-color: #FF0000;
}
dl.pre, dl.post, dl.invariant
{
border-color: #00D000;
}
dl.deprecated
{
border-color: #505050;
}
dl.todo
{
border-color: #00C0E0;
}
dl.test
{
border-color: #3030E0;
}
dl.bug
{
border-color: #C08050;
}
#projectlogo
{
text-align: center;
vertical-align: bottom;
border-collapse: separate;
}
#projectlogo img
{
border: 0px none;
}
#projectname
{
font: 300% Tahoma, Arial,sans-serif;
margin: 0px;
padding: 2px 0px;
}
#projectbrief
{
font: 120% Tahoma, Arial,sans-serif;
margin: 0px;
padding: 0px;
}
#projectnumber
{
font: 50% Tahoma, Arial,sans-serif;
margin: 0px;
padding: 0px;
}
#titlearea
{
padding: 0px;
margin: 0px;
width: 100%;
border-bottom: 1px solid #5373B4;
}
.image
{
text-align: center;
}
.dotgraph
{
text-align: center;
}
.mscgraph
{
text-align: center;
}
.caption
{
font-weight: bold;
}

25
doc/resolve-asciidoc-refs.py Executable file
View File

@ -0,0 +1,25 @@
#!/usr/bin/env python
import fileinput
import re
import sys
refs = {}
complete_file = ""
for line in open(sys.argv[1], 'r'):
complete_file += line
for m in re.findall('\[\[(.+)\]\]\n=+ ([^\n]+)', complete_file):
ref, title = m
refs["<<" + ref + ">>"] = "<<" + ref + ", " + title + ">>"
def translate(match):
try:
return refs[match.group(0)]
except KeyError:
return ""
rc = re.compile('|'.join(map(re.escape, sorted(refs, reverse=True))))
for line in open(sys.argv[1], 'r'):
print rc.sub(translate, line),

View File

@ -35,50 +35,316 @@ commonly used In user space the term _network interface_ is very common.
The routing netlink protocol uses the term _link_ and so does the _iproute2_
utility and most routing daemons.
=== Protocol Definition
=== Netlink Protocol
This section describes the protocol semantics of the netlink link configuration
interface. The following netlink message types are defined:
This section describes the protocol semantics of the netlink based link
configuration interface. The following messages are defined:
[options="header", cols="1,2,2"]
|==============================================================================
| Message Type | User -> Kernel | Kernel -> User
| +RTM_NEWLINK+ | Create new virtual network device | Notification: Link changed or added
| +RTM_DELLINK+ | Delete virtual network device | Notification: Link deleted or disappeared
| +RTM_NEWLINK+ | Create or update virtual network device
| Reply to +RTM_GETLINK+ request or notification of link added or updated
| +RTM_DELLINK+ | Delete virtual network device
| Notification of link deleted or disappeared
| +RTM_GETLINK+ | Retrieve link configuration and statistics |
| +RTM_SETLINK+ | Modify link configuration |
|==============================================================================
See the link:core.html#core_msg_types[Message Types] section of the Netlink
Library documentation for more information on common semantics of these message
types.
See link:core.html#core_msg_types[Netlink Library - Message Types] for more
information on common semantics of these message types.
.Link Message Header
==== Link Message Format
All netlink link messages share the following common header which is appended
after the netlink message header (+struct nlmsghdr+). It is defined in the
header +<linux/rtnetlink.h>+
All netlink link messages share a common header (+struct ifinfomsg+) which
is appended after the netlink header (+struct nlmsghdr+).
[source,c]
-----
struct ifinfomsg {
unsigned char ifi_family;
unsigned char __ifi_pad;
unsigned short ifi_type; /* ARPHRD_* */
int ifi_index; /* Link index */
unsigned ifi_flags; /* IFF_* flags */
unsigned ifi_change; /* IFF_* change mask */
};
-----
image:ifinfomsg.png["Link Message Header"]
The meaning of each field may differ depending on the message type.
The meaning of each field may differ depending on the message type. A
+struct ifinfomsg+ is defined in +<linux/rtnetlink.h>+ to represent the
header.
.Attributes
Address Family (8bit)::
The address family is usually set to +AF_UNSPEC+ but may be specified in
+RTM_GETLINK+ requests to limit the returned links to a specific address
family.
Link Layer Type (16bit)::
Currently only used in kernel->user messages to report the link layer type
of a link. The value corresponds to the +ARPHRD_*+ defines found in
+<linux/if_arp.h>+. Translation from/to strings can be done using the
functions nl_llproto2str()/nl_str2llproto().
Link Index (32bit)::
Carries the interface index and is used to identify existing links.
Flags (32bit)::
In kernel->user messages the value of this field represents the current
state of the link flags. In user->kernel messages this field is used to
change flags or set the initial flag state of new links. Note that in order
to change a flag, the flag must also be set in the _Flags Change Mask_ field.
Flags Change Mask (32bit)::
The primary use of this field is to specify a mask of flags that should be
changed based on the value of the _Flags_ field. A special meaning is given
to this field when present in link notifications, see TODO.
Attributes (variable)::
All link message types may carry netlink attributes. They are defined in the
header file <linux/if_link.h> and share the prefix +IFLA_+.
==== Link Message Types
.RTM_GETLINK (user->kernel)
Lookup link by 1. interface index or 2. link name (+IFLA_IFNAME+) and return
a single +RTM_NEWLINK+ message containing the link configuration and statistics
or a netlink error message if no such link was found.
*Parameters:*
* *Address family*
** If the address family is set to +PF_BRIDGE+, only bridging devices will be
returned.
** If the address family is set to +PF_INET6+, only ipv6 enabled devices will
be returned.
*Flags:*
* +NLM_F_DUMP+ If set, all links will be returned in form of a multipart
message.
*Returns:*
* +EINVAL+ if neither interface nor link name are set
* +ENODEV+ if no link was found
* +ENOBUFS+ if allocation failed
.RTM_NEWLINK (user->kernel)
Creates a new or updates an existing link. Only virtual links may be created
but all links may be updated.
*Flags:*
- +NLM_F_CREATE+ Create link if it does not exist
- +NLM_F_EXCL+ Return +EEXIST+ if link already exists
*Returns:*
- +EINVAL+ malformed message or invalid configuration parameters
- +EAFNOSUPPORT+ if a address family specific configuration (+IFLA_AF_SPEC+)
is not supported.
- +EOPNOTSUPP+ if the link does not support modification of parameters
- +EEXIST+ if +NLM_F_EXCL+ was set and the link exists alraedy
- +ENODEV+ if the link does not exist and +NLM_F_CREATE+ is not set
.RTM_NEWLINK (kernel->user)
This message type is used in reply to a +RTM_GETLINK+ request and carries
the configuration and statistics of a link. If multiple links need to
be sent, the messages will be sent in form of a multipart message.
The message type is also used for notifications sent by the kernel to the
multicast group +RTNLGRP_LINK+ to inform about various link events. It is
therefore recommended to always use a separate link socket for link
notifications in order to separate between the two message types.
TODO: document how to detect different notifications
.RTM_DELLINK (user->kernel)
Lookup link by 1. interface index or 2. link name (+IFLA_IFNAME+) and delete
the virtual link.
*Returns:*
* +EINVAL+ if neither interface nor link name are set
* +ENODEV+ if no link was found
* +ENOTSUPP+ if the operation is not supported (not a virtual link)
.RTM_DELLINK (kernel->user)
Notification sent by the kernel to the multicast group +RTNLGRP_LINK+ when
a. a network device was unregistered (change == ~0)
b. a bridging device was deleted (address family will be +PF_BRIDGE+)
[source,c]
-----
#define IFF_UP 0x1 /* interface is up */
#define IFF_BROADCAST 0x2 /* broadcast address valid */
#define IFF_DEBUG 0x4 /* turn on debugging */
#define IFF_LOOPBACK 0x8 /* is a loopback net */
#define IFF_POINTOPOINT 0x10 /* interface is has p-p link */
#define IFF_NOTRAILERS 0x20 /* avoid use of trailers */
#define IFF_RUNNING 0x40 /* interface RFC2863 OPER_UP */
#define IFF_NOARP 0x80 /* no ARP protocol */
#define IFF_PROMISC 0x100 /* receive all packets */
#define IFF_ALLMULTI 0x200 /* receive all multicast packets*/
#define IFF_MASTER 0x400 /* master of a load balancer */
#define IFF_SLAVE 0x800 /* slave of a load balancer */
#define IFF_MULTICAST 0x1000 /* Supports multicast */
#define IFF_PORTSEL 0x2000 /* can set media type */
#define IFF_AUTOMEDIA 0x4000 /* auto media select active */
#define IFF_DYNAMIC 0x8000 /* dialup device with changing addresses*/
#define IFF_LOWER_UP 0x10000 /* driver signals L1 up */
#define IFF_DORMANT 0x20000 /* driver signals dormant */
#define IFF_ECHO 0x40000 /* echo sent packets */
-----
=== Get / List
[[link_list]]
==== Get list of links
To retrieve the list of links in the kernel, allocate a new link cache
using +rtnl_link_alloc_cache()+ to hold the links. It will automatically
construct and send a +RTM_GETLINK+ message requesting a dump of all links
from the kernel and feed the returned +RTM_NEWLINK+ to the internal link
message parser which adds the returned links to the cache.
[source,c]
-----
#include <netlink/route/link.h>
int rtnl_link_alloc_cache(struct nl_sock *sk, int family, struct nl_cache **result)
-----
The cache will contain link objects (+struct rtnl_link+, see <<link_object>>)
and can be accessed using the standard cache functions. By setting the
+family+ parameter to an address familly other than +AF_UNSPEC+, the resulting
cache will only contain links supporting the specified address family.
The following direct search functions are provided to search by interface
index and by link name:
[source,c]
-----
#include <netlink/route/link.h>
struct rtnl_link *rtnl_link_get(struct nl_cache *cache, int ifindex);
struct rtnl_link *rtnl_link_get_by_name(struct nl_cache *cache, const char *name);
-----
.Example: Link Cache
[source,c]
-----
struct nl_cache *cache;
struct rtnl_link *link;
if (rtnl_link_alloc_cache(sock, AF_UNSPEC, &cache)) < 0)
/* error */
if (!(link = rtnl_link_get_by_name(cache, "eth1")))
/* link does not exist */
/* do something with link */
rtnl_link_put(link);
nl_cache_put(cache);
-----
==== Lookup Single Link (Direct Lookup)
If only a single link is of interest, the link can be looked up directly
without the use of a link cache using the function +rtnl_link_get_kernel()+.
[source,c]
-----
#include <netlink/route/link.h>
int rtnl_link_get_kernel(struct nl_sock *sk, int ifindex, const char *name, struct rtnl_link **result);
-----
It will construct and send a +RTM_GETLINK+ request using the parameters
provided and wait for a +RTM_NEWLINK+ or netlink error message sent in
return. If the link exists, the link is returned as link object
(see <<link_object>>).
.Example: Direct link lookup
[source,c]
-----
struct rtnl_link *link;
if (rtnl_link_get_kernel(sock, 0, "eth1", &link) < 0)
/* error */
/* do something with link */
rtnl_link_put(link);
-----
NOTE: While using this function can save a substantial amount of bandwidth
on the netlink socket, the result will not be cached, subsequent calls
to rtnl_link_get_kernel() will always trigger sending a +RTM_GETLINK+
request.
==== Translating interface index to link name
Applications which require to translate interface index to a link name or
vice verase may use the following functions to do so. Both functions require
a filled link cache to work with.
[source,c]
-----
char *rtnl_link_i2name (struct nl_cache *cache, int ifindex, char *dst, size_t len);
int rtnl_link_name2i (struct nl_cache *cache, const char *name);
-----
=== Add / Modify
Several types of virtual link can be added on the fly using the function
+rtnl_link_add()+.
[source,c]
-----
#include <netlink/route/link.h>
int rtnl_link_add(struct nl_sock *sk, struct rtnl_link *link, int flags);
-----
=== Delete
The deletion of virtual links such as VLAN devices or dummy devices is done
using the function +rtnl_link_delete()+. The link passed on to the function
can be a link from a link cache or it can be construct with the minimal
attributes needed to identify the link.
[source,c]
-----
#include <netlink/route/link.h>
int rtnl_link_delete(struct nl_sock *sk, const struct rtnl_link *link);
-----
The function will construct and send a +RTM_DELLINK+ request message and
returns any errors returned by the kernel.
.Example: Delete link by name
[source,c]
-----
struct rtnl_link *link;
if (!(link = rtnl_link_alloc()))
/* error */
rtnl_link_set_name(link, "my_vlan");
if (rtnl_link_delete(sock, link) < 0)
/* error */
rtnl_link_put(link);
-----
[[link_object]]
=== Link Object
Name::
@ -86,6 +352,8 @@ The name of a network device is the human readable representation of a
network device and secondary identification parameter besides the interface
index.
+
Kernels >= 2.6.11 support identification by link name.
+
[source,c]
-----
void rtnl_link_set_name(struct rtnl_link *link, const char *name);
@ -141,8 +409,81 @@ void rtnl_link_set_weight(struct rtnl_link *link, unsigned int weight);
unsigned int rtnl_link_get_weight(struct rtnl_link *link);
-----
=== Link Cache
=== Modules
[[link_bonding]]
==== Bonding
.Example: Add bonding link
[source,c]
-----
#include <netlink/route/link.h>
struct rtnl_link *link;
link = rtnl_link_alloc();
rtnl_link_set_name(link, "my_bond");
rtnl_link_set_type(link, "bond");
/* requires admin privileges */
if (rtnl_link_add(sk, link, NLM_F_CREATE) < 0)
/* error */
rtnl_link_put(link);
-----
==== VLAN
[source,c]
-----
extern char * rtnl_link_vlan_flags2str(int, char *, size_t);
extern int rtnl_link_vlan_str2flags(const char *);
extern int rtnl_link_vlan_set_id(struct rtnl_link *, int);
extern int rtnl_link_vlan_get_id(struct rtnl_link *);
extern int rtnl_link_vlan_set_flags(struct rtnl_link *,
unsigned int);
extern int rtnl_link_vlan_unset_flags(struct rtnl_link *,
unsigned int);
extern unsigned int rtnl_link_vlan_get_flags(struct rtnl_link *);
extern int rtnl_link_vlan_set_ingress_map(struct rtnl_link *,
int, uint32_t);
extern uint32_t * rtnl_link_vlan_get_ingress_map(struct rtnl_link *);
extern int rtnl_link_vlan_set_egress_map(struct rtnl_link *,
uint32_t, int);
extern struct vlan_map *rtnl_link_vlan_get_egress_map(struct rtnl_link *,
int *);
-----
.Example: Add a VLAN device
[source,c]
-----
struct rtnl_link *link;
int master_index;
/* lookup interface index of eth0 */
if (!(master_index = rtnl_link_name2i(link_cache, "eth0")))
/* error */
/* allocate new link object to configure the vlan device */
link = rtnl_link_alloc();
/* set eth0 to be our master device */
rtnl_link_set_link(link, master_index);
if ((err = rtnl_link_set_type(link, "vlan")) < 0)
/* error */
rtnl_link_vlan_set_id(link, 10);
if ((err = rtnl_link_add(sk, link, NLM_F_CREATE)) < 0)
/* error */
rtnl_link_put(link);
-----
== Neighbouring
@ -347,8 +688,7 @@ uint32_t rtnl_tc_get_parent(struct rtnl_tc *tc);
-----
Statistics::
Generic statistics, see <<tc_stats, Accessing Statistics>> for
additional information.
Generic statistics, see <<tc_stats>> for additional information.
+
[source,c]
-----
@ -593,8 +933,7 @@ if (!(qdisc = rtnl_qdisc_alloc()))
-----
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>>.
object interface described in the section <<tc_attr>>.
The following attributes must be specified:
- IfIndex

View File

@ -23,12 +23,16 @@ body {
a {
/* color: blue; */
color: #990000;
text-decoration: underline;
text-decoration: none;
}
a:visited {
/* color: fuchsia; */
}
a:hover {
text-decoration: underline;
}
em {
font-style: italic;
/* color: navy; */