Table of Contents

About

Sometimes it is useful to run all interfaces on a bridge in order to avoid having to manually route packets within the same machine. One good example is the usage of virtualization, specifically, libvirt and bridged networking where virtual machines bridge their virtual interface to the local machine bridge. In doing so, the virtual machine can access the network directly without any additional routing. As an usage scenario, if the wireless device can also be on the same bridge then the virtual machines can be accessed directly over wireless, thereby sparing the need of cables.

Wireless Clients Configuration

In order to bridge a wireless interface, the interface must support 4addr mode. This can be verified using iw:

iw dev wlan0 set 4addr on

where:

that should not return an error in case 4addr is supported. After that, the wireless device wlan0 can be bridged:

brctl addbr br0
brctl addif br0 wlan0

where:

Usually, the procedure to add a wireless interface to a bridge runs as follows, in order:

  1. enable 4addr on the wireless interface,
  2. add the interface to the bridge,
  3. use wpa_supplicant to authenticate to the AP,
  4. run a DHCP client on the bridge (in case DHCP is used) on the bridge to borrow an IP address

Here is an example of wpa_supplicant being used to authenticate to the AP:

wpa_supplicant -P /run/wpa_supplicant.pid -B -b br0 -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf

where:

Generating /etc/wpa_supplicant/wpa_supplicant.conf is a matter of running:

wpa_passphrase AP PASSPHRASE > /etc/wpa_supplicant/wpa_supplicant.conf

where:

Wireless Access Point Configuration

WDS must be enabled on the access point for 4addr to work. If hostapd is used, then the following configuration parameters must be added to the hostapd configuration file:

interface=wlan0
bridge=br0

wds_sta=1
wds_bridge=br0

where:

Fortunately, hostapd will set the interface too 4addr on its own so no other configuration is required.

ifupdown

Using ifupdown on Debian, the whole process can be reduced to setting up interfaces. Here is a complete configuration for a wireless client that bridges its wireless interface and uses DHCP to borrow an IP address from the local network.

Let's assume:

then, the following are the contents of the interface files created within /etc/network/interfaces.d.

eth0

The wired network device will be set to manual because it will just be bridged.

iface eth0 inet manual

wlan0

Even though the wireless interface wlan0 is set to manual due to being bridged, ifupdown scripts are leveraged to enable 4addr on the wireless interface.

auto wlan0
iface wlan0 inet manual
    pre-up iw dev wlan0 set 4addr on

br0

As per ifupdown the bridge is configured to bridge the local wired interface wlan0 but the wireless interface is bridged manually.

auto br0
iface br0 inet dhcp
    bridge_ports eth0
    bridge_stp on
    # fix PXE
    bridge_fd 2
    # bridge wlan0 interface manually
    pre-up ifup wlan0
    pre-up brctl addbr br0
    pre-up brctl addif br0 wlan0
    pre-up /usr/sbin/wpa_supplicant -P /run/wpa_supplicant.pid -B -b br0 -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf
    post-down kill -s TERM `cat /run/wpa_supplicant.pid`
    post-down brctl delif br0 wlan0
    post-down brctl delbr br0

There is no easy way to do this due to ifupdown lacking specific hooks to get everything to work together except to use shell scripts. Here is a rundown of what is happening here and why:

Were this to be done any other way, either 4addr would not be set on the wireless interface and then adding the wireless interface to the bridge as per:

iface br0 inet dhcp
    bridge_ports eth0 wlan0
    # ...

would fail due to wpa_supplicant not being launched soon enough.

Using an up script instead of a pre-up script, as in:

iface br0 inet dhcp
    bridge_ports eth0 wlan0
    # ...
    up /usr/sbin/wpa_supplicant -P /run/wpa_supplicant.pid -B -b br0 -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf
    # ...

would have the effect of wpa_supplicant being launched too late, before ifupdown launches a DHCP client to retrieve an IP address such that the bridge interface would end up with no address if wlan0 would be the only inteface.

The post-down scripts are just used to clean up were the bridge interface going down.