Add optional scan result filter based on SSID

filter_ssids=1 global configuration parameter can now be used to
enable scan result filtering (with -Dnl80211 only for now) based on
the configured SSIDs. In other words, only the scan results that have
an SSID matching with one of the configured networks are included in the
BSS table. This can be used to reduce memory needs in environments that
have huge number of APs.
This commit is contained in:
Jouni Malinen 2010-03-05 21:42:06 +02:00
parent c9c38b0996
commit 3812464cda
7 changed files with 155 additions and 4 deletions

View file

@ -337,6 +337,14 @@ struct wpa_config {
* bss_max_count - Maximum number of BSS entries to keep in memory
*/
unsigned int bss_max_count;
/**
* filter_ssids - SSID-based scan result filtering
*
* 0 = do not filter scan results
* 1 = only include configured SSIDs in scan results/BSS table
*/
int filter_ssids;
};

View file

@ -458,7 +458,8 @@ static const struct global_parse_data global_fields[] = {
{ INT_RANGE(wps_cred_processing, 0, 2) },
#endif /* CONFIG_WPS */
{ FUNC(country) },
{ INT(bss_max_count) }
{ INT(bss_max_count) },
{ INT_RANGE(filter_ssids, 0, 1) }
};
#undef FUNC
@ -892,6 +893,8 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
}
if (config->bss_max_count != DEFAULT_BSS_MAX_COUNT)
fprintf(f, "bss_max_count=%u\n", config->bss_max_count);
if (config->filter_ssids)
fprintf(f, "filter_ssids=%d\n", config->filter_ssids);
}
#endif /* CONFIG_NO_CONFIG_WRITE */

View file

@ -259,6 +259,8 @@ static int wpa_config_read_global(struct wpa_config *config, HKEY hk)
wpa_config_read_reg_dword(hk, TEXT("bss_max_count"),
&config->bss_max_count);
wpa_config_read_reg_dword(hk, TEXT("filter_ssids"),
&config->filter_ssids);
return errors ? -1 : 0;
}
@ -589,6 +591,8 @@ static int wpa_config_write_global(struct wpa_config *config, HKEY hk)
wpa_config_write_reg_dword(hk, TEXT("bss_max_count"),
config->bss_max_count,
DEFAULT_BSS_MAX_COUNT);
wpa_config_write_reg_dword(hk, TEXT("filter_ssids"),
config->filter_ssids, 0);
return 0;
}

View file

@ -204,6 +204,39 @@ int wpa_supplicant_trigger_scan(struct wpa_supplicant *wpa_s,
}
static struct wpa_driver_scan_filter *
wpa_supplicant_build_filter_ssids(struct wpa_config *conf, size_t *num_ssids)
{
struct wpa_driver_scan_filter *ssids;
struct wpa_ssid *ssid;
size_t count;
*num_ssids = 0;
if (!conf->filter_ssids)
return NULL;
for (count = 0, ssid = conf->ssid; ssid; ssid = ssid->next) {
if (ssid->ssid && ssid->ssid_len)
count++;
}
if (count == 0)
return NULL;
ssids = os_zalloc(count * sizeof(struct wpa_driver_scan_filter));
if (ssids == NULL)
return NULL;
for (ssid = conf->ssid; ssid; ssid = ssid->next) {
if (!ssid->ssid || !ssid->ssid_len)
continue;
os_memcpy(ssids[*num_ssids].ssid, ssid->ssid, ssid->ssid_len);
ssids[*num_ssids].ssid_len = ssid->ssid_len;
(*num_ssids)++;
}
return ssids;
}
static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
{
struct wpa_supplicant *wpa_s = eloop_ctx;
@ -258,7 +291,7 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
if (wpa_s->scan_res_tried == 0 && wpa_s->conf->ap_scan == 1 &&
!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) &&
wps != 2) {
wps != 2 && !wpa_s->conf->filter_ssids) {
wpa_s->scan_res_tried++;
wpa_printf(MSG_DEBUG, "Trying to get current scan results "
"first without requesting a new scan to speed up "
@ -363,10 +396,14 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
}
#endif /* CONFIG_WPS */
params.filter_ssids = wpa_supplicant_build_filter_ssids(
wpa_s->conf, &params.num_filter_ssids);
ret = wpa_supplicant_trigger_scan(wpa_s, &params);
wpabuf_free(wps_ie);
os_free(params.freqs);
os_free(params.filter_ssids);
if (ret) {
wpa_printf(MSG_WARNING, "Failed to initiate AP scan.");

View file

@ -218,6 +218,12 @@ fast_reauth=1
#bss_max_count=200
# filter_ssids - SSID-based scan result filtering
# 0 = do not filter scan results (default)
# 1 = only include configured SSIDs in scan results/BSS table
#filter_ssids=0
# network block
#
# Each network (usually AP's sharing the same SSID) is configured as a separate