From d9c5d601f15c5dbf39719ccda90d160481f02c17 Mon Sep 17 00:00:00 2001 From: Sriram R Date: Thu, 28 Mar 2024 23:46:38 +0530 Subject: [PATCH] AP NLD: Extend support for cohosted ML BSS Modify necessary helper functions to support multiple BSS support for MLO to make the changes scalable. Signed-off-by: Sriram R Signed-off-by: Aditya Kumar Singh --- src/ap/ieee802_11.c | 117 ++++++++++++++++------------------------ src/ap/ieee802_11_eht.c | 25 +++------ src/ap/wpa_auth_glue.c | 52 ++++++++++-------- 3 files changed, 83 insertions(+), 111 deletions(-) diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index bd63a56f8..c53c0f2fb 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -4556,7 +4556,7 @@ int hostapd_process_assoc_ml_info(struct hostapd_data *hapd, bool offload) { #ifdef CONFIG_IEEE80211BE - unsigned int i, j; + unsigned int i; if (!hostapd_is_mld_ap(hapd)) return 0; @@ -4571,25 +4571,25 @@ int hostapd_process_assoc_ml_info(struct hostapd_data *hapd, hostapd_wpa_ie(hapd, WLAN_EID_RSNX); for (i = 0; i < MAX_NUM_MLD_LINKS; i++) { - struct hostapd_iface *iface = NULL; + struct hostapd_data *bss = NULL; struct mld_link_info *link = &sta->mld_info.links[i]; + bool link_bss_found = false; if (!link->valid) continue; - for (j = 0; j < hapd->iface->interfaces->count; j++) { - iface = hapd->iface->interfaces->iface[j]; - - if (hapd->iface == iface) + for_each_mld_link(bss, hapd) { + if (bss == hapd) continue; - if (hostapd_is_ml_partner(hapd, iface->bss[0]) && - i == iface->bss[0]->mld_link_id) - break; + if (bss->mld_link_id != i) + continue; + + link_bss_found = true; + break; } - if (!iface || j == hapd->iface->interfaces->count || - TEST_FAIL()) { + if (!link_bss_found || TEST_FAIL()) { wpa_printf(MSG_DEBUG, "MLD: No link match for link_id=%u", i); @@ -4602,7 +4602,7 @@ int hostapd_process_assoc_ml_info(struct hostapd_data *hapd, if (!offload) ieee80211_ml_build_assoc_resp(hapd, link); } else { - if (ieee80211_ml_process_link(iface->bss[0], sta, link, + if (ieee80211_ml_process_link(bss, sta, link, ies, ies_len, reassoc, offload)) return -1; @@ -5765,7 +5765,7 @@ static bool hostapd_ml_handle_disconnect(struct hostapd_data *hapd, #ifdef CONFIG_IEEE80211BE struct hostapd_data *assoc_hapd, *tmp_hapd; struct sta_info *assoc_sta; - unsigned int i, link_id; + struct sta_info *tmp_sta; if (!hostapd_is_mld_ap(hapd)) return false; @@ -5778,45 +5778,25 @@ static bool hostapd_ml_handle_disconnect(struct hostapd_data *hapd, if (!assoc_sta) return false; - for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) { - for (i = 0; i < assoc_hapd->iface->interfaces->count; i++) { - struct sta_info *tmp_sta; + for_each_mld_link(tmp_hapd, assoc_hapd) { + if (tmp_hapd == assoc_hapd) + continue; - if (!assoc_sta->mld_info.links[link_id].valid) + if (!assoc_sta->mld_info.links[tmp_hapd->mld_link_id].valid) + continue; + + for (tmp_sta = tmp_hapd->sta_list; tmp_sta; + tmp_sta = tmp_sta->next) { + if (tmp_sta->mld_assoc_link_id != + assoc_sta->mld_assoc_link_id || + tmp_sta->aid != assoc_sta->aid) continue; - tmp_hapd = - assoc_hapd->iface->interfaces->iface[i]->bss[0]; - - if (!hostapd_is_ml_partner(assoc_hapd, tmp_hapd)) - continue; - - for (tmp_sta = tmp_hapd->sta_list; tmp_sta; - tmp_sta = tmp_sta->next) { - /* - * Remove the station on which the association - * was done only after all other link stations - * are removed. Since there is only a single - * station per struct hostapd_hapd with the - * same association link simply break out from - * the loop. - */ - if (tmp_sta == assoc_sta) - break; - - if (tmp_sta->mld_assoc_link_id != - assoc_sta->mld_assoc_link_id || - tmp_sta->aid != assoc_sta->aid) - continue; - - if (!disassoc) - hostapd_deauth_sta(tmp_hapd, tmp_sta, - mgmt); - else - hostapd_disassoc_sta(tmp_hapd, tmp_sta, - mgmt); - break; - } + if (!disassoc) + hostapd_deauth_sta(tmp_hapd, tmp_sta, mgmt); + else + hostapd_disassoc_sta(tmp_hapd, tmp_sta, mgmt); + break; } } @@ -6439,38 +6419,33 @@ static void hostapd_ml_handle_assoc_cb(struct hostapd_data *hapd, struct sta_info *sta, bool ok) { #ifdef CONFIG_IEEE80211BE - unsigned int i, link_id; + struct hostapd_data *tmp_hapd; if (!hostapd_is_mld_ap(hapd)) return; - for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) { - struct mld_link_info *link = &sta->mld_info.links[link_id]; + for_each_mld_link(tmp_hapd, hapd) { + struct mld_link_info *link; + struct sta_info *tmp_sta; + if (tmp_hapd == hapd) + continue; + + link = &sta->mld_info.links[tmp_hapd->mld_link_id]; if (!link->valid) continue; - for (i = 0; i < hapd->iface->interfaces->count; i++) { - struct sta_info *tmp_sta; - struct hostapd_data *tmp_hapd = - hapd->iface->interfaces->iface[i]->bss[0]; - - if (!hostapd_is_ml_partner(tmp_hapd, hapd)) + for (tmp_sta = tmp_hapd->sta_list; tmp_sta; + tmp_sta = tmp_sta->next) { + if (tmp_sta == sta || + tmp_sta->mld_assoc_link_id != + sta->mld_assoc_link_id || + tmp_sta->aid != sta->aid) continue; - for (tmp_sta = tmp_hapd->sta_list; tmp_sta; - tmp_sta = tmp_sta->next) { - if (tmp_sta == sta || - tmp_sta->mld_assoc_link_id != - sta->mld_assoc_link_id || - tmp_sta->aid != sta->aid) - continue; - - ieee80211_ml_link_sta_assoc_cb(tmp_hapd, - tmp_sta, link, - ok); - break; - } + ieee80211_ml_link_sta_assoc_cb(tmp_hapd, tmp_sta, link, + ok); + break; } } #endif /* CONFIG_IEEE80211BE */ diff --git a/src/ap/ieee802_11_eht.c b/src/ap/ieee802_11_eht.c index f553766e5..b935ee889 100644 --- a/src/ap/ieee802_11_eht.c +++ b/src/ap/ieee802_11_eht.c @@ -1030,7 +1030,7 @@ const u8 * hostapd_process_ml_auth(struct hostapd_data *hapd, static int hostapd_mld_validate_assoc_info(struct hostapd_data *hapd, struct sta_info *sta) { - u8 i, link_id; + u8 link_id; struct mld_info *info = &sta->mld_info; if (!ap_sta_is_mld(hapd, sta)) { @@ -1050,31 +1050,18 @@ static int hostapd_mld_validate_assoc_info(struct hostapd_data *hapd, for (link_id = 0; link_id < MAX_NUM_MLD_LINKS; link_id++) { struct hostapd_data *other_hapd; - if (!info->links[link_id].valid) + if (!info->links[link_id].valid || link_id == hapd->mld_link_id) continue; - for (i = 0; i < hapd->iface->interfaces->count; i++) { - other_hapd = hapd->iface->interfaces->iface[i]->bss[0]; - - if (hapd == other_hapd) - continue; - - if (hostapd_is_ml_partner(hapd, other_hapd) && - link_id == other_hapd->mld_link_id) - break; - } - - if (i == hapd->iface->interfaces->count && - link_id != hapd->mld_link_id) { + other_hapd = hostapd_mld_get_link_bss(hapd, link_id); + if (!other_hapd) { wpa_printf(MSG_DEBUG, "MLD: Invalid link ID=%u", link_id); return -1; } - if (i < hapd->iface->interfaces->count) - os_memcpy(info->links[link_id].local_addr, - other_hapd->own_addr, - ETH_ALEN); + os_memcpy(info->links[link_id].local_addr, other_hapd->own_addr, + ETH_ALEN); } return 0; diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c index 012f2b803..c786d580e 100644 --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -1537,7 +1537,7 @@ static int hostapd_wpa_auth_get_ml_rsn_info(void *ctx, struct wpa_auth_ml_rsn_info *info) { struct hostapd_data *hapd = ctx; - unsigned int i, j; + unsigned int i; wpa_printf(MSG_DEBUG, "WPA_AUTH: MLD: Get RSN info CB: n_mld_links=%u", info->n_mld_links); @@ -1547,26 +1547,30 @@ static int hostapd_wpa_auth_get_ml_rsn_info(void *ctx, for (i = 0; i < info->n_mld_links; i++) { unsigned int link_id = info->links[i].link_id; + struct hostapd_data *bss; + bool link_bss_found = false; wpa_printf(MSG_DEBUG, "WPA_AUTH: MLD: Get link RSN CB: link_id=%u", link_id); - for (j = 0; j < hapd->iface->interfaces->count; j++) { - struct hostapd_iface *iface = - hapd->iface->interfaces->iface[j]; + if (hapd->mld_link_id == link_id) { + wpa_auth_ml_get_rsn_info(hapd->wpa_auth, + &info->links[i]); + continue; + } - if (!hostapd_is_ml_partner(hapd, iface->bss[0]) || - link_id != iface->bss[0]->mld_link_id || - !iface->bss[0]->wpa_auth) + for_each_mld_link(bss, hapd) { + if (bss == hapd || bss->mld_link_id != link_id) continue; - wpa_auth_ml_get_rsn_info(iface->bss[0]->wpa_auth, + wpa_auth_ml_get_rsn_info(bss->wpa_auth, &info->links[i]); + link_bss_found = true; break; } - if (j == hapd->iface->interfaces->count) + if (!link_bss_found) wpa_printf(MSG_DEBUG, "WPA_AUTH: MLD: link=%u not found", link_id); } @@ -1579,7 +1583,7 @@ static int hostapd_wpa_auth_get_ml_key_info(void *ctx, struct wpa_auth_ml_key_info *info) { struct hostapd_data *hapd = ctx; - unsigned int i, j; + unsigned int i; wpa_printf(MSG_DEBUG, "WPA_AUTH: MLD: Get key info CB: n_mld_links=%u", info->n_mld_links); @@ -1588,29 +1592,35 @@ static int hostapd_wpa_auth_get_ml_key_info(void *ctx, return -1; for (i = 0; i < info->n_mld_links; i++) { + struct hostapd_data *bss; u8 link_id = info->links[i].link_id; + bool link_bss_found = false; wpa_printf(MSG_DEBUG, "WPA_AUTH: MLD: Get link info CB: link_id=%u", link_id); - for (j = 0; j < hapd->iface->interfaces->count; j++) { - struct hostapd_iface *iface = - hapd->iface->interfaces->iface[j]; - - if (!hostapd_is_ml_partner(hapd, iface->bss[0]) || - link_id != iface->bss[0]->mld_link_id || - !iface->bss[0]->wpa_auth) - continue; - - wpa_auth_ml_get_key_info(iface->bss[0]->wpa_auth, + if (hapd->mld_link_id == link_id) { + wpa_auth_ml_get_key_info(hapd->wpa_auth, &info->links[i], info->mgmt_frame_prot, info->beacon_prot); + continue; + } + + for_each_mld_link(bss, hapd) { + if (bss == hapd || bss->mld_link_id != link_id) + continue; + + wpa_auth_ml_get_key_info(bss->wpa_auth, + &info->links[i], + info->mgmt_frame_prot, + info->beacon_prot); + link_bss_found = true; break; } - if (j == hapd->iface->interfaces->count) + if (!link_bss_found) wpa_printf(MSG_DEBUG, "WPA_AUTH: MLD: link=%u not found", link_id); }