Linux Audio

Check our new training course

Real-Time Linux with PREEMPT_RT training

Feb 18-20, 2025
Register
Loading...
v4.10.11
 
  1/*
  2 * cfg80211 MLME SAP interface
  3 *
  4 * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
  5 * Copyright (c) 2015		Intel Deutschland GmbH
 
  6 */
  7
  8#include <linux/kernel.h>
  9#include <linux/module.h>
 10#include <linux/etherdevice.h>
 11#include <linux/netdevice.h>
 12#include <linux/nl80211.h>
 13#include <linux/slab.h>
 14#include <linux/wireless.h>
 15#include <net/cfg80211.h>
 16#include <net/iw_handler.h>
 17#include "core.h"
 18#include "nl80211.h"
 19#include "rdev-ops.h"
 20
 21
 22void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss,
 23			    const u8 *buf, size_t len, int uapsd_queues)
 24{
 25	struct wireless_dev *wdev = dev->ieee80211_ptr;
 26	struct wiphy *wiphy = wdev->wiphy;
 27	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
 28	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
 29	u8 *ie = mgmt->u.assoc_resp.variable;
 30	int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
 31	u16 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 32
 33	trace_cfg80211_send_rx_assoc(dev, bss);
 34
 35	/*
 36	 * This is a bit of a hack, we don't notify userspace of
 37	 * a (re-)association reply if we tried to send a reassoc
 38	 * and got a reject -- we only try again with an assoc
 39	 * frame instead of reassoc.
 40	 */
 41	if (cfg80211_sme_rx_assoc_resp(wdev, status_code)) {
 42		cfg80211_unhold_bss(bss_from_pub(bss));
 43		cfg80211_put_bss(wiphy, bss);
 
 
 
 
 
 
 
 44		return;
 45	}
 46
 47	nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL, uapsd_queues);
 48	/* update current_bss etc., consumes the bss reference */
 49	__cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
 50				  status_code,
 51				  status_code == WLAN_STATUS_SUCCESS, bss);
 52}
 53EXPORT_SYMBOL(cfg80211_rx_assoc_resp);
 54
 55static void cfg80211_process_auth(struct wireless_dev *wdev,
 56				  const u8 *buf, size_t len)
 57{
 58	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
 59
 60	nl80211_send_rx_auth(rdev, wdev->netdev, buf, len, GFP_KERNEL);
 61	cfg80211_sme_rx_auth(wdev, buf, len);
 62}
 63
 64static void cfg80211_process_deauth(struct wireless_dev *wdev,
 65				    const u8 *buf, size_t len)
 
 66{
 67	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
 68	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
 69	const u8 *bssid = mgmt->bssid;
 70	u16 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
 71	bool from_ap = !ether_addr_equal(mgmt->sa, wdev->netdev->dev_addr);
 72
 73	nl80211_send_deauth(rdev, wdev->netdev, buf, len, GFP_KERNEL);
 74
 75	if (!wdev->current_bss ||
 76	    !ether_addr_equal(wdev->current_bss->pub.bssid, bssid))
 77		return;
 78
 79	__cfg80211_disconnected(wdev->netdev, NULL, 0, reason_code, from_ap);
 80	cfg80211_sme_deauth(wdev);
 81}
 82
 83static void cfg80211_process_disassoc(struct wireless_dev *wdev,
 84				      const u8 *buf, size_t len)
 
 85{
 86	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
 87	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
 88	const u8 *bssid = mgmt->bssid;
 89	u16 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
 90	bool from_ap = !ether_addr_equal(mgmt->sa, wdev->netdev->dev_addr);
 91
 92	nl80211_send_disassoc(rdev, wdev->netdev, buf, len, GFP_KERNEL);
 
 93
 94	if (WARN_ON(!wdev->current_bss ||
 95		    !ether_addr_equal(wdev->current_bss->pub.bssid, bssid)))
 96		return;
 97
 98	__cfg80211_disconnected(wdev->netdev, NULL, 0, reason_code, from_ap);
 99	cfg80211_sme_disassoc(wdev);
100}
101
102void cfg80211_rx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len)
103{
104	struct wireless_dev *wdev = dev->ieee80211_ptr;
105	struct ieee80211_mgmt *mgmt = (void *)buf;
106
107	ASSERT_WDEV_LOCK(wdev);
108
109	trace_cfg80211_rx_mlme_mgmt(dev, buf, len);
110
111	if (WARN_ON(len < 2))
112		return;
113
114	if (ieee80211_is_auth(mgmt->frame_control))
115		cfg80211_process_auth(wdev, buf, len);
116	else if (ieee80211_is_deauth(mgmt->frame_control))
117		cfg80211_process_deauth(wdev, buf, len);
118	else if (ieee80211_is_disassoc(mgmt->frame_control))
119		cfg80211_process_disassoc(wdev, buf, len);
120}
121EXPORT_SYMBOL(cfg80211_rx_mlme_mgmt);
122
123void cfg80211_auth_timeout(struct net_device *dev, const u8 *addr)
124{
125	struct wireless_dev *wdev = dev->ieee80211_ptr;
126	struct wiphy *wiphy = wdev->wiphy;
127	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
128
129	trace_cfg80211_send_auth_timeout(dev, addr);
130
131	nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL);
132	cfg80211_sme_auth_timeout(wdev);
133}
134EXPORT_SYMBOL(cfg80211_auth_timeout);
135
136void cfg80211_assoc_timeout(struct net_device *dev, struct cfg80211_bss *bss)
 
137{
138	struct wireless_dev *wdev = dev->ieee80211_ptr;
139	struct wiphy *wiphy = wdev->wiphy;
140	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
 
 
141
142	trace_cfg80211_send_assoc_timeout(dev, bss->bssid);
143
144	nl80211_send_assoc_timeout(rdev, dev, bss->bssid, GFP_KERNEL);
145	cfg80211_sme_assoc_timeout(wdev);
146
147	cfg80211_unhold_bss(bss_from_pub(bss));
148	cfg80211_put_bss(wiphy, bss);
149}
150EXPORT_SYMBOL(cfg80211_assoc_timeout);
 
 
151
152void cfg80211_abandon_assoc(struct net_device *dev, struct cfg80211_bss *bss)
153{
154	struct wireless_dev *wdev = dev->ieee80211_ptr;
155	struct wiphy *wiphy = wdev->wiphy;
156
157	cfg80211_sme_abandon_assoc(wdev);
 
158
159	cfg80211_unhold_bss(bss_from_pub(bss));
160	cfg80211_put_bss(wiphy, bss);
 
161}
162EXPORT_SYMBOL(cfg80211_abandon_assoc);
163
164void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len)
 
165{
166	struct wireless_dev *wdev = dev->ieee80211_ptr;
167	struct ieee80211_mgmt *mgmt = (void *)buf;
168
169	ASSERT_WDEV_LOCK(wdev);
170
171	trace_cfg80211_tx_mlme_mgmt(dev, buf, len);
172
173	if (WARN_ON(len < 2))
174		return;
175
176	if (ieee80211_is_deauth(mgmt->frame_control))
177		cfg80211_process_deauth(wdev, buf, len);
178	else
179		cfg80211_process_disassoc(wdev, buf, len);
180}
181EXPORT_SYMBOL(cfg80211_tx_mlme_mgmt);
182
183void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
184				  enum nl80211_key_type key_type, int key_id,
185				  const u8 *tsc, gfp_t gfp)
186{
187	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
188	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
189#ifdef CONFIG_CFG80211_WEXT
190	union iwreq_data wrqu;
191	char *buf = kmalloc(128, gfp);
192
193	if (buf) {
194		sprintf(buf, "MLME-MICHAELMICFAILURE.indication("
195			"keyid=%d %scast addr=%pM)", key_id,
196			key_type == NL80211_KEYTYPE_GROUP ? "broad" : "uni",
197			addr);
198		memset(&wrqu, 0, sizeof(wrqu));
199		wrqu.data.length = strlen(buf);
 
 
 
 
200		wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
201		kfree(buf);
202	}
203#endif
204
205	trace_cfg80211_michael_mic_failure(dev, addr, key_type, key_id, tsc);
206	nl80211_michael_mic_failure(rdev, dev, addr, key_type, key_id, tsc, gfp);
207}
208EXPORT_SYMBOL(cfg80211_michael_mic_failure);
209
210/* some MLME handling for userspace SME */
211int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
212		       struct net_device *dev,
213		       struct ieee80211_channel *chan,
214		       enum nl80211_auth_type auth_type,
215		       const u8 *bssid,
216		       const u8 *ssid, int ssid_len,
217		       const u8 *ie, int ie_len,
218		       const u8 *key, int key_len, int key_idx,
219		       const u8 *auth_data, int auth_data_len)
220{
221	struct wireless_dev *wdev = dev->ieee80211_ptr;
222	struct cfg80211_auth_request req = {
223		.ie = ie,
224		.ie_len = ie_len,
225		.auth_data = auth_data,
226		.auth_data_len = auth_data_len,
227		.auth_type = auth_type,
228		.key = key,
229		.key_len = key_len,
230		.key_idx = key_idx,
231	};
232	int err;
233
234	ASSERT_WDEV_LOCK(wdev);
 
 
 
 
 
 
 
235
236	if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
237		if (!key || !key_len || key_idx < 0 || key_idx > 3)
 
238			return -EINVAL;
 
239
240	if (wdev->current_bss &&
241	    ether_addr_equal(bssid, wdev->current_bss->pub.bssid))
242		return -EALREADY;
243
244	req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
245				   IEEE80211_BSS_TYPE_ESS,
246				   IEEE80211_PRIVACY_ANY);
247	if (!req.bss)
248		return -ENOENT;
249
250	err = rdev_auth(rdev, dev, &req);
251
252	cfg80211_put_bss(&rdev->wiphy, req.bss);
253	return err;
254}
255
256/*  Do a logical ht_capa &= ht_capa_mask.  */
257void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
258			       const struct ieee80211_ht_cap *ht_capa_mask)
259{
260	int i;
261	u8 *p1, *p2;
262	if (!ht_capa_mask) {
263		memset(ht_capa, 0, sizeof(*ht_capa));
264		return;
265	}
266
267	p1 = (u8*)(ht_capa);
268	p2 = (u8*)(ht_capa_mask);
269	for (i = 0; i<sizeof(*ht_capa); i++)
270		p1[i] &= p2[i];
271}
272
273/*  Do a logical ht_capa &= ht_capa_mask.  */
274void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa,
275				const struct ieee80211_vht_cap *vht_capa_mask)
276{
277	int i;
278	u8 *p1, *p2;
279	if (!vht_capa_mask) {
280		memset(vht_capa, 0, sizeof(*vht_capa));
281		return;
282	}
283
284	p1 = (u8*)(vht_capa);
285	p2 = (u8*)(vht_capa_mask);
286	for (i = 0; i < sizeof(*vht_capa); i++)
287		p1[i] &= p2[i];
288}
289
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
290int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
291			struct net_device *dev,
292			struct ieee80211_channel *chan,
293			const u8 *bssid,
294			const u8 *ssid, int ssid_len,
295			struct cfg80211_assoc_request *req)
296{
297	struct wireless_dev *wdev = dev->ieee80211_ptr;
298	int err;
299
300	ASSERT_WDEV_LOCK(wdev);
 
 
 
 
301
302	if (wdev->current_bss &&
303	    (!req->prev_bssid || !ether_addr_equal(wdev->current_bss->pub.bssid,
304						   req->prev_bssid)))
305		return -EALREADY;
306
 
 
 
 
 
307	cfg80211_oper_and_ht_capa(&req->ht_capa_mask,
308				  rdev->wiphy.ht_capa_mod_mask);
309	cfg80211_oper_and_vht_capa(&req->vht_capa_mask,
310				   rdev->wiphy.vht_capa_mod_mask);
311
312	req->bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
313				    IEEE80211_BSS_TYPE_ESS,
314				    IEEE80211_PRIVACY_ANY);
315	if (!req->bss)
316		return -ENOENT;
317
318	err = rdev_assoc(rdev, dev, req);
319	if (!err)
320		cfg80211_hold_bss(bss_from_pub(req->bss));
321	else
322		cfg80211_put_bss(&rdev->wiphy, req->bss);
323
 
 
 
 
 
 
 
 
 
 
 
 
324	return err;
325}
326
327int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
328			 struct net_device *dev, const u8 *bssid,
329			 const u8 *ie, int ie_len, u16 reason,
330			 bool local_state_change)
331{
332	struct wireless_dev *wdev = dev->ieee80211_ptr;
333	struct cfg80211_deauth_request req = {
334		.bssid = bssid,
335		.reason_code = reason,
336		.ie = ie,
337		.ie_len = ie_len,
338		.local_state_change = local_state_change,
339	};
340
341	ASSERT_WDEV_LOCK(wdev);
342
343	if (local_state_change &&
344	    (!wdev->current_bss ||
345	     !ether_addr_equal(wdev->current_bss->pub.bssid, bssid)))
346		return 0;
347
 
 
 
 
 
348	return rdev_deauth(rdev, dev, &req);
349}
350
351int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
352			   struct net_device *dev, const u8 *bssid,
353			   const u8 *ie, int ie_len, u16 reason,
354			   bool local_state_change)
355{
356	struct wireless_dev *wdev = dev->ieee80211_ptr;
357	struct cfg80211_disassoc_request req = {
358		.reason_code = reason,
359		.local_state_change = local_state_change,
360		.ie = ie,
361		.ie_len = ie_len,
 
362	};
363	int err;
364
365	ASSERT_WDEV_LOCK(wdev);
366
367	if (!wdev->current_bss)
368		return -ENOTCONN;
369
370	if (ether_addr_equal(wdev->current_bss->pub.bssid, bssid))
371		req.bss = &wdev->current_bss->pub;
372	else
373		return -ENOTCONN;
374
375	err = rdev_disassoc(rdev, dev, &req);
376	if (err)
377		return err;
378
379	/* driver should have reported the disassoc */
380	WARN_ON(wdev->current_bss);
381	return 0;
382}
383
384void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
385			struct net_device *dev)
386{
387	struct wireless_dev *wdev = dev->ieee80211_ptr;
388	u8 bssid[ETH_ALEN];
389
390	ASSERT_WDEV_LOCK(wdev);
391
392	if (!rdev->ops->deauth)
393		return;
394
395	if (!wdev->current_bss)
396		return;
397
398	memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN);
399	cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0,
400			     WLAN_REASON_DEAUTH_LEAVING, false);
401}
402
403struct cfg80211_mgmt_registration {
404	struct list_head list;
405	struct wireless_dev *wdev;
406
407	u32 nlportid;
408
409	int match_len;
410
411	__le16 frame_type;
412
 
 
413	u8 match[];
414};
415
416static void
417cfg80211_process_mlme_unregistrations(struct cfg80211_registered_device *rdev)
418{
 
 
419	struct cfg80211_mgmt_registration *reg;
 
420
421	ASSERT_RTNL();
422
423	spin_lock_bh(&rdev->mlme_unreg_lock);
424	while ((reg = list_first_entry_or_null(&rdev->mlme_unreg,
425					       struct cfg80211_mgmt_registration,
426					       list))) {
427		list_del(&reg->list);
428		spin_unlock_bh(&rdev->mlme_unreg_lock);
429
430		if (rdev->ops->mgmt_frame_register) {
431			u16 frame_type = le16_to_cpu(reg->frame_type);
 
 
 
432
433			rdev_mgmt_frame_register(rdev, reg->wdev,
434						 frame_type, false);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
435		}
 
 
436
437		kfree(reg);
 
438
439		spin_lock_bh(&rdev->mlme_unreg_lock);
440	}
441	spin_unlock_bh(&rdev->mlme_unreg_lock);
442}
443
444void cfg80211_mlme_unreg_wk(struct work_struct *wk)
445{
446	struct cfg80211_registered_device *rdev;
 
447
448	rdev = container_of(wk, struct cfg80211_registered_device,
449			    mlme_unreg_wk);
450
451	rtnl_lock();
452	cfg80211_process_mlme_unregistrations(rdev);
453	rtnl_unlock();
 
454}
455
456int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid,
457				u16 frame_type, const u8 *match_data,
458				int match_len)
 
459{
460	struct wiphy *wiphy = wdev->wiphy;
461	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
462	struct cfg80211_mgmt_registration *reg, *nreg;
463	int err = 0;
464	u16 mgmt_type;
 
465
466	if (!wdev->wiphy->mgmt_stypes)
467		return -EOPNOTSUPP;
468
469	if ((frame_type & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT)
 
470		return -EINVAL;
 
471
472	if (frame_type & ~(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE))
 
473		return -EINVAL;
 
474
475	mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
476	if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].rx & BIT(mgmt_type)))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
477		return -EINVAL;
 
478
479	nreg = kzalloc(sizeof(*reg) + match_len, GFP_KERNEL);
480	if (!nreg)
481		return -ENOMEM;
482
483	spin_lock_bh(&wdev->mgmt_registrations_lock);
484
485	list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
486		int mlen = min(match_len, reg->match_len);
487
488		if (frame_type != le16_to_cpu(reg->frame_type))
489			continue;
490
491		if (memcmp(reg->match, match_data, mlen) == 0) {
 
 
 
 
 
 
492			err = -EALREADY;
493			break;
494		}
495	}
496
497	if (err) {
498		kfree(nreg);
499		goto out;
500	}
501
502	memcpy(nreg->match, match_data, match_len);
503	nreg->match_len = match_len;
504	nreg->nlportid = snd_portid;
505	nreg->frame_type = cpu_to_le16(frame_type);
506	nreg->wdev = wdev;
507	list_add(&nreg->list, &wdev->mgmt_registrations);
508	spin_unlock_bh(&wdev->mgmt_registrations_lock);
509
510	/* process all unregistrations to avoid driver confusion */
511	cfg80211_process_mlme_unregistrations(rdev);
 
 
 
 
 
 
 
 
 
 
 
512
513	if (rdev->ops->mgmt_frame_register)
514		rdev_mgmt_frame_register(rdev, wdev, frame_type, true);
515
516	return 0;
517
518 out:
519	spin_unlock_bh(&wdev->mgmt_registrations_lock);
 
520
521	return err;
522}
523
524void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlportid)
525{
526	struct wiphy *wiphy = wdev->wiphy;
527	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
528	struct cfg80211_mgmt_registration *reg, *tmp;
529
530	spin_lock_bh(&wdev->mgmt_registrations_lock);
531
532	list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
533		if (reg->nlportid != nlportid)
534			continue;
535
536		list_del(&reg->list);
537		spin_lock(&rdev->mlme_unreg_lock);
538		list_add_tail(&reg->list, &rdev->mlme_unreg);
539		spin_unlock(&rdev->mlme_unreg_lock);
540
541		schedule_work(&rdev->mlme_unreg_wk);
 
542	}
543
544	spin_unlock_bh(&wdev->mgmt_registrations_lock);
545
546	if (nlportid && rdev->crit_proto_nlportid == nlportid) {
547		rdev->crit_proto_nlportid = 0;
548		rdev_crit_proto_stop(rdev, wdev);
549	}
550
551	if (nlportid == wdev->ap_unexpected_nlportid)
552		wdev->ap_unexpected_nlportid = 0;
553}
554
555void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
556{
557	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
558
559	spin_lock_bh(&wdev->mgmt_registrations_lock);
560	spin_lock(&rdev->mlme_unreg_lock);
561	list_splice_tail_init(&wdev->mgmt_registrations, &rdev->mlme_unreg);
562	spin_unlock(&rdev->mlme_unreg_lock);
563	spin_unlock_bh(&wdev->mgmt_registrations_lock);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
564
565	cfg80211_process_mlme_unregistrations(rdev);
566}
567
568int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
569			  struct wireless_dev *wdev,
570			  struct cfg80211_mgmt_tx_params *params, u64 *cookie)
571{
572	const struct ieee80211_mgmt *mgmt;
573	u16 stype;
574
 
 
575	if (!wdev->wiphy->mgmt_stypes)
576		return -EOPNOTSUPP;
577
578	if (!rdev->ops->mgmt_tx)
579		return -EOPNOTSUPP;
580
581	if (params->len < 24 + 1)
582		return -EINVAL;
583
584	mgmt = (const struct ieee80211_mgmt *)params->buf;
585
586	if (!ieee80211_is_mgmt(mgmt->frame_control))
587		return -EINVAL;
588
589	stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
590	if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].tx & BIT(stype >> 4)))
591		return -EINVAL;
592
593	if (ieee80211_is_action(mgmt->frame_control) &&
594	    mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) {
595		int err = 0;
596
597		wdev_lock(wdev);
598
599		switch (wdev->iftype) {
600		case NL80211_IFTYPE_ADHOC:
 
 
 
 
 
 
 
 
 
 
 
601		case NL80211_IFTYPE_STATION:
602		case NL80211_IFTYPE_P2P_CLIENT:
603			if (!wdev->current_bss) {
604				err = -ENOTCONN;
605				break;
606			}
607
608			if (!ether_addr_equal(wdev->current_bss->pub.bssid,
 
 
609					      mgmt->bssid)) {
610				err = -ENOTCONN;
611				break;
612			}
613
614			/*
615			 * check for IBSS DA must be done by driver as
616			 * cfg80211 doesn't track the stations
617			 */
618			if (wdev->iftype == NL80211_IFTYPE_ADHOC)
619				break;
620
621			/* for station, check that DA is the AP */
622			if (!ether_addr_equal(wdev->current_bss->pub.bssid,
623					      mgmt->da)) {
624				err = -ENOTCONN;
625				break;
626			}
627			break;
628		case NL80211_IFTYPE_AP:
629		case NL80211_IFTYPE_P2P_GO:
630		case NL80211_IFTYPE_AP_VLAN:
631			if (!ether_addr_equal(mgmt->bssid, wdev_address(wdev)))
 
 
 
632				err = -EINVAL;
633			break;
634		case NL80211_IFTYPE_MESH_POINT:
635			if (!ether_addr_equal(mgmt->sa, mgmt->bssid)) {
636				err = -EINVAL;
637				break;
638			}
639			/*
640			 * check for mesh DA must be done by driver as
641			 * cfg80211 doesn't track the stations
642			 */
643			break;
644		case NL80211_IFTYPE_P2P_DEVICE:
645			/*
646			 * fall through, P2P device only supports
647			 * public action frames
648			 */
649		case NL80211_IFTYPE_NAN:
650		default:
651			err = -EOPNOTSUPP;
652			break;
653		}
654		wdev_unlock(wdev);
655
656		if (err)
657			return err;
658	}
659
660	if (!ether_addr_equal(mgmt->sa, wdev_address(wdev)))
 
661		return -EINVAL;
662
663	/* Transmit the Action frame as requested by user space */
664	return rdev_mgmt_tx(rdev, wdev, params, cookie);
665}
666
667bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm,
668		      const u8 *buf, size_t len, u32 flags)
669{
670	struct wiphy *wiphy = wdev->wiphy;
671	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
672	struct cfg80211_mgmt_registration *reg;
673	const struct ieee80211_txrx_stypes *stypes =
674		&wiphy->mgmt_stypes[wdev->iftype];
675	struct ieee80211_mgmt *mgmt = (void *)buf;
676	const u8 *data;
677	int data_len;
678	bool result = false;
679	__le16 ftype = mgmt->frame_control &
680		cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE);
681	u16 stype;
682
683	trace_cfg80211_rx_mgmt(wdev, freq, sig_mbm);
684	stype = (le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) >> 4;
685
686	if (!(stypes->rx & BIT(stype))) {
687		trace_cfg80211_return_bool(false);
688		return false;
689	}
690
691	data = buf + ieee80211_hdrlen(mgmt->frame_control);
692	data_len = len - ieee80211_hdrlen(mgmt->frame_control);
693
694	spin_lock_bh(&wdev->mgmt_registrations_lock);
695
696	list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
697		if (reg->frame_type != ftype)
698			continue;
699
700		if (reg->match_len > data_len)
701			continue;
702
703		if (memcmp(reg->match, data, reg->match_len))
704			continue;
705
706		/* found match! */
707
708		/* Indicate the received Action frame to user space */
709		if (nl80211_send_mgmt(rdev, wdev, reg->nlportid,
710				      freq, sig_mbm,
711				      buf, len, flags, GFP_ATOMIC))
712			continue;
713
714		result = true;
715		break;
716	}
717
718	spin_unlock_bh(&wdev->mgmt_registrations_lock);
719
720	trace_cfg80211_return_bool(result);
721	return result;
722}
723EXPORT_SYMBOL(cfg80211_rx_mgmt);
 
 
 
 
 
 
724
725void cfg80211_dfs_channels_update_work(struct work_struct *work)
726{
727	struct delayed_work *delayed_work = to_delayed_work(work);
728	struct cfg80211_registered_device *rdev;
729	struct cfg80211_chan_def chandef;
730	struct ieee80211_supported_band *sband;
731	struct ieee80211_channel *c;
732	struct wiphy *wiphy;
733	bool check_again = false;
734	unsigned long timeout, next_time = 0;
 
 
735	int bandid, i;
736
737	rdev = container_of(delayed_work, struct cfg80211_registered_device,
738			    dfs_update_channels_wk);
739	wiphy = &rdev->wiphy;
740
741	rtnl_lock();
742	for (bandid = 0; bandid < NUM_NL80211_BANDS; bandid++) {
743		sband = wiphy->bands[bandid];
744		if (!sband)
745			continue;
746
747		for (i = 0; i < sband->n_channels; i++) {
748			c = &sband->channels[i];
749
750			if (c->dfs_state != NL80211_DFS_UNAVAILABLE)
751				continue;
752
753			timeout = c->dfs_state_entered + msecs_to_jiffies(
754					IEEE80211_DFS_MIN_NOP_TIME_MS);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
755
756			if (time_after_eq(jiffies, timeout)) {
757				c->dfs_state = NL80211_DFS_USABLE;
758				c->dfs_state_entered = jiffies;
759
760				cfg80211_chandef_create(&chandef, c,
761							NL80211_CHAN_NO_HT);
762
763				nl80211_radar_notify(rdev, &chandef,
764						     NL80211_RADAR_NOP_FINISHED,
765						     NULL, GFP_ATOMIC);
 
 
 
 
766				continue;
767			}
768
769			if (!check_again)
770				next_time = timeout - jiffies;
771			else
772				next_time = min(next_time, timeout - jiffies);
773			check_again = true;
774		}
775	}
776	rtnl_unlock();
777
778	/* reschedule if there are other channels waiting to be cleared again */
779	if (check_again)
780		queue_delayed_work(cfg80211_wq, &rdev->dfs_update_channels_wk,
781				   next_time);
782}
783
784
785void cfg80211_radar_event(struct wiphy *wiphy,
786			  struct cfg80211_chan_def *chandef,
787			  gfp_t gfp)
788{
789	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
790	unsigned long timeout;
791
792	trace_cfg80211_radar_event(wiphy, chandef);
793
794	/* only set the chandef supplied channel to unavailable, in
795	 * case the radar is detected on only one of multiple channels
796	 * spanned by the chandef.
797	 */
798	cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_UNAVAILABLE);
799
800	timeout = msecs_to_jiffies(IEEE80211_DFS_MIN_NOP_TIME_MS);
801	queue_delayed_work(cfg80211_wq, &rdev->dfs_update_channels_wk,
802			   timeout);
 
803
804	nl80211_radar_notify(rdev, chandef, NL80211_RADAR_DETECTED, NULL, gfp);
 
 
 
805}
806EXPORT_SYMBOL(cfg80211_radar_event);
807
808void cfg80211_cac_event(struct net_device *netdev,
809			const struct cfg80211_chan_def *chandef,
810			enum nl80211_radar_event event, gfp_t gfp)
 
811{
812	struct wireless_dev *wdev = netdev->ieee80211_ptr;
813	struct wiphy *wiphy = wdev->wiphy;
814	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
815	unsigned long timeout;
816
817	trace_cfg80211_cac_event(netdev, event);
818
819	if (WARN_ON(!wdev->cac_started))
820		return;
821
822	if (WARN_ON(!wdev->chandef.chan))
 
 
 
823		return;
824
825	switch (event) {
826	case NL80211_RADAR_CAC_FINISHED:
827		timeout = wdev->cac_start_time +
828			  msecs_to_jiffies(wdev->cac_time_ms);
829		WARN_ON(!time_after_eq(jiffies, timeout));
830		cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);
831		break;
 
 
 
 
832	case NL80211_RADAR_CAC_ABORTED:
 
 
 
 
833		break;
834	default:
835		WARN_ON(1);
836		return;
837	}
838	wdev->cac_started = false;
839
840	nl80211_radar_notify(rdev, chandef, event, netdev, gfp);
841}
842EXPORT_SYMBOL(cfg80211_cac_event);
v6.13.7
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * cfg80211 MLME SAP interface
   4 *
   5 * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
   6 * Copyright (c) 2015		Intel Deutschland GmbH
   7 * Copyright (C) 2019-2020, 2022-2024 Intel Corporation
   8 */
   9
  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>
  19#include "core.h"
  20#include "nl80211.h"
  21#include "rdev-ops.h"
  22
  23
  24void cfg80211_rx_assoc_resp(struct net_device *dev,
  25			    const struct cfg80211_rx_assoc_resp_data *data)
  26{
  27	struct wireless_dev *wdev = dev->ieee80211_ptr;
  28	struct wiphy *wiphy = wdev->wiphy;
  29	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
  30	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)data->buf;
  31	struct cfg80211_connect_resp_params cr = {
  32		.timeout_reason = NL80211_TIMEOUT_UNSPECIFIED,
  33		.req_ie = data->req_ies,
  34		.req_ie_len = data->req_ies_len,
  35		.resp_ie = mgmt->u.assoc_resp.variable,
  36		.resp_ie_len = data->len -
  37			       offsetof(struct ieee80211_mgmt,
  38					u.assoc_resp.variable),
  39		.status = le16_to_cpu(mgmt->u.assoc_resp.status_code),
  40		.ap_mld_addr = data->ap_mld_addr,
  41	};
  42	unsigned int link_id;
  43
  44	for (link_id = 0; link_id < ARRAY_SIZE(data->links); link_id++) {
  45		cr.links[link_id].status = data->links[link_id].status;
  46		cr.links[link_id].bss = data->links[link_id].bss;
  47
  48		WARN_ON_ONCE(cr.links[link_id].status != WLAN_STATUS_SUCCESS &&
  49			     (!cr.ap_mld_addr || !cr.links[link_id].bss));
  50
  51		if (!cr.links[link_id].bss)
  52			continue;
  53		cr.links[link_id].bssid = data->links[link_id].bss->bssid;
  54		cr.links[link_id].addr = data->links[link_id].addr;
  55		/* need to have local link addresses for MLO connections */
  56		WARN_ON(cr.ap_mld_addr &&
  57			!is_valid_ether_addr(cr.links[link_id].addr));
  58
  59		BUG_ON(!cr.links[link_id].bss->channel);
  60
  61		if (cr.links[link_id].bss->channel->band == NL80211_BAND_S1GHZ) {
  62			WARN_ON(link_id);
  63			cr.resp_ie = (u8 *)&mgmt->u.s1g_assoc_resp.variable;
  64			cr.resp_ie_len = data->len -
  65					 offsetof(struct ieee80211_mgmt,
  66						  u.s1g_assoc_resp.variable);
  67		}
  68
  69		if (cr.ap_mld_addr)
  70			cr.valid_links |= BIT(link_id);
  71	}
  72
  73	trace_cfg80211_send_rx_assoc(dev, data);
  74
  75	/*
  76	 * This is a bit of a hack, we don't notify userspace of
  77	 * a (re-)association reply if we tried to send a reassoc
  78	 * and got a reject -- we only try again with an assoc
  79	 * frame instead of reassoc.
  80	 */
  81	if (cfg80211_sme_rx_assoc_resp(wdev, cr.status)) {
  82		for (link_id = 0; link_id < ARRAY_SIZE(data->links); link_id++) {
  83			struct cfg80211_bss *bss = data->links[link_id].bss;
  84
  85			if (!bss)
  86				continue;
  87
  88			cfg80211_unhold_bss(bss_from_pub(bss));
  89			cfg80211_put_bss(wiphy, bss);
  90		}
  91		return;
  92	}
  93
  94	nl80211_send_rx_assoc(rdev, dev, data);
  95	/* update current_bss etc., consumes the bss reference */
  96	__cfg80211_connect_result(dev, &cr, cr.status == WLAN_STATUS_SUCCESS);
 
 
  97}
  98EXPORT_SYMBOL(cfg80211_rx_assoc_resp);
  99
 100static void cfg80211_process_auth(struct wireless_dev *wdev,
 101				  const u8 *buf, size_t len)
 102{
 103	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
 104
 105	nl80211_send_rx_auth(rdev, wdev->netdev, buf, len, GFP_KERNEL);
 106	cfg80211_sme_rx_auth(wdev, buf, len);
 107}
 108
 109static void cfg80211_process_deauth(struct wireless_dev *wdev,
 110				    const u8 *buf, size_t len,
 111				    bool reconnect)
 112{
 113	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
 114	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
 115	const u8 *bssid = mgmt->bssid;
 116	u16 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
 117	bool from_ap = !ether_addr_equal(mgmt->sa, wdev->netdev->dev_addr);
 118
 119	nl80211_send_deauth(rdev, wdev->netdev, buf, len, reconnect, GFP_KERNEL);
 120
 121	if (!wdev->connected || !ether_addr_equal(wdev->u.client.connected_addr, bssid))
 
 122		return;
 123
 124	__cfg80211_disconnected(wdev->netdev, NULL, 0, reason_code, from_ap);
 125	cfg80211_sme_deauth(wdev);
 126}
 127
 128static void cfg80211_process_disassoc(struct wireless_dev *wdev,
 129				      const u8 *buf, size_t len,
 130				      bool reconnect)
 131{
 132	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
 133	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
 134	const u8 *bssid = mgmt->bssid;
 135	u16 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
 136	bool from_ap = !ether_addr_equal(mgmt->sa, wdev->netdev->dev_addr);
 137
 138	nl80211_send_disassoc(rdev, wdev->netdev, buf, len, reconnect,
 139			      GFP_KERNEL);
 140
 141	if (WARN_ON(!wdev->connected ||
 142		    !ether_addr_equal(wdev->u.client.connected_addr, bssid)))
 143		return;
 144
 145	__cfg80211_disconnected(wdev->netdev, NULL, 0, reason_code, from_ap);
 146	cfg80211_sme_disassoc(wdev);
 147}
 148
 149void cfg80211_rx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len)
 150{
 151	struct wireless_dev *wdev = dev->ieee80211_ptr;
 152	struct ieee80211_mgmt *mgmt = (void *)buf;
 153
 154	lockdep_assert_wiphy(wdev->wiphy);
 155
 156	trace_cfg80211_rx_mlme_mgmt(dev, buf, len);
 157
 158	if (WARN_ON(len < 2))
 159		return;
 160
 161	if (ieee80211_is_auth(mgmt->frame_control))
 162		cfg80211_process_auth(wdev, buf, len);
 163	else if (ieee80211_is_deauth(mgmt->frame_control))
 164		cfg80211_process_deauth(wdev, buf, len, false);
 165	else if (ieee80211_is_disassoc(mgmt->frame_control))
 166		cfg80211_process_disassoc(wdev, buf, len, false);
 167}
 168EXPORT_SYMBOL(cfg80211_rx_mlme_mgmt);
 169
 170void cfg80211_auth_timeout(struct net_device *dev, const u8 *addr)
 171{
 172	struct wireless_dev *wdev = dev->ieee80211_ptr;
 173	struct wiphy *wiphy = wdev->wiphy;
 174	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
 175
 176	trace_cfg80211_send_auth_timeout(dev, addr);
 177
 178	nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL);
 179	cfg80211_sme_auth_timeout(wdev);
 180}
 181EXPORT_SYMBOL(cfg80211_auth_timeout);
 182
 183void cfg80211_assoc_failure(struct net_device *dev,
 184			    struct cfg80211_assoc_failure *data)
 185{
 186	struct wireless_dev *wdev = dev->ieee80211_ptr;
 187	struct wiphy *wiphy = wdev->wiphy;
 188	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
 189	const u8 *addr = data->ap_mld_addr ?: data->bss[0]->bssid;
 190	int i;
 191
 192	trace_cfg80211_send_assoc_failure(dev, data);
 
 
 
 193
 194	if (data->timeout) {
 195		nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL);
 196		cfg80211_sme_assoc_timeout(wdev);
 197	} else {
 198		cfg80211_sme_abandon_assoc(wdev);
 199	}
 200
 201	for (i = 0; i < ARRAY_SIZE(data->bss); i++) {
 202		struct cfg80211_bss *bss = data->bss[i];
 
 
 203
 204		if (!bss)
 205			continue;
 206
 207		cfg80211_unhold_bss(bss_from_pub(bss));
 208		cfg80211_put_bss(wiphy, bss);
 209	}
 210}
 211EXPORT_SYMBOL(cfg80211_assoc_failure);
 212
 213void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len,
 214			   bool reconnect)
 215{
 216	struct wireless_dev *wdev = dev->ieee80211_ptr;
 217	struct ieee80211_mgmt *mgmt = (void *)buf;
 218
 219	lockdep_assert_wiphy(wdev->wiphy);
 220
 221	trace_cfg80211_tx_mlme_mgmt(dev, buf, len, reconnect);
 222
 223	if (WARN_ON(len < 2))
 224		return;
 225
 226	if (ieee80211_is_deauth(mgmt->frame_control))
 227		cfg80211_process_deauth(wdev, buf, len, reconnect);
 228	else
 229		cfg80211_process_disassoc(wdev, buf, len, reconnect);
 230}
 231EXPORT_SYMBOL(cfg80211_tx_mlme_mgmt);
 232
 233void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
 234				  enum nl80211_key_type key_type, int key_id,
 235				  const u8 *tsc, gfp_t gfp)
 236{
 237	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
 238	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
 239#ifdef CONFIG_CFG80211_WEXT
 240	union iwreq_data wrqu;
 241	char *buf = kmalloc(128, gfp);
 242
 243	if (buf) {
 
 
 
 
 244		memset(&wrqu, 0, sizeof(wrqu));
 245		wrqu.data.length =
 246			sprintf(buf, "MLME-MICHAELMICFAILURE."
 247				"indication(keyid=%d %scast addr=%pM)",
 248				key_id, key_type == NL80211_KEYTYPE_GROUP
 249				? "broad" : "uni", addr);
 250		wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
 251		kfree(buf);
 252	}
 253#endif
 254
 255	trace_cfg80211_michael_mic_failure(dev, addr, key_type, key_id, tsc);
 256	nl80211_michael_mic_failure(rdev, dev, addr, key_type, key_id, tsc, gfp);
 257}
 258EXPORT_SYMBOL(cfg80211_michael_mic_failure);
 259
 260/* some MLME handling for userspace SME */
 261int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
 262		       struct net_device *dev,
 263		       struct cfg80211_auth_request *req)
 
 
 
 
 
 
 264{
 265	struct wireless_dev *wdev = dev->ieee80211_ptr;
 
 
 
 
 
 
 
 
 
 
 
 266
 267	lockdep_assert_wiphy(wdev->wiphy);
 268
 269	if (!req->bss)
 270		return -ENOENT;
 271
 272	if (req->link_id >= 0 &&
 273	    !(wdev->wiphy->flags & WIPHY_FLAG_SUPPORTS_MLO))
 274		return -EINVAL;
 275
 276	if (req->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
 277		if (!req->key || !req->key_len ||
 278		    req->key_idx < 0 || req->key_idx > 3)
 279			return -EINVAL;
 280	}
 281
 282	if (wdev->connected &&
 283	    ether_addr_equal(req->bss->bssid, wdev->u.client.connected_addr))
 284		return -EALREADY;
 285
 286	if (ether_addr_equal(req->bss->bssid, dev->dev_addr) ||
 287	    (req->link_id >= 0 &&
 288	     ether_addr_equal(req->ap_mld_addr, dev->dev_addr)))
 289		return -EINVAL;
 
 
 
 290
 291	return rdev_auth(rdev, dev, req);
 
 292}
 293
 294/*  Do a logical ht_capa &= ht_capa_mask.  */
 295void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
 296			       const struct ieee80211_ht_cap *ht_capa_mask)
 297{
 298	int i;
 299	u8 *p1, *p2;
 300	if (!ht_capa_mask) {
 301		memset(ht_capa, 0, sizeof(*ht_capa));
 302		return;
 303	}
 304
 305	p1 = (u8*)(ht_capa);
 306	p2 = (u8*)(ht_capa_mask);
 307	for (i = 0; i < sizeof(*ht_capa); i++)
 308		p1[i] &= p2[i];
 309}
 310
 311/*  Do a logical vht_capa &= vht_capa_mask.  */
 312void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa,
 313				const struct ieee80211_vht_cap *vht_capa_mask)
 314{
 315	int i;
 316	u8 *p1, *p2;
 317	if (!vht_capa_mask) {
 318		memset(vht_capa, 0, sizeof(*vht_capa));
 319		return;
 320	}
 321
 322	p1 = (u8*)(vht_capa);
 323	p2 = (u8*)(vht_capa_mask);
 324	for (i = 0; i < sizeof(*vht_capa); i++)
 325		p1[i] &= p2[i];
 326}
 327
 328static int
 329cfg80211_mlme_check_mlo_compat(const struct ieee80211_multi_link_elem *mle_a,
 330			       const struct ieee80211_multi_link_elem *mle_b,
 331			       struct netlink_ext_ack *extack)
 332{
 333	const struct ieee80211_mle_basic_common_info *common_a, *common_b;
 334
 335	common_a = (const void *)mle_a->variable;
 336	common_b = (const void *)mle_b->variable;
 337
 338	if (memcmp(common_a->mld_mac_addr, common_b->mld_mac_addr, ETH_ALEN)) {
 339		NL_SET_ERR_MSG(extack, "AP MLD address mismatch");
 340		return -EINVAL;
 341	}
 342
 343	if (ieee80211_mle_get_eml_cap((const u8 *)mle_a) !=
 344	    ieee80211_mle_get_eml_cap((const u8 *)mle_b)) {
 345		NL_SET_ERR_MSG(extack, "link EML capabilities mismatch");
 346		return -EINVAL;
 347	}
 348
 349	if (ieee80211_mle_get_mld_capa_op((const u8 *)mle_a) !=
 350	    ieee80211_mle_get_mld_capa_op((const u8 *)mle_b)) {
 351		NL_SET_ERR_MSG(extack, "link MLD capabilities/ops mismatch");
 352		return -EINVAL;
 353	}
 354
 355	return 0;
 356}
 357
 358static int cfg80211_mlme_check_mlo(struct net_device *dev,
 359				   struct cfg80211_assoc_request *req,
 360				   struct netlink_ext_ack *extack)
 361{
 362	const struct ieee80211_multi_link_elem *mles[ARRAY_SIZE(req->links)] = {};
 363	int i;
 364
 365	if (req->link_id < 0)
 366		return 0;
 367
 368	if (!req->links[req->link_id].bss) {
 369		NL_SET_ERR_MSG(extack, "no BSS for assoc link");
 370		return -EINVAL;
 371	}
 372
 373	rcu_read_lock();
 374	for (i = 0; i < ARRAY_SIZE(req->links); i++) {
 375		const struct cfg80211_bss_ies *ies;
 376		const struct element *ml;
 377
 378		if (!req->links[i].bss)
 379			continue;
 380
 381		if (ether_addr_equal(req->links[i].bss->bssid, dev->dev_addr)) {
 382			NL_SET_ERR_MSG(extack, "BSSID must not be our address");
 383			req->links[i].error = -EINVAL;
 384			goto error;
 385		}
 386
 387		ies = rcu_dereference(req->links[i].bss->ies);
 388		ml = cfg80211_find_ext_elem(WLAN_EID_EXT_EHT_MULTI_LINK,
 389					    ies->data, ies->len);
 390		if (!ml) {
 391			NL_SET_ERR_MSG(extack, "MLO BSS w/o ML element");
 392			req->links[i].error = -EINVAL;
 393			goto error;
 394		}
 395
 396		if (!ieee80211_mle_type_ok(ml->data + 1,
 397					   IEEE80211_ML_CONTROL_TYPE_BASIC,
 398					   ml->datalen - 1)) {
 399			NL_SET_ERR_MSG(extack, "BSS with invalid ML element");
 400			req->links[i].error = -EINVAL;
 401			goto error;
 402		}
 403
 404		mles[i] = (const void *)(ml->data + 1);
 405
 406		if (ieee80211_mle_get_link_id((const u8 *)mles[i]) != i) {
 407			NL_SET_ERR_MSG(extack, "link ID mismatch");
 408			req->links[i].error = -EINVAL;
 409			goto error;
 410		}
 411	}
 412
 413	if (WARN_ON(!mles[req->link_id]))
 414		goto error;
 415
 416	for (i = 0; i < ARRAY_SIZE(req->links); i++) {
 417		if (i == req->link_id || !req->links[i].bss)
 418			continue;
 419
 420		if (WARN_ON(!mles[i]))
 421			goto error;
 422
 423		if (cfg80211_mlme_check_mlo_compat(mles[req->link_id], mles[i],
 424						   extack)) {
 425			req->links[i].error = -EINVAL;
 426			goto error;
 427		}
 428	}
 429
 430	rcu_read_unlock();
 431	return 0;
 432error:
 433	rcu_read_unlock();
 434	return -EINVAL;
 435}
 436
 437/* Note: caller must cfg80211_put_bss() regardless of result */
 438int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
 439			struct net_device *dev,
 440			struct cfg80211_assoc_request *req,
 441			struct netlink_ext_ack *extack)
 
 
 442{
 443	struct wireless_dev *wdev = dev->ieee80211_ptr;
 444	int err;
 445
 446	lockdep_assert_wiphy(wdev->wiphy);
 447
 448	err = cfg80211_mlme_check_mlo(dev, req, extack);
 449	if (err)
 450		return err;
 451
 452	if (wdev->connected &&
 453	    (!req->prev_bssid ||
 454	     !ether_addr_equal(wdev->u.client.connected_addr, req->prev_bssid)))
 455		return -EALREADY;
 456
 457	if ((req->bss && ether_addr_equal(req->bss->bssid, dev->dev_addr)) ||
 458	    (req->link_id >= 0 &&
 459	     ether_addr_equal(req->ap_mld_addr, dev->dev_addr)))
 460		return -EINVAL;
 461
 462	cfg80211_oper_and_ht_capa(&req->ht_capa_mask,
 463				  rdev->wiphy.ht_capa_mod_mask);
 464	cfg80211_oper_and_vht_capa(&req->vht_capa_mask,
 465				   rdev->wiphy.vht_capa_mod_mask);
 466
 
 
 
 
 
 
 467	err = rdev_assoc(rdev, dev, req);
 468	if (!err) {
 469		int link_id;
 
 
 470
 471		if (req->bss) {
 472			cfg80211_ref_bss(&rdev->wiphy, req->bss);
 473			cfg80211_hold_bss(bss_from_pub(req->bss));
 474		}
 475
 476		for (link_id = 0; link_id < ARRAY_SIZE(req->links); link_id++) {
 477			if (!req->links[link_id].bss)
 478				continue;
 479			cfg80211_ref_bss(&rdev->wiphy, req->links[link_id].bss);
 480			cfg80211_hold_bss(bss_from_pub(req->links[link_id].bss));
 481		}
 482	}
 483	return err;
 484}
 485
 486int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
 487			 struct net_device *dev, const u8 *bssid,
 488			 const u8 *ie, int ie_len, u16 reason,
 489			 bool local_state_change)
 490{
 491	struct wireless_dev *wdev = dev->ieee80211_ptr;
 492	struct cfg80211_deauth_request req = {
 493		.bssid = bssid,
 494		.reason_code = reason,
 495		.ie = ie,
 496		.ie_len = ie_len,
 497		.local_state_change = local_state_change,
 498	};
 499
 500	lockdep_assert_wiphy(wdev->wiphy);
 501
 502	if (local_state_change &&
 503	    (!wdev->connected ||
 504	     !ether_addr_equal(wdev->u.client.connected_addr, bssid)))
 505		return 0;
 506
 507	if (ether_addr_equal(wdev->disconnect_bssid, bssid) ||
 508	    (wdev->connected &&
 509	     ether_addr_equal(wdev->u.client.connected_addr, bssid)))
 510		wdev->conn_owner_nlportid = 0;
 511
 512	return rdev_deauth(rdev, dev, &req);
 513}
 514
 515int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
 516			   struct net_device *dev, const u8 *ap_addr,
 517			   const u8 *ie, int ie_len, u16 reason,
 518			   bool local_state_change)
 519{
 520	struct wireless_dev *wdev = dev->ieee80211_ptr;
 521	struct cfg80211_disassoc_request req = {
 522		.reason_code = reason,
 523		.local_state_change = local_state_change,
 524		.ie = ie,
 525		.ie_len = ie_len,
 526		.ap_addr = ap_addr,
 527	};
 528	int err;
 529
 530	lockdep_assert_wiphy(wdev->wiphy);
 531
 532	if (!wdev->connected)
 533		return -ENOTCONN;
 534
 535	if (memcmp(wdev->u.client.connected_addr, ap_addr, ETH_ALEN))
 
 
 536		return -ENOTCONN;
 537
 538	err = rdev_disassoc(rdev, dev, &req);
 539	if (err)
 540		return err;
 541
 542	/* driver should have reported the disassoc */
 543	WARN_ON(wdev->connected);
 544	return 0;
 545}
 546
 547void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
 548			struct net_device *dev)
 549{
 550	struct wireless_dev *wdev = dev->ieee80211_ptr;
 551	u8 bssid[ETH_ALEN];
 552
 553	lockdep_assert_wiphy(wdev->wiphy);
 554
 555	if (!rdev->ops->deauth)
 556		return;
 557
 558	if (!wdev->connected)
 559		return;
 560
 561	memcpy(bssid, wdev->u.client.connected_addr, ETH_ALEN);
 562	cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0,
 563			     WLAN_REASON_DEAUTH_LEAVING, false);
 564}
 565
 566struct cfg80211_mgmt_registration {
 567	struct list_head list;
 568	struct wireless_dev *wdev;
 569
 570	u32 nlportid;
 571
 572	int match_len;
 573
 574	__le16 frame_type;
 575
 576	bool multicast_rx;
 577
 578	u8 match[];
 579};
 580
 581static void cfg80211_mgmt_registrations_update(struct wireless_dev *wdev)
 
 582{
 583	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
 584	struct wireless_dev *tmp;
 585	struct cfg80211_mgmt_registration *reg;
 586	struct mgmt_frame_regs upd = {};
 587
 588	lockdep_assert_held(&rdev->wiphy.mtx);
 
 
 
 
 
 
 
 589
 590	spin_lock_bh(&rdev->mgmt_registrations_lock);
 591	if (!wdev->mgmt_registrations_need_update) {
 592		spin_unlock_bh(&rdev->mgmt_registrations_lock);
 593		return;
 594	}
 595
 596	rcu_read_lock();
 597	list_for_each_entry_rcu(tmp, &rdev->wiphy.wdev_list, list) {
 598		list_for_each_entry(reg, &tmp->mgmt_registrations, list) {
 599			u32 mask = BIT(le16_to_cpu(reg->frame_type) >> 4);
 600			u32 mcast_mask = 0;
 601
 602			if (reg->multicast_rx)
 603				mcast_mask = mask;
 604
 605			upd.global_stypes |= mask;
 606			upd.global_mcast_stypes |= mcast_mask;
 607
 608			if (tmp == wdev) {
 609				upd.interface_stypes |= mask;
 610				upd.interface_mcast_stypes |= mcast_mask;
 611			}
 612		}
 613	}
 614	rcu_read_unlock();
 615
 616	wdev->mgmt_registrations_need_update = 0;
 617	spin_unlock_bh(&rdev->mgmt_registrations_lock);
 618
 619	rdev_update_mgmt_frame_registrations(rdev, wdev, &upd);
 
 
 620}
 621
 622void cfg80211_mgmt_registrations_update_wk(struct work_struct *wk)
 623{
 624	struct cfg80211_registered_device *rdev;
 625	struct wireless_dev *wdev;
 626
 627	rdev = container_of(wk, struct cfg80211_registered_device,
 628			    mgmt_registrations_update_wk);
 629
 630	wiphy_lock(&rdev->wiphy);
 631	list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list)
 632		cfg80211_mgmt_registrations_update(wdev);
 633	wiphy_unlock(&rdev->wiphy);
 634}
 635
 636int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid,
 637				u16 frame_type, const u8 *match_data,
 638				int match_len, bool multicast_rx,
 639				struct netlink_ext_ack *extack)
 640{
 641	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
 
 642	struct cfg80211_mgmt_registration *reg, *nreg;
 643	int err = 0;
 644	u16 mgmt_type;
 645	bool update_multicast = false;
 646
 647	if (!wdev->wiphy->mgmt_stypes)
 648		return -EOPNOTSUPP;
 649
 650	if ((frame_type & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT) {
 651		NL_SET_ERR_MSG(extack, "frame type not management");
 652		return -EINVAL;
 653	}
 654
 655	if (frame_type & ~(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) {
 656		NL_SET_ERR_MSG(extack, "Invalid frame type");
 657		return -EINVAL;
 658	}
 659
 660	mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
 661	if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].rx & BIT(mgmt_type))) {
 662		NL_SET_ERR_MSG(extack,
 663			       "Registration to specific type not supported");
 664		return -EINVAL;
 665	}
 666
 667	/*
 668	 * To support Pre Association Security Negotiation (PASN), registration
 669	 * for authentication frames should be supported. However, as some
 670	 * versions of the user space daemons wrongly register to all types of
 671	 * authentication frames (which might result in unexpected behavior)
 672	 * allow such registration if the request is for a specific
 673	 * authentication algorithm number.
 674	 */
 675	if (wdev->iftype == NL80211_IFTYPE_STATION &&
 676	    (frame_type & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_AUTH &&
 677	    !(match_data && match_len >= 2)) {
 678		NL_SET_ERR_MSG(extack,
 679			       "Authentication algorithm number required");
 680		return -EINVAL;
 681	}
 682
 683	nreg = kzalloc(sizeof(*reg) + match_len, GFP_KERNEL);
 684	if (!nreg)
 685		return -ENOMEM;
 686
 687	spin_lock_bh(&rdev->mgmt_registrations_lock);
 688
 689	list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
 690		int mlen = min(match_len, reg->match_len);
 691
 692		if (frame_type != le16_to_cpu(reg->frame_type))
 693			continue;
 694
 695		if (memcmp(reg->match, match_data, mlen) == 0) {
 696			if (reg->multicast_rx != multicast_rx) {
 697				update_multicast = true;
 698				reg->multicast_rx = multicast_rx;
 699				break;
 700			}
 701			NL_SET_ERR_MSG(extack, "Match already configured");
 702			err = -EALREADY;
 703			break;
 704		}
 705	}
 706
 707	if (err)
 
 708		goto out;
 
 
 
 
 
 
 
 
 
 709
 710	if (update_multicast) {
 711		kfree(nreg);
 712	} else {
 713		memcpy(nreg->match, match_data, match_len);
 714		nreg->match_len = match_len;
 715		nreg->nlportid = snd_portid;
 716		nreg->frame_type = cpu_to_le16(frame_type);
 717		nreg->wdev = wdev;
 718		nreg->multicast_rx = multicast_rx;
 719		list_add(&nreg->list, &wdev->mgmt_registrations);
 720	}
 721	wdev->mgmt_registrations_need_update = 1;
 722	spin_unlock_bh(&rdev->mgmt_registrations_lock);
 723
 724	cfg80211_mgmt_registrations_update(wdev);
 
 725
 726	return 0;
 727
 728 out:
 729	kfree(nreg);
 730	spin_unlock_bh(&rdev->mgmt_registrations_lock);
 731
 732	return err;
 733}
 734
 735void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlportid)
 736{
 737	struct wiphy *wiphy = wdev->wiphy;
 738	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
 739	struct cfg80211_mgmt_registration *reg, *tmp;
 740
 741	spin_lock_bh(&rdev->mgmt_registrations_lock);
 742
 743	list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
 744		if (reg->nlportid != nlportid)
 745			continue;
 746
 747		list_del(&reg->list);
 748		kfree(reg);
 
 
 749
 750		wdev->mgmt_registrations_need_update = 1;
 751		schedule_work(&rdev->mgmt_registrations_update_wk);
 752	}
 753
 754	spin_unlock_bh(&rdev->mgmt_registrations_lock);
 755
 756	if (nlportid && rdev->crit_proto_nlportid == nlportid) {
 757		rdev->crit_proto_nlportid = 0;
 758		rdev_crit_proto_stop(rdev, wdev);
 759	}
 760
 761	if (nlportid == wdev->ap_unexpected_nlportid)
 762		wdev->ap_unexpected_nlportid = 0;
 763}
 764
 765void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
 766{
 767	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
 768	struct cfg80211_mgmt_registration *reg, *tmp;
 769
 770	spin_lock_bh(&rdev->mgmt_registrations_lock);
 771	list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
 772		list_del(&reg->list);
 773		kfree(reg);
 774	}
 775	wdev->mgmt_registrations_need_update = 1;
 776	spin_unlock_bh(&rdev->mgmt_registrations_lock);
 777
 778	cfg80211_mgmt_registrations_update(wdev);
 779}
 780
 781static bool cfg80211_allowed_address(struct wireless_dev *wdev, const u8 *addr)
 782{
 783	int i;
 784
 785	for_each_valid_link(wdev, i) {
 786		if (ether_addr_equal(addr, wdev->links[i].addr))
 787			return true;
 788	}
 789
 790	return ether_addr_equal(addr, wdev_address(wdev));
 791}
 792
 793static bool cfg80211_allowed_random_address(struct wireless_dev *wdev,
 794					    const struct ieee80211_mgmt *mgmt)
 795{
 796	if (ieee80211_is_auth(mgmt->frame_control) ||
 797	    ieee80211_is_deauth(mgmt->frame_control)) {
 798		/* Allow random TA to be used with authentication and
 799		 * deauthentication frames if the driver has indicated support.
 800		 */
 801		if (wiphy_ext_feature_isset(
 802			    wdev->wiphy,
 803			    NL80211_EXT_FEATURE_AUTH_AND_DEAUTH_RANDOM_TA))
 804			return true;
 805	} else if (ieee80211_is_action(mgmt->frame_control) &&
 806		   mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) {
 807		/* Allow random TA to be used with Public Action frames if the
 808		 * driver has indicated support.
 809		 */
 810		if (!wdev->connected &&
 811		    wiphy_ext_feature_isset(
 812			    wdev->wiphy,
 813			    NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA))
 814			return true;
 815
 816		if (wdev->connected &&
 817		    wiphy_ext_feature_isset(
 818			    wdev->wiphy,
 819			    NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED))
 820			return true;
 821	}
 822
 823	return false;
 824}
 825
 826int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
 827			  struct wireless_dev *wdev,
 828			  struct cfg80211_mgmt_tx_params *params, u64 *cookie)
 829{
 830	const struct ieee80211_mgmt *mgmt;
 831	u16 stype;
 832
 833	lockdep_assert_wiphy(&rdev->wiphy);
 834
 835	if (!wdev->wiphy->mgmt_stypes)
 836		return -EOPNOTSUPP;
 837
 838	if (!rdev->ops->mgmt_tx)
 839		return -EOPNOTSUPP;
 840
 841	if (params->len < 24 + 1)
 842		return -EINVAL;
 843
 844	mgmt = (const struct ieee80211_mgmt *)params->buf;
 845
 846	if (!ieee80211_is_mgmt(mgmt->frame_control))
 847		return -EINVAL;
 848
 849	stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
 850	if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].tx & BIT(stype >> 4)))
 851		return -EINVAL;
 852
 853	if (ieee80211_is_action(mgmt->frame_control) &&
 854	    mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) {
 855		int err = 0;
 856
 
 
 857		switch (wdev->iftype) {
 858		case NL80211_IFTYPE_ADHOC:
 859			/*
 860			 * check for IBSS DA must be done by driver as
 861			 * cfg80211 doesn't track the stations
 862			 */
 863			if (!wdev->u.ibss.current_bss ||
 864			    !ether_addr_equal(wdev->u.ibss.current_bss->pub.bssid,
 865					      mgmt->bssid)) {
 866				err = -ENOTCONN;
 867				break;
 868			}
 869			break;
 870		case NL80211_IFTYPE_STATION:
 871		case NL80211_IFTYPE_P2P_CLIENT:
 872			if (!wdev->connected) {
 873				err = -ENOTCONN;
 874				break;
 875			}
 876
 877			/* FIXME: MLD may address this differently */
 878
 879			if (!ether_addr_equal(wdev->u.client.connected_addr,
 880					      mgmt->bssid)) {
 881				err = -ENOTCONN;
 882				break;
 883			}
 884
 
 
 
 
 
 
 
 885			/* for station, check that DA is the AP */
 886			if (!ether_addr_equal(wdev->u.client.connected_addr,
 887					      mgmt->da)) {
 888				err = -ENOTCONN;
 889				break;
 890			}
 891			break;
 892		case NL80211_IFTYPE_AP:
 893		case NL80211_IFTYPE_P2P_GO:
 894		case NL80211_IFTYPE_AP_VLAN:
 895			if (!ether_addr_equal(mgmt->bssid, wdev_address(wdev)) &&
 896			    (params->link_id < 0 ||
 897			     !ether_addr_equal(mgmt->bssid,
 898					       wdev->links[params->link_id].addr)))
 899				err = -EINVAL;
 900			break;
 901		case NL80211_IFTYPE_MESH_POINT:
 902			if (!ether_addr_equal(mgmt->sa, mgmt->bssid)) {
 903				err = -EINVAL;
 904				break;
 905			}
 906			/*
 907			 * check for mesh DA must be done by driver as
 908			 * cfg80211 doesn't track the stations
 909			 */
 910			break;
 911		case NL80211_IFTYPE_P2P_DEVICE:
 912			/*
 913			 * fall through, P2P device only supports
 914			 * public action frames
 915			 */
 916		case NL80211_IFTYPE_NAN:
 917		default:
 918			err = -EOPNOTSUPP;
 919			break;
 920		}
 
 921
 922		if (err)
 923			return err;
 924	}
 925
 926	if (!cfg80211_allowed_address(wdev, mgmt->sa) &&
 927	    !cfg80211_allowed_random_address(wdev, mgmt))
 928		return -EINVAL;
 929
 930	/* Transmit the management frame as requested by user space */
 931	return rdev_mgmt_tx(rdev, wdev, params, cookie);
 932}
 933
 934bool cfg80211_rx_mgmt_ext(struct wireless_dev *wdev,
 935			  struct cfg80211_rx_info *info)
 936{
 937	struct wiphy *wiphy = wdev->wiphy;
 938	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
 939	struct cfg80211_mgmt_registration *reg;
 940	const struct ieee80211_txrx_stypes *stypes =
 941		&wiphy->mgmt_stypes[wdev->iftype];
 942	struct ieee80211_mgmt *mgmt = (void *)info->buf;
 943	const u8 *data;
 944	int data_len;
 945	bool result = false;
 946	__le16 ftype = mgmt->frame_control &
 947		cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE);
 948	u16 stype;
 949
 950	trace_cfg80211_rx_mgmt(wdev, info);
 951	stype = (le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) >> 4;
 952
 953	if (!(stypes->rx & BIT(stype))) {
 954		trace_cfg80211_return_bool(false);
 955		return false;
 956	}
 957
 958	data = info->buf + ieee80211_hdrlen(mgmt->frame_control);
 959	data_len = info->len - ieee80211_hdrlen(mgmt->frame_control);
 960
 961	spin_lock_bh(&rdev->mgmt_registrations_lock);
 962
 963	list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
 964		if (reg->frame_type != ftype)
 965			continue;
 966
 967		if (reg->match_len > data_len)
 968			continue;
 969
 970		if (memcmp(reg->match, data, reg->match_len))
 971			continue;
 972
 973		/* found match! */
 974
 975		/* Indicate the received Action frame to user space */
 976		if (nl80211_send_mgmt(rdev, wdev, reg->nlportid, info,
 977				      GFP_ATOMIC))
 
 978			continue;
 979
 980		result = true;
 981		break;
 982	}
 983
 984	spin_unlock_bh(&rdev->mgmt_registrations_lock);
 985
 986	trace_cfg80211_return_bool(result);
 987	return result;
 988}
 989EXPORT_SYMBOL(cfg80211_rx_mgmt_ext);
 990
 991void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev)
 992{
 993	cancel_delayed_work(&rdev->dfs_update_channels_wk);
 994	queue_delayed_work(cfg80211_wq, &rdev->dfs_update_channels_wk, 0);
 995}
 996
 997void cfg80211_dfs_channels_update_work(struct work_struct *work)
 998{
 999	struct delayed_work *delayed_work = to_delayed_work(work);
1000	struct cfg80211_registered_device *rdev;
1001	struct cfg80211_chan_def chandef;
1002	struct ieee80211_supported_band *sband;
1003	struct ieee80211_channel *c;
1004	struct wiphy *wiphy;
1005	bool check_again = false;
1006	unsigned long timeout, next_time = 0;
1007	unsigned long time_dfs_update;
1008	enum nl80211_radar_event radar_event;
1009	int bandid, i;
1010
1011	rdev = container_of(delayed_work, struct cfg80211_registered_device,
1012			    dfs_update_channels_wk);
1013	wiphy = &rdev->wiphy;
1014
1015	rtnl_lock();
1016	for (bandid = 0; bandid < NUM_NL80211_BANDS; bandid++) {
1017		sband = wiphy->bands[bandid];
1018		if (!sband)
1019			continue;
1020
1021		for (i = 0; i < sband->n_channels; i++) {
1022			c = &sband->channels[i];
1023
1024			if (!(c->flags & IEEE80211_CHAN_RADAR))
1025				continue;
1026
1027			if (c->dfs_state != NL80211_DFS_UNAVAILABLE &&
1028			    c->dfs_state != NL80211_DFS_AVAILABLE)
1029				continue;
1030
1031			if (c->dfs_state == NL80211_DFS_UNAVAILABLE) {
1032				time_dfs_update = IEEE80211_DFS_MIN_NOP_TIME_MS;
1033				radar_event = NL80211_RADAR_NOP_FINISHED;
1034			} else {
1035				if (regulatory_pre_cac_allowed(wiphy) ||
1036				    cfg80211_any_wiphy_oper_chan(wiphy, c))
1037					continue;
1038
1039				time_dfs_update = REG_PRE_CAC_EXPIRY_GRACE_MS;
1040				radar_event = NL80211_RADAR_PRE_CAC_EXPIRED;
1041			}
1042
1043			timeout = c->dfs_state_entered +
1044				  msecs_to_jiffies(time_dfs_update);
1045
1046			if (time_after_eq(jiffies, timeout)) {
1047				c->dfs_state = NL80211_DFS_USABLE;
1048				c->dfs_state_entered = jiffies;
1049
1050				cfg80211_chandef_create(&chandef, c,
1051							NL80211_CHAN_NO_HT);
1052
1053				nl80211_radar_notify(rdev, &chandef,
1054						     radar_event, NULL,
1055						     GFP_ATOMIC);
1056
1057				regulatory_propagate_dfs_state(wiphy, &chandef,
1058							       c->dfs_state,
1059							       radar_event);
1060				continue;
1061			}
1062
1063			if (!check_again)
1064				next_time = timeout - jiffies;
1065			else
1066				next_time = min(next_time, timeout - jiffies);
1067			check_again = true;
1068		}
1069	}
1070	rtnl_unlock();
1071
1072	/* reschedule if there are other channels waiting to be cleared again */
1073	if (check_again)
1074		queue_delayed_work(cfg80211_wq, &rdev->dfs_update_channels_wk,
1075				   next_time);
1076}
1077
1078
1079void __cfg80211_radar_event(struct wiphy *wiphy,
1080			    struct cfg80211_chan_def *chandef,
1081			    bool offchan, gfp_t gfp)
1082{
1083	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
 
1084
1085	trace_cfg80211_radar_event(wiphy, chandef, offchan);
1086
1087	/* only set the chandef supplied channel to unavailable, in
1088	 * case the radar is detected on only one of multiple channels
1089	 * spanned by the chandef.
1090	 */
1091	cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_UNAVAILABLE);
1092
1093	if (offchan)
1094		queue_work(cfg80211_wq, &rdev->background_cac_abort_wk);
1095
1096	cfg80211_sched_dfs_chan_update(rdev);
1097
1098	nl80211_radar_notify(rdev, chandef, NL80211_RADAR_DETECTED, NULL, gfp);
1099
1100	memcpy(&rdev->radar_chandef, chandef, sizeof(struct cfg80211_chan_def));
1101	queue_work(cfg80211_wq, &rdev->propagate_radar_detect_wk);
1102}
1103EXPORT_SYMBOL(__cfg80211_radar_event);
1104
1105void cfg80211_cac_event(struct net_device *netdev,
1106			const struct cfg80211_chan_def *chandef,
1107			enum nl80211_radar_event event, gfp_t gfp,
1108			unsigned int link_id)
1109{
1110	struct wireless_dev *wdev = netdev->ieee80211_ptr;
1111	struct wiphy *wiphy = wdev->wiphy;
1112	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
1113	unsigned long timeout;
1114
1115	if (WARN_ON(wdev->valid_links &&
1116		    !(wdev->valid_links & BIT(link_id))))
 
1117		return;
1118
1119	trace_cfg80211_cac_event(netdev, event, link_id);
1120
1121	if (WARN_ON(!wdev->links[link_id].cac_started &&
1122		    event != NL80211_RADAR_CAC_STARTED))
1123		return;
1124
1125	switch (event) {
1126	case NL80211_RADAR_CAC_FINISHED:
1127		timeout = wdev->links[link_id].cac_start_time +
1128			  msecs_to_jiffies(wdev->links[link_id].cac_time_ms);
1129		WARN_ON(!time_after_eq(jiffies, timeout));
1130		cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);
1131		memcpy(&rdev->cac_done_chandef, chandef,
1132		       sizeof(struct cfg80211_chan_def));
1133		queue_work(cfg80211_wq, &rdev->propagate_cac_done_wk);
1134		cfg80211_sched_dfs_chan_update(rdev);
1135		fallthrough;
1136	case NL80211_RADAR_CAC_ABORTED:
1137		wdev->links[link_id].cac_started = false;
1138		break;
1139	case NL80211_RADAR_CAC_STARTED:
1140		wdev->links[link_id].cac_started = true;
1141		break;
1142	default:
1143		WARN_ON(1);
1144		return;
1145	}
 
1146
1147	nl80211_radar_notify(rdev, chandef, event, netdev, gfp);
1148}
1149EXPORT_SYMBOL(cfg80211_cac_event);
1150
1151static void
1152__cfg80211_background_cac_event(struct cfg80211_registered_device *rdev,
1153				struct wireless_dev *wdev,
1154				const struct cfg80211_chan_def *chandef,
1155				enum nl80211_radar_event event)
1156{
1157	struct wiphy *wiphy = &rdev->wiphy;
1158	struct net_device *netdev;
1159
1160	lockdep_assert_wiphy(&rdev->wiphy);
1161
1162	if (!cfg80211_chandef_valid(chandef))
1163		return;
1164
1165	if (!rdev->background_radar_wdev)
1166		return;
1167
1168	switch (event) {
1169	case NL80211_RADAR_CAC_FINISHED:
1170		cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);
1171		memcpy(&rdev->cac_done_chandef, chandef, sizeof(*chandef));
1172		queue_work(cfg80211_wq, &rdev->propagate_cac_done_wk);
1173		cfg80211_sched_dfs_chan_update(rdev);
1174		wdev = rdev->background_radar_wdev;
1175		break;
1176	case NL80211_RADAR_CAC_ABORTED:
1177		if (!cancel_delayed_work(&rdev->background_cac_done_wk))
1178			return;
1179		wdev = rdev->background_radar_wdev;
1180		break;
1181	case NL80211_RADAR_CAC_STARTED:
1182		break;
1183	default:
1184		return;
1185	}
1186
1187	netdev = wdev ? wdev->netdev : NULL;
1188	nl80211_radar_notify(rdev, chandef, event, netdev, GFP_KERNEL);
1189}
1190
1191static void
1192cfg80211_background_cac_event(struct cfg80211_registered_device *rdev,
1193			      const struct cfg80211_chan_def *chandef,
1194			      enum nl80211_radar_event event)
1195{
1196	wiphy_lock(&rdev->wiphy);
1197	__cfg80211_background_cac_event(rdev, rdev->background_radar_wdev,
1198					chandef, event);
1199	wiphy_unlock(&rdev->wiphy);
1200}
1201
1202void cfg80211_background_cac_done_wk(struct work_struct *work)
1203{
1204	struct delayed_work *delayed_work = to_delayed_work(work);
1205	struct cfg80211_registered_device *rdev;
1206
1207	rdev = container_of(delayed_work, struct cfg80211_registered_device,
1208			    background_cac_done_wk);
1209	cfg80211_background_cac_event(rdev, &rdev->background_radar_chandef,
1210				      NL80211_RADAR_CAC_FINISHED);
1211}
1212
1213void cfg80211_background_cac_abort_wk(struct work_struct *work)
1214{
1215	struct cfg80211_registered_device *rdev;
1216
1217	rdev = container_of(work, struct cfg80211_registered_device,
1218			    background_cac_abort_wk);
1219	cfg80211_background_cac_event(rdev, &rdev->background_radar_chandef,
1220				      NL80211_RADAR_CAC_ABORTED);
1221}
1222
1223void cfg80211_background_cac_abort(struct wiphy *wiphy)
1224{
1225	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
1226
1227	queue_work(cfg80211_wq, &rdev->background_cac_abort_wk);
1228}
1229EXPORT_SYMBOL(cfg80211_background_cac_abort);
1230
1231int
1232cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rdev,
1233					  struct wireless_dev *wdev,
1234					  struct cfg80211_chan_def *chandef)
1235{
1236	unsigned int cac_time_ms;
1237	int err;
1238
1239	lockdep_assert_wiphy(&rdev->wiphy);
1240
1241	if (!wiphy_ext_feature_isset(&rdev->wiphy,
1242				     NL80211_EXT_FEATURE_RADAR_BACKGROUND))
1243		return -EOPNOTSUPP;
1244
1245	/* Offchannel chain already locked by another wdev */
1246	if (rdev->background_radar_wdev && rdev->background_radar_wdev != wdev)
1247		return -EBUSY;
1248
1249	/* CAC already in progress on the offchannel chain */
1250	if (rdev->background_radar_wdev == wdev &&
1251	    delayed_work_pending(&rdev->background_cac_done_wk))
1252		return -EBUSY;
1253
1254	err = rdev_set_radar_background(rdev, chandef);
1255	if (err)
1256		return err;
1257
1258	cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, chandef);
1259	if (!cac_time_ms)
1260		cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
1261
1262	rdev->background_radar_chandef = *chandef;
1263	rdev->background_radar_wdev = wdev; /* Get offchain ownership */
1264
1265	__cfg80211_background_cac_event(rdev, wdev, chandef,
1266					NL80211_RADAR_CAC_STARTED);
1267	queue_delayed_work(cfg80211_wq, &rdev->background_cac_done_wk,
1268			   msecs_to_jiffies(cac_time_ms));
1269
1270	return 0;
1271}
1272
1273void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev)
1274{
1275	struct wiphy *wiphy = wdev->wiphy;
1276	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
1277
1278	lockdep_assert_wiphy(wiphy);
1279
1280	if (wdev != rdev->background_radar_wdev)
1281		return;
1282
1283	rdev_set_radar_background(rdev, NULL);
1284	rdev->background_radar_wdev = NULL; /* Release offchain ownership */
1285
1286	__cfg80211_background_cac_event(rdev, wdev,
1287					&rdev->background_radar_chandef,
1288					NL80211_RADAR_CAC_ABORTED);
1289}