File Index
Files and directories
Sign in
FILE

scan.c

File preview with syntax highlighting.

linux-6.19.14/net/wireless/scan.c C
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * cfg80211 scan result handling
   4 *
   5 * Copyright 2008 Johannes Berg <johannes@sipsolutions.net>
   6 * Copyright 2013-2014  Intel Mobile Communications GmbH
   7 * Copyright 2016	Intel Deutschland GmbH
   8 * Copyright (C) 2018-2025 Intel Corporation
   9 */
  10#include <linux/kernel.h>
  11#include <linux/slab.h>
  12#include <linux/module.h>
  13#include <linux/netdevice.h>
  14#include <linux/wireless.h>
  15#include <linux/nl80211.h>
  16#include <linux/etherdevice.h>
  17#include <linux/crc32.h>
  18#include <linux/bitfield.h>
  19#include <net/arp.h>
  20#include <net/cfg80211.h>
  21#include <net/cfg80211-wext.h>
  22#include <net/iw_handler.h>
  23#include <kunit/visibility.h>
  24#include "core.h"
  25#include "nl80211.h"
  26#include "wext-compat.h"
  27#include "rdev-ops.h"
  28
  29/**
  30 * DOC: BSS tree/list structure
  31 *
  32 * At the top level, the BSS list is kept in both a list in each
  33 * registered device (@bss_list) as well as an RB-tree for faster
  34 * lookup. In the RB-tree, entries can be looked up using their
  35 * channel, MESHID, MESHCONF (for MBSSes) or channel, BSSID, SSID
  36 * for other BSSes.
  37 *
  38 * Due to the possibility of hidden SSIDs, there's a second level
  39 * structure, the "hidden_list" and "hidden_beacon_bss" pointer.
  40 * The hidden_list connects all BSSes belonging to a single AP
  41 * that has a hidden SSID, and connects beacon and probe response
  42 * entries. For a probe response entry for a hidden SSID, the
  43 * hidden_beacon_bss pointer points to the BSS struct holding the
  44 * beacon's information.
  45 *
  46 * Reference counting is done for all these references except for
  47 * the hidden_list, so that a beacon BSS struct that is otherwise
  48 * not referenced has one reference for being on the bss_list and
  49 * one for each probe response entry that points to it using the
  50 * hidden_beacon_bss pointer. When a BSS struct that has such a
  51 * pointer is get/put, the refcount update is also propagated to
  52 * the referenced struct, this ensure that it cannot get removed
  53 * while somebody is using the probe response version.
  54 *
  55 * Note that the hidden_beacon_bss pointer never changes, due to
  56 * the reference counting. Therefore, no locking is needed for
  57 * it.
  58 *
  59 * Also note that the hidden_beacon_bss pointer is only relevant
  60 * if the driver uses something other than the IEs, e.g. private
  61 * data stored in the BSS struct, since the beacon IEs are
  62 * also linked into the probe response struct.
  63 */
  64
  65/*
  66 * Limit the number of BSS entries stored in mac80211. Each one is
  67 * a bit over 4k at most, so this limits to roughly 4-5M of memory.
  68 * If somebody wants to really attack this though, they'd likely
  69 * use small beacons, and only one type of frame, limiting each of
  70 * the entries to a much smaller size (in order to generate more
  71 * entries in total, so overhead is bigger.)
  72 */
  73static int bss_entries_limit = 1000;
  74module_param(bss_entries_limit, int, 0644);
  75MODULE_PARM_DESC(bss_entries_limit,
  76                 "limit to number of scan BSS entries (per wiphy, default 1000)");
  77
  78#define IEEE80211_SCAN_RESULT_EXPIRE	(30 * HZ)
  79
  80static void bss_free(struct cfg80211_internal_bss *bss)
  81{
  82	struct cfg80211_bss_ies *ies;
  83
  84	if (WARN_ON(atomic_read(&bss->hold)))
  85		return;
  86
  87	ies = (void *)rcu_access_pointer(bss->pub.beacon_ies);
  88	if (ies && !bss->pub.hidden_beacon_bss)
  89		kfree_rcu(ies, rcu_head);
  90	ies = (void *)rcu_access_pointer(bss->pub.proberesp_ies);
  91	if (ies)
  92		kfree_rcu(ies, rcu_head);
  93
  94	/*
  95	 * This happens when the module is removed, it doesn't
  96	 * really matter any more save for completeness
  97	 */
  98	if (!list_empty(&bss->hidden_list))
  99		list_del(&bss->hidden_list);
 100
 101	kfree(bss);
 102}
 103
 104static inline void bss_ref_get(struct cfg80211_registered_device *rdev,
 105			       struct cfg80211_internal_bss *bss)
 106{
 107	lockdep_assert_held(&rdev->bss_lock);
 108
 109	bss->refcount++;
 110
 111	if (bss->pub.hidden_beacon_bss)
 112		bss_from_pub(bss->pub.hidden_beacon_bss)->refcount++;
 113
 114	if (bss->pub.transmitted_bss)
 115		bss_from_pub(bss->pub.transmitted_bss)->refcount++;
 116}
 117
 118static inline void bss_ref_put(struct cfg80211_registered_device *rdev,
 119			       struct cfg80211_internal_bss *bss)
 120{
 121	lockdep_assert_held(&rdev->bss_lock);
 122
 123	if (bss->pub.hidden_beacon_bss) {
 124		struct cfg80211_internal_bss *hbss;
 125
 126		hbss = bss_from_pub(bss->pub.hidden_beacon_bss);
 127		hbss->refcount--;
 128		if (hbss->refcount == 0)
 129			bss_free(hbss);
 130	}
 131
 132	if (bss->pub.transmitted_bss) {
 133		struct cfg80211_internal_bss *tbss;
 134
 135		tbss = bss_from_pub(bss->pub.transmitted_bss);
 136		tbss->refcount--;
 137		if (tbss->refcount == 0)
 138			bss_free(tbss);
 139	}
 140
 141	bss->refcount--;
 142	if (bss->refcount == 0)
 143		bss_free(bss);
 144}
 145
 146static bool __cfg80211_unlink_bss(struct cfg80211_registered_device *rdev,
 147				  struct cfg80211_internal_bss *bss)
 148{
 149	lockdep_assert_held(&rdev->bss_lock);
 150
 151	if (!list_empty(&bss->hidden_list)) {
 152		/*
 153		 * don't remove the beacon entry if it has
 154		 * probe responses associated with it
 155		 */
 156		if (!bss->pub.hidden_beacon_bss)
 157			return false;
 158		/*
 159		 * if it's a probe response entry break its
 160		 * link to the other entries in the group
 161		 */
 162		list_del_init(&bss->hidden_list);
 163	}
 164
 165	list_del_init(&bss->list);
 166	list_del_init(&bss->pub.nontrans_list);
 167	rb_erase(&bss->rbn, &rdev->bss_tree);
 168	rdev->bss_entries--;
 169	WARN_ONCE((rdev->bss_entries == 0) ^ list_empty(&rdev->bss_list),
 170		  "rdev bss entries[%d]/list[empty:%d] corruption\n",
 171		  rdev->bss_entries, list_empty(&rdev->bss_list));
 172	bss_ref_put(rdev, bss);
 173	return true;
 174}
 175
 176bool cfg80211_is_element_inherited(const struct element *elem,
 177				   const struct element *non_inherit_elem)
 178{
 179	u8 id_len, ext_id_len, i, loop_len, id;
 180	const u8 *list;
 181
 182	if (elem->id == WLAN_EID_MULTIPLE_BSSID)
 183		return false;
 184
 185	if (elem->id == WLAN_EID_EXTENSION && elem->datalen > 1 &&
 186	    elem->data[0] == WLAN_EID_EXT_EHT_MULTI_LINK)
 187		return false;
 188
 189	if (!non_inherit_elem || non_inherit_elem->datalen < 2)
 190		return true;
 191
 192	/*
 193	 * non inheritance element format is:
 194	 * ext ID (56) | IDs list len | list | extension IDs list len | list
 195	 * Both lists are optional. Both lengths are mandatory.
 196	 * This means valid length is:
 197	 * elem_len = 1 (extension ID) + 2 (list len fields) + list lengths
 198	 */
 199	id_len = non_inherit_elem->data[1];
 200	if (non_inherit_elem->datalen < 3 + id_len)
 201		return true;
 202
 203	ext_id_len = non_inherit_elem->data[2 + id_len];
 204	if (non_inherit_elem->datalen < 3 + id_len + ext_id_len)
 205		return true;
 206
 207	if (elem->id == WLAN_EID_EXTENSION) {
 208		if (!ext_id_len)
 209			return true;
 210		loop_len = ext_id_len;
 211		list = &non_inherit_elem->data[3 + id_len];
 212		id = elem->data[0];
 213	} else {
 214		if (!id_len)
 215			return true;
 216		loop_len = id_len;
 217		list = &non_inherit_elem->data[2];
 218		id = elem->id;
 219	}
 220
 221	for (i = 0; i < loop_len; i++) {
 222		if (list[i] == id)
 223			return false;
 224	}
 225
 226	return true;
 227}
 228EXPORT_SYMBOL(cfg80211_is_element_inherited);
 229
 230static size_t cfg80211_copy_elem_with_frags(const struct element *elem,
 231					    const u8 *ie, size_t ie_len,
 232					    u8 **pos, u8 *buf, size_t buf_len)
 233{
 234	if (WARN_ON((u8 *)elem < ie || elem->data > ie + ie_len ||
 235		    elem->data + elem->datalen > ie + ie_len))
 236		return 0;
 237
 238	if (elem->datalen + 2 > buf + buf_len - *pos)
 239		return 0;
 240
 241	memcpy(*pos, elem, elem->datalen + 2);
 242	*pos += elem->datalen + 2;
 243
 244	/* Finish if it is not fragmented  */
 245	if (elem->datalen != 255)
 246		return *pos - buf;
 247
 248	ie_len = ie + ie_len - elem->data - elem->datalen;
 249	ie = (const u8 *)elem->data + elem->datalen;
 250
 251	for_each_element(elem, ie, ie_len) {
 252		if (elem->id != WLAN_EID_FRAGMENT)
 253			break;
 254
 255		if (elem->datalen + 2 > buf + buf_len - *pos)
 256			return 0;
 257
 258		memcpy(*pos, elem, elem->datalen + 2);
 259		*pos += elem->datalen + 2;
 260
 261		if (elem->datalen != 255)
 262			break;
 263	}
 264
 265	return *pos - buf;
 266}
 267
 268VISIBLE_IF_CFG80211_KUNIT size_t
 269cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
 270		    const u8 *subie, size_t subie_len,
 271		    u8 *new_ie, size_t new_ie_len)
 272{
 273	const struct element *non_inherit_elem, *parent, *sub;
 274	u8 *pos = new_ie;
 275	const u8 *mbssid_index_ie;
 276	u8 id, ext_id, bssid_index = 255;
 277	unsigned int match_len;
 278
 279	non_inherit_elem = cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
 280						  subie, subie_len);
 281
 282	mbssid_index_ie = cfg80211_find_ie(WLAN_EID_MULTI_BSSID_IDX, subie,
 283					   subie_len);
 284	if (mbssid_index_ie && mbssid_index_ie[1] > 0 &&
 285	    mbssid_index_ie[2] > 0 && mbssid_index_ie[2] <= 46)
 286		bssid_index = mbssid_index_ie[2];
 287
 288	/* We copy the elements one by one from the parent to the generated
 289	 * elements.
 290	 * If they are not inherited (included in subie or in the non
 291	 * inheritance element), then we copy all occurrences the first time
 292	 * we see this element type.
 293	 */
 294	for_each_element(parent, ie, ielen) {
 295		if (parent->id == WLAN_EID_FRAGMENT)
 296			continue;
 297
 298		if (parent->id == WLAN_EID_EXTENSION) {
 299			if (parent->datalen < 1)
 300				continue;
 301
 302			id = WLAN_EID_EXTENSION;
 303			ext_id = parent->data[0];
 304			match_len = 1;
 305		} else {
 306			id = parent->id;
 307			match_len = 0;
 308		}
 309
 310		/* Find first occurrence in subie */
 311		sub = cfg80211_find_elem_match(id, subie, subie_len,
 312					       &ext_id, match_len, 0);
 313
 314		/* Copy from parent if not in subie and inherited */
 315		if (!sub &&
 316		    cfg80211_is_element_inherited(parent, non_inherit_elem)) {
 317			if (!cfg80211_copy_elem_with_frags(parent,
 318							   ie, ielen,
 319							   &pos, new_ie,
 320							   new_ie_len))
 321				return 0;
 322
 323			continue;
 324		}
 325
 326		/* For ML probe response, match the MLE in the frame body with
 327		 * MLD id being 'bssid_index'
 328		 */
 329		if (parent->id == WLAN_EID_EXTENSION && parent->datalen > 1 &&
 330		    parent->data[0] == WLAN_EID_EXT_EHT_MULTI_LINK &&
 331		    bssid_index == ieee80211_mle_get_mld_id(parent->data + 1)) {
 332			if (!cfg80211_copy_elem_with_frags(parent,
 333							   ie, ielen,
 334							   &pos, new_ie,
 335							   new_ie_len))
 336				return 0;
 337
 338			/* Continue here to prevent processing the MLE in
 339			 * sub-element, which AP MLD should not carry
 340			 */
 341			continue;
 342		}
 343
 344		/* Already copied if an earlier element had the same type */
 345		if (cfg80211_find_elem_match(id, ie, (u8 *)parent - ie,
 346					     &ext_id, match_len, 0))
 347			continue;
 348
 349		/* Not inheriting, copy all similar elements from subie */
 350		while (sub) {
 351			if (!cfg80211_copy_elem_with_frags(sub,
 352							   subie, subie_len,
 353							   &pos, new_ie,
 354							   new_ie_len))
 355				return 0;
 356
 357			sub = cfg80211_find_elem_match(id,
 358						       sub->data + sub->datalen,
 359						       subie_len + subie -
 360						       (sub->data +
 361							sub->datalen),
 362						       &ext_id, match_len, 0);
 363		}
 364	}
 365
 366	/* The above misses elements that are included in subie but not in the
 367	 * parent, so do a pass over subie and append those.
 368	 * Skip the non-tx BSSID caps and non-inheritance element.
 369	 */
 370	for_each_element(sub, subie, subie_len) {
 371		if (sub->id == WLAN_EID_NON_TX_BSSID_CAP)
 372			continue;
 373
 374		if (sub->id == WLAN_EID_FRAGMENT)
 375			continue;
 376
 377		if (sub->id == WLAN_EID_EXTENSION) {
 378			if (sub->datalen < 1)
 379				continue;
 380
 381			id = WLAN_EID_EXTENSION;
 382			ext_id = sub->data[0];
 383			match_len = 1;
 384
 385			if (ext_id == WLAN_EID_EXT_NON_INHERITANCE)
 386				continue;
 387		} else {
 388			id = sub->id;
 389			match_len = 0;
 390		}
 391
 392		/* Processed if one was included in the parent */
 393		if (cfg80211_find_elem_match(id, ie, ielen,
 394					     &ext_id, match_len, 0))
 395			continue;
 396
 397		if (!cfg80211_copy_elem_with_frags(sub, subie, subie_len,
 398						   &pos, new_ie, new_ie_len))
 399			return 0;
 400	}
 401
 402	return pos - new_ie;
 403}
 404EXPORT_SYMBOL_IF_CFG80211_KUNIT(cfg80211_gen_new_ie);
 405
 406static bool is_bss(struct cfg80211_bss *a, const u8 *bssid,
 407		   const u8 *ssid, size_t ssid_len)
 408{
 409	const struct cfg80211_bss_ies *ies;
 410	const struct element *ssid_elem;
 411
 412	if (bssid && !ether_addr_equal(a->bssid, bssid))
 413		return false;
 414
 415	if (!ssid)
 416		return true;
 417
 418	ies = rcu_access_pointer(a->ies);
 419	if (!ies)
 420		return false;
 421	ssid_elem = cfg80211_find_elem(WLAN_EID_SSID, ies->data, ies->len);
 422	if (!ssid_elem)
 423		return false;
 424	if (ssid_elem->datalen != ssid_len)
 425		return false;
 426	return memcmp(ssid_elem->data, ssid, ssid_len) == 0;
 427}
 428
 429static int
 430cfg80211_add_nontrans_list(struct cfg80211_bss *trans_bss,
 431			   struct cfg80211_bss *nontrans_bss)
 432{
 433	const struct element *ssid_elem;
 434	struct cfg80211_bss *bss = NULL;
 435
 436	rcu_read_lock();
 437	ssid_elem = ieee80211_bss_get_elem(nontrans_bss, WLAN_EID_SSID);
 438	if (!ssid_elem) {
 439		rcu_read_unlock();
 440		return -EINVAL;
 441	}
 442
 443	/* check if nontrans_bss is in the list */
 444	list_for_each_entry(bss, &trans_bss->nontrans_list, nontrans_list) {
 445		if (is_bss(bss, nontrans_bss->bssid, ssid_elem->data,
 446			   ssid_elem->datalen)) {
 447			rcu_read_unlock();
 448			return 0;
 449		}
 450	}
 451
 452	rcu_read_unlock();
 453
 454	/*
 455	 * This is a bit weird - it's not on the list, but already on another
 456	 * one! The only way that could happen is if there's some BSSID/SSID
 457	 * shared by multiple APs in their multi-BSSID profiles, potentially
 458	 * with hidden SSID mixed in ... ignore it.
 459	 */
 460	if (!list_empty(&nontrans_bss->nontrans_list))
 461		return -EINVAL;
 462
 463	/* add to the list */
 464	list_add_tail(&nontrans_bss->nontrans_list, &trans_bss->nontrans_list);
 465	return 0;
 466}
 467
 468static void __cfg80211_bss_expire(struct cfg80211_registered_device *rdev,
 469				  unsigned long expire_time)
 470{
 471	struct cfg80211_internal_bss *bss, *tmp;
 472	bool expired = false;
 473
 474	lockdep_assert_held(&rdev->bss_lock);
 475
 476	list_for_each_entry_safe(bss, tmp, &rdev->bss_list, list) {
 477		if (atomic_read(&bss->hold))
 478			continue;
 479		if (!time_after(expire_time, bss->ts))
 480			continue;
 481
 482		if (__cfg80211_unlink_bss(rdev, bss))
 483			expired = true;
 484	}
 485
 486	if (expired)
 487		rdev->bss_generation++;
 488}
 489
 490static bool cfg80211_bss_expire_oldest(struct cfg80211_registered_device *rdev)
 491{
 492	struct cfg80211_internal_bss *bss, *oldest = NULL;
 493	bool ret;
 494
 495	lockdep_assert_held(&rdev->bss_lock);
 496
 497	list_for_each_entry(bss, &rdev->bss_list, list) {
 498		if (atomic_read(&bss->hold))
 499			continue;
 500
 501		if (!list_empty(&bss->hidden_list) &&
 502		    !bss->pub.hidden_beacon_bss)
 503			continue;
 504
 505		if (oldest && time_before(oldest->ts, bss->ts))
 506			continue;
 507		oldest = bss;
 508	}
 509
 510	if (WARN_ON(!oldest))
 511		return false;
 512
 513	/*
 514	 * The callers make sure to increase rdev->bss_generation if anything
 515	 * gets removed (and a new entry added), so there's no need to also do
 516	 * it here.
 517	 */
 518
 519	ret = __cfg80211_unlink_bss(rdev, oldest);
 520	WARN_ON(!ret);
 521	return ret;
 522}
 523
 524static u8 cfg80211_parse_bss_param(u8 data,
 525				   struct cfg80211_colocated_ap *coloc_ap)
 526{
 527	coloc_ap->oct_recommended =
 528		u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_OCT_RECOMMENDED);
 529	coloc_ap->same_ssid =
 530		u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_SAME_SSID);
 531	coloc_ap->multi_bss =
 532		u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_MULTI_BSSID);
 533	coloc_ap->transmitted_bssid =
 534		u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_TRANSMITTED_BSSID);
 535	coloc_ap->unsolicited_probe =
 536		u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_PROBE_ACTIVE);
 537	coloc_ap->colocated_ess =
 538		u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_COLOC_ESS);
 539
 540	return u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_COLOC_AP);
 541}
 542
 543static int cfg80211_calc_short_ssid(const struct cfg80211_bss_ies *ies,
 544				    const struct element **elem, u32 *s_ssid)
 545{
 546
 547	*elem = cfg80211_find_elem(WLAN_EID_SSID, ies->data, ies->len);
 548	if (!*elem || (*elem)->datalen > IEEE80211_MAX_SSID_LEN)
 549		return -EINVAL;
 550
 551	*s_ssid = ~crc32_le(~0, (*elem)->data, (*elem)->datalen);
 552	return 0;
 553}
 554
 555VISIBLE_IF_CFG80211_KUNIT void
 556cfg80211_free_coloc_ap_list(struct list_head *coloc_ap_list)
 557{
 558	struct cfg80211_colocated_ap *ap, *tmp_ap;
 559
 560	list_for_each_entry_safe(ap, tmp_ap, coloc_ap_list, list) {
 561		list_del(&ap->list);
 562		kfree(ap);
 563	}
 564}
 565EXPORT_SYMBOL_IF_CFG80211_KUNIT(cfg80211_free_coloc_ap_list);
 566
 567static int cfg80211_parse_ap_info(struct cfg80211_colocated_ap *entry,
 568				  const u8 *pos, u8 length,
 569				  const struct element *ssid_elem,
 570				  u32 s_ssid_tmp)
 571{
 572	u8 bss_params;
 573
 574	entry->psd_20 = IEEE80211_RNR_TBTT_PARAMS_PSD_RESERVED;
 575
 576	/* The length is already verified by the caller to contain bss_params */
 577	if (length > sizeof(struct ieee80211_tbtt_info_7_8_9)) {
 578		struct ieee80211_tbtt_info_ge_11 *tbtt_info = (void *)pos;
 579
 580		memcpy(entry->bssid, tbtt_info->bssid, ETH_ALEN);
 581		entry->short_ssid = le32_to_cpu(tbtt_info->short_ssid);
 582		entry->short_ssid_valid = true;
 583
 584		bss_params = tbtt_info->bss_params;
 585
 586		/* Ignore disabled links */
 587		if (length >= offsetofend(typeof(*tbtt_info), mld_params)) {
 588			if (le16_get_bits(tbtt_info->mld_params.params,
 589					  IEEE80211_RNR_MLD_PARAMS_DISABLED_LINK))
 590				return -EINVAL;
 591		}
 592
 593		if (length >= offsetofend(struct ieee80211_tbtt_info_ge_11,
 594					  psd_20))
 595			entry->psd_20 = tbtt_info->psd_20;
 596	} else {
 597		struct ieee80211_tbtt_info_7_8_9 *tbtt_info = (void *)pos;
 598
 599		memcpy(entry->bssid, tbtt_info->bssid, ETH_ALEN);
 600
 601		bss_params = tbtt_info->bss_params;
 602
 603		if (length == offsetofend(struct ieee80211_tbtt_info_7_8_9,
 604					  psd_20))
 605			entry->psd_20 = tbtt_info->psd_20;
 606	}
 607
 608	/* ignore entries with invalid BSSID */
 609	if (!is_valid_ether_addr(entry->bssid))
 610		return -EINVAL;
 611
 612	/* skip non colocated APs */
 613	if (!cfg80211_parse_bss_param(bss_params, entry))
 614		return -EINVAL;
 615
 616	/* no information about the short ssid. Consider the entry valid
 617	 * for now. It would later be dropped in case there are explicit
 618	 * SSIDs that need to be matched
 619	 */
 620	if (!entry->same_ssid && !entry->short_ssid_valid)
 621		return 0;
 622
 623	if (entry->same_ssid) {
 624		entry->short_ssid = s_ssid_tmp;
 625		entry->short_ssid_valid = true;
 626
 627		/*
 628		 * This is safe because we validate datalen in
 629		 * cfg80211_parse_colocated_ap(), before calling this
 630		 * function.
 631		 */
 632		memcpy(&entry->ssid, &ssid_elem->data, ssid_elem->datalen);
 633		entry->ssid_len = ssid_elem->datalen;
 634	}
 635
 636	return 0;
 637}
 638
 639bool cfg80211_iter_rnr(const u8 *elems, size_t elems_len,
 640		       enum cfg80211_rnr_iter_ret
 641		       (*iter)(void *data, u8 type,
 642			       const struct ieee80211_neighbor_ap_info *info,
 643			       const u8 *tbtt_info, u8 tbtt_info_len),
 644		       void *iter_data)
 645{
 646	const struct element *rnr;
 647	const u8 *pos, *end;
 648
 649	for_each_element_id(rnr, WLAN_EID_REDUCED_NEIGHBOR_REPORT,
 650			    elems, elems_len) {
 651		const struct ieee80211_neighbor_ap_info *info;
 652
 653		pos = rnr->data;
 654		end = rnr->data + rnr->datalen;
 655
 656		/* RNR IE may contain more than one NEIGHBOR_AP_INFO */
 657		while (sizeof(*info) <= end - pos) {
 658			u8 length, i, count;
 659			u8 type;
 660
 661			info = (void *)pos;
 662			count = u8_get_bits(info->tbtt_info_hdr,
 663					    IEEE80211_AP_INFO_TBTT_HDR_COUNT) +
 664				1;
 665			length = info->tbtt_info_len;
 666
 667			pos += sizeof(*info);
 668
 669			if (count * length > end - pos)
 670				return false;
 671
 672			type = u8_get_bits(info->tbtt_info_hdr,
 673					   IEEE80211_AP_INFO_TBTT_HDR_TYPE);
 674
 675			for (i = 0; i < count; i++) {
 676				switch (iter(iter_data, type, info,
 677					     pos, length)) {
 678				case RNR_ITER_CONTINUE:
 679					break;
 680				case RNR_ITER_BREAK:
 681					return true;
 682				case RNR_ITER_ERROR:
 683					return false;
 684				}
 685
 686				pos += length;
 687			}
 688		}
 689
 690		if (pos != end)
 691			return false;
 692	}
 693
 694	return true;
 695}
 696EXPORT_SYMBOL_GPL(cfg80211_iter_rnr);
 697
 698struct colocated_ap_data {
 699	const struct element *ssid_elem;
 700	struct list_head ap_list;
 701	u32 s_ssid_tmp;
 702	int n_coloc;
 703};
 704
 705static enum cfg80211_rnr_iter_ret
 706cfg80211_parse_colocated_ap_iter(void *_data, u8 type,
 707				 const struct ieee80211_neighbor_ap_info *info,
 708				 const u8 *tbtt_info, u8 tbtt_info_len)
 709{
 710	struct colocated_ap_data *data = _data;
 711	struct cfg80211_colocated_ap *entry;
 712	enum nl80211_band band;
 713
 714	if (type != IEEE80211_TBTT_INFO_TYPE_TBTT)
 715		return RNR_ITER_CONTINUE;
 716
 717	if (!ieee80211_operating_class_to_band(info->op_class, &band))
 718		return RNR_ITER_CONTINUE;
 719
 720	/* TBTT info must include bss param + BSSID + (short SSID or
 721	 * same_ssid bit to be set). Ignore other options, and move to
 722	 * the next AP info
 723	 */
 724	if (band != NL80211_BAND_6GHZ ||
 725	    !(tbtt_info_len == offsetofend(struct ieee80211_tbtt_info_7_8_9,
 726					   bss_params) ||
 727	      tbtt_info_len == sizeof(struct ieee80211_tbtt_info_7_8_9) ||
 728	      tbtt_info_len >= offsetofend(struct ieee80211_tbtt_info_ge_11,
 729					   bss_params)))
 730		return RNR_ITER_CONTINUE;
 731
 732	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
 733	if (!entry)
 734		return RNR_ITER_ERROR;
 735
 736	entry->center_freq =
 737		ieee80211_channel_to_frequency(info->channel, band);
 738
 739	if (!cfg80211_parse_ap_info(entry, tbtt_info, tbtt_info_len,
 740				    data->ssid_elem, data->s_ssid_tmp)) {
 741		struct cfg80211_colocated_ap *tmp;
 742
 743		/* Don't add duplicate BSSIDs on the same channel. */
 744		list_for_each_entry(tmp, &data->ap_list, list) {
 745			if (ether_addr_equal(tmp->bssid, entry->bssid) &&
 746			    tmp->center_freq == entry->center_freq) {
 747				kfree(entry);
 748				return RNR_ITER_CONTINUE;
 749			}
 750		}
 751
 752		data->n_coloc++;
 753		list_add_tail(&entry->list, &data->ap_list);
 754	} else {
 755		kfree(entry);
 756	}
 757
 758	return RNR_ITER_CONTINUE;
 759}
 760
 761VISIBLE_IF_CFG80211_KUNIT int
 762cfg80211_parse_colocated_ap(const struct cfg80211_bss_ies *ies,
 763			    struct list_head *list)
 764{
 765	struct colocated_ap_data data = {};
 766	int ret;
 767
 768	INIT_LIST_HEAD(&data.ap_list);
 769
 770	ret = cfg80211_calc_short_ssid(ies, &data.ssid_elem, &data.s_ssid_tmp);
 771	if (ret)
 772		return 0;
 773
 774	if (!cfg80211_iter_rnr(ies->data, ies->len,
 775			       cfg80211_parse_colocated_ap_iter, &data)) {
 776		cfg80211_free_coloc_ap_list(&data.ap_list);
 777		return 0;
 778	}
 779
 780	list_splice_tail(&data.ap_list, list);
 781	return data.n_coloc;
 782}
 783EXPORT_SYMBOL_IF_CFG80211_KUNIT(cfg80211_parse_colocated_ap);
 784
 785static void cfg80211_scan_req_add_chan(struct cfg80211_scan_request *request,
 786				       struct ieee80211_channel *chan,
 787				       bool add_to_6ghz)
 788{
 789	int i;
 790	u32 n_channels = request->n_channels;
 791	struct cfg80211_scan_6ghz_params *params =
 792		&request->scan_6ghz_params[request->n_6ghz_params];
 793
 794	for (i = 0; i < n_channels; i++) {
 795		if (request->channels[i] == chan) {
 796			if (add_to_6ghz)
 797				params->channel_idx = i;
 798			return;
 799		}
 800	}
 801
 802	request->n_channels++;
 803	request->channels[n_channels] = chan;
 804	if (add_to_6ghz)
 805		request->scan_6ghz_params[request->n_6ghz_params].channel_idx =
 806			n_channels;
 807}
 808
 809static bool cfg80211_find_ssid_match(struct cfg80211_colocated_ap *ap,
 810				     struct cfg80211_scan_request *request)
 811{
 812	int i;
 813	u32 s_ssid;
 814
 815	for (i = 0; i < request->n_ssids; i++) {
 816		/* wildcard ssid in the scan request */
 817		if (!request->ssids[i].ssid_len) {
 818			if (ap->multi_bss && !ap->transmitted_bssid)
 819				continue;
 820
 821			return true;
 822		}
 823
 824		if (ap->ssid_len &&
 825		    ap->ssid_len == request->ssids[i].ssid_len) {
 826			if (!memcmp(request->ssids[i].ssid, ap->ssid,
 827				    ap->ssid_len))
 828				return true;
 829		} else if (ap->short_ssid_valid) {
 830			s_ssid = ~crc32_le(~0, request->ssids[i].ssid,
 831					   request->ssids[i].ssid_len);
 832
 833			if (ap->short_ssid == s_ssid)
 834				return true;
 835		}
 836	}
 837
 838	return false;
 839}
 840
 841static int cfg80211_scan_6ghz(struct cfg80211_registered_device *rdev,
 842			      bool first_part)
 843{
 844	u8 i;
 845	struct cfg80211_colocated_ap *ap;
 846	int n_channels, count = 0, err;
 847	struct cfg80211_scan_request_int *request, *rdev_req = rdev->scan_req;
 848	LIST_HEAD(coloc_ap_list);
 849	bool need_scan_psc = true;
 850	const struct ieee80211_sband_iftype_data *iftd;
 851	size_t size, offs_ssids, offs_6ghz_params, offs_ies;
 852
 853	rdev_req->req.scan_6ghz = true;
 854	rdev_req->req.first_part = first_part;
 855
 856	if (!rdev->wiphy.bands[NL80211_BAND_6GHZ])
 857		return -EOPNOTSUPP;
 858
 859	iftd = ieee80211_get_sband_iftype_data(rdev->wiphy.bands[NL80211_BAND_6GHZ],
 860					       rdev_req->req.wdev->iftype);
 861	if (!iftd || !iftd->he_cap.has_he)
 862		return -EOPNOTSUPP;
 863
 864	n_channels = rdev->wiphy.bands[NL80211_BAND_6GHZ]->n_channels;
 865
 866	if (rdev_req->req.flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ) {
 867		struct cfg80211_internal_bss *intbss;
 868
 869		spin_lock_bh(&rdev->bss_lock);
 870		list_for_each_entry(intbss, &rdev->bss_list, list) {
 871			struct cfg80211_bss *res = &intbss->pub;
 872			const struct cfg80211_bss_ies *ies;
 873			const struct element *ssid_elem;
 874			struct cfg80211_colocated_ap *entry;
 875			u32 s_ssid_tmp;
 876			int ret;
 877
 878			ies = rcu_access_pointer(res->ies);
 879			count += cfg80211_parse_colocated_ap(ies,
 880							     &coloc_ap_list);
 881
 882			/* In case the scan request specified a specific BSSID
 883			 * and the BSS is found and operating on 6GHz band then
 884			 * add this AP to the collocated APs list.
 885			 * This is relevant for ML probe requests when the lower
 886			 * band APs have not been discovered.
 887			 */
 888			if (is_broadcast_ether_addr(rdev_req->req.bssid) ||
 889			    !ether_addr_equal(rdev_req->req.bssid, res->bssid) ||
 890			    res->channel->band != NL80211_BAND_6GHZ)
 891				continue;
 892
 893			ret = cfg80211_calc_short_ssid(ies, &ssid_elem,
 894						       &s_ssid_tmp);
 895			if (ret)
 896				continue;
 897
 898			entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
 899			if (!entry)
 900				continue;
 901
 902			memcpy(entry->bssid, res->bssid, ETH_ALEN);
 903			entry->short_ssid = s_ssid_tmp;
 904			memcpy(entry->ssid, ssid_elem->data,
 905			       ssid_elem->datalen);
 906			entry->ssid_len = ssid_elem->datalen;
 907			entry->short_ssid_valid = true;
 908			entry->center_freq = res->channel->center_freq;
 909
 910			list_add_tail(&entry->list, &coloc_ap_list);
 911			count++;
 912		}
 913		spin_unlock_bh(&rdev->bss_lock);
 914	}
 915
 916	size = struct_size(request, req.channels, n_channels);
 917	offs_ssids = size;
 918	size += sizeof(*request->req.ssids) * rdev_req->req.n_ssids;
 919	offs_6ghz_params = size;
 920	size += sizeof(*request->req.scan_6ghz_params) * count;
 921	offs_ies = size;
 922	size += rdev_req->req.ie_len;
 923
 924	request = kzalloc(size, GFP_KERNEL);
 925	if (!request) {
 926		cfg80211_free_coloc_ap_list(&coloc_ap_list);
 927		return -ENOMEM;
 928	}
 929
 930	*request = *rdev_req;
 931	request->req.n_channels = 0;
 932	request->req.n_6ghz_params = 0;
 933	if (rdev_req->req.n_ssids) {
 934		/*
 935		 * Add the ssids from the parent scan request to the new
 936		 * scan request, so the driver would be able to use them
 937		 * in its probe requests to discover hidden APs on PSC
 938		 * channels.
 939		 */
 940		request->req.ssids = (void *)request + offs_ssids;
 941		memcpy(request->req.ssids, rdev_req->req.ssids,
 942		       sizeof(*request->req.ssids) * request->req.n_ssids);
 943	}
 944	request->req.scan_6ghz_params = (void *)request + offs_6ghz_params;
 945
 946	if (rdev_req->req.ie_len) {
 947		void *ie = (void *)request + offs_ies;
 948
 949		memcpy(ie, rdev_req->req.ie, rdev_req->req.ie_len);
 950		request->req.ie = ie;
 951	}
 952
 953	/*
 954	 * PSC channels should not be scanned in case of direct scan with 1 SSID
 955	 * and at least one of the reported co-located APs with same SSID
 956	 * indicating that all APs in the same ESS are co-located
 957	 */
 958	if (count &&
 959	    request->req.n_ssids == 1 &&
 960	    request->req.ssids[0].ssid_len) {
 961		list_for_each_entry(ap, &coloc_ap_list, list) {
 962			if (ap->colocated_ess &&
 963			    cfg80211_find_ssid_match(ap, &request->req)) {
 964				need_scan_psc = false;
 965				break;
 966			}
 967		}
 968	}
 969
 970	/*
 971	 * add to the scan request the channels that need to be scanned
 972	 * regardless of the collocated APs (PSC channels or all channels
 973	 * in case that NL80211_SCAN_FLAG_COLOCATED_6GHZ is not set)
 974	 */
 975	for (i = 0; i < rdev_req->req.n_channels; i++) {
 976		if (rdev_req->req.channels[i]->band == NL80211_BAND_6GHZ &&
 977		    ((need_scan_psc &&
 978		      cfg80211_channel_is_psc(rdev_req->req.channels[i])) ||
 979		     !(rdev_req->req.flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ))) {
 980			cfg80211_scan_req_add_chan(&request->req,
 981						   rdev_req->req.channels[i],
 982						   false);
 983		}
 984	}
 985
 986	if (!(rdev_req->req.flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ))
 987		goto skip;
 988
 989	list_for_each_entry(ap, &coloc_ap_list, list) {
 990		bool found = false;
 991		struct cfg80211_scan_6ghz_params *scan_6ghz_params =
 992			&request->req.scan_6ghz_params[request->req.n_6ghz_params];
 993		struct ieee80211_channel *chan =
 994			ieee80211_get_channel(&rdev->wiphy, ap->center_freq);
 995
 996		if (!chan || chan->flags & IEEE80211_CHAN_DISABLED ||
 997		    !cfg80211_wdev_channel_allowed(rdev_req->req.wdev, chan))
 998			continue;
 999
1000		for (i = 0; i < rdev_req->req.n_channels; i++) {
1001			if (rdev_req->req.channels[i] == chan)
1002				found = true;
1003		}
1004
1005		if (!found)
1006			continue;
1007
1008		if (request->req.n_ssids > 0 &&
1009		    !cfg80211_find_ssid_match(ap, &request->req))
1010			continue;
1011
1012		if (!is_broadcast_ether_addr(request->req.bssid) &&
1013		    !ether_addr_equal(request->req.bssid, ap->bssid))
1014			continue;
1015
1016		if (!request->req.n_ssids && ap->multi_bss &&
1017		    !ap->transmitted_bssid)
1018			continue;
1019
1020		cfg80211_scan_req_add_chan(&request->req, chan, true);
1021		memcpy(scan_6ghz_params->bssid, ap->bssid, ETH_ALEN);
1022		scan_6ghz_params->short_ssid = ap->short_ssid;
1023		scan_6ghz_params->short_ssid_valid = ap->short_ssid_valid;
1024		scan_6ghz_params->unsolicited_probe = ap->unsolicited_probe;
1025		scan_6ghz_params->psd_20 = ap->psd_20;
1026
1027		/*
1028		 * If a PSC channel is added to the scan and 'need_scan_psc' is
1029		 * set to false, then all the APs that the scan logic is
1030		 * interested with on the channel are collocated and thus there
1031		 * is no need to perform the initial PSC channel listen.
1032		 */
1033		if (cfg80211_channel_is_psc(chan) && !need_scan_psc)
1034			scan_6ghz_params->psc_no_listen = true;
1035
1036		request->req.n_6ghz_params++;
1037	}
1038
1039skip:
1040	cfg80211_free_coloc_ap_list(&coloc_ap_list);
1041
1042	if (request->req.n_channels) {
1043		struct cfg80211_scan_request_int *old = rdev->int_scan_req;
1044
1045		rdev->int_scan_req = request;
1046
1047		/*
1048		 * If this scan follows a previous scan, save the scan start
1049		 * info from the first part of the scan
1050		 */
1051		if (!first_part && !WARN_ON(!old))
1052			rdev->int_scan_req->info = old->info;
1053
1054		err = rdev_scan(rdev, request);
1055		if (err) {
1056			rdev->int_scan_req = old;
1057			kfree(request);
1058		} else {
1059			kfree(old);
1060		}
1061
1062		return err;
1063	}
1064
1065	kfree(request);
1066	return -EINVAL;
1067}
1068
1069int cfg80211_scan(struct cfg80211_registered_device *rdev)
1070{
1071	struct cfg80211_scan_request_int *request;
1072	struct cfg80211_scan_request_int *rdev_req = rdev->scan_req;
1073	u32 n_channels = 0, idx, i;
1074
1075	if (!(rdev->wiphy.flags & WIPHY_FLAG_SPLIT_SCAN_6GHZ)) {
1076		rdev_req->req.first_part = true;
1077		return rdev_scan(rdev, rdev_req);
1078	}
1079
1080	for (i = 0; i < rdev_req->req.n_channels; i++) {
1081		if (rdev_req->req.channels[i]->band != NL80211_BAND_6GHZ)
1082			n_channels++;
1083	}
1084
1085	if (!n_channels)
1086		return cfg80211_scan_6ghz(rdev, true);
1087
1088	request = kzalloc(struct_size(request, req.channels, n_channels),
1089			  GFP_KERNEL);
1090	if (!request)
1091		return -ENOMEM;
1092
1093	*request = *rdev_req;
1094	request->req.n_channels = n_channels;
1095
1096	for (i = idx = 0; i < rdev_req->req.n_channels; i++) {
1097		if (rdev_req->req.channels[i]->band != NL80211_BAND_6GHZ)
1098			request->req.channels[idx++] =
1099				rdev_req->req.channels[i];
1100	}
1101
1102	rdev_req->req.scan_6ghz = false;
1103	rdev_req->req.first_part = true;
1104	rdev->int_scan_req = request;
1105	return rdev_scan(rdev, request);
1106}
1107
1108void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
1109			   bool send_message)
1110{
1111	struct cfg80211_scan_request_int *request, *rdev_req;
1112	struct wireless_dev *wdev;
1113	struct sk_buff *msg;
1114#ifdef CONFIG_CFG80211_WEXT
1115	union iwreq_data wrqu;
1116#endif
1117
1118	lockdep_assert_held(&rdev->wiphy.mtx);
1119
1120	if (rdev->scan_msg) {
1121		nl80211_send_scan_msg(rdev, rdev->scan_msg);
1122		rdev->scan_msg = NULL;
1123		return;
1124	}
1125
1126	rdev_req = rdev->scan_req;
1127	if (!rdev_req)
1128		return;
1129
1130	wdev = rdev_req->req.wdev;
1131	request = rdev->int_scan_req ? rdev->int_scan_req : rdev_req;
1132
1133	if (wdev_running(wdev) &&
1134	    (rdev->wiphy.flags & WIPHY_FLAG_SPLIT_SCAN_6GHZ) &&
1135	    !rdev_req->req.scan_6ghz && !request->info.aborted &&
1136	    !cfg80211_scan_6ghz(rdev, false))
1137		return;
1138
1139	/*
1140	 * This must be before sending the other events!
1141	 * Otherwise, wpa_supplicant gets completely confused with
1142	 * wext events.
1143	 */
1144	if (wdev->netdev)
1145		cfg80211_sme_scan_done(wdev->netdev);
1146
1147	if (!request->info.aborted &&
1148	    request->req.flags & NL80211_SCAN_FLAG_FLUSH) {
1149		/* flush entries from previous scans */
1150		spin_lock_bh(&rdev->bss_lock);
1151		__cfg80211_bss_expire(rdev, request->req.scan_start);
1152		spin_unlock_bh(&rdev->bss_lock);
1153	}
1154
1155	msg = nl80211_build_scan_msg(rdev, wdev, request->info.aborted);
1156
1157#ifdef CONFIG_CFG80211_WEXT
1158	if (wdev->netdev && !request->info.aborted) {
1159		memset(&wrqu, 0, sizeof(wrqu));
1160
1161		wireless_send_event(wdev->netdev, SIOCGIWSCAN, &wrqu, NULL);
1162	}
1163#endif
1164
1165	dev_put(wdev->netdev);
1166
1167	kfree(rdev->int_scan_req);
1168	rdev->int_scan_req = NULL;
1169
1170	kfree(rdev->scan_req);
1171	rdev->scan_req = NULL;
1172
1173	if (!send_message)
1174		rdev->scan_msg = msg;
1175	else
1176		nl80211_send_scan_msg(rdev, msg);
1177}
1178
1179void __cfg80211_scan_done(struct wiphy *wiphy, struct wiphy_work *wk)
1180{
1181	___cfg80211_scan_done(wiphy_to_rdev(wiphy), true);
1182}
1183
1184void cfg80211_scan_done(struct cfg80211_scan_request *request,
1185			struct cfg80211_scan_info *info)
1186{
1187	struct cfg80211_scan_request_int *intreq =
1188		container_of(request, struct cfg80211_scan_request_int, req);
1189	struct cfg80211_registered_device *rdev = wiphy_to_rdev(request->wiphy);
1190	struct cfg80211_scan_info old_info = intreq->info;
1191
1192	trace_cfg80211_scan_done(intreq, info);
1193	WARN_ON(intreq != rdev->scan_req &&
1194		intreq != rdev->int_scan_req);
1195
1196	intreq->info = *info;
1197
1198	/*
1199	 * In case the scan is split, the scan_start_tsf and tsf_bssid should
1200	 * be of the first part. In such a case old_info.scan_start_tsf should
1201	 * be non zero.
1202	 */
1203	if (request->scan_6ghz && old_info.scan_start_tsf) {
1204		intreq->info.scan_start_tsf = old_info.scan_start_tsf;
1205		memcpy(intreq->info.tsf_bssid, old_info.tsf_bssid,
1206		       sizeof(intreq->info.tsf_bssid));
1207	}
1208
1209	intreq->notified = true;
1210	wiphy_work_queue(request->wiphy, &rdev->scan_done_wk);
1211}
1212EXPORT_SYMBOL(cfg80211_scan_done);
1213
1214void cfg80211_add_sched_scan_req(struct cfg80211_registered_device *rdev,
1215				 struct cfg80211_sched_scan_request *req)
1216{
1217	lockdep_assert_held(&rdev->wiphy.mtx);
1218
1219	list_add_rcu(&req->list, &rdev->sched_scan_req_list);
1220}
1221
1222static void cfg80211_del_sched_scan_req(struct cfg80211_registered_device *rdev,
1223					struct cfg80211_sched_scan_request *req)
1224{
1225	lockdep_assert_held(&rdev->wiphy.mtx);
1226
1227	list_del_rcu(&req->list);
1228	kfree_rcu(req, rcu_head);
1229}
1230
1231static struct cfg80211_sched_scan_request *
1232cfg80211_find_sched_scan_req(struct cfg80211_registered_device *rdev, u64 reqid)
1233{
1234	struct cfg80211_sched_scan_request *pos;
1235
1236	list_for_each_entry_rcu(pos, &rdev->sched_scan_req_list, list,
1237				lockdep_is_held(&rdev->wiphy.mtx)) {
1238		if (pos->reqid == reqid)
1239			return pos;
1240	}
1241	return NULL;
1242}
1243
1244/*
1245 * Determines if a scheduled scan request can be handled. When a legacy
1246 * scheduled scan is running no other scheduled scan is allowed regardless
1247 * whether the request is for legacy or multi-support scan. When a multi-support
1248 * scheduled scan is running a request for legacy scan is not allowed. In this
1249 * case a request for multi-support scan can be handled if resources are
1250 * available, ie. struct wiphy::max_sched_scan_reqs limit is not yet reached.
1251 */
1252int cfg80211_sched_scan_req_possible(struct cfg80211_registered_device *rdev,
1253				     bool want_multi)
1254{
1255	struct cfg80211_sched_scan_request *pos;
1256	int i = 0;
1257
1258	list_for_each_entry(pos, &rdev->sched_scan_req_list, list) {
1259		/* request id zero means legacy in progress */
1260		if (!i && !pos->reqid)
1261			return -EINPROGRESS;
1262		i++;
1263	}
1264
1265	if (i) {
1266		/* no legacy allowed when multi request(s) are active */
1267		if (!want_multi)
1268			return -EINPROGRESS;
1269
1270		/* resource limit reached */
1271		if (i == rdev->wiphy.max_sched_scan_reqs)
1272			return -ENOSPC;
1273	}
1274	return 0;
1275}
1276
1277void cfg80211_sched_scan_results_wk(struct work_struct *work)
1278{
1279	struct cfg80211_registered_device *rdev;
1280	struct cfg80211_sched_scan_request *req, *tmp;
1281
1282	rdev = container_of(work, struct cfg80211_registered_device,
1283			   sched_scan_res_wk);
1284
1285	guard(wiphy)(&rdev->wiphy);
1286
1287	list_for_each_entry_safe(req, tmp, &rdev->sched_scan_req_list, list) {
1288		if (req->report_results) {
1289			req->report_results = false;
1290			if (req->flags & NL80211_SCAN_FLAG_FLUSH) {
1291				/* flush entries from previous scans */
1292				spin_lock_bh(&rdev->bss_lock);
1293				__cfg80211_bss_expire(rdev, req->scan_start);
1294				spin_unlock_bh(&rdev->bss_lock);
1295				req->scan_start = jiffies;
1296			}
1297			nl80211_send_sched_scan(req,
1298						NL80211_CMD_SCHED_SCAN_RESULTS);
1299		}
1300	}
1301}
1302
1303void cfg80211_sched_scan_results(struct wiphy *wiphy, u64 reqid)
1304{
1305	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
1306	struct cfg80211_sched_scan_request *request;
1307
1308	trace_cfg80211_sched_scan_results(wiphy, reqid);
1309	/* ignore if we're not scanning */
1310
1311	rcu_read_lock();
1312	request = cfg80211_find_sched_scan_req(rdev, reqid);
1313	if (request) {
1314		request->report_results = true;
1315		queue_work(cfg80211_wq, &rdev->sched_scan_res_wk);
1316	}
1317	rcu_read_unlock();
1318}
1319EXPORT_SYMBOL(cfg80211_sched_scan_results);
1320
1321void cfg80211_sched_scan_stopped_locked(struct wiphy *wiphy, u64 reqid)
1322{
1323	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
1324
1325	lockdep_assert_held(&wiphy->mtx);
1326
1327	trace_cfg80211_sched_scan_stopped(wiphy, reqid);
1328
1329	__cfg80211_stop_sched_scan(rdev, reqid, true);
1330}
1331EXPORT_SYMBOL(cfg80211_sched_scan_stopped_locked);
1332
1333void cfg80211_sched_scan_stopped(struct wiphy *wiphy, u64 reqid)
1334{
1335	guard(wiphy)(wiphy);
1336
1337	cfg80211_sched_scan_stopped_locked(wiphy, reqid);
1338}
1339EXPORT_SYMBOL(cfg80211_sched_scan_stopped);
1340
1341int cfg80211_stop_sched_scan_req(struct cfg80211_registered_device *rdev,
1342				 struct cfg80211_sched_scan_request *req,
1343				 bool driver_initiated)
1344{
1345	lockdep_assert_held(&rdev->wiphy.mtx);
1346
1347	if (!driver_initiated) {
1348		int err = rdev_sched_scan_stop(rdev, req->dev, req->reqid);
1349		if (err)
1350			return err;
1351	}
1352
1353	nl80211_send_sched_scan(req, NL80211_CMD_SCHED_SCAN_STOPPED);
1354
1355	cfg80211_del_sched_scan_req(rdev, req);
1356
1357	return 0;
1358}
1359
1360int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
1361			       u64 reqid, bool driver_initiated)
1362{
1363	struct cfg80211_sched_scan_request *sched_scan_req;
1364
1365	lockdep_assert_held(&rdev->wiphy.mtx);
1366
1367	sched_scan_req = cfg80211_find_sched_scan_req(rdev, reqid);
1368	if (!sched_scan_req)
1369		return -ENOENT;
1370
1371	return cfg80211_stop_sched_scan_req(rdev, sched_scan_req,
1372					    driver_initiated);
1373}
1374
1375void cfg80211_bss_age(struct cfg80211_registered_device *rdev,
1376                      unsigned long age_secs)
1377{
1378	struct cfg80211_internal_bss *bss;
1379	unsigned long age_jiffies = secs_to_jiffies(age_secs);
1380
1381	spin_lock_bh(&rdev->bss_lock);
1382	list_for_each_entry(bss, &rdev->bss_list, list)
1383		bss->ts -= age_jiffies;
1384	spin_unlock_bh(&rdev->bss_lock);
1385}
1386
1387void cfg80211_bss_expire(struct cfg80211_registered_device *rdev)
1388{
1389	__cfg80211_bss_expire(rdev, jiffies - IEEE80211_SCAN_RESULT_EXPIRE);
1390}
1391
1392void cfg80211_bss_flush(struct wiphy *wiphy)
1393{
1394	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
1395
1396	spin_lock_bh(&rdev->bss_lock);
1397	__cfg80211_bss_expire(rdev, jiffies);
1398	spin_unlock_bh(&rdev->bss_lock);
1399}
1400EXPORT_SYMBOL(cfg80211_bss_flush);
1401
1402const struct element *
1403cfg80211_find_elem_match(u8 eid, const u8 *ies, unsigned int len,
1404			 const u8 *match, unsigned int match_len,
1405			 unsigned int match_offset)
1406{
1407	const struct element *elem;
1408
1409	for_each_element_id(elem, eid, ies, len) {
1410		if (elem->datalen >= match_offset + match_len &&
1411		    !memcmp(elem->data + match_offset, match, match_len))
1412			return elem;
1413	}
1414
1415	return NULL;
1416}
1417EXPORT_SYMBOL(cfg80211_find_elem_match);
1418
1419const struct element *cfg80211_find_vendor_elem(unsigned int oui, int oui_type,
1420						const u8 *ies,
1421						unsigned int len)
1422{
1423	const struct element *elem;
1424	u8 match[] = { oui >> 16, oui >> 8, oui, oui_type };
1425	int match_len = (oui_type < 0) ? 3 : sizeof(match);
1426
1427	if (WARN_ON(oui_type > 0xff))
1428		return NULL;
1429
1430	elem = cfg80211_find_elem_match(WLAN_EID_VENDOR_SPECIFIC, ies, len,
1431					match, match_len, 0);
1432
1433	if (!elem || elem->datalen < 4)
1434		return NULL;
1435
1436	return elem;
1437}
1438EXPORT_SYMBOL(cfg80211_find_vendor_elem);
1439
1440/**
1441 * enum bss_compare_mode - BSS compare mode
1442 * @BSS_CMP_REGULAR: regular compare mode (for insertion and normal find)
1443 * @BSS_CMP_HIDE_ZLEN: find hidden SSID with zero-length mode
1444 * @BSS_CMP_HIDE_NUL: find hidden SSID with NUL-ed out mode
1445 */
1446enum bss_compare_mode {
1447	BSS_CMP_REGULAR,
1448	BSS_CMP_HIDE_ZLEN,
1449	BSS_CMP_HIDE_NUL,
1450};
1451
1452static int cmp_bss(struct cfg80211_bss *a,
1453		   struct cfg80211_bss *b,
1454		   enum bss_compare_mode mode)
1455{
1456	const struct cfg80211_bss_ies *a_ies, *b_ies;
1457	const u8 *ie1 = NULL;
1458	const u8 *ie2 = NULL;
1459	int i, r;
1460
1461	if (a->channel != b->channel)
1462		return (b->channel->center_freq * 1000 + b->channel->freq_offset) -
1463		       (a->channel->center_freq * 1000 + a->channel->freq_offset);
1464
1465	a_ies = rcu_access_pointer(a->ies);
1466	if (!a_ies)
1467		return -1;
1468	b_ies = rcu_access_pointer(b->ies);
1469	if (!b_ies)
1470		return 1;
1471
1472	if (WLAN_CAPABILITY_IS_STA_BSS(a->capability))
1473		ie1 = cfg80211_find_ie(WLAN_EID_MESH_ID,
1474				       a_ies->data, a_ies->len);
1475	if (WLAN_CAPABILITY_IS_STA_BSS(b->capability))
1476		ie2 = cfg80211_find_ie(WLAN_EID_MESH_ID,
1477				       b_ies->data, b_ies->len);
1478	if (ie1 && ie2) {
1479		int mesh_id_cmp;
1480
1481		if (ie1[1] == ie2[1])
1482			mesh_id_cmp = memcmp(ie1 + 2, ie2 + 2, ie1[1]);
1483		else
1484			mesh_id_cmp = ie2[1] - ie1[1];
1485
1486		ie1 = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
1487				       a_ies->data, a_ies->len);
1488		ie2 = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
1489				       b_ies->data, b_ies->len);
1490		if (ie1 && ie2) {
1491			if (mesh_id_cmp)
1492				return mesh_id_cmp;
1493			if (ie1[1] != ie2[1])
1494				return ie2[1] - ie1[1];
1495			return memcmp(ie1 + 2, ie2 + 2, ie1[1]);
1496		}
1497	}
1498
1499	r = memcmp(a->bssid, b->bssid, sizeof(a->bssid));
1500	if (r)
1501		return r;
1502
1503	ie1 = cfg80211_find_ie(WLAN_EID_SSID, a_ies->data, a_ies->len);
1504	ie2 = cfg80211_find_ie(WLAN_EID_SSID, b_ies->data, b_ies->len);
1505
1506	if (!ie1 && !ie2)
1507		return 0;
1508
1509	/*
1510	 * Note that with "hide_ssid", the function returns a match if
1511	 * the already-present BSS ("b") is a hidden SSID beacon for
1512	 * the new BSS ("a").
1513	 */
1514
1515	/* sort missing IE before (left of) present IE */
1516	if (!ie1)
1517		return -1;
1518	if (!ie2)
1519		return 1;
1520
1521	switch (mode) {
1522	case BSS_CMP_HIDE_ZLEN:
1523		/*
1524		 * In ZLEN mode we assume the BSS entry we're
1525		 * looking for has a zero-length SSID. So if
1526		 * the one we're looking at right now has that,
1527		 * return 0. Otherwise, return the difference
1528		 * in length, but since we're looking for the
1529		 * 0-length it's really equivalent to returning
1530		 * the length of the one we're looking at.
1531		 *
1532		 * No content comparison is needed as we assume
1533		 * the content length is zero.
1534		 */
1535		return ie2[1];
1536	case BSS_CMP_REGULAR:
1537	default:
1538		/* sort by length first, then by contents */
1539		if (ie1[1] != ie2[1])
1540			return ie2[1] - ie1[1];
1541		return memcmp(ie1 + 2, ie2 + 2, ie1[1]);
1542	case BSS_CMP_HIDE_NUL:
1543		if (ie1[1] != ie2[1])
1544			return ie2[1] - ie1[1];
1545		/* this is equivalent to memcmp(zeroes, ie2 + 2, len) */
1546		for (i = 0; i < ie2[1]; i++)
1547			if (ie2[i + 2])
1548				return -1;
1549		return 0;
1550	}
1551}
1552
1553static bool cfg80211_bss_type_match(u16 capability,
1554				    enum nl80211_band band,
1555				    enum ieee80211_bss_type bss_type)
1556{
1557	bool ret = true;
1558	u16 mask, val;
1559
1560	if (bss_type == IEEE80211_BSS_TYPE_ANY)
1561		return ret;
1562
1563	if (band == NL80211_BAND_60GHZ) {
1564		mask = WLAN_CAPABILITY_DMG_TYPE_MASK;
1565		switch (bss_type) {
1566		case IEEE80211_BSS_TYPE_ESS:
1567			val = WLAN_CAPABILITY_DMG_TYPE_AP;
1568			break;
1569		case IEEE80211_BSS_TYPE_PBSS:
1570			val = WLAN_CAPABILITY_DMG_TYPE_PBSS;
1571			break;
1572		case IEEE80211_BSS_TYPE_IBSS:
1573			val = WLAN_CAPABILITY_DMG_TYPE_IBSS;
1574			break;
1575		default:
1576			return false;
1577		}
1578	} else {
1579		mask = WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS;
1580		switch (bss_type) {
1581		case IEEE80211_BSS_TYPE_ESS:
1582			val = WLAN_CAPABILITY_ESS;
1583			break;
1584		case IEEE80211_BSS_TYPE_IBSS:
1585			val = WLAN_CAPABILITY_IBSS;
1586			break;
1587		case IEEE80211_BSS_TYPE_MBSS:
1588			val = 0;
1589			break;
1590		default:
1591			return false;
1592		}
1593	}
1594
1595	ret = ((capability & mask) == val);
1596	return ret;
1597}
1598
1599/* Returned bss is reference counted and must be cleaned up appropriately. */
1600struct cfg80211_bss *__cfg80211_get_bss(struct wiphy *wiphy,
1601					struct ieee80211_channel *channel,
1602					const u8 *bssid,
1603					const u8 *ssid, size_t ssid_len,
1604					enum ieee80211_bss_type bss_type,
1605					enum ieee80211_privacy privacy,
1606					u32 use_for)
1607{
1608	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
1609	struct cfg80211_internal_bss *bss, *res = NULL;
1610	unsigned long now = jiffies;
1611	int bss_privacy;
1612
1613	trace_cfg80211_get_bss(wiphy, channel, bssid, ssid, ssid_len, bss_type,
1614			       privacy);
1615
1616	spin_lock_bh(&rdev->bss_lock);
1617
1618	list_for_each_entry(bss, &rdev->bss_list, list) {
1619		if (!cfg80211_bss_type_match(bss->pub.capability,
1620					     bss->pub.channel->band, bss_type))
1621			continue;
1622
1623		bss_privacy = (bss->pub.capability & WLAN_CAPABILITY_PRIVACY);
1624		if ((privacy == IEEE80211_PRIVACY_ON && !bss_privacy) ||
1625		    (privacy == IEEE80211_PRIVACY_OFF && bss_privacy))
1626			continue;
1627		if (channel && bss->pub.channel != channel)
1628			continue;
1629		if (!is_valid_ether_addr(bss->pub.bssid))
1630			continue;
1631		if ((bss->pub.use_for & use_for) != use_for)
1632			continue;
1633		/* Don't get expired BSS structs */
1634		if (time_after(now, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE) &&
1635		    !atomic_read(&bss->hold))
1636			continue;
1637		if (is_bss(&bss->pub, bssid, ssid, ssid_len)) {
1638			res = bss;
1639			bss_ref_get(rdev, res);
1640			break;
1641		}
1642	}
1643
1644	spin_unlock_bh(&rdev->bss_lock);
1645	if (!res)
1646		return NULL;
1647	trace_cfg80211_return_bss(&res->pub);
1648	return &res->pub;
1649}
1650EXPORT_SYMBOL(__cfg80211_get_bss);
1651
1652static bool rb_insert_bss(struct cfg80211_registered_device *rdev,
1653			  struct cfg80211_internal_bss *bss)
1654{
1655	struct rb_node **p = &rdev->bss_tree.rb_node;
1656	struct rb_node *parent = NULL;
1657	struct cfg80211_internal_bss *tbss;
1658	int cmp;
1659
1660	while (*p) {
1661		parent = *p;
1662		tbss = rb_entry(parent, struct cfg80211_internal_bss, rbn);
1663
1664		cmp = cmp_bss(&bss->pub, &tbss->pub, BSS_CMP_REGULAR);
1665
1666		if (WARN_ON(!cmp)) {
1667			/* will sort of leak this BSS */
1668			return false;
1669		}
1670
1671		if (cmp < 0)
1672			p = &(*p)->rb_left;
1673		else
1674			p = &(*p)->rb_right;
1675	}
1676
1677	rb_link_node(&bss->rbn, parent, p);
1678	rb_insert_color(&bss->rbn, &rdev->bss_tree);
1679	return true;
1680}
1681
1682static struct cfg80211_internal_bss *
1683rb_find_bss(struct cfg80211_registered_device *rdev,
1684	    struct cfg80211_internal_bss *res,
1685	    enum bss_compare_mode mode)
1686{
1687	struct rb_node *n = rdev->bss_tree.rb_node;
1688	struct cfg80211_internal_bss *bss;
1689	int r;
1690
1691	while (n) {
1692		bss = rb_entry(n, struct cfg80211_internal_bss, rbn);
1693		r = cmp_bss(&res->pub, &bss->pub, mode);
1694
1695		if (r == 0)
1696			return bss;
1697		else if (r < 0)
1698			n = n->rb_left;
1699		else
1700			n = n->rb_right;
1701	}
1702
1703	return NULL;
1704}
1705
1706static void cfg80211_insert_bss(struct cfg80211_registered_device *rdev,
1707				struct cfg80211_internal_bss *bss)
1708{
1709	lockdep_assert_held(&rdev->bss_lock);
1710
1711	if (!rb_insert_bss(rdev, bss))
1712		return;
1713	list_add_tail(&bss->list, &rdev->bss_list);
1714	rdev->bss_entries++;
1715}
1716
1717static void cfg80211_rehash_bss(struct cfg80211_registered_device *rdev,
1718                                struct cfg80211_internal_bss *bss)
1719{
1720	lockdep_assert_held(&rdev->bss_lock);
1721
1722	rb_erase(&bss->rbn, &rdev->bss_tree);
1723	if (!rb_insert_bss(rdev, bss)) {
1724		list_del(&bss->list);
1725		if (!list_empty(&bss->hidden_list))
1726			list_del_init(&bss->hidden_list);
1727		if (!list_empty(&bss->pub.nontrans_list))
1728			list_del_init(&bss->pub.nontrans_list);
1729		rdev->bss_entries--;
1730	}
1731	rdev->bss_generation++;
1732}
1733
1734static bool cfg80211_combine_bsses(struct cfg80211_registered_device *rdev,
1735				   struct cfg80211_internal_bss *new)
1736{
1737	const struct cfg80211_bss_ies *ies;
1738	struct cfg80211_internal_bss *bss;
1739	const u8 *ie;
1740	int i, ssidlen;
1741	u8 fold = 0;
1742	u32 n_entries = 0;
1743
1744	ies = rcu_access_pointer(new->pub.beacon_ies);
1745	if (WARN_ON(!ies))
1746		return false;
1747
1748	ie = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len);
1749	if (!ie) {
1750		/* nothing to do */
1751		return true;
1752	}
1753
1754	ssidlen = ie[1];
1755	for (i = 0; i < ssidlen; i++)
1756		fold |= ie[2 + i];
1757
1758	if (fold) {
1759		/* not a hidden SSID */
1760		return true;
1761	}
1762
1763	/* This is the bad part ... */
1764
1765	list_for_each_entry(bss, &rdev->bss_list, list) {
1766		/*
1767		 * we're iterating all the entries anyway, so take the
1768		 * opportunity to validate the list length accounting
1769		 */
1770		n_entries++;
1771
1772		if (!ether_addr_equal(bss->pub.bssid, new->pub.bssid))
1773			continue;
1774		if (bss->pub.channel != new->pub.channel)
1775			continue;
1776		if (rcu_access_pointer(bss->pub.beacon_ies))
1777			continue;
1778		ies = rcu_access_pointer(bss->pub.ies);
1779		if (!ies)
1780			continue;
1781		ie = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len);
1782		if (!ie)
1783			continue;
1784		if (ssidlen && ie[1] != ssidlen)
1785			continue;
1786		if (WARN_ON_ONCE(bss->pub.hidden_beacon_bss))
1787			continue;
1788		if (WARN_ON_ONCE(!list_empty(&bss->hidden_list)))
1789			list_del(&bss->hidden_list);
1790		/* combine them */
1791		list_add(&bss->hidden_list, &new->hidden_list);
1792		bss->pub.hidden_beacon_bss = &new->pub;
1793		new->refcount += bss->refcount;
1794		rcu_assign_pointer(bss->pub.beacon_ies,
1795				   new->pub.beacon_ies);
1796	}
1797
1798	WARN_ONCE(n_entries != rdev->bss_entries,
1799		  "rdev bss entries[%d]/list[len:%d] corruption\n",
1800		  rdev->bss_entries, n_entries);
1801
1802	return true;
1803}
1804
1805static void cfg80211_update_hidden_bsses(struct cfg80211_internal_bss *known,
1806					 const struct cfg80211_bss_ies *new_ies,
1807					 const struct cfg80211_bss_ies *old_ies)
1808{
1809	struct cfg80211_internal_bss *bss;
1810
1811	/* Assign beacon IEs to all sub entries */
1812	list_for_each_entry(bss, &known->hidden_list, hidden_list) {
1813		const struct cfg80211_bss_ies *ies;
1814
1815		ies = rcu_access_pointer(bss->pub.beacon_ies);
1816		WARN_ON(ies != old_ies);
1817
1818		rcu_assign_pointer(bss->pub.beacon_ies, new_ies);
1819
1820		bss->ts = known->ts;
1821		bss->pub.ts_boottime = known->pub.ts_boottime;
1822	}
1823}
1824
1825static void cfg80211_check_stuck_ecsa(struct cfg80211_registered_device *rdev,
1826				      struct cfg80211_internal_bss *known,
1827				      const struct cfg80211_bss_ies *old)
1828{
1829	const struct ieee80211_ext_chansw_ie *ecsa;
1830	const struct element *elem_new, *elem_old;
1831	const struct cfg80211_bss_ies *new, *bcn;
1832
1833	if (known->pub.proberesp_ecsa_stuck)
1834		return;
1835
1836	new = rcu_dereference_protected(known->pub.proberesp_ies,
1837					lockdep_is_held(&rdev->bss_lock));
1838	if (WARN_ON(!new))
1839		return;
1840
1841	if (new->tsf - old->tsf < USEC_PER_SEC)
1842		return;
1843
1844	elem_old = cfg80211_find_elem(WLAN_EID_EXT_CHANSWITCH_ANN,
1845				      old->data, old->len);
1846	if (!elem_old)
1847		return;
1848
1849	elem_new = cfg80211_find_elem(WLAN_EID_EXT_CHANSWITCH_ANN,
1850				      new->data, new->len);
1851	if (!elem_new)
1852		return;
1853
1854	bcn = rcu_dereference_protected(known->pub.beacon_ies,
1855					lockdep_is_held(&rdev->bss_lock));
1856	if (bcn &&
1857	    cfg80211_find_elem(WLAN_EID_EXT_CHANSWITCH_ANN,
1858			       bcn->data, bcn->len))
1859		return;
1860
1861	if (elem_new->datalen != elem_old->datalen)
1862		return;
1863	if (elem_new->datalen < sizeof(struct ieee80211_ext_chansw_ie))
1864		return;
1865	if (memcmp(elem_new->data, elem_old->data, elem_new->datalen))
1866		return;
1867
1868	ecsa = (void *)elem_new->data;
1869
1870	if (!ecsa->mode)
1871		return;
1872
1873	if (ecsa->new_ch_num !=
1874	    ieee80211_frequency_to_channel(known->pub.channel->center_freq))
1875		return;
1876
1877	known->pub.proberesp_ecsa_stuck = 1;
1878}
1879
1880static bool
1881cfg80211_update_known_bss(struct cfg80211_registered_device *rdev,
1882			  struct cfg80211_internal_bss *known,
1883			  struct cfg80211_internal_bss *new,
1884			  bool signal_valid)
1885{
1886	lockdep_assert_held(&rdev->bss_lock);
1887
1888	/* Update time stamps */
1889	known->ts = new->ts;
1890	known->pub.ts_boottime = new->pub.ts_boottime;
1891
1892	/* Update IEs */
1893	if (rcu_access_pointer(new->pub.proberesp_ies)) {
1894		const struct cfg80211_bss_ies *old;
1895
1896		old = rcu_access_pointer(known->pub.proberesp_ies);
1897
1898		rcu_assign_pointer(known->pub.proberesp_ies,
1899				   new->pub.proberesp_ies);
1900		/* Override possible earlier Beacon frame IEs */
1901		rcu_assign_pointer(known->pub.ies,
1902				   new->pub.proberesp_ies);
1903		if (old) {
1904			cfg80211_check_stuck_ecsa(rdev, known, old);
1905			kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
1906		}
1907	}
1908
1909	if (rcu_access_pointer(new->pub.beacon_ies)) {
1910		const struct cfg80211_bss_ies *old;
1911
1912		if (known->pub.hidden_beacon_bss &&
1913		    !list_empty(&known->hidden_list)) {
1914			const struct cfg80211_bss_ies *f;
1915
1916			/* The known BSS struct is one of the probe
1917			 * response members of a group, but we're
1918			 * receiving a beacon (beacon_ies in the new
1919			 * bss is used). This can only mean that the
1920			 * AP changed its beacon from not having an
1921			 * SSID to showing it, which is confusing so
1922			 * drop this information.
1923			 */
1924
1925			f = rcu_access_pointer(new->pub.beacon_ies);
1926			if (!new->pub.hidden_beacon_bss)
1927				kfree_rcu((struct cfg80211_bss_ies *)f, rcu_head);
1928			return false;
1929		}
1930
1931		old = rcu_access_pointer(known->pub.beacon_ies);
1932
1933		rcu_assign_pointer(known->pub.beacon_ies, new->pub.beacon_ies);
1934
1935		/* Override IEs if they were from a beacon before */
1936		if (old == rcu_access_pointer(known->pub.ies))
1937			rcu_assign_pointer(known->pub.ies, new->pub.beacon_ies);
1938
1939		cfg80211_update_hidden_bsses(known,
1940					     rcu_access_pointer(new->pub.beacon_ies),
1941					     old);
1942
1943		if (old)
1944			kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
1945	}
1946
1947	known->pub.beacon_interval = new->pub.beacon_interval;
1948
1949	/* don't update the signal if beacon was heard on
1950	 * adjacent channel.
1951	 */
1952	if (signal_valid)
1953		known->pub.signal = new->pub.signal;
1954	known->pub.capability = new->pub.capability;
1955	known->parent_tsf = new->parent_tsf;
1956	known->pub.chains = new->pub.chains;
1957	memcpy(known->pub.chain_signal, new->pub.chain_signal,
1958	       IEEE80211_MAX_CHAINS);
1959	ether_addr_copy(known->parent_bssid, new->parent_bssid);
1960	known->pub.max_bssid_indicator = new->pub.max_bssid_indicator;
1961	known->pub.bssid_index = new->pub.bssid_index;
1962	known->pub.use_for = new->pub.use_for;
1963	known->pub.cannot_use_reasons = new->pub.cannot_use_reasons;
1964	known->bss_source = new->bss_source;
1965
1966	return true;
1967}
1968
1969/* Returned bss is reference counted and must be cleaned up appropriately. */
1970static struct cfg80211_internal_bss *
1971__cfg80211_bss_update(struct cfg80211_registered_device *rdev,
1972		      struct cfg80211_internal_bss *tmp,
1973		      bool signal_valid, unsigned long ts)
1974{
1975	struct cfg80211_internal_bss *found = NULL;
1976	struct cfg80211_bss_ies *ies;
1977
1978	if (WARN_ON(!tmp->pub.channel))
1979		goto free_ies;
1980
1981	tmp->ts = ts;
1982
1983	if (WARN_ON(!rcu_access_pointer(tmp->pub.ies)))
1984		goto free_ies;
1985
1986	found = rb_find_bss(rdev, tmp, BSS_CMP_REGULAR);
1987
1988	if (found) {
1989		if (!cfg80211_update_known_bss(rdev, found, tmp, signal_valid))
1990			return NULL;
1991	} else {
1992		struct cfg80211_internal_bss *new;
1993		struct cfg80211_internal_bss *hidden;
1994
1995		/*
1996		 * create a copy -- the "res" variable that is passed in
1997		 * is allocated on the stack since it's not needed in the
1998		 * more common case of an update
1999		 */
2000		new = kzalloc(sizeof(*new) + rdev->wiphy.bss_priv_size,
2001			      GFP_ATOMIC);
2002		if (!new)
2003			goto free_ies;
2004		memcpy(new, tmp, sizeof(*new));
2005		new->refcount = 1;
2006		INIT_LIST_HEAD(&new->hidden_list);
2007		INIT_LIST_HEAD(&new->pub.nontrans_list);
2008		/* we'll set this later if it was non-NULL */
2009		new->pub.transmitted_bss = NULL;
2010
2011		if (rcu_access_pointer(tmp->pub.proberesp_ies)) {
2012			hidden = rb_find_bss(rdev, tmp, BSS_CMP_HIDE_ZLEN);
2013			if (!hidden)
2014				hidden = rb_find_bss(rdev, tmp,
2015						     BSS_CMP_HIDE_NUL);
2016			if (hidden) {
2017				new->pub.hidden_beacon_bss = &hidden->pub;
2018				list_add(&new->hidden_list,
2019					 &hidden->hidden_list);
2020				hidden->refcount++;
2021
2022				ies = (void *)rcu_access_pointer(new->pub.beacon_ies);
2023				rcu_assign_pointer(new->pub.beacon_ies,
2024						   hidden->pub.beacon_ies);
2025				if (ies)
2026					kfree_rcu(ies, rcu_head);
2027			}
2028		} else {
2029			/*
2030			 * Ok so we found a beacon, and don't have an entry. If
2031			 * it's a beacon with hidden SSID, we might be in for an
2032			 * expensive search for any probe responses that should
2033			 * be grouped with this beacon for updates ...
2034			 */
2035			if (!cfg80211_combine_bsses(rdev, new)) {
2036				bss_ref_put(rdev, new);
2037				return NULL;
2038			}
2039		}
2040
2041		if (rdev->bss_entries >= bss_entries_limit &&
2042		    !cfg80211_bss_expire_oldest(rdev)) {
2043			bss_ref_put(rdev, new);
2044			return NULL;
2045		}
2046
2047		/* This must be before the call to bss_ref_get */
2048		if (tmp->pub.transmitted_bss) {
2049			new->pub.transmitted_bss = tmp->pub.transmitted_bss;
2050			bss_ref_get(rdev, bss_from_pub(tmp->pub.transmitted_bss));
2051		}
2052
2053		cfg80211_insert_bss(rdev, new);
2054		found = new;
2055	}
2056
2057	rdev->bss_generation++;
2058	bss_ref_get(rdev, found);
2059
2060	return found;
2061
2062free_ies:
2063	ies = (void *)rcu_access_pointer(tmp->pub.beacon_ies);
2064	if (ies)
2065		kfree_rcu(ies, rcu_head);
2066	ies = (void *)rcu_access_pointer(tmp->pub.proberesp_ies);
2067	if (ies)
2068		kfree_rcu(ies, rcu_head);
2069
2070	return NULL;
2071}
2072
2073struct cfg80211_internal_bss *
2074cfg80211_bss_update(struct cfg80211_registered_device *rdev,
2075		    struct cfg80211_internal_bss *tmp,
2076		    bool signal_valid, unsigned long ts)
2077{
2078	struct cfg80211_internal_bss *res;
2079
2080	spin_lock_bh(&rdev->bss_lock);
2081	res = __cfg80211_bss_update(rdev, tmp, signal_valid, ts);
2082	spin_unlock_bh(&rdev->bss_lock);
2083
2084	return res;
2085}
2086
2087int cfg80211_get_ies_channel_number(const u8 *ie, size_t ielen,
2088				    enum nl80211_band band)
2089{
2090	const struct element *tmp;
2091
2092	if (band == NL80211_BAND_6GHZ) {
2093		struct ieee80211_he_operation *he_oper;
2094
2095		tmp = cfg80211_find_ext_elem(WLAN_EID_EXT_HE_OPERATION, ie,
2096					     ielen);
2097		if (tmp && tmp->datalen >= sizeof(*he_oper) &&
2098		    tmp->datalen >= ieee80211_he_oper_size(&tmp->data[1])) {
2099			const struct ieee80211_he_6ghz_oper *he_6ghz_oper;
2100
2101			he_oper = (void *)&tmp->data[1];
2102
2103			he_6ghz_oper = ieee80211_he_6ghz_oper(he_oper);
2104			if (!he_6ghz_oper)
2105				return -1;
2106
2107			return he_6ghz_oper->primary;
2108		}
2109	} else if (band == NL80211_BAND_S1GHZ) {
2110		tmp = cfg80211_find_elem(WLAN_EID_S1G_OPERATION, ie, ielen);
2111		if (tmp && tmp->datalen >= sizeof(struct ieee80211_s1g_oper_ie)) {
2112			struct ieee80211_s1g_oper_ie *s1gop = (void *)tmp->data;
2113
2114			return s1gop->oper_ch;
2115		}
2116	} else {
2117		tmp = cfg80211_find_elem(WLAN_EID_DS_PARAMS, ie, ielen);
2118		if (tmp && tmp->datalen == 1)
2119			return tmp->data[0];
2120
2121		tmp = cfg80211_find_elem(WLAN_EID_HT_OPERATION, ie, ielen);
2122		if (tmp &&
2123		    tmp->datalen >= sizeof(struct ieee80211_ht_operation)) {
2124			struct ieee80211_ht_operation *htop = (void *)tmp->data;
2125
2126			return htop->primary_chan;
2127		}
2128	}
2129
2130	return -1;
2131}
2132EXPORT_SYMBOL(cfg80211_get_ies_channel_number);
2133
2134/*
2135 * Update RX channel information based on the available frame payload
2136 * information. This is mainly for the 2.4 GHz band where frames can be received
2137 * from neighboring channels and the Beacon frames use the DSSS Parameter Set
2138 * element to indicate the current (transmitting) channel, but this might also
2139 * be needed on other bands if RX frequency does not match with the actual
2140 * operating channel of a BSS, or if the AP reports a different primary channel.
2141 */
2142static struct ieee80211_channel *
2143cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen,
2144			 struct ieee80211_channel *channel)
2145{
2146	u32 freq;
2147	int channel_number;
2148	struct ieee80211_channel *alt_channel;
2149
2150	channel_number = cfg80211_get_ies_channel_number(ie, ielen,
2151							 channel->band);
2152
2153	if (channel_number < 0) {
2154		/* No channel information in frame payload */
2155		return channel;
2156	}
2157
2158	freq = ieee80211_channel_to_freq_khz(channel_number, channel->band);
2159
2160	/*
2161	 * Frame info (beacon/prob res) is the same as received channel,
2162	 * no need for further processing.
2163	 */
2164	if (freq == ieee80211_channel_to_khz(channel))
2165		return channel;
2166
2167	alt_channel = ieee80211_get_channel_khz(wiphy, freq);
2168	if (!alt_channel) {
2169		if (channel->band == NL80211_BAND_2GHZ ||
2170		    channel->band == NL80211_BAND_6GHZ) {
2171			/*
2172			 * Better not allow unexpected channels when that could
2173			 * be going beyond the 1-11 range (e.g., discovering
2174			 * BSS on channel 12 when radio is configured for
2175			 * channel 11) or beyond the 6 GHz channel range.
2176			 */
2177			return NULL;
2178		}
2179
2180		/* No match for the payload channel number - ignore it */
2181		return channel;
2182	}
2183
2184	/*
2185	 * Use the channel determined through the payload channel number
2186	 * instead of the RX channel reported by the driver.
2187	 */
2188	if (alt_channel->flags & IEEE80211_CHAN_DISABLED)
2189		return NULL;
2190	return alt_channel;
2191}
2192
2193struct cfg80211_inform_single_bss_data {
2194	struct cfg80211_inform_bss *drv_data;
2195	enum cfg80211_bss_frame_type ftype;
2196	struct ieee80211_channel *channel;
2197	u8 bssid[ETH_ALEN];
2198	u64 tsf;
2199	u16 capability;
2200	u16 beacon_interval;
2201	const u8 *ie;
2202	size_t ielen;
2203
2204	enum bss_source_type bss_source;
2205	/* Set if reporting bss_source != BSS_SOURCE_DIRECT */
2206	struct cfg80211_bss *source_bss;
2207	u8 max_bssid_indicator;
2208	u8 bssid_index;
2209
2210	u8 use_for;
2211	u64 cannot_use_reasons;
2212};
2213
2214enum ieee80211_ap_reg_power
2215cfg80211_get_6ghz_power_type(const u8 *elems, size_t elems_len,
2216			     u32 client_flags)
2217{
2218	const struct ieee80211_he_6ghz_oper *he_6ghz_oper;
2219	struct ieee80211_he_operation *he_oper;
2220	const struct element *tmp;
2221
2222	tmp = cfg80211_find_ext_elem(WLAN_EID_EXT_HE_OPERATION,
2223				     elems, elems_len);
2224	if (!tmp || tmp->datalen < sizeof(*he_oper) + 1 ||
2225	    tmp->datalen < ieee80211_he_oper_size(tmp->data + 1))
2226		return IEEE80211_REG_UNSET_AP;
2227
2228	he_oper = (void *)&tmp->data[1];
2229	he_6ghz_oper = ieee80211_he_6ghz_oper(he_oper);
2230
2231	if (!he_6ghz_oper)
2232		return IEEE80211_REG_UNSET_AP;
2233
2234	return cfg80211_6ghz_power_type(he_6ghz_oper->control, client_flags);
2235}
2236
2237static bool cfg80211_6ghz_power_type_valid(const u8 *elems, size_t elems_len,
2238					   const u32 flags)
2239{
2240	switch (cfg80211_get_6ghz_power_type(elems, elems_len, flags)) {
2241	case IEEE80211_REG_LPI_AP:
2242		return true;
2243	case IEEE80211_REG_SP_AP:
2244		return !(flags & IEEE80211_CHAN_NO_6GHZ_AFC_CLIENT);
2245	case IEEE80211_REG_VLP_AP:
2246		return !(flags & IEEE80211_CHAN_NO_6GHZ_VLP_CLIENT);
2247	default:
2248		return false;
2249	}
2250}
2251
2252/* Returned bss is reference counted and must be cleaned up appropriately. */
2253static struct cfg80211_bss *
2254cfg80211_inform_single_bss_data(struct wiphy *wiphy,
2255				struct cfg80211_inform_single_bss_data *data,
2256				gfp_t gfp)
2257{
2258	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
2259	struct cfg80211_inform_bss *drv_data = data->drv_data;
2260	struct cfg80211_bss_ies *ies;
2261	struct ieee80211_channel *channel;
2262	struct cfg80211_internal_bss tmp = {}, *res;
2263	int bss_type;
2264	bool signal_valid;
2265	unsigned long ts;
2266
2267	if (WARN_ON(!wiphy))
2268		return NULL;
2269
2270	if (WARN_ON(wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
2271		    (drv_data->signal < 0 || drv_data->signal > 100)))
2272		return NULL;
2273
2274	if (WARN_ON(data->bss_source != BSS_SOURCE_DIRECT && !data->source_bss))
2275		return NULL;
2276
2277	channel = data->channel;
2278	if (!channel)
2279		channel = cfg80211_get_bss_channel(wiphy, data->ie, data->ielen,
2280						   drv_data->chan);
2281	if (!channel)
2282		return NULL;
2283
2284	if (channel->band == NL80211_BAND_6GHZ &&
2285	    !cfg80211_6ghz_power_type_valid(data->ie, data->ielen,
2286					    channel->flags)) {
2287		data->use_for = 0;
2288		data->cannot_use_reasons =
2289			NL80211_BSS_CANNOT_USE_6GHZ_PWR_MISMATCH;
2290	}
2291
2292	memcpy(tmp.pub.bssid, data->bssid, ETH_ALEN);
2293	tmp.pub.channel = channel;
2294	if (data->bss_source != BSS_SOURCE_STA_PROFILE)
2295		tmp.pub.signal = drv_data->signal;
2296	else
2297		tmp.pub.signal = 0;
2298	tmp.pub.beacon_interval = data->beacon_interval;
2299	tmp.pub.capability = data->capability;
2300	tmp.pub.ts_boottime = drv_data->boottime_ns;
2301	tmp.parent_tsf = drv_data->parent_tsf;
2302	ether_addr_copy(tmp.parent_bssid, drv_data->parent_bssid);
2303	tmp.pub.chains = drv_data->chains;
2304	memcpy(tmp.pub.chain_signal, drv_data->chain_signal,
2305	       IEEE80211_MAX_CHAINS);
2306	tmp.pub.use_for = data->use_for;
2307	tmp.pub.cannot_use_reasons = data->cannot_use_reasons;
2308	tmp.bss_source = data->bss_source;
2309
2310	switch (data->bss_source) {
2311	case BSS_SOURCE_MBSSID:
2312		tmp.pub.transmitted_bss = data->source_bss;
2313		fallthrough;
2314	case BSS_SOURCE_STA_PROFILE:
2315		ts = bss_from_pub(data->source_bss)->ts;
2316		tmp.pub.bssid_index = data->bssid_index;
2317		tmp.pub.max_bssid_indicator = data->max_bssid_indicator;
2318		break;
2319	case BSS_SOURCE_DIRECT:
2320		ts = jiffies;
2321
2322		if (channel->band == NL80211_BAND_60GHZ) {
2323			bss_type = data->capability &
2324				   WLAN_CAPABILITY_DMG_TYPE_MASK;
2325			if (bss_type == WLAN_CAPABILITY_DMG_TYPE_AP ||
2326			    bss_type == WLAN_CAPABILITY_DMG_TYPE_PBSS)
2327				regulatory_hint_found_beacon(wiphy, channel,
2328							     gfp);
2329		} else {
2330			if (data->capability & WLAN_CAPABILITY_ESS)
2331				regulatory_hint_found_beacon(wiphy, channel,
2332							     gfp);
2333		}
2334		break;
2335	}
2336
2337	/*
2338	 * If we do not know here whether the IEs are from a Beacon or Probe
2339	 * Response frame, we need to pick one of the options and only use it
2340	 * with the driver that does not provide the full Beacon/Probe Response
2341	 * frame. Use Beacon frame pointer to avoid indicating that this should
2342	 * override the IEs pointer should we have received an earlier
2343	 * indication of Probe Response data.
2344	 */
2345	ies = kzalloc(sizeof(*ies) + data->ielen, gfp);
2346	if (!ies)
2347		return NULL;
2348	ies->len = data->ielen;
2349	ies->tsf = data->tsf;
2350	ies->from_beacon = false;
2351	memcpy(ies->data, data->ie, data->ielen);
2352
2353	switch (data->ftype) {
2354	case CFG80211_BSS_FTYPE_BEACON:
2355	case CFG80211_BSS_FTYPE_S1G_BEACON:
2356		ies->from_beacon = true;
2357		fallthrough;
2358	case CFG80211_BSS_FTYPE_UNKNOWN:
2359		rcu_assign_pointer(tmp.pub.beacon_ies, ies);
2360		break;
2361	case CFG80211_BSS_FTYPE_PRESP:
2362		rcu_assign_pointer(tmp.pub.proberesp_ies, ies);
2363		break;
2364	}
2365	rcu_assign_pointer(tmp.pub.ies, ies);
2366
2367	signal_valid = drv_data->chan == channel;
2368	spin_lock_bh(&rdev->bss_lock);
2369	res = __cfg80211_bss_update(rdev, &tmp, signal_valid, ts);
2370	if (!res)
2371		goto drop;
2372
2373	rdev_inform_bss(rdev, &res->pub, ies, drv_data->drv_data);
2374
2375	if (data->bss_source == BSS_SOURCE_MBSSID) {
2376		/* this is a nontransmitting bss, we need to add it to
2377		 * transmitting bss' list if it is not there
2378		 */
2379		if (cfg80211_add_nontrans_list(data->source_bss, &res->pub)) {
2380			if (__cfg80211_unlink_bss(rdev, res)) {
2381				rdev->bss_generation++;
2382				res = NULL;
2383			}
2384		}
2385
2386		if (!res)
2387			goto drop;
2388	}
2389	spin_unlock_bh(&rdev->bss_lock);
2390
2391	trace_cfg80211_return_bss(&res->pub);
2392	/* __cfg80211_bss_update gives us a referenced result */
2393	return &res->pub;
2394
2395drop:
2396	spin_unlock_bh(&rdev->bss_lock);
2397	return NULL;
2398}
2399
2400static const struct element
2401*cfg80211_get_profile_continuation(const u8 *ie, size_t ielen,
2402				   const struct element *mbssid_elem,
2403				   const struct element *sub_elem)
2404{
2405	const u8 *mbssid_end = mbssid_elem->data + mbssid_elem->datalen;
2406	const struct element *next_mbssid;
2407	const struct element *next_sub;
2408
2409	next_mbssid = cfg80211_find_elem(WLAN_EID_MULTIPLE_BSSID,
2410					 mbssid_end,
2411					 ielen - (mbssid_end - ie));
2412
2413	/*
2414	 * If it is not the last subelement in current MBSSID IE or there isn't
2415	 * a next MBSSID IE - profile is complete.
2416	*/
2417	if ((sub_elem->data + sub_elem->datalen < mbssid_end - 1) ||
2418	    !next_mbssid)
2419		return NULL;
2420
2421	/* For any length error, just return NULL */
2422
2423	if (next_mbssid->datalen < 4)
2424		return NULL;
2425
2426	next_sub = (void *)&next_mbssid->data[1];
2427
2428	if (next_mbssid->data + next_mbssid->datalen <
2429	    next_sub->data + next_sub->datalen)
2430		return NULL;
2431
2432	if (next_sub->id != 0 || next_sub->datalen < 2)
2433		return NULL;
2434
2435	/*
2436	 * Check if the first element in the next sub element is a start
2437	 * of a new profile
2438	 */
2439	return next_sub->data[0] == WLAN_EID_NON_TX_BSSID_CAP ?
2440	       NULL : next_mbssid;
2441}
2442
2443size_t cfg80211_merge_profile(const u8 *ie, size_t ielen,
2444			      const struct element *mbssid_elem,
2445			      const struct element *sub_elem,
2446			      u8 *merged_ie, size_t max_copy_len)
2447{
2448	size_t copied_len = sub_elem->datalen;
2449	const struct element *next_mbssid;
2450
2451	if (sub_elem->datalen > max_copy_len)
2452		return 0;
2453
2454	memcpy(merged_ie, sub_elem->data, sub_elem->datalen);
2455
2456	while ((next_mbssid = cfg80211_get_profile_continuation(ie, ielen,
2457								mbssid_elem,
2458								sub_elem))) {
2459		const struct element *next_sub = (void *)&next_mbssid->data[1];
2460
2461		if (copied_len + next_sub->datalen > max_copy_len)
2462			break;
2463		memcpy(merged_ie + copied_len, next_sub->data,
2464		       next_sub->datalen);
2465		copied_len += next_sub->datalen;
2466	}
2467
2468	return copied_len;
2469}
2470EXPORT_SYMBOL(cfg80211_merge_profile);
2471
2472static void
2473cfg80211_parse_mbssid_data(struct wiphy *wiphy,
2474			   struct cfg80211_inform_single_bss_data *tx_data,
2475			   struct cfg80211_bss *source_bss,
2476			   gfp_t gfp)
2477{
2478	struct cfg80211_inform_single_bss_data data = {
2479		.drv_data = tx_data->drv_data,
2480		.ftype = tx_data->ftype,
2481		.tsf = tx_data->tsf,
2482		.beacon_interval = tx_data->beacon_interval,
2483		.source_bss = source_bss,
2484		.bss_source = BSS_SOURCE_MBSSID,
2485		.use_for = tx_data->use_for,
2486		.cannot_use_reasons = tx_data->cannot_use_reasons,
2487	};
2488	const u8 *mbssid_index_ie;
2489	const struct element *elem, *sub;
2490	u8 *new_ie, *profile;
2491	u64 seen_indices = 0;
2492	struct cfg80211_bss *bss;
2493
2494	if (!source_bss)
2495		return;
2496	if (!cfg80211_find_elem(WLAN_EID_MULTIPLE_BSSID,
2497				tx_data->ie, tx_data->ielen))
2498		return;
2499	if (!wiphy->support_mbssid)
2500		return;
2501	if (wiphy->support_only_he_mbssid &&
2502	    !cfg80211_find_ext_elem(WLAN_EID_EXT_HE_CAPABILITY,
2503				    tx_data->ie, tx_data->ielen))
2504		return;
2505
2506	new_ie = kmalloc(IEEE80211_MAX_DATA_LEN, gfp);
2507	if (!new_ie)
2508		return;
2509
2510	profile = kmalloc(tx_data->ielen, gfp);
2511	if (!profile)
2512		goto out;
2513
2514	for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID,
2515			    tx_data->ie, tx_data->ielen) {
2516		if (elem->datalen < 4)
2517			continue;
2518		if (elem->data[0] < 1 || (int)elem->data[0] > 8)
2519			continue;
2520		for_each_element(sub, elem->data + 1, elem->datalen - 1) {
2521			u8 profile_len;
2522
2523			if (sub->id != 0 || sub->datalen < 4) {
2524				/* not a valid BSS profile */
2525				continue;
2526			}
2527
2528			if (sub->data[0] != WLAN_EID_NON_TX_BSSID_CAP ||
2529			    sub->data[1] != 2) {
2530				/* The first element within the Nontransmitted
2531				 * BSSID Profile is not the Nontransmitted
2532				 * BSSID Capability element.
2533				 */
2534				continue;
2535			}
2536
2537			memset(profile, 0, tx_data->ielen);
2538			profile_len = cfg80211_merge_profile(tx_data->ie,
2539							     tx_data->ielen,
2540							     elem,
2541							     sub,
2542							     profile,
2543							     tx_data->ielen);
2544
2545			/* found a Nontransmitted BSSID Profile */
2546			mbssid_index_ie = cfg80211_find_ie
2547				(WLAN_EID_MULTI_BSSID_IDX,
2548				 profile, profile_len);
2549			if (!mbssid_index_ie || mbssid_index_ie[1] < 1 ||
2550			    mbssid_index_ie[2] == 0 ||
2551			    mbssid_index_ie[2] > 46 ||
2552			    mbssid_index_ie[2] >= (1 << elem->data[0])) {
2553				/* No valid Multiple BSSID-Index element */
2554				continue;
2555			}
2556
2557			if (seen_indices & BIT_ULL(mbssid_index_ie[2]))
2558				/* We don't support legacy split of a profile */
2559				net_dbg_ratelimited("Partial info for BSSID index %d\n",
2560						    mbssid_index_ie[2]);
2561
2562			seen_indices |= BIT_ULL(mbssid_index_ie[2]);
2563
2564			data.bssid_index = mbssid_index_ie[2];
2565			data.max_bssid_indicator = elem->data[0];
2566
2567			cfg80211_gen_new_bssid(tx_data->bssid,
2568					       data.max_bssid_indicator,
2569					       data.bssid_index,
2570					       data.bssid);
2571
2572			memset(new_ie, 0, IEEE80211_MAX_DATA_LEN);
2573			data.ie = new_ie;
2574			data.ielen = cfg80211_gen_new_ie(tx_data->ie,
2575							 tx_data->ielen,
2576							 profile,
2577							 profile_len,
2578							 new_ie,
2579							 IEEE80211_MAX_DATA_LEN);
2580			if (!data.ielen)
2581				continue;
2582
2583			data.capability = get_unaligned_le16(profile + 2);
2584			bss = cfg80211_inform_single_bss_data(wiphy, &data, gfp);
2585			if (!bss)
2586				break;
2587			cfg80211_put_bss(wiphy, bss);
2588		}
2589	}
2590
2591out:
2592	kfree(new_ie);
2593	kfree(profile);
2594}
2595
2596ssize_t cfg80211_defragment_element(const struct element *elem, const u8 *ies,
2597				    size_t ieslen, u8 *data, size_t data_len,
2598				    u8 frag_id)
2599{
2600	const struct element *next;
2601	ssize_t copied;
2602	u8 elem_datalen;
2603
2604	if (!elem)
2605		return -EINVAL;
2606
2607	/* elem might be invalid after the memmove */
2608	next = (void *)(elem->data + elem->datalen);
2609	elem_datalen = elem->datalen;
2610
2611	if (elem->id == WLAN_EID_EXTENSION) {
2612		copied = elem->datalen - 1;
2613
2614		if (data) {
2615			if (copied > data_len)
2616				return -ENOSPC;
2617
2618			memmove(data, elem->data + 1, copied);
2619		}
2620	} else {
2621		copied = elem->datalen;
2622
2623		if (data) {
2624			if (copied > data_len)
2625				return -ENOSPC;
2626
2627			memmove(data, elem->data, copied);
2628		}
2629	}
2630
2631	/* Fragmented elements must have 255 bytes */
2632	if (elem_datalen < 255)
2633		return copied;
2634
2635	for (elem = next;
2636	     elem->data < ies + ieslen &&
2637		elem->data + elem->datalen <= ies + ieslen;
2638	     elem = next) {
2639		/* elem might be invalid after the memmove */
2640		next = (void *)(elem->data + elem->datalen);
2641
2642		if (elem->id != frag_id)
2643			break;
2644
2645		elem_datalen = elem->datalen;
2646
2647		if (data) {
2648			if (copied + elem_datalen > data_len)
2649				return -ENOSPC;
2650
2651			memmove(data + copied, elem->data, elem_datalen);
2652		}
2653
2654		copied += elem_datalen;
2655
2656		/* Only the last fragment may be short */
2657		if (elem_datalen != 255)
2658			break;
2659	}
2660
2661	return copied;
2662}
2663EXPORT_SYMBOL(cfg80211_defragment_element);
2664
2665struct cfg80211_mle {
2666	struct ieee80211_multi_link_elem *mle;
2667	struct ieee80211_mle_per_sta_profile
2668		*sta_prof[IEEE80211_MLD_MAX_NUM_LINKS];
2669	ssize_t sta_prof_len[IEEE80211_MLD_MAX_NUM_LINKS];
2670
2671	u8 data[];
2672};
2673
2674static struct cfg80211_mle *
2675cfg80211_defrag_mle(const struct element *mle, const u8 *ie, size_t ielen,
2676		    gfp_t gfp)
2677{
2678	const struct element *elem;
2679	struct cfg80211_mle *res;
2680	size_t buf_len;
2681	ssize_t mle_len;
2682	u8 common_size, idx;
2683
2684	if (!mle || !ieee80211_mle_size_ok(mle->data + 1, mle->datalen - 1))
2685		return NULL;
2686
2687	/* Required length for first defragmentation */
2688	buf_len = mle->datalen - 1;
2689	for_each_element(elem, mle->data + mle->datalen,
2690			 ie + ielen - mle->data - mle->datalen) {
2691		if (elem->id != WLAN_EID_FRAGMENT)
2692			break;
2693
2694		buf_len += elem->datalen;
2695	}
2696
2697	res = kzalloc(struct_size(res, data, buf_len), gfp);
2698	if (!res)
2699		return NULL;
2700
2701	mle_len = cfg80211_defragment_element(mle, ie, ielen,
2702					      res->data, buf_len,
2703					      WLAN_EID_FRAGMENT);
2704	if (mle_len < 0)
2705		goto error;
2706
2707	res->mle = (void *)res->data;
2708
2709	/* Find the sub-element area in the buffer */
2710	common_size = ieee80211_mle_common_size((u8 *)res->mle);
2711	ie = res->data + common_size;
2712	ielen = mle_len - common_size;
2713
2714	idx = 0;
2715	for_each_element_id(elem, IEEE80211_MLE_SUBELEM_PER_STA_PROFILE,
2716			    ie, ielen) {
2717		res->sta_prof[idx] = (void *)elem->data;
2718		res->sta_prof_len[idx] = elem->datalen;
2719
2720		idx++;
2721		if (idx >= IEEE80211_MLD_MAX_NUM_LINKS)
2722			break;
2723	}
2724	if (!for_each_element_completed(elem, ie, ielen))
2725		goto error;
2726
2727	/* Defragment sta_info in-place */
2728	for (idx = 0; idx < IEEE80211_MLD_MAX_NUM_LINKS && res->sta_prof[idx];
2729	     idx++) {
2730		if (res->sta_prof_len[idx] < 255)
2731			continue;
2732
2733		elem = (void *)res->sta_prof[idx] - 2;
2734
2735		if (idx + 1 < ARRAY_SIZE(res->sta_prof) &&
2736		    res->sta_prof[idx + 1])
2737			buf_len = (u8 *)res->sta_prof[idx + 1] -
2738				  (u8 *)res->sta_prof[idx];
2739		else
2740			buf_len = ielen + ie - (u8 *)elem;
2741
2742		res->sta_prof_len[idx] =
2743			cfg80211_defragment_element(elem,
2744						    (u8 *)elem, buf_len,
2745						    (u8 *)res->sta_prof[idx],
2746						    buf_len,
2747						    IEEE80211_MLE_SUBELEM_FRAGMENT);
2748		if (res->sta_prof_len[idx] < 0)
2749			goto error;
2750	}
2751
2752	return res;
2753
2754error:
2755	kfree(res);
2756	return NULL;
2757}
2758
2759struct tbtt_info_iter_data {
2760	const struct ieee80211_neighbor_ap_info *ap_info;
2761	u8 param_ch_count;
2762	u32 use_for;
2763	u8 mld_id, link_id;
2764	bool non_tx;
2765};
2766
2767static enum cfg80211_rnr_iter_ret
2768cfg802121_mld_ap_rnr_iter(void *_data, u8 type,
2769			  const struct ieee80211_neighbor_ap_info *info,
2770			  const u8 *tbtt_info, u8 tbtt_info_len)
2771{
2772	const struct ieee80211_rnr_mld_params *mld_params;
2773	struct tbtt_info_iter_data *data = _data;
2774	u8 link_id;
2775	bool non_tx = false;
2776
2777	if (type == IEEE80211_TBTT_INFO_TYPE_TBTT &&
2778	    tbtt_info_len >= offsetofend(struct ieee80211_tbtt_info_ge_11,
2779					 mld_params)) {
2780		const struct ieee80211_tbtt_info_ge_11 *tbtt_info_ge_11 =
2781			(void *)tbtt_info;
2782
2783		non_tx = (tbtt_info_ge_11->bss_params &
2784			  (IEEE80211_RNR_TBTT_PARAMS_MULTI_BSSID |
2785			   IEEE80211_RNR_TBTT_PARAMS_TRANSMITTED_BSSID)) ==
2786			 IEEE80211_RNR_TBTT_PARAMS_MULTI_BSSID;
2787		mld_params = &tbtt_info_ge_11->mld_params;
2788	} else if (type == IEEE80211_TBTT_INFO_TYPE_MLD &&
2789		 tbtt_info_len >= sizeof(struct ieee80211_rnr_mld_params))
2790		mld_params = (void *)tbtt_info;
2791	else
2792		return RNR_ITER_CONTINUE;
2793
2794	link_id = le16_get_bits(mld_params->params,
2795				IEEE80211_RNR_MLD_PARAMS_LINK_ID);
2796
2797	if (data->mld_id != mld_params->mld_id)
2798		return RNR_ITER_CONTINUE;
2799
2800	if (data->link_id != link_id)
2801		return RNR_ITER_CONTINUE;
2802
2803	data->ap_info = info;
2804	data->param_ch_count =
2805		le16_get_bits(mld_params->params,
2806			      IEEE80211_RNR_MLD_PARAMS_BSS_CHANGE_COUNT);
2807	data->non_tx = non_tx;
2808
2809	if (type == IEEE80211_TBTT_INFO_TYPE_TBTT)
2810		data->use_for = NL80211_BSS_USE_FOR_ALL;
2811	else
2812		data->use_for = NL80211_BSS_USE_FOR_MLD_LINK;
2813	return RNR_ITER_BREAK;
2814}
2815
2816static u8
2817cfg80211_rnr_info_for_mld_ap(const u8 *ie, size_t ielen, u8 mld_id, u8 link_id,
2818			     const struct ieee80211_neighbor_ap_info **ap_info,
2819			     u8 *param_ch_count, bool *non_tx)
2820{
2821	struct tbtt_info_iter_data data = {
2822		.mld_id = mld_id,
2823		.link_id = link_id,
2824	};
2825
2826	cfg80211_iter_rnr(ie, ielen, cfg802121_mld_ap_rnr_iter, &data);
2827
2828	*ap_info = data.ap_info;
2829	*param_ch_count = data.param_ch_count;
2830	*non_tx = data.non_tx;
2831
2832	return data.use_for;
2833}
2834
2835static struct element *
2836cfg80211_gen_reporter_rnr(struct cfg80211_bss *source_bss, bool is_mbssid,
2837			  bool same_mld, u8 link_id, u8 bss_change_count,
2838			  gfp_t gfp)
2839{
2840	const struct cfg80211_bss_ies *ies;
2841	struct ieee80211_neighbor_ap_info ap_info;
2842	struct ieee80211_tbtt_info_ge_11 tbtt_info;
2843	u32 short_ssid;
2844	const struct element *elem;
2845	struct element *res;
2846
2847	/*
2848	 * We only generate the RNR to permit ML lookups. For that we do not
2849	 * need an entry for the corresponding transmitting BSS, lets just skip
2850	 * it even though it would be easy to add.
2851	 */
2852	if (!same_mld)
2853		return NULL;
2854
2855	/* We could use tx_data->ies if we change cfg80211_calc_short_ssid */
2856	rcu_read_lock();
2857	ies = rcu_dereference(source_bss->ies);
2858
2859	ap_info.tbtt_info_len = offsetofend(typeof(tbtt_info), mld_params);
2860	ap_info.tbtt_info_hdr =
2861			u8_encode_bits(IEEE80211_TBTT_INFO_TYPE_TBTT,
2862				       IEEE80211_AP_INFO_TBTT_HDR_TYPE) |
2863			u8_encode_bits(0, IEEE80211_AP_INFO_TBTT_HDR_COUNT);
2864
2865	ap_info.channel = ieee80211_frequency_to_channel(source_bss->channel->center_freq);
2866
2867	/* operating class */
2868	elem = cfg80211_find_elem(WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
2869				  ies->data, ies->len);
2870	if (elem && elem->datalen >= 1) {
2871		ap_info.op_class = elem->data[0];
2872	} else {
2873		struct cfg80211_chan_def chandef;
2874
2875		/* The AP is not providing us with anything to work with. So
2876		 * make up a somewhat reasonable operating class, but don't
2877		 * bother with it too much as no one will ever use the
2878		 * information.
2879		 */
2880		cfg80211_chandef_create(&chandef, source_bss->channel,
2881					NL80211_CHAN_NO_HT);
2882
2883		if (!ieee80211_chandef_to_operating_class(&chandef,
2884							  &ap_info.op_class))
2885			goto out_unlock;
2886	}
2887
2888	/* Just set TBTT offset and PSD 20 to invalid/unknown */
2889	tbtt_info.tbtt_offset = 255;
2890	tbtt_info.psd_20 = IEEE80211_RNR_TBTT_PARAMS_PSD_RESERVED;
2891
2892	memcpy(tbtt_info.bssid, source_bss->bssid, ETH_ALEN);
2893	if (cfg80211_calc_short_ssid(ies, &elem, &short_ssid))
2894		goto out_unlock;
2895
2896	rcu_read_unlock();
2897
2898	tbtt_info.short_ssid = cpu_to_le32(short_ssid);
2899
2900	tbtt_info.bss_params = IEEE80211_RNR_TBTT_PARAMS_SAME_SSID;
2901
2902	if (is_mbssid) {
2903		tbtt_info.bss_params |= IEEE80211_RNR_TBTT_PARAMS_MULTI_BSSID;
2904		tbtt_info.bss_params |= IEEE80211_RNR_TBTT_PARAMS_TRANSMITTED_BSSID;
2905	}
2906
2907	tbtt_info.mld_params.mld_id = 0;
2908	tbtt_info.mld_params.params =
2909		le16_encode_bits(link_id, IEEE80211_RNR_MLD_PARAMS_LINK_ID) |
2910		le16_encode_bits(bss_change_count,
2911				 IEEE80211_RNR_MLD_PARAMS_BSS_CHANGE_COUNT);
2912
2913	res = kzalloc(struct_size(res, data,
2914				  sizeof(ap_info) + ap_info.tbtt_info_len),
2915		      gfp);
2916	if (!res)
2917		return NULL;
2918
2919	/* Copy the data */
2920	res->id = WLAN_EID_REDUCED_NEIGHBOR_REPORT;
2921	res->datalen = sizeof(ap_info) + ap_info.tbtt_info_len;
2922	memcpy(res->data, &ap_info, sizeof(ap_info));
2923	memcpy(res->data + sizeof(ap_info), &tbtt_info, ap_info.tbtt_info_len);
2924
2925	return res;
2926
2927out_unlock:
2928	rcu_read_unlock();
2929	return NULL;
2930}
2931
2932static void
2933cfg80211_parse_ml_elem_sta_data(struct wiphy *wiphy,
2934				struct cfg80211_inform_single_bss_data *tx_data,
2935				struct cfg80211_bss *source_bss,
2936				const struct element *elem,
2937				gfp_t gfp)
2938{
2939	struct cfg80211_inform_single_bss_data data = {
2940		.drv_data = tx_data->drv_data,
2941		.ftype = tx_data->ftype,
2942		.source_bss = source_bss,
2943		.bss_source = BSS_SOURCE_STA_PROFILE,
2944	};
2945	struct element *reporter_rnr = NULL;
2946	struct ieee80211_multi_link_elem *ml_elem;
2947	struct cfg80211_mle *mle;
2948	const struct element *ssid_elem;
2949	const u8 *ssid = NULL;
2950	size_t ssid_len = 0;
2951	u16 control;
2952	u8 ml_common_len;
2953	u8 *new_ie = NULL;
2954	struct cfg80211_bss *bss;
2955	u8 mld_id, reporter_link_id, bss_change_count;
2956	u16 seen_links = 0;
2957	u8 i;
2958
2959	if (!ieee80211_mle_type_ok(elem->data + 1,
2960				   IEEE80211_ML_CONTROL_TYPE_BASIC,
2961				   elem->datalen - 1))
2962		return;
2963
2964	ml_elem = (void *)(elem->data + 1);
2965	control = le16_to_cpu(ml_elem->control);
2966	ml_common_len = ml_elem->variable[0];
2967
2968	/* Must be present when transmitted by an AP (in a probe response) */
2969	if (!(control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT) ||
2970	    !(control & IEEE80211_MLC_BASIC_PRES_LINK_ID) ||
2971	    !(control & IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP))
2972		return;
2973
2974	reporter_link_id = ieee80211_mle_get_link_id(elem->data + 1);
2975	bss_change_count = ieee80211_mle_get_bss_param_ch_cnt(elem->data + 1);
2976
2977	/*
2978	 * The MLD ID of the reporting AP is always zero. It is set if the AP
2979	 * is part of an MBSSID set and will be non-zero for ML Elements
2980	 * relating to a nontransmitted BSS (matching the Multi-BSSID Index,
2981	 * Draft P802.11be_D3.2, 35.3.4.2)
2982	 */
2983	mld_id = ieee80211_mle_get_mld_id(elem->data + 1);
2984
2985	/* Fully defrag the ML element for sta information/profile iteration */
2986	mle = cfg80211_defrag_mle(elem, tx_data->ie, tx_data->ielen, gfp);
2987	if (!mle)
2988		return;
2989
2990	/* No point in doing anything if there is no per-STA profile */
2991	if (!mle->sta_prof[0])
2992		goto out;
2993
2994	new_ie = kmalloc(IEEE80211_MAX_DATA_LEN, gfp);
2995	if (!new_ie)
2996		goto out;
2997
2998	reporter_rnr = cfg80211_gen_reporter_rnr(source_bss,
2999						 u16_get_bits(control,
3000							      IEEE80211_MLC_BASIC_PRES_MLD_ID),
3001						 mld_id == 0, reporter_link_id,
3002						 bss_change_count,
3003						 gfp);
3004
3005	ssid_elem = cfg80211_find_elem(WLAN_EID_SSID, tx_data->ie,
3006				       tx_data->ielen);
3007	if (ssid_elem) {
3008		ssid = ssid_elem->data;
3009		ssid_len = ssid_elem->datalen;
3010	}
3011
3012	for (i = 0; i < ARRAY_SIZE(mle->sta_prof) && mle->sta_prof[i]; i++) {
3013		const struct ieee80211_neighbor_ap_info *ap_info;
3014		enum nl80211_band band;
3015		u32 freq;
3016		const u8 *profile;
3017		ssize_t profile_len;
3018		u8 param_ch_count;
3019		u8 link_id, use_for;
3020		bool non_tx;
3021
3022		if (!ieee80211_mle_basic_sta_prof_size_ok((u8 *)mle->sta_prof[i],
3023							  mle->sta_prof_len[i]))
3024			continue;
3025
3026		control = le16_to_cpu(mle->sta_prof[i]->control);
3027
3028		if (!(control & IEEE80211_MLE_STA_CONTROL_COMPLETE_PROFILE))
3029			continue;
3030
3031		link_id = u16_get_bits(control,
3032				       IEEE80211_MLE_STA_CONTROL_LINK_ID);
3033		if (seen_links & BIT(link_id))
3034			break;
3035		seen_links |= BIT(link_id);
3036
3037		if (!(control & IEEE80211_MLE_STA_CONTROL_BEACON_INT_PRESENT) ||
3038		    !(control & IEEE80211_MLE_STA_CONTROL_TSF_OFFS_PRESENT) ||
3039		    !(control & IEEE80211_MLE_STA_CONTROL_STA_MAC_ADDR_PRESENT))
3040			continue;
3041
3042		memcpy(data.bssid, mle->sta_prof[i]->variable, ETH_ALEN);
3043		data.beacon_interval =
3044			get_unaligned_le16(mle->sta_prof[i]->variable + 6);
3045		data.tsf = tx_data->tsf +
3046			   get_unaligned_le64(mle->sta_prof[i]->variable + 8);
3047
3048		/* sta_info_len counts itself */
3049		profile = mle->sta_prof[i]->variable +
3050			  mle->sta_prof[i]->sta_info_len - 1;
3051		profile_len = (u8 *)mle->sta_prof[i] + mle->sta_prof_len[i] -
3052			      profile;
3053
3054		if (profile_len < 2)
3055			continue;
3056
3057		data.capability = get_unaligned_le16(profile);
3058		profile += 2;
3059		profile_len -= 2;
3060
3061		/* Find in RNR to look up channel information */
3062		use_for = cfg80211_rnr_info_for_mld_ap(tx_data->ie,
3063						       tx_data->ielen,
3064						       mld_id, link_id,
3065						       &ap_info,
3066						       &param_ch_count,
3067						       &non_tx);
3068		if (!use_for)
3069			continue;
3070
3071		/*
3072		 * As of 802.11be_D5.0, the specification does not give us any
3073		 * way of discovering both the MaxBSSID and the Multiple-BSSID
3074		 * Index. It does seem like the Multiple-BSSID Index element
3075		 * may be provided, but section 9.4.2.45 explicitly forbids
3076		 * including a Multiple-BSSID Element (in this case without any
3077		 * subelements).
3078		 * Without both pieces of information we cannot calculate the
3079		 * reference BSSID, so simply ignore the BSS.
3080		 */
3081		if (non_tx)
3082			continue;
3083
3084		/* We could sanity check the BSSID is included */
3085
3086		if (!ieee80211_operating_class_to_band(ap_info->op_class,
3087						       &band))
3088			continue;
3089
3090		freq = ieee80211_channel_to_freq_khz(ap_info->channel, band);
3091		data.channel = ieee80211_get_channel_khz(wiphy, freq);
3092
3093		/* Skip if RNR element specifies an unsupported channel */
3094		if (!data.channel)
3095			continue;
3096
3097		/* Skip if BSS entry generated from MBSSID or DIRECT source
3098		 * frame data available already.
3099		 */
3100		bss = cfg80211_get_bss(wiphy, data.channel, data.bssid, ssid,
3101				       ssid_len, IEEE80211_BSS_TYPE_ANY,
3102				       IEEE80211_PRIVACY_ANY);
3103		if (bss) {
3104			struct cfg80211_internal_bss *ibss = bss_from_pub(bss);
3105
3106			if (data.capability == bss->capability &&
3107			    ibss->bss_source != BSS_SOURCE_STA_PROFILE) {
3108				cfg80211_put_bss(wiphy, bss);
3109				continue;
3110			}
3111			cfg80211_put_bss(wiphy, bss);
3112		}
3113
3114		if (use_for == NL80211_BSS_USE_FOR_MLD_LINK &&
3115		    !(wiphy->flags & WIPHY_FLAG_SUPPORTS_NSTR_NONPRIMARY)) {
3116			use_for = 0;
3117			data.cannot_use_reasons =
3118				NL80211_BSS_CANNOT_USE_NSTR_NONPRIMARY;
3119		}
3120		data.use_for = use_for;
3121
3122		/* Generate new elements */
3123		memset(new_ie, 0, IEEE80211_MAX_DATA_LEN);
3124		data.ie = new_ie;
3125		data.ielen = cfg80211_gen_new_ie(tx_data->ie, tx_data->ielen,
3126						 profile, profile_len,
3127						 new_ie,
3128						 IEEE80211_MAX_DATA_LEN);
3129		if (!data.ielen)
3130			continue;
3131
3132		/* The generated elements do not contain:
3133		 *  - Basic ML element
3134		 *  - A TBTT entry in the RNR for the transmitting AP
3135		 *
3136		 * This information is needed both internally and in userspace
3137		 * as such, we should append it here.
3138		 */
3139		if (data.ielen + 3 + sizeof(*ml_elem) + ml_common_len >
3140		    IEEE80211_MAX_DATA_LEN)
3141			continue;
3142
3143		/* Copy the Basic Multi-Link element including the common
3144		 * information, and then fix up the link ID and BSS param
3145		 * change count.
3146		 * Note that the ML element length has been verified and we
3147		 * also checked that it contains the link ID.
3148		 */
3149		new_ie[data.ielen++] = WLAN_EID_EXTENSION;
3150		new_ie[data.ielen++] = 1 + sizeof(*ml_elem) + ml_common_len;
3151		new_ie[data.ielen++] = WLAN_EID_EXT_EHT_MULTI_LINK;
3152		memcpy(new_ie + data.ielen, ml_elem,
3153		       sizeof(*ml_elem) + ml_common_len);
3154
3155		new_ie[data.ielen + sizeof(*ml_elem) + 1 + ETH_ALEN] = link_id;
3156		new_ie[data.ielen + sizeof(*ml_elem) + 1 + ETH_ALEN + 1] =
3157			param_ch_count;
3158
3159		data.ielen += sizeof(*ml_elem) + ml_common_len;
3160
3161		if (reporter_rnr && (use_for & NL80211_BSS_USE_FOR_NORMAL)) {
3162			if (data.ielen + sizeof(struct element) +
3163			    reporter_rnr->datalen > IEEE80211_MAX_DATA_LEN)
3164				continue;
3165
3166			memcpy(new_ie + data.ielen, reporter_rnr,
3167			       sizeof(struct element) + reporter_rnr->datalen);
3168			data.ielen += sizeof(struct element) +
3169				      reporter_rnr->datalen;
3170		}
3171
3172		bss = cfg80211_inform_single_bss_data(wiphy, &data, gfp);
3173		if (!bss)
3174			break;
3175		cfg80211_put_bss(wiphy, bss);
3176	}
3177
3178out:
3179	kfree(reporter_rnr);
3180	kfree(new_ie);
3181	kfree(mle);
3182}
3183
3184static void cfg80211_parse_ml_sta_data(struct wiphy *wiphy,
3185				       struct cfg80211_inform_single_bss_data *tx_data,
3186				       struct cfg80211_bss *source_bss,
3187				       gfp_t gfp)
3188{
3189	const struct element *elem;
3190
3191	if (!source_bss)
3192		return;
3193
3194	if (tx_data->ftype != CFG80211_BSS_FTYPE_PRESP)
3195		return;
3196
3197	for_each_element_extid(elem, WLAN_EID_EXT_EHT_MULTI_LINK,
3198			       tx_data->ie, tx_data->ielen)
3199		cfg80211_parse_ml_elem_sta_data(wiphy, tx_data, source_bss,
3200						elem, gfp);
3201}
3202
3203struct cfg80211_bss *
3204cfg80211_inform_bss_data(struct wiphy *wiphy,
3205			 struct cfg80211_inform_bss *data,
3206			 enum cfg80211_bss_frame_type ftype,
3207			 const u8 *bssid, u64 tsf, u16 capability,
3208			 u16 beacon_interval, const u8 *ie, size_t ielen,
3209			 gfp_t gfp)
3210{
3211	struct cfg80211_inform_single_bss_data inform_data = {
3212		.drv_data = data,
3213		.ftype = ftype,
3214		.tsf = tsf,
3215		.capability = capability,
3216		.beacon_interval = beacon_interval,
3217		.ie = ie,
3218		.ielen = ielen,
3219		.use_for = data->restrict_use ?
3220				data->use_for :
3221				NL80211_BSS_USE_FOR_ALL,
3222		.cannot_use_reasons = data->cannot_use_reasons,
3223	};
3224	struct cfg80211_bss *res;
3225
3226	memcpy(inform_data.bssid, bssid, ETH_ALEN);
3227
3228	res = cfg80211_inform_single_bss_data(wiphy, &inform_data, gfp);
3229	if (!res)
3230		return NULL;
3231
3232	/* don't do any further MBSSID/ML handling for S1G */
3233	if (ftype == CFG80211_BSS_FTYPE_S1G_BEACON)
3234		return res;
3235
3236	cfg80211_parse_mbssid_data(wiphy, &inform_data, res, gfp);
3237
3238	cfg80211_parse_ml_sta_data(wiphy, &inform_data, res, gfp);
3239
3240	return res;
3241}
3242EXPORT_SYMBOL(cfg80211_inform_bss_data);
3243
3244struct cfg80211_bss *
3245cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
3246			       struct cfg80211_inform_bss *data,
3247			       struct ieee80211_mgmt *mgmt, size_t len,
3248			       gfp_t gfp)
3249{
3250	size_t min_hdr_len;
3251	struct ieee80211_ext *ext = NULL;
3252	enum cfg80211_bss_frame_type ftype;
3253	u16 beacon_interval;
3254	const u8 *bssid;
3255	u16 capability;
3256	const u8 *ie;
3257	size_t ielen;
3258	u64 tsf;
3259	size_t s1g_optional_len;
3260
3261	if (WARN_ON(!mgmt))
3262		return NULL;
3263
3264	if (WARN_ON(!wiphy))
3265		return NULL;
3266
3267	BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) !=
3268		     offsetof(struct ieee80211_mgmt, u.beacon.variable));
3269
3270	trace_cfg80211_inform_bss_frame(wiphy, data, mgmt, len);
3271
3272	if (ieee80211_is_s1g_beacon(mgmt->frame_control)) {
3273		ext = (void *) mgmt;
3274		s1g_optional_len =
3275			ieee80211_s1g_optional_len(ext->frame_control);
3276		min_hdr_len =
3277			offsetof(struct ieee80211_ext, u.s1g_beacon.variable) +
3278			s1g_optional_len;
3279	} else {
3280		/* same for beacons */
3281		min_hdr_len = offsetof(struct ieee80211_mgmt,
3282				       u.probe_resp.variable);
3283	}
3284
3285	if (WARN_ON(len < min_hdr_len))
3286		return NULL;
3287
3288	ielen = len - min_hdr_len;
3289	ie = mgmt->u.probe_resp.variable;
3290	if (ext) {
3291		const struct ieee80211_s1g_bcn_compat_ie *compat;
3292		const struct element *elem;
3293
3294		ie = ext->u.s1g_beacon.variable + s1g_optional_len;
3295		elem = cfg80211_find_elem(WLAN_EID_S1G_BCN_COMPAT, ie, ielen);
3296		if (!elem)
3297			return NULL;
3298		if (elem->datalen < sizeof(*compat))
3299			return NULL;
3300		compat = (void *)elem->data;
3301		bssid = ext->u.s1g_beacon.sa;
3302		capability = le16_to_cpu(compat->compat_info);
3303		beacon_interval = le16_to_cpu(compat->beacon_int);
3304	} else {
3305		bssid = mgmt->bssid;
3306		beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
3307		capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
3308	}
3309
3310	tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
3311
3312	if (ieee80211_is_probe_resp(mgmt->frame_control))
3313		ftype = CFG80211_BSS_FTYPE_PRESP;
3314	else if (ext)
3315		ftype = CFG80211_BSS_FTYPE_S1G_BEACON;
3316	else
3317		ftype = CFG80211_BSS_FTYPE_BEACON;
3318
3319	return cfg80211_inform_bss_data(wiphy, data, ftype,
3320					bssid, tsf, capability,
3321					beacon_interval, ie, ielen,
3322					gfp);
3323}
3324EXPORT_SYMBOL(cfg80211_inform_bss_frame_data);
3325
3326void cfg80211_ref_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
3327{
3328	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
3329
3330	if (!pub)
3331		return;
3332
3333	spin_lock_bh(&rdev->bss_lock);
3334	bss_ref_get(rdev, bss_from_pub(pub));
3335	spin_unlock_bh(&rdev->bss_lock);
3336}
3337EXPORT_SYMBOL(cfg80211_ref_bss);
3338
3339void cfg80211_put_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
3340{
3341	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
3342
3343	if (!pub)
3344		return;
3345
3346	spin_lock_bh(&rdev->bss_lock);
3347	bss_ref_put(rdev, bss_from_pub(pub));
3348	spin_unlock_bh(&rdev->bss_lock);
3349}
3350EXPORT_SYMBOL(cfg80211_put_bss);
3351
3352void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
3353{
3354	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
3355	struct cfg80211_internal_bss *bss, *tmp1;
3356	struct cfg80211_bss *nontrans_bss, *tmp;
3357
3358	if (WARN_ON(!pub))
3359		return;
3360
3361	bss = bss_from_pub(pub);
3362
3363	spin_lock_bh(&rdev->bss_lock);
3364	if (list_empty(&bss->list))
3365		goto out;
3366
3367	list_for_each_entry_safe(nontrans_bss, tmp,
3368				 &pub->nontrans_list,
3369				 nontrans_list) {
3370		tmp1 = bss_from_pub(nontrans_bss);
3371		if (__cfg80211_unlink_bss(rdev, tmp1))
3372			rdev->bss_generation++;
3373	}
3374
3375	if (__cfg80211_unlink_bss(rdev, bss))
3376		rdev->bss_generation++;
3377out:
3378	spin_unlock_bh(&rdev->bss_lock);
3379}
3380EXPORT_SYMBOL(cfg80211_unlink_bss);
3381
3382void cfg80211_bss_iter(struct wiphy *wiphy,
3383		       struct cfg80211_chan_def *chandef,
3384		       void (*iter)(struct wiphy *wiphy,
3385				    struct cfg80211_bss *bss,
3386				    void *data),
3387		       void *iter_data)
3388{
3389	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
3390	struct cfg80211_internal_bss *bss;
3391
3392	spin_lock_bh(&rdev->bss_lock);
3393
3394	list_for_each_entry(bss, &rdev->bss_list, list) {
3395		if (!chandef || cfg80211_is_sub_chan(chandef, bss->pub.channel,
3396						     false))
3397			iter(wiphy, &bss->pub, iter_data);
3398	}
3399
3400	spin_unlock_bh(&rdev->bss_lock);
3401}
3402EXPORT_SYMBOL(cfg80211_bss_iter);
3403
3404void cfg80211_update_assoc_bss_entry(struct wireless_dev *wdev,
3405				     unsigned int link_id,
3406				     struct ieee80211_channel *chan)
3407{
3408	struct wiphy *wiphy = wdev->wiphy;
3409	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
3410	struct cfg80211_internal_bss *cbss = wdev->links[link_id].client.current_bss;
3411	struct cfg80211_internal_bss *new = NULL;
3412	struct cfg80211_internal_bss *bss;
3413	struct cfg80211_bss *nontrans_bss;
3414	struct cfg80211_bss *tmp;
3415
3416	spin_lock_bh(&rdev->bss_lock);
3417
3418	/*
3419	 * Some APs use CSA also for bandwidth changes, i.e., without actually
3420	 * changing the control channel, so no need to update in such a case.
3421	 */
3422	if (cbss->pub.channel == chan)
3423		goto done;
3424
3425	/* use transmitting bss */
3426	if (cbss->pub.transmitted_bss)
3427		cbss = bss_from_pub(cbss->pub.transmitted_bss);
3428
3429	cbss->pub.channel = chan;
3430
3431	list_for_each_entry(bss, &rdev->bss_list, list) {
3432		if (!cfg80211_bss_type_match(bss->pub.capability,
3433					     bss->pub.channel->band,
3434					     wdev->conn_bss_type))
3435			continue;
3436
3437		if (bss == cbss)
3438			continue;
3439
3440		if (!cmp_bss(&bss->pub, &cbss->pub, BSS_CMP_REGULAR)) {
3441			new = bss;
3442			break;
3443		}
3444	}
3445
3446	if (new) {
3447		/* to save time, update IEs for transmitting bss only */
3448		cfg80211_update_known_bss(rdev, cbss, new, false);
3449		new->pub.proberesp_ies = NULL;
3450		new->pub.beacon_ies = NULL;
3451
3452		list_for_each_entry_safe(nontrans_bss, tmp,
3453					 &new->pub.nontrans_list,
3454					 nontrans_list) {
3455			bss = bss_from_pub(nontrans_bss);
3456			if (__cfg80211_unlink_bss(rdev, bss))
3457				rdev->bss_generation++;
3458		}
3459
3460		WARN_ON(atomic_read(&new->hold));
3461		if (!WARN_ON(!__cfg80211_unlink_bss(rdev, new)))
3462			rdev->bss_generation++;
3463	}
3464	cfg80211_rehash_bss(rdev, cbss);
3465
3466	list_for_each_entry_safe(nontrans_bss, tmp,
3467				 &cbss->pub.nontrans_list,
3468				 nontrans_list) {
3469		bss = bss_from_pub(nontrans_bss);
3470		bss->pub.channel = chan;
3471		cfg80211_rehash_bss(rdev, bss);
3472	}
3473
3474done:
3475	spin_unlock_bh(&rdev->bss_lock);
3476}
3477
3478#ifdef CONFIG_CFG80211_WEXT
3479static struct cfg80211_registered_device *
3480cfg80211_get_dev_from_ifindex(struct net *net, int ifindex)
3481{
3482	struct cfg80211_registered_device *rdev;
3483	struct net_device *dev;
3484
3485	ASSERT_RTNL();
3486
3487	dev = dev_get_by_index(net, ifindex);
3488	if (!dev)
3489		return ERR_PTR(-ENODEV);
3490	if (dev->ieee80211_ptr)
3491		rdev = wiphy_to_rdev(dev->ieee80211_ptr->wiphy);
3492	else
3493		rdev = ERR_PTR(-ENODEV);
3494	dev_put(dev);
3495	return rdev;
3496}
3497
3498int cfg80211_wext_siwscan(struct net_device *dev,
3499			  struct iw_request_info *info,
3500			  union iwreq_data *wrqu, char *extra)
3501{
3502	struct cfg80211_registered_device *rdev;
3503	struct wiphy *wiphy;
3504	struct iw_scan_req *wreq = NULL;
3505	struct cfg80211_scan_request_int *creq;
3506	int i, err, n_channels = 0;
3507	enum nl80211_band band;
3508
3509	if (!netif_running(dev))
3510		return -ENETDOWN;
3511
3512	if (wrqu->data.length == sizeof(struct iw_scan_req))
3513		wreq = (struct iw_scan_req *)extra;
3514
3515	rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex);
3516
3517	if (IS_ERR(rdev))
3518		return PTR_ERR(rdev);
3519
3520	if (rdev->scan_req || rdev->scan_msg)
3521		return -EBUSY;
3522
3523	wiphy = &rdev->wiphy;
3524
3525	/* Determine number of channels, needed to allocate creq */
3526	if (wreq && wreq->num_channels) {
3527		/* Passed from userspace so should be checked */
3528		if (unlikely(wreq->num_channels > IW_MAX_FREQUENCIES))
3529			return -EINVAL;
3530		n_channels = wreq->num_channels;
3531	} else {
3532		n_channels = ieee80211_get_num_supported_channels(wiphy);
3533	}
3534
3535	creq = kzalloc(struct_size(creq, req.channels, n_channels) +
3536		       sizeof(struct cfg80211_ssid),
3537		       GFP_ATOMIC);
3538	if (!creq)
3539		return -ENOMEM;
3540
3541	creq->req.wiphy = wiphy;
3542	creq->req.wdev = dev->ieee80211_ptr;
3543	/* SSIDs come after channels */
3544	creq->req.ssids = (void *)creq +
3545			  struct_size(creq, req.channels, n_channels);
3546	creq->req.n_channels = n_channels;
3547	creq->req.n_ssids = 1;
3548	creq->req.scan_start = jiffies;
3549
3550	/* translate "Scan on frequencies" request */
3551	i = 0;
3552	for (band = 0; band < NUM_NL80211_BANDS; band++) {
3553		int j;
3554
3555		if (!wiphy->bands[band])
3556			continue;
3557
3558		for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
3559			struct ieee80211_channel *chan;
3560
3561			/* ignore disabled channels */
3562			chan = &wiphy->bands[band]->channels[j];
3563			if (chan->flags & IEEE80211_CHAN_DISABLED ||
3564			    !cfg80211_wdev_channel_allowed(creq->req.wdev, chan))
3565				continue;
3566
3567			/* If we have a wireless request structure and the
3568			 * wireless request specifies frequencies, then search
3569			 * for the matching hardware channel.
3570			 */
3571			if (wreq && wreq->num_channels) {
3572				int k;
3573				int wiphy_freq = wiphy->bands[band]->channels[j].center_freq;
3574				for (k = 0; k < wreq->num_channels; k++) {
3575					struct iw_freq *freq =
3576						&wreq->channel_list[k];
3577					int wext_freq =
3578						cfg80211_wext_freq(freq);
3579
3580					if (wext_freq == wiphy_freq)
3581						goto wext_freq_found;
3582				}
3583				goto wext_freq_not_found;
3584			}
3585
3586		wext_freq_found:
3587			creq->req.channels[i] =
3588				&wiphy->bands[band]->channels[j];
3589			i++;
3590		wext_freq_not_found: ;
3591		}
3592	}
3593	/* No channels found? */
3594	if (!i) {
3595		err = -EINVAL;
3596		goto out;
3597	}
3598
3599	/* Set real number of channels specified in creq->req.channels[] */
3600	creq->req.n_channels = i;
3601
3602	/* translate "Scan for SSID" request */
3603	if (wreq) {
3604		if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
3605			if (wreq->essid_len > IEEE80211_MAX_SSID_LEN)
3606				return -EINVAL;
3607			memcpy(creq->req.ssids[0].ssid, wreq->essid,
3608			       wreq->essid_len);
3609			creq->req.ssids[0].ssid_len = wreq->essid_len;
3610		}
3611		if (wreq->scan_type == IW_SCAN_TYPE_PASSIVE) {
3612			creq->req.ssids = NULL;
3613			creq->req.n_ssids = 0;
3614		}
3615	}
3616
3617	for (i = 0; i < NUM_NL80211_BANDS; i++)
3618		if (wiphy->bands[i])
3619			creq->req.rates[i] =
3620				(1 << wiphy->bands[i]->n_bitrates) - 1;
3621
3622	eth_broadcast_addr(creq->req.bssid);
3623
3624	scoped_guard(wiphy, &rdev->wiphy) {
3625		rdev->scan_req = creq;
3626		err = rdev_scan(rdev, creq);
3627		if (err) {
3628			rdev->scan_req = NULL;
3629			/* creq will be freed below */
3630		} else {
3631			nl80211_send_scan_start(rdev, dev->ieee80211_ptr);
3632			/* creq now owned by driver */
3633			creq = NULL;
3634			dev_hold(dev);
3635		}
3636	}
3637
3638 out:
3639	kfree(creq);
3640	return err;
3641}
3642
3643static char *ieee80211_scan_add_ies(struct iw_request_info *info,
3644				    const struct cfg80211_bss_ies *ies,
3645				    char *current_ev, char *end_buf)
3646{
3647	const u8 *pos, *end, *next;
3648	struct iw_event iwe;
3649
3650	if (!ies)
3651		return current_ev;
3652
3653	/*
3654	 * If needed, fragment the IEs buffer (at IE boundaries) into short
3655	 * enough fragments to fit into IW_GENERIC_IE_MAX octet messages.
3656	 */
3657	pos = ies->data;
3658	end = pos + ies->len;
3659
3660	while (end - pos > IW_GENERIC_IE_MAX) {
3661		next = pos + 2 + pos[1];
3662		while (next + 2 + next[1] - pos < IW_GENERIC_IE_MAX)
3663			next = next + 2 + next[1];
3664
3665		memset(&iwe, 0, sizeof(iwe));
3666		iwe.cmd = IWEVGENIE;
3667		iwe.u.data.length = next - pos;
3668		current_ev = iwe_stream_add_point_check(info, current_ev,
3669							end_buf, &iwe,
3670							(void *)pos);
3671		if (IS_ERR(current_ev))
3672			return current_ev;
3673		pos = next;
3674	}
3675
3676	if (end > pos) {
3677		memset(&iwe, 0, sizeof(iwe));
3678		iwe.cmd = IWEVGENIE;
3679		iwe.u.data.length = end - pos;
3680		current_ev = iwe_stream_add_point_check(info, current_ev,
3681							end_buf, &iwe,
3682							(void *)pos);
3683		if (IS_ERR(current_ev))
3684			return current_ev;
3685	}
3686
3687	return current_ev;
3688}
3689
3690static char *
3691ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
3692	      struct cfg80211_internal_bss *bss, char *current_ev,
3693	      char *end_buf)
3694{
3695	const struct cfg80211_bss_ies *ies;
3696	struct iw_event iwe;
3697	const u8 *ie;
3698	u8 buf[50];
3699	u8 *cfg, *p, *tmp;
3700	int rem, i, sig;
3701	bool ismesh = false;
3702
3703	memset(&iwe, 0, sizeof(iwe));
3704	iwe.cmd = SIOCGIWAP;
3705	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
3706	memcpy(iwe.u.ap_addr.sa_data, bss->pub.bssid, ETH_ALEN);
3707	current_ev = iwe_stream_add_event_check(info, current_ev, end_buf, &iwe,
3708						IW_EV_ADDR_LEN);
3709	if (IS_ERR(current_ev))
3710		return current_ev;
3711
3712	memset(&iwe, 0, sizeof(iwe));
3713	iwe.cmd = SIOCGIWFREQ;
3714	iwe.u.freq.m = ieee80211_frequency_to_channel(bss->pub.channel->center_freq);
3715	iwe.u.freq.e = 0;
3716	current_ev = iwe_stream_add_event_check(info, current_ev, end_buf, &iwe,
3717						IW_EV_FREQ_LEN);
3718	if (IS_ERR(current_ev))
3719		return current_ev;
3720
3721	memset(&iwe, 0, sizeof(iwe));
3722	iwe.cmd = SIOCGIWFREQ;
3723	iwe.u.freq.m = bss->pub.channel->center_freq;
3724	iwe.u.freq.e = 6;
3725	current_ev = iwe_stream_add_event_check(info, current_ev, end_buf, &iwe,
3726						IW_EV_FREQ_LEN);
3727	if (IS_ERR(current_ev))
3728		return current_ev;
3729
3730	if (wiphy->signal_type != CFG80211_SIGNAL_TYPE_NONE) {
3731		memset(&iwe, 0, sizeof(iwe));
3732		iwe.cmd = IWEVQUAL;
3733		iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED |
3734				     IW_QUAL_NOISE_INVALID |
3735				     IW_QUAL_QUAL_UPDATED;
3736		switch (wiphy->signal_type) {
3737		case CFG80211_SIGNAL_TYPE_MBM:
3738			sig = bss->pub.signal / 100;
3739			iwe.u.qual.level = sig;
3740			iwe.u.qual.updated |= IW_QUAL_DBM;
3741			if (sig < -110)		/* rather bad */
3742				sig = -110;
3743			else if (sig > -40)	/* perfect */
3744				sig = -40;
3745			/* will give a range of 0 .. 70 */
3746			iwe.u.qual.qual = sig + 110;
3747			break;
3748		case CFG80211_SIGNAL_TYPE_UNSPEC:
3749			iwe.u.qual.level = bss->pub.signal;
3750			/* will give range 0 .. 100 */
3751			iwe.u.qual.qual = bss->pub.signal;
3752			break;
3753		default:
3754			/* not reached */
3755			break;
3756		}
3757		current_ev = iwe_stream_add_event_check(info, current_ev,
3758							end_buf, &iwe,
3759							IW_EV_QUAL_LEN);
3760		if (IS_ERR(current_ev))
3761			return current_ev;
3762	}
3763
3764	memset(&iwe, 0, sizeof(iwe));
3765	iwe.cmd = SIOCGIWENCODE;
3766	if (bss->pub.capability & WLAN_CAPABILITY_PRIVACY)
3767		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
3768	else
3769		iwe.u.data.flags = IW_ENCODE_DISABLED;
3770	iwe.u.data.length = 0;
3771	current_ev = iwe_stream_add_point_check(info, current_ev, end_buf,
3772						&iwe, "");
3773	if (IS_ERR(current_ev))
3774		return current_ev;
3775
3776	rcu_read_lock();
3777	ies = rcu_dereference(bss->pub.ies);
3778	rem = ies->len;
3779	ie = ies->data;
3780
3781	while (rem >= 2) {
3782		/* invalid data */
3783		if (ie[1] > rem - 2)
3784			break;
3785
3786		switch (ie[0]) {
3787		case WLAN_EID_SSID:
3788			memset(&iwe, 0, sizeof(iwe));
3789			iwe.cmd = SIOCGIWESSID;
3790			iwe.u.data.length = ie[1];
3791			iwe.u.data.flags = 1;
3792			current_ev = iwe_stream_add_point_check(info,
3793								current_ev,
3794								end_buf, &iwe,
3795								(u8 *)ie + 2);
3796			if (IS_ERR(current_ev))
3797				goto unlock;
3798			break;
3799		case WLAN_EID_MESH_ID:
3800			memset(&iwe, 0, sizeof(iwe));
3801			iwe.cmd = SIOCGIWESSID;
3802			iwe.u.data.length = ie[1];
3803			iwe.u.data.flags = 1;
3804			current_ev = iwe_stream_add_point_check(info,
3805								current_ev,
3806								end_buf, &iwe,
3807								(u8 *)ie + 2);
3808			if (IS_ERR(current_ev))
3809				goto unlock;
3810			break;
3811		case WLAN_EID_MESH_CONFIG:
3812			ismesh = true;
3813			if (ie[1] != sizeof(struct ieee80211_meshconf_ie))
3814				break;
3815			cfg = (u8 *)ie + 2;
3816			memset(&iwe, 0, sizeof(iwe));
3817			iwe.cmd = IWEVCUSTOM;
3818			iwe.u.data.length = sprintf(buf,
3819						    "Mesh Network Path Selection Protocol ID: 0x%02X",
3820						    cfg[0]);
3821			current_ev = iwe_stream_add_point_check(info,
3822								current_ev,
3823								end_buf,
3824								&iwe, buf);
3825			if (IS_ERR(current_ev))
3826				goto unlock;
3827			iwe.u.data.length = sprintf(buf,
3828						    "Path Selection Metric ID: 0x%02X",
3829						    cfg[1]);
3830			current_ev = iwe_stream_add_point_check(info,
3831								current_ev,
3832								end_buf,
3833								&iwe, buf);
3834			if (IS_ERR(current_ev))
3835				goto unlock;
3836			iwe.u.data.length = sprintf(buf,
3837						    "Congestion Control Mode ID: 0x%02X",
3838						    cfg[2]);
3839			current_ev = iwe_stream_add_point_check(info,
3840								current_ev,
3841								end_buf,
3842								&iwe, buf);
3843			if (IS_ERR(current_ev))
3844				goto unlock;
3845			iwe.u.data.length = sprintf(buf,
3846						    "Synchronization ID: 0x%02X",
3847						    cfg[3]);
3848			current_ev = iwe_stream_add_point_check(info,
3849								current_ev,
3850								end_buf,
3851								&iwe, buf);
3852			if (IS_ERR(current_ev))
3853				goto unlock;
3854			iwe.u.data.length = sprintf(buf,
3855						    "Authentication ID: 0x%02X",
3856						    cfg[4]);
3857			current_ev = iwe_stream_add_point_check(info,
3858								current_ev,
3859								end_buf,
3860								&iwe, buf);
3861			if (IS_ERR(current_ev))
3862				goto unlock;
3863			iwe.u.data.length = sprintf(buf,
3864						    "Formation Info: 0x%02X",
3865						    cfg[5]);
3866			current_ev = iwe_stream_add_point_check(info,
3867								current_ev,
3868								end_buf,
3869								&iwe, buf);
3870			if (IS_ERR(current_ev))
3871				goto unlock;
3872			iwe.u.data.length = sprintf(buf,
3873						    "Capabilities: 0x%02X",
3874						    cfg[6]);
3875			current_ev = iwe_stream_add_point_check(info,
3876								current_ev,
3877								end_buf,
3878								&iwe, buf);
3879			if (IS_ERR(current_ev))
3880				goto unlock;
3881			break;
3882		case WLAN_EID_SUPP_RATES:
3883		case WLAN_EID_EXT_SUPP_RATES:
3884			/* display all supported rates in readable format */
3885			p = current_ev + iwe_stream_lcp_len(info);
3886
3887			memset(&iwe, 0, sizeof(iwe));
3888			iwe.cmd = SIOCGIWRATE;
3889			/* Those two flags are ignored... */
3890			iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
3891
3892			for (i = 0; i < ie[1]; i++) {
3893				iwe.u.bitrate.value =
3894					((ie[i + 2] & 0x7f) * 500000);
3895				tmp = p;
3896				p = iwe_stream_add_value(info, current_ev, p,
3897							 end_buf, &iwe,
3898							 IW_EV_PARAM_LEN);
3899				if (p == tmp) {
3900					current_ev = ERR_PTR(-E2BIG);
3901					goto unlock;
3902				}
3903			}
3904			current_ev = p;
3905			break;
3906		}
3907		rem -= ie[1] + 2;
3908		ie += ie[1] + 2;
3909	}
3910
3911	if (bss->pub.capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS) ||
3912	    ismesh) {
3913		memset(&iwe, 0, sizeof(iwe));
3914		iwe.cmd = SIOCGIWMODE;
3915		if (ismesh)
3916			iwe.u.mode = IW_MODE_MESH;
3917		else if (bss->pub.capability & WLAN_CAPABILITY_ESS)
3918			iwe.u.mode = IW_MODE_MASTER;
3919		else
3920			iwe.u.mode = IW_MODE_ADHOC;
3921		current_ev = iwe_stream_add_event_check(info, current_ev,
3922							end_buf, &iwe,
3923							IW_EV_UINT_LEN);
3924		if (IS_ERR(current_ev))
3925			goto unlock;
3926	}
3927
3928	memset(&iwe, 0, sizeof(iwe));
3929	iwe.cmd = IWEVCUSTOM;
3930	iwe.u.data.length = sprintf(buf, "tsf=%016llx",
3931				    (unsigned long long)(ies->tsf));
3932	current_ev = iwe_stream_add_point_check(info, current_ev, end_buf,
3933						&iwe, buf);
3934	if (IS_ERR(current_ev))
3935		goto unlock;
3936	memset(&iwe, 0, sizeof(iwe));
3937	iwe.cmd = IWEVCUSTOM;
3938	iwe.u.data.length = sprintf(buf, " Last beacon: %ums ago",
3939				    elapsed_jiffies_msecs(bss->ts));
3940	current_ev = iwe_stream_add_point_check(info, current_ev,
3941						end_buf, &iwe, buf);
3942	if (IS_ERR(current_ev))
3943		goto unlock;
3944
3945	current_ev = ieee80211_scan_add_ies(info, ies, current_ev, end_buf);
3946
3947 unlock:
3948	rcu_read_unlock();
3949	return current_ev;
3950}
3951
3952
3953static int ieee80211_scan_results(struct cfg80211_registered_device *rdev,
3954				  struct iw_request_info *info,
3955				  char *buf, size_t len)
3956{
3957	char *current_ev = buf;
3958	char *end_buf = buf + len;
3959	struct cfg80211_internal_bss *bss;
3960	int err = 0;
3961
3962	spin_lock_bh(&rdev->bss_lock);
3963	cfg80211_bss_expire(rdev);
3964
3965	list_for_each_entry(bss, &rdev->bss_list, list) {
3966		if (buf + len - current_ev <= IW_EV_ADDR_LEN) {
3967			err = -E2BIG;
3968			break;
3969		}
3970		current_ev = ieee80211_bss(&rdev->wiphy, info, bss,
3971					   current_ev, end_buf);
3972		if (IS_ERR(current_ev)) {
3973			err = PTR_ERR(current_ev);
3974			break;
3975		}
3976	}
3977	spin_unlock_bh(&rdev->bss_lock);
3978
3979	if (err)
3980		return err;
3981	return current_ev - buf;
3982}
3983
3984
3985int cfg80211_wext_giwscan(struct net_device *dev,
3986			  struct iw_request_info *info,
3987			  union iwreq_data *wrqu, char *extra)
3988{
3989	struct iw_point *data = &wrqu->data;
3990	struct cfg80211_registered_device *rdev;
3991	int res;
3992
3993	if (!netif_running(dev))
3994		return -ENETDOWN;
3995
3996	rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex);
3997
3998	if (IS_ERR(rdev))
3999		return PTR_ERR(rdev);
4000
4001	if (rdev->scan_req || rdev->scan_msg)
4002		return -EAGAIN;
4003
4004	res = ieee80211_scan_results(rdev, info, extra, data->length);
4005	data->length = 0;
4006	if (res >= 0) {
4007		data->length = res;
4008		res = 0;
4009	}
4010
4011	return res;
4012}
4013#endif
~/ Read-only file preview.