How Linux Bridges Work: A Step‑by‑Step Guide with veth and IP Configuration
This tutorial walks through creating and configuring a Linux bridge, connecting it to veth pairs and a physical NIC, assigning IPs, troubleshooting ARP issues, and demonstrates common use cases for virtual machines and Docker containers.
What Is a Bridge?
A bridge is a virtual network device that can be configured with IP and MAC addresses, essentially acting as a virtual switch with functionality similar to a physical switch.
Unlike a typical network device that has only two ends, a bridge has multiple ports and forwards traffic based on MAC addresses, much like a physical switch.
Creating a Bridge
Use iproute2 to create a bridge:
sudo ip link add name br0 type bridge
sudo ip link set br0 upWhen first created, the bridge has only one port connected to the protocol stack and no functional ports:
+----------------------------------------------------------------+
| |
| +------------------------------------------------+ |
| | Network Protocol Stack | |
| +------------------------------------------------+ |
| ↑ ↑ |
|..............|................................|................|
| ↓ ↓ |
| +----------+ +------------+ |
| | eth0 | | br0 | |
| +----------+ +------------+ |
| 192.168.3.21 ↑ |
| | |
| | |
+--------------|-------------------------------------------------+
↓
Physical NetworkAssume eth0 is the physical NIC with IP 192.168.3.21 and gateway 192.168.3.1 .
Connecting the Bridge to veth Devices
Create a veth pair and assign IPs:
sudo ip link add veth0 type veth peer name veth1
sudo ip addr add 192.168.3.101/24 dev veth0
sudo ip addr add 192.168.3.102/24 dev veth1
sudo ip link set veth0 up
sudo ip link set veth1 upAttach veth0 to br0:
sudo ip link set dev veth0 master br0
# Show devices attached to br0
sudo bridge linkResulting network diagram:
+----------------------------------------------------------------+
| |
| +------------------------------------------------+ |
| | Network Protocol Stack | |
| +------------------------------------------------+ |
| ↑ ↑ | ↑ |
|............|............|..............|............|..........|
| ↓ ↓ ↓ ↓ |
| +------+ +--------+ +-------+ +-------+ |
| | .3.21| | | | .3.101| | .3.102| |
| +------+ +--------+ +-------+ +-------+ |
| | eth0 | | br0 |<--->| veth0 | | veth1 | |
| +------+ +--------+ +-------+ +-------+ |
| ↑ ↑ ↑ |
| | | | |
| | +------------+ |
| | |
+------------|---------------------------------------------------+
↓
Physical NetworkAfter linking, the following changes occur:
br0 and veth0 are connected with a bidirectional channel.
The protocol stack and veth0 become a single‑direction channel; the stack can send data to veth0, but data received by veth0 is not forwarded back to the stack.
br0 adopts veth0's MAC address.
Effectively, the bridge inserts itself between the protocol stack and veth0, intercepting traffic and forwarding it to the bridge.
Testing Connectivity
Ping from veth0 to veth1 fails:
ping -c 1 -I veth0 192.168.3.102
# Destination Host UnreachablePacket capture shows ARP requests and replies are exchanged, but the reply is delivered to br0 instead of the protocol stack, preventing the stack from learning veth1 's MAC address.
# Capture on veth1
sudo tcpdump -n -i veth1
# Capture on veth0
sudo tcpdump -n -i veth0
# Capture on br0 (only the reply is seen)
sudo tcpdump -n -i br0The analysis reveals that after receiving the ARP reply, veth0 forwards the packet to br0, so the protocol stack never receives the MAC address of veth1, causing the ping failure.
Assigning an IP to the Bridge
Since assigning an IP to veth0 is ineffective, move the IP to the bridge:
sudo ip addr del 192.168.3.101/24 dev veth0
sudo ip addr add 192.168.3.101/24 dev br0Now ping through br0 succeeds:
ping -c 1 -I br0 192.168.3.102
# 64 bytes from 192.168.3.102Ping to the gateway still fails because the bridge knows only the two internal addresses and has no route to 192.168.3.1.
Adding the Physical NIC to the Bridge
Attach eth0 to br0:
sudo ip link set dev eth0 master br0
sudo bridge linkAfter the attachment, eth0 behaves like a cable; traffic received on the external network is forwarded to br0. Ping via eth0 still fails, but ping via br0 succeeds because the bridge now has a path to the external switch.
# Ping via eth0 (fails)
ping -c 1 -I eth0 192.168.3.1
# Ping via br0 (succeeds)
ping -c 1 -I br0 192.168.3.1
# Ping via veth1 (succeeds)
ping -c 1 -I veth1 192.168.3.1Since eth0 no longer provides a useful IP, remove it to avoid routing conflicts: sudo ip addr del 192.168.3.21/24 dev eth0 Update the routing table accordingly; if a default route is needed, add it back manually:
sudo ip route add default via 192.168.3.1Important Tips
If running inside a VM, enable promiscuous mode on the virtual NIC; otherwise packets destined for veth1 may be dropped.
Linux's ARP handling may reply with two ARP responses (one for br0, one for veth1), causing occasional traffic to be received on the wrong interface. Tweaking rp_filter, arp_filter, etc., can mitigate this but is complex.
In wireless environments, the access point expects a single MAC address. Align the MAC addresses of all devices attached to the bridge with the physical NIC's MAC to avoid connectivity issues.
Does a Bridge Need an IP?
Physical switches may or may not have an IP for management. A Linux bridge also has a virtual NIC that can be assigned an IP for remote configuration, but the bridge's forwarding functionality does not depend on that IP.
Removing the IP from br0 does not affect intra‑bridge communication; devices can still ping the gateway as long as the bridge remains connected to a physical NIC. sudo ip addr del 192.168.3.101/24 dev br0 After removal, the network still functions and can reach the gateway.
Common Bridge Use Cases
Virtual Machines
VMs use tun/tap or similar virtual NICs that connect to br0. Packets from the VM go to the bridge first, then out through eth0 without passing the host's protocol stack, offering high efficiency.
Docker Containers
Containers run in separate network namespaces and connect to the bridge via a veth pair. Traffic passes through the host's stack and typically requires NAT, which adds overhead compared to the VM scenario.
Both deployment models give each interface its own protocol stack, avoiding the multiple‑ARP issue described earlier.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Open Source Linux
Focused on sharing Linux/Unix content, covering fundamentals, system development, network programming, automation/operations, cloud computing, and related professional knowledge.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
