summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2011-07-21 14:24:31 (GMT)
committerThomas Graf <tgraf@suug.ch>2011-07-21 14:24:31 (GMT)
commit50074732af4fbfc0ca5ae4bb07e971bc9e222126 (patch)
tree8211dd82daaf32efaba045f76adfc8bae58b12ea
parentdea6de42f69a5137544723f7a96bc097adbbdd29 (diff)
downloadlibnl-50074732af4fbfc0ca5ae4bb07e971bc9e222126.zip
libnl-50074732af4fbfc0ca5ae4bb07e971bc9e222126.tar.gz
libnl-50074732af4fbfc0ca5ae4bb07e971bc9e222126.tar.bz2
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
-rw-r--r--doc/Doxyfile.in2
-rw-r--r--doc/DoxygenLayout.xml185
-rw-r--r--doc/Makefile.am8
-rw-r--r--doc/core.txt311
-rw-r--r--doc/images/attribute_hdr.pngbin0 -> 14996 bytes
-rw-r--r--doc/images/ifinfomsg.pngbin0 -> 44814 bytes
-rw-r--r--doc/images/library_overview.pngbin0 -> 23870 bytes
-rw-r--r--doc/images/nlmsgerr.pngbin0 -> 43810 bytes
-rw-r--r--doc/images/nlmsghdr.pngbin0 -> 19553 bytes
-rw-r--r--doc/index.txt28
-rw-r--r--doc/libnl.css271
-rwxr-xr-xdoc/resolve-asciidoc-refs.py25
-rw-r--r--doc/route.txt397
-rw-r--r--doc/stylesheets/asciidoc.css6
14 files changed, 998 insertions, 235 deletions
diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in
index ed78bfe..5deba44 100644
--- a/doc/Doxyfile.in
+++ b/doc/Doxyfile.in
@@ -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
diff --git a/doc/DoxygenLayout.xml b/doc/DoxygenLayout.xml
new file mode 100644
index 0000000..29049d1
--- /dev/null
+++ b/doc/DoxygenLayout.xml
@@ -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>
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 165660b..149daba 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -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
diff --git a/doc/core.txt b/doc/core.txt
index 42f1035..0ab32ec 100644
--- a/doc/core.txt
+++ b/doc/core.txt
@@ -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.
diff --git a/doc/images/attribute_hdr.png b/doc/images/attribute_hdr.png
new file mode 100644
index 0000000..0e6cfda
--- /dev/null
+++ b/doc/images/attribute_hdr.png
Binary files differ
diff --git a/doc/images/ifinfomsg.png b/doc/images/ifinfomsg.png
new file mode 100644
index 0000000..fb94cf7
--- /dev/null
+++ b/doc/images/ifinfomsg.png
Binary files differ
diff --git a/doc/images/library_overview.png b/doc/images/library_overview.png
new file mode 100644
index 0000000..dd9d5fe
--- /dev/null
+++ b/doc/images/library_overview.png
Binary files differ
diff --git a/doc/images/nlmsgerr.png b/doc/images/nlmsgerr.png
new file mode 100644
index 0000000..58e53d5
--- /dev/null
+++ b/doc/images/nlmsgerr.png
Binary files differ
diff --git a/doc/images/nlmsghdr.png b/doc/images/nlmsghdr.png
new file mode 100644
index 0000000..dd39b9c
--- /dev/null
+++ b/doc/images/nlmsghdr.png
Binary files differ
diff --git a/doc/index.txt b/doc/index.txt
index c59be0e..c207b44 100644
--- a/doc/index.txt
+++ b/doc/index.txt
@@ -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
diff --git a/doc/libnl.css b/doc/libnl.css
index b92bafc..ddc6ac3 100644
--- a/doc/libnl.css
+++ b/doc/libnl.css
@@ -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;
+}
+
diff --git a/doc/resolve-asciidoc-refs.py b/doc/resolve-asciidoc-refs.py
new file mode 100755
index 0000000..5418747
--- /dev/null
+++ b/doc/resolve-asciidoc-refs.py
@@ -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),
diff --git a/doc/route.txt b/doc/route.txt
index 1f68116..b9b50b6 100644
--- a/doc/route.txt
+++ b/doc/route.txt
@@ -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 Format
+
+All netlink link messages share a common header (+struct ifinfomsg+) which
+is appended after the netlink header (+struct nlmsghdr+).
+
+image:ifinfomsg.png["Link Message Header"]
+
+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.
+
+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:*
-.Link Message Header
+* +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)
-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>+
+.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]
-----
-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 */
-};
+#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 */
-----
-The meaning of each field may differ depending on the message type.
+=== Get / List
-.Attributes
+[[link_list]]
+==== Get list of links
-All link message types may carry netlink attributes. They are defined in the
-header file <linux/if_link.h> and share the prefix +IFLA_+.
+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
diff --git a/doc/stylesheets/asciidoc.css b/doc/stylesheets/asciidoc.css
index 19796dd..8ded7c9 100644
--- a/doc/stylesheets/asciidoc.css
+++ b/doc/stylesheets/asciidoc.css
@@ -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; */