1
commit f47d639d495b32f0348c09a0fd0ff5b5791720d4
2
Author: Jouni Malinen <jouni.malinen@atheros.com>
3
Date: Thu Nov 25 22:51:56 2010 +0200
5
SME: Optimize recovery from common load balancing mechanisms
7
When authentication or association fails when trying to connect to
8
a BSS in an ESS that has multiple BSSes based on previous scans,
9
limit the first recovery scan to only the known channels that has
10
been seen previously. This speeds up recovery in some of the most
11
commonly used load balancing mechanisms in enterprise WLAN
14
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
15
index 2769c2f..68c8ce0 100644
16
--- a/wpa_supplicant/scan.c
17
+++ b/wpa_supplicant/scan.c
18
@@ -448,6 +448,14 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
20
#endif /* CONFIG_WPS */
22
+ if (params.freqs == NULL && wpa_s->next_scan_freqs) {
23
+ wpa_printf(MSG_DEBUG, "Optimize scan based on previously "
24
+ "generated frequency list");
25
+ params.freqs = wpa_s->next_scan_freqs;
27
+ os_free(wpa_s->next_scan_freqs);
28
+ wpa_s->next_scan_freqs = NULL;
30
params.filter_ssids = wpa_supplicant_build_filter_ssids(
31
wpa_s->conf, ¶ms.num_filter_ssids);
33
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
34
index 55788de..604b0a5 100644
35
--- a/wpa_supplicant/sme.c
36
+++ b/wpa_supplicant/sme.c
41
-static int sme_another_bss_in_ess(struct wpa_supplicant *wpa_s)
42
+static void add_freq(int *freqs, int *num_freqs, int freq)
46
+ for (i = 0; i < *num_freqs; i++) {
47
+ if (freqs[i] == freq)
51
+ freqs[*num_freqs] = freq;
56
+static int * sme_another_bss_in_ess(struct wpa_supplicant *wpa_s)
58
struct wpa_bss *bss, *cbss;
59
+ const int max_freqs = 10;
63
+ freqs = os_zalloc(sizeof(int) * (max_freqs + 1));
67
cbss = wpa_s->current_bss;
69
@@ -44,11 +65,19 @@ static int sme_another_bss_in_ess(struct wpa_supplicant *wpa_s)
71
if (bss->ssid_len == cbss->ssid_len &&
72
os_memcmp(bss->ssid, cbss->ssid, bss->ssid_len) == 0 &&
73
- wpa_blacklist_get(wpa_s, bss->bssid) == NULL)
75
+ wpa_blacklist_get(wpa_s, bss->bssid) == NULL) {
76
+ add_freq(freqs, &num_freqs, bss->freq);
77
+ if (num_freqs == max_freqs)
83
+ if (num_freqs == 0) {
92
@@ -57,6 +86,7 @@ static void sme_connection_failed(struct wpa_supplicant *wpa_s,
99
* Add the failed BSSID into the blacklist and speed up next scan
100
@@ -74,10 +104,18 @@ static void sme_connection_failed(struct wpa_supplicant *wpa_s,
101
* next. Otherwise, we may as well try this one once more
102
* before allowing other, likely worse, ESSes to be considered.
104
- if (sme_another_bss_in_ess(wpa_s)) {
105
+ freqs = sme_another_bss_in_ess(wpa_s);
107
wpa_printf(MSG_DEBUG, "SME: Another BSS in this ESS "
108
"has been seen; try it next");
109
wpa_blacklist_add(wpa_s, bssid);
111
+ * On the next scan, go through only the known channels
112
+ * used in this ESS based on previous scans to speed up
113
+ * common load balancing use case.
115
+ os_free(wpa_s->next_scan_freqs);
116
+ wpa_s->next_scan_freqs = freqs;
120
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
121
index 0a603af..e990911 100644
122
--- a/wpa_supplicant/wpa_supplicant.c
123
+++ b/wpa_supplicant/wpa_supplicant.c
124
@@ -433,6 +433,9 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
126
wpa_supplicant_ap_deinit(wpa_s);
127
#endif /* CONFIG_AP */
129
+ os_free(wpa_s->next_scan_freqs);
130
+ wpa_s->next_scan_freqs = NULL;
134
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
135
index 853968c..4c6fa4f 100644
136
--- a/wpa_supplicant/wpa_supplicant_i.h
137
+++ b/wpa_supplicant/wpa_supplicant_i.h
138
@@ -404,6 +404,7 @@ struct wpa_supplicant {
139
int scan_req; /* manual scan request; this forces a scan even if there
140
* are no enabled networks in the configuration */
141
int scan_runs; /* number of scan runs since WPS was started */
142
+ int *next_scan_freqs;
144
struct wpa_client_mlme mlme;
145
unsigned int drv_flags;