[PATCH] nl80211: fix AP scan with STA fallback error path

Nicolas Escande nico.escande at gmail.com
Fri Apr 26 05:35:53 PDT 2024


I've run into a case where I can bring a 2.4GHz AP up whithout it being in a
bridge while I used the 'bridge=' config option. This happens when the HT scan
needed for 40MHz operation failed to start from the get go because another dev
on the same phy was already in a scan. At the end the AP is up and running but
not enslaved to any bridge.

Upon looking at the code, It seems that some hardware fails to issue a scan
while in AP and thus we have a fallback that switches the interface from AP to
STA before retrying another scan (it will change it back to AP later on when
finished). As we cannot have a (non wds) STA in a bridge, during that procedure,
we also remove/add the AP/STA from/to the bridge as needed.

However, in wpa_driver_nl80211_scan() we do not set drv->ap_scan_as_station
until the end of the switch-to-sta & retry-scan-start block. This means that
when the recursive call to wpa_driver_nl80211_scan() fails (the hardware is busy
in my case) we restore the interface to AP with wpa_driver_nl80211_set_mode()
but that will not add it back to the bridge. Problem.

To Fix this lets always set drv->ap_scan_as_station before calling
wpa_driver_nl80211_set_mode(). In case wpa_driver_nl80211_set_mode() or
wpa_driver_nl80211_scan() fails lets call nl80211_restore_ap_mode() that will
set the mode back to AP but also handle the bridge thing as needed.

Signed-off-by: Nicolas Escande <nico.escande at gmail.com>
---
 src/drivers/driver_nl80211_scan.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/src/drivers/driver_nl80211_scan.c b/src/drivers/driver_nl80211_scan.c
index 1eb437405..621667c4f 100644
--- a/src/drivers/driver_nl80211_scan.c
+++ b/src/drivers/driver_nl80211_scan.c
@@ -402,23 +402,18 @@ int wpa_driver_nl80211_scan(struct i802_bss *bss,
 		wpa_printf(MSG_DEBUG, "nl80211: Scan trigger failed: ret=%d "
 			   "(%s)", ret, strerror(-ret));
 		if (drv->hostapd && is_ap_interface(drv->nlmode)) {
-			enum nl80211_iftype old_mode = drv->nlmode;
-
 			/*
 			 * mac80211 does not allow scan requests in AP mode, so
 			 * try to do this in station mode.
 			 */
+			drv->ap_scan_as_station = drv->nlmode;
 			if (wpa_driver_nl80211_set_mode(
-				    bss, NL80211_IFTYPE_STATION))
-				goto fail;
-
-			if (wpa_driver_nl80211_scan(bss, params)) {
-				wpa_driver_nl80211_set_mode(bss, old_mode);
+						bss, NL80211_IFTYPE_STATION) ||
+			    wpa_driver_nl80211_scan(bss, params)) {
+				nl80211_restore_ap_mode(bss);
 				goto fail;
 			}
 
-			/* Restore AP mode when processing scan results */
-			drv->ap_scan_as_station = old_mode;
 			ret = 0;
 		} else
 			goto fail;
-- 
2.44.0




More information about the Hostap mailing list