Netlink协议的一个缺点是,协议簇数不能超过32(MAX_LINKS)个。这是开发通用Netlink簇的主要原因之一——旨在支持添加更多的协议簇。它就像是Netlink多路复用器,使用单个Netlink协议簇(NETLINK_GENERIC)。通用Netlink协议以Netlink协议为基础,并使用其API。
通用Netlink消息的开头是一个Netlink报头,接下来是通用Netlink消息报头以及可选的用户特定报头,然后才是可选的有效载荷,如下图所示。

struct genlmsghdr {
__u8 cmd;//通用Netlink消息类型。注册的每个通用簇都将添加自己的命令。
__u8 version;//提供版本控制支持。作用:能够在不破坏向后兼容性的情况下修改消息的格式。
__u16 reserved;//保留
};
为通用Netlink消息分配缓冲区的工作由下面的方法完成。sk_buff *genlmsg_new(size_t payload,gfp_t flags),它实际上是一个nlmsg_new()包装器。
使用genlmsg_new()分配缓冲区后,调用genlmsg_put()来创建通用Netlink报头。它是一个genlmsghdr实例。单播通用Netlink消息是使用genlmsg_unicast()发送的。它实际上是一个nlmsg_unicast()包装器。发送组播通用Netlink消息的方式有如下两种。
genlmsg_multicast(): 此方法将消息发送到默认网络命名空间net_init()。
qenlmsg multicast allns():此方法将消息发送到所有网络命名空间。
generic netlink支持1023个子协议号,弥补了netlink协议类型较少的缺陷。支持协议号自动分配。它基于netlink,但是在内核中,generic netlink的接口与netlink并不相同。
Generic netlink结构
消息格式差别:
Generic netlink相对于当前使用的netlink多了两层头
Genlmsghdr头
Nlattr头
注册一个Generic Netlink Family
定义family,
定义自己的genl_family变量,主要是指定family name和操作集合。
定义操作,
根据功能需要定义操作cmd,属性attr等。
注册这个family,
注册操作
消息处理
1.接收消息:generic netlink socket是系统创建的socket,收到消息后,首先会确认消息属于哪个family,在根据不同cmd调用family对应cmd的回掉函数。
2.发送消息:构造generic netlink消息头,调用genlmsg_unicast函数发送。
用户态使用generic netlink流程
1.创建generic netlink,和其他类型一样,只是需把netlink类型指定为generic类型(16)。
2.绑定socket,同其他类型的netlink socket。
3. 获取familyid,这个过程是generic netlink独有的,通过事先定义的family name(family name需和内核一致,且唯一,且不超过16字符),获取到familyid。
4.收发消息,同其他类型netlink,只是消息格式不同。
Netlink协议的一个缺点是,协议簇数不能超过32(MAX_LINKS)个。这是开发通用Netlink簇的主要原因之一——旨在支持添加更多的协议簇。它就像是Netlink多路复用器,使用单个Netlink协议簇(NETLINK_GENERIC)。通用Netlink协议以Netlink协议为基础,并使用其API。
通用Netlink消息
通用Netlink消息的开头是一个Netlink报头,接下来是通用Netlink消息报头以及可选的用户特定报头,然后才是可选的有效载荷,如下图所示。

struct genlmsghdr {
__u8 cmd;
__u8 version;
__u16 reserved;
};
cmd:通用Netlink消息类型。你注册的每个通用簇都将添加自己的命令。
version:可用于提供版本控制支持。版本号的作用是:能够在不破坏向后兼容性的情况下修改消息的格式。
reserved:保留,供以后使用。
为通用Netlink消息分配缓冲区的工作由下面的方法完成。sk_buff *genlmsg_new(size_t payload,gfp_t flags)
它实际上是一个nlmsg_new()包装器。
使用genlmsg_new()分配缓冲区后,调用genlmsg_put()来创建通用Netlink报头。它是一个genlmsghdr实例。单播通用Netlink消息是使用genlmsg_unicast()发送的。它实际上是一个nlmsg_unicast()包装器。发送组播通用Netlink消息的方式有如下两种。
genlmsg_multicast(): 此方法将消息发送到默认网络命名空间net_init()。
qenlmsg multicast allns():此方法将消息发送到所有网络命名空间。
————————————————
版权声明:本文为CSDN博主「爱好学习的青年人」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:blog.csdn.net/qq_53111905…
Generic Netlink内核实现分析(一):初始化