Troubleshooting Linux Bridge Packet Forwarding Issues in Virtualized Environments


2 views

When setting up a Linux bridge between two Ethernet interfaces in a virtualized environment (Hyper-V in this case), several configuration elements need to be verified:

# Sample bridge configuration (/etc/conf.d/net)
bridge_br0=("eth0 eth1")
config_eth0=("null")
config_eth1=("null")
config_br0=("192.168.1.197 netmask 255.255.255.0 brd 192.168.1.255")
routes_br0=("default via 192.168.1.101")

First, check if the bridge is properly created and interfaces are added:

# brctl show
bridge name     bridge id             STP enabled     interfaces
br0             8000.00155d000108     no              eth0
                                                        eth1

The forwarding state of each interface is crucial:

# brctl showstp br0
eth0 (1)               state               forwarding
eth1 (2)               state               forwarding

Several kernel parameters affect bridge packet forwarding:

# /etc/sysctl.conf settings
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-arptables = 0
net.bridge.bridge-nf-call-iptables = 0

Verify that MAC addresses are being learned correctly:

# brctl showmacs br0
port no mac addr                is local?    ageing timer
  1     00:15:5d:00:01:03       no           1.51
  1     00:15:5d:00:01:08       yes          0.00
  2     00:15:5d:00:01:12       no          36.22
  2     00:15:5d:00:01:13       yes          0.00

When working with Hyper-V or other hypervisors:

  • Ensure promiscuous mode is enabled for virtual switches
  • Verify that MAC address spoofing is allowed
  • Check for VLAN tagging conflicts

Additional diagnostic tools can help identify issues:

# Check bridge filtering
ebtables -L --Lc

# Monitor bridge traffic
tcpdump -i br0 -nn -e

# Verify ARP entries
arp -n

For modern Linux systems, consider using iproute2 instead of brctl:

# Create bridge with iproute2
ip link add name br0 type bridge
ip link set dev eth0 master br0
ip link set dev eth1 master br0
ip link set br0 up

After making changes, verify connectivity:

# From bridge host
ping 192.168.1.195  # NUX3
ping 192.168.1.101  # Router

# From NUX3
ping 192.168.1.197  # Bridge
ping 192.168.1.101  # Router

We're working with a virtualized environment where:

  • NUX3 (192.168.1.195/24) connects to eth1
  • Router (192.168.1.101/24) connects to eth0
  • Bridge br0 has IP 192.168.1.197/24

The bridge is correctly set up with both interfaces showing as forwarding:

# brctl showstp br0
eth0 (1)               state               forwarding
eth1 (2)               state               forwarding

However, connectivity fails between NUX3 and the bridge/router despite proper MAC address learning:

# brctl showmacs br0
port no mac addr                    is local?        ageing timer
  1     00:15:5d:00:01:03           no                   1.51
  1     00:15:5d:00:01:08           yes                  0.00
  2     00:15:5d:00:01:12           no                  36.22
  2     00:15:5d:00:01:13           yes                  0.00

First, verify the bridge filtering database:

# bridge fdb show
00:15:5d:00:01:03 dev eth0
00:15:5d:00:01:12 dev eth1

Check for VLAN filtering (common issue in virtualized environments):

# bridge vlan show
port    vlan ids
eth0     1 PVID Egress Untagged
eth1     1 PVID Egress Untagged
br0      1 PVID Egress Untagged

For Hyper-V virtual switches, ensure MAC address spoofing is enabled:

# Check if NICs are in promiscuous mode
# ip link show eth0
# ip link show eth1

Verify the virtual switch configuration in Hyper-V Manager:

  • Ensure the vSwitch is in External mode
  • Check "Allow management OS to share this network adapter"
  • Enable MAC address spoofing for both NICs

Packet capture verification:

# tcpdump -i eth0 -n -e
# tcpdump -i eth1 -n -e
# tcpdump -i br0 -n -e

Bridge monitoring:

# watch -n 1 "brctl showmacs br0"

Try these configuration adjustments:

# Disable bridge netfilter completely
echo 0 > /proc/sys/net/bridge/bridge-nf-call-iptables
echo 0 > /proc/sys/net/bridge/bridge-nf-call-ip6tables
echo 0 > /proc/sys/net/bridge/bridge-nf-call-arptables

# Set bridge forward delay to 0
brctl setfd br0 0

# Enable hairpin mode (for virtualized environments)
brctl hairpin br0 eth0 on
brctl hairpin br0 eth1 on

Alternative configuration file (/etc/network/interfaces style):

auto br0
iface br0 inet static
    address 192.168.1.197
    netmask 255.255.255.0
    gateway 192.168.1.101
    bridge_ports eth0 eth1
    bridge_stp off
    bridge_fd 0
    bridge_maxwait 0

Check kernel bridging statistics:

# cat /sys/class/net/br0/bridge/forward_delay
# cat /sys/class/net/br0/bridge/stp_state

Monitor bridge traffic with counters:

# brctl showstp br0 | grep -A 10 transmitted
# ethtool -S eth0 | grep -i discard
# ethtool -S eth1 | grep -i discard

After applying changes, verify with:

# ping -I br0 192.168.1.101
# ping -I br0 192.168.1.195
# arping -I br0 192.168.1.195
# tracepath -n 192.168.1.195