Linux Audio

Check our new training course

Embedded Linux training

Mar 31-Apr 8, 2025
Register
Loading...
   1/*
   2 * cfg80211 scan result handling
   3 *
   4 * Copyright 2008 Johannes Berg <johannes@sipsolutions.net>
 
   5 */
   6#include <linux/kernel.h>
   7#include <linux/slab.h>
   8#include <linux/module.h>
   9#include <linux/netdevice.h>
  10#include <linux/wireless.h>
  11#include <linux/nl80211.h>
  12#include <linux/etherdevice.h>
  13#include <net/arp.h>
  14#include <net/cfg80211.h>
  15#include <net/cfg80211-wext.h>
  16#include <net/iw_handler.h>
  17#include "core.h"
  18#include "nl80211.h"
  19#include "wext-compat.h"
  20#include "rdev-ops.h"
  21
  22/**
  23 * DOC: BSS tree/list structure
  24 *
  25 * At the top level, the BSS list is kept in both a list in each
  26 * registered device (@bss_list) as well as an RB-tree for faster
  27 * lookup. In the RB-tree, entries can be looked up using their
  28 * channel, MESHID, MESHCONF (for MBSSes) or channel, BSSID, SSID
  29 * for other BSSes.
  30 *
  31 * Due to the possibility of hidden SSIDs, there's a second level
  32 * structure, the "hidden_list" and "hidden_beacon_bss" pointer.
  33 * The hidden_list connects all BSSes belonging to a single AP
  34 * that has a hidden SSID, and connects beacon and probe response
  35 * entries. For a probe response entry for a hidden SSID, the
  36 * hidden_beacon_bss pointer points to the BSS struct holding the
  37 * beacon's information.
  38 *
  39 * Reference counting is done for all these references except for
  40 * the hidden_list, so that a beacon BSS struct that is otherwise
  41 * not referenced has one reference for being on the bss_list and
  42 * one for each probe response entry that points to it using the
  43 * hidden_beacon_bss pointer. When a BSS struct that has such a
  44 * pointer is get/put, the refcount update is also propagated to
  45 * the referenced struct, this ensure that it cannot get removed
  46 * while somebody is using the probe response version.
  47 *
  48 * Note that the hidden_beacon_bss pointer never changes, due to
  49 * the reference counting. Therefore, no locking is needed for
  50 * it.
  51 *
  52 * Also note that the hidden_beacon_bss pointer is only relevant
  53 * if the driver uses something other than the IEs, e.g. private
  54 * data stored stored in the BSS struct, since the beacon IEs are
  55 * also linked into the probe response struct.
  56 */
  57
  58#define IEEE80211_SCAN_RESULT_EXPIRE	(30 * HZ)
  59
  60static void bss_free(struct cfg80211_internal_bss *bss)
  61{
  62	struct cfg80211_bss_ies *ies;
  63
  64	if (WARN_ON(atomic_read(&bss->hold)))
  65		return;
  66
  67	ies = (void *)rcu_access_pointer(bss->pub.beacon_ies);
  68	if (ies && !bss->pub.hidden_beacon_bss)
  69		kfree_rcu(ies, rcu_head);
  70	ies = (void *)rcu_access_pointer(bss->pub.proberesp_ies);
  71	if (ies)
  72		kfree_rcu(ies, rcu_head);
  73
  74	/*
  75	 * This happens when the module is removed, it doesn't
  76	 * really matter any more save for completeness
  77	 */
  78	if (!list_empty(&bss->hidden_list))
  79		list_del(&bss->hidden_list);
  80
  81	kfree(bss);
  82}
  83
  84static inline void bss_ref_get(struct cfg80211_registered_device *dev,
  85			       struct cfg80211_internal_bss *bss)
  86{
  87	lockdep_assert_held(&dev->bss_lock);
  88
  89	bss->refcount++;
  90	if (bss->pub.hidden_beacon_bss) {
  91		bss = container_of(bss->pub.hidden_beacon_bss,
  92				   struct cfg80211_internal_bss,
  93				   pub);
  94		bss->refcount++;
  95	}
  96}
  97
  98static inline void bss_ref_put(struct cfg80211_registered_device *dev,
  99			       struct cfg80211_internal_bss *bss)
 100{
 101	lockdep_assert_held(&dev->bss_lock);
 102
 103	if (bss->pub.hidden_beacon_bss) {
 104		struct cfg80211_internal_bss *hbss;
 105		hbss = container_of(bss->pub.hidden_beacon_bss,
 106				    struct cfg80211_internal_bss,
 107				    pub);
 108		hbss->refcount--;
 109		if (hbss->refcount == 0)
 110			bss_free(hbss);
 111	}
 112	bss->refcount--;
 113	if (bss->refcount == 0)
 114		bss_free(bss);
 115}
 116
 117static bool __cfg80211_unlink_bss(struct cfg80211_registered_device *dev,
 118				  struct cfg80211_internal_bss *bss)
 119{
 120	lockdep_assert_held(&dev->bss_lock);
 121
 122	if (!list_empty(&bss->hidden_list)) {
 123		/*
 124		 * don't remove the beacon entry if it has
 125		 * probe responses associated with it
 126		 */
 127		if (!bss->pub.hidden_beacon_bss)
 128			return false;
 129		/*
 130		 * if it's a probe response entry break its
 131		 * link to the other entries in the group
 132		 */
 133		list_del_init(&bss->hidden_list);
 134	}
 135
 136	list_del_init(&bss->list);
 137	rb_erase(&bss->rbn, &dev->bss_tree);
 138	bss_ref_put(dev, bss);
 139	return true;
 140}
 141
 142static void __cfg80211_bss_expire(struct cfg80211_registered_device *dev,
 143				  unsigned long expire_time)
 144{
 145	struct cfg80211_internal_bss *bss, *tmp;
 146	bool expired = false;
 147
 148	lockdep_assert_held(&dev->bss_lock);
 149
 150	list_for_each_entry_safe(bss, tmp, &dev->bss_list, list) {
 151		if (atomic_read(&bss->hold))
 152			continue;
 153		if (!time_after(expire_time, bss->ts))
 154			continue;
 155
 156		if (__cfg80211_unlink_bss(dev, bss))
 157			expired = true;
 158	}
 159
 160	if (expired)
 161		dev->bss_generation++;
 162}
 163
 164void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
 165			   bool send_message)
 166{
 167	struct cfg80211_scan_request *request;
 168	struct wireless_dev *wdev;
 169	struct sk_buff *msg;
 170#ifdef CONFIG_CFG80211_WEXT
 171	union iwreq_data wrqu;
 172#endif
 173
 174	ASSERT_RTNL();
 175
 176	if (rdev->scan_msg) {
 177		nl80211_send_scan_result(rdev, rdev->scan_msg);
 178		rdev->scan_msg = NULL;
 179		return;
 180	}
 181
 182	request = rdev->scan_req;
 183	if (!request)
 184		return;
 185
 186	wdev = request->wdev;
 187
 188	/*
 189	 * This must be before sending the other events!
 190	 * Otherwise, wpa_supplicant gets completely confused with
 191	 * wext events.
 192	 */
 193	if (wdev->netdev)
 194		cfg80211_sme_scan_done(wdev->netdev);
 195
 196	if (!request->aborted &&
 197	    request->flags & NL80211_SCAN_FLAG_FLUSH) {
 198		/* flush entries from previous scans */
 199		spin_lock_bh(&rdev->bss_lock);
 200		__cfg80211_bss_expire(rdev, request->scan_start);
 201		spin_unlock_bh(&rdev->bss_lock);
 202	}
 203
 204	msg = nl80211_build_scan_msg(rdev, wdev, request->aborted);
 205
 206#ifdef CONFIG_CFG80211_WEXT
 207	if (wdev->netdev && !request->aborted) {
 208		memset(&wrqu, 0, sizeof(wrqu));
 209
 210		wireless_send_event(wdev->netdev, SIOCGIWSCAN, &wrqu, NULL);
 211	}
 212#endif
 213
 214	if (wdev->netdev)
 215		dev_put(wdev->netdev);
 216
 217	rdev->scan_req = NULL;
 218	kfree(request);
 219
 220	if (!send_message)
 221		rdev->scan_msg = msg;
 222	else
 223		nl80211_send_scan_result(rdev, msg);
 224}
 225
 226void __cfg80211_scan_done(struct work_struct *wk)
 227{
 228	struct cfg80211_registered_device *rdev;
 229
 230	rdev = container_of(wk, struct cfg80211_registered_device,
 231			    scan_done_wk);
 232
 233	rtnl_lock();
 234	___cfg80211_scan_done(rdev, true);
 235	rtnl_unlock();
 236}
 237
 238void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
 239{
 240	trace_cfg80211_scan_done(request, aborted);
 241	WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);
 242
 243	request->aborted = aborted;
 244	request->notified = true;
 245	queue_work(cfg80211_wq, &wiphy_to_dev(request->wiphy)->scan_done_wk);
 246}
 247EXPORT_SYMBOL(cfg80211_scan_done);
 248
 249void __cfg80211_sched_scan_results(struct work_struct *wk)
 250{
 251	struct cfg80211_registered_device *rdev;
 252	struct cfg80211_sched_scan_request *request;
 253
 254	rdev = container_of(wk, struct cfg80211_registered_device,
 255			    sched_scan_results_wk);
 256
 257	rtnl_lock();
 258
 259	request = rdev->sched_scan_req;
 260
 261	/* we don't have sched_scan_req anymore if the scan is stopping */
 262	if (request) {
 263		if (request->flags & NL80211_SCAN_FLAG_FLUSH) {
 264			/* flush entries from previous scans */
 265			spin_lock_bh(&rdev->bss_lock);
 266			__cfg80211_bss_expire(rdev, request->scan_start);
 267			spin_unlock_bh(&rdev->bss_lock);
 268			request->scan_start =
 269				jiffies + msecs_to_jiffies(request->interval);
 270		}
 271		nl80211_send_sched_scan_results(rdev, request->dev);
 272	}
 273
 274	rtnl_unlock();
 275}
 276
 277void cfg80211_sched_scan_results(struct wiphy *wiphy)
 278{
 279	trace_cfg80211_sched_scan_results(wiphy);
 280	/* ignore if we're not scanning */
 281	if (wiphy_to_dev(wiphy)->sched_scan_req)
 
 282		queue_work(cfg80211_wq,
 283			   &wiphy_to_dev(wiphy)->sched_scan_results_wk);
 284}
 285EXPORT_SYMBOL(cfg80211_sched_scan_results);
 286
 287void cfg80211_sched_scan_stopped_rtnl(struct wiphy *wiphy)
 288{
 289	struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
 290
 291	ASSERT_RTNL();
 292
 293	trace_cfg80211_sched_scan_stopped(wiphy);
 294
 295	__cfg80211_stop_sched_scan(rdev, true);
 296}
 297EXPORT_SYMBOL(cfg80211_sched_scan_stopped_rtnl);
 298
 299void cfg80211_sched_scan_stopped(struct wiphy *wiphy)
 300{
 301	rtnl_lock();
 302	cfg80211_sched_scan_stopped_rtnl(wiphy);
 303	rtnl_unlock();
 304}
 305EXPORT_SYMBOL(cfg80211_sched_scan_stopped);
 306
 307int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
 308			       bool driver_initiated)
 309{
 
 310	struct net_device *dev;
 311
 312	ASSERT_RTNL();
 313
 314	if (!rdev->sched_scan_req)
 315		return -ENOENT;
 316
 317	dev = rdev->sched_scan_req->dev;
 
 318
 319	if (!driver_initiated) {
 320		int err = rdev_sched_scan_stop(rdev, dev);
 321		if (err)
 322			return err;
 323	}
 324
 325	nl80211_send_sched_scan(rdev, dev, NL80211_CMD_SCHED_SCAN_STOPPED);
 326
 327	kfree(rdev->sched_scan_req);
 328	rdev->sched_scan_req = NULL;
 329
 330	return 0;
 331}
 332
 333void cfg80211_bss_age(struct cfg80211_registered_device *dev,
 334                      unsigned long age_secs)
 335{
 336	struct cfg80211_internal_bss *bss;
 337	unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC);
 338
 339	spin_lock_bh(&dev->bss_lock);
 340	list_for_each_entry(bss, &dev->bss_list, list)
 341		bss->ts -= age_jiffies;
 342	spin_unlock_bh(&dev->bss_lock);
 343}
 344
 345void cfg80211_bss_expire(struct cfg80211_registered_device *dev)
 346{
 347	__cfg80211_bss_expire(dev, jiffies - IEEE80211_SCAN_RESULT_EXPIRE);
 348}
 349
 350const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len)
 351{
 352	while (len > 2 && ies[0] != eid) {
 353		len -= ies[1] + 2;
 354		ies += ies[1] + 2;
 355	}
 356	if (len < 2)
 357		return NULL;
 358	if (len < 2 + ies[1])
 359		return NULL;
 360	return ies;
 361}
 362EXPORT_SYMBOL(cfg80211_find_ie);
 363
 364const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type,
 365				  const u8 *ies, int len)
 366{
 367	struct ieee80211_vendor_ie *ie;
 368	const u8 *pos = ies, *end = ies + len;
 369	int ie_oui;
 370
 371	while (pos < end) {
 372		pos = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, pos,
 373				       end - pos);
 374		if (!pos)
 375			return NULL;
 376
 377		ie = (struct ieee80211_vendor_ie *)pos;
 378
 379		/* make sure we can access ie->len */
 380		BUILD_BUG_ON(offsetof(struct ieee80211_vendor_ie, len) != 1);
 381
 382		if (ie->len < sizeof(*ie))
 383			goto cont;
 384
 385		ie_oui = ie->oui[0] << 16 | ie->oui[1] << 8 | ie->oui[2];
 386		if (ie_oui == oui && ie->oui_type == oui_type)
 387			return pos;
 388cont:
 389		pos += 2 + ie->len;
 390	}
 391	return NULL;
 392}
 393EXPORT_SYMBOL(cfg80211_find_vendor_ie);
 394
 395static bool is_bss(struct cfg80211_bss *a, const u8 *bssid,
 396		   const u8 *ssid, size_t ssid_len)
 397{
 398	const struct cfg80211_bss_ies *ies;
 399	const u8 *ssidie;
 400
 401	if (bssid && !ether_addr_equal(a->bssid, bssid))
 402		return false;
 403
 404	if (!ssid)
 405		return true;
 406
 407	ies = rcu_access_pointer(a->ies);
 408	if (!ies)
 409		return false;
 410	ssidie = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len);
 411	if (!ssidie)
 412		return false;
 413	if (ssidie[1] != ssid_len)
 414		return false;
 415	return memcmp(ssidie + 2, ssid, ssid_len) == 0;
 416}
 417
 418/**
 419 * enum bss_compare_mode - BSS compare mode
 420 * @BSS_CMP_REGULAR: regular compare mode (for insertion and normal find)
 421 * @BSS_CMP_HIDE_ZLEN: find hidden SSID with zero-length mode
 422 * @BSS_CMP_HIDE_NUL: find hidden SSID with NUL-ed out mode
 423 */
 424enum bss_compare_mode {
 425	BSS_CMP_REGULAR,
 426	BSS_CMP_HIDE_ZLEN,
 427	BSS_CMP_HIDE_NUL,
 428};
 429
 430static int cmp_bss(struct cfg80211_bss *a,
 431		   struct cfg80211_bss *b,
 432		   enum bss_compare_mode mode)
 433{
 434	const struct cfg80211_bss_ies *a_ies, *b_ies;
 435	const u8 *ie1 = NULL;
 436	const u8 *ie2 = NULL;
 437	int i, r;
 438
 439	if (a->channel != b->channel)
 440		return b->channel->center_freq - a->channel->center_freq;
 441
 442	a_ies = rcu_access_pointer(a->ies);
 443	if (!a_ies)
 444		return -1;
 445	b_ies = rcu_access_pointer(b->ies);
 446	if (!b_ies)
 447		return 1;
 448
 449	if (WLAN_CAPABILITY_IS_STA_BSS(a->capability))
 450		ie1 = cfg80211_find_ie(WLAN_EID_MESH_ID,
 451				       a_ies->data, a_ies->len);
 452	if (WLAN_CAPABILITY_IS_STA_BSS(b->capability))
 453		ie2 = cfg80211_find_ie(WLAN_EID_MESH_ID,
 454				       b_ies->data, b_ies->len);
 455	if (ie1 && ie2) {
 456		int mesh_id_cmp;
 457
 458		if (ie1[1] == ie2[1])
 459			mesh_id_cmp = memcmp(ie1 + 2, ie2 + 2, ie1[1]);
 460		else
 461			mesh_id_cmp = ie2[1] - ie1[1];
 462
 463		ie1 = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
 464				       a_ies->data, a_ies->len);
 465		ie2 = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
 466				       b_ies->data, b_ies->len);
 467		if (ie1 && ie2) {
 468			if (mesh_id_cmp)
 469				return mesh_id_cmp;
 470			if (ie1[1] != ie2[1])
 471				return ie2[1] - ie1[1];
 472			return memcmp(ie1 + 2, ie2 + 2, ie1[1]);
 473		}
 474	}
 475
 476	r = memcmp(a->bssid, b->bssid, sizeof(a->bssid));
 477	if (r)
 478		return r;
 479
 480	ie1 = cfg80211_find_ie(WLAN_EID_SSID, a_ies->data, a_ies->len);
 481	ie2 = cfg80211_find_ie(WLAN_EID_SSID, b_ies->data, b_ies->len);
 482
 483	if (!ie1 && !ie2)
 484		return 0;
 485
 486	/*
 487	 * Note that with "hide_ssid", the function returns a match if
 488	 * the already-present BSS ("b") is a hidden SSID beacon for
 489	 * the new BSS ("a").
 490	 */
 491
 492	/* sort missing IE before (left of) present IE */
 493	if (!ie1)
 494		return -1;
 495	if (!ie2)
 496		return 1;
 497
 498	switch (mode) {
 499	case BSS_CMP_HIDE_ZLEN:
 500		/*
 501		 * In ZLEN mode we assume the BSS entry we're
 502		 * looking for has a zero-length SSID. So if
 503		 * the one we're looking at right now has that,
 504		 * return 0. Otherwise, return the difference
 505		 * in length, but since we're looking for the
 506		 * 0-length it's really equivalent to returning
 507		 * the length of the one we're looking at.
 508		 *
 509		 * No content comparison is needed as we assume
 510		 * the content length is zero.
 511		 */
 512		return ie2[1];
 513	case BSS_CMP_REGULAR:
 514	default:
 515		/* sort by length first, then by contents */
 516		if (ie1[1] != ie2[1])
 517			return ie2[1] - ie1[1];
 518		return memcmp(ie1 + 2, ie2 + 2, ie1[1]);
 519	case BSS_CMP_HIDE_NUL:
 520		if (ie1[1] != ie2[1])
 521			return ie2[1] - ie1[1];
 522		/* this is equivalent to memcmp(zeroes, ie2 + 2, len) */
 523		for (i = 0; i < ie2[1]; i++)
 524			if (ie2[i + 2])
 525				return -1;
 526		return 0;
 527	}
 528}
 529
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 530/* Returned bss is reference counted and must be cleaned up appropriately. */
 531struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
 532				      struct ieee80211_channel *channel,
 533				      const u8 *bssid,
 534				      const u8 *ssid, size_t ssid_len,
 535				      u16 capa_mask, u16 capa_val)
 
 536{
 537	struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
 538	struct cfg80211_internal_bss *bss, *res = NULL;
 539	unsigned long now = jiffies;
 
 
 
 
 540
 541	trace_cfg80211_get_bss(wiphy, channel, bssid, ssid, ssid_len, capa_mask,
 542			       capa_val);
 543
 544	spin_lock_bh(&dev->bss_lock);
 
 
 
 545
 546	list_for_each_entry(bss, &dev->bss_list, list) {
 547		if ((bss->pub.capability & capa_mask) != capa_val)
 
 548			continue;
 549		if (channel && bss->pub.channel != channel)
 550			continue;
 
 
 551		/* Don't get expired BSS structs */
 552		if (time_after(now, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE) &&
 553		    !atomic_read(&bss->hold))
 554			continue;
 555		if (is_bss(&bss->pub, bssid, ssid, ssid_len)) {
 556			res = bss;
 557			bss_ref_get(dev, res);
 558			break;
 559		}
 560	}
 561
 562	spin_unlock_bh(&dev->bss_lock);
 563	if (!res)
 564		return NULL;
 565	trace_cfg80211_return_bss(&res->pub);
 566	return &res->pub;
 567}
 568EXPORT_SYMBOL(cfg80211_get_bss);
 569
 570static void rb_insert_bss(struct cfg80211_registered_device *dev,
 571			  struct cfg80211_internal_bss *bss)
 572{
 573	struct rb_node **p = &dev->bss_tree.rb_node;
 574	struct rb_node *parent = NULL;
 575	struct cfg80211_internal_bss *tbss;
 576	int cmp;
 577
 578	while (*p) {
 579		parent = *p;
 580		tbss = rb_entry(parent, struct cfg80211_internal_bss, rbn);
 581
 582		cmp = cmp_bss(&bss->pub, &tbss->pub, BSS_CMP_REGULAR);
 583
 584		if (WARN_ON(!cmp)) {
 585			/* will sort of leak this BSS */
 586			return;
 587		}
 588
 589		if (cmp < 0)
 590			p = &(*p)->rb_left;
 591		else
 592			p = &(*p)->rb_right;
 593	}
 594
 595	rb_link_node(&bss->rbn, parent, p);
 596	rb_insert_color(&bss->rbn, &dev->bss_tree);
 597}
 598
 599static struct cfg80211_internal_bss *
 600rb_find_bss(struct cfg80211_registered_device *dev,
 601	    struct cfg80211_internal_bss *res,
 602	    enum bss_compare_mode mode)
 603{
 604	struct rb_node *n = dev->bss_tree.rb_node;
 605	struct cfg80211_internal_bss *bss;
 606	int r;
 607
 608	while (n) {
 609		bss = rb_entry(n, struct cfg80211_internal_bss, rbn);
 610		r = cmp_bss(&res->pub, &bss->pub, mode);
 611
 612		if (r == 0)
 613			return bss;
 614		else if (r < 0)
 615			n = n->rb_left;
 616		else
 617			n = n->rb_right;
 618	}
 619
 620	return NULL;
 621}
 622
 623static bool cfg80211_combine_bsses(struct cfg80211_registered_device *dev,
 624				   struct cfg80211_internal_bss *new)
 625{
 626	const struct cfg80211_bss_ies *ies;
 627	struct cfg80211_internal_bss *bss;
 628	const u8 *ie;
 629	int i, ssidlen;
 630	u8 fold = 0;
 631
 632	ies = rcu_access_pointer(new->pub.beacon_ies);
 633	if (WARN_ON(!ies))
 634		return false;
 635
 636	ie = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len);
 637	if (!ie) {
 638		/* nothing to do */
 639		return true;
 640	}
 641
 642	ssidlen = ie[1];
 643	for (i = 0; i < ssidlen; i++)
 644		fold |= ie[2 + i];
 645
 646	if (fold) {
 647		/* not a hidden SSID */
 648		return true;
 649	}
 650
 651	/* This is the bad part ... */
 652
 653	list_for_each_entry(bss, &dev->bss_list, list) {
 654		if (!ether_addr_equal(bss->pub.bssid, new->pub.bssid))
 655			continue;
 656		if (bss->pub.channel != new->pub.channel)
 657			continue;
 658		if (bss->pub.scan_width != new->pub.scan_width)
 659			continue;
 660		if (rcu_access_pointer(bss->pub.beacon_ies))
 661			continue;
 662		ies = rcu_access_pointer(bss->pub.ies);
 663		if (!ies)
 664			continue;
 665		ie = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len);
 666		if (!ie)
 667			continue;
 668		if (ssidlen && ie[1] != ssidlen)
 669			continue;
 670		if (WARN_ON_ONCE(bss->pub.hidden_beacon_bss))
 671			continue;
 672		if (WARN_ON_ONCE(!list_empty(&bss->hidden_list)))
 673			list_del(&bss->hidden_list);
 674		/* combine them */
 675		list_add(&bss->hidden_list, &new->hidden_list);
 676		bss->pub.hidden_beacon_bss = &new->pub;
 677		new->refcount += bss->refcount;
 678		rcu_assign_pointer(bss->pub.beacon_ies,
 679				   new->pub.beacon_ies);
 680	}
 681
 682	return true;
 683}
 684
 685/* Returned bss is reference counted and must be cleaned up appropriately. */
 686static struct cfg80211_internal_bss *
 687cfg80211_bss_update(struct cfg80211_registered_device *dev,
 688		    struct cfg80211_internal_bss *tmp,
 689		    bool signal_valid)
 690{
 691	struct cfg80211_internal_bss *found = NULL;
 692
 693	if (WARN_ON(!tmp->pub.channel))
 694		return NULL;
 695
 696	tmp->ts = jiffies;
 697
 698	spin_lock_bh(&dev->bss_lock);
 699
 700	if (WARN_ON(!rcu_access_pointer(tmp->pub.ies))) {
 701		spin_unlock_bh(&dev->bss_lock);
 702		return NULL;
 703	}
 704
 705	found = rb_find_bss(dev, tmp, BSS_CMP_REGULAR);
 706
 707	if (found) {
 708		/* Update IEs */
 709		if (rcu_access_pointer(tmp->pub.proberesp_ies)) {
 710			const struct cfg80211_bss_ies *old;
 711
 712			old = rcu_access_pointer(found->pub.proberesp_ies);
 713
 714			rcu_assign_pointer(found->pub.proberesp_ies,
 715					   tmp->pub.proberesp_ies);
 716			/* Override possible earlier Beacon frame IEs */
 717			rcu_assign_pointer(found->pub.ies,
 718					   tmp->pub.proberesp_ies);
 719			if (old)
 720				kfree_rcu((struct cfg80211_bss_ies *)old,
 721					  rcu_head);
 722		} else if (rcu_access_pointer(tmp->pub.beacon_ies)) {
 723			const struct cfg80211_bss_ies *old;
 724			struct cfg80211_internal_bss *bss;
 725
 726			if (found->pub.hidden_beacon_bss &&
 727			    !list_empty(&found->hidden_list)) {
 728				const struct cfg80211_bss_ies *f;
 729
 730				/*
 731				 * The found BSS struct is one of the probe
 732				 * response members of a group, but we're
 733				 * receiving a beacon (beacon_ies in the tmp
 734				 * bss is used). This can only mean that the
 735				 * AP changed its beacon from not having an
 736				 * SSID to showing it, which is confusing so
 737				 * drop this information.
 738				 */
 739
 740				f = rcu_access_pointer(tmp->pub.beacon_ies);
 741				kfree_rcu((struct cfg80211_bss_ies *)f,
 742					  rcu_head);
 743				goto drop;
 744			}
 745
 746			old = rcu_access_pointer(found->pub.beacon_ies);
 747
 748			rcu_assign_pointer(found->pub.beacon_ies,
 749					   tmp->pub.beacon_ies);
 750
 751			/* Override IEs if they were from a beacon before */
 752			if (old == rcu_access_pointer(found->pub.ies))
 753				rcu_assign_pointer(found->pub.ies,
 754						   tmp->pub.beacon_ies);
 755
 756			/* Assign beacon IEs to all sub entries */
 757			list_for_each_entry(bss, &found->hidden_list,
 758					    hidden_list) {
 759				const struct cfg80211_bss_ies *ies;
 760
 761				ies = rcu_access_pointer(bss->pub.beacon_ies);
 762				WARN_ON(ies != old);
 763
 764				rcu_assign_pointer(bss->pub.beacon_ies,
 765						   tmp->pub.beacon_ies);
 766			}
 767
 768			if (old)
 769				kfree_rcu((struct cfg80211_bss_ies *)old,
 770					  rcu_head);
 771		}
 772
 773		found->pub.beacon_interval = tmp->pub.beacon_interval;
 774		/*
 775		 * don't update the signal if beacon was heard on
 776		 * adjacent channel.
 777		 */
 778		if (signal_valid)
 779			found->pub.signal = tmp->pub.signal;
 780		found->pub.capability = tmp->pub.capability;
 781		found->ts = tmp->ts;
 
 782	} else {
 783		struct cfg80211_internal_bss *new;
 784		struct cfg80211_internal_bss *hidden;
 785		struct cfg80211_bss_ies *ies;
 786
 787		/*
 788		 * create a copy -- the "res" variable that is passed in
 789		 * is allocated on the stack since it's not needed in the
 790		 * more common case of an update
 791		 */
 792		new = kzalloc(sizeof(*new) + dev->wiphy.bss_priv_size,
 793			      GFP_ATOMIC);
 794		if (!new) {
 795			ies = (void *)rcu_dereference(tmp->pub.beacon_ies);
 796			if (ies)
 797				kfree_rcu(ies, rcu_head);
 798			ies = (void *)rcu_dereference(tmp->pub.proberesp_ies);
 799			if (ies)
 800				kfree_rcu(ies, rcu_head);
 801			goto drop;
 802		}
 803		memcpy(new, tmp, sizeof(*new));
 804		new->refcount = 1;
 805		INIT_LIST_HEAD(&new->hidden_list);
 806
 807		if (rcu_access_pointer(tmp->pub.proberesp_ies)) {
 808			hidden = rb_find_bss(dev, tmp, BSS_CMP_HIDE_ZLEN);
 809			if (!hidden)
 810				hidden = rb_find_bss(dev, tmp,
 811						     BSS_CMP_HIDE_NUL);
 812			if (hidden) {
 813				new->pub.hidden_beacon_bss = &hidden->pub;
 814				list_add(&new->hidden_list,
 815					 &hidden->hidden_list);
 816				hidden->refcount++;
 817				rcu_assign_pointer(new->pub.beacon_ies,
 818						   hidden->pub.beacon_ies);
 819			}
 820		} else {
 821			/*
 822			 * Ok so we found a beacon, and don't have an entry. If
 823			 * it's a beacon with hidden SSID, we might be in for an
 824			 * expensive search for any probe responses that should
 825			 * be grouped with this beacon for updates ...
 826			 */
 827			if (!cfg80211_combine_bsses(dev, new)) {
 828				kfree(new);
 829				goto drop;
 830			}
 831		}
 832
 833		list_add_tail(&new->list, &dev->bss_list);
 834		rb_insert_bss(dev, new);
 835		found = new;
 836	}
 837
 838	dev->bss_generation++;
 839	bss_ref_get(dev, found);
 840	spin_unlock_bh(&dev->bss_lock);
 841
 842	return found;
 843 drop:
 844	spin_unlock_bh(&dev->bss_lock);
 845	return NULL;
 846}
 847
 848static struct ieee80211_channel *
 849cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen,
 850			 struct ieee80211_channel *channel)
 851{
 852	const u8 *tmp;
 853	u32 freq;
 854	int channel_number = -1;
 855
 856	tmp = cfg80211_find_ie(WLAN_EID_DS_PARAMS, ie, ielen);
 857	if (tmp && tmp[1] == 1) {
 858		channel_number = tmp[2];
 859	} else {
 860		tmp = cfg80211_find_ie(WLAN_EID_HT_OPERATION, ie, ielen);
 861		if (tmp && tmp[1] >= sizeof(struct ieee80211_ht_operation)) {
 862			struct ieee80211_ht_operation *htop = (void *)(tmp + 2);
 863
 864			channel_number = htop->primary_chan;
 865		}
 866	}
 867
 868	if (channel_number < 0)
 869		return channel;
 870
 871	freq = ieee80211_channel_to_frequency(channel_number, channel->band);
 872	channel = ieee80211_get_channel(wiphy, freq);
 873	if (!channel)
 874		return NULL;
 875	if (channel->flags & IEEE80211_CHAN_DISABLED)
 876		return NULL;
 877	return channel;
 878}
 879
 880/* Returned bss is reference counted and must be cleaned up appropriately. */
 881struct cfg80211_bss*
 882cfg80211_inform_bss_width(struct wiphy *wiphy,
 883			  struct ieee80211_channel *rx_channel,
 884			  enum nl80211_bss_scan_width scan_width,
 885			  const u8 *bssid, u64 tsf, u16 capability,
 886			  u16 beacon_interval, const u8 *ie, size_t ielen,
 887			  s32 signal, gfp_t gfp)
 888{
 889	struct cfg80211_bss_ies *ies;
 890	struct ieee80211_channel *channel;
 891	struct cfg80211_internal_bss tmp = {}, *res;
 
 
 892
 893	if (WARN_ON(!wiphy))
 894		return NULL;
 895
 896	if (WARN_ON(wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
 897			(signal < 0 || signal > 100)))
 898		return NULL;
 899
 900	channel = cfg80211_get_bss_channel(wiphy, ie, ielen, rx_channel);
 901	if (!channel)
 902		return NULL;
 903
 904	memcpy(tmp.pub.bssid, bssid, ETH_ALEN);
 905	tmp.pub.channel = channel;
 906	tmp.pub.scan_width = scan_width;
 907	tmp.pub.signal = signal;
 908	tmp.pub.beacon_interval = beacon_interval;
 909	tmp.pub.capability = capability;
 
 
 910	/*
 911	 * Since we do not know here whether the IEs are from a Beacon or Probe
 912	 * Response frame, we need to pick one of the options and only use it
 913	 * with the driver that does not provide the full Beacon/Probe Response
 914	 * frame. Use Beacon frame pointer to avoid indicating that this should
 915	 * override the IEs pointer should we have received an earlier
 916	 * indication of Probe Response data.
 917	 */
 918	ies = kmalloc(sizeof(*ies) + ielen, gfp);
 919	if (!ies)
 920		return NULL;
 921	ies->len = ielen;
 922	ies->tsf = tsf;
 
 923	memcpy(ies->data, ie, ielen);
 924
 925	rcu_assign_pointer(tmp.pub.beacon_ies, ies);
 
 
 
 
 
 
 
 
 
 
 926	rcu_assign_pointer(tmp.pub.ies, ies);
 927
 928	res = cfg80211_bss_update(wiphy_to_dev(wiphy), &tmp,
 929				  rx_channel == channel);
 
 930	if (!res)
 931		return NULL;
 932
 933	if (res->pub.capability & WLAN_CAPABILITY_ESS)
 934		regulatory_hint_found_beacon(wiphy, channel, gfp);
 
 
 
 
 
 
 
 935
 936	trace_cfg80211_return_bss(&res->pub);
 937	/* cfg80211_bss_update gives us a referenced result */
 938	return &res->pub;
 939}
 940EXPORT_SYMBOL(cfg80211_inform_bss_width);
 941
 942/* Returned bss is reference counted and must be cleaned up appropriately. */
 943struct cfg80211_bss *
 944cfg80211_inform_bss_width_frame(struct wiphy *wiphy,
 945				struct ieee80211_channel *rx_channel,
 946				enum nl80211_bss_scan_width scan_width,
 947				struct ieee80211_mgmt *mgmt, size_t len,
 948				s32 signal, gfp_t gfp)
 949{
 950	struct cfg80211_internal_bss tmp = {}, *res;
 951	struct cfg80211_bss_ies *ies;
 952	struct ieee80211_channel *channel;
 
 953	size_t ielen = len - offsetof(struct ieee80211_mgmt,
 954				      u.probe_resp.variable);
 
 955
 956	BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) !=
 957			offsetof(struct ieee80211_mgmt, u.beacon.variable));
 958
 959	trace_cfg80211_inform_bss_width_frame(wiphy, rx_channel, scan_width, mgmt,
 960					      len, signal);
 961
 962	if (WARN_ON(!mgmt))
 963		return NULL;
 964
 965	if (WARN_ON(!wiphy))
 966		return NULL;
 967
 968	if (WARN_ON(wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
 969		    (signal < 0 || signal > 100)))
 970		return NULL;
 971
 972	if (WARN_ON(len < offsetof(struct ieee80211_mgmt, u.probe_resp.variable)))
 973		return NULL;
 974
 975	channel = cfg80211_get_bss_channel(wiphy, mgmt->u.beacon.variable,
 976					   ielen, rx_channel);
 977	if (!channel)
 978		return NULL;
 979
 980	ies = kmalloc(sizeof(*ies) + ielen, gfp);
 981	if (!ies)
 982		return NULL;
 983	ies->len = ielen;
 984	ies->tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
 
 985	memcpy(ies->data, mgmt->u.probe_resp.variable, ielen);
 986
 987	if (ieee80211_is_probe_resp(mgmt->frame_control))
 988		rcu_assign_pointer(tmp.pub.proberesp_ies, ies);
 989	else
 990		rcu_assign_pointer(tmp.pub.beacon_ies, ies);
 991	rcu_assign_pointer(tmp.pub.ies, ies);
 992	
 993	memcpy(tmp.pub.bssid, mgmt->bssid, ETH_ALEN);
 994	tmp.pub.channel = channel;
 995	tmp.pub.scan_width = scan_width;
 996	tmp.pub.signal = signal;
 997	tmp.pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
 998	tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
 
 999
1000	res = cfg80211_bss_update(wiphy_to_dev(wiphy), &tmp,
1001				  rx_channel == channel);
 
1002	if (!res)
1003		return NULL;
1004
1005	if (res->pub.capability & WLAN_CAPABILITY_ESS)
1006		regulatory_hint_found_beacon(wiphy, channel, gfp);
 
 
 
 
 
 
 
1007
1008	trace_cfg80211_return_bss(&res->pub);
1009	/* cfg80211_bss_update gives us a referenced result */
1010	return &res->pub;
1011}
1012EXPORT_SYMBOL(cfg80211_inform_bss_width_frame);
1013
1014void cfg80211_ref_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
1015{
1016	struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
1017	struct cfg80211_internal_bss *bss;
1018
1019	if (!pub)
1020		return;
1021
1022	bss = container_of(pub, struct cfg80211_internal_bss, pub);
1023
1024	spin_lock_bh(&dev->bss_lock);
1025	bss_ref_get(dev, bss);
1026	spin_unlock_bh(&dev->bss_lock);
1027}
1028EXPORT_SYMBOL(cfg80211_ref_bss);
1029
1030void cfg80211_put_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
1031{
1032	struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
1033	struct cfg80211_internal_bss *bss;
1034
1035	if (!pub)
1036		return;
1037
1038	bss = container_of(pub, struct cfg80211_internal_bss, pub);
1039
1040	spin_lock_bh(&dev->bss_lock);
1041	bss_ref_put(dev, bss);
1042	spin_unlock_bh(&dev->bss_lock);
1043}
1044EXPORT_SYMBOL(cfg80211_put_bss);
1045
1046void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
1047{
1048	struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
1049	struct cfg80211_internal_bss *bss;
1050
1051	if (WARN_ON(!pub))
1052		return;
1053
1054	bss = container_of(pub, struct cfg80211_internal_bss, pub);
1055
1056	spin_lock_bh(&dev->bss_lock);
1057	if (!list_empty(&bss->list)) {
1058		if (__cfg80211_unlink_bss(dev, bss))
1059			dev->bss_generation++;
1060	}
1061	spin_unlock_bh(&dev->bss_lock);
1062}
1063EXPORT_SYMBOL(cfg80211_unlink_bss);
1064
1065#ifdef CONFIG_CFG80211_WEXT
1066static struct cfg80211_registered_device *
1067cfg80211_get_dev_from_ifindex(struct net *net, int ifindex)
1068{
1069	struct cfg80211_registered_device *rdev;
1070	struct net_device *dev;
1071
1072	ASSERT_RTNL();
1073
1074	dev = dev_get_by_index(net, ifindex);
1075	if (!dev)
1076		return ERR_PTR(-ENODEV);
1077	if (dev->ieee80211_ptr)
1078		rdev = wiphy_to_dev(dev->ieee80211_ptr->wiphy);
1079	else
1080		rdev = ERR_PTR(-ENODEV);
1081	dev_put(dev);
1082	return rdev;
1083}
1084
1085int cfg80211_wext_siwscan(struct net_device *dev,
1086			  struct iw_request_info *info,
1087			  union iwreq_data *wrqu, char *extra)
1088{
1089	struct cfg80211_registered_device *rdev;
1090	struct wiphy *wiphy;
1091	struct iw_scan_req *wreq = NULL;
1092	struct cfg80211_scan_request *creq = NULL;
1093	int i, err, n_channels = 0;
1094	enum ieee80211_band band;
1095
1096	if (!netif_running(dev))
1097		return -ENETDOWN;
1098
1099	if (wrqu->data.length == sizeof(struct iw_scan_req))
1100		wreq = (struct iw_scan_req *)extra;
1101
1102	rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex);
1103
1104	if (IS_ERR(rdev))
1105		return PTR_ERR(rdev);
1106
1107	if (rdev->scan_req || rdev->scan_msg) {
1108		err = -EBUSY;
1109		goto out;
1110	}
1111
1112	wiphy = &rdev->wiphy;
1113
1114	/* Determine number of channels, needed to allocate creq */
1115	if (wreq && wreq->num_channels)
1116		n_channels = wreq->num_channels;
1117	else
1118		n_channels = ieee80211_get_num_supported_channels(wiphy);
1119
1120	creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) +
1121		       n_channels * sizeof(void *),
1122		       GFP_ATOMIC);
1123	if (!creq) {
1124		err = -ENOMEM;
1125		goto out;
1126	}
1127
1128	creq->wiphy = wiphy;
1129	creq->wdev = dev->ieee80211_ptr;
1130	/* SSIDs come after channels */
1131	creq->ssids = (void *)&creq->channels[n_channels];
1132	creq->n_channels = n_channels;
1133	creq->n_ssids = 1;
1134	creq->scan_start = jiffies;
1135
1136	/* translate "Scan on frequencies" request */
1137	i = 0;
1138	for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
1139		int j;
1140
1141		if (!wiphy->bands[band])
1142			continue;
1143
1144		for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
1145			/* ignore disabled channels */
1146			if (wiphy->bands[band]->channels[j].flags &
1147						IEEE80211_CHAN_DISABLED)
1148				continue;
1149
1150			/* If we have a wireless request structure and the
1151			 * wireless request specifies frequencies, then search
1152			 * for the matching hardware channel.
1153			 */
1154			if (wreq && wreq->num_channels) {
1155				int k;
1156				int wiphy_freq = wiphy->bands[band]->channels[j].center_freq;
1157				for (k = 0; k < wreq->num_channels; k++) {
1158					int wext_freq = cfg80211_wext_freq(wiphy, &wreq->channel_list[k]);
 
 
 
 
1159					if (wext_freq == wiphy_freq)
1160						goto wext_freq_found;
1161				}
1162				goto wext_freq_not_found;
1163			}
1164
1165		wext_freq_found:
1166			creq->channels[i] = &wiphy->bands[band]->channels[j];
1167			i++;
1168		wext_freq_not_found: ;
1169		}
1170	}
1171	/* No channels found? */
1172	if (!i) {
1173		err = -EINVAL;
1174		goto out;
1175	}
1176
1177	/* Set real number of channels specified in creq->channels[] */
1178	creq->n_channels = i;
1179
1180	/* translate "Scan for SSID" request */
1181	if (wreq) {
1182		if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
1183			if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) {
1184				err = -EINVAL;
1185				goto out;
1186			}
1187			memcpy(creq->ssids[0].ssid, wreq->essid, wreq->essid_len);
1188			creq->ssids[0].ssid_len = wreq->essid_len;
1189		}
1190		if (wreq->scan_type == IW_SCAN_TYPE_PASSIVE)
1191			creq->n_ssids = 0;
1192	}
1193
1194	for (i = 0; i < IEEE80211_NUM_BANDS; i++)
1195		if (wiphy->bands[i])
1196			creq->rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1;
1197
1198	rdev->scan_req = creq;
1199	err = rdev_scan(rdev, creq);
1200	if (err) {
1201		rdev->scan_req = NULL;
1202		/* creq will be freed below */
1203	} else {
1204		nl80211_send_scan_start(rdev, dev->ieee80211_ptr);
1205		/* creq now owned by driver */
1206		creq = NULL;
1207		dev_hold(dev);
1208	}
1209 out:
1210	kfree(creq);
1211	return err;
1212}
1213EXPORT_SYMBOL_GPL(cfg80211_wext_siwscan);
1214
1215static void ieee80211_scan_add_ies(struct iw_request_info *info,
1216				   const struct cfg80211_bss_ies *ies,
1217				   char **current_ev, char *end_buf)
1218{
1219	const u8 *pos, *end, *next;
1220	struct iw_event iwe;
1221
1222	if (!ies)
1223		return;
1224
1225	/*
1226	 * If needed, fragment the IEs buffer (at IE boundaries) into short
1227	 * enough fragments to fit into IW_GENERIC_IE_MAX octet messages.
1228	 */
1229	pos = ies->data;
1230	end = pos + ies->len;
1231
1232	while (end - pos > IW_GENERIC_IE_MAX) {
1233		next = pos + 2 + pos[1];
1234		while (next + 2 + next[1] - pos < IW_GENERIC_IE_MAX)
1235			next = next + 2 + next[1];
1236
1237		memset(&iwe, 0, sizeof(iwe));
1238		iwe.cmd = IWEVGENIE;
1239		iwe.u.data.length = next - pos;
1240		*current_ev = iwe_stream_add_point(info, *current_ev,
1241						   end_buf, &iwe,
1242						   (void *)pos);
1243
 
1244		pos = next;
1245	}
1246
1247	if (end > pos) {
1248		memset(&iwe, 0, sizeof(iwe));
1249		iwe.cmd = IWEVGENIE;
1250		iwe.u.data.length = end - pos;
1251		*current_ev = iwe_stream_add_point(info, *current_ev,
1252						   end_buf, &iwe,
1253						   (void *)pos);
 
 
1254	}
 
 
1255}
1256
1257static char *
1258ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
1259	      struct cfg80211_internal_bss *bss, char *current_ev,
1260	      char *end_buf)
1261{
1262	const struct cfg80211_bss_ies *ies;
1263	struct iw_event iwe;
1264	const u8 *ie;
1265	u8 *buf, *cfg, *p;
 
1266	int rem, i, sig;
1267	bool ismesh = false;
1268
1269	memset(&iwe, 0, sizeof(iwe));
1270	iwe.cmd = SIOCGIWAP;
1271	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
1272	memcpy(iwe.u.ap_addr.sa_data, bss->pub.bssid, ETH_ALEN);
1273	current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
1274					  IW_EV_ADDR_LEN);
 
 
1275
1276	memset(&iwe, 0, sizeof(iwe));
1277	iwe.cmd = SIOCGIWFREQ;
1278	iwe.u.freq.m = ieee80211_frequency_to_channel(bss->pub.channel->center_freq);
1279	iwe.u.freq.e = 0;
1280	current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
1281					  IW_EV_FREQ_LEN);
 
 
1282
1283	memset(&iwe, 0, sizeof(iwe));
1284	iwe.cmd = SIOCGIWFREQ;
1285	iwe.u.freq.m = bss->pub.channel->center_freq;
1286	iwe.u.freq.e = 6;
1287	current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
1288					  IW_EV_FREQ_LEN);
 
 
1289
1290	if (wiphy->signal_type != CFG80211_SIGNAL_TYPE_NONE) {
1291		memset(&iwe, 0, sizeof(iwe));
1292		iwe.cmd = IWEVQUAL;
1293		iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED |
1294				     IW_QUAL_NOISE_INVALID |
1295				     IW_QUAL_QUAL_UPDATED;
1296		switch (wiphy->signal_type) {
1297		case CFG80211_SIGNAL_TYPE_MBM:
1298			sig = bss->pub.signal / 100;
1299			iwe.u.qual.level = sig;
1300			iwe.u.qual.updated |= IW_QUAL_DBM;
1301			if (sig < -110)		/* rather bad */
1302				sig = -110;
1303			else if (sig > -40)	/* perfect */
1304				sig = -40;
1305			/* will give a range of 0 .. 70 */
1306			iwe.u.qual.qual = sig + 110;
1307			break;
1308		case CFG80211_SIGNAL_TYPE_UNSPEC:
1309			iwe.u.qual.level = bss->pub.signal;
1310			/* will give range 0 .. 100 */
1311			iwe.u.qual.qual = bss->pub.signal;
1312			break;
1313		default:
1314			/* not reached */
1315			break;
1316		}
1317		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
1318						  &iwe, IW_EV_QUAL_LEN);
 
 
 
1319	}
1320
1321	memset(&iwe, 0, sizeof(iwe));
1322	iwe.cmd = SIOCGIWENCODE;
1323	if (bss->pub.capability & WLAN_CAPABILITY_PRIVACY)
1324		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
1325	else
1326		iwe.u.data.flags = IW_ENCODE_DISABLED;
1327	iwe.u.data.length = 0;
1328	current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1329					  &iwe, "");
 
 
1330
1331	rcu_read_lock();
1332	ies = rcu_dereference(bss->pub.ies);
1333	rem = ies->len;
1334	ie = ies->data;
1335
1336	while (rem >= 2) {
1337		/* invalid data */
1338		if (ie[1] > rem - 2)
1339			break;
1340
1341		switch (ie[0]) {
1342		case WLAN_EID_SSID:
1343			memset(&iwe, 0, sizeof(iwe));
1344			iwe.cmd = SIOCGIWESSID;
1345			iwe.u.data.length = ie[1];
1346			iwe.u.data.flags = 1;
1347			current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1348							  &iwe, (u8 *)ie + 2);
 
 
 
 
1349			break;
1350		case WLAN_EID_MESH_ID:
1351			memset(&iwe, 0, sizeof(iwe));
1352			iwe.cmd = SIOCGIWESSID;
1353			iwe.u.data.length = ie[1];
1354			iwe.u.data.flags = 1;
1355			current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1356							  &iwe, (u8 *)ie + 2);
 
 
 
 
1357			break;
1358		case WLAN_EID_MESH_CONFIG:
1359			ismesh = true;
1360			if (ie[1] != sizeof(struct ieee80211_meshconf_ie))
1361				break;
1362			buf = kmalloc(50, GFP_ATOMIC);
1363			if (!buf)
1364				break;
1365			cfg = (u8 *)ie + 2;
1366			memset(&iwe, 0, sizeof(iwe));
1367			iwe.cmd = IWEVCUSTOM;
1368			sprintf(buf, "Mesh Network Path Selection Protocol ID: "
1369				"0x%02X", cfg[0]);
1370			iwe.u.data.length = strlen(buf);
1371			current_ev = iwe_stream_add_point(info, current_ev,
1372							  end_buf,
1373							  &iwe, buf);
 
 
 
1374			sprintf(buf, "Path Selection Metric ID: 0x%02X",
1375				cfg[1]);
1376			iwe.u.data.length = strlen(buf);
1377			current_ev = iwe_stream_add_point(info, current_ev,
1378							  end_buf,
1379							  &iwe, buf);
 
 
 
1380			sprintf(buf, "Congestion Control Mode ID: 0x%02X",
1381				cfg[2]);
1382			iwe.u.data.length = strlen(buf);
1383			current_ev = iwe_stream_add_point(info, current_ev,
1384							  end_buf,
1385							  &iwe, buf);
 
 
 
1386			sprintf(buf, "Synchronization ID: 0x%02X", cfg[3]);
1387			iwe.u.data.length = strlen(buf);
1388			current_ev = iwe_stream_add_point(info, current_ev,
1389							  end_buf,
1390							  &iwe, buf);
 
 
 
1391			sprintf(buf, "Authentication ID: 0x%02X", cfg[4]);
1392			iwe.u.data.length = strlen(buf);
1393			current_ev = iwe_stream_add_point(info, current_ev,
1394							  end_buf,
1395							  &iwe, buf);
 
 
 
1396			sprintf(buf, "Formation Info: 0x%02X", cfg[5]);
1397			iwe.u.data.length = strlen(buf);
1398			current_ev = iwe_stream_add_point(info, current_ev,
1399							  end_buf,
1400							  &iwe, buf);
 
 
 
1401			sprintf(buf, "Capabilities: 0x%02X", cfg[6]);
1402			iwe.u.data.length = strlen(buf);
1403			current_ev = iwe_stream_add_point(info, current_ev,
1404							  end_buf,
1405							  &iwe, buf);
1406			kfree(buf);
 
 
1407			break;
1408		case WLAN_EID_SUPP_RATES:
1409		case WLAN_EID_EXT_SUPP_RATES:
1410			/* display all supported rates in readable format */
1411			p = current_ev + iwe_stream_lcp_len(info);
1412
1413			memset(&iwe, 0, sizeof(iwe));
1414			iwe.cmd = SIOCGIWRATE;
1415			/* Those two flags are ignored... */
1416			iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
1417
1418			for (i = 0; i < ie[1]; i++) {
1419				iwe.u.bitrate.value =
1420					((ie[i + 2] & 0x7f) * 500000);
 
1421				p = iwe_stream_add_value(info, current_ev, p,
1422						end_buf, &iwe, IW_EV_PARAM_LEN);
 
 
 
 
 
1423			}
1424			current_ev = p;
1425			break;
1426		}
1427		rem -= ie[1] + 2;
1428		ie += ie[1] + 2;
1429	}
1430
1431	if (bss->pub.capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS) ||
1432	    ismesh) {
1433		memset(&iwe, 0, sizeof(iwe));
1434		iwe.cmd = SIOCGIWMODE;
1435		if (ismesh)
1436			iwe.u.mode = IW_MODE_MESH;
1437		else if (bss->pub.capability & WLAN_CAPABILITY_ESS)
1438			iwe.u.mode = IW_MODE_MASTER;
1439		else
1440			iwe.u.mode = IW_MODE_ADHOC;
1441		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
1442						  &iwe, IW_EV_UINT_LEN);
 
 
 
1443	}
1444
1445	buf = kmalloc(31, GFP_ATOMIC);
1446	if (buf) {
1447		memset(&iwe, 0, sizeof(iwe));
1448		iwe.cmd = IWEVCUSTOM;
1449		sprintf(buf, "tsf=%016llx", (unsigned long long)(ies->tsf));
1450		iwe.u.data.length = strlen(buf);
1451		current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1452						  &iwe, buf);
1453		memset(&iwe, 0, sizeof(iwe));
1454		iwe.cmd = IWEVCUSTOM;
1455		sprintf(buf, " Last beacon: %ums ago",
1456			elapsed_jiffies_msecs(bss->ts));
1457		iwe.u.data.length = strlen(buf);
1458		current_ev = iwe_stream_add_point(info, current_ev,
1459						  end_buf, &iwe, buf);
1460		kfree(buf);
1461	}
1462
1463	ieee80211_scan_add_ies(info, ies, &current_ev, end_buf);
1464	rcu_read_unlock();
1465
 
 
1466	return current_ev;
1467}
1468
1469
1470static int ieee80211_scan_results(struct cfg80211_registered_device *dev,
1471				  struct iw_request_info *info,
1472				  char *buf, size_t len)
1473{
1474	char *current_ev = buf;
1475	char *end_buf = buf + len;
1476	struct cfg80211_internal_bss *bss;
 
1477
1478	spin_lock_bh(&dev->bss_lock);
1479	cfg80211_bss_expire(dev);
1480
1481	list_for_each_entry(bss, &dev->bss_list, list) {
1482		if (buf + len - current_ev <= IW_EV_ADDR_LEN) {
1483			spin_unlock_bh(&dev->bss_lock);
1484			return -E2BIG;
1485		}
1486		current_ev = ieee80211_bss(&dev->wiphy, info, bss,
1487					   current_ev, end_buf);
 
 
 
 
1488	}
1489	spin_unlock_bh(&dev->bss_lock);
 
 
 
1490	return current_ev - buf;
1491}
1492
1493
1494int cfg80211_wext_giwscan(struct net_device *dev,
1495			  struct iw_request_info *info,
1496			  struct iw_point *data, char *extra)
1497{
1498	struct cfg80211_registered_device *rdev;
1499	int res;
1500
1501	if (!netif_running(dev))
1502		return -ENETDOWN;
1503
1504	rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex);
1505
1506	if (IS_ERR(rdev))
1507		return PTR_ERR(rdev);
1508
1509	if (rdev->scan_req || rdev->scan_msg)
1510		return -EAGAIN;
1511
1512	res = ieee80211_scan_results(rdev, info, extra, data->length);
1513	data->length = 0;
1514	if (res >= 0) {
1515		data->length = res;
1516		res = 0;
1517	}
1518
1519	return res;
1520}
1521EXPORT_SYMBOL_GPL(cfg80211_wext_giwscan);
1522#endif
   1/*
   2 * cfg80211 scan result handling
   3 *
   4 * Copyright 2008 Johannes Berg <johannes@sipsolutions.net>
   5 * Copyright 2013-2014  Intel Mobile Communications GmbH
   6 */
   7#include <linux/kernel.h>
   8#include <linux/slab.h>
   9#include <linux/module.h>
  10#include <linux/netdevice.h>
  11#include <linux/wireless.h>
  12#include <linux/nl80211.h>
  13#include <linux/etherdevice.h>
  14#include <net/arp.h>
  15#include <net/cfg80211.h>
  16#include <net/cfg80211-wext.h>
  17#include <net/iw_handler.h>
  18#include "core.h"
  19#include "nl80211.h"
  20#include "wext-compat.h"
  21#include "rdev-ops.h"
  22
  23/**
  24 * DOC: BSS tree/list structure
  25 *
  26 * At the top level, the BSS list is kept in both a list in each
  27 * registered device (@bss_list) as well as an RB-tree for faster
  28 * lookup. In the RB-tree, entries can be looked up using their
  29 * channel, MESHID, MESHCONF (for MBSSes) or channel, BSSID, SSID
  30 * for other BSSes.
  31 *
  32 * Due to the possibility of hidden SSIDs, there's a second level
  33 * structure, the "hidden_list" and "hidden_beacon_bss" pointer.
  34 * The hidden_list connects all BSSes belonging to a single AP
  35 * that has a hidden SSID, and connects beacon and probe response
  36 * entries. For a probe response entry for a hidden SSID, the
  37 * hidden_beacon_bss pointer points to the BSS struct holding the
  38 * beacon's information.
  39 *
  40 * Reference counting is done for all these references except for
  41 * the hidden_list, so that a beacon BSS struct that is otherwise
  42 * not referenced has one reference for being on the bss_list and
  43 * one for each probe response entry that points to it using the
  44 * hidden_beacon_bss pointer. When a BSS struct that has such a
  45 * pointer is get/put, the refcount update is also propagated to
  46 * the referenced struct, this ensure that it cannot get removed
  47 * while somebody is using the probe response version.
  48 *
  49 * Note that the hidden_beacon_bss pointer never changes, due to
  50 * the reference counting. Therefore, no locking is needed for
  51 * it.
  52 *
  53 * Also note that the hidden_beacon_bss pointer is only relevant
  54 * if the driver uses something other than the IEs, e.g. private
  55 * data stored stored in the BSS struct, since the beacon IEs are
  56 * also linked into the probe response struct.
  57 */
  58
  59#define IEEE80211_SCAN_RESULT_EXPIRE	(30 * HZ)
  60
  61static void bss_free(struct cfg80211_internal_bss *bss)
  62{
  63	struct cfg80211_bss_ies *ies;
  64
  65	if (WARN_ON(atomic_read(&bss->hold)))
  66		return;
  67
  68	ies = (void *)rcu_access_pointer(bss->pub.beacon_ies);
  69	if (ies && !bss->pub.hidden_beacon_bss)
  70		kfree_rcu(ies, rcu_head);
  71	ies = (void *)rcu_access_pointer(bss->pub.proberesp_ies);
  72	if (ies)
  73		kfree_rcu(ies, rcu_head);
  74
  75	/*
  76	 * This happens when the module is removed, it doesn't
  77	 * really matter any more save for completeness
  78	 */
  79	if (!list_empty(&bss->hidden_list))
  80		list_del(&bss->hidden_list);
  81
  82	kfree(bss);
  83}
  84
  85static inline void bss_ref_get(struct cfg80211_registered_device *rdev,
  86			       struct cfg80211_internal_bss *bss)
  87{
  88	lockdep_assert_held(&rdev->bss_lock);
  89
  90	bss->refcount++;
  91	if (bss->pub.hidden_beacon_bss) {
  92		bss = container_of(bss->pub.hidden_beacon_bss,
  93				   struct cfg80211_internal_bss,
  94				   pub);
  95		bss->refcount++;
  96	}
  97}
  98
  99static inline void bss_ref_put(struct cfg80211_registered_device *rdev,
 100			       struct cfg80211_internal_bss *bss)
 101{
 102	lockdep_assert_held(&rdev->bss_lock);
 103
 104	if (bss->pub.hidden_beacon_bss) {
 105		struct cfg80211_internal_bss *hbss;
 106		hbss = container_of(bss->pub.hidden_beacon_bss,
 107				    struct cfg80211_internal_bss,
 108				    pub);
 109		hbss->refcount--;
 110		if (hbss->refcount == 0)
 111			bss_free(hbss);
 112	}
 113	bss->refcount--;
 114	if (bss->refcount == 0)
 115		bss_free(bss);
 116}
 117
 118static bool __cfg80211_unlink_bss(struct cfg80211_registered_device *rdev,
 119				  struct cfg80211_internal_bss *bss)
 120{
 121	lockdep_assert_held(&rdev->bss_lock);
 122
 123	if (!list_empty(&bss->hidden_list)) {
 124		/*
 125		 * don't remove the beacon entry if it has
 126		 * probe responses associated with it
 127		 */
 128		if (!bss->pub.hidden_beacon_bss)
 129			return false;
 130		/*
 131		 * if it's a probe response entry break its
 132		 * link to the other entries in the group
 133		 */
 134		list_del_init(&bss->hidden_list);
 135	}
 136
 137	list_del_init(&bss->list);
 138	rb_erase(&bss->rbn, &rdev->bss_tree);
 139	bss_ref_put(rdev, bss);
 140	return true;
 141}
 142
 143static void __cfg80211_bss_expire(struct cfg80211_registered_device *rdev,
 144				  unsigned long expire_time)
 145{
 146	struct cfg80211_internal_bss *bss, *tmp;
 147	bool expired = false;
 148
 149	lockdep_assert_held(&rdev->bss_lock);
 150
 151	list_for_each_entry_safe(bss, tmp, &rdev->bss_list, list) {
 152		if (atomic_read(&bss->hold))
 153			continue;
 154		if (!time_after(expire_time, bss->ts))
 155			continue;
 156
 157		if (__cfg80211_unlink_bss(rdev, bss))
 158			expired = true;
 159	}
 160
 161	if (expired)
 162		rdev->bss_generation++;
 163}
 164
 165void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
 166			   bool send_message)
 167{
 168	struct cfg80211_scan_request *request;
 169	struct wireless_dev *wdev;
 170	struct sk_buff *msg;
 171#ifdef CONFIG_CFG80211_WEXT
 172	union iwreq_data wrqu;
 173#endif
 174
 175	ASSERT_RTNL();
 176
 177	if (rdev->scan_msg) {
 178		nl80211_send_scan_result(rdev, rdev->scan_msg);
 179		rdev->scan_msg = NULL;
 180		return;
 181	}
 182
 183	request = rdev->scan_req;
 184	if (!request)
 185		return;
 186
 187	wdev = request->wdev;
 188
 189	/*
 190	 * This must be before sending the other events!
 191	 * Otherwise, wpa_supplicant gets completely confused with
 192	 * wext events.
 193	 */
 194	if (wdev->netdev)
 195		cfg80211_sme_scan_done(wdev->netdev);
 196
 197	if (!request->aborted &&
 198	    request->flags & NL80211_SCAN_FLAG_FLUSH) {
 199		/* flush entries from previous scans */
 200		spin_lock_bh(&rdev->bss_lock);
 201		__cfg80211_bss_expire(rdev, request->scan_start);
 202		spin_unlock_bh(&rdev->bss_lock);
 203	}
 204
 205	msg = nl80211_build_scan_msg(rdev, wdev, request->aborted);
 206
 207#ifdef CONFIG_CFG80211_WEXT
 208	if (wdev->netdev && !request->aborted) {
 209		memset(&wrqu, 0, sizeof(wrqu));
 210
 211		wireless_send_event(wdev->netdev, SIOCGIWSCAN, &wrqu, NULL);
 212	}
 213#endif
 214
 215	if (wdev->netdev)
 216		dev_put(wdev->netdev);
 217
 218	rdev->scan_req = NULL;
 219	kfree(request);
 220
 221	if (!send_message)
 222		rdev->scan_msg = msg;
 223	else
 224		nl80211_send_scan_result(rdev, msg);
 225}
 226
 227void __cfg80211_scan_done(struct work_struct *wk)
 228{
 229	struct cfg80211_registered_device *rdev;
 230
 231	rdev = container_of(wk, struct cfg80211_registered_device,
 232			    scan_done_wk);
 233
 234	rtnl_lock();
 235	___cfg80211_scan_done(rdev, true);
 236	rtnl_unlock();
 237}
 238
 239void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
 240{
 241	trace_cfg80211_scan_done(request, aborted);
 242	WARN_ON(request != wiphy_to_rdev(request->wiphy)->scan_req);
 243
 244	request->aborted = aborted;
 245	request->notified = true;
 246	queue_work(cfg80211_wq, &wiphy_to_rdev(request->wiphy)->scan_done_wk);
 247}
 248EXPORT_SYMBOL(cfg80211_scan_done);
 249
 250void __cfg80211_sched_scan_results(struct work_struct *wk)
 251{
 252	struct cfg80211_registered_device *rdev;
 253	struct cfg80211_sched_scan_request *request;
 254
 255	rdev = container_of(wk, struct cfg80211_registered_device,
 256			    sched_scan_results_wk);
 257
 258	rtnl_lock();
 259
 260	request = rtnl_dereference(rdev->sched_scan_req);
 261
 262	/* we don't have sched_scan_req anymore if the scan is stopping */
 263	if (request) {
 264		if (request->flags & NL80211_SCAN_FLAG_FLUSH) {
 265			/* flush entries from previous scans */
 266			spin_lock_bh(&rdev->bss_lock);
 267			__cfg80211_bss_expire(rdev, request->scan_start);
 268			spin_unlock_bh(&rdev->bss_lock);
 269			request->scan_start = jiffies;
 
 270		}
 271		nl80211_send_sched_scan_results(rdev, request->dev);
 272	}
 273
 274	rtnl_unlock();
 275}
 276
 277void cfg80211_sched_scan_results(struct wiphy *wiphy)
 278{
 279	trace_cfg80211_sched_scan_results(wiphy);
 280	/* ignore if we're not scanning */
 281
 282	if (rcu_access_pointer(wiphy_to_rdev(wiphy)->sched_scan_req))
 283		queue_work(cfg80211_wq,
 284			   &wiphy_to_rdev(wiphy)->sched_scan_results_wk);
 285}
 286EXPORT_SYMBOL(cfg80211_sched_scan_results);
 287
 288void cfg80211_sched_scan_stopped_rtnl(struct wiphy *wiphy)
 289{
 290	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
 291
 292	ASSERT_RTNL();
 293
 294	trace_cfg80211_sched_scan_stopped(wiphy);
 295
 296	__cfg80211_stop_sched_scan(rdev, true);
 297}
 298EXPORT_SYMBOL(cfg80211_sched_scan_stopped_rtnl);
 299
 300void cfg80211_sched_scan_stopped(struct wiphy *wiphy)
 301{
 302	rtnl_lock();
 303	cfg80211_sched_scan_stopped_rtnl(wiphy);
 304	rtnl_unlock();
 305}
 306EXPORT_SYMBOL(cfg80211_sched_scan_stopped);
 307
 308int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
 309			       bool driver_initiated)
 310{
 311	struct cfg80211_sched_scan_request *sched_scan_req;
 312	struct net_device *dev;
 313
 314	ASSERT_RTNL();
 315
 316	if (!rdev->sched_scan_req)
 317		return -ENOENT;
 318
 319	sched_scan_req = rtnl_dereference(rdev->sched_scan_req);
 320	dev = sched_scan_req->dev;
 321
 322	if (!driver_initiated) {
 323		int err = rdev_sched_scan_stop(rdev, dev);
 324		if (err)
 325			return err;
 326	}
 327
 328	nl80211_send_sched_scan(rdev, dev, NL80211_CMD_SCHED_SCAN_STOPPED);
 329
 330	RCU_INIT_POINTER(rdev->sched_scan_req, NULL);
 331	kfree_rcu(sched_scan_req, rcu_head);
 332
 333	return 0;
 334}
 335
 336void cfg80211_bss_age(struct cfg80211_registered_device *rdev,
 337                      unsigned long age_secs)
 338{
 339	struct cfg80211_internal_bss *bss;
 340	unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC);
 341
 342	spin_lock_bh(&rdev->bss_lock);
 343	list_for_each_entry(bss, &rdev->bss_list, list)
 344		bss->ts -= age_jiffies;
 345	spin_unlock_bh(&rdev->bss_lock);
 346}
 347
 348void cfg80211_bss_expire(struct cfg80211_registered_device *rdev)
 349{
 350	__cfg80211_bss_expire(rdev, jiffies - IEEE80211_SCAN_RESULT_EXPIRE);
 351}
 352
 353const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len)
 354{
 355	while (len > 2 && ies[0] != eid) {
 356		len -= ies[1] + 2;
 357		ies += ies[1] + 2;
 358	}
 359	if (len < 2)
 360		return NULL;
 361	if (len < 2 + ies[1])
 362		return NULL;
 363	return ies;
 364}
 365EXPORT_SYMBOL(cfg80211_find_ie);
 366
 367const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type,
 368				  const u8 *ies, int len)
 369{
 370	struct ieee80211_vendor_ie *ie;
 371	const u8 *pos = ies, *end = ies + len;
 372	int ie_oui;
 373
 374	while (pos < end) {
 375		pos = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, pos,
 376				       end - pos);
 377		if (!pos)
 378			return NULL;
 379
 380		ie = (struct ieee80211_vendor_ie *)pos;
 381
 382		/* make sure we can access ie->len */
 383		BUILD_BUG_ON(offsetof(struct ieee80211_vendor_ie, len) != 1);
 384
 385		if (ie->len < sizeof(*ie))
 386			goto cont;
 387
 388		ie_oui = ie->oui[0] << 16 | ie->oui[1] << 8 | ie->oui[2];
 389		if (ie_oui == oui && ie->oui_type == oui_type)
 390			return pos;
 391cont:
 392		pos += 2 + ie->len;
 393	}
 394	return NULL;
 395}
 396EXPORT_SYMBOL(cfg80211_find_vendor_ie);
 397
 398static bool is_bss(struct cfg80211_bss *a, const u8 *bssid,
 399		   const u8 *ssid, size_t ssid_len)
 400{
 401	const struct cfg80211_bss_ies *ies;
 402	const u8 *ssidie;
 403
 404	if (bssid && !ether_addr_equal(a->bssid, bssid))
 405		return false;
 406
 407	if (!ssid)
 408		return true;
 409
 410	ies = rcu_access_pointer(a->ies);
 411	if (!ies)
 412		return false;
 413	ssidie = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len);
 414	if (!ssidie)
 415		return false;
 416	if (ssidie[1] != ssid_len)
 417		return false;
 418	return memcmp(ssidie + 2, ssid, ssid_len) == 0;
 419}
 420
 421/**
 422 * enum bss_compare_mode - BSS compare mode
 423 * @BSS_CMP_REGULAR: regular compare mode (for insertion and normal find)
 424 * @BSS_CMP_HIDE_ZLEN: find hidden SSID with zero-length mode
 425 * @BSS_CMP_HIDE_NUL: find hidden SSID with NUL-ed out mode
 426 */
 427enum bss_compare_mode {
 428	BSS_CMP_REGULAR,
 429	BSS_CMP_HIDE_ZLEN,
 430	BSS_CMP_HIDE_NUL,
 431};
 432
 433static int cmp_bss(struct cfg80211_bss *a,
 434		   struct cfg80211_bss *b,
 435		   enum bss_compare_mode mode)
 436{
 437	const struct cfg80211_bss_ies *a_ies, *b_ies;
 438	const u8 *ie1 = NULL;
 439	const u8 *ie2 = NULL;
 440	int i, r;
 441
 442	if (a->channel != b->channel)
 443		return b->channel->center_freq - a->channel->center_freq;
 444
 445	a_ies = rcu_access_pointer(a->ies);
 446	if (!a_ies)
 447		return -1;
 448	b_ies = rcu_access_pointer(b->ies);
 449	if (!b_ies)
 450		return 1;
 451
 452	if (WLAN_CAPABILITY_IS_STA_BSS(a->capability))
 453		ie1 = cfg80211_find_ie(WLAN_EID_MESH_ID,
 454				       a_ies->data, a_ies->len);
 455	if (WLAN_CAPABILITY_IS_STA_BSS(b->capability))
 456		ie2 = cfg80211_find_ie(WLAN_EID_MESH_ID,
 457				       b_ies->data, b_ies->len);
 458	if (ie1 && ie2) {
 459		int mesh_id_cmp;
 460
 461		if (ie1[1] == ie2[1])
 462			mesh_id_cmp = memcmp(ie1 + 2, ie2 + 2, ie1[1]);
 463		else
 464			mesh_id_cmp = ie2[1] - ie1[1];
 465
 466		ie1 = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
 467				       a_ies->data, a_ies->len);
 468		ie2 = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
 469				       b_ies->data, b_ies->len);
 470		if (ie1 && ie2) {
 471			if (mesh_id_cmp)
 472				return mesh_id_cmp;
 473			if (ie1[1] != ie2[1])
 474				return ie2[1] - ie1[1];
 475			return memcmp(ie1 + 2, ie2 + 2, ie1[1]);
 476		}
 477	}
 478
 479	r = memcmp(a->bssid, b->bssid, sizeof(a->bssid));
 480	if (r)
 481		return r;
 482
 483	ie1 = cfg80211_find_ie(WLAN_EID_SSID, a_ies->data, a_ies->len);
 484	ie2 = cfg80211_find_ie(WLAN_EID_SSID, b_ies->data, b_ies->len);
 485
 486	if (!ie1 && !ie2)
 487		return 0;
 488
 489	/*
 490	 * Note that with "hide_ssid", the function returns a match if
 491	 * the already-present BSS ("b") is a hidden SSID beacon for
 492	 * the new BSS ("a").
 493	 */
 494
 495	/* sort missing IE before (left of) present IE */
 496	if (!ie1)
 497		return -1;
 498	if (!ie2)
 499		return 1;
 500
 501	switch (mode) {
 502	case BSS_CMP_HIDE_ZLEN:
 503		/*
 504		 * In ZLEN mode we assume the BSS entry we're
 505		 * looking for has a zero-length SSID. So if
 506		 * the one we're looking at right now has that,
 507		 * return 0. Otherwise, return the difference
 508		 * in length, but since we're looking for the
 509		 * 0-length it's really equivalent to returning
 510		 * the length of the one we're looking at.
 511		 *
 512		 * No content comparison is needed as we assume
 513		 * the content length is zero.
 514		 */
 515		return ie2[1];
 516	case BSS_CMP_REGULAR:
 517	default:
 518		/* sort by length first, then by contents */
 519		if (ie1[1] != ie2[1])
 520			return ie2[1] - ie1[1];
 521		return memcmp(ie1 + 2, ie2 + 2, ie1[1]);
 522	case BSS_CMP_HIDE_NUL:
 523		if (ie1[1] != ie2[1])
 524			return ie2[1] - ie1[1];
 525		/* this is equivalent to memcmp(zeroes, ie2 + 2, len) */
 526		for (i = 0; i < ie2[1]; i++)
 527			if (ie2[i + 2])
 528				return -1;
 529		return 0;
 530	}
 531}
 532
 533static bool cfg80211_bss_type_match(u16 capability,
 534				    enum ieee80211_band band,
 535				    enum ieee80211_bss_type bss_type)
 536{
 537	bool ret = true;
 538	u16 mask, val;
 539
 540	if (bss_type == IEEE80211_BSS_TYPE_ANY)
 541		return ret;
 542
 543	if (band == IEEE80211_BAND_60GHZ) {
 544		mask = WLAN_CAPABILITY_DMG_TYPE_MASK;
 545		switch (bss_type) {
 546		case IEEE80211_BSS_TYPE_ESS:
 547			val = WLAN_CAPABILITY_DMG_TYPE_AP;
 548			break;
 549		case IEEE80211_BSS_TYPE_PBSS:
 550			val = WLAN_CAPABILITY_DMG_TYPE_PBSS;
 551			break;
 552		case IEEE80211_BSS_TYPE_IBSS:
 553			val = WLAN_CAPABILITY_DMG_TYPE_IBSS;
 554			break;
 555		default:
 556			return false;
 557		}
 558	} else {
 559		mask = WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS;
 560		switch (bss_type) {
 561		case IEEE80211_BSS_TYPE_ESS:
 562			val = WLAN_CAPABILITY_ESS;
 563			break;
 564		case IEEE80211_BSS_TYPE_IBSS:
 565			val = WLAN_CAPABILITY_IBSS;
 566			break;
 567		case IEEE80211_BSS_TYPE_MBSS:
 568			val = 0;
 569			break;
 570		default:
 571			return false;
 572		}
 573	}
 574
 575	ret = ((capability & mask) == val);
 576	return ret;
 577}
 578
 579/* Returned bss is reference counted and must be cleaned up appropriately. */
 580struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
 581				      struct ieee80211_channel *channel,
 582				      const u8 *bssid,
 583				      const u8 *ssid, size_t ssid_len,
 584				      enum ieee80211_bss_type bss_type,
 585				      enum ieee80211_privacy privacy)
 586{
 587	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
 588	struct cfg80211_internal_bss *bss, *res = NULL;
 589	unsigned long now = jiffies;
 590	int bss_privacy;
 591
 592	trace_cfg80211_get_bss(wiphy, channel, bssid, ssid, ssid_len, bss_type,
 593			       privacy);
 594
 595	spin_lock_bh(&rdev->bss_lock);
 
 596
 597	list_for_each_entry(bss, &rdev->bss_list, list) {
 598		if (!cfg80211_bss_type_match(bss->pub.capability,
 599					     bss->pub.channel->band, bss_type))
 600			continue;
 601
 602		bss_privacy = (bss->pub.capability & WLAN_CAPABILITY_PRIVACY);
 603		if ((privacy == IEEE80211_PRIVACY_ON && !bss_privacy) ||
 604		    (privacy == IEEE80211_PRIVACY_OFF && bss_privacy))
 605			continue;
 606		if (channel && bss->pub.channel != channel)
 607			continue;
 608		if (!is_valid_ether_addr(bss->pub.bssid))
 609			continue;
 610		/* Don't get expired BSS structs */
 611		if (time_after(now, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE) &&
 612		    !atomic_read(&bss->hold))
 613			continue;
 614		if (is_bss(&bss->pub, bssid, ssid, ssid_len)) {
 615			res = bss;
 616			bss_ref_get(rdev, res);
 617			break;
 618		}
 619	}
 620
 621	spin_unlock_bh(&rdev->bss_lock);
 622	if (!res)
 623		return NULL;
 624	trace_cfg80211_return_bss(&res->pub);
 625	return &res->pub;
 626}
 627EXPORT_SYMBOL(cfg80211_get_bss);
 628
 629static void rb_insert_bss(struct cfg80211_registered_device *rdev,
 630			  struct cfg80211_internal_bss *bss)
 631{
 632	struct rb_node **p = &rdev->bss_tree.rb_node;
 633	struct rb_node *parent = NULL;
 634	struct cfg80211_internal_bss *tbss;
 635	int cmp;
 636
 637	while (*p) {
 638		parent = *p;
 639		tbss = rb_entry(parent, struct cfg80211_internal_bss, rbn);
 640
 641		cmp = cmp_bss(&bss->pub, &tbss->pub, BSS_CMP_REGULAR);
 642
 643		if (WARN_ON(!cmp)) {
 644			/* will sort of leak this BSS */
 645			return;
 646		}
 647
 648		if (cmp < 0)
 649			p = &(*p)->rb_left;
 650		else
 651			p = &(*p)->rb_right;
 652	}
 653
 654	rb_link_node(&bss->rbn, parent, p);
 655	rb_insert_color(&bss->rbn, &rdev->bss_tree);
 656}
 657
 658static struct cfg80211_internal_bss *
 659rb_find_bss(struct cfg80211_registered_device *rdev,
 660	    struct cfg80211_internal_bss *res,
 661	    enum bss_compare_mode mode)
 662{
 663	struct rb_node *n = rdev->bss_tree.rb_node;
 664	struct cfg80211_internal_bss *bss;
 665	int r;
 666
 667	while (n) {
 668		bss = rb_entry(n, struct cfg80211_internal_bss, rbn);
 669		r = cmp_bss(&res->pub, &bss->pub, mode);
 670
 671		if (r == 0)
 672			return bss;
 673		else if (r < 0)
 674			n = n->rb_left;
 675		else
 676			n = n->rb_right;
 677	}
 678
 679	return NULL;
 680}
 681
 682static bool cfg80211_combine_bsses(struct cfg80211_registered_device *rdev,
 683				   struct cfg80211_internal_bss *new)
 684{
 685	const struct cfg80211_bss_ies *ies;
 686	struct cfg80211_internal_bss *bss;
 687	const u8 *ie;
 688	int i, ssidlen;
 689	u8 fold = 0;
 690
 691	ies = rcu_access_pointer(new->pub.beacon_ies);
 692	if (WARN_ON(!ies))
 693		return false;
 694
 695	ie = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len);
 696	if (!ie) {
 697		/* nothing to do */
 698		return true;
 699	}
 700
 701	ssidlen = ie[1];
 702	for (i = 0; i < ssidlen; i++)
 703		fold |= ie[2 + i];
 704
 705	if (fold) {
 706		/* not a hidden SSID */
 707		return true;
 708	}
 709
 710	/* This is the bad part ... */
 711
 712	list_for_each_entry(bss, &rdev->bss_list, list) {
 713		if (!ether_addr_equal(bss->pub.bssid, new->pub.bssid))
 714			continue;
 715		if (bss->pub.channel != new->pub.channel)
 716			continue;
 717		if (bss->pub.scan_width != new->pub.scan_width)
 718			continue;
 719		if (rcu_access_pointer(bss->pub.beacon_ies))
 720			continue;
 721		ies = rcu_access_pointer(bss->pub.ies);
 722		if (!ies)
 723			continue;
 724		ie = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len);
 725		if (!ie)
 726			continue;
 727		if (ssidlen && ie[1] != ssidlen)
 728			continue;
 729		if (WARN_ON_ONCE(bss->pub.hidden_beacon_bss))
 730			continue;
 731		if (WARN_ON_ONCE(!list_empty(&bss->hidden_list)))
 732			list_del(&bss->hidden_list);
 733		/* combine them */
 734		list_add(&bss->hidden_list, &new->hidden_list);
 735		bss->pub.hidden_beacon_bss = &new->pub;
 736		new->refcount += bss->refcount;
 737		rcu_assign_pointer(bss->pub.beacon_ies,
 738				   new->pub.beacon_ies);
 739	}
 740
 741	return true;
 742}
 743
 744/* Returned bss is reference counted and must be cleaned up appropriately. */
 745static struct cfg80211_internal_bss *
 746cfg80211_bss_update(struct cfg80211_registered_device *rdev,
 747		    struct cfg80211_internal_bss *tmp,
 748		    bool signal_valid)
 749{
 750	struct cfg80211_internal_bss *found = NULL;
 751
 752	if (WARN_ON(!tmp->pub.channel))
 753		return NULL;
 754
 755	tmp->ts = jiffies;
 756
 757	spin_lock_bh(&rdev->bss_lock);
 758
 759	if (WARN_ON(!rcu_access_pointer(tmp->pub.ies))) {
 760		spin_unlock_bh(&rdev->bss_lock);
 761		return NULL;
 762	}
 763
 764	found = rb_find_bss(rdev, tmp, BSS_CMP_REGULAR);
 765
 766	if (found) {
 767		/* Update IEs */
 768		if (rcu_access_pointer(tmp->pub.proberesp_ies)) {
 769			const struct cfg80211_bss_ies *old;
 770
 771			old = rcu_access_pointer(found->pub.proberesp_ies);
 772
 773			rcu_assign_pointer(found->pub.proberesp_ies,
 774					   tmp->pub.proberesp_ies);
 775			/* Override possible earlier Beacon frame IEs */
 776			rcu_assign_pointer(found->pub.ies,
 777					   tmp->pub.proberesp_ies);
 778			if (old)
 779				kfree_rcu((struct cfg80211_bss_ies *)old,
 780					  rcu_head);
 781		} else if (rcu_access_pointer(tmp->pub.beacon_ies)) {
 782			const struct cfg80211_bss_ies *old;
 783			struct cfg80211_internal_bss *bss;
 784
 785			if (found->pub.hidden_beacon_bss &&
 786			    !list_empty(&found->hidden_list)) {
 787				const struct cfg80211_bss_ies *f;
 788
 789				/*
 790				 * The found BSS struct is one of the probe
 791				 * response members of a group, but we're
 792				 * receiving a beacon (beacon_ies in the tmp
 793				 * bss is used). This can only mean that the
 794				 * AP changed its beacon from not having an
 795				 * SSID to showing it, which is confusing so
 796				 * drop this information.
 797				 */
 798
 799				f = rcu_access_pointer(tmp->pub.beacon_ies);
 800				kfree_rcu((struct cfg80211_bss_ies *)f,
 801					  rcu_head);
 802				goto drop;
 803			}
 804
 805			old = rcu_access_pointer(found->pub.beacon_ies);
 806
 807			rcu_assign_pointer(found->pub.beacon_ies,
 808					   tmp->pub.beacon_ies);
 809
 810			/* Override IEs if they were from a beacon before */
 811			if (old == rcu_access_pointer(found->pub.ies))
 812				rcu_assign_pointer(found->pub.ies,
 813						   tmp->pub.beacon_ies);
 814
 815			/* Assign beacon IEs to all sub entries */
 816			list_for_each_entry(bss, &found->hidden_list,
 817					    hidden_list) {
 818				const struct cfg80211_bss_ies *ies;
 819
 820				ies = rcu_access_pointer(bss->pub.beacon_ies);
 821				WARN_ON(ies != old);
 822
 823				rcu_assign_pointer(bss->pub.beacon_ies,
 824						   tmp->pub.beacon_ies);
 825			}
 826
 827			if (old)
 828				kfree_rcu((struct cfg80211_bss_ies *)old,
 829					  rcu_head);
 830		}
 831
 832		found->pub.beacon_interval = tmp->pub.beacon_interval;
 833		/*
 834		 * don't update the signal if beacon was heard on
 835		 * adjacent channel.
 836		 */
 837		if (signal_valid)
 838			found->pub.signal = tmp->pub.signal;
 839		found->pub.capability = tmp->pub.capability;
 840		found->ts = tmp->ts;
 841		found->ts_boottime = tmp->ts_boottime;
 842	} else {
 843		struct cfg80211_internal_bss *new;
 844		struct cfg80211_internal_bss *hidden;
 845		struct cfg80211_bss_ies *ies;
 846
 847		/*
 848		 * create a copy -- the "res" variable that is passed in
 849		 * is allocated on the stack since it's not needed in the
 850		 * more common case of an update
 851		 */
 852		new = kzalloc(sizeof(*new) + rdev->wiphy.bss_priv_size,
 853			      GFP_ATOMIC);
 854		if (!new) {
 855			ies = (void *)rcu_dereference(tmp->pub.beacon_ies);
 856			if (ies)
 857				kfree_rcu(ies, rcu_head);
 858			ies = (void *)rcu_dereference(tmp->pub.proberesp_ies);
 859			if (ies)
 860				kfree_rcu(ies, rcu_head);
 861			goto drop;
 862		}
 863		memcpy(new, tmp, sizeof(*new));
 864		new->refcount = 1;
 865		INIT_LIST_HEAD(&new->hidden_list);
 866
 867		if (rcu_access_pointer(tmp->pub.proberesp_ies)) {
 868			hidden = rb_find_bss(rdev, tmp, BSS_CMP_HIDE_ZLEN);
 869			if (!hidden)
 870				hidden = rb_find_bss(rdev, tmp,
 871						     BSS_CMP_HIDE_NUL);
 872			if (hidden) {
 873				new->pub.hidden_beacon_bss = &hidden->pub;
 874				list_add(&new->hidden_list,
 875					 &hidden->hidden_list);
 876				hidden->refcount++;
 877				rcu_assign_pointer(new->pub.beacon_ies,
 878						   hidden->pub.beacon_ies);
 879			}
 880		} else {
 881			/*
 882			 * Ok so we found a beacon, and don't have an entry. If
 883			 * it's a beacon with hidden SSID, we might be in for an
 884			 * expensive search for any probe responses that should
 885			 * be grouped with this beacon for updates ...
 886			 */
 887			if (!cfg80211_combine_bsses(rdev, new)) {
 888				kfree(new);
 889				goto drop;
 890			}
 891		}
 892
 893		list_add_tail(&new->list, &rdev->bss_list);
 894		rb_insert_bss(rdev, new);
 895		found = new;
 896	}
 897
 898	rdev->bss_generation++;
 899	bss_ref_get(rdev, found);
 900	spin_unlock_bh(&rdev->bss_lock);
 901
 902	return found;
 903 drop:
 904	spin_unlock_bh(&rdev->bss_lock);
 905	return NULL;
 906}
 907
 908static struct ieee80211_channel *
 909cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen,
 910			 struct ieee80211_channel *channel)
 911{
 912	const u8 *tmp;
 913	u32 freq;
 914	int channel_number = -1;
 915
 916	tmp = cfg80211_find_ie(WLAN_EID_DS_PARAMS, ie, ielen);
 917	if (tmp && tmp[1] == 1) {
 918		channel_number = tmp[2];
 919	} else {
 920		tmp = cfg80211_find_ie(WLAN_EID_HT_OPERATION, ie, ielen);
 921		if (tmp && tmp[1] >= sizeof(struct ieee80211_ht_operation)) {
 922			struct ieee80211_ht_operation *htop = (void *)(tmp + 2);
 923
 924			channel_number = htop->primary_chan;
 925		}
 926	}
 927
 928	if (channel_number < 0)
 929		return channel;
 930
 931	freq = ieee80211_channel_to_frequency(channel_number, channel->band);
 932	channel = ieee80211_get_channel(wiphy, freq);
 933	if (!channel)
 934		return NULL;
 935	if (channel->flags & IEEE80211_CHAN_DISABLED)
 936		return NULL;
 937	return channel;
 938}
 939
 940/* Returned bss is reference counted and must be cleaned up appropriately. */
 941struct cfg80211_bss *
 942cfg80211_inform_bss_data(struct wiphy *wiphy,
 943			 struct cfg80211_inform_bss *data,
 944			 enum cfg80211_bss_frame_type ftype,
 945			 const u8 *bssid, u64 tsf, u16 capability,
 946			 u16 beacon_interval, const u8 *ie, size_t ielen,
 947			 gfp_t gfp)
 948{
 949	struct cfg80211_bss_ies *ies;
 950	struct ieee80211_channel *channel;
 951	struct cfg80211_internal_bss tmp = {}, *res;
 952	int bss_type;
 953	bool signal_valid;
 954
 955	if (WARN_ON(!wiphy))
 956		return NULL;
 957
 958	if (WARN_ON(wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
 959		    (data->signal < 0 || data->signal > 100)))
 960		return NULL;
 961
 962	channel = cfg80211_get_bss_channel(wiphy, ie, ielen, data->chan);
 963	if (!channel)
 964		return NULL;
 965
 966	memcpy(tmp.pub.bssid, bssid, ETH_ALEN);
 967	tmp.pub.channel = channel;
 968	tmp.pub.scan_width = data->scan_width;
 969	tmp.pub.signal = data->signal;
 970	tmp.pub.beacon_interval = beacon_interval;
 971	tmp.pub.capability = capability;
 972	tmp.ts_boottime = data->boottime_ns;
 973
 974	/*
 975	 * If we do not know here whether the IEs are from a Beacon or Probe
 976	 * Response frame, we need to pick one of the options and only use it
 977	 * with the driver that does not provide the full Beacon/Probe Response
 978	 * frame. Use Beacon frame pointer to avoid indicating that this should
 979	 * override the IEs pointer should we have received an earlier
 980	 * indication of Probe Response data.
 981	 */
 982	ies = kzalloc(sizeof(*ies) + ielen, gfp);
 983	if (!ies)
 984		return NULL;
 985	ies->len = ielen;
 986	ies->tsf = tsf;
 987	ies->from_beacon = false;
 988	memcpy(ies->data, ie, ielen);
 989
 990	switch (ftype) {
 991	case CFG80211_BSS_FTYPE_BEACON:
 992		ies->from_beacon = true;
 993		/* fall through to assign */
 994	case CFG80211_BSS_FTYPE_UNKNOWN:
 995		rcu_assign_pointer(tmp.pub.beacon_ies, ies);
 996		break;
 997	case CFG80211_BSS_FTYPE_PRESP:
 998		rcu_assign_pointer(tmp.pub.proberesp_ies, ies);
 999		break;
1000	}
1001	rcu_assign_pointer(tmp.pub.ies, ies);
1002
1003	signal_valid = abs(data->chan->center_freq - channel->center_freq) <=
1004		wiphy->max_adj_channel_rssi_comp;
1005	res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid);
1006	if (!res)
1007		return NULL;
1008
1009	if (channel->band == IEEE80211_BAND_60GHZ) {
1010		bss_type = res->pub.capability & WLAN_CAPABILITY_DMG_TYPE_MASK;
1011		if (bss_type == WLAN_CAPABILITY_DMG_TYPE_AP ||
1012		    bss_type == WLAN_CAPABILITY_DMG_TYPE_PBSS)
1013			regulatory_hint_found_beacon(wiphy, channel, gfp);
1014	} else {
1015		if (res->pub.capability & WLAN_CAPABILITY_ESS)
1016			regulatory_hint_found_beacon(wiphy, channel, gfp);
1017	}
1018
1019	trace_cfg80211_return_bss(&res->pub);
1020	/* cfg80211_bss_update gives us a referenced result */
1021	return &res->pub;
1022}
1023EXPORT_SYMBOL(cfg80211_inform_bss_data);
1024
1025/* cfg80211_inform_bss_width_frame helper */
1026struct cfg80211_bss *
1027cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
1028			       struct cfg80211_inform_bss *data,
1029			       struct ieee80211_mgmt *mgmt, size_t len,
1030			       gfp_t gfp)
1031
1032{
1033	struct cfg80211_internal_bss tmp = {}, *res;
1034	struct cfg80211_bss_ies *ies;
1035	struct ieee80211_channel *channel;
1036	bool signal_valid;
1037	size_t ielen = len - offsetof(struct ieee80211_mgmt,
1038				      u.probe_resp.variable);
1039	int bss_type;
1040
1041	BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) !=
1042			offsetof(struct ieee80211_mgmt, u.beacon.variable));
1043
1044	trace_cfg80211_inform_bss_frame(wiphy, data, mgmt, len);
 
1045
1046	if (WARN_ON(!mgmt))
1047		return NULL;
1048
1049	if (WARN_ON(!wiphy))
1050		return NULL;
1051
1052	if (WARN_ON(wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
1053		    (data->signal < 0 || data->signal > 100)))
1054		return NULL;
1055
1056	if (WARN_ON(len < offsetof(struct ieee80211_mgmt, u.probe_resp.variable)))
1057		return NULL;
1058
1059	channel = cfg80211_get_bss_channel(wiphy, mgmt->u.beacon.variable,
1060					   ielen, data->chan);
1061	if (!channel)
1062		return NULL;
1063
1064	ies = kzalloc(sizeof(*ies) + ielen, gfp);
1065	if (!ies)
1066		return NULL;
1067	ies->len = ielen;
1068	ies->tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
1069	ies->from_beacon = ieee80211_is_beacon(mgmt->frame_control);
1070	memcpy(ies->data, mgmt->u.probe_resp.variable, ielen);
1071
1072	if (ieee80211_is_probe_resp(mgmt->frame_control))
1073		rcu_assign_pointer(tmp.pub.proberesp_ies, ies);
1074	else
1075		rcu_assign_pointer(tmp.pub.beacon_ies, ies);
1076	rcu_assign_pointer(tmp.pub.ies, ies);
1077	
1078	memcpy(tmp.pub.bssid, mgmt->bssid, ETH_ALEN);
1079	tmp.pub.channel = channel;
1080	tmp.pub.scan_width = data->scan_width;
1081	tmp.pub.signal = data->signal;
1082	tmp.pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
1083	tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
1084	tmp.ts_boottime = data->boottime_ns;
1085
1086	signal_valid = abs(data->chan->center_freq - channel->center_freq) <=
1087		wiphy->max_adj_channel_rssi_comp;
1088	res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid);
1089	if (!res)
1090		return NULL;
1091
1092	if (channel->band == IEEE80211_BAND_60GHZ) {
1093		bss_type = res->pub.capability & WLAN_CAPABILITY_DMG_TYPE_MASK;
1094		if (bss_type == WLAN_CAPABILITY_DMG_TYPE_AP ||
1095		    bss_type == WLAN_CAPABILITY_DMG_TYPE_PBSS)
1096			regulatory_hint_found_beacon(wiphy, channel, gfp);
1097	} else {
1098		if (res->pub.capability & WLAN_CAPABILITY_ESS)
1099			regulatory_hint_found_beacon(wiphy, channel, gfp);
1100	}
1101
1102	trace_cfg80211_return_bss(&res->pub);
1103	/* cfg80211_bss_update gives us a referenced result */
1104	return &res->pub;
1105}
1106EXPORT_SYMBOL(cfg80211_inform_bss_frame_data);
1107
1108void cfg80211_ref_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
1109{
1110	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
1111	struct cfg80211_internal_bss *bss;
1112
1113	if (!pub)
1114		return;
1115
1116	bss = container_of(pub, struct cfg80211_internal_bss, pub);
1117
1118	spin_lock_bh(&rdev->bss_lock);
1119	bss_ref_get(rdev, bss);
1120	spin_unlock_bh(&rdev->bss_lock);
1121}
1122EXPORT_SYMBOL(cfg80211_ref_bss);
1123
1124void cfg80211_put_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
1125{
1126	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
1127	struct cfg80211_internal_bss *bss;
1128
1129	if (!pub)
1130		return;
1131
1132	bss = container_of(pub, struct cfg80211_internal_bss, pub);
1133
1134	spin_lock_bh(&rdev->bss_lock);
1135	bss_ref_put(rdev, bss);
1136	spin_unlock_bh(&rdev->bss_lock);
1137}
1138EXPORT_SYMBOL(cfg80211_put_bss);
1139
1140void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
1141{
1142	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
1143	struct cfg80211_internal_bss *bss;
1144
1145	if (WARN_ON(!pub))
1146		return;
1147
1148	bss = container_of(pub, struct cfg80211_internal_bss, pub);
1149
1150	spin_lock_bh(&rdev->bss_lock);
1151	if (!list_empty(&bss->list)) {
1152		if (__cfg80211_unlink_bss(rdev, bss))
1153			rdev->bss_generation++;
1154	}
1155	spin_unlock_bh(&rdev->bss_lock);
1156}
1157EXPORT_SYMBOL(cfg80211_unlink_bss);
1158
1159#ifdef CONFIG_CFG80211_WEXT
1160static struct cfg80211_registered_device *
1161cfg80211_get_dev_from_ifindex(struct net *net, int ifindex)
1162{
1163	struct cfg80211_registered_device *rdev;
1164	struct net_device *dev;
1165
1166	ASSERT_RTNL();
1167
1168	dev = dev_get_by_index(net, ifindex);
1169	if (!dev)
1170		return ERR_PTR(-ENODEV);
1171	if (dev->ieee80211_ptr)
1172		rdev = wiphy_to_rdev(dev->ieee80211_ptr->wiphy);
1173	else
1174		rdev = ERR_PTR(-ENODEV);
1175	dev_put(dev);
1176	return rdev;
1177}
1178
1179int cfg80211_wext_siwscan(struct net_device *dev,
1180			  struct iw_request_info *info,
1181			  union iwreq_data *wrqu, char *extra)
1182{
1183	struct cfg80211_registered_device *rdev;
1184	struct wiphy *wiphy;
1185	struct iw_scan_req *wreq = NULL;
1186	struct cfg80211_scan_request *creq = NULL;
1187	int i, err, n_channels = 0;
1188	enum ieee80211_band band;
1189
1190	if (!netif_running(dev))
1191		return -ENETDOWN;
1192
1193	if (wrqu->data.length == sizeof(struct iw_scan_req))
1194		wreq = (struct iw_scan_req *)extra;
1195
1196	rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex);
1197
1198	if (IS_ERR(rdev))
1199		return PTR_ERR(rdev);
1200
1201	if (rdev->scan_req || rdev->scan_msg) {
1202		err = -EBUSY;
1203		goto out;
1204	}
1205
1206	wiphy = &rdev->wiphy;
1207
1208	/* Determine number of channels, needed to allocate creq */
1209	if (wreq && wreq->num_channels)
1210		n_channels = wreq->num_channels;
1211	else
1212		n_channels = ieee80211_get_num_supported_channels(wiphy);
1213
1214	creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) +
1215		       n_channels * sizeof(void *),
1216		       GFP_ATOMIC);
1217	if (!creq) {
1218		err = -ENOMEM;
1219		goto out;
1220	}
1221
1222	creq->wiphy = wiphy;
1223	creq->wdev = dev->ieee80211_ptr;
1224	/* SSIDs come after channels */
1225	creq->ssids = (void *)&creq->channels[n_channels];
1226	creq->n_channels = n_channels;
1227	creq->n_ssids = 1;
1228	creq->scan_start = jiffies;
1229
1230	/* translate "Scan on frequencies" request */
1231	i = 0;
1232	for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
1233		int j;
1234
1235		if (!wiphy->bands[band])
1236			continue;
1237
1238		for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
1239			/* ignore disabled channels */
1240			if (wiphy->bands[band]->channels[j].flags &
1241						IEEE80211_CHAN_DISABLED)
1242				continue;
1243
1244			/* If we have a wireless request structure and the
1245			 * wireless request specifies frequencies, then search
1246			 * for the matching hardware channel.
1247			 */
1248			if (wreq && wreq->num_channels) {
1249				int k;
1250				int wiphy_freq = wiphy->bands[band]->channels[j].center_freq;
1251				for (k = 0; k < wreq->num_channels; k++) {
1252					struct iw_freq *freq =
1253						&wreq->channel_list[k];
1254					int wext_freq =
1255						cfg80211_wext_freq(freq);
1256
1257					if (wext_freq == wiphy_freq)
1258						goto wext_freq_found;
1259				}
1260				goto wext_freq_not_found;
1261			}
1262
1263		wext_freq_found:
1264			creq->channels[i] = &wiphy->bands[band]->channels[j];
1265			i++;
1266		wext_freq_not_found: ;
1267		}
1268	}
1269	/* No channels found? */
1270	if (!i) {
1271		err = -EINVAL;
1272		goto out;
1273	}
1274
1275	/* Set real number of channels specified in creq->channels[] */
1276	creq->n_channels = i;
1277
1278	/* translate "Scan for SSID" request */
1279	if (wreq) {
1280		if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
1281			if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) {
1282				err = -EINVAL;
1283				goto out;
1284			}
1285			memcpy(creq->ssids[0].ssid, wreq->essid, wreq->essid_len);
1286			creq->ssids[0].ssid_len = wreq->essid_len;
1287		}
1288		if (wreq->scan_type == IW_SCAN_TYPE_PASSIVE)
1289			creq->n_ssids = 0;
1290	}
1291
1292	for (i = 0; i < IEEE80211_NUM_BANDS; i++)
1293		if (wiphy->bands[i])
1294			creq->rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1;
1295
1296	rdev->scan_req = creq;
1297	err = rdev_scan(rdev, creq);
1298	if (err) {
1299		rdev->scan_req = NULL;
1300		/* creq will be freed below */
1301	} else {
1302		nl80211_send_scan_start(rdev, dev->ieee80211_ptr);
1303		/* creq now owned by driver */
1304		creq = NULL;
1305		dev_hold(dev);
1306	}
1307 out:
1308	kfree(creq);
1309	return err;
1310}
1311EXPORT_WEXT_HANDLER(cfg80211_wext_siwscan);
1312
1313static char *ieee80211_scan_add_ies(struct iw_request_info *info,
1314				    const struct cfg80211_bss_ies *ies,
1315				    char *current_ev, char *end_buf)
1316{
1317	const u8 *pos, *end, *next;
1318	struct iw_event iwe;
1319
1320	if (!ies)
1321		return current_ev;
1322
1323	/*
1324	 * If needed, fragment the IEs buffer (at IE boundaries) into short
1325	 * enough fragments to fit into IW_GENERIC_IE_MAX octet messages.
1326	 */
1327	pos = ies->data;
1328	end = pos + ies->len;
1329
1330	while (end - pos > IW_GENERIC_IE_MAX) {
1331		next = pos + 2 + pos[1];
1332		while (next + 2 + next[1] - pos < IW_GENERIC_IE_MAX)
1333			next = next + 2 + next[1];
1334
1335		memset(&iwe, 0, sizeof(iwe));
1336		iwe.cmd = IWEVGENIE;
1337		iwe.u.data.length = next - pos;
1338		current_ev = iwe_stream_add_point_check(info, current_ev,
1339							end_buf, &iwe,
1340							(void *)pos);
1341		if (IS_ERR(current_ev))
1342			return current_ev;
1343		pos = next;
1344	}
1345
1346	if (end > pos) {
1347		memset(&iwe, 0, sizeof(iwe));
1348		iwe.cmd = IWEVGENIE;
1349		iwe.u.data.length = end - pos;
1350		current_ev = iwe_stream_add_point_check(info, current_ev,
1351							end_buf, &iwe,
1352							(void *)pos);
1353		if (IS_ERR(current_ev))
1354			return current_ev;
1355	}
1356
1357	return current_ev;
1358}
1359
1360static char *
1361ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
1362	      struct cfg80211_internal_bss *bss, char *current_ev,
1363	      char *end_buf)
1364{
1365	const struct cfg80211_bss_ies *ies;
1366	struct iw_event iwe;
1367	const u8 *ie;
1368	u8 buf[50];
1369	u8 *cfg, *p, *tmp;
1370	int rem, i, sig;
1371	bool ismesh = false;
1372
1373	memset(&iwe, 0, sizeof(iwe));
1374	iwe.cmd = SIOCGIWAP;
1375	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
1376	memcpy(iwe.u.ap_addr.sa_data, bss->pub.bssid, ETH_ALEN);
1377	current_ev = iwe_stream_add_event_check(info, current_ev, end_buf, &iwe,
1378						IW_EV_ADDR_LEN);
1379	if (IS_ERR(current_ev))
1380		return current_ev;
1381
1382	memset(&iwe, 0, sizeof(iwe));
1383	iwe.cmd = SIOCGIWFREQ;
1384	iwe.u.freq.m = ieee80211_frequency_to_channel(bss->pub.channel->center_freq);
1385	iwe.u.freq.e = 0;
1386	current_ev = iwe_stream_add_event_check(info, current_ev, end_buf, &iwe,
1387						IW_EV_FREQ_LEN);
1388	if (IS_ERR(current_ev))
1389		return current_ev;
1390
1391	memset(&iwe, 0, sizeof(iwe));
1392	iwe.cmd = SIOCGIWFREQ;
1393	iwe.u.freq.m = bss->pub.channel->center_freq;
1394	iwe.u.freq.e = 6;
1395	current_ev = iwe_stream_add_event_check(info, current_ev, end_buf, &iwe,
1396						IW_EV_FREQ_LEN);
1397	if (IS_ERR(current_ev))
1398		return current_ev;
1399
1400	if (wiphy->signal_type != CFG80211_SIGNAL_TYPE_NONE) {
1401		memset(&iwe, 0, sizeof(iwe));
1402		iwe.cmd = IWEVQUAL;
1403		iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED |
1404				     IW_QUAL_NOISE_INVALID |
1405				     IW_QUAL_QUAL_UPDATED;
1406		switch (wiphy->signal_type) {
1407		case CFG80211_SIGNAL_TYPE_MBM:
1408			sig = bss->pub.signal / 100;
1409			iwe.u.qual.level = sig;
1410			iwe.u.qual.updated |= IW_QUAL_DBM;
1411			if (sig < -110)		/* rather bad */
1412				sig = -110;
1413			else if (sig > -40)	/* perfect */
1414				sig = -40;
1415			/* will give a range of 0 .. 70 */
1416			iwe.u.qual.qual = sig + 110;
1417			break;
1418		case CFG80211_SIGNAL_TYPE_UNSPEC:
1419			iwe.u.qual.level = bss->pub.signal;
1420			/* will give range 0 .. 100 */
1421			iwe.u.qual.qual = bss->pub.signal;
1422			break;
1423		default:
1424			/* not reached */
1425			break;
1426		}
1427		current_ev = iwe_stream_add_event_check(info, current_ev,
1428							end_buf, &iwe,
1429							IW_EV_QUAL_LEN);
1430		if (IS_ERR(current_ev))
1431			return current_ev;
1432	}
1433
1434	memset(&iwe, 0, sizeof(iwe));
1435	iwe.cmd = SIOCGIWENCODE;
1436	if (bss->pub.capability & WLAN_CAPABILITY_PRIVACY)
1437		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
1438	else
1439		iwe.u.data.flags = IW_ENCODE_DISABLED;
1440	iwe.u.data.length = 0;
1441	current_ev = iwe_stream_add_point_check(info, current_ev, end_buf,
1442						&iwe, "");
1443	if (IS_ERR(current_ev))
1444		return current_ev;
1445
1446	rcu_read_lock();
1447	ies = rcu_dereference(bss->pub.ies);
1448	rem = ies->len;
1449	ie = ies->data;
1450
1451	while (rem >= 2) {
1452		/* invalid data */
1453		if (ie[1] > rem - 2)
1454			break;
1455
1456		switch (ie[0]) {
1457		case WLAN_EID_SSID:
1458			memset(&iwe, 0, sizeof(iwe));
1459			iwe.cmd = SIOCGIWESSID;
1460			iwe.u.data.length = ie[1];
1461			iwe.u.data.flags = 1;
1462			current_ev = iwe_stream_add_point_check(info,
1463								current_ev,
1464								end_buf, &iwe,
1465								(u8 *)ie + 2);
1466			if (IS_ERR(current_ev))
1467				goto unlock;
1468			break;
1469		case WLAN_EID_MESH_ID:
1470			memset(&iwe, 0, sizeof(iwe));
1471			iwe.cmd = SIOCGIWESSID;
1472			iwe.u.data.length = ie[1];
1473			iwe.u.data.flags = 1;
1474			current_ev = iwe_stream_add_point_check(info,
1475								current_ev,
1476								end_buf, &iwe,
1477								(u8 *)ie + 2);
1478			if (IS_ERR(current_ev))
1479				goto unlock;
1480			break;
1481		case WLAN_EID_MESH_CONFIG:
1482			ismesh = true;
1483			if (ie[1] != sizeof(struct ieee80211_meshconf_ie))
1484				break;
 
 
 
1485			cfg = (u8 *)ie + 2;
1486			memset(&iwe, 0, sizeof(iwe));
1487			iwe.cmd = IWEVCUSTOM;
1488			sprintf(buf, "Mesh Network Path Selection Protocol ID: "
1489				"0x%02X", cfg[0]);
1490			iwe.u.data.length = strlen(buf);
1491			current_ev = iwe_stream_add_point_check(info,
1492								current_ev,
1493								end_buf,
1494								&iwe, buf);
1495			if (IS_ERR(current_ev))
1496				goto unlock;
1497			sprintf(buf, "Path Selection Metric ID: 0x%02X",
1498				cfg[1]);
1499			iwe.u.data.length = strlen(buf);
1500			current_ev = iwe_stream_add_point_check(info,
1501								current_ev,
1502								end_buf,
1503								&iwe, buf);
1504			if (IS_ERR(current_ev))
1505				goto unlock;
1506			sprintf(buf, "Congestion Control Mode ID: 0x%02X",
1507				cfg[2]);
1508			iwe.u.data.length = strlen(buf);
1509			current_ev = iwe_stream_add_point_check(info,
1510								current_ev,
1511								end_buf,
1512								&iwe, buf);
1513			if (IS_ERR(current_ev))
1514				goto unlock;
1515			sprintf(buf, "Synchronization ID: 0x%02X", cfg[3]);
1516			iwe.u.data.length = strlen(buf);
1517			current_ev = iwe_stream_add_point_check(info,
1518								current_ev,
1519								end_buf,
1520								&iwe, buf);
1521			if (IS_ERR(current_ev))
1522				goto unlock;
1523			sprintf(buf, "Authentication ID: 0x%02X", cfg[4]);
1524			iwe.u.data.length = strlen(buf);
1525			current_ev = iwe_stream_add_point_check(info,
1526								current_ev,
1527								end_buf,
1528								&iwe, buf);
1529			if (IS_ERR(current_ev))
1530				goto unlock;
1531			sprintf(buf, "Formation Info: 0x%02X", cfg[5]);
1532			iwe.u.data.length = strlen(buf);
1533			current_ev = iwe_stream_add_point_check(info,
1534								current_ev,
1535								end_buf,
1536								&iwe, buf);
1537			if (IS_ERR(current_ev))
1538				goto unlock;
1539			sprintf(buf, "Capabilities: 0x%02X", cfg[6]);
1540			iwe.u.data.length = strlen(buf);
1541			current_ev = iwe_stream_add_point_check(info,
1542								current_ev,
1543								end_buf,
1544								&iwe, buf);
1545			if (IS_ERR(current_ev))
1546				goto unlock;
1547			break;
1548		case WLAN_EID_SUPP_RATES:
1549		case WLAN_EID_EXT_SUPP_RATES:
1550			/* display all supported rates in readable format */
1551			p = current_ev + iwe_stream_lcp_len(info);
1552
1553			memset(&iwe, 0, sizeof(iwe));
1554			iwe.cmd = SIOCGIWRATE;
1555			/* Those two flags are ignored... */
1556			iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
1557
1558			for (i = 0; i < ie[1]; i++) {
1559				iwe.u.bitrate.value =
1560					((ie[i + 2] & 0x7f) * 500000);
1561				tmp = p;
1562				p = iwe_stream_add_value(info, current_ev, p,
1563							 end_buf, &iwe,
1564							 IW_EV_PARAM_LEN);
1565				if (p == tmp) {
1566					current_ev = ERR_PTR(-E2BIG);
1567					goto unlock;
1568				}
1569			}
1570			current_ev = p;
1571			break;
1572		}
1573		rem -= ie[1] + 2;
1574		ie += ie[1] + 2;
1575	}
1576
1577	if (bss->pub.capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS) ||
1578	    ismesh) {
1579		memset(&iwe, 0, sizeof(iwe));
1580		iwe.cmd = SIOCGIWMODE;
1581		if (ismesh)
1582			iwe.u.mode = IW_MODE_MESH;
1583		else if (bss->pub.capability & WLAN_CAPABILITY_ESS)
1584			iwe.u.mode = IW_MODE_MASTER;
1585		else
1586			iwe.u.mode = IW_MODE_ADHOC;
1587		current_ev = iwe_stream_add_event_check(info, current_ev,
1588							end_buf, &iwe,
1589							IW_EV_UINT_LEN);
1590		if (IS_ERR(current_ev))
1591			goto unlock;
1592	}
1593
1594	memset(&iwe, 0, sizeof(iwe));
1595	iwe.cmd = IWEVCUSTOM;
1596	sprintf(buf, "tsf=%016llx", (unsigned long long)(ies->tsf));
1597	iwe.u.data.length = strlen(buf);
1598	current_ev = iwe_stream_add_point_check(info, current_ev, end_buf,
1599						&iwe, buf);
1600	if (IS_ERR(current_ev))
1601		goto unlock;
1602	memset(&iwe, 0, sizeof(iwe));
1603	iwe.cmd = IWEVCUSTOM;
1604	sprintf(buf, " Last beacon: %ums ago",
1605		elapsed_jiffies_msecs(bss->ts));
1606	iwe.u.data.length = strlen(buf);
1607	current_ev = iwe_stream_add_point_check(info, current_ev,
1608						end_buf, &iwe, buf);
1609	if (IS_ERR(current_ev))
1610		goto unlock;
1611
1612	current_ev = ieee80211_scan_add_ies(info, ies, current_ev, end_buf);
 
1613
1614 unlock:
1615	rcu_read_unlock();
1616	return current_ev;
1617}
1618
1619
1620static int ieee80211_scan_results(struct cfg80211_registered_device *rdev,
1621				  struct iw_request_info *info,
1622				  char *buf, size_t len)
1623{
1624	char *current_ev = buf;
1625	char *end_buf = buf + len;
1626	struct cfg80211_internal_bss *bss;
1627	int err = 0;
1628
1629	spin_lock_bh(&rdev->bss_lock);
1630	cfg80211_bss_expire(rdev);
1631
1632	list_for_each_entry(bss, &rdev->bss_list, list) {
1633		if (buf + len - current_ev <= IW_EV_ADDR_LEN) {
1634			err = -E2BIG;
1635			break;
1636		}
1637		current_ev = ieee80211_bss(&rdev->wiphy, info, bss,
1638					   current_ev, end_buf);
1639		if (IS_ERR(current_ev)) {
1640			err = PTR_ERR(current_ev);
1641			break;
1642		}
1643	}
1644	spin_unlock_bh(&rdev->bss_lock);
1645
1646	if (err)
1647		return err;
1648	return current_ev - buf;
1649}
1650
1651
1652int cfg80211_wext_giwscan(struct net_device *dev,
1653			  struct iw_request_info *info,
1654			  struct iw_point *data, char *extra)
1655{
1656	struct cfg80211_registered_device *rdev;
1657	int res;
1658
1659	if (!netif_running(dev))
1660		return -ENETDOWN;
1661
1662	rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex);
1663
1664	if (IS_ERR(rdev))
1665		return PTR_ERR(rdev);
1666
1667	if (rdev->scan_req || rdev->scan_msg)
1668		return -EAGAIN;
1669
1670	res = ieee80211_scan_results(rdev, info, extra, data->length);
1671	data->length = 0;
1672	if (res >= 0) {
1673		data->length = res;
1674		res = 0;
1675	}
1676
1677	return res;
1678}
1679EXPORT_WEXT_HANDLER(cfg80211_wext_giwscan);
1680#endif