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);
|
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
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
int (*register_frame)(void *priv, u16 type,
|
int (*register_frame)(void *priv, u16 type,
|
||||||
const u8 *match, size_t match_len,
|
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(
|
static void wpa_driver_nl80211_event_newlink(
|
||||||
struct nl80211_global *global, struct wpa_driver_nl80211_data *drv,
|
struct nl80211_global *global, struct wpa_driver_nl80211_data *drv,
|
||||||
int ifindex, const char *ifname)
|
int ifindex, const char *ifname)
|
||||||
|
@ -12777,6 +12791,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
|
||||||
#ifdef CONFIG_DPP
|
#ifdef CONFIG_DPP
|
||||||
.dpp_listen = nl80211_dpp_listen,
|
.dpp_listen = nl80211_dpp_listen,
|
||||||
#endif /* CONFIG_DPP */
|
#endif /* CONFIG_DPP */
|
||||||
|
.get_sta_mlo_info = nl80211_get_sta_mlo_info,
|
||||||
#ifdef CONFIG_TESTING_OPTIONS
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
.register_frame = testing_nl80211_register_frame,
|
.register_frame = testing_nl80211_register_frame,
|
||||||
.radio_disable = testing_nl80211_radio_disable,
|
.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)
|
static int wpa_bss_in_use(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
if (bss == wpa_s->current_bss)
|
if (bss == wpa_s->current_bss)
|
||||||
return 1;
|
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))
|
bss->ssid_len) != 0))
|
||||||
return 0; /* SSID has changed */
|
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->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);
|
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 */
|
#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)
|
static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s)
|
||||||
{
|
{
|
||||||
struct wpa_ssid *ssid, *old_ssid;
|
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)
|
void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
|
||||||
{
|
{
|
||||||
int bssid_changed;
|
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)
|
if (wpa_s->enabled_4addr_mode && wpa_drv_set_4addr_mode(wpa_s, 0) == 0)
|
||||||
wpa_s->enabled_4addr_mode = 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,
|
static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
|
||||||
union wpa_event_data *data)
|
union wpa_event_data *data)
|
||||||
{
|
{
|
||||||
|
@ -3360,6 +3444,13 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
|
||||||
return;
|
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 &&
|
if (ft_completed &&
|
||||||
(wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION)) {
|
(wpa_s->drv_flags & WPA_DRIVER_FLAGS_BSS_SELECTION)) {
|
||||||
wpa_msg(wpa_s, MSG_INFO, "Attempt to roam to " MACSTR,
|
wpa_msg(wpa_s, MSG_INFO, "Attempt to roam to " MACSTR,
|
||||||
|
|
|
@ -739,6 +739,14 @@ struct wpa_supplicant {
|
||||||
struct wpa_bss *current_bss;
|
struct wpa_bss *current_bss;
|
||||||
int ap_ies_from_associnfo;
|
int ap_ies_from_associnfo;
|
||||||
unsigned int assoc_freq;
|
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;
|
u8 *last_con_fail_realm;
|
||||||
size_t last_con_fail_realm_len;
|
size_t last_con_fail_realm_len;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue