]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
AP/MLO: Forward Management frame TX status to correct BSS
authorAndrei Otcheretianski <andrei.otcheretianski@intel.com>
Mon, 22 May 2023 19:34:10 +0000 (22:34 +0300)
committerJouni Malinen <j@w1.fi>
Thu, 15 Jun 2023 14:34:02 +0000 (17:34 +0300)
In case of MLO AP and legacy client, make sure Management frame TX
status is processed on the correct BSS.

Since there's only one instance of i802_bss for all BSSs in an AP MLD in
the nl80211 driver interface, the link ID is needed to forward the
status to the correct BSS. Store the link ID when transmitting
Managements frames and report it in TX status.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
src/ap/drv_callbacks.c
src/drivers/driver.h
src/drivers/driver_nl80211.c
src/drivers/driver_nl80211.h
src/drivers/driver_nl80211_event.c

index ab956f0c1a0ebb2aa29cff8e5f078c76dc53edbc..92439e3760fe2bdd98f0f05922b948bd1b22031a 100644 (file)
@@ -1555,10 +1555,19 @@ static int hostapd_mgmt_rx(struct hostapd_data *hapd, struct rx_mgmt *rx_mgmt)
 
 
 static void hostapd_mgmt_tx_cb(struct hostapd_data *hapd, const u8 *buf,
-                              size_t len, u16 stype, int ok)
+                              size_t len, u16 stype, int ok, int link_id)
 {
        struct ieee80211_hdr *hdr;
-       struct hostapd_data *orig_hapd = hapd, *tmp_hapd;
+       struct hostapd_data *orig_hapd, *tmp_hapd;
+
+#ifdef CONFIG_IEEE80211BE
+       if (hapd->conf->mld_ap && link_id != -1) {
+               tmp_hapd = hostapd_mld_get_link_bss(hapd, link_id);
+               if (tmp_hapd)
+                       hapd = tmp_hapd;
+       }
+#endif /* CONFIG_IEEE80211BE */
+       orig_hapd = hapd;
 
        hdr = (struct ieee80211_hdr *) buf;
        tmp_hapd = get_hapd_bssid(hapd->iface, get_hdr_bssid(hdr, len));
@@ -1975,7 +1984,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                        hostapd_mgmt_tx_cb(hapd, data->tx_status.data,
                                           data->tx_status.data_len,
                                           data->tx_status.stype,
-                                          data->tx_status.ack);
+                                          data->tx_status.ack,
+                                          data->tx_status.link_id);
                        break;
                case WLAN_FC_TYPE_DATA:
                        hostapd_tx_status(hapd, data->tx_status.dst,
index 196bcd287db338ca4dfbe54e9fc28c21bd6dd8da..24daa25db280c883bc2ac5ebef4f1d485774044f 100644 (file)
@@ -6187,6 +6187,7 @@ union wpa_event_data {
                const u8 *data;
                size_t data_len;
                int ack;
+               int link_id;
        } tx_status;
 
        /**
index 31e0b1d2f2abf5dc5c35c5fa2b3b529bbbef56a4..1df3145a69f12a629e9e3214bc0792d968247755 100644 (file)
@@ -4291,8 +4291,9 @@ static int wpa_driver_nl80211_send_mlme(struct i802_bss *bss, const u8 *data,
                                            noack);
        }
 
-       if (noack || WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT ||
-           WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_ACTION)
+       if ((noack || WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT ||
+            WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_ACTION) &&
+           link_id == NL80211_DRV_LINK_ID_NA)
                use_cookie = 0;
 send_frame_cmd:
 #ifdef CONFIG_TESTING_OPTIONS
@@ -4312,6 +4313,8 @@ send_frame_cmd:
        res = nl80211_send_frame_cmd(bss, freq, wait_time, data, data_len,
                                     use_cookie, no_cck, noack, offchanok,
                                     csa_offs, csa_offs_len);
+       if (!res)
+               drv->send_frame_link_id = link_id;
 
        return res;
 }
index 42307a9a7db4e1115e7085e2177f913ecd84d064..aee8c451243caa0d465262db2a9b27ab6378b30a 100644 (file)
@@ -206,6 +206,7 @@ struct wpa_driver_nl80211_data {
        u64 vendor_scan_cookie;
        u64 remain_on_chan_cookie;
        u64 send_frame_cookie;
+       int send_frame_link_id;
 #define MAX_SEND_FRAME_COOKIES 20
        u64 send_frame_cookies[MAX_SEND_FRAME_COOKIES];
        unsigned int num_send_frame_cookies;
index 0e97a7f4faef5fe4e08cc61941aa18aa554438b2..34e74da7f91f24099a8d6fb34638e809629cd1e3 100644 (file)
@@ -1424,6 +1424,8 @@ static void mlme_event_mgmt_tx_status(struct wpa_driver_nl80211_data *drv,
        event.tx_status.data = frame;
        event.tx_status.data_len = len;
        event.tx_status.ack = ack != NULL;
+       event.tx_status.link_id = cookie_val == drv->send_frame_cookie ?
+               drv->send_frame_link_id : NL80211_DRV_LINK_ID_NA;
        wpa_supplicant_event(drv->ctx, EVENT_TX_STATUS, &event);
 }