dect
/
libnl
Archived
13
0
Fork 0

doc: documentation restructuring

- changes the modules hierarchy to better represent the set of libaries
- list the header file that needs to be included
- remove examples/doc from api ref that is included in the guide
- add references to the guide
- fix doxygen api linking for version 1.8.0
- readd doxygen mainpage to config file
- fix a couple of doxygen doc bugs
This commit is contained in:
Thomas Graf 2012-05-10 12:03:59 +02:00
parent 32057bc154
commit fec10a2823
29 changed files with 245 additions and 676 deletions

View File

@ -91,17 +91,6 @@ if test "x$generate_doc" != "xno"; then
AC_MSG_ERROR([*** doxygen package required to generate documentation])
fi
link_doc=yes
AC_CHECK_PROG(HAVE_XMLSTARLET, [xmlstarlet], yes, no)
if test "x$HAVE_XMLSTARLET" = "xno"; then
if test "x$generate_doc" = "xyes"; then
AC_MSG_ERROR([*** xmlstarlet package required to generate documentation])
else
AC_MSG_WARN([*** xmlstarlet not found, linking to APi reference disabled])
link_doc=no
fi
fi
AC_CHECK_PROG(HAVE_ASCIIDOC, [asciidoc], yes, no)
if test "x$HAVE_ASCIIDOC" = "xno"; then
if test "x$generate_doc" = "xyes"; then
@ -123,6 +112,7 @@ if test "x$generate_doc" != "xno"; then
fi
fi
link_doc=yes
if test "x$HAVE_DOXYGEN" = "xno"; then
AC_MSG_WARN([*** Disabling API linking due to missing doxygen package])
link_doc=no

View File

@ -181,11 +181,11 @@ TAB_SIZE = 8
ALIASES = arg=\param
ALIASES += ref_asciidoc{3}="<a href=\"../\1.html#\2\">\3</a>"
ALIASES += ref_core{2}="\ref_asciidoc{core,\1,\2 (Netlink Library)}"
ALIASES += ref_route{2}="\ref_asciidoc{route,\1,\2 (Routing Family Library)}"
ALIASES += core_doc{2}="\par Related Documentation:\n\ref_core{\1,\2}"
ALIASES += route_doc{2}="\par Related Documentation:\n\ref_route{\1,\2}"
ALIASES += ref_asciidoc{3}="<a href=\"../\1.html#\2\"><b>\3</b></a>"
ALIASES += ref_core{2}="\ref_asciidoc{core,\1,\2 (Netlink Core Library Development Guide)}"
ALIASES += ref_route{2}="\ref_asciidoc{route,\1,\2 (Netlink Routing Development Guide)}"
ALIASES += core_doc{2}="\ref_core{\1,\2}"
ALIASES += route_doc{2}="\ref_route{\1,\2}"
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
# sources only. Doxygen will then generate output that is more tailored for C.
@ -590,7 +590,8 @@ WARN_LOGFILE =
INPUT = @top_srcdir@/lib \
@top_srcdir@/src/lib \
@top_srcdir@/include/netlink \
@top_srcdir@/src
@top_srcdir@/src \
@top_srcdir@/doc/src
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is

View File

@ -20,7 +20,6 @@ EXTRA_DIST = \
doxygen-link.py \
gen-tags.sh \
resolve-asciidoc-refs.py \
tags2dict.sh \
stylesheets/asciidoc.css \
stylesheets/asciidoc-manpage.css \
stylesheets/docbook-xsl.css \
@ -78,28 +77,26 @@ EXTRA_DIST = \
images/icons/callouts/14.png \
images/icons/callouts/15.png
%.html: %.txt
link_doc:
if LINK_DOC
./gen-tags.sh > libnl.dict
else
@echo "Warning: Linking to API reference is disabled, check configure output"
endif
%.html: %.txt link_doc
./resolve-asciidoc-refs.py $< > asciidoc.tmp
asciidoc $(ASCIIDOCOPTS) -o $@ asciidoc.tmp
if LINK_DOC
./doxygen-link.py libnl.dict $@ > asciidoc.tmp
mv asciidoc.tmp $@
else
asciidoc $(ASCIIDOCOPTS) -o $@ $<
endif
asciidoc: core.html route.html index.html
link_doc:
if LINK_DOC
./gen-tags.sh | ./tags2dict.sh > libnl.dict
else
@echo "Warning: Linking to API reference is disabled, check configure output"
endif
api_ref:
doxygen Doxyfile;
$(MAKE) link_doc
gendoc:
if GENERATE_DOC

View File

@ -6,5 +6,5 @@ mscgen
mscgen-filter-1.2
http://code.google.com/p/asciidoc-mscgen-filter/
asciidoc 8.6.x
doxygen
asciidoc > 8.6.x
doxygen > 1.8.0

1
doc/api/.gitignore vendored
View File

@ -3,5 +3,6 @@
*.css
*.map
*.md5
*.js
formula.repository
jquery.js

View File

@ -2811,6 +2811,17 @@ is stored in +*result+.
NOTE: Make sure to return the reference to an address using
`nl_addr_put()` after usage to allow memory being freed.
.Example: Transform character string to abstract address
[source,c]
-----
struct nl_addr *a = nl_addr_parse("::1", AF_UNSPEC);
printf("Address family: %s\n", nl_af2str(nl_addr_get_family(a)));
nl_addr_put(a);
a = nl_addr_parse("11:22:33:44:55:66", AF_UNSPEC);
printf("Address family: %s\n", nl_af2str(nl_addr_get_family(a)));
nl_addr_put(a);
-----
.Address References
Abstract addresses use reference counting to account for all users of

View File

@ -5,16 +5,10 @@
# written by Carsten Haitzler <ras...@rasterman.com>
#
echo '<libnltags>'
for f in api/group__*.html
do
bf=$(basename $f)
grep -oE '<!-- doxytag.* -->' $f |
sed 's/<!-- doxytag:/<libnltag/' |
sed "s/-->/file=\"$bf\" \/>/" |
sed "s/ ref=\"/ href=\"$bf#/" |
sed 's/ member="\([^:]*::\)\([^"]*\)"/ member="\2"/' |
sed 's/ member="\([^"]*\)"/ short="\1"/'
grep -oE "href=\"$bf#[a-z0-9]+\">[^<]+</a>" $f |
sed 's/href="\([^"]*\)">\([^<]*\)<\/a>/\2=api\/\1/'
done
echo '</libnltags>'

View File

@ -9,11 +9,11 @@
libnl is a set of libraries to deal with the netlink protocol and some
of the high level protocols implemented on top of it. The goal is to
provide APIs on different levels of abstraction. The core library libnl.so
provide APIs on different levels of abstraction. The core library libnl
provides a fundamental set of functions to deal with sockets, construct
messages, and send/receive those messages. Additional high level interfaces
for several individual netlink protocols are provided in separate
libraries (e.g. "nl-route.so", "nl-genl.so", ...).
libraries (e.g. "nl-route", "nl-genl", ...).
The library is designed to ensure that all components are optional, i.e.
even though the core library provides a caching system which allows to
@ -33,16 +33,9 @@ version is used with a considerably older kernel.
\subsection tree_dev Development Tree
@code
git://git.kernel.org/pub/scm/libs/netlink/libnl.git
git://git.infradead.org/users/tgr/libnl.git
@endcode
- Web: http://www.kernel.org/pub/scm/libs/netlink/libnl.git
\subsection tree_stable Stable Tree
@code
git://git.kernel.org/pub/scm/libs/netlink/libnl-stable.git
@endcode
- Web: http://www.kernel.org/pub/scm/libs/netlink/libnl-stable.git
- Web: http://git.infradead.org/users/tgr/libnl.git
\section main_website Website
@ -50,7 +43,7 @@ git://git.kernel.org/pub/scm/libs/netlink/libnl-stable.git
\section main_mailinglist Mailinglist
Please post question and patches to the libnl mailinglist:
Please post questions and patches to the libnl mailinglist:
@code
libnl@lists.infradead.org

View File

@ -1,8 +0,0 @@
#!/bin/bash
xmlstarlet sel -t \
-m "/libnltags/libnltag[@href]" \
-v "@short" \
-o "=api/" \
-v "@href" \
-n

View File

@ -28,12 +28,12 @@ struct nl_msg;
* @{
*/
/**
* @ingroup attr
* Basic attribute data types
*
* See \ref attr_datatypes for more details.
*/
/**
* @ingroup attr
* Basic attribute data types
*
* See section @core_doc{core_attr_parse,Attribute Parsing} for more details.
*/
enum {
NLA_UNSPEC, /**< Unspecified type, binary data chunk */
NLA_U8, /**< 8 bit integer */
@ -55,7 +55,7 @@ enum {
* @ingroup attr
* Attribute validation policy.
*
* See \ref attr_datatypes for more details.
* See section @core_doc{core_attr_parse,Attribute Parsing} for more details.
*/
struct nla_policy {
/** Type of attribute or NLA_UNSPEC */

View File

@ -1,12 +1,12 @@
/*
* netlink/netlink-types.h Netlink Types
* netlink/types.h Definition of public types
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
#ifndef __NETLINK_TYPES_H_
@ -15,8 +15,8 @@
#include <stdio.h>
/**
* Dumping types (dp_type)
* @ingroup utils
* Enumeration of dumping variations (dp_type)
*/
enum nl_dump_type {
NL_DUMP_LINE, /**< Dump object briefly on one line */
@ -27,8 +27,8 @@ enum nl_dump_type {
#define NL_DUMP_MAX (__NL_DUMP_MAX - 1)
/**
* Dumping parameters
* @ingroup utils
* Dumping parameters
*/
struct nl_dump_params
{

View File

@ -6,7 +6,7 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
#ifndef NETLINK_UTILS_H_
@ -31,7 +31,7 @@ extern "C" {
#define NL_PROB_MIN 0x0
/**
* Upper probability limit
* Upper probability limit nl_dump_type
* @ingroup utils
*/
#define NL_PROB_MAX 0xffffffff

View File

@ -1,28 +1,30 @@
/*
* lib/addr.c Abstract Address
* lib/addr.c Network Address
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2010 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
/**
* @ingroup core
* @defgroup addr Abstract Address
* @ingroup core_types
* @defgroup addr Network Address
*
* Abstract data type representing any kind of network address
*
* Related sections in the development guide:
* - @core_doc{_abstract_address, Network Addresses}
*
* @par 1) Transform character string to abstract address
* @code
* struct nl_addr *a = nl_addr_parse("::1", AF_UNSPEC);
* printf("Address family: %s\n", nl_af2str(nl_addr_get_family(a)));
* nl_addr_put(a);
* a = nl_addr_parse("11:22:33:44:55:66", AF_UNSPEC);
* printf("Address family: %s\n", nl_af2str(nl_addr_get_family(a)));
* nl_addr_put(a);
* @endcode
* @{
*
* Header
* ------
* ~~~~{.c}
* #include <netlink/addr.h>
* ~~~~
*/
#include <netlink-local.h>
@ -163,7 +165,7 @@ static void addr_destroy(struct nl_addr *addr)
}
/**
* @name Creating Abstract Addresses
* @name Creating Abstract Network Addresses
* @{
*/

View File

@ -22,356 +22,16 @@
* @defgroup attr Attributes
* Netlink Attributes Construction/Parsing Interface
*
* \section attr_sec Netlink Attributes
* Netlink attributes allow for data chunks of arbitary length to be
* attached to a netlink message. Each attribute is encoded with a
* type and length field, both 16 bits, stored in the attribute header
* preceding the attribute data. The main advantage of using attributes
* over packing everything into the family header is that the interface
* stays extendable as new attributes can supersede old attributes while
* remaining backwards compatible. Also attributes can be defined optional
* thus avoiding the transmission of unnecessary empty data blocks.
* Special nested attributes allow for more complex data structures to
* be transmitted, e.g. trees, lists, etc.
*
* While not required, netlink attributes typically follow the family
* header of a netlink message and must be properly aligned to NLA_ALIGNTO:
* @code
* +----------------+- - -+---------------+- - -+------------+- - -+
* | Netlink Header | Pad | Family Header | Pad | Attributes | Pad |
* +----------------+- - -+---------------+- - -+------------+- - -+
* @endcode
*
* The actual attributes are chained together each separately aligned to
* NLA_ALIGNTO. The position of an attribute is defined based on the
* length field of the preceding attributes:
* @code
* +-------------+- - -+-------------+- - -+------
* | Attribute 1 | Pad | Attribute 2 | Pad | ...
* +-------------+- - -+-------------+- - -+------
* nla_next(attr1)------^
* @endcode
*
* The attribute itself consists of the attribute header followed by
* the actual payload also aligned to NLA_ALIGNTO. The function nla_data()
* returns a pointer to the start of the payload while nla_len() returns
* the length of the payload in bytes.
*
* \b Note: Be aware, NLA_ALIGNTO equals to 4 bytes, therefore it is not
* safe to dereference any 64 bit data types directly.
*
* @code
* <----------- nla_total_size(payload) ----------->
* <-------- nla_attr_size(payload) --------->
* +------------------+- - -+- - - - - - - - - +- - -+
* | Attribute Header | Pad | Payload | Pad |
* +------------------+- - -+- - - - - - - - - +- - -+
* nla_data(nla)-------------^
* <- nla_len(nla) ->
* @endcode
*
* @subsection attr_datatypes Attribute Data Types
* A number of basic data types are supported to simplify access and
* validation of netlink attributes. This data type information is
* not encoded in the attribute, both the kernel and userspace part
* are required to share this information on their own.
*
* One of the major advantages of these basic types is the automatic
* validation of each attribute based on an attribute policy. The
* validation covers most of the checks required to safely use
* attributes and thus keeps the individual sanity check to a minimum.
*
* Never access attribute payload without ensuring basic validation
* first, attributes may:
* - not be present even though required
* - contain less actual payload than expected
* - fake a attribute length which exceeds the end of the message
* - contain unterminated character strings
*
* Policies are defined as array of the struct nla_policy. The array is
* indexed with the attribute type, therefore the array must be sized
* accordingly.
* @code
* static struct nla_policy my_policy[ATTR_MAX+1] = {
* [ATTR_FOO] = { .type = ..., .minlen = ..., .maxlen = ... },
* };
*
* err = nla_validate(attrs, attrlen, ATTR_MAX, &my_policy);
* @endcode
*
* Some basic validations are performed on every attribute, regardless of type.
* - If the attribute type exceeds the maximum attribute type specified or
* the attribute type is lesser-or-equal than zero, the attribute will
* be silently ignored.
* - If the payload length falls below the \a minlen value the attribute
* will be rejected.
* - If \a maxlen is non-zero and the payload length exceeds the \a maxlen
* value the attribute will be rejected.
*
*
* @par Unspecific Attribute (NLA_UNSPEC)
* This is the standard type if no type is specified. It is used for
* binary data of arbitary length. Typically this attribute carries
* a binary structure or a stream of bytes.
* @par
* @code
* // In this example, we will assume a binary structure requires to
* // be transmitted. The definition of the structure will typically
* // go into a header file available to both the kernel and userspace
* // side.
* //
* // Note: Be careful when putting 64 bit data types into a structure.
* // The attribute payload is only aligned to 4 bytes, dereferencing
* // the member may fail.
* struct my_struct {
* int a;
* int b;
* };
*
* // The validation function will not enforce an exact length match to
* // allow structures to grow as required. Note: While it is allowed
* // to add members to the end of the structure, changing the order or
* // inserting members in the middle of the structure will break your
* // binary interface.
* static struct nla_policy my_policy[ATTR_MAX+1] = {
* [ATTR_MY_STRICT] = { .type = NLA_UNSPEC,
* .minlen = sizeof(struct my_struct) },
*
* // The binary structure is appened to the message using nla_put()
* struct my_struct foo = { .a = 1, .b = 2 };
* nla_put(msg, ATTR_MY_STRUCT, sizeof(foo), &foo);
*
* // On the receiving side, a pointer to the structure pointing inside
* // the message payload is returned by nla_get().
* if (attrs[ATTR_MY_STRUCT])
* struct my_struct *foo = nla_get(attrs[ATTR_MY_STRUCT]);
* @endcode
*
* @par Integers (NLA_U8, NLA_U16, NLA_U32, NLA_U64)
* Integers come in different sizes from 8 bit to 64 bit. However, since the
* payload length is aligned to 4 bytes, integers smaller than 32 bit are
* only useful to enforce the maximum range of values.
* @par
* \b Note: There is no difference made between signed and unsigned integers.
* The validation only enforces the minimal payload length required to store
* an integer of specified type.
* @par
* @code
* // Even though possible, it does not make sense to specify .minlen or
* // .maxlen for integer types. The data types implies the corresponding
* // minimal payload length.
* static struct nla_policy my_policy[ATTR_MAX+1] = {
* [ATTR_FOO] = { .type = NLA_U32 },
*
* // Numeric values can be appended directly using the respective
* // nla_put_uxxx() function
* nla_put_u32(msg, ATTR_FOO, 123);
*
* // Same for the receiving side.
* if (attrs[ATTR_FOO])
* uint32_t foo = nla_get_u32(attrs[ATTR_FOO]);
* @endcode
*
* @par Character string (NLA_STRING)
* This data type represents a NUL terminated character string of variable
* length. For binary data streams the type NLA_UNSPEC is recommended.
* @par
* @code
* // Enforce a NUL terminated character string of at most 4 characters
* // including the NUL termination.
* static struct nla_policy my_policy[ATTR_MAX+1] = {
* [ATTR_BAR] = { .type = NLA_STRING, maxlen = 4 },
*
* // nla_put_string() creates a string attribute of the necessary length
* // and appends it to the message including the NUL termination.
* nla_put_string(msg, ATTR_BAR, "some text");
*
* // It is safe to use the returned character string directly if the
* // attribute has been validated as the validation enforces the proper
* // termination of the string.
* if (attrs[ATTR_BAR])
* char *text = nla_get_string(attrs[ATTR_BAR]);
* @endcode
*
* @par Flag (NLA_FLAG)
* This attribute type may be used to indicate the presence of a flag. The
* attribute is only valid if the payload length is zero. The presence of
* the attribute header indicates the presence of the flag.
* @par
* @code
* // This attribute type is special as .minlen and .maxlen have no effect.
* static struct nla_policy my_policy[ATTR_MAX+1] = {
* [ATTR_FLAG] = { .type = NLA_FLAG },
*
* // nla_put_flag() appends a zero sized attribute to the message.
* nla_put_flag(msg, ATTR_FLAG);
*
* // There is no need for a receival function, the presence is the value.
* if (attrs[ATTR_FLAG])
* // flag is present
* @endcode
*
* @par Micro Seconds (NLA_MSECS)
*
* @par Nested Attribute (NLA_NESTED)
* Attributes can be nested and put into a container to create groups, lists
* or to construct trees of attributes. Nested attributes are often used to
* pass attributes to a subsystem where the top layer has no knowledge of the
* configuration possibilities of each subsystem.
* @par
* \b Note: When validating the attributes using nlmsg_validate() or
* nlmsg_parse() it will only affect the top level attributes. Each
* level of nested attributes must be validated seperately using
* nla_parse_nested() or nla_validate().
* @par
* @code
* // The minimal length policy may be used to enforce the presence of at
* // least one attribute.
* static struct nla_policy my_policy[ATTR_MAX+1] = {
* [ATTR_OPTS] = { .type = NLA_NESTED, minlen = NLA_HDRLEN },
*
* // Nested attributes are constructed by enclosing the attributes
* // to be nested with calls to nla_nest_start() respetively nla_nest_end().
* struct nlattr *opts = nla_nest_start(msg, ATTR_OPTS);
* nla_put_u32(msg, ATTR_FOO, 123);
* nla_put_string(msg, ATTR_BAR, "some text");
* nla_nest_end(msg, opts);
*
* // Various methods exist to parse nested attributes, the easiest being
* // nla_parse_nested() which also allows validation in the same step.
* if (attrs[ATTR_OPTS]) {
* struct nlattr *nested[ATTR_MAX+1];
*
* nla_parse_nested(nested, ATTR_MAX, attrs[ATTR_OPTS], &policy);
*
* if (nested[ATTR_FOO])
* uint32_t foo = nla_get_u32(nested[ATTR_FOO]);
* }
* @endcode
*
* @subsection attr_exceptions Exception Based Attribute Construction
* Often a large number of attributes are added to a message in a single
* function. In order to simplify error handling, a second set of
* construction functions exist which jump to a error label when they
* fail instead of returning an error code. This second set consists
* of macros which are named after their error code based counterpart
* except that the name is written all uppercase.
*
* All of the macros jump to the target \c nla_put_failure if they fail.
* @code
* void my_func(struct nl_msg *msg)
* {
* NLA_PUT_U32(msg, ATTR_FOO, 10);
* NLA_PUT_STRING(msg, ATTR_BAR, "bar");
*
* return 0;
*
* nla_put_failure:
* return -NLE_NOMEM;
* }
* @endcode
*
* @subsection attr_examples Examples
* @par Example 1.1 Constructing a netlink message with attributes.
* @code
* struct nl_msg *build_msg(int ifindex, struct nl_addr *lladdr, int mtu)
* {
* struct nl_msg *msg;
* struct nlattr *info, *vlan;
* struct ifinfomsg ifi = {
* .ifi_family = AF_INET,
* .ifi_index = ifindex,
* };
*
* // Allocate a new netlink message, type=RTM_SETLINK, flags=NLM_F_ECHO
* if (!(msg = nlmsg_alloc_simple(RTM_SETLINK, NLM_F_ECHO)))
* return NULL;
*
* // Append the family specific header (struct ifinfomsg)
* if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0)
* goto nla_put_failure
*
* // Append a 32 bit integer attribute to carry the MTU
* NLA_PUT_U32(msg, IFLA_MTU, mtu);
*
* // Append a unspecific attribute to carry the link layer address
* NLA_PUT_ADDR(msg, IFLA_ADDRESS, lladdr);
*
* // Append a container for nested attributes to carry link information
* if (!(info = nla_nest_start(msg, IFLA_LINKINFO)))
* goto nla_put_failure;
*
* // Put a string attribute into the container
* NLA_PUT_STRING(msg, IFLA_INFO_KIND, "vlan");
*
* // Append another container inside the open container to carry
* // vlan specific attributes
* if (!(vlan = nla_nest_start(msg, IFLA_INFO_DATA)))
* goto nla_put_failure;
*
* // add vlan specific info attributes here...
*
* // Finish nesting the vlan attributes and close the second container.
* nla_nest_end(msg, vlan);
*
* // Finish nesting the link info attribute and close the first container.
* nla_nest_end(msg, info);
*
* return msg;
*
* // If any of the construction macros fails, we end up here.
* nla_put_failure:
* nlmsg_free(msg);
* return NULL;
* }
* @endcode
*
* @par Example 2.1 Parsing a netlink message with attributes.
* @code
* int parse_message(struct nl_msg *msg)
* {
* // The policy defines two attributes: a 32 bit integer and a container
* // for nested attributes.
* struct nla_policy attr_policy[ATTR_MAX+1] = {
* [ATTR_FOO] = { .type = NLA_U32 },
* [ATTR_BAR] = { .type = NLA_NESTED },
* };
* struct nlattr *attrs[ATTR_MAX+1];
* int err;
*
* // The nlmsg_parse() function will make sure that the message contains
* // enough payload to hold the header (struct my_hdr), validates any
* // attributes attached to the messages and stores a pointer to each
* // attribute in the attrs[] array accessable by attribute type.
* if ((err = nlmsg_parse(nlmsg_hdr(msg), sizeof(struct my_hdr), attrs,
* ATTR_MAX, attr_policy)) < 0)
* goto errout;
*
* if (attrs[ATTR_FOO]) {
* // It is safe to directly access the attribute payload without
* // any further checks since nlmsg_parse() enforced the policy.
* uint32_t foo = nla_get_u32(attrs[ATTR_FOO]);
* }
*
* if (attrs[ATTR_BAR]) {
* struct nlattr *nested[NESTED_MAX+1];
*
* // Attributes nested in a container can be parsed the same way
* // as top level attributes.
* if ((err = nla_parse_nested(nested, NESTED_MAX, attrs[ATTR_BAR],
* nested_policy)) < 0)
* goto errout;
*
* // Process nested attributes here.
* }
*
* err = 0;
* errout:
* return err;
* }
* @endcode
* Related sections in the development guide:
* - @core_doc{core_attr,Netlink Attributes}
*
* @{
*
* Header
* ------
* ~~~~{.c}
* #include <netlink/attr.h>
* ~~~~
*/
/**
@ -628,8 +288,7 @@ errout:
* than the maximum type specified will be silently ignored in order to
* maintain backwards compatibility.
*
* See \ref attr_datatypes for more details on what kind of validation
* checks are performed on each attribute data type.
* See section @core_doc{core_attr_parse,Attribute Parsing} for more details.
*
* @return 0 on success or a negative error code.
*/

View File

@ -37,7 +37,16 @@
* | | Core Netlink
* @endcode
*
* Related sections in the development guide:
* - @core_doc{core_cache, Caching System}
*
* @{
*
* Header
* ------
* ~~~~{.c}
* #include <netlink/cache.h>
* ~~~~
*/
#include <netlink-local.h>

View File

@ -12,9 +12,24 @@
/**
* @ingroup cache_mngt
* @defgroup cache_mngr Manager
* @brief Automatically keep caches up to date
* @brief Manager keeping caches up to date automatically.
*
* The cache manager keeps caches up to date automatically by listening to
* netlink notifications and integrating the received information into the
* existing cache.
*
* @note This functionality is still considered experimental.
*
* Related sections in the development guide:
* - @core_doc{_cache_manager,Cache Manager}
*
* @{
*
* Header
* ------
* ~~~~{.c}
* #include <netlink/cache.h>
* ~~~~
*/
#include <netlink-local.h>

View File

@ -6,13 +6,23 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
/**
* @ingroup core
* @defgroup cache_mngt Caching
* @defgroup cache_mngt Caching System
*
* Related sections in the development guide:
* - @core_doc{core_cache, Caching System}
*
* @{
*
* Header
* ------
* ~~~~{.c}
* #include <netlink/cache.h>
* ~~~~
*/
#include <netlink-local.h>

View File

@ -6,13 +6,25 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
/**
* @ingroup core
* @ingroup core_types
* @defgroup data Abstract Data
*
* Abstract data type representing a binary data blob.
*
* Related sections in the development guide:
* - @core_doc{_abstract_data, Abstract Data}
*
* @{
*
* Header
* ------
* ~~~~{.c}
* #include <netlink/data.h>
* ~~~~
*/
#include <netlink-local.h>

View File

@ -6,10 +6,11 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
/**
* @ingroup rtnl
* @defgroup fib_lookup FIB Lookup
* @brief
* @{

View File

@ -6,11 +6,11 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
/**
* @defgroup genl Generic Netlink
* @defgroup genl Generic Netlink Library (libnl-genl)
*
* @par Message Format
* @code

View File

@ -13,21 +13,16 @@
* @ingroup core
* @defgroup cb Callbacks/Customization
*
* @details
* @par 1) Setting up a callback set
* @code
* // Allocate a callback set and initialize it to the verbose default set
* struct nl_cb *cb = nl_cb_alloc(NL_CB_VERBOSE);
* Related sections in the development guide:
* - @core_doc{core_cb, Callback Configuration}
*
* // Modify the set to call my_func() for all valid messages
* nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, my_func, NULL);
*
* // Set the error message handler to the verbose default implementation
* // and direct it to print all errors to the given file descriptor.
* FILE *file = fopen(...);
* nl_cb_err(cb, NL_CB_VERBOSE, NULL, file);
* @endcode
* @{
*
* Header
* ------
* ~~~~{.c}
* #include <netlink/handlers.h>
* ~~~~
*/
#include <netlink-local.h>

152
lib/msg.c
View File

@ -6,156 +6,24 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
/**
* @ingroup core
* @defgroup msg Messages
* @defgroup msg Message Construction & Parsing
* Netlink Message Construction/Parsing Interface
*
* The following information is partly extracted from RFC3549
* (ftp://ftp.rfc-editor.org/in-notes/rfc3549.txt)
* Related sections in the development guide:
* - @core_doc{_message_parsing_amp_construction,Message Parsing & Construction}
*
* @par Message Format
* Netlink messages consist of a byte stream with one or multiple
* Netlink headers and an associated payload. If the payload is too big
* to fit into a single message it, can be split over multiple Netlink
* messages, collectively called a multipart message. For multipart
* messages, the first and all following headers have the \c NLM_F_MULTI
* Netlink header flag set, except for the last header which has the
* Netlink header type \c NLMSG_DONE.
*
* @par
* The Netlink message header (struct nlmsghdr) is shown below.
* @code
* 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 | Flags |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Sequence Number |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Process ID (PID) |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* @endcode
*
* @par
* The netlink message header and payload must be aligned properly:
* @code
* <------- NLMSG_ALIGN(hlen) ------> <---- NLMSG_ALIGN(len) --->
* +----------------------------+- - -+- - - - - - - - - - -+- - -+
* | Header | Pad | Payload | Pad |
* | struct nlmsghdr | | | |
* +----------------------------+- - -+- - - - - - - - - - -+- - -+
* @endcode
* @par
* Message Format:
* @code
* <--- nlmsg_total_size(payload) --->
* <-- nlmsg_msg_size(payload) ->
* +----------+- - -+-------------+- - -+-------- - -
* | nlmsghdr | Pad | Payload | Pad | nlmsghdr
* +----------+- - -+-------------+- - -+-------- - -
* nlmsg_data(nlh)---^ ^
* nlmsg_next(nlh)-----------------------+
* @endcode
* @par
* The payload may consist of arbitary data but may have strict
* alignment and formatting rules depening on the specific netlink
* families.
* @par
* @code
* <---------------------- nlmsg_len(nlh) --------------------->
* <------ hdrlen ------> <- nlmsg_attrlen(nlh, hdrlen) ->
* +----------------------+- - -+--------------------------------+
* | Family Header | Pad | Attributes |
* +----------------------+- - -+--------------------------------+
* nlmsg_attrdata(nlh, hdrlen)---^
* @endcode
* @par The ACK Netlink Message
* This message is actually used to denote both an ACK and a NACK.
* Typically, the direction is from FEC to CPC (in response to an ACK
* request message). However, the CPC should be able to send ACKs back
* to FEC when requested.
* @code
* 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
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Netlink message header |
* | type = NLMSG_ERROR |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Error code |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | OLD Netlink message header |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* @endcode
*
* @par Example
* @code
* // Various methods exist to create/allocate a new netlink
* // message.
* //
* // nlmsg_alloc() will allocate an empty netlink message with
* // a maximum payload size which defaults to the page size of
* // the system. This default size can be modified using the
* // function nlmsg_set_default_size().
* struct nl_msg *msg = nlmsg_alloc();
*
* // Very often, the message type and message flags are known
* // at allocation time while the other fields are auto generated:
* struct nl_msg *msg = nlmsg_alloc_simple(MY_TYPE, MY_FLAGS);
*
* // Alternatively an existing netlink message header can be used
* // to inherit the header values:
* struct nlmsghdr hdr = {
* .nlmsg_type = MY_TYPE,
* .nlmsg_flags = MY_FLAGS,
* };
* struct nl_msg *msg = nlmsg_inherit(&hdr);
*
* // Last but not least, netlink messages received from netlink sockets
* // can be converted into nl_msg objects using nlmsg_convert(). This
* // will create a message with a maximum payload size which equals the
* // length of the existing netlink message, therefore no more data can
* // be appened without calling nlmsg_expand() first.
* struct nl_msg *msg = nlmsg_convert(nlh_from_nl_sock);
*
* // Payload may be added to the message via nlmsg_append(). The fourth
* // parameter specifies the number of alignment bytes the data should
* // be padding with at the end. Common values are 0 to disable it or
* // NLMSG_ALIGNTO to ensure proper netlink message padding.
* nlmsg_append(msg, &mydata, sizeof(mydata), 0);
*
* // Sometimes it may be necessary to reserve room for data but defer
* // the actual copying to a later point, nlmsg_reserve() can be used
* // for this purpose:
* void *data = nlmsg_reserve(msg, sizeof(mydata), NLMSG_ALIGNTO);
*
* // Attributes may be added using the attributes interface.
*
* // After successful use of the message, the memory must be freed
* // using nlmsg_free()
* nlmsg_free(msg);
* @endcode
*
* @par 4) Parsing messages
* @code
* int n;
* unsigned char *buf;
* struct nlmsghdr *hdr;
*
* n = nl_recv(handle, NULL, &buf);
*
* hdr = (struct nlmsghdr *) buf;
* while (nlmsg_ok(hdr, n)) {
* // Process message here...
* hdr = nlmsg_next(hdr, &n);
* }
* @endcode
* @{
*
* Header
* ------
* ~~~~{.c}
* #include <netlink/msg.h>
* ~~~~
*/
#include <netlink-local.h>

View File

@ -6,13 +6,13 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
* Copyright (c) 2007 Secure Computing Corporation
*/
/**
* @defgroup nfnl Netfilter Netlink
* @defgroup nfnl Netfilter Library (libnl-nf)
*
* @par Message Format
* @code

100
lib/nl.c
View File

@ -6,78 +6,22 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
/**
* @defgroup core Core
* @defgroup core Core Library (libnl)
*
* @details
* @par 1) Connecting the socket
* @code
* // Bind and connect the socket to a protocol, NETLINK_ROUTE in this example.
* nl_connect(sk, NETLINK_ROUTE);
* @endcode
* Socket handling, connection management, sending and receiving of data,
* message construction and parsing, object caching system, ...
*
* @par 2) Sending data
* @code
* // The most rudimentary method is to use nl_sendto() simply pushing
* // a piece of data to the other netlink peer. This method is not
* // recommended.
* const char buf[] = { 0x01, 0x02, 0x03, 0x04 };
* nl_sendto(sk, buf, sizeof(buf));
* This is the API reference of the core library. It is not meant as a guide
* but as a reference. Please refer to the core library guide for detailed
* documentation on the library architecture and examples:
*
* // A more comfortable interface is nl_send() taking a pointer to
* // a netlink message.
* struct nl_msg *msg = my_msg_builder();
* nl_send(sk, nlmsg_hdr(msg));
* * @ref_asciidoc{core,_,Netlink Core Library Development Guide}
*
* // nl_sendmsg() provides additional control over the sendmsg() message
* // header in order to allow more specific addressing of multiple peers etc.
* struct msghdr hdr = { ... };
* nl_sendmsg(sk, nlmsg_hdr(msg), &hdr);
*
* // You're probably too lazy to fill out the netlink pid, sequence number
* // and message flags all the time. nl_send_auto_complete() automatically
* // extends your message header as needed with an appropriate sequence
* // number, the netlink pid stored in the netlink socket and the message
* // flags NLM_F_REQUEST and NLM_F_ACK (if not disabled in the socket)
* nl_send_auto_complete(sk, nlmsg_hdr(msg));
*
* // Simple protocols don't require the complex message construction interface
* // and may favour nl_send_simple() to easly send a bunch of payload
* // encapsulated in a netlink message header.
* nl_send_simple(sk, MY_MSG_TYPE, 0, buf, sizeof(buf));
* @endcode
*
* @par 3) Receiving data
* @code
* // nl_recv() receives a single message allocating a buffer for the message
* // content and gives back the pointer to you.
* struct sockaddr_nl peer;
* unsigned char *msg;
* nl_recv(sk, &peer, &msg);
*
* // nl_recvmsgs() receives a bunch of messages until the callback system
* // orders it to state, usually after receving a compolete multi part
* // message series.
* nl_recvmsgs(sk, my_callback_configuration);
*
* // nl_recvmsgs_default() acts just like nl_recvmsg() but uses the callback
* // configuration stored in the socket.
* nl_recvmsgs_default(sk);
*
* // In case you want to wait for the ACK to be recieved that you requested
* // with your latest message, you can call nl_wait_for_ack()
* nl_wait_for_ack(sk);
* @endcode
*
* @par 4) Closing
* @code
* // Close the socket first to release kernel memory
* nl_close(sk);
* @endcode
*
* @{
*/
@ -88,6 +32,30 @@
#include <netlink/msg.h>
#include <netlink/attr.h>
/**
* @defgroup core_types Data Types
*
* Core library data types
* @{
* @}
*
* @defgroup send_recv Send & Receive Data
*
* Connection management, sending & receiving of data
*
* Related sections in the development guide:
* - @core_doc{core_send_recv, Sending & Receiving}
* - @core_doc{core_sockets, Sockets}
*
* @{
*
* Header
* ------
* ~~~~{.c}
* #include <netlink/netlink.h>
* ~~~~
*/
/**
* @name Connection Management
* @{
@ -541,6 +509,7 @@ abort:
return 0;
}
/** @cond SKIP */
#define NL_CB_CALL(cb, type, msg) \
do { \
err = nl_cb_call(cb, type, msg); \
@ -556,6 +525,7 @@ do { \
goto out; \
} \
} while (0)
/** @endcond */
static int recvmsgs(struct nl_sock *sk, struct nl_cb *cb)
{
@ -923,3 +893,5 @@ errout:
/** @} */
/** @} */
/** @} */

View File

@ -10,9 +10,21 @@
*/
/**
* @ingroup cache
* @defgroup object Object
* @ingroup core_types
* @defgroup object Object (Cacheable)
*
* Generic object data type, for inheritance purposes to implement cacheable
* data types.
*
* Related sections in the development guide:
*
* @{
*
* Header
* ------
* ~~~~{.c}
* #include <netlink/object.h>
* ~~~~
*/
#include <netlink-local.h>

View File

@ -1442,8 +1442,7 @@ struct rtnl_link *rtnl_link_alloc(void)
/**
* Return a link object reference
*
* @copydetails nl_object_put()
* @arg link Link object
*/
void rtnl_link_put(struct rtnl_link *link)
{

View File

@ -6,11 +6,11 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
/**
* @defgroup rtnl Routing Family
* @defgroup rtnl Routing Library (libnl-route)
* @{
*/

View File

@ -6,13 +6,25 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
/**
* @ingroup core
* @ingroup core_types
* @defgroup socket Socket
*
* Representation of a netlink socket
*
* Related sections in the development guide:
* - @core_doc{core_sockets, Netlink Sockets}
*
* @{
*
* Header
* ------
* ~~~~{.c}
* #include <netlink/socket.h>
* ~~~~
*/
#include <pthread.h>

View File

@ -6,13 +6,22 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
*/
/**
* @ingroup core
* @defgroup utils Utilities
*
* Collection of helper functions
*
* @{
*
* Header
* ------
* ~~~~{.c}
* #include <netlink/utils.h>
* ~~~~
*/
#include <netlink-local.h>
@ -21,10 +30,24 @@
#include <linux/socket.h>
/**
* Debug level
* Global variable indicating the desired level of debugging output.
*
* Level | Messages Printed
* ----- | ---------------------------------------------------------
* 0 | Debugging output disabled
* 1 | Warnings, important events and notifications
* 2 | More or less important debugging messages
* 3 | Repetitive events causing a flood of debugging messages
* 4 | Even less important messages
*
* If available, the variable will be initialized to the value of the
* environment variable `NLDBG`. The default value is 0 (disabled).
*
* For more information, see section @core_doc{_debugging, Debugging}.
*/
int nl_debug = 0;
/** @cond SKIP */
struct nl_dump_params nl_debug_dp = {
.dp_type = NL_DUMP_DETAILS,
};
@ -84,9 +107,10 @@ int __nl_read_num_str_file(const char *path, int (*cb)(long, const char *))
return 0;
}
/** @endcond */
/**
* @name Unit Pretty-Printing
* @name Pretty Printing of Numbers
* @{
*/