Translation(s): English - Français - Português (Brasil)


Information about sending packets between multiple physical networks (e.g. a device's WiFi and wired networks) as if they were all connected to each other. For general information about network configuration, see NetworkConfiguration.

Use cases for bridges include:

Installing the software

Install bridge-utils, which teaches /etc/network/interfaces about bridge-utils-interfaces, and lets you create bridge virtual network interfaces (like eth0 or eth1 but not associated with a physical device).

Setting up your Bridge

/!\ some routers block unauthorized switches (e.g. by detecting BPDU packets). If your machine refuses to work after you set it up, you may need to change the router's configuration.

Manual bridge setup

Create the bridge device:

sudo brctl addbr br0

br0 ("bridge 0") is a good default name, but you might prefer e.g. bridge1, mylan, or something more appropriate for your use case.

Check which interfaces exist on your computer:

# Should print e.g. "1: lo: ...", "2: eno1: ...", "3: eno2: ..."  etc.:
sudo ip addr show | grep ^[0-9]

Add all the interfaces you want to the bridge:

sudo brctl addif br0 eno1 eno2 ...

Finally, bring your bridge up:

sudo ifup br0

ip addr should show your bridge exists, but still needs to be configured.

Configuring bridging in /etc/network/interfaces

Edit /etc/network/interfaces to make your bridge configuration permanent.

Assuming your device names are br0, eno1 and eno2, and you want to use DHCP, your /etc/network/interfaces should look something like this:

# The loopback network interface
auto lo
iface lo inet loopback

# Set up interfaces manually, avoiding conflicts with, e.g., network manager
iface eno1 inet manual
iface eno2 inet manual

# Bridge setup
auto br0
iface br0 inet dhcp
    bridge_ports eno1 eno2

For static IP address, change the "Bridge setup" section to look something like this:

# Bridge setup
auto br0
iface br0 inet static
    bridge_ports eth0 eth1
    address 192.168.1.2
    broadcast 192.168.1.255
    netmask 255.255.255.0
    gateway 192.168.1.1

You can even set bridge_ports with a regular expression. For example, to select anything that begins with e or w (eno1, wifi2 etc.), do:

# Bridge setup
auto br0
iface br0 inet dhcp
    bridge_ports regex (e|w).*

Restart networking to apply your changes:

sudo systemctl restart networking
# or sudo systemctl restart network-manager

Useful options for virtualised environments

Some other useful options to use in any stanza in a virtualised environment are:

  bridge_stp off          # disable Spanning Tree Protocol
  bridge_waitport 0       # no delay before a port becomes available
  bridge_fd 0             # no forwarding delay
  bridge_ports none       # if you do not want to bind to any ports
  bridge_ports regex eth* # use a regular expression to define ports

There are several kernel variables that affect bridge operation. In some cases you may need to put them in a sysctl configuration file like /etc/sysctl.d/bridge_local.conf.

Libvirt and bridging

Libvirt is a virtualization API that supports KVM (and various other virtualization technologies). It's often desirable to share a physical network interface with guests by creating a bridge. This usually offers excellent performance and doesn't require NAT. This operation is composed of two parts:

The libvirt Networking Handbook provides thorough instructions.

You can verify if bridging is working properly by looking at brctl output:

root@server:/etc/libvirt/qemu# brctl show
bridge name     bridge id               STP enabled     interfaces
br0             8000.001ec952d26b       yes             eth0
                                                        vnet0
                                                        vnet1
                                                        vnet2
virbr0          8000.000000000000       yes

As can be seen, guest network interfaces vnet0, vnet1 and vnet2 are bound with the physical interface eth0 in the bridge br0. The virbr0 interface is only used by libvirt to give guests NAT connectivity.

Bridging with a wireless NIC

Just like you can bridge two wired ethernet interfaces, you can bridge between an ethernet interface and a wireless interface. However, most Access Points (APs) will reject frames that have a source address that didn’t authenticate with the AP. Since Linux does ethernet bridging transparently (doesn’t modify outgoing or incoming frames), we have to set up some rules to do this with a program called ebtables.

For an alternative Layer 3 approach using proxy ARP and routing, see BridgeNetworkConnectionsProxyArp.

ebtables Overview

ebtables is essentially like iptables, except it operates on the MAC sublayer of the data-link layer of the OSI model, instead of the network layer. In our case, this allows to change the source MAC address of all of our frames. This is handy because we fool our AP into thinking that all of our forwarded frames come from the machine which authenticated to the AP.

bridge-utils Modifications

Before this will work, you need to modify your /etc/network/interfaces file, and add this line to your bridge stanza:

 pre-up iwconfig wlan0 essid $YOUR_ESSID
 bridge_hw $MAC_ADDRESS_OF_YOUR_WIRELESS_CARD

Obviously replacing $MAC_ADDRESS_OF_YOUR_WIRELESS_CARD with the actual MAC address of your wireless card, and $YOUR_ESSID as the ESSID of your wireless network. If you don’t know your MAC address, you can find it by typing

 # ip link show wlan0

Where wlan0 is your wireless interface. Your MAC address is listed as the HWaddr.

Setting up the rules

First, install ebtables:

 # aptitude install ebtables

Now we can start setting up the rules. The syntax for ebtables is almost identical to that of iptables, so if you have experience with iptables, this will look pretty familiar to you.

The first rule we’re going to set up will set the source MAC address to the MAC address of the bridge for all frames sent to the AP.

sudo ebtables -t nat -A POSTROUTING -o wlan0 -j snat --to-src $MAC_OF_BRIDGE --snat-arp --snat-target ACCEPT

The next rules will require you to know the MAC and IP of each of the machines behind your bridge. Replace $MAC and $IP with these.

sudo ebtables -t nat -A PREROUTING -p IPv4 -i wlan0 --ip-dst $IP -j dnat --to-dst $MAC --dnat-target ACCEPT
sudo ebtables -t nat -A PREROUTING -p ARP -i wlan0 --arp-ip-dst $IP -j dnat --to-dst $MAC --dnat-target ACCEPT

This is tedious to have to type in everytime you add a new computer to a switch behind your bridge, so I wrote a script to do it for you

#!/bin/bash
# addcomputer
# Will Orr - 2009

INIF="wlan0"

function add_ebtables () {
  COMPIP=$1
  COMPMAC=$2

  ebtables -t nat -A PREROUTING -i $INIF -p IPv4 --ip-dst $COMPIP -j \
  dnat --to-dst $COMPMAC --dnat-target ACCEPT
  ebtables -t nat -A PREROUTING -i $INIF -p ARP --arp-ip-dst $COMPIP \
  -j dnat --to-dst $COMPMAC --dnat-target ACCEPT

}

if [[ $# -ne 2 ]]; then
  echo "Usage: $0 ip mac"
elif [[ $(whoami) != "root" ]]; then
  echo "Error: must be root"
else
  add_ebtables $1 $2
fi

Saving your rules

After you have written your ebtables rules, you need to save them in an atomic file. Otherwise, your rules will not be preserved. Saving them is rather simple though.

sudo EBTABLES_ATOMIC_FILE=/root/ebtables-atomic ebtables -t nat --atomic-save

And then load them like this:

sudo EBTABLES_ATOMIC_FILE=/root/ebtables-atomic ebtables -t nat --atomic-commit

If you want to load your ebtables rules at boot time, a handy place to stick the commit command is in /etc/rc.local. Just pop it in there before the exit 0 line.

Bridging without switching

By default, the Linux "bridge" actually acts like a switch - it sends packets via the previously-seen port for known MAC addresses, instead of broadcasting to all ports. You can change to dumb "bridge" behaviour by adding these to the relevant part of /etc/network/interfaces:

    up /sbin/brctl setageing br0 0
    up /sbin/brctl stp br0 off

{i} Linux bridges do not support dedicated MAC address tables per VLAN, so you will need dumb bridge behaviour if you have a bridge where the same MAC addresses can be seen from both interfaces, but with a different VLAN.

Link Aggregation (LACP) with VLANs

Here is an example of the /etc/network/interfaces file for 2 interfaces LACP bonded together with VLANs defined on top of the bond.

Notes: Tested on Debian Jessie 8.0 rc1 on 3/11/2015 (AMD64 arch)

Required debian packages for vlan and bonding:

aptitude install vlan ifenslave
echo "8021q" >> /etc/modules

The /etc/network/interfaces could be:

auto lo
iface lo inet loopback
# there is one other thing I am forgetting here... see bonding setup above

###### Bonded 10Gig setup - LACP Aggregation #######  bond eth4 and eth5
#### (set up from switch as trunk links with LACP)  then split out VLANS

## View status with:   cat /proc/net/bonding/bond0

auto bond0
iface bond0 inet manual
        up ifconfig bond0 0.0.0.0 up
        slaves eth4 eth5
# bond-mode 4 = 802.3ad
        bond-mode 4
        bond-miimon 100
        bond-downdelay 200
        bond-updelay 200
        bond-lacp-rate 1
        bond-xmit-hash-policy layer2+3


auto vlan1023
iface vlan1023 inet static

        address 18.28.4.123
        netmask 255.255.255.0
        gateway 18.28.4.1
        vlan-raw-device bond0


auto vlan1024
iface vlan1024 inet static

        address 10.15.160.1
        netmask 255.255.255.0
        gateway 10.15.160.100
        vlan-raw-device bond0

Example configurations

Connect a server to 2 switches

Connect a server to 2 switches (via eno1 and eno2) by defining bridge 0, and give the server an IP address in this subnet:

auto br0
iface br0 inet static
    address 10.10.0.15/24
    gateway 10.10.0.1
    bridge_ports eno1 eno2
    up /usr/sbin/brctl stp br0 on

The brctl command above enables the spanning tree protocol, which avoid loops when the server is connected to multiple switches.

Create a bridge without an IP address

Bridge setup without IP address configuration (use "manual" instead of "static") to "forward" an interface to a guest VM. The static bridge config contains only 1 physical interface. The virtual interface will be added to the bridge when the VM is started.

auto br1
iface br1 inet manual
        bridge_ports eno5
        up /usr/sbin/brctl setageing br1 0
        up /usr/sbin/brctl stp br1 off

Note: The Linux bridge only supports STP, not RSTP (Rapid Spanning Tree). Therefore it supports only the old STP Costs, not the new RSTP Costs (see Spanning_Tree_Protocol). This is usually fine with Cisco Switches, but eg. Juniper switches use the RSTP costs and therefore this may lead to different spanning tree calculations and loop problems. This can be fixed by setting the costs manually, either on the switch or on the server. Setting the cost on the switch is preferred as Linux changes back to the default costs whenever an interface goes down/up.

More information


CategoryNetwork