Like many people, I'm using a Raspberry Pi 4B running Ubuntu 20.10 arm64 as a LAN/wifi bridge, using hostapd and netplan. Everything works fine except that the bridge is not configured correctly when the machine reboots. brctl show shows that br0 only includes eth0 and not wlan0 as it should. However, running netplan apply or systemctl restart systemd-networkd after booting adds wlan0 to the bridge, and then everything else works.
/var/log/syslog includes the messages:
Jan 1 06:09:25 triangle systemd-networkd[1819]: br0: Link UP Jan 1 06:09:25 triangle systemd-networkd[1819]: wlan0: Could not join netdev: Device does not allow enslaving to a bridge. Operation not supported Jan 1 06:09:25 triangle systemd-networkd[1819]: wlan0: Failed and later:
Jan 1 06:09:25 triangle systemd-networkd[1819]: wlan0: Link UP Jan 1 06:09:25 triangle hostapd[1889]: wlan0: interface state UNINITIALIZED->COUNTRY_UPDATE Jan 1 06:09:25 triangle systemd-networkd[1819]: wlan0: Gained carrier Jan 1 06:09:25 triangle kernel: [ 21.926114] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready I think the problem is that when netplan runs at boot, the wlan0 interface is down, and so netplan fails to add it to the bridge. The interface comes up after hostapd finishes configuring it, but then it's too late.
I have worked around with @reboot sleep 5 ; /usr/bin/systemctl restart systemd-networkd in root's crontab, but is there a proper solution?
The contents of etc/netplan/01-netcfg.yaml are:
network: version: 2 renderer: networkd ethernets: eth0: dhcp4: no dhcp6: no wakeonlan: yes wlan0: optional: true bridges: br0: interfaces: [eth0, wlan0] dhcp4: yes parameters: stp: true forward-delay: 4 The contents of hostapd.conf are:
interface=wlan0 driver=nl80211 logger_syslog=-1 logger_syslog_level=2 logger_stdout=-1 logger_stdout_level=2 ctrl_interface=/var/run/hostapd ctrl_interface_group=0 ssid=xxxxxxxxxxxxxxxx country_code=US ieee80211d=1 ieee80211h=1 hw_mode=a channel=161 beacon_int=100 dtim_period=2 max_num_sta=255 rts_threshold=-1 fragm_threshold=-1 macaddr_acl=0 auth_algs=3 ignore_broadcast_ssid=0 wmm_enabled=1 wmm_ac_bk_cwmin=4 wmm_ac_bk_cwmax=10 wmm_ac_bk_aifs=7 wmm_ac_bk_txop_limit=0 wmm_ac_bk_acm=0 wmm_ac_be_aifs=3 wmm_ac_be_cwmin=4 wmm_ac_be_cwmax=10 wmm_ac_be_txop_limit=0 wmm_ac_be_acm=0 wmm_ac_vi_aifs=2 wmm_ac_vi_cwmin=3 wmm_ac_vi_cwmax=4 wmm_ac_vi_txop_limit=94 wmm_ac_vi_acm=0 wmm_ac_vo_aifs=2 wmm_ac_vo_cwmin=2 wmm_ac_vo_cwmax=3 wmm_ac_vo_txop_limit=47 wmm_ac_vo_acm=0 ieee80211n=1 ieee80211ac=1 eapol_key_index_workaround=0 eap_server=0 own_ip_addr=127.0.0.1 wpa=2 wpa_psk_file=/etc/hostapd/hostapd.wpa_psk wpa_key_mgmt=WPA-PSK wpa_pairwise=CCMP rsn_pairwise=CCMP 1 Answer
I met the same problem,on boot the wlan0 link set to client mode or so...
see the kernel source br_if.c#L605 here reject bridge func br_add_if
if (dev->priv_flags & IFF_DONT_BRIDGE) { NL_SET_ERR_MSG(extack, "Device does not allow enslaving to a bridge"); return -EOPNOTSUPP; } and when wlan device register wireless/core.c#L1305 set the IFF_DONT_BRIDGE flag
if ((wdev->iftype == NL80211_IFTYPE_STATION || wdev->iftype == NL80211_IFTYPE_P2P_CLIENT || wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr) wdev->netdev->priv_flags |= IFF_DONT_BRIDGE; it seems that networkd register wlan0 in module NL80211_IFTYPE_STATION on boot.
Fine! Here is my resolutions:
- Remove wlan0 from netplan, keep networkd unmanaged wlan0 link.
- Then,you may noticed that hostapd.conf has field like
bridge=br0,using that to bridge wlan0 to br0.
in your case the config are:
etc/netplan/01-netcfg.yaml
network: version: 2 renderer: networkd ethernets: eth0: dhcp4: no dhcp6: no wakeonlan: yes bridges: br0: interfaces: [eth0] dhcp4: yes parameters: stp: true forward-delay: 4 hostapd.conf
interface=wlan0 driver=nl80211 bridge=br0 logger_syslog=-1 ...