NETLINK_GENERIC

223 阅读4分钟

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…

blog.csdn.net/luckyapple1…

blog.csdn.net/armlinuxww/…

Generic Netlink内核实现分析(一):初始化

blog.csdn.net/luckyapple1…