[PATCH 13/22] hostapd: MLO: handle link_id in EAPOL Tx status handler

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


From: Sriram R <quic_srirrama at quicinc.com>

Add link id support in EAPOL Tx status handler so that event can be
routed to appropriate link BSS.

In order to support this, modify hostapd_find_by_sta() function to check
each BSS's other parnter link BSS sta list as well.

Signed-off-by: Sriram R <quic_srirrama at quicinc.com>
Signed-off-by: Aditya Kumar Singh <quic_adisi at quicinc.com>
---
 src/ap/drv_callbacks.c | 108 +++++++++++++++--------------------------
 1 file changed, 38 insertions(+), 70 deletions(-)

diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
index 12e6b3f361fc..064c7abae166 100644
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
@@ -1945,53 +1945,46 @@ static int hostapd_event_new_sta(struct hostapd_data *hapd, const u8 *addr)
 
 
 static struct hostapd_data * hostapd_find_by_sta(struct hostapd_iface *iface,
-						 const u8 *src, bool rsn)
+						 const u8 *src, bool rsn,
+						 struct sta_info **sta_ret)
 {
+	struct hostapd_data *hapd;
 	struct sta_info *sta;
 	unsigned int j;
 
+	if (sta_ret)
+		*sta_ret = NULL;
+
 	for (j = 0; j < iface->num_bss; j++) {
-		sta = ap_get_sta(iface->bss[j], src);
+		hapd = iface->bss[j];
+		sta = ap_get_sta(hapd, src);
 		if (sta && (sta->flags & WLAN_STA_ASSOC) &&
-		    (!rsn || sta->wpa_sm))
-			return iface->bss[j];
-	}
-
-	return NULL;
-}
-
-
+		    (!rsn || sta->wpa_sm)) {
+			if (sta_ret)
+				*sta_ret = sta;
+			return hapd;
 #ifdef CONFIG_IEEE80211BE
-static bool search_mld_sta(struct hostapd_data **p_hapd, const u8 *src)
-{
-	struct hostapd_data *hapd = *p_hapd;
-	unsigned int i;
-
-	/* Search for STA on other MLO BSSs */
-	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(h_hapd, hapd))
-			continue;
+		} else if (hapd->conf->mld_ap) {
+			struct hostapd_data *p_hapd;
 
-		h_hapd = hostapd_find_by_sta(h, src, false);
-		if (h_hapd) {
-			struct sta_info *sta = ap_get_sta(h_hapd, src);
+			for_each_mld_link(p_hapd, hapd) {
+				if (p_hapd == hapd)
+					continue;
 
-			if (sta && sta->mld_info.mld_sta &&
-			    sta->mld_assoc_link_id != h_hapd->mld_link_id)
-				continue;
-			*p_hapd = h_hapd;
-			return true;
+				sta = ap_get_sta(p_hapd, src);
+				if (sta && (sta->flags & WLAN_STA_ASSOC) &&
+				    (!rsn || sta->wpa_sm)) {
+					if (sta_ret)
+						*sta_ret = sta;
+					return p_hapd;
+				}
+			}
+#endif /* CONFIG_IEEE80211BE */
 		}
 	}
 
-	return false;
+	return NULL;
 }
-#endif /* CONFIG_IEEE80211BE */
-
 
 static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src,
 				   const u8 *data, size_t data_len,
@@ -2001,28 +1994,10 @@ static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src,
 	struct hostapd_data *orig_hapd = hapd;
 
 #ifdef CONFIG_IEEE80211BE
-	if (link_id != -1) {
-		struct hostapd_data *h_hapd;
-
-		hapd = switch_link_hapd(hapd, link_id);
-		h_hapd = hostapd_find_by_sta(hapd->iface, src, true);
-		if (!h_hapd)
-			h_hapd = hostapd_find_by_sta(orig_hapd->iface, src,
-						     true);
-		if (!h_hapd)
-			h_hapd = hostapd_find_by_sta(hapd->iface, src, false);
-		if (!h_hapd)
-			h_hapd = hostapd_find_by_sta(orig_hapd->iface, src,
-						     false);
-		if (h_hapd)
-			hapd = h_hapd;
-	} else if (hapd->conf->mld_ap) {
-		search_mld_sta(&hapd, src);
-	} else {
-		hapd = hostapd_find_by_sta(hapd->iface, src, false);
-	}
+	hapd = switch_link_hapd(hapd, link_id);
+	hapd = hostapd_find_by_sta(hapd->iface, src, true, NULL);
 #else /* CONFIG_IEEE80211BE */
-	hapd = hostapd_find_by_sta(hapd->iface, src, false);
+	hapd = hostapd_find_by_sta(hapd->iface, src, false, NULL);
 #endif /* CONFIG_IEEE80211BE */
 
 	if (!hapd) {
@@ -2349,22 +2324,15 @@ err:
 #endif /* CONFIG_OWE */
 
 static void hostapd_eapol_tx_status(struct hostapd_data *hapd, const u8 *dst,
-				    const u8 *data, size_t len, int ack)
+				    const u8 *data, size_t len, int ack,
+				    int link_id)
 {
 	struct sta_info *sta;
-	struct hostapd_iface *iface = hapd->iface;
 
-	sta = ap_get_sta(hapd, dst);
-	if (sta == NULL && iface->num_bss > 1) {
-		size_t j;
-		for (j = 0; j < iface->num_bss; j++) {
-			hapd = iface->bss[j];
-			sta = ap_get_sta(hapd, dst);
-			if (sta)
-				break;
-		}
-	}
-	if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) {
+	hapd = switch_link_hapd(hapd, link_id);
+	hapd = hostapd_find_by_sta(hapd->iface, dst, false, &sta);
+
+	if (sta == NULL) {
 		wpa_printf(MSG_DEBUG, "Ignore TX status for Data frame to STA "
 			   MACSTR " that is not currently associated",
 			   MAC2STR(dst));
@@ -2431,11 +2399,11 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
 		}
 		break;
 	case EVENT_EAPOL_TX_STATUS:
-		hapd = switch_link_hapd(hapd, data->eapol_tx_status.link_id);
 		hostapd_eapol_tx_status(hapd, data->eapol_tx_status.dst,
 					data->eapol_tx_status.data,
 					data->eapol_tx_status.data_len,
-					data->eapol_tx_status.ack);
+					data->eapol_tx_status.ack,
+					data->eapol_tx_status.link_id);
 		break;
 	case EVENT_DRIVER_CLIENT_POLL_OK:
 		hostapd_client_poll_ok(hapd, data->client_poll.addr);
-- 
2.25.1




More information about the Hostap mailing list