Linux Audio

Check our new training course

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