[PATCH 07/22] hostapd: MLO: add support for cohosted ML BSS

Aditya Kumar Singh quic_adisi at quicinc.com
Thu Mar 28 11:16:37 PDT 2024


From: Sriram R <quic_srirrama at quicinc.com>

Currently MLO is being supported with an assumption of only single BSS per
link in the hostapd conf file. This needs to be extended when cohosted ML
BSS exist in the same config file.

Extend the support for cohosted BSSes. This is required for MBSSID MLO
support as well.

Signed-off-by: Sriram R <quic_srirrama at quicinc.com>
Signed-off-by: Aditya Kumar Singh <quic_adisi at quicinc.com>
---
 hostapd/main.c   | 38 +++++++-------------------
 src/ap/hostapd.c | 70 +++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 73 insertions(+), 35 deletions(-)

diff --git a/hostapd/main.c b/hostapd/main.c
index a43d3a5be1d5..524a102742b7 100644
--- a/hostapd/main.c
+++ b/hostapd/main.c
@@ -158,6 +158,9 @@ static int hostapd_driver_init(struct hostapd_iface *iface)
 	struct hostapd_bss_config *conf = hapd->conf;
 	u8 *b = conf->bssid;
 	struct wpa_driver_capa capa;
+#ifdef CONFIG_IEEE80211BE
+	struct hostapd_data *h_hapd = NULL;
+#endif /* CONFIG_IEEE80211BE */
 
 	if (hapd->driver == NULL || hapd->driver->hapd_init == NULL) {
 		wpa_printf(MSG_ERROR, "No hostapd driver wrapper available");
@@ -165,35 +168,10 @@ static int hostapd_driver_init(struct hostapd_iface *iface)
 	}
 
 #ifdef CONFIG_IEEE80211BE
-	for (i = 0; conf->mld_ap && i < iface->interfaces->count; i++) {
-		struct hostapd_iface *h = iface->interfaces->iface[i];
-		struct hostapd_data *h_hapd = h->bss[0];
-		struct hostapd_bss_config *hconf = h_hapd->conf;
-
-		if (h == iface) {
-			wpa_printf(MSG_DEBUG, "MLD: Skip own interface");
-			continue;
-		}
-
-		if (!hconf->mld_ap) {
-			wpa_printf(MSG_DEBUG,
-				   "MLD: Skip non-MLD");
-			continue;
-		}
-
-		if (!hostapd_is_ml_partner(hapd, h_hapd)) {
-			wpa_printf(MSG_DEBUG,
-				   "MLD: Skip non matching MLD vif name");
-			continue;
-		}
-
-		wpa_printf(MSG_DEBUG, "MLD: Found matching MLD interface");
-		if (!h_hapd->drv_priv) {
-			wpa_printf(MSG_DEBUG,
-				   "MLD: Matching MLD BSS not initialized yet");
-			continue;
-		}
+	if (conf->mld_ap)
+		h_hapd = hostapd_mld_get_first_bss(hapd);
 
+	if (h_hapd) {
 		hapd->drv_priv = h_hapd->drv_priv;
 		hapd->interface_added = h_hapd->interface_added;
 
@@ -214,6 +192,8 @@ static int hostapd_driver_init(struct hostapd_iface *iface)
 		}
 
 		hostapd_mld_add_link(hapd);
+		wpa_printf(MSG_DEBUG, "Setup of non first link (%d) BSS of MLD %s",
+			   hapd->mld_link_id, hapd->conf->iface);
 
 		goto setup_mld;
 	}
@@ -298,6 +278,8 @@ static int hostapd_driver_init(struct hostapd_iface *iface)
 			os_memcpy(hapd->own_addr, b, ETH_ALEN);
 
 		hostapd_mld_add_link(hapd);
+		wpa_printf(MSG_DEBUG, "Setup of first link (%d) BSS of MLD %s",
+			   hapd->mld_link_id, hapd->conf->iface);
 	}
 
 setup_mld:
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index f8cb6432d007..ff1d8f9d08e7 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -1333,6 +1333,9 @@ static int hostapd_setup_bss(struct hostapd_data *hapd, int first,
 	char force_ifname[IFNAMSIZ];
 	u8 if_addr[ETH_ALEN];
 	int flush_old_stations = 1;
+#ifdef CONFIG_IEEE80211BE
+	struct hostapd_data *h_hapd = NULL;
+#endif /* CONFIG_IEEE80211BE */
 
 	if (!hostapd_mld_is_first_bss(hapd))
 		wpa_printf(MSG_DEBUG,
@@ -1379,6 +1382,21 @@ static int hostapd_setup_bss(struct hostapd_data *hapd, int first,
 			} while (mac_in_conf(hapd->iconf, hapd->own_addr));
 		}
 
+#ifdef CONFIG_IEEE80211BE
+		if (conf->mld_ap) {
+			h_hapd = hostapd_mld_get_first_bss(hapd);
+
+			if (h_hapd) {
+				hapd->drv_priv = h_hapd->drv_priv;
+				hapd->interface_added = h_hapd->interface_added;
+				hostapd_mld_add_link(hapd);
+				wpa_printf(MSG_DEBUG, "Setup of non first link (%d) BSS of MLD %s",
+					   hapd->mld_link_id, hapd->conf->iface);
+				goto setup_mld;
+			}
+		}
+#endif /* CONFIG_IEEE80211BE */
+
 		hapd->interface_added = 1;
 		if (hostapd_if_add(hapd->iface->bss[0], WPA_IF_AP_BSS,
 				   conf->iface, addr, hapd,
@@ -1393,8 +1411,33 @@ static int hostapd_setup_bss(struct hostapd_data *hapd, int first,
 
 		if (!addr)
 			os_memcpy(hapd->own_addr, if_addr, ETH_ALEN);
+
+#ifdef CONFIG_IEEE80211BE
+		if (hapd->conf->mld_ap) {
+			wpa_printf(MSG_DEBUG, "Setup of first link (%d) BSS of MLD %s",
+				   hapd->mld_link_id, hapd->conf->iface);
+			os_memcpy(hapd->mld->mld_addr, hapd->own_addr, ETH_ALEN);
+			hostapd_mld_add_link(hapd);
+		}
 	}
 
+setup_mld:
+
+	if (hapd->conf->mld_ap && !first) {
+		wpa_printf(MSG_DEBUG,
+			   "MLD: Set link_id=%u, mld_addr=" MACSTR
+			   ", own_addr=" MACSTR,
+			   hapd->mld_link_id, MAC2STR(hapd->mld->mld_addr),
+			   MAC2STR(hapd->own_addr));
+
+		if (hostapd_drv_link_add(hapd, hapd->mld_link_id,
+					 hapd->own_addr))
+			return -1;
+	}
+#else
+	}
+#endif /* CONFIG_IEEE80211BE */
+
 	if (conf->wmm_enabled < 0)
 		conf->wmm_enabled = hapd->iconf->ieee80211n |
 			hapd->iconf->ieee80211ax;
@@ -4679,17 +4722,30 @@ void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx)
 struct hostapd_data * hostapd_mld_get_link_bss(struct hostapd_data *hapd,
 					       u8 link_id)
 {
-	unsigned int i;
+	struct hostapd_iface *iface;
+	struct hostapd_data *bss;
+	struct hostapd_bss_config *conf;
+	unsigned int i, j;
 
 	for (i = 0; i < hapd->iface->interfaces->count; i++) {
-		struct hostapd_iface *h = hapd->iface->interfaces->iface[i];
-		struct hostapd_data *h_hapd = h->bss[0];
-
-		if (!hostapd_is_ml_partner(hapd, h_hapd))
+		iface = hapd->iface->interfaces->iface[i];
+		if (!iface)
 			continue;
 
-		if (h_hapd->mld_link_id == link_id)
-			return h_hapd;
+		for (j = 0; j < iface->num_bss; j++) {
+			bss = iface->bss[j];
+			conf = bss->conf;
+
+			if (!conf->mld_ap ||
+			    !hostapd_is_ml_partner(hapd, bss))
+				continue;
+
+			if (!bss->drv_priv)
+				continue;
+
+			if (bss->mld_link_id == link_id)
+				return bss;
+		}
 	}
 
 	return NULL;
-- 
2.25.1




More information about the Hostap mailing list