hostapd: shut down client mode on the same phy while restarting AP
authorFelix Fietkau <nbd@nbd.name>
Fri, 11 Aug 2023 13:45:14 +0000 (15:45 +0200)
committerFelix Fietkau <nbd@nbd.name>
Fri, 11 Aug 2023 21:29:22 +0000 (23:29 +0200)
An active client mode interface could prevent the AP from claiming its channel
and mess up the bringup sequence order

Signed-off-by: Felix Fietkau <nbd@nbd.name>
package/network/services/hostapd/files/hostapd.uc
package/network/services/hostapd/files/wpa_supplicant.uc

index 9bb8f8d29de0d40b44f461109353aff34794bcbd..401f7c92662d43bdfc8a43a75cea6fab574925b1 100644 (file)
@@ -66,10 +66,12 @@ function iface_restart(phy, config, old_config)
        if (err)
                hostapd.printf(`Failed to create ${bss.ifname} on phy ${phy}: ${err}`);
        let config_inline = iface_gen_config(phy, config);
-       if (hostapd.add_iface(`bss_config=${bss.ifname}:${config_inline}`) < 0) {
+
+       let ubus = hostapd.data.ubus;
+       ubus.call("wpa_supplicant", "phy_set_state", { phy: phy, stop: true });
+       if (hostapd.add_iface(`bss_config=${bss.ifname}:${config_inline}`) < 0)
                hostapd.printf(`hostapd.add_iface failed for phy ${phy} ifname=${bss.ifname}`);
-               return;
-       }
+       ubus.call("wpa_supplicant", "phy_set_state", { phy: phy, stop: false });
 }
 
 function array_to_obj(arr, key, start)
index 412f87b4b18478f5e444dc83c360c8334243483f..6308fd54e2d332140c3e914f3d5689c3a2340a8c 100644 (file)
@@ -11,6 +11,9 @@ function iface_stop(iface)
 {
        let ifname = iface.config.iface;
 
+       if (!iface.running)
+               return;
+
        delete wpas.data.iface_phy[ifname];
        wpas.remove_iface(ifname);
        wdev_remove(ifname);
@@ -40,7 +43,7 @@ function iface_cb(new_if, old_if)
                return;
        }
 
-       if (old_if && old_if.running)
+       if (old_if)
                iface_stop(old_if);
 }
 
@@ -76,6 +79,28 @@ function start_pending(phy_name)
 }
 
 let main_obj = {
+       phy_set_state: {
+               args: {
+                       phy: "",
+                       stop: true,
+               },
+               call: function(req) {
+                       if (!req.args.phy || req.args.stop == null)
+                               return libubus.STATUS_INVALID_ARGUMENT;
+
+                       let phy = wpas.data.config[req.args.phy];
+                       if (!phy)
+                               return libubus.STATUS_NOT_FOUND;
+
+                       if (req.args.stop) {
+                               for (let ifname in phy.data)
+                                       iface_stop(phy.data[ifname]);
+                       } else {
+                               start_pending(req.args.phy);
+                       }
+                       return 0;
+               }
+       },
        config_set: {
                args: {
                        phy: "",