I want to correctly match TAP/TUN devices with the processes they are using, and I want to do this from outside of these processes using TAP/TUN devices (that is, I cannot issue any ioctl()
s because I don't have access to a particular file descriptor inside its process itself).
I'm aware of the answers to How to find the connection between tap interface and its file descriptor?, that is: /proc/[PID]/fdinfo/[FD]
has an additional iff:
key-value pair that gives the name of the corresponding TAP/TUN network interface.
However, there's a problem with network namespaces, especially when TAP/TUN network interfaces get moved around network namespaces after their user-space processes have attached to them; for instance (here, tapclient
is a simple variation of a34729t's tunclient.c
, which accepts a tap network name and attaches to it):
$ sudo ip tuntap add tap123 mode tap
$ sudo tapclient tap123 &
$ sudo ip netns add fooz
$ sudo ip link set tap123 netns fooz
$ PID=$(ps faux | grep tapclient | grep -v -e sudo -e grep | awk '{print $2}')
$ sudo cat /proc/$PID/fdinfo/3
...which then gives: iff: tap123
-- but not the network namespace where the tap123
network interface is currently located in.
Of course, tap123
can be located by iterating over all network namespaces and looking for a matching network interface inside one of them. Unfortunately, there might be duplicate names, such as when creating another tap123
in the host namespace after we've moved the first one of this name into the fooz
network namespace above:
$ sudo ip tuntap add tap123 mode tap
$ ip link show tap123
$ sudo ip netns exec fooz ip link show tap123
So we now have two tap123
s in separate network namespaces, and fdinfo
only gives us an ambiguous iff: tap123
.
Unfortunately, looking at the /proc/$PID/ns/net
network namespace of the tapclient won't help either, since that doesn't match the current network namespace of tap123
any longer:
$ findmnt -t nsfs | grep /run/netns/fooz
$ sudo readlink /proc/$PID/ns/net
For instance, this gives net:[4026532591]
versus net:[4026531993]
.
It there a way to unambiguously match the tapclient
process with the correct tap123
network interface instance it is attached to?
ip netns identify $PID
that should give you the net namespace of$PID
without you having to look at nsfs inode numbers (andip netns pids fooz
to go the other way), but they don't seem to find anything either. Sounds like a kernel bug. – TooTea Mar 07 '19 at 10:40ip netns identify $PID
is doing nothing more than taking/proc/$PID/ns/net
and then trying to match only against its own list of bind-mounted symbolic network namespace names. Unfortunately, that's most of the time rather pointless as few are using iproute2's bindmount positions. My example is just usingip netns ...
to give an easily reproducable example to check the underlying mechanisms, but it's not a typical deployment situation. – TheDiveO Mar 07 '19 at 14:16