0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/kernel.h>
0011 #include <linux/slab.h>
0012 #include <linux/module.h>
0013 #include <linux/netdevice.h>
0014 #include <linux/wireless.h>
0015 #include <linux/nl80211.h>
0016 #include <linux/etherdevice.h>
0017 #include <linux/crc32.h>
0018 #include <linux/bitfield.h>
0019 #include <net/arp.h>
0020 #include <net/cfg80211.h>
0021 #include <net/cfg80211-wext.h>
0022 #include <net/iw_handler.h>
0023 #include "core.h"
0024 #include "nl80211.h"
0025 #include "wext-compat.h"
0026 #include "rdev-ops.h"
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072 static int bss_entries_limit = 1000;
0073 module_param(bss_entries_limit, int, 0644);
0074 MODULE_PARM_DESC(bss_entries_limit,
0075 "limit to number of scan BSS entries (per wiphy, default 1000)");
0076
0077 #define IEEE80211_SCAN_RESULT_EXPIRE (30 * HZ)
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100 struct cfg80211_colocated_ap {
0101 struct list_head list;
0102 u8 bssid[ETH_ALEN];
0103 u8 ssid[IEEE80211_MAX_SSID_LEN];
0104 size_t ssid_len;
0105 u32 short_ssid;
0106 u32 center_freq;
0107 u8 unsolicited_probe:1,
0108 oct_recommended:1,
0109 same_ssid:1,
0110 multi_bss:1,
0111 transmitted_bssid:1,
0112 colocated_ess:1,
0113 short_ssid_valid:1;
0114 };
0115
0116 static void bss_free(struct cfg80211_internal_bss *bss)
0117 {
0118 struct cfg80211_bss_ies *ies;
0119
0120 if (WARN_ON(atomic_read(&bss->hold)))
0121 return;
0122
0123 ies = (void *)rcu_access_pointer(bss->pub.beacon_ies);
0124 if (ies && !bss->pub.hidden_beacon_bss)
0125 kfree_rcu(ies, rcu_head);
0126 ies = (void *)rcu_access_pointer(bss->pub.proberesp_ies);
0127 if (ies)
0128 kfree_rcu(ies, rcu_head);
0129
0130
0131
0132
0133
0134 if (!list_empty(&bss->hidden_list))
0135 list_del(&bss->hidden_list);
0136
0137 kfree(bss);
0138 }
0139
0140 static inline void bss_ref_get(struct cfg80211_registered_device *rdev,
0141 struct cfg80211_internal_bss *bss)
0142 {
0143 lockdep_assert_held(&rdev->bss_lock);
0144
0145 bss->refcount++;
0146 if (bss->pub.hidden_beacon_bss) {
0147 bss = container_of(bss->pub.hidden_beacon_bss,
0148 struct cfg80211_internal_bss,
0149 pub);
0150 bss->refcount++;
0151 }
0152 if (bss->pub.transmitted_bss) {
0153 bss = container_of(bss->pub.transmitted_bss,
0154 struct cfg80211_internal_bss,
0155 pub);
0156 bss->refcount++;
0157 }
0158 }
0159
0160 static inline void bss_ref_put(struct cfg80211_registered_device *rdev,
0161 struct cfg80211_internal_bss *bss)
0162 {
0163 lockdep_assert_held(&rdev->bss_lock);
0164
0165 if (bss->pub.hidden_beacon_bss) {
0166 struct cfg80211_internal_bss *hbss;
0167 hbss = container_of(bss->pub.hidden_beacon_bss,
0168 struct cfg80211_internal_bss,
0169 pub);
0170 hbss->refcount--;
0171 if (hbss->refcount == 0)
0172 bss_free(hbss);
0173 }
0174
0175 if (bss->pub.transmitted_bss) {
0176 struct cfg80211_internal_bss *tbss;
0177
0178 tbss = container_of(bss->pub.transmitted_bss,
0179 struct cfg80211_internal_bss,
0180 pub);
0181 tbss->refcount--;
0182 if (tbss->refcount == 0)
0183 bss_free(tbss);
0184 }
0185
0186 bss->refcount--;
0187 if (bss->refcount == 0)
0188 bss_free(bss);
0189 }
0190
0191 static bool __cfg80211_unlink_bss(struct cfg80211_registered_device *rdev,
0192 struct cfg80211_internal_bss *bss)
0193 {
0194 lockdep_assert_held(&rdev->bss_lock);
0195
0196 if (!list_empty(&bss->hidden_list)) {
0197
0198
0199
0200
0201 if (!bss->pub.hidden_beacon_bss)
0202 return false;
0203
0204
0205
0206
0207 list_del_init(&bss->hidden_list);
0208 }
0209
0210 list_del_init(&bss->list);
0211 list_del_init(&bss->pub.nontrans_list);
0212 rb_erase(&bss->rbn, &rdev->bss_tree);
0213 rdev->bss_entries--;
0214 WARN_ONCE((rdev->bss_entries == 0) ^ list_empty(&rdev->bss_list),
0215 "rdev bss entries[%d]/list[empty:%d] corruption\n",
0216 rdev->bss_entries, list_empty(&rdev->bss_list));
0217 bss_ref_put(rdev, bss);
0218 return true;
0219 }
0220
0221 bool cfg80211_is_element_inherited(const struct element *elem,
0222 const struct element *non_inherit_elem)
0223 {
0224 u8 id_len, ext_id_len, i, loop_len, id;
0225 const u8 *list;
0226
0227 if (elem->id == WLAN_EID_MULTIPLE_BSSID)
0228 return false;
0229
0230 if (!non_inherit_elem || non_inherit_elem->datalen < 2)
0231 return true;
0232
0233
0234
0235
0236
0237
0238
0239
0240 id_len = non_inherit_elem->data[1];
0241 if (non_inherit_elem->datalen < 3 + id_len)
0242 return true;
0243
0244 ext_id_len = non_inherit_elem->data[2 + id_len];
0245 if (non_inherit_elem->datalen < 3 + id_len + ext_id_len)
0246 return true;
0247
0248 if (elem->id == WLAN_EID_EXTENSION) {
0249 if (!ext_id_len)
0250 return true;
0251 loop_len = ext_id_len;
0252 list = &non_inherit_elem->data[3 + id_len];
0253 id = elem->data[0];
0254 } else {
0255 if (!id_len)
0256 return true;
0257 loop_len = id_len;
0258 list = &non_inherit_elem->data[2];
0259 id = elem->id;
0260 }
0261
0262 for (i = 0; i < loop_len; i++) {
0263 if (list[i] == id)
0264 return false;
0265 }
0266
0267 return true;
0268 }
0269 EXPORT_SYMBOL(cfg80211_is_element_inherited);
0270
0271 static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
0272 const u8 *subelement, size_t subie_len,
0273 u8 *new_ie, gfp_t gfp)
0274 {
0275 u8 *pos, *tmp;
0276 const u8 *tmp_old, *tmp_new;
0277 const struct element *non_inherit_elem;
0278 u8 *sub_copy;
0279
0280
0281
0282
0283 sub_copy = kmemdup(subelement, subie_len, gfp);
0284 if (!sub_copy)
0285 return 0;
0286
0287 pos = &new_ie[0];
0288
0289
0290 tmp_new = cfg80211_find_ie(WLAN_EID_SSID, sub_copy, subie_len);
0291 if (tmp_new) {
0292 memcpy(pos, tmp_new, tmp_new[1] + 2);
0293 pos += (tmp_new[1] + 2);
0294 }
0295
0296
0297 non_inherit_elem =
0298 cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
0299 sub_copy, subie_len);
0300
0301
0302
0303
0304 tmp_old = cfg80211_find_ie(WLAN_EID_SSID, ie, ielen);
0305 tmp_old = (tmp_old) ? tmp_old + tmp_old[1] + 2 : ie;
0306
0307 while (tmp_old + tmp_old[1] + 2 - ie <= ielen) {
0308 if (tmp_old[0] == 0) {
0309 tmp_old++;
0310 continue;
0311 }
0312
0313 if (tmp_old[0] == WLAN_EID_EXTENSION)
0314 tmp = (u8 *)cfg80211_find_ext_ie(tmp_old[2], sub_copy,
0315 subie_len);
0316 else
0317 tmp = (u8 *)cfg80211_find_ie(tmp_old[0], sub_copy,
0318 subie_len);
0319
0320 if (!tmp) {
0321 const struct element *old_elem = (void *)tmp_old;
0322
0323
0324 if (cfg80211_is_element_inherited(old_elem,
0325 non_inherit_elem)) {
0326 memcpy(pos, tmp_old, tmp_old[1] + 2);
0327 pos += tmp_old[1] + 2;
0328 }
0329 } else {
0330
0331
0332
0333
0334
0335
0336
0337 if (tmp_old[0] == WLAN_EID_VENDOR_SPECIFIC) {
0338 if (!memcmp(tmp_old + 2, tmp + 2, 5)) {
0339
0340
0341
0342 memcpy(pos, tmp, tmp[1] + 2);
0343 pos += tmp[1] + 2;
0344 tmp[0] = WLAN_EID_SSID;
0345 } else {
0346 memcpy(pos, tmp_old, tmp_old[1] + 2);
0347 pos += tmp_old[1] + 2;
0348 }
0349 } else {
0350
0351 memcpy(pos, tmp, tmp[1] + 2);
0352 pos += tmp[1] + 2;
0353 tmp[0] = WLAN_EID_SSID;
0354 }
0355 }
0356
0357 if (tmp_old + tmp_old[1] + 2 - ie == ielen)
0358 break;
0359
0360 tmp_old += tmp_old[1] + 2;
0361 }
0362
0363
0364
0365
0366 tmp_new = sub_copy;
0367 while (tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) {
0368 if (!(tmp_new[0] == WLAN_EID_NON_TX_BSSID_CAP ||
0369 tmp_new[0] == WLAN_EID_SSID)) {
0370 memcpy(pos, tmp_new, tmp_new[1] + 2);
0371 pos += tmp_new[1] + 2;
0372 }
0373 if (tmp_new + tmp_new[1] + 2 - sub_copy == subie_len)
0374 break;
0375 tmp_new += tmp_new[1] + 2;
0376 }
0377
0378 kfree(sub_copy);
0379 return pos - new_ie;
0380 }
0381
0382 static bool is_bss(struct cfg80211_bss *a, const u8 *bssid,
0383 const u8 *ssid, size_t ssid_len)
0384 {
0385 const struct cfg80211_bss_ies *ies;
0386 const struct element *ssid_elem;
0387
0388 if (bssid && !ether_addr_equal(a->bssid, bssid))
0389 return false;
0390
0391 if (!ssid)
0392 return true;
0393
0394 ies = rcu_access_pointer(a->ies);
0395 if (!ies)
0396 return false;
0397 ssid_elem = cfg80211_find_elem(WLAN_EID_SSID, ies->data, ies->len);
0398 if (!ssid_elem)
0399 return false;
0400 if (ssid_elem->datalen != ssid_len)
0401 return false;
0402 return memcmp(ssid_elem->data, ssid, ssid_len) == 0;
0403 }
0404
0405 static int
0406 cfg80211_add_nontrans_list(struct cfg80211_bss *trans_bss,
0407 struct cfg80211_bss *nontrans_bss)
0408 {
0409 const struct element *ssid_elem;
0410 struct cfg80211_bss *bss = NULL;
0411
0412 rcu_read_lock();
0413 ssid_elem = ieee80211_bss_get_elem(nontrans_bss, WLAN_EID_SSID);
0414 if (!ssid_elem) {
0415 rcu_read_unlock();
0416 return -EINVAL;
0417 }
0418
0419
0420 list_for_each_entry(bss, &trans_bss->nontrans_list, nontrans_list) {
0421 if (is_bss(bss, nontrans_bss->bssid, ssid_elem->data,
0422 ssid_elem->datalen)) {
0423 rcu_read_unlock();
0424 return 0;
0425 }
0426 }
0427
0428 rcu_read_unlock();
0429
0430
0431 list_add_tail(&nontrans_bss->nontrans_list, &trans_bss->nontrans_list);
0432 return 0;
0433 }
0434
0435 static void __cfg80211_bss_expire(struct cfg80211_registered_device *rdev,
0436 unsigned long expire_time)
0437 {
0438 struct cfg80211_internal_bss *bss, *tmp;
0439 bool expired = false;
0440
0441 lockdep_assert_held(&rdev->bss_lock);
0442
0443 list_for_each_entry_safe(bss, tmp, &rdev->bss_list, list) {
0444 if (atomic_read(&bss->hold))
0445 continue;
0446 if (!time_after(expire_time, bss->ts))
0447 continue;
0448
0449 if (__cfg80211_unlink_bss(rdev, bss))
0450 expired = true;
0451 }
0452
0453 if (expired)
0454 rdev->bss_generation++;
0455 }
0456
0457 static bool cfg80211_bss_expire_oldest(struct cfg80211_registered_device *rdev)
0458 {
0459 struct cfg80211_internal_bss *bss, *oldest = NULL;
0460 bool ret;
0461
0462 lockdep_assert_held(&rdev->bss_lock);
0463
0464 list_for_each_entry(bss, &rdev->bss_list, list) {
0465 if (atomic_read(&bss->hold))
0466 continue;
0467
0468 if (!list_empty(&bss->hidden_list) &&
0469 !bss->pub.hidden_beacon_bss)
0470 continue;
0471
0472 if (oldest && time_before(oldest->ts, bss->ts))
0473 continue;
0474 oldest = bss;
0475 }
0476
0477 if (WARN_ON(!oldest))
0478 return false;
0479
0480
0481
0482
0483
0484
0485
0486 ret = __cfg80211_unlink_bss(rdev, oldest);
0487 WARN_ON(!ret);
0488 return ret;
0489 }
0490
0491 static u8 cfg80211_parse_bss_param(u8 data,
0492 struct cfg80211_colocated_ap *coloc_ap)
0493 {
0494 coloc_ap->oct_recommended =
0495 u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_OCT_RECOMMENDED);
0496 coloc_ap->same_ssid =
0497 u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_SAME_SSID);
0498 coloc_ap->multi_bss =
0499 u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_MULTI_BSSID);
0500 coloc_ap->transmitted_bssid =
0501 u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_TRANSMITTED_BSSID);
0502 coloc_ap->unsolicited_probe =
0503 u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_PROBE_ACTIVE);
0504 coloc_ap->colocated_ess =
0505 u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_COLOC_ESS);
0506
0507 return u8_get_bits(data, IEEE80211_RNR_TBTT_PARAMS_COLOC_AP);
0508 }
0509
0510 static int cfg80211_calc_short_ssid(const struct cfg80211_bss_ies *ies,
0511 const struct element **elem, u32 *s_ssid)
0512 {
0513
0514 *elem = cfg80211_find_elem(WLAN_EID_SSID, ies->data, ies->len);
0515 if (!*elem || (*elem)->datalen > IEEE80211_MAX_SSID_LEN)
0516 return -EINVAL;
0517
0518 *s_ssid = ~crc32_le(~0, (*elem)->data, (*elem)->datalen);
0519 return 0;
0520 }
0521
0522 static void cfg80211_free_coloc_ap_list(struct list_head *coloc_ap_list)
0523 {
0524 struct cfg80211_colocated_ap *ap, *tmp_ap;
0525
0526 list_for_each_entry_safe(ap, tmp_ap, coloc_ap_list, list) {
0527 list_del(&ap->list);
0528 kfree(ap);
0529 }
0530 }
0531
0532 static int cfg80211_parse_ap_info(struct cfg80211_colocated_ap *entry,
0533 const u8 *pos, u8 length,
0534 const struct element *ssid_elem,
0535 int s_ssid_tmp)
0536 {
0537
0538 pos++;
0539
0540 memcpy(entry->bssid, pos, ETH_ALEN);
0541 pos += ETH_ALEN;
0542
0543 if (length == IEEE80211_TBTT_INFO_OFFSET_BSSID_SSSID_BSS_PARAM) {
0544 memcpy(&entry->short_ssid, pos,
0545 sizeof(entry->short_ssid));
0546 entry->short_ssid_valid = true;
0547 pos += 4;
0548 }
0549
0550
0551 if (!cfg80211_parse_bss_param(*pos, entry))
0552 return -EINVAL;
0553 pos++;
0554
0555 if (length == IEEE80211_TBTT_INFO_OFFSET_BSSID_BSS_PARAM) {
0556
0557
0558
0559
0560
0561 if (!entry->same_ssid)
0562 return 0;
0563 }
0564
0565 if (entry->same_ssid) {
0566 entry->short_ssid = s_ssid_tmp;
0567 entry->short_ssid_valid = true;
0568
0569
0570
0571
0572
0573
0574 memcpy(&entry->ssid, &ssid_elem->data,
0575 ssid_elem->datalen);
0576 entry->ssid_len = ssid_elem->datalen;
0577 }
0578 return 0;
0579 }
0580
0581 static int cfg80211_parse_colocated_ap(const struct cfg80211_bss_ies *ies,
0582 struct list_head *list)
0583 {
0584 struct ieee80211_neighbor_ap_info *ap_info;
0585 const struct element *elem, *ssid_elem;
0586 const u8 *pos, *end;
0587 u32 s_ssid_tmp;
0588 int n_coloc = 0, ret;
0589 LIST_HEAD(ap_list);
0590
0591 elem = cfg80211_find_elem(WLAN_EID_REDUCED_NEIGHBOR_REPORT, ies->data,
0592 ies->len);
0593 if (!elem)
0594 return 0;
0595
0596 pos = elem->data;
0597 end = pos + elem->datalen;
0598
0599 ret = cfg80211_calc_short_ssid(ies, &ssid_elem, &s_ssid_tmp);
0600 if (ret)
0601 return ret;
0602
0603
0604 while (pos + sizeof(*ap_info) <= end) {
0605 enum nl80211_band band;
0606 int freq;
0607 u8 length, i, count;
0608
0609 ap_info = (void *)pos;
0610 count = u8_get_bits(ap_info->tbtt_info_hdr,
0611 IEEE80211_AP_INFO_TBTT_HDR_COUNT) + 1;
0612 length = ap_info->tbtt_info_len;
0613
0614 pos += sizeof(*ap_info);
0615
0616 if (!ieee80211_operating_class_to_band(ap_info->op_class,
0617 &band))
0618 break;
0619
0620 freq = ieee80211_channel_to_frequency(ap_info->channel, band);
0621
0622 if (end - pos < count * length)
0623 break;
0624
0625
0626
0627
0628
0629
0630
0631 if (band != NL80211_BAND_6GHZ ||
0632 (length != IEEE80211_TBTT_INFO_OFFSET_BSSID_BSS_PARAM &&
0633 length < IEEE80211_TBTT_INFO_OFFSET_BSSID_SSSID_BSS_PARAM)) {
0634 pos += count * length;
0635 continue;
0636 }
0637
0638 for (i = 0; i < count; i++) {
0639 struct cfg80211_colocated_ap *entry;
0640
0641 entry = kzalloc(sizeof(*entry) + IEEE80211_MAX_SSID_LEN,
0642 GFP_ATOMIC);
0643
0644 if (!entry)
0645 break;
0646
0647 entry->center_freq = freq;
0648
0649 if (!cfg80211_parse_ap_info(entry, pos, length,
0650 ssid_elem, s_ssid_tmp)) {
0651 n_coloc++;
0652 list_add_tail(&entry->list, &ap_list);
0653 } else {
0654 kfree(entry);
0655 }
0656
0657 pos += length;
0658 }
0659 }
0660
0661 if (pos != end) {
0662 cfg80211_free_coloc_ap_list(&ap_list);
0663 return 0;
0664 }
0665
0666 list_splice_tail(&ap_list, list);
0667 return n_coloc;
0668 }
0669
0670 static void cfg80211_scan_req_add_chan(struct cfg80211_scan_request *request,
0671 struct ieee80211_channel *chan,
0672 bool add_to_6ghz)
0673 {
0674 int i;
0675 u32 n_channels = request->n_channels;
0676 struct cfg80211_scan_6ghz_params *params =
0677 &request->scan_6ghz_params[request->n_6ghz_params];
0678
0679 for (i = 0; i < n_channels; i++) {
0680 if (request->channels[i] == chan) {
0681 if (add_to_6ghz)
0682 params->channel_idx = i;
0683 return;
0684 }
0685 }
0686
0687 request->channels[n_channels] = chan;
0688 if (add_to_6ghz)
0689 request->scan_6ghz_params[request->n_6ghz_params].channel_idx =
0690 n_channels;
0691
0692 request->n_channels++;
0693 }
0694
0695 static bool cfg80211_find_ssid_match(struct cfg80211_colocated_ap *ap,
0696 struct cfg80211_scan_request *request)
0697 {
0698 int i;
0699 u32 s_ssid;
0700
0701 for (i = 0; i < request->n_ssids; i++) {
0702
0703 if (!request->ssids[i].ssid_len) {
0704 if (ap->multi_bss && !ap->transmitted_bssid)
0705 continue;
0706
0707 return true;
0708 }
0709
0710 if (ap->ssid_len &&
0711 ap->ssid_len == request->ssids[i].ssid_len) {
0712 if (!memcmp(request->ssids[i].ssid, ap->ssid,
0713 ap->ssid_len))
0714 return true;
0715 } else if (ap->short_ssid_valid) {
0716 s_ssid = ~crc32_le(~0, request->ssids[i].ssid,
0717 request->ssids[i].ssid_len);
0718
0719 if (ap->short_ssid == s_ssid)
0720 return true;
0721 }
0722 }
0723
0724 return false;
0725 }
0726
0727 static int cfg80211_scan_6ghz(struct cfg80211_registered_device *rdev)
0728 {
0729 u8 i;
0730 struct cfg80211_colocated_ap *ap;
0731 int n_channels, count = 0, err;
0732 struct cfg80211_scan_request *request, *rdev_req = rdev->scan_req;
0733 LIST_HEAD(coloc_ap_list);
0734 bool need_scan_psc = true;
0735 const struct ieee80211_sband_iftype_data *iftd;
0736
0737 rdev_req->scan_6ghz = true;
0738
0739 if (!rdev->wiphy.bands[NL80211_BAND_6GHZ])
0740 return -EOPNOTSUPP;
0741
0742 iftd = ieee80211_get_sband_iftype_data(rdev->wiphy.bands[NL80211_BAND_6GHZ],
0743 rdev_req->wdev->iftype);
0744 if (!iftd || !iftd->he_cap.has_he)
0745 return -EOPNOTSUPP;
0746
0747 n_channels = rdev->wiphy.bands[NL80211_BAND_6GHZ]->n_channels;
0748
0749 if (rdev_req->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ) {
0750 struct cfg80211_internal_bss *intbss;
0751
0752 spin_lock_bh(&rdev->bss_lock);
0753 list_for_each_entry(intbss, &rdev->bss_list, list) {
0754 struct cfg80211_bss *res = &intbss->pub;
0755 const struct cfg80211_bss_ies *ies;
0756
0757 ies = rcu_access_pointer(res->ies);
0758 count += cfg80211_parse_colocated_ap(ies,
0759 &coloc_ap_list);
0760 }
0761 spin_unlock_bh(&rdev->bss_lock);
0762 }
0763
0764 request = kzalloc(struct_size(request, channels, n_channels) +
0765 sizeof(*request->scan_6ghz_params) * count +
0766 sizeof(*request->ssids) * rdev_req->n_ssids,
0767 GFP_KERNEL);
0768 if (!request) {
0769 cfg80211_free_coloc_ap_list(&coloc_ap_list);
0770 return -ENOMEM;
0771 }
0772
0773 *request = *rdev_req;
0774 request->n_channels = 0;
0775 request->scan_6ghz_params =
0776 (void *)&request->channels[n_channels];
0777
0778
0779
0780
0781
0782
0783 if (count && request->n_ssids == 1 && request->ssids[0].ssid_len) {
0784 list_for_each_entry(ap, &coloc_ap_list, list) {
0785 if (ap->colocated_ess &&
0786 cfg80211_find_ssid_match(ap, request)) {
0787 need_scan_psc = false;
0788 break;
0789 }
0790 }
0791 }
0792
0793
0794
0795
0796
0797
0798 for (i = 0; i < rdev_req->n_channels; i++) {
0799 if (rdev_req->channels[i]->band == NL80211_BAND_6GHZ &&
0800 ((need_scan_psc &&
0801 cfg80211_channel_is_psc(rdev_req->channels[i])) ||
0802 !(rdev_req->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ))) {
0803 cfg80211_scan_req_add_chan(request,
0804 rdev_req->channels[i],
0805 false);
0806 }
0807 }
0808
0809 if (!(rdev_req->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ))
0810 goto skip;
0811
0812 list_for_each_entry(ap, &coloc_ap_list, list) {
0813 bool found = false;
0814 struct cfg80211_scan_6ghz_params *scan_6ghz_params =
0815 &request->scan_6ghz_params[request->n_6ghz_params];
0816 struct ieee80211_channel *chan =
0817 ieee80211_get_channel(&rdev->wiphy, ap->center_freq);
0818
0819 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
0820 continue;
0821
0822 for (i = 0; i < rdev_req->n_channels; i++) {
0823 if (rdev_req->channels[i] == chan)
0824 found = true;
0825 }
0826
0827 if (!found)
0828 continue;
0829
0830 if (request->n_ssids > 0 &&
0831 !cfg80211_find_ssid_match(ap, request))
0832 continue;
0833
0834 if (!request->n_ssids && ap->multi_bss && !ap->transmitted_bssid)
0835 continue;
0836
0837 cfg80211_scan_req_add_chan(request, chan, true);
0838 memcpy(scan_6ghz_params->bssid, ap->bssid, ETH_ALEN);
0839 scan_6ghz_params->short_ssid = ap->short_ssid;
0840 scan_6ghz_params->short_ssid_valid = ap->short_ssid_valid;
0841 scan_6ghz_params->unsolicited_probe = ap->unsolicited_probe;
0842
0843
0844
0845
0846
0847
0848
0849 if (cfg80211_channel_is_psc(chan) && !need_scan_psc)
0850 scan_6ghz_params->psc_no_listen = true;
0851
0852 request->n_6ghz_params++;
0853 }
0854
0855 skip:
0856 cfg80211_free_coloc_ap_list(&coloc_ap_list);
0857
0858 if (request->n_channels) {
0859 struct cfg80211_scan_request *old = rdev->int_scan_req;
0860 rdev->int_scan_req = request;
0861
0862
0863
0864
0865
0866
0867 request->ssids = (void *)&request->channels[request->n_channels];
0868 request->n_ssids = rdev_req->n_ssids;
0869 memcpy(request->ssids, rdev_req->ssids, sizeof(*request->ssids) *
0870 request->n_ssids);
0871
0872
0873
0874
0875
0876 if (old)
0877 rdev->int_scan_req->info = old->info;
0878
0879 err = rdev_scan(rdev, request);
0880 if (err) {
0881 rdev->int_scan_req = old;
0882 kfree(request);
0883 } else {
0884 kfree(old);
0885 }
0886
0887 return err;
0888 }
0889
0890 kfree(request);
0891 return -EINVAL;
0892 }
0893
0894 int cfg80211_scan(struct cfg80211_registered_device *rdev)
0895 {
0896 struct cfg80211_scan_request *request;
0897 struct cfg80211_scan_request *rdev_req = rdev->scan_req;
0898 u32 n_channels = 0, idx, i;
0899
0900 if (!(rdev->wiphy.flags & WIPHY_FLAG_SPLIT_SCAN_6GHZ))
0901 return rdev_scan(rdev, rdev_req);
0902
0903 for (i = 0; i < rdev_req->n_channels; i++) {
0904 if (rdev_req->channels[i]->band != NL80211_BAND_6GHZ)
0905 n_channels++;
0906 }
0907
0908 if (!n_channels)
0909 return cfg80211_scan_6ghz(rdev);
0910
0911 request = kzalloc(struct_size(request, channels, n_channels),
0912 GFP_KERNEL);
0913 if (!request)
0914 return -ENOMEM;
0915
0916 *request = *rdev_req;
0917 request->n_channels = n_channels;
0918
0919 for (i = idx = 0; i < rdev_req->n_channels; i++) {
0920 if (rdev_req->channels[i]->band != NL80211_BAND_6GHZ)
0921 request->channels[idx++] = rdev_req->channels[i];
0922 }
0923
0924 rdev_req->scan_6ghz = false;
0925 rdev->int_scan_req = request;
0926 return rdev_scan(rdev, request);
0927 }
0928
0929 void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
0930 bool send_message)
0931 {
0932 struct cfg80211_scan_request *request, *rdev_req;
0933 struct wireless_dev *wdev;
0934 struct sk_buff *msg;
0935 #ifdef CONFIG_CFG80211_WEXT
0936 union iwreq_data wrqu;
0937 #endif
0938
0939 lockdep_assert_held(&rdev->wiphy.mtx);
0940
0941 if (rdev->scan_msg) {
0942 nl80211_send_scan_msg(rdev, rdev->scan_msg);
0943 rdev->scan_msg = NULL;
0944 return;
0945 }
0946
0947 rdev_req = rdev->scan_req;
0948 if (!rdev_req)
0949 return;
0950
0951 wdev = rdev_req->wdev;
0952 request = rdev->int_scan_req ? rdev->int_scan_req : rdev_req;
0953
0954 if (wdev_running(wdev) &&
0955 (rdev->wiphy.flags & WIPHY_FLAG_SPLIT_SCAN_6GHZ) &&
0956 !rdev_req->scan_6ghz && !request->info.aborted &&
0957 !cfg80211_scan_6ghz(rdev))
0958 return;
0959
0960
0961
0962
0963
0964
0965 if (wdev->netdev)
0966 cfg80211_sme_scan_done(wdev->netdev);
0967
0968 if (!request->info.aborted &&
0969 request->flags & NL80211_SCAN_FLAG_FLUSH) {
0970
0971 spin_lock_bh(&rdev->bss_lock);
0972 __cfg80211_bss_expire(rdev, request->scan_start);
0973 spin_unlock_bh(&rdev->bss_lock);
0974 }
0975
0976 msg = nl80211_build_scan_msg(rdev, wdev, request->info.aborted);
0977
0978 #ifdef CONFIG_CFG80211_WEXT
0979 if (wdev->netdev && !request->info.aborted) {
0980 memset(&wrqu, 0, sizeof(wrqu));
0981
0982 wireless_send_event(wdev->netdev, SIOCGIWSCAN, &wrqu, NULL);
0983 }
0984 #endif
0985
0986 dev_put(wdev->netdev);
0987
0988 kfree(rdev->int_scan_req);
0989 rdev->int_scan_req = NULL;
0990
0991 kfree(rdev->scan_req);
0992 rdev->scan_req = NULL;
0993
0994 if (!send_message)
0995 rdev->scan_msg = msg;
0996 else
0997 nl80211_send_scan_msg(rdev, msg);
0998 }
0999
1000 void __cfg80211_scan_done(struct work_struct *wk)
1001 {
1002 struct cfg80211_registered_device *rdev;
1003
1004 rdev = container_of(wk, struct cfg80211_registered_device,
1005 scan_done_wk);
1006
1007 wiphy_lock(&rdev->wiphy);
1008 ___cfg80211_scan_done(rdev, true);
1009 wiphy_unlock(&rdev->wiphy);
1010 }
1011
1012 void cfg80211_scan_done(struct cfg80211_scan_request *request,
1013 struct cfg80211_scan_info *info)
1014 {
1015 struct cfg80211_scan_info old_info = request->info;
1016
1017 trace_cfg80211_scan_done(request, info);
1018 WARN_ON(request != wiphy_to_rdev(request->wiphy)->scan_req &&
1019 request != wiphy_to_rdev(request->wiphy)->int_scan_req);
1020
1021 request->info = *info;
1022
1023
1024
1025
1026
1027
1028 if (request->scan_6ghz && old_info.scan_start_tsf) {
1029 request->info.scan_start_tsf = old_info.scan_start_tsf;
1030 memcpy(request->info.tsf_bssid, old_info.tsf_bssid,
1031 sizeof(request->info.tsf_bssid));
1032 }
1033
1034 request->notified = true;
1035 queue_work(cfg80211_wq, &wiphy_to_rdev(request->wiphy)->scan_done_wk);
1036 }
1037 EXPORT_SYMBOL(cfg80211_scan_done);
1038
1039 void cfg80211_add_sched_scan_req(struct cfg80211_registered_device *rdev,
1040 struct cfg80211_sched_scan_request *req)
1041 {
1042 lockdep_assert_held(&rdev->wiphy.mtx);
1043
1044 list_add_rcu(&req->list, &rdev->sched_scan_req_list);
1045 }
1046
1047 static void cfg80211_del_sched_scan_req(struct cfg80211_registered_device *rdev,
1048 struct cfg80211_sched_scan_request *req)
1049 {
1050 lockdep_assert_held(&rdev->wiphy.mtx);
1051
1052 list_del_rcu(&req->list);
1053 kfree_rcu(req, rcu_head);
1054 }
1055
1056 static struct cfg80211_sched_scan_request *
1057 cfg80211_find_sched_scan_req(struct cfg80211_registered_device *rdev, u64 reqid)
1058 {
1059 struct cfg80211_sched_scan_request *pos;
1060
1061 list_for_each_entry_rcu(pos, &rdev->sched_scan_req_list, list,
1062 lockdep_is_held(&rdev->wiphy.mtx)) {
1063 if (pos->reqid == reqid)
1064 return pos;
1065 }
1066 return NULL;
1067 }
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077 int cfg80211_sched_scan_req_possible(struct cfg80211_registered_device *rdev,
1078 bool want_multi)
1079 {
1080 struct cfg80211_sched_scan_request *pos;
1081 int i = 0;
1082
1083 list_for_each_entry(pos, &rdev->sched_scan_req_list, list) {
1084
1085 if (!i && !pos->reqid)
1086 return -EINPROGRESS;
1087 i++;
1088 }
1089
1090 if (i) {
1091
1092 if (!want_multi)
1093 return -EINPROGRESS;
1094
1095
1096 if (i == rdev->wiphy.max_sched_scan_reqs)
1097 return -ENOSPC;
1098 }
1099 return 0;
1100 }
1101
1102 void cfg80211_sched_scan_results_wk(struct work_struct *work)
1103 {
1104 struct cfg80211_registered_device *rdev;
1105 struct cfg80211_sched_scan_request *req, *tmp;
1106
1107 rdev = container_of(work, struct cfg80211_registered_device,
1108 sched_scan_res_wk);
1109
1110 wiphy_lock(&rdev->wiphy);
1111 list_for_each_entry_safe(req, tmp, &rdev->sched_scan_req_list, list) {
1112 if (req->report_results) {
1113 req->report_results = false;
1114 if (req->flags & NL80211_SCAN_FLAG_FLUSH) {
1115
1116 spin_lock_bh(&rdev->bss_lock);
1117 __cfg80211_bss_expire(rdev, req->scan_start);
1118 spin_unlock_bh(&rdev->bss_lock);
1119 req->scan_start = jiffies;
1120 }
1121 nl80211_send_sched_scan(req,
1122 NL80211_CMD_SCHED_SCAN_RESULTS);
1123 }
1124 }
1125 wiphy_unlock(&rdev->wiphy);
1126 }
1127
1128 void cfg80211_sched_scan_results(struct wiphy *wiphy, u64 reqid)
1129 {
1130 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
1131 struct cfg80211_sched_scan_request *request;
1132
1133 trace_cfg80211_sched_scan_results(wiphy, reqid);
1134
1135
1136 rcu_read_lock();
1137 request = cfg80211_find_sched_scan_req(rdev, reqid);
1138 if (request) {
1139 request->report_results = true;
1140 queue_work(cfg80211_wq, &rdev->sched_scan_res_wk);
1141 }
1142 rcu_read_unlock();
1143 }
1144 EXPORT_SYMBOL(cfg80211_sched_scan_results);
1145
1146 void cfg80211_sched_scan_stopped_locked(struct wiphy *wiphy, u64 reqid)
1147 {
1148 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
1149
1150 lockdep_assert_held(&wiphy->mtx);
1151
1152 trace_cfg80211_sched_scan_stopped(wiphy, reqid);
1153
1154 __cfg80211_stop_sched_scan(rdev, reqid, true);
1155 }
1156 EXPORT_SYMBOL(cfg80211_sched_scan_stopped_locked);
1157
1158 void cfg80211_sched_scan_stopped(struct wiphy *wiphy, u64 reqid)
1159 {
1160 wiphy_lock(wiphy);
1161 cfg80211_sched_scan_stopped_locked(wiphy, reqid);
1162 wiphy_unlock(wiphy);
1163 }
1164 EXPORT_SYMBOL(cfg80211_sched_scan_stopped);
1165
1166 int cfg80211_stop_sched_scan_req(struct cfg80211_registered_device *rdev,
1167 struct cfg80211_sched_scan_request *req,
1168 bool driver_initiated)
1169 {
1170 lockdep_assert_held(&rdev->wiphy.mtx);
1171
1172 if (!driver_initiated) {
1173 int err = rdev_sched_scan_stop(rdev, req->dev, req->reqid);
1174 if (err)
1175 return err;
1176 }
1177
1178 nl80211_send_sched_scan(req, NL80211_CMD_SCHED_SCAN_STOPPED);
1179
1180 cfg80211_del_sched_scan_req(rdev, req);
1181
1182 return 0;
1183 }
1184
1185 int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
1186 u64 reqid, bool driver_initiated)
1187 {
1188 struct cfg80211_sched_scan_request *sched_scan_req;
1189
1190 lockdep_assert_held(&rdev->wiphy.mtx);
1191
1192 sched_scan_req = cfg80211_find_sched_scan_req(rdev, reqid);
1193 if (!sched_scan_req)
1194 return -ENOENT;
1195
1196 return cfg80211_stop_sched_scan_req(rdev, sched_scan_req,
1197 driver_initiated);
1198 }
1199
1200 void cfg80211_bss_age(struct cfg80211_registered_device *rdev,
1201 unsigned long age_secs)
1202 {
1203 struct cfg80211_internal_bss *bss;
1204 unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC);
1205
1206 spin_lock_bh(&rdev->bss_lock);
1207 list_for_each_entry(bss, &rdev->bss_list, list)
1208 bss->ts -= age_jiffies;
1209 spin_unlock_bh(&rdev->bss_lock);
1210 }
1211
1212 void cfg80211_bss_expire(struct cfg80211_registered_device *rdev)
1213 {
1214 __cfg80211_bss_expire(rdev, jiffies - IEEE80211_SCAN_RESULT_EXPIRE);
1215 }
1216
1217 void cfg80211_bss_flush(struct wiphy *wiphy)
1218 {
1219 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
1220
1221 spin_lock_bh(&rdev->bss_lock);
1222 __cfg80211_bss_expire(rdev, jiffies);
1223 spin_unlock_bh(&rdev->bss_lock);
1224 }
1225 EXPORT_SYMBOL(cfg80211_bss_flush);
1226
1227 const struct element *
1228 cfg80211_find_elem_match(u8 eid, const u8 *ies, unsigned int len,
1229 const u8 *match, unsigned int match_len,
1230 unsigned int match_offset)
1231 {
1232 const struct element *elem;
1233
1234 for_each_element_id(elem, eid, ies, len) {
1235 if (elem->datalen >= match_offset + match_len &&
1236 !memcmp(elem->data + match_offset, match, match_len))
1237 return elem;
1238 }
1239
1240 return NULL;
1241 }
1242 EXPORT_SYMBOL(cfg80211_find_elem_match);
1243
1244 const struct element *cfg80211_find_vendor_elem(unsigned int oui, int oui_type,
1245 const u8 *ies,
1246 unsigned int len)
1247 {
1248 const struct element *elem;
1249 u8 match[] = { oui >> 16, oui >> 8, oui, oui_type };
1250 int match_len = (oui_type < 0) ? 3 : sizeof(match);
1251
1252 if (WARN_ON(oui_type > 0xff))
1253 return NULL;
1254
1255 elem = cfg80211_find_elem_match(WLAN_EID_VENDOR_SPECIFIC, ies, len,
1256 match, match_len, 0);
1257
1258 if (!elem || elem->datalen < 4)
1259 return NULL;
1260
1261 return elem;
1262 }
1263 EXPORT_SYMBOL(cfg80211_find_vendor_elem);
1264
1265
1266
1267
1268
1269
1270
1271 enum bss_compare_mode {
1272 BSS_CMP_REGULAR,
1273 BSS_CMP_HIDE_ZLEN,
1274 BSS_CMP_HIDE_NUL,
1275 };
1276
1277 static int cmp_bss(struct cfg80211_bss *a,
1278 struct cfg80211_bss *b,
1279 enum bss_compare_mode mode)
1280 {
1281 const struct cfg80211_bss_ies *a_ies, *b_ies;
1282 const u8 *ie1 = NULL;
1283 const u8 *ie2 = NULL;
1284 int i, r;
1285
1286 if (a->channel != b->channel)
1287 return b->channel->center_freq - a->channel->center_freq;
1288
1289 a_ies = rcu_access_pointer(a->ies);
1290 if (!a_ies)
1291 return -1;
1292 b_ies = rcu_access_pointer(b->ies);
1293 if (!b_ies)
1294 return 1;
1295
1296 if (WLAN_CAPABILITY_IS_STA_BSS(a->capability))
1297 ie1 = cfg80211_find_ie(WLAN_EID_MESH_ID,
1298 a_ies->data, a_ies->len);
1299 if (WLAN_CAPABILITY_IS_STA_BSS(b->capability))
1300 ie2 = cfg80211_find_ie(WLAN_EID_MESH_ID,
1301 b_ies->data, b_ies->len);
1302 if (ie1 && ie2) {
1303 int mesh_id_cmp;
1304
1305 if (ie1[1] == ie2[1])
1306 mesh_id_cmp = memcmp(ie1 + 2, ie2 + 2, ie1[1]);
1307 else
1308 mesh_id_cmp = ie2[1] - ie1[1];
1309
1310 ie1 = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
1311 a_ies->data, a_ies->len);
1312 ie2 = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
1313 b_ies->data, b_ies->len);
1314 if (ie1 && ie2) {
1315 if (mesh_id_cmp)
1316 return mesh_id_cmp;
1317 if (ie1[1] != ie2[1])
1318 return ie2[1] - ie1[1];
1319 return memcmp(ie1 + 2, ie2 + 2, ie1[1]);
1320 }
1321 }
1322
1323 r = memcmp(a->bssid, b->bssid, sizeof(a->bssid));
1324 if (r)
1325 return r;
1326
1327 ie1 = cfg80211_find_ie(WLAN_EID_SSID, a_ies->data, a_ies->len);
1328 ie2 = cfg80211_find_ie(WLAN_EID_SSID, b_ies->data, b_ies->len);
1329
1330 if (!ie1 && !ie2)
1331 return 0;
1332
1333
1334
1335
1336
1337
1338
1339
1340 if (!ie1)
1341 return -1;
1342 if (!ie2)
1343 return 1;
1344
1345 switch (mode) {
1346 case BSS_CMP_HIDE_ZLEN:
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359 return ie2[1];
1360 case BSS_CMP_REGULAR:
1361 default:
1362
1363 if (ie1[1] != ie2[1])
1364 return ie2[1] - ie1[1];
1365 return memcmp(ie1 + 2, ie2 + 2, ie1[1]);
1366 case BSS_CMP_HIDE_NUL:
1367 if (ie1[1] != ie2[1])
1368 return ie2[1] - ie1[1];
1369
1370 for (i = 0; i < ie2[1]; i++)
1371 if (ie2[i + 2])
1372 return -1;
1373 return 0;
1374 }
1375 }
1376
1377 static bool cfg80211_bss_type_match(u16 capability,
1378 enum nl80211_band band,
1379 enum ieee80211_bss_type bss_type)
1380 {
1381 bool ret = true;
1382 u16 mask, val;
1383
1384 if (bss_type == IEEE80211_BSS_TYPE_ANY)
1385 return ret;
1386
1387 if (band == NL80211_BAND_60GHZ) {
1388 mask = WLAN_CAPABILITY_DMG_TYPE_MASK;
1389 switch (bss_type) {
1390 case IEEE80211_BSS_TYPE_ESS:
1391 val = WLAN_CAPABILITY_DMG_TYPE_AP;
1392 break;
1393 case IEEE80211_BSS_TYPE_PBSS:
1394 val = WLAN_CAPABILITY_DMG_TYPE_PBSS;
1395 break;
1396 case IEEE80211_BSS_TYPE_IBSS:
1397 val = WLAN_CAPABILITY_DMG_TYPE_IBSS;
1398 break;
1399 default:
1400 return false;
1401 }
1402 } else {
1403 mask = WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS;
1404 switch (bss_type) {
1405 case IEEE80211_BSS_TYPE_ESS:
1406 val = WLAN_CAPABILITY_ESS;
1407 break;
1408 case IEEE80211_BSS_TYPE_IBSS:
1409 val = WLAN_CAPABILITY_IBSS;
1410 break;
1411 case IEEE80211_BSS_TYPE_MBSS:
1412 val = 0;
1413 break;
1414 default:
1415 return false;
1416 }
1417 }
1418
1419 ret = ((capability & mask) == val);
1420 return ret;
1421 }
1422
1423
1424 struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
1425 struct ieee80211_channel *channel,
1426 const u8 *bssid,
1427 const u8 *ssid, size_t ssid_len,
1428 enum ieee80211_bss_type bss_type,
1429 enum ieee80211_privacy privacy)
1430 {
1431 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
1432 struct cfg80211_internal_bss *bss, *res = NULL;
1433 unsigned long now = jiffies;
1434 int bss_privacy;
1435
1436 trace_cfg80211_get_bss(wiphy, channel, bssid, ssid, ssid_len, bss_type,
1437 privacy);
1438
1439 spin_lock_bh(&rdev->bss_lock);
1440
1441 list_for_each_entry(bss, &rdev->bss_list, list) {
1442 if (!cfg80211_bss_type_match(bss->pub.capability,
1443 bss->pub.channel->band, bss_type))
1444 continue;
1445
1446 bss_privacy = (bss->pub.capability & WLAN_CAPABILITY_PRIVACY);
1447 if ((privacy == IEEE80211_PRIVACY_ON && !bss_privacy) ||
1448 (privacy == IEEE80211_PRIVACY_OFF && bss_privacy))
1449 continue;
1450 if (channel && bss->pub.channel != channel)
1451 continue;
1452 if (!is_valid_ether_addr(bss->pub.bssid))
1453 continue;
1454
1455 if (time_after(now, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE) &&
1456 !atomic_read(&bss->hold))
1457 continue;
1458 if (is_bss(&bss->pub, bssid, ssid, ssid_len)) {
1459 res = bss;
1460 bss_ref_get(rdev, res);
1461 break;
1462 }
1463 }
1464
1465 spin_unlock_bh(&rdev->bss_lock);
1466 if (!res)
1467 return NULL;
1468 trace_cfg80211_return_bss(&res->pub);
1469 return &res->pub;
1470 }
1471 EXPORT_SYMBOL(cfg80211_get_bss);
1472
1473 static void rb_insert_bss(struct cfg80211_registered_device *rdev,
1474 struct cfg80211_internal_bss *bss)
1475 {
1476 struct rb_node **p = &rdev->bss_tree.rb_node;
1477 struct rb_node *parent = NULL;
1478 struct cfg80211_internal_bss *tbss;
1479 int cmp;
1480
1481 while (*p) {
1482 parent = *p;
1483 tbss = rb_entry(parent, struct cfg80211_internal_bss, rbn);
1484
1485 cmp = cmp_bss(&bss->pub, &tbss->pub, BSS_CMP_REGULAR);
1486
1487 if (WARN_ON(!cmp)) {
1488
1489 return;
1490 }
1491
1492 if (cmp < 0)
1493 p = &(*p)->rb_left;
1494 else
1495 p = &(*p)->rb_right;
1496 }
1497
1498 rb_link_node(&bss->rbn, parent, p);
1499 rb_insert_color(&bss->rbn, &rdev->bss_tree);
1500 }
1501
1502 static struct cfg80211_internal_bss *
1503 rb_find_bss(struct cfg80211_registered_device *rdev,
1504 struct cfg80211_internal_bss *res,
1505 enum bss_compare_mode mode)
1506 {
1507 struct rb_node *n = rdev->bss_tree.rb_node;
1508 struct cfg80211_internal_bss *bss;
1509 int r;
1510
1511 while (n) {
1512 bss = rb_entry(n, struct cfg80211_internal_bss, rbn);
1513 r = cmp_bss(&res->pub, &bss->pub, mode);
1514
1515 if (r == 0)
1516 return bss;
1517 else if (r < 0)
1518 n = n->rb_left;
1519 else
1520 n = n->rb_right;
1521 }
1522
1523 return NULL;
1524 }
1525
1526 static bool cfg80211_combine_bsses(struct cfg80211_registered_device *rdev,
1527 struct cfg80211_internal_bss *new)
1528 {
1529 const struct cfg80211_bss_ies *ies;
1530 struct cfg80211_internal_bss *bss;
1531 const u8 *ie;
1532 int i, ssidlen;
1533 u8 fold = 0;
1534 u32 n_entries = 0;
1535
1536 ies = rcu_access_pointer(new->pub.beacon_ies);
1537 if (WARN_ON(!ies))
1538 return false;
1539
1540 ie = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len);
1541 if (!ie) {
1542
1543 return true;
1544 }
1545
1546 ssidlen = ie[1];
1547 for (i = 0; i < ssidlen; i++)
1548 fold |= ie[2 + i];
1549
1550 if (fold) {
1551
1552 return true;
1553 }
1554
1555
1556
1557 list_for_each_entry(bss, &rdev->bss_list, list) {
1558
1559
1560
1561
1562 n_entries++;
1563
1564 if (!ether_addr_equal(bss->pub.bssid, new->pub.bssid))
1565 continue;
1566 if (bss->pub.channel != new->pub.channel)
1567 continue;
1568 if (bss->pub.scan_width != new->pub.scan_width)
1569 continue;
1570 if (rcu_access_pointer(bss->pub.beacon_ies))
1571 continue;
1572 ies = rcu_access_pointer(bss->pub.ies);
1573 if (!ies)
1574 continue;
1575 ie = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len);
1576 if (!ie)
1577 continue;
1578 if (ssidlen && ie[1] != ssidlen)
1579 continue;
1580 if (WARN_ON_ONCE(bss->pub.hidden_beacon_bss))
1581 continue;
1582 if (WARN_ON_ONCE(!list_empty(&bss->hidden_list)))
1583 list_del(&bss->hidden_list);
1584
1585 list_add(&bss->hidden_list, &new->hidden_list);
1586 bss->pub.hidden_beacon_bss = &new->pub;
1587 new->refcount += bss->refcount;
1588 rcu_assign_pointer(bss->pub.beacon_ies,
1589 new->pub.beacon_ies);
1590 }
1591
1592 WARN_ONCE(n_entries != rdev->bss_entries,
1593 "rdev bss entries[%d]/list[len:%d] corruption\n",
1594 rdev->bss_entries, n_entries);
1595
1596 return true;
1597 }
1598
1599 struct cfg80211_non_tx_bss {
1600 struct cfg80211_bss *tx_bss;
1601 u8 max_bssid_indicator;
1602 u8 bssid_index;
1603 };
1604
1605 static bool
1606 cfg80211_update_known_bss(struct cfg80211_registered_device *rdev,
1607 struct cfg80211_internal_bss *known,
1608 struct cfg80211_internal_bss *new,
1609 bool signal_valid)
1610 {
1611 lockdep_assert_held(&rdev->bss_lock);
1612
1613
1614 if (rcu_access_pointer(new->pub.proberesp_ies)) {
1615 const struct cfg80211_bss_ies *old;
1616
1617 old = rcu_access_pointer(known->pub.proberesp_ies);
1618
1619 rcu_assign_pointer(known->pub.proberesp_ies,
1620 new->pub.proberesp_ies);
1621
1622 rcu_assign_pointer(known->pub.ies,
1623 new->pub.proberesp_ies);
1624 if (old)
1625 kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
1626 } else if (rcu_access_pointer(new->pub.beacon_ies)) {
1627 const struct cfg80211_bss_ies *old;
1628 struct cfg80211_internal_bss *bss;
1629
1630 if (known->pub.hidden_beacon_bss &&
1631 !list_empty(&known->hidden_list)) {
1632 const struct cfg80211_bss_ies *f;
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643 f = rcu_access_pointer(new->pub.beacon_ies);
1644 kfree_rcu((struct cfg80211_bss_ies *)f, rcu_head);
1645 return false;
1646 }
1647
1648 old = rcu_access_pointer(known->pub.beacon_ies);
1649
1650 rcu_assign_pointer(known->pub.beacon_ies, new->pub.beacon_ies);
1651
1652
1653 if (old == rcu_access_pointer(known->pub.ies))
1654 rcu_assign_pointer(known->pub.ies, new->pub.beacon_ies);
1655
1656
1657 list_for_each_entry(bss, &known->hidden_list, hidden_list) {
1658 const struct cfg80211_bss_ies *ies;
1659
1660 ies = rcu_access_pointer(bss->pub.beacon_ies);
1661 WARN_ON(ies != old);
1662
1663 rcu_assign_pointer(bss->pub.beacon_ies,
1664 new->pub.beacon_ies);
1665 }
1666
1667 if (old)
1668 kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
1669 }
1670
1671 known->pub.beacon_interval = new->pub.beacon_interval;
1672
1673
1674
1675
1676 if (signal_valid)
1677 known->pub.signal = new->pub.signal;
1678 known->pub.capability = new->pub.capability;
1679 known->ts = new->ts;
1680 known->ts_boottime = new->ts_boottime;
1681 known->parent_tsf = new->parent_tsf;
1682 known->pub.chains = new->pub.chains;
1683 memcpy(known->pub.chain_signal, new->pub.chain_signal,
1684 IEEE80211_MAX_CHAINS);
1685 ether_addr_copy(known->parent_bssid, new->parent_bssid);
1686 known->pub.max_bssid_indicator = new->pub.max_bssid_indicator;
1687 known->pub.bssid_index = new->pub.bssid_index;
1688
1689 return true;
1690 }
1691
1692
1693 struct cfg80211_internal_bss *
1694 cfg80211_bss_update(struct cfg80211_registered_device *rdev,
1695 struct cfg80211_internal_bss *tmp,
1696 bool signal_valid, unsigned long ts)
1697 {
1698 struct cfg80211_internal_bss *found = NULL;
1699
1700 if (WARN_ON(!tmp->pub.channel))
1701 return NULL;
1702
1703 tmp->ts = ts;
1704
1705 spin_lock_bh(&rdev->bss_lock);
1706
1707 if (WARN_ON(!rcu_access_pointer(tmp->pub.ies))) {
1708 spin_unlock_bh(&rdev->bss_lock);
1709 return NULL;
1710 }
1711
1712 found = rb_find_bss(rdev, tmp, BSS_CMP_REGULAR);
1713
1714 if (found) {
1715 if (!cfg80211_update_known_bss(rdev, found, tmp, signal_valid))
1716 goto drop;
1717 } else {
1718 struct cfg80211_internal_bss *new;
1719 struct cfg80211_internal_bss *hidden;
1720 struct cfg80211_bss_ies *ies;
1721
1722
1723
1724
1725
1726
1727 new = kzalloc(sizeof(*new) + rdev->wiphy.bss_priv_size,
1728 GFP_ATOMIC);
1729 if (!new) {
1730 ies = (void *)rcu_dereference(tmp->pub.beacon_ies);
1731 if (ies)
1732 kfree_rcu(ies, rcu_head);
1733 ies = (void *)rcu_dereference(tmp->pub.proberesp_ies);
1734 if (ies)
1735 kfree_rcu(ies, rcu_head);
1736 goto drop;
1737 }
1738 memcpy(new, tmp, sizeof(*new));
1739 new->refcount = 1;
1740 INIT_LIST_HEAD(&new->hidden_list);
1741 INIT_LIST_HEAD(&new->pub.nontrans_list);
1742
1743 if (rcu_access_pointer(tmp->pub.proberesp_ies)) {
1744 hidden = rb_find_bss(rdev, tmp, BSS_CMP_HIDE_ZLEN);
1745 if (!hidden)
1746 hidden = rb_find_bss(rdev, tmp,
1747 BSS_CMP_HIDE_NUL);
1748 if (hidden) {
1749 new->pub.hidden_beacon_bss = &hidden->pub;
1750 list_add(&new->hidden_list,
1751 &hidden->hidden_list);
1752 hidden->refcount++;
1753 rcu_assign_pointer(new->pub.beacon_ies,
1754 hidden->pub.beacon_ies);
1755 }
1756 } else {
1757
1758
1759
1760
1761
1762
1763 if (!cfg80211_combine_bsses(rdev, new)) {
1764 bss_ref_put(rdev, new);
1765 goto drop;
1766 }
1767 }
1768
1769 if (rdev->bss_entries >= bss_entries_limit &&
1770 !cfg80211_bss_expire_oldest(rdev)) {
1771 bss_ref_put(rdev, new);
1772 goto drop;
1773 }
1774
1775
1776 if (tmp->pub.transmitted_bss) {
1777 struct cfg80211_internal_bss *pbss =
1778 container_of(tmp->pub.transmitted_bss,
1779 struct cfg80211_internal_bss,
1780 pub);
1781
1782 new->pub.transmitted_bss = tmp->pub.transmitted_bss;
1783 bss_ref_get(rdev, pbss);
1784 }
1785
1786 list_add_tail(&new->list, &rdev->bss_list);
1787 rdev->bss_entries++;
1788 rb_insert_bss(rdev, new);
1789 found = new;
1790 }
1791
1792 rdev->bss_generation++;
1793 bss_ref_get(rdev, found);
1794 spin_unlock_bh(&rdev->bss_lock);
1795
1796 return found;
1797 drop:
1798 spin_unlock_bh(&rdev->bss_lock);
1799 return NULL;
1800 }
1801
1802 int cfg80211_get_ies_channel_number(const u8 *ie, size_t ielen,
1803 enum nl80211_band band,
1804 enum cfg80211_bss_frame_type ftype)
1805 {
1806 const struct element *tmp;
1807
1808 if (band == NL80211_BAND_6GHZ) {
1809 struct ieee80211_he_operation *he_oper;
1810
1811 tmp = cfg80211_find_ext_elem(WLAN_EID_EXT_HE_OPERATION, ie,
1812 ielen);
1813 if (tmp && tmp->datalen >= sizeof(*he_oper) &&
1814 tmp->datalen >= ieee80211_he_oper_size(&tmp->data[1])) {
1815 const struct ieee80211_he_6ghz_oper *he_6ghz_oper;
1816
1817 he_oper = (void *)&tmp->data[1];
1818
1819 he_6ghz_oper = ieee80211_he_6ghz_oper(he_oper);
1820 if (!he_6ghz_oper)
1821 return -1;
1822
1823 if (ftype != CFG80211_BSS_FTYPE_BEACON ||
1824 he_6ghz_oper->control & IEEE80211_HE_6GHZ_OPER_CTRL_DUP_BEACON)
1825 return he_6ghz_oper->primary;
1826 }
1827 } else if (band == NL80211_BAND_S1GHZ) {
1828 tmp = cfg80211_find_elem(WLAN_EID_S1G_OPERATION, ie, ielen);
1829 if (tmp && tmp->datalen >= sizeof(struct ieee80211_s1g_oper_ie)) {
1830 struct ieee80211_s1g_oper_ie *s1gop = (void *)tmp->data;
1831
1832 return s1gop->oper_ch;
1833 }
1834 } else {
1835 tmp = cfg80211_find_elem(WLAN_EID_DS_PARAMS, ie, ielen);
1836 if (tmp && tmp->datalen == 1)
1837 return tmp->data[0];
1838
1839 tmp = cfg80211_find_elem(WLAN_EID_HT_OPERATION, ie, ielen);
1840 if (tmp &&
1841 tmp->datalen >= sizeof(struct ieee80211_ht_operation)) {
1842 struct ieee80211_ht_operation *htop = (void *)tmp->data;
1843
1844 return htop->primary_chan;
1845 }
1846 }
1847
1848 return -1;
1849 }
1850 EXPORT_SYMBOL(cfg80211_get_ies_channel_number);
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860 static struct ieee80211_channel *
1861 cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen,
1862 struct ieee80211_channel *channel,
1863 enum nl80211_bss_scan_width scan_width,
1864 enum cfg80211_bss_frame_type ftype)
1865 {
1866 u32 freq;
1867 int channel_number;
1868 struct ieee80211_channel *alt_channel;
1869
1870 channel_number = cfg80211_get_ies_channel_number(ie, ielen,
1871 channel->band, ftype);
1872
1873 if (channel_number < 0) {
1874
1875 return channel;
1876 }
1877
1878 freq = ieee80211_channel_to_freq_khz(channel_number, channel->band);
1879
1880
1881
1882
1883
1884 if (channel->band == NL80211_BAND_6GHZ &&
1885 (freq == channel->center_freq ||
1886 abs(freq - channel->center_freq) > 80))
1887 return channel;
1888
1889 alt_channel = ieee80211_get_channel_khz(wiphy, freq);
1890 if (!alt_channel) {
1891 if (channel->band == NL80211_BAND_2GHZ) {
1892
1893
1894
1895
1896
1897
1898 return NULL;
1899 }
1900
1901
1902 return channel;
1903 }
1904
1905 if (scan_width == NL80211_BSS_CHAN_WIDTH_10 ||
1906 scan_width == NL80211_BSS_CHAN_WIDTH_5) {
1907
1908
1909
1910
1911
1912 return channel;
1913 }
1914
1915
1916
1917
1918
1919 if (alt_channel->flags & IEEE80211_CHAN_DISABLED)
1920 return NULL;
1921 return alt_channel;
1922 }
1923
1924
1925 static struct cfg80211_bss *
1926 cfg80211_inform_single_bss_data(struct wiphy *wiphy,
1927 struct cfg80211_inform_bss *data,
1928 enum cfg80211_bss_frame_type ftype,
1929 const u8 *bssid, u64 tsf, u16 capability,
1930 u16 beacon_interval, const u8 *ie, size_t ielen,
1931 struct cfg80211_non_tx_bss *non_tx_data,
1932 gfp_t gfp)
1933 {
1934 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
1935 struct cfg80211_bss_ies *ies;
1936 struct ieee80211_channel *channel;
1937 struct cfg80211_internal_bss tmp = {}, *res;
1938 int bss_type;
1939 bool signal_valid;
1940 unsigned long ts;
1941
1942 if (WARN_ON(!wiphy))
1943 return NULL;
1944
1945 if (WARN_ON(wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
1946 (data->signal < 0 || data->signal > 100)))
1947 return NULL;
1948
1949 channel = cfg80211_get_bss_channel(wiphy, ie, ielen, data->chan,
1950 data->scan_width, ftype);
1951 if (!channel)
1952 return NULL;
1953
1954 memcpy(tmp.pub.bssid, bssid, ETH_ALEN);
1955 tmp.pub.channel = channel;
1956 tmp.pub.scan_width = data->scan_width;
1957 tmp.pub.signal = data->signal;
1958 tmp.pub.beacon_interval = beacon_interval;
1959 tmp.pub.capability = capability;
1960 tmp.ts_boottime = data->boottime_ns;
1961 tmp.parent_tsf = data->parent_tsf;
1962 ether_addr_copy(tmp.parent_bssid, data->parent_bssid);
1963
1964 if (non_tx_data) {
1965 tmp.pub.transmitted_bss = non_tx_data->tx_bss;
1966 ts = bss_from_pub(non_tx_data->tx_bss)->ts;
1967 tmp.pub.bssid_index = non_tx_data->bssid_index;
1968 tmp.pub.max_bssid_indicator = non_tx_data->max_bssid_indicator;
1969 } else {
1970 ts = jiffies;
1971 }
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981 ies = kzalloc(sizeof(*ies) + ielen, gfp);
1982 if (!ies)
1983 return NULL;
1984 ies->len = ielen;
1985 ies->tsf = tsf;
1986 ies->from_beacon = false;
1987 memcpy(ies->data, ie, ielen);
1988
1989 switch (ftype) {
1990 case CFG80211_BSS_FTYPE_BEACON:
1991 ies->from_beacon = true;
1992 fallthrough;
1993 case CFG80211_BSS_FTYPE_UNKNOWN:
1994 rcu_assign_pointer(tmp.pub.beacon_ies, ies);
1995 break;
1996 case CFG80211_BSS_FTYPE_PRESP:
1997 rcu_assign_pointer(tmp.pub.proberesp_ies, ies);
1998 break;
1999 }
2000 rcu_assign_pointer(tmp.pub.ies, ies);
2001
2002 signal_valid = data->chan == channel;
2003 res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid, ts);
2004 if (!res)
2005 return NULL;
2006
2007 if (channel->band == NL80211_BAND_60GHZ) {
2008 bss_type = res->pub.capability & WLAN_CAPABILITY_DMG_TYPE_MASK;
2009 if (bss_type == WLAN_CAPABILITY_DMG_TYPE_AP ||
2010 bss_type == WLAN_CAPABILITY_DMG_TYPE_PBSS)
2011 regulatory_hint_found_beacon(wiphy, channel, gfp);
2012 } else {
2013 if (res->pub.capability & WLAN_CAPABILITY_ESS)
2014 regulatory_hint_found_beacon(wiphy, channel, gfp);
2015 }
2016
2017 if (non_tx_data) {
2018
2019
2020
2021 spin_lock_bh(&rdev->bss_lock);
2022 if (cfg80211_add_nontrans_list(non_tx_data->tx_bss,
2023 &res->pub)) {
2024 if (__cfg80211_unlink_bss(rdev, res))
2025 rdev->bss_generation++;
2026 }
2027 spin_unlock_bh(&rdev->bss_lock);
2028 }
2029
2030 trace_cfg80211_return_bss(&res->pub);
2031
2032 return &res->pub;
2033 }
2034
2035 static const struct element
2036 *cfg80211_get_profile_continuation(const u8 *ie, size_t ielen,
2037 const struct element *mbssid_elem,
2038 const struct element *sub_elem)
2039 {
2040 const u8 *mbssid_end = mbssid_elem->data + mbssid_elem->datalen;
2041 const struct element *next_mbssid;
2042 const struct element *next_sub;
2043
2044 next_mbssid = cfg80211_find_elem(WLAN_EID_MULTIPLE_BSSID,
2045 mbssid_end,
2046 ielen - (mbssid_end - ie));
2047
2048
2049
2050
2051
2052 if ((sub_elem->data + sub_elem->datalen < mbssid_end - 1) ||
2053 !next_mbssid)
2054 return NULL;
2055
2056
2057
2058 if (next_mbssid->datalen < 4)
2059 return NULL;
2060
2061 next_sub = (void *)&next_mbssid->data[1];
2062
2063 if (next_mbssid->data + next_mbssid->datalen <
2064 next_sub->data + next_sub->datalen)
2065 return NULL;
2066
2067 if (next_sub->id != 0 || next_sub->datalen < 2)
2068 return NULL;
2069
2070
2071
2072
2073
2074 return next_sub->data[0] == WLAN_EID_NON_TX_BSSID_CAP ?
2075 NULL : next_mbssid;
2076 }
2077
2078 size_t cfg80211_merge_profile(const u8 *ie, size_t ielen,
2079 const struct element *mbssid_elem,
2080 const struct element *sub_elem,
2081 u8 *merged_ie, size_t max_copy_len)
2082 {
2083 size_t copied_len = sub_elem->datalen;
2084 const struct element *next_mbssid;
2085
2086 if (sub_elem->datalen > max_copy_len)
2087 return 0;
2088
2089 memcpy(merged_ie, sub_elem->data, sub_elem->datalen);
2090
2091 while ((next_mbssid = cfg80211_get_profile_continuation(ie, ielen,
2092 mbssid_elem,
2093 sub_elem))) {
2094 const struct element *next_sub = (void *)&next_mbssid->data[1];
2095
2096 if (copied_len + next_sub->datalen > max_copy_len)
2097 break;
2098 memcpy(merged_ie + copied_len, next_sub->data,
2099 next_sub->datalen);
2100 copied_len += next_sub->datalen;
2101 }
2102
2103 return copied_len;
2104 }
2105 EXPORT_SYMBOL(cfg80211_merge_profile);
2106
2107 static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
2108 struct cfg80211_inform_bss *data,
2109 enum cfg80211_bss_frame_type ftype,
2110 const u8 *bssid, u64 tsf,
2111 u16 beacon_interval, const u8 *ie,
2112 size_t ielen,
2113 struct cfg80211_non_tx_bss *non_tx_data,
2114 gfp_t gfp)
2115 {
2116 const u8 *mbssid_index_ie;
2117 const struct element *elem, *sub;
2118 size_t new_ie_len;
2119 u8 new_bssid[ETH_ALEN];
2120 u8 *new_ie, *profile;
2121 u64 seen_indices = 0;
2122 u16 capability;
2123 struct cfg80211_bss *bss;
2124
2125 if (!non_tx_data)
2126 return;
2127 if (!cfg80211_find_elem(WLAN_EID_MULTIPLE_BSSID, ie, ielen))
2128 return;
2129 if (!wiphy->support_mbssid)
2130 return;
2131 if (wiphy->support_only_he_mbssid &&
2132 !cfg80211_find_ext_elem(WLAN_EID_EXT_HE_CAPABILITY, ie, ielen))
2133 return;
2134
2135 new_ie = kmalloc(IEEE80211_MAX_DATA_LEN, gfp);
2136 if (!new_ie)
2137 return;
2138
2139 profile = kmalloc(ielen, gfp);
2140 if (!profile)
2141 goto out;
2142
2143 for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, ie, ielen) {
2144 if (elem->datalen < 4)
2145 continue;
2146 for_each_element(sub, elem->data + 1, elem->datalen - 1) {
2147 u8 profile_len;
2148
2149 if (sub->id != 0 || sub->datalen < 4) {
2150
2151 continue;
2152 }
2153
2154 if (sub->data[0] != WLAN_EID_NON_TX_BSSID_CAP ||
2155 sub->data[1] != 2) {
2156
2157
2158
2159
2160 continue;
2161 }
2162
2163 memset(profile, 0, ielen);
2164 profile_len = cfg80211_merge_profile(ie, ielen,
2165 elem,
2166 sub,
2167 profile,
2168 ielen);
2169
2170
2171 mbssid_index_ie = cfg80211_find_ie
2172 (WLAN_EID_MULTI_BSSID_IDX,
2173 profile, profile_len);
2174 if (!mbssid_index_ie || mbssid_index_ie[1] < 1 ||
2175 mbssid_index_ie[2] == 0 ||
2176 mbssid_index_ie[2] > 46) {
2177
2178 continue;
2179 }
2180
2181 if (seen_indices & BIT_ULL(mbssid_index_ie[2]))
2182
2183 net_dbg_ratelimited("Partial info for BSSID index %d\n",
2184 mbssid_index_ie[2]);
2185
2186 seen_indices |= BIT_ULL(mbssid_index_ie[2]);
2187
2188 non_tx_data->bssid_index = mbssid_index_ie[2];
2189 non_tx_data->max_bssid_indicator = elem->data[0];
2190
2191 cfg80211_gen_new_bssid(bssid,
2192 non_tx_data->max_bssid_indicator,
2193 non_tx_data->bssid_index,
2194 new_bssid);
2195 memset(new_ie, 0, IEEE80211_MAX_DATA_LEN);
2196 new_ie_len = cfg80211_gen_new_ie(ie, ielen,
2197 profile,
2198 profile_len, new_ie,
2199 gfp);
2200 if (!new_ie_len)
2201 continue;
2202
2203 capability = get_unaligned_le16(profile + 2);
2204 bss = cfg80211_inform_single_bss_data(wiphy, data,
2205 ftype,
2206 new_bssid, tsf,
2207 capability,
2208 beacon_interval,
2209 new_ie,
2210 new_ie_len,
2211 non_tx_data,
2212 gfp);
2213 if (!bss)
2214 break;
2215 cfg80211_put_bss(wiphy, bss);
2216 }
2217 }
2218
2219 out:
2220 kfree(new_ie);
2221 kfree(profile);
2222 }
2223
2224 struct cfg80211_bss *
2225 cfg80211_inform_bss_data(struct wiphy *wiphy,
2226 struct cfg80211_inform_bss *data,
2227 enum cfg80211_bss_frame_type ftype,
2228 const u8 *bssid, u64 tsf, u16 capability,
2229 u16 beacon_interval, const u8 *ie, size_t ielen,
2230 gfp_t gfp)
2231 {
2232 struct cfg80211_bss *res;
2233 struct cfg80211_non_tx_bss non_tx_data;
2234
2235 res = cfg80211_inform_single_bss_data(wiphy, data, ftype, bssid, tsf,
2236 capability, beacon_interval, ie,
2237 ielen, NULL, gfp);
2238 if (!res)
2239 return NULL;
2240 non_tx_data.tx_bss = res;
2241 cfg80211_parse_mbssid_data(wiphy, data, ftype, bssid, tsf,
2242 beacon_interval, ie, ielen, &non_tx_data,
2243 gfp);
2244 return res;
2245 }
2246 EXPORT_SYMBOL(cfg80211_inform_bss_data);
2247
2248 static void
2249 cfg80211_parse_mbssid_frame_data(struct wiphy *wiphy,
2250 struct cfg80211_inform_bss *data,
2251 struct ieee80211_mgmt *mgmt, size_t len,
2252 struct cfg80211_non_tx_bss *non_tx_data,
2253 gfp_t gfp)
2254 {
2255 enum cfg80211_bss_frame_type ftype;
2256 const u8 *ie = mgmt->u.probe_resp.variable;
2257 size_t ielen = len - offsetof(struct ieee80211_mgmt,
2258 u.probe_resp.variable);
2259
2260 ftype = ieee80211_is_beacon(mgmt->frame_control) ?
2261 CFG80211_BSS_FTYPE_BEACON : CFG80211_BSS_FTYPE_PRESP;
2262
2263 cfg80211_parse_mbssid_data(wiphy, data, ftype, mgmt->bssid,
2264 le64_to_cpu(mgmt->u.probe_resp.timestamp),
2265 le16_to_cpu(mgmt->u.probe_resp.beacon_int),
2266 ie, ielen, non_tx_data, gfp);
2267 }
2268
2269 static void
2270 cfg80211_update_notlisted_nontrans(struct wiphy *wiphy,
2271 struct cfg80211_bss *nontrans_bss,
2272 struct ieee80211_mgmt *mgmt, size_t len)
2273 {
2274 u8 *ie, *new_ie, *pos;
2275 const struct element *nontrans_ssid;
2276 const u8 *trans_ssid, *mbssid;
2277 size_t ielen = len - offsetof(struct ieee80211_mgmt,
2278 u.probe_resp.variable);
2279 size_t new_ie_len;
2280 struct cfg80211_bss_ies *new_ies;
2281 const struct cfg80211_bss_ies *old;
2282 u8 cpy_len;
2283
2284 lockdep_assert_held(&wiphy_to_rdev(wiphy)->bss_lock);
2285
2286 ie = mgmt->u.probe_resp.variable;
2287
2288 new_ie_len = ielen;
2289 trans_ssid = cfg80211_find_ie(WLAN_EID_SSID, ie, ielen);
2290 if (!trans_ssid)
2291 return;
2292 new_ie_len -= trans_ssid[1];
2293 mbssid = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ie, ielen);
2294
2295
2296
2297
2298
2299 if (!mbssid || mbssid < trans_ssid)
2300 return;
2301 new_ie_len -= mbssid[1];
2302
2303 nontrans_ssid = ieee80211_bss_get_elem(nontrans_bss, WLAN_EID_SSID);
2304 if (!nontrans_ssid)
2305 return;
2306
2307 new_ie_len += nontrans_ssid->datalen;
2308
2309
2310
2311
2312
2313 new_ie = kzalloc(new_ie_len, GFP_ATOMIC);
2314 if (!new_ie)
2315 return;
2316
2317 new_ies = kzalloc(sizeof(*new_ies) + new_ie_len, GFP_ATOMIC);
2318 if (!new_ies)
2319 goto out_free;
2320
2321 pos = new_ie;
2322
2323
2324 cpy_len = nontrans_ssid->datalen + 2;
2325 memcpy(pos, nontrans_ssid, cpy_len);
2326 pos += cpy_len;
2327
2328 cpy_len = trans_ssid[1] + 2;
2329 memcpy(pos, (trans_ssid + cpy_len), (mbssid - (trans_ssid + cpy_len)));
2330 pos += (mbssid - (trans_ssid + cpy_len));
2331
2332 cpy_len = mbssid[1] + 2;
2333 memcpy(pos, mbssid + cpy_len, ((ie + ielen) - (mbssid + cpy_len)));
2334
2335
2336 new_ies->len = new_ie_len;
2337 new_ies->tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
2338 new_ies->from_beacon = ieee80211_is_beacon(mgmt->frame_control);
2339 memcpy(new_ies->data, new_ie, new_ie_len);
2340 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
2341 old = rcu_access_pointer(nontrans_bss->proberesp_ies);
2342 rcu_assign_pointer(nontrans_bss->proberesp_ies, new_ies);
2343 rcu_assign_pointer(nontrans_bss->ies, new_ies);
2344 if (old)
2345 kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
2346 } else {
2347 old = rcu_access_pointer(nontrans_bss->beacon_ies);
2348 rcu_assign_pointer(nontrans_bss->beacon_ies, new_ies);
2349 rcu_assign_pointer(nontrans_bss->ies, new_ies);
2350 if (old)
2351 kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
2352 }
2353
2354 out_free:
2355 kfree(new_ie);
2356 }
2357
2358
2359 static struct cfg80211_bss *
2360 cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy,
2361 struct cfg80211_inform_bss *data,
2362 struct ieee80211_mgmt *mgmt, size_t len,
2363 gfp_t gfp)
2364 {
2365 struct cfg80211_internal_bss tmp = {}, *res;
2366 struct cfg80211_bss_ies *ies;
2367 struct ieee80211_channel *channel;
2368 bool signal_valid;
2369 struct ieee80211_ext *ext = NULL;
2370 u8 *bssid, *variable;
2371 u16 capability, beacon_int;
2372 size_t ielen, min_hdr_len = offsetof(struct ieee80211_mgmt,
2373 u.probe_resp.variable);
2374 int bss_type;
2375 enum cfg80211_bss_frame_type ftype;
2376
2377 BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) !=
2378 offsetof(struct ieee80211_mgmt, u.beacon.variable));
2379
2380 trace_cfg80211_inform_bss_frame(wiphy, data, mgmt, len);
2381
2382 if (WARN_ON(!mgmt))
2383 return NULL;
2384
2385 if (WARN_ON(!wiphy))
2386 return NULL;
2387
2388 if (WARN_ON(wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
2389 (data->signal < 0 || data->signal > 100)))
2390 return NULL;
2391
2392 if (ieee80211_is_s1g_beacon(mgmt->frame_control)) {
2393 ext = (void *) mgmt;
2394 min_hdr_len = offsetof(struct ieee80211_ext, u.s1g_beacon);
2395 if (ieee80211_is_s1g_short_beacon(mgmt->frame_control))
2396 min_hdr_len = offsetof(struct ieee80211_ext,
2397 u.s1g_short_beacon.variable);
2398 }
2399
2400 if (WARN_ON(len < min_hdr_len))
2401 return NULL;
2402
2403 ielen = len - min_hdr_len;
2404 variable = mgmt->u.probe_resp.variable;
2405 if (ext) {
2406 if (ieee80211_is_s1g_short_beacon(mgmt->frame_control))
2407 variable = ext->u.s1g_short_beacon.variable;
2408 else
2409 variable = ext->u.s1g_beacon.variable;
2410 }
2411
2412 if (ieee80211_is_beacon(mgmt->frame_control))
2413 ftype = CFG80211_BSS_FTYPE_BEACON;
2414 else if (ieee80211_is_probe_resp(mgmt->frame_control))
2415 ftype = CFG80211_BSS_FTYPE_PRESP;
2416 else
2417 ftype = CFG80211_BSS_FTYPE_UNKNOWN;
2418
2419 channel = cfg80211_get_bss_channel(wiphy, variable,
2420 ielen, data->chan, data->scan_width,
2421 ftype);
2422 if (!channel)
2423 return NULL;
2424
2425 if (ext) {
2426 const struct ieee80211_s1g_bcn_compat_ie *compat;
2427 const struct element *elem;
2428
2429 elem = cfg80211_find_elem(WLAN_EID_S1G_BCN_COMPAT,
2430 variable, ielen);
2431 if (!elem)
2432 return NULL;
2433 if (elem->datalen < sizeof(*compat))
2434 return NULL;
2435 compat = (void *)elem->data;
2436 bssid = ext->u.s1g_beacon.sa;
2437 capability = le16_to_cpu(compat->compat_info);
2438 beacon_int = le16_to_cpu(compat->beacon_int);
2439 } else {
2440 bssid = mgmt->bssid;
2441 beacon_int = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
2442 capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
2443 }
2444
2445 ies = kzalloc(sizeof(*ies) + ielen, gfp);
2446 if (!ies)
2447 return NULL;
2448 ies->len = ielen;
2449 ies->tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
2450 ies->from_beacon = ieee80211_is_beacon(mgmt->frame_control) ||
2451 ieee80211_is_s1g_beacon(mgmt->frame_control);
2452 memcpy(ies->data, variable, ielen);
2453
2454 if (ieee80211_is_probe_resp(mgmt->frame_control))
2455 rcu_assign_pointer(tmp.pub.proberesp_ies, ies);
2456 else
2457 rcu_assign_pointer(tmp.pub.beacon_ies, ies);
2458 rcu_assign_pointer(tmp.pub.ies, ies);
2459
2460 memcpy(tmp.pub.bssid, bssid, ETH_ALEN);
2461 tmp.pub.beacon_interval = beacon_int;
2462 tmp.pub.capability = capability;
2463 tmp.pub.channel = channel;
2464 tmp.pub.scan_width = data->scan_width;
2465 tmp.pub.signal = data->signal;
2466 tmp.ts_boottime = data->boottime_ns;
2467 tmp.parent_tsf = data->parent_tsf;
2468 tmp.pub.chains = data->chains;
2469 memcpy(tmp.pub.chain_signal, data->chain_signal, IEEE80211_MAX_CHAINS);
2470 ether_addr_copy(tmp.parent_bssid, data->parent_bssid);
2471
2472 signal_valid = data->chan == channel;
2473 res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid,
2474 jiffies);
2475 if (!res)
2476 return NULL;
2477
2478 if (channel->band == NL80211_BAND_60GHZ) {
2479 bss_type = res->pub.capability & WLAN_CAPABILITY_DMG_TYPE_MASK;
2480 if (bss_type == WLAN_CAPABILITY_DMG_TYPE_AP ||
2481 bss_type == WLAN_CAPABILITY_DMG_TYPE_PBSS)
2482 regulatory_hint_found_beacon(wiphy, channel, gfp);
2483 } else {
2484 if (res->pub.capability & WLAN_CAPABILITY_ESS)
2485 regulatory_hint_found_beacon(wiphy, channel, gfp);
2486 }
2487
2488 trace_cfg80211_return_bss(&res->pub);
2489
2490 return &res->pub;
2491 }
2492
2493 struct cfg80211_bss *
2494 cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
2495 struct cfg80211_inform_bss *data,
2496 struct ieee80211_mgmt *mgmt, size_t len,
2497 gfp_t gfp)
2498 {
2499 struct cfg80211_bss *res, *tmp_bss;
2500 const u8 *ie = mgmt->u.probe_resp.variable;
2501 const struct cfg80211_bss_ies *ies1, *ies2;
2502 size_t ielen = len - offsetof(struct ieee80211_mgmt,
2503 u.probe_resp.variable);
2504 struct cfg80211_non_tx_bss non_tx_data;
2505
2506 res = cfg80211_inform_single_bss_frame_data(wiphy, data, mgmt,
2507 len, gfp);
2508 if (!res || !wiphy->support_mbssid ||
2509 !cfg80211_find_elem(WLAN_EID_MULTIPLE_BSSID, ie, ielen))
2510 return res;
2511 if (wiphy->support_only_he_mbssid &&
2512 !cfg80211_find_ext_elem(WLAN_EID_EXT_HE_CAPABILITY, ie, ielen))
2513 return res;
2514
2515 non_tx_data.tx_bss = res;
2516
2517 cfg80211_parse_mbssid_frame_data(wiphy, data, mgmt, len,
2518 &non_tx_data, gfp);
2519
2520 spin_lock_bh(&wiphy_to_rdev(wiphy)->bss_lock);
2521
2522
2523
2524
2525 ies1 = rcu_access_pointer(res->ies);
2526
2527
2528
2529
2530
2531 list_for_each_entry(tmp_bss, &res->nontrans_list,
2532 nontrans_list) {
2533 ies2 = rcu_access_pointer(tmp_bss->ies);
2534 if (ies2->tsf < ies1->tsf)
2535 cfg80211_update_notlisted_nontrans(wiphy, tmp_bss,
2536 mgmt, len);
2537 }
2538 spin_unlock_bh(&wiphy_to_rdev(wiphy)->bss_lock);
2539
2540 return res;
2541 }
2542 EXPORT_SYMBOL(cfg80211_inform_bss_frame_data);
2543
2544 void cfg80211_ref_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
2545 {
2546 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
2547 struct cfg80211_internal_bss *bss;
2548
2549 if (!pub)
2550 return;
2551
2552 bss = container_of(pub, struct cfg80211_internal_bss, pub);
2553
2554 spin_lock_bh(&rdev->bss_lock);
2555 bss_ref_get(rdev, bss);
2556 spin_unlock_bh(&rdev->bss_lock);
2557 }
2558 EXPORT_SYMBOL(cfg80211_ref_bss);
2559
2560 void cfg80211_put_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
2561 {
2562 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
2563 struct cfg80211_internal_bss *bss;
2564
2565 if (!pub)
2566 return;
2567
2568 bss = container_of(pub, struct cfg80211_internal_bss, pub);
2569
2570 spin_lock_bh(&rdev->bss_lock);
2571 bss_ref_put(rdev, bss);
2572 spin_unlock_bh(&rdev->bss_lock);
2573 }
2574 EXPORT_SYMBOL(cfg80211_put_bss);
2575
2576 void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
2577 {
2578 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
2579 struct cfg80211_internal_bss *bss, *tmp1;
2580 struct cfg80211_bss *nontrans_bss, *tmp;
2581
2582 if (WARN_ON(!pub))
2583 return;
2584
2585 bss = container_of(pub, struct cfg80211_internal_bss, pub);
2586
2587 spin_lock_bh(&rdev->bss_lock);
2588 if (list_empty(&bss->list))
2589 goto out;
2590
2591 list_for_each_entry_safe(nontrans_bss, tmp,
2592 &pub->nontrans_list,
2593 nontrans_list) {
2594 tmp1 = container_of(nontrans_bss,
2595 struct cfg80211_internal_bss, pub);
2596 if (__cfg80211_unlink_bss(rdev, tmp1))
2597 rdev->bss_generation++;
2598 }
2599
2600 if (__cfg80211_unlink_bss(rdev, bss))
2601 rdev->bss_generation++;
2602 out:
2603 spin_unlock_bh(&rdev->bss_lock);
2604 }
2605 EXPORT_SYMBOL(cfg80211_unlink_bss);
2606
2607 void cfg80211_bss_iter(struct wiphy *wiphy,
2608 struct cfg80211_chan_def *chandef,
2609 void (*iter)(struct wiphy *wiphy,
2610 struct cfg80211_bss *bss,
2611 void *data),
2612 void *iter_data)
2613 {
2614 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
2615 struct cfg80211_internal_bss *bss;
2616
2617 spin_lock_bh(&rdev->bss_lock);
2618
2619 list_for_each_entry(bss, &rdev->bss_list, list) {
2620 if (!chandef || cfg80211_is_sub_chan(chandef, bss->pub.channel,
2621 false))
2622 iter(wiphy, &bss->pub, iter_data);
2623 }
2624
2625 spin_unlock_bh(&rdev->bss_lock);
2626 }
2627 EXPORT_SYMBOL(cfg80211_bss_iter);
2628
2629 void cfg80211_update_assoc_bss_entry(struct wireless_dev *wdev,
2630 unsigned int link_id,
2631 struct ieee80211_channel *chan)
2632 {
2633 struct wiphy *wiphy = wdev->wiphy;
2634 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
2635 struct cfg80211_internal_bss *cbss = wdev->links[link_id].client.current_bss;
2636 struct cfg80211_internal_bss *new = NULL;
2637 struct cfg80211_internal_bss *bss;
2638 struct cfg80211_bss *nontrans_bss;
2639 struct cfg80211_bss *tmp;
2640
2641 spin_lock_bh(&rdev->bss_lock);
2642
2643
2644
2645
2646
2647 if (cbss->pub.channel == chan)
2648 goto done;
2649
2650
2651 if (cbss->pub.transmitted_bss)
2652 cbss = container_of(cbss->pub.transmitted_bss,
2653 struct cfg80211_internal_bss,
2654 pub);
2655
2656 cbss->pub.channel = chan;
2657
2658 list_for_each_entry(bss, &rdev->bss_list, list) {
2659 if (!cfg80211_bss_type_match(bss->pub.capability,
2660 bss->pub.channel->band,
2661 wdev->conn_bss_type))
2662 continue;
2663
2664 if (bss == cbss)
2665 continue;
2666
2667 if (!cmp_bss(&bss->pub, &cbss->pub, BSS_CMP_REGULAR)) {
2668 new = bss;
2669 break;
2670 }
2671 }
2672
2673 if (new) {
2674
2675 if (cfg80211_update_known_bss(rdev, cbss, new, false)) {
2676 new->pub.proberesp_ies = NULL;
2677 new->pub.beacon_ies = NULL;
2678 }
2679
2680 list_for_each_entry_safe(nontrans_bss, tmp,
2681 &new->pub.nontrans_list,
2682 nontrans_list) {
2683 bss = container_of(nontrans_bss,
2684 struct cfg80211_internal_bss, pub);
2685 if (__cfg80211_unlink_bss(rdev, bss))
2686 rdev->bss_generation++;
2687 }
2688
2689 WARN_ON(atomic_read(&new->hold));
2690 if (!WARN_ON(!__cfg80211_unlink_bss(rdev, new)))
2691 rdev->bss_generation++;
2692 }
2693
2694 rb_erase(&cbss->rbn, &rdev->bss_tree);
2695 rb_insert_bss(rdev, cbss);
2696 rdev->bss_generation++;
2697
2698 list_for_each_entry_safe(nontrans_bss, tmp,
2699 &cbss->pub.nontrans_list,
2700 nontrans_list) {
2701 bss = container_of(nontrans_bss,
2702 struct cfg80211_internal_bss, pub);
2703 bss->pub.channel = chan;
2704 rb_erase(&bss->rbn, &rdev->bss_tree);
2705 rb_insert_bss(rdev, bss);
2706 rdev->bss_generation++;
2707 }
2708
2709 done:
2710 spin_unlock_bh(&rdev->bss_lock);
2711 }
2712
2713 #ifdef CONFIG_CFG80211_WEXT
2714 static struct cfg80211_registered_device *
2715 cfg80211_get_dev_from_ifindex(struct net *net, int ifindex)
2716 {
2717 struct cfg80211_registered_device *rdev;
2718 struct net_device *dev;
2719
2720 ASSERT_RTNL();
2721
2722 dev = dev_get_by_index(net, ifindex);
2723 if (!dev)
2724 return ERR_PTR(-ENODEV);
2725 if (dev->ieee80211_ptr)
2726 rdev = wiphy_to_rdev(dev->ieee80211_ptr->wiphy);
2727 else
2728 rdev = ERR_PTR(-ENODEV);
2729 dev_put(dev);
2730 return rdev;
2731 }
2732
2733 int cfg80211_wext_siwscan(struct net_device *dev,
2734 struct iw_request_info *info,
2735 union iwreq_data *wrqu, char *extra)
2736 {
2737 struct cfg80211_registered_device *rdev;
2738 struct wiphy *wiphy;
2739 struct iw_scan_req *wreq = NULL;
2740 struct cfg80211_scan_request *creq;
2741 int i, err, n_channels = 0;
2742 enum nl80211_band band;
2743
2744 if (!netif_running(dev))
2745 return -ENETDOWN;
2746
2747 if (wrqu->data.length == sizeof(struct iw_scan_req))
2748 wreq = (struct iw_scan_req *)extra;
2749
2750 rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex);
2751
2752 if (IS_ERR(rdev))
2753 return PTR_ERR(rdev);
2754
2755 if (rdev->scan_req || rdev->scan_msg)
2756 return -EBUSY;
2757
2758 wiphy = &rdev->wiphy;
2759
2760
2761 if (wreq && wreq->num_channels)
2762 n_channels = wreq->num_channels;
2763 else
2764 n_channels = ieee80211_get_num_supported_channels(wiphy);
2765
2766 creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) +
2767 n_channels * sizeof(void *),
2768 GFP_ATOMIC);
2769 if (!creq)
2770 return -ENOMEM;
2771
2772 creq->wiphy = wiphy;
2773 creq->wdev = dev->ieee80211_ptr;
2774
2775 creq->ssids = (void *)&creq->channels[n_channels];
2776 creq->n_channels = n_channels;
2777 creq->n_ssids = 1;
2778 creq->scan_start = jiffies;
2779
2780
2781 i = 0;
2782 for (band = 0; band < NUM_NL80211_BANDS; band++) {
2783 int j;
2784
2785 if (!wiphy->bands[band])
2786 continue;
2787
2788 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
2789
2790 if (wiphy->bands[band]->channels[j].flags &
2791 IEEE80211_CHAN_DISABLED)
2792 continue;
2793
2794
2795
2796
2797
2798 if (wreq && wreq->num_channels) {
2799 int k;
2800 int wiphy_freq = wiphy->bands[band]->channels[j].center_freq;
2801 for (k = 0; k < wreq->num_channels; k++) {
2802 struct iw_freq *freq =
2803 &wreq->channel_list[k];
2804 int wext_freq =
2805 cfg80211_wext_freq(freq);
2806
2807 if (wext_freq == wiphy_freq)
2808 goto wext_freq_found;
2809 }
2810 goto wext_freq_not_found;
2811 }
2812
2813 wext_freq_found:
2814 creq->channels[i] = &wiphy->bands[band]->channels[j];
2815 i++;
2816 wext_freq_not_found: ;
2817 }
2818 }
2819
2820 if (!i) {
2821 err = -EINVAL;
2822 goto out;
2823 }
2824
2825
2826 creq->n_channels = i;
2827
2828
2829 if (wreq) {
2830 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
2831 if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) {
2832 err = -EINVAL;
2833 goto out;
2834 }
2835 memcpy(creq->ssids[0].ssid, wreq->essid, wreq->essid_len);
2836 creq->ssids[0].ssid_len = wreq->essid_len;
2837 }
2838 if (wreq->scan_type == IW_SCAN_TYPE_PASSIVE)
2839 creq->n_ssids = 0;
2840 }
2841
2842 for (i = 0; i < NUM_NL80211_BANDS; i++)
2843 if (wiphy->bands[i])
2844 creq->rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1;
2845
2846 eth_broadcast_addr(creq->bssid);
2847
2848 wiphy_lock(&rdev->wiphy);
2849
2850 rdev->scan_req = creq;
2851 err = rdev_scan(rdev, creq);
2852 if (err) {
2853 rdev->scan_req = NULL;
2854
2855 } else {
2856 nl80211_send_scan_start(rdev, dev->ieee80211_ptr);
2857
2858 creq = NULL;
2859 dev_hold(dev);
2860 }
2861 wiphy_unlock(&rdev->wiphy);
2862 out:
2863 kfree(creq);
2864 return err;
2865 }
2866 EXPORT_WEXT_HANDLER(cfg80211_wext_siwscan);
2867
2868 static char *ieee80211_scan_add_ies(struct iw_request_info *info,
2869 const struct cfg80211_bss_ies *ies,
2870 char *current_ev, char *end_buf)
2871 {
2872 const u8 *pos, *end, *next;
2873 struct iw_event iwe;
2874
2875 if (!ies)
2876 return current_ev;
2877
2878
2879
2880
2881
2882 pos = ies->data;
2883 end = pos + ies->len;
2884
2885 while (end - pos > IW_GENERIC_IE_MAX) {
2886 next = pos + 2 + pos[1];
2887 while (next + 2 + next[1] - pos < IW_GENERIC_IE_MAX)
2888 next = next + 2 + next[1];
2889
2890 memset(&iwe, 0, sizeof(iwe));
2891 iwe.cmd = IWEVGENIE;
2892 iwe.u.data.length = next - pos;
2893 current_ev = iwe_stream_add_point_check(info, current_ev,
2894 end_buf, &iwe,
2895 (void *)pos);
2896 if (IS_ERR(current_ev))
2897 return current_ev;
2898 pos = next;
2899 }
2900
2901 if (end > pos) {
2902 memset(&iwe, 0, sizeof(iwe));
2903 iwe.cmd = IWEVGENIE;
2904 iwe.u.data.length = end - pos;
2905 current_ev = iwe_stream_add_point_check(info, current_ev,
2906 end_buf, &iwe,
2907 (void *)pos);
2908 if (IS_ERR(current_ev))
2909 return current_ev;
2910 }
2911
2912 return current_ev;
2913 }
2914
2915 static char *
2916 ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
2917 struct cfg80211_internal_bss *bss, char *current_ev,
2918 char *end_buf)
2919 {
2920 const struct cfg80211_bss_ies *ies;
2921 struct iw_event iwe;
2922 const u8 *ie;
2923 u8 buf[50];
2924 u8 *cfg, *p, *tmp;
2925 int rem, i, sig;
2926 bool ismesh = false;
2927
2928 memset(&iwe, 0, sizeof(iwe));
2929 iwe.cmd = SIOCGIWAP;
2930 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
2931 memcpy(iwe.u.ap_addr.sa_data, bss->pub.bssid, ETH_ALEN);
2932 current_ev = iwe_stream_add_event_check(info, current_ev, end_buf, &iwe,
2933 IW_EV_ADDR_LEN);
2934 if (IS_ERR(current_ev))
2935 return current_ev;
2936
2937 memset(&iwe, 0, sizeof(iwe));
2938 iwe.cmd = SIOCGIWFREQ;
2939 iwe.u.freq.m = ieee80211_frequency_to_channel(bss->pub.channel->center_freq);
2940 iwe.u.freq.e = 0;
2941 current_ev = iwe_stream_add_event_check(info, current_ev, end_buf, &iwe,
2942 IW_EV_FREQ_LEN);
2943 if (IS_ERR(current_ev))
2944 return current_ev;
2945
2946 memset(&iwe, 0, sizeof(iwe));
2947 iwe.cmd = SIOCGIWFREQ;
2948 iwe.u.freq.m = bss->pub.channel->center_freq;
2949 iwe.u.freq.e = 6;
2950 current_ev = iwe_stream_add_event_check(info, current_ev, end_buf, &iwe,
2951 IW_EV_FREQ_LEN);
2952 if (IS_ERR(current_ev))
2953 return current_ev;
2954
2955 if (wiphy->signal_type != CFG80211_SIGNAL_TYPE_NONE) {
2956 memset(&iwe, 0, sizeof(iwe));
2957 iwe.cmd = IWEVQUAL;
2958 iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED |
2959 IW_QUAL_NOISE_INVALID |
2960 IW_QUAL_QUAL_UPDATED;
2961 switch (wiphy->signal_type) {
2962 case CFG80211_SIGNAL_TYPE_MBM:
2963 sig = bss->pub.signal / 100;
2964 iwe.u.qual.level = sig;
2965 iwe.u.qual.updated |= IW_QUAL_DBM;
2966 if (sig < -110)
2967 sig = -110;
2968 else if (sig > -40)
2969 sig = -40;
2970
2971 iwe.u.qual.qual = sig + 110;
2972 break;
2973 case CFG80211_SIGNAL_TYPE_UNSPEC:
2974 iwe.u.qual.level = bss->pub.signal;
2975
2976 iwe.u.qual.qual = bss->pub.signal;
2977 break;
2978 default:
2979
2980 break;
2981 }
2982 current_ev = iwe_stream_add_event_check(info, current_ev,
2983 end_buf, &iwe,
2984 IW_EV_QUAL_LEN);
2985 if (IS_ERR(current_ev))
2986 return current_ev;
2987 }
2988
2989 memset(&iwe, 0, sizeof(iwe));
2990 iwe.cmd = SIOCGIWENCODE;
2991 if (bss->pub.capability & WLAN_CAPABILITY_PRIVACY)
2992 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
2993 else
2994 iwe.u.data.flags = IW_ENCODE_DISABLED;
2995 iwe.u.data.length = 0;
2996 current_ev = iwe_stream_add_point_check(info, current_ev, end_buf,
2997 &iwe, "");
2998 if (IS_ERR(current_ev))
2999 return current_ev;
3000
3001 rcu_read_lock();
3002 ies = rcu_dereference(bss->pub.ies);
3003 rem = ies->len;
3004 ie = ies->data;
3005
3006 while (rem >= 2) {
3007
3008 if (ie[1] > rem - 2)
3009 break;
3010
3011 switch (ie[0]) {
3012 case WLAN_EID_SSID:
3013 memset(&iwe, 0, sizeof(iwe));
3014 iwe.cmd = SIOCGIWESSID;
3015 iwe.u.data.length = ie[1];
3016 iwe.u.data.flags = 1;
3017 current_ev = iwe_stream_add_point_check(info,
3018 current_ev,
3019 end_buf, &iwe,
3020 (u8 *)ie + 2);
3021 if (IS_ERR(current_ev))
3022 goto unlock;
3023 break;
3024 case WLAN_EID_MESH_ID:
3025 memset(&iwe, 0, sizeof(iwe));
3026 iwe.cmd = SIOCGIWESSID;
3027 iwe.u.data.length = ie[1];
3028 iwe.u.data.flags = 1;
3029 current_ev = iwe_stream_add_point_check(info,
3030 current_ev,
3031 end_buf, &iwe,
3032 (u8 *)ie + 2);
3033 if (IS_ERR(current_ev))
3034 goto unlock;
3035 break;
3036 case WLAN_EID_MESH_CONFIG:
3037 ismesh = true;
3038 if (ie[1] != sizeof(struct ieee80211_meshconf_ie))
3039 break;
3040 cfg = (u8 *)ie + 2;
3041 memset(&iwe, 0, sizeof(iwe));
3042 iwe.cmd = IWEVCUSTOM;
3043 sprintf(buf, "Mesh Network Path Selection Protocol ID: "
3044 "0x%02X", cfg[0]);
3045 iwe.u.data.length = strlen(buf);
3046 current_ev = iwe_stream_add_point_check(info,
3047 current_ev,
3048 end_buf,
3049 &iwe, buf);
3050 if (IS_ERR(current_ev))
3051 goto unlock;
3052 sprintf(buf, "Path Selection Metric ID: 0x%02X",
3053 cfg[1]);
3054 iwe.u.data.length = strlen(buf);
3055 current_ev = iwe_stream_add_point_check(info,
3056 current_ev,
3057 end_buf,
3058 &iwe, buf);
3059 if (IS_ERR(current_ev))
3060 goto unlock;
3061 sprintf(buf, "Congestion Control Mode ID: 0x%02X",
3062 cfg[2]);
3063 iwe.u.data.length = strlen(buf);
3064 current_ev = iwe_stream_add_point_check(info,
3065 current_ev,
3066 end_buf,
3067 &iwe, buf);
3068 if (IS_ERR(current_ev))
3069 goto unlock;
3070 sprintf(buf, "Synchronization ID: 0x%02X", cfg[3]);
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, "Authentication ID: 0x%02X", cfg[4]);
3079 iwe.u.data.length = strlen(buf);
3080 current_ev = iwe_stream_add_point_check(info,
3081 current_ev,
3082 end_buf,
3083 &iwe, buf);
3084 if (IS_ERR(current_ev))
3085 goto unlock;
3086 sprintf(buf, "Formation Info: 0x%02X", cfg[5]);
3087 iwe.u.data.length = strlen(buf);
3088 current_ev = iwe_stream_add_point_check(info,
3089 current_ev,
3090 end_buf,
3091 &iwe, buf);
3092 if (IS_ERR(current_ev))
3093 goto unlock;
3094 sprintf(buf, "Capabilities: 0x%02X", cfg[6]);
3095 iwe.u.data.length = strlen(buf);
3096 current_ev = iwe_stream_add_point_check(info,
3097 current_ev,
3098 end_buf,
3099 &iwe, buf);
3100 if (IS_ERR(current_ev))
3101 goto unlock;
3102 break;
3103 case WLAN_EID_SUPP_RATES:
3104 case WLAN_EID_EXT_SUPP_RATES:
3105
3106 p = current_ev + iwe_stream_lcp_len(info);
3107
3108 memset(&iwe, 0, sizeof(iwe));
3109 iwe.cmd = SIOCGIWRATE;
3110
3111 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
3112
3113 for (i = 0; i < ie[1]; i++) {
3114 iwe.u.bitrate.value =
3115 ((ie[i + 2] & 0x7f) * 500000);
3116 tmp = p;
3117 p = iwe_stream_add_value(info, current_ev, p,
3118 end_buf, &iwe,
3119 IW_EV_PARAM_LEN);
3120 if (p == tmp) {
3121 current_ev = ERR_PTR(-E2BIG);
3122 goto unlock;
3123 }
3124 }
3125 current_ev = p;
3126 break;
3127 }
3128 rem -= ie[1] + 2;
3129 ie += ie[1] + 2;
3130 }
3131
3132 if (bss->pub.capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS) ||
3133 ismesh) {
3134 memset(&iwe, 0, sizeof(iwe));
3135 iwe.cmd = SIOCGIWMODE;
3136 if (ismesh)
3137 iwe.u.mode = IW_MODE_MESH;
3138 else if (bss->pub.capability & WLAN_CAPABILITY_ESS)
3139 iwe.u.mode = IW_MODE_MASTER;
3140 else
3141 iwe.u.mode = IW_MODE_ADHOC;
3142 current_ev = iwe_stream_add_event_check(info, current_ev,
3143 end_buf, &iwe,
3144 IW_EV_UINT_LEN);
3145 if (IS_ERR(current_ev))
3146 goto unlock;
3147 }
3148
3149 memset(&iwe, 0, sizeof(iwe));
3150 iwe.cmd = IWEVCUSTOM;
3151 sprintf(buf, "tsf=%016llx", (unsigned long long)(ies->tsf));
3152 iwe.u.data.length = strlen(buf);
3153 current_ev = iwe_stream_add_point_check(info, current_ev, end_buf,
3154 &iwe, buf);
3155 if (IS_ERR(current_ev))
3156 goto unlock;
3157 memset(&iwe, 0, sizeof(iwe));
3158 iwe.cmd = IWEVCUSTOM;
3159 sprintf(buf, " Last beacon: %ums ago",
3160 elapsed_jiffies_msecs(bss->ts));
3161 iwe.u.data.length = strlen(buf);
3162 current_ev = iwe_stream_add_point_check(info, current_ev,
3163 end_buf, &iwe, buf);
3164 if (IS_ERR(current_ev))
3165 goto unlock;
3166
3167 current_ev = ieee80211_scan_add_ies(info, ies, current_ev, end_buf);
3168
3169 unlock:
3170 rcu_read_unlock();
3171 return current_ev;
3172 }
3173
3174
3175 static int ieee80211_scan_results(struct cfg80211_registered_device *rdev,
3176 struct iw_request_info *info,
3177 char *buf, size_t len)
3178 {
3179 char *current_ev = buf;
3180 char *end_buf = buf + len;
3181 struct cfg80211_internal_bss *bss;
3182 int err = 0;
3183
3184 spin_lock_bh(&rdev->bss_lock);
3185 cfg80211_bss_expire(rdev);
3186
3187 list_for_each_entry(bss, &rdev->bss_list, list) {
3188 if (buf + len - current_ev <= IW_EV_ADDR_LEN) {
3189 err = -E2BIG;
3190 break;
3191 }
3192 current_ev = ieee80211_bss(&rdev->wiphy, info, bss,
3193 current_ev, end_buf);
3194 if (IS_ERR(current_ev)) {
3195 err = PTR_ERR(current_ev);
3196 break;
3197 }
3198 }
3199 spin_unlock_bh(&rdev->bss_lock);
3200
3201 if (err)
3202 return err;
3203 return current_ev - buf;
3204 }
3205
3206
3207 int cfg80211_wext_giwscan(struct net_device *dev,
3208 struct iw_request_info *info,
3209 struct iw_point *data, char *extra)
3210 {
3211 struct cfg80211_registered_device *rdev;
3212 int res;
3213
3214 if (!netif_running(dev))
3215 return -ENETDOWN;
3216
3217 rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex);
3218
3219 if (IS_ERR(rdev))
3220 return PTR_ERR(rdev);
3221
3222 if (rdev->scan_req || rdev->scan_msg)
3223 return -EAGAIN;
3224
3225 res = ieee80211_scan_results(rdev, info, extra, data->length);
3226 data->length = 0;
3227 if (res >= 0) {
3228 data->length = res;
3229 res = 0;
3230 }
3231
3232 return res;
3233 }
3234 EXPORT_WEXT_HANDLER(cfg80211_wext_giwscan);
3235 #endif