The Linux man page for network namespaces(7) says:
Network namespaces provide isolation of the system resources associated with networking: [...], the /sys/class/net directory, [...].
However, simply switching into a different network namespace doesn't seem to change the contents of /sys/class/net
(see below for how to reproduce). Am I just mistaken here in thinking that the setns()
into the network namespace is already sufficient? Is it always necessary to remount /sys
in order to get the correct /sys/class/net
matching the currently joined network namespace? Or am I missing something else here?
Example to Reproduce
Take an *ubuntu system, find the PID of the rtkit-daemon, enter the daemon's network namespace, show its network interfaces, and then check /sys/class/net
:
$ PID=`sudo lsns -t net -n -o PID,COMMAND | grep rtkit-daemon | cut -d ' ' -f 2`
$ sudo nsenter -t $PID -n
# ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
# ls /sys/class/net
docker0 enp3s0 lo lxcbr0 ...
Please notice that while ip link show
correctly only shows lo
, /sys/class/net
shows all network interfaces visible in the "root" network namespace (and "root" mount namespace).
In the case of rtkit-daemon
also entering the mount namespace of it doesn't make a difference: sudo nsenter -t $PID -n -m
and then ls /sys/class/net
still shows network interfaces not present in the network namespace.
"Fix"
Many kudos to @Danila Kiver for explaining what really is going on behind the Linux kernel scenes. Remounting sysfs
while the correct network namespace is joined will show the correct entries in /sys/class/net
:
$ PID=`sudo lsns -t net -n -o PID,COMMAND | grep rtkit-daemon | cut -d ' ' -f 2`
$ sudo nsenter -t $PID -n
# MNT=`mktemp -d`
# mount -t sysfs none $MNT
# ls $MNT/class/net/
lo
# umount $MNT
# rmdir $MNT
# exit
So this now yields the correct results in /sys/class/net
.