Reject authentication start during BSS TM requests

After receiving a BSS Transition Management request,
wpa_supplicant_connect() will abort ongoing scans, which will cause scan
results to be reported. Since the reassociate bit is set, this will
trigger a connection attempt based on the aborted scan's scan results
and cancel the initial connection request. This often causes
wpa_supplicant to reassociate to the same AP it is currently associated
to instead of the AP it was asked to transition to.

Add a bss_trans_mgmt_in_progress flag to indicate that we're currently
transitioning to a different AP so that we don't initiate another
connection attempt based on the possibly received scan results from a
scan that was in progress at the time the BSS Transition Management
request was received.

This is the equivalent of commit 5ac977758d ("Reject authentication
start during explicit roam requests") for the roaming scenario.

Signed-off-by: Nicolas Norvez <norvez@chromium.org>
This commit is contained in:
Nicolas Norvez 2022-01-05 01:35:13 +00:00 committed by Jouni Malinen
parent af6d4031d7
commit 16b5ea9e91
3 changed files with 22 additions and 0 deletions

View file

@ -946,6 +946,9 @@ static void sme_auth_start_cb(struct wpa_radio_work *work, int deinit)
struct wpa_supplicant *wpa_s = work->wpa_s; struct wpa_supplicant *wpa_s = work->wpa_s;
wpa_s->roam_in_progress = false; wpa_s->roam_in_progress = false;
#ifdef CONFIG_WNM
wpa_s->bss_trans_mgmt_in_progress = false;
#endif /* CONFIG_WNM */
if (deinit) { if (deinit) {
if (work->started) if (work->started)
@ -992,6 +995,13 @@ void sme_authenticate(struct wpa_supplicant *wpa_s,
"SME: Reject sme_authenticate() in favor of explicit roam request"); "SME: Reject sme_authenticate() in favor of explicit roam request");
return; return;
} }
#ifdef CONFIG_WNM
if (wpa_s->bss_trans_mgmt_in_progress) {
wpa_dbg(wpa_s, MSG_DEBUG,
"SME: Reject sme_authenticate() in favor of BSS transition management request");
return;
}
#endif /* CONFIG_WNM */
if (radio_work_pending(wpa_s, "sme-connect")) { if (radio_work_pending(wpa_s, "sme-connect")) {
/* /*
* The previous sme-connect work might no longer be valid due to * The previous sme-connect work might no longer be valid due to

View file

@ -1097,6 +1097,8 @@ static void wnm_bss_tm_connect(struct wpa_supplicant *wpa_s,
struct wpa_bss *bss, struct wpa_ssid *ssid, struct wpa_bss *bss, struct wpa_ssid *ssid,
int after_new_scan) int after_new_scan)
{ {
struct wpa_radio_work *already_connecting;
wpa_dbg(wpa_s, MSG_DEBUG, wpa_dbg(wpa_s, MSG_DEBUG,
"WNM: Transition to BSS " MACSTR "WNM: Transition to BSS " MACSTR
" based on BSS Transition Management Request (old BSSID " " based on BSS Transition Management Request (old BSSID "
@ -1121,9 +1123,18 @@ static void wnm_bss_tm_connect(struct wpa_supplicant *wpa_s,
return; return;
} }
already_connecting = radio_work_pending(wpa_s, "sme-connect");
wpa_s->reassociate = 1; wpa_s->reassociate = 1;
wpa_printf(MSG_DEBUG, "WNM: Issuing connect"); wpa_printf(MSG_DEBUG, "WNM: Issuing connect");
wpa_supplicant_connect(wpa_s, bss, ssid); wpa_supplicant_connect(wpa_s, bss, ssid);
/*
* Indicate that a BSS transition is in progress so scan results that
* come in before the 'sme-connect' radio work gets executed do not
* override the original connection attempt.
*/
if (!already_connecting && radio_work_pending(wpa_s, "sme-connect"))
wpa_s->bss_trans_mgmt_in_progress = true;
wnm_deallocate_memory(wpa_s); wnm_deallocate_memory(wpa_s);
} }

View file

@ -1286,6 +1286,7 @@ struct wpa_supplicant {
struct os_reltime wnm_cand_valid_until; struct os_reltime wnm_cand_valid_until;
u8 wnm_cand_from_bss[ETH_ALEN]; u8 wnm_cand_from_bss[ETH_ALEN];
enum bss_trans_mgmt_status_code bss_tm_status; enum bss_trans_mgmt_status_code bss_tm_status;
bool bss_trans_mgmt_in_progress;
struct wpabuf *coloc_intf_elems; struct wpabuf *coloc_intf_elems;
u8 coloc_intf_dialog_token; u8 coloc_intf_dialog_token;
u8 coloc_intf_auto_report; u8 coloc_intf_auto_report;