xref: /openbmc/linux/net/wireless/mlme.c (revision b595076a)
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 
18 void 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 }
54 EXPORT_SYMBOL(cfg80211_send_rx_auth);
55 
56 void 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 }
141 EXPORT_SYMBOL(cfg80211_send_rx_assoc);
142 
143 void __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, ETH_ALEN) == 0) {
174 			cfg80211_unhold_bss(wdev->authtry_bsses[i]);
175 			cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
176 			wdev->authtry_bsses[i] = NULL;
177 			found = true;
178 			break;
179 		}
180 	}
181 
182 	if (!found)
183 		return;
184 
185 	nl80211_send_deauth(rdev, dev, buf, len, GFP_KERNEL);
186 
187 	if (wdev->sme_state == CFG80211_SME_CONNECTED && was_current) {
188 		u16 reason_code;
189 		bool from_ap;
190 
191 		reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
192 
193 		from_ap = memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0;
194 		__cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
195 	} else if (wdev->sme_state == CFG80211_SME_CONNECTING) {
196 		__cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0,
197 					  WLAN_STATUS_UNSPECIFIED_FAILURE,
198 					  false, NULL);
199 	}
200 }
201 EXPORT_SYMBOL(__cfg80211_send_deauth);
202 
203 void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len)
204 {
205 	struct wireless_dev *wdev = dev->ieee80211_ptr;
206 
207 	wdev_lock(wdev);
208 	__cfg80211_send_deauth(dev, buf, len);
209 	wdev_unlock(wdev);
210 }
211 EXPORT_SYMBOL(cfg80211_send_deauth);
212 
213 void __cfg80211_send_disassoc(struct net_device *dev,
214 				     const u8 *buf, size_t len)
215 {
216 	struct wireless_dev *wdev = dev->ieee80211_ptr;
217 	struct wiphy *wiphy = wdev->wiphy;
218 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
219 	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
220 	const u8 *bssid = mgmt->bssid;
221 	int i;
222 	u16 reason_code;
223 	bool from_ap;
224 	bool done = false;
225 
226 	ASSERT_WDEV_LOCK(wdev);
227 
228 	nl80211_send_disassoc(rdev, dev, buf, len, GFP_KERNEL);
229 
230 	if (wdev->sme_state != CFG80211_SME_CONNECTED)
231 		return;
232 
233 	if (wdev->current_bss &&
234 	    memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
235 		for (i = 0; i < MAX_AUTH_BSSES; i++) {
236 			if (wdev->authtry_bsses[i] || wdev->auth_bsses[i])
237 				continue;
238 			wdev->auth_bsses[i] = wdev->current_bss;
239 			wdev->current_bss = NULL;
240 			done = true;
241 			cfg80211_sme_disassoc(dev, i);
242 			break;
243 		}
244 		WARN_ON(!done);
245 	} else
246 		WARN_ON(1);
247 
248 
249 	reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
250 
251 	from_ap = memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0;
252 	__cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
253 }
254 EXPORT_SYMBOL(__cfg80211_send_disassoc);
255 
256 void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len)
257 {
258 	struct wireless_dev *wdev = dev->ieee80211_ptr;
259 
260 	wdev_lock(wdev);
261 	__cfg80211_send_disassoc(dev, buf, len);
262 	wdev_unlock(wdev);
263 }
264 EXPORT_SYMBOL(cfg80211_send_disassoc);
265 
266 static void __cfg80211_auth_remove(struct wireless_dev *wdev, const u8 *addr)
267 {
268 	int i;
269 	bool done = false;
270 
271 	ASSERT_WDEV_LOCK(wdev);
272 
273 	for (i = 0; addr && i < MAX_AUTH_BSSES; i++) {
274 		if (wdev->authtry_bsses[i] &&
275 		    memcmp(wdev->authtry_bsses[i]->pub.bssid,
276 			   addr, ETH_ALEN) == 0) {
277 			cfg80211_unhold_bss(wdev->authtry_bsses[i]);
278 			cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
279 			wdev->authtry_bsses[i] = NULL;
280 			done = true;
281 			break;
282 		}
283 	}
284 
285 	WARN_ON(!done);
286 }
287 
288 void __cfg80211_auth_canceled(struct net_device *dev, const u8 *addr)
289 {
290 	__cfg80211_auth_remove(dev->ieee80211_ptr, addr);
291 }
292 EXPORT_SYMBOL(__cfg80211_auth_canceled);
293 
294 void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
295 {
296 	struct wireless_dev *wdev = dev->ieee80211_ptr;
297 	struct wiphy *wiphy = wdev->wiphy;
298 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
299 
300 	wdev_lock(wdev);
301 
302 	nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL);
303 	if (wdev->sme_state == CFG80211_SME_CONNECTING)
304 		__cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
305 					  WLAN_STATUS_UNSPECIFIED_FAILURE,
306 					  false, NULL);
307 
308 	__cfg80211_auth_remove(wdev, addr);
309 
310 	wdev_unlock(wdev);
311 }
312 EXPORT_SYMBOL(cfg80211_send_auth_timeout);
313 
314 void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr)
315 {
316 	struct wireless_dev *wdev = dev->ieee80211_ptr;
317 	struct wiphy *wiphy = wdev->wiphy;
318 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
319 	int i;
320 	bool done = false;
321 
322 	wdev_lock(wdev);
323 
324 	nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL);
325 	if (wdev->sme_state == CFG80211_SME_CONNECTING)
326 		__cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
327 					  WLAN_STATUS_UNSPECIFIED_FAILURE,
328 					  false, NULL);
329 
330 	for (i = 0; addr && i < MAX_AUTH_BSSES; i++) {
331 		if (wdev->auth_bsses[i] &&
332 		    memcmp(wdev->auth_bsses[i]->pub.bssid,
333 			   addr, ETH_ALEN) == 0) {
334 			cfg80211_unhold_bss(wdev->auth_bsses[i]);
335 			cfg80211_put_bss(&wdev->auth_bsses[i]->pub);
336 			wdev->auth_bsses[i] = NULL;
337 			done = true;
338 			break;
339 		}
340 	}
341 
342 	WARN_ON(!done);
343 
344 	wdev_unlock(wdev);
345 }
346 EXPORT_SYMBOL(cfg80211_send_assoc_timeout);
347 
348 void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
349 				  enum nl80211_key_type key_type, int key_id,
350 				  const u8 *tsc, gfp_t gfp)
351 {
352 	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
353 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
354 #ifdef CONFIG_CFG80211_WEXT
355 	union iwreq_data wrqu;
356 	char *buf = kmalloc(128, gfp);
357 
358 	if (buf) {
359 		sprintf(buf, "MLME-MICHAELMICFAILURE.indication("
360 			"keyid=%d %scast addr=%pM)", key_id,
361 			key_type == NL80211_KEYTYPE_GROUP ? "broad" : "uni",
362 			addr);
363 		memset(&wrqu, 0, sizeof(wrqu));
364 		wrqu.data.length = strlen(buf);
365 		wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
366 		kfree(buf);
367 	}
368 #endif
369 
370 	nl80211_michael_mic_failure(rdev, dev, addr, key_type, key_id, tsc, gfp);
371 }
372 EXPORT_SYMBOL(cfg80211_michael_mic_failure);
373 
374 /* some MLME handling for userspace SME */
375 int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
376 			 struct net_device *dev,
377 			 struct ieee80211_channel *chan,
378 			 enum nl80211_auth_type auth_type,
379 			 const u8 *bssid,
380 			 const u8 *ssid, int ssid_len,
381 			 const u8 *ie, int ie_len,
382 			 const u8 *key, int key_len, int key_idx,
383 			 bool local_state_change)
384 {
385 	struct wireless_dev *wdev = dev->ieee80211_ptr;
386 	struct cfg80211_auth_request req;
387 	struct cfg80211_internal_bss *bss;
388 	int i, err, slot = -1, nfree = 0;
389 
390 	ASSERT_WDEV_LOCK(wdev);
391 
392 	if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
393 		if (!key || !key_len || key_idx < 0 || key_idx > 4)
394 			return -EINVAL;
395 
396 	if (wdev->current_bss &&
397 	    memcmp(bssid, wdev->current_bss->pub.bssid, ETH_ALEN) == 0)
398 		return -EALREADY;
399 
400 	for (i = 0; i < MAX_AUTH_BSSES; i++) {
401 		if (wdev->authtry_bsses[i] &&
402 		    memcmp(bssid, wdev->authtry_bsses[i]->pub.bssid,
403 						ETH_ALEN) == 0)
404 			return -EALREADY;
405 		if (wdev->auth_bsses[i] &&
406 		    memcmp(bssid, wdev->auth_bsses[i]->pub.bssid,
407 						ETH_ALEN) == 0)
408 			return -EALREADY;
409 	}
410 
411 	memset(&req, 0, sizeof(req));
412 
413 	req.local_state_change = local_state_change;
414 	req.ie = ie;
415 	req.ie_len = ie_len;
416 	req.auth_type = auth_type;
417 	req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
418 				   WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
419 	req.key = key;
420 	req.key_len = key_len;
421 	req.key_idx = key_idx;
422 	if (!req.bss)
423 		return -ENOENT;
424 
425 	bss = bss_from_pub(req.bss);
426 
427 	for (i = 0; i < MAX_AUTH_BSSES; i++) {
428 		if (!wdev->auth_bsses[i] && !wdev->authtry_bsses[i]) {
429 			slot = i;
430 			nfree++;
431 		}
432 	}
433 
434 	/* we need one free slot for disassoc and one for this auth */
435 	if (nfree < 2) {
436 		err = -ENOSPC;
437 		goto out;
438 	}
439 
440 	if (local_state_change)
441 		wdev->auth_bsses[slot] = bss;
442 	else
443 		wdev->authtry_bsses[slot] = bss;
444 	cfg80211_hold_bss(bss);
445 
446 	err = rdev->ops->auth(&rdev->wiphy, dev, &req);
447 	if (err) {
448 		if (local_state_change)
449 			wdev->auth_bsses[slot] = NULL;
450 		else
451 			wdev->authtry_bsses[slot] = NULL;
452 		cfg80211_unhold_bss(bss);
453 	}
454 
455  out:
456 	if (err)
457 		cfg80211_put_bss(req.bss);
458 	return err;
459 }
460 
461 int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
462 		       struct net_device *dev, struct ieee80211_channel *chan,
463 		       enum nl80211_auth_type auth_type, const u8 *bssid,
464 		       const u8 *ssid, int ssid_len,
465 		       const u8 *ie, int ie_len,
466 		       const u8 *key, int key_len, int key_idx,
467 		       bool local_state_change)
468 {
469 	int err;
470 
471 	wdev_lock(dev->ieee80211_ptr);
472 	err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
473 				   ssid, ssid_len, ie, ie_len,
474 				   key, key_len, key_idx, local_state_change);
475 	wdev_unlock(dev->ieee80211_ptr);
476 
477 	return err;
478 }
479 
480 int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
481 			  struct net_device *dev,
482 			  struct ieee80211_channel *chan,
483 			  const u8 *bssid, const u8 *prev_bssid,
484 			  const u8 *ssid, int ssid_len,
485 			  const u8 *ie, int ie_len, bool use_mfp,
486 			  struct cfg80211_crypto_settings *crypt)
487 {
488 	struct wireless_dev *wdev = dev->ieee80211_ptr;
489 	struct cfg80211_assoc_request req;
490 	struct cfg80211_internal_bss *bss;
491 	int i, err, slot = -1;
492 	bool was_connected = false;
493 
494 	ASSERT_WDEV_LOCK(wdev);
495 
496 	memset(&req, 0, sizeof(req));
497 
498 	if (wdev->current_bss && prev_bssid &&
499 	    memcmp(wdev->current_bss->pub.bssid, prev_bssid, ETH_ALEN) == 0) {
500 		/*
501 		 * Trying to reassociate: Allow this to proceed and let the old
502 		 * association to be dropped when the new one is completed.
503 		 */
504 		if (wdev->sme_state == CFG80211_SME_CONNECTED) {
505 			was_connected = true;
506 			wdev->sme_state = CFG80211_SME_CONNECTING;
507 		}
508 	} else if (wdev->current_bss)
509 		return -EALREADY;
510 
511 	req.ie = ie;
512 	req.ie_len = ie_len;
513 	memcpy(&req.crypto, crypt, sizeof(req.crypto));
514 	req.use_mfp = use_mfp;
515 	req.prev_bssid = prev_bssid;
516 	req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
517 				   WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
518 	if (!req.bss) {
519 		if (was_connected)
520 			wdev->sme_state = CFG80211_SME_CONNECTED;
521 		return -ENOENT;
522 	}
523 
524 	bss = bss_from_pub(req.bss);
525 
526 	for (i = 0; i < MAX_AUTH_BSSES; i++) {
527 		if (bss == wdev->auth_bsses[i]) {
528 			slot = i;
529 			break;
530 		}
531 	}
532 
533 	if (slot < 0) {
534 		err = -ENOTCONN;
535 		goto out;
536 	}
537 
538 	err = rdev->ops->assoc(&rdev->wiphy, dev, &req);
539  out:
540 	if (err && was_connected)
541 		wdev->sme_state = CFG80211_SME_CONNECTED;
542 	/* still a reference in wdev->auth_bsses[slot] */
543 	cfg80211_put_bss(req.bss);
544 	return err;
545 }
546 
547 int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
548 			struct net_device *dev,
549 			struct ieee80211_channel *chan,
550 			const u8 *bssid, const u8 *prev_bssid,
551 			const u8 *ssid, int ssid_len,
552 			const u8 *ie, int ie_len, bool use_mfp,
553 			struct cfg80211_crypto_settings *crypt)
554 {
555 	struct wireless_dev *wdev = dev->ieee80211_ptr;
556 	int err;
557 
558 	wdev_lock(wdev);
559 	err = __cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid,
560 				    ssid, ssid_len, ie, ie_len, use_mfp, crypt);
561 	wdev_unlock(wdev);
562 
563 	return err;
564 }
565 
566 int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
567 			   struct net_device *dev, const u8 *bssid,
568 			   const u8 *ie, int ie_len, u16 reason,
569 			   bool local_state_change)
570 {
571 	struct wireless_dev *wdev = dev->ieee80211_ptr;
572 	struct cfg80211_deauth_request req;
573 	int i;
574 
575 	ASSERT_WDEV_LOCK(wdev);
576 
577 	memset(&req, 0, sizeof(req));
578 	req.reason_code = reason;
579 	req.local_state_change = local_state_change;
580 	req.ie = ie;
581 	req.ie_len = ie_len;
582 	if (wdev->current_bss &&
583 	    memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
584 		req.bss = &wdev->current_bss->pub;
585 	} else for (i = 0; i < MAX_AUTH_BSSES; i++) {
586 		if (wdev->auth_bsses[i] &&
587 		    memcmp(bssid, wdev->auth_bsses[i]->pub.bssid, ETH_ALEN) == 0) {
588 			req.bss = &wdev->auth_bsses[i]->pub;
589 			break;
590 		}
591 		if (wdev->authtry_bsses[i] &&
592 		    memcmp(bssid, wdev->authtry_bsses[i]->pub.bssid, ETH_ALEN) == 0) {
593 			req.bss = &wdev->authtry_bsses[i]->pub;
594 			break;
595 		}
596 	}
597 
598 	if (!req.bss)
599 		return -ENOTCONN;
600 
601 	return rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
602 }
603 
604 int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
605 			 struct net_device *dev, const u8 *bssid,
606 			 const u8 *ie, int ie_len, u16 reason,
607 			 bool local_state_change)
608 {
609 	struct wireless_dev *wdev = dev->ieee80211_ptr;
610 	int err;
611 
612 	wdev_lock(wdev);
613 	err = __cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason,
614 				     local_state_change);
615 	wdev_unlock(wdev);
616 
617 	return err;
618 }
619 
620 static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
621 				    struct net_device *dev, const u8 *bssid,
622 				    const u8 *ie, int ie_len, u16 reason,
623 				    bool local_state_change)
624 {
625 	struct wireless_dev *wdev = dev->ieee80211_ptr;
626 	struct cfg80211_disassoc_request req;
627 
628 	ASSERT_WDEV_LOCK(wdev);
629 
630 	if (wdev->sme_state != CFG80211_SME_CONNECTED)
631 		return -ENOTCONN;
632 
633 	if (WARN_ON(!wdev->current_bss))
634 		return -ENOTCONN;
635 
636 	memset(&req, 0, sizeof(req));
637 	req.reason_code = reason;
638 	req.local_state_change = local_state_change;
639 	req.ie = ie;
640 	req.ie_len = ie_len;
641 	if (memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0)
642 		req.bss = &wdev->current_bss->pub;
643 	else
644 		return -ENOTCONN;
645 
646 	return rdev->ops->disassoc(&rdev->wiphy, dev, &req, wdev);
647 }
648 
649 int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
650 			   struct net_device *dev, const u8 *bssid,
651 			   const u8 *ie, int ie_len, u16 reason,
652 			   bool local_state_change)
653 {
654 	struct wireless_dev *wdev = dev->ieee80211_ptr;
655 	int err;
656 
657 	wdev_lock(wdev);
658 	err = __cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason,
659 				       local_state_change);
660 	wdev_unlock(wdev);
661 
662 	return err;
663 }
664 
665 void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
666 			struct net_device *dev)
667 {
668 	struct wireless_dev *wdev = dev->ieee80211_ptr;
669 	struct cfg80211_deauth_request req;
670 	int i;
671 
672 	ASSERT_WDEV_LOCK(wdev);
673 
674 	if (!rdev->ops->deauth)
675 		return;
676 
677 	memset(&req, 0, sizeof(req));
678 	req.reason_code = WLAN_REASON_DEAUTH_LEAVING;
679 	req.ie = NULL;
680 	req.ie_len = 0;
681 
682 	if (wdev->current_bss) {
683 		req.bss = &wdev->current_bss->pub;
684 		rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
685 		if (wdev->current_bss) {
686 			cfg80211_unhold_bss(wdev->current_bss);
687 			cfg80211_put_bss(&wdev->current_bss->pub);
688 			wdev->current_bss = NULL;
689 		}
690 	}
691 
692 	for (i = 0; i < MAX_AUTH_BSSES; i++) {
693 		if (wdev->auth_bsses[i]) {
694 			req.bss = &wdev->auth_bsses[i]->pub;
695 			rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
696 			if (wdev->auth_bsses[i]) {
697 				cfg80211_unhold_bss(wdev->auth_bsses[i]);
698 				cfg80211_put_bss(&wdev->auth_bsses[i]->pub);
699 				wdev->auth_bsses[i] = NULL;
700 			}
701 		}
702 		if (wdev->authtry_bsses[i]) {
703 			req.bss = &wdev->authtry_bsses[i]->pub;
704 			rdev->ops->deauth(&rdev->wiphy, dev, &req, wdev);
705 			if (wdev->authtry_bsses[i]) {
706 				cfg80211_unhold_bss(wdev->authtry_bsses[i]);
707 				cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
708 				wdev->authtry_bsses[i] = NULL;
709 			}
710 		}
711 	}
712 }
713 
714 void cfg80211_ready_on_channel(struct net_device *dev, u64 cookie,
715 			       struct ieee80211_channel *chan,
716 			       enum nl80211_channel_type channel_type,
717 			       unsigned int duration, gfp_t gfp)
718 {
719 	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
720 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
721 
722 	nl80211_send_remain_on_channel(rdev, dev, cookie, chan, channel_type,
723 				       duration, gfp);
724 }
725 EXPORT_SYMBOL(cfg80211_ready_on_channel);
726 
727 void cfg80211_remain_on_channel_expired(struct net_device *dev,
728 					u64 cookie,
729 					struct ieee80211_channel *chan,
730 					enum nl80211_channel_type channel_type,
731 					gfp_t gfp)
732 {
733 	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
734 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
735 
736 	nl80211_send_remain_on_channel_cancel(rdev, dev, cookie, chan,
737 					      channel_type, gfp);
738 }
739 EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
740 
741 void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
742 		      struct station_info *sinfo, gfp_t gfp)
743 {
744 	struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
745 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
746 
747 	nl80211_send_sta_event(rdev, dev, mac_addr, sinfo, gfp);
748 }
749 EXPORT_SYMBOL(cfg80211_new_sta);
750 
751 struct cfg80211_mgmt_registration {
752 	struct list_head list;
753 
754 	u32 nlpid;
755 
756 	int match_len;
757 
758 	__le16 frame_type;
759 
760 	u8 match[];
761 };
762 
763 int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid,
764 				u16 frame_type, const u8 *match_data,
765 				int match_len)
766 {
767 	struct wiphy *wiphy = wdev->wiphy;
768 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
769 	struct cfg80211_mgmt_registration *reg, *nreg;
770 	int err = 0;
771 	u16 mgmt_type;
772 
773 	if (!wdev->wiphy->mgmt_stypes)
774 		return -EOPNOTSUPP;
775 
776 	if ((frame_type & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT)
777 		return -EINVAL;
778 
779 	if (frame_type & ~(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE))
780 		return -EINVAL;
781 
782 	mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
783 	if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].rx & BIT(mgmt_type)))
784 		return -EINVAL;
785 
786 	nreg = kzalloc(sizeof(*reg) + match_len, GFP_KERNEL);
787 	if (!nreg)
788 		return -ENOMEM;
789 
790 	spin_lock_bh(&wdev->mgmt_registrations_lock);
791 
792 	list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
793 		int mlen = min(match_len, reg->match_len);
794 
795 		if (frame_type != le16_to_cpu(reg->frame_type))
796 			continue;
797 
798 		if (memcmp(reg->match, match_data, mlen) == 0) {
799 			err = -EALREADY;
800 			break;
801 		}
802 	}
803 
804 	if (err) {
805 		kfree(nreg);
806 		goto out;
807 	}
808 
809 	memcpy(nreg->match, match_data, match_len);
810 	nreg->match_len = match_len;
811 	nreg->nlpid = snd_pid;
812 	nreg->frame_type = cpu_to_le16(frame_type);
813 	list_add(&nreg->list, &wdev->mgmt_registrations);
814 
815 	if (rdev->ops->mgmt_frame_register)
816 		rdev->ops->mgmt_frame_register(wiphy, wdev->netdev,
817 					       frame_type, true);
818 
819  out:
820 	spin_unlock_bh(&wdev->mgmt_registrations_lock);
821 
822 	return err;
823 }
824 
825 void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid)
826 {
827 	struct wiphy *wiphy = wdev->wiphy;
828 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
829 	struct cfg80211_mgmt_registration *reg, *tmp;
830 
831 	spin_lock_bh(&wdev->mgmt_registrations_lock);
832 
833 	list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
834 		if (reg->nlpid != nlpid)
835 			continue;
836 
837 		if (rdev->ops->mgmt_frame_register) {
838 			u16 frame_type = le16_to_cpu(reg->frame_type);
839 
840 			rdev->ops->mgmt_frame_register(wiphy, wdev->netdev,
841 						       frame_type, false);
842 		}
843 
844 		list_del(&reg->list);
845 		kfree(reg);
846 	}
847 
848 	spin_unlock_bh(&wdev->mgmt_registrations_lock);
849 }
850 
851 void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
852 {
853 	struct cfg80211_mgmt_registration *reg, *tmp;
854 
855 	spin_lock_bh(&wdev->mgmt_registrations_lock);
856 
857 	list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
858 		list_del(&reg->list);
859 		kfree(reg);
860 	}
861 
862 	spin_unlock_bh(&wdev->mgmt_registrations_lock);
863 }
864 
865 int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
866 			  struct net_device *dev,
867 			  struct ieee80211_channel *chan,
868 			  enum nl80211_channel_type channel_type,
869 			  bool channel_type_valid,
870 			  const u8 *buf, size_t len, u64 *cookie)
871 {
872 	struct wireless_dev *wdev = dev->ieee80211_ptr;
873 	const struct ieee80211_mgmt *mgmt;
874 	u16 stype;
875 
876 	if (!wdev->wiphy->mgmt_stypes)
877 		return -EOPNOTSUPP;
878 
879 	if (!rdev->ops->mgmt_tx)
880 		return -EOPNOTSUPP;
881 
882 	if (len < 24 + 1)
883 		return -EINVAL;
884 
885 	mgmt = (const struct ieee80211_mgmt *) buf;
886 
887 	if (!ieee80211_is_mgmt(mgmt->frame_control))
888 		return -EINVAL;
889 
890 	stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
891 	if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].tx & BIT(stype >> 4)))
892 		return -EINVAL;
893 
894 	if (ieee80211_is_action(mgmt->frame_control) &&
895 	    mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) {
896 		int err = 0;
897 
898 		wdev_lock(wdev);
899 
900 		switch (wdev->iftype) {
901 		case NL80211_IFTYPE_ADHOC:
902 		case NL80211_IFTYPE_STATION:
903 		case NL80211_IFTYPE_P2P_CLIENT:
904 			if (!wdev->current_bss) {
905 				err = -ENOTCONN;
906 				break;
907 			}
908 
909 			if (memcmp(wdev->current_bss->pub.bssid,
910 				   mgmt->bssid, ETH_ALEN)) {
911 				err = -ENOTCONN;
912 				break;
913 			}
914 
915 			/*
916 			 * check for IBSS DA must be done by driver as
917 			 * cfg80211 doesn't track the stations
918 			 */
919 			if (wdev->iftype == NL80211_IFTYPE_ADHOC)
920 				break;
921 
922 			/* for station, check that DA is the AP */
923 			if (memcmp(wdev->current_bss->pub.bssid,
924 				   mgmt->da, ETH_ALEN)) {
925 				err = -ENOTCONN;
926 				break;
927 			}
928 			break;
929 		case NL80211_IFTYPE_AP:
930 		case NL80211_IFTYPE_P2P_GO:
931 		case NL80211_IFTYPE_AP_VLAN:
932 			if (memcmp(mgmt->bssid, dev->dev_addr, ETH_ALEN))
933 				err = -EINVAL;
934 			break;
935 		default:
936 			err = -EOPNOTSUPP;
937 			break;
938 		}
939 		wdev_unlock(wdev);
940 
941 		if (err)
942 			return err;
943 	}
944 
945 	if (memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0)
946 		return -EINVAL;
947 
948 	/* Transmit the Action frame as requested by user space */
949 	return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, channel_type,
950 				  channel_type_valid, buf, len, cookie);
951 }
952 
953 bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf,
954 		      size_t len, gfp_t gfp)
955 {
956 	struct wireless_dev *wdev = dev->ieee80211_ptr;
957 	struct wiphy *wiphy = wdev->wiphy;
958 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
959 	struct cfg80211_mgmt_registration *reg;
960 	const struct ieee80211_txrx_stypes *stypes =
961 		&wiphy->mgmt_stypes[wdev->iftype];
962 	struct ieee80211_mgmt *mgmt = (void *)buf;
963 	const u8 *data;
964 	int data_len;
965 	bool result = false;
966 	__le16 ftype = mgmt->frame_control &
967 		cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE);
968 	u16 stype;
969 
970 	stype = (le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) >> 4;
971 
972 	if (!(stypes->rx & BIT(stype)))
973 		return false;
974 
975 	data = buf + ieee80211_hdrlen(mgmt->frame_control);
976 	data_len = len - ieee80211_hdrlen(mgmt->frame_control);
977 
978 	spin_lock_bh(&wdev->mgmt_registrations_lock);
979 
980 	list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
981 		if (reg->frame_type != ftype)
982 			continue;
983 
984 		if (reg->match_len > data_len)
985 			continue;
986 
987 		if (memcmp(reg->match, data, reg->match_len))
988 			continue;
989 
990 		/* found match! */
991 
992 		/* Indicate the received Action frame to user space */
993 		if (nl80211_send_mgmt(rdev, dev, reg->nlpid, freq,
994 				      buf, len, gfp))
995 			continue;
996 
997 		result = true;
998 		break;
999 	}
1000 
1001 	spin_unlock_bh(&wdev->mgmt_registrations_lock);
1002 
1003 	return result;
1004 }
1005 EXPORT_SYMBOL(cfg80211_rx_mgmt);
1006 
1007 void cfg80211_mgmt_tx_status(struct net_device *dev, u64 cookie,
1008 			     const u8 *buf, size_t len, bool ack, gfp_t gfp)
1009 {
1010 	struct wireless_dev *wdev = dev->ieee80211_ptr;
1011 	struct wiphy *wiphy = wdev->wiphy;
1012 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
1013 
1014 	/* Indicate TX status of the Action frame to user space */
1015 	nl80211_send_mgmt_tx_status(rdev, dev, cookie, buf, len, ack, gfp);
1016 }
1017 EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
1018 
1019 void cfg80211_cqm_rssi_notify(struct net_device *dev,
1020 			      enum nl80211_cqm_rssi_threshold_event rssi_event,
1021 			      gfp_t gfp)
1022 {
1023 	struct wireless_dev *wdev = dev->ieee80211_ptr;
1024 	struct wiphy *wiphy = wdev->wiphy;
1025 	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
1026 
1027 	/* Indicate roaming trigger event to user space */
1028 	nl80211_send_cqm_rssi_notify(rdev, dev, rssi_event, gfp);
1029 }
1030 EXPORT_SYMBOL(cfg80211_cqm_rssi_notify);
1031