PolarSPARC

Hands-on Linux Virtual Ethernet (Veth)


Bhaskar S 01/24/2026


Overview


Most of us are familiar how networking works with physical machine(s) connected via a router. Ever wondered how networking works with container(s) ???

This is Virtual Networking in action !!!

In order to better understand virtual networking, one needs to first understand some important concepts in Linux.

A network namespace in Linux provides isolation of network resources, such as, interfaces, routing tables, firewall rules, network ports, etc., thereby enabling multiple container(s) or vm(s) to co-exist on a host system with their own isolated and private network environment.

A virtual ethernet device (or veth for short) in Linux are pairs of virtual network interfaces that are used for connecting two network namespaces in order to facilitate full duplex communication between them. Think of them as virtual ethernet cables connecting two network namespaces.

A bridge in Linux network operates at Layer 2 ( Data Link layer) of the OSI network model and acts like a virtual network switch, which enables two or more virtual interfaces communicate with one other as a single network segment.


Hands-on Virtual Ethernet (Veth)


All the commands will be executed on a Ubuntu 24.04 LTS based Linux desktop.

To list all the network namespaces in the system, execute the following command in a terminal window:


$ ip netns show


There will be no output as we have not defined any network namespaces yet !

For the hands-on demonstration, we will setup the virtual network topology as shown in the illustration below:


Virtual Network 1
Figure.1

To create the two network namespaces named ns1 and ns2, execute the following commands:


$ sudo ip netns add ns1

$ sudo ip netns add ns2


There will be no output.

To list all the network namespaces in the system, execute the following command in a terminal window:


$ ip netns show


The following would be a typical output:


Output.1

ns2
ns1

To list all the veth interfaces in the system, execute the following command in a terminal window:


$ ip link show type veth


There will be no output as we have not defined any veth interfaces yet !

To create the two veth pairs starting with names vth1_x and vth2_x, execute the following commands:


$ sudo ip link add name vth1_1 type veth peer vth1_2

$ sudo ip link add name vth2_1 type veth peer vth2_2


There will be no output.

To list all the veth interfaces in the system, execute the following command in a terminal window:


$ ip link show type veth


The following would be a typical output:


Output.2

5: vth1_2@vth1_1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 02:a8:b9:15:82:da brd ff:ff:ff:ff:ff:ff
6: vth1_1@vth1_2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 72:6f:16:6e:7c:3d brd ff:ff:ff:ff:ff:ff
7: vth2_2@vth2_1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 16:33:db:0d:8f:80 brd ff:ff:ff:ff:ff:ff
8: vth2_1@vth2_2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether ca:2e:57:3a:3e:e2 brd ff:ff:ff:ff:ff:ff

To connect one of the pairs of each veth interface to the respective network namespaces, execute the following commands:


$ sudo ip link set dev vth1_1 netns ns1

$ sudo ip link set dev vth2_1 netns ns2


There will be no output.

To bring up each of the connected end of the veth interface, execute the following commands:


$ sudo ip -n ns1 link set dev vth1_1 up

$ sudo ip -n ns2 link set dev vth2_1 up


There will be no output.

To assign ip address to each of the connected end of the veth interface, execute the following commands:


$ sudo ip -n ns1 address add 192.168.5.1/24 dev vth1_1

$ sudo ip -n ns2 address add 192.168.5.2/24 dev vth2_1


There will be no output.

Now, to create a bridge named br0, execute the following command:


$ sudo ip link add name br0 type bridge


There will be no output.

To list all the bridges in the system, execute the following command in a terminal window:


$ ip link show type bridge


The following would be a typical output:


Output.3

9: br0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether ea:10:9c:12:36:e1 brd ff:ff:ff:ff:ff:ff

To connect the other end of each of the veth interface to the bridge, execute the following commands:


$ sudo ip link set dev vth1_2 master br0

$ sudo ip link set dev vth2_2 master br0


There will be no output.

To bring up each of the just connected end of the veth interface to the bridge, execute the following commands:


$ sudo ip link set dev vth1_2 up

$ sudo ip link set dev vth2_2 up


There will be no output.

Finally, to bring up the bridge, execute the following command:


$ sudo ip link set dev br0 up


There will be no output.

To list all the interfaces including the bridges on the host, execute the following command:


$ ip link show


The following would be a typical output:


Output.4

5: vth1_2@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UP mode DEFAULT group default qlen 1000
    link/ether 02:a8:b9:15:82:da brd ff:ff:ff:ff:ff:ff link-netns ns1
7: vth2_2@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UP mode DEFAULT group default qlen 1000
    link/ether 16:33:db:0d:8f:80 brd ff:ff:ff:ff:ff:ff link-netns ns2
9: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether ea:10:9c:12:36:e1 brd ff:ff:ff:ff:ff:ff

As is evident from the Output.4 above, all the interfaces and the bridge are UP !

To check if one can the ip address 192.168.5.2 (which is in namespace ns2) from namespace ns1, execute the following command:


$ sudo ip netns exec ns1 ping -c 3 192.168.5.2


The following would be a typical output:


Output.5

PING 192.168.5.2 (192.168.5.2) 56(84) bytes of data.
64 bytes from 192.168.5.2: icmp_seq=1 ttl=64 time=0.068 ms
64 bytes from 192.168.5.2: icmp_seq=2 ttl=64 time=0.109 ms
64 bytes from 192.168.5.2: icmp_seq=3 ttl=64 time=0.121 ms

--- 192.168.5.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2072ms
rtt min/avg/max/mdev = 0.068/0.099/0.121/0.022 ms

Thats it - this concludes the hands-on demonstration of Linux virtual ethernet (veth) !!!



© PolarSPARC