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 <benjamin.berg@intel.com>
This commit is contained in:
parent
770f3cb30b
commit
17a2aa822c
2 changed files with 33 additions and 24 deletions
|
@ -1071,7 +1071,7 @@ static int wnm_send_bss_transition_mgmt_resp(
|
||||||
wpabuf_put_data(buf, "\0\0\0\0\0\0", ETH_ALEN);
|
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);
|
wnm_add_cand_list(wpa_s, &buf);
|
||||||
|
|
||||||
#ifdef CONFIG_MBO
|
#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
|
* 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.
|
* one of the links is removed and the other links remain associated.
|
||||||
* Ignore the Disassociation Imminent field in such a case.
|
* 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 &&
|
if (disassoc_imminent && wpa_s->valid_links &&
|
||||||
(wpa_s->valid_links & (wpa_s->valid_links - 1)) != 0 &&
|
|
||||||
(wpa_s->wnm_mode & WNM_BSS_TM_REQ_LINK_REMOVAL_IMMINENT) &&
|
(wpa_s->wnm_mode & WNM_BSS_TM_REQ_LINK_REMOVAL_IMMINENT) &&
|
||||||
(wpa_s->wnm_mode & WNM_BSS_TM_REQ_BSS_TERMINATION_INCLUDED)) {
|
(wpa_s->wnm_mode & WNM_BSS_TM_REQ_BSS_TERMINATION_INCLUDED)) {
|
||||||
|
/* 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,
|
wpa_printf(MSG_INFO,
|
||||||
"WNM: BTM request for a single MLO link - ignore disassociation imminent since other links remain associated");
|
"WNM: BTM request for a single MLO link - ignore disassociation imminent since other links remain associated");
|
||||||
disassoc_imminent = false;
|
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;
|
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) {
|
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)
|
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))
|
if (!(wpa_s->wnm_mode & WNM_BSS_TM_REQ_DISASSOC_IMMINENT))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -2043,24 +2060,15 @@ 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
|
* In case disassociation imminent is set, do no try to use a BSS to
|
||||||
* which we are connected.
|
* which we are connected.
|
||||||
*/
|
*/
|
||||||
|
if (wpa_s->wnm_link_removal ||
|
||||||
if (wpa_s->current_bss &&
|
!(wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_MLO) ||
|
||||||
ether_addr_equal(wpa_s->current_bss->bssid, bss->bssid)) {
|
is_zero_ether_addr(bss->mld_addr)) {
|
||||||
wpa_dbg(wpa_s, MSG_DEBUG,
|
if (ether_addr_equal(bss->bssid, wpa_s->wnm_dissoc_addr))
|
||||||
"WNM: Disassociation imminent: current BSS");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
} else {
|
||||||
|
if (ether_addr_equal(bss->mld_addr, wpa_s->wnm_dissoc_addr))
|
||||||
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");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1305,6 +1305,7 @@ struct wpa_supplicant {
|
||||||
u8 wnm_num_neighbor_report;
|
u8 wnm_num_neighbor_report;
|
||||||
u8 wnm_mode;
|
u8 wnm_mode;
|
||||||
bool wnm_link_removal;
|
bool wnm_link_removal;
|
||||||
|
u8 wnm_dissoc_addr[ETH_ALEN];
|
||||||
u16 wnm_dissoc_timer;
|
u16 wnm_dissoc_timer;
|
||||||
u8 wnm_bss_termination_duration[12];
|
u8 wnm_bss_termination_duration[12];
|
||||||
struct neighbor_report *wnm_neighbor_report_elements;
|
struct neighbor_report *wnm_neighbor_report_elements;
|
||||||
|
|
Loading…
Reference in a new issue