Spekii

Spekii
Showing posts with label openvswitch. Show all posts
Showing posts with label openvswitch. Show all posts

Sunday, September 15, 2013

Network labs with Linux namespaces...

If like me you need to build many network testing environments, and you feel that is a pain to spawn many virtual servers only to realize some little networking tests, namespaces are made for you !


Linux namespaces


The purpose of the namespaces is to wrap system resources in a way that makes that a process associated to the namespaces has its own version of these resources.

 Currently there are six kind of namespaces:

  •     network namespaces, we are going to use these ones.
  •     User namespaces
  •     PID namespaces
  •     UTS namespaces
  •     IPC namespaces
  •     Mount namespaces

Your first lab


First, assume we want to connect two virtual servers to a network. So to achieve this topology we are going to create two network namespaces which will act as two nodes.

The following lines create the two namespaces :

# ip netns add vm1
# ip netns add vm2

Now that we have two namespaces, we need to create the network interfaces for both of them.

Following lines create a virtual Ethernet (veth) pair :

# ip link add name vm1-eth0 type veth peer name vm1-eth0.1
# ip link add name vm2-eth0 type veth peer name vm2-eth0.1

Now we need to add one veth to a namespace for each node :

# ip link set vm1-eth0.1 netns vm1
# ip link set vm2-eth0.1 netns vm2

Every network namespace comes with its own loopback interface. We need to set all interfaces belonging to a namespace to up.

# ip netns exec vm1 ip l set lo up
# ip netns exec vm1 ip l set vm1-eth0.1 up
# ip netns exec vm2 ip l set lo up
# ip netns exec vm2 ip l set vm2-eth0.1 up

By the way, we can see above that to be able to execute a command in a namespace context, we just need to use the following command template :

# ip netns exec <NS> <COMMAND>

Now let's add addresses :

# ip netns exec vm1 ip a add 192.168.0.1 dev vm1-eth0.1
# ip netns exec vm2 ip a add 192.168.0.2 dev vm2-eth0.1

And the routes :

# ip netns exec vm1 ip r add 192.168.0.0/24 dev vm1-eth0.1
# ip netns exec vm2 ip r add 192.168.0.0/24 dev vm2-eth0.1

Now it's the time to connect both nodes together. To achieve this, we can either use a bridge or a virtual switch like Openvswitch.

Let's see with a bridge :

# brctl addbr br1
# ip l set br1 up

# ip l set vm1-eth0 up
# brctl addif br1 vm1-eth0

# ip l set vm2-eth0 up
# brctl addif br1 vm2-eth0

Or with Openvswitch :

# ovs-vsctl add-br br1
# ip l set br1 up

# ip l set vm1-eth0 up
# ovs-vsctl add-port br1 vm1-eth0

# ip l set vm2-eth0 up
# ovs-vsctl add-port br1 vm2-eth0

Finally you should be able to ping a node from the other one.

# ip netns exec vm1 ping 192.168.0.2

Here the full script :
#!/bin/sh

ip netns add vm1
ip netns add vm2
ip link add name vm1-eth0 type veth peer name vm1-eth0.1
ip link add name vm2-eth0 type veth peer name vm2-eth0.1
ip link set vm1-eth0.1 netns vm1
ip link set vm2-eth0.1 netns vm2
ip netns exec vm1 ip l set lo up
ip netns exec vm1 ip l set vm1-eth0.1 up
ip netns exec vm2 ip l set lo up
ip netns exec vm2 ip l set vm2-eth0.1 up
ip netns exec vm1 ip a add 192.168.0.1 dev vm1-eth0.1
ip netns exec vm2 ip a add 192.168.0.2 dev vm2-eth0.1
ip netns exec vm1 ip r add 192.168.0.0/24 dev vm1-eth0.1
ip netns exec vm2 ip r add 192.168.0.0/24 dev vm2-eth0.1
brctl addbr br1
ip l set br1 up
ip l set vm1-eth0 up
brctl addif br1 vm1-eth0
ip l set vm2-eth0 up
brctl addif br1 vm2-eth0

ip netns exec vm1 ping 192.168.0.2 -c 5

This article was just a little introduction of the huge possibilities offered by namespaces.