In the Linux world, the VRFs of the professional networking world got the name “network namespace”
In L2 switching World, More than one switch instance runs on single switch by VLAN
In L3 Routing World, More than one Router instance also known as Virtual router runs on one Real Router got the name Virtual Routing and Forwarding- VRF and in Linux World known as “network namespace”
And VRF is now possible in Linux by tools known as “iproute” rpm with version 2.X and release “X.netns.2”
Each network namespace has it’s own routing table, it’s own iptables setup providing nat and filtering. Linux network namespaces offer in addition the capability to run processes within the network namespace.
Command to manage network space : – ip netns
and for help: # ip netns help
Check your Linux OS support this feature or not, by adding one namespace
Creating a network namespace
# add a new namespace
ip netnas add <network namespace name>
#Example:
ip netns add lwnet
Listing all existing network namespaces in the system
# list all namespaces
ip netns list
#will show the namespace from above
lwnet
Deleting a network namespace
# ip netns delete <network namespace name>
Executing a command in a network namespace
The command ip offers the “black magic” to execute commands in the network namespace. The following is used:
# execute a command in a namespace
ip netns exec <network namespace name> <command>
#Example using the namespace from above:
ip netns exec lwnet ip addr
shows all ip interfaces and addresses in the namespace
3: lo: <LOOPBACK> mtu 16436 qdisc noop state DOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
Note: if you create one more namespace and check its interface details , it show ID 4, ie. VLAN id to separate this network from other namespace at L2 layer by VLAN number
# ip netns add test
# ip netns exec test ip a
4: lo: <LOOPBACK> mtu 16436 qdisc noop state DOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
———————————————————————————————————————————————————————
A “dirty” trick is to not start each command with the prefix ip netns exec…. Start a shell in the network namespace using
# ip netns exec <network namespace name> bash
[root@openstack ~]# ip netns exec lwnet bash
Now below commands only show results on “lwnet” namespace
[root@openstack ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
[root@openstack ~]# ip a
3: lo: <LOOPBACK> mtu 16436 qdisc noop state DOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
[root@openstack ~]# ifconfig -a
lo Link encap:Local Loopback
LOOPBACK MTU:16436 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
[root@openstack ~]# iptables -t nat -nvL
But do not forget, that you are now “trapped” in the network namespace. Just type exit to leave
———————————————————————————————————————————————————
Exploring the network namespace
After creating the namespace with the command above, the first task is to bring up the loopback interface of the new namespace. You may have noticed from the output above, that the loopback interface is DOWN after creating the network namespace
# set the link of lo in the namespace to up
ip netns exec lwnet ip link set dev lo up
# list all interfaces and the state in the namespace
ip netns exec lwnet ip link
and the loopback interface is now UP. Now it’s time to connect the network namespace to the outside world.
Adding interfaces to a network namespace
It is not possible to assign physical interfaces of your Linux box to a network namespace. It’s only possible to attach virtual interfaces. So we have to create a virtual interface. The tool is – again – ip. The command
# ip link add veth-a type veth peer name veth-b
creates two virtual interfaces veth-a and veth-b, which are connected using “a virtual cable”. The command ip link shows both interfaces in the default namespace.
# ip link
veth-b: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
link/ether 72:01:ad:c5:67:84 brd ff:ff:ff:ff:ff:ff
veth-a: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
link/ether 8e:8b:bd:b1:88:e5 brd ff:ff:ff:ff:ff:ff
We can now take one end of this construct and attach it to the created namespace nstest using the command
# ip link set veth-b netns lwnet
Now ip link in the default namespace does not show this interface any more. It shows up now in the network namespace lwnet, Verify this using the command
# list all interfaces in the namespace lwnet
# ip netns exec lwnet ip link
lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
veth-b: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
link/ether 72:01:ad:c5:67:84 brd ff:ff:ff:ff:ff:ff
Assign ip addresses to the veth interfaces
Now it’s time to assign ip addresses to the veth interfaces and bring the interfaces up
# default namespace
ip addr add 10.0.0.1/24 dev veth-a
ip link set dev veth-a up
#
# namespace lwnet
ip netns exec lwnet ip addr add 10.0.0.2/24 dev veth-b
ip netns exec lwnet ip link set dev veth-b up
Verify, that the interfaces are up (use ip link), have ip addresses assigned (use ip addr) and a route is existing (use ip route).Now you can ping from the default namespace interface veth-a to the lwnet namespace interface veth-b:
ping 10.0.0.2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_req=1 ttl=64 time=0.054 ms
64 bytes from 10.0.0.2: icmp_req=2 ttl=64 time=0.034 ms
And from the lwnet namespace interface veth-b to the default namespace interface veth-a:
ip netns exec lwnet ping 10.0.0.1
PING 10.0.0.1 (100.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_req=1 ttl=64 time=0.064 ms
64 bytes from 10.0.0.1: icmp_req=2 ttl=64 time=0.036 ms
Which software is using network namespaces?
Network namespaces are used by many container and virtualization techniques. LXC is one of the virtualization container techniques. Openstack neutron is also using the Linux network namespaces.Virtual inferfaces and network namespaces are very useful, when a virtual switch, e.g. Openvswitch, is installed.
Linux Switching – Interconnecting Namespaces :
The software switching classical tool is the linuxbridge, which is available in the Linux kernel for a long time. The frontend to manage the linuxbridge is brctl. The newer tool is the Openvswitch (at http://openvswitch.org/). The main frontend is ovs-vsctl.
I will show multiple solutions to interconnect Linux namespaces using a software based switch.
tap interfaces
Linux tap interfaces created with ip tun / tap cannot be used to attach network namespaces to linuxbridges or the openvswitch.
Solution 1 : veth pair
The simple solution to connect two network namespaces is the usage of one veth pair.
# add the namespaces
ip netns add ns1
ip netns add ns2
# create the veth pair
ip link add tap1 type veth peer name tap2
# move the interfaces to the namespaces
ip link set tap1 netns ns1
ip link set tap2 netns ns2
# bring up the links
ip netns exec ns1 ip link set dev tap1 up
ip netns exec ns2 ip link set dev tap2 up
# now assign the ip addresses
Solution 2 : linux bridge and two veth pairs
When more than two network namespaces (or KVM or LXC instances) must be connected a switch should be used. Linux offers as one solution the well known linux bridge.
We need for this setup one switch, and two connectors. In this setup we use a linuxbridge and two veth pairs.
# add the namespaces
ip netns add ns1
ip netns add ns2
# create the switch
$BRIDGE=br-test
brctl addbr $BRIDGE
brctl stp $BRIDGE off
ip link set dev $BRIDGE up
#
#### PORT 1
# create a port pair
ip link add tap1 type veth peer name br-tap1
# attach one side to linuxbridge
brctl addif br-test br-tap1
# attach the other side to namespace
ip link set tap1 netns ns1
# set the ports to up
ip netns exec ns1 ip link set dev tap1 up
ip link set dev br-tap1 up
#
#### PORT 2
# create a port pair
ip link add tap2 type veth peer name br-tap2
# attach one side to linuxbridge
brctl addif br-test br-tap2
# attach the other side to namespace
ip link set tap2 netns ns2
# set the ports to up
ip netns exec ns2 ip link set dev tap2 up
ip link set dev br-tap2 up
#
Solution 3 : openvswitch and two veth pairs
Another solution is to use the openvswitch instead of the “old” linuxbrige. The configuration is nearly the same as for the linuxbridge.
We need for this setup one switch, and two connectors. In this setup we use an openvswitch and two veth pairs.
# add the namespaces
ip netns add ns1
ip netns add ns2
# create the switch
$BRIDGE=ovs-test
ovs-vsctl add-br $BRIDGE
#
#### PORT 1
# create a port pair
ip link add tap1 type veth peer name ovs-tap1
# attach one side to ovs
ovs-vsctl add-port $BRIDGE ovs-tap1
# attach the other side to namespace
ip link set tap1 netns ns1
# set the ports to up
ip netns exec ns1 ip link set dev tap1 up
ip link set dev ovs-tap1 up
#
#### PORT 2
# create a port pair
ip link add tap2 type veth peer name ovs-tap2
# attach one side to ovs
ovs-vsctl add-port $BRIDGE ovs-tap2
# attach the other side to namespace
ip link set tap2 netns ns2
# set the ports to up
ip netns exec ns2 ip link set dev tap2 up
ip link set dev ovs-tap2 up
#
Solution 4 : openvswitch and two openvswitch ports
Another solution is to use the openvswitch and make use of the openvswitch internal ports. This avoids the usage of the veth pairs, which must be used in all other solutions.
We need for this setup one switch, and two connectors. In this setup we use an openvswitch and two openvswitch ports.
# add the namespaces
ip netns add ns1
ip netns add ns2
# create the switch
$BRIDGE=ovs-test
ovs-vsctl add-br$BRIDGE
#
#### PORT 1
# create an internal ovs port
ovs-vsctl add-port$BRIDGEtap1–set Interfacetap1 type=internal
# attach it to namespace
ip linkset tap1 netns ns1
# set the ports to up
ip netns exec ns1 ip linkset dev tap1 up
#
#### PORT 2
# create an internal ovs port
ovs-vsctl add-port$BRIDGEtap2–set Interfacetap2 type=internal
# attach it to namespace
ip linkset tap2 netns ns2
# set the ports to up
ip netns exec ns2 ip linkset dev tap2 up
openvswitch and two openvswitch ports
Another solution is to use the openvswitch and make use of the openvswitch internal ports. This avoids the usage of the veth pairs, which must be used in all other solutions.
We need for this setup one switch, and two connectors. In this setup we use an openvswitch and two openvswitch ports.
# add the namespaces
ip netns add ns1
ip netns add ns2
# create the switch
$BRIDGE=ovs-test
ovs-vsctl add-br $BRIDGE
#
#### PORT 1
# create an internal ovs port
ovs-vsctl add-port $BRIDGE tap1 — set Interface tap1 type=internal
# attach it to namespace
ip link set tap1 netns ns1
# set the ports to up
ip netns exec ns1 ip link set dev tap1 up
#
#### PORT 2
# create an internal ovs port
ovs-vsctl add-port $BRIDGE tap2 — set Interface tap2 type=internal
# attach it to namespace
ip link set tap2 netns ns2
# set the ports to up
ip netns exec ns2 ip link set dev tap2 up
Switching Performance : Connecting Linux Network Namespaces
The openvswitch using two internal openvswitch ports has the best throughput and the best efficiency.
So if you are using a server platform, you should avoid veth pairs and linuxbridges. They just suck CPU cycles and are doing nothing useful.
Use the openvswitch together with ovs internal ports.
Openstack
If you are running Openstack Neutron, you should use the Openvswitch. Avoid linuxbridges. When connecting the Neutron networking Router/LBaas/DHCP namespaces DO NOT enable ovs_use_veth. If you enable this, the performance impact will be huge.