blob: ab69545b3571b16875bcab9ceecf553dae3e18a4 [file] [log] [blame]
developer66e89bc2024-04-23 14:50:01 +08001From aa339ee77d60fe9314182cf0e60fa2da4da72b44 Mon Sep 17 00:00:00 2001
2From: Sriram R <quic_srirrama@quicinc.com>
3Date: Thu, 28 Mar 2024 23:46:43 +0530
4Subject: [PATCH 013/104] hostapd: MLO: handle link_id in EAPOL Tx status
5 handler
6
7Add link id support in EAPOL Tx status handler so that event can be
8routed to appropriate link BSS.
9
10In order to support this, modify hostapd_find_by_sta() function to check
11each BSS's other parnter link BSS sta list as well.
12
13Signed-off-by: Sriram R <quic_srirrama@quicinc.com>
14Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
15---
16 src/ap/drv_callbacks.c | 108 +++++++++++++++--------------------------
17 1 file changed, 38 insertions(+), 70 deletions(-)
18
19diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
20index 12e6b3f36..064c7abae 100644
21--- a/src/ap/drv_callbacks.c
22+++ b/src/ap/drv_callbacks.c
23@@ -1945,53 +1945,46 @@ static int hostapd_event_new_sta(struct hostapd_data *hapd, const u8 *addr)
24
25
26 static struct hostapd_data * hostapd_find_by_sta(struct hostapd_iface *iface,
27- const u8 *src, bool rsn)
28+ const u8 *src, bool rsn,
29+ struct sta_info **sta_ret)
30 {
31+ struct hostapd_data *hapd;
32 struct sta_info *sta;
33 unsigned int j;
34
35+ if (sta_ret)
36+ *sta_ret = NULL;
37+
38 for (j = 0; j < iface->num_bss; j++) {
39- sta = ap_get_sta(iface->bss[j], src);
40+ hapd = iface->bss[j];
41+ sta = ap_get_sta(hapd, src);
42 if (sta && (sta->flags & WLAN_STA_ASSOC) &&
43- (!rsn || sta->wpa_sm))
44- return iface->bss[j];
45- }
46-
47- return NULL;
48-}
49-
50-
51+ (!rsn || sta->wpa_sm)) {
52+ if (sta_ret)
53+ *sta_ret = sta;
54+ return hapd;
55 #ifdef CONFIG_IEEE80211BE
56-static bool search_mld_sta(struct hostapd_data **p_hapd, const u8 *src)
57-{
58- struct hostapd_data *hapd = *p_hapd;
59- unsigned int i;
60-
61- /* Search for STA on other MLO BSSs */
62- for (i = 0; i < hapd->iface->interfaces->count; i++) {
63- struct hostapd_iface *h =
64- hapd->iface->interfaces->iface[i];
65- struct hostapd_data *h_hapd = h->bss[0];
66-
67- if (!hostapd_is_ml_partner(h_hapd, hapd))
68- continue;
69+ } else if (hapd->conf->mld_ap) {
70+ struct hostapd_data *p_hapd;
71
72- h_hapd = hostapd_find_by_sta(h, src, false);
73- if (h_hapd) {
74- struct sta_info *sta = ap_get_sta(h_hapd, src);
75+ for_each_mld_link(p_hapd, hapd) {
76+ if (p_hapd == hapd)
77+ continue;
78
79- if (sta && sta->mld_info.mld_sta &&
80- sta->mld_assoc_link_id != h_hapd->mld_link_id)
81- continue;
82- *p_hapd = h_hapd;
83- return true;
84+ sta = ap_get_sta(p_hapd, src);
85+ if (sta && (sta->flags & WLAN_STA_ASSOC) &&
86+ (!rsn || sta->wpa_sm)) {
87+ if (sta_ret)
88+ *sta_ret = sta;
89+ return p_hapd;
90+ }
91+ }
92+#endif /* CONFIG_IEEE80211BE */
93 }
94 }
95
96- return false;
97+ return NULL;
98 }
99-#endif /* CONFIG_IEEE80211BE */
100-
101
102 static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src,
103 const u8 *data, size_t data_len,
104@@ -2001,28 +1994,10 @@ static void hostapd_event_eapol_rx(struct hostapd_data *hapd, const u8 *src,
105 struct hostapd_data *orig_hapd = hapd;
106
107 #ifdef CONFIG_IEEE80211BE
108- if (link_id != -1) {
109- struct hostapd_data *h_hapd;
110-
111- hapd = switch_link_hapd(hapd, link_id);
112- h_hapd = hostapd_find_by_sta(hapd->iface, src, true);
113- if (!h_hapd)
114- h_hapd = hostapd_find_by_sta(orig_hapd->iface, src,
115- true);
116- if (!h_hapd)
117- h_hapd = hostapd_find_by_sta(hapd->iface, src, false);
118- if (!h_hapd)
119- h_hapd = hostapd_find_by_sta(orig_hapd->iface, src,
120- false);
121- if (h_hapd)
122- hapd = h_hapd;
123- } else if (hapd->conf->mld_ap) {
124- search_mld_sta(&hapd, src);
125- } else {
126- hapd = hostapd_find_by_sta(hapd->iface, src, false);
127- }
128+ hapd = switch_link_hapd(hapd, link_id);
129+ hapd = hostapd_find_by_sta(hapd->iface, src, true, NULL);
130 #else /* CONFIG_IEEE80211BE */
131- hapd = hostapd_find_by_sta(hapd->iface, src, false);
132+ hapd = hostapd_find_by_sta(hapd->iface, src, false, NULL);
133 #endif /* CONFIG_IEEE80211BE */
134
135 if (!hapd) {
136@@ -2349,22 +2324,15 @@ err:
137 #endif /* CONFIG_OWE */
138
139 static void hostapd_eapol_tx_status(struct hostapd_data *hapd, const u8 *dst,
140- const u8 *data, size_t len, int ack)
141+ const u8 *data, size_t len, int ack,
142+ int link_id)
143 {
144 struct sta_info *sta;
145- struct hostapd_iface *iface = hapd->iface;
146
147- sta = ap_get_sta(hapd, dst);
148- if (sta == NULL && iface->num_bss > 1) {
149- size_t j;
150- for (j = 0; j < iface->num_bss; j++) {
151- hapd = iface->bss[j];
152- sta = ap_get_sta(hapd, dst);
153- if (sta)
154- break;
155- }
156- }
157- if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) {
158+ hapd = switch_link_hapd(hapd, link_id);
159+ hapd = hostapd_find_by_sta(hapd->iface, dst, false, &sta);
160+
161+ if (sta == NULL) {
162 wpa_printf(MSG_DEBUG, "Ignore TX status for Data frame to STA "
163 MACSTR " that is not currently associated",
164 MAC2STR(dst));
165@@ -2431,11 +2399,11 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
166 }
167 break;
168 case EVENT_EAPOL_TX_STATUS:
169- hapd = switch_link_hapd(hapd, data->eapol_tx_status.link_id);
170 hostapd_eapol_tx_status(hapd, data->eapol_tx_status.dst,
171 data->eapol_tx_status.data,
172 data->eapol_tx_status.data_len,
173- data->eapol_tx_status.ack);
174+ data->eapol_tx_status.ack,
175+ data->eapol_tx_status.link_id);
176 break;
177 case EVENT_DRIVER_CLIENT_POLL_OK:
178 hostapd_client_poll_ok(hapd, data->client_poll.addr);
179--
1802.39.2
181