diff options
Diffstat (limited to 'doc/src/core.c')
-rw-r--r-- | doc/src/core.c | 2303 |
1 files changed, 0 insertions, 2303 deletions
diff --git a/doc/src/core.c b/doc/src/core.c deleted file mode 100644 index a173a43..0000000 --- a/doc/src/core.c +++ /dev/null @@ -1,2303 +0,0 @@ -/** - * \cond skip - * vim:syntax=c.doxygen - * \endcond - -\page core_doc Netlink Core Library (-lnl) - -\section core_intro Introduction - -The core library contains the fundamentals required to communicate over -netlink sockets. It deals with connecting and disconnectng of sockets, -sending and receiving of data, construction and parsing of messages, -provides a customizeable receiving state machine, and provides a abstract -data type framework which eases the implementation of object based netlink -protocols where objects are added, removed, or modified with the help of -netlink messages. - -\section core_toc Table of Contents - -- \ref core_lib - - \ref core_lib_howto - - \ref core_lib_link -- \ref proto_fund - - \ref core_format - - \ref core_msg_type - - \ref core_multipart - - \ref core_errmsg - - \ref core_ack - - \ref core_msg_flags - - \ref core_seq - - \ref core_multicast -- \ref sk_doc - - \ref core_sk_alloc - - \ref core_sk_seq_num - - \ref core_sk_groups - - \ref core_sk_cb - - \ref core_sk_attrs - - \ref core_sk_local_port - - \ref core_sk_peer_port - - \ref core_sk_fd - - \ref core_sk_buffer_size - - \ref core_sk_cred - - \ref core_sk_auto_ack - - \ref core_sk_msg_peek - - \ref core_sk_pktinfo -- \ref core_send_recv - - \ref core_send - - \ref core_nl_send - - \ref core_nl_send_iovec - - \ref core_nl_sendmsg - - \ref core_send_raw - - \ref core_send_simple - - \ref core_recv - - \ref core_nl_recvmsgs - - \ref core_recvmsgs - - \ref core_recv_parse - - \ref core_auto_ack -- \ref core_msg - - \ref core_msg_format - - \ref core_msg_fmt_align - - \ref core_msg_parse - - \ref core_msg_split - - \ref core_msg_payload - - \ref core_msg_parse_attr - - \ref core_nlmsg_parse - - \ref core_msg_constr - - \ref core_msg_alloc - - \ref core_msg_nlmsg_put - - \ref core_msg_reserve - - \ref core_msg_append -- \ref core_attr - - \ref core_attr_format - - \ref core_attr_parse - - \ref core_attr_parse_split - - \ref core_attr_payload - - \ref core_attr_validation - - \ref core_attr_nla_parse - - \ref core_attr_find - - \ref core_attr_iterate - - \ref core_attr_constr - - \ref core_attr_exception - - \ref core_attr_data_type - - \ref core_attr_int - - \ref core_attr_string - - \ref core_attr_flag - - \ref core_attr_nested - - \ref core_attr_unspec - - \ref core_attr_examples - - \ref core_attr_example_constr - - \ref core_attr_example_parse -- \ref core_cb - - \ref core_cb_hooks - - \ref core_cb_default - - \ref core_cb_msg_proc - - \ref core_cb_errmsg - - \ref core_cb_example - - \ref core_cb_overwrite - - \ref core_cb_ow_recvmsgs - - \ref core_cb_ow_recv - - \ref core_cb_ow_send -- \ref core_cache -- \ref core_abstract_types - - \ref core_abstract_addr - - \ref core_abstract_addr_alloc - - \ref core_abstract_addr_ref - - \ref core_abstract_addr_attr - - \ref core_abstract_addr_prefix - - \ref core_abstract_addr_helpers - - \ref core_abstract_data - - \ref core_abstract_data_alloc - - \ref core_abstract_data_access - - \ref core_abstract_data_helpers - -\section core_lib 1. Introduction to the Library - -\subsection core_lib_howto 1.1 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. - -Even though the library tries to be as consistent and as intuitive as -possible it may be difficult to understand where to start looking for -information. - - - -\subsection core_lib_link 1.2 Linking to this Library - - -\subsection flags Flags to Character StringTranslations - -All functions converting a set of flags to a character string follow -the same principles, therefore, the following information applies -to all functions convertings flags to a character string and vice versa. - -\subsubsection flags2str Flags to Character String -\code -char *<object name>_flags2str(int flags, char *buf, size_t len) -\endcode -\arg flags Flags. -\arg buf Destination buffer. -\arg len Buffer length. - -Converts the specified flags to a character string separated by -commas and stores it in the specified destination buffer. - -\return The destination buffer - -\subsubsection str2flags Character String to Flags -\code -int <object name>_str2flags(const char *name) -\endcode -\arg name Name of flag. - -Converts the provided character string specifying a flag -to the corresponding numeric value. - -\return Link flag or a negative value if none was found. - -\subsubsection type2str Type to Character String -\code -char *<object name>_<type>2str(int type, char *buf, size_t len) -\endcode -\arg type Type as numeric value -\arg buf Destination buffer. -\arg len Buffer length. - -Converts an identifier (type) to a character string and stores -it in the specified destination buffer. - -\return The destination buffer or the type encoded in hexidecimal - form if the identifier is unknown. - -\subsubsection str2type Character String to Type -\code -int <object name>_str2<type>(const char *name) -\endcode -\arg name Name of identifier (type). - -Converts the provided character string specifying a identifier -to the corresponding numeric value. - -\return Identifier as numeric value or a negative value if none was found. - - -\section proto_fund 1. Netlink Protocol Fundamentals - -The netlink protocol is a socket based IPC mechanism used for communication -between userspace processes and the kernel or between userspace processes -themselves. The netlink protocol is based on BSD sockets and uses the -\c AF_NETLINK address family. Every netlink protocol uses its own protocol -number (e.g. NETLINK_ROUTE, NETLINK_NETFILTER, etc). Its addressing schema -is based on a 32 bit port number, formerly referred to as PID, which uniquely -identifies each peer. - -\subsection core_format 1.1 Message Format - -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 a fixed -size protocol specific header followed by a stream of attributes. - -The netlink message header (struct nlmsghdr) has the following format: - -\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 | -+-------------------------------------------------------------+ -| Port (Address) | -+-------------------------------------------------------------+ -\endcode - -\subsection core_msg_type 1.2 Message Types - -Netlink differs between requests, notifications, and replies. Requests -are messages which have the \c NLM_F_REQUEST flag set and are meant to -request an action from the receiver. A request is typically sent from -a userspace process to the kernel. While not strictly enforced, requests -should carry a sequence number incremented for each request sent. - -Depending on the nature of the request, the receiver may reply to the -request with another netlink message. The sequence number of a reply -must match the sequence number of the request it relates to. - -Notifications are of informal nature and no reply is expected, therefore -the sequence number is typically set to 0. - -\msc -A,B; -A=>B [label="GET (seq=1, NLM_F_REQUEST)"]; -A<=B [label="PUT (seq=1)"]; -...; -A<=B [label="NOTIFY (seq=0)"]; -\endmsc - -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: - -- \c NLMSG_NOOP - No operation, message must be discarded -- \c NLMSG_ERROR - Error message or ACK, see \ref core_errmsg, - respectively \ref core_ack -- \c NLMSG_DONE - End of multipart sequence, see \ref core_multipart. -- \c NLMSG_OVERRUN - Overrun notification (Error) - -Every netlink protocol is free to define own message types. Note that -message type values < \c NLMSG_MIN_TYPE (0x10) are reserved and may not -be used. - -It is common practice to use own message types to implement RPC schemas. -Suppose the goal of the netlink protocol you are implementing is allow -configuration of a particular network device, therefore you want to -provide read/write access to various configuration options. The typical -"netlink way" of doing this would be to define two message types -\c MSG_SETCFG, \c MSG_GETCFG: - -\code -#define MSG_SETCFG 0x11 -#define MSG_GETCFG 0x12 -\endcode - -Sending a \c MSG_GETCFG request message will typically trigger a reply -with the message type \c MSG_SETCFG containing the current configuration. -In object oriented terms one would describe this as "the kernel sets -the local copy of the configuration in userspace". - -\msc -A,B; -A=>B [label="MSG_GETCFG (seq=1, NLM_F_REQUEST)"]; -A<=B [label="MSG_SETCFG (seq=1)"]; -\endmsc - -The configuration may be changed by sending a \c MSG_SETCFG which will -be responded to with either a ACK (see \ref core_ack) or a error -message (see \ref core_errmsg). - -\msc -A,B; -A=>B [label="MSG_SETCFG (seq=1, NLM_F_REQUEST, NLM_F_ACK)"]; -A<=B [label="ACK (seq=1)"]; -\endmsc - -Optionally, the kernel may send out notifications for configuration -changes allowing userspace to listen for changes instead of polling -frequently. Notifications typically reuse an existing message type -and rely on the application using a separate socket to differ between -requests and notifications but you may also specify a separate message -type. - -\msc -A,B; -A<=B [label="MSG_SETCFG (seq=0)"]; -\endmsc - -\subsubsection core_multipart 1.2.1 Multipart Messages - -Although in theory a netlink message can be up to 4GiB in size. The socket -buffers are very likely not large enough to hold message of such sizes. -Therefore it is common to limit messages to one page size (PAGE_SIZE) and -use the multipart mechanism to split large pieces of data into several -messages. A multipart message has the \c flag NLM_F_MULTI set and the -receiver is expected to continue receiving and parsing until the special -message type \c NLMSG_DONE is received. - -Multipart messages unlike fragmented ip packets must not be reassmbled -even though it is perfectly legal to do so if the protocols wishes to -work this way. Often multipart message are used to send lists or trees -of objects were each multipart message simply carries multiple objects -allow for each message to be parsed independently. - -\msc -A,B; -A=>B [label="GET (seq=1, NLM_F_REQUEST)"]; -A<=B [label="PUT (seq=1, NLM_F_MULTI)"]; -...; -A<=B [label="PUT (seq=1, NLM_F_MULTI)"]; -A<=B [label="NLMSG_DONE (seq=1)"]; -\endmsc - -\subsubsection core_errmsg 1.2.2 Error Message - -Error messages can be sent in response to a request. Error messages must -use the standard message type \c NLMSG_ERROR. The payload consists of a -error code and the original netlink mesage header of the request. - -\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 | -+------------------------------+------------------------------+ -| .nlmsg_type = NLMSG_ERROR | .nlmsg_flags = 0 | -+------------------------------+------------------------------+ -| Sequence number of the orig request | -+-------------------------------------------------------------+ -| Port number of the orig request | -+-------------------------------------------------------------+ -| Error Code (e.g. EINVAL) | -+-------------------------------------------------------------+ -| Netlink Message Header of orig. request | -. . -. . -+-------------------------------------------------------------+ -\endcode - -Error messages should set the sequence number to the sequence number -of the request which caused the error. - -\msc -A,B; -A=>B [label="GET (seq=1, NLM_F_REQUEST)"]; -A<=B [label="NLMSG_ERROR code=EINVAL (seq=1)"]; -\endmsc - -\subsubsection core_ack 1.2.3 ACKs - -A sender can request an ACK message to be sent back for each request -processed by setting the \c NLM_F_ACK flag in the request. This is typically -used to allow the sender to synchronize further processing until the -request has been processed by the receiver. - -\msc -A,B; -A=>B [label="GET (seq=1, NLM_F_REQUEST | NLM_F_ACK)"]; -A<=B [label="ACK (seq=1)"]; -\endmsc - -ACK messages also use the message type \c NLMSG_ERROR and payload format -but the error code is set to 0. - -\subsubsection core_msg_flags 1.3 Message Flags - -The following standard flags are defined - -\code -#define NLM_F_REQUEST 1 -#define NLM_F_MULTI 2 -#define NLM_F_ACK 4 -#define NLM_F_ECHO 8 -\endcode - -- \c NLM_F_REQUEST - Message is a request, see \ref core_msg_type. -- \c NLM_F_MULTI - Multipart message, see \ref core_multipart. -- \c NLM_F_ACK - ACK message requested, see \ref core_ack. -- \c NLM_F_ECHO - Request to echo the request. - -The flag \c NLM_F_ECHO is similar to the \c NLM_F_ACK flag. It can be -used in combination with \c 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 \ref core_multicast. - -Additional universal message flags are defined which only apply for -\c GET requests: - -\code -#define NLM_F_ROOT 0x100 -#define NLM_F_MATCH 0x200 -#define NLM_F_ATOMIC 0x400 -#define NLM_F_DUMP (NLM_F_ROOT|NLM_F_MATCH) -\endcode - -- \c NLM_F_ROOT - Return based on root of tree. -- \c NLM_F_MATCH - Return all matching entries. -- \c NLM_F_ATOMIC - Obsoleted, once used to request an atomic operation. -- \c NLM_F_DUMP - Return a list of all objects \c (NLM_F_ROOT|NLM_F_MATCH). - -Use of these flags is completely optional and many netlink protocols only -make use of the \c 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 \ref core_multipart). - -Another set of flags exist related to \c NEW or \c SET requests. These -flags are mutually exclusive to the \c GET flags: - -\code -#define NLM_F_REPLACE 0x100 -#define NLM_F_EXCL 0x200 -#define NLM_F_CREATE 0x400 -#define NLM_F_APPEND 0x800 -\endcode - -- \c NLM_F_REPLACE - Replace an existing object if it exists. -- \c NLM_F_EXCL - Do not update object if it exists already. -- \c NLM_F_CREATE - Create object if it does not exist yet. -- \c NLM_F_APPEND - Add object at end of list. - -Behaviour of these flags may differ slightly between different netlink -protocols. - -\subsection core_seq 1.4 Sequence Numbers - -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 \ref core_msg_type for more information. - -Sequence numbers are managed on a per socket basis, see -\ref core_sk_seq_num for more information on how to use sequence numbers. - -\subsection core_multicast 1.5 Multicast Groups - -TODO - -See \ref core_sk_groups. - -\section sk_doc 2. Netlink Sockets - -In order to use the netlink protocol, a netlink socket is required. Each -socket defines a completely independent context for sending and receiving -of messages. An application may use multiple sockets for the same netlink -protocol, e.g. one socket to send requests and receive replies and another -socket subscribed to a multicast group to receive notifications. - -\subsection core_sk_alloc 2.1 Socket Allocation & Freeing - -The netlink socket and all its related attributes are represented by -struct nl_sock. - -\code -#include <netlink/socket.h> - -struct nl_sock *nl_socket_alloc(void) -void nl_socket_free(struct nl_sock *sk) -\endcode - -\subsection core_sk_seq_num 2.2 Sequence Numbers - -The library will automatically take care of sequence number handling for -the application. A sequence number counter is stored in struct nl_sock which -is meant to be used when sending messages which will produce a reply, error -or any other message which needs to be related to the original message. - -The counter can be used directly with the function nl_socket_use_seq() -which will return the current value of the counter and increment it by -one afterwards. - -\code -#include <netlink/socket.h> - -unsigned int nl_socket_use_seq(struct nl_sock *sk); -\endcode - -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 -\ref 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 -used to receive notification messages. - -\code -#include <netlink/socket.h> - -void nl_socket_disable_seq_check(struct nl_sock *sk); -\endcode - -\subsection core_sk_groups 2.3 Multicast Group Subscriptions - -Each socket can subscribe to any number of multicast groups of the -netlink protocol it is connected to. The socket will then receive a copy -of each message sent to any of the groups. Multicast groups are commonly -used to implement event notifications. - -Prior to kernel 2.6.14 the group subscription was performed using a bitmask -which limited the number of groups per protocol family to 32. This outdated -interface can still be accessed via the function nl_join_groups even though -it is not recommended for new code. - -\code -#include <netlink/socket.h> - -void nl_join_groups(struct nl_sock *sk, int bitmask); -\endcode - -Starting with 2.6.14 a new method was introduced which supports subscribing -to an almost infinite number of multicast groups. - -\code -#include <netlink/socket.h> - -int nl_socket_add_memberships(struct nl_sock *sk, int group, ...); -int nl_socket_drop_memberships(struct nl_sock *sk, int group, ...); -\endcode - -\subsubsection core_sk_group_example 2.3.1 Multicast Example - -\include sk_group_example.c - -\subsection core_sk_cb 2.4 Modifiying Socket Callback Configuration - -See \ref core_cb for more information on callback hooks and overwriting -capabilities - -Each socket is assigned a callback configuration which controls the -behaviour of the socket. This is f.e. required to have a separate message -receive function per socket. It is perfectly legal to share callback -configurations between sockets though. - -The following functions can be used to access and set the callback -configuration of a socket: - -\code -#include <netlink/socket.h> - -struct nl_cb *nl_socket_get_cb(const struct nl_sock *sk); -void nl_socket_set_cb(struct nl_sock *sk, struct nl_cb *cb); -\endcode - -Additionaly a shortcut exists to modify the callback configuration assigned -to a socket directly: - -\code -#include <netlink/socket.h> - -int nl_socket_modify_cb(struct nl_sock *sk, enum nl_cb_type type, enum nl_cb_kind kind, - nl_recvmsg_msg_cb_t func, void *arg); -\endcode - -Example: -\code -#include <netlink/socket.h> - -// Call my_input() for all valid messages received in socket sk -nl_socket_modify_cb(sk, NL_CB_VALID, NL_CB_CUSTOM, my_input, NULL); -\endcode - -\subsection core_sk_attrs 2.5 Socket Attributes - -\subsubsection core_sk_local_port 2.5.1 Local Port - -The local port number uniquely identifies the socket and is used to -address it. A unique local port is generated automatically when the socket -is allocated. It will consist of the Process ID (22 bits) and a random -number (10 bits) thus allowing up to 1024 sockets per process. - -\code -#include <netlink/socket.h> - -uint32_t nl_socket_get_local_port(const struct nl_sock *sk); -void nl_socket_set_local_port(struct nl_sock *sk, uint32_t port); -\endcode - -\b Note: Overwriting the local port is possible but you have to ensure -that the provided value is unique and no other socket in any other -application is using the same value. - -\subsubsection core_sk_peer_port 2.5.2 Peer Port - -A peer port can be assigned to the socket which will result in all unicast -messages sent over the socket to be addresses to the peer. If no peer is -specified, the message is sent to the kernel which will try to automatically -bind the socket to a kernel side socket of the same netlink protocol family. -It is common practice not to bind the socket to a peer port as typically -only one kernel side socket exists per netlink protocol family. - -\code -#include <netlink/socket.h> - -uint32_t nl_socket_get_peer_port(const struct nl_sock *sk); -void nl_socket_set_peer_port(struct nl_sock *sk, uint32_t port); -\endcode - -\subsubsection core_sk_fd 2.5.3 File Descriptor - -Netlink uses the BSD socket interface, therefore a file descriptor -is behind each socket and you may use it directly. - -\code -#include <netlink/socket.h> - -int nl_socket_get_fd(const struct nl_sock *sk); -\endcode - -If a socket is used to only receive notifications it usually is best -to put the socket in non-blocking mode and periodically poll for new -notifications. - -\code -#include <netlink/socket.h> - -int nl_socket_set_nonblocking(const struct nl_sock *sk); -\endcode - -\subsubsection core_sk_buffer_size 2.5.4 Send/Receive Buffer Size - -The socket buffer is used to queue netlink messages between sender -and receiver. The size of these buffers specifies the maximum size -you will be able to write() to a netlink socket, i.e. it will indirectly -define the maximum message size. The default is 32KiB. - -\code -#include <netlink/socket.h> - -int nl_socket_set_buffer_size(struct nl_sock *sk, int rx, int tx); -\endcode - - -\subsubsection core_sk_cred 2.5.5 Enable/Disable Credentials - -TODO - -\code -#include <netlink/socket.h> - -int nl_socket_set_passcred(struct nl_sock *sk, int state); -\endcode - -\subsubsection core_sk_auto_ack 2.5.6 Enable/Disable Auto-ACK Mode - -The following functions allow to enable/disable Auto-ACK mode on a -socket. See \ref core_auto_ack for more information on what implications -that has. Auto-ACK mode is enabled by default. - -\code -#include <netlink/socket.h> - -void nl_socket_enable_auto_ack(struct nl_sock *sk); -void nl_socket_disable_auto_ack(struct nl_sock *sk); -\endcode - -\subsubsection core_sk_msg_peek 2.5.7 Enable/Disable Message Peeking - -If enabled, message peeking causes nl_recv() to try and use MSG_PEEK to -retrieve the size of the next message received and allocate a buffer -of that size. Message peeking is enabled by default but can be disabled -using the following function: - -\code -#include <netlink/socket.h> - -void nl_socket_enable_msg_peek(struct nl_sock *sk); -void nl_socket_disable_msg_peek(struct nl_sock *sk); -\endcode - -\subsubsection core_sk_pktinfo 2.5.8 Enable/Disable Receival of Packet Information - -If enabled, each received netlink message from the kernel will include an -additional struct nl_pktinfo in the control message. The following function -can be used to enable/disable receival of packet information. - -\code -#include <netlink/socket.h> - -int nl_socket_recv_pktinfo(struct nl_sock *sk, int state); -\endcode - -\b Note: Processing of NETLINK_PKTINFO has not been implemented yet. - -\section core_send_recv 3. Sending and Receiving of Messages / Data - -\subsection core_send 3.1 Sending Netlink 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 -the netlink message by filling the missing bits and pieces in the -netlink message header and will deal with addressing based on the -options and address set in the netlink socket. The message is then passed -on to nl_send(). - -If the default sending semantics implemented by nl_send() do not suit the -application, it may overwrite the sending function nl_send() by -specifying an own implementation using the function nl_cb_overwrite_send(). - -\code - nl_send_auto(sk, msg) - | - |-----> nl_complete_msg(sk, msg) - | - | - | Own send function specified via nl_cb_overwrite_send() - |- - - - - - - - - - - - - - - - - - - - - v v - nl_send(sk, msg) send_func() -\endcode - -\subsubsection core_nl_send 3.1.1 Using nl_send() - -If you do not require any of the automatic message completion functionality -you may use nl_send() directly but beware that any internal calls to -nl_send_auto() by the library to send netlink messages will still use -nl_send(). Therefore if you wish to use any higher level interfaces and the -behaviour of nl_send() is to your dislike then you must overwrite the -nl_send() function via nl_cb_overwrite_send() - -The purpose of nl_send() is to embed the netlink message into a iovec -structure and pass it on to nl_send_iovec(). - -\code - nl_send(sk, msg) - | - v - nl_send_iovec(sk, msg, iov, iovlen) -\endcode - -\subsubsection core_nl_send_iovec 3.1.2 Using nl_send_iovec() - -nl_send_iovec() expects a finalized netlink message and fills out the -struct msghdr used for addressing. It will first check if the struct nl_msg -is addressed to a specific peer (see nlmsg_set_dst()). If not, it will try -to fall back to the peer address specified in the socket (see -nl_socket_set_peer_port(). Otherwise the message will be sent unaddressed -and it is left to the kernel to find the correct peer. - -nl_send_iovec() also adds credentials if present and enabled -(see \ref core_sk_cred). - -The message is then passed on to nl_sendmsg(). - -\code - nl_send_iovec(sk, msg, iov, iovlen) - | - v - nl_sendmsg(sk, msg, msghdr) -\endcode - -\subsubsection core_nl_sendmsg 3.1.3 Using nl_sendmsg() - -nl_sendmsg() expects a finalized netlink message and an optional struct -msghdr containing the peer address. It will copy the local address as -defined in the socket (see nl_socket_set_local_port()) into the netlink -message header. - -At this point, construction of the message finished and it is ready to -be sent. - -\code - nl_sendmsg(sk, msg, msghdr) - |- - - - - - - - - - - - - - - - - - - - v - | NL_CB_MSG_OUT() - |<- - - - - - - - - - - - - - - - - - - -+ - v - sendmsg() -\endcode - -Before sending the application has one last chance to modify the message. -It is passed to the NL_CB_MSG_OUT callback function which 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 -\ref core_sk_cb for more information on how to set callbacks. - -\subsubsection core_send_raw 3.1.4 Sending Raw Data with nl_sendto() - -If you wish to send raw data over a netlink socket, the following -function will pass on any buffer provided to it directly to sendto(): - -\code -#include <netlink/netlink.h> - -int nl_sendto(struct nl_sock *sk, void *buf, size_t size); -\endcode - -\subsubsection core_send_simple 3.1.5 Sending of Simple Messages - -A special interface exists for sending of trivial messages. The function -expects the netlink message type, optional netlink message flags, and an -optional data buffer and data length. -\code -#include <netlink/netlink.h> - -int nl_send_simple(struct nl_sock *sk, int type, int flags, - void *buf, size_t size); -\endcode - -The function will construct a netlink message header based on the message -type and flags provided and append the data buffer as message payload. The -newly constructed message is sent with nl_send_auto(). - -The following example will send a netlink request message causing the -kernel to dump a list of all network links to userspace: -\include nl_send_simple.c - -\subsection core_recv 3.2 Receiving Netlink 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 -application may customize these in detail although the default behaviour will -probably suit most applications. - -nl_recvmsgs_default() will also be called internally by the library whenever -it needs to receive and parse a netlink message. - -The function will fetch the callback configuration stored in the socket and -call nl_recvmsgs(): - -\code - nl_recvmsgs_default(sk) - | - | cb = nl_socket_get_cb(sk) - v - nl_recvmsgs(sk, cb) -\endcode - -\subsubsection core_nl_recvmsgs 3.2.1 Using nl_recvmsgs() - -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. - -See \ref core_recvmsgs for more information on the behaviour of -nl_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 \ref 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(). - -\code - nl_recvmsgs(sk, cb) - | - | Own recvmsgs function specified via nl_cb_overwrite_recvmsgs() - |- - - - - - - - - - - - - - - - - - - - - v v - internal_recvmsgs() my_recvmsgs() -\endcode - -\subsubsection core_recvmsgs 3.2.2 Receive Characteristics - -If the application does not provide its own recvmsgs() implementation -with the function nl_cb_overwrite_recvmsgs() the following characteristics -apply while receiving data from a netlink socket: - -\code - internal_recvmsgs() - | -+-------------->| Own recv function specified with nl_cb_overwrite_recv() -| |- - - - - - - - - - - - - - - - -| v v -| nl_recv() my_recv() -| |<- - - - - - - - - - - - - - -+ -| |<-------------+ -| v | More data to parse? (nlmsg_next()) -| Parse Message | -| |--------------+ -| v -+------- NLM_F_MULTI set? - | - v - (SUCCESS) -\endcode - -The function nl_recv() is invoked first to receive data from the netlink -socket. This function may be overwritten by the application by an own -implementation using the function nl_cb_overwrite_recv(). This may be -useful if the netlink byte stream is in fact not received from a socket -directly but is read from a file or another source. - -If data has been read, it will be attemped to parse the data -(see \ref core_recv_parse). This 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 \ref 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 \ref core_recv_parse for information on how to extract valid netlink -messages from the parser and on how to control the behaviour of it. - -\subsubsection core_recv_parse 3.2.3 Parsing Characteristics - -The internal parser is invoked for each netlink message received from a -netlink socket. It is typically fed by nl_recv() (see \ref core_recvmsgs). - -The parser will first ensure that the length of the data stream provided -is sufficient to contain a netlink message header and that the message -length as specified in the message header does not exceed it. - -If this criteria is met, a new struct nl_msg is allocated and the message -is passed on to the the callback function NL_CB_MSG_IN if one is set. Like -any other callback function, it may return NL_SKIP to skip the current -message but continue parsing the next message or NL_STOP to stop parsing -completely. - -The next step is to check the sequence number of the message against the -currently expected sequence number. The application may provide its own -sequence number checking algorithm by setting the callback function -NL_CB_SEQ_CHECK to its own implementation. In fact, calling -nl_socket_disable_seq_check() to disable sequence number checking will -do nothing more than set the NL_CB_SEQ_CHECK hook to a function which -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 \ref core_ack). - -\code - parse() - | - v - nlmsg_ok() --> Ignore - | - |- - - - - - - - - - - - - - - v - | NL_CB_MSG_IN() - |<- - - - - - - - - - - - - - -+ - | - |- - - - - - - - - - - - - - - v - Sequence Check NL_CB_SEQ_CHECK() - |<- - - - - - - - - - - - - - -+ - | - | Message has NLM_F_ACK set - |- - - - - - - - - - - - - - - v - | NL_CB_SEND_ACK() - |<- - - - - - - - - - - - - - -+ - | - Handle Message Type -\endcode - -\subsection core_auto_ack 3.3 Auto-ACK Mode - -TODO - -\section core_msg 4. Netlink Message Parsing & Construction - -\subsection core_msg_format 4.1 Message Format - -See \ref proto_fund for an introduction to the netlink protocol and its -message format. - -\subsubsection core_msg_fmt_align 4.1.1 Alignment - -Most netlink protocols enforce a strict alignment policy for all boundries. -The alignment value is defined by NLMSG_ALIGNTO and is fixed to 4 bytes. -Therefore all netlink message headers, begin of payload sections, protocol -specific headers, and attribute sections must start at an offset which is -a multiple of NLMSG_ALIGNTO. - -\code -#include <netlink/msg.h> - -int nlmsg_size(int payloadlen); -int nlmsg_total_size(int payloadlen); -\endcode - -The library provides a set of function to handle alignment requirements -automatically. The function nlmsg_total_size() returns the total size -of a netlink message including the padding to ensure the next message -header is aligned correctly. - -\code - <----------- nlmsg_total_size(len) ------------> - <----------- nlmsg_size(len) ------------> - +-------------------+- - -+- - - - - - - - +- - -+-------------------+- - - - | struct nlmsghdr | Pad | Payload | Pad | struct nlsmghdr | - +-------------------+- - -+- - - - - - - - +- - -+-------------------+- - - - <---- NLMSG_HDRLEN -----> <- NLMSG_ALIGN(len) -> <---- NLMSG_HDRLEN --- -\endcode - -If you need to know if padding needs to be added at the end of a message, -nlmsg_padlen() returns the number of padding bytes that need to be added -for a specific payload length. - -\code -#include <netlink/msg.h> -int nlmsg_padlen(int payloadlen); -\endcode - -\subsection core_msg_parse 4.2 Parsing a Message - -The library offers two different methods of parsing netlink messages. -It offers a low level interface for applications which want to do all -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 \ref core_cache. - -\subsubsection core_msg_split 4.2.1 Splitting a byte stream into separate messages - -What you receive from a netlink socket is typically a stream of -messages. You will be given a buffer and its length, the buffer may -contain any number of netlink messages. - -The first message header starts at the beginning of message stream. Any -subsequent message headers are access by calling nlmsg_next() on the -previous header. - -\code -#include <netlink/msg.h> - -struct nlmsghdr *nlmsg_next(struct nlmsghdr *hdr, int *remaining); -\endcode - -The function nlmsg_next() will automatically substract the size of -the previous message from the remaining number of bytes. - -Please note, there is no indication in the previous message whether -another message follows or not. You must assume that more messages -follow until all bytes of the message stream have been processed. - -To simplify this, the function nlmsg_ok() exists which returns true if -another message fits into the remaining number of bytes in the message -stream. nlmsg_valid_hdr() is similar, it checks whether a specific -netlink message contains at least a minimum of payload. - -\code -#include <netlink/msg.h> - -int nlmsg_valid_hdr(const struct nlmsghdr *hdr, int payloadlen); -int nlmsg_ok(const struct nlmsghdr *hdr, int remaining); -\endcode - -A typical use of these functions looks like this: - -\include my_parse.c - -\b Note: nlmsg_ok() only returns true if the \b complete message including - the message payload fits into the remaining buffer length. It will - return false if only a part of it fits. - -The above can also be written using the iterator nlmsg_for_each(): - -\include nlmsg_for_each.c - - -\subsubsection core_msg_payload 4.2.2 Message Payload - -The message payload is appended to the message header and is guranteed -to start at a multiple of NLMSG_ALIGNTO. Padding at the end of the -message header is added if necessary to ensure this. The function -nlmsg_data() will calculate the necessary offset based on the message -and returns a pointer to the start of the message payload. - -\code -#include <netlink/msg.h> - -void *nlmsg_data(const struct nlmsghdr *nlh); -void *nlmsg_tail(const struct nlmsghdr *nlh); -int nlmsg_datalen(const struct nlmsghdr *nlh); -\endcode - -The length of the message payload is returned by nlmsg_datalen(). - -\code - <--- nlmsg_datalen(nlh) ---> - +-------------------+- - -+----------------------------+- - -+ - | struct nlmsghdr | Pad | Payload | Pad | - +-------------------+- - -+----------------------------+- - -+ -nlmsg_data(nlh) ---------------^ ^ -nlmsg_tail(nlh) --------------------------------------------------^ -\endcode - -The payload may consist of arbitary data but may have strict alignment -and formatting rules depening on the actual netlink protocol. - -\subsubsection core_msg_parse_attr 4.2.3 Message Attributes - -Most netlink protocols use netlink attributes. It not only makes the -protocol self documenting but also gives flexibility in expanding -the protocol at a later point. New attributes can be added at any time -and older attributes can be obsoleted by newer ones without breaking -binary compatibility of the protocol. - -\code - <---------------------- payload -------------------------> - <----- hdrlen ----> <- nlmsg_attrlen(nlh, hdrlen) -> - +-------------------+- - -+----- ------------+- - -+--------------------------------+- - -+ - | struct nlmsghdr | Pad | Protocol Header | Pad | Attributes | Pad | - +-------------------+- - -+-------------------+- - -+--------------------------------+- - -+ -nlmsg_attrdata(nlh, hdrlen) -----------------------------^ -\endcode - -The function nlmsg_attrdata() returns a pointer to the begin of the -attributes section. The length of the attributes section is returned -by the function nlmsg_attrlen(). - -\code -#include <netlink/msg.h> - -struct nlattr *nlmsg_attrdata(const struct nlmsghdr *hdr, int hdrlen); -int nlmsg_attrlen(const struct nlmsghdr *hdr, int hdrlen); -\endcode - -See \ref core_attr for more information on how to use netlink attributes. - -\subsubsection core_nlmsg_parse 4.2.4 Parsing a Message the Easy Way - -The function nlmsg_parse() validate a complete netlink message in -one step. If \p 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 \ref core_attr_nla_parse. - -\code -int nlmsg_parse(struct nlmsghdr *hdr, int hdrlen, struct nlattr **attrs, - int maxtype, struct nla_policy *policy); -\endcode - -The function nlmsg_validate() is based on nla_validate() and behaves -exactly the same as nlmsg_parse() except that it only validates and will -not fill a array with pointers to each attribute. - -\code -int nlmsg_validate(struct nlmsghdr *hdr, int hdrlen, intmaxtype, - struct nla_policy *policy); -\endcode - -See \ref core_attr_nla_parse for an example and more information on -attribute parsing. - -\subsection core_msg_constr 4.3 Construction of a Message - -See \ref 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 \b does \b not -point to the netlink message header. Use nlmsg_hdr() to retrieve a -pointer to the netlink message header. - -At allocation time, a maximum message size is specified. It defaults to -a page (PAGE_SIZE). The application constructing the message will reserve -space out of this maximum message size repeatedly for each header or -attribute added. This allows construction of messages across various -layers of code where lower layers do not need to know about the space -requirements of upper layers. - -<b>Why is setting the maximum message size necessary?</b> This question -is often raised in combination with the proposed solution of reallocating -the message payload buffer on the fly using realloc(). While it is -possible to reallocate the buffer during construction using nlmsg_expand() -it will make all pointers into the message buffer become stale. This -breaks usage of nlmsg_hdr(), nla_nest_start(), and nla_nest_end() and is -therefore not acceptable as default behaviour. - -\subsubsection core_msg_alloc 4.3.1 Allocating struct nl_msg - -The first step in constructing a new netlink message it to allocate a -\c struct \c nl_msg to hold the message header and payload. Several -functions exist to simplify various tasks. - -\code -#include <netlink/msg.h> - -struct nl_msg *nlmsg_alloc(void); -void nlmsg_free(struct nl_msg *msg); -\endcode - -The function nlmsg_alloc() is the default message allocation function. -It allocates a new message using the default maximum message size which -equals to one page (PAGE_SIZE). The application can change the default -size for messages by calling nlmsg_set_default_size(): - -\code -void nlmsg_set_default_size(size_t); -\endcode - -\b Note: Calling nlmsg_set_default_size() does not change the maximum - message size of already allocated messages. - -\code -struct nl_msg *nlmsg_alloc_size(size_t max); -\endcode - -Instead of changing the default message size, the function -nlmsg_alloc_size() can be used to allocate a message with a individual -maximum message size. - - -If the netlink message header is already known at allocation time, the -application may sue nlmsg_inherit(). It will allocate a message using -the default maximum message size and copy the header into the message. -Calling nlmsg_inherit with \p set to NULL is equivalent to calling -nlmsg_alloc(). - -\code -struct nl_msg *nlmsg_inherit(struct nlmsghdr *hdr); -\endcode - -Alternatively nlmsg_alloc_simple() takes a netlink message type and -netlink message flags. It is equivalent to nlmsg_inherit() except that it -takes the two common header fields as arguments instead of a complete -header. - -\code -#include <netlink/msg.h> - -struct nl_msg *nlmsg_alloc_simple(int nlmsg_type, int flags); -\endcode - -\subsubsection core_msg_nlmsg_put 4.3.2 Appending the netlink message header - -After allocating struct nl_msg, the netlink message header needs to be -added unless one of the function nlmsg_alloc_simple() or nlmsg_inherit() -have been used for allocation in which case this step will replace the -netlink message header already in place. - -\code -#include <netlink/msg.h> - -struct nlmsghdr *nlmsg_put(struct nl_msg *msg, uint32_t port, uint32_t seqnr, - int nlmsg_type, int payload, int nlmsg_flags); -\endcode - -The function nlmsg_put() will build a netlink message header out of -\p nlmsg_type, \p nlmsg_flags, \p seqnr, and \p port and copy it into -the netlink message. \p seqnr can be set to \p NL_AUTO_SEQ to indiciate -that the next possible sequence number should be used automatically. To -use this feature, the message must be sent using the function -nl_send_auto(). Like \p port, the argument \p seqnr can be set to -\c 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 \ref proto_fund for more information on -how to fill the header. - -The argument \p 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 -\ref core_msg_reserve for more information on reserving room for data. - -\b Example: -\include nlmsg_put.c - -\subsubsection core_msg_reserve 4.3.3 Reserving room at the end of the message - -Most functions described later on will automatically take care of -reserving room for the data that is added to the end of the netlink -message. In some situations it may be requried for the application -to reserve room directly though. - -\code -#include <netlink/msg.h> - -void *nlmsg_reserve(struct nl_msg *msg, size_t len, int pad); -\endcode - -The function nlmsg_reserve() reserves \p len bytes at the end of the -netlink message and returns a pointer to the start of the reserved area. -The \p pad argument can be used to request \p len to be aligned to any -number of bytes prior to reservation. - -The following example requests to reserve a 17 bytes area at the end of -message aligned to 4 bytes. Therefore a total of 20 bytes will be -reserved. - -\code -#include <netlink/msg.h> - -void *buf = nlmsg_reserve(msg, 17, 4); -\endcode - -\b Note: nlmsg_reserve() will \b not align the start of the buffer. Any - alignment requirements must be provided by the owner of the - previous message section. - -\subsubsection core_msg_append 4.3.4 Appending data at the end of the message - -The function nlmsg_append() appends \p len bytes at the end of the message, -padding it if requested and necessary. - -\code -#include <netlink/msg.h> - -int nlmsg_append(struct nl_msg *msg, void *data, size_t len, int pad); -\endcode - -It is equivalent to calling nlmsg_reserve() and memcpy()ing the data into -the freshly reserved data section. - -\b Note: nlmsg_append() will \b not align the start of the data. Any - alignment requirements must be provided by the owner of the - previous message section. - -\subsubsection core_msg_put_attr 4.3.5 Adding attribtues to a message - -Construction of attributes and addition of attribtues to the message is -covereted in section \ref core_attr. - -\section core_attr 5. Netlink Attributes - -Any form of payload should be encoded as netlink attributes whenever -possible. Use of attributes allows to extend any netlink protocol in -the future without breaking binary compatibility. F.e. Suppose your -device may currently be using 32 bit counters for statistics but years -later the device switches to maintaining 64 bit counters to account -for faster network hardware. If your protocol is using attributes the -move to 64 bit counters is trivial and only involves in sending an -additional attribute containing the 64 bit variants while still -providing the old legacy 32 bit counters. If your protocol is not using -attributes you will not be able to switch data types without breaking -all existing users of the protocol. - -The concept of nested attributes also allows for subsystems of your -protocol to implement and maintain their own attribute schemas. Suppose -a new generation of network device is introduced which requires a -completely new set of configuration settings which was unthinkable when -the netlink protocol was initially designed. Using attributes the new -generation of devices may define a new attribute and fill it with its -own new structure of attributes which extend or even obsolete the old -attributes. - -Therefore, \e always use attributes even if you are almost certain that -the message format will never ever change in the future. - -\subsection core_attr_format 5.1 Attribute Format - -Netlink attributes allow for any number of data chunks of arbitary -length to be attached to a netlink message. See \ref core_msg_parse_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: - -\code - <----------- nla_total_size(payload) -----------> - <---------- nla_size(payload) -----------> - +-----------------+- - -+- - - - - - - - - +- - -+-----------------+- - - - | struct nlattr | Pad | Payload | Pad | struct nlattr | - +-----------------+- - -+- - - - - - - - - +- - -+-----------------+- - - - <---- NLA_HDRLEN -----> <--- NLA_ALIGN(len) ---> <---- NLA_HDRLEN --- -\endcode - -Every attribute must start at an offset which is a multiple of -\c NLA_ALIGNTO (4 bytes). If you need to know whether an attribute needs -to be padded at the end, the function nla_padlen() returns the number -of padding bytes that will or need to be added. - -\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 | -+------------------------------+------------------------------+ -| Attribute Payload | -. . -. . -+-------------------------------------------------------------+ -\endcode - -Every attribute is encoded with a type and length field, both 16 bits, -stored in the attribute header (struct nlattr) preceding the attribute -payload. The length of an attribute is used to calculate the offset to -the next attribute. - -\subsection core_attr_parse 5.2 Parsing Attributes - -\subsubsection core_attr_parse_split 5.2.1 Splitting an Attributes Stream into Attributes - -Although most applications will use one of the functions from the -nlmsg_parse() family (See \ref core_attr_nla_parse) an interface -exists to split the attributes stream manually. - -As described in \ref core_attr_format the attributes section contains a -infinite sequence or stream of attributes. The pointer returned by -nlmsg_attrdata() (See \ref core_msg_parse_attr) points to the first -attribute header. Any subsequent attribute is accessed with the function -nla_next() based on the previous header. - -\code -#include <netlink/attr.h> - -struct nlattr *nla_next(const struct nlattr *attr, int *remaining); -\endcode - -The semantics are equivalent to nlmsg_next() and thus nla_next() will also -subtract the size of the previous attribute from the remaining number of -bytes in the attributes stream. - -Like messages, attributes do not contain an indicator whether another -attribute follows or not. The only indication is the number of bytes left -in the attribute stream. The function nla_ok() exists to determine whether -another attribute fits into the remaining number of bytes or not. - -\code -#include <netlink/attr.h> - -int nla_ok(const struct nlattr *attr, int remaining); -\endcode - -A typical use of nla_ok() and nla_next() looks like this: - -\include nla_ok.c - -\b Note: nla_ok() only returns true if the \b complete attributes - including the attribute payload fits into the remaining number - of bytes. - -\subsubsection core_attr_payload 5.2.2 Accessing Attribute Header and Payload - -Once the individual attributes have been sorted out by either splitting -the attributes stream or using another interface the attribute header -and payload can be accessed. - -\code - <- nla_len(hdr) -> - +-----------------+- - -+- - - - - - - - - +- - -+ - | struct nlattr | Pad | Payload | Pad | - +-----------------+- - -+- - - - - - - - - +- - -+ -nla_data(hdr) ---------------^ -\endcode - -The functions nla_len() and nla_type() can be used to access the attribute -header. nla_len() will return the length of the payload not including -eventual padding bytes. nla_type returns the attribute type. - -\code -#include <netlink/attr.h> - -int nla_len(const struct nlattr *hdr); -int nla_type(const struct nlattr *hdr); -\endcode - -The function nla_data() will return a pointer to the attribute payload. -Please note that due to NLA_ALIGNTO being 4 bytes it may not be safe to -cast and dereference the pointer for any datatype larger than 32 bit -depending on the architecture the application is run on. - -\code -#include <netlink/attr.h> - -void *nla_data(const struct nlattr *hdr); -\endcode - -\b Note: Never rely on the size of a payload being what you expect it to - be. \e Always verify the payload size and make sure that it - matches your expectations. See \ref core_attr_validation. - -\subsubsection core_attr_validation 5.2.3 Attribute Validation - -When receiving netlink attributes, the receiver has certain expections -on how the attributes should look like. These expectations must be -defined to make sure the sending side meets our expecations. For this -purpose, a attribute validation interface exists which must be used -prior to accessing any payload. - -All functions providing attribute validation functionality are based -on struct nla_policy: - -\code -struct nla_policy { - uint16_t type; - uint16_t minlen; - uint16_t maxlen; -}; -\endcode - -The \p type member specifies the datatype of the attribute, e.g. -NLA_U32, NLA_STRING, NLA_FLAG. The default is NLA_UNSPEC. The \p minlen -member defines the minmum payload length of an attribute to be -considered a valid attribute. The value for \p minlen is implicit for -most basic datatypes such as integers or flags. The \p maxlen member -can be used to define a maximum payload length for an attribute to -still be considered valid. - -\b Note: Specyfing a maximum payload length is not recommended when -encoding structures in an attribute as it will prevent any extension of -the structure in the future. Something that is frequently done in -netlink protocols and does not break backwards compatibility. - -One of the functions which use struct nla_policy is nla_validate(). -The function expects an array of struct nla_policy and will access the -array using the attribute type as index. If an attribute type is out -of bounds the attribute is assumed to be valid. This is intentional -behaviour to allow older applications not yet aware of recently -introduced attributes to continue functioning. - -\code -#include <netlink/attr.h> - -int nla_validate(struct nlattr *head, int len, int maxtype, - struct nla_policy *policy); -\endcode - -The function nla_validate() returns 0 if all attributes are valid, -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 -\ref core_attr_nla_parse for an example and more information. - -The validation process in detail: --# If attribute type is 0 or exceeds \p maxtype attribute is - considered valid, 0 is returned. --# If payload length is < \p minlen, -NLE_ERANGE is returned. --# If \p maxlen is defined and payload exceeds it, NLE_ERANGE - is returned. --# Datatype specific requirements rules, see \ref core_attr_data_type. --# If all is ok, 0 is returned. - -\subsubsection core_attr_nla_parse 5.2.4 Parsing Attributes the Easy Way - -Most applications will not want to deal with splitting attribute streams -themselves as described in \ref core_attr_parse_split. A much easier -method is to use nla_parse(). - -\code -#include <netlink/attr.h> - -int nla_parse(struct nlattr **attrs, int maxtype, struct nlattr *head, - int len, struct nla_policy *policy); -\endcode - -The function nla_parse() will iterate over a stream of attributes, -validate each attribute as described in \ref core_attr_validation. If -the validation of all attributes succeeds, a pointer to each attribute -is stored in the \p attrs array at \c 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 -\ref core_nlmsg_parse for information on how to use these functions. - -\b Example: - -The following example demonstrates how to parse a netlink message sent -over a netlink protocol which does not use protocol headers. The example -does enforce a attribute policy however, the attribute MY_ATTR_FOO must -be a 32 bit integer, and the attribute MY_ATTR_BAR must be a string with -a maximum length of 16 characters. - -\include nlmsg_parse.c - -\subsubsection core_attr_find 5.2.5 Locating a Single Attribute - -An application only interested in a single attribute can use one of the -functions nla_find() or nlmsg_find_attr(). These function will iterate -over all attributes, search for a matching attribute and return a pointer -to the corresponding attribute header. - -\code -#include <netlink/attr.h> - -struct nlattr *nla_find(struct nlattr *head, int len, int attrtype); -\endcode - -\code -#include <netlink/msg.h> - -struct nlattr *nlmsg_find_attr(struct nlmsghdr *hdr, int hdrlen, int attrtype); -\endcode - -\b Note: nla_find() and nlmsg_find_attr() will \b not search in nested - attributes recursively, see \ref core_attr_nested. - -\subsubsection core_attr_iterate 5.2.6 Iterating over a Stream of Attributes - -In some situations it does not make sense to assign a unique attribute -type to each attribute in the attribute stream. For example a list may -be transferd using a stream of attributes and even if the attribute type -is incremented for each attribute it may not make sense to use the -nlmsg_parse() or nla_parse() function to fill an array. - -Therefore methods exist to iterate over a stream of attributes: - -\code -#include <netlink/attr.h> - -nla_for_each_attr(attr, head, len, remaining) -\endcode - -nla_for_each_attr() is a macro which can be used in front of a code -block: - -\include nla_for_each_attr.c - -\subsection core_attr_constr 5.3 Attribute Construction - -The interface to add attributes to a netlink message is based on the -regular message construction interface. It assumes that the message -header and an eventual protocol header has been added to the message -already. - -\code -struct nlattr *nla_reserve(struct nl_msg *msg, int attrtype, int len); -\endcode - -The function nla_reserve() adds an attribute header at the end of the -message and reserves room for \p len bytes of payload. The function -returns a pointer to the attribute payload section inside the message. -Padding is added at the end of the attribute to ensure the next -attribute is properly aligned. - -\code -int nla_put(struct nl_msg *msg, int attrtype, int attrlen, const void *data); -\endcode - -The function nla_put() is base don nla_reserve() but takes an additional -pointer \p data pointing to a buffer containing the attribute payload. -It will copy the buffer into the message automatically. - -\b Example: - -\include nla_put.c - -See \ref core_attr_data_type for datatype specific attribute construction -functions. - -\subsubsection core_attr_exception 5.3.1 Exception Based Attribute Construction - -Like in the kernel API an exception based construction interface is -provided. The behaviour of the macros is identical to their regular -function counterparts except that in case of an error, the target -\c nla_put_failure is jumped. - -\b Example: - -\include NLA_PUT.c - -See \ref core_attr_data_type for more information on the datatype -specific exception based variants. - -\subsection core_attr_data_type 5.4 Attribute Data Types - -A number of basic data types have been defined to simplify access and -validation of attributes. The datatype is not encoded in the attribute, -therefore bthe sender and receiver are required to use the same -definition on what attribute is of what type. - -Besides simplified access to the payload of such datatypes, the major -advantage is the automatic validation of each attribute based on a -policy. The validation ensures safe access to the payload by checking -for minimal payload size and can also be used to enforce maximum -payload size for some datatypes. - -\subsubsection core_attr_int 5.4.1 Integer Attributes - -The most frequently used datatypes are integers. Integers come in four -different sizes: -- \c NLA_U8 - 8bit integer -- \c NLA_U16 - 16bit integer -- \c NLA_U32 - 32bit integer -- \c NLA_U64 - 64bit integer - -Note that due to the alignment requirements of attributes the integer -attribtue \c NLA_u8 and \c NLA_U16 will not result in space savings in -the netlink message. Their use is intended to limit the range of values. - -<b>Parsing Integer Attributes</b> - -\code -#include <netlink/attr.h> - -uint8_t nla_get_u8(struct nlattr *hdr); -uint16_t nla_get_u16(struct nlattr *hdr); -uint32_t nla_get_u32(struct nlattr *hdr); -uint64_t nla_get_u64(struct nlattr *hdr); -\endcode - -Example: - -\code -if (attrs[MY_ATTR_FOO]) - uint32_t val = nla_get_u32(attrs[MY_ATTR_FOO]); -\endcode - -<b>Constructing Integer Attributes</b> - -\code -#include <netlink/attr.h> - -int nla_put_u8(struct nl_msg *msg, int attrtype, uint8_t value); -int nla_put_u16(struct nl_msg *msg, int attrtype, uint16_t value); -int nla_put_u32(struct nl_msg *msg, int attrtype, uint32_t value); -int nla_put_u64(struct nl_msg *msg, int attrtype, uint64_t value); -\endcode - -Exception based: - -\code -NLA_PUT_U8(msg, attrtype, value) -NLA_PUT_U16(msg, attrtype, value) -NLA_PUT_U32(msg, attrtype, value) -NLA_PUT_U64(msg, attrtype, value) -\endcode - -<b>Validation</b> - -Use \p NLA_U8, \p NLA_U16, \p NLA_U32, or \p NLA_U64 to define the type -of integer when filling out a struct nla_policy array. It will -automatically enforce the correct minimum payload length policy. - -Validation does not differ between signed and unsigned integers, only -the size matters. If the appliaction wishes to enforce particular value -ranges it must do so itself. - -\code -static struct nla_policy my_policy[ATTR_MAX+1] = { - [ATTR_FOO] = { .type = NLA_U32 }, - [ATTR_BAR] = { .type = NLA_U8 }, -}; -\endcode - -The above is equivalent to: -\code -static struct nla_policy my_policy[ATTR_MAX+1] = { - [ATTR_FOO] = { .minlen = sizeof(uint32_t) }, - [ATTR_BAR] = { .minlen = sizeof(uint8_t) }, -}; -\endcode - -\subsubsection core_attr_string 5.4.2 String Attributes - -The string datatype represents a NUL termianted character string of -variable length. It is not intended for binary data streams. - -The payload of string attributes can be accessed with the function -nla_get_string(). nla_strdup() calls strdup() on the payload and returns -the newly allocated string. - -\code -#include <netlink/attr.h> - -char *nla_get_string(struct nlattr *hdr); -char *nla_strdup(struct nlattr *hdr); -\endcode - -String attributes are constructed with the function nla_put_string() -respectively NLA_PUT_STRING(). The length of the payload will be strlen()+1, -the trailing NUL byte is included. - -\code -int nla_put_string(struct nl_msg *msg, int attrtype, const char *data); - -NLA_PUT_STRING(msg, attrtype, data) -\endcode - -For validation purposes the type \p NLA_STRING can be used in -struct nla_policy definitions. It implies a minimum payload length of 1 -byte and checks for a trailing NUL byte. Optionally the \p maxlen member -defines the maximum length of a character string (including the trailing -NUL byte). - -\code -static struct nla_policy my_policy[] = { - [ATTR_FOO] = { .type = NLA_STRING, - .maxlen = IFNAMSIZ }, -}; -\endcode - -\subsubsection core_attr_flag 5.4.3 Flag Attributes - -The flag attribute represents a boolean datatype. The presence of the -attribute implies a value of \p true, the absence of the attribute -implies the value \p false. Therefore the payload length of flag -attributes is always 0. - -\code -int nla_get_flag(struct nlattr *hdr); -int nla_put_flag(struct nl_msg *msg, int attrtype); -\endcode - -The type \p NLA_FLAG is used for validation purposes. It implies a -\p maxlen value of 0 and thus enforces a maximum payload length of 0. - -\b Example: - -\include nla_flag.c - -\subsubsection core_attr_nested 5.4.4 Nested Attributes - -As described in \ref 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. - -<b>IMPORTANT NOTICE:</b> When validating the attributes using -nlmsg_validate(), nlmsg_parse(), nla_validate(), or nla_parse() only -the attributes on the first level are being validated. None of these -functions will validate attributes recursively. Therefore you must -explicitely call nla_validate() or use nla_parse_nested() for each -level of nested attributes. - -The type \p NLA_NESTED should be used when defining nested attributes -in a struct nla_policy definition. It will not enforce any minimum -payload length unless \p minlen is specified explicitely. This is -because some netlink protocols implicitely allow empty container -attributes. - -\code -static struct nla_policy my_policy[] = { - [ATTR_OPTS] = { .type = NLA_NESTED }, -}; -\endcode - -<b>Parsing of Nested Attributes</b> - -The function nla_parse_nested() is used to parse nested attributes. -Its behaviour is identical to nla_parse() except that it takes a -struct nlattr as argument and will use the payload as stream of -attributes. - -\include nla_parse_nested.c - -<b>Construction of Nested Attributes</b> - -Attributes are nested by surrounding them with calls to nla_nest_start() -and nla_nest_end(). nla_nest_start() will add a attribute header to -the message but no actual payload. All data added to the message from -this point on will be part of the container attribute until nla_nest_end() -is called which "closes" the attribute, correcting its payload length to -include all data length. - -\include nla_nest_start.c - -\subsubsection core_attr_unspec 5.4.5 Unspecified Attribute - -This is the default attribute type and used when none of the basic -datatypes is suitable. It represents data of arbitary type and length. - -See \ref core_abstract_addr_alloc for a more information on a special -interface allowing the allocation of abstract address object based on -netlink attributes which carry some form of network address. - -See \ref core_abstract_data_alloc for more information on how to -allocate abstract data objects based on netlink attributes. - -Use the function nla_get() and nla_put() to access the payload and -construct attributes. See \ref core_attr_constr for an example. - -\subsection core_attr_examples 5.5 Examples - -\subsubsection core_attr_example_constr 5.5.1 Constructing a Netlink Message with Attributes - -\include msg_constr_attr.c - -\subsubsection core_attr_example_parse 5.5.2 Parsing a Netlink Message with Attributes - -\include msg_parse_attr.c - -\section core_cb 6. Callback Configurations - -Callback hooks and overwriting capabilities are provided in various places -inside library to control the behaviour of several functions. All the -callback and overwrite functions are packed together in struct nl_cb which -is attached to a netlink socket or passed on to functions directly. - -\subsection core_cb_hooks 6.1 Callback Hooks - -Callback hooks are spread across the library to provide entry points for -message processing and to take action upon certain events. - -Callback functions may return the following return codes: -\code -Return Code | Description -------------------------------------------------------------------------- -NL_OK | Proceed. -NL_SKIP | Skip message currently being processed and continue - | parsing the receive buffer. -NL_STOP | Stop parsing and discard all remaining data in the - | receive buffer. -\endcode - -\subsubsection core_cb_default 6.1.1 Default Callback Implementations - -The library provides three sets of default callback implementations: -- \b NL_CB_DEFAULT This is the default set. It implets the default behaviour. - See the table below for more information on the return codes of each - function. -- \b NL_CB_VERBOSE This set is based on the default set but will cause an - error message to be printed to stderr for error messages, invalid - messages, message overruns and unhandled valid messages. The \p arg - pointer in nl_cb_set() and nl_cb_err() can be used to provide a FILE * - which overwrites stderr. -- \b NL_CB_DEBUG This set is intended for debugging purposes. It is based - on the verbose set but will decode and dump each message sent or - received to the console. - -\subsubsection core_cb_msg_proc 6.1.2 Message Processing Callbacks - -nl_sendmsg() callback hooks: -\code -Callback ID | Description | Default Return Value ------------------------------------------------------------------------------ -NL_CB_MSG_OUT | Each message sent | NL_OK -\endcode - -Any function called by NL_CB_MSG_OUT may return a negative error code to -prevent the message from being sent and the error code being returned. - -nl_recvmsgs() callback hooks (ordered by priority): -\code -Callback ID | Description | Default Return Value ------------------------------------------------------------------------------ -NL_CB_MSG_IN | Each message received | NL_OK -NL_CB_SEQ_CHECK | May overwrite sequence check algo | NL_OK -NL_CB_INVALID | Invalid messages | NL_STOP -NL_CB_SEND_ACK | Messages with NLM_F_ACK flag set | NL_OK -NL_CB_FINISH | Messages of type NLMSG_DONE | NL_STOP -NL_CB_SKIPPED | Messages of type NLMSG_NOOP | NL_SKIP -NL_CB_OVERRUN | Messages of type NLMSG_OVERRUN | NL_STOP -NL_CB_ACK | ACK Messages | NL_STOP -NL_CB_VALID | Each valid message | NL_OK -\endcode - -Any of these functions may return NL_OK, NL_SKIP, or NL_STOP. - -Message processing callback functions are set with nl_cb_set(): -\code -#include <netlink/handlers.h> - -int nl_cb_set(struct nl_cb *cb, enum nl_cb_type type, enum nl_cb_kind kind, - nl_recvmsg_msg_cb_t func, void *cb); - -typedef int (*nl_recvmsg_msg_cb_t)(struct nl_msg *msg, void *arg); -\endcode - -\subsubsection core_cb_errmsg 6.1.4 Callback for Error Messages - -A special function prototype is used for the error message callback hook: - -\code -#include <netlink/handlers.h> - -int nl_cb_err(struct nl_cb *cb, enum nl_cb_kind kind, nl_recvmsg_err_cb_t func, void * arg); - -typedef int(* nl_recvmsg_err_cb_t)(struct sockaddr_nl *nla, struct nlmsgerr *nlerr, void *arg); -\endcode - -\subsubsection core_cb_example 6.1.4 Example: Setting up a callback set -\include nl_cb_set.c - -\subsection core_cb_overwrite 6.2 Overwriting of Internal Functions - -When the library needs to send or receive netlink messages in high level -interfaces it does so by calling its own low level API. In the case the -default characteristics are not sufficient for the application, it may -overwrite several internal function calls with own implementations. - -\subsubsection core_cb_ow_recvmsgs 6.2.1 Overwriting recvmsgs() - -See \ref core_recv for more information on how and when recvmsgs() is -called internally. - -\code -#include <netlink/handlers.h> - -void nl_cb_overwrite_recvmsgs(struct nl_cb *cb, - int (*func)(struct nl_sock *sk, struct nl_cb *cb)); -\endcode - -The following criteras must be met if a recvmsgs() implementation is -supposed to work with high level interfaces: -- MUST respect the callback configuration in \c cb, therefore: - - MUST call NL_CB_VALID for all valid messages, passing on - - MUST call NL_CB_ACK for all ACK messages - - MUST correctly handle multipart messages, calling NL_CB_VALID for - each message until a NLMSG_DONE message is received. -- MUST report error code if a NLMSG_ERROR or NLMSG_OVERRUN mesasge is - received. - -\subsubsection core_cb_ow_recv 6.2.2 Overwriting nl_recv() - -Often it is sufficient to overwrite nl_recv() which is responsible from -receiving the actual data from the socket instead of replacing the complete -recvmsgs() logic. - -See \ref core_recvmsgs for more information on how and when nl_recv() -is called internally. - -\code -#include <netlink/handlers.h> - -void nl_cb_overwrite_recv(struct nl_cb *cb, - int (*func)(struct nl_sock * sk, - struct sockaddr_nl *addr, - unsigned char **buf, - struct ucred **cred)); -\endcode - -The following criteras must be met for an own nl_recv() implementation: -- MUST return the number of bytes read or a negative error code if an - error occured. The function may also return 0 to indicate that no - data has been read. -- MUST set \c *buf to a buffer containing the data read. It must be safe - for the caller to access the number of bytes read returned as return code. -- MAY fill out \c *addr with the netlink address of the peer the data - has been received from. -- MAY set \c *cred to a newly allocated struct ucred containg credentials. - -\subsubsection core_cb_ow_send 6.2.3 Overwriting nl_send() - -See \ref core_send for more information on how and when nl_send() is -called internally. - -\code -#include <netlink/handlers.h> - -void nl_cb_overwrite_send(struct nl_cb *cb, int (*func)(struct nl_sock *sk, - struct nl_msg *msg)); -\endcode - -Own implementations must send the netlink message and return 0 on success -or a negative error code. - -\section core_cache 7. Cache System - -\subsection cache_alloc 7.1 Allocation of Caches - -Almost all subsystem provide a function to allocate a new cache -of some form. The function usually looks like this: -\code -struct nl_cache *<object name>_alloc_cache(struct nl_sock *sk); -\endcode - -These functions allocate a new cache for the own object type, -initializes it properly and updates it to represent the current -state of their master, e.g. a link cache would include all -links currently configured in the kernel. - -Some of the allocation functions may take additional arguments -to further specify what will be part of the cache. - -All such functions return a newly allocated cache or NULL -in case of an error. - -\section core_abstract_types 8. Abstract Data Types - -A few high level abstract data types which are used by a majority netlink -protocols are implemented in the core library. More may be added in the -future if the need arises. - -\subsection core_abstract_addr 8.1 Abstract Address - -Most netlink protocols deal with networking related topics and thus -dealing with network addresses is a common task. - -Currently the following address families are supported: -- AF_INET -- AF_INET6 -- AF_LLC -- AF_DECnet -- AF_UNSPEC - -\subsubsection core_abstract_addr_alloc 8.1.1 Address Allocation - -The function nl_addr_alloc() allocates a new empty address. The -\p maxsize argument defines the maximum length of an address in bytes. -The size of an address is address family specific. If the address -family and address data are known at allocation time the function -nl_addr_build() can be used alternatively. You may also clone -an address by calling nl_addr_clone() - -\code -#include <netlink/addr.h> - -struct nl_addr *nl_addr_alloc(size_t maxsize); -struct nl_addr *nl_addr_clone(struct nl_addr *addr); -struct nl_addr *nl_addr_build(int family, void *addr, size_t size); -\endcode - -If the address is transported in a netlink attribute, the function -nl_addr_alloc_attr() allocates a new address based on the payload -of the attribute provided. The \p family argument is used to specify -the address family of the address, set to \p AF_UNSPEC if unknown. - -\code -#include <netlink/addr.h> - -struct nl_addr *nl_addr_alloc_attr(struct nlattr *attr, int family); -\endcode - -If the address is provided by a user, it is usually stored in a human -readable format. The function nl_addr_parse() parses a character -string representing an address and allocates a new address based on -it. - -\code -#include <netlink/addr.h> - -int nl_addr_parse(const char *addr, int hint, struct nl_addr **result); -\endcode - -If parsing succeeds the function returns 0 and the allocated address -is stored in \p *result. - -\b Note: Make sure to return the reference to an address using - nl_addr_put() after usage to allow memory being freed. - -\subsubsection core_abstract_addr_ref 8.1.2 Address References - -Abstract addresses use reference counting to account for all users of -a particular address. After the last user has returned the reference -the address is freed. - -If you pass on a address object to another function and you are not -sure how long it will be used, make sure to call nl_addr_get() to -acquire an additional reference and have that function or code path -call nl_addr_put() as soon as it has finished using the address. - -\code -#include <netlink/addr.h> - -struct nl_addr *nl_addr_get(struct nl_addr *addr); -void nl_addr_put(struct nl_addr *addr); -int nl_addr_shared(struct nl_addr *addr); -\endcode - -You may call nl_addr_shared() at any time to check if you are the only -user of an address. - -\subsubsection core_abstract_addr_attr 8.1.3 Address Attributes - -The address is usually set at allocation time. If it was unknown at that -time it can be specified later by calling nl_addr_set_family() and is -accessed with the function nl_addr_get_family(). - -\code -#include <netlink/addr.h> - -void nl_addr_set_family(struct nl_addr *addr, int family); -int nl_addr_get_family(struct nl_addr *addr); -\endcode - -The same is true for the actual address data. It is typically present -at allocation time. For exceptions it can be specified later or -overwritten with the function nl_addr_set_binary_addr(). Beware that -the length of the address may not exceed \p maxlen specified at -allocation time. The address data is returned by the function -nl_addr_get_binary_addr() and its length by the function -nl_addr_get_len(). - -\code -#include <netlink/addr.h> - -int nl_addr_set_binary_addr(struct nl_addr *addr, void *data, size_t size); -void *nl_addr_get_binary_addr(struct nl_addr *addr); -unsigned int nl_addr_get_len(struct nl_addr *addr); -\endcode - -If you only want to check if the address data consists of all zeros -the function nl_addr_iszero() is a shortcut to that. - -\code -#include <netlink/addr.h> - -int nl_addr_iszero(struct nl_addr *addr); -\endcode - -\subsubsection core_abstract_addr_prefix 8.1.4 Address Prefix Length - -Although this functionality is somewhat specific to routing it has -been implemented here. Addresses can have a prefix length assigned -which implies that only the first n bits are of importance. This -is f.e. used to implement subnets. - -Use set functions nl_addr_set_prefixlen() and nl_addr_get_prefixlen() -to work with prefix lengths. - -\code -#include <netlink/addr.h> - -void nl_addr_set_prefixlen(struct nl_addr *addr, int n); -unsigned int nl_addr_get_prefixlen(struct nl_addr *addr); -\endcode - -\b Note: The default prefix length is set to (address length * 8) - -\subsubsection core_abstract_addr_helpers 8.1.5 Address Helpers - -Several functions exist to help when dealing with addresses. The -function nl_addr_cmp() compares two addresses and returns an integer -less than, equal to or greater than zero without considering the prefix -length at all. If you want to consider the prefix length, use the -function nl_addr_cmp_prefix(). - -\code -#include <netlink/addr.h> - -int nl_addr_cmp(struct nl_addr *addr, struct nl_addr *addr); -int nl_addr_cmp_prefix(struct nl_addr *addr, struct nl_addr *addr); -\endcode - -If an abstract address needs to presented to the user it should be done -in a human readable format which differs depending on the address -family. The function nl_addr2str() takes care of this by calling the -appropriate conversion functions internaly. It expects a \p buf of -length \p size to write the character string into and returns a pointer -to \p buf for easy printf() usage. - -\code -#include <netlink/addr.h> - -char *nl_addr2str(struct nl_addr *addr, char *buf, size_t size); -\endcode - -If the address family is unknown, the address data will be printed in -hexadecimal format AA:BB:CC:DD:... - -Often the only way to figure out the address family is by looking at -the length of the address. The function nl_addr_guess_family() does just -this and returns the address family guessed based on the address size. - -\code -#include <netlink/addr.h> - -int nl_addr_guess_family(struct nl_addr *addr); -\endcode - -Before allocating an address you may want to check if the character -string actually represents a valid address of the address family you are -expecting. The function nl_addr_valid() can be used for that, it returns -1 if the supplised \p addr is a valid address in the context of \p family. -See inet_pton(3), dnet_pton(3) for more information on valid adddress -formats. - -\code -#include <netlink/addr.h> - -int nl_addr_valid(char *addr, int family); -\endcode - -\subsection core_abstract_data 8.2 Abstract Data - -The abstract data type is a trivial datatype with the primary purpose -to simplify usage of netlink attributes of arbitary length. - -\subsubsection core_abstract_data_alloc 8.2.1 Allocation of a Data Object - -The function nl_data_alloc() alloctes a new abstract data object and -fill it with the provided data. nl_data_alloc_attr() does the same but -bases the data on the payload of a netlink attribute. New data objects -can also be allocated by cloning existing ones by using nl_data_clone(). - -\code -struct nl_data *nl_data_alloc(void *buf, size_t size); -struct nl_data *nl_data_alloc_attr(struct nlattr *attr); -struct nl_data *nl_data_clone(struct nl_data *data); -void nl_data_free(struct nl_data *data); -\endcode - -\subsubsection core_abstract_data_access 8.2.2 Access to Data - -The function nl_data_get() returns a pointer to the data, the size of -data is returned by nl_data_get_size(). - -\code -void *nl_data_get(struct nl_data *data); -size_t nl_data_get_size(struct nl_data *data); -\endcode - -\subsubsection core_abstract_data_helpers 8.2.3 Data Helpers - -The function nl_data_append() reallocates the internal data buffers and -appends the specified \p buf to the existing data. - -\code -int nl_data_append(struct nl_data *data, void *buf, size_t size); -\endcode - -\b Note: Call nl_data_append() invalidates all pointers returned by - nl_data_get(). - -\code -int nl_data_cmp(struct nl_data *data, struct nl_data *data); -\endcode - -*/ |