From 17a2aa822c26b042b89491677b844730f29699dc Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Tue, 20 Feb 2024 14:18:26 +0100 Subject: [PATCH] WNM: Follow BTM procedure if the last link is dropped If the last link is dropped, it makes sense to follow the BTM procedure. However, in that case we need to prevent reconnection to this link specifically, while if the AP MLD is terminating we need to forbid connecting to the AP MLD. As such, add a new variable to track the BSSID or AP MLD MAC address. Which one it refers to depends on whether wnm_link_removal is set. This also simplifies the check in wnm_is_bss_excluded() and untangles it from wpa_s->current_bss. Signed-off-by: Benjamin Berg --- wpa_supplicant/wnm_sta.c | 56 ++++++++++++++++++------------- wpa_supplicant/wpa_supplicant_i.h | 1 + 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/wpa_supplicant/wnm_sta.c b/wpa_supplicant/wnm_sta.c index 8a14566a8..bd4c1317d 100644 --- a/wpa_supplicant/wnm_sta.c +++ b/wpa_supplicant/wnm_sta.c @@ -1071,7 +1071,7 @@ static int wnm_send_bss_transition_mgmt_resp( wpabuf_put_data(buf, "\0\0\0\0\0\0", ETH_ALEN); } - if (status == WNM_BSS_TM_ACCEPT && !wpa_s->wnm_link_removal) + if (status == WNM_BSS_TM_ACCEPT && target_bssid) wnm_add_cand_list(wpa_s, &buf); #ifdef CONFIG_MBO @@ -1467,15 +1467,34 @@ static void ieee802_11_rx_bss_trans_mgmt_req(struct wpa_supplicant *wpa_s, * set to 1, and the BSS Termination Included field is set to 1, only * one of the links is removed and the other links remain associated. * Ignore the Disassociation Imminent field in such a case. + * + * TODO: We should check if the AP has more than one link. + * TODO: We should pass the RX link and use that */ - if (disassoc_imminent && - (wpa_s->valid_links & (wpa_s->valid_links - 1)) != 0 && + if (disassoc_imminent && wpa_s->valid_links && (wpa_s->wnm_mode & WNM_BSS_TM_REQ_LINK_REMOVAL_IMMINENT) && (wpa_s->wnm_mode & WNM_BSS_TM_REQ_BSS_TERMINATION_INCLUDED)) { - wpa_printf(MSG_INFO, - "WNM: BTM request for a single MLO link - ignore disassociation imminent since other links remain associated"); - disassoc_imminent = false; + /* If we still have a link, then just accept the request */ + if (wpa_s->valid_links & (wpa_s->valid_links - 1)) { + wpa_printf(MSG_INFO, + "WNM: BTM request for a single MLO link - ignore disassociation imminent since other links remain associated"); + disassoc_imminent = false; + + wnm_send_bss_transition_mgmt_resp( + wpa_s, WNM_BSS_TM_ACCEPT, 0, 0, NULL); + + return; + } + + /* The last link is being removed (which must be the assoc link) + */ wpa_s->wnm_link_removal = true; + os_memcpy(wpa_s->wnm_dissoc_addr, + wpa_s->links[wpa_s->mlo_assoc_link_id].bssid, + ETH_ALEN); + } else { + os_memcpy(wpa_s->wnm_dissoc_addr, wpa_s->valid_links ? + wpa_s->ap_mld_addr : wpa_s->bssid, ETH_ALEN); } if (disassoc_imminent) { @@ -2034,8 +2053,6 @@ void wnm_clear_coloc_intf_reporting(struct wpa_supplicant *wpa_s) bool wnm_is_bss_excluded(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) { - unsigned int i; - if (!(wpa_s->wnm_mode & WNM_BSS_TM_REQ_DISASSOC_IMMINENT)) return false; @@ -2043,23 +2060,14 @@ bool wnm_is_bss_excluded(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) * In case disassociation imminent is set, do no try to use a BSS to * which we are connected. */ - - if (wpa_s->current_bss && - ether_addr_equal(wpa_s->current_bss->bssid, bss->bssid)) { - wpa_dbg(wpa_s, MSG_DEBUG, - "WNM: Disassociation imminent: current BSS"); - return true; - } - - if (!wpa_s->valid_links) - return false; - - for_each_link(wpa_s->valid_links, i) { - if (ether_addr_equal(wpa_s->links[i].bssid, bss->bssid)) { - wpa_dbg(wpa_s, MSG_DEBUG, - "WNM: MLD: Disassociation imminent: current link"); + if (wpa_s->wnm_link_removal || + !(wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_MLO) || + is_zero_ether_addr(bss->mld_addr)) { + if (ether_addr_equal(bss->bssid, wpa_s->wnm_dissoc_addr)) + return true; + } else { + if (ether_addr_equal(bss->mld_addr, wpa_s->wnm_dissoc_addr)) return true; - } } return false; diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 80ea515aa..97aa86279 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1305,6 +1305,7 @@ struct wpa_supplicant { u8 wnm_num_neighbor_report; u8 wnm_mode; bool wnm_link_removal; + u8 wnm_dissoc_addr[ETH_ALEN]; u16 wnm_dissoc_timer; u8 wnm_bss_termination_duration[12]; struct neighbor_report *wnm_neighbor_report_elements;