struct nlmsghdr {

_u32 nlmsg_len; /* Length of message including header */

_u16 nlmsg_flags; /* Additional flags */

36The protocol family operations netlink_family_ops point to this function. Recall from Section 12.10.4 that the creation function is automatically called when a new socket is created.

37The kernel offers the standard data structure struct nlattr if netlink is used to transport attributes. This possibility is not discussed in detail, but note that all attribute definitions and a useful set of auxiliary helper functions can be found in include/net/netlink.h.

□ The length of the total message — including header and any required padding — is stored in nlmsg_len.

□ The message type is denoted by nlmsg_type. The value is private to the family and not inspected or modified by generic netlink code.

□ Various flags can be stored in nlmsg_flags. All possible values are defined in <netlink.h>. For our purposes, mainly two flags are of relevance: nlm_f_request is set if a message contains a request to perform some specific action (as opposed to transferring just some status information), and nlm_f_ack requests that an acknowledgment is sent on receiving the message and successfully processing the request.

□ nlmsg_seq holds a sequence number that induces a temporal relationship amongst a series of messages.

□ The unique port ID that identifies the sender is stored in nlmsg_pid.

Note that the constituents of netlink messages are always aligned to nlmsg_alignto (usually set to 4) byte boundaries as indicated in the figure. Since the size of struct nlmsghdr is currently a multiple of nlmsg_alignto, the alignment criterion is automatically fulfilled for the header. Padding might, however, be required behind the payload. To ensure that the padding requirements are fulfilled, the kernel introduces several macros in <netlink.h> that can be used to properly compute the boundaries. Since they are well documented in the manual page netlink(3), the information is not repeated here.

The length of a message should fit into a single page because this places only little pressure on memory allocation. However, if pages larger the 8 KiB are used, then the message size should not exceed 8 KiB because userland should not be forced to allocate excessively big buffers to receive netlink messages. The kernel defines the constant nlmsg_goodsize, which contains the preferred amount of total space for a message. nlmsg_default_size specifies how much space is available for the payload without header. When a socket buffer into which a netlink message is constructed is allocated, nlmsg_goodsize is a good choice for its size.

Keeping Track of Netlink Connections

The kernel keeps track of all netlink connections as represented by sock instances using several hash tables. They are implemented around the global array nl_table, which contains pointers to instances of struct netlink_table. The actual definition of this structure does not bother us in detail because the hashing method follows a rather straightforward path:

1. Each array element of nl_table provides a separate hash for each protocol family member. Recall that each family member is identified by one of the constants defined by netlink_xxx, where XXX includes route or kobject_uevent, for instance.

2. The hash chain number is determined using nl_pid_hashfn based on the port ID and a (unique) random number associated with the hash chain.38

38Actually, the situation is more complicated because the kernel rehashes the elements on the hash table when there are too many entries, but this extra complexity is ignored here.

netlink_insert is used to insert new entries into the hash table, while netlink_lookup allows for finding sock instances:

Continue reading here: Netnetlinkafnetlinkc

Was this article helpful?

0 0