hostapd: fix a race condition on adding AP mode wds sta interfaces
authorFelix Fietkau <nbd@nbd.name>
Wed, 20 Oct 2021 19:13:10 +0000 (21:13 +0200)
committerFelix Fietkau <nbd@nbd.name>
Tue, 23 Nov 2021 17:30:04 +0000 (18:30 +0100)
Both hostapd and netifd attempt to add a VLAN device to a bridge.
Depending on which one wins the race, bridge vlan settings might be incomplete,
or hostapd might run into an error and refuse to service the client.
Fix this by preventing hostapd from adding interfaces to the bridge and
instead rely entirely on netifd handling this properly

Signed-off-by: Felix Fietkau <nbd@nbd.name>
(cherry-picked from commit da4be02fcd5d642954b1c9d9855d9e8d1e6205f4)
(cherry-picked from commit 63c01ad025981eaa841353dc0fc27e5017febe21)

package/network/services/hostapd/files/hostapd.sh
package/network/services/hostapd/patches/711-wds_bridge_force.patch [new file with mode: 0644]
package/network/services/hostapd/patches/740-snoop_iface.patch

index b5388ee46c0daffd30b80d93bbb37b831dbe04c5..f79155221dcb00536a87b525f5c9bc6ea6ece224 100644 (file)
@@ -729,7 +729,7 @@ hostapd_set_bss_options() {
        }
 
        append bss_conf "ssid=$ssid" "$N"
-       [ -n "$network_bridge" ] && append bss_conf "bridge=$network_bridge" "$N"
+       [ -n "$network_bridge" ] && append bss_conf "bridge=$network_bridge${N}wds_bridge=" "$N"
        [ -n "$network_ifname" ] && append bss_conf "snoop_iface=$network_ifname" "$N"
        [ -n "$iapp_interface" ] && {
                local ifname
diff --git a/package/network/services/hostapd/patches/711-wds_bridge_force.patch b/package/network/services/hostapd/patches/711-wds_bridge_force.patch
new file mode 100644 (file)
index 0000000..d3f8864
--- /dev/null
@@ -0,0 +1,22 @@
+--- a/hostapd/config_file.c
++++ b/hostapd/config_file.c
+@@ -2357,6 +2357,8 @@ static int hostapd_config_fill(struct ho
+                          sizeof(conf->bss[0]->iface));
+       } else if (os_strcmp(buf, "bridge") == 0) {
+               os_strlcpy(bss->bridge, pos, sizeof(bss->bridge));
++              if (!bss->wds_bridge[0])
++                      os_strlcpy(bss->wds_bridge, pos, sizeof(bss->wds_bridge));
+       } else if (os_strcmp(buf, "vlan_bridge") == 0) {
+               os_strlcpy(bss->vlan_bridge, pos, sizeof(bss->vlan_bridge));
+       } else if (os_strcmp(buf, "wds_bridge") == 0) {
+--- a/src/ap/ap_drv_ops.c
++++ b/src/ap/ap_drv_ops.c
+@@ -340,8 +340,6 @@ int hostapd_set_wds_sta(struct hostapd_d
+               return -1;
+       if (hapd->conf->wds_bridge[0])
+               bridge = hapd->conf->wds_bridge;
+-      else if (hapd->conf->bridge[0])
+-              bridge = hapd->conf->bridge;
+       return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val,
+                                        bridge, ifname_wds);
+ }
index 8d928f8505594309adad476ba7814f88610778b0..d206ed73229b0abbe3b13d8ad724fa940aa14e67 100644 (file)
                           "x_snoop: Failed to initialize L2 packet processing %s",
 --- a/hostapd/config_file.c
 +++ b/hostapd/config_file.c
-@@ -2357,6 +2357,8 @@ static int hostapd_config_fill(struct ho
-                          sizeof(conf->bss[0]->iface));
-       } else if (os_strcmp(buf, "bridge") == 0) {
+@@ -2359,6 +2359,8 @@ static int hostapd_config_fill(struct ho
                os_strlcpy(bss->bridge, pos, sizeof(bss->bridge));
+               if (!bss->wds_bridge[0])
+                       os_strlcpy(bss->wds_bridge, pos, sizeof(bss->wds_bridge));
 +      } else if (os_strcmp(buf, "snoop_iface") == 0) {
 +              os_strlcpy(bss->snoop_iface, pos, sizeof(bss->snoop_iface));
        } else if (os_strcmp(buf, "vlan_bridge") == 0) {