MLD STA: Fetch MLO connection info into core wpa_supplicant
Add support to fetch MLO connection info from the driver to the wpa_supplicant instance of corresponding MLD STA interface. In addition, return true for BSSs associated with MLO links from wpa_bss_in_use() to avoid getting them cleared from scan results. Co-authored-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com> Signed-off-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com> Signed-off-by: Shivani Baranwal <quic_shivbara@quicinc.com>
This commit is contained in:
parent
e2147f917f
commit
7784964cbe
6 changed files with 154 additions and 3 deletions
|
@ -4803,6 +4803,17 @@ struct wpa_driver_ops {
|
|||
*/
|
||||
int (*send_pasn_resp)(void *priv, struct pasn_auth *params);
|
||||
|
||||
/**
|
||||
* get_sta_mlo_info - Get the current multi-link association info
|
||||
* @priv: Private driver interface data
|
||||
* @mlo: Pointer to fill multi-link association 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);
|
||||
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
int (*register_frame)(void *priv, u16 type,
|
||||
const u8 *match, size_t match_len,
|
||||
|
|
|
@ -1020,6 +1020,20 @@ 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)
|
||||
|
@ -12777,6 +12791,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
|
|||
#ifdef CONFIG_DPP
|
||||
.dpp_listen = nl80211_dpp_listen,
|
||||
#endif /* CONFIG_DPP */
|
||||
.get_sta_mlo_info = nl80211_get_sta_mlo_info,
|
||||
#ifdef CONFIG_TESTING_OPTIONS
|
||||
.register_frame = testing_nl80211_register_frame,
|
||||
.radio_disable = testing_nl80211_radio_disable,
|
||||
|
|
|
@ -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) &&
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -167,6 +167,21 @@ wpa_supplicant_update_current_bss(struct wpa_supplicant *wpa_s, const u8 *bssid)
|
|||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
struct wpa_ssid *ssid, *old_ssid;
|
||||
|
@ -285,6 +300,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 +380,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 +3355,60 @@ 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) != 0 ||
|
||||
os_memcmp(wpa_s->links[i].bssid, mlo.links[i].bssid,
|
||||
ETH_ALEN) != 0) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (match &&
|
||||
os_memcmp(wpa_s->ap_mld_addr, mlo.ap_mld_addr,
|
||||
ETH_ALEN) == 0)
|
||||
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 +3444,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,
|
||||
|
|
|
@ -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];
|
||||
unsigned int freq;
|
||||
struct wpa_bss *bss;
|
||||
} links[MAX_NUM_MLD_LINKS];
|
||||
u8 *last_con_fail_realm;
|
||||
size_t last_con_fail_realm_len;
|
||||
|
||||
|
|
Loading…
Reference in a new issue