diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h index a8a81d79b..c77ffa11a 100644 --- a/wpa_supplicant/config_ssid.h +++ b/wpa_supplicant/config_ssid.h @@ -837,6 +837,14 @@ struct wpa_ssid { */ struct os_reltime disabled_until; + /** + * disabled_due_to - BSSID of the disabling failure + * + * This identifies the BSS that failed the connection attempt that + * resulted in the network being temporarily disabled. + */ + u8 disabled_due_to[ETH_ALEN]; + /** * parent_cred - Pointer to parent wpa_cred entry * diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 5af3b6177..35f3694a0 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -2845,7 +2845,7 @@ static int wpa_supplicant_use_own_rsne_params(struct wpa_supplicant *wpa_s, if (!ssid->psk_set) { wpa_dbg(wpa_s, MSG_INFO, "No PSK available for association"); - wpas_auth_failed(wpa_s, "NO_PSK_AVAILABLE"); + wpas_auth_failed(wpa_s, "NO_PSK_AVAILABLE", NULL); return -1; } @@ -3895,7 +3895,7 @@ static void wpa_supplicant_event_disassoc_finish(struct wpa_supplicant *wpa_s, "pre-shared key may be incorrect"); if (wpas_p2p_4way_hs_failed(wpa_s) > 0) return; /* P2P group removed */ - wpas_auth_failed(wpa_s, "WRONG_KEY"); + wpas_auth_failed(wpa_s, "WRONG_KEY", prev_pending_bssid); #ifdef CONFIG_DPP2 wpas_dpp_send_conn_status_result(wpa_s, DPP_STATUS_AUTH_FAILURE); @@ -4399,7 +4399,7 @@ static void wpas_event_disconnect(struct wpa_supplicant *wpa_s, const u8 *addr, (wpa_s->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA)) && eapol_sm_failed(wpa_s->eapol))) && !wpa_s->eap_expected_failure)) - wpas_auth_failed(wpa_s, "AUTH_FAILED"); + wpas_auth_failed(wpa_s, "AUTH_FAILED", addr); #ifdef CONFIG_P2P if (deauth && reason_code > 0) { diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index f9409f56a..ab2e70b5d 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -2011,7 +2011,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, if (!psk_set) { wpa_msg(wpa_s, MSG_INFO, "No PSK available for association"); - wpas_auth_failed(wpa_s, "NO_PSK_AVAILABLE"); + wpas_auth_failed(wpa_s, "NO_PSK_AVAILABLE", NULL); return -1; } #ifdef CONFIG_OWE @@ -7919,7 +7919,7 @@ void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid) if (wpa_s->consecutive_conn_failures > 3 && wpa_s->current_ssid) { wpa_printf(MSG_DEBUG, "Continuous association failures - " "consider temporary network disabling"); - wpas_auth_failed(wpa_s, "CONN_FAILED"); + wpas_auth_failed(wpa_s, "CONN_FAILED", bssid); } /* * Multiple consecutive connection failures mean that other APs are @@ -8266,7 +8266,8 @@ int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s) } -void wpas_auth_failed(struct wpa_supplicant *wpa_s, char *reason) +void wpas_auth_failed(struct wpa_supplicant *wpa_s, const char *reason, + const u8 *bssid) { struct wpa_ssid *ssid = wpa_s->current_ssid; int dur; @@ -8323,6 +8324,9 @@ void wpas_auth_failed(struct wpa_supplicant *wpa_s, char *reason) "id=%d ssid=\"%s\" auth_failures=%u duration=%d reason=%s", ssid->id, wpa_ssid_txt(ssid->ssid, ssid->ssid_len), ssid->auth_failures, dur, reason); + + if (bssid) + os_memcpy(ssid->disabled_due_to, bssid, ETH_ALEN); } @@ -8339,8 +8343,15 @@ void wpas_clear_temp_disabled(struct wpa_supplicant *wpa_s, } ssid->disabled_until.sec = 0; ssid->disabled_until.usec = 0; - if (clear_failures) + if (clear_failures) { ssid->auth_failures = 0; + } else if (!is_zero_ether_addr(ssid->disabled_due_to)) { + wpa_printf(MSG_DEBUG, "Mark BSSID " MACSTR + " ignored to allow a lower priority BSS, if any, to be tried next", + MAC2STR(ssid->disabled_due_to)); + wpa_bssid_ignore_add(wpa_s, ssid->disabled_due_to); + os_memset(ssid->disabled_due_to, 0, ETH_ALEN); + } } diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 3e35b9ca8..add24f07d 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1629,7 +1629,8 @@ void fils_connection_failure(struct wpa_supplicant *wpa_s); void fils_pmksa_cache_flush(struct wpa_supplicant *wpa_s); int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s); int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s); -void wpas_auth_failed(struct wpa_supplicant *wpa_s, char *reason); +void wpas_auth_failed(struct wpa_supplicant *wpa_s, const char *reason, + const u8 *bssid); void wpas_clear_temp_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, int clear_failures); int disallowed_bssid(struct wpa_supplicant *wpa_s, const u8 *bssid);