diff --git a/wpa_supplicant/blacklist.c b/wpa_supplicant/blacklist.c index 2e01e7fea..c88a69acd 100644 --- a/wpa_supplicant/blacklist.c +++ b/wpa_supplicant/blacklist.c @@ -56,16 +56,29 @@ struct wpa_blacklist * wpa_blacklist_get(struct wpa_supplicant *wpa_s, int wpa_blacklist_add(struct wpa_supplicant *wpa_s, const u8 *bssid) { struct wpa_blacklist *e; + struct os_reltime now; if (wpa_s == NULL || bssid == NULL) return -1; e = wpa_blacklist_get(wpa_s, bssid); + os_get_reltime(&now); if (e) { + e->blacklist_start = now; e->count++; - wpa_printf(MSG_DEBUG, "BSSID " MACSTR " blacklist count " - "incremented to %d", - MAC2STR(bssid), e->count); + if (e->count > 5) + e->timeout_secs = 1800; + else if (e->count == 5) + e->timeout_secs = 600; + else if (e->count == 4) + e->timeout_secs = 120; + else if (e->count == 3) + e->timeout_secs = 60; + else + e->timeout_secs = 10; + wpa_printf(MSG_INFO, "BSSID " MACSTR + " blacklist count incremented to %d, blacklisting for %d seconds", + MAC2STR(bssid), e->count, e->timeout_secs); return e->count; } @@ -74,10 +87,13 @@ int wpa_blacklist_add(struct wpa_supplicant *wpa_s, const u8 *bssid) return -1; os_memcpy(e->bssid, bssid, ETH_ALEN); e->count = 1; + e->timeout_secs = 10; + e->blacklist_start = now; e->next = wpa_s->blacklist; wpa_s->blacklist = e; - wpa_printf(MSG_DEBUG, "Added BSSID " MACSTR " into blacklist", - MAC2STR(bssid)); + wpa_printf(MSG_DEBUG, "Added BSSID " MACSTR + " into blacklist, blacklisting for %d seconds", + MAC2STR(bssid), e->timeout_secs); return e->count; } @@ -116,6 +132,27 @@ int wpa_blacklist_del(struct wpa_supplicant *wpa_s, const u8 *bssid) } +/** + * wpa_blacklist_is_blacklisted - Check the blacklist status of a BSS + * @wpa_s: Pointer to wpa_supplicant data + * @bssid: BSSID to be checked + * Returns: count if BSS is currently considered to be blacklisted, 0 otherwise + */ +int wpa_blacklist_is_blacklisted(struct wpa_supplicant *wpa_s, const u8 *bssid) +{ + struct wpa_blacklist *e; + struct os_reltime now; + + e = wpa_blacklist_get(wpa_s, bssid); + if (!e) + return 0; + os_get_reltime(&now); + if (os_reltime_expired(&now, &e->blacklist_start, e->timeout_secs)) + return 0; + return e->count; +} + + /** * wpa_blacklist_clear - Clear the blacklist of all entries * @wpa_s: Pointer to wpa_supplicant data diff --git a/wpa_supplicant/blacklist.h b/wpa_supplicant/blacklist.h index ae06986f3..54ca6a37f 100644 --- a/wpa_supplicant/blacklist.h +++ b/wpa_supplicant/blacklist.h @@ -13,12 +13,20 @@ struct wpa_blacklist { struct wpa_blacklist *next; u8 bssid[ETH_ALEN]; int count; + /* Time of most recent blacklist event. */ + struct os_reltime blacklist_start; + /* + * Number of seconds after blacklist_start that the entry will be + * considered blacklisted. + */ + int timeout_secs; }; struct wpa_blacklist * wpa_blacklist_get(struct wpa_supplicant *wpa_s, const u8 *bssid); int wpa_blacklist_add(struct wpa_supplicant *wpa_s, const u8 *bssid); int wpa_blacklist_del(struct wpa_supplicant *wpa_s, const u8 *bssid); +int wpa_blacklist_is_blacklisted(struct wpa_supplicant *wpa_s, const u8 *bssid); void wpa_blacklist_clear(struct wpa_supplicant *wpa_s); #endif /* BLACKLIST_H */ diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 7b7802c46..1b46a9715 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -1085,7 +1085,7 @@ static int disabled_freq(struct wpa_supplicant *wpa_s, int freq) static bool wpa_scan_res_ok(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, const u8 *match_ssid, size_t match_ssid_len, - struct wpa_bss *bss, struct wpa_blacklist *e, + struct wpa_bss *bss, int blacklist_count, bool debug_print); @@ -1099,7 +1099,7 @@ static bool sae_pk_acceptable_bss_with_pk(struct wpa_supplicant *wpa_s, struct wpa_bss *bss; dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { - struct wpa_blacklist *e; + int count; const u8 *ie; u8 rsnxe_capa = 0; @@ -1117,9 +1117,9 @@ static bool sae_pk_acceptable_bss_with_pk(struct wpa_supplicant *wpa_s, if (bss->est_throughput < 2000) return false; - e = wpa_blacklist_get(wpa_s, bss->bssid); + count = wpa_blacklist_is_blacklisted(wpa_s, bss->bssid); if (wpa_scan_res_ok(wpa_s, ssid, match_ssid, match_ssid_len, - bss, e, 0)) + bss, count, 0)) return true; } @@ -1130,7 +1130,7 @@ static bool sae_pk_acceptable_bss_with_pk(struct wpa_supplicant *wpa_s, static bool wpa_scan_res_ok(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, const u8 *match_ssid, size_t match_ssid_len, - struct wpa_bss *bss, struct wpa_blacklist *e, + struct wpa_bss *bss, int blacklist_count, bool debug_print) { int res; @@ -1178,7 +1178,7 @@ static bool wpa_scan_res_ok(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, } #ifdef CONFIG_WPS - if ((ssid->key_mgmt & WPA_KEY_MGMT_WPS) && e && e->count > 0) { + if ((ssid->key_mgmt & WPA_KEY_MGMT_WPS) && blacklist_count) { if (debug_print) wpa_dbg(wpa_s, MSG_DEBUG, " skip - blacklisted (WPS)"); @@ -1472,12 +1472,12 @@ struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s, int only_first_ssid, int debug_print) { u8 wpa_ie_len, rsn_ie_len; - struct wpa_blacklist *e; const u8 *ie; struct wpa_ssid *ssid; int osen; const u8 *match_ssid; size_t match_ssid_len; + int blacklist_count; ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); wpa_ie_len = ie ? ie[1] : 0; @@ -1503,8 +1503,8 @@ struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s, osen ? " osen=1" : ""); } - e = wpa_blacklist_get(wpa_s, bss->bssid); - if (e) { + blacklist_count = wpa_blacklist_is_blacklisted(wpa_s, bss->bssid); + if (blacklist_count) { int limit = 1; if (wpa_supplicant_enabled_networks(wpa_s) == 1) { /* @@ -1517,11 +1517,11 @@ struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s, */ limit = 0; } - if (e->count > limit) { + if (blacklist_count > limit) { if (debug_print) { wpa_dbg(wpa_s, MSG_DEBUG, " skip - blacklisted (count=%d limit=%d)", - e->count, limit); + blacklist_count, limit); } return NULL; } @@ -1557,7 +1557,7 @@ struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s, for (ssid = group; ssid; ssid = only_first_ssid ? NULL : ssid->pnext) { if (wpa_scan_res_ok(wpa_s, ssid, match_ssid, match_ssid_len, - bss, e, debug_print)) + bss, blacklist_count, debug_print)) return ssid; } diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 29c5d34e7..30fb04786 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -984,7 +984,6 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s, fils_hlp_sent ? " FILS_HLP_SENT" : ""); #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ wpas_clear_temp_disabled(wpa_s, ssid, 1); - wpa_blacklist_clear(wpa_s); wpa_s->consecutive_conn_failures = 0; wpa_s->new_connection = 0; wpa_drv_set_operstate(wpa_s, 1); @@ -7324,7 +7323,7 @@ static int * get_bss_freqs_in_ess(struct wpa_supplicant *wpa_s) continue; if (bss->ssid_len == cbss->ssid_len && os_memcmp(bss->ssid, cbss->ssid, bss->ssid_len) == 0 && - wpa_blacklist_get(wpa_s, bss->bssid) == NULL) { + !wpa_blacklist_is_blacklisted(wpa_s, bss->bssid)) { add_freq(freqs, &num_freqs, bss->freq); if (num_freqs == max_freqs) break;