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