]> Pileus Git - ~andy/linux/blob - net/wireless/mlme.c
cfg80211: move exported event functions into nl80211
[~andy/linux] / net / wireless / mlme.c
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>
9 #include <linux/etherdevice.h>
10 #include <linux/netdevice.h>
11 #include <linux/nl80211.h>
12 #include <linux/slab.h>
13 #include <linux/wireless.h>
14 #include <net/cfg80211.h>
15 #include <net/iw_handler.h>
16 #include "core.h"
17 #include "nl80211.h"
18 #include "rdev-ops.h"
19
20
21 void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len)
22 {
23         struct wireless_dev *wdev = dev->ieee80211_ptr;
24         struct wiphy *wiphy = wdev->wiphy;
25         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
26
27         trace_cfg80211_send_rx_auth(dev);
28         wdev_lock(wdev);
29
30         nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL);
31         cfg80211_sme_rx_auth(dev, buf, len);
32
33         wdev_unlock(wdev);
34 }
35 EXPORT_SYMBOL(cfg80211_send_rx_auth);
36
37 void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
38                             const u8 *buf, size_t len)
39 {
40         u16 status_code;
41         struct wireless_dev *wdev = dev->ieee80211_ptr;
42         struct wiphy *wiphy = wdev->wiphy;
43         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
44         struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
45         u8 *ie = mgmt->u.assoc_resp.variable;
46         int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
47
48         trace_cfg80211_send_rx_assoc(dev, bss);
49         wdev_lock(wdev);
50
51         status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
52
53         /*
54          * This is a bit of a hack, we don't notify userspace of
55          * a (re-)association reply if we tried to send a reassoc
56          * and got a reject -- we only try again with an assoc
57          * frame instead of reassoc.
58          */
59         if (status_code != WLAN_STATUS_SUCCESS && wdev->conn &&
60             cfg80211_sme_failed_reassoc(wdev)) {
61                 cfg80211_put_bss(wiphy, bss);
62                 goto out;
63         }
64
65         nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL);
66
67         if (status_code != WLAN_STATUS_SUCCESS && wdev->conn) {
68                 cfg80211_sme_failed_assoc(wdev);
69                 /*
70                  * do not call connect_result() now because the
71                  * sme will schedule work that does it later.
72                  */
73                 cfg80211_put_bss(wiphy, bss);
74                 goto out;
75         }
76
77         if (!wdev->conn && wdev->sme_state == CFG80211_SME_IDLE) {
78                 /*
79                  * This is for the userspace SME, the CONNECTING
80                  * state will be changed to CONNECTED by
81                  * __cfg80211_connect_result() below.
82                  */
83                 wdev->sme_state = CFG80211_SME_CONNECTING;
84         }
85
86         /* this consumes the bss reference */
87         __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
88                                   status_code,
89                                   status_code == WLAN_STATUS_SUCCESS, bss);
90  out:
91         wdev_unlock(wdev);
92 }
93 EXPORT_SYMBOL(cfg80211_send_rx_assoc);
94
95 void __cfg80211_send_deauth(struct net_device *dev,
96                                    const u8 *buf, size_t len)
97 {
98         struct wireless_dev *wdev = dev->ieee80211_ptr;
99         struct wiphy *wiphy = wdev->wiphy;
100         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
101         struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
102         const u8 *bssid = mgmt->bssid;
103         bool was_current = false;
104
105         trace___cfg80211_send_deauth(dev);
106         ASSERT_WDEV_LOCK(wdev);
107
108         if (wdev->current_bss &&
109             ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) {
110                 cfg80211_unhold_bss(wdev->current_bss);
111                 cfg80211_put_bss(wiphy, &wdev->current_bss->pub);
112                 wdev->current_bss = NULL;
113                 was_current = true;
114         }
115
116         nl80211_send_deauth(rdev, dev, buf, len, GFP_KERNEL);
117
118         if (wdev->sme_state == CFG80211_SME_CONNECTED && was_current) {
119                 u16 reason_code;
120                 bool from_ap;
121
122                 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
123
124                 from_ap = !ether_addr_equal(mgmt->sa, dev->dev_addr);
125                 __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
126         } else if (wdev->sme_state == CFG80211_SME_CONNECTING) {
127                 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0,
128                                           WLAN_STATUS_UNSPECIFIED_FAILURE,
129                                           false, NULL);
130         }
131 }
132 EXPORT_SYMBOL(__cfg80211_send_deauth);
133
134 void 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 }
142 EXPORT_SYMBOL(cfg80211_send_deauth);
143
144 void __cfg80211_send_disassoc(struct net_device *dev,
145                                      const u8 *buf, size_t len)
146 {
147         struct wireless_dev *wdev = dev->ieee80211_ptr;
148         struct wiphy *wiphy = wdev->wiphy;
149         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
150         struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
151         const u8 *bssid = mgmt->bssid;
152         u16 reason_code;
153         bool from_ap;
154
155         trace___cfg80211_send_disassoc(dev);
156         ASSERT_WDEV_LOCK(wdev);
157
158         nl80211_send_disassoc(rdev, dev, buf, len, GFP_KERNEL);
159
160         if (wdev->sme_state != CFG80211_SME_CONNECTED)
161                 return;
162
163         if (wdev->current_bss &&
164             ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) {
165                 cfg80211_sme_disassoc(dev, wdev->current_bss);
166                 cfg80211_unhold_bss(wdev->current_bss);
167                 cfg80211_put_bss(wiphy, &wdev->current_bss->pub);
168                 wdev->current_bss = NULL;
169         } else
170                 WARN_ON(1);
171
172
173         reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
174
175         from_ap = !ether_addr_equal(mgmt->sa, dev->dev_addr);
176         __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
177 }
178 EXPORT_SYMBOL(__cfg80211_send_disassoc);
179
180 void 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 }
188 EXPORT_SYMBOL(cfg80211_send_disassoc);
189
190 void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
191 {
192         struct wireless_dev *wdev = dev->ieee80211_ptr;
193         struct wiphy *wiphy = wdev->wiphy;
194         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
195
196         trace_cfg80211_send_auth_timeout(dev, addr);
197         wdev_lock(wdev);
198
199         nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL);
200         if (wdev->sme_state == CFG80211_SME_CONNECTING)
201                 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
202                                           WLAN_STATUS_UNSPECIFIED_FAILURE,
203                                           false, NULL);
204
205         wdev_unlock(wdev);
206 }
207 EXPORT_SYMBOL(cfg80211_send_auth_timeout);
208
209 void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr)
210 {
211         struct wireless_dev *wdev = dev->ieee80211_ptr;
212         struct wiphy *wiphy = wdev->wiphy;
213         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
214
215         trace_cfg80211_send_assoc_timeout(dev, addr);
216         wdev_lock(wdev);
217
218         nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL);
219         if (wdev->sme_state == CFG80211_SME_CONNECTING)
220                 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
221                                           WLAN_STATUS_UNSPECIFIED_FAILURE,
222                                           false, NULL);
223
224         wdev_unlock(wdev);
225 }
226 EXPORT_SYMBOL(cfg80211_send_assoc_timeout);
227
228 void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
229                                   enum nl80211_key_type key_type, int key_id,
230                                   const u8 *tsc, gfp_t gfp)
231 {
232         struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
233         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
234 #ifdef CONFIG_CFG80211_WEXT
235         union iwreq_data wrqu;
236         char *buf = kmalloc(128, gfp);
237
238         if (buf) {
239                 sprintf(buf, "MLME-MICHAELMICFAILURE.indication("
240                         "keyid=%d %scast addr=%pM)", key_id,
241                         key_type == NL80211_KEYTYPE_GROUP ? "broad" : "uni",
242                         addr);
243                 memset(&wrqu, 0, sizeof(wrqu));
244                 wrqu.data.length = strlen(buf);
245                 wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
246                 kfree(buf);
247         }
248 #endif
249
250         trace_cfg80211_michael_mic_failure(dev, addr, key_type, key_id, tsc);
251         nl80211_michael_mic_failure(rdev, dev, addr, key_type, key_id, tsc, gfp);
252 }
253 EXPORT_SYMBOL(cfg80211_michael_mic_failure);
254
255 /* some MLME handling for userspace SME */
256 int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
257                          struct net_device *dev,
258                          struct ieee80211_channel *chan,
259                          enum nl80211_auth_type auth_type,
260                          const u8 *bssid,
261                          const u8 *ssid, int ssid_len,
262                          const u8 *ie, int ie_len,
263                          const u8 *key, int key_len, int key_idx,
264                          const u8 *sae_data, int sae_data_len)
265 {
266         struct wireless_dev *wdev = dev->ieee80211_ptr;
267         struct cfg80211_auth_request req;
268         int err;
269
270         ASSERT_WDEV_LOCK(wdev);
271
272         if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
273                 if (!key || !key_len || key_idx < 0 || key_idx > 4)
274                         return -EINVAL;
275
276         if (wdev->current_bss &&
277             ether_addr_equal(bssid, wdev->current_bss->pub.bssid))
278                 return -EALREADY;
279
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,
288                                    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)
293                 return -ENOENT;
294
295         err = cfg80211_can_use_chan(rdev, wdev, req.bss->channel,
296                                     CHAN_MODE_SHARED);
297         if (err)
298                 goto out;
299
300         err = rdev_auth(rdev, dev, &req);
301
302 out:
303         cfg80211_put_bss(&rdev->wiphy, req.bss);
304         return err;
305 }
306
307 int 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.  */
330 void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
331                                const struct ieee80211_ht_cap *ht_capa_mask)
332 {
333         int i;
334         u8 *p1, *p2;
335         if (!ht_capa_mask) {
336                 memset(ht_capa, 0, sizeof(*ht_capa));
337                 return;
338         }
339
340         p1 = (u8*)(ht_capa);
341         p2 = (u8*)(ht_capa_mask);
342         for (i = 0; i<sizeof(*ht_capa); i++)
343                 p1[i] &= p2[i];
344 }
345
346 int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
347                           struct net_device *dev,
348                           struct ieee80211_channel *chan,
349                           const u8 *bssid, const u8 *prev_bssid,
350                           const u8 *ssid, int ssid_len,
351                           const u8 *ie, int ie_len, bool use_mfp,
352                           struct cfg80211_crypto_settings *crypt,
353                           u32 assoc_flags, struct ieee80211_ht_cap *ht_capa,
354                           struct ieee80211_ht_cap *ht_capa_mask)
355 {
356         struct wireless_dev *wdev = dev->ieee80211_ptr;
357         struct cfg80211_assoc_request req;
358         int err;
359         bool was_connected = false;
360
361         ASSERT_WDEV_LOCK(wdev);
362
363         memset(&req, 0, sizeof(req));
364
365         if (wdev->current_bss && prev_bssid &&
366             ether_addr_equal(wdev->current_bss->pub.bssid, prev_bssid)) {
367                 /*
368                  * Trying to reassociate: Allow this to proceed and let the old
369                  * association to be dropped when the new one is completed.
370                  */
371                 if (wdev->sme_state == CFG80211_SME_CONNECTED) {
372                         was_connected = true;
373                         wdev->sme_state = CFG80211_SME_CONNECTING;
374                 }
375         } else if (wdev->current_bss)
376                 return -EALREADY;
377
378         req.ie = ie;
379         req.ie_len = ie_len;
380         memcpy(&req.crypto, crypt, sizeof(req.crypto));
381         req.use_mfp = use_mfp;
382         req.prev_bssid = prev_bssid;
383         req.flags = assoc_flags;
384         if (ht_capa)
385                 memcpy(&req.ht_capa, ht_capa, sizeof(req.ht_capa));
386         if (ht_capa_mask)
387                 memcpy(&req.ht_capa_mask, ht_capa_mask,
388                        sizeof(req.ht_capa_mask));
389         cfg80211_oper_and_ht_capa(&req.ht_capa_mask,
390                                   rdev->wiphy.ht_capa_mod_mask);
391
392         req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
393                                    WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
394         if (!req.bss) {
395                 if (was_connected)
396                         wdev->sme_state = CFG80211_SME_CONNECTED;
397                 return -ENOENT;
398         }
399
400         err = cfg80211_can_use_chan(rdev, wdev, req.bss->channel,
401                                     CHAN_MODE_SHARED);
402         if (err)
403                 goto out;
404
405         err = rdev_assoc(rdev, dev, &req);
406
407 out:
408         if (err) {
409                 if (was_connected)
410                         wdev->sme_state = CFG80211_SME_CONNECTED;
411                 cfg80211_put_bss(&rdev->wiphy, req.bss);
412         }
413
414         return err;
415 }
416
417 int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
418                         struct net_device *dev,
419                         struct ieee80211_channel *chan,
420                         const u8 *bssid, const u8 *prev_bssid,
421                         const u8 *ssid, int ssid_len,
422                         const u8 *ie, int ie_len, bool use_mfp,
423                         struct cfg80211_crypto_settings *crypt,
424                         u32 assoc_flags, struct ieee80211_ht_cap *ht_capa,
425                         struct ieee80211_ht_cap *ht_capa_mask)
426 {
427         struct wireless_dev *wdev = dev->ieee80211_ptr;
428         int err;
429
430         mutex_lock(&rdev->devlist_mtx);
431         wdev_lock(wdev);
432         err = __cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid,
433                                     ssid, ssid_len, ie, ie_len, use_mfp, crypt,
434                                     assoc_flags, ht_capa, ht_capa_mask);
435         wdev_unlock(wdev);
436         mutex_unlock(&rdev->devlist_mtx);
437
438         return err;
439 }
440
441 int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
442                            struct net_device *dev, const u8 *bssid,
443                            const u8 *ie, int ie_len, u16 reason,
444                            bool local_state_change)
445 {
446         struct wireless_dev *wdev = dev->ieee80211_ptr;
447         struct cfg80211_deauth_request req = {
448                 .bssid = bssid,
449                 .reason_code = reason,
450                 .ie = ie,
451                 .ie_len = ie_len,
452                 .local_state_change = local_state_change,
453         };
454
455         ASSERT_WDEV_LOCK(wdev);
456
457         if (local_state_change && (!wdev->current_bss ||
458             !ether_addr_equal(wdev->current_bss->pub.bssid, bssid)))
459                 return 0;
460
461         return rdev_deauth(rdev, dev, &req);
462 }
463
464 int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
465                          struct net_device *dev, const u8 *bssid,
466                          const u8 *ie, int ie_len, u16 reason,
467                          bool local_state_change)
468 {
469         struct wireless_dev *wdev = dev->ieee80211_ptr;
470         int err;
471
472         wdev_lock(wdev);
473         err = __cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason,
474                                      local_state_change);
475         wdev_unlock(wdev);
476
477         return err;
478 }
479
480 static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
481                                     struct net_device *dev, const u8 *bssid,
482                                     const u8 *ie, int ie_len, u16 reason,
483                                     bool local_state_change)
484 {
485         struct wireless_dev *wdev = dev->ieee80211_ptr;
486         struct cfg80211_disassoc_request req;
487
488         ASSERT_WDEV_LOCK(wdev);
489
490         if (wdev->sme_state != CFG80211_SME_CONNECTED)
491                 return -ENOTCONN;
492
493         if (WARN(!wdev->current_bss, "sme_state=%d\n", wdev->sme_state))
494                 return -ENOTCONN;
495
496         memset(&req, 0, sizeof(req));
497         req.reason_code = reason;
498         req.local_state_change = local_state_change;
499         req.ie = ie;
500         req.ie_len = ie_len;
501         if (ether_addr_equal(wdev->current_bss->pub.bssid, bssid))
502                 req.bss = &wdev->current_bss->pub;
503         else
504                 return -ENOTCONN;
505
506         return rdev_disassoc(rdev, dev, &req);
507 }
508
509 int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
510                            struct net_device *dev, const u8 *bssid,
511                            const u8 *ie, int ie_len, u16 reason,
512                            bool local_state_change)
513 {
514         struct wireless_dev *wdev = dev->ieee80211_ptr;
515         int err;
516
517         wdev_lock(wdev);
518         err = __cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason,
519                                        local_state_change);
520         wdev_unlock(wdev);
521
522         return err;
523 }
524
525 void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
526                         struct net_device *dev)
527 {
528         struct wireless_dev *wdev = dev->ieee80211_ptr;
529         struct cfg80211_deauth_request req;
530         u8 bssid[ETH_ALEN];
531
532         ASSERT_WDEV_LOCK(wdev);
533
534         if (!rdev->ops->deauth)
535                 return;
536
537         memset(&req, 0, sizeof(req));
538         req.reason_code = WLAN_REASON_DEAUTH_LEAVING;
539         req.ie = NULL;
540         req.ie_len = 0;
541
542         if (!wdev->current_bss)
543                 return;
544
545         memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN);
546         req.bssid = bssid;
547         rdev_deauth(rdev, dev, &req);
548
549         if (wdev->current_bss) {
550                 cfg80211_unhold_bss(wdev->current_bss);
551                 cfg80211_put_bss(&rdev->wiphy, &wdev->current_bss->pub);
552                 wdev->current_bss = NULL;
553         }
554 }
555
556 struct cfg80211_mgmt_registration {
557         struct list_head list;
558
559         u32 nlportid;
560
561         int match_len;
562
563         __le16 frame_type;
564
565         u8 match[];
566 };
567
568 int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid,
569                                 u16 frame_type, const u8 *match_data,
570                                 int match_len)
571 {
572         struct wiphy *wiphy = wdev->wiphy;
573         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
574         struct cfg80211_mgmt_registration *reg, *nreg;
575         int err = 0;
576         u16 mgmt_type;
577
578         if (!wdev->wiphy->mgmt_stypes)
579                 return -EOPNOTSUPP;
580
581         if ((frame_type & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT)
582                 return -EINVAL;
583
584         if (frame_type & ~(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE))
585                 return -EINVAL;
586
587         mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
588         if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].rx & BIT(mgmt_type)))
589                 return -EINVAL;
590
591         nreg = kzalloc(sizeof(*reg) + match_len, GFP_KERNEL);
592         if (!nreg)
593                 return -ENOMEM;
594
595         spin_lock_bh(&wdev->mgmt_registrations_lock);
596
597         list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
598                 int mlen = min(match_len, reg->match_len);
599
600                 if (frame_type != le16_to_cpu(reg->frame_type))
601                         continue;
602
603                 if (memcmp(reg->match, match_data, mlen) == 0) {
604                         err = -EALREADY;
605                         break;
606                 }
607         }
608
609         if (err) {
610                 kfree(nreg);
611                 goto out;
612         }
613
614         memcpy(nreg->match, match_data, match_len);
615         nreg->match_len = match_len;
616         nreg->nlportid = snd_portid;
617         nreg->frame_type = cpu_to_le16(frame_type);
618         list_add(&nreg->list, &wdev->mgmt_registrations);
619
620         if (rdev->ops->mgmt_frame_register)
621                 rdev_mgmt_frame_register(rdev, wdev, frame_type, true);
622
623  out:
624         spin_unlock_bh(&wdev->mgmt_registrations_lock);
625
626         return err;
627 }
628
629 void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlportid)
630 {
631         struct wiphy *wiphy = wdev->wiphy;
632         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
633         struct cfg80211_mgmt_registration *reg, *tmp;
634
635         spin_lock_bh(&wdev->mgmt_registrations_lock);
636
637         list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
638                 if (reg->nlportid != nlportid)
639                         continue;
640
641                 if (rdev->ops->mgmt_frame_register) {
642                         u16 frame_type = le16_to_cpu(reg->frame_type);
643
644                         rdev_mgmt_frame_register(rdev, wdev,
645                                                  frame_type, false);
646                 }
647
648                 list_del(&reg->list);
649                 kfree(reg);
650         }
651
652         spin_unlock_bh(&wdev->mgmt_registrations_lock);
653
654         if (nlportid == wdev->ap_unexpected_nlportid)
655                 wdev->ap_unexpected_nlportid = 0;
656 }
657
658 void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
659 {
660         struct cfg80211_mgmt_registration *reg, *tmp;
661
662         spin_lock_bh(&wdev->mgmt_registrations_lock);
663
664         list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
665                 list_del(&reg->list);
666                 kfree(reg);
667         }
668
669         spin_unlock_bh(&wdev->mgmt_registrations_lock);
670 }
671
672 int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
673                           struct wireless_dev *wdev,
674                           struct ieee80211_channel *chan, bool offchan,
675                           unsigned int wait, const u8 *buf, size_t len,
676                           bool no_cck, bool dont_wait_for_ack, u64 *cookie)
677 {
678         const struct ieee80211_mgmt *mgmt;
679         u16 stype;
680
681         if (!wdev->wiphy->mgmt_stypes)
682                 return -EOPNOTSUPP;
683
684         if (!rdev->ops->mgmt_tx)
685                 return -EOPNOTSUPP;
686
687         if (len < 24 + 1)
688                 return -EINVAL;
689
690         mgmt = (const struct ieee80211_mgmt *) buf;
691
692         if (!ieee80211_is_mgmt(mgmt->frame_control))
693                 return -EINVAL;
694
695         stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
696         if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].tx & BIT(stype >> 4)))
697                 return -EINVAL;
698
699         if (ieee80211_is_action(mgmt->frame_control) &&
700             mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) {
701                 int err = 0;
702
703                 wdev_lock(wdev);
704
705                 switch (wdev->iftype) {
706                 case NL80211_IFTYPE_ADHOC:
707                 case NL80211_IFTYPE_STATION:
708                 case NL80211_IFTYPE_P2P_CLIENT:
709                         if (!wdev->current_bss) {
710                                 err = -ENOTCONN;
711                                 break;
712                         }
713
714                         if (!ether_addr_equal(wdev->current_bss->pub.bssid,
715                                               mgmt->bssid)) {
716                                 err = -ENOTCONN;
717                                 break;
718                         }
719
720                         /*
721                          * check for IBSS DA must be done by driver as
722                          * cfg80211 doesn't track the stations
723                          */
724                         if (wdev->iftype == NL80211_IFTYPE_ADHOC)
725                                 break;
726
727                         /* for station, check that DA is the AP */
728                         if (!ether_addr_equal(wdev->current_bss->pub.bssid,
729                                               mgmt->da)) {
730                                 err = -ENOTCONN;
731                                 break;
732                         }
733                         break;
734                 case NL80211_IFTYPE_AP:
735                 case NL80211_IFTYPE_P2P_GO:
736                 case NL80211_IFTYPE_AP_VLAN:
737                         if (!ether_addr_equal(mgmt->bssid, wdev_address(wdev)))
738                                 err = -EINVAL;
739                         break;
740                 case NL80211_IFTYPE_MESH_POINT:
741                         if (!ether_addr_equal(mgmt->sa, mgmt->bssid)) {
742                                 err = -EINVAL;
743                                 break;
744                         }
745                         /*
746                          * check for mesh DA must be done by driver as
747                          * cfg80211 doesn't track the stations
748                          */
749                         break;
750                 case NL80211_IFTYPE_P2P_DEVICE:
751                         /*
752                          * fall through, P2P device only supports
753                          * public action frames
754                          */
755                 default:
756                         err = -EOPNOTSUPP;
757                         break;
758                 }
759                 wdev_unlock(wdev);
760
761                 if (err)
762                         return err;
763         }
764
765         if (!ether_addr_equal(mgmt->sa, wdev_address(wdev)))
766                 return -EINVAL;
767
768         /* Transmit the Action frame as requested by user space */
769         return rdev_mgmt_tx(rdev, wdev, chan, offchan,
770                             wait, buf, len, no_cck, dont_wait_for_ack,
771                             cookie);
772 }
773
774 bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm,
775                       const u8 *buf, size_t len, gfp_t gfp)
776 {
777         struct wiphy *wiphy = wdev->wiphy;
778         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
779         struct cfg80211_mgmt_registration *reg;
780         const struct ieee80211_txrx_stypes *stypes =
781                 &wiphy->mgmt_stypes[wdev->iftype];
782         struct ieee80211_mgmt *mgmt = (void *)buf;
783         const u8 *data;
784         int data_len;
785         bool result = false;
786         __le16 ftype = mgmt->frame_control &
787                 cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE);
788         u16 stype;
789
790         trace_cfg80211_rx_mgmt(wdev, freq, sig_mbm);
791         stype = (le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) >> 4;
792
793         if (!(stypes->rx & BIT(stype))) {
794                 trace_cfg80211_return_bool(false);
795                 return false;
796         }
797
798         data = buf + ieee80211_hdrlen(mgmt->frame_control);
799         data_len = len - ieee80211_hdrlen(mgmt->frame_control);
800
801         spin_lock_bh(&wdev->mgmt_registrations_lock);
802
803         list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
804                 if (reg->frame_type != ftype)
805                         continue;
806
807                 if (reg->match_len > data_len)
808                         continue;
809
810                 if (memcmp(reg->match, data, reg->match_len))
811                         continue;
812
813                 /* found match! */
814
815                 /* Indicate the received Action frame to user space */
816                 if (nl80211_send_mgmt(rdev, wdev, reg->nlportid,
817                                       freq, sig_mbm,
818                                       buf, len, gfp))
819                         continue;
820
821                 result = true;
822                 break;
823         }
824
825         spin_unlock_bh(&wdev->mgmt_registrations_lock);
826
827         trace_cfg80211_return_bool(result);
828         return result;
829 }
830 EXPORT_SYMBOL(cfg80211_rx_mgmt);
831
832 void cfg80211_dfs_channels_update_work(struct work_struct *work)
833 {
834         struct delayed_work *delayed_work;
835         struct cfg80211_registered_device *rdev;
836         struct cfg80211_chan_def chandef;
837         struct ieee80211_supported_band *sband;
838         struct ieee80211_channel *c;
839         struct wiphy *wiphy;
840         bool check_again = false;
841         unsigned long timeout, next_time = 0;
842         int bandid, i;
843
844         delayed_work = container_of(work, struct delayed_work, work);
845         rdev = container_of(delayed_work, struct cfg80211_registered_device,
846                             dfs_update_channels_wk);
847         wiphy = &rdev->wiphy;
848
849         mutex_lock(&cfg80211_mutex);
850         for (bandid = 0; bandid < IEEE80211_NUM_BANDS; bandid++) {
851                 sband = wiphy->bands[bandid];
852                 if (!sband)
853                         continue;
854
855                 for (i = 0; i < sband->n_channels; i++) {
856                         c = &sband->channels[i];
857
858                         if (c->dfs_state != NL80211_DFS_UNAVAILABLE)
859                                 continue;
860
861                         timeout = c->dfs_state_entered +
862                                   IEEE80211_DFS_MIN_NOP_TIME_MS;
863
864                         if (time_after_eq(jiffies, timeout)) {
865                                 c->dfs_state = NL80211_DFS_USABLE;
866                                 cfg80211_chandef_create(&chandef, c,
867                                                         NL80211_CHAN_NO_HT);
868
869                                 nl80211_radar_notify(rdev, &chandef,
870                                                      NL80211_RADAR_NOP_FINISHED,
871                                                      NULL, GFP_ATOMIC);
872                                 continue;
873                         }
874
875                         if (!check_again)
876                                 next_time = timeout - jiffies;
877                         else
878                                 next_time = min(next_time, timeout - jiffies);
879                         check_again = true;
880                 }
881         }
882         mutex_unlock(&cfg80211_mutex);
883
884         /* reschedule if there are other channels waiting to be cleared again */
885         if (check_again)
886                 queue_delayed_work(cfg80211_wq, &rdev->dfs_update_channels_wk,
887                                    next_time);
888 }
889
890
891 void cfg80211_radar_event(struct wiphy *wiphy,
892                           struct cfg80211_chan_def *chandef,
893                           gfp_t gfp)
894 {
895         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
896         unsigned long timeout;
897
898         trace_cfg80211_radar_event(wiphy, chandef);
899
900         /* only set the chandef supplied channel to unavailable, in
901          * case the radar is detected on only one of multiple channels
902          * spanned by the chandef.
903          */
904         cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_UNAVAILABLE);
905
906         timeout = msecs_to_jiffies(IEEE80211_DFS_MIN_NOP_TIME_MS);
907         queue_delayed_work(cfg80211_wq, &rdev->dfs_update_channels_wk,
908                            timeout);
909
910         nl80211_radar_notify(rdev, chandef, NL80211_RADAR_DETECTED, NULL, gfp);
911 }
912 EXPORT_SYMBOL(cfg80211_radar_event);
913
914 void cfg80211_cac_event(struct net_device *netdev,
915                         enum nl80211_radar_event event, gfp_t gfp)
916 {
917         struct wireless_dev *wdev = netdev->ieee80211_ptr;
918         struct wiphy *wiphy = wdev->wiphy;
919         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
920         struct cfg80211_chan_def chandef;
921         unsigned long timeout;
922
923         trace_cfg80211_cac_event(netdev, event);
924
925         if (WARN_ON(!wdev->cac_started))
926                 return;
927
928         if (WARN_ON(!wdev->channel))
929                 return;
930
931         cfg80211_chandef_create(&chandef, wdev->channel, NL80211_CHAN_NO_HT);
932
933         switch (event) {
934         case NL80211_RADAR_CAC_FINISHED:
935                 timeout = wdev->cac_start_time +
936                           msecs_to_jiffies(IEEE80211_DFS_MIN_CAC_TIME_MS);
937                 WARN_ON(!time_after_eq(jiffies, timeout));
938                 cfg80211_set_dfs_state(wiphy, &chandef, NL80211_DFS_AVAILABLE);
939                 break;
940         case NL80211_RADAR_CAC_ABORTED:
941                 break;
942         default:
943                 WARN_ON(1);
944                 return;
945         }
946         wdev->cac_started = false;
947
948         nl80211_radar_notify(rdev, &chandef, event, netdev, gfp);
949 }
950 EXPORT_SYMBOL(cfg80211_cac_event);