我可以在内核空间中拥有超过32个netlink套接字吗?

时间:2015-10-01 23:07:29

标签: sockets linux-kernel kernel-module netlink

我有几个需要与用户空间交互的内核模块。因此,每个模块都有一个Netlink套接字。

我的问题是这些插座相互干扰。这是因为它们都注册到同一个Netlink地址系列(因为没有多少可用的开头 - max is 32more than half are already reserved),也因为它们都绑定到同一个pid(内核pid - 零)。

我希望地址家庭有更多空间。或者,更好的是,我希望我可以将我的插座绑定到其他pids上。如果一次只能打开32个套接字,Netlink如何成为首选的用户内核通道?

libnl-3's documentation

  

netlink地址(端口)由32位整数组成。端口0(零)保留给内核,并引用每个netlink协议族的内核端套接字。其他端口号通常是指用户空间拥有的套接字,但这不是强制执行的。

最后的说法现在似乎是个谎言。内核使用constant as pid并且不会导出更多功能:

if (netlink_insert(sk, 0))
    goto out_sock_release;

我想我可以重新编译内核并增加地址族限制。但这些是内核模块;我不应该这样做。

我错过了什么吗?

2 个答案:

答案 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);