Commit 95de817b9034d50860319f6033ec85d25024694c

Authored by Johannes Berg
Committed by John W. Linville
1 parent 7852e36186

cfg80211: stop tracking authenticated state

To track authenticated state seems to have been
a design mistake in cfg80211. It is possible to
have out of band authentication (FT), tracking
multiple authentications caused more problems
than it ever helped, and the implementation in
mac80211 is too complex.

Remove all this complexity, and let userspace
do whatever it wants to, mac80211 can deal with
that just fine. Association is still tracked of
course, but authentication no longer is. Local
auth state changes are thus no longer of value,
so ignore them completely.

This will also help implement SAE -- asking the
driver to do an authentication is now almost
equivalent to sending an authentication frame,
with the exception of shared key authentication
which is still handled completely.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

Showing 7 changed files with 91 additions and 362 deletions Side-by-side Diff

Documentation/DocBook/80211.tmpl
... ... @@ -129,7 +129,6 @@
129 129 !Finclude/net/cfg80211.h cfg80211_pmksa
130 130 !Finclude/net/cfg80211.h cfg80211_send_rx_auth
131 131 !Finclude/net/cfg80211.h cfg80211_send_auth_timeout
132   -!Finclude/net/cfg80211.h __cfg80211_auth_canceled
133 132 !Finclude/net/cfg80211.h cfg80211_send_rx_assoc
134 133 !Finclude/net/cfg80211.h cfg80211_send_assoc_timeout
135 134 !Finclude/net/cfg80211.h cfg80211_send_deauth
include/net/cfg80211.h
... ... @@ -1039,10 +1039,6 @@
1039 1039 * @key_len: length of WEP key for shared key authentication
1040 1040 * @key_idx: index of WEP key for shared key authentication
1041 1041 * @key: WEP key for shared key authentication
1042   - * @local_state_change: This is a request for a local state only, i.e., no
1043   - * Authentication frame is to be transmitted and authentication state is
1044   - * to be changed without having to wait for a response from the peer STA
1045   - * (AP).
1046 1042 */
1047 1043 struct cfg80211_auth_request {
1048 1044 struct cfg80211_bss *bss;
... ... @@ -1051,7 +1047,6 @@
1051 1047 enum nl80211_auth_type auth_type;
1052 1048 const u8 *key;
1053 1049 u8 key_len, key_idx;
1054   - bool local_state_change;
1055 1050 };
1056 1051  
1057 1052 /**
... ... @@ -1068,7 +1063,11 @@
1068 1063 *
1069 1064 * This structure provides information needed to complete IEEE 802.11
1070 1065 * (re)association.
1071   - * @bss: The BSS to associate with.
  1066 + * @bss: The BSS to associate with. If the call is successful the driver
  1067 + * is given a reference that it must release, normally via a call to
  1068 + * cfg80211_send_rx_assoc(), or, if association timed out, with a
  1069 + * call to cfg80211_put_bss() (in addition to calling
  1070 + * cfg80211_send_assoc_timeout())
1072 1071 * @ie: Extra IEs to add to (Re)Association Request frame or %NULL
1073 1072 * @ie_len: Length of ie buffer in octets
1074 1073 * @use_mfp: Use management frame protection (IEEE 802.11w) in this association
1075 1074  
1076 1075  
1077 1076  
... ... @@ -1096,19 +1095,16 @@
1096 1095 * This structure provides information needed to complete IEEE 802.11
1097 1096 * deauthentication.
1098 1097 *
1099   - * @bss: the BSS to deauthenticate from
  1098 + * @bssid: the BSSID of the BSS to deauthenticate from
1100 1099 * @ie: Extra IEs to add to Deauthentication frame or %NULL
1101 1100 * @ie_len: Length of ie buffer in octets
1102 1101 * @reason_code: The reason code for the deauthentication
1103   - * @local_state_change: This is a request for a local state only, i.e., no
1104   - * Deauthentication frame is to be transmitted.
1105 1102 */
1106 1103 struct cfg80211_deauth_request {
1107   - struct cfg80211_bss *bss;
  1104 + const u8 *bssid;
1108 1105 const u8 *ie;
1109 1106 size_t ie_len;
1110 1107 u16 reason_code;
1111   - bool local_state_change;
1112 1108 };
1113 1109  
1114 1110 /**
... ... @@ -2206,8 +2202,6 @@
2206 2202 struct cfg80211_internal_bss;
2207 2203 struct cfg80211_cached_keys;
2208 2204  
2209   -#define MAX_AUTH_BSSES 4
2210   -
2211 2205 /**
2212 2206 * struct wireless_dev - wireless per-netdev state
2213 2207 *
... ... @@ -2271,8 +2265,6 @@
2271 2265 struct list_head event_list;
2272 2266 spinlock_t event_lock;
2273 2267  
2274   - struct cfg80211_internal_bss *authtry_bsses[MAX_AUTH_BSSES];
2275   - struct cfg80211_internal_bss *auth_bsses[MAX_AUTH_BSSES];
2276 2268 struct cfg80211_internal_bss *current_bss; /* associated / joined */
2277 2269 struct ieee80211_channel *channel;
2278 2270  
2279 2271  
... ... @@ -2764,20 +2756,10 @@
2764 2756 void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr);
2765 2757  
2766 2758 /**
2767   - * __cfg80211_auth_canceled - notify cfg80211 that authentication was canceled
2768   - * @dev: network device
2769   - * @addr: The MAC address of the device with which the authentication timed out
2770   - *
2771   - * When a pending authentication had no action yet, the driver may decide
2772   - * to not send a deauth frame, but in that case must calls this function
2773   - * to tell cfg80211 about this decision. It is only valid to call this
2774   - * function within the deauth() callback.
2775   - */
2776   -void __cfg80211_auth_canceled(struct net_device *dev, const u8 *addr);
2777   -
2778   -/**
2779 2759 * cfg80211_send_rx_assoc - notification of processed association
2780 2760 * @dev: network device
  2761 + * @bss: the BSS struct association was requested for, the struct reference
  2762 + * is owned by cfg80211 after this call
2781 2763 * @buf: (re)association response frame (header + body)
2782 2764 * @len: length of the frame data
2783 2765 *
... ... @@ -2786,7 +2768,8 @@
2786 2768 * function or cfg80211_send_assoc_timeout() to indicate the result of
2787 2769 * cfg80211_ops::assoc() call. This function may sleep.
2788 2770 */
2789   -void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len);
  2771 +void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
  2772 + const u8 *buf, size_t len);
2790 2773  
2791 2774 /**
2792 2775 * cfg80211_send_assoc_timeout - notification of timed out association
... ... @@ -2459,9 +2459,6 @@
2459 2459 struct ieee80211_work *wk;
2460 2460 u16 auth_alg;
2461 2461  
2462   - if (req->local_state_change)
2463   - return 0; /* no need to update mac80211 state */
2464   -
2465 2462 switch (req->auth_type) {
2466 2463 case NL80211_AUTHTYPE_OPEN_SYSTEM:
2467 2464 auth_alg = WLAN_AUTH_OPEN;
... ... @@ -2593,7 +2590,7 @@
2593 2590 sta_info_destroy_addr(wk->sdata, cbss->bssid);
2594 2591 }
2595 2592  
2596   - cfg80211_send_rx_assoc(wk->sdata->dev, skb->data, skb->len);
  2593 + cfg80211_send_rx_assoc(wk->sdata->dev, cbss, skb->data, skb->len);
2597 2594 destroy:
2598 2595 if (wk->assoc.synced)
2599 2596 drv_finish_tx_sync(local, wk->sdata, wk->filter_ta,
2600 2597  
... ... @@ -2750,13 +2747,12 @@
2750 2747 {
2751 2748 struct ieee80211_local *local = sdata->local;
2752 2749 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2753   - u8 bssid[ETH_ALEN];
2754 2750 bool assoc_bss = false;
2755 2751  
2756 2752 mutex_lock(&ifmgd->mtx);
2757 2753  
2758   - memcpy(bssid, req->bss->bssid, ETH_ALEN);
2759   - if (ifmgd->associated == req->bss) {
  2754 + if (ifmgd->associated &&
  2755 + memcmp(ifmgd->associated->bssid, req->bssid, ETH_ALEN) == 0) {
2760 2756 ieee80211_set_disassoc(sdata, false, true);
2761 2757 mutex_unlock(&ifmgd->mtx);
2762 2758 assoc_bss = true;
... ... @@ -2777,7 +2773,7 @@
2777 2773 tmp->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
2778 2774 continue;
2779 2775  
2780   - if (memcmp(req->bss->bssid, tmp->filter_ta, ETH_ALEN))
  2776 + if (memcmp(req->bssid, tmp->filter_ta, ETH_ALEN))
2781 2777 continue;
2782 2778  
2783 2779 not_auth_yet = tmp->type == IEEE80211_WORK_DIRECT_PROBE;
2784 2780  
2785 2781  
2786 2782  
... ... @@ -2811,18 +2807,15 @@
2811 2807 * frame, and if it's IDLE we have completed the auth
2812 2808 * process already.
2813 2809 */
2814   - if (not_auth_yet) {
2815   - __cfg80211_auth_canceled(sdata->dev, bssid);
  2810 + if (not_auth_yet)
2816 2811 return 0;
2817   - }
2818 2812 }
2819 2813  
2820 2814 printk(KERN_DEBUG "%s: deauthenticating from %pM by local choice (reason=%d)\n",
2821   - sdata->name, bssid, req->reason_code);
  2815 + sdata->name, req->bssid, req->reason_code);
2822 2816  
2823   - ieee80211_send_deauth_disassoc(sdata, bssid, IEEE80211_STYPE_DEAUTH,
2824   - req->reason_code, cookie,
2825   - !req->local_state_change);
  2817 + ieee80211_send_deauth_disassoc(sdata, req->bssid, IEEE80211_STYPE_DEAUTH,
  2818 + req->reason_code, cookie, true);
2826 2819 if (assoc_bss)
2827 2820 sta_info_flush(sdata->local, sdata);
2828 2821  
... ... @@ -325,15 +325,13 @@
325 325 const u8 *bssid,
326 326 const u8 *ssid, int ssid_len,
327 327 const u8 *ie, int ie_len,
328   - const u8 *key, int key_len, int key_idx,
329   - bool local_state_change);
  328 + const u8 *key, int key_len, int key_idx);
330 329 int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
331 330 struct net_device *dev, struct ieee80211_channel *chan,
332 331 enum nl80211_auth_type auth_type, const u8 *bssid,
333 332 const u8 *ssid, int ssid_len,
334 333 const u8 *ie, int ie_len,
335   - const u8 *key, int key_len, int key_idx,
336   - bool local_state_change);
  334 + const u8 *key, int key_len, int key_idx);
337 335 int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
338 336 struct net_device *dev,
339 337 struct ieee80211_channel *chan,
... ... @@ -421,7 +419,8 @@
421 419 size_t ie_len, u16 reason, bool from_ap);
422 420 void cfg80211_sme_scan_done(struct net_device *dev);
423 421 void cfg80211_sme_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
424   -void cfg80211_sme_disassoc(struct net_device *dev, int idx);
  422 +void cfg80211_sme_disassoc(struct net_device *dev,
  423 + struct cfg80211_internal_bss *bss);
425 424 void __cfg80211_scan_done(struct work_struct *wk);
426 425 void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak);
427 426 void __cfg80211_sched_scan_results(struct work_struct *wk);
... ... @@ -20,40 +20,18 @@
20 20 struct wireless_dev *wdev = dev->ieee80211_ptr;
21 21 struct wiphy *wiphy = wdev->wiphy;
22 22 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
23   - struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
24   - u8 *bssid = mgmt->bssid;
25   - int i;
26   - u16 status = le16_to_cpu(mgmt->u.auth.status_code);
27   - bool done = false;
28 23  
29 24 wdev_lock(wdev);
30 25  
31   - for (i = 0; i < MAX_AUTH_BSSES; i++) {
32   - if (wdev->authtry_bsses[i] &&
33   - memcmp(wdev->authtry_bsses[i]->pub.bssid, bssid,
34   - ETH_ALEN) == 0) {
35   - if (status == WLAN_STATUS_SUCCESS) {
36   - wdev->auth_bsses[i] = wdev->authtry_bsses[i];
37   - } else {
38   - cfg80211_unhold_bss(wdev->authtry_bsses[i]);
39   - cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
40   - }
41   - wdev->authtry_bsses[i] = NULL;
42   - done = true;
43   - break;
44   - }
45   - }
  26 + nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL);
  27 + cfg80211_sme_rx_auth(dev, buf, len);
46 28  
47   - if (done) {
48   - nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL);
49   - cfg80211_sme_rx_auth(dev, buf, len);
50   - }
51   -
52 29 wdev_unlock(wdev);
53 30 }
54 31 EXPORT_SYMBOL(cfg80211_send_rx_auth);
55 32  
56   -void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
  33 +void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
  34 + const u8 *buf, size_t len)
57 35 {
58 36 u16 status_code;
59 37 struct wireless_dev *wdev = dev->ieee80211_ptr;
... ... @@ -61,8 +39,7 @@
61 39 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
62 40 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
63 41 u8 *ie = mgmt->u.assoc_resp.variable;
64   - int i, ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
65   - struct cfg80211_internal_bss *bss = NULL;
  42 + int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
66 43  
67 44 wdev_lock(wdev);
68 45  
69 46  
70 47  
71 48  
... ... @@ -75,43 +52,20 @@
75 52 * frame instead of reassoc.
76 53 */
77 54 if (status_code != WLAN_STATUS_SUCCESS && wdev->conn &&
78   - cfg80211_sme_failed_reassoc(wdev))
  55 + cfg80211_sme_failed_reassoc(wdev)) {
  56 + cfg80211_put_bss(bss);
79 57 goto out;
  58 + }
80 59  
81 60 nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL);
82 61  
83   - if (status_code == WLAN_STATUS_SUCCESS) {
84   - for (i = 0; i < MAX_AUTH_BSSES; i++) {
85   - if (!wdev->auth_bsses[i])
86   - continue;
87   - if (memcmp(wdev->auth_bsses[i]->pub.bssid, mgmt->bssid,
88   - ETH_ALEN) == 0) {
89   - bss = wdev->auth_bsses[i];
90   - wdev->auth_bsses[i] = NULL;
91   - /* additional reference to drop hold */
92   - cfg80211_ref_bss(bss);
93   - break;
94   - }
95   - }
96   -
97   - /*
98   - * We might be coming here because the driver reported
99   - * a successful association at the same time as the
100   - * user requested a deauth. In that case, we will have
101   - * removed the BSS from the auth_bsses list due to the
102   - * deauth request when the assoc response makes it. If
103   - * the two code paths acquire the lock the other way
104   - * around, that's just the standard situation of a
105   - * deauth being requested while connected.
106   - */
107   - if (!bss)
108   - goto out;
109   - } else if (wdev->conn) {
  62 + if (status_code != WLAN_STATUS_SUCCESS && wdev->conn) {
110 63 cfg80211_sme_failed_assoc(wdev);
111 64 /*
112 65 * do not call connect_result() now because the
113 66 * sme will schedule work that does it later.
114 67 */
  68 + cfg80211_put_bss(bss);
115 69 goto out;
116 70 }
117 71  
118 72  
... ... @@ -124,17 +78,10 @@
124 78 wdev->sme_state = CFG80211_SME_CONNECTING;
125 79 }
126 80  
127   - /* this consumes one bss reference (unless bss is NULL) */
  81 + /* this consumes the bss reference */
128 82 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
129 83 status_code,
130   - status_code == WLAN_STATUS_SUCCESS,
131   - bss ? &bss->pub : NULL);
132   - /* drop hold now, and also reference acquired above */
133   - if (bss) {
134   - cfg80211_unhold_bss(bss);
135   - cfg80211_put_bss(&bss->pub);
136   - }
137   -
  84 + status_code == WLAN_STATUS_SUCCESS, bss);
138 85 out:
139 86 wdev_unlock(wdev);
140 87 }
... ... @@ -148,8 +95,7 @@
148 95 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
149 96 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
150 97 const u8 *bssid = mgmt->bssid;
151   - int i;
152   - bool found = false, was_current = false;
  98 + bool was_current = false;
153 99  
154 100 ASSERT_WDEV_LOCK(wdev);
155 101  
156 102  
157 103  
... ... @@ -158,32 +104,9 @@
158 104 cfg80211_unhold_bss(wdev->current_bss);
159 105 cfg80211_put_bss(&wdev->current_bss->pub);
160 106 wdev->current_bss = NULL;
161   - found = true;
162 107 was_current = true;
163   - } else for (i = 0; i < MAX_AUTH_BSSES; i++) {
164   - if (wdev->auth_bsses[i] &&
165   - memcmp(wdev->auth_bsses[i]->pub.bssid, bssid, ETH_ALEN) == 0) {
166   - cfg80211_unhold_bss(wdev->auth_bsses[i]);
167   - cfg80211_put_bss(&wdev->auth_bsses[i]->pub);
168   - wdev->auth_bsses[i] = NULL;
169   - found = true;
170   - break;
171   - }
172   - if (wdev->authtry_bsses[i] &&
173   - memcmp(wdev->authtry_bsses[i]->pub.bssid, bssid,
174   - ETH_ALEN) == 0 &&
175   - memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) == 0) {
176   - cfg80211_unhold_bss(wdev->authtry_bsses[i]);
177   - cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
178   - wdev->authtry_bsses[i] = NULL;
179   - found = true;
180   - break;
181   - }
182 108 }
183 109  
184   - if (!found)
185   - return;
186   -
187 110 nl80211_send_deauth(rdev, dev, buf, len, GFP_KERNEL);
188 111  
189 112 if (wdev->sme_state == CFG80211_SME_CONNECTED && was_current) {
190 113  
... ... @@ -220,10 +143,8 @@
220 143 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
221 144 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
222 145 const u8 *bssid = mgmt->bssid;
223   - int i;
224 146 u16 reason_code;
225 147 bool from_ap;
226   - bool done = false;
227 148  
228 149 ASSERT_WDEV_LOCK(wdev);
229 150  
... ... @@ -234,16 +155,10 @@
234 155  
235 156 if (wdev->current_bss &&
236 157 memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
237   - for (i = 0; i < MAX_AUTH_BSSES; i++) {
238   - if (wdev->authtry_bsses[i] || wdev->auth_bsses[i])
239   - continue;
240   - wdev->auth_bsses[i] = wdev->current_bss;
241   - wdev->current_bss = NULL;
242   - done = true;
243   - cfg80211_sme_disassoc(dev, i);
244   - break;
245   - }
246   - WARN_ON(!done);
  158 + cfg80211_sme_disassoc(dev, wdev->current_bss);
  159 + cfg80211_unhold_bss(wdev->current_bss);
  160 + cfg80211_put_bss(&wdev->current_bss->pub);
  161 + wdev->current_bss = NULL;
247 162 } else
248 163 WARN_ON(1);
249 164  
... ... @@ -287,34 +202,6 @@
287 202 }
288 203 EXPORT_SYMBOL(cfg80211_send_unprot_disassoc);
289 204  
290   -static void __cfg80211_auth_remove(struct wireless_dev *wdev, const u8 *addr)
291   -{
292   - int i;
293   - bool done = false;
294   -
295   - ASSERT_WDEV_LOCK(wdev);
296   -
297   - for (i = 0; addr && i < MAX_AUTH_BSSES; i++) {
298   - if (wdev->authtry_bsses[i] &&
299   - memcmp(wdev->authtry_bsses[i]->pub.bssid,
300   - addr, ETH_ALEN) == 0) {
301   - cfg80211_unhold_bss(wdev->authtry_bsses[i]);
302   - cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
303   - wdev->authtry_bsses[i] = NULL;
304   - done = true;
305   - break;
306   - }
307   - }
308   -
309   - WARN_ON(!done);
310   -}
311   -
312   -void __cfg80211_auth_canceled(struct net_device *dev, const u8 *addr)
313   -{
314   - __cfg80211_auth_remove(dev->ieee80211_ptr, addr);
315   -}
316   -EXPORT_SYMBOL(__cfg80211_auth_canceled);
317   -
318 205 void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
319 206 {
320 207 struct wireless_dev *wdev = dev->ieee80211_ptr;
... ... @@ -329,8 +216,6 @@
329 216 WLAN_STATUS_UNSPECIFIED_FAILURE,
330 217 false, NULL);
331 218  
332   - __cfg80211_auth_remove(wdev, addr);
333   -
334 219 wdev_unlock(wdev);
335 220 }
336 221 EXPORT_SYMBOL(cfg80211_send_auth_timeout);
... ... @@ -340,8 +225,6 @@
340 225 struct wireless_dev *wdev = dev->ieee80211_ptr;
341 226 struct wiphy *wiphy = wdev->wiphy;
342 227 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
343   - int i;
344   - bool done = false;
345 228  
346 229 wdev_lock(wdev);
347 230  
... ... @@ -351,20 +234,6 @@
351 234 WLAN_STATUS_UNSPECIFIED_FAILURE,
352 235 false, NULL);
353 236  
354   - for (i = 0; addr && i < MAX_AUTH_BSSES; i++) {
355   - if (wdev->auth_bsses[i] &&
356   - memcmp(wdev->auth_bsses[i]->pub.bssid,
357   - addr, ETH_ALEN) == 0) {
358   - cfg80211_unhold_bss(wdev->auth_bsses[i]);
359   - cfg80211_put_bss(&wdev->auth_bsses[i]->pub);
360   - wdev->auth_bsses[i] = NULL;
361   - done = true;
362   - break;
363   - }
364   - }
365   -
366   - WARN_ON(!done);
367   -
368 237 wdev_unlock(wdev);
369 238 }
370 239 EXPORT_SYMBOL(cfg80211_send_assoc_timeout);
371 240  
... ... @@ -403,13 +272,11 @@
403 272 const u8 *bssid,
404 273 const u8 *ssid, int ssid_len,
405 274 const u8 *ie, int ie_len,
406   - const u8 *key, int key_len, int key_idx,
407   - bool local_state_change)
  275 + const u8 *key, int key_len, int key_idx)
408 276 {
409 277 struct wireless_dev *wdev = dev->ieee80211_ptr;
410 278 struct cfg80211_auth_request req;
411   - struct cfg80211_internal_bss *bss;
412   - int i, err, slot = -1, nfree = 0;
  279 + int err;
413 280  
414 281 ASSERT_WDEV_LOCK(wdev);
415 282  
416 283  
... ... @@ -421,20 +288,8 @@
421 288 memcmp(bssid, wdev->current_bss->pub.bssid, ETH_ALEN) == 0)
422 289 return -EALREADY;
423 290  
424   - for (i = 0; i < MAX_AUTH_BSSES; i++) {
425   - if (wdev->authtry_bsses[i] &&
426   - memcmp(bssid, wdev->authtry_bsses[i]->pub.bssid,
427   - ETH_ALEN) == 0)
428   - return -EALREADY;
429   - if (wdev->auth_bsses[i] &&
430   - memcmp(bssid, wdev->auth_bsses[i]->pub.bssid,
431   - ETH_ALEN) == 0)
432   - return -EALREADY;
433   - }
434   -
435 291 memset(&req, 0, sizeof(req));
436 292  
437   - req.local_state_change = local_state_change;
438 293 req.ie = ie;
439 294 req.ie_len = ie_len;
440 295 req.auth_type = auth_type;
441 296  
442 297  
... ... @@ -446,39 +301,9 @@
446 301 if (!req.bss)
447 302 return -ENOENT;
448 303  
449   - bss = bss_from_pub(req.bss);
450   -
451   - for (i = 0; i < MAX_AUTH_BSSES; i++) {
452   - if (!wdev->auth_bsses[i] && !wdev->authtry_bsses[i]) {
453   - slot = i;
454   - nfree++;
455   - }
456   - }
457   -
458   - /* we need one free slot for disassoc and one for this auth */
459   - if (nfree < 2) {
460   - err = -ENOSPC;
461   - goto out;
462   - }
463   -
464   - if (local_state_change)
465   - wdev->auth_bsses[slot] = bss;
466   - else
467   - wdev->authtry_bsses[slot] = bss;
468   - cfg80211_hold_bss(bss);
469   -
470 304 err = rdev->ops->auth(&rdev->wiphy, dev, &req);
471   - if (err) {
472   - if (local_state_change)
473   - wdev->auth_bsses[slot] = NULL;
474   - else
475   - wdev->authtry_bsses[slot] = NULL;
476   - cfg80211_unhold_bss(bss);
477   - }
478 305  
479   - out:
480   - if (err)
481   - cfg80211_put_bss(req.bss);
  306 + cfg80211_put_bss(req.bss);
482 307 return err;
483 308 }
484 309  
485 310  
... ... @@ -487,15 +312,14 @@
487 312 enum nl80211_auth_type auth_type, const u8 *bssid,
488 313 const u8 *ssid, int ssid_len,
489 314 const u8 *ie, int ie_len,
490   - const u8 *key, int key_len, int key_idx,
491   - bool local_state_change)
  315 + const u8 *key, int key_len, int key_idx)
492 316 {
493 317 int err;
494 318  
495 319 wdev_lock(dev->ieee80211_ptr);
496 320 err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
497 321 ssid, ssid_len, ie, ie_len,
498   - key, key_len, key_idx, local_state_change);
  322 + key, key_len, key_idx);
499 323 wdev_unlock(dev->ieee80211_ptr);
500 324  
501 325 return err;
... ... @@ -530,8 +354,7 @@
530 354 {
531 355 struct wireless_dev *wdev = dev->ieee80211_ptr;
532 356 struct cfg80211_assoc_request req;
533   - struct cfg80211_internal_bss *bss;
534   - int i, err, slot = -1;
  357 + int err;
535 358 bool was_connected = false;
536 359  
537 360 ASSERT_WDEV_LOCK(wdev);
538 361  
539 362  
... ... @@ -573,26 +396,14 @@
573 396 return -ENOENT;
574 397 }
575 398  
576   - bss = bss_from_pub(req.bss);
  399 + err = rdev->ops->assoc(&rdev->wiphy, dev, &req);
577 400  
578   - for (i = 0; i < MAX_AUTH_BSSES; i++) {
579   - if (bss == wdev->auth_bsses[i]) {
580   - slot = i;
581   - break;
582   - }
  401 + if (err) {
  402 + if (was_connected)
  403 + wdev->sme_state = CFG80211_SME_CONNECTED;
  404 + cfg80211_put_bss(req.bss);
583 405 }
584 406  
585   - if (slot < 0) {
586   - err = -ENOTCONN;
587   - goto out;
588   - }
589   -
590   - err = rdev->ops->assoc(&rdev->wiphy, dev, &req);
591   - out:
592   - if (err && was_connected)
593   - wdev->sme_state = CFG80211_SME_CONNECTED;
594   - /* still a reference in wdev->auth_bsses[slot] */
595   - cfg80211_put_bss(req.bss);
596 407 return err;
597 408 }
598 409  
599 410  
600 411  
601 412  
... ... @@ -624,35 +435,26 @@
624 435 bool local_state_change)
625 436 {
626 437 struct wireless_dev *wdev = dev->ieee80211_ptr;
627   - struct cfg80211_deauth_request req;
628   - int i;
  438 + struct cfg80211_deauth_request req = {
  439 + .bssid = bssid,
  440 + .reason_code = reason,
  441 + .ie = ie,
  442 + .ie_len = ie_len,
  443 + };
629 444  
630 445 ASSERT_WDEV_LOCK(wdev);
631 446  
632   - memset(&req, 0, sizeof(req));
633   - req.reason_code = reason;
634   - req.local_state_change = local_state_change;
635   - req.ie = ie;
636   - req.ie_len = ie_len;
637   - if (wdev->current_bss &&
638   - memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
639   - req.bss = &wdev->current_bss->pub;
640   - } else for (i = 0; i < MAX_AUTH_BSSES; i++) {
641   - if (wdev->auth_bsses[i] &&
642   - memcmp(bssid, wdev->auth_bsses[i]->pub.bssid, ETH_ALEN) == 0) {
643   - req.bss = &wdev->auth_bsses[i]->pub;
644   - break;
  447 + if (local_state_change) {
  448 + if (wdev->current_bss &&
  449 + memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
  450 + cfg80211_unhold_bss(wdev->current_bss);
  451 + cfg80211_put_bss(&wdev->current_bss->pub);
  452 + wdev->current_bss = NULL;
645 453 }
646   - if (wdev->authtry_bsses[i] &&
647   - memcmp(bssid, wdev->authtry_bsses[i]->pub.bssid, ETH_ALEN) == 0) {
648   - req.bss = &wdev->authtry_bsses[i]->pub;
649   - break;
650   - }
  454 +
  455 + return 0;
651 456 }
652 457  
653   - if (!req.bss)
654   - return -ENOTCONN;
655   -
656 458 return rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
657 459 }
658 460  
... ... @@ -722,7 +524,7 @@
722 524 {
723 525 struct wireless_dev *wdev = dev->ieee80211_ptr;
724 526 struct cfg80211_deauth_request req;
725   - int i;
  527 + u8 bssid[ETH_ALEN];
726 528  
727 529 ASSERT_WDEV_LOCK(wdev);
728 530  
729 531  
... ... @@ -734,35 +536,17 @@
734 536 req.ie = NULL;
735 537 req.ie_len = 0;
736 538  
737   - if (wdev->current_bss) {
738   - req.bss = &wdev->current_bss->pub;
739   - rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
740   - if (wdev->current_bss) {
741   - cfg80211_unhold_bss(wdev->current_bss);
742   - cfg80211_put_bss(&wdev->current_bss->pub);
743   - wdev->current_bss = NULL;
744   - }
745   - }
  539 + if (!wdev->current_bss)
  540 + return;
746 541  
747   - for (i = 0; i < MAX_AUTH_BSSES; i++) {
748   - if (wdev->auth_bsses[i]) {
749   - req.bss = &wdev->auth_bsses[i]->pub;
750   - rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
751   - if (wdev->auth_bsses[i]) {
752   - cfg80211_unhold_bss(wdev->auth_bsses[i]);
753   - cfg80211_put_bss(&wdev->auth_bsses[i]->pub);
754   - wdev->auth_bsses[i] = NULL;
755   - }
756   - }
757   - if (wdev->authtry_bsses[i]) {
758   - req.bss = &wdev->authtry_bsses[i]->pub;
759   - rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
760   - if (wdev->authtry_bsses[i]) {
761   - cfg80211_unhold_bss(wdev->authtry_bsses[i]);
762   - cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
763   - wdev->authtry_bsses[i] = NULL;
764   - }
765   - }
  542 + memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN);
  543 + req.bssid = bssid;
  544 + rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
  545 +
  546 + if (wdev->current_bss) {
  547 + cfg80211_unhold_bss(wdev->current_bss);
  548 + cfg80211_put_bss(&wdev->current_bss->pub);
  549 + wdev->current_bss = NULL;
766 550 }
767 551 }
768 552  
net/wireless/nl80211.c
... ... @@ -4083,7 +4083,6 @@
4083 4083 struct cfg80211_bss *res = &intbss->pub;
4084 4084 void *hdr;
4085 4085 struct nlattr *bss;
4086   - int i;
4087 4086  
4088 4087 ASSERT_WDEV_LOCK(wdev);
4089 4088  
... ... @@ -4136,13 +4135,6 @@
4136 4135 if (intbss == wdev->current_bss)
4137 4136 NLA_PUT_U32(msg, NL80211_BSS_STATUS,
4138 4137 NL80211_BSS_STATUS_ASSOCIATED);
4139   - else for (i = 0; i < MAX_AUTH_BSSES; i++) {
4140   - if (intbss != wdev->auth_bsses[i])
4141   - continue;
4142   - NLA_PUT_U32(msg, NL80211_BSS_STATUS,
4143   - NL80211_BSS_STATUS_AUTHENTICATED);
4144   - break;
4145   - }
4146 4138 break;
4147 4139 case NL80211_IFTYPE_ADHOC:
4148 4140 if (intbss == wdev->current_bss)
4149 4141  
... ... @@ -4410,10 +4402,16 @@
4410 4402  
4411 4403 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
4412 4404  
  4405 + /*
  4406 + * Since we no longer track auth state, ignore
  4407 + * requests to only change local state.
  4408 + */
  4409 + if (local_state_change)
  4410 + return 0;
  4411 +
4413 4412 return cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
4414 4413 ssid, ssid_len, ie, ie_len,
4415   - key.p.key, key.p.key_len, key.idx,
4416   - local_state_change);
  4414 + key.p.key, key.p.key_len, key.idx);
4417 4415 }
4418 4416  
4419 4417 static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
... ... @@ -179,7 +179,7 @@
179 179 params->ssid, params->ssid_len,
180 180 NULL, 0,
181 181 params->key, params->key_len,
182   - params->key_idx, false);
  182 + params->key_idx);
183 183 case CFG80211_CONN_ASSOCIATE_NEXT:
184 184 BUG_ON(!rdev->ops->assoc);
185 185 wdev->conn->state = CFG80211_CONN_ASSOCIATING;
... ... @@ -477,6 +477,7 @@
477 477 kfree(wdev->connect_keys);
478 478 wdev->connect_keys = NULL;
479 479 wdev->ssid_len = 0;
  480 + cfg80211_put_bss(bss);
480 481 return;
481 482 }
482 483  
483 484  
... ... @@ -701,31 +702,10 @@
701 702 wdev->ssid_len = 0;
702 703  
703 704 if (wdev->conn) {
704   - const u8 *bssid;
705   - int ret;
706   -
707 705 kfree(wdev->conn->ie);
708 706 wdev->conn->ie = NULL;
709 707 kfree(wdev->conn);
710 708 wdev->conn = NULL;
711   -
712   - /*
713   - * If this disconnect was due to a disassoc, we
714   - * we might still have an auth BSS around. For
715   - * the userspace SME that's currently expected,
716   - * but for the kernel SME (nl80211 CONNECT or
717   - * wireless extensions) we want to clear up all
718   - * state.
719   - */
720   - for (i = 0; i < MAX_AUTH_BSSES; i++) {
721   - if (!wdev->auth_bsses[i])
722   - continue;
723   - bssid = wdev->auth_bsses[i]->pub.bssid;
724   - ret = __cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0,
725   - WLAN_REASON_DEAUTH_LEAVING,
726   - false);
727   - WARN(ret, "deauth failed: %d\n", ret);
728   - }
729 709 }
730 710  
731 711 nl80211_send_disconnected(rdev, dev, reason, ie, ie_len, from_ap);
... ... @@ -1012,7 +992,8 @@
1012 992 return err;
1013 993 }
1014 994  
1015   -void cfg80211_sme_disassoc(struct net_device *dev, int idx)
  995 +void cfg80211_sme_disassoc(struct net_device *dev,
  996 + struct cfg80211_internal_bss *bss)
1016 997 {
1017 998 struct wireless_dev *wdev = dev->ieee80211_ptr;
1018 999 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
1019 1000  
... ... @@ -1031,17 +1012,9 @@
1031 1012 * want it any more so deauthenticate too.
1032 1013 */
1033 1014  
1034   - if (!wdev->auth_bsses[idx])
1035   - return;
  1015 + memcpy(bssid, bss->pub.bssid, ETH_ALEN);
1036 1016  
1037   - memcpy(bssid, wdev->auth_bsses[idx]->pub.bssid, ETH_ALEN);
1038   - if (__cfg80211_mlme_deauth(rdev, dev, bssid,
1039   - NULL, 0, WLAN_REASON_DEAUTH_LEAVING,
1040   - false)) {
1041   - /* whatever -- assume gone anyway */
1042   - cfg80211_unhold_bss(wdev->auth_bsses[idx]);
1043   - cfg80211_put_bss(&wdev->auth_bsses[idx]->pub);
1044   - wdev->auth_bsses[idx] = NULL;
1045   - }
  1017 + __cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0,
  1018 + WLAN_REASON_DEAUTH_LEAVING, false);
1046 1019 }