[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