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

Yd *_*hrk 5 sockets kernel-module linux-kernel netlink

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

我的问题是这些套接字相互干扰。这是因为它们都注册到同一个 Netlink 地址族(因为一开始可用的地址族不多 - 最大值为 32,并且超过一半已经被保留),而且因为它们都将自己绑定到相同的 pid(内核 pid - 零)。

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

libnl-3 的文档说

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

最后一个说法现在看来是一个谎言。内核使用常量作为 pid,并且不导出更多通用函数:

if (netlink_insert(sk, 0))
    goto out_sock_release;
Run Code Online (Sandbox Code Playgroud)

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

我错过了什么吗?

Yd *_*hrk 8

不。

Netlink 的套接字数量限制是Generic Netlink存在的原因。

Generic Netlink 是现有 Netlink 之上的一层。您无需打开套接字,而是在已建立的套接字上注册回调,并侦听指向那里的“子”系列的消息。鉴于有更多可用的系列插槽(1023)并且没有端口,我假设他们认为在这一层没有必要区分系列和端口。

要在内核空间中注册侦听器,请使用genl_register_family()或其兄弟。在用户空间中,可以通过libnl-3的API使用Generic Netlink (虽然它相当有限,但是代码讲了很多并且是开放的)。