Linux Audio

Check our new training course

Loading...
v3.1
 
   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/netdevice.h>
  10#include <linux/nl80211.h>
  11#include <linux/slab.h>
  12#include <linux/wireless.h>
  13#include <net/cfg80211.h>
  14#include <net/iw_handler.h>
  15#include "core.h"
  16#include "nl80211.h"
 
  17
  18void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len)
  19{
  20	struct wireless_dev *wdev = dev->ieee80211_ptr;
  21	struct wiphy *wiphy = wdev->wiphy;
  22	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
  23	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
  24	u8 *bssid = mgmt->bssid;
  25	int i;
  26	u16 status = le16_to_cpu(mgmt->u.auth.status_code);
  27	bool done = false;
  28
  29	wdev_lock(wdev);
  30
  31	for (i = 0; i < MAX_AUTH_BSSES; i++) {
  32		if (wdev->authtry_bsses[i] &&
  33		    memcmp(wdev->authtry_bsses[i]->pub.bssid, bssid,
  34							ETH_ALEN) == 0) {
  35			if (status == WLAN_STATUS_SUCCESS) {
  36				wdev->auth_bsses[i] = wdev->authtry_bsses[i];
  37			} else {
  38				cfg80211_unhold_bss(wdev->authtry_bsses[i]);
  39				cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
  40			}
  41			wdev->authtry_bsses[i] = NULL;
  42			done = true;
  43			break;
  44		}
  45	}
  46
  47	if (done) {
  48		nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL);
  49		cfg80211_sme_rx_auth(dev, buf, len);
  50	}
  51
  52	wdev_unlock(wdev);
  53}
  54EXPORT_SYMBOL(cfg80211_send_rx_auth);
  55
  56void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
  57{
  58	u16 status_code;
  59	struct wireless_dev *wdev = dev->ieee80211_ptr;
  60	struct wiphy *wiphy = wdev->wiphy;
  61	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
  62	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
  63	u8 *ie = mgmt->u.assoc_resp.variable;
  64	int i, ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
  65	struct cfg80211_internal_bss *bss = NULL;
  66
  67	wdev_lock(wdev);
 
 
 
 
 
 
 
 
 
  68
  69	status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
  70
  71	/*
  72	 * This is a bit of a hack, we don't notify userspace of
  73	 * a (re-)association reply if we tried to send a reassoc
  74	 * and got a reject -- we only try again with an assoc
  75	 * frame instead of reassoc.
  76	 */
  77	if (status_code != WLAN_STATUS_SUCCESS && wdev->conn &&
  78	    cfg80211_sme_failed_reassoc(wdev))
  79		goto out;
  80
  81	nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL);
  82
  83	if (status_code == WLAN_STATUS_SUCCESS) {
  84		for (i = 0; i < MAX_AUTH_BSSES; i++) {
  85			if (!wdev->auth_bsses[i])
  86				continue;
  87			if (memcmp(wdev->auth_bsses[i]->pub.bssid, mgmt->bssid,
  88				   ETH_ALEN) == 0) {
  89				bss = wdev->auth_bsses[i];
  90				wdev->auth_bsses[i] = NULL;
  91				/* additional reference to drop hold */
  92				cfg80211_ref_bss(bss);
  93				break;
  94			}
  95		}
  96
  97		/*
  98		 * We might be coming here because the driver reported
  99		 * a successful association at the same time as the
 100		 * user requested a deauth. In that case, we will have
 101		 * removed the BSS from the auth_bsses list due to the
 102		 * deauth request when the assoc response makes it. If
 103		 * the two code paths acquire the lock the other way
 104		 * around, that's just the standard situation of a
 105		 * deauth being requested while connected.
 106		 */
 107		if (!bss)
 108			goto out;
 109	} else if (wdev->conn) {
 110		cfg80211_sme_failed_assoc(wdev);
 111		/*
 112		 * do not call connect_result() now because the
 113		 * sme will schedule work that does it later.
 114		 */
 115		goto out;
 116	}
 117
 118	if (!wdev->conn && wdev->sme_state == CFG80211_SME_IDLE) {
 119		/*
 120		 * This is for the userspace SME, the CONNECTING
 121		 * state will be changed to CONNECTED by
 122		 * __cfg80211_connect_result() below.
 123		 */
 124		wdev->sme_state = CFG80211_SME_CONNECTING;
 125	}
 126
 127	/* this consumes one bss reference (unless bss is NULL) */
 128	__cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
 129				  status_code,
 130				  status_code == WLAN_STATUS_SUCCESS,
 131				  bss ? &bss->pub : NULL);
 132	/* drop hold now, and also reference acquired above */
 133	if (bss) {
 134		cfg80211_unhold_bss(bss);
 135		cfg80211_put_bss(&bss->pub);
 136	}
 137
 138 out:
 139	wdev_unlock(wdev);
 140}
 141EXPORT_SYMBOL(cfg80211_send_rx_assoc);
 142
 143void __cfg80211_send_deauth(struct net_device *dev,
 144				   const u8 *buf, size_t len)
 145{
 146	struct wireless_dev *wdev = dev->ieee80211_ptr;
 147	struct wiphy *wiphy = wdev->wiphy;
 148	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 149	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
 150	const u8 *bssid = mgmt->bssid;
 151	int i;
 152	bool found = false, was_current = false;
 153
 154	ASSERT_WDEV_LOCK(wdev);
 155
 156	if (wdev->current_bss &&
 157	    memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
 158		cfg80211_unhold_bss(wdev->current_bss);
 159		cfg80211_put_bss(&wdev->current_bss->pub);
 160		wdev->current_bss = NULL;
 161		found = true;
 162		was_current = true;
 163	} else for (i = 0; i < MAX_AUTH_BSSES; i++) {
 164		if (wdev->auth_bsses[i] &&
 165		    memcmp(wdev->auth_bsses[i]->pub.bssid, bssid, ETH_ALEN) == 0) {
 166			cfg80211_unhold_bss(wdev->auth_bsses[i]);
 167			cfg80211_put_bss(&wdev->auth_bsses[i]->pub);
 168			wdev->auth_bsses[i] = NULL;
 169			found = true;
 170			break;
 171		}
 172		if (wdev->authtry_bsses[i] &&
 173		    memcmp(wdev->authtry_bsses[i]->pub.bssid, bssid,
 174			   ETH_ALEN) == 0 &&
 175		    memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) == 0) {
 176			cfg80211_unhold_bss(wdev->authtry_bsses[i]);
 177			cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
 178			wdev->authtry_bsses[i] = NULL;
 179			found = true;
 180			break;
 181		}
 182	}
 183
 184	if (!found)
 
 185		return;
 186
 187	nl80211_send_deauth(rdev, dev, buf, len, GFP_KERNEL);
 188
 189	if (wdev->sme_state == CFG80211_SME_CONNECTED && was_current) {
 190		u16 reason_code;
 191		bool from_ap;
 192
 193		reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
 194
 195		from_ap = memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0;
 196		__cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
 197	} else if (wdev->sme_state == CFG80211_SME_CONNECTING) {
 198		__cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0,
 199					  WLAN_STATUS_UNSPECIFIED_FAILURE,
 200					  false, NULL);
 201	}
 202}
 203EXPORT_SYMBOL(__cfg80211_send_deauth);
 204
 205void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len)
 
 206{
 207	struct wireless_dev *wdev = dev->ieee80211_ptr;
 208
 209	wdev_lock(wdev);
 210	__cfg80211_send_deauth(dev, buf, len);
 211	wdev_unlock(wdev);
 212}
 213EXPORT_SYMBOL(cfg80211_send_deauth);
 214
 215void __cfg80211_send_disassoc(struct net_device *dev,
 216				     const u8 *buf, size_t len)
 217{
 218	struct wireless_dev *wdev = dev->ieee80211_ptr;
 219	struct wiphy *wiphy = wdev->wiphy;
 220	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 221	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
 222	const u8 *bssid = mgmt->bssid;
 223	int i;
 224	u16 reason_code;
 225	bool from_ap;
 226	bool done = false;
 227
 228	ASSERT_WDEV_LOCK(wdev);
 229
 230	nl80211_send_disassoc(rdev, dev, buf, len, GFP_KERNEL);
 231
 232	if (wdev->sme_state != CFG80211_SME_CONNECTED)
 
 233		return;
 234
 235	if (wdev->current_bss &&
 236	    memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
 237		for (i = 0; i < MAX_AUTH_BSSES; i++) {
 238			if (wdev->authtry_bsses[i] || wdev->auth_bsses[i])
 239				continue;
 240			wdev->auth_bsses[i] = wdev->current_bss;
 241			wdev->current_bss = NULL;
 242			done = true;
 243			cfg80211_sme_disassoc(dev, i);
 244			break;
 245		}
 246		WARN_ON(!done);
 247	} else
 248		WARN_ON(1);
 249
 250
 251	reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
 252
 253	from_ap = memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0;
 254	__cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
 255}
 256EXPORT_SYMBOL(__cfg80211_send_disassoc);
 257
 258void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len)
 259{
 260	struct wireless_dev *wdev = dev->ieee80211_ptr;
 
 
 
 
 
 
 
 
 261
 262	wdev_lock(wdev);
 263	__cfg80211_send_disassoc(dev, buf, len);
 264	wdev_unlock(wdev);
 
 
 
 265}
 266EXPORT_SYMBOL(cfg80211_send_disassoc);
 267
 268void cfg80211_send_unprot_deauth(struct net_device *dev, const u8 *buf,
 269				 size_t len)
 270{
 271	struct wireless_dev *wdev = dev->ieee80211_ptr;
 272	struct wiphy *wiphy = wdev->wiphy;
 273	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 
 
 274
 275	nl80211_send_unprot_deauth(rdev, dev, buf, len, GFP_ATOMIC);
 
 276}
 277EXPORT_SYMBOL(cfg80211_send_unprot_deauth);
 278
 279void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf,
 280				   size_t len)
 281{
 282	struct wireless_dev *wdev = dev->ieee80211_ptr;
 283	struct wiphy *wiphy = wdev->wiphy;
 284	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 285
 286	nl80211_send_unprot_disassoc(rdev, dev, buf, len, GFP_ATOMIC);
 287}
 288EXPORT_SYMBOL(cfg80211_send_unprot_disassoc);
 289
 290static void __cfg80211_auth_remove(struct wireless_dev *wdev, const u8 *addr)
 291{
 292	int i;
 293	bool done = false;
 294
 295	ASSERT_WDEV_LOCK(wdev);
 
 296
 297	for (i = 0; addr && i < MAX_AUTH_BSSES; i++) {
 298		if (wdev->authtry_bsses[i] &&
 299		    memcmp(wdev->authtry_bsses[i]->pub.bssid,
 300			   addr, ETH_ALEN) == 0) {
 301			cfg80211_unhold_bss(wdev->authtry_bsses[i]);
 302			cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
 303			wdev->authtry_bsses[i] = NULL;
 304			done = true;
 305			break;
 306		}
 307	}
 308
 309	WARN_ON(!done);
 310}
 311
 312void __cfg80211_auth_canceled(struct net_device *dev, const u8 *addr)
 313{
 314	__cfg80211_auth_remove(dev->ieee80211_ptr, addr);
 315}
 316EXPORT_SYMBOL(__cfg80211_auth_canceled);
 317
 318void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
 319{
 320	struct wireless_dev *wdev = dev->ieee80211_ptr;
 321	struct wiphy *wiphy = wdev->wiphy;
 322	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 323
 324	wdev_lock(wdev);
 325
 326	nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL);
 327	if (wdev->sme_state == CFG80211_SME_CONNECTING)
 328		__cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
 329					  WLAN_STATUS_UNSPECIFIED_FAILURE,
 330					  false, NULL);
 331
 332	__cfg80211_auth_remove(wdev, addr);
 333
 334	wdev_unlock(wdev);
 335}
 336EXPORT_SYMBOL(cfg80211_send_auth_timeout);
 337
 338void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr)
 339{
 340	struct wireless_dev *wdev = dev->ieee80211_ptr;
 341	struct wiphy *wiphy = wdev->wiphy;
 342	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 343	int i;
 344	bool done = false;
 345
 346	wdev_lock(wdev);
 347
 348	nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL);
 349	if (wdev->sme_state == CFG80211_SME_CONNECTING)
 350		__cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
 351					  WLAN_STATUS_UNSPECIFIED_FAILURE,
 352					  false, NULL);
 353
 354	for (i = 0; addr && i < MAX_AUTH_BSSES; i++) {
 355		if (wdev->auth_bsses[i] &&
 356		    memcmp(wdev->auth_bsses[i]->pub.bssid,
 357			   addr, ETH_ALEN) == 0) {
 358			cfg80211_unhold_bss(wdev->auth_bsses[i]);
 359			cfg80211_put_bss(&wdev->auth_bsses[i]->pub);
 360			wdev->auth_bsses[i] = NULL;
 361			done = true;
 362			break;
 363		}
 364	}
 365
 366	WARN_ON(!done);
 
 367
 368	wdev_unlock(wdev);
 
 
 
 369}
 370EXPORT_SYMBOL(cfg80211_send_assoc_timeout);
 371
 372void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
 373				  enum nl80211_key_type key_type, int key_id,
 374				  const u8 *tsc, gfp_t gfp)
 375{
 376	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
 377	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 378#ifdef CONFIG_CFG80211_WEXT
 379	union iwreq_data wrqu;
 380	char *buf = kmalloc(128, gfp);
 381
 382	if (buf) {
 383		sprintf(buf, "MLME-MICHAELMICFAILURE.indication("
 384			"keyid=%d %scast addr=%pM)", key_id,
 385			key_type == NL80211_KEYTYPE_GROUP ? "broad" : "uni",
 386			addr);
 387		memset(&wrqu, 0, sizeof(wrqu));
 388		wrqu.data.length = strlen(buf);
 389		wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
 390		kfree(buf);
 391	}
 392#endif
 393
 
 394	nl80211_michael_mic_failure(rdev, dev, addr, key_type, key_id, tsc, gfp);
 395}
 396EXPORT_SYMBOL(cfg80211_michael_mic_failure);
 397
 398/* some MLME handling for userspace SME */
 399int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
 400			 struct net_device *dev,
 401			 struct ieee80211_channel *chan,
 402			 enum nl80211_auth_type auth_type,
 403			 const u8 *bssid,
 404			 const u8 *ssid, int ssid_len,
 405			 const u8 *ie, int ie_len,
 406			 const u8 *key, int key_len, int key_idx,
 407			 bool local_state_change)
 408{
 409	struct wireless_dev *wdev = dev->ieee80211_ptr;
 410	struct cfg80211_auth_request req;
 411	struct cfg80211_internal_bss *bss;
 412	int i, err, slot = -1, nfree = 0;
 
 
 
 
 
 
 
 
 413
 414	ASSERT_WDEV_LOCK(wdev);
 415
 416	if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
 417		if (!key || !key_len || key_idx < 0 || key_idx > 4)
 418			return -EINVAL;
 419
 420	if (wdev->current_bss &&
 421	    memcmp(bssid, wdev->current_bss->pub.bssid, ETH_ALEN) == 0)
 422		return -EALREADY;
 423
 424	for (i = 0; i < MAX_AUTH_BSSES; i++) {
 425		if (wdev->authtry_bsses[i] &&
 426		    memcmp(bssid, wdev->authtry_bsses[i]->pub.bssid,
 427						ETH_ALEN) == 0)
 428			return -EALREADY;
 429		if (wdev->auth_bsses[i] &&
 430		    memcmp(bssid, wdev->auth_bsses[i]->pub.bssid,
 431						ETH_ALEN) == 0)
 432			return -EALREADY;
 433	}
 434
 435	memset(&req, 0, sizeof(req));
 436
 437	req.local_state_change = local_state_change;
 438	req.ie = ie;
 439	req.ie_len = ie_len;
 440	req.auth_type = auth_type;
 441	req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
 442				   WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
 443	req.key = key;
 444	req.key_len = key_len;
 445	req.key_idx = key_idx;
 446	if (!req.bss)
 447		return -ENOENT;
 448
 449	bss = bss_from_pub(req.bss);
 450
 451	for (i = 0; i < MAX_AUTH_BSSES; i++) {
 452		if (!wdev->auth_bsses[i] && !wdev->authtry_bsses[i]) {
 453			slot = i;
 454			nfree++;
 455		}
 456	}
 457
 458	/* we need one free slot for disassoc and one for this auth */
 459	if (nfree < 2) {
 460		err = -ENOSPC;
 461		goto out;
 462	}
 463
 464	if (local_state_change)
 465		wdev->auth_bsses[slot] = bss;
 466	else
 467		wdev->authtry_bsses[slot] = bss;
 468	cfg80211_hold_bss(bss);
 469
 470	err = rdev->ops->auth(&rdev->wiphy, dev, &req);
 471	if (err) {
 472		if (local_state_change)
 473			wdev->auth_bsses[slot] = NULL;
 474		else
 475			wdev->authtry_bsses[slot] = NULL;
 476		cfg80211_unhold_bss(bss);
 477	}
 478
 479 out:
 480	if (err)
 481		cfg80211_put_bss(req.bss);
 482	return err;
 483}
 484
 485int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
 486		       struct net_device *dev, struct ieee80211_channel *chan,
 487		       enum nl80211_auth_type auth_type, const u8 *bssid,
 488		       const u8 *ssid, int ssid_len,
 489		       const u8 *ie, int ie_len,
 490		       const u8 *key, int key_len, int key_idx,
 491		       bool local_state_change)
 492{
 493	int err;
 494
 495	wdev_lock(dev->ieee80211_ptr);
 496	err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
 497				   ssid, ssid_len, ie, ie_len,
 498				   key, key_len, key_idx, local_state_change);
 499	wdev_unlock(dev->ieee80211_ptr);
 500
 501	return err;
 
 
 
 502}
 503
 504int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
 505			  struct net_device *dev,
 506			  struct ieee80211_channel *chan,
 507			  const u8 *bssid, const u8 *prev_bssid,
 508			  const u8 *ssid, int ssid_len,
 509			  const u8 *ie, int ie_len, bool use_mfp,
 510			  struct cfg80211_crypto_settings *crypt)
 511{
 512	struct wireless_dev *wdev = dev->ieee80211_ptr;
 513	struct cfg80211_assoc_request req;
 514	struct cfg80211_internal_bss *bss;
 515	int i, err, slot = -1;
 516	bool was_connected = false;
 517
 518	ASSERT_WDEV_LOCK(wdev);
 519
 520	memset(&req, 0, sizeof(req));
 521
 522	if (wdev->current_bss && prev_bssid &&
 523	    memcmp(wdev->current_bss->pub.bssid, prev_bssid, ETH_ALEN) == 0) {
 524		/*
 525		 * Trying to reassociate: Allow this to proceed and let the old
 526		 * association to be dropped when the new one is completed.
 527		 */
 528		if (wdev->sme_state == CFG80211_SME_CONNECTED) {
 529			was_connected = true;
 530			wdev->sme_state = CFG80211_SME_CONNECTING;
 531		}
 532	} else if (wdev->current_bss)
 533		return -EALREADY;
 534
 535	req.ie = ie;
 536	req.ie_len = ie_len;
 537	memcpy(&req.crypto, crypt, sizeof(req.crypto));
 538	req.use_mfp = use_mfp;
 539	req.prev_bssid = prev_bssid;
 540	req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
 541				   WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
 542	if (!req.bss) {
 543		if (was_connected)
 544			wdev->sme_state = CFG80211_SME_CONNECTED;
 545		return -ENOENT;
 546	}
 547
 548	bss = bss_from_pub(req.bss);
 549
 550	for (i = 0; i < MAX_AUTH_BSSES; i++) {
 551		if (bss == wdev->auth_bsses[i]) {
 552			slot = i;
 553			break;
 554		}
 555	}
 556
 557	if (slot < 0) {
 558		err = -ENOTCONN;
 559		goto out;
 560	}
 561
 562	err = rdev->ops->assoc(&rdev->wiphy, dev, &req);
 563 out:
 564	if (err && was_connected)
 565		wdev->sme_state = CFG80211_SME_CONNECTED;
 566	/* still a reference in wdev->auth_bsses[slot] */
 567	cfg80211_put_bss(req.bss);
 568	return err;
 569}
 570
 571int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
 572			struct net_device *dev,
 573			struct ieee80211_channel *chan,
 574			const u8 *bssid, const u8 *prev_bssid,
 575			const u8 *ssid, int ssid_len,
 576			const u8 *ie, int ie_len, bool use_mfp,
 577			struct cfg80211_crypto_settings *crypt)
 578{
 579	struct wireless_dev *wdev = dev->ieee80211_ptr;
 580	int err;
 581
 582	wdev_lock(wdev);
 583	err = __cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid,
 584				    ssid, ssid_len, ie, ie_len, use_mfp, crypt);
 585	wdev_unlock(wdev);
 586
 587	return err;
 588}
 589
 590int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
 591			   struct net_device *dev, const u8 *bssid,
 592			   const u8 *ie, int ie_len, u16 reason,
 593			   bool local_state_change)
 594{
 595	struct wireless_dev *wdev = dev->ieee80211_ptr;
 596	struct cfg80211_deauth_request req;
 597	int i;
 598
 599	ASSERT_WDEV_LOCK(wdev);
 600
 601	memset(&req, 0, sizeof(req));
 602	req.reason_code = reason;
 603	req.local_state_change = local_state_change;
 604	req.ie = ie;
 605	req.ie_len = ie_len;
 606	if (wdev->current_bss &&
 607	    memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
 608		req.bss = &wdev->current_bss->pub;
 609	} else for (i = 0; i < MAX_AUTH_BSSES; i++) {
 610		if (wdev->auth_bsses[i] &&
 611		    memcmp(bssid, wdev->auth_bsses[i]->pub.bssid, ETH_ALEN) == 0) {
 612			req.bss = &wdev->auth_bsses[i]->pub;
 613			break;
 614		}
 615		if (wdev->authtry_bsses[i] &&
 616		    memcmp(bssid, wdev->authtry_bsses[i]->pub.bssid, ETH_ALEN) == 0) {
 617			req.bss = &wdev->authtry_bsses[i]->pub;
 618			break;
 619		}
 620	}
 621
 622	if (!req.bss)
 623		return -ENOTCONN;
 
 
 
 
 
 
 
 
 624
 625	return rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
 
 
 
 
 
 
 626}
 627
 628int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
 629			 struct net_device *dev, const u8 *bssid,
 630			 const u8 *ie, int ie_len, u16 reason,
 631			 bool local_state_change)
 632{
 633	struct wireless_dev *wdev = dev->ieee80211_ptr;
 634	int err;
 
 
 
 
 
 
 635
 636	wdev_lock(wdev);
 637	err = __cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason,
 638				     local_state_change);
 639	wdev_unlock(wdev);
 640
 641	return err;
 
 
 
 
 
 
 
 
 
 
 642}
 643
 644static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
 645				    struct net_device *dev, const u8 *bssid,
 646				    const u8 *ie, int ie_len, u16 reason,
 647				    bool local_state_change)
 648{
 649	struct wireless_dev *wdev = dev->ieee80211_ptr;
 650	struct cfg80211_disassoc_request req;
 
 
 
 
 
 
 651
 652	ASSERT_WDEV_LOCK(wdev);
 653
 654	if (wdev->sme_state != CFG80211_SME_CONNECTED)
 655		return -ENOTCONN;
 656
 657	if (WARN_ON(!wdev->current_bss))
 658		return -ENOTCONN;
 659
 660	memset(&req, 0, sizeof(req));
 661	req.reason_code = reason;
 662	req.local_state_change = local_state_change;
 663	req.ie = ie;
 664	req.ie_len = ie_len;
 665	if (memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0)
 666		req.bss = &wdev->current_bss->pub;
 667	else
 668		return -ENOTCONN;
 669
 670	return rdev->ops->disassoc(&rdev->wiphy, dev, &req, wdev);
 671}
 672
 673int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
 674			   struct net_device *dev, const u8 *bssid,
 675			   const u8 *ie, int ie_len, u16 reason,
 676			   bool local_state_change)
 677{
 678	struct wireless_dev *wdev = dev->ieee80211_ptr;
 679	int err;
 680
 681	wdev_lock(wdev);
 682	err = __cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason,
 683				       local_state_change);
 684	wdev_unlock(wdev);
 685
 686	return err;
 
 
 687}
 688
 689void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
 690			struct net_device *dev)
 691{
 692	struct wireless_dev *wdev = dev->ieee80211_ptr;
 693	struct cfg80211_deauth_request req;
 694	int i;
 695
 696	ASSERT_WDEV_LOCK(wdev);
 697
 698	if (!rdev->ops->deauth)
 699		return;
 700
 701	memset(&req, 0, sizeof(req));
 702	req.reason_code = WLAN_REASON_DEAUTH_LEAVING;
 703	req.ie = NULL;
 704	req.ie_len = 0;
 705
 706	if (wdev->current_bss) {
 707		req.bss = &wdev->current_bss->pub;
 708		rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
 709		if (wdev->current_bss) {
 710			cfg80211_unhold_bss(wdev->current_bss);
 711			cfg80211_put_bss(&wdev->current_bss->pub);
 712			wdev->current_bss = NULL;
 713		}
 714	}
 715
 716	for (i = 0; i < MAX_AUTH_BSSES; i++) {
 717		if (wdev->auth_bsses[i]) {
 718			req.bss = &wdev->auth_bsses[i]->pub;
 719			rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
 720			if (wdev->auth_bsses[i]) {
 721				cfg80211_unhold_bss(wdev->auth_bsses[i]);
 722				cfg80211_put_bss(&wdev->auth_bsses[i]->pub);
 723				wdev->auth_bsses[i] = NULL;
 724			}
 725		}
 726		if (wdev->authtry_bsses[i]) {
 727			req.bss = &wdev->authtry_bsses[i]->pub;
 728			rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
 729			if (wdev->authtry_bsses[i]) {
 730				cfg80211_unhold_bss(wdev->authtry_bsses[i]);
 731				cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
 732				wdev->authtry_bsses[i] = NULL;
 733			}
 734		}
 735	}
 736}
 737
 738void cfg80211_ready_on_channel(struct net_device *dev, u64 cookie,
 739			       struct ieee80211_channel *chan,
 740			       enum nl80211_channel_type channel_type,
 741			       unsigned int duration, gfp_t gfp)
 742{
 743	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
 744	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 745
 746	nl80211_send_remain_on_channel(rdev, dev, cookie, chan, channel_type,
 747				       duration, gfp);
 748}
 749EXPORT_SYMBOL(cfg80211_ready_on_channel);
 750
 751void cfg80211_remain_on_channel_expired(struct net_device *dev,
 752					u64 cookie,
 753					struct ieee80211_channel *chan,
 754					enum nl80211_channel_type channel_type,
 755					gfp_t gfp)
 756{
 757	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
 758	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 759
 760	nl80211_send_remain_on_channel_cancel(rdev, dev, cookie, chan,
 761					      channel_type, gfp);
 762}
 763EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
 764
 765void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
 766		      struct station_info *sinfo, gfp_t gfp)
 767{
 768	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
 769	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 770
 771	nl80211_send_sta_event(rdev, dev, mac_addr, sinfo, gfp);
 772}
 773EXPORT_SYMBOL(cfg80211_new_sta);
 774
 775void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp)
 776{
 777	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
 778	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 
 
 779
 780	nl80211_send_sta_del_event(rdev, dev, mac_addr, gfp);
 781}
 782EXPORT_SYMBOL(cfg80211_del_sta);
 783
 784struct cfg80211_mgmt_registration {
 785	struct list_head list;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 786
 787	u32 nlpid;
 
 788
 789	int match_len;
 
 790
 791	__le16 frame_type;
 
 
 
 792
 793	u8 match[];
 794};
 
 
 
 
 
 
 795
 796int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid,
 797				u16 frame_type, const u8 *match_data,
 798				int match_len)
 
 799{
 800	struct wiphy *wiphy = wdev->wiphy;
 801	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 802	struct cfg80211_mgmt_registration *reg, *nreg;
 803	int err = 0;
 804	u16 mgmt_type;
 
 805
 806	if (!wdev->wiphy->mgmt_stypes)
 807		return -EOPNOTSUPP;
 808
 809	if ((frame_type & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT)
 
 810		return -EINVAL;
 
 811
 812	if (frame_type & ~(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE))
 
 813		return -EINVAL;
 
 814
 815	mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
 816	if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].rx & BIT(mgmt_type)))
 
 
 817		return -EINVAL;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 818
 819	nreg = kzalloc(sizeof(*reg) + match_len, GFP_KERNEL);
 820	if (!nreg)
 821		return -ENOMEM;
 822
 823	spin_lock_bh(&wdev->mgmt_registrations_lock);
 824
 825	list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
 826		int mlen = min(match_len, reg->match_len);
 827
 828		if (frame_type != le16_to_cpu(reg->frame_type))
 829			continue;
 830
 831		if (memcmp(reg->match, match_data, mlen) == 0) {
 
 
 
 
 
 
 832			err = -EALREADY;
 833			break;
 834		}
 835	}
 836
 837	if (err) {
 838		kfree(nreg);
 839		goto out;
 
 
 
 
 
 
 
 
 
 
 
 840	}
 
 
 841
 842	memcpy(nreg->match, match_data, match_len);
 843	nreg->match_len = match_len;
 844	nreg->nlpid = snd_pid;
 845	nreg->frame_type = cpu_to_le16(frame_type);
 846	list_add(&nreg->list, &wdev->mgmt_registrations);
 847
 848	if (rdev->ops->mgmt_frame_register)
 849		rdev->ops->mgmt_frame_register(wiphy, wdev->netdev,
 850					       frame_type, true);
 851
 852 out:
 
 853	spin_unlock_bh(&wdev->mgmt_registrations_lock);
 854
 855	return err;
 856}
 857
 858void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid)
 859{
 860	struct wiphy *wiphy = wdev->wiphy;
 861	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 862	struct cfg80211_mgmt_registration *reg, *tmp;
 863
 864	spin_lock_bh(&wdev->mgmt_registrations_lock);
 865
 866	list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
 867		if (reg->nlpid != nlpid)
 868			continue;
 869
 870		if (rdev->ops->mgmt_frame_register) {
 871			u16 frame_type = le16_to_cpu(reg->frame_type);
 872
 873			rdev->ops->mgmt_frame_register(wiphy, wdev->netdev,
 874						       frame_type, false);
 875		}
 876
 877		list_del(&reg->list);
 878		kfree(reg);
 
 
 
 879	}
 880
 881	spin_unlock_bh(&wdev->mgmt_registrations_lock);
 
 
 
 
 
 
 
 
 882}
 883
 884void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
 885{
 886	struct cfg80211_mgmt_registration *reg, *tmp;
 887
 888	spin_lock_bh(&wdev->mgmt_registrations_lock);
 889
 890	list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
 891		list_del(&reg->list);
 892		kfree(reg);
 893	}
 894
 895	spin_unlock_bh(&wdev->mgmt_registrations_lock);
 
 
 896}
 897
 898int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
 899			  struct net_device *dev,
 900			  struct ieee80211_channel *chan, bool offchan,
 901			  enum nl80211_channel_type channel_type,
 902			  bool channel_type_valid, unsigned int wait,
 903			  const u8 *buf, size_t len, u64 *cookie)
 904{
 905	struct wireless_dev *wdev = dev->ieee80211_ptr;
 906	const struct ieee80211_mgmt *mgmt;
 907	u16 stype;
 908
 909	if (!wdev->wiphy->mgmt_stypes)
 910		return -EOPNOTSUPP;
 911
 912	if (!rdev->ops->mgmt_tx)
 913		return -EOPNOTSUPP;
 914
 915	if (len < 24 + 1)
 916		return -EINVAL;
 917
 918	mgmt = (const struct ieee80211_mgmt *) buf;
 919
 920	if (!ieee80211_is_mgmt(mgmt->frame_control))
 921		return -EINVAL;
 922
 923	stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
 924	if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].tx & BIT(stype >> 4)))
 925		return -EINVAL;
 926
 927	if (ieee80211_is_action(mgmt->frame_control) &&
 928	    mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) {
 929		int err = 0;
 930
 931		wdev_lock(wdev);
 932
 933		switch (wdev->iftype) {
 934		case NL80211_IFTYPE_ADHOC:
 935		case NL80211_IFTYPE_STATION:
 936		case NL80211_IFTYPE_P2P_CLIENT:
 937			if (!wdev->current_bss) {
 938				err = -ENOTCONN;
 939				break;
 940			}
 941
 942			if (memcmp(wdev->current_bss->pub.bssid,
 943				   mgmt->bssid, ETH_ALEN)) {
 944				err = -ENOTCONN;
 945				break;
 946			}
 947
 948			/*
 949			 * check for IBSS DA must be done by driver as
 950			 * cfg80211 doesn't track the stations
 951			 */
 952			if (wdev->iftype == NL80211_IFTYPE_ADHOC)
 953				break;
 954
 955			/* for station, check that DA is the AP */
 956			if (memcmp(wdev->current_bss->pub.bssid,
 957				   mgmt->da, ETH_ALEN)) {
 958				err = -ENOTCONN;
 959				break;
 960			}
 961			break;
 962		case NL80211_IFTYPE_AP:
 963		case NL80211_IFTYPE_P2P_GO:
 964		case NL80211_IFTYPE_AP_VLAN:
 965			if (memcmp(mgmt->bssid, dev->dev_addr, ETH_ALEN))
 966				err = -EINVAL;
 967			break;
 968		case NL80211_IFTYPE_MESH_POINT:
 969			if (memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN)) {
 970				err = -EINVAL;
 971				break;
 972			}
 973			/*
 974			 * check for mesh DA must be done by driver as
 975			 * cfg80211 doesn't track the stations
 976			 */
 977			break;
 
 
 
 
 
 
 978		default:
 979			err = -EOPNOTSUPP;
 980			break;
 981		}
 982		wdev_unlock(wdev);
 983
 984		if (err)
 985			return err;
 986	}
 987
 988	if (memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0)
 989		return -EINVAL;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 990
 991	/* Transmit the Action frame as requested by user space */
 992	return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, offchan,
 993				  channel_type, channel_type_valid,
 994				  wait, buf, len, cookie);
 995}
 996
 997bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf,
 998		      size_t len, gfp_t gfp)
 999{
1000	struct wireless_dev *wdev = dev->ieee80211_ptr;
1001	struct wiphy *wiphy = wdev->wiphy;
1002	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
1003	struct cfg80211_mgmt_registration *reg;
1004	const struct ieee80211_txrx_stypes *stypes =
1005		&wiphy->mgmt_stypes[wdev->iftype];
1006	struct ieee80211_mgmt *mgmt = (void *)buf;
1007	const u8 *data;
1008	int data_len;
1009	bool result = false;
1010	__le16 ftype = mgmt->frame_control &
1011		cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE);
1012	u16 stype;
1013
 
1014	stype = (le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) >> 4;
1015
1016	if (!(stypes->rx & BIT(stype)))
 
1017		return false;
 
1018
1019	data = buf + ieee80211_hdrlen(mgmt->frame_control);
1020	data_len = len - ieee80211_hdrlen(mgmt->frame_control);
1021
1022	spin_lock_bh(&wdev->mgmt_registrations_lock);
1023
1024	list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
1025		if (reg->frame_type != ftype)
1026			continue;
1027
1028		if (reg->match_len > data_len)
1029			continue;
1030
1031		if (memcmp(reg->match, data, reg->match_len))
1032			continue;
1033
1034		/* found match! */
1035
1036		/* Indicate the received Action frame to user space */
1037		if (nl80211_send_mgmt(rdev, dev, reg->nlpid, freq,
1038				      buf, len, gfp))
 
1039			continue;
1040
1041		result = true;
1042		break;
1043	}
1044
1045	spin_unlock_bh(&wdev->mgmt_registrations_lock);
1046
 
1047	return result;
1048}
1049EXPORT_SYMBOL(cfg80211_rx_mgmt);
1050
1051void cfg80211_mgmt_tx_status(struct net_device *dev, u64 cookie,
1052			     const u8 *buf, size_t len, bool ack, gfp_t gfp)
1053{
1054	struct wireless_dev *wdev = dev->ieee80211_ptr;
1055	struct wiphy *wiphy = wdev->wiphy;
1056	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
1057
1058	/* Indicate TX status of the Action frame to user space */
1059	nl80211_send_mgmt_tx_status(rdev, dev, cookie, buf, len, ack, gfp);
1060}
1061EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
1062
1063void cfg80211_cqm_rssi_notify(struct net_device *dev,
1064			      enum nl80211_cqm_rssi_threshold_event rssi_event,
1065			      gfp_t gfp)
1066{
1067	struct wireless_dev *wdev = dev->ieee80211_ptr;
1068	struct wiphy *wiphy = wdev->wiphy;
1069	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1070
1071	/* Indicate roaming trigger event to user space */
1072	nl80211_send_cqm_rssi_notify(rdev, dev, rssi_event, gfp);
 
 
1073}
1074EXPORT_SYMBOL(cfg80211_cqm_rssi_notify);
1075
1076void cfg80211_cqm_pktloss_notify(struct net_device *dev,
1077				 const u8 *peer, u32 num_packets, gfp_t gfp)
 
 
1078{
1079	struct wireless_dev *wdev = dev->ieee80211_ptr;
1080	struct wiphy *wiphy = wdev->wiphy;
1081	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 
 
 
 
 
 
 
 
 
 
1082
1083	/* Indicate roaming trigger event to user space */
1084	nl80211_send_cqm_pktloss_notify(rdev, dev, peer, num_packets, gfp);
1085}
1086EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify);
1087
1088void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
1089			       const u8 *replay_ctr, gfp_t gfp)
 
1090{
1091	struct wireless_dev *wdev = dev->ieee80211_ptr;
1092	struct wiphy *wiphy = wdev->wiphy;
1093	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1094
1095	nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp);
1096}
1097EXPORT_SYMBOL(cfg80211_gtk_rekey_notify);
v5.9
  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 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, struct cfg80211_bss *bss,
 25			    const u8 *buf, size_t len, int uapsd_queues,
 26			    const u8 *req_ies, size_t req_ies_len)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 27{
 
 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
 34	memset(&cr, 0, sizeof(cr));
 35	cr.status = (int)le16_to_cpu(mgmt->u.assoc_resp.status_code);
 36	cr.bssid = mgmt->bssid;
 37	cr.bss = bss;
 38	cr.req_ie = req_ies;
 39	cr.req_ie_len = req_ies_len;
 40	cr.resp_ie = mgmt->u.assoc_resp.variable;
 41	cr.resp_ie_len =
 42		len - offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
 43	cr.timeout_reason = NL80211_TIMEOUT_UNSPECIFIED;
 44
 45	trace_cfg80211_send_rx_assoc(dev, bss);
 46
 47	/*
 48	 * This is a bit of a hack, we don't notify userspace of
 49	 * a (re-)association reply if we tried to send a reassoc
 50	 * and got a reject -- we only try again with an assoc
 51	 * frame instead of reassoc.
 52	 */
 53	if (cfg80211_sme_rx_assoc_resp(wdev, cr.status)) {
 54		cfg80211_unhold_bss(bss_from_pub(bss));
 55		cfg80211_put_bss(wiphy, bss);
 56		return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 57	}
 58
 59	nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL, uapsd_queues,
 60			      req_ies, req_ies_len);
 61	/* update current_bss etc., consumes the bss reference */
 62	__cfg80211_connect_result(dev, &cr, cr.status == WLAN_STATUS_SUCCESS);
 63}
 64EXPORT_SYMBOL(cfg80211_rx_assoc_resp);
 
 
 65
 66static void cfg80211_process_auth(struct wireless_dev *wdev,
 67				  const u8 *buf, size_t len)
 68{
 69	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
 
 
 
 
 
 
 70
 71	nl80211_send_rx_auth(rdev, wdev->netdev, buf, len, GFP_KERNEL);
 72	cfg80211_sme_rx_auth(wdev, buf, len);
 73}
 
 74
 75static void cfg80211_process_deauth(struct wireless_dev *wdev,
 76				    const u8 *buf, size_t len)
 77{
 78	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
 
 
 79	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
 80	const u8 *bssid = mgmt->bssid;
 81	u16 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
 82	bool from_ap = !ether_addr_equal(mgmt->sa, wdev->netdev->dev_addr);
 
 
 83
 84	nl80211_send_deauth(rdev, wdev->netdev, buf, len, GFP_KERNEL);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 85
 86	if (!wdev->current_bss ||
 87	    !ether_addr_equal(wdev->current_bss->pub.bssid, bssid))
 88		return;
 89
 90	__cfg80211_disconnected(wdev->netdev, NULL, 0, reason_code, from_ap);
 91	cfg80211_sme_deauth(wdev);
 
 
 
 
 
 
 
 
 
 
 
 
 
 92}
 
 93
 94static void cfg80211_process_disassoc(struct wireless_dev *wdev,
 95				      const u8 *buf, size_t len)
 96{
 97	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
 
 
 
 
 
 
 
 
 
 
 
 
 
 98	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
 99	const u8 *bssid = mgmt->bssid;
100	u16 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
101	bool from_ap = !ether_addr_equal(mgmt->sa, wdev->netdev->dev_addr);
 
 
102
103	nl80211_send_disassoc(rdev, wdev->netdev, buf, len, GFP_KERNEL);
 
 
104
105	if (WARN_ON(!wdev->current_bss ||
106		    !ether_addr_equal(wdev->current_bss->pub.bssid, bssid)))
107		return;
108
109	__cfg80211_disconnected(wdev->netdev, NULL, 0, reason_code, from_ap);
110	cfg80211_sme_disassoc(wdev);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111}
 
112
113void cfg80211_rx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len)
114{
115	struct wireless_dev *wdev = dev->ieee80211_ptr;
116	struct ieee80211_mgmt *mgmt = (void *)buf;
117
118	ASSERT_WDEV_LOCK(wdev);
119
120	trace_cfg80211_rx_mlme_mgmt(dev, buf, len);
121
122	if (WARN_ON(len < 2))
123		return;
124
125	if (ieee80211_is_auth(mgmt->frame_control))
126		cfg80211_process_auth(wdev, buf, len);
127	else if (ieee80211_is_deauth(mgmt->frame_control))
128		cfg80211_process_deauth(wdev, buf, len);
129	else if (ieee80211_is_disassoc(mgmt->frame_control))
130		cfg80211_process_disassoc(wdev, buf, len);
131}
132EXPORT_SYMBOL(cfg80211_rx_mlme_mgmt);
133
134void cfg80211_auth_timeout(struct net_device *dev, const u8 *addr)
 
135{
136	struct wireless_dev *wdev = dev->ieee80211_ptr;
137	struct wiphy *wiphy = wdev->wiphy;
138	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
139
140	trace_cfg80211_send_auth_timeout(dev, addr);
141
142	nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL);
143	cfg80211_sme_auth_timeout(wdev);
144}
145EXPORT_SYMBOL(cfg80211_auth_timeout);
146
147void cfg80211_assoc_timeout(struct net_device *dev, struct cfg80211_bss *bss)
 
148{
149	struct wireless_dev *wdev = dev->ieee80211_ptr;
150	struct wiphy *wiphy = wdev->wiphy;
151	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
 
 
 
 
152
153	trace_cfg80211_send_assoc_timeout(dev, bss->bssid);
 
 
 
154
155	nl80211_send_assoc_timeout(rdev, dev, bss->bssid, GFP_KERNEL);
156	cfg80211_sme_assoc_timeout(wdev);
157
158	cfg80211_unhold_bss(bss_from_pub(bss));
159	cfg80211_put_bss(wiphy, bss);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160}
161EXPORT_SYMBOL(cfg80211_assoc_timeout);
162
163void cfg80211_abandon_assoc(struct net_device *dev, struct cfg80211_bss *bss)
164{
165	struct wireless_dev *wdev = dev->ieee80211_ptr;
166	struct wiphy *wiphy = wdev->wiphy;
 
167
168	cfg80211_sme_abandon_assoc(wdev);
169
170	cfg80211_unhold_bss(bss_from_pub(bss));
171	cfg80211_put_bss(wiphy, bss);
 
 
 
 
 
 
 
172}
173EXPORT_SYMBOL(cfg80211_abandon_assoc);
174
175void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len)
176{
177	struct wireless_dev *wdev = dev->ieee80211_ptr;
178	struct ieee80211_mgmt *mgmt = (void *)buf;
 
 
 
179
180	ASSERT_WDEV_LOCK(wdev);
181
182	trace_cfg80211_tx_mlme_mgmt(dev, buf, len);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
184	if (WARN_ON(len < 2))
185		return;
186
187	if (ieee80211_is_deauth(mgmt->frame_control))
188		cfg80211_process_deauth(wdev, buf, len);
189	else
190		cfg80211_process_disassoc(wdev, buf, len);
191}
192EXPORT_SYMBOL(cfg80211_tx_mlme_mgmt);
193
194void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
195				  enum nl80211_key_type key_type, int key_id,
196				  const u8 *tsc, gfp_t gfp)
197{
198	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
199	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
200#ifdef CONFIG_CFG80211_WEXT
201	union iwreq_data wrqu;
202	char *buf = kmalloc(128, gfp);
203
204	if (buf) {
205		sprintf(buf, "MLME-MICHAELMICFAILURE.indication("
206			"keyid=%d %scast addr=%pM)", key_id,
207			key_type == NL80211_KEYTYPE_GROUP ? "broad" : "uni",
208			addr);
209		memset(&wrqu, 0, sizeof(wrqu));
210		wrqu.data.length = strlen(buf);
211		wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
212		kfree(buf);
213	}
214#endif
215
216	trace_cfg80211_michael_mic_failure(dev, addr, key_type, key_id, tsc);
217	nl80211_michael_mic_failure(rdev, dev, addr, key_type, key_id, tsc, gfp);
218}
219EXPORT_SYMBOL(cfg80211_michael_mic_failure);
220
221/* some MLME handling for userspace SME */
222int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
223		       struct net_device *dev,
224		       struct ieee80211_channel *chan,
225		       enum nl80211_auth_type auth_type,
226		       const u8 *bssid,
227		       const u8 *ssid, int ssid_len,
228		       const u8 *ie, int ie_len,
229		       const u8 *key, int key_len, int key_idx,
230		       const u8 *auth_data, int auth_data_len)
231{
232	struct wireless_dev *wdev = dev->ieee80211_ptr;
233	struct cfg80211_auth_request req = {
234		.ie = ie,
235		.ie_len = ie_len,
236		.auth_data = auth_data,
237		.auth_data_len = auth_data_len,
238		.auth_type = auth_type,
239		.key = key,
240		.key_len = key_len,
241		.key_idx = key_idx,
242	};
243	int err;
244
245	ASSERT_WDEV_LOCK(wdev);
246
247	if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
248		if (!key || !key_len || key_idx < 0 || key_idx > 3)
249			return -EINVAL;
250
251	if (wdev->current_bss &&
252	    ether_addr_equal(bssid, wdev->current_bss->pub.bssid))
253		return -EALREADY;
254
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
255	req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
256				   IEEE80211_BSS_TYPE_ESS,
257				   IEEE80211_PRIVACY_ANY);
 
 
258	if (!req.bss)
259		return -ENOENT;
260
261	err = rdev_auth(rdev, dev, &req);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
262
263	cfg80211_put_bss(&rdev->wiphy, req.bss);
 
 
264	return err;
265}
266
267/*  Do a logical ht_capa &= ht_capa_mask.  */
268void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
269			       const struct ieee80211_ht_cap *ht_capa_mask)
 
 
 
 
270{
271	int i;
272	u8 *p1, *p2;
273	if (!ht_capa_mask) {
274		memset(ht_capa, 0, sizeof(*ht_capa));
275		return;
276	}
 
277
278	p1 = (u8*)(ht_capa);
279	p2 = (u8*)(ht_capa_mask);
280	for (i = 0; i < sizeof(*ht_capa); i++)
281		p1[i] &= p2[i];
282}
283
284/*  Do a logical vht_capa &= vht_capa_mask.  */
285void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa,
286				const struct ieee80211_vht_cap *vht_capa_mask)
 
 
 
 
287{
288	int i;
289	u8 *p1, *p2;
290	if (!vht_capa_mask) {
291		memset(vht_capa, 0, sizeof(*vht_capa));
292		return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
293	}
294
295	p1 = (u8*)(vht_capa);
296	p2 = (u8*)(vht_capa_mask);
297	for (i = 0; i < sizeof(*vht_capa); i++)
298		p1[i] &= p2[i];
 
 
 
299}
300
301int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
302			struct net_device *dev,
303			struct ieee80211_channel *chan,
304			const u8 *bssid,
305			const u8 *ssid, int ssid_len,
306			struct cfg80211_assoc_request *req)
 
307{
308	struct wireless_dev *wdev = dev->ieee80211_ptr;
309	int err;
310
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
311	ASSERT_WDEV_LOCK(wdev);
312
 
 
 
 
 
313	if (wdev->current_bss &&
314	    (!req->prev_bssid || !ether_addr_equal(wdev->current_bss->pub.bssid,
315						   req->prev_bssid)))
316		return -EALREADY;
 
 
 
 
 
 
 
 
 
 
 
317
318	cfg80211_oper_and_ht_capa(&req->ht_capa_mask,
319				  rdev->wiphy.ht_capa_mod_mask);
320	cfg80211_oper_and_vht_capa(&req->vht_capa_mask,
321				   rdev->wiphy.vht_capa_mod_mask);
322
323	req->bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
324				    IEEE80211_BSS_TYPE_ESS,
325				    IEEE80211_PRIVACY_ANY);
326	if (!req->bss)
327		return -ENOENT;
328
329	err = rdev_assoc(rdev, dev, req);
330	if (!err)
331		cfg80211_hold_bss(bss_from_pub(req->bss));
332	else
333		cfg80211_put_bss(&rdev->wiphy, req->bss);
334
335	return err;
336}
337
338int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
339			 struct net_device *dev, const u8 *bssid,
340			 const u8 *ie, int ie_len, u16 reason,
341			 bool local_state_change)
342{
343	struct wireless_dev *wdev = dev->ieee80211_ptr;
344	struct cfg80211_deauth_request req = {
345		.bssid = bssid,
346		.reason_code = reason,
347		.ie = ie,
348		.ie_len = ie_len,
349		.local_state_change = local_state_change,
350	};
351
352	ASSERT_WDEV_LOCK(wdev);
 
 
 
353
354	if (local_state_change &&
355	    (!wdev->current_bss ||
356	     !ether_addr_equal(wdev->current_bss->pub.bssid, bssid)))
357		return 0;
358
359	if (ether_addr_equal(wdev->disconnect_bssid, bssid) ||
360	    (wdev->current_bss &&
361	     ether_addr_equal(wdev->current_bss->pub.bssid, bssid)))
362		wdev->conn_owner_nlportid = 0;
363
364	return rdev_deauth(rdev, dev, &req);
365}
366
367int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
368			   struct net_device *dev, const u8 *bssid,
369			   const u8 *ie, int ie_len, u16 reason,
370			   bool local_state_change)
371{
372	struct wireless_dev *wdev = dev->ieee80211_ptr;
373	struct cfg80211_disassoc_request req = {
374		.reason_code = reason,
375		.local_state_change = local_state_change,
376		.ie = ie,
377		.ie_len = ie_len,
378	};
379	int err;
380
381	ASSERT_WDEV_LOCK(wdev);
382
383	if (!wdev->current_bss)
384		return -ENOTCONN;
385
386	if (ether_addr_equal(wdev->current_bss->pub.bssid, bssid))
 
 
 
 
 
 
 
 
387		req.bss = &wdev->current_bss->pub;
388	else
389		return -ENOTCONN;
390
391	err = rdev_disassoc(rdev, dev, &req);
392	if (err)
393		return err;
 
 
 
 
 
 
 
 
 
 
 
 
394
395	/* driver should have reported the disassoc */
396	WARN_ON(wdev->current_bss);
397	return 0;
398}
399
400void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
401			struct net_device *dev)
402{
403	struct wireless_dev *wdev = dev->ieee80211_ptr;
404	u8 bssid[ETH_ALEN];
 
405
406	ASSERT_WDEV_LOCK(wdev);
407
408	if (!rdev->ops->deauth)
409		return;
410
411	if (!wdev->current_bss)
412		return;
 
 
 
 
 
 
 
 
 
 
 
 
413
414	memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN);
415	cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0,
416			     WLAN_REASON_DEAUTH_LEAVING, false);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
417}
418
419struct cfg80211_mgmt_registration {
420	struct list_head list;
421	struct wireless_dev *wdev;
 
 
 
 
422
423	u32 nlportid;
 
 
 
424
425	int match_len;
 
 
 
 
 
 
 
426
427	__le16 frame_type;
 
 
 
428
429	bool multicast_rx;
 
 
 
 
430
431	u8 match[];
432};
 
433
434static void cfg80211_mgmt_registrations_update(struct wireless_dev *wdev)
435{
436	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
437	struct wireless_dev *tmp;
438	struct cfg80211_mgmt_registration *reg;
439	struct mgmt_frame_regs upd = {};
440
441	ASSERT_RTNL();
 
 
442
443	spin_lock_bh(&wdev->mgmt_registrations_lock);
444	if (!wdev->mgmt_registrations_need_update) {
445		spin_unlock_bh(&wdev->mgmt_registrations_lock);
446		return;
447	}
448
449	rcu_read_lock();
450	list_for_each_entry_rcu(tmp, &rdev->wiphy.wdev_list, list) {
451		list_for_each_entry(reg, &tmp->mgmt_registrations, list) {
452			u32 mask = BIT(le16_to_cpu(reg->frame_type) >> 4);
453			u32 mcast_mask = 0;
454
455			if (reg->multicast_rx)
456				mcast_mask = mask;
457
458			upd.global_stypes |= mask;
459			upd.global_mcast_stypes |= mcast_mask;
460
461			if (tmp == wdev) {
462				upd.interface_stypes |= mask;
463				upd.interface_mcast_stypes |= mcast_mask;
464			}
465		}
466	}
467	rcu_read_unlock();
468
469	wdev->mgmt_registrations_need_update = 0;
470	spin_unlock_bh(&wdev->mgmt_registrations_lock);
471
472	rdev_update_mgmt_frame_registrations(rdev, wdev, &upd);
473}
474
475void cfg80211_mgmt_registrations_update_wk(struct work_struct *wk)
476{
477	struct cfg80211_registered_device *rdev;
478	struct wireless_dev *wdev;
479
480	rdev = container_of(wk, struct cfg80211_registered_device,
481			    mgmt_registrations_update_wk);
482
483	rtnl_lock();
484	list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list)
485		cfg80211_mgmt_registrations_update(wdev);
486	rtnl_unlock();
487}
488
489int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid,
490				u16 frame_type, const u8 *match_data,
491				int match_len, bool multicast_rx,
492				struct netlink_ext_ack *extack)
493{
 
 
494	struct cfg80211_mgmt_registration *reg, *nreg;
495	int err = 0;
496	u16 mgmt_type;
497	bool update_multicast = false;
498
499	if (!wdev->wiphy->mgmt_stypes)
500		return -EOPNOTSUPP;
501
502	if ((frame_type & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT) {
503		NL_SET_ERR_MSG(extack, "frame type not management");
504		return -EINVAL;
505	}
506
507	if (frame_type & ~(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) {
508		NL_SET_ERR_MSG(extack, "Invalid frame type");
509		return -EINVAL;
510	}
511
512	mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
513	if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].rx & BIT(mgmt_type))) {
514		NL_SET_ERR_MSG(extack,
515			       "Registration to specific type not supported");
516		return -EINVAL;
517	}
518
519	/*
520	 * To support Pre Association Security Negotiation (PASN), registration
521	 * for authentication frames should be supported. However, as some
522	 * versions of the user space daemons wrongly register to all types of
523	 * authentication frames (which might result in unexpected behavior)
524	 * allow such registration if the request is for a specific
525	 * authentication algorithm number.
526	 */
527	if (wdev->iftype == NL80211_IFTYPE_STATION &&
528	    (frame_type & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_AUTH &&
529	    !(match_data && match_len >= 2)) {
530		NL_SET_ERR_MSG(extack,
531			       "Authentication algorithm number required");
532		return -EINVAL;
533	}
534
535	nreg = kzalloc(sizeof(*reg) + match_len, GFP_KERNEL);
536	if (!nreg)
537		return -ENOMEM;
538
539	spin_lock_bh(&wdev->mgmt_registrations_lock);
540
541	list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
542		int mlen = min(match_len, reg->match_len);
543
544		if (frame_type != le16_to_cpu(reg->frame_type))
545			continue;
546
547		if (memcmp(reg->match, match_data, mlen) == 0) {
548			if (reg->multicast_rx != multicast_rx) {
549				update_multicast = true;
550				reg->multicast_rx = multicast_rx;
551				break;
552			}
553			NL_SET_ERR_MSG(extack, "Match already configured");
554			err = -EALREADY;
555			break;
556		}
557	}
558
559	if (err)
 
560		goto out;
561
562	if (update_multicast) {
563		kfree(nreg);
564	} else {
565		memcpy(nreg->match, match_data, match_len);
566		nreg->match_len = match_len;
567		nreg->nlportid = snd_portid;
568		nreg->frame_type = cpu_to_le16(frame_type);
569		nreg->wdev = wdev;
570		nreg->multicast_rx = multicast_rx;
571		list_add(&nreg->list, &wdev->mgmt_registrations);
572	}
573	wdev->mgmt_registrations_need_update = 1;
574	spin_unlock_bh(&wdev->mgmt_registrations_lock);
575
576	cfg80211_mgmt_registrations_update(wdev);
577
578	return 0;
 
 
 
 
 
 
579
580 out:
581	kfree(nreg);
582	spin_unlock_bh(&wdev->mgmt_registrations_lock);
583
584	return err;
585}
586
587void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlportid)
588{
589	struct wiphy *wiphy = wdev->wiphy;
590	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
591	struct cfg80211_mgmt_registration *reg, *tmp;
592
593	spin_lock_bh(&wdev->mgmt_registrations_lock);
594
595	list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
596		if (reg->nlportid != nlportid)
597			continue;
598
 
 
 
 
 
 
 
599		list_del(&reg->list);
600		kfree(reg);
601
602		wdev->mgmt_registrations_need_update = 1;
603		schedule_work(&rdev->mgmt_registrations_update_wk);
604	}
605
606	spin_unlock_bh(&wdev->mgmt_registrations_lock);
607
608	if (nlportid && rdev->crit_proto_nlportid == nlportid) {
609		rdev->crit_proto_nlportid = 0;
610		rdev_crit_proto_stop(rdev, wdev);
611	}
612
613	if (nlportid == wdev->ap_unexpected_nlportid)
614		wdev->ap_unexpected_nlportid = 0;
615}
616
617void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
618{
619	struct cfg80211_mgmt_registration *reg, *tmp;
620
621	spin_lock_bh(&wdev->mgmt_registrations_lock);
 
622	list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
623		list_del(&reg->list);
624		kfree(reg);
625	}
626	wdev->mgmt_registrations_need_update = 1;
627	spin_unlock_bh(&wdev->mgmt_registrations_lock);
628
629	cfg80211_mgmt_registrations_update(wdev);
630}
631
632int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
633			  struct wireless_dev *wdev,
634			  struct cfg80211_mgmt_tx_params *params, u64 *cookie)
 
 
 
635{
 
636	const struct ieee80211_mgmt *mgmt;
637	u16 stype;
638
639	if (!wdev->wiphy->mgmt_stypes)
640		return -EOPNOTSUPP;
641
642	if (!rdev->ops->mgmt_tx)
643		return -EOPNOTSUPP;
644
645	if (params->len < 24 + 1)
646		return -EINVAL;
647
648	mgmt = (const struct ieee80211_mgmt *)params->buf;
649
650	if (!ieee80211_is_mgmt(mgmt->frame_control))
651		return -EINVAL;
652
653	stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
654	if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].tx & BIT(stype >> 4)))
655		return -EINVAL;
656
657	if (ieee80211_is_action(mgmt->frame_control) &&
658	    mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) {
659		int err = 0;
660
661		wdev_lock(wdev);
662
663		switch (wdev->iftype) {
664		case NL80211_IFTYPE_ADHOC:
665		case NL80211_IFTYPE_STATION:
666		case NL80211_IFTYPE_P2P_CLIENT:
667			if (!wdev->current_bss) {
668				err = -ENOTCONN;
669				break;
670			}
671
672			if (!ether_addr_equal(wdev->current_bss->pub.bssid,
673					      mgmt->bssid)) {
674				err = -ENOTCONN;
675				break;
676			}
677
678			/*
679			 * check for IBSS DA must be done by driver as
680			 * cfg80211 doesn't track the stations
681			 */
682			if (wdev->iftype == NL80211_IFTYPE_ADHOC)
683				break;
684
685			/* for station, check that DA is the AP */
686			if (!ether_addr_equal(wdev->current_bss->pub.bssid,
687					      mgmt->da)) {
688				err = -ENOTCONN;
689				break;
690			}
691			break;
692		case NL80211_IFTYPE_AP:
693		case NL80211_IFTYPE_P2P_GO:
694		case NL80211_IFTYPE_AP_VLAN:
695			if (!ether_addr_equal(mgmt->bssid, wdev_address(wdev)))
696				err = -EINVAL;
697			break;
698		case NL80211_IFTYPE_MESH_POINT:
699			if (!ether_addr_equal(mgmt->sa, mgmt->bssid)) {
700				err = -EINVAL;
701				break;
702			}
703			/*
704			 * check for mesh DA must be done by driver as
705			 * cfg80211 doesn't track the stations
706			 */
707			break;
708		case NL80211_IFTYPE_P2P_DEVICE:
709			/*
710			 * fall through, P2P device only supports
711			 * public action frames
712			 */
713		case NL80211_IFTYPE_NAN:
714		default:
715			err = -EOPNOTSUPP;
716			break;
717		}
718		wdev_unlock(wdev);
719
720		if (err)
721			return err;
722	}
723
724	if (!ether_addr_equal(mgmt->sa, wdev_address(wdev))) {
725		/* Allow random TA to be used with Public Action frames if the
726		 * driver has indicated support for this. Otherwise, only allow
727		 * the local address to be used.
728		 */
729		if (!ieee80211_is_action(mgmt->frame_control) ||
730		    mgmt->u.action.category != WLAN_CATEGORY_PUBLIC)
731			return -EINVAL;
732		if (!wdev->current_bss &&
733		    !wiphy_ext_feature_isset(
734			    &rdev->wiphy,
735			    NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA))
736			return -EINVAL;
737		if (wdev->current_bss &&
738		    !wiphy_ext_feature_isset(
739			    &rdev->wiphy,
740			    NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED))
741			return -EINVAL;
742	}
743
744	/* Transmit the Action frame as requested by user space */
745	return rdev_mgmt_tx(rdev, wdev, params, cookie);
 
 
746}
747
748bool cfg80211_rx_mgmt_khz(struct wireless_dev *wdev, int freq, int sig_dbm,
749			  const u8 *buf, size_t len, u32 flags)
750{
 
751	struct wiphy *wiphy = wdev->wiphy;
752	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
753	struct cfg80211_mgmt_registration *reg;
754	const struct ieee80211_txrx_stypes *stypes =
755		&wiphy->mgmt_stypes[wdev->iftype];
756	struct ieee80211_mgmt *mgmt = (void *)buf;
757	const u8 *data;
758	int data_len;
759	bool result = false;
760	__le16 ftype = mgmt->frame_control &
761		cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE);
762	u16 stype;
763
764	trace_cfg80211_rx_mgmt(wdev, freq, sig_dbm);
765	stype = (le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) >> 4;
766
767	if (!(stypes->rx & BIT(stype))) {
768		trace_cfg80211_return_bool(false);
769		return false;
770	}
771
772	data = buf + ieee80211_hdrlen(mgmt->frame_control);
773	data_len = len - ieee80211_hdrlen(mgmt->frame_control);
774
775	spin_lock_bh(&wdev->mgmt_registrations_lock);
776
777	list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
778		if (reg->frame_type != ftype)
779			continue;
780
781		if (reg->match_len > data_len)
782			continue;
783
784		if (memcmp(reg->match, data, reg->match_len))
785			continue;
786
787		/* found match! */
788
789		/* Indicate the received Action frame to user space */
790		if (nl80211_send_mgmt(rdev, wdev, reg->nlportid,
791				      freq, sig_dbm,
792				      buf, len, flags, GFP_ATOMIC))
793			continue;
794
795		result = true;
796		break;
797	}
798
799	spin_unlock_bh(&wdev->mgmt_registrations_lock);
800
801	trace_cfg80211_return_bool(result);
802	return result;
803}
804EXPORT_SYMBOL(cfg80211_rx_mgmt_khz);
805
806void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev)
 
807{
808	cancel_delayed_work(&rdev->dfs_update_channels_wk);
809	queue_delayed_work(cfg80211_wq, &rdev->dfs_update_channels_wk, 0);
 
 
 
 
810}
 
811
812void cfg80211_dfs_channels_update_work(struct work_struct *work)
813{
814	struct delayed_work *delayed_work = to_delayed_work(work);
815	struct cfg80211_registered_device *rdev;
816	struct cfg80211_chan_def chandef;
817	struct ieee80211_supported_band *sband;
818	struct ieee80211_channel *c;
819	struct wiphy *wiphy;
820	bool check_again = false;
821	unsigned long timeout, next_time = 0;
822	unsigned long time_dfs_update;
823	enum nl80211_radar_event radar_event;
824	int bandid, i;
825
826	rdev = container_of(delayed_work, struct cfg80211_registered_device,
827			    dfs_update_channels_wk);
828	wiphy = &rdev->wiphy;
829
830	rtnl_lock();
831	for (bandid = 0; bandid < NUM_NL80211_BANDS; bandid++) {
832		sband = wiphy->bands[bandid];
833		if (!sband)
834			continue;
835
836		for (i = 0; i < sband->n_channels; i++) {
837			c = &sband->channels[i];
838
839			if (!(c->flags & IEEE80211_CHAN_RADAR))
840				continue;
841
842			if (c->dfs_state != NL80211_DFS_UNAVAILABLE &&
843			    c->dfs_state != NL80211_DFS_AVAILABLE)
844				continue;
845
846			if (c->dfs_state == NL80211_DFS_UNAVAILABLE) {
847				time_dfs_update = IEEE80211_DFS_MIN_NOP_TIME_MS;
848				radar_event = NL80211_RADAR_NOP_FINISHED;
849			} else {
850				if (regulatory_pre_cac_allowed(wiphy) ||
851				    cfg80211_any_wiphy_oper_chan(wiphy, c))
852					continue;
853
854				time_dfs_update = REG_PRE_CAC_EXPIRY_GRACE_MS;
855				radar_event = NL80211_RADAR_PRE_CAC_EXPIRED;
856			}
857
858			timeout = c->dfs_state_entered +
859				  msecs_to_jiffies(time_dfs_update);
860
861			if (time_after_eq(jiffies, timeout)) {
862				c->dfs_state = NL80211_DFS_USABLE;
863				c->dfs_state_entered = jiffies;
864
865				cfg80211_chandef_create(&chandef, c,
866							NL80211_CHAN_NO_HT);
867
868				nl80211_radar_notify(rdev, &chandef,
869						     radar_event, NULL,
870						     GFP_ATOMIC);
871
872				regulatory_propagate_dfs_state(wiphy, &chandef,
873							       c->dfs_state,
874							       radar_event);
875				continue;
876			}
877
878			if (!check_again)
879				next_time = timeout - jiffies;
880			else
881				next_time = min(next_time, timeout - jiffies);
882			check_again = true;
883		}
884	}
885	rtnl_unlock();
886
887	/* reschedule if there are other channels waiting to be cleared again */
888	if (check_again)
889		queue_delayed_work(cfg80211_wq, &rdev->dfs_update_channels_wk,
890				   next_time);
891}
 
892
893
894void cfg80211_radar_event(struct wiphy *wiphy,
895			  struct cfg80211_chan_def *chandef,
896			  gfp_t gfp)
897{
898	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
899
900	trace_cfg80211_radar_event(wiphy, chandef);
901
902	/* only set the chandef supplied channel to unavailable, in
903	 * case the radar is detected on only one of multiple channels
904	 * spanned by the chandef.
905	 */
906	cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_UNAVAILABLE);
907
908	cfg80211_sched_dfs_chan_update(rdev);
909
910	nl80211_radar_notify(rdev, chandef, NL80211_RADAR_DETECTED, NULL, gfp);
911
912	memcpy(&rdev->radar_chandef, chandef, sizeof(struct cfg80211_chan_def));
913	queue_work(cfg80211_wq, &rdev->propagate_radar_detect_wk);
914}
915EXPORT_SYMBOL(cfg80211_radar_event);
916
917void cfg80211_cac_event(struct net_device *netdev,
918			const struct cfg80211_chan_def *chandef,
919			enum nl80211_radar_event event, gfp_t gfp)
920{
921	struct wireless_dev *wdev = netdev->ieee80211_ptr;
922	struct wiphy *wiphy = wdev->wiphy;
923	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
924	unsigned long timeout;
925
926	trace_cfg80211_cac_event(netdev, event);
927
928	if (WARN_ON(!wdev->cac_started && event != NL80211_RADAR_CAC_STARTED))
929		return;
930
931	if (WARN_ON(!wdev->chandef.chan))
932		return;
933
934	switch (event) {
935	case NL80211_RADAR_CAC_FINISHED:
936		timeout = wdev->cac_start_time +
937			  msecs_to_jiffies(wdev->cac_time_ms);
938		WARN_ON(!time_after_eq(jiffies, timeout));
939		cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);
940		memcpy(&rdev->cac_done_chandef, chandef,
941		       sizeof(struct cfg80211_chan_def));
942		queue_work(cfg80211_wq, &rdev->propagate_cac_done_wk);
943		cfg80211_sched_dfs_chan_update(rdev);
944		fallthrough;
945	case NL80211_RADAR_CAC_ABORTED:
946		wdev->cac_started = false;
947		break;
948	case NL80211_RADAR_CAC_STARTED:
949		wdev->cac_started = true;
950		break;
951	default:
952		WARN_ON(1);
953		return;
954	}
955
956	nl80211_radar_notify(rdev, chandef, event, netdev, gfp);
957}
958EXPORT_SYMBOL(cfg80211_cac_event);