cfg80211: Disallow HT/WEP in IBSS mode
[GitHub/exynos8895/android_kernel_samsung_universal8895.git] / net / wireless / mlme.c
CommitLineData
6039f6d2
JM
1/*
2 * cfg80211 MLME SAP interface
3 *
4 * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
5 */
6
7#include <linux/kernel.h>
8#include <linux/module.h>
c6fb08aa 9#include <linux/etherdevice.h>
6039f6d2
JM
10#include <linux/netdevice.h>
11#include <linux/nl80211.h>
5a0e3ad6 12#include <linux/slab.h>
a9a11622 13#include <linux/wireless.h>
6039f6d2 14#include <net/cfg80211.h>
a9a11622 15#include <net/iw_handler.h>
6039f6d2
JM
16#include "core.h"
17#include "nl80211.h"
18
cb0b4beb 19void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len)
6039f6d2 20{
19957bb3
JB
21 struct wireless_dev *wdev = dev->ieee80211_ptr;
22 struct wiphy *wiphy = wdev->wiphy;
6039f6d2 23 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
19957bb3 24
667503dd 25 wdev_lock(wdev);
cb0b4beb 26
95de817b
JB
27 nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL);
28 cfg80211_sme_rx_auth(dev, buf, len);
667503dd
JB
29
30 wdev_unlock(wdev);
6039f6d2
JM
31}
32EXPORT_SYMBOL(cfg80211_send_rx_auth);
33
95de817b
JB
34void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
35 const u8 *buf, size_t len)
6039f6d2 36{
6829c878
JB
37 u16 status_code;
38 struct wireless_dev *wdev = dev->ieee80211_ptr;
39 struct wiphy *wiphy = wdev->wiphy;
6039f6d2 40 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
6829c878
JB
41 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
42 u8 *ie = mgmt->u.assoc_resp.variable;
95de817b 43 int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
6829c878 44
667503dd 45 wdev_lock(wdev);
cb0b4beb 46
6829c878
JB
47 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
48
f401a6f7
JB
49 /*
50 * This is a bit of a hack, we don't notify userspace of
51 * a (re-)association reply if we tried to send a reassoc
52 * and got a reject -- we only try again with an assoc
53 * frame instead of reassoc.
54 */
55 if (status_code != WLAN_STATUS_SUCCESS && wdev->conn &&
95de817b
JB
56 cfg80211_sme_failed_reassoc(wdev)) {
57 cfg80211_put_bss(bss);
f401a6f7 58 goto out;
95de817b 59 }
f401a6f7 60
cb0b4beb 61 nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL);
6829c878 62
95de817b 63 if (status_code != WLAN_STATUS_SUCCESS && wdev->conn) {
7d930bc3 64 cfg80211_sme_failed_assoc(wdev);
7d930bc3
JB
65 /*
66 * do not call connect_result() now because the
67 * sme will schedule work that does it later.
68 */
95de817b 69 cfg80211_put_bss(bss);
7d930bc3 70 goto out;
df7fc0f9
JB
71 }
72
ea416a79
JB
73 if (!wdev->conn && wdev->sme_state == CFG80211_SME_IDLE) {
74 /*
75 * This is for the userspace SME, the CONNECTING
76 * state will be changed to CONNECTED by
77 * __cfg80211_connect_result() below.
78 */
79 wdev->sme_state = CFG80211_SME_CONNECTING;
80 }
81
95de817b 82 /* this consumes the bss reference */
df7fc0f9
JB
83 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
84 status_code,
95de817b 85 status_code == WLAN_STATUS_SUCCESS, bss);
f401a6f7 86 out:
667503dd 87 wdev_unlock(wdev);
6039f6d2
JM
88}
89EXPORT_SYMBOL(cfg80211_send_rx_assoc);
90
ce470613 91void __cfg80211_send_deauth(struct net_device *dev,
667503dd 92 const u8 *buf, size_t len)
6039f6d2 93{
6829c878
JB
94 struct wireless_dev *wdev = dev->ieee80211_ptr;
95 struct wiphy *wiphy = wdev->wiphy;
6039f6d2 96 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
6829c878 97 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
19957bb3 98 const u8 *bssid = mgmt->bssid;
95de817b 99 bool was_current = false;
6829c878 100
667503dd 101 ASSERT_WDEV_LOCK(wdev);
cb0b4beb 102
19957bb3 103 if (wdev->current_bss &&
ac422d3c 104 ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) {
19957bb3
JB
105 cfg80211_unhold_bss(wdev->current_bss);
106 cfg80211_put_bss(&wdev->current_bss->pub);
107 wdev->current_bss = NULL;
3f3b6a8d 108 was_current = true;
19957bb3 109 }
19957bb3 110
5fba4af3
JB
111 nl80211_send_deauth(rdev, dev, buf, len, GFP_KERNEL);
112
3f3b6a8d 113 if (wdev->sme_state == CFG80211_SME_CONNECTED && was_current) {
6829c878
JB
114 u16 reason_code;
115 bool from_ap;
116
117 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
118
ac422d3c 119 from_ap = !ether_addr_equal(mgmt->sa, dev->dev_addr);
667503dd 120 __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
6829c878 121 } else if (wdev->sme_state == CFG80211_SME_CONNECTING) {
667503dd
JB
122 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0,
123 WLAN_STATUS_UNSPECIFIED_FAILURE,
df7fc0f9 124 false, NULL);
667503dd
JB
125 }
126}
ce470613 127EXPORT_SYMBOL(__cfg80211_send_deauth);
667503dd 128
ce470613 129void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len)
667503dd
JB
130{
131 struct wireless_dev *wdev = dev->ieee80211_ptr;
132
ce470613
HS
133 wdev_lock(wdev);
134 __cfg80211_send_deauth(dev, buf, len);
135 wdev_unlock(wdev);
6039f6d2 136}
53b46b84 137EXPORT_SYMBOL(cfg80211_send_deauth);
6039f6d2 138
ce470613 139void __cfg80211_send_disassoc(struct net_device *dev,
667503dd 140 const u8 *buf, size_t len)
6039f6d2 141{
6829c878
JB
142 struct wireless_dev *wdev = dev->ieee80211_ptr;
143 struct wiphy *wiphy = wdev->wiphy;
6039f6d2 144 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
6829c878 145 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
19957bb3 146 const u8 *bssid = mgmt->bssid;
19957bb3
JB
147 u16 reason_code;
148 bool from_ap;
6829c878 149
596a07c1 150 ASSERT_WDEV_LOCK(wdev);
cb0b4beb
JB
151
152 nl80211_send_disassoc(rdev, dev, buf, len, GFP_KERNEL);
a3b8b056 153
596a07c1
JB
154 if (wdev->sme_state != CFG80211_SME_CONNECTED)
155 return;
6829c878 156
19957bb3 157 if (wdev->current_bss &&
ac422d3c 158 ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) {
95de817b
JB
159 cfg80211_sme_disassoc(dev, wdev->current_bss);
160 cfg80211_unhold_bss(wdev->current_bss);
161 cfg80211_put_bss(&wdev->current_bss->pub);
162 wdev->current_bss = NULL;
19957bb3
JB
163 } else
164 WARN_ON(1);
6829c878 165
6829c878 166
19957bb3
JB
167 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
168
ac422d3c 169 from_ap = !ether_addr_equal(mgmt->sa, dev->dev_addr);
667503dd 170 __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
667503dd 171}
ce470613 172EXPORT_SYMBOL(__cfg80211_send_disassoc);
667503dd 173
ce470613 174void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len)
667503dd
JB
175{
176 struct wireless_dev *wdev = dev->ieee80211_ptr;
177
ce470613
HS
178 wdev_lock(wdev);
179 __cfg80211_send_disassoc(dev, buf, len);
180 wdev_unlock(wdev);
1965c853 181}
6829c878 182EXPORT_SYMBOL(cfg80211_send_disassoc);
1965c853 183
cf4e594e
JM
184void cfg80211_send_unprot_deauth(struct net_device *dev, const u8 *buf,
185 size_t len)
186{
187 struct wireless_dev *wdev = dev->ieee80211_ptr;
188 struct wiphy *wiphy = wdev->wiphy;
189 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
190
191 nl80211_send_unprot_deauth(rdev, dev, buf, len, GFP_ATOMIC);
192}
193EXPORT_SYMBOL(cfg80211_send_unprot_deauth);
194
195void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf,
196 size_t len)
197{
198 struct wireless_dev *wdev = dev->ieee80211_ptr;
199 struct wiphy *wiphy = wdev->wiphy;
200 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
201
202 nl80211_send_unprot_disassoc(rdev, dev, buf, len, GFP_ATOMIC);
203}
204EXPORT_SYMBOL(cfg80211_send_unprot_disassoc);
205
a58ce43f
JB
206void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
207{
208 struct wireless_dev *wdev = dev->ieee80211_ptr;
209 struct wiphy *wiphy = wdev->wiphy;
210 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
211
212 wdev_lock(wdev);
213
214 nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL);
215 if (wdev->sme_state == CFG80211_SME_CONNECTING)
216 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
217 WLAN_STATUS_UNSPECIFIED_FAILURE,
218 false, NULL);
219
667503dd 220 wdev_unlock(wdev);
1965c853
JM
221}
222EXPORT_SYMBOL(cfg80211_send_auth_timeout);
223
cb0b4beb 224void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr)
1965c853 225{
6829c878
JB
226 struct wireless_dev *wdev = dev->ieee80211_ptr;
227 struct wiphy *wiphy = wdev->wiphy;
1965c853 228 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
19957bb3 229
667503dd 230 wdev_lock(wdev);
cb0b4beb
JB
231
232 nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL);
6829c878 233 if (wdev->sme_state == CFG80211_SME_CONNECTING)
667503dd
JB
234 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
235 WLAN_STATUS_UNSPECIFIED_FAILURE,
df7fc0f9 236 false, NULL);
19957bb3 237
667503dd 238 wdev_unlock(wdev);
1965c853
JM
239}
240EXPORT_SYMBOL(cfg80211_send_assoc_timeout);
241
a3b8b056
JM
242void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
243 enum nl80211_key_type key_type, int key_id,
e6d6e342 244 const u8 *tsc, gfp_t gfp)
a3b8b056
JM
245{
246 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
247 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
3d23e349 248#ifdef CONFIG_CFG80211_WEXT
f58d4ed9 249 union iwreq_data wrqu;
e6d6e342 250 char *buf = kmalloc(128, gfp);
f58d4ed9
JB
251
252 if (buf) {
253 sprintf(buf, "MLME-MICHAELMICFAILURE.indication("
254 "keyid=%d %scast addr=%pM)", key_id,
255 key_type == NL80211_KEYTYPE_GROUP ? "broad" : "uni",
256 addr);
257 memset(&wrqu, 0, sizeof(wrqu));
258 wrqu.data.length = strlen(buf);
259 wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
260 kfree(buf);
261 }
262#endif
263
e6d6e342 264 nl80211_michael_mic_failure(rdev, dev, addr, key_type, key_id, tsc, gfp);
a3b8b056
JM
265}
266EXPORT_SYMBOL(cfg80211_michael_mic_failure);
19957bb3
JB
267
268/* some MLME handling for userspace SME */
667503dd
JB
269int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
270 struct net_device *dev,
271 struct ieee80211_channel *chan,
272 enum nl80211_auth_type auth_type,
273 const u8 *bssid,
274 const u8 *ssid, int ssid_len,
fffd0934 275 const u8 *ie, int ie_len,
e39e5b5e
JM
276 const u8 *key, int key_len, int key_idx,
277 const u8 *sae_data, int sae_data_len)
19957bb3
JB
278{
279 struct wireless_dev *wdev = dev->ieee80211_ptr;
280 struct cfg80211_auth_request req;
95de817b 281 int err;
19957bb3 282
667503dd
JB
283 ASSERT_WDEV_LOCK(wdev);
284
fffd0934
JB
285 if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
286 if (!key || !key_len || key_idx < 0 || key_idx > 4)
287 return -EINVAL;
288
0a9b5e17 289 if (wdev->current_bss &&
ac422d3c 290 ether_addr_equal(bssid, wdev->current_bss->pub.bssid))
0a9b5e17
JB
291 return -EALREADY;
292
19957bb3
JB
293 memset(&req, 0, sizeof(req));
294
295 req.ie = ie;
296 req.ie_len = ie_len;
e39e5b5e
JM
297 req.sae_data = sae_data;
298 req.sae_data_len = sae_data_len;
19957bb3
JB
299 req.auth_type = auth_type;
300 req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
301 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
fffd0934
JB
302 req.key = key;
303 req.key_len = key_len;
304 req.key_idx = key_idx;
19957bb3
JB
305 if (!req.bss)
306 return -ENOENT;
307
e4e32459
MK
308 err = cfg80211_can_use_chan(rdev, wdev, req.bss->channel,
309 CHAN_MODE_SHARED);
310 if (err)
311 goto out;
312
19957bb3 313 err = rdev->ops->auth(&rdev->wiphy, dev, &req);
19957bb3 314
e4e32459 315out:
95de817b 316 cfg80211_put_bss(req.bss);
19957bb3
JB
317 return err;
318}
319
667503dd
JB
320int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
321 struct net_device *dev, struct ieee80211_channel *chan,
322 enum nl80211_auth_type auth_type, const u8 *bssid,
323 const u8 *ssid, int ssid_len,
fffd0934 324 const u8 *ie, int ie_len,
e39e5b5e
JM
325 const u8 *key, int key_len, int key_idx,
326 const u8 *sae_data, int sae_data_len)
667503dd
JB
327{
328 int err;
329
e4e32459 330 mutex_lock(&rdev->devlist_mtx);
667503dd
JB
331 wdev_lock(dev->ieee80211_ptr);
332 err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
fffd0934 333 ssid, ssid_len, ie, ie_len,
e39e5b5e
JM
334 key, key_len, key_idx,
335 sae_data, sae_data_len);
667503dd 336 wdev_unlock(dev->ieee80211_ptr);
e4e32459 337 mutex_unlock(&rdev->devlist_mtx);
667503dd
JB
338
339 return err;
340}
341
7e7c8926
BG
342/* Do a logical ht_capa &= ht_capa_mask. */
343void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
344 const struct ieee80211_ht_cap *ht_capa_mask)
345{
346 int i;
347 u8 *p1, *p2;
348 if (!ht_capa_mask) {
349 memset(ht_capa, 0, sizeof(*ht_capa));
350 return;
351 }
352
353 p1 = (u8*)(ht_capa);
354 p2 = (u8*)(ht_capa_mask);
355 for (i = 0; i<sizeof(*ht_capa); i++)
356 p1[i] &= p2[i];
357}
358
667503dd
JB
359int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
360 struct net_device *dev,
361 struct ieee80211_channel *chan,
362 const u8 *bssid, const u8 *prev_bssid,
363 const u8 *ssid, int ssid_len,
364 const u8 *ie, int ie_len, bool use_mfp,
7e7c8926
BG
365 struct cfg80211_crypto_settings *crypt,
366 u32 assoc_flags, struct ieee80211_ht_cap *ht_capa,
367 struct ieee80211_ht_cap *ht_capa_mask)
19957bb3
JB
368{
369 struct wireless_dev *wdev = dev->ieee80211_ptr;
370 struct cfg80211_assoc_request req;
95de817b 371 int err;
24b6b15f 372 bool was_connected = false;
19957bb3 373
667503dd
JB
374 ASSERT_WDEV_LOCK(wdev);
375
19957bb3
JB
376 memset(&req, 0, sizeof(req));
377
24b6b15f 378 if (wdev->current_bss && prev_bssid &&
ac422d3c 379 ether_addr_equal(wdev->current_bss->pub.bssid, prev_bssid)) {
24b6b15f
JM
380 /*
381 * Trying to reassociate: Allow this to proceed and let the old
382 * association to be dropped when the new one is completed.
383 */
384 if (wdev->sme_state == CFG80211_SME_CONNECTED) {
385 was_connected = true;
386 wdev->sme_state = CFG80211_SME_CONNECTING;
387 }
388 } else if (wdev->current_bss)
19957bb3
JB
389 return -EALREADY;
390
391 req.ie = ie;
392 req.ie_len = ie_len;
393 memcpy(&req.crypto, crypt, sizeof(req.crypto));
394 req.use_mfp = use_mfp;
3e5d7649 395 req.prev_bssid = prev_bssid;
7e7c8926
BG
396 req.flags = assoc_flags;
397 if (ht_capa)
398 memcpy(&req.ht_capa, ht_capa, sizeof(req.ht_capa));
399 if (ht_capa_mask)
400 memcpy(&req.ht_capa_mask, ht_capa_mask,
401 sizeof(req.ht_capa_mask));
402 cfg80211_oper_and_ht_capa(&req.ht_capa_mask,
403 rdev->wiphy.ht_capa_mod_mask);
404
19957bb3
JB
405 req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
406 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
24b6b15f
JM
407 if (!req.bss) {
408 if (was_connected)
409 wdev->sme_state = CFG80211_SME_CONNECTED;
19957bb3 410 return -ENOENT;
24b6b15f 411 }
19957bb3 412
e4e32459
MK
413 err = cfg80211_can_use_chan(rdev, wdev, req.bss->channel,
414 CHAN_MODE_SHARED);
415 if (err)
416 goto out;
417
95de817b 418 err = rdev->ops->assoc(&rdev->wiphy, dev, &req);
19957bb3 419
e4e32459 420out:
95de817b
JB
421 if (err) {
422 if (was_connected)
423 wdev->sme_state = CFG80211_SME_CONNECTED;
424 cfg80211_put_bss(req.bss);
19957bb3
JB
425 }
426
19957bb3
JB
427 return err;
428}
429
667503dd
JB
430int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
431 struct net_device *dev,
432 struct ieee80211_channel *chan,
433 const u8 *bssid, const u8 *prev_bssid,
434 const u8 *ssid, int ssid_len,
435 const u8 *ie, int ie_len, bool use_mfp,
7e7c8926
BG
436 struct cfg80211_crypto_settings *crypt,
437 u32 assoc_flags, struct ieee80211_ht_cap *ht_capa,
438 struct ieee80211_ht_cap *ht_capa_mask)
667503dd
JB
439{
440 struct wireless_dev *wdev = dev->ieee80211_ptr;
441 int err;
442
e4e32459 443 mutex_lock(&rdev->devlist_mtx);
667503dd
JB
444 wdev_lock(wdev);
445 err = __cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid,
7e7c8926
BG
446 ssid, ssid_len, ie, ie_len, use_mfp, crypt,
447 assoc_flags, ht_capa, ht_capa_mask);
667503dd 448 wdev_unlock(wdev);
e4e32459 449 mutex_unlock(&rdev->devlist_mtx);
667503dd
JB
450
451 return err;
452}
453
454int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
455 struct net_device *dev, const u8 *bssid,
d5cdfacb
JM
456 const u8 *ie, int ie_len, u16 reason,
457 bool local_state_change)
19957bb3
JB
458{
459 struct wireless_dev *wdev = dev->ieee80211_ptr;
95de817b
JB
460 struct cfg80211_deauth_request req = {
461 .bssid = bssid,
462 .reason_code = reason,
463 .ie = ie,
464 .ie_len = ie_len,
465 };
19957bb3 466
667503dd
JB
467 ASSERT_WDEV_LOCK(wdev);
468
95de817b
JB
469 if (local_state_change) {
470 if (wdev->current_bss &&
ac422d3c 471 ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) {
95de817b
JB
472 cfg80211_unhold_bss(wdev->current_bss);
473 cfg80211_put_bss(&wdev->current_bss->pub);
474 wdev->current_bss = NULL;
19957bb3 475 }
19957bb3 476
95de817b
JB
477 return 0;
478 }
19957bb3 479
63c9c5e7 480 return rdev->ops->deauth(&rdev->wiphy, dev, &req);
19957bb3
JB
481}
482
667503dd
JB
483int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
484 struct net_device *dev, const u8 *bssid,
d5cdfacb
JM
485 const u8 *ie, int ie_len, u16 reason,
486 bool local_state_change)
667503dd
JB
487{
488 struct wireless_dev *wdev = dev->ieee80211_ptr;
489 int err;
490
491 wdev_lock(wdev);
d5cdfacb
JM
492 err = __cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason,
493 local_state_change);
667503dd
JB
494 wdev_unlock(wdev);
495
496 return err;
497}
498
499static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
500 struct net_device *dev, const u8 *bssid,
d5cdfacb
JM
501 const u8 *ie, int ie_len, u16 reason,
502 bool local_state_change)
19957bb3
JB
503{
504 struct wireless_dev *wdev = dev->ieee80211_ptr;
505 struct cfg80211_disassoc_request req;
506
667503dd
JB
507 ASSERT_WDEV_LOCK(wdev);
508
f9d6b402
JB
509 if (wdev->sme_state != CFG80211_SME_CONNECTED)
510 return -ENOTCONN;
511
512 if (WARN_ON(!wdev->current_bss))
513 return -ENOTCONN;
514
19957bb3
JB
515 memset(&req, 0, sizeof(req));
516 req.reason_code = reason;
d5cdfacb 517 req.local_state_change = local_state_change;
19957bb3
JB
518 req.ie = ie;
519 req.ie_len = ie_len;
ac422d3c 520 if (ether_addr_equal(wdev->current_bss->pub.bssid, bssid))
19957bb3
JB
521 req.bss = &wdev->current_bss->pub;
522 else
523 return -ENOTCONN;
524
63c9c5e7 525 return rdev->ops->disassoc(&rdev->wiphy, dev, &req);
667503dd
JB
526}
527
528int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
529 struct net_device *dev, const u8 *bssid,
d5cdfacb
JM
530 const u8 *ie, int ie_len, u16 reason,
531 bool local_state_change)
667503dd
JB
532{
533 struct wireless_dev *wdev = dev->ieee80211_ptr;
534 int err;
535
536 wdev_lock(wdev);
d5cdfacb
JM
537 err = __cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason,
538 local_state_change);
667503dd
JB
539 wdev_unlock(wdev);
540
541 return err;
19957bb3
JB
542}
543
544void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
545 struct net_device *dev)
546{
547 struct wireless_dev *wdev = dev->ieee80211_ptr;
548 struct cfg80211_deauth_request req;
95de817b 549 u8 bssid[ETH_ALEN];
19957bb3 550
667503dd
JB
551 ASSERT_WDEV_LOCK(wdev);
552
19957bb3
JB
553 if (!rdev->ops->deauth)
554 return;
555
556 memset(&req, 0, sizeof(req));
557 req.reason_code = WLAN_REASON_DEAUTH_LEAVING;
558 req.ie = NULL;
559 req.ie_len = 0;
560
95de817b
JB
561 if (!wdev->current_bss)
562 return;
19957bb3 563
95de817b
JB
564 memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN);
565 req.bssid = bssid;
63c9c5e7 566 rdev->ops->deauth(&rdev->wiphy, dev, &req);
95de817b
JB
567
568 if (wdev->current_bss) {
569 cfg80211_unhold_bss(wdev->current_bss);
570 cfg80211_put_bss(&wdev->current_bss->pub);
571 wdev->current_bss = NULL;
19957bb3
JB
572 }
573}
9588bbd5 574
71bbc994 575void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
9588bbd5
JM
576 struct ieee80211_channel *chan,
577 enum nl80211_channel_type channel_type,
578 unsigned int duration, gfp_t gfp)
579{
71bbc994 580 struct wiphy *wiphy = wdev->wiphy;
9588bbd5
JM
581 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
582
71bbc994 583 nl80211_send_remain_on_channel(rdev, wdev, cookie, chan, channel_type,
9588bbd5
JM
584 duration, gfp);
585}
586EXPORT_SYMBOL(cfg80211_ready_on_channel);
587
71bbc994 588void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
9588bbd5
JM
589 struct ieee80211_channel *chan,
590 enum nl80211_channel_type channel_type,
591 gfp_t gfp)
592{
71bbc994 593 struct wiphy *wiphy = wdev->wiphy;
9588bbd5
JM
594 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
595
71bbc994 596 nl80211_send_remain_on_channel_cancel(rdev, wdev, cookie, chan,
9588bbd5
JM
597 channel_type, gfp);
598}
599EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
98b62183
JB
600
601void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
602 struct station_info *sinfo, gfp_t gfp)
603{
604 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
605 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
606
607 nl80211_send_sta_event(rdev, dev, mac_addr, sinfo, gfp);
608}
609EXPORT_SYMBOL(cfg80211_new_sta);
026331c4 610
ec15e68b
JM
611void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp)
612{
613 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
614 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
615
616 nl80211_send_sta_del_event(rdev, dev, mac_addr, gfp);
617}
618EXPORT_SYMBOL(cfg80211_del_sta);
619
ed44a951
PP
620void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
621 enum nl80211_connect_failed_reason reason,
622 gfp_t gfp)
623{
624 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
625 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
626
627 nl80211_send_conn_failed_event(rdev, dev, mac_addr, reason, gfp);
628}
629EXPORT_SYMBOL(cfg80211_conn_failed);
630
2e161f78 631struct cfg80211_mgmt_registration {
026331c4
JM
632 struct list_head list;
633
15e47304 634 u32 nlportid;
026331c4
JM
635
636 int match_len;
637
2e161f78
JB
638 __le16 frame_type;
639
026331c4
JM
640 u8 match[];
641};
642
15e47304 643int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid,
2e161f78
JB
644 u16 frame_type, const u8 *match_data,
645 int match_len)
026331c4 646{
271733cf
JB
647 struct wiphy *wiphy = wdev->wiphy;
648 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
2e161f78 649 struct cfg80211_mgmt_registration *reg, *nreg;
026331c4 650 int err = 0;
2e161f78
JB
651 u16 mgmt_type;
652
653 if (!wdev->wiphy->mgmt_stypes)
654 return -EOPNOTSUPP;
655
656 if ((frame_type & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT)
657 return -EINVAL;
658
659 if (frame_type & ~(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE))
660 return -EINVAL;
661
662 mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
663 if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].rx & BIT(mgmt_type)))
664 return -EINVAL;
026331c4
JM
665
666 nreg = kzalloc(sizeof(*reg) + match_len, GFP_KERNEL);
667 if (!nreg)
668 return -ENOMEM;
669
2e161f78 670 spin_lock_bh(&wdev->mgmt_registrations_lock);
026331c4 671
2e161f78 672 list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
026331c4
JM
673 int mlen = min(match_len, reg->match_len);
674
2e161f78
JB
675 if (frame_type != le16_to_cpu(reg->frame_type))
676 continue;
677
026331c4
JM
678 if (memcmp(reg->match, match_data, mlen) == 0) {
679 err = -EALREADY;
680 break;
681 }
682 }
683
684 if (err) {
685 kfree(nreg);
686 goto out;
687 }
688
689 memcpy(nreg->match, match_data, match_len);
690 nreg->match_len = match_len;
15e47304 691 nreg->nlportid = snd_portid;
2e161f78
JB
692 nreg->frame_type = cpu_to_le16(frame_type);
693 list_add(&nreg->list, &wdev->mgmt_registrations);
026331c4 694
271733cf 695 if (rdev->ops->mgmt_frame_register)
71bbc994 696 rdev->ops->mgmt_frame_register(wiphy, wdev, frame_type, true);
271733cf 697
026331c4 698 out:
2e161f78 699 spin_unlock_bh(&wdev->mgmt_registrations_lock);
271733cf 700
026331c4
JM
701 return err;
702}
703
15e47304 704void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlportid)
026331c4 705{
271733cf
JB
706 struct wiphy *wiphy = wdev->wiphy;
707 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
2e161f78 708 struct cfg80211_mgmt_registration *reg, *tmp;
026331c4 709
2e161f78 710 spin_lock_bh(&wdev->mgmt_registrations_lock);
026331c4 711
2e161f78 712 list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
15e47304 713 if (reg->nlportid != nlportid)
271733cf
JB
714 continue;
715
716 if (rdev->ops->mgmt_frame_register) {
717 u16 frame_type = le16_to_cpu(reg->frame_type);
718
71bbc994 719 rdev->ops->mgmt_frame_register(wiphy, wdev,
271733cf 720 frame_type, false);
026331c4 721 }
271733cf
JB
722
723 list_del(&reg->list);
724 kfree(reg);
026331c4
JM
725 }
726
2e161f78 727 spin_unlock_bh(&wdev->mgmt_registrations_lock);
28946da7 728
15e47304
EB
729 if (nlportid == wdev->ap_unexpected_nlportid)
730 wdev->ap_unexpected_nlportid = 0;
026331c4
JM
731}
732
2e161f78 733void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
026331c4 734{
2e161f78 735 struct cfg80211_mgmt_registration *reg, *tmp;
026331c4 736
2e161f78 737 spin_lock_bh(&wdev->mgmt_registrations_lock);
026331c4 738
2e161f78 739 list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
026331c4
JM
740 list_del(&reg->list);
741 kfree(reg);
742 }
743
2e161f78 744 spin_unlock_bh(&wdev->mgmt_registrations_lock);
026331c4
JM
745}
746
2e161f78 747int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
71bbc994 748 struct wireless_dev *wdev,
f7ca38df 749 struct ieee80211_channel *chan, bool offchan,
2e161f78 750 enum nl80211_channel_type channel_type,
f7ca38df 751 bool channel_type_valid, unsigned int wait,
e9f935e3 752 const u8 *buf, size_t len, bool no_cck,
e247bd90 753 bool dont_wait_for_ack, u64 *cookie)
026331c4 754{
026331c4 755 const struct ieee80211_mgmt *mgmt;
2e161f78
JB
756 u16 stype;
757
758 if (!wdev->wiphy->mgmt_stypes)
759 return -EOPNOTSUPP;
026331c4 760
2e161f78 761 if (!rdev->ops->mgmt_tx)
026331c4 762 return -EOPNOTSUPP;
2e161f78 763
026331c4
JM
764 if (len < 24 + 1)
765 return -EINVAL;
766
767 mgmt = (const struct ieee80211_mgmt *) buf;
2e161f78
JB
768
769 if (!ieee80211_is_mgmt(mgmt->frame_control))
026331c4 770 return -EINVAL;
2e161f78
JB
771
772 stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
773 if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].tx & BIT(stype >> 4)))
774 return -EINVAL;
775
776 if (ieee80211_is_action(mgmt->frame_control) &&
777 mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) {
663fcafd
JB
778 int err = 0;
779
fe100acd
JB
780 wdev_lock(wdev);
781
663fcafd
JB
782 switch (wdev->iftype) {
783 case NL80211_IFTYPE_ADHOC:
784 case NL80211_IFTYPE_STATION:
785 case NL80211_IFTYPE_P2P_CLIENT:
786 if (!wdev->current_bss) {
787 err = -ENOTCONN;
788 break;
789 }
790
ac422d3c
JP
791 if (!ether_addr_equal(wdev->current_bss->pub.bssid,
792 mgmt->bssid)) {
663fcafd
JB
793 err = -ENOTCONN;
794 break;
795 }
796
797 /*
798 * check for IBSS DA must be done by driver as
799 * cfg80211 doesn't track the stations
800 */
801 if (wdev->iftype == NL80211_IFTYPE_ADHOC)
802 break;
fe100acd 803
663fcafd 804 /* for station, check that DA is the AP */
ac422d3c
JP
805 if (!ether_addr_equal(wdev->current_bss->pub.bssid,
806 mgmt->da)) {
663fcafd
JB
807 err = -ENOTCONN;
808 break;
809 }
810 break;
811 case NL80211_IFTYPE_AP:
812 case NL80211_IFTYPE_P2P_GO:
813 case NL80211_IFTYPE_AP_VLAN:
98104fde 814 if (!ether_addr_equal(mgmt->bssid, wdev_address(wdev)))
663fcafd
JB
815 err = -EINVAL;
816 break;
0778a6a3 817 case NL80211_IFTYPE_MESH_POINT:
ac422d3c 818 if (!ether_addr_equal(mgmt->sa, mgmt->bssid)) {
0778a6a3
JC
819 err = -EINVAL;
820 break;
821 }
822 /*
823 * check for mesh DA must be done by driver as
824 * cfg80211 doesn't track the stations
825 */
826 break;
98104fde
JB
827 case NL80211_IFTYPE_P2P_DEVICE:
828 /*
829 * fall through, P2P device only supports
830 * public action frames
831 */
663fcafd
JB
832 default:
833 err = -EOPNOTSUPP;
834 break;
835 }
fe100acd 836 wdev_unlock(wdev);
663fcafd
JB
837
838 if (err)
839 return err;
026331c4
JM
840 }
841
98104fde 842 if (!ether_addr_equal(mgmt->sa, wdev_address(wdev)))
026331c4
JM
843 return -EINVAL;
844
845 /* Transmit the Action frame as requested by user space */
71bbc994 846 return rdev->ops->mgmt_tx(&rdev->wiphy, wdev, chan, offchan,
f7ca38df 847 channel_type, channel_type_valid,
e247bd90
JB
848 wait, buf, len, no_cck, dont_wait_for_ack,
849 cookie);
026331c4
JM
850}
851
71bbc994 852bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm,
804483e9 853 const u8 *buf, size_t len, gfp_t gfp)
026331c4 854{
026331c4
JM
855 struct wiphy *wiphy = wdev->wiphy;
856 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
2e161f78
JB
857 struct cfg80211_mgmt_registration *reg;
858 const struct ieee80211_txrx_stypes *stypes =
859 &wiphy->mgmt_stypes[wdev->iftype];
860 struct ieee80211_mgmt *mgmt = (void *)buf;
861 const u8 *data;
862 int data_len;
026331c4 863 bool result = false;
2e161f78
JB
864 __le16 ftype = mgmt->frame_control &
865 cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE);
866 u16 stype;
026331c4 867
2e161f78 868 stype = (le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) >> 4;
026331c4 869
2e161f78
JB
870 if (!(stypes->rx & BIT(stype)))
871 return false;
026331c4 872
2e161f78
JB
873 data = buf + ieee80211_hdrlen(mgmt->frame_control);
874 data_len = len - ieee80211_hdrlen(mgmt->frame_control);
875
876 spin_lock_bh(&wdev->mgmt_registrations_lock);
877
878 list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
879 if (reg->frame_type != ftype)
880 continue;
026331c4 881
2e161f78 882 if (reg->match_len > data_len)
026331c4
JM
883 continue;
884
2e161f78 885 if (memcmp(reg->match, data, reg->match_len))
026331c4
JM
886 continue;
887
888 /* found match! */
889
890 /* Indicate the received Action frame to user space */
15e47304 891 if (nl80211_send_mgmt(rdev, wdev, reg->nlportid,
804483e9 892 freq, sig_mbm,
2e161f78 893 buf, len, gfp))
026331c4
JM
894 continue;
895
896 result = true;
897 break;
898 }
899
2e161f78 900 spin_unlock_bh(&wdev->mgmt_registrations_lock);
026331c4
JM
901
902 return result;
903}
2e161f78 904EXPORT_SYMBOL(cfg80211_rx_mgmt);
026331c4 905
71bbc994 906void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
2e161f78 907 const u8 *buf, size_t len, bool ack, gfp_t gfp)
026331c4 908{
026331c4
JM
909 struct wiphy *wiphy = wdev->wiphy;
910 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
911
912 /* Indicate TX status of the Action frame to user space */
71bbc994 913 nl80211_send_mgmt_tx_status(rdev, wdev, cookie, buf, len, ack, gfp);
026331c4 914}
2e161f78 915EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
d6dc1a38
JO
916
917void cfg80211_cqm_rssi_notify(struct net_device *dev,
918 enum nl80211_cqm_rssi_threshold_event rssi_event,
919 gfp_t gfp)
920{
921 struct wireless_dev *wdev = dev->ieee80211_ptr;
922 struct wiphy *wiphy = wdev->wiphy;
923 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
924
925 /* Indicate roaming trigger event to user space */
926 nl80211_send_cqm_rssi_notify(rdev, dev, rssi_event, gfp);
927}
928EXPORT_SYMBOL(cfg80211_cqm_rssi_notify);
c063dbf5
JB
929
930void cfg80211_cqm_pktloss_notify(struct net_device *dev,
931 const u8 *peer, u32 num_packets, gfp_t gfp)
932{
933 struct wireless_dev *wdev = dev->ieee80211_ptr;
934 struct wiphy *wiphy = wdev->wiphy;
935 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
936
937 /* Indicate roaming trigger event to user space */
938 nl80211_send_cqm_pktloss_notify(rdev, dev, peer, num_packets, gfp);
939}
940EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify);
e5497d76 941
84f10708
TP
942void cfg80211_cqm_txe_notify(struct net_device *dev,
943 const u8 *peer, u32 num_packets,
944 u32 rate, u32 intvl, gfp_t gfp)
945{
946 struct wireless_dev *wdev = dev->ieee80211_ptr;
947 struct wiphy *wiphy = wdev->wiphy;
948 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
949
950 nl80211_send_cqm_txe_notify(rdev, dev, peer, num_packets,
951 rate, intvl, gfp);
952}
953EXPORT_SYMBOL(cfg80211_cqm_txe_notify);
954
e5497d76
JB
955void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
956 const u8 *replay_ctr, gfp_t gfp)
957{
958 struct wireless_dev *wdev = dev->ieee80211_ptr;
959 struct wiphy *wiphy = wdev->wiphy;
960 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
961
962 nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp);
963}
964EXPORT_SYMBOL(cfg80211_gtk_rekey_notify);
c9df56b4
JM
965
966void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
967 const u8 *bssid, bool preauth, gfp_t gfp)
968{
969 struct wireless_dev *wdev = dev->ieee80211_ptr;
970 struct wiphy *wiphy = wdev->wiphy;
971 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
972
973 nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp);
974}
975EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
28946da7 976
5314526b
TP
977void cfg80211_ch_switch_notify(struct net_device *dev, int freq,
978 enum nl80211_channel_type type)
979{
980 struct wireless_dev *wdev = dev->ieee80211_ptr;
981 struct wiphy *wiphy = wdev->wiphy;
982 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
983 struct ieee80211_channel *chan;
984
985 wdev_lock(wdev);
986
987 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
988 wdev->iftype != NL80211_IFTYPE_P2P_GO))
989 goto out;
990
991 chan = rdev_freq_to_chan(rdev, freq, type);
992 if (WARN_ON(!chan))
993 goto out;
994
f4489ebe 995 wdev->channel = chan;
5314526b
TP
996 nl80211_ch_switch_notify(rdev, dev, freq, type, GFP_KERNEL);
997out:
998 wdev_unlock(wdev);
999 return;
1000}
1001EXPORT_SYMBOL(cfg80211_ch_switch_notify);
1002
28946da7
JB
1003bool cfg80211_rx_spurious_frame(struct net_device *dev,
1004 const u8 *addr, gfp_t gfp)
1005{
1006 struct wireless_dev *wdev = dev->ieee80211_ptr;
1007
1008 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
1009 wdev->iftype != NL80211_IFTYPE_P2P_GO))
1010 return false;
1011
1012 return nl80211_unexpected_frame(dev, addr, gfp);
1013}
1014EXPORT_SYMBOL(cfg80211_rx_spurious_frame);
b92ab5d8
JB
1015
1016bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
1017 const u8 *addr, gfp_t gfp)
1018{
1019 struct wireless_dev *wdev = dev->ieee80211_ptr;
1020
1021 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
1022 wdev->iftype != NL80211_IFTYPE_P2P_GO &&
1023 wdev->iftype != NL80211_IFTYPE_AP_VLAN))
1024 return false;
1025
1026 return nl80211_unexpected_4addr_frame(dev, addr, gfp);
1027}
1028EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame);