From: Shivani Baranwal <quic_shivbara@xxxxxxxxxxx> 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@xxxxxxxxxxx> --- 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 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap