2

I just started studying network namespaces and I'm looking at a very common example. This is just connecting two namespaces thanks to two veth (no bridge involved).

ip netns add net1
ip netns add net2
ip netns exec net1 ifconfig lo up
ip netns exec net2 ifconfig lo up
ip link add veth1 type veth peer name veth2
ip link set veth1 netns net1
ip link set veth2 netns net2
ip netns exec net1 ifconfig veth1 10.0.15.1/24 up
ip netns exec net2 ifconfig veth2 10.0.15.2/24 up
ip netns exec net1 ping 10.0.15.2

The output is:

PING 10.0.15.2 (10.0.15.2) 56(84) bytes of data.
64 bytes from 10.0.15.2: icmp_seq=1 ttl=64 time=0.355 ms
64 bytes from 10.0.15.2: icmp_seq=2 ttl=64 time=0.189 ms
64 bytes from 10.0.15.2: icmp_seq=3 ttl=64 time=0.187 ms
64 bytes from 10.0.15.2: icmp_seq=4 ttl=64 time=0.184 ms
64 bytes from 10.0.15.2: icmp_seq=5 ttl=64 time=0.158 ms
64 bytes from 10.0.15.2: icmp_seq=6 ttl=64 time=0.300 ms
64 bytes from 10.0.15.2: icmp_seq=7 ttl=64 time=0.189 ms
64 bytes from 10.0.15.2: icmp_seq=8 ttl=64 time=0.186 ms
64 bytes from 10.0.15.2: icmp_seq=9 ttl=64 time=0.186 ms

What I can't undersant is why in every example I saw, when we give IP to the veth, we always give it a /24 class IP. When I tried giving it a single IP:

ip netns exec net2 ifconfig veth2 10.0.15.2/32 up

the output I got was:

PING 10.0.15.2 (10.0.15.2) 56(84) bytes of data.
From 10.0.15.1 icmp_seq=9 Destination Host Unreachable
From 10.0.15.1 icmp_seq=10 Destination Host Unreachable
From 10.0.15.1 icmp_seq=11 Destination Host Unreachable
From 10.0.15.1 icmp_seq=12 Destination Host Unreachable
From 10.0.15.1 icmp_seq=13 Destination Host Unreachable
From 10.0.15.1 icmp_seq=14 Destination Host Unreachable
From 10.0.15.1 icmp_seq=15 Destination Host Unreachable

Why I am not able to give it a single ip address?

1

TL;DR

Linux adds implicit routes when adding addresses. When the address is a /32 there can't be an implicit route added. You need then to manually add the route to other IP(s). When it's intended to route only to one destination (LAN or IP but when it's symmetric, it's often to only peer's IP), this can be abbreviated with ip address's peer parameter to add the route in the same shot. So instead of the two ifconfig commands, use this (with newer ip commands), and ping will work:

ip -n net1 link set veth1 up
ip -n net2 link set veth2 up
ip -n net1 address add 10.0.15.1 peer 10.0.15.2 dev veth1
ip -n net2 address add 10.0.15.2 peer 10.0.15.1 dev veth2

Longer answer:

A few remarks first:

  • Your issue is not related to network namespaces, but to routing alone, along with Linux peculiarities. Anyway network namespaces are very handy to do the mockup for a whole setup.
  • On Linux, you should drop the use of the ifconfig command (as well as route, brctl etc. commands) to the profit of the set of commands provided by iproute2. ifconfig's API (ioctl) has been half abandonned on Linux to use instead the netlink API, so some newer features may be available only through the ip ... kind of command.
  • Recent enough iproute2 tools have for most of their sub-commands the -netns option as a shortcut when using namespaces: ip -netns net1 FOO is equivalent to ip netns exec net1 ip FOO. I'll be using this shortcut when possible below. Many commands have abbreviated versions (eg: ip addr or even ip a instead of ip address) and some parameters keywords can be omitted. I won't use abbreviations here (except -n instead of -netns).

Linux implicitly adds a route when an address with a netmask is set. When the netmask is /32 there can't be a route added this way (or actually there still is: a local scope route, but it's hidden in the local routing table (ip -n net1 route show table local) rather than in the main routing table. This addition can be prevented when using ip address add with the flag noprefixroute for some setups where the implicit route is not wanted. Note that ifconfig also adds a few default settings, like by default (all host's bits set variant) broadcast address. Those must be explicitly asked when using ip address.

Here are a few examples to help understand what's happening

Right before adding the addresses, run ip monitor in one of the namespaces, in a separate terminal. It will display any of a lot of possible network changes in the network namespace, then run the first address addition(ip netns exec net1 ifconfig veth1 10.0.15.1/24 up). Here's what you can typically get:

# ip -4 -n net1 monitor route
local 10.0.15.1 dev veth1 table local proto kernel scope host src 10.0.15.1 
broadcast 10.255.255.255 dev veth1 table local proto kernel scope link src 10.0.15.1 linkdown 
10.0.0.0/8 dev veth1 proto kernel scope link src 10.0.15.1 linkdown 
broadcast 10.0.0.0 dev veth1 table local proto kernel scope link src 10.0.15.1 linkdown 
Deleted 10.0.0.0/8 dev veth1 proto kernel scope link src 10.0.15.1 linkdown 
Deleted broadcast 10.255.255.255 dev veth1 table local proto kernel scope link src 10.0.15.1 linkdown 
Deleted broadcast 10.0.0.0 dev veth1 table local proto kernel scope link src 10.0.15.1 linkdown 
Deleted local 10.0.15.1 dev veth1 table local proto kernel scope host src 10.0.15.1 
local 10.0.15.1 dev veth1 table local proto kernel scope host src 10.0.15.1 
broadcast 10.0.15.255 dev veth1 table local proto kernel scope link src 10.0.15.1 linkdown 
10.0.15.0/24 dev veth1 proto kernel scope link src 10.0.15.1 linkdown 
broadcast 10.0.15.0 dev veth1 table local proto kernel scope link src 10.0.15.1 linkdown

It appears here that ifconfig is working inefficiently: it first adds a /8 route then removes it and puts the asked /24 route. That's probably a leftover from the past never corrected. Here would be the equivalent with ip -n net1 link set veth1 up; ip -n net1 address add 10.0.15.1/24 broadcast + dev veth1:

local 10.0.15.1 dev veth1 table local proto kernel scope host src 10.0.15.1 
broadcast 10.0.15.255 dev veth1 table local proto kernel scope link src 10.0.15.1 linkdown 
10.0.15.0/24 dev veth1 proto kernel scope link src 10.0.15.1 linkdown 
broadcast 10.0.15.0 dev veth1 table local proto kernel scope link src 10.0.15.1 linkdown 

So what if you don't want any /24? You can set /32 IPs and add the route yourself, like this (At the same time I rewrite a(n arguably) shorter version of the whole setup):

ip netns add net1
ip netns add net2
ip -n net1 link set lo up
ip -n net2 link set lo up
ip -n net1 link add name veth1 type veth peer netns net2 name veth2

Set the interfaces up (can be done before or after, this won't change the final result once it's up):

ip -n net1 link set veth1 up
ip -n net2 link set veth2 up

Addresses:

ip -n net1 address add 10.0.15.1/32 dev veth1
ip -n net2 address add 10.0.15.2/32 dev veth2

Here an ip -4 -n net1 monitor route would have only shown local 10.0.15.1 dev veth1 table local proto kernel scope host src 10.0.15.1: only the hidden local route.

Routes:

ip -n net1 route add 10.0.15.2/32 dev veth1
ip -n net2 route add 10.0.15.1/32 dev veth2

The two addresses values can be completely unrelated. You could likewise use 192.0.2.1 and 198.51.100.2. Some hosting providers use this mechanism to provide additional "failover IPs". Actually there's a shortcut for this specific case, where again a route will be added along the address in one shot, as long as the relevant informations are provided. So instead of the 4 previous commands, this is enough:

ip -n net1 address add 10.0.15.1 peer 10.0.15.2 dev veth1
ip -n net2 address add 10.0.15.2 peer 10.0.15.1 dev veth2

Note that in all cases, those are still Ethernet interfaces, not point-to-point, so there will still be ARP requests done at the link layer to find the other IP.

Final note: if you intend to use more than two network namespaces together, you should probably revert to using a LAN netmask, and you'll very likely need to create a bridge interface (you can put it in the original namespace, in one of the newly created namespaces, but I advise you to put it in its own reserved namespace, to avoid unforseen interactions). Then for each pair of veth interface, one side should be put in the bridge's network namespace and enslaved to the bridge (eg: ip -n mybridgens link set vethp1 master bridge0).

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.