Получение netnsid сетевого пространства имен в Python - PullRequest
0 голосов
/ 06 мая 2018

При попытке найти правильный интерфейс одноранговой сети для пары veth, которая находится в другом пространстве имен, этот конец указывается не только свойством iflink, но и link-netnsid. link-netnsid - это идентификатор пространства имен сети, который имеет смысл только в текущем пространстве имен сети.

Ядро Linux не предлагает сопоставлять netnsid с номером inode пространства имен сети, который является единственным уникальным идентификатором. Однако Linux предлагает запрос RTM_GETNSID, который отображает пространство имен сети, идентифицируемое либо с помощью fd (NETNSA_FD), либо с помощью PID (NETNSA_PID), на локальный netnsid.

Как сделать такой запрос RTM_GETNSID в Python, предпочтительно с использованием библиотеки pyroute2? До сих пор я не мог успешно запросить netnsid для пространства имен, идентифицируемого PID, а только получить неверную ошибку аргумента 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)

1 Ответ

0 голосов
/ 07 мая 2018

Оказывается, мой код на самом деле правильный, но в 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)
...