[PATCH 04/18] MLD STA: Add support to fetch MLO connection info to wpa_s

Veerendranath Jakkam quic_vjakkam at quicinc.com
Thu Jul 28 06:45:33 PDT 2022


From: Shivani Baranwal <quic_shivbara at quicinc.com>

Add support to fetch MLO connection info from driver to wpa_s instance
of corresponding MLD STA interface.

Signed-off-by: Shivani Baranwal <quic_shivbara at quicinc.com>
---
 src/drivers/driver.h              | 13 +++++
 src/drivers/driver_nl80211.c      | 14 +++++
 wpa_supplicant/driver_i.h         | 10 ++++
 wpa_supplicant/events.c           | 93 +++++++++++++++++++++++++++++++
 wpa_supplicant/wpa_supplicant_i.h |  8 +++
 5 files changed, 138 insertions(+)

diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 504d52f48..3ac2f278b 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -4681,6 +4681,19 @@ struct wpa_driver_ops {
 			      const u8 *match, size_t match_len,
 			      bool multicast);
 #endif /* CONFIG_TESTING_OPTIONS */
+
+
+	/**
+	 * get_sta_mlo_info - Get the current multi-link associtaion info
+	 * @priv: private driver interface data
+	 * @mlo: pointer to fill multi-link associtaion info
+	 * Returns: 0 on success, -1 on failure
+	 *
+	 * This callback is used to fetch multi-link of the current association.
+	 */
+	int (*get_sta_mlo_info)(void *priv,
+				struct driver_sta_mlo_info *mlo_info);
+
 };
 
 /**
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index a04495e6a..9849ef483 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -1014,6 +1014,19 @@ static int wpa_driver_nl80211_get_ssid(void *priv, u8 *ssid)
 }
 
 
+static int nl80211_get_sta_mlo_info(void *priv,
+				    struct driver_sta_mlo_info *mlo_info)
+{
+	struct i802_bss *bss = priv;
+	struct wpa_driver_nl80211_data *drv = bss->drv;
+
+	if (!drv->associated)
+		return -1;
+
+	os_memcpy(mlo_info, &drv->sta_mlo_info, sizeof(*mlo_info));
+	return 0;
+}
+
 static void wpa_driver_nl80211_event_newlink(
 	struct nl80211_global *global, struct wpa_driver_nl80211_data *drv,
 	int ifindex, const char *ifname)
@@ -12566,4 +12579,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
 	.register_frame = testing_nl80211_register_frame,
 	.radio_disable = testing_nl80211_radio_disable,
 #endif /* CONFIG_TESTING_OPTIONS */
+	.get_sta_mlo_info = nl80211_get_sta_mlo_info,
 };
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index b0af1cd98..e20259073 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -1117,4 +1117,14 @@ static inline int wpa_drv_dpp_listen(struct wpa_supplicant *wpa_s, bool enable)
 	return wpa_s->driver->dpp_listen(wpa_s->drv_priv, enable);
 }
 
+static inline int
+wpas_drv_get_sta_mlo_info(struct wpa_supplicant *wpa_s,
+			  struct driver_sta_mlo_info *mlo_info)
+{
+	if (!wpa_s->driver->get_sta_mlo_info)
+		return 0;
+
+	return wpa_s->driver->get_sta_mlo_info(wpa_s->drv_priv, mlo_info);
+}
+
 #endif /* DRIVER_I_H */
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index ec56cfdc0..a574aa8fc 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -166,6 +166,20 @@ wpa_supplicant_update_current_bss(struct wpa_supplicant *wpa_s, const u8 *bssid)
 	return bss;
 }
 
+static void wpa_supplicant_update_link_bss(struct wpa_supplicant *wpa_s,
+					   u8 link_id,
+					   const u8 *bssid)
+{
+	struct wpa_bss *bss = wpa_supplicant_get_new_bss(wpa_s, bssid);
+
+	if (!bss) {
+		wpa_supplicant_update_scan_results(wpa_s);
+		bss = wpa_supplicant_get_new_bss(wpa_s, bssid);
+	}
+
+	if (bss)
+		wpa_s->links[link_id].bss = bss;
+}
 
 static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s)
 {
@@ -285,6 +299,19 @@ void wpa_supplicant_stop_countermeasures(void *eloop_ctx, void *sock_ctx)
 }
 
 
+static void wpas_reset_mlo_info(struct wpa_supplicant *wpa_s)
+{
+	int i;
+
+	if (!wpa_s->valid_links)
+		return;
+
+	wpa_s->valid_links = 0;
+	for (i = 0; i < MAX_NUM_MLD_LINKS; i++)
+		wpa_s->links[i].bss = NULL;
+}
+
+
 void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
 {
 	int bssid_changed;
@@ -351,6 +378,8 @@ void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
 
 	if (wpa_s->enabled_4addr_mode && wpa_drv_set_4addr_mode(wpa_s, 0) == 0)
 		wpa_s->enabled_4addr_mode = 0;
+
+	wpas_reset_mlo_info(wpa_s);
 }
 
 
@@ -3302,6 +3331,63 @@ static void wpas_fst_update_mb_assoc(struct wpa_supplicant *wpa_s,
 }
 
 
+static int wpa_drv_get_mlo_info(struct wpa_supplicant *wpa_s)
+{
+	struct driver_sta_mlo_info mlo;
+	int i;
+
+	mlo.valid_links = 0;
+	if (wpas_drv_get_sta_mlo_info(wpa_s, &mlo)) {
+		wpa_dbg(wpa_s, MSG_ERROR, "Failed to get MLO link info");
+		wpa_supplicant_deauthenticate(
+			wpa_s, WLAN_REASON_DEAUTH_LEAVING);
+		return -1;
+	}
+
+	if (wpa_s->valid_links == mlo.valid_links) {
+		bool match = true;
+
+		if (!mlo.valid_links)
+			return 0;
+
+		for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
+			if (!(mlo.valid_links & BIT(i)))
+				continue;
+
+			if (os_memcmp(wpa_s->links[i].addr, mlo.links[i].addr,
+				      ETH_ALEN)) {
+				match = false;
+				break;
+			}
+
+			if (os_memcmp(wpa_s->links[i].bssid, mlo.links[i].bssid,
+				      ETH_ALEN)) {
+				match = false;
+				break;
+			}
+		}
+
+		if (match &&
+		    !os_memcmp(wpa_s->ap_mld_addr, mlo.ap_mld_addr, ETH_ALEN))
+			return 0;
+	}
+
+	wpa_s->valid_links = mlo.valid_links;
+	os_memcpy(wpa_s->ap_mld_addr, mlo.ap_mld_addr, ETH_ALEN);
+	for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
+		if (!(wpa_s->valid_links & BIT(i)))
+			continue;
+
+		os_memcpy(wpa_s->links[i].addr, mlo.links[i].addr, ETH_ALEN);
+		os_memcpy(wpa_s->links[i].bssid, mlo.links[i].bssid, ETH_ALEN);
+		wpa_s->links[i].freq = mlo.links[i].freq;
+		wpa_supplicant_update_link_bss(wpa_s, i, mlo.links[i].bssid);
+	}
+
+	return 0;
+}
+
+
 static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
 				       union wpa_event_data *data)
 {
@@ -3337,6 +3423,13 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
 		return;
 	}
 
+	if (wpa_drv_get_mlo_info(wpa_s) < 0) {
+		wpa_dbg(wpa_s, MSG_ERROR, "Failed to get MLO connection info");
+		wpa_supplicant_deauthenticate(
+			wpa_s, WLAN_REASON_DEAUTH_LEAVING);
+		return;
+	}
+
 	if (ft_completed &&
 	    (wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION)) {
 		wpa_msg(wpa_s, MSG_INFO, "Attempt to roam to " MACSTR,
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 5f9bbe32d..b6c9dbb6d 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -739,6 +739,14 @@ struct wpa_supplicant {
 	struct wpa_bss *current_bss;
 	int ap_ies_from_associnfo;
 	unsigned int assoc_freq;
+	u8 ap_mld_addr[ETH_ALEN];
+	u8 valid_links;
+	struct {
+		u8 addr[ETH_ALEN];
+		u8 bssid[ETH_ALEN];
+		u32 freq;
+		struct wpa_bss *bss;
+	} links[MAX_NUM_MLD_LINKS];
 	u8 *last_con_fail_realm;
 	size_t last_con_fail_realm_len;
 
-- 
2.25.1




More information about the Hostap mailing list