[openwrt/openwrt] wpa_supplicant: fix getting phy status and setting state for MLD

LEDE Commits lede-commits at lists.infradead.org
Thu Sep 25 03:09:07 PDT 2025


nbd pushed a commit to openwrt/openwrt.git, branch main:
https://git.openwrt.org/8c37f5f2f2c07ed02f39adc179c0e28afc23914e

commit 8c37f5f2f2c07ed02f39adc179c0e28afc23914e
Author: Felix Fietkau <nbd at nbd.name>
AuthorDate: Wed Sep 24 19:46:36 2025 +0200

    wpa_supplicant: fix getting phy status and setting state for MLD
    
    Fixes some AP+STA related issues
    
    Signed-off-by: Felix Fietkau <nbd at nbd.name>
---
 .../services/hostapd/files/wpa_supplicant.uc       | 92 +++++++++++++++-------
 1 file changed, 65 insertions(+), 27 deletions(-)

diff --git a/package/network/services/hostapd/files/wpa_supplicant.uc b/package/network/services/hostapd/files/wpa_supplicant.uc
index b4cafe80a6..9b006878d4 100644
--- a/package/network/services/hostapd/files/wpa_supplicant.uc
+++ b/package/network/services/hostapd/files/wpa_supplicant.uc
@@ -355,6 +355,32 @@ function set_config(config_name, phy_name, radio, num_global_macaddr, macaddr_ba
 	phy.update(values);
 }
 
+function iface_status_fill_radio_link(mld, radio, msg, link)
+{
+	let config = mld.phy_config[radio];
+	if (!config)
+		return;
+
+	let freq_list = config.freq_list;
+	if (!freq_list)
+		return;
+
+	if (!link || index(freq_list, link.frequency) < 0)
+		return;
+
+	msg.frequency = link.frequency;
+	msg.sec_chan_offset = link.sec_chan_offset;
+}
+
+function iface_status_fill_radio(mld, radio, msg, status)
+{
+	if (status.links)
+		for (let link in status.links)
+			iface_status_fill_radio_link(mld, radio, msg, link);
+	else
+		iface_status_fill_radio_link(mld, radio, msg, status);
+}
+
 let main_obj = {
 	phy_set_state: {
 		args: {
@@ -371,11 +397,27 @@ let main_obj = {
 			if (!phy)
 				return libubus.STATUS_NOT_FOUND;
 
+			let radio_mask = phy.radio != null ? (1 << phy.radio) : 0;
 			if (req.args.stop) {
 				for (let ifname in phy.data)
 					iface_stop(phy.data[ifname]);
+				for (let name, data in wpas.data.mld) {
+					data.radio_mask_present &= ~radio_mask;
+					if (data.radio_mask_up & radio_mask)
+						mld_update_iface(name, data);
+				}
 			} else {
 				start_pending(name);
+
+				let found;
+				for (let name, data in wpas.data.mld) {
+					if (!(data.radio_mask & radio_mask))
+						continue;
+					data.radio_mask_present |= radio_mask;
+					found = true;
+				}
+				if (found)
+					mld_start();
 			}
 
 			return 0;
@@ -410,7 +452,13 @@ let main_obj = {
 			if (!phy)
 				return libubus.STATUS_NOT_FOUND;
 
-			for (let ifname in phy.data) {
+			let ifnames = keys(phy.data);
+			let radio_mask = phy.radio != null ? (1 << phy.radio) : 0;
+			for (let name, data in wpas.data.mld)
+				if (data.radio_mask_up & radio_mask)
+					push(ifnames, name);
+
+			for (let ifname in ifnames) {
 				try {
 					let iface = wpas.interfaces[ifname];
 					if (!iface)
@@ -423,9 +471,21 @@ let main_obj = {
 					if (status.state == "INTERFACE_DISABLED")
 						continue;
 
-					status.ifname = ifname;
-					return status;
+					if (phy.data[ifname]) {
+						status.ifname = ifname;
+						return status;
+					}
+
+					let ret = {
+						ifname,
+						state: status.state,
+					};
+
+					let mld = wpas.data.mld[ifname];
+					iface_status_fill_radio(mld, phy.radio, ret, status);
+					return ret;
 				} catch (e) {
+					ex_handler(e);
 					continue;
 				}
 			}
@@ -553,23 +613,6 @@ function iface_event(type, name, data) {
 	ubus.call("service", "event", { type: `wpa_supplicant.${name}.${type}`, data: {} });
 }
 
-function iface_hostapd_fill_radio_link(mld, radio, msg, link)
-{
-	let config = mld.phy_config[radio];
-	if (!config)
-		return;
-
-	let freq_list = config.freq_list;
-	if (!freq_list)
-		return;
-
-	if (!link || index(freq_list, link.frequency) < 0)
-		return;
-
-	msg.frequency = link.frequency;
-	msg.sec_chan_offset = link.sec_chan_offset;
-}
-
 function iface_hostapd_notify(ifname, iface, state)
 {
 	let status = iface.status();
@@ -621,13 +664,8 @@ function iface_hostapd_notify(ifname, iface, state)
 			radio: i,
 		};
 
-		if (state == "COMPLETED") {
-			if (status.links)
-				for (let link in status.links)
-					iface_hostapd_fill_radio_link(mld, i, radio_msg, link);
-			else
-				iface_hostapd_fill_radio_link(mld, i, radio_msg, status);
-		}
+		if (state == "COMPLETED")
+			iface_status_fill_radio(mld, i, radio_msg, status);
 
 		ubus.call("hostapd", "apsta_state", radio_msg);
 	}




More information about the lede-commits mailing list