1 // SPDX-License-Identifier: GPL-2.0
3 * cfg80211 scan result handling
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-2019 Intel Corporation
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>
18 #include <net/cfg80211.h>
19 #include <net/cfg80211-wext.h>
20 #include <net/iw_handler.h>
23 #include "wext-compat.h"
27 * DOC: BSS tree/list structure
29 * At the top level, the BSS list is kept in both a list in each
30 * registered device (@bss_list) as well as an RB-tree for faster
31 * lookup. In the RB-tree, entries can be looked up using their
32 * channel, MESHID, MESHCONF (for MBSSes) or channel, BSSID, SSID
35 * Due to the possibility of hidden SSIDs, there's a second level
36 * structure, the "hidden_list" and "hidden_beacon_bss" pointer.
37 * The hidden_list connects all BSSes belonging to a single AP
38 * that has a hidden SSID, and connects beacon and probe response
39 * entries. For a probe response entry for a hidden SSID, the
40 * hidden_beacon_bss pointer points to the BSS struct holding the
41 * beacon's information.
43 * Reference counting is done for all these references except for
44 * the hidden_list, so that a beacon BSS struct that is otherwise
45 * not referenced has one reference for being on the bss_list and
46 * one for each probe response entry that points to it using the
47 * hidden_beacon_bss pointer. When a BSS struct that has such a
48 * pointer is get/put, the refcount update is also propagated to
49 * the referenced struct, this ensure that it cannot get removed
50 * while somebody is using the probe response version.
52 * Note that the hidden_beacon_bss pointer never changes, due to
53 * the reference counting. Therefore, no locking is needed for
56 * Also note that the hidden_beacon_bss pointer is only relevant
57 * if the driver uses something other than the IEs, e.g. private
58 * data stored stored in the BSS struct, since the beacon IEs are
59 * also linked into the probe response struct.
63 * Limit the number of BSS entries stored in mac80211. Each one is
64 * a bit over 4k at most, so this limits to roughly 4-5M of memory.
65 * If somebody wants to really attack this though, they'd likely
66 * use small beacons, and only one type of frame, limiting each of
67 * the entries to a much smaller size (in order to generate more
68 * entries in total, so overhead is bigger.)
70 static int bss_entries_limit = 1000;
71 module_param(bss_entries_limit, int, 0644);
72 MODULE_PARM_DESC(bss_entries_limit,
73 "limit to number of scan BSS entries (per wiphy, default 1000)");
75 #define IEEE80211_SCAN_RESULT_EXPIRE (30 * HZ)
77 static void bss_free(struct cfg80211_internal_bss *bss)
79 struct cfg80211_bss_ies *ies;
81 if (WARN_ON(atomic_read(&bss->hold)))
84 ies = (void *)rcu_access_pointer(bss->pub.beacon_ies);
85 if (ies && !bss->pub.hidden_beacon_bss)
86 kfree_rcu(ies, rcu_head);
87 ies = (void *)rcu_access_pointer(bss->pub.proberesp_ies);
89 kfree_rcu(ies, rcu_head);
92 * This happens when the module is removed, it doesn't
93 * really matter any more save for completeness
95 if (!list_empty(&bss->hidden_list))
96 list_del(&bss->hidden_list);
101 static inline void bss_ref_get(struct cfg80211_registered_device *rdev,
102 struct cfg80211_internal_bss *bss)
104 lockdep_assert_held(&rdev->bss_lock);
107 if (bss->pub.hidden_beacon_bss) {
108 bss = container_of(bss->pub.hidden_beacon_bss,
109 struct cfg80211_internal_bss,
113 if (bss->pub.transmitted_bss) {
114 bss = container_of(bss->pub.transmitted_bss,
115 struct cfg80211_internal_bss,
121 static inline void bss_ref_put(struct cfg80211_registered_device *rdev,
122 struct cfg80211_internal_bss *bss)
124 lockdep_assert_held(&rdev->bss_lock);
126 if (bss->pub.hidden_beacon_bss) {
127 struct cfg80211_internal_bss *hbss;
128 hbss = container_of(bss->pub.hidden_beacon_bss,
129 struct cfg80211_internal_bss,
132 if (hbss->refcount == 0)
136 if (bss->pub.transmitted_bss) {
137 struct cfg80211_internal_bss *tbss;
139 tbss = container_of(bss->pub.transmitted_bss,
140 struct cfg80211_internal_bss,
143 if (tbss->refcount == 0)
148 if (bss->refcount == 0)
152 static bool __cfg80211_unlink_bss(struct cfg80211_registered_device *rdev,
153 struct cfg80211_internal_bss *bss)
155 lockdep_assert_held(&rdev->bss_lock);
157 if (!list_empty(&bss->hidden_list)) {
159 * don't remove the beacon entry if it has
160 * probe responses associated with it
162 if (!bss->pub.hidden_beacon_bss)
165 * if it's a probe response entry break its
166 * link to the other entries in the group
168 list_del_init(&bss->hidden_list);
171 list_del_init(&bss->list);
172 list_del_init(&bss->pub.nontrans_list);
173 rb_erase(&bss->rbn, &rdev->bss_tree);
175 WARN_ONCE((rdev->bss_entries == 0) ^ list_empty(&rdev->bss_list),
176 "rdev bss entries[%d]/list[empty:%d] corruption\n",
177 rdev->bss_entries, list_empty(&rdev->bss_list));
178 bss_ref_put(rdev, bss);
182 bool cfg80211_is_element_inherited(const struct element *elem,
183 const struct element *non_inherit_elem)
185 u8 id_len, ext_id_len, i, loop_len, id;
188 if (elem->id == WLAN_EID_MULTIPLE_BSSID)
191 if (!non_inherit_elem || non_inherit_elem->datalen < 2)
195 * non inheritance element format is:
196 * ext ID (56) | IDs list len | list | extension IDs list len | list
197 * Both lists are optional. Both lengths are mandatory.
198 * This means valid length is:
199 * elem_len = 1 (extension ID) + 2 (list len fields) + list lengths
201 id_len = non_inherit_elem->data[1];
202 if (non_inherit_elem->datalen < 3 + id_len)
205 ext_id_len = non_inherit_elem->data[2 + id_len];
206 if (non_inherit_elem->datalen < 3 + id_len + ext_id_len)
209 if (elem->id == WLAN_EID_EXTENSION) {
212 loop_len = ext_id_len;
213 list = &non_inherit_elem->data[3 + id_len];
219 list = &non_inherit_elem->data[2];
223 for (i = 0; i < loop_len; i++) {
230 EXPORT_SYMBOL(cfg80211_is_element_inherited);
232 static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
233 const u8 *subelement, size_t subie_len,
234 u8 *new_ie, gfp_t gfp)
237 const u8 *tmp_old, *tmp_new;
238 const struct element *non_inherit_elem;
241 /* copy subelement as we need to change its content to
242 * mark an ie after it is processed.
244 sub_copy = kmemdup(subelement, subie_len, gfp);
251 tmp_new = cfg80211_find_ie(WLAN_EID_SSID, sub_copy, subie_len);
253 memcpy(pos, tmp_new, tmp_new[1] + 2);
254 pos += (tmp_new[1] + 2);
257 /* get non inheritance list if exists */
259 cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
260 sub_copy, subie_len);
262 /* go through IEs in ie (skip SSID) and subelement,
263 * merge them into new_ie
265 tmp_old = cfg80211_find_ie(WLAN_EID_SSID, ie, ielen);
266 tmp_old = (tmp_old) ? tmp_old + tmp_old[1] + 2 : ie;
268 while (tmp_old + tmp_old[1] + 2 - ie <= ielen) {
269 if (tmp_old[0] == 0) {
274 if (tmp_old[0] == WLAN_EID_EXTENSION)
275 tmp = (u8 *)cfg80211_find_ext_ie(tmp_old[2], sub_copy,
278 tmp = (u8 *)cfg80211_find_ie(tmp_old[0], sub_copy,
282 const struct element *old_elem = (void *)tmp_old;
284 /* ie in old ie but not in subelement */
285 if (cfg80211_is_element_inherited(old_elem,
287 memcpy(pos, tmp_old, tmp_old[1] + 2);
288 pos += tmp_old[1] + 2;
291 /* ie in transmitting ie also in subelement,
292 * copy from subelement and flag the ie in subelement
293 * as copied (by setting eid field to WLAN_EID_SSID,
294 * which is skipped anyway).
295 * For vendor ie, compare OUI + type + subType to
296 * determine if they are the same ie.
298 if (tmp_old[0] == WLAN_EID_VENDOR_SPECIFIC) {
299 if (!memcmp(tmp_old + 2, tmp + 2, 5)) {
300 /* same vendor ie, copy from
303 memcpy(pos, tmp, tmp[1] + 2);
305 tmp[0] = WLAN_EID_SSID;
307 memcpy(pos, tmp_old, tmp_old[1] + 2);
308 pos += tmp_old[1] + 2;
311 /* copy ie from subelement into new ie */
312 memcpy(pos, tmp, tmp[1] + 2);
314 tmp[0] = WLAN_EID_SSID;
318 if (tmp_old + tmp_old[1] + 2 - ie == ielen)
321 tmp_old += tmp_old[1] + 2;
324 /* go through subelement again to check if there is any ie not
325 * copied to new ie, skip ssid, capability, bssid-index ie
328 while (tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) {
329 if (!(tmp_new[0] == WLAN_EID_NON_TX_BSSID_CAP ||
330 tmp_new[0] == WLAN_EID_SSID)) {
331 memcpy(pos, tmp_new, tmp_new[1] + 2);
332 pos += tmp_new[1] + 2;
334 if (tmp_new + tmp_new[1] + 2 - sub_copy == subie_len)
336 tmp_new += tmp_new[1] + 2;
343 static bool is_bss(struct cfg80211_bss *a, const u8 *bssid,
344 const u8 *ssid, size_t ssid_len)
346 const struct cfg80211_bss_ies *ies;
349 if (bssid && !ether_addr_equal(a->bssid, bssid))
355 ies = rcu_access_pointer(a->ies);
358 ssidie = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len);
361 if (ssidie[1] != ssid_len)
363 return memcmp(ssidie + 2, ssid, ssid_len) == 0;
367 cfg80211_add_nontrans_list(struct cfg80211_bss *trans_bss,
368 struct cfg80211_bss *nontrans_bss)
372 struct cfg80211_bss *bss = NULL;
375 ssid = ieee80211_bss_get_ie(nontrans_bss, WLAN_EID_SSID);
383 /* check if nontrans_bss is in the list */
384 list_for_each_entry(bss, &trans_bss->nontrans_list, nontrans_list) {
385 if (is_bss(bss, nontrans_bss->bssid, ssid, ssid_len)) {
393 /* add to the list */
394 list_add_tail(&nontrans_bss->nontrans_list, &trans_bss->nontrans_list);
398 static void __cfg80211_bss_expire(struct cfg80211_registered_device *rdev,
399 unsigned long expire_time)
401 struct cfg80211_internal_bss *bss, *tmp;
402 bool expired = false;
404 lockdep_assert_held(&rdev->bss_lock);
406 list_for_each_entry_safe(bss, tmp, &rdev->bss_list, list) {
407 if (atomic_read(&bss->hold))
409 if (!time_after(expire_time, bss->ts))
412 if (__cfg80211_unlink_bss(rdev, bss))
417 rdev->bss_generation++;
420 static bool cfg80211_bss_expire_oldest(struct cfg80211_registered_device *rdev)
422 struct cfg80211_internal_bss *bss, *oldest = NULL;
425 lockdep_assert_held(&rdev->bss_lock);
427 list_for_each_entry(bss, &rdev->bss_list, list) {
428 if (atomic_read(&bss->hold))
431 if (!list_empty(&bss->hidden_list) &&
432 !bss->pub.hidden_beacon_bss)
435 if (oldest && time_before(oldest->ts, bss->ts))
440 if (WARN_ON(!oldest))
444 * The callers make sure to increase rdev->bss_generation if anything
445 * gets removed (and a new entry added), so there's no need to also do
449 ret = __cfg80211_unlink_bss(rdev, oldest);
454 void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
457 struct cfg80211_scan_request *request;
458 struct wireless_dev *wdev;
460 #ifdef CONFIG_CFG80211_WEXT
461 union iwreq_data wrqu;
466 if (rdev->scan_msg) {
467 nl80211_send_scan_msg(rdev, rdev->scan_msg);
468 rdev->scan_msg = NULL;
472 request = rdev->scan_req;
476 wdev = request->wdev;
479 * This must be before sending the other events!
480 * Otherwise, wpa_supplicant gets completely confused with
484 cfg80211_sme_scan_done(wdev->netdev);
486 if (!request->info.aborted &&
487 request->flags & NL80211_SCAN_FLAG_FLUSH) {
488 /* flush entries from previous scans */
489 spin_lock_bh(&rdev->bss_lock);
490 __cfg80211_bss_expire(rdev, request->scan_start);
491 spin_unlock_bh(&rdev->bss_lock);
494 msg = nl80211_build_scan_msg(rdev, wdev, request->info.aborted);
496 #ifdef CONFIG_CFG80211_WEXT
497 if (wdev->netdev && !request->info.aborted) {
498 memset(&wrqu, 0, sizeof(wrqu));
500 wireless_send_event(wdev->netdev, SIOCGIWSCAN, &wrqu, NULL);
505 dev_put(wdev->netdev);
507 rdev->scan_req = NULL;
511 rdev->scan_msg = msg;
513 nl80211_send_scan_msg(rdev, msg);
516 void __cfg80211_scan_done(struct work_struct *wk)
518 struct cfg80211_registered_device *rdev;
520 rdev = container_of(wk, struct cfg80211_registered_device,
524 ___cfg80211_scan_done(rdev, true);
528 void cfg80211_scan_done(struct cfg80211_scan_request *request,
529 struct cfg80211_scan_info *info)
531 trace_cfg80211_scan_done(request, info);
532 WARN_ON(request != wiphy_to_rdev(request->wiphy)->scan_req);
534 request->info = *info;
535 request->notified = true;
536 queue_work(cfg80211_wq, &wiphy_to_rdev(request->wiphy)->scan_done_wk);
538 EXPORT_SYMBOL(cfg80211_scan_done);
540 void cfg80211_add_sched_scan_req(struct cfg80211_registered_device *rdev,
541 struct cfg80211_sched_scan_request *req)
545 list_add_rcu(&req->list, &rdev->sched_scan_req_list);
548 static void cfg80211_del_sched_scan_req(struct cfg80211_registered_device *rdev,
549 struct cfg80211_sched_scan_request *req)
553 list_del_rcu(&req->list);
554 kfree_rcu(req, rcu_head);
557 static struct cfg80211_sched_scan_request *
558 cfg80211_find_sched_scan_req(struct cfg80211_registered_device *rdev, u64 reqid)
560 struct cfg80211_sched_scan_request *pos;
562 WARN_ON_ONCE(!rcu_read_lock_held() && !lockdep_rtnl_is_held());
564 list_for_each_entry_rcu(pos, &rdev->sched_scan_req_list, list) {
565 if (pos->reqid == reqid)
572 * Determines if a scheduled scan request can be handled. When a legacy
573 * scheduled scan is running no other scheduled scan is allowed regardless
574 * whether the request is for legacy or multi-support scan. When a multi-support
575 * scheduled scan is running a request for legacy scan is not allowed. In this
576 * case a request for multi-support scan can be handled if resources are
577 * available, ie. struct wiphy::max_sched_scan_reqs limit is not yet reached.
579 int cfg80211_sched_scan_req_possible(struct cfg80211_registered_device *rdev,
582 struct cfg80211_sched_scan_request *pos;
585 list_for_each_entry(pos, &rdev->sched_scan_req_list, list) {
586 /* request id zero means legacy in progress */
587 if (!i && !pos->reqid)
593 /* no legacy allowed when multi request(s) are active */
597 /* resource limit reached */
598 if (i == rdev->wiphy.max_sched_scan_reqs)
604 void cfg80211_sched_scan_results_wk(struct work_struct *work)
606 struct cfg80211_registered_device *rdev;
607 struct cfg80211_sched_scan_request *req, *tmp;
609 rdev = container_of(work, struct cfg80211_registered_device,
613 list_for_each_entry_safe(req, tmp, &rdev->sched_scan_req_list, list) {
614 if (req->report_results) {
615 req->report_results = false;
616 if (req->flags & NL80211_SCAN_FLAG_FLUSH) {
617 /* flush entries from previous scans */
618 spin_lock_bh(&rdev->bss_lock);
619 __cfg80211_bss_expire(rdev, req->scan_start);
620 spin_unlock_bh(&rdev->bss_lock);
621 req->scan_start = jiffies;
623 nl80211_send_sched_scan(req,
624 NL80211_CMD_SCHED_SCAN_RESULTS);
630 void cfg80211_sched_scan_results(struct wiphy *wiphy, u64 reqid)
632 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
633 struct cfg80211_sched_scan_request *request;
635 trace_cfg80211_sched_scan_results(wiphy, reqid);
636 /* ignore if we're not scanning */
639 request = cfg80211_find_sched_scan_req(rdev, reqid);
641 request->report_results = true;
642 queue_work(cfg80211_wq, &rdev->sched_scan_res_wk);
646 EXPORT_SYMBOL(cfg80211_sched_scan_results);
648 void cfg80211_sched_scan_stopped_rtnl(struct wiphy *wiphy, u64 reqid)
650 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
654 trace_cfg80211_sched_scan_stopped(wiphy, reqid);
656 __cfg80211_stop_sched_scan(rdev, reqid, true);
658 EXPORT_SYMBOL(cfg80211_sched_scan_stopped_rtnl);
660 void cfg80211_sched_scan_stopped(struct wiphy *wiphy, u64 reqid)
663 cfg80211_sched_scan_stopped_rtnl(wiphy, reqid);
666 EXPORT_SYMBOL(cfg80211_sched_scan_stopped);
668 int cfg80211_stop_sched_scan_req(struct cfg80211_registered_device *rdev,
669 struct cfg80211_sched_scan_request *req,
670 bool driver_initiated)
674 if (!driver_initiated) {
675 int err = rdev_sched_scan_stop(rdev, req->dev, req->reqid);
680 nl80211_send_sched_scan(req, NL80211_CMD_SCHED_SCAN_STOPPED);
682 cfg80211_del_sched_scan_req(rdev, req);
687 int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
688 u64 reqid, bool driver_initiated)
690 struct cfg80211_sched_scan_request *sched_scan_req;
694 sched_scan_req = cfg80211_find_sched_scan_req(rdev, reqid);
698 return cfg80211_stop_sched_scan_req(rdev, sched_scan_req,
702 void cfg80211_bss_age(struct cfg80211_registered_device *rdev,
703 unsigned long age_secs)
705 struct cfg80211_internal_bss *bss;
706 unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC);
708 spin_lock_bh(&rdev->bss_lock);
709 list_for_each_entry(bss, &rdev->bss_list, list)
710 bss->ts -= age_jiffies;
711 spin_unlock_bh(&rdev->bss_lock);
714 void cfg80211_bss_expire(struct cfg80211_registered_device *rdev)
716 __cfg80211_bss_expire(rdev, jiffies - IEEE80211_SCAN_RESULT_EXPIRE);
719 const struct element *
720 cfg80211_find_elem_match(u8 eid, const u8 *ies, unsigned int len,
721 const u8 *match, unsigned int match_len,
722 unsigned int match_offset)
724 const struct element *elem;
726 for_each_element_id(elem, eid, ies, len) {
727 if (elem->datalen >= match_offset + match_len &&
728 !memcmp(elem->data + match_offset, match, match_len))
734 EXPORT_SYMBOL(cfg80211_find_elem_match);
736 const struct element *cfg80211_find_vendor_elem(unsigned int oui, int oui_type,
740 const struct element *elem;
741 u8 match[] = { oui >> 16, oui >> 8, oui, oui_type };
742 int match_len = (oui_type < 0) ? 3 : sizeof(match);
744 if (WARN_ON(oui_type > 0xff))
747 elem = cfg80211_find_elem_match(WLAN_EID_VENDOR_SPECIFIC, ies, len,
748 match, match_len, 0);
750 if (!elem || elem->datalen < 4)
755 EXPORT_SYMBOL(cfg80211_find_vendor_elem);
758 * enum bss_compare_mode - BSS compare mode
759 * @BSS_CMP_REGULAR: regular compare mode (for insertion and normal find)
760 * @BSS_CMP_HIDE_ZLEN: find hidden SSID with zero-length mode
761 * @BSS_CMP_HIDE_NUL: find hidden SSID with NUL-ed out mode
763 enum bss_compare_mode {
769 static int cmp_bss(struct cfg80211_bss *a,
770 struct cfg80211_bss *b,
771 enum bss_compare_mode mode)
773 const struct cfg80211_bss_ies *a_ies, *b_ies;
774 const u8 *ie1 = NULL;
775 const u8 *ie2 = NULL;
778 if (a->channel != b->channel)
779 return b->channel->center_freq - a->channel->center_freq;
781 a_ies = rcu_access_pointer(a->ies);
784 b_ies = rcu_access_pointer(b->ies);
788 if (WLAN_CAPABILITY_IS_STA_BSS(a->capability))
789 ie1 = cfg80211_find_ie(WLAN_EID_MESH_ID,
790 a_ies->data, a_ies->len);
791 if (WLAN_CAPABILITY_IS_STA_BSS(b->capability))
792 ie2 = cfg80211_find_ie(WLAN_EID_MESH_ID,
793 b_ies->data, b_ies->len);
797 if (ie1[1] == ie2[1])
798 mesh_id_cmp = memcmp(ie1 + 2, ie2 + 2, ie1[1]);
800 mesh_id_cmp = ie2[1] - ie1[1];
802 ie1 = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
803 a_ies->data, a_ies->len);
804 ie2 = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
805 b_ies->data, b_ies->len);
809 if (ie1[1] != ie2[1])
810 return ie2[1] - ie1[1];
811 return memcmp(ie1 + 2, ie2 + 2, ie1[1]);
815 r = memcmp(a->bssid, b->bssid, sizeof(a->bssid));
819 ie1 = cfg80211_find_ie(WLAN_EID_SSID, a_ies->data, a_ies->len);
820 ie2 = cfg80211_find_ie(WLAN_EID_SSID, b_ies->data, b_ies->len);
826 * Note that with "hide_ssid", the function returns a match if
827 * the already-present BSS ("b") is a hidden SSID beacon for
831 /* sort missing IE before (left of) present IE */
838 case BSS_CMP_HIDE_ZLEN:
840 * In ZLEN mode we assume the BSS entry we're
841 * looking for has a zero-length SSID. So if
842 * the one we're looking at right now has that,
843 * return 0. Otherwise, return the difference
844 * in length, but since we're looking for the
845 * 0-length it's really equivalent to returning
846 * the length of the one we're looking at.
848 * No content comparison is needed as we assume
849 * the content length is zero.
852 case BSS_CMP_REGULAR:
854 /* sort by length first, then by contents */
855 if (ie1[1] != ie2[1])
856 return ie2[1] - ie1[1];
857 return memcmp(ie1 + 2, ie2 + 2, ie1[1]);
858 case BSS_CMP_HIDE_NUL:
859 if (ie1[1] != ie2[1])
860 return ie2[1] - ie1[1];
861 /* this is equivalent to memcmp(zeroes, ie2 + 2, len) */
862 for (i = 0; i < ie2[1]; i++)
869 static bool cfg80211_bss_type_match(u16 capability,
870 enum nl80211_band band,
871 enum ieee80211_bss_type bss_type)
876 if (bss_type == IEEE80211_BSS_TYPE_ANY)
879 if (band == NL80211_BAND_60GHZ) {
880 mask = WLAN_CAPABILITY_DMG_TYPE_MASK;
882 case IEEE80211_BSS_TYPE_ESS:
883 val = WLAN_CAPABILITY_DMG_TYPE_AP;
885 case IEEE80211_BSS_TYPE_PBSS:
886 val = WLAN_CAPABILITY_DMG_TYPE_PBSS;
888 case IEEE80211_BSS_TYPE_IBSS:
889 val = WLAN_CAPABILITY_DMG_TYPE_IBSS;
895 mask = WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS;
897 case IEEE80211_BSS_TYPE_ESS:
898 val = WLAN_CAPABILITY_ESS;
900 case IEEE80211_BSS_TYPE_IBSS:
901 val = WLAN_CAPABILITY_IBSS;
903 case IEEE80211_BSS_TYPE_MBSS:
911 ret = ((capability & mask) == val);
915 /* Returned bss is reference counted and must be cleaned up appropriately. */
916 struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
917 struct ieee80211_channel *channel,
919 const u8 *ssid, size_t ssid_len,
920 enum ieee80211_bss_type bss_type,
921 enum ieee80211_privacy privacy)
923 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
924 struct cfg80211_internal_bss *bss, *res = NULL;
925 unsigned long now = jiffies;
928 trace_cfg80211_get_bss(wiphy, channel, bssid, ssid, ssid_len, bss_type,
931 spin_lock_bh(&rdev->bss_lock);
933 list_for_each_entry(bss, &rdev->bss_list, list) {
934 if (!cfg80211_bss_type_match(bss->pub.capability,
935 bss->pub.channel->band, bss_type))
938 bss_privacy = (bss->pub.capability & WLAN_CAPABILITY_PRIVACY);
939 if ((privacy == IEEE80211_PRIVACY_ON && !bss_privacy) ||
940 (privacy == IEEE80211_PRIVACY_OFF && bss_privacy))
942 if (channel && bss->pub.channel != channel)
944 if (!is_valid_ether_addr(bss->pub.bssid))
946 /* Don't get expired BSS structs */
947 if (time_after(now, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE) &&
948 !atomic_read(&bss->hold))
950 if (is_bss(&bss->pub, bssid, ssid, ssid_len)) {
952 bss_ref_get(rdev, res);
957 spin_unlock_bh(&rdev->bss_lock);
960 trace_cfg80211_return_bss(&res->pub);
963 EXPORT_SYMBOL(cfg80211_get_bss);
965 static void rb_insert_bss(struct cfg80211_registered_device *rdev,
966 struct cfg80211_internal_bss *bss)
968 struct rb_node **p = &rdev->bss_tree.rb_node;
969 struct rb_node *parent = NULL;
970 struct cfg80211_internal_bss *tbss;
975 tbss = rb_entry(parent, struct cfg80211_internal_bss, rbn);
977 cmp = cmp_bss(&bss->pub, &tbss->pub, BSS_CMP_REGULAR);
980 /* will sort of leak this BSS */
990 rb_link_node(&bss->rbn, parent, p);
991 rb_insert_color(&bss->rbn, &rdev->bss_tree);
994 static struct cfg80211_internal_bss *
995 rb_find_bss(struct cfg80211_registered_device *rdev,
996 struct cfg80211_internal_bss *res,
997 enum bss_compare_mode mode)
999 struct rb_node *n = rdev->bss_tree.rb_node;
1000 struct cfg80211_internal_bss *bss;
1004 bss = rb_entry(n, struct cfg80211_internal_bss, rbn);
1005 r = cmp_bss(&res->pub, &bss->pub, mode);
1018 static bool cfg80211_combine_bsses(struct cfg80211_registered_device *rdev,
1019 struct cfg80211_internal_bss *new)
1021 const struct cfg80211_bss_ies *ies;
1022 struct cfg80211_internal_bss *bss;
1028 ies = rcu_access_pointer(new->pub.beacon_ies);
1032 ie = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len);
1039 for (i = 0; i < ssidlen; i++)
1043 /* not a hidden SSID */
1047 /* This is the bad part ... */
1049 list_for_each_entry(bss, &rdev->bss_list, list) {
1051 * we're iterating all the entries anyway, so take the
1052 * opportunity to validate the list length accounting
1056 if (!ether_addr_equal(bss->pub.bssid, new->pub.bssid))
1058 if (bss->pub.channel != new->pub.channel)
1060 if (bss->pub.scan_width != new->pub.scan_width)
1062 if (rcu_access_pointer(bss->pub.beacon_ies))
1064 ies = rcu_access_pointer(bss->pub.ies);
1067 ie = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len);
1070 if (ssidlen && ie[1] != ssidlen)
1072 if (WARN_ON_ONCE(bss->pub.hidden_beacon_bss))
1074 if (WARN_ON_ONCE(!list_empty(&bss->hidden_list)))
1075 list_del(&bss->hidden_list);
1077 list_add(&bss->hidden_list, &new->hidden_list);
1078 bss->pub.hidden_beacon_bss = &new->pub;
1079 new->refcount += bss->refcount;
1080 rcu_assign_pointer(bss->pub.beacon_ies,
1081 new->pub.beacon_ies);
1084 WARN_ONCE(n_entries != rdev->bss_entries,
1085 "rdev bss entries[%d]/list[len:%d] corruption\n",
1086 rdev->bss_entries, n_entries);
1091 struct cfg80211_non_tx_bss {
1092 struct cfg80211_bss *tx_bss;
1093 u8 max_bssid_indicator;
1098 cfg80211_update_known_bss(struct cfg80211_registered_device *rdev,
1099 struct cfg80211_internal_bss *known,
1100 struct cfg80211_internal_bss *new,
1103 lockdep_assert_held(&rdev->bss_lock);
1106 if (rcu_access_pointer(new->pub.proberesp_ies)) {
1107 const struct cfg80211_bss_ies *old;
1109 old = rcu_access_pointer(known->pub.proberesp_ies);
1111 rcu_assign_pointer(known->pub.proberesp_ies,
1112 new->pub.proberesp_ies);
1113 /* Override possible earlier Beacon frame IEs */
1114 rcu_assign_pointer(known->pub.ies,
1115 new->pub.proberesp_ies);
1117 kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
1118 } else if (rcu_access_pointer(new->pub.beacon_ies)) {
1119 const struct cfg80211_bss_ies *old;
1120 struct cfg80211_internal_bss *bss;
1122 if (known->pub.hidden_beacon_bss &&
1123 !list_empty(&known->hidden_list)) {
1124 const struct cfg80211_bss_ies *f;
1126 /* The known BSS struct is one of the probe
1127 * response members of a group, but we're
1128 * receiving a beacon (beacon_ies in the new
1129 * bss is used). This can only mean that the
1130 * AP changed its beacon from not having an
1131 * SSID to showing it, which is confusing so
1132 * drop this information.
1135 f = rcu_access_pointer(new->pub.beacon_ies);
1136 kfree_rcu((struct cfg80211_bss_ies *)f, rcu_head);
1140 old = rcu_access_pointer(known->pub.beacon_ies);
1142 rcu_assign_pointer(known->pub.beacon_ies, new->pub.beacon_ies);
1144 /* Override IEs if they were from a beacon before */
1145 if (old == rcu_access_pointer(known->pub.ies))
1146 rcu_assign_pointer(known->pub.ies, new->pub.beacon_ies);
1148 /* Assign beacon IEs to all sub entries */
1149 list_for_each_entry(bss, &known->hidden_list, hidden_list) {
1150 const struct cfg80211_bss_ies *ies;
1152 ies = rcu_access_pointer(bss->pub.beacon_ies);
1153 WARN_ON(ies != old);
1155 rcu_assign_pointer(bss->pub.beacon_ies,
1156 new->pub.beacon_ies);
1160 kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
1163 known->pub.beacon_interval = new->pub.beacon_interval;
1165 /* don't update the signal if beacon was heard on
1169 known->pub.signal = new->pub.signal;
1170 known->pub.capability = new->pub.capability;
1171 known->ts = new->ts;
1172 known->ts_boottime = new->ts_boottime;
1173 known->parent_tsf = new->parent_tsf;
1174 known->pub.chains = new->pub.chains;
1175 memcpy(known->pub.chain_signal, new->pub.chain_signal,
1176 IEEE80211_MAX_CHAINS);
1177 ether_addr_copy(known->parent_bssid, new->parent_bssid);
1178 known->pub.max_bssid_indicator = new->pub.max_bssid_indicator;
1179 known->pub.bssid_index = new->pub.bssid_index;
1184 /* Returned bss is reference counted and must be cleaned up appropriately. */
1185 struct cfg80211_internal_bss *
1186 cfg80211_bss_update(struct cfg80211_registered_device *rdev,
1187 struct cfg80211_internal_bss *tmp,
1188 bool signal_valid, unsigned long ts)
1190 struct cfg80211_internal_bss *found = NULL;
1192 if (WARN_ON(!tmp->pub.channel))
1197 spin_lock_bh(&rdev->bss_lock);
1199 if (WARN_ON(!rcu_access_pointer(tmp->pub.ies))) {
1200 spin_unlock_bh(&rdev->bss_lock);
1204 found = rb_find_bss(rdev, tmp, BSS_CMP_REGULAR);
1207 if (!cfg80211_update_known_bss(rdev, found, tmp, signal_valid))
1210 struct cfg80211_internal_bss *new;
1211 struct cfg80211_internal_bss *hidden;
1212 struct cfg80211_bss_ies *ies;
1215 * create a copy -- the "res" variable that is passed in
1216 * is allocated on the stack since it's not needed in the
1217 * more common case of an update
1219 new = kzalloc(sizeof(*new) + rdev->wiphy.bss_priv_size,
1222 ies = (void *)rcu_dereference(tmp->pub.beacon_ies);
1224 kfree_rcu(ies, rcu_head);
1225 ies = (void *)rcu_dereference(tmp->pub.proberesp_ies);
1227 kfree_rcu(ies, rcu_head);
1230 memcpy(new, tmp, sizeof(*new));
1232 INIT_LIST_HEAD(&new->hidden_list);
1233 INIT_LIST_HEAD(&new->pub.nontrans_list);
1235 if (rcu_access_pointer(tmp->pub.proberesp_ies)) {
1236 hidden = rb_find_bss(rdev, tmp, BSS_CMP_HIDE_ZLEN);
1238 hidden = rb_find_bss(rdev, tmp,
1241 new->pub.hidden_beacon_bss = &hidden->pub;
1242 list_add(&new->hidden_list,
1243 &hidden->hidden_list);
1245 rcu_assign_pointer(new->pub.beacon_ies,
1246 hidden->pub.beacon_ies);
1250 * Ok so we found a beacon, and don't have an entry. If
1251 * it's a beacon with hidden SSID, we might be in for an
1252 * expensive search for any probe responses that should
1253 * be grouped with this beacon for updates ...
1255 if (!cfg80211_combine_bsses(rdev, new)) {
1256 bss_ref_put(rdev, new);
1261 if (rdev->bss_entries >= bss_entries_limit &&
1262 !cfg80211_bss_expire_oldest(rdev)) {
1263 bss_ref_put(rdev, new);
1267 /* This must be before the call to bss_ref_get */
1268 if (tmp->pub.transmitted_bss) {
1269 struct cfg80211_internal_bss *pbss =
1270 container_of(tmp->pub.transmitted_bss,
1271 struct cfg80211_internal_bss,
1274 new->pub.transmitted_bss = tmp->pub.transmitted_bss;
1275 bss_ref_get(rdev, pbss);
1278 list_add_tail(&new->list, &rdev->bss_list);
1279 rdev->bss_entries++;
1280 rb_insert_bss(rdev, new);
1284 rdev->bss_generation++;
1285 bss_ref_get(rdev, found);
1286 spin_unlock_bh(&rdev->bss_lock);
1290 spin_unlock_bh(&rdev->bss_lock);
1295 * Update RX channel information based on the available frame payload
1296 * information. This is mainly for the 2.4 GHz band where frames can be received
1297 * from neighboring channels and the Beacon frames use the DSSS Parameter Set
1298 * element to indicate the current (transmitting) channel, but this might also
1299 * be needed on other bands if RX frequency does not match with the actual
1300 * operating channel of a BSS.
1302 static struct ieee80211_channel *
1303 cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen,
1304 struct ieee80211_channel *channel,
1305 enum nl80211_bss_scan_width scan_width)
1309 int channel_number = -1;
1310 struct ieee80211_channel *alt_channel;
1312 tmp = cfg80211_find_ie(WLAN_EID_DS_PARAMS, ie, ielen);
1313 if (tmp && tmp[1] == 1) {
1314 channel_number = tmp[2];
1316 tmp = cfg80211_find_ie(WLAN_EID_HT_OPERATION, ie, ielen);
1317 if (tmp && tmp[1] >= sizeof(struct ieee80211_ht_operation)) {
1318 struct ieee80211_ht_operation *htop = (void *)(tmp + 2);
1320 channel_number = htop->primary_chan;
1324 if (channel_number < 0) {
1325 /* No channel information in frame payload */
1329 freq = ieee80211_channel_to_frequency(channel_number, channel->band);
1330 alt_channel = ieee80211_get_channel(wiphy, freq);
1332 if (channel->band == NL80211_BAND_2GHZ) {
1334 * Better not allow unexpected channels when that could
1335 * be going beyond the 1-11 range (e.g., discovering
1336 * BSS on channel 12 when radio is configured for
1342 /* No match for the payload channel number - ignore it */
1346 if (scan_width == NL80211_BSS_CHAN_WIDTH_10 ||
1347 scan_width == NL80211_BSS_CHAN_WIDTH_5) {
1349 * Ignore channel number in 5 and 10 MHz channels where there
1350 * may not be an n:1 or 1:n mapping between frequencies and
1357 * Use the channel determined through the payload channel number
1358 * instead of the RX channel reported by the driver.
1360 if (alt_channel->flags & IEEE80211_CHAN_DISABLED)
1365 /* Returned bss is reference counted and must be cleaned up appropriately. */
1366 static struct cfg80211_bss *
1367 cfg80211_inform_single_bss_data(struct wiphy *wiphy,
1368 struct cfg80211_inform_bss *data,
1369 enum cfg80211_bss_frame_type ftype,
1370 const u8 *bssid, u64 tsf, u16 capability,
1371 u16 beacon_interval, const u8 *ie, size_t ielen,
1372 struct cfg80211_non_tx_bss *non_tx_data,
1375 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
1376 struct cfg80211_bss_ies *ies;
1377 struct ieee80211_channel *channel;
1378 struct cfg80211_internal_bss tmp = {}, *res;
1383 if (WARN_ON(!wiphy))
1386 if (WARN_ON(wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
1387 (data->signal < 0 || data->signal > 100)))
1390 channel = cfg80211_get_bss_channel(wiphy, ie, ielen, data->chan,
1395 memcpy(tmp.pub.bssid, bssid, ETH_ALEN);
1396 tmp.pub.channel = channel;
1397 tmp.pub.scan_width = data->scan_width;
1398 tmp.pub.signal = data->signal;
1399 tmp.pub.beacon_interval = beacon_interval;
1400 tmp.pub.capability = capability;
1401 tmp.ts_boottime = data->boottime_ns;
1403 tmp.pub.transmitted_bss = non_tx_data->tx_bss;
1404 ts = bss_from_pub(non_tx_data->tx_bss)->ts;
1405 tmp.pub.bssid_index = non_tx_data->bssid_index;
1406 tmp.pub.max_bssid_indicator = non_tx_data->max_bssid_indicator;
1412 * If we do not know here whether the IEs are from a Beacon or Probe
1413 * Response frame, we need to pick one of the options and only use it
1414 * with the driver that does not provide the full Beacon/Probe Response
1415 * frame. Use Beacon frame pointer to avoid indicating that this should
1416 * override the IEs pointer should we have received an earlier
1417 * indication of Probe Response data.
1419 ies = kzalloc(sizeof(*ies) + ielen, gfp);
1424 ies->from_beacon = false;
1425 memcpy(ies->data, ie, ielen);
1428 case CFG80211_BSS_FTYPE_BEACON:
1429 ies->from_beacon = true;
1431 case CFG80211_BSS_FTYPE_UNKNOWN:
1432 rcu_assign_pointer(tmp.pub.beacon_ies, ies);
1434 case CFG80211_BSS_FTYPE_PRESP:
1435 rcu_assign_pointer(tmp.pub.proberesp_ies, ies);
1438 rcu_assign_pointer(tmp.pub.ies, ies);
1440 signal_valid = abs(data->chan->center_freq - channel->center_freq) <=
1441 wiphy->max_adj_channel_rssi_comp;
1442 res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid, ts);
1446 if (channel->band == NL80211_BAND_60GHZ) {
1447 bss_type = res->pub.capability & WLAN_CAPABILITY_DMG_TYPE_MASK;
1448 if (bss_type == WLAN_CAPABILITY_DMG_TYPE_AP ||
1449 bss_type == WLAN_CAPABILITY_DMG_TYPE_PBSS)
1450 regulatory_hint_found_beacon(wiphy, channel, gfp);
1452 if (res->pub.capability & WLAN_CAPABILITY_ESS)
1453 regulatory_hint_found_beacon(wiphy, channel, gfp);
1457 /* this is a nontransmitting bss, we need to add it to
1458 * transmitting bss' list if it is not there
1460 spin_lock_bh(&rdev->bss_lock);
1461 if (cfg80211_add_nontrans_list(non_tx_data->tx_bss,
1463 if (__cfg80211_unlink_bss(rdev, res))
1464 rdev->bss_generation++;
1466 spin_unlock_bh(&rdev->bss_lock);
1469 trace_cfg80211_return_bss(&res->pub);
1470 /* cfg80211_bss_update gives us a referenced result */
1474 static const struct element
1475 *cfg80211_get_profile_continuation(const u8 *ie, size_t ielen,
1476 const struct element *mbssid_elem,
1477 const struct element *sub_elem)
1479 const u8 *mbssid_end = mbssid_elem->data + mbssid_elem->datalen;
1480 const struct element *next_mbssid;
1481 const struct element *next_sub;
1483 next_mbssid = cfg80211_find_elem(WLAN_EID_MULTIPLE_BSSID,
1485 ielen - (mbssid_end - ie));
1488 * If is is not the last subelement in current MBSSID IE or there isn't
1489 * a next MBSSID IE - profile is complete.
1491 if ((sub_elem->data + sub_elem->datalen < mbssid_end - 1) ||
1495 /* For any length error, just return NULL */
1497 if (next_mbssid->datalen < 4)
1500 next_sub = (void *)&next_mbssid->data[1];
1502 if (next_mbssid->data + next_mbssid->datalen <
1503 next_sub->data + next_sub->datalen)
1506 if (next_sub->id != 0 || next_sub->datalen < 2)
1510 * Check if the first element in the next sub element is a start
1513 return next_sub->data[0] == WLAN_EID_NON_TX_BSSID_CAP ?
1517 size_t cfg80211_merge_profile(const u8 *ie, size_t ielen,
1518 const struct element *mbssid_elem,
1519 const struct element *sub_elem,
1520 u8 *merged_ie, size_t max_copy_len)
1522 size_t copied_len = sub_elem->datalen;
1523 const struct element *next_mbssid;
1525 if (sub_elem->datalen > max_copy_len)
1528 memcpy(merged_ie, sub_elem->data, sub_elem->datalen);
1530 while ((next_mbssid = cfg80211_get_profile_continuation(ie, ielen,
1533 const struct element *next_sub = (void *)&next_mbssid->data[1];
1535 if (copied_len + next_sub->datalen > max_copy_len)
1537 memcpy(merged_ie + copied_len, next_sub->data,
1539 copied_len += next_sub->datalen;
1544 EXPORT_SYMBOL(cfg80211_merge_profile);
1546 static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
1547 struct cfg80211_inform_bss *data,
1548 enum cfg80211_bss_frame_type ftype,
1549 const u8 *bssid, u64 tsf,
1550 u16 beacon_interval, const u8 *ie,
1552 struct cfg80211_non_tx_bss *non_tx_data,
1555 const u8 *mbssid_index_ie;
1556 const struct element *elem, *sub;
1558 u8 new_bssid[ETH_ALEN];
1559 u8 *new_ie, *profile;
1560 u64 seen_indices = 0;
1562 struct cfg80211_bss *bss;
1566 if (!cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ie, ielen))
1568 if (!wiphy->support_mbssid)
1570 if (wiphy->support_only_he_mbssid &&
1571 !cfg80211_find_ext_ie(WLAN_EID_EXT_HE_CAPABILITY, ie, ielen))
1574 new_ie = kmalloc(IEEE80211_MAX_DATA_LEN, gfp);
1578 profile = kmalloc(ielen, gfp);
1582 for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, ie, ielen) {
1583 if (elem->datalen < 4)
1585 for_each_element(sub, elem->data + 1, elem->datalen - 1) {
1588 if (sub->id != 0 || sub->datalen < 4) {
1589 /* not a valid BSS profile */
1593 if (sub->data[0] != WLAN_EID_NON_TX_BSSID_CAP ||
1594 sub->data[1] != 2) {
1595 /* The first element within the Nontransmitted
1596 * BSSID Profile is not the Nontransmitted
1597 * BSSID Capability element.
1602 memset(profile, 0, ielen);
1603 profile_len = cfg80211_merge_profile(ie, ielen,
1609 /* found a Nontransmitted BSSID Profile */
1610 mbssid_index_ie = cfg80211_find_ie
1611 (WLAN_EID_MULTI_BSSID_IDX,
1612 profile, profile_len);
1613 if (!mbssid_index_ie || mbssid_index_ie[1] < 1 ||
1614 mbssid_index_ie[2] == 0 ||
1615 mbssid_index_ie[2] > 46) {
1616 /* No valid Multiple BSSID-Index element */
1620 if (seen_indices & BIT_ULL(mbssid_index_ie[2]))
1621 /* We don't support legacy split of a profile */
1622 net_dbg_ratelimited("Partial info for BSSID index %d\n",
1623 mbssid_index_ie[2]);
1625 seen_indices |= BIT_ULL(mbssid_index_ie[2]);
1627 non_tx_data->bssid_index = mbssid_index_ie[2];
1628 non_tx_data->max_bssid_indicator = elem->data[0];
1630 cfg80211_gen_new_bssid(bssid,
1631 non_tx_data->max_bssid_indicator,
1632 non_tx_data->bssid_index,
1634 memset(new_ie, 0, IEEE80211_MAX_DATA_LEN);
1635 new_ie_len = cfg80211_gen_new_ie(ie, ielen,
1637 profile_len, new_ie,
1642 capability = get_unaligned_le16(profile + 2);
1643 bss = cfg80211_inform_single_bss_data(wiphy, data,
1654 cfg80211_put_bss(wiphy, bss);
1663 struct cfg80211_bss *
1664 cfg80211_inform_bss_data(struct wiphy *wiphy,
1665 struct cfg80211_inform_bss *data,
1666 enum cfg80211_bss_frame_type ftype,
1667 const u8 *bssid, u64 tsf, u16 capability,
1668 u16 beacon_interval, const u8 *ie, size_t ielen,
1671 struct cfg80211_bss *res;
1672 struct cfg80211_non_tx_bss non_tx_data;
1674 res = cfg80211_inform_single_bss_data(wiphy, data, ftype, bssid, tsf,
1675 capability, beacon_interval, ie,
1679 non_tx_data.tx_bss = res;
1680 cfg80211_parse_mbssid_data(wiphy, data, ftype, bssid, tsf,
1681 beacon_interval, ie, ielen, &non_tx_data,
1685 EXPORT_SYMBOL(cfg80211_inform_bss_data);
1688 cfg80211_parse_mbssid_frame_data(struct wiphy *wiphy,
1689 struct cfg80211_inform_bss *data,
1690 struct ieee80211_mgmt *mgmt, size_t len,
1691 struct cfg80211_non_tx_bss *non_tx_data,
1694 enum cfg80211_bss_frame_type ftype;
1695 const u8 *ie = mgmt->u.probe_resp.variable;
1696 size_t ielen = len - offsetof(struct ieee80211_mgmt,
1697 u.probe_resp.variable);
1699 ftype = ieee80211_is_beacon(mgmt->frame_control) ?
1700 CFG80211_BSS_FTYPE_BEACON : CFG80211_BSS_FTYPE_PRESP;
1702 cfg80211_parse_mbssid_data(wiphy, data, ftype, mgmt->bssid,
1703 le64_to_cpu(mgmt->u.probe_resp.timestamp),
1704 le16_to_cpu(mgmt->u.probe_resp.beacon_int),
1705 ie, ielen, non_tx_data, gfp);
1709 cfg80211_update_notlisted_nontrans(struct wiphy *wiphy,
1710 struct cfg80211_bss *nontrans_bss,
1711 struct ieee80211_mgmt *mgmt, size_t len)
1713 u8 *ie, *new_ie, *pos;
1714 const u8 *nontrans_ssid, *trans_ssid, *mbssid;
1715 size_t ielen = len - offsetof(struct ieee80211_mgmt,
1716 u.probe_resp.variable);
1718 struct cfg80211_bss_ies *new_ies;
1719 const struct cfg80211_bss_ies *old;
1722 lockdep_assert_held(&wiphy_to_rdev(wiphy)->bss_lock);
1724 ie = mgmt->u.probe_resp.variable;
1727 trans_ssid = cfg80211_find_ie(WLAN_EID_SSID, ie, ielen);
1730 new_ie_len -= trans_ssid[1];
1731 mbssid = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ie, ielen);
1733 * It's not valid to have the MBSSID element before SSID
1734 * ignore if that happens - the code below assumes it is
1735 * after (while copying things inbetween).
1737 if (!mbssid || mbssid < trans_ssid)
1739 new_ie_len -= mbssid[1];
1741 nontrans_ssid = ieee80211_bss_get_ie(nontrans_bss, WLAN_EID_SSID);
1745 new_ie_len += nontrans_ssid[1];
1747 /* generate new ie for nontrans BSS
1748 * 1. replace SSID with nontrans BSS' SSID
1751 new_ie = kzalloc(new_ie_len, GFP_ATOMIC);
1755 new_ies = kzalloc(sizeof(*new_ies) + new_ie_len, GFP_ATOMIC);
1761 /* copy the nontransmitted SSID */
1762 cpy_len = nontrans_ssid[1] + 2;
1763 memcpy(pos, nontrans_ssid, cpy_len);
1765 /* copy the IEs between SSID and MBSSID */
1766 cpy_len = trans_ssid[1] + 2;
1767 memcpy(pos, (trans_ssid + cpy_len), (mbssid - (trans_ssid + cpy_len)));
1768 pos += (mbssid - (trans_ssid + cpy_len));
1769 /* copy the IEs after MBSSID */
1770 cpy_len = mbssid[1] + 2;
1771 memcpy(pos, mbssid + cpy_len, ((ie + ielen) - (mbssid + cpy_len)));
1774 new_ies->len = new_ie_len;
1775 new_ies->tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
1776 new_ies->from_beacon = ieee80211_is_beacon(mgmt->frame_control);
1777 memcpy(new_ies->data, new_ie, new_ie_len);
1778 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
1779 old = rcu_access_pointer(nontrans_bss->proberesp_ies);
1780 rcu_assign_pointer(nontrans_bss->proberesp_ies, new_ies);
1781 rcu_assign_pointer(nontrans_bss->ies, new_ies);
1783 kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
1785 old = rcu_access_pointer(nontrans_bss->beacon_ies);
1786 rcu_assign_pointer(nontrans_bss->beacon_ies, new_ies);
1787 rcu_assign_pointer(nontrans_bss->ies, new_ies);
1789 kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
1796 /* cfg80211_inform_bss_width_frame helper */
1797 static struct cfg80211_bss *
1798 cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy,
1799 struct cfg80211_inform_bss *data,
1800 struct ieee80211_mgmt *mgmt, size_t len,
1803 struct cfg80211_internal_bss tmp = {}, *res;
1804 struct cfg80211_bss_ies *ies;
1805 struct ieee80211_channel *channel;
1807 size_t ielen = len - offsetof(struct ieee80211_mgmt,
1808 u.probe_resp.variable);
1811 BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) !=
1812 offsetof(struct ieee80211_mgmt, u.beacon.variable));
1814 trace_cfg80211_inform_bss_frame(wiphy, data, mgmt, len);
1819 if (WARN_ON(!wiphy))
1822 if (WARN_ON(wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
1823 (data->signal < 0 || data->signal > 100)))
1826 if (WARN_ON(len < offsetof(struct ieee80211_mgmt, u.probe_resp.variable)))
1829 channel = cfg80211_get_bss_channel(wiphy, mgmt->u.beacon.variable,
1830 ielen, data->chan, data->scan_width);
1834 ies = kzalloc(sizeof(*ies) + ielen, gfp);
1838 ies->tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
1839 ies->from_beacon = ieee80211_is_beacon(mgmt->frame_control);
1840 memcpy(ies->data, mgmt->u.probe_resp.variable, ielen);
1842 if (ieee80211_is_probe_resp(mgmt->frame_control))
1843 rcu_assign_pointer(tmp.pub.proberesp_ies, ies);
1845 rcu_assign_pointer(tmp.pub.beacon_ies, ies);
1846 rcu_assign_pointer(tmp.pub.ies, ies);
1848 memcpy(tmp.pub.bssid, mgmt->bssid, ETH_ALEN);
1849 tmp.pub.channel = channel;
1850 tmp.pub.scan_width = data->scan_width;
1851 tmp.pub.signal = data->signal;
1852 tmp.pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
1853 tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
1854 tmp.ts_boottime = data->boottime_ns;
1855 tmp.parent_tsf = data->parent_tsf;
1856 tmp.pub.chains = data->chains;
1857 memcpy(tmp.pub.chain_signal, data->chain_signal, IEEE80211_MAX_CHAINS);
1858 ether_addr_copy(tmp.parent_bssid, data->parent_bssid);
1860 signal_valid = abs(data->chan->center_freq - channel->center_freq) <=
1861 wiphy->max_adj_channel_rssi_comp;
1862 res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid,
1867 if (channel->band == NL80211_BAND_60GHZ) {
1868 bss_type = res->pub.capability & WLAN_CAPABILITY_DMG_TYPE_MASK;
1869 if (bss_type == WLAN_CAPABILITY_DMG_TYPE_AP ||
1870 bss_type == WLAN_CAPABILITY_DMG_TYPE_PBSS)
1871 regulatory_hint_found_beacon(wiphy, channel, gfp);
1873 if (res->pub.capability & WLAN_CAPABILITY_ESS)
1874 regulatory_hint_found_beacon(wiphy, channel, gfp);
1877 trace_cfg80211_return_bss(&res->pub);
1878 /* cfg80211_bss_update gives us a referenced result */
1882 struct cfg80211_bss *
1883 cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
1884 struct cfg80211_inform_bss *data,
1885 struct ieee80211_mgmt *mgmt, size_t len,
1888 struct cfg80211_bss *res, *tmp_bss;
1889 const u8 *ie = mgmt->u.probe_resp.variable;
1890 const struct cfg80211_bss_ies *ies1, *ies2;
1891 size_t ielen = len - offsetof(struct ieee80211_mgmt,
1892 u.probe_resp.variable);
1893 struct cfg80211_non_tx_bss non_tx_data;
1895 res = cfg80211_inform_single_bss_frame_data(wiphy, data, mgmt,
1897 if (!res || !wiphy->support_mbssid ||
1898 !cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ie, ielen))
1900 if (wiphy->support_only_he_mbssid &&
1901 !cfg80211_find_ext_ie(WLAN_EID_EXT_HE_CAPABILITY, ie, ielen))
1904 non_tx_data.tx_bss = res;
1905 /* process each non-transmitting bss */
1906 cfg80211_parse_mbssid_frame_data(wiphy, data, mgmt, len,
1909 spin_lock_bh(&wiphy_to_rdev(wiphy)->bss_lock);
1911 /* check if the res has other nontransmitting bss which is not
1914 ies1 = rcu_access_pointer(res->ies);
1916 /* go through nontrans_list, if the timestamp of the BSS is
1917 * earlier than the timestamp of the transmitting BSS then
1920 list_for_each_entry(tmp_bss, &res->nontrans_list,
1922 ies2 = rcu_access_pointer(tmp_bss->ies);
1923 if (ies2->tsf < ies1->tsf)
1924 cfg80211_update_notlisted_nontrans(wiphy, tmp_bss,
1927 spin_unlock_bh(&wiphy_to_rdev(wiphy)->bss_lock);
1931 EXPORT_SYMBOL(cfg80211_inform_bss_frame_data);
1933 void cfg80211_ref_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
1935 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
1936 struct cfg80211_internal_bss *bss;
1941 bss = container_of(pub, struct cfg80211_internal_bss, pub);
1943 spin_lock_bh(&rdev->bss_lock);
1944 bss_ref_get(rdev, bss);
1945 spin_unlock_bh(&rdev->bss_lock);
1947 EXPORT_SYMBOL(cfg80211_ref_bss);
1949 void cfg80211_put_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
1951 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
1952 struct cfg80211_internal_bss *bss;
1957 bss = container_of(pub, struct cfg80211_internal_bss, pub);
1959 spin_lock_bh(&rdev->bss_lock);
1960 bss_ref_put(rdev, bss);
1961 spin_unlock_bh(&rdev->bss_lock);
1963 EXPORT_SYMBOL(cfg80211_put_bss);
1965 void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
1967 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
1968 struct cfg80211_internal_bss *bss, *tmp1;
1969 struct cfg80211_bss *nontrans_bss, *tmp;
1974 bss = container_of(pub, struct cfg80211_internal_bss, pub);
1976 spin_lock_bh(&rdev->bss_lock);
1977 if (list_empty(&bss->list))
1980 list_for_each_entry_safe(nontrans_bss, tmp,
1981 &pub->nontrans_list,
1983 tmp1 = container_of(nontrans_bss,
1984 struct cfg80211_internal_bss, pub);
1985 if (__cfg80211_unlink_bss(rdev, tmp1))
1986 rdev->bss_generation++;
1989 if (__cfg80211_unlink_bss(rdev, bss))
1990 rdev->bss_generation++;
1992 spin_unlock_bh(&rdev->bss_lock);
1994 EXPORT_SYMBOL(cfg80211_unlink_bss);
1996 void cfg80211_bss_iter(struct wiphy *wiphy,
1997 struct cfg80211_chan_def *chandef,
1998 void (*iter)(struct wiphy *wiphy,
1999 struct cfg80211_bss *bss,
2003 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
2004 struct cfg80211_internal_bss *bss;
2006 spin_lock_bh(&rdev->bss_lock);
2008 list_for_each_entry(bss, &rdev->bss_list, list) {
2009 if (!chandef || cfg80211_is_sub_chan(chandef, bss->pub.channel))
2010 iter(wiphy, &bss->pub, iter_data);
2013 spin_unlock_bh(&rdev->bss_lock);
2015 EXPORT_SYMBOL(cfg80211_bss_iter);
2017 void cfg80211_update_assoc_bss_entry(struct wireless_dev *wdev,
2018 struct ieee80211_channel *chan)
2020 struct wiphy *wiphy = wdev->wiphy;
2021 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
2022 struct cfg80211_internal_bss *cbss = wdev->current_bss;
2023 struct cfg80211_internal_bss *new = NULL;
2024 struct cfg80211_internal_bss *bss;
2025 struct cfg80211_bss *nontrans_bss;
2026 struct cfg80211_bss *tmp;
2028 spin_lock_bh(&rdev->bss_lock);
2031 * Some APs use CSA also for bandwidth changes, i.e., without actually
2032 * changing the control channel, so no need to update in such a case.
2034 if (cbss->pub.channel == chan)
2037 /* use transmitting bss */
2038 if (cbss->pub.transmitted_bss)
2039 cbss = container_of(cbss->pub.transmitted_bss,
2040 struct cfg80211_internal_bss,
2043 cbss->pub.channel = chan;
2045 list_for_each_entry(bss, &rdev->bss_list, list) {
2046 if (!cfg80211_bss_type_match(bss->pub.capability,
2047 bss->pub.channel->band,
2048 wdev->conn_bss_type))
2054 if (!cmp_bss(&bss->pub, &cbss->pub, BSS_CMP_REGULAR)) {
2061 /* to save time, update IEs for transmitting bss only */
2062 if (cfg80211_update_known_bss(rdev, cbss, new, false)) {
2063 new->pub.proberesp_ies = NULL;
2064 new->pub.beacon_ies = NULL;
2067 list_for_each_entry_safe(nontrans_bss, tmp,
2068 &new->pub.nontrans_list,
2070 bss = container_of(nontrans_bss,
2071 struct cfg80211_internal_bss, pub);
2072 if (__cfg80211_unlink_bss(rdev, bss))
2073 rdev->bss_generation++;
2076 WARN_ON(atomic_read(&new->hold));
2077 if (!WARN_ON(!__cfg80211_unlink_bss(rdev, new)))
2078 rdev->bss_generation++;
2081 rb_erase(&cbss->rbn, &rdev->bss_tree);
2082 rb_insert_bss(rdev, cbss);
2083 rdev->bss_generation++;
2085 list_for_each_entry_safe(nontrans_bss, tmp,
2086 &cbss->pub.nontrans_list,
2088 bss = container_of(nontrans_bss,
2089 struct cfg80211_internal_bss, pub);
2090 bss->pub.channel = chan;
2091 rb_erase(&bss->rbn, &rdev->bss_tree);
2092 rb_insert_bss(rdev, bss);
2093 rdev->bss_generation++;
2097 spin_unlock_bh(&rdev->bss_lock);
2100 #ifdef CONFIG_CFG80211_WEXT
2101 static struct cfg80211_registered_device *
2102 cfg80211_get_dev_from_ifindex(struct net *net, int ifindex)
2104 struct cfg80211_registered_device *rdev;
2105 struct net_device *dev;
2109 dev = dev_get_by_index(net, ifindex);
2111 return ERR_PTR(-ENODEV);
2112 if (dev->ieee80211_ptr)
2113 rdev = wiphy_to_rdev(dev->ieee80211_ptr->wiphy);
2115 rdev = ERR_PTR(-ENODEV);
2120 int cfg80211_wext_siwscan(struct net_device *dev,
2121 struct iw_request_info *info,
2122 union iwreq_data *wrqu, char *extra)
2124 struct cfg80211_registered_device *rdev;
2125 struct wiphy *wiphy;
2126 struct iw_scan_req *wreq = NULL;
2127 struct cfg80211_scan_request *creq = NULL;
2128 int i, err, n_channels = 0;
2129 enum nl80211_band band;
2131 if (!netif_running(dev))
2134 if (wrqu->data.length == sizeof(struct iw_scan_req))
2135 wreq = (struct iw_scan_req *)extra;
2137 rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex);
2140 return PTR_ERR(rdev);
2142 if (rdev->scan_req || rdev->scan_msg) {
2147 wiphy = &rdev->wiphy;
2149 /* Determine number of channels, needed to allocate creq */
2150 if (wreq && wreq->num_channels)
2151 n_channels = wreq->num_channels;
2153 n_channels = ieee80211_get_num_supported_channels(wiphy);
2155 creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) +
2156 n_channels * sizeof(void *),
2163 creq->wiphy = wiphy;
2164 creq->wdev = dev->ieee80211_ptr;
2165 /* SSIDs come after channels */
2166 creq->ssids = (void *)&creq->channels[n_channels];
2167 creq->n_channels = n_channels;
2169 creq->scan_start = jiffies;
2171 /* translate "Scan on frequencies" request */
2173 for (band = 0; band < NUM_NL80211_BANDS; band++) {
2176 if (!wiphy->bands[band])
2179 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
2180 /* ignore disabled channels */
2181 if (wiphy->bands[band]->channels[j].flags &
2182 IEEE80211_CHAN_DISABLED)
2185 /* If we have a wireless request structure and the
2186 * wireless request specifies frequencies, then search
2187 * for the matching hardware channel.
2189 if (wreq && wreq->num_channels) {
2191 int wiphy_freq = wiphy->bands[band]->channels[j].center_freq;
2192 for (k = 0; k < wreq->num_channels; k++) {
2193 struct iw_freq *freq =
2194 &wreq->channel_list[k];
2196 cfg80211_wext_freq(freq);
2198 if (wext_freq == wiphy_freq)
2199 goto wext_freq_found;
2201 goto wext_freq_not_found;
2205 creq->channels[i] = &wiphy->bands[band]->channels[j];
2207 wext_freq_not_found: ;
2210 /* No channels found? */
2216 /* Set real number of channels specified in creq->channels[] */
2217 creq->n_channels = i;
2219 /* translate "Scan for SSID" request */
2221 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
2222 if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) {
2226 memcpy(creq->ssids[0].ssid, wreq->essid, wreq->essid_len);
2227 creq->ssids[0].ssid_len = wreq->essid_len;
2229 if (wreq->scan_type == IW_SCAN_TYPE_PASSIVE)
2233 for (i = 0; i < NUM_NL80211_BANDS; i++)
2234 if (wiphy->bands[i])
2235 creq->rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1;
2237 eth_broadcast_addr(creq->bssid);
2239 rdev->scan_req = creq;
2240 err = rdev_scan(rdev, creq);
2242 rdev->scan_req = NULL;
2243 /* creq will be freed below */
2245 nl80211_send_scan_start(rdev, dev->ieee80211_ptr);
2246 /* creq now owned by driver */
2254 EXPORT_WEXT_HANDLER(cfg80211_wext_siwscan);
2256 static char *ieee80211_scan_add_ies(struct iw_request_info *info,
2257 const struct cfg80211_bss_ies *ies,
2258 char *current_ev, char *end_buf)
2260 const u8 *pos, *end, *next;
2261 struct iw_event iwe;
2267 * If needed, fragment the IEs buffer (at IE boundaries) into short
2268 * enough fragments to fit into IW_GENERIC_IE_MAX octet messages.
2271 end = pos + ies->len;
2273 while (end - pos > IW_GENERIC_IE_MAX) {
2274 next = pos + 2 + pos[1];
2275 while (next + 2 + next[1] - pos < IW_GENERIC_IE_MAX)
2276 next = next + 2 + next[1];
2278 memset(&iwe, 0, sizeof(iwe));
2279 iwe.cmd = IWEVGENIE;
2280 iwe.u.data.length = next - pos;
2281 current_ev = iwe_stream_add_point_check(info, current_ev,
2284 if (IS_ERR(current_ev))
2290 memset(&iwe, 0, sizeof(iwe));
2291 iwe.cmd = IWEVGENIE;
2292 iwe.u.data.length = end - pos;
2293 current_ev = iwe_stream_add_point_check(info, current_ev,
2296 if (IS_ERR(current_ev))
2304 ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
2305 struct cfg80211_internal_bss *bss, char *current_ev,
2308 const struct cfg80211_bss_ies *ies;
2309 struct iw_event iwe;
2314 bool ismesh = false;
2316 memset(&iwe, 0, sizeof(iwe));
2317 iwe.cmd = SIOCGIWAP;
2318 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
2319 memcpy(iwe.u.ap_addr.sa_data, bss->pub.bssid, ETH_ALEN);
2320 current_ev = iwe_stream_add_event_check(info, current_ev, end_buf, &iwe,
2322 if (IS_ERR(current_ev))
2325 memset(&iwe, 0, sizeof(iwe));
2326 iwe.cmd = SIOCGIWFREQ;
2327 iwe.u.freq.m = ieee80211_frequency_to_channel(bss->pub.channel->center_freq);
2329 current_ev = iwe_stream_add_event_check(info, current_ev, end_buf, &iwe,
2331 if (IS_ERR(current_ev))
2334 memset(&iwe, 0, sizeof(iwe));
2335 iwe.cmd = SIOCGIWFREQ;
2336 iwe.u.freq.m = bss->pub.channel->center_freq;
2338 current_ev = iwe_stream_add_event_check(info, current_ev, end_buf, &iwe,
2340 if (IS_ERR(current_ev))
2343 if (wiphy->signal_type != CFG80211_SIGNAL_TYPE_NONE) {
2344 memset(&iwe, 0, sizeof(iwe));
2346 iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED |
2347 IW_QUAL_NOISE_INVALID |
2348 IW_QUAL_QUAL_UPDATED;
2349 switch (wiphy->signal_type) {
2350 case CFG80211_SIGNAL_TYPE_MBM:
2351 sig = bss->pub.signal / 100;
2352 iwe.u.qual.level = sig;
2353 iwe.u.qual.updated |= IW_QUAL_DBM;
2354 if (sig < -110) /* rather bad */
2356 else if (sig > -40) /* perfect */
2358 /* will give a range of 0 .. 70 */
2359 iwe.u.qual.qual = sig + 110;
2361 case CFG80211_SIGNAL_TYPE_UNSPEC:
2362 iwe.u.qual.level = bss->pub.signal;
2363 /* will give range 0 .. 100 */
2364 iwe.u.qual.qual = bss->pub.signal;
2370 current_ev = iwe_stream_add_event_check(info, current_ev,
2373 if (IS_ERR(current_ev))
2377 memset(&iwe, 0, sizeof(iwe));
2378 iwe.cmd = SIOCGIWENCODE;
2379 if (bss->pub.capability & WLAN_CAPABILITY_PRIVACY)
2380 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
2382 iwe.u.data.flags = IW_ENCODE_DISABLED;
2383 iwe.u.data.length = 0;
2384 current_ev = iwe_stream_add_point_check(info, current_ev, end_buf,
2386 if (IS_ERR(current_ev))
2390 ies = rcu_dereference(bss->pub.ies);
2396 if (ie[1] > rem - 2)
2401 memset(&iwe, 0, sizeof(iwe));
2402 iwe.cmd = SIOCGIWESSID;
2403 iwe.u.data.length = ie[1];
2404 iwe.u.data.flags = 1;
2405 current_ev = iwe_stream_add_point_check(info,
2409 if (IS_ERR(current_ev))
2412 case WLAN_EID_MESH_ID:
2413 memset(&iwe, 0, sizeof(iwe));
2414 iwe.cmd = SIOCGIWESSID;
2415 iwe.u.data.length = ie[1];
2416 iwe.u.data.flags = 1;
2417 current_ev = iwe_stream_add_point_check(info,
2421 if (IS_ERR(current_ev))
2424 case WLAN_EID_MESH_CONFIG:
2426 if (ie[1] != sizeof(struct ieee80211_meshconf_ie))
2429 memset(&iwe, 0, sizeof(iwe));
2430 iwe.cmd = IWEVCUSTOM;
2431 sprintf(buf, "Mesh Network Path Selection Protocol ID: "
2433 iwe.u.data.length = strlen(buf);
2434 current_ev = iwe_stream_add_point_check(info,
2438 if (IS_ERR(current_ev))
2440 sprintf(buf, "Path Selection Metric ID: 0x%02X",
2442 iwe.u.data.length = strlen(buf);
2443 current_ev = iwe_stream_add_point_check(info,
2447 if (IS_ERR(current_ev))
2449 sprintf(buf, "Congestion Control Mode ID: 0x%02X",
2451 iwe.u.data.length = strlen(buf);
2452 current_ev = iwe_stream_add_point_check(info,
2456 if (IS_ERR(current_ev))
2458 sprintf(buf, "Synchronization ID: 0x%02X", cfg[3]);
2459 iwe.u.data.length = strlen(buf);
2460 current_ev = iwe_stream_add_point_check(info,
2464 if (IS_ERR(current_ev))
2466 sprintf(buf, "Authentication ID: 0x%02X", cfg[4]);
2467 iwe.u.data.length = strlen(buf);
2468 current_ev = iwe_stream_add_point_check(info,
2472 if (IS_ERR(current_ev))
2474 sprintf(buf, "Formation Info: 0x%02X", cfg[5]);
2475 iwe.u.data.length = strlen(buf);
2476 current_ev = iwe_stream_add_point_check(info,
2480 if (IS_ERR(current_ev))
2482 sprintf(buf, "Capabilities: 0x%02X", cfg[6]);
2483 iwe.u.data.length = strlen(buf);
2484 current_ev = iwe_stream_add_point_check(info,
2488 if (IS_ERR(current_ev))
2491 case WLAN_EID_SUPP_RATES:
2492 case WLAN_EID_EXT_SUPP_RATES:
2493 /* display all supported rates in readable format */
2494 p = current_ev + iwe_stream_lcp_len(info);
2496 memset(&iwe, 0, sizeof(iwe));
2497 iwe.cmd = SIOCGIWRATE;
2498 /* Those two flags are ignored... */
2499 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
2501 for (i = 0; i < ie[1]; i++) {
2502 iwe.u.bitrate.value =
2503 ((ie[i + 2] & 0x7f) * 500000);
2505 p = iwe_stream_add_value(info, current_ev, p,
2509 current_ev = ERR_PTR(-E2BIG);
2520 if (bss->pub.capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS) ||
2522 memset(&iwe, 0, sizeof(iwe));
2523 iwe.cmd = SIOCGIWMODE;
2525 iwe.u.mode = IW_MODE_MESH;
2526 else if (bss->pub.capability & WLAN_CAPABILITY_ESS)
2527 iwe.u.mode = IW_MODE_MASTER;
2529 iwe.u.mode = IW_MODE_ADHOC;
2530 current_ev = iwe_stream_add_event_check(info, current_ev,
2533 if (IS_ERR(current_ev))
2537 memset(&iwe, 0, sizeof(iwe));
2538 iwe.cmd = IWEVCUSTOM;
2539 sprintf(buf, "tsf=%016llx", (unsigned long long)(ies->tsf));
2540 iwe.u.data.length = strlen(buf);
2541 current_ev = iwe_stream_add_point_check(info, current_ev, end_buf,
2543 if (IS_ERR(current_ev))
2545 memset(&iwe, 0, sizeof(iwe));
2546 iwe.cmd = IWEVCUSTOM;
2547 sprintf(buf, " Last beacon: %ums ago",
2548 elapsed_jiffies_msecs(bss->ts));
2549 iwe.u.data.length = strlen(buf);
2550 current_ev = iwe_stream_add_point_check(info, current_ev,
2551 end_buf, &iwe, buf);
2552 if (IS_ERR(current_ev))
2555 current_ev = ieee80211_scan_add_ies(info, ies, current_ev, end_buf);
2563 static int ieee80211_scan_results(struct cfg80211_registered_device *rdev,
2564 struct iw_request_info *info,
2565 char *buf, size_t len)
2567 char *current_ev = buf;
2568 char *end_buf = buf + len;
2569 struct cfg80211_internal_bss *bss;
2572 spin_lock_bh(&rdev->bss_lock);
2573 cfg80211_bss_expire(rdev);
2575 list_for_each_entry(bss, &rdev->bss_list, list) {
2576 if (buf + len - current_ev <= IW_EV_ADDR_LEN) {
2580 current_ev = ieee80211_bss(&rdev->wiphy, info, bss,
2581 current_ev, end_buf);
2582 if (IS_ERR(current_ev)) {
2583 err = PTR_ERR(current_ev);
2587 spin_unlock_bh(&rdev->bss_lock);
2591 return current_ev - buf;
2595 int cfg80211_wext_giwscan(struct net_device *dev,
2596 struct iw_request_info *info,
2597 struct iw_point *data, char *extra)
2599 struct cfg80211_registered_device *rdev;
2602 if (!netif_running(dev))
2605 rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex);
2608 return PTR_ERR(rdev);
2610 if (rdev->scan_req || rdev->scan_msg)
2613 res = ieee80211_scan_results(rdev, info, extra, data->length);
2622 EXPORT_WEXT_HANDLER(cfg80211_wext_giwscan);