1

当试图找到veth位于不同命名空间中的一对的正确对等网络接口时,该端不仅由​​其iflink属性指示,而且由link-netnsid. 这link-netnsid是一个网络命名空间 ID,仅在当前网络命名空间内有意义。

Linux 内核不提供将 netnsid 映射到网络命名空间 inode 编号,这是唯一的唯一标识。但是,Linux 提供的请求将由 fd ( ) 或 PID ( )RTM_GETNSID标识的网络名称空间映射到本地 netnsid。NETNSA_FDNETNSA_PID

如何RTM_GETNSID在 Python 中提出这样的请求,最好使用pyroute2库?到目前为止,我无法成功为 PID 标识的命名空间请求 netnsid,而只能使用以下脚本返回无效参数错误 22:

from pyroute2 import IPRoute
from pyroute2.netlink import NLM_F_REQUEST
import pyroute2.netlink.rtnl as rtnl
import pyroute2.netlink.rtnl.nsidmsg as nsidmsg

netstack = IPRoute()
req = nsidmsg.nsidmsg()
req['rtgen_family'] = 0
# 12345 is PID of a process inside another network namespace
req['attrs'] = [('NETNSA_PID', 12345)]
ret = netstack.nlm_request(req, rtnl.RTM_GETNSID, NLM_F_REQUEST)
4

1 回答 1

0

事实证明,我的代码实际上是正确的,但是有一个错误pyroute2导致 RTNETLINK 消息太短了几个八位字节(在 中可见strace)。作为围绕这个库错误的临时破解,设置两个属性就足够了,以便内核接受 RTNETLINK 数据包并对其进行处理,即使它不完全正确。

from pyroute2 import IPRoute
from pyroute2.netlink import NLM_F_REQUEST
import pyroute2.netlink.rtnl as rtnl
import pyroute2.netlink.rtnl.nsidmsg as nsidmsg

netstack = IPRoute()
req = nsidmsg.nsidmsg()
req['rtgen_family'] = 0
# 12345 is PID of a process inside another network namespace
req['attrs'] = [('NETNSA_PID', 12345), ('NETNSA_PID', 0]  # hack around pyroute 0.5.0 bug
ret = netstack.nlm_request(req, rtnl.RTM_GETNSID, NLM_F_REQUEST)
于 2018-05-07T18:01:32.290 回答