Linux
中与内核通信的
Netlink
机制
Netlink
在
2.6
版本的内核中变化也是很大的,
在最新的
2.6.37
内核中,
其定义已经改成下面
这种形式,
传递的参数已经达到
6
个。
其中第一个参数和
mutex
参数都是最新添加的。
Mutex
也可以为空。这里主要是关于内核空间中的
netlink
函数的使用。
extern struct sock *netlink_kernel_create(struct net *net,
int unit,unsigned int groups,
void (*input)(struct sk_buff *skb),
struct mutex *cb_mutex,
struct module *module);
struct net
是一个网络名字空间
namespace
,在不同的名字空间里面可以有自己的转发信息
库,有自己的一套
net_device
等等。默认情况下都是使用
init_net
这个全局变量,下面是内
核中调用
netlink_kernel_create()
函数的一个示例。
在内核中,
audit_sock = netlink_kernel_create(&init_net, NETLINK_AUDIT, 0,
audit_receive, NULL, THIS_MODULE);
模块调用函数
netlink_unicast
来发送单播消息:
int
netlink_unicast(struct
sock
*ssk,
struct
sk_buff *skb, u32 pid, int nonblock)
参数
ssk
为函数
netlink_kernel_create()
返回的
socket
,参数
skb
存放消息,它的
data
字
段指向要发送的
netlink
消息结构,而
skb
的控制块保存了消息的地址信息,前面的宏
NETLINK_CB(skb)
就用于方便设置该控制块,
参数
pid
为接收消息进程的
pid
,
参数
nonblock
表示该函数是否为非阻塞,如果为
1
,该函数将在没有接收缓存可利用时立即返回,而如果
为
0
,该函数在没有接收缓存可利用
定时睡眠。
netlink
的内核实现在
.c
文件
net/core/af_netlink.c
中,
内核模块要想使用
netlink
,
也必须
包含头文件
linux/netlink.h
。内核使用
netlink
需要专门的
API
,这完全不同于用户态应用对
netlink
的使用。
如果用户需要增加新的
netlink
协议类型,
必须通过修改
linux/netlink.h
来实
现,
当然,
目前的
netlink
实现已经包含了一个通用的协议类型
NETLINK_GENERIC
以方便
用户使用,
用户可以直接使用它而不必增加新的协议类型。
前面讲到,
为了增加新的
netlink
协议类型,用户仅需增加如下定义到
linux/netlink.h
就可以:
只要增加这个定义之后,用户就可以在内核的任何地方引用该协议。
在内核中,为了创建一个
netlink socket
用户需要调用如下函数:
extern struct sock *netlink_kernel_create(struct net *net,
int unit,unsigned int groups,
void (*input)(struct sk_buff *skb),
struct mutex *cb_mutex,