# Linux Network Namespace and Virtual Ethernet Namespaces provide a way to isolate from the processes running in a host and as well as for the host network and routing table. Containers uses namespaces to isolate itself from the rest of the host environment and from other containers. Let us try to understand how network namespaces and virtual ethernet devices work by building the topology as shown below. > NOTE:You need to use `sudo` to run some of the commands otherwise login as a root user. ![](https://hackmd.io/_uploads/H1Z3UE7Dn.png) ## Creating a network namespace To create a network namespace, do the following ```bash! ip netns add client ip netns add router ip netns add server ``` ## Listing the namespace ```bash root@dev:~# ip netns server router client ``` ## Listing interfaces ### On the Host To list the namespace on the host use `ip link` as shown below: ```bash root@dev:~# ip link 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000 link/ether 00:50:56:8a:05:c7 brd ff:ff:ff:ff:ff:ff altname enp3s0 ``` ### Within a namespace To see the same, within a namespace say `client`, prefix with `ip netns exec client` like the one shown below: ```bash root@dev:~# ip netns exec client ip link 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 ``` This will cause the `ip link` to be executed within the client namespace Alternatively, you could do the following ```bash ip -n client link ``` If you see now `client`, `server` and `router` name spaces do not have any links. ## Connecting namespaces ### Connecting client and router 1. Create a link between client and router by creating virtual ethernet devices as shown below: ```bash ip link add dev veth-cl type veth peer name veth-rt-cl; ``` 2. Set the interfaces to appropriate namespaces... ```bash ip link set dev veth-cl netns client ip link set dev veth-rt-cl netns router ``` 3. Bring up the devices... ```bash ip netns exec client ip link set dev veth-cl up; ip netns exec router ip link set dev veth-rt-cl up; ``` 3. Assign IP addresses... ```bash ip netns exec client ip addr add 192.168.11.1 dev veth-cl; ip netns exec router ip addr add 192.168.11.2 dev veth-rt-cl; ``` 4. Add a route to send packets out of client and router as follows ```bash ip netns exec client ip route add 192.168.11.0/24 dev veth-cl ip netns exec router ip route add 192.168.11.0/24 dev veth-rt-cl ``` 5. Try to ping the router interface connected to client from client ```bash ip netns exec client ping 192.168.11.2 ``` 6. Ping must be successfull... ### Connecting router and server 1. Create a link between server and router by creating virtual ethernet devices as shown below: ```bash ip link add dev veth-sr type veth peer name veth-rt-sr; ``` 2. Set the interfaces to appropriate namespaces... ```bash ip link set dev veth-sr netns server ip link set dev veth-rt-sr netns router ``` 3. Bring up the devices... ```bash ip netns exec server ip link set dev veth-sr up; ip netns exec router ip link set dev veth-rt-sr up; ``` 3. Assign IP addresses... ```bash ip netns exec server ip addr add 192.168.12.1 dev veth-sr; ip netns exec router ip addr add 192.168.12.2 dev veth-rt-sr; ``` 4. Add a route to send packets out of server ```bash ip netns exec server ip route add 192.168.12.0/24 dev veth-sr ip netns exec router ip route add 192.168.12.0/24 dev veth-rt-sr ``` 5. Try to ping the router interface connected to server from server ```bash ip netns exec server ping 192.168.12.2 ``` 6. Ping must be successfull... ### Enable IP forwarding on the router This is done by executing the following in router: ```bash ip netns exec router sysctl -w net.ipv4.ip_forward=1 ``` Now try to ping from client to server: ```bash ip netns exec client ping 192.168.12.1 ``` You will see as follows: ```bash root@dev:~# ip netns exec client ping 192.168.12.1 ping: connect: Network is unreachable ``` This is because there are no routes in client or server to reach each other. Let us now add default routes... ### Default Routes 1. Add default route in client ```bash ip netns exec client ip route add default via 192.168.11.2 ``` 2. Add default route in server ```bash ip netns exec server ip route add default via 192.168.12.2 ``` ## Success at last Now try to ping from client to server: ```bash ip netns exec client ping 192.168.12.1 ``` ```bash root@dev:~# ip netns exec client ping 192.168.12.1 PING 192.168.12.1 (192.168.12.1) 56(84) bytes of data. 64 bytes from 192.168.12.1: icmp_seq=1 ttl=63 time=0.260 ms 64 bytes from 192.168.12.1: icmp_seq=2 ttl=63 time=0.094 ms ``` It should be successful. ## Usefull commands for debugging 1. See what happens in router interface connected to client ```bash ip netns exec router tcpdump -i veth-rt-cl ```