diff mbox series

[08/22] hostapd: MLO: extend support for cohosted ML BSS

Message ID 20240328181652.2956122-9-quic_adisi@quicinc.com
State Accepted
Headers show
Series [01/22] hostapd: MLO: fix for_each_mld_link macro | expand

Commit Message

Aditya Kumar Singh March 28, 2024, 6:16 p.m. UTC
From: Sriram R <quic_srirrama@quicinc.com>

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 mbox series

Patch

diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 98398ccdd693..26e3d8356bb6 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 7365057adb00..353a4116e5dd 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 012f2b80343c..d3cd446952b8 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);
 	}