diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h index 3000c43b4..d2a52d760 100644 --- a/wpa_supplicant/config_ssid.h +++ b/wpa_supplicant/config_ssid.h @@ -927,6 +927,16 @@ struct wpa_ssid { * 1 = disable transition mode (allow connection only with OWE) */ int owe_only; + + /** + * owe_transition_bss_select_count - OWE transition BSS select count + * + * This is an internally used variable (i.e., not used in external + * configuration) to track the number of selection attempts done for + * OWE BSS in transition mode. This allows fallback to an open BSS if + * the selection attempts for OWE BSS exceed the configured threshold. + */ + int owe_transition_bss_select_count; }; #endif /* CONFIG_SSID_H */ diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 349f81997..115913106 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -50,6 +50,9 @@ #include "dpp_supplicant.h" +#define MAX_OWE_TRANSITION_BSS_SELECT_COUNT 5 + + #ifndef CONFIG_NO_SCAN_PROCESSING static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s, int new_scan, int own_request); @@ -703,6 +706,18 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s, #ifdef CONFIG_OWE if ((ssid->key_mgmt & WPA_KEY_MGMT_OWE) && !ssid->owe_only && !wpa_ie && !rsn_ie) { + if (wpa_s->owe_transition_select && + wpa_bss_get_vendor_ie(bss, OWE_IE_VENDOR_TYPE) && + ssid->owe_transition_bss_select_count + 1 <= + MAX_OWE_TRANSITION_BSS_SELECT_COUNT) { + ssid->owe_transition_bss_select_count++; + if (debug_print) + wpa_dbg(wpa_s, MSG_DEBUG, + " skip OWE transition BSS (selection count %d does not exceed %d)", + ssid->owe_transition_bss_select_count, + MAX_OWE_TRANSITION_BSS_SELECT_COUNT); + return 0; + } if (debug_print) wpa_dbg(wpa_s, MSG_DEBUG, " allow in OWE transition mode"); @@ -1387,8 +1402,11 @@ wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s, for (i = 0; i < wpa_s->last_scan_res_used; i++) { struct wpa_bss *bss = wpa_s->last_scan_res[i]; + + wpa_s->owe_transition_select = 1; *selected_ssid = wpa_scan_res_match(wpa_s, i, bss, group, only_first_ssid, 1); + wpa_s->owe_transition_select = 0; if (!*selected_ssid) continue; wpa_dbg(wpa_s, MSG_DEBUG, " selected BSS " MACSTR diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 4531c62a7..eed973590 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -3307,6 +3307,7 @@ static void wpa_supplicant_enable_one_network(struct wpa_supplicant *wpa_s, return; ssid->disabled = 0; + ssid->owe_transition_bss_select_count = 0; wpas_clear_temp_disabled(wpa_s, ssid, 1); wpas_notify_network_enabled_changed(wpa_s, ssid); @@ -3571,6 +3572,8 @@ void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s, wpa_s->disconnected = 0; wpa_s->reassociate = 1; wpa_s->last_owe_group = 0; + if (ssid) + ssid->owe_transition_bss_select_count = 0; if (wpa_s->connect_without_scan || wpa_supplicant_fast_associate(wpa_s) != 1) { diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 9b8d1fa1e..271f3776a 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -743,6 +743,7 @@ struct wpa_supplicant { unsigned int mac_addr_changed:1; unsigned int added_vif:1; unsigned int wnmsleep_used:1; + unsigned int owe_transition_select:1; struct os_reltime last_mac_addr_change; int last_mac_addr_style;