我有几个需要与用户空间交互的内核模块。因此,每个模块都有一个Netlink套接字。
我的问题是这些插座相互干扰。这是因为它们都注册到同一个Netlink地址系列(因为没有多少可用的开头 - max is 32和more than half are already reserved),也因为它们都绑定到同一个pid(内核pid - 零)。
我希望地址家庭有更多空间。或者,更好的是,我希望我可以将我的插座绑定到其他pids上。如果一次只能打开32个套接字,Netlink如何成为首选的用户内核通道?
netlink地址(端口)由32位整数组成。端口0(零)保留给内核,并引用每个netlink协议族的内核端套接字。其他端口号通常是指用户空间拥有的套接字,但这不是强制执行的。
最后的说法现在似乎是个谎言。内核使用constant as pid并且不会导出更多功能:
if (netlink_insert(sk, 0))
goto out_sock_release;
我想我可以重新编译内核并增加地址族限制。但这些是内核模块;我不应该这样做。
我错过了什么吗?
答案 0 :(得分:1)
Netlink的套接字计数限制是value_counts
存在的原因。
Generic Netlink是Netlink股票的最高层。您可以在已经建立的套接字上注册回调,而不是打开套接字,并在那里收听指向" sub" -family的消息。鉴于有更多可用的家庭插槽(1023)且没有端口,我假设他们认为家庭和端口之间的分离是不必要的。
要在内核空间中注册侦听器,请使用Generic Netlink或其genl_register_family()
。在用户空间中,可以通过siblings使用Generic Netlink(虽然它相当有限,但代码说了很多而且是开放的。)
答案 1 :(得分:0)
您对MAX_LINKS
变量名称感到困惑。它不是"最大数量的链接" ,它是"最大数量的家庭" 。您列出的内容是 netlink系列或IOW netlink群组。确实有32个家庭。每个家庭都致力于为某一特定目的服务。例如NETLINK_SELINUX
用于SELinux通知,NETLINK_KOBJECT_UEVENT
用于kobject通知(这些是 udev 处理的)。
但是对每个家庭的插座数量没有限制。
当您致电netlink_create
时,它会检查您的协议号码,如果netlink套接字是netlink系列,请NETLINK_SELINUX
。看the code
static int netlink_create(struct net *net, struct socket *sock, int protocol,
int kern)
{
...
if (protocol < 0 || protocol >= MAX_LINKS)
return -EPROTONOSUPPORT;
...
这是您的MAX_LINKS使用方式。
稍后,当实际创建套接字时,它会调用__netlink_create
,然后调用sk_alloc
,然后调用sk_prot_alloc
。现在,在sk_prot_alloc
中,它按kmalloc
分配套接字(netlink没有自己的slab缓存):
slab = prot->slab;
if (slab != NULL) {
sk = kmem_cache_alloc(slab, priority & ~__GFP_ZERO);
if (!sk)
return sk;
if (priority & __GFP_ZERO) {
if (prot->clear_sk)
prot->clear_sk(sk, prot->obj_size);
else
sk_prot_clear_nulls(sk, prot->obj_size);
}
} else
sk = kmalloc(prot->obj_size, priority);