blob: ab69545b3571b16875bcab9ceecf553dae3e18a4 [file] [log] [blame]
From aa339ee77d60fe9314182cf0e60fa2da4da72b44 Mon Sep 17 00:00:00 2001
From: Sriram R <quic_srirrama@quicinc.com>
Date: Thu, 28 Mar 2024 23:46:43 +0530
Subject: [PATCH 013/104] hostapd: MLO: handle link_id in EAPOL Tx status
handler
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@quicinc.com>
Signed-off-by: Aditya Kumar Singh <quic_adisi@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 12e6b3f36..064c7abae 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.39.2