blob: 42c4b675fa76fce0a72bfe7c43ff0c1b3113bc3d [file] [log] [blame]
From 27dbd9d9796d656c8cf78d51d48162208080a987 Mon Sep 17 00:00:00 2001
From: Sriram R <quic_srirrama@quicinc.com>
Date: Thu, 28 Mar 2024 23:46:38 +0530
Subject: [PATCH 008/104] hostapd: MLO: extend support for cohosted ML BSS
Modify necessary helper apis to support multiple BSS support for MLO to
make the changes scalable.
Signed-off-by: Sriram R <quic_srirrama@quicinc.com>
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
---
src/ap/ieee802_11.c | 116 ++++++++++++++++------------------------
src/ap/ieee802_11_eht.c | 27 +++-------
src/ap/wpa_auth_glue.c | 52 +++++++++++-------
3 files changed, 89 insertions(+), 106 deletions(-)
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 98398ccdd..26e3d8356 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -4567,7 +4567,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;
@@ -4582,25 +4582,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];
+ for_each_mld_link(bss, hapd) {
+ if (bss == hapd)
+ continue;
- if (hapd->iface == iface)
+ if (bss->mld_link_id != i)
continue;
- if (hostapd_is_ml_partner(hapd, iface->bss[0]) &&
- i == iface->bss[0]->mld_link_id)
- break;
+ 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);
@@ -4613,7 +4613,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;
@@ -5777,7 +5777,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;
@@ -5790,45 +5790,27 @@ 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;
-
- if (!assoc_sta->mld_info.links[link_id].valid)
- continue;
+ for_each_mld_link(tmp_hapd, assoc_hapd) {
+ if (tmp_hapd == assoc_hapd)
+ continue;
- tmp_hapd =
- assoc_hapd->iface->interfaces->iface[i]->bss[0];
+ if (!assoc_sta->mld_info.links[tmp_hapd->mld_link_id].valid)
+ continue;
- if (!hostapd_is_ml_partner(assoc_hapd, tmp_hapd))
+ 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;
- 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;
}
}
@@ -6451,38 +6433,34 @@ 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 =
+ &sta->mld_info.links[tmp_hapd->mld_link_id];
+ struct sta_info *tmp_sta;
- if (!link->valid)
+ if (tmp_hapd == hapd)
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 (!link->valid)
+ continue;
- 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 7365057ad..353a4116e 100644
--- a/src/ap/ieee802_11_eht.c
+++ b/src/ap/ieee802_11_eht.c
@@ -1029,7 +1029,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)) {
@@ -1049,31 +1049,20 @@ 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..d3cd44695 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,33 @@ 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 = NULL;
+ 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)
continue;
- wpa_auth_ml_get_rsn_info(iface->bss[0]->wpa_auth,
+ if (bss->mld_link_id != link_id)
+ continue;
+
+ 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 +1586,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 +1595,38 @@ 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 = NULL;
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 (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)
+ continue;
- if (!hostapd_is_ml_partner(hapd, iface->bss[0]) ||
- link_id != iface->bss[0]->mld_link_id ||
- !iface->bss[0]->wpa_auth)
+ if (bss->mld_link_id != link_id)
continue;
- wpa_auth_ml_get_key_info(iface->bss[0]->wpa_auth,
+ 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);
}
--
2.39.2