Bridge VLAN

Linux bridge as a virtual switch. VLAN filtering, PVID configuration, ephemeral vs persistent settings, and the Cisco-to-Linux mental model.

Concept: Linux Bridge as a Virtual Switch

A Linux bridge is a virtual Cisco switch inside the server.

Linux Cisco Equivalent Purpose

br-mgmt

Virtual switch

Connects VMs and physical uplink

eno8 (bridge port)

Trunk uplink

10GbE to physical switch

vnet0, vnet1…​

Access/trunk ports

Each VM NIC gets a vnet

PVID

Native VLAN

Untagged traffic gets this VLAN tag

bridge vlan add

switchport trunk allowed vlan add

Tags a port for a VLAN

VLAN filtering

Per-port VLAN enforcement

When on, VLANs are enforced; when off, all traffic passes

Viewing VLAN State

Show VLAN assignments on all bridge ports
bridge vlan show
Show VLANs on a specific port
bridge vlan show dev eno8
bridge vlan show dev br-mgmt
Expected output — PVID 100, no VLAN 1
port              vlan-id
eno8              10
                  20
                  30
                  40
                  100 PVID Egress Untagged
                  110
                  120
Check if VLAN filtering is enabled
cat /sys/class/net/br-mgmt/bridge/vlan_filtering
# 1 = enabled (VLANs enforced), 0 = disabled (all traffic passes)

Modifying VLANs (Ephemeral)

bridge vlan commands are ephemeral — lost on reboot. Use nmcli connection modify for persistence. See nmcli codex entry.
Enable VLAN filtering
sudo ip link set br-mgmt type bridge vlan_filtering 1
Remove default VLAN 1
sudo bridge vlan del vid 1 dev eno8
sudo bridge vlan del vid 1 dev br-mgmt self
The self flag targets the bridge device itself, not a port on the bridge. Without self, the command targets the port.
Add tagged VLANs
for vid in 10 20 30 40 110 120; do
  sudo bridge vlan add vid $vid dev eno8
  sudo bridge vlan add vid $vid dev br-mgmt self
done
Set PVID (native VLAN) — must come after tagged VLANs
sudo bridge vlan add vid 100 dev eno8 pvid untagged
sudo bridge vlan add vid 100 dev br-mgmt self pvid untagged

Complete Bridge VLAN Fix Script

Production script — run from IPMI/console, never SSH
#!/bin/bash
# Fix br-mgmt VLAN config — PVID 100, remove VLAN 1
# Run: sudo bash /tmp/fix-bridge-vlans.sh

echo "=== Before ==="
bridge vlan show dev eno8
bridge vlan show dev br-mgmt

bridge vlan del vid 1 dev eno8
bridge vlan del vid 1 dev br-mgmt self

for vid in 10 20 30 40 110 120; do
  bridge vlan add vid $vid dev eno8
  bridge vlan add vid $vid dev br-mgmt self
done

bridge vlan add vid 100 dev eno8 pvid untagged
bridge vlan add vid 100 dev br-mgmt self pvid untagged

echo "=== After ==="
bridge vlan show dev eno8
bridge vlan show dev br-mgmt

ping -c 2 10.50.1.1 && echo "Gateway OK" || echo "Gateway FAILED"

Fixing VM vnet VLANs

Manually apply PVID 100 to all vnets — when libvirt hook doesn’t fire
for vnet in $(ip link show master br-mgmt 2>/dev/null | awk -F': ' '/vnet/{print $2}'); do
  sudo bridge vlan del vid 1 dev $vnet pvid untagged 2>/dev/null
  for vid in 10 20 30 40 100 110 120; do
    sudo bridge vlan add vid $vid dev $vnet
  done
  sudo bridge vlan add vid 100 dev $vnet pvid untagged
done

Persistence: nmcli vs bridge vlan

Make bridge VLAN config survive reboot — nmcli is authoritative
sudo nmcli connection modify br-mgmt \
  bridge.vlan-filtering yes \
  bridge.vlan-default-pvid 0 \
  bridge.vlans "100 pvid untagged, 10, 20, 30, 40, 110, 120"
Verify persistent config
nmcli c s br-mgmt | grep bridge.vlan

Bridge Inspection

Show which interfaces are members of the bridge
bridge link show
ip link show master br-mgmt
Show FDB (MAC table) — which MACs are learned on which vnets
bridge fdb show br br-mgmt | awk '/52:54:00/'
Port inventory — state, speed, bridge membership
for port in eno{1..8}; do
  state=$(cat /sys/class/net/$port/operstate 2>/dev/null || echo "missing")
  speed=$(cat /sys/class/net/$port/speed 2>/dev/null || echo "?")
  master=$(ip link show $port 2>/dev/null | awk -F'master ' '{print $2}' | awk '{print $1}')
  printf "%-6s  %-6s  %5sMbps  %s\n" "$port" "$state" "$speed" "${master:-[none]}"
done

Critical Rules

  1. Never modify bridge VLANs over SSH — use IPMI/console. PVID changes can isolate the host from the network.

  2. PVID on eno8 must match the switch trunk native VLAN — mismatch means no communication.

  3. bridge vlan is ephemeral, nmcli is persistent — use both: nmcli for boot, bridge vlan for runtime fixes.

  4. self flag matters — without it, you’re configuring a port on the bridge, not the bridge device itself.

See Also

  • nmcli — persistent bridge VLAN configuration

  • Bridge (Networking) — bridge inspection, VM mapping, troubleshooting

  • virsh — VM network interface management