xref: /kernel/linux/linux-6.6/net/wireless/sme.c (revision 62306a36)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * SME code for cfg80211
4 * both driver SME event handling and the SME implementation
5 * (for nl80211's connect() and wext)
6 *
7 * Copyright 2009	Johannes Berg <johannes@sipsolutions.net>
8 * Copyright (C) 2009, 2020, 2022-2023 Intel Corporation. All rights reserved.
9 * Copyright 2017	Intel Deutschland GmbH
10 */
11
12#include <linux/etherdevice.h>
13#include <linux/if_arp.h>
14#include <linux/slab.h>
15#include <linux/workqueue.h>
16#include <linux/wireless.h>
17#include <linux/export.h>
18#include <net/iw_handler.h>
19#include <net/cfg80211.h>
20#include <net/rtnetlink.h>
21#include "nl80211.h"
22#include "reg.h"
23#include "rdev-ops.h"
24
25/*
26 * Software SME in cfg80211, using auth/assoc/deauth calls to the
27 * driver. This is for implementing nl80211's connect/disconnect
28 * and wireless extensions (if configured.)
29 */
30
31struct cfg80211_conn {
32	struct cfg80211_connect_params params;
33	/* these are sub-states of the _CONNECTING sme_state */
34	enum {
35		CFG80211_CONN_SCANNING,
36		CFG80211_CONN_SCAN_AGAIN,
37		CFG80211_CONN_AUTHENTICATE_NEXT,
38		CFG80211_CONN_AUTHENTICATING,
39		CFG80211_CONN_AUTH_FAILED_TIMEOUT,
40		CFG80211_CONN_ASSOCIATE_NEXT,
41		CFG80211_CONN_ASSOCIATING,
42		CFG80211_CONN_ASSOC_FAILED,
43		CFG80211_CONN_ASSOC_FAILED_TIMEOUT,
44		CFG80211_CONN_DEAUTH,
45		CFG80211_CONN_ABANDON,
46		CFG80211_CONN_CONNECTED,
47	} state;
48	u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN];
49	const u8 *ie;
50	size_t ie_len;
51	bool auto_auth, prev_bssid_valid;
52};
53
54static void cfg80211_sme_free(struct wireless_dev *wdev)
55{
56	if (!wdev->conn)
57		return;
58
59	kfree(wdev->conn->ie);
60	kfree(wdev->conn);
61	wdev->conn = NULL;
62}
63
64static int cfg80211_conn_scan(struct wireless_dev *wdev)
65{
66	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
67	struct cfg80211_scan_request *request;
68	int n_channels, err;
69
70	ASSERT_WDEV_LOCK(wdev);
71
72	if (rdev->scan_req || rdev->scan_msg)
73		return -EBUSY;
74
75	if (wdev->conn->params.channel)
76		n_channels = 1;
77	else
78		n_channels = ieee80211_get_num_supported_channels(wdev->wiphy);
79
80	request = kzalloc(sizeof(*request) + sizeof(request->ssids[0]) +
81			  sizeof(request->channels[0]) * n_channels,
82			  GFP_KERNEL);
83	if (!request)
84		return -ENOMEM;
85
86	if (wdev->conn->params.channel) {
87		enum nl80211_band band = wdev->conn->params.channel->band;
88		struct ieee80211_supported_band *sband =
89			wdev->wiphy->bands[band];
90
91		if (!sband) {
92			kfree(request);
93			return -EINVAL;
94		}
95		request->channels[0] = wdev->conn->params.channel;
96		request->rates[band] = (1 << sband->n_bitrates) - 1;
97	} else {
98		int i = 0, j;
99		enum nl80211_band band;
100		struct ieee80211_supported_band *bands;
101		struct ieee80211_channel *channel;
102
103		for (band = 0; band < NUM_NL80211_BANDS; band++) {
104			bands = wdev->wiphy->bands[band];
105			if (!bands)
106				continue;
107			for (j = 0; j < bands->n_channels; j++) {
108				channel = &bands->channels[j];
109				if (channel->flags & IEEE80211_CHAN_DISABLED)
110					continue;
111				request->channels[i++] = channel;
112			}
113			request->rates[band] = (1 << bands->n_bitrates) - 1;
114		}
115		n_channels = i;
116	}
117	request->n_channels = n_channels;
118	request->ssids = (void *)&request->channels[n_channels];
119	request->n_ssids = 1;
120
121	memcpy(request->ssids[0].ssid, wdev->conn->params.ssid,
122		wdev->conn->params.ssid_len);
123	request->ssids[0].ssid_len = wdev->conn->params.ssid_len;
124
125	eth_broadcast_addr(request->bssid);
126
127	request->wdev = wdev;
128	request->wiphy = &rdev->wiphy;
129	request->scan_start = jiffies;
130
131	rdev->scan_req = request;
132
133	err = rdev_scan(rdev, request);
134	if (!err) {
135		wdev->conn->state = CFG80211_CONN_SCANNING;
136		nl80211_send_scan_start(rdev, wdev);
137		dev_hold(wdev->netdev);
138	} else {
139		rdev->scan_req = NULL;
140		kfree(request);
141	}
142	return err;
143}
144
145static int cfg80211_conn_do_work(struct wireless_dev *wdev,
146				 enum nl80211_timeout_reason *treason)
147{
148	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
149	struct cfg80211_connect_params *params;
150	struct cfg80211_auth_request auth_req = {};
151	struct cfg80211_assoc_request req = {};
152	int err;
153
154	ASSERT_WDEV_LOCK(wdev);
155
156	if (!wdev->conn)
157		return 0;
158
159	params = &wdev->conn->params;
160
161	switch (wdev->conn->state) {
162	case CFG80211_CONN_SCANNING:
163		/* didn't find it during scan ... */
164		return -ENOENT;
165	case CFG80211_CONN_SCAN_AGAIN:
166		return cfg80211_conn_scan(wdev);
167	case CFG80211_CONN_AUTHENTICATE_NEXT:
168		if (WARN_ON(!rdev->ops->auth))
169			return -EOPNOTSUPP;
170		wdev->conn->state = CFG80211_CONN_AUTHENTICATING;
171		auth_req.key = params->key;
172		auth_req.key_len = params->key_len;
173		auth_req.key_idx = params->key_idx;
174		auth_req.auth_type = params->auth_type;
175		auth_req.bss = cfg80211_get_bss(&rdev->wiphy, params->channel,
176						params->bssid,
177						params->ssid, params->ssid_len,
178						IEEE80211_BSS_TYPE_ESS,
179						IEEE80211_PRIVACY_ANY);
180		auth_req.link_id = -1;
181		err = cfg80211_mlme_auth(rdev, wdev->netdev, &auth_req);
182		cfg80211_put_bss(&rdev->wiphy, auth_req.bss);
183		return err;
184	case CFG80211_CONN_AUTH_FAILED_TIMEOUT:
185		*treason = NL80211_TIMEOUT_AUTH;
186		return -ENOTCONN;
187	case CFG80211_CONN_ASSOCIATE_NEXT:
188		if (WARN_ON(!rdev->ops->assoc))
189			return -EOPNOTSUPP;
190		wdev->conn->state = CFG80211_CONN_ASSOCIATING;
191		if (wdev->conn->prev_bssid_valid)
192			req.prev_bssid = wdev->conn->prev_bssid;
193		req.ie = params->ie;
194		req.ie_len = params->ie_len;
195		req.use_mfp = params->mfp != NL80211_MFP_NO;
196		req.crypto = params->crypto;
197		req.flags = params->flags;
198		req.ht_capa = params->ht_capa;
199		req.ht_capa_mask = params->ht_capa_mask;
200		req.vht_capa = params->vht_capa;
201		req.vht_capa_mask = params->vht_capa_mask;
202		req.link_id = -1;
203
204		req.bss = cfg80211_get_bss(&rdev->wiphy, params->channel,
205					   params->bssid,
206					   params->ssid, params->ssid_len,
207					   IEEE80211_BSS_TYPE_ESS,
208					   IEEE80211_PRIVACY_ANY);
209		if (!req.bss) {
210			err = -ENOENT;
211		} else {
212			err = cfg80211_mlme_assoc(rdev, wdev->netdev, &req);
213			cfg80211_put_bss(&rdev->wiphy, req.bss);
214		}
215
216		if (err)
217			cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
218					     NULL, 0,
219					     WLAN_REASON_DEAUTH_LEAVING,
220					     false);
221		return err;
222	case CFG80211_CONN_ASSOC_FAILED_TIMEOUT:
223		*treason = NL80211_TIMEOUT_ASSOC;
224		fallthrough;
225	case CFG80211_CONN_ASSOC_FAILED:
226		cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
227				     NULL, 0,
228				     WLAN_REASON_DEAUTH_LEAVING, false);
229		return -ENOTCONN;
230	case CFG80211_CONN_DEAUTH:
231		cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
232				     NULL, 0,
233				     WLAN_REASON_DEAUTH_LEAVING, false);
234		fallthrough;
235	case CFG80211_CONN_ABANDON:
236		/* free directly, disconnected event already sent */
237		cfg80211_sme_free(wdev);
238		return 0;
239	default:
240		return 0;
241	}
242}
243
244void cfg80211_conn_work(struct work_struct *work)
245{
246	struct cfg80211_registered_device *rdev =
247		container_of(work, struct cfg80211_registered_device, conn_work);
248	struct wireless_dev *wdev;
249	u8 bssid_buf[ETH_ALEN], *bssid = NULL;
250	enum nl80211_timeout_reason treason;
251
252	wiphy_lock(&rdev->wiphy);
253
254	list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
255		if (!wdev->netdev)
256			continue;
257
258		wdev_lock(wdev);
259		if (!netif_running(wdev->netdev)) {
260			wdev_unlock(wdev);
261			continue;
262		}
263		if (!wdev->conn ||
264		    wdev->conn->state == CFG80211_CONN_CONNECTED) {
265			wdev_unlock(wdev);
266			continue;
267		}
268		if (wdev->conn->params.bssid) {
269			memcpy(bssid_buf, wdev->conn->params.bssid, ETH_ALEN);
270			bssid = bssid_buf;
271		}
272		treason = NL80211_TIMEOUT_UNSPECIFIED;
273		if (cfg80211_conn_do_work(wdev, &treason)) {
274			struct cfg80211_connect_resp_params cr;
275
276			memset(&cr, 0, sizeof(cr));
277			cr.status = -1;
278			cr.links[0].bssid = bssid;
279			cr.timeout_reason = treason;
280			__cfg80211_connect_result(wdev->netdev, &cr, false);
281		}
282		wdev_unlock(wdev);
283	}
284
285	wiphy_unlock(&rdev->wiphy);
286}
287
288static void cfg80211_step_auth_next(struct cfg80211_conn *conn,
289				    struct cfg80211_bss *bss)
290{
291	memcpy(conn->bssid, bss->bssid, ETH_ALEN);
292	conn->params.bssid = conn->bssid;
293	conn->params.channel = bss->channel;
294	conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
295}
296
297/* Returned bss is reference counted and must be cleaned up appropriately. */
298static struct cfg80211_bss *cfg80211_get_conn_bss(struct wireless_dev *wdev)
299{
300	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
301	struct cfg80211_bss *bss;
302
303	ASSERT_WDEV_LOCK(wdev);
304
305	bss = cfg80211_get_bss(wdev->wiphy, wdev->conn->params.channel,
306			       wdev->conn->params.bssid,
307			       wdev->conn->params.ssid,
308			       wdev->conn->params.ssid_len,
309			       wdev->conn_bss_type,
310			       IEEE80211_PRIVACY(wdev->conn->params.privacy));
311	if (!bss)
312		return NULL;
313
314	cfg80211_step_auth_next(wdev->conn, bss);
315	schedule_work(&rdev->conn_work);
316
317	return bss;
318}
319
320static void __cfg80211_sme_scan_done(struct net_device *dev)
321{
322	struct wireless_dev *wdev = dev->ieee80211_ptr;
323	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
324	struct cfg80211_bss *bss;
325
326	ASSERT_WDEV_LOCK(wdev);
327
328	if (!wdev->conn)
329		return;
330
331	if (wdev->conn->state != CFG80211_CONN_SCANNING &&
332	    wdev->conn->state != CFG80211_CONN_SCAN_AGAIN)
333		return;
334
335	bss = cfg80211_get_conn_bss(wdev);
336	if (bss)
337		cfg80211_put_bss(&rdev->wiphy, bss);
338	else
339		schedule_work(&rdev->conn_work);
340}
341
342void cfg80211_sme_scan_done(struct net_device *dev)
343{
344	struct wireless_dev *wdev = dev->ieee80211_ptr;
345
346	wdev_lock(wdev);
347	__cfg80211_sme_scan_done(dev);
348	wdev_unlock(wdev);
349}
350
351void cfg80211_sme_rx_auth(struct wireless_dev *wdev, const u8 *buf, size_t len)
352{
353	struct wiphy *wiphy = wdev->wiphy;
354	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
355	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
356	u16 status_code = le16_to_cpu(mgmt->u.auth.status_code);
357
358	ASSERT_WDEV_LOCK(wdev);
359
360	if (!wdev->conn || wdev->conn->state == CFG80211_CONN_CONNECTED)
361		return;
362
363	if (status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG &&
364	    wdev->conn->auto_auth &&
365	    wdev->conn->params.auth_type != NL80211_AUTHTYPE_NETWORK_EAP) {
366		/* select automatically between only open, shared, leap */
367		switch (wdev->conn->params.auth_type) {
368		case NL80211_AUTHTYPE_OPEN_SYSTEM:
369			if (wdev->connect_keys)
370				wdev->conn->params.auth_type =
371					NL80211_AUTHTYPE_SHARED_KEY;
372			else
373				wdev->conn->params.auth_type =
374					NL80211_AUTHTYPE_NETWORK_EAP;
375			break;
376		case NL80211_AUTHTYPE_SHARED_KEY:
377			wdev->conn->params.auth_type =
378				NL80211_AUTHTYPE_NETWORK_EAP;
379			break;
380		default:
381			/* huh? */
382			wdev->conn->params.auth_type =
383				NL80211_AUTHTYPE_OPEN_SYSTEM;
384			break;
385		}
386		wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
387		schedule_work(&rdev->conn_work);
388	} else if (status_code != WLAN_STATUS_SUCCESS) {
389		struct cfg80211_connect_resp_params cr;
390
391		memset(&cr, 0, sizeof(cr));
392		cr.status = status_code;
393		cr.links[0].bssid = mgmt->bssid;
394		cr.timeout_reason = NL80211_TIMEOUT_UNSPECIFIED;
395		__cfg80211_connect_result(wdev->netdev, &cr, false);
396	} else if (wdev->conn->state == CFG80211_CONN_AUTHENTICATING) {
397		wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;
398		schedule_work(&rdev->conn_work);
399	}
400}
401
402bool cfg80211_sme_rx_assoc_resp(struct wireless_dev *wdev, u16 status)
403{
404	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
405
406	if (!wdev->conn)
407		return false;
408
409	if (status == WLAN_STATUS_SUCCESS) {
410		wdev->conn->state = CFG80211_CONN_CONNECTED;
411		return false;
412	}
413
414	if (wdev->conn->prev_bssid_valid) {
415		/*
416		 * Some stupid APs don't accept reassoc, so we
417		 * need to fall back to trying regular assoc;
418		 * return true so no event is sent to userspace.
419		 */
420		wdev->conn->prev_bssid_valid = false;
421		wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;
422		schedule_work(&rdev->conn_work);
423		return true;
424	}
425
426	wdev->conn->state = CFG80211_CONN_ASSOC_FAILED;
427	schedule_work(&rdev->conn_work);
428	return false;
429}
430
431void cfg80211_sme_deauth(struct wireless_dev *wdev)
432{
433	cfg80211_sme_free(wdev);
434}
435
436void cfg80211_sme_auth_timeout(struct wireless_dev *wdev)
437{
438	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
439
440	if (!wdev->conn)
441		return;
442
443	wdev->conn->state = CFG80211_CONN_AUTH_FAILED_TIMEOUT;
444	schedule_work(&rdev->conn_work);
445}
446
447void cfg80211_sme_disassoc(struct wireless_dev *wdev)
448{
449	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
450
451	if (!wdev->conn)
452		return;
453
454	wdev->conn->state = CFG80211_CONN_DEAUTH;
455	schedule_work(&rdev->conn_work);
456}
457
458void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev)
459{
460	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
461
462	if (!wdev->conn)
463		return;
464
465	wdev->conn->state = CFG80211_CONN_ASSOC_FAILED_TIMEOUT;
466	schedule_work(&rdev->conn_work);
467}
468
469void cfg80211_sme_abandon_assoc(struct wireless_dev *wdev)
470{
471	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
472
473	if (!wdev->conn)
474		return;
475
476	wdev->conn->state = CFG80211_CONN_ABANDON;
477	schedule_work(&rdev->conn_work);
478}
479
480static void cfg80211_wdev_release_bsses(struct wireless_dev *wdev)
481{
482	unsigned int link;
483
484	for_each_valid_link(wdev, link) {
485		if (!wdev->links[link].client.current_bss)
486			continue;
487		cfg80211_unhold_bss(wdev->links[link].client.current_bss);
488		cfg80211_put_bss(wdev->wiphy,
489				 &wdev->links[link].client.current_bss->pub);
490		wdev->links[link].client.current_bss = NULL;
491	}
492}
493
494void cfg80211_wdev_release_link_bsses(struct wireless_dev *wdev, u16 link_mask)
495{
496	unsigned int link;
497
498	for_each_valid_link(wdev, link) {
499		if (!wdev->links[link].client.current_bss ||
500		    !(link_mask & BIT(link)))
501			continue;
502		cfg80211_unhold_bss(wdev->links[link].client.current_bss);
503		cfg80211_put_bss(wdev->wiphy,
504				 &wdev->links[link].client.current_bss->pub);
505		wdev->links[link].client.current_bss = NULL;
506	}
507}
508
509static int cfg80211_sme_get_conn_ies(struct wireless_dev *wdev,
510				     const u8 *ies, size_t ies_len,
511				     const u8 **out_ies, size_t *out_ies_len)
512{
513	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
514	u8 *buf;
515	size_t offs;
516
517	if (!rdev->wiphy.extended_capabilities_len ||
518	    (ies && cfg80211_find_ie(WLAN_EID_EXT_CAPABILITY, ies, ies_len))) {
519		*out_ies = kmemdup(ies, ies_len, GFP_KERNEL);
520		if (!*out_ies)
521			return -ENOMEM;
522		*out_ies_len = ies_len;
523		return 0;
524	}
525
526	buf = kmalloc(ies_len + rdev->wiphy.extended_capabilities_len + 2,
527		      GFP_KERNEL);
528	if (!buf)
529		return -ENOMEM;
530
531	if (ies_len) {
532		static const u8 before_extcapa[] = {
533			/* not listing IEs expected to be created by driver */
534			WLAN_EID_RSN,
535			WLAN_EID_QOS_CAPA,
536			WLAN_EID_RRM_ENABLED_CAPABILITIES,
537			WLAN_EID_MOBILITY_DOMAIN,
538			WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
539			WLAN_EID_BSS_COEX_2040,
540		};
541
542		offs = ieee80211_ie_split(ies, ies_len, before_extcapa,
543					  ARRAY_SIZE(before_extcapa), 0);
544		memcpy(buf, ies, offs);
545		/* leave a whole for extended capabilities IE */
546		memcpy(buf + offs + rdev->wiphy.extended_capabilities_len + 2,
547		       ies + offs, ies_len - offs);
548	} else {
549		offs = 0;
550	}
551
552	/* place extended capabilities IE (with only driver capabilities) */
553	buf[offs] = WLAN_EID_EXT_CAPABILITY;
554	buf[offs + 1] = rdev->wiphy.extended_capabilities_len;
555	memcpy(buf + offs + 2,
556	       rdev->wiphy.extended_capabilities,
557	       rdev->wiphy.extended_capabilities_len);
558
559	*out_ies = buf;
560	*out_ies_len = ies_len + rdev->wiphy.extended_capabilities_len + 2;
561
562	return 0;
563}
564
565static int cfg80211_sme_connect(struct wireless_dev *wdev,
566				struct cfg80211_connect_params *connect,
567				const u8 *prev_bssid)
568{
569	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
570	struct cfg80211_bss *bss;
571	int err;
572
573	if (!rdev->ops->auth || !rdev->ops->assoc)
574		return -EOPNOTSUPP;
575
576	cfg80211_wdev_release_bsses(wdev);
577
578	if (wdev->connected) {
579		cfg80211_sme_free(wdev);
580		wdev->connected = false;
581	}
582
583	if (wdev->conn)
584		return -EINPROGRESS;
585
586	wdev->conn = kzalloc(sizeof(*wdev->conn), GFP_KERNEL);
587	if (!wdev->conn)
588		return -ENOMEM;
589
590	/*
591	 * Copy all parameters, and treat explicitly IEs, BSSID, SSID.
592	 */
593	memcpy(&wdev->conn->params, connect, sizeof(*connect));
594	if (connect->bssid) {
595		wdev->conn->params.bssid = wdev->conn->bssid;
596		memcpy(wdev->conn->bssid, connect->bssid, ETH_ALEN);
597	}
598
599	if (cfg80211_sme_get_conn_ies(wdev, connect->ie, connect->ie_len,
600				      &wdev->conn->ie,
601				      &wdev->conn->params.ie_len)) {
602		kfree(wdev->conn);
603		wdev->conn = NULL;
604		return -ENOMEM;
605	}
606	wdev->conn->params.ie = wdev->conn->ie;
607
608	if (connect->auth_type == NL80211_AUTHTYPE_AUTOMATIC) {
609		wdev->conn->auto_auth = true;
610		/* start with open system ... should mostly work */
611		wdev->conn->params.auth_type =
612			NL80211_AUTHTYPE_OPEN_SYSTEM;
613	} else {
614		wdev->conn->auto_auth = false;
615	}
616
617	wdev->conn->params.ssid = wdev->u.client.ssid;
618	wdev->conn->params.ssid_len = wdev->u.client.ssid_len;
619
620	/* see if we have the bss already */
621	bss = cfg80211_get_bss(wdev->wiphy, wdev->conn->params.channel,
622			       wdev->conn->params.bssid,
623			       wdev->conn->params.ssid,
624			       wdev->conn->params.ssid_len,
625			       wdev->conn_bss_type,
626			       IEEE80211_PRIVACY(wdev->conn->params.privacy));
627
628	if (prev_bssid) {
629		memcpy(wdev->conn->prev_bssid, prev_bssid, ETH_ALEN);
630		wdev->conn->prev_bssid_valid = true;
631	}
632
633	/* we're good if we have a matching bss struct */
634	if (bss) {
635		enum nl80211_timeout_reason treason;
636
637		cfg80211_step_auth_next(wdev->conn, bss);
638		err = cfg80211_conn_do_work(wdev, &treason);
639		cfg80211_put_bss(wdev->wiphy, bss);
640	} else {
641		/* otherwise we'll need to scan for the AP first */
642		err = cfg80211_conn_scan(wdev);
643
644		/*
645		 * If we can't scan right now, then we need to scan again
646		 * after the current scan finished, since the parameters
647		 * changed (unless we find a good AP anyway).
648		 */
649		if (err == -EBUSY) {
650			err = 0;
651			wdev->conn->state = CFG80211_CONN_SCAN_AGAIN;
652		}
653	}
654
655	if (err)
656		cfg80211_sme_free(wdev);
657
658	return err;
659}
660
661static int cfg80211_sme_disconnect(struct wireless_dev *wdev, u16 reason)
662{
663	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
664	int err;
665
666	if (!wdev->conn)
667		return 0;
668
669	if (!rdev->ops->deauth)
670		return -EOPNOTSUPP;
671
672	if (wdev->conn->state == CFG80211_CONN_SCANNING ||
673	    wdev->conn->state == CFG80211_CONN_SCAN_AGAIN) {
674		err = 0;
675		goto out;
676	}
677
678	/* wdev->conn->params.bssid must be set if > SCANNING */
679	err = cfg80211_mlme_deauth(rdev, wdev->netdev,
680				   wdev->conn->params.bssid,
681				   NULL, 0, reason, false);
682 out:
683	cfg80211_sme_free(wdev);
684	return err;
685}
686
687/*
688 * code shared for in-device and software SME
689 */
690
691static bool cfg80211_is_all_idle(void)
692{
693	struct cfg80211_registered_device *rdev;
694	struct wireless_dev *wdev;
695	bool is_all_idle = true;
696
697	/*
698	 * All devices must be idle as otherwise if you are actively
699	 * scanning some new beacon hints could be learned and would
700	 * count as new regulatory hints.
701	 * Also if there is any other active beaconing interface we
702	 * need not issue a disconnect hint and reset any info such
703	 * as chan dfs state, etc.
704	 */
705	list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
706		list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
707			wdev_lock(wdev);
708			if (wdev->conn || wdev->connected ||
709			    cfg80211_beaconing_iface_active(wdev))
710				is_all_idle = false;
711			wdev_unlock(wdev);
712		}
713	}
714
715	return is_all_idle;
716}
717
718static void disconnect_work(struct work_struct *work)
719{
720	rtnl_lock();
721	if (cfg80211_is_all_idle())
722		regulatory_hint_disconnect();
723	rtnl_unlock();
724}
725
726DECLARE_WORK(cfg80211_disconnect_work, disconnect_work);
727
728static void
729cfg80211_connect_result_release_bsses(struct wireless_dev *wdev,
730				      struct cfg80211_connect_resp_params *cr)
731{
732	unsigned int link;
733
734	for_each_valid_link(cr, link) {
735		if (!cr->links[link].bss)
736			continue;
737		cfg80211_unhold_bss(bss_from_pub(cr->links[link].bss));
738		cfg80211_put_bss(wdev->wiphy, cr->links[link].bss);
739	}
740}
741
742/*
743 * API calls for drivers implementing connect/disconnect and
744 * SME event handling
745 */
746
747/* This method must consume bss one way or another */
748void __cfg80211_connect_result(struct net_device *dev,
749			       struct cfg80211_connect_resp_params *cr,
750			       bool wextev)
751{
752	struct wireless_dev *wdev = dev->ieee80211_ptr;
753	const struct element *country_elem = NULL;
754	const struct element *ssid;
755	const u8 *country_data;
756	u8 country_datalen;
757#ifdef CONFIG_CFG80211_WEXT
758	union iwreq_data wrqu;
759#endif
760	unsigned int link;
761	const u8 *connected_addr;
762	bool bss_not_found = false;
763
764	ASSERT_WDEV_LOCK(wdev);
765
766	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
767		    wdev->iftype != NL80211_IFTYPE_P2P_CLIENT))
768		goto out;
769
770	if (cr->valid_links) {
771		if (WARN_ON(!cr->ap_mld_addr))
772			goto out;
773
774		for_each_valid_link(cr, link) {
775			if (WARN_ON(!cr->links[link].addr))
776				goto out;
777		}
778
779		if (WARN_ON(wdev->connect_keys))
780			goto out;
781	}
782
783	wdev->unprot_beacon_reported = 0;
784	nl80211_send_connect_result(wiphy_to_rdev(wdev->wiphy), dev, cr,
785				    GFP_KERNEL);
786	connected_addr = cr->valid_links ? cr->ap_mld_addr : cr->links[0].bssid;
787
788#ifdef CONFIG_CFG80211_WEXT
789	if (wextev && !cr->valid_links) {
790		if (cr->req_ie && cr->status == WLAN_STATUS_SUCCESS) {
791			memset(&wrqu, 0, sizeof(wrqu));
792			wrqu.data.length = cr->req_ie_len;
793			wireless_send_event(dev, IWEVASSOCREQIE, &wrqu,
794					    cr->req_ie);
795		}
796
797		if (cr->resp_ie && cr->status == WLAN_STATUS_SUCCESS) {
798			memset(&wrqu, 0, sizeof(wrqu));
799			wrqu.data.length = cr->resp_ie_len;
800			wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu,
801					    cr->resp_ie);
802		}
803
804		memset(&wrqu, 0, sizeof(wrqu));
805		wrqu.ap_addr.sa_family = ARPHRD_ETHER;
806		if (connected_addr && cr->status == WLAN_STATUS_SUCCESS) {
807			memcpy(wrqu.ap_addr.sa_data, connected_addr, ETH_ALEN);
808			memcpy(wdev->wext.prev_bssid, connected_addr, ETH_ALEN);
809			wdev->wext.prev_bssid_valid = true;
810		}
811		wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
812	}
813#endif
814
815	if (cr->status == WLAN_STATUS_SUCCESS) {
816		if (!wiphy_to_rdev(wdev->wiphy)->ops->connect) {
817			for_each_valid_link(cr, link) {
818				if (WARN_ON_ONCE(!cr->links[link].bss))
819					break;
820			}
821		}
822
823		for_each_valid_link(cr, link) {
824			/* don't do extra lookups for failures */
825			if (cr->links[link].status != WLAN_STATUS_SUCCESS)
826				continue;
827
828			if (cr->links[link].bss)
829				continue;
830
831			cr->links[link].bss =
832				cfg80211_get_bss(wdev->wiphy, NULL,
833						 cr->links[link].bssid,
834						 wdev->u.client.ssid,
835						 wdev->u.client.ssid_len,
836						 wdev->conn_bss_type,
837						 IEEE80211_PRIVACY_ANY);
838			if (!cr->links[link].bss) {
839				bss_not_found = true;
840				break;
841			}
842			cfg80211_hold_bss(bss_from_pub(cr->links[link].bss));
843		}
844	}
845
846	cfg80211_wdev_release_bsses(wdev);
847
848	if (cr->status != WLAN_STATUS_SUCCESS) {
849		kfree_sensitive(wdev->connect_keys);
850		wdev->connect_keys = NULL;
851		wdev->u.client.ssid_len = 0;
852		wdev->conn_owner_nlportid = 0;
853		cfg80211_connect_result_release_bsses(wdev, cr);
854		cfg80211_sme_free(wdev);
855		return;
856	}
857
858	if (WARN_ON(bss_not_found)) {
859		cfg80211_connect_result_release_bsses(wdev, cr);
860		return;
861	}
862
863	memset(wdev->links, 0, sizeof(wdev->links));
864	for_each_valid_link(cr, link) {
865		if (cr->links[link].status == WLAN_STATUS_SUCCESS)
866			continue;
867		cr->valid_links &= ~BIT(link);
868		/* don't require bss pointer for failed links */
869		if (!cr->links[link].bss)
870			continue;
871		cfg80211_unhold_bss(bss_from_pub(cr->links[link].bss));
872		cfg80211_put_bss(wdev->wiphy, cr->links[link].bss);
873	}
874	wdev->valid_links = cr->valid_links;
875	for_each_valid_link(cr, link)
876		wdev->links[link].client.current_bss =
877			bss_from_pub(cr->links[link].bss);
878	wdev->connected = true;
879	ether_addr_copy(wdev->u.client.connected_addr, connected_addr);
880	if (cr->valid_links) {
881		for_each_valid_link(cr, link)
882			memcpy(wdev->links[link].addr, cr->links[link].addr,
883			       ETH_ALEN);
884	}
885
886	cfg80211_upload_connect_keys(wdev);
887
888	rcu_read_lock();
889	for_each_valid_link(cr, link) {
890		country_elem =
891			ieee80211_bss_get_elem(cr->links[link].bss,
892					       WLAN_EID_COUNTRY);
893		if (country_elem)
894			break;
895	}
896	if (!country_elem) {
897		rcu_read_unlock();
898		return;
899	}
900
901	country_datalen = country_elem->datalen;
902	country_data = kmemdup(country_elem->data, country_datalen, GFP_ATOMIC);
903	rcu_read_unlock();
904
905	if (!country_data)
906		return;
907
908	regulatory_hint_country_ie(wdev->wiphy,
909				   cr->links[link].bss->channel->band,
910				   country_data, country_datalen);
911	kfree(country_data);
912
913	if (!wdev->u.client.ssid_len) {
914		rcu_read_lock();
915		for_each_valid_link(cr, link) {
916			ssid = ieee80211_bss_get_elem(cr->links[link].bss,
917						      WLAN_EID_SSID);
918
919			if (!ssid || !ssid->datalen)
920				continue;
921
922			memcpy(wdev->u.client.ssid, ssid->data, ssid->datalen);
923			wdev->u.client.ssid_len = ssid->datalen;
924			break;
925		}
926		rcu_read_unlock();
927	}
928
929	return;
930out:
931	for_each_valid_link(cr, link)
932		cfg80211_put_bss(wdev->wiphy, cr->links[link].bss);
933}
934
935static void cfg80211_update_link_bss(struct wireless_dev *wdev,
936				     struct cfg80211_bss **bss)
937{
938	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
939	struct cfg80211_internal_bss *ibss;
940
941	if (!*bss)
942		return;
943
944	ibss = bss_from_pub(*bss);
945	if (list_empty(&ibss->list)) {
946		struct cfg80211_bss *found = NULL, *tmp = *bss;
947
948		found = cfg80211_get_bss(wdev->wiphy, NULL,
949					 (*bss)->bssid,
950					 wdev->u.client.ssid,
951					 wdev->u.client.ssid_len,
952					 wdev->conn_bss_type,
953					 IEEE80211_PRIVACY_ANY);
954		if (found) {
955			/* The same BSS is already updated so use it
956			 * instead, as it has latest info.
957			 */
958			*bss = found;
959		} else {
960			/* Update with BSS provided by driver, it will
961			 * be freshly added and ref cnted, we can free
962			 * the old one.
963			 *
964			 * signal_valid can be false, as we are not
965			 * expecting the BSS to be found.
966			 *
967			 * keep the old timestamp to avoid confusion
968			 */
969			cfg80211_bss_update(rdev, ibss, false,
970					    ibss->ts);
971		}
972
973		cfg80211_put_bss(wdev->wiphy, tmp);
974	}
975}
976
977/* Consumes bss object(s) one way or another */
978void cfg80211_connect_done(struct net_device *dev,
979			   struct cfg80211_connect_resp_params *params,
980			   gfp_t gfp)
981{
982	struct wireless_dev *wdev = dev->ieee80211_ptr;
983	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
984	struct cfg80211_event *ev;
985	unsigned long flags;
986	u8 *next;
987	size_t link_info_size = 0;
988	unsigned int link;
989
990	for_each_valid_link(params, link) {
991		cfg80211_update_link_bss(wdev, &params->links[link].bss);
992		link_info_size += params->links[link].bssid ? ETH_ALEN : 0;
993		link_info_size += params->links[link].addr ? ETH_ALEN : 0;
994	}
995
996	ev = kzalloc(sizeof(*ev) + (params->ap_mld_addr ? ETH_ALEN : 0) +
997		     params->req_ie_len + params->resp_ie_len +
998		     params->fils.kek_len + params->fils.pmk_len +
999		     (params->fils.pmkid ? WLAN_PMKID_LEN : 0) + link_info_size,
1000		     gfp);
1001
1002	if (!ev) {
1003		for_each_valid_link(params, link)
1004			cfg80211_put_bss(wdev->wiphy,
1005					 params->links[link].bss);
1006		return;
1007	}
1008
1009	ev->type = EVENT_CONNECT_RESULT;
1010	next = ((u8 *)ev) + sizeof(*ev);
1011	if (params->ap_mld_addr) {
1012		ev->cr.ap_mld_addr = next;
1013		memcpy((void *)ev->cr.ap_mld_addr, params->ap_mld_addr,
1014		       ETH_ALEN);
1015		next += ETH_ALEN;
1016	}
1017	if (params->req_ie_len) {
1018		ev->cr.req_ie = next;
1019		ev->cr.req_ie_len = params->req_ie_len;
1020		memcpy((void *)ev->cr.req_ie, params->req_ie,
1021		       params->req_ie_len);
1022		next += params->req_ie_len;
1023	}
1024	if (params->resp_ie_len) {
1025		ev->cr.resp_ie = next;
1026		ev->cr.resp_ie_len = params->resp_ie_len;
1027		memcpy((void *)ev->cr.resp_ie, params->resp_ie,
1028		       params->resp_ie_len);
1029		next += params->resp_ie_len;
1030	}
1031	if (params->fils.kek_len) {
1032		ev->cr.fils.kek = next;
1033		ev->cr.fils.kek_len = params->fils.kek_len;
1034		memcpy((void *)ev->cr.fils.kek, params->fils.kek,
1035		       params->fils.kek_len);
1036		next += params->fils.kek_len;
1037	}
1038	if (params->fils.pmk_len) {
1039		ev->cr.fils.pmk = next;
1040		ev->cr.fils.pmk_len = params->fils.pmk_len;
1041		memcpy((void *)ev->cr.fils.pmk, params->fils.pmk,
1042		       params->fils.pmk_len);
1043		next += params->fils.pmk_len;
1044	}
1045	if (params->fils.pmkid) {
1046		ev->cr.fils.pmkid = next;
1047		memcpy((void *)ev->cr.fils.pmkid, params->fils.pmkid,
1048		       WLAN_PMKID_LEN);
1049		next += WLAN_PMKID_LEN;
1050	}
1051	ev->cr.fils.update_erp_next_seq_num = params->fils.update_erp_next_seq_num;
1052	if (params->fils.update_erp_next_seq_num)
1053		ev->cr.fils.erp_next_seq_num = params->fils.erp_next_seq_num;
1054	ev->cr.valid_links = params->valid_links;
1055	for_each_valid_link(params, link) {
1056		if (params->links[link].bss)
1057			cfg80211_hold_bss(
1058				bss_from_pub(params->links[link].bss));
1059		ev->cr.links[link].bss = params->links[link].bss;
1060
1061		if (params->links[link].addr) {
1062			ev->cr.links[link].addr = next;
1063			memcpy((void *)ev->cr.links[link].addr,
1064			       params->links[link].addr,
1065			       ETH_ALEN);
1066			next += ETH_ALEN;
1067		}
1068		if (params->links[link].bssid) {
1069			ev->cr.links[link].bssid = next;
1070			memcpy((void *)ev->cr.links[link].bssid,
1071			       params->links[link].bssid,
1072			       ETH_ALEN);
1073			next += ETH_ALEN;
1074		}
1075	}
1076	ev->cr.status = params->status;
1077	ev->cr.timeout_reason = params->timeout_reason;
1078
1079	spin_lock_irqsave(&wdev->event_lock, flags);
1080	list_add_tail(&ev->list, &wdev->event_list);
1081	spin_unlock_irqrestore(&wdev->event_lock, flags);
1082	queue_work(cfg80211_wq, &rdev->event_work);
1083}
1084EXPORT_SYMBOL(cfg80211_connect_done);
1085
1086/* Consumes bss object one way or another */
1087void __cfg80211_roamed(struct wireless_dev *wdev,
1088		       struct cfg80211_roam_info *info)
1089{
1090#ifdef CONFIG_CFG80211_WEXT
1091	union iwreq_data wrqu;
1092#endif
1093	unsigned int link;
1094	const u8 *connected_addr;
1095
1096	ASSERT_WDEV_LOCK(wdev);
1097
1098	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
1099		    wdev->iftype != NL80211_IFTYPE_P2P_CLIENT))
1100		goto out;
1101
1102	if (WARN_ON(!wdev->connected))
1103		goto out;
1104
1105	if (info->valid_links) {
1106		if (WARN_ON(!info->ap_mld_addr))
1107			goto out;
1108
1109		for_each_valid_link(info, link) {
1110			if (WARN_ON(!info->links[link].addr))
1111				goto out;
1112		}
1113	}
1114
1115	cfg80211_wdev_release_bsses(wdev);
1116
1117	for_each_valid_link(info, link) {
1118		if (WARN_ON(!info->links[link].bss))
1119			goto out;
1120	}
1121
1122	memset(wdev->links, 0, sizeof(wdev->links));
1123	wdev->valid_links = info->valid_links;
1124	for_each_valid_link(info, link) {
1125		cfg80211_hold_bss(bss_from_pub(info->links[link].bss));
1126		wdev->links[link].client.current_bss =
1127			bss_from_pub(info->links[link].bss);
1128	}
1129
1130	connected_addr = info->valid_links ?
1131			 info->ap_mld_addr :
1132			 info->links[0].bss->bssid;
1133	ether_addr_copy(wdev->u.client.connected_addr, connected_addr);
1134	if (info->valid_links) {
1135		for_each_valid_link(info, link)
1136			memcpy(wdev->links[link].addr, info->links[link].addr,
1137			       ETH_ALEN);
1138	}
1139	wdev->unprot_beacon_reported = 0;
1140	nl80211_send_roamed(wiphy_to_rdev(wdev->wiphy),
1141			    wdev->netdev, info, GFP_KERNEL);
1142
1143#ifdef CONFIG_CFG80211_WEXT
1144	if (!info->valid_links) {
1145		if (info->req_ie) {
1146			memset(&wrqu, 0, sizeof(wrqu));
1147			wrqu.data.length = info->req_ie_len;
1148			wireless_send_event(wdev->netdev, IWEVASSOCREQIE,
1149					    &wrqu, info->req_ie);
1150		}
1151
1152		if (info->resp_ie) {
1153			memset(&wrqu, 0, sizeof(wrqu));
1154			wrqu.data.length = info->resp_ie_len;
1155			wireless_send_event(wdev->netdev, IWEVASSOCRESPIE,
1156					    &wrqu, info->resp_ie);
1157		}
1158
1159		memset(&wrqu, 0, sizeof(wrqu));
1160		wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1161		memcpy(wrqu.ap_addr.sa_data, connected_addr, ETH_ALEN);
1162		memcpy(wdev->wext.prev_bssid, connected_addr, ETH_ALEN);
1163		wdev->wext.prev_bssid_valid = true;
1164		wireless_send_event(wdev->netdev, SIOCGIWAP, &wrqu, NULL);
1165	}
1166#endif
1167
1168	return;
1169out:
1170	for_each_valid_link(info, link)
1171		cfg80211_put_bss(wdev->wiphy, info->links[link].bss);
1172}
1173
1174/* Consumes info->links.bss object(s) one way or another */
1175void cfg80211_roamed(struct net_device *dev, struct cfg80211_roam_info *info,
1176		     gfp_t gfp)
1177{
1178	struct wireless_dev *wdev = dev->ieee80211_ptr;
1179	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
1180	struct cfg80211_event *ev;
1181	unsigned long flags;
1182	u8 *next;
1183	unsigned int link;
1184	size_t link_info_size = 0;
1185	bool bss_not_found = false;
1186
1187	for_each_valid_link(info, link) {
1188		link_info_size += info->links[link].addr ? ETH_ALEN : 0;
1189		link_info_size += info->links[link].bssid ? ETH_ALEN : 0;
1190
1191		if (info->links[link].bss)
1192			continue;
1193
1194		info->links[link].bss =
1195			cfg80211_get_bss(wdev->wiphy,
1196					 info->links[link].channel,
1197					 info->links[link].bssid,
1198					 wdev->u.client.ssid,
1199					 wdev->u.client.ssid_len,
1200					 wdev->conn_bss_type,
1201					 IEEE80211_PRIVACY_ANY);
1202
1203		if (!info->links[link].bss) {
1204			bss_not_found = true;
1205			break;
1206		}
1207	}
1208
1209	if (WARN_ON(bss_not_found))
1210		goto out;
1211
1212	ev = kzalloc(sizeof(*ev) + info->req_ie_len + info->resp_ie_len +
1213		     info->fils.kek_len + info->fils.pmk_len +
1214		     (info->fils.pmkid ? WLAN_PMKID_LEN : 0) +
1215		     (info->ap_mld_addr ? ETH_ALEN : 0) + link_info_size, gfp);
1216	if (!ev)
1217		goto out;
1218
1219	ev->type = EVENT_ROAMED;
1220	next = ((u8 *)ev) + sizeof(*ev);
1221	if (info->req_ie_len) {
1222		ev->rm.req_ie = next;
1223		ev->rm.req_ie_len = info->req_ie_len;
1224		memcpy((void *)ev->rm.req_ie, info->req_ie, info->req_ie_len);
1225		next += info->req_ie_len;
1226	}
1227	if (info->resp_ie_len) {
1228		ev->rm.resp_ie = next;
1229		ev->rm.resp_ie_len = info->resp_ie_len;
1230		memcpy((void *)ev->rm.resp_ie, info->resp_ie,
1231		       info->resp_ie_len);
1232		next += info->resp_ie_len;
1233	}
1234	if (info->fils.kek_len) {
1235		ev->rm.fils.kek = next;
1236		ev->rm.fils.kek_len = info->fils.kek_len;
1237		memcpy((void *)ev->rm.fils.kek, info->fils.kek,
1238		       info->fils.kek_len);
1239		next += info->fils.kek_len;
1240	}
1241	if (info->fils.pmk_len) {
1242		ev->rm.fils.pmk = next;
1243		ev->rm.fils.pmk_len = info->fils.pmk_len;
1244		memcpy((void *)ev->rm.fils.pmk, info->fils.pmk,
1245		       info->fils.pmk_len);
1246		next += info->fils.pmk_len;
1247	}
1248	if (info->fils.pmkid) {
1249		ev->rm.fils.pmkid = next;
1250		memcpy((void *)ev->rm.fils.pmkid, info->fils.pmkid,
1251		       WLAN_PMKID_LEN);
1252		next += WLAN_PMKID_LEN;
1253	}
1254	ev->rm.fils.update_erp_next_seq_num = info->fils.update_erp_next_seq_num;
1255	if (info->fils.update_erp_next_seq_num)
1256		ev->rm.fils.erp_next_seq_num = info->fils.erp_next_seq_num;
1257	if (info->ap_mld_addr) {
1258		ev->rm.ap_mld_addr = next;
1259		memcpy((void *)ev->rm.ap_mld_addr, info->ap_mld_addr,
1260		       ETH_ALEN);
1261		next += ETH_ALEN;
1262	}
1263	ev->rm.valid_links = info->valid_links;
1264	for_each_valid_link(info, link) {
1265		ev->rm.links[link].bss = info->links[link].bss;
1266
1267		if (info->links[link].addr) {
1268			ev->rm.links[link].addr = next;
1269			memcpy((void *)ev->rm.links[link].addr,
1270			       info->links[link].addr,
1271			       ETH_ALEN);
1272			next += ETH_ALEN;
1273		}
1274
1275		if (info->links[link].bssid) {
1276			ev->rm.links[link].bssid = next;
1277			memcpy((void *)ev->rm.links[link].bssid,
1278			       info->links[link].bssid,
1279			       ETH_ALEN);
1280			next += ETH_ALEN;
1281		}
1282	}
1283
1284	spin_lock_irqsave(&wdev->event_lock, flags);
1285	list_add_tail(&ev->list, &wdev->event_list);
1286	spin_unlock_irqrestore(&wdev->event_lock, flags);
1287	queue_work(cfg80211_wq, &rdev->event_work);
1288
1289	return;
1290out:
1291	for_each_valid_link(info, link)
1292		cfg80211_put_bss(wdev->wiphy, info->links[link].bss);
1293
1294}
1295EXPORT_SYMBOL(cfg80211_roamed);
1296
1297void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid,
1298					const u8 *td_bitmap, u8 td_bitmap_len)
1299{
1300	ASSERT_WDEV_LOCK(wdev);
1301
1302	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
1303		    wdev->iftype != NL80211_IFTYPE_P2P_CLIENT))
1304		return;
1305
1306	if (WARN_ON(!wdev->connected) ||
1307	    WARN_ON(!ether_addr_equal(wdev->u.client.connected_addr, bssid)))
1308		return;
1309
1310	nl80211_send_port_authorized(wiphy_to_rdev(wdev->wiphy), wdev->netdev,
1311				     bssid, td_bitmap, td_bitmap_len);
1312}
1313
1314void cfg80211_port_authorized(struct net_device *dev, const u8 *bssid,
1315			      const u8 *td_bitmap, u8 td_bitmap_len, gfp_t gfp)
1316{
1317	struct wireless_dev *wdev = dev->ieee80211_ptr;
1318	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
1319	struct cfg80211_event *ev;
1320	unsigned long flags;
1321
1322	if (WARN_ON(!bssid))
1323		return;
1324
1325	ev = kzalloc(sizeof(*ev) + td_bitmap_len, gfp);
1326	if (!ev)
1327		return;
1328
1329	ev->type = EVENT_PORT_AUTHORIZED;
1330	memcpy(ev->pa.bssid, bssid, ETH_ALEN);
1331	ev->pa.td_bitmap = ((u8 *)ev) + sizeof(*ev);
1332	ev->pa.td_bitmap_len = td_bitmap_len;
1333	memcpy((void *)ev->pa.td_bitmap, td_bitmap, td_bitmap_len);
1334
1335	/*
1336	 * Use the wdev event list so that if there are pending
1337	 * connected/roamed events, they will be reported first.
1338	 */
1339	spin_lock_irqsave(&wdev->event_lock, flags);
1340	list_add_tail(&ev->list, &wdev->event_list);
1341	spin_unlock_irqrestore(&wdev->event_lock, flags);
1342	queue_work(cfg80211_wq, &rdev->event_work);
1343}
1344EXPORT_SYMBOL(cfg80211_port_authorized);
1345
1346void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
1347			     size_t ie_len, u16 reason, bool from_ap)
1348{
1349	struct wireless_dev *wdev = dev->ieee80211_ptr;
1350	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
1351	int i;
1352#ifdef CONFIG_CFG80211_WEXT
1353	union iwreq_data wrqu;
1354#endif
1355
1356	ASSERT_WDEV_LOCK(wdev);
1357
1358	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
1359		    wdev->iftype != NL80211_IFTYPE_P2P_CLIENT))
1360		return;
1361
1362	cfg80211_wdev_release_bsses(wdev);
1363	wdev->connected = false;
1364	wdev->u.client.ssid_len = 0;
1365	wdev->conn_owner_nlportid = 0;
1366	kfree_sensitive(wdev->connect_keys);
1367	wdev->connect_keys = NULL;
1368
1369	nl80211_send_disconnected(rdev, dev, reason, ie, ie_len, from_ap);
1370
1371	/* stop critical protocol if supported */
1372	if (rdev->ops->crit_proto_stop && rdev->crit_proto_nlportid) {
1373		rdev->crit_proto_nlportid = 0;
1374		rdev_crit_proto_stop(rdev, wdev);
1375	}
1376
1377	/*
1378	 * Delete all the keys ... pairwise keys can't really
1379	 * exist any more anyway, but default keys might.
1380	 */
1381	if (rdev->ops->del_key) {
1382		int max_key_idx = 5;
1383
1384		if (wiphy_ext_feature_isset(
1385			    wdev->wiphy,
1386			    NL80211_EXT_FEATURE_BEACON_PROTECTION) ||
1387		    wiphy_ext_feature_isset(
1388			    wdev->wiphy,
1389			    NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT))
1390			max_key_idx = 7;
1391		for (i = 0; i <= max_key_idx; i++)
1392			rdev_del_key(rdev, dev, -1, i, false, NULL);
1393	}
1394
1395	rdev_set_qos_map(rdev, dev, NULL);
1396
1397#ifdef CONFIG_CFG80211_WEXT
1398	memset(&wrqu, 0, sizeof(wrqu));
1399	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1400	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
1401	wdev->wext.connect.ssid_len = 0;
1402#endif
1403
1404	schedule_work(&cfg80211_disconnect_work);
1405}
1406
1407void cfg80211_disconnected(struct net_device *dev, u16 reason,
1408			   const u8 *ie, size_t ie_len,
1409			   bool locally_generated, gfp_t gfp)
1410{
1411	struct wireless_dev *wdev = dev->ieee80211_ptr;
1412	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
1413	struct cfg80211_event *ev;
1414	unsigned long flags;
1415
1416	ev = kzalloc(sizeof(*ev) + ie_len, gfp);
1417	if (!ev)
1418		return;
1419
1420	ev->type = EVENT_DISCONNECTED;
1421	ev->dc.ie = ((u8 *)ev) + sizeof(*ev);
1422	ev->dc.ie_len = ie_len;
1423	memcpy((void *)ev->dc.ie, ie, ie_len);
1424	ev->dc.reason = reason;
1425	ev->dc.locally_generated = locally_generated;
1426
1427	spin_lock_irqsave(&wdev->event_lock, flags);
1428	list_add_tail(&ev->list, &wdev->event_list);
1429	spin_unlock_irqrestore(&wdev->event_lock, flags);
1430	queue_work(cfg80211_wq, &rdev->event_work);
1431}
1432EXPORT_SYMBOL(cfg80211_disconnected);
1433
1434/*
1435 * API calls for nl80211/wext compatibility code
1436 */
1437int cfg80211_connect(struct cfg80211_registered_device *rdev,
1438		     struct net_device *dev,
1439		     struct cfg80211_connect_params *connect,
1440		     struct cfg80211_cached_keys *connkeys,
1441		     const u8 *prev_bssid)
1442{
1443	struct wireless_dev *wdev = dev->ieee80211_ptr;
1444	int err;
1445
1446	ASSERT_WDEV_LOCK(wdev);
1447
1448	/*
1449	 * If we have an ssid_len, we're trying to connect or are
1450	 * already connected, so reject a new SSID unless it's the
1451	 * same (which is the case for re-association.)
1452	 */
1453	if (wdev->u.client.ssid_len &&
1454	    (wdev->u.client.ssid_len != connect->ssid_len ||
1455	     memcmp(wdev->u.client.ssid, connect->ssid, wdev->u.client.ssid_len)))
1456		return -EALREADY;
1457
1458	/*
1459	 * If connected, reject (re-)association unless prev_bssid
1460	 * matches the current BSSID.
1461	 */
1462	if (wdev->connected) {
1463		if (!prev_bssid)
1464			return -EALREADY;
1465		if (!ether_addr_equal(prev_bssid,
1466				      wdev->u.client.connected_addr))
1467			return -ENOTCONN;
1468	}
1469
1470	/*
1471	 * Reject if we're in the process of connecting with WEP,
1472	 * this case isn't very interesting and trying to handle
1473	 * it would make the code much more complex.
1474	 */
1475	if (wdev->connect_keys)
1476		return -EINPROGRESS;
1477
1478	cfg80211_oper_and_ht_capa(&connect->ht_capa_mask,
1479				  rdev->wiphy.ht_capa_mod_mask);
1480	cfg80211_oper_and_vht_capa(&connect->vht_capa_mask,
1481				   rdev->wiphy.vht_capa_mod_mask);
1482
1483	if (connkeys && connkeys->def >= 0) {
1484		int idx;
1485		u32 cipher;
1486
1487		idx = connkeys->def;
1488		cipher = connkeys->params[idx].cipher;
1489		/* If given a WEP key we may need it for shared key auth */
1490		if (cipher == WLAN_CIPHER_SUITE_WEP40 ||
1491		    cipher == WLAN_CIPHER_SUITE_WEP104) {
1492			connect->key_idx = idx;
1493			connect->key = connkeys->params[idx].key;
1494			connect->key_len = connkeys->params[idx].key_len;
1495
1496			/*
1497			 * If ciphers are not set (e.g. when going through
1498			 * iwconfig), we have to set them appropriately here.
1499			 */
1500			if (connect->crypto.cipher_group == 0)
1501				connect->crypto.cipher_group = cipher;
1502
1503			if (connect->crypto.n_ciphers_pairwise == 0) {
1504				connect->crypto.n_ciphers_pairwise = 1;
1505				connect->crypto.ciphers_pairwise[0] = cipher;
1506			}
1507		}
1508	} else {
1509		if (WARN_ON(connkeys))
1510			return -EINVAL;
1511
1512		/* connect can point to wdev->wext.connect which
1513		 * can hold key data from a previous connection
1514		 */
1515		connect->key = NULL;
1516		connect->key_len = 0;
1517		connect->key_idx = 0;
1518	}
1519
1520	wdev->connect_keys = connkeys;
1521	memcpy(wdev->u.client.ssid, connect->ssid, connect->ssid_len);
1522	wdev->u.client.ssid_len = connect->ssid_len;
1523
1524	wdev->conn_bss_type = connect->pbss ? IEEE80211_BSS_TYPE_PBSS :
1525					      IEEE80211_BSS_TYPE_ESS;
1526
1527	if (!rdev->ops->connect)
1528		err = cfg80211_sme_connect(wdev, connect, prev_bssid);
1529	else
1530		err = rdev_connect(rdev, dev, connect);
1531
1532	if (err) {
1533		wdev->connect_keys = NULL;
1534		/*
1535		 * This could be reassoc getting refused, don't clear
1536		 * ssid_len in that case.
1537		 */
1538		if (!wdev->connected)
1539			wdev->u.client.ssid_len = 0;
1540		return err;
1541	}
1542
1543	return 0;
1544}
1545
1546int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
1547			struct net_device *dev, u16 reason, bool wextev)
1548{
1549	struct wireless_dev *wdev = dev->ieee80211_ptr;
1550	int err = 0;
1551
1552	ASSERT_WDEV_LOCK(wdev);
1553
1554	kfree_sensitive(wdev->connect_keys);
1555	wdev->connect_keys = NULL;
1556
1557	wdev->conn_owner_nlportid = 0;
1558
1559	if (wdev->conn)
1560		err = cfg80211_sme_disconnect(wdev, reason);
1561	else if (!rdev->ops->disconnect)
1562		cfg80211_mlme_down(rdev, dev);
1563	else if (wdev->u.client.ssid_len)
1564		err = rdev_disconnect(rdev, dev, reason);
1565
1566	/*
1567	 * Clear ssid_len unless we actually were fully connected,
1568	 * in which case cfg80211_disconnected() will take care of
1569	 * this later.
1570	 */
1571	if (!wdev->connected)
1572		wdev->u.client.ssid_len = 0;
1573
1574	return err;
1575}
1576
1577/*
1578 * Used to clean up after the connection / connection attempt owner socket
1579 * disconnects
1580 */
1581void cfg80211_autodisconnect_wk(struct work_struct *work)
1582{
1583	struct wireless_dev *wdev =
1584		container_of(work, struct wireless_dev, disconnect_wk);
1585	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
1586
1587	wiphy_lock(wdev->wiphy);
1588	wdev_lock(wdev);
1589
1590	if (wdev->conn_owner_nlportid) {
1591		switch (wdev->iftype) {
1592		case NL80211_IFTYPE_ADHOC:
1593			__cfg80211_leave_ibss(rdev, wdev->netdev, false);
1594			break;
1595		case NL80211_IFTYPE_AP:
1596		case NL80211_IFTYPE_P2P_GO:
1597			__cfg80211_stop_ap(rdev, wdev->netdev, -1, false);
1598			break;
1599		case NL80211_IFTYPE_MESH_POINT:
1600			__cfg80211_leave_mesh(rdev, wdev->netdev);
1601			break;
1602		case NL80211_IFTYPE_STATION:
1603		case NL80211_IFTYPE_P2P_CLIENT:
1604			/*
1605			 * Use disconnect_bssid if still connecting and
1606			 * ops->disconnect not implemented.  Otherwise we can
1607			 * use cfg80211_disconnect.
1608			 */
1609			if (rdev->ops->disconnect || wdev->connected)
1610				cfg80211_disconnect(rdev, wdev->netdev,
1611						    WLAN_REASON_DEAUTH_LEAVING,
1612						    true);
1613			else
1614				cfg80211_mlme_deauth(rdev, wdev->netdev,
1615						     wdev->disconnect_bssid,
1616						     NULL, 0,
1617						     WLAN_REASON_DEAUTH_LEAVING,
1618						     false);
1619			break;
1620		default:
1621			break;
1622		}
1623	}
1624
1625	wdev_unlock(wdev);
1626	wiphy_unlock(wdev->wiphy);
1627}
1628