Fun with Linux Network Namespaces

A feature of the Linux kernel called namespace isolation [1] defines groups of separated processes such that each process cannot "see" resources in the other groups. This is a form of lightweight process virtualization used in some container implementations such as LXC.

There are currently six namespaces implementations:
- mnt: mount points and filesystems isolation
- pid: process isolation
- net: network stack isolation
- ipc: System V IPC isolation
- uts: hostname isolation
- user: user isolation by means of UIDs

In this post I'll show few examples of how to create network namespaces and use them with Open vSwitch.

A network namespace is a separate copy of the network stack - it contains its own routes, network devices and iptables rules. It is defined in include/net/net_namespace.h where each device belongs to only one network namespace. 

There's always the default network namespace, called the root namespace where all network interfaces are assigned to:

In this case you can see 3 network interfaces - lo, eth0 and eth1.

Now lets create 2 network namespaces called ns1 and ns2 and list them:
To execute a command inside the namespace: We can use "ip netns exec ns1 command" where command is either the actual command we want to execute or bash, which puts us in the namespace's shell, where we can run commands as usual without the need of prefixing them with "ip netns exec ns1".

As you can see the ns1 namespace only contains the loopback interface in a DOWN state. The same is true for the ns2 network namespace.

To connect the two lets first create a software switch using Open vSwitch:
Lets create a link between the namespaces ns1 and ns2 through the virtual switch by specifying the two ends of the connection, called a virtual pair.

To create the two pairs run:
The commands above created two virtual links in the root namespace, each having two interface on each end - eth1-ns1/veth-ns1 and eth1-ns2/veth-ns2. Think of the eth1-ns1 and veth-ns1 interfaces as two opposite ends of the same pipe. The names are arbitrary.

First lets connect one end of the virtual connections to each name space:
Notice how the eth1-ns1 and eth1-ns2 interfaces no longer show in the root name space, but in their newly assigned ns1 and ns2 namespaces.

Then lets connect the other end to a port on the OVS:
The end result is two network namespaces ns1 and ns2 each having eth1-ns1/2 interface connected to an OVS ports veth-ns1/2. Let's bring the interfaces up and assign IPs.

In the root namespace lets bring the veth-ns1/2 interfaces up:
Then in each network namespace ns1 and ns2 lets bring the lo and eth-ns1/2 interfaces up and assign IPs:
We should now have network connectivity between ns1 and ns2. Let's verify:
Now lets start a dnsmasq server in ns1 and try to get an IP lease from ns2:
The logs also show that ns2 got a new IP lease from the ns1 dnsmasq process:
To isolate both name spaces into their own VLANs:
Now connectivity between both ns1 and ns2 should be lost.

Resources:
[1]. http://man7.org/linux/man-pages/man7/namespaces.7.html