| 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 |
| |