Skip to content

NetNS does not handle fd parameters #1123

Closed
@liske

Description

@liske

Using get_netnsid with a fd works for IPRoute instances, calling it on NetNS does fail.

I've created two (iproute2 netns'ish) network namespaces:

  • service
  • tenant1

I need a nsid to create a vlan link inside of tenant1 linked to a physical interface in the service namespace. To reference the other namespace I need to use the bind mount in /var/run/netns as there is no pid inside this netns. When calling a netns method of NetNS with the fd parameter, it will be passed into the proxy NetNS process where the fd is invalid.

Affected NetNS methods:

  • NetNS.get_netnsid
  • NetNS.set_netnsid
# python3
Python 3.11.2 (main, Mar 13 2023, 12:18:29) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from pyroute2 import NetNS
>>> n = NetNS('tenant1')
>>> with open('/var/run/netns/service', 'r') as fh:
...   n.get_netnsid(fd=fh.fileno())
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/home/thomas/src/ifstate/.venv/lib/python3.11/site-packages/pyroute2/iproute/linux.py", line 687, in get_netnsid
    response = self.nlm_request(msg, RTM_GETNSID, NLM_F_REQUEST)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/thomas/src/ifstate/.venv/lib/python3.11/site-packages/pyroute2/netlink/nlsocket.py", line 870, in nlm_request
    return tuple(self._genlm_request(*argv, **kwarg))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/thomas/src/ifstate/.venv/lib/python3.11/site-packages/pyroute2/netlink/nlsocket.py", line 1214, in nlm_request
    for msg in self.get(
               ^^^^^^^^^
  File "/home/thomas/src/ifstate/.venv/lib/python3.11/site-packages/pyroute2/netlink/nlsocket.py", line 873, in get
    return tuple(self._genlm_get(*argv, **kwarg))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/thomas/src/ifstate/.venv/lib/python3.11/site-packages/pyroute2/netlink/nlsocket.py", line 550, in get
    raise msg['header']['error']
pyroute2.netlink.exceptions.NetlinkError: (9, 'Bad file descriptor')
>>> with open('/var/run/netns/service', 'r') as fh:
...   n.get_netnsid(fd=fh.fileno())
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/home/thomas/src/ifstate/.venv/lib/python3.11/site-packages/pyroute2/iproute/linux.py", line 687, in get_netnsid
    response = self.nlm_request(msg, RTM_GETNSID, NLM_F_REQUEST)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/thomas/src/ifstate/.venv/lib/python3.11/site-packages/pyroute2/netlink/nlsocket.py", line 870, in nlm_request
    return tuple(self._genlm_request(*argv, **kwarg))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/thomas/src/ifstate/.venv/lib/python3.11/site-packages/pyroute2/netlink/nlsocket.py", line 1214, in nlm_request
    for msg in self.get(
               ^^^^^^^^^
  File "/home/thomas/src/ifstate/.venv/lib/python3.11/site-packages/pyroute2/netlink/nlsocket.py", line 873, in get
    return tuple(self._genlm_get(*argv, **kwarg))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/thomas/src/ifstate/.venv/lib/python3.11/site-packages/pyroute2/netlink/nlsocket.py", line 550, in get
    raise msg['header']['error']
pyroute2.netlink.exceptions.NetlinkError: (9, 'Bad file descriptor')
>>> 

An strace of the NetNS proxy process shows this output:

# strace -f -p 1019132
strace: Process 1019132 attached
pselect6(8, [5 7], NULL, [5 7], NULL, NULL) = 1 (in [5])
read(5, "\21\1\0\0\0\0\0\0", 8)         = 8
read(5, "\200\4\225\376\0\0\0\0\0\0\0}\224(\214\5stage\224\214\vreconstr"..., 265) = 265
sendto(7, [{nlmsg_len=28, nlmsg_type=0x5a /* NLMSG_??? */, nlmsg_flags=NLM_F_REQUEST, nlmsg_seq=256, nlmsg_pid=1018897}, "\x00\x00\x00\x00\x08\x00\x03\x00\x09\x00\x00\x00"], 28, 0, {sa_family=AF_NETLINK, nl_pad=0x1e01, nl_pid=0, nl_groups=00000000}, 12) = 28
write(4, "K\0\0\0\0\0\0\0\200\4\2258\0\0\0\0\0\0\0}\224(\214\5stage\224\214\v"..., 75) = 75
pselect6(8, [5 7], NULL, [5 7], NULL, NULL) = 1 (in [7])
getsockopt(7, SOL_SOCKET, SO_RCVBUF, [425984], [4]) = 0
recvfrom(7, "", 0, MSG_PEEK|MSG_TRUNC|MSG_DONTWAIT, {sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, [12]) = 48
recvfrom(7, [{nlmsg_len=48, nlmsg_type=NLMSG_ERROR, nlmsg_flags=0, nlmsg_seq=256, nlmsg_pid=1019132}, {error=-EBADF, msg=[{nlmsg_len=28, nlmsg_type=0x5a /* NLMSG_??? */, nlmsg_flags=NLM_F_REQUEST, nlmsg_seq=256, nlmsg_pid=1018897}, "\x00\x00\x00\x00\x08\x00\x03\x00\x09\x00\x00\x00"]}], 48, 0, NULL, NULL) = 48

The error is expected as there is no such fd open:

# ls -lha /proc/1019132/fd
total 0
dr-x------ 2 root root  0 Aug 20 11:39 .
dr-xr-xr-x 9 root root  0 Aug 20 11:39 ..
lrwx------ 1 root root 64 Aug 20 12:02 0 -> /dev/pts/3
lrwx------ 1 root root 64 Aug 20 12:02 1 -> /dev/pts/3
lrwx------ 1 root root 64 Aug 20 12:02 2 -> /dev/pts/3
lr-x------ 1 root root 64 Aug 20 12:02 3 -> 'pipe:[1861959]'
l-wx------ 1 root root 64 Aug 20 12:02 4 -> 'pipe:[1858288]'
lr-x------ 1 root root 64 Aug 20 12:02 5 -> 'pipe:[1858289]'
l-wx------ 1 root root 64 Aug 20 12:02 6 -> 'pipe:[1861959]'
lrwx------ 1 root root 64 Aug 20 11:39 7 -> 'socket:[1861960]'

Even if I understand the reason for the exception it is not clear to me how this can be solved 😵‍💫

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions