aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/mlme.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/mlme.c')
-rw-r--r--net/wireless/mlme.c216
1 files changed, 53 insertions, 163 deletions
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 0c7b7dd855f6..7bde5d9c0003 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -25,12 +25,9 @@ void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len)
25 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 25 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
26 26
27 trace_cfg80211_send_rx_auth(dev); 27 trace_cfg80211_send_rx_auth(dev);
28 wdev_lock(wdev);
29 28
30 nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL); 29 nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL);
31 cfg80211_sme_rx_auth(dev, buf, len); 30 cfg80211_sme_rx_auth(dev, buf, len);
32
33 wdev_unlock(wdev);
34} 31}
35EXPORT_SYMBOL(cfg80211_send_rx_auth); 32EXPORT_SYMBOL(cfg80211_send_rx_auth);
36 33
@@ -46,7 +43,6 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
46 int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable); 43 int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
47 44
48 trace_cfg80211_send_rx_assoc(dev, bss); 45 trace_cfg80211_send_rx_assoc(dev, bss);
49 wdev_lock(wdev);
50 46
51 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); 47 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
52 48
@@ -59,7 +55,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
59 if (status_code != WLAN_STATUS_SUCCESS && wdev->conn && 55 if (status_code != WLAN_STATUS_SUCCESS && wdev->conn &&
60 cfg80211_sme_failed_reassoc(wdev)) { 56 cfg80211_sme_failed_reassoc(wdev)) {
61 cfg80211_put_bss(wiphy, bss); 57 cfg80211_put_bss(wiphy, bss);
62 goto out; 58 return;
63 } 59 }
64 60
65 nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL); 61 nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL);
@@ -71,7 +67,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
71 * sme will schedule work that does it later. 67 * sme will schedule work that does it later.
72 */ 68 */
73 cfg80211_put_bss(wiphy, bss); 69 cfg80211_put_bss(wiphy, bss);
74 goto out; 70 return;
75 } 71 }
76 72
77 if (!wdev->conn && wdev->sme_state == CFG80211_SME_IDLE) { 73 if (!wdev->conn && wdev->sme_state == CFG80211_SME_IDLE) {
@@ -87,13 +83,11 @@ void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
87 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs, 83 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
88 status_code, 84 status_code,
89 status_code == WLAN_STATUS_SUCCESS, bss); 85 status_code == WLAN_STATUS_SUCCESS, bss);
90 out:
91 wdev_unlock(wdev);
92} 86}
93EXPORT_SYMBOL(cfg80211_send_rx_assoc); 87EXPORT_SYMBOL(cfg80211_send_rx_assoc);
94 88
95void __cfg80211_send_deauth(struct net_device *dev, 89void cfg80211_send_deauth(struct net_device *dev,
96 const u8 *buf, size_t len) 90 const u8 *buf, size_t len)
97{ 91{
98 struct wireless_dev *wdev = dev->ieee80211_ptr; 92 struct wireless_dev *wdev = dev->ieee80211_ptr;
99 struct wiphy *wiphy = wdev->wiphy; 93 struct wiphy *wiphy = wdev->wiphy;
@@ -102,7 +96,7 @@ void __cfg80211_send_deauth(struct net_device *dev,
102 const u8 *bssid = mgmt->bssid; 96 const u8 *bssid = mgmt->bssid;
103 bool was_current = false; 97 bool was_current = false;
104 98
105 trace___cfg80211_send_deauth(dev); 99 trace_cfg80211_send_deauth(dev);
106 ASSERT_WDEV_LOCK(wdev); 100 ASSERT_WDEV_LOCK(wdev);
107 101
108 if (wdev->current_bss && 102 if (wdev->current_bss &&
@@ -129,20 +123,10 @@ void __cfg80211_send_deauth(struct net_device *dev,
129 false, NULL); 123 false, NULL);
130 } 124 }
131} 125}
132EXPORT_SYMBOL(__cfg80211_send_deauth);
133
134void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len)
135{
136 struct wireless_dev *wdev = dev->ieee80211_ptr;
137
138 wdev_lock(wdev);
139 __cfg80211_send_deauth(dev, buf, len);
140 wdev_unlock(wdev);
141}
142EXPORT_SYMBOL(cfg80211_send_deauth); 126EXPORT_SYMBOL(cfg80211_send_deauth);
143 127
144void __cfg80211_send_disassoc(struct net_device *dev, 128void cfg80211_send_disassoc(struct net_device *dev,
145 const u8 *buf, size_t len) 129 const u8 *buf, size_t len)
146{ 130{
147 struct wireless_dev *wdev = dev->ieee80211_ptr; 131 struct wireless_dev *wdev = dev->ieee80211_ptr;
148 struct wiphy *wiphy = wdev->wiphy; 132 struct wiphy *wiphy = wdev->wiphy;
@@ -152,7 +136,7 @@ void __cfg80211_send_disassoc(struct net_device *dev,
152 u16 reason_code; 136 u16 reason_code;
153 bool from_ap; 137 bool from_ap;
154 138
155 trace___cfg80211_send_disassoc(dev); 139 trace_cfg80211_send_disassoc(dev);
156 ASSERT_WDEV_LOCK(wdev); 140 ASSERT_WDEV_LOCK(wdev);
157 141
158 nl80211_send_disassoc(rdev, dev, buf, len, GFP_KERNEL); 142 nl80211_send_disassoc(rdev, dev, buf, len, GFP_KERNEL);
@@ -175,16 +159,6 @@ void __cfg80211_send_disassoc(struct net_device *dev,
175 from_ap = !ether_addr_equal(mgmt->sa, dev->dev_addr); 159 from_ap = !ether_addr_equal(mgmt->sa, dev->dev_addr);
176 __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap); 160 __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
177} 161}
178EXPORT_SYMBOL(__cfg80211_send_disassoc);
179
180void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len)
181{
182 struct wireless_dev *wdev = dev->ieee80211_ptr;
183
184 wdev_lock(wdev);
185 __cfg80211_send_disassoc(dev, buf, len);
186 wdev_unlock(wdev);
187}
188EXPORT_SYMBOL(cfg80211_send_disassoc); 162EXPORT_SYMBOL(cfg80211_send_disassoc);
189 163
190void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr) 164void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
@@ -194,15 +168,12 @@ void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
194 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 168 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
195 169
196 trace_cfg80211_send_auth_timeout(dev, addr); 170 trace_cfg80211_send_auth_timeout(dev, addr);
197 wdev_lock(wdev);
198 171
199 nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL); 172 nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL);
200 if (wdev->sme_state == CFG80211_SME_CONNECTING) 173 if (wdev->sme_state == CFG80211_SME_CONNECTING)
201 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0, 174 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
202 WLAN_STATUS_UNSPECIFIED_FAILURE, 175 WLAN_STATUS_UNSPECIFIED_FAILURE,
203 false, NULL); 176 false, NULL);
204
205 wdev_unlock(wdev);
206} 177}
207EXPORT_SYMBOL(cfg80211_send_auth_timeout); 178EXPORT_SYMBOL(cfg80211_send_auth_timeout);
208 179
@@ -213,15 +184,12 @@ void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr)
213 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 184 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
214 185
215 trace_cfg80211_send_assoc_timeout(dev, addr); 186 trace_cfg80211_send_assoc_timeout(dev, addr);
216 wdev_lock(wdev);
217 187
218 nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL); 188 nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL);
219 if (wdev->sme_state == CFG80211_SME_CONNECTING) 189 if (wdev->sme_state == CFG80211_SME_CONNECTING)
220 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0, 190 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
221 WLAN_STATUS_UNSPECIFIED_FAILURE, 191 WLAN_STATUS_UNSPECIFIED_FAILURE,
222 false, NULL); 192 false, NULL);
223
224 wdev_unlock(wdev);
225} 193}
226EXPORT_SYMBOL(cfg80211_send_assoc_timeout); 194EXPORT_SYMBOL(cfg80211_send_assoc_timeout);
227 195
@@ -253,18 +221,27 @@ void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
253EXPORT_SYMBOL(cfg80211_michael_mic_failure); 221EXPORT_SYMBOL(cfg80211_michael_mic_failure);
254 222
255/* some MLME handling for userspace SME */ 223/* some MLME handling for userspace SME */
256int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, 224int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
257 struct net_device *dev, 225 struct net_device *dev,
258 struct ieee80211_channel *chan, 226 struct ieee80211_channel *chan,
259 enum nl80211_auth_type auth_type, 227 enum nl80211_auth_type auth_type,
260 const u8 *bssid, 228 const u8 *bssid,
261 const u8 *ssid, int ssid_len, 229 const u8 *ssid, int ssid_len,
262 const u8 *ie, int ie_len, 230 const u8 *ie, int ie_len,
263 const u8 *key, int key_len, int key_idx, 231 const u8 *key, int key_len, int key_idx,
264 const u8 *sae_data, int sae_data_len) 232 const u8 *sae_data, int sae_data_len)
265{ 233{
266 struct wireless_dev *wdev = dev->ieee80211_ptr; 234 struct wireless_dev *wdev = dev->ieee80211_ptr;
267 struct cfg80211_auth_request req; 235 struct cfg80211_auth_request req = {
236 .ie = ie,
237 .ie_len = ie_len,
238 .sae_data = sae_data,
239 .sae_data_len = sae_data_len,
240 .auth_type = auth_type,
241 .key = key,
242 .key_len = key_len,
243 .key_idx = key_idx,
244 };
268 int err; 245 int err;
269 246
270 ASSERT_WDEV_LOCK(wdev); 247 ASSERT_WDEV_LOCK(wdev);
@@ -277,18 +254,8 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
277 ether_addr_equal(bssid, wdev->current_bss->pub.bssid)) 254 ether_addr_equal(bssid, wdev->current_bss->pub.bssid))
278 return -EALREADY; 255 return -EALREADY;
279 256
280 memset(&req, 0, sizeof(req));
281
282 req.ie = ie;
283 req.ie_len = ie_len;
284 req.sae_data = sae_data;
285 req.sae_data_len = sae_data_len;
286 req.auth_type = auth_type;
287 req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, 257 req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
288 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); 258 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
289 req.key = key;
290 req.key_len = key_len;
291 req.key_idx = key_idx;
292 if (!req.bss) 259 if (!req.bss)
293 return -ENOENT; 260 return -ENOENT;
294 261
@@ -304,28 +271,6 @@ out:
304 return err; 271 return err;
305} 272}
306 273
307int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
308 struct net_device *dev, struct ieee80211_channel *chan,
309 enum nl80211_auth_type auth_type, const u8 *bssid,
310 const u8 *ssid, int ssid_len,
311 const u8 *ie, int ie_len,
312 const u8 *key, int key_len, int key_idx,
313 const u8 *sae_data, int sae_data_len)
314{
315 int err;
316
317 mutex_lock(&rdev->devlist_mtx);
318 wdev_lock(dev->ieee80211_ptr);
319 err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
320 ssid, ssid_len, ie, ie_len,
321 key, key_len, key_idx,
322 sae_data, sae_data_len);
323 wdev_unlock(dev->ieee80211_ptr);
324 mutex_unlock(&rdev->devlist_mtx);
325
326 return err;
327}
328
329/* Do a logical ht_capa &= ht_capa_mask. */ 274/* Do a logical ht_capa &= ht_capa_mask. */
330void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa, 275void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
331 const struct ieee80211_ht_cap *ht_capa_mask) 276 const struct ieee80211_ht_cap *ht_capa_mask)
@@ -360,12 +305,12 @@ void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa,
360 p1[i] &= p2[i]; 305 p1[i] &= p2[i];
361} 306}
362 307
363int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, 308int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
364 struct net_device *dev, 309 struct net_device *dev,
365 struct ieee80211_channel *chan, 310 struct ieee80211_channel *chan,
366 const u8 *bssid, 311 const u8 *bssid,
367 const u8 *ssid, int ssid_len, 312 const u8 *ssid, int ssid_len,
368 struct cfg80211_assoc_request *req) 313 struct cfg80211_assoc_request *req)
369{ 314{
370 struct wireless_dev *wdev = dev->ieee80211_ptr; 315 struct wireless_dev *wdev = dev->ieee80211_ptr;
371 int err; 316 int err;
@@ -415,30 +360,10 @@ out:
415 return err; 360 return err;
416} 361}
417 362
418int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, 363int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
419 struct net_device *dev, 364 struct net_device *dev, const u8 *bssid,
420 struct ieee80211_channel *chan, 365 const u8 *ie, int ie_len, u16 reason,
421 const u8 *bssid, 366 bool local_state_change)
422 const u8 *ssid, int ssid_len,
423 struct cfg80211_assoc_request *req)
424{
425 struct wireless_dev *wdev = dev->ieee80211_ptr;
426 int err;
427
428 mutex_lock(&rdev->devlist_mtx);
429 wdev_lock(wdev);
430 err = __cfg80211_mlme_assoc(rdev, dev, chan, bssid,
431 ssid, ssid_len, req);
432 wdev_unlock(wdev);
433 mutex_unlock(&rdev->devlist_mtx);
434
435 return err;
436}
437
438int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
439 struct net_device *dev, const u8 *bssid,
440 const u8 *ie, int ie_len, u16 reason,
441 bool local_state_change)
442{ 367{
443 struct wireless_dev *wdev = dev->ieee80211_ptr; 368 struct wireless_dev *wdev = dev->ieee80211_ptr;
444 struct cfg80211_deauth_request req = { 369 struct cfg80211_deauth_request req = {
@@ -458,29 +383,18 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
458 return rdev_deauth(rdev, dev, &req); 383 return rdev_deauth(rdev, dev, &req);
459} 384}
460 385
461int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, 386int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
462 struct net_device *dev, const u8 *bssid, 387 struct net_device *dev, const u8 *bssid,
463 const u8 *ie, int ie_len, u16 reason, 388 const u8 *ie, int ie_len, u16 reason,
464 bool local_state_change) 389 bool local_state_change)
465{
466 struct wireless_dev *wdev = dev->ieee80211_ptr;
467 int err;
468
469 wdev_lock(wdev);
470 err = __cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason,
471 local_state_change);
472 wdev_unlock(wdev);
473
474 return err;
475}
476
477static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
478 struct net_device *dev, const u8 *bssid,
479 const u8 *ie, int ie_len, u16 reason,
480 bool local_state_change)
481{ 390{
482 struct wireless_dev *wdev = dev->ieee80211_ptr; 391 struct wireless_dev *wdev = dev->ieee80211_ptr;
483 struct cfg80211_disassoc_request req; 392 struct cfg80211_disassoc_request req = {
393 .reason_code = reason,
394 .local_state_change = local_state_change,
395 .ie = ie,
396 .ie_len = ie_len,
397 };
484 398
485 ASSERT_WDEV_LOCK(wdev); 399 ASSERT_WDEV_LOCK(wdev);
486 400
@@ -490,11 +404,6 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
490 if (WARN(!wdev->current_bss, "sme_state=%d\n", wdev->sme_state)) 404 if (WARN(!wdev->current_bss, "sme_state=%d\n", wdev->sme_state))
491 return -ENOTCONN; 405 return -ENOTCONN;
492 406
493 memset(&req, 0, sizeof(req));
494 req.reason_code = reason;
495 req.local_state_change = local_state_change;
496 req.ie = ie;
497 req.ie_len = ie_len;
498 if (ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) 407 if (ether_addr_equal(wdev->current_bss->pub.bssid, bssid))
499 req.bss = &wdev->current_bss->pub; 408 req.bss = &wdev->current_bss->pub;
500 else 409 else
@@ -503,44 +412,25 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
503 return rdev_disassoc(rdev, dev, &req); 412 return rdev_disassoc(rdev, dev, &req);
504} 413}
505 414
506int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
507 struct net_device *dev, const u8 *bssid,
508 const u8 *ie, int ie_len, u16 reason,
509 bool local_state_change)
510{
511 struct wireless_dev *wdev = dev->ieee80211_ptr;
512 int err;
513
514 wdev_lock(wdev);
515 err = __cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason,
516 local_state_change);
517 wdev_unlock(wdev);
518
519 return err;
520}
521
522void cfg80211_mlme_down(struct cfg80211_registered_device *rdev, 415void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
523 struct net_device *dev) 416 struct net_device *dev)
524{ 417{
525 struct wireless_dev *wdev = dev->ieee80211_ptr; 418 struct wireless_dev *wdev = dev->ieee80211_ptr;
526 struct cfg80211_deauth_request req;
527 u8 bssid[ETH_ALEN]; 419 u8 bssid[ETH_ALEN];
420 struct cfg80211_deauth_request req = {
421 .reason_code = WLAN_REASON_DEAUTH_LEAVING,
422 .bssid = bssid,
423 };
528 424
529 ASSERT_WDEV_LOCK(wdev); 425 ASSERT_WDEV_LOCK(wdev);
530 426
531 if (!rdev->ops->deauth) 427 if (!rdev->ops->deauth)
532 return; 428 return;
533 429
534 memset(&req, 0, sizeof(req));
535 req.reason_code = WLAN_REASON_DEAUTH_LEAVING;
536 req.ie = NULL;
537 req.ie_len = 0;
538
539 if (!wdev->current_bss) 430 if (!wdev->current_bss)
540 return; 431 return;
541 432
542 memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN); 433 memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN);
543 req.bssid = bssid;
544 rdev_deauth(rdev, dev, &req); 434 rdev_deauth(rdev, dev, &req);
545 435
546 if (wdev->current_bss) { 436 if (wdev->current_bss) {
@@ -848,7 +738,7 @@ void cfg80211_dfs_channels_update_work(struct work_struct *work)
848 dfs_update_channels_wk); 738 dfs_update_channels_wk);
849 wiphy = &rdev->wiphy; 739 wiphy = &rdev->wiphy;
850 740
851 mutex_lock(&cfg80211_mutex); 741 rtnl_lock();
852 for (bandid = 0; bandid < IEEE80211_NUM_BANDS; bandid++) { 742 for (bandid = 0; bandid < IEEE80211_NUM_BANDS; bandid++) {
853 sband = wiphy->bands[bandid]; 743 sband = wiphy->bands[bandid];
854 if (!sband) 744 if (!sband)
@@ -881,7 +771,7 @@ void cfg80211_dfs_channels_update_work(struct work_struct *work)
881 check_again = true; 771 check_again = true;
882 } 772 }
883 } 773 }
884 mutex_unlock(&cfg80211_mutex); 774 rtnl_unlock();
885 775
886 /* reschedule if there are other channels waiting to be cleared again */ 776 /* reschedule if there are other channels waiting to be cleared again */
887 if (check_again) 777 if (check_again)