I create several network namespaces with
ip netns add ns1,
ip netns add ns1.
When I try to start/stop network interfaces inside network namespaces with
ifdown the interface state is wrong:
$ ifup lo ifup: interface lo already configured
I believe this is because the /run/network/ is where
ifdown keep the state and it is shared between default and additional network namespaces when created as above. I think so because when I create veth interfaces inside a network namespace, the corresponding entries turn up in main space in /run/network. This problem applies to
lo interface as well.
I'm seeing same problem in Ubuntu-12-LTS and 2020-02-13-raspbian-buster-lite. I have a vague memory dealing with similar symptoms in
CentOS-7.4 a while back just not investigating it for causes.
To demonstrate (on Raspbian) I create and ifup/ifdown a bridge inside each network namespace, and check content of /run/network/ in the default space.
$ echo 'iface br2 inet manual' > /etc/network/interfaces.d/br2 $ ip netns add ns1 $ ip netns add ns2 $ ip netns exec ns1 ip link add br2 type bridge $ ip netns exec ns2 ip link add br2 type bridge
br2 state does not exists
$ cat /run/network/ifstate.br2 cat: /run/network/ifstate.br2: No such file or directory
br2 has not been
ifdowned ever in any namespace.
Bring up/down/up the interface on 1st namespace
$ ip netns exec ns1 ifup br2 $ cat /run/network/ifstate.br2 br2 $ ip netns exec ns1 ifdown br2 $ cat /run/network/ifstate.br2 $ ip netns exec ns1 ifup br2 $ cat /run/network/ifstate.br2 br2
OK, and now do same up/down/up on 2nd namespace, causes error
$ ip netns exec ns2 ifup br2 ifup: interface br2 already configured $ cat /run/network/ifstate.br2 br2
This above is the problem! Stop the interface via 2nd namespace (note it was started via 1st)
$ ip netns exec ns2 ifdown br2 $ cat /run/network/ifstate.br2
Now back to 1st namespace
$ ip netns exec ns1 ifdown br2 ifdown: interface br2 not configured $ cat /run/network/ifstate.br2
Above is similar problem, interface wad stopped in 2nd namespace, but is reported as down in 1st.
Unfortunately this applies to
lo so it's impossible to avoid it by simply having unique names inside each namespace. I just have to keep cycling interfaces with 'up/down/up' to get around this issue. I hope there is a cleaner way to do this.
My use case and goals: I create multiple identical namespaces similar to test above only wrapped into systemd instanced service units, start their interfaces (having to up/down/up to work around the issue). At various times I launch programs inside each namespace, with
ip netns exec nsX prog args often also by other systemd services. Some time later I dismantle certain namespace, and I need to do this carefully. I need
ifdown to do its work properly as it tidies things up. The networks are non-trivial, with several
veth interfaces, bridges and associate
sysctl settings, so I really want
ifdown to work well and not get confused by other namespace's state. E.g.
veth interfaces. Certainly workaround are possible, but it gets hacky/dirty quickly.
I feel like I need to mount tmpfs onto
/run/network within network namespace somehow, but I don't know how. The
ip netns exec bind mounts few things only for duration of the program that runs, not permanently attached to the network namespace itself, it seems. If I bind mount during setup invocation
ip netns exec ns1 ifup ... it will exit and not be available later when I need to do
I am open to different methods of creating network namespaces. I just need some way of tracking things so I can launch several programs in the right namespace at different points in time.