[PATCH v2 05/17] MLD STA: Add support to fetch MLO connection info to wpa_s
Veerendranath Jakkam
quic_vjakkam at quicinc.com
Thu Sep 8 07:44:11 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. In addition, return true for BSSes
associated with MLO links from wpa_bss_in_use() to avoid getting them
cleared from scan results.
Co-authored-by: Veerendranath Jakkam <quic_vjakkam at quicinc.com>
Signed-off-by: Veerendranath Jakkam <quic_vjakkam at quicinc.com>
Signed-off-by: Shivani Baranwal <quic_shivbara at quicinc.com>
---
src/drivers/driver.h | 13 +++++
src/drivers/driver_nl80211.c | 14 +++++
wpa_supplicant/bss.c | 22 +++++++-
wpa_supplicant/driver_i.h | 10 ++++
wpa_supplicant/events.c | 93 +++++++++++++++++++++++++++++++
wpa_supplicant/wpa_supplicant_i.h | 8 +++
6 files changed, 157 insertions(+), 3 deletions(-)
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 5d5075347..9bebebcc6 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -4808,6 +4808,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 93b3eea69..0235e69d8 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -1020,6 +1020,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)
@@ -12785,4 +12798,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/bss.c b/wpa_supplicant/bss.c
index eb97a618d..7dcdb9969 100644
--- a/wpa_supplicant/bss.c
+++ b/wpa_supplicant/bss.c
@@ -379,6 +379,8 @@ static int wpa_bss_known(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
static int wpa_bss_in_use(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
{
+ int i;
+
if (bss == wpa_s->current_bss)
return 1;
@@ -388,9 +390,23 @@ static int wpa_bss_in_use(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
bss->ssid_len) != 0))
return 0; /* SSID has changed */
- return !is_zero_ether_addr(bss->bssid) &&
- (os_memcmp(bss->bssid, wpa_s->bssid, ETH_ALEN) == 0 ||
- os_memcmp(bss->bssid, wpa_s->pending_bssid, ETH_ALEN) == 0);
+ if (!is_zero_ether_addr(bss->bssid) &&
+ (os_memcmp(bss->bssid, wpa_s->bssid, ETH_ALEN) == 0 ||
+ os_memcmp(bss->bssid, wpa_s->pending_bssid, ETH_ALEN) == 0))
+ return 1;
+
+ if (!wpa_s->valid_links)
+ return 0;
+
+ for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
+ if (!(wpa_s->valid_links & BIT(i)))
+ continue;
+
+ if (os_memcmp(bss->bssid, wpa_s->links[i].bssid, ETH_ALEN) == 0)
+ return 1;
+ }
+
+ return 0;
}
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index d20e06136..41d353f91 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -1152,4 +1152,14 @@ static inline int wpa_drv_set_secure_ranging_ctx(struct wpa_supplicant *wpa_s,
return wpa_s->driver->set_secure_ranging_ctx(wpa_s->drv_priv, ¶ms);
}
+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 b3b2c4932..fc662a770 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;
@@ -352,6 +379,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);
}
@@ -3325,6 +3354,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)
{
@@ -3360,6 +3446,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 076081ec8..a9af64ab1 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; /* bitmap of valid MLO link IDs */
+ 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