Table of Contents
Generic Netlink
Generic Netlink Architecture
Generic Netlink communications are essentially a series of different communication channels which are multiplexed on a single Netlink family.
Communication channels are uniquely identified by channel numbers which are dynamically allocated by the Generic Netlink controller.
The controller is a special Generic Netlink user which listens on a fixed communication channel, number 0x10, which is always present. Kernel or userspace users which provide services over the Generic Netlink bus establish new communication channels by registering their services with the Generic Netlink controller.
Users who want to use a service query the controller to see if the service exists and to determine the correct channel number.
+---------------------+ +---------------------+
| (3) application "A" | | (3) application "B" |
+------+--------------+ +--------------+------+
| |
\ /
\ /
| |
+-------+--------------------------------+-------+
| : : | user-space
=====+ : (5) kernel socket API : +================
| : : | kernel-space
+--------+-------------------------------+-------+
| |
+-----+-------------------------------+----+
| (1) Netlink subsystem |
+---------------------+--------------------+
|
+---------------------+--------------------+
| (2) Generic Netlink bus |
+--+--------------------------+-------+----+
| | |
+-------+---------+ | |
| (4) controller | / \
+-----------------+ / \
| |
+------------------+--+ +--+------------------+
| (3) kernel user "X" | | (3) kernel user "Y" |
+---------------------+ +---------------------+
Data Structure of Generic Netlink
One Family Data structure
--------------------------
-- |Global attribute: attrbuf |
----------------------- --
|
|
|
One Family -- |
|
| -----------------------------------------------
| --| 1st operation: unique command and its policy |
| -----------------------------------------------
------------------------ -----------------------------------------------
-- |operation list:ops_list | --| 2nd operation: unique command and its policy |
------------------------ -----------------------------------------------
-----------------------------------------------
--| nth operation: unique command and its policy |
-----------------------------------------------
Generic Netlink message format
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 (nlmsghdr) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Generic Netlink message header (genlmsghdr) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Optional user specific message header | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Optional Generic Netlink message payload | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Procedure in kernel
Register a family
Generic Netlink families are defined by the genl_family structure, which is shown below:
struct genl_family
{
unsigned int id;
unsigned int hdrsize;
char name[GENL_NAMSIZ];
unsigned int version;
unsigned int maxattr;
struct nlattr ** attrbuf;
struct list_head ops_list;
struct list_head family_list;
};
Fig: The genl_family structure
The genl_family structure fields are used in the following manner:
unsigned int id
This is the dynamically allocated channel number. A value of 0x0 signifies that the channel number should be assigned by the controller and the 0x10 value is reserved for use by the controller. Users should always use GENL_ID_GENERATE macro/constant (value 0x0) when registering a new family.
unsigned int hdrsize
If the family makes use of a family specific header, its size is stored here. If there is no family specific header this value should be zero.
char name[GENL_NAMSIZ]
This string should be unique to the family as it is the key that the controller uses to lookup channel numbers when requested.
unsigned int version
Family specific version number.
unsigned int maxattr
Generic Netlink makes use of the standard Netlink attributes; this value holds the maximum number of attributes defined for the Generic Netlink family.
struct nlattr **attrbuf
This is a private field and should not be modified.
struct list_head ops_list
This is a private field and should not be modified.
struct list_head family_list
This is a private field and should not be modified.
Define operation and policy
Operation
Generic Netlink operations are defined by the genl_ops structure, which is shown below:
struct genl_ops
{
u8 cmd;
unsigned int flags;
struct nla_policy *policy;
int (*doit)(struct sk_buff *skb,
struct genl_info *info);
int (*dumpit)(struct sk_buff *skb,
struct netlink_callback *cb);
struct list_head ops_list;
};
Fig: The genl_ops structure
The genl_ops structure fields are used in the following manner:
u8 cmd
This value is unique across the corresponding Generic Netlink family and is used to reference the operation.
unsigned int flags
This field is used to specify any special attributes of the operation. The following flags may be used (multiple flags can be OR'd together):
GENL_ADMIN_PERM
The operation requires the CAP_NET_ADMIN privilege
struct nla_policy policy
This field defines the Netlink attribute policy for the operation request message. If specified, the Generic Netlink mechanism uses this policy to verify all of the attributes in the operation request message before calling the operation handler.
The attribute policy is defined as an array of nla_policy structures indexed by the attribute number. The nla_policy structure is defined as shown in figure #11.
int (*doit)(struct skbuff *skb, struct genl_info *info)
This callback is similar in use to the standard Netlink doit() callback, the primary difference being the change in parameters.
The doit() handler receives two parameters: the first is the message buffer which triggered the handler and the second is a Generic Netlink genl_info structure which is defined as shown in figure #10.
int (*dumpit)(struct sk_buff *skb, struct netlink_callback *cb)
This callback is similar in use to the standard Netlink dumpit() callback. The dumpit() callback is invoked when the Generic Netlink message is received with the NLM_F_DUMP flag set.
The main difference between the dumpit() handler and the doit() handler is that the dumpit() handler does not allocate a message buffer for a response; a pre-allocated sk_buff is passed to the dumpit() handler as the first parameter. The dumpit() handler should fill the message buffer with the appropriate response message and return the size of the sk_buff, i.e. sk_buff->len, and the message buffer will automatically be sent to the Generic Netlink client that initiated the request. As long as the dumpit() handler returns a value greater than zero it will be called again with a newly allocated message buffer to fill. When the handler has no more data to send it should return zero; error conditions are indicated by returning a negative value. If necessary, state can be preserved in the netlink_callback parameter which is passed to the dumpit() handler; the netlink_callback parameter values will be preserved across handler calls for a single request.
struct list_head ops_list
This is a private field and should not be modified.
Policy
when sending netlink messages the sender needs to adhere to the protocol format. The receiver of the message will use struct nla_policy to validate the attributes before the payload is accessed.
The nla_policy Structure
Generic Netlink attribute policy is defined by the nla_policy structure, which is shown below:
struct nla_policy
{
u16 type;
u16 len;
};
Fig: The nla_policy structure
The fields are used in the following manner:
u16 type
This specifies the type of the attribute; presently the following types are defined for general use:
NLA_UNSPEC
Undefined type
NLA_U8
An 8-bit unsigned integer
NLA_U16
A 16-bit unsigned integer
NLA_U32
A 32-bit unsigned integer
NLA_U64
A 64-bit unsigned integer
NLA_FLAG
A simple boolean flag
NLA_MSECS
A 64-bit time value in msecs
NLA_STRING
A variable length string
NLA_NUL_STRING
A variable length NULL terminated string
NLA_NESTED
A stream of attributes
u16 len
When the attribute type is one of the string types then this field should be set to the maximum length of the string, not including the terminal NULL byte. If the attribute type is unknown or NLA_UNSPEC then this field should be set to the exact length of the attribute's payload.
Unless the attribute type is one of the fixed-length types above, a value of zero indicates that no validation of the attribute should be performed.
Define attribute
Notes: Attributes And Message Payloads
Most common data structures can be represented with Netlink attributes:
scalar values: Most scalar values already have well-defined attribute types; Arrays: Arrays can be represented by using a single nested attribute as a container with several of the same attribute type inside each representing a spot in the array.
It is also important to use unique attributes as much as possible. This helps make the most of the Netlink attribute mechanisms and provides for easy changes to the message format in the future.
Define Message structure
Generic Netlink message information is passed by the genl_info structure, which is shown below:
struct genl_info
{
u32 snd_seq;
u32 snd_pid;
struct nlmsghdr * nlhdr;
struct genlmsghdr * genlhdr;
void * userhdr;
struct nlattr ** attrs;
};
Fig: The genl_info structure
The fields are populated in the following manner:
u32 snd_seq
This is the Netlink sequence number of the request.
u32 snd_pid
This is the Netlink PID of the client which issued the request; it is important to note that the Netlink PID is not the same as the standard kernel PID.
struct nlmsghdr *nlhdr
This is set to point to the Netlink message header of the request.
struct genlmsghdr *genlhdr
This is set to point to the Generic Netlink message header of the request.
void *userhdr
If the Generic Netlink family makes use of a family specific header, this pointer will be set to point to the start of the family specific header.
struct nlattr **attrs
The parsed Netlink attributes from the request; if the Generic Netlink family definition specified a Netlink attribute policy then the attributes would have already been validated.
The doit() handler should do whatever processing is necessary and return zero on success or a negative value on failure. Negative return values will cause an NLMSG_ERROR message to be sent while a zero return value will only cause the NLMSG_ERROR message to be sent if the request is received with the NLM_F_ACK flag set.



