# 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.

## 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
```