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;
}
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;
}
}
+/**
+ * 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
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 */
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);
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;
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;
}
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;
}
#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)");
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;
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) {
/*
*/
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;
}
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;
}
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);
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;