MLD STA: Set MLO connection info to wpa_sm
Update the following MLO connection information to wpa_sm: - AP MLD address and link ID of the (re)association link. - Bitmap of requested links and accepted links - Own link address for each requested link - AP link address, RSNE and RSNXE for each requested link Signed-off-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
This commit is contained in:
parent
cc2236299f
commit
472a0b8d60
5 changed files with 197 additions and 0 deletions
|
@ -37,6 +37,27 @@
|
|||
static const u8 null_rsc[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
|
||||
static void wpa_hexdump_link(int level, u8 link_id, const char *title,
|
||||
const void *buf, size_t len)
|
||||
{
|
||||
char *link_title = NULL;
|
||||
|
||||
if (link_id >= MAX_NUM_MLD_LINKS)
|
||||
goto out;
|
||||
|
||||
link_title = os_malloc(os_strlen(title) + 20);
|
||||
if (!link_title)
|
||||
goto out;
|
||||
|
||||
os_snprintf(link_title, os_strlen(title) + 20, "MLO link[%u]: %s",
|
||||
link_id, title);
|
||||
|
||||
out:
|
||||
wpa_hexdump(level, link_title ? link_title : title, buf, len);
|
||||
os_free(link_title);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* wpa_eapol_key_send - Send WPA/RSN EAPOL-Key message
|
||||
* @sm: Pointer to WPA state machine data from wpa_sm_init()
|
||||
|
@ -3006,6 +3027,8 @@ struct wpa_sm * wpa_sm_init(struct wpa_sm_ctx *ctx)
|
|||
*/
|
||||
void wpa_sm_deinit(struct wpa_sm *sm)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (sm == NULL)
|
||||
return;
|
||||
pmksa_cache_deinit(sm->pmksa);
|
||||
|
@ -3016,6 +3039,10 @@ void wpa_sm_deinit(struct wpa_sm *sm)
|
|||
os_free(sm->ap_wpa_ie);
|
||||
os_free(sm->ap_rsn_ie);
|
||||
os_free(sm->ap_rsnxe);
|
||||
for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
|
||||
os_free(sm->mlo.links[i].ap_rsne);
|
||||
os_free(sm->mlo.links[i].ap_rsnxe);
|
||||
}
|
||||
wpa_sm_drop_sa(sm);
|
||||
os_free(sm->ctx);
|
||||
#ifdef CONFIG_IEEE80211R
|
||||
|
@ -3304,6 +3331,81 @@ void wpa_sm_set_config(struct wpa_sm *sm, struct rsn_supp_config *config)
|
|||
}
|
||||
|
||||
|
||||
int wpa_sm_set_mlo_params(struct wpa_sm *sm, const struct wpa_sm_mlo *mlo)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!sm)
|
||||
return -1;
|
||||
|
||||
os_memcpy(sm->mlo.ap_mld_addr, mlo->ap_mld_addr, ETH_ALEN);
|
||||
sm->mlo.assoc_link_id = mlo->assoc_link_id;
|
||||
sm->mlo.valid_links = mlo->valid_links;
|
||||
sm->mlo.req_links = mlo->req_links;
|
||||
|
||||
for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
|
||||
const u8 *ie;
|
||||
size_t len;
|
||||
|
||||
if (sm->mlo.req_links & BIT(i)) {
|
||||
if (!mlo->links[i].ap_rsne ||
|
||||
mlo->links[i].ap_rsne_len == 0) {
|
||||
wpa_dbg(sm->ctx->msg_ctx, MSG_INFO,
|
||||
"RSN: No RSNE for AP MLO link %d with BSSID "
|
||||
MACSTR,
|
||||
i, MAC2STR(mlo->links[i].bssid));
|
||||
return -1;
|
||||
|
||||
}
|
||||
os_memcpy(sm->mlo.links[i].addr, mlo->links[i].addr,
|
||||
ETH_ALEN);
|
||||
os_memcpy(sm->mlo.links[i].bssid, mlo->links[i].bssid,
|
||||
ETH_ALEN);
|
||||
}
|
||||
|
||||
ie = mlo->links[i].ap_rsne;
|
||||
len = mlo->links[i].ap_rsne_len;
|
||||
os_free(sm->mlo.links[i].ap_rsne);
|
||||
if (!ie || len == 0) {
|
||||
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
|
||||
"RSN: Clearing MLO link[%u] AP RSNE", i);
|
||||
sm->mlo.links[i].ap_rsne = NULL;
|
||||
sm->mlo.links[i].ap_rsne_len = 0;
|
||||
} else {
|
||||
wpa_hexdump_link(MSG_DEBUG, i, "RSN: Set AP RSNE",
|
||||
ie, len);
|
||||
sm->mlo.links[i].ap_rsne = os_memdup(ie, len);
|
||||
if (!sm->mlo.links[i].ap_rsne) {
|
||||
sm->mlo.links[i].ap_rsne_len = 0;
|
||||
return -1;
|
||||
}
|
||||
sm->mlo.links[i].ap_rsne_len = len;
|
||||
}
|
||||
|
||||
ie = mlo->links[i].ap_rsnxe;
|
||||
len = mlo->links[i].ap_rsnxe_len;
|
||||
os_free(sm->mlo.links[i].ap_rsnxe);
|
||||
if (!ie || len == 0) {
|
||||
wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
|
||||
"RSN: Clearing MLO link[%u] AP RSNXE", i);
|
||||
sm->mlo.links[i].ap_rsnxe = NULL;
|
||||
sm->mlo.links[i].ap_rsnxe_len = 0;
|
||||
} else {
|
||||
wpa_hexdump_link(MSG_DEBUG, i, "RSN: Set AP RSNXE", ie,
|
||||
len);
|
||||
sm->mlo.links[i].ap_rsnxe = os_memdup(ie, len);
|
||||
if (!sm->mlo.links[i].ap_rsnxe) {
|
||||
sm->mlo.links[i].ap_rsnxe_len = 0;
|
||||
return -1;
|
||||
}
|
||||
sm->mlo.links[i].ap_rsnxe_len = len;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* wpa_sm_set_own_addr - Set own MAC address
|
||||
* @sm: Pointer to WPA state machine data from wpa_sm_init()
|
||||
|
|
|
@ -145,6 +145,21 @@ struct rsn_supp_config {
|
|||
bool force_kdk_derivation;
|
||||
};
|
||||
|
||||
struct wpa_sm_link {
|
||||
u8 addr[ETH_ALEN];
|
||||
u8 bssid[ETH_ALEN];
|
||||
u8 *ap_rsne, *ap_rsnxe;
|
||||
size_t ap_rsne_len, ap_rsnxe_len;
|
||||
};
|
||||
|
||||
struct wpa_sm_mlo {
|
||||
u8 ap_mld_addr[ETH_ALEN];
|
||||
u8 assoc_link_id;
|
||||
u16 valid_links; /* bitmap of accepted links */
|
||||
u16 req_links; /* bitmap of requested links */
|
||||
struct wpa_sm_link links[MAX_NUM_MLD_LINKS];
|
||||
};
|
||||
|
||||
#ifndef CONFIG_NO_WPA
|
||||
|
||||
struct wpa_sm * wpa_sm_init(struct wpa_sm_ctx *ctx);
|
||||
|
@ -224,6 +239,7 @@ void wpa_sm_set_ptk_kck_kek(struct wpa_sm *sm,
|
|||
const u8 *ptk_kek, size_t ptk_kek_len);
|
||||
int wpa_fils_is_completed(struct wpa_sm *sm);
|
||||
void wpa_sm_pmksa_cache_reconfig(struct wpa_sm *sm);
|
||||
int wpa_sm_set_mlo_params(struct wpa_sm *sm, const struct wpa_sm_mlo *mlo);
|
||||
|
||||
#else /* CONFIG_NO_WPA */
|
||||
|
||||
|
@ -438,6 +454,12 @@ static inline void wpa_sm_pmksa_cache_reconfig(struct wpa_sm *sm)
|
|||
{
|
||||
}
|
||||
|
||||
static inline int wpa_sm_set_mlo_params(struct wpa_sm *sm,
|
||||
const struct wpa_sm_mlo *mlo)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NO_WPA */
|
||||
|
||||
#ifdef CONFIG_IEEE80211R
|
||||
|
|
|
@ -218,6 +218,7 @@ struct wpa_sm {
|
|||
struct wpabuf *dpp_z;
|
||||
int dpp_pfs;
|
||||
#endif /* CONFIG_DPP2 */
|
||||
struct wpa_sm_mlo mlo;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -3410,6 +3410,66 @@ static int wpa_drv_get_mlo_info(struct wpa_supplicant *wpa_s)
|
|||
}
|
||||
|
||||
|
||||
static int wpa_sm_set_ml_info(struct wpa_supplicant *wpa_s)
|
||||
{
|
||||
struct driver_sta_mlo_info drv_mlo;
|
||||
struct wpa_sm_mlo wpa_mlo;
|
||||
const u8 *bss_rsn = NULL, *bss_rsnx = NULL;
|
||||
int i;
|
||||
|
||||
os_memset(&drv_mlo, 0, sizeof(drv_mlo));
|
||||
if (wpas_drv_get_sta_mlo_info(wpa_s, &drv_mlo)) {
|
||||
wpa_dbg(wpa_s, MSG_INFO, "Failed to get MLO link info");
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_memset(&wpa_mlo, 0, sizeof(wpa_mlo));
|
||||
if (!drv_mlo.valid_links)
|
||||
goto out;
|
||||
|
||||
os_memcpy(wpa_mlo.ap_mld_addr, drv_mlo.ap_mld_addr, ETH_ALEN);
|
||||
wpa_mlo.assoc_link_id = drv_mlo.assoc_link_id;
|
||||
wpa_mlo.valid_links = drv_mlo.valid_links;
|
||||
wpa_mlo.req_links = drv_mlo.req_links;
|
||||
|
||||
for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
|
||||
struct wpa_bss *bss;
|
||||
|
||||
if (!(drv_mlo.req_links & BIT(i)))
|
||||
continue;
|
||||
|
||||
bss = wpa_supplicant_get_new_bss(wpa_s, drv_mlo.links[i].bssid);
|
||||
if (!bss) {
|
||||
wpa_supplicant_update_scan_results(wpa_s);
|
||||
bss = wpa_supplicant_get_new_bss(
|
||||
wpa_s, drv_mlo.links[i].bssid);
|
||||
}
|
||||
|
||||
if (!bss) {
|
||||
wpa_dbg(wpa_s, MSG_INFO,
|
||||
"Failed to get MLO link %d BSS", i);
|
||||
return -1;
|
||||
}
|
||||
|
||||
bss_rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
|
||||
bss_rsnx = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
|
||||
|
||||
wpa_mlo.links[i].ap_rsne = bss_rsn ? (u8 *) bss_rsn : NULL;
|
||||
wpa_mlo.links[i].ap_rsne_len = bss_rsn ? 2 + bss_rsn[1] : 0;
|
||||
wpa_mlo.links[i].ap_rsnxe = bss_rsnx ? (u8 *) bss_rsnx : NULL;
|
||||
wpa_mlo.links[i].ap_rsnxe_len = bss_rsnx ? 2 + bss_rsnx[1] : 0;
|
||||
|
||||
os_memcpy(wpa_mlo.links[i].bssid, drv_mlo.links[i].bssid,
|
||||
ETH_ALEN);
|
||||
os_memcpy(wpa_mlo.links[i].addr, drv_mlo.links[i].addr,
|
||||
ETH_ALEN);
|
||||
}
|
||||
|
||||
out:
|
||||
return wpa_sm_set_mlo_params(wpa_s->wpa, &wpa_mlo);
|
||||
}
|
||||
|
||||
|
||||
static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
|
||||
union wpa_event_data *data)
|
||||
{
|
||||
|
@ -3534,6 +3594,15 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
|
|||
wpa_supplicant_scard_init(wpa_s, wpa_s->current_ssid);
|
||||
}
|
||||
wpa_sm_notify_assoc(wpa_s->wpa, bssid);
|
||||
|
||||
if (wpa_sm_set_ml_info(wpa_s)) {
|
||||
wpa_dbg(wpa_s, MSG_INFO,
|
||||
"Failed to set MLO connection info to wpa_sm");
|
||||
wpa_supplicant_deauthenticate(wpa_s,
|
||||
WLAN_REASON_DEAUTH_LEAVING);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wpa_s->l2)
|
||||
l2_packet_notify_auth_start(wpa_s->l2);
|
||||
|
||||
|
|
|
@ -403,6 +403,7 @@ void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s,
|
|||
#ifdef CONFIG_WEP
|
||||
int i;
|
||||
#endif /* CONFIG_WEP */
|
||||
struct wpa_sm_mlo mlo;
|
||||
|
||||
if (ssid->key_mgmt & WPA_KEY_MGMT_WPS)
|
||||
wpa_s->key_mgmt = WPA_KEY_MGMT_WPS;
|
||||
|
@ -443,6 +444,8 @@ void wpa_supplicant_set_non_wpa_policy(struct wpa_supplicant *wpa_s,
|
|||
wpa_s->mgmt_group_cipher);
|
||||
|
||||
pmksa_cache_clear_current(wpa_s->wpa);
|
||||
os_memset(&mlo, 0, sizeof(mlo));
|
||||
wpa_sm_set_mlo_params(wpa_s->wpa, &mlo);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue