1 // SPDX-License-Identifier: GPL-2.0
3 * cfg80211 MLME SAP interface
5 * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
6 * Copyright (c) 2015 Intel Deutschland GmbH
7 * Copyright (C) 2019-2020 Intel Corporation
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/etherdevice.h>
13 #include <linux/netdevice.h>
14 #include <linux/nl80211.h>
15 #include <linux/slab.h>
16 #include <linux/wireless.h>
17 #include <net/cfg80211.h>
18 #include <net/iw_handler.h>
24 void cfg80211_rx_assoc_resp(struct net_device
*dev
, struct cfg80211_bss
*bss
,
25 const u8
*buf
, size_t len
, int uapsd_queues
,
26 const u8
*req_ies
, size_t req_ies_len
)
28 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
29 struct wiphy
*wiphy
= wdev
->wiphy
;
30 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
31 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
32 struct cfg80211_connect_resp_params cr
;
33 const u8
*resp_ie
= mgmt
->u
.assoc_resp
.variable
;
34 size_t resp_ie_len
= len
- offsetof(struct ieee80211_mgmt
,
35 u
.assoc_resp
.variable
);
37 if (bss
->channel
->band
== NL80211_BAND_S1GHZ
) {
38 resp_ie
= (u8
*)&mgmt
->u
.s1g_assoc_resp
.variable
;
39 resp_ie_len
= len
- offsetof(struct ieee80211_mgmt
,
40 u
.s1g_assoc_resp
.variable
);
43 memset(&cr
, 0, sizeof(cr
));
44 cr
.status
= (int)le16_to_cpu(mgmt
->u
.assoc_resp
.status_code
);
45 cr
.bssid
= mgmt
->bssid
;
48 cr
.req_ie_len
= req_ies_len
;
50 cr
.resp_ie_len
= resp_ie_len
;
51 cr
.timeout_reason
= NL80211_TIMEOUT_UNSPECIFIED
;
53 trace_cfg80211_send_rx_assoc(dev
, bss
);
56 * This is a bit of a hack, we don't notify userspace of
57 * a (re-)association reply if we tried to send a reassoc
58 * and got a reject -- we only try again with an assoc
59 * frame instead of reassoc.
61 if (cfg80211_sme_rx_assoc_resp(wdev
, cr
.status
)) {
62 cfg80211_unhold_bss(bss_from_pub(bss
));
63 cfg80211_put_bss(wiphy
, bss
);
67 nl80211_send_rx_assoc(rdev
, dev
, buf
, len
, GFP_KERNEL
, uapsd_queues
,
68 req_ies
, req_ies_len
);
69 /* update current_bss etc., consumes the bss reference */
70 __cfg80211_connect_result(dev
, &cr
, cr
.status
== WLAN_STATUS_SUCCESS
);
72 EXPORT_SYMBOL(cfg80211_rx_assoc_resp
);
74 static void cfg80211_process_auth(struct wireless_dev
*wdev
,
75 const u8
*buf
, size_t len
)
77 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
79 nl80211_send_rx_auth(rdev
, wdev
->netdev
, buf
, len
, GFP_KERNEL
);
80 cfg80211_sme_rx_auth(wdev
, buf
, len
);
83 static void cfg80211_process_deauth(struct wireless_dev
*wdev
,
84 const u8
*buf
, size_t len
,
87 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
88 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
89 const u8
*bssid
= mgmt
->bssid
;
90 u16 reason_code
= le16_to_cpu(mgmt
->u
.deauth
.reason_code
);
91 bool from_ap
= !ether_addr_equal(mgmt
->sa
, wdev
->netdev
->dev_addr
);
93 nl80211_send_deauth(rdev
, wdev
->netdev
, buf
, len
, reconnect
, GFP_KERNEL
);
95 if (!wdev
->current_bss
||
96 !ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
))
99 __cfg80211_disconnected(wdev
->netdev
, NULL
, 0, reason_code
, from_ap
);
100 cfg80211_sme_deauth(wdev
);
103 static void cfg80211_process_disassoc(struct wireless_dev
*wdev
,
104 const u8
*buf
, size_t len
,
107 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
108 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*)buf
;
109 const u8
*bssid
= mgmt
->bssid
;
110 u16 reason_code
= le16_to_cpu(mgmt
->u
.disassoc
.reason_code
);
111 bool from_ap
= !ether_addr_equal(mgmt
->sa
, wdev
->netdev
->dev_addr
);
113 nl80211_send_disassoc(rdev
, wdev
->netdev
, buf
, len
, reconnect
,
116 if (WARN_ON(!wdev
->current_bss
||
117 !ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
)))
120 __cfg80211_disconnected(wdev
->netdev
, NULL
, 0, reason_code
, from_ap
);
121 cfg80211_sme_disassoc(wdev
);
124 void cfg80211_rx_mlme_mgmt(struct net_device
*dev
, const u8
*buf
, size_t len
)
126 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
127 struct ieee80211_mgmt
*mgmt
= (void *)buf
;
129 ASSERT_WDEV_LOCK(wdev
);
131 trace_cfg80211_rx_mlme_mgmt(dev
, buf
, len
);
133 if (WARN_ON(len
< 2))
136 if (ieee80211_is_auth(mgmt
->frame_control
))
137 cfg80211_process_auth(wdev
, buf
, len
);
138 else if (ieee80211_is_deauth(mgmt
->frame_control
))
139 cfg80211_process_deauth(wdev
, buf
, len
, false);
140 else if (ieee80211_is_disassoc(mgmt
->frame_control
))
141 cfg80211_process_disassoc(wdev
, buf
, len
, false);
143 EXPORT_SYMBOL(cfg80211_rx_mlme_mgmt
);
145 void cfg80211_auth_timeout(struct net_device
*dev
, const u8
*addr
)
147 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
148 struct wiphy
*wiphy
= wdev
->wiphy
;
149 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
151 trace_cfg80211_send_auth_timeout(dev
, addr
);
153 nl80211_send_auth_timeout(rdev
, dev
, addr
, GFP_KERNEL
);
154 cfg80211_sme_auth_timeout(wdev
);
156 EXPORT_SYMBOL(cfg80211_auth_timeout
);
158 void cfg80211_assoc_timeout(struct net_device
*dev
, struct cfg80211_bss
*bss
)
160 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
161 struct wiphy
*wiphy
= wdev
->wiphy
;
162 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
164 trace_cfg80211_send_assoc_timeout(dev
, bss
->bssid
);
166 nl80211_send_assoc_timeout(rdev
, dev
, bss
->bssid
, GFP_KERNEL
);
167 cfg80211_sme_assoc_timeout(wdev
);
169 cfg80211_unhold_bss(bss_from_pub(bss
));
170 cfg80211_put_bss(wiphy
, bss
);
172 EXPORT_SYMBOL(cfg80211_assoc_timeout
);
174 void cfg80211_abandon_assoc(struct net_device
*dev
, struct cfg80211_bss
*bss
)
176 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
177 struct wiphy
*wiphy
= wdev
->wiphy
;
179 cfg80211_sme_abandon_assoc(wdev
);
181 cfg80211_unhold_bss(bss_from_pub(bss
));
182 cfg80211_put_bss(wiphy
, bss
);
184 EXPORT_SYMBOL(cfg80211_abandon_assoc
);
186 void cfg80211_tx_mlme_mgmt(struct net_device
*dev
, const u8
*buf
, size_t len
,
189 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
190 struct ieee80211_mgmt
*mgmt
= (void *)buf
;
192 ASSERT_WDEV_LOCK(wdev
);
194 trace_cfg80211_tx_mlme_mgmt(dev
, buf
, len
, reconnect
);
196 if (WARN_ON(len
< 2))
199 if (ieee80211_is_deauth(mgmt
->frame_control
))
200 cfg80211_process_deauth(wdev
, buf
, len
, reconnect
);
202 cfg80211_process_disassoc(wdev
, buf
, len
, reconnect
);
204 EXPORT_SYMBOL(cfg80211_tx_mlme_mgmt
);
206 void cfg80211_michael_mic_failure(struct net_device
*dev
, const u8
*addr
,
207 enum nl80211_key_type key_type
, int key_id
,
208 const u8
*tsc
, gfp_t gfp
)
210 struct wiphy
*wiphy
= dev
->ieee80211_ptr
->wiphy
;
211 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
212 #ifdef CONFIG_CFG80211_WEXT
213 union iwreq_data wrqu
;
214 char *buf
= kmalloc(128, gfp
);
217 sprintf(buf
, "MLME-MICHAELMICFAILURE.indication("
218 "keyid=%d %scast addr=%pM)", key_id
,
219 key_type
== NL80211_KEYTYPE_GROUP
? "broad" : "uni",
221 memset(&wrqu
, 0, sizeof(wrqu
));
222 wrqu
.data
.length
= strlen(buf
);
223 wireless_send_event(dev
, IWEVCUSTOM
, &wrqu
, buf
);
228 trace_cfg80211_michael_mic_failure(dev
, addr
, key_type
, key_id
, tsc
);
229 nl80211_michael_mic_failure(rdev
, dev
, addr
, key_type
, key_id
, tsc
, gfp
);
231 EXPORT_SYMBOL(cfg80211_michael_mic_failure
);
233 /* some MLME handling for userspace SME */
234 int cfg80211_mlme_auth(struct cfg80211_registered_device
*rdev
,
235 struct net_device
*dev
,
236 struct ieee80211_channel
*chan
,
237 enum nl80211_auth_type auth_type
,
239 const u8
*ssid
, int ssid_len
,
240 const u8
*ie
, int ie_len
,
241 const u8
*key
, int key_len
, int key_idx
,
242 const u8
*auth_data
, int auth_data_len
)
244 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
245 struct cfg80211_auth_request req
= {
248 .auth_data
= auth_data
,
249 .auth_data_len
= auth_data_len
,
250 .auth_type
= auth_type
,
257 ASSERT_WDEV_LOCK(wdev
);
259 if (auth_type
== NL80211_AUTHTYPE_SHARED_KEY
)
260 if (!key
|| !key_len
|| key_idx
< 0 || key_idx
> 3)
263 if (wdev
->current_bss
&&
264 ether_addr_equal(bssid
, wdev
->current_bss
->pub
.bssid
))
267 req
.bss
= cfg80211_get_bss(&rdev
->wiphy
, chan
, bssid
, ssid
, ssid_len
,
268 IEEE80211_BSS_TYPE_ESS
,
269 IEEE80211_PRIVACY_ANY
);
273 err
= rdev_auth(rdev
, dev
, &req
);
275 cfg80211_put_bss(&rdev
->wiphy
, req
.bss
);
279 /* Do a logical ht_capa &= ht_capa_mask. */
280 void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap
*ht_capa
,
281 const struct ieee80211_ht_cap
*ht_capa_mask
)
286 memset(ht_capa
, 0, sizeof(*ht_capa
));
291 p2
= (u8
*)(ht_capa_mask
);
292 for (i
= 0; i
< sizeof(*ht_capa
); i
++)
296 /* Do a logical vht_capa &= vht_capa_mask. */
297 void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap
*vht_capa
,
298 const struct ieee80211_vht_cap
*vht_capa_mask
)
302 if (!vht_capa_mask
) {
303 memset(vht_capa
, 0, sizeof(*vht_capa
));
307 p1
= (u8
*)(vht_capa
);
308 p2
= (u8
*)(vht_capa_mask
);
309 for (i
= 0; i
< sizeof(*vht_capa
); i
++)
313 int cfg80211_mlme_assoc(struct cfg80211_registered_device
*rdev
,
314 struct net_device
*dev
,
315 struct ieee80211_channel
*chan
,
317 const u8
*ssid
, int ssid_len
,
318 struct cfg80211_assoc_request
*req
)
320 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
323 ASSERT_WDEV_LOCK(wdev
);
325 if (wdev
->current_bss
&&
326 (!req
->prev_bssid
|| !ether_addr_equal(wdev
->current_bss
->pub
.bssid
,
330 cfg80211_oper_and_ht_capa(&req
->ht_capa_mask
,
331 rdev
->wiphy
.ht_capa_mod_mask
);
332 cfg80211_oper_and_vht_capa(&req
->vht_capa_mask
,
333 rdev
->wiphy
.vht_capa_mod_mask
);
335 req
->bss
= cfg80211_get_bss(&rdev
->wiphy
, chan
, bssid
, ssid
, ssid_len
,
336 IEEE80211_BSS_TYPE_ESS
,
337 IEEE80211_PRIVACY_ANY
);
341 err
= rdev_assoc(rdev
, dev
, req
);
343 cfg80211_hold_bss(bss_from_pub(req
->bss
));
345 cfg80211_put_bss(&rdev
->wiphy
, req
->bss
);
350 int cfg80211_mlme_deauth(struct cfg80211_registered_device
*rdev
,
351 struct net_device
*dev
, const u8
*bssid
,
352 const u8
*ie
, int ie_len
, u16 reason
,
353 bool local_state_change
)
355 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
356 struct cfg80211_deauth_request req
= {
358 .reason_code
= reason
,
361 .local_state_change
= local_state_change
,
364 ASSERT_WDEV_LOCK(wdev
);
366 if (local_state_change
&&
367 (!wdev
->current_bss
||
368 !ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
)))
371 if (ether_addr_equal(wdev
->disconnect_bssid
, bssid
) ||
372 (wdev
->current_bss
&&
373 ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
)))
374 wdev
->conn_owner_nlportid
= 0;
376 return rdev_deauth(rdev
, dev
, &req
);
379 int cfg80211_mlme_disassoc(struct cfg80211_registered_device
*rdev
,
380 struct net_device
*dev
, const u8
*bssid
,
381 const u8
*ie
, int ie_len
, u16 reason
,
382 bool local_state_change
)
384 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
385 struct cfg80211_disassoc_request req
= {
386 .reason_code
= reason
,
387 .local_state_change
= local_state_change
,
393 ASSERT_WDEV_LOCK(wdev
);
395 if (!wdev
->current_bss
)
398 if (ether_addr_equal(wdev
->current_bss
->pub
.bssid
, bssid
))
399 req
.bss
= &wdev
->current_bss
->pub
;
403 err
= rdev_disassoc(rdev
, dev
, &req
);
407 /* driver should have reported the disassoc */
408 WARN_ON(wdev
->current_bss
);
412 void cfg80211_mlme_down(struct cfg80211_registered_device
*rdev
,
413 struct net_device
*dev
)
415 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
418 ASSERT_WDEV_LOCK(wdev
);
420 if (!rdev
->ops
->deauth
)
423 if (!wdev
->current_bss
)
426 memcpy(bssid
, wdev
->current_bss
->pub
.bssid
, ETH_ALEN
);
427 cfg80211_mlme_deauth(rdev
, dev
, bssid
, NULL
, 0,
428 WLAN_REASON_DEAUTH_LEAVING
, false);
431 struct cfg80211_mgmt_registration
{
432 struct list_head list
;
433 struct wireless_dev
*wdev
;
446 static void cfg80211_mgmt_registrations_update(struct wireless_dev
*wdev
)
448 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wdev
->wiphy
);
449 struct wireless_dev
*tmp
;
450 struct cfg80211_mgmt_registration
*reg
;
451 struct mgmt_frame_regs upd
= {};
453 lockdep_assert_held(&rdev
->wiphy
.mtx
);
455 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
456 if (!wdev
->mgmt_registrations_need_update
) {
457 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
462 list_for_each_entry_rcu(tmp
, &rdev
->wiphy
.wdev_list
, list
) {
463 list_for_each_entry(reg
, &tmp
->mgmt_registrations
, list
) {
464 u32 mask
= BIT(le16_to_cpu(reg
->frame_type
) >> 4);
467 if (reg
->multicast_rx
)
470 upd
.global_stypes
|= mask
;
471 upd
.global_mcast_stypes
|= mcast_mask
;
474 upd
.interface_stypes
|= mask
;
475 upd
.interface_mcast_stypes
|= mcast_mask
;
481 wdev
->mgmt_registrations_need_update
= 0;
482 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
484 rdev_update_mgmt_frame_registrations(rdev
, wdev
, &upd
);
487 void cfg80211_mgmt_registrations_update_wk(struct work_struct
*wk
)
489 struct cfg80211_registered_device
*rdev
;
490 struct wireless_dev
*wdev
;
492 rdev
= container_of(wk
, struct cfg80211_registered_device
,
493 mgmt_registrations_update_wk
);
495 wiphy_lock(&rdev
->wiphy
);
496 list_for_each_entry(wdev
, &rdev
->wiphy
.wdev_list
, list
)
497 cfg80211_mgmt_registrations_update(wdev
);
498 wiphy_unlock(&rdev
->wiphy
);
501 int cfg80211_mlme_register_mgmt(struct wireless_dev
*wdev
, u32 snd_portid
,
502 u16 frame_type
, const u8
*match_data
,
503 int match_len
, bool multicast_rx
,
504 struct netlink_ext_ack
*extack
)
506 struct cfg80211_mgmt_registration
*reg
, *nreg
;
509 bool update_multicast
= false;
511 if (!wdev
->wiphy
->mgmt_stypes
)
514 if ((frame_type
& IEEE80211_FCTL_FTYPE
) != IEEE80211_FTYPE_MGMT
) {
515 NL_SET_ERR_MSG(extack
, "frame type not management");
519 if (frame_type
& ~(IEEE80211_FCTL_FTYPE
| IEEE80211_FCTL_STYPE
)) {
520 NL_SET_ERR_MSG(extack
, "Invalid frame type");
524 mgmt_type
= (frame_type
& IEEE80211_FCTL_STYPE
) >> 4;
525 if (!(wdev
->wiphy
->mgmt_stypes
[wdev
->iftype
].rx
& BIT(mgmt_type
))) {
526 NL_SET_ERR_MSG(extack
,
527 "Registration to specific type not supported");
532 * To support Pre Association Security Negotiation (PASN), registration
533 * for authentication frames should be supported. However, as some
534 * versions of the user space daemons wrongly register to all types of
535 * authentication frames (which might result in unexpected behavior)
536 * allow such registration if the request is for a specific
537 * authentication algorithm number.
539 if (wdev
->iftype
== NL80211_IFTYPE_STATION
&&
540 (frame_type
& IEEE80211_FCTL_STYPE
) == IEEE80211_STYPE_AUTH
&&
541 !(match_data
&& match_len
>= 2)) {
542 NL_SET_ERR_MSG(extack
,
543 "Authentication algorithm number required");
547 nreg
= kzalloc(sizeof(*reg
) + match_len
, GFP_KERNEL
);
551 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
553 list_for_each_entry(reg
, &wdev
->mgmt_registrations
, list
) {
554 int mlen
= min(match_len
, reg
->match_len
);
556 if (frame_type
!= le16_to_cpu(reg
->frame_type
))
559 if (memcmp(reg
->match
, match_data
, mlen
) == 0) {
560 if (reg
->multicast_rx
!= multicast_rx
) {
561 update_multicast
= true;
562 reg
->multicast_rx
= multicast_rx
;
565 NL_SET_ERR_MSG(extack
, "Match already configured");
574 if (update_multicast
) {
577 memcpy(nreg
->match
, match_data
, match_len
);
578 nreg
->match_len
= match_len
;
579 nreg
->nlportid
= snd_portid
;
580 nreg
->frame_type
= cpu_to_le16(frame_type
);
582 nreg
->multicast_rx
= multicast_rx
;
583 list_add(&nreg
->list
, &wdev
->mgmt_registrations
);
585 wdev
->mgmt_registrations_need_update
= 1;
586 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
588 cfg80211_mgmt_registrations_update(wdev
);
594 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
599 void cfg80211_mlme_unregister_socket(struct wireless_dev
*wdev
, u32 nlportid
)
601 struct wiphy
*wiphy
= wdev
->wiphy
;
602 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
603 struct cfg80211_mgmt_registration
*reg
, *tmp
;
605 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
607 list_for_each_entry_safe(reg
, tmp
, &wdev
->mgmt_registrations
, list
) {
608 if (reg
->nlportid
!= nlportid
)
611 list_del(®
->list
);
614 wdev
->mgmt_registrations_need_update
= 1;
615 schedule_work(&rdev
->mgmt_registrations_update_wk
);
618 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
620 if (nlportid
&& rdev
->crit_proto_nlportid
== nlportid
) {
621 rdev
->crit_proto_nlportid
= 0;
622 rdev_crit_proto_stop(rdev
, wdev
);
625 if (nlportid
== wdev
->ap_unexpected_nlportid
)
626 wdev
->ap_unexpected_nlportid
= 0;
629 void cfg80211_mlme_purge_registrations(struct wireless_dev
*wdev
)
631 struct cfg80211_mgmt_registration
*reg
, *tmp
;
633 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
634 list_for_each_entry_safe(reg
, tmp
, &wdev
->mgmt_registrations
, list
) {
635 list_del(®
->list
);
638 wdev
->mgmt_registrations_need_update
= 1;
639 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
641 cfg80211_mgmt_registrations_update(wdev
);
644 int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device
*rdev
,
645 struct wireless_dev
*wdev
,
646 struct cfg80211_mgmt_tx_params
*params
, u64
*cookie
)
648 const struct ieee80211_mgmt
*mgmt
;
651 if (!wdev
->wiphy
->mgmt_stypes
)
654 if (!rdev
->ops
->mgmt_tx
)
657 if (params
->len
< 24 + 1)
660 mgmt
= (const struct ieee80211_mgmt
*)params
->buf
;
662 if (!ieee80211_is_mgmt(mgmt
->frame_control
))
665 stype
= le16_to_cpu(mgmt
->frame_control
) & IEEE80211_FCTL_STYPE
;
666 if (!(wdev
->wiphy
->mgmt_stypes
[wdev
->iftype
].tx
& BIT(stype
>> 4)))
669 if (ieee80211_is_action(mgmt
->frame_control
) &&
670 mgmt
->u
.action
.category
!= WLAN_CATEGORY_PUBLIC
) {
675 switch (wdev
->iftype
) {
676 case NL80211_IFTYPE_ADHOC
:
677 case NL80211_IFTYPE_STATION
:
678 case NL80211_IFTYPE_P2P_CLIENT
:
679 if (!wdev
->current_bss
) {
684 if (!ether_addr_equal(wdev
->current_bss
->pub
.bssid
,
691 * check for IBSS DA must be done by driver as
692 * cfg80211 doesn't track the stations
694 if (wdev
->iftype
== NL80211_IFTYPE_ADHOC
)
697 /* for station, check that DA is the AP */
698 if (!ether_addr_equal(wdev
->current_bss
->pub
.bssid
,
704 case NL80211_IFTYPE_AP
:
705 case NL80211_IFTYPE_P2P_GO
:
706 case NL80211_IFTYPE_AP_VLAN
:
707 if (!ether_addr_equal(mgmt
->bssid
, wdev_address(wdev
)))
710 case NL80211_IFTYPE_MESH_POINT
:
711 if (!ether_addr_equal(mgmt
->sa
, mgmt
->bssid
)) {
716 * check for mesh DA must be done by driver as
717 * cfg80211 doesn't track the stations
720 case NL80211_IFTYPE_P2P_DEVICE
:
722 * fall through, P2P device only supports
723 * public action frames
725 case NL80211_IFTYPE_NAN
:
736 if (!ether_addr_equal(mgmt
->sa
, wdev_address(wdev
))) {
737 /* Allow random TA to be used with Public Action frames if the
738 * driver has indicated support for this. Otherwise, only allow
739 * the local address to be used.
741 if (!ieee80211_is_action(mgmt
->frame_control
) ||
742 mgmt
->u
.action
.category
!= WLAN_CATEGORY_PUBLIC
)
744 if (!wdev
->current_bss
&&
745 !wiphy_ext_feature_isset(
747 NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA
))
749 if (wdev
->current_bss
&&
750 !wiphy_ext_feature_isset(
752 NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED
))
756 /* Transmit the Action frame as requested by user space */
757 return rdev_mgmt_tx(rdev
, wdev
, params
, cookie
);
760 bool cfg80211_rx_mgmt_khz(struct wireless_dev
*wdev
, int freq
, int sig_dbm
,
761 const u8
*buf
, size_t len
, u32 flags
)
763 struct wiphy
*wiphy
= wdev
->wiphy
;
764 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
765 struct cfg80211_mgmt_registration
*reg
;
766 const struct ieee80211_txrx_stypes
*stypes
=
767 &wiphy
->mgmt_stypes
[wdev
->iftype
];
768 struct ieee80211_mgmt
*mgmt
= (void *)buf
;
772 __le16 ftype
= mgmt
->frame_control
&
773 cpu_to_le16(IEEE80211_FCTL_FTYPE
| IEEE80211_FCTL_STYPE
);
776 trace_cfg80211_rx_mgmt(wdev
, freq
, sig_dbm
);
777 stype
= (le16_to_cpu(mgmt
->frame_control
) & IEEE80211_FCTL_STYPE
) >> 4;
779 if (!(stypes
->rx
& BIT(stype
))) {
780 trace_cfg80211_return_bool(false);
784 data
= buf
+ ieee80211_hdrlen(mgmt
->frame_control
);
785 data_len
= len
- ieee80211_hdrlen(mgmt
->frame_control
);
787 spin_lock_bh(&wdev
->mgmt_registrations_lock
);
789 list_for_each_entry(reg
, &wdev
->mgmt_registrations
, list
) {
790 if (reg
->frame_type
!= ftype
)
793 if (reg
->match_len
> data_len
)
796 if (memcmp(reg
->match
, data
, reg
->match_len
))
801 /* Indicate the received Action frame to user space */
802 if (nl80211_send_mgmt(rdev
, wdev
, reg
->nlportid
,
804 buf
, len
, flags
, GFP_ATOMIC
))
811 spin_unlock_bh(&wdev
->mgmt_registrations_lock
);
813 trace_cfg80211_return_bool(result
);
816 EXPORT_SYMBOL(cfg80211_rx_mgmt_khz
);
818 void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device
*rdev
)
820 cancel_delayed_work(&rdev
->dfs_update_channels_wk
);
821 queue_delayed_work(cfg80211_wq
, &rdev
->dfs_update_channels_wk
, 0);
824 void cfg80211_dfs_channels_update_work(struct work_struct
*work
)
826 struct delayed_work
*delayed_work
= to_delayed_work(work
);
827 struct cfg80211_registered_device
*rdev
;
828 struct cfg80211_chan_def chandef
;
829 struct ieee80211_supported_band
*sband
;
830 struct ieee80211_channel
*c
;
832 bool check_again
= false;
833 unsigned long timeout
, next_time
= 0;
834 unsigned long time_dfs_update
;
835 enum nl80211_radar_event radar_event
;
838 rdev
= container_of(delayed_work
, struct cfg80211_registered_device
,
839 dfs_update_channels_wk
);
840 wiphy
= &rdev
->wiphy
;
843 for (bandid
= 0; bandid
< NUM_NL80211_BANDS
; bandid
++) {
844 sband
= wiphy
->bands
[bandid
];
848 for (i
= 0; i
< sband
->n_channels
; i
++) {
849 c
= &sband
->channels
[i
];
851 if (!(c
->flags
& IEEE80211_CHAN_RADAR
))
854 if (c
->dfs_state
!= NL80211_DFS_UNAVAILABLE
&&
855 c
->dfs_state
!= NL80211_DFS_AVAILABLE
)
858 if (c
->dfs_state
== NL80211_DFS_UNAVAILABLE
) {
859 time_dfs_update
= IEEE80211_DFS_MIN_NOP_TIME_MS
;
860 radar_event
= NL80211_RADAR_NOP_FINISHED
;
862 if (regulatory_pre_cac_allowed(wiphy
) ||
863 cfg80211_any_wiphy_oper_chan(wiphy
, c
))
866 time_dfs_update
= REG_PRE_CAC_EXPIRY_GRACE_MS
;
867 radar_event
= NL80211_RADAR_PRE_CAC_EXPIRED
;
870 timeout
= c
->dfs_state_entered
+
871 msecs_to_jiffies(time_dfs_update
);
873 if (time_after_eq(jiffies
, timeout
)) {
874 c
->dfs_state
= NL80211_DFS_USABLE
;
875 c
->dfs_state_entered
= jiffies
;
877 cfg80211_chandef_create(&chandef
, c
,
880 nl80211_radar_notify(rdev
, &chandef
,
884 regulatory_propagate_dfs_state(wiphy
, &chandef
,
891 next_time
= timeout
- jiffies
;
893 next_time
= min(next_time
, timeout
- jiffies
);
899 /* reschedule if there are other channels waiting to be cleared again */
901 queue_delayed_work(cfg80211_wq
, &rdev
->dfs_update_channels_wk
,
906 void cfg80211_radar_event(struct wiphy
*wiphy
,
907 struct cfg80211_chan_def
*chandef
,
910 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
912 trace_cfg80211_radar_event(wiphy
, chandef
);
914 /* only set the chandef supplied channel to unavailable, in
915 * case the radar is detected on only one of multiple channels
916 * spanned by the chandef.
918 cfg80211_set_dfs_state(wiphy
, chandef
, NL80211_DFS_UNAVAILABLE
);
920 cfg80211_sched_dfs_chan_update(rdev
);
922 nl80211_radar_notify(rdev
, chandef
, NL80211_RADAR_DETECTED
, NULL
, gfp
);
924 memcpy(&rdev
->radar_chandef
, chandef
, sizeof(struct cfg80211_chan_def
));
925 queue_work(cfg80211_wq
, &rdev
->propagate_radar_detect_wk
);
927 EXPORT_SYMBOL(cfg80211_radar_event
);
929 void cfg80211_cac_event(struct net_device
*netdev
,
930 const struct cfg80211_chan_def
*chandef
,
931 enum nl80211_radar_event event
, gfp_t gfp
)
933 struct wireless_dev
*wdev
= netdev
->ieee80211_ptr
;
934 struct wiphy
*wiphy
= wdev
->wiphy
;
935 struct cfg80211_registered_device
*rdev
= wiphy_to_rdev(wiphy
);
936 unsigned long timeout
;
938 trace_cfg80211_cac_event(netdev
, event
);
940 if (WARN_ON(!wdev
->cac_started
&& event
!= NL80211_RADAR_CAC_STARTED
))
943 if (WARN_ON(!wdev
->chandef
.chan
))
947 case NL80211_RADAR_CAC_FINISHED
:
948 timeout
= wdev
->cac_start_time
+
949 msecs_to_jiffies(wdev
->cac_time_ms
);
950 WARN_ON(!time_after_eq(jiffies
, timeout
));
951 cfg80211_set_dfs_state(wiphy
, chandef
, NL80211_DFS_AVAILABLE
);
952 memcpy(&rdev
->cac_done_chandef
, chandef
,
953 sizeof(struct cfg80211_chan_def
));
954 queue_work(cfg80211_wq
, &rdev
->propagate_cac_done_wk
);
955 cfg80211_sched_dfs_chan_update(rdev
);
957 case NL80211_RADAR_CAC_ABORTED
:
958 wdev
->cac_started
= false;
960 case NL80211_RADAR_CAC_STARTED
:
961 wdev
->cac_started
= true;
968 nl80211_radar_notify(rdev
, chandef
, event
, netdev
, gfp
);
970 EXPORT_SYMBOL(cfg80211_cac_event
);