From: Andrei Otcheretianski Date: Mon, 22 May 2023 19:34:10 +0000 (+0300) Subject: AP/MLO: Forward Management frame TX status to correct BSS X-Git-Tag: hostap_2_11~1110 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5c6cad01fd684dfb365a548209d6ac48f69dae3f;p=thirdparty%2Fhostap.git AP/MLO: Forward Management frame TX status to correct BSS 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 --- diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c index ab956f0c1..92439e376 100644 --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -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, diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 196bcd287..24daa25db 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -6187,6 +6187,7 @@ union wpa_event_data { const u8 *data; size_t data_len; int ack; + int link_id; } tx_status; /** diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 31e0b1d2f..1df3145a6 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -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; } diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h index 42307a9a7..aee8c4512 100644 --- a/src/drivers/driver_nl80211.h +++ b/src/drivers/driver_nl80211.h @@ -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; diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c index 0e97a7f4f..34e74da7f 100644 --- a/src/drivers/driver_nl80211_event.c +++ b/src/drivers/driver_nl80211_event.c @@ -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); }