From 734fa392f7b46cdcdf2b705207d2c0934c63c944 Mon Sep 17 00:00:00 2001 From: Kuan-Chung Chen Date: Fri, 28 Jan 2022 17:25:46 +0800 Subject: [PATCH] MBO: Check association disallowed in Beacon frames, if newer When a station receives either a Beacon frame or a Probe Response frame from an AP that contains an MBO element with the Association Disallowed attribute, the station should prevent association to that AP. When using passive scanning, it is possible for the scan results to contain the latest information in the Beacon frame elements instead of the Probe Response frame elements. That could result in using old information and not noticing the AP having changed its state to disallowing new associations. Make it more likely to follow the AP's change to disallow associations by checking the Beacon frame elements instead of Probe Response frame elements if the scan results are known to contain newer information for the Beacon frame. Signed-off-by: Kuan-Chung Chen --- wpa_supplicant/events.c | 2 +- wpa_supplicant/mbo.c | 25 +++++++++++++++++++++---- wpa_supplicant/wpa_supplicant_i.h | 2 +- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index a977bca76..81f4a5f43 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -1454,7 +1454,7 @@ static bool wpa_scan_res_ok(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, if (wpa_s->ignore_assoc_disallow) goto skip_assoc_disallow; #endif /* CONFIG_TESTING_OPTIONS */ - assoc_disallow = wpas_mbo_get_bss_attr(bss, MBO_ATTR_ID_ASSOC_DISALLOW); + assoc_disallow = wpas_mbo_check_assoc_disallow(bss); if (assoc_disallow && assoc_disallow[1] >= 1) { if (debug_print) wpa_dbg(wpa_s, MSG_DEBUG, diff --git a/wpa_supplicant/mbo.c b/wpa_supplicant/mbo.c index 3df86ef07..59b15daf6 100644 --- a/wpa_supplicant/mbo.c +++ b/wpa_supplicant/mbo.c @@ -65,14 +65,18 @@ const u8 * mbo_get_attr_from_ies(const u8 *ies, size_t ies_len, } -const u8 * wpas_mbo_get_bss_attr(struct wpa_bss *bss, enum mbo_attr_id attr) +static const u8 * wpas_mbo_get_bss_attr(struct wpa_bss *bss, + enum mbo_attr_id attr, bool beacon) { const u8 *mbo, *end; if (!bss) return NULL; - mbo = wpa_bss_get_vendor_ie(bss, MBO_IE_VENDOR_TYPE); + if (beacon) + mbo = wpa_bss_get_vendor_ie_beacon(bss, MBO_IE_VENDOR_TYPE); + else + mbo = wpa_bss_get_vendor_ie(bss, MBO_IE_VENDOR_TYPE); if (!mbo) return NULL; @@ -83,6 +87,19 @@ const u8 * wpas_mbo_get_bss_attr(struct wpa_bss *bss, enum mbo_attr_id attr) } +const u8 * wpas_mbo_check_assoc_disallow(struct wpa_bss *bss) +{ + const u8 *assoc_disallow; + + assoc_disallow = wpas_mbo_get_bss_attr(bss, MBO_ATTR_ID_ASSOC_DISALLOW, + bss->beacon_newer); + if (assoc_disallow && assoc_disallow[1] >= 1) + return assoc_disallow; + + return NULL; +} + + void wpas_mbo_check_pmf(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, struct wpa_ssid *ssid) { @@ -92,8 +109,8 @@ void wpas_mbo_check_pmf(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, wpa_s->disable_mbo_oce = 0; if (!bss) return; - mbo = wpas_mbo_get_bss_attr(bss, MBO_ATTR_ID_AP_CAPA_IND); - oce = wpas_mbo_get_bss_attr(bss, OCE_ATTR_ID_CAPA_IND); + mbo = wpas_mbo_get_bss_attr(bss, MBO_ATTR_ID_AP_CAPA_IND, false); + oce = wpas_mbo_get_bss_attr(bss, OCE_ATTR_ID_CAPA_IND, false); if (!mbo && !oce) return; if (oce && oce[1] >= 1 && (oce[2] & OCE_IS_STA_CFON)) diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index da3c36166..0ba352fcb 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1686,7 +1686,7 @@ void wpa_supplicant_reset_bgscan(struct wpa_supplicant *wpa_s); int wpas_mbo_ie(struct wpa_supplicant *wpa_s, u8 *buf, size_t len, int add_oce_capa); const u8 * mbo_attr_from_mbo_ie(const u8 *mbo_ie, enum mbo_attr_id attr); -const u8 * wpas_mbo_get_bss_attr(struct wpa_bss *bss, enum mbo_attr_id attr); +const u8 * wpas_mbo_check_assoc_disallow(struct wpa_bss *bss); void wpas_mbo_check_pmf(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, struct wpa_ssid *ssid); const u8 * mbo_get_attr_from_ies(const u8 *ies, size_t ies_len,