diff mbox series

[04/16] hostapd: MLO: use MLD struct for MLD level info

Message ID 20240306173947.2611965-5-quic_adisi@quicinc.com
State Accepted
Headers show
Series hostapd: scale up MLO flows | expand

Commit Message

Aditya Kumar Singh March 6, 2024, 5:39 p.m. UTC
MLD level structure is present to store the MLD level info.

Add changes to use MLD structure instead of its own BSS to get/set the MLD
level info.

Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
---
 hostapd/ctrl_iface.c       |  6 ++--
 hostapd/main.c             | 21 +++++------
 src/ap/ap_drv_ops.c        |  6 ++--
 src/ap/authsrv.c           | 20 +++++++----
 src/ap/ctrl_iface_ap.c     |  2 +-
 src/ap/drv_callbacks.c     |  6 ++--
 src/ap/hostapd.c           | 73 +++++++++++++++++++++++++++++++++-----
 src/ap/hostapd.h           |  7 +---
 src/ap/ieee802_11.c        | 22 +++++++-----
 src/ap/ieee802_11_eht.c    |  4 +--
 src/ap/ieee802_11_shared.c |  4 +--
 src/ap/ieee802_1x.c        | 10 ++++--
 src/ap/wnm_ap.c            |  2 +-
 13 files changed, 122 insertions(+), 61 deletions(-)
diff mbox series

Patch

diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index 6f2b31eaf6be..714d09837605 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -1944,7 +1944,7 @@  static int hostapd_ctrl_iface_data_test_config(struct hostapd_data *hapd,
 
 #ifdef CONFIG_IEEE80211BE
 	if (hapd->conf->mld_ap)
-		addr = hapd->mld_addr;
+		addr = hapd->mld->mld_addr;
 #endif /* CONFIG_IEEE80211BE */
 	hapd->l2_test = l2_packet_init(ifname, addr,
 					ETHERTYPE_IP, hostapd_data_test_rx,
@@ -3523,7 +3523,7 @@  static int hostapd_ctrl_iface_disable_mld(struct hostapd_iface *iface)
 		    !hostapd_is_ml_partner(h_hapd, iface->bss[0]))
 			continue;
 
-		if (!h_hapd->mld_first_bss) {
+		if (hostapd_mld_is_first_bss(h_hapd)) {
 			first_iface = h_iface;
 			continue;
 		}
@@ -3542,7 +3542,7 @@  static int hostapd_ctrl_iface_disable_mld(struct hostapd_iface *iface)
 
 		if (!h_conf->mld_ap ||
 		    !hostapd_is_ml_partner(h_hapd, iface->bss[0]) ||
-		    !h_hapd->mld_first_bss)
+		    hostapd_mld_is_first_bss(h_hapd))
 			continue;
 
 		if (hostapd_disable_iface(h_iface)) {
diff --git a/hostapd/main.c b/hostapd/main.c
index 2c0f44719300..6df7868c778b 100644
--- a/hostapd/main.c
+++ b/hostapd/main.c
@@ -204,20 +204,15 @@  static int hostapd_driver_init(struct hostapd_iface *iface)
 		 * is not configured, and otherwise it would be the
 		 * configured BSSID.
 		 */
-		os_memcpy(hapd->mld_addr, h_hapd->mld_addr, ETH_ALEN);
 		if (is_zero_ether_addr(b)) {
-			os_memcpy(hapd->own_addr, h_hapd->mld_addr, ETH_ALEN);
+			os_memcpy(hapd->own_addr, h_hapd->mld->mld_addr, ETH_ALEN);
 			random_mac_addr_keep_oui(hapd->own_addr);
 		} else {
 			os_memcpy(hapd->own_addr, b, ETH_ALEN);
 		}
 
-		/*
-		 * Mark the interface as a secondary interface, as this
-		 * is needed for the de-initialization flow
-		 */
-		hapd->mld_first_bss = h_hapd;
-		hapd->mld_link_id = hapd->mld_first_bss->mld_next_link_id++;
+		hapd->mld_link_id = hapd->mld->next_link_id++;
+		hostapd_mld_add_link(hapd);
 
 		goto setup_mld;
 	}
@@ -294,13 +289,15 @@  static int hostapd_driver_init(struct hostapd_iface *iface)
 	 * configured, and otherwise it would be the configured BSSID.
 	 */
 	if (hapd->conf->mld_ap) {
-		os_memcpy(hapd->mld_addr, hapd->own_addr, ETH_ALEN);
-		hapd->mld_next_link_id = 0;
-		hapd->mld_link_id = hapd->mld_next_link_id++;
+		os_memcpy(hapd->mld->mld_addr, hapd->own_addr, ETH_ALEN);
+
 		if (!b)
 			random_mac_addr_keep_oui(hapd->own_addr);
 		else
 			os_memcpy(hapd->own_addr, b, ETH_ALEN);
+
+		hapd->mld_link_id = hapd->mld->next_link_id++;
+		hostapd_mld_add_link(hapd);
 	}
 
 setup_mld:
@@ -354,7 +351,7 @@  setup_mld:
 		wpa_printf(MSG_DEBUG,
 			   "MLD: Set link_id=%u, mld_addr=" MACSTR
 			   ", own_addr=" MACSTR,
-			   hapd->mld_link_id, MAC2STR(hapd->mld_addr),
+			   hapd->mld_link_id, MAC2STR(hapd->mld->mld_addr),
 			   MAC2STR(hapd->own_addr));
 
 		hostapd_drv_link_add(hapd, hapd->mld_link_id,
diff --git a/src/ap/ap_drv_ops.c b/src/ap/ap_drv_ops.c
index 60d66e4c0888..a6f53fd8cbb1 100644
--- a/src/ap/ap_drv_ops.c
+++ b/src/ap/ap_drv_ops.c
@@ -840,7 +840,7 @@  int hostapd_drv_sta_deauth(struct hostapd_data *hapd,
 
 		link_id = hapd->mld_link_id;
 		if (ap_sta_is_mld(hapd, sta))
-			own_addr = hapd->mld_addr;
+			own_addr = hapd->mld->mld_addr;
 	}
 #endif /* CONFIG_IEEE80211BE */
 
@@ -861,7 +861,7 @@  int hostapd_drv_sta_disassoc(struct hostapd_data *hapd,
 		struct sta_info *sta = ap_get_sta(hapd, addr);
 
 		if (ap_sta_is_mld(hapd, sta))
-			own_addr = hapd->mld_addr;
+			own_addr = hapd->mld->mld_addr;
 	}
 #endif /* CONFIG_IEEE80211BE */
 
@@ -919,7 +919,7 @@  static int hapd_drv_send_action(struct hostapd_data *hapd, unsigned int freq,
 		sta = ap_get_sta(hapd, dst);
 
 		if (ap_sta_is_mld(hapd, sta)) {
-			own_addr = hapd->mld_addr;
+			own_addr = hapd->mld->mld_addr;
 			bssid = own_addr;
 		}
 #endif /* CONFIG_IEEE80211BE */
diff --git a/src/ap/authsrv.c b/src/ap/authsrv.c
index 1488dccc3d7f..3a3514e93b82 100644
--- a/src/ap/authsrv.c
+++ b/src/ap/authsrv.c
@@ -107,13 +107,15 @@  static int hostapd_setup_radius_srv(struct hostapd_data *hapd)
 	struct radius_server_conf srv;
 	struct hostapd_bss_config *conf = hapd->conf;
 
-	if (hapd->mld_first_bss) {
+#ifdef CONFIG_IEEE80211BE
+	if (!hostapd_mld_is_first_bss(hapd)) {
 		wpa_printf(MSG_DEBUG,
 			   "MLD: Using RADIUS server of the first BSS");
 
-		hapd->radius_srv = hapd->mld_first_bss->radius_srv;
+		hapd->radius_srv = hostapd_mld_get_first_bss(hapd)->radius_srv;
 		return 0;
 	}
+#endif /* CONFIG_IEEE80211BE */
 
 	os_memset(&srv, 0, sizeof(srv));
 	srv.client_file = conf->radius_server_clients;
@@ -249,18 +251,20 @@  static struct eap_config * authsrv_eap_config(struct hostapd_data *hapd)
 
 int authsrv_init(struct hostapd_data *hapd)
 {
-	if (hapd->mld_first_bss) {
+#ifdef CONFIG_IEEE80211BE
+	if (!hostapd_mld_is_first_bss(hapd)) {
 		wpa_printf(MSG_DEBUG, "MLD: Using auth_serv of the first BSS");
 
 #ifdef EAP_TLS_FUNCS
-		hapd->ssl_ctx = hapd->mld_first_bss->ssl_ctx;
+		hapd->ssl_ctx = hostapd_mld_get_first_bss(hapd)->ssl_ctx;
 #endif /* EAP_TLS_FUNCS */
-		hapd->eap_cfg = hapd->mld_first_bss->eap_cfg;
+		hapd->eap_cfg = hostapd_mld_get_first_bss(hapd)->eap_cfg;
 #ifdef EAP_SIM_DB
-		hapd->eap_sim_db_priv = hapd->mld_first_bss->eap_sim_db_priv;
+		hapd->eap_sim_db_priv = hostapd_mld_get_first_bss(hapd)->eap_sim_db_priv;
 #endif /* EAP_SIM_DB */
 		return 0;
 	}
+#endif /* CONFIG_IEEE80211BE */
 
 #ifdef EAP_TLS_FUNCS
 	if (hapd->conf->eap_server &&
@@ -376,7 +380,8 @@  int authsrv_init(struct hostapd_data *hapd)
 
 void authsrv_deinit(struct hostapd_data *hapd)
 {
-	if (hapd->mld_first_bss) {
+#ifdef CONFIG_IEEE80211BE
+	if (!hostapd_mld_is_first_bss(hapd)) {
 		wpa_printf(MSG_DEBUG,
 			   "MLD: Deinit auth_serv of a non-first BSS");
 
@@ -390,6 +395,7 @@  void authsrv_deinit(struct hostapd_data *hapd)
 #endif /* EAP_TLS_FUNCS */
 		return;
 	}
+#endif /* CONFIG_IEEE80211BE */
 
 #ifdef RADIUS_SERVER
 	radius_server_deinit(hapd->radius_srv);
diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c
index cdd777287361..2723177740b0 100644
--- a/src/ap/ctrl_iface_ap.c
+++ b/src/ap/ctrl_iface_ap.c
@@ -1012,7 +1012,7 @@  int hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf,
 					  "mld_addr[%d]=" MACSTR "\n"
 					  "mld_id[%d]=%d\n"
 					  "mld_link_id[%d]=%d\n",
-					  (int) i, MAC2STR(bss->mld_addr),
+					  (int) i, MAC2STR(bss->mld->mld_addr),
 					  (int) i, hostapd_get_mld_id(bss),
 					  (int) i, bss->mld_link_id);
 			if (os_snprintf_error(buflen - len, ret))
diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
index 3b89c700d33f..021b79e9f637 100644
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
@@ -517,7 +517,7 @@  int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
 		if (ap_sta_is_mld(hapd, sta)) {
 			wpa_printf(MSG_DEBUG,
 				   "MLD: Set ML info in RSN Authenticator");
-			wpa_auth_set_ml_info(sta->wpa_sm, hapd->mld_addr,
+			wpa_auth_set_ml_info(sta->wpa_sm, hapd->mld->mld_addr,
 					     sta->mld_assoc_link_id,
 					     &sta->mld_info);
 		}
@@ -1815,7 +1815,7 @@  static int hostapd_mgmt_rx(struct hostapd_data *hapd, struct rx_mgmt *rx_mgmt)
 
 #ifdef CONFIG_IEEE80211BE
 	if (hapd->conf->mld_ap &&
-	    ether_addr_equal(hapd->mld_addr, bssid))
+	    ether_addr_equal(hapd->mld->mld_addr, bssid))
 		is_mld = true;
 #endif /* CONFIG_IEEE80211BE */
 
@@ -1887,7 +1887,7 @@  static void hostapd_mgmt_tx_cb(struct hostapd_data *hapd, const u8 *buf,
 		hapd = tmp_hapd;
 #ifdef CONFIG_IEEE80211BE
 	} else if (hapd->conf->mld_ap &&
-		   ether_addr_equal(hapd->mld_addr, get_hdr_bssid(hdr, len))) {
+		   ether_addr_equal(hapd->mld->mld_addr, get_hdr_bssid(hdr, len))) {
 		/* AP MLD address match - use hapd pointer as-is */
 #endif /* CONFIG_IEEE80211BE */
 	} else {
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index f75edaf71692..13b2873c6cbf 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -399,6 +399,7 @@  static int hostapd_broadcast_wep_set(struct hostapd_data *hapd)
 
 static void hostapd_clear_drv_priv(struct hostapd_data *hapd)
 {
+#ifdef CONFIG_IEEE80211BE
 	unsigned int i;
 
 	for (i = 0; i < hapd->iface->interfaces->count; i++) {
@@ -408,9 +409,10 @@  static void hostapd_clear_drv_priv(struct hostapd_data *hapd)
 			continue;
 
 		if (iface->bss && iface->bss[0] &&
-		    iface->bss[0]->mld_first_bss == hapd)
+		    hostapd_mld_get_first_bss(iface->bss[0]) == hapd)
 			iface->bss[0]->drv_priv = NULL;
 	}
+#endif /* CONFIG_IEEE80211BE */
 
 	hapd->drv_priv = NULL;
 }
@@ -498,7 +500,8 @@  void hostapd_free_hapd_data(struct hostapd_data *hapd)
 	vlan_deinit(hapd);
 	hostapd_acl_deinit(hapd);
 #ifndef CONFIG_NO_RADIUS
-	if (!hapd->mld_first_bss) {
+#ifdef CONFIG_IEEE80211BE
+	if (hostapd_mld_is_first_bss(hapd)) {
 		struct hapd_interfaces *ifaces = hapd->iface->interfaces;
 		size_t i;
 
@@ -517,9 +520,12 @@  void hostapd_free_hapd_data(struct hostapd_data *hapd)
 					h->radius_das = NULL;
 			}
 		}
+#endif /* CONFIG_IEEE80211BE */
 		radius_client_deinit(hapd->radius);
 		radius_das_deinit(hapd->radius_das);
+#ifdef CONFIG_IEEE80211BE
 	}
+#endif /* CONFIG_IEEE80211BE */
 	hapd->radius = NULL;
 	hapd->radius_das = NULL;
 #endif /* CONFIG_NO_RADIUS */
@@ -615,6 +621,39 @@  void hostapd_free_hapd_data(struct hostapd_data *hapd)
 #endif /* CONFIG_IEEE80211AX */
 }
 
+/* hostapd_bss_link_deinit - Per-BSS ML cleanup (deinitialization)
+ * @hapd: Pointer to BSS data
+ *
+ * This function is used to unlink the BSS from the MLD.
+ * If the BSS being removed is the first link, then the next link
+ * becomes the first BSS
+ */
+static void hostapd_bss_link_deinit(struct hostapd_data *hapd)
+{
+#ifdef CONFIG_IEEE80211BE
+	if (!hapd->conf || !hapd->conf->mld_ap)
+		return;
+
+	if (!hapd->mld->num_links)
+		return;
+
+	/* if not started then not yet linked to the MLD. However, first
+	 * BSS, is always linked since it is linked during driver_init(),
+	 * hence need to remove it from MLD
+	 */
+	if (!hapd->started && hapd->iface->bss[0] != hapd)
+		return;
+
+	/* first BSS can also be only linked when at least driver_init() is
+	 * executd. But, if previous interface fails, then it will not,
+	 * hence safe to skip
+	 */
+	if (hapd->iface->bss[0] == hapd && !hapd->drv_priv)
+		return;
+
+	hostapd_mld_remove_link(hapd);
+#endif
+}
 
 /**
  * hostapd_cleanup - Per-BSS cleanup (deinitialization)
@@ -1305,9 +1344,11 @@  static int hostapd_setup_bss(struct hostapd_data *hapd, int first,
 	u8 if_addr[ETH_ALEN];
 	int flush_old_stations = 1;
 
-	if (hapd->mld_first_bss)
+#ifdef CONFIG_IEEE80211BE
+	if (!hostapd_mld_is_first_bss(hapd))
 		wpa_printf(MSG_DEBUG,
 			   "MLD: %s: Setting non-first BSS", __func__);
+#endif /* CONFIG_IEEE80211BE */
 
 	wpa_printf(MSG_DEBUG, "%s(hapd=%p (%s), first=%d)",
 		   __func__, hapd, conf->iface, first);
@@ -1467,7 +1508,9 @@  static int hostapd_setup_bss(struct hostapd_data *hapd, int first,
 	}
 #endif /* CONFIG_SQLITE */
 
-	if (!hapd->mld_first_bss) {
+#ifdef CONFIG_IEEE80211BE
+	if (hostapd_mld_is_first_bss(hapd)) {
+#endif /* CONFIG_IEEE80211BE */
 		hapd->radius = radius_client_init(hapd, conf->radius);
 		if (!hapd->radius) {
 			wpa_printf(MSG_ERROR,
@@ -1499,12 +1542,14 @@  static int hostapd_setup_bss(struct hostapd_data *hapd, int first,
 				return -1;
 			}
 		}
+#ifdef CONFIG_IEEE80211BE
 	} else {
 		wpa_printf(MSG_DEBUG,
 			   "MLD: Using RADIUS client of the first BSS");
-		hapd->radius = hapd->mld_first_bss->radius;
-		hapd->radius_das = hapd->mld_first_bss->radius_das;
+		hapd->radius = hostapd_mld_get_first_bss(hapd)->radius;
+		hapd->radius_das = hostapd_mld_get_first_bss(hapd)->radius_das;
 	}
+#endif /* CONFIG_IEEE80211BE */
 #endif /* CONFIG_NO_RADIUS */
 
 	if (hostapd_acl_init(hapd)) {
@@ -1741,6 +1786,7 @@  static int start_ctrl_iface(struct hostapd_iface *iface)
 static void hostapd_no_ir_cleanup(struct hostapd_data *bss)
 {
 	hostapd_bss_deinit_no_free(bss);
+	hostapd_bss_link_deinit(bss);
 	hostapd_free_hapd_data(bss);
 	hostapd_cleanup_iface_partial(bss->iface);
 }
@@ -2799,6 +2845,8 @@  static void hostapd_bss_deinit(struct hostapd_data *hapd)
 		hapd->rad_attr_db = NULL;
 	}
 #endif /* CONFIG_SQLITE */
+
+	hostapd_bss_link_deinit(hapd);
 	hostapd_cleanup(hapd);
 }
 
@@ -3150,7 +3198,9 @@  void hostapd_interface_deinit_free(struct hostapd_iface *iface)
 	wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit",
 		   __func__, driver, drv_priv);
 	if (driver && driver->hapd_deinit && drv_priv) {
-		if (!iface->bss[0]->mld_first_bss)
+#ifdef CONFIG_IEEE80211BE
+		if (hostapd_mld_is_first_bss(iface->bss[0]))
+#endif /* CONFIG_IEEE80211BE */
 			driver->hapd_deinit(drv_priv);
 		hostapd_clear_drv_priv(iface->bss[0]);
 	}
@@ -3167,7 +3217,9 @@  static void hostapd_deinit_driver(const struct wpa_driver_ops *driver,
 	wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit",
 		   __func__, driver, drv_priv);
 	if (driver && driver->hapd_deinit && drv_priv) {
-		if (!hapd_iface->bss[0]->mld_first_bss)
+#ifdef CONFIG_IEEE80211BE
+		if (hostapd_mld_is_first_bss(hapd_iface->bss[0]))
+#endif /* CONFIG_IEEE80211BE */
 			driver->hapd_deinit(drv_priv);
 		for (j = 0; j < hapd_iface->num_bss; j++) {
 			wpa_printf(MSG_DEBUG, "%s:bss[%d]->drv_priv=%p",
@@ -3281,7 +3333,7 @@  int hostapd_disable_iface(struct hostapd_iface *hapd_iface)
 
 #ifdef CONFIG_IEEE80211BE
 	if (hapd_iface->bss[0]->conf->mld_ap &&
-	    !hapd_iface->bss[0]->mld_first_bss) {
+	    hostapd_mld_is_first_bss((hapd_iface->bss[0]))) {
 		/* Do not allow mld_first_bss disabling before other BSSs */
 		for (j = 0; j < hapd_iface->interfaces->count; ++j) {
 			struct hostapd_iface *h_iface =
@@ -3320,6 +3372,7 @@  int hostapd_disable_iface(struct hostapd_iface *hapd_iface)
 	for (j = 0; j < hapd_iface->num_bss; j++) {
 		struct hostapd_data *hapd = hapd_iface->bss[j];
 		hostapd_bss_deinit_no_free(hapd);
+		hostapd_bss_link_deinit(hapd);
 		hostapd_free_hapd_data(hapd);
 	}
 
@@ -3517,6 +3570,7 @@  int hostapd_add_iface(struct hapd_interfaces *interfaces, char *buf)
 			if (start_ctrl_iface_bss(hapd) < 0 ||
 			    (hapd_iface->state == HAPD_IFACE_ENABLED &&
 			     hostapd_setup_bss(hapd, -1, true))) {
+				hostapd_bss_link_deinit(hapd);
 				hostapd_cleanup(hapd);
 				hapd_iface->bss[hapd_iface->num_bss - 1] = NULL;
 				hapd_iface->conf->num_bss--;
@@ -3614,6 +3668,7 @@  fail:
 				wpa_printf(MSG_DEBUG, "%s: free hapd %p (%s)",
 					   __func__, hapd_iface->bss[i],
 					   hapd->conf->iface);
+				hostapd_bss_link_deinit(hapd);
 				hostapd_cleanup(hapd);
 				os_free(hapd);
 				hapd_iface->bss[i] = NULL;
diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
index 9aa0651c876f..ec090cbbaa85 100644
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -182,12 +182,6 @@  struct hostapd_data {
 	unsigned int reenable_beacon:1;
 
 	u8 own_addr[ETH_ALEN];
-	u8 mld_addr[ETH_ALEN];
-	u8 mld_link_id;
-	/* Used for mld_link_id assignment - valid on the first MLD BSS only */
-	u8 mld_next_link_id;
-
-	struct hostapd_data *mld_first_bss;
 
 	int num_sta; /* number of entries in sta_list */
 	struct sta_info *sta_list; /* STA info list head */
@@ -481,6 +475,7 @@  struct hostapd_data {
 	u8 eht_mld_bss_param_change;
 	struct hostapd_mld *mld;
 	struct dl_list link;
+	u8 mld_link_id;
 #ifdef CONFIG_TESTING_OPTIONS
 	u8 eht_mld_link_removal_count;
 #endif /* CONFIG_TESTING_OPTIONS */
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 22f3841752e1..c246b5a9c4cc 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -409,7 +409,7 @@  static int send_auth_reply(struct hostapd_data *hapd, struct sta_info *sta,
 	 * the addresses.
 	 */
 	if (ap_sta_is_mld(hapd, sta)) {
-		sa = hapd->mld_addr;
+		sa = hapd->mld->mld_addr;
 
 		ml_resp = hostapd_ml_auth_resp(hapd);
 		if (!ml_resp)
@@ -610,7 +610,7 @@  static struct wpabuf * auth_build_sae_commit(struct hostapd_data *hapd,
 
 #ifdef CONFIG_IEEE80211BE
 	if (ap_sta_is_mld(hapd, sta))
-		own_addr = hapd->mld_addr;
+		own_addr = hapd->mld->mld_addr;
 #endif /* CONFIG_IEEE80211BE */
 
 	if (sta->sae->tmp) {
@@ -2806,7 +2806,9 @@  static void handle_auth(struct hostapd_data *hapd,
 	u16 seq_ctrl;
 	struct radius_sta rad_info;
 	const u8 *dst, *sa, *bssid;
+#ifdef CONFIG_IEEE80211BE
 	bool mld_sta = false;
+#endif /* CONFIG_IEEE80211BE */
 
 	if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
 		wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)",
@@ -2924,15 +2926,17 @@  static void handle_auth(struct hostapd_data *hapd,
 		goto fail;
 	}
 
+#ifdef CONFIG_IEEE80211BE
 	if (mld_sta &&
 	    (ether_addr_equal(sa, hapd->own_addr) ||
-	     ether_addr_equal(sa, hapd->mld_addr))) {
+	     ether_addr_equal(sa, hapd->mld->mld_addr))) {
 		wpa_printf(MSG_INFO,
 			   "Station " MACSTR " not allowed to authenticate",
 			   MAC2STR(sa));
 		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
 		goto fail;
 	}
+#endif /* CONFIG_IEEE80211BE */
 
 	if (hapd->conf->no_auth_if_seen_on) {
 		struct hostapd_data *other;
@@ -3255,7 +3259,7 @@  static void handle_auth(struct hostapd_data *hapd,
 	  */
 	if (ap_sta_is_mld(hapd, sta)) {
 		dst = sta->addr;
-		bssid = hapd->mld_addr;
+		bssid = hapd->mld->mld_addr;
 	}
 #endif /* CONFIG_IEEE80211BE */
 
@@ -3745,7 +3749,7 @@  u16 owe_process_rsn_ie(struct hostapd_data *hapd,
 	}
 #ifdef CONFIG_IEEE80211BE
 	if (ap_sta_is_mld(hapd, sta))
-		wpa_auth_set_ml_info(sta->wpa_sm, hapd->mld_addr,
+		wpa_auth_set_ml_info(sta->wpa_sm, hapd->mld->mld_addr,
 				     sta->mld_assoc_link_id, &sta->mld_info);
 #endif /* CONFIG_IEEE80211BE */
 	rsn_ie -= 2;
@@ -4030,7 +4034,7 @@  static int __check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
 				wpa_printf(MSG_DEBUG,
 					   "MLD: Set ML info in RSN Authenticator");
 				wpa_auth_set_ml_info(sta->wpa_sm,
-						     hapd->mld_addr,
+						     hapd->mld->mld_addr,
 						     sta->mld_assoc_link_id,
 						     info);
 			}
@@ -4792,7 +4796,7 @@  static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
 	 * MLD MAC address.
 	 */
 	if (ap_sta_is_mld(hapd, sta) && allow_mld_addr_trans)
-		sa = hapd->mld_addr;
+		sa = hapd->mld->mld_addr;
 #endif /* CONFIG_IEEE80211BE */
 
 	os_memcpy(reply->da, addr, ETH_ALEN);
@@ -6211,7 +6215,7 @@  int ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len,
 #endif /* CONFIG_MESH */
 #ifdef CONFIG_IEEE80211BE
 	    !(hapd->conf->mld_ap &&
-	      ether_addr_equal(hapd->mld_addr, mgmt->bssid)) &&
+	      ether_addr_equal(hapd->mld->mld_addr, mgmt->bssid)) &&
 #endif /* CONFIG_IEEE80211BE */
 	    !ether_addr_equal(mgmt->bssid, hapd->own_addr)) {
 		wpa_printf(MSG_INFO, "MGMT: BSSID=" MACSTR " not our address",
@@ -6234,7 +6238,7 @@  int ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len,
 	     stype != WLAN_FC_STYPE_ACTION) &&
 #ifdef CONFIG_IEEE80211BE
 	    !(hapd->conf->mld_ap &&
-	      ether_addr_equal(hapd->mld_addr, mgmt->bssid)) &&
+	      ether_addr_equal(hapd->mld->mld_addr, mgmt->bssid)) &&
 #endif /* CONFIG_IEEE80211BE */
 #ifdef CONFIG_NAN_USD
 	    !ether_addr_equal(mgmt->da, nan_network_id) &&
diff --git a/src/ap/ieee802_11_eht.c b/src/ap/ieee802_11_eht.c
index de5855ebe352..826edc5029d8 100644
--- a/src/ap/ieee802_11_eht.c
+++ b/src/ap/ieee802_11_eht.c
@@ -495,7 +495,7 @@  static u8 * hostapd_eid_eht_basic_ml_common(struct hostapd_data *hapd,
 	wpabuf_put_u8(buf, common_info_len);
 
 	/* Own MLD MAC Address */
-	wpabuf_put_data(buf, hapd->mld_addr, ETH_ALEN);
+	wpabuf_put_data(buf, hapd->mld->mld_addr, ETH_ALEN);
 
 	/* Own Link ID */
 	wpabuf_put_u8(buf, hapd->mld_link_id);
@@ -812,7 +812,7 @@  struct wpabuf * hostapd_ml_auth_resp(struct hostapd_data *hapd)
 	wpabuf_put_u8(buf, WLAN_EID_EXT_MULTI_LINK);
 	wpabuf_put_le16(buf, MULTI_LINK_CONTROL_TYPE_BASIC);
 	wpabuf_put_u8(buf, ETH_ALEN + 1);
-	wpabuf_put_data(buf, hapd->mld_addr, ETH_ALEN);
+	wpabuf_put_data(buf, hapd->mld->mld_addr, ETH_ALEN);
 
 	return buf;
 }
diff --git a/src/ap/ieee802_11_shared.c b/src/ap/ieee802_11_shared.c
index 0c38483a98c1..a5716f0379b5 100644
--- a/src/ap/ieee802_11_shared.c
+++ b/src/ap/ieee802_11_shared.c
@@ -121,7 +121,7 @@  void ieee802_11_send_sa_query_req(struct hostapd_data *hapd,
 
 #ifdef CONFIG_IEEE80211BE
 	if (ap_sta_is_mld(hapd, sta))
-		own_addr = hapd->mld_addr;
+		own_addr = hapd->mld->mld_addr;
 #endif /* CONFIG_IEEE80211BE */
 
 	mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
@@ -219,7 +219,7 @@  static void ieee802_11_send_sa_query_resp(struct hostapd_data *hapd,
 
 #ifdef CONFIG_IEEE80211BE
 	if (ap_sta_is_mld(hapd, sta))
-		own_addr = hapd->mld_addr;
+		own_addr = hapd->mld->mld_addr;
 #endif /* CONFIG_IEEE80211BE */
 
 	resp->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
index 42eb5a173e45..876f9e39dd45 100644
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -2540,13 +2540,15 @@  int ieee802_1x_init(struct hostapd_data *hapd)
 	struct eapol_auth_config conf;
 	struct eapol_auth_cb cb;
 
-	if (hapd->mld_first_bss) {
+#ifdef CONFIG_IEEE80211BE
+	if (!hostapd_mld_is_first_bss(hapd)) {
 		wpa_printf(MSG_DEBUG,
 			   "MLD: Using IEEE 802.1X state machine of the first BSS");
 
-		hapd->eapol_auth = hapd->mld_first_bss->eapol_auth;
+		hapd->eapol_auth = hostapd_mld_get_first_bss(hapd)->eapol_auth;
 		return 0;
 	}
+#endif /* CONFIG_IEEE80211BE */
 
 	dl_list_init(&hapd->erp_keys);
 
@@ -2632,13 +2634,15 @@  void ieee802_1x_erp_flush(struct hostapd_data *hapd)
 
 void ieee802_1x_deinit(struct hostapd_data *hapd)
 {
-	if (hapd->mld_first_bss) {
+#ifdef CONFIG_IEEE80211BE
+	if (!hostapd_mld_is_first_bss(hapd)) {
 		wpa_printf(MSG_DEBUG,
 			   "MLD: Deinit IEEE 802.1X state machine of a non-first BSS");
 
 		hapd->eapol_auth = NULL;
 		return;
 	}
+#endif /* CONFIG_IEEE80211BE */
 
 #ifdef CONFIG_WEP
 	eloop_cancel_timeout(ieee802_1x_rekey, hapd, NULL);
diff --git a/src/ap/wnm_ap.c b/src/ap/wnm_ap.c
index b77e21bd15e3..af8cccaefcde 100644
--- a/src/ap/wnm_ap.c
+++ b/src/ap/wnm_ap.c
@@ -51,7 +51,7 @@  static const u8 * wnm_ap_get_own_addr(struct hostapd_data *hapd,
 
 #ifdef CONFIG_IEEE80211BE
 	if (hapd->conf->mld_ap && (!sta || ap_sta_is_mld(hapd, sta)))
-		own_addr = hapd->mld_addr;
+		own_addr = hapd->mld->mld_addr;
 #endif /* CONFIG_IEEE80211BE */
 
 	return own_addr;