Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 12: Networks


__u32 nlmsg_seq; /* Sequence number */
__u32 nlmsg_pid; /* Sending process port ID */
};

❑ The length of the total message — including header and any required padding — is stored in
nlmsg_len.
❑ The message type is denoted bynlmsg_type. The value is private to the family and not inspected
or modified by generic netlink code.
❑ Various flags can be stored innlmsg_flags. All possible values are defined in<netlink.h>.For
our purposes, mainly two flags are of relevance:NLM_F_REQUESTis set if a message contains a
request to perform some specific action (as opposed to transferring just some status informa-
tion), andNLM_F_ACKrequests that an acknowledgment is sent on receiving the message and
successfully processing the request.
❑ nlmsg_seqholds a sequence number that induces a temporal relationship amongst a series of
messages.
❑ The unique port ID that identifies the sender is stored innlmsg_pid.

Note that the constituents of netlink messages are always aligned toNLMSG_ALIGNTO(usually set to 4)
byte boundaries as indicated in the figure. Since the size ofstruct nlmsghdris currently a multiple of
NLMSG_ALIGNTO, the alignment criterion is automatically fulfilled for the header. Padding might, how-
ever, 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 pagenetlink(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 constantNLMSG_GOODSIZE, which contains the preferred amount of total space for a
message.NLMSG_DEFAULT_SIZEspecifies how much space is available for the payload without header.
When a socket buffer into which a netlink message is constructed is allocated,NLMSG_GOODSIZEis a good
choice for its size.

Keeping Track of Netlink Connections


The kernel keeps track of all netlink connections as represented bysockinstances using several hash
tables. They are implemented around the global arraynl_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 ofnl_tableprovides a separate hash for each protocol family member.
    Recall that each family member is identified by one of the constants defined byNETLINK_XXX,
    whereXXXincludesROUTEorKOBJECT_UEVENT, for instance.

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


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

Free download pdf