hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/wireless/mlme.c
....@@ -4,6 +4,7 @@
44 *
55 * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
66 * Copyright (c) 2015 Intel Deutschland GmbH
7
+ * Copyright (C) 2019 Intel Corporation
78 */
89
910 #include <linux/kernel.h>
....@@ -21,21 +22,32 @@
2122
2223
2324 void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss,
24
- const u8 *buf, size_t len, int uapsd_queues)
25
+ const u8 *buf, size_t len, int uapsd_queues,
26
+ const u8 *req_ies, size_t req_ies_len)
2527 {
2628 struct wireless_dev *wdev = dev->ieee80211_ptr;
2729 struct wiphy *wiphy = wdev->wiphy;
2830 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
2931 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
3032 struct cfg80211_connect_resp_params cr;
33
+ const u8 *resp_ie = mgmt->u.assoc_resp.variable;
34
+ size_t resp_ie_len = len - offsetof(struct ieee80211_mgmt,
35
+ u.assoc_resp.variable);
36
+
37
+ if (bss->channel->band == NL80211_BAND_S1GHZ) {
38
+ resp_ie = (u8 *)&mgmt->u.s1g_assoc_resp.variable;
39
+ resp_ie_len = len - offsetof(struct ieee80211_mgmt,
40
+ u.s1g_assoc_resp.variable);
41
+ }
3142
3243 memset(&cr, 0, sizeof(cr));
3344 cr.status = (int)le16_to_cpu(mgmt->u.assoc_resp.status_code);
3445 cr.bssid = mgmt->bssid;
3546 cr.bss = bss;
36
- cr.resp_ie = mgmt->u.assoc_resp.variable;
37
- cr.resp_ie_len =
38
- len - offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
47
+ cr.req_ie = req_ies;
48
+ cr.req_ie_len = req_ies_len;
49
+ cr.resp_ie = resp_ie;
50
+ cr.resp_ie_len = resp_ie_len;
3951 cr.timeout_reason = NL80211_TIMEOUT_UNSPECIFIED;
4052
4153 trace_cfg80211_send_rx_assoc(dev, bss);
....@@ -52,7 +64,8 @@
5264 return;
5365 }
5466
55
- nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL, uapsd_queues);
67
+ nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL, uapsd_queues,
68
+ req_ies, req_ies_len);
5669 /* update current_bss etc., consumes the bss reference */
5770 __cfg80211_connect_result(dev, &cr, cr.status == WLAN_STATUS_SUCCESS);
5871 }
....@@ -272,11 +285,11 @@
272285
273286 p1 = (u8*)(ht_capa);
274287 p2 = (u8*)(ht_capa_mask);
275
- for (i = 0; i<sizeof(*ht_capa); i++)
288
+ for (i = 0; i < sizeof(*ht_capa); i++)
276289 p1[i] &= p2[i];
277290 }
278291
279
-/* Do a logical ht_capa &= ht_capa_mask. */
292
+/* Do a logical vht_capa &= vht_capa_mask. */
280293 void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa,
281294 const struct ieee80211_vht_cap *vht_capa_mask)
282295 {
....@@ -421,77 +434,118 @@
421434
422435 __le16 frame_type;
423436
437
+ bool multicast_rx;
438
+
424439 u8 match[];
425440 };
426441
427
-static void
428
-cfg80211_process_mlme_unregistrations(struct cfg80211_registered_device *rdev)
442
+static void cfg80211_mgmt_registrations_update(struct wireless_dev *wdev)
429443 {
444
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
445
+ struct wireless_dev *tmp;
430446 struct cfg80211_mgmt_registration *reg;
447
+ struct mgmt_frame_regs upd = {};
431448
432449 ASSERT_RTNL();
433450
434
- spin_lock_bh(&rdev->mlme_unreg_lock);
435
- while ((reg = list_first_entry_or_null(&rdev->mlme_unreg,
436
- struct cfg80211_mgmt_registration,
437
- list))) {
438
- list_del(&reg->list);
439
- spin_unlock_bh(&rdev->mlme_unreg_lock);
440
-
441
- if (rdev->ops->mgmt_frame_register) {
442
- u16 frame_type = le16_to_cpu(reg->frame_type);
443
-
444
- rdev_mgmt_frame_register(rdev, reg->wdev,
445
- frame_type, false);
446
- }
447
-
448
- kfree(reg);
449
-
450
- spin_lock_bh(&rdev->mlme_unreg_lock);
451
+ spin_lock_bh(&rdev->mgmt_registrations_lock);
452
+ if (!wdev->mgmt_registrations_need_update) {
453
+ spin_unlock_bh(&rdev->mgmt_registrations_lock);
454
+ return;
451455 }
452
- spin_unlock_bh(&rdev->mlme_unreg_lock);
456
+
457
+ rcu_read_lock();
458
+ list_for_each_entry_rcu(tmp, &rdev->wiphy.wdev_list, list) {
459
+ list_for_each_entry(reg, &tmp->mgmt_registrations, list) {
460
+ u32 mask = BIT(le16_to_cpu(reg->frame_type) >> 4);
461
+ u32 mcast_mask = 0;
462
+
463
+ if (reg->multicast_rx)
464
+ mcast_mask = mask;
465
+
466
+ upd.global_stypes |= mask;
467
+ upd.global_mcast_stypes |= mcast_mask;
468
+
469
+ if (tmp == wdev) {
470
+ upd.interface_stypes |= mask;
471
+ upd.interface_mcast_stypes |= mcast_mask;
472
+ }
473
+ }
474
+ }
475
+ rcu_read_unlock();
476
+
477
+ wdev->mgmt_registrations_need_update = 0;
478
+ spin_unlock_bh(&rdev->mgmt_registrations_lock);
479
+
480
+ rdev_update_mgmt_frame_registrations(rdev, wdev, &upd);
453481 }
454482
455
-void cfg80211_mlme_unreg_wk(struct work_struct *wk)
483
+void cfg80211_mgmt_registrations_update_wk(struct work_struct *wk)
456484 {
457485 struct cfg80211_registered_device *rdev;
486
+ struct wireless_dev *wdev;
458487
459488 rdev = container_of(wk, struct cfg80211_registered_device,
460
- mlme_unreg_wk);
489
+ mgmt_registrations_update_wk);
461490
462491 rtnl_lock();
463
- cfg80211_process_mlme_unregistrations(rdev);
492
+ list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list)
493
+ cfg80211_mgmt_registrations_update(wdev);
464494 rtnl_unlock();
465495 }
466496
467497 int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid,
468498 u16 frame_type, const u8 *match_data,
469
- int match_len)
499
+ int match_len, bool multicast_rx,
500
+ struct netlink_ext_ack *extack)
470501 {
471
- struct wiphy *wiphy = wdev->wiphy;
472
- struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
502
+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
473503 struct cfg80211_mgmt_registration *reg, *nreg;
474504 int err = 0;
475505 u16 mgmt_type;
506
+ bool update_multicast = false;
476507
477508 if (!wdev->wiphy->mgmt_stypes)
478509 return -EOPNOTSUPP;
479510
480
- if ((frame_type & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT)
511
+ if ((frame_type & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT) {
512
+ NL_SET_ERR_MSG(extack, "frame type not management");
481513 return -EINVAL;
514
+ }
482515
483
- if (frame_type & ~(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE))
516
+ if (frame_type & ~(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) {
517
+ NL_SET_ERR_MSG(extack, "Invalid frame type");
484518 return -EINVAL;
519
+ }
485520
486521 mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
487
- if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].rx & BIT(mgmt_type)))
522
+ if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].rx & BIT(mgmt_type))) {
523
+ NL_SET_ERR_MSG(extack,
524
+ "Registration to specific type not supported");
488525 return -EINVAL;
526
+ }
527
+
528
+ /*
529
+ * To support Pre Association Security Negotiation (PASN), registration
530
+ * for authentication frames should be supported. However, as some
531
+ * versions of the user space daemons wrongly register to all types of
532
+ * authentication frames (which might result in unexpected behavior)
533
+ * allow such registration if the request is for a specific
534
+ * authentication algorithm number.
535
+ */
536
+ if (wdev->iftype == NL80211_IFTYPE_STATION &&
537
+ (frame_type & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_AUTH &&
538
+ !(match_data && match_len >= 2)) {
539
+ NL_SET_ERR_MSG(extack,
540
+ "Authentication algorithm number required");
541
+ return -EINVAL;
542
+ }
489543
490544 nreg = kzalloc(sizeof(*reg) + match_len, GFP_KERNEL);
491545 if (!nreg)
492546 return -ENOMEM;
493547
494
- spin_lock_bh(&wdev->mgmt_registrations_lock);
548
+ spin_lock_bh(&rdev->mgmt_registrations_lock);
495549
496550 list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
497551 int mlen = min(match_len, reg->match_len);
....@@ -500,34 +554,41 @@
500554 continue;
501555
502556 if (memcmp(reg->match, match_data, mlen) == 0) {
557
+ if (reg->multicast_rx != multicast_rx) {
558
+ update_multicast = true;
559
+ reg->multicast_rx = multicast_rx;
560
+ break;
561
+ }
562
+ NL_SET_ERR_MSG(extack, "Match already configured");
503563 err = -EALREADY;
504564 break;
505565 }
506566 }
507567
508
- if (err) {
509
- kfree(nreg);
568
+ if (err)
510569 goto out;
570
+
571
+ if (update_multicast) {
572
+ kfree(nreg);
573
+ } else {
574
+ memcpy(nreg->match, match_data, match_len);
575
+ nreg->match_len = match_len;
576
+ nreg->nlportid = snd_portid;
577
+ nreg->frame_type = cpu_to_le16(frame_type);
578
+ nreg->wdev = wdev;
579
+ nreg->multicast_rx = multicast_rx;
580
+ list_add(&nreg->list, &wdev->mgmt_registrations);
511581 }
582
+ wdev->mgmt_registrations_need_update = 1;
583
+ spin_unlock_bh(&rdev->mgmt_registrations_lock);
512584
513
- memcpy(nreg->match, match_data, match_len);
514
- nreg->match_len = match_len;
515
- nreg->nlportid = snd_portid;
516
- nreg->frame_type = cpu_to_le16(frame_type);
517
- nreg->wdev = wdev;
518
- list_add(&nreg->list, &wdev->mgmt_registrations);
519
- spin_unlock_bh(&wdev->mgmt_registrations_lock);
520
-
521
- /* process all unregistrations to avoid driver confusion */
522
- cfg80211_process_mlme_unregistrations(rdev);
523
-
524
- if (rdev->ops->mgmt_frame_register)
525
- rdev_mgmt_frame_register(rdev, wdev, frame_type, true);
585
+ cfg80211_mgmt_registrations_update(wdev);
526586
527587 return 0;
528588
529589 out:
530
- spin_unlock_bh(&wdev->mgmt_registrations_lock);
590
+ kfree(nreg);
591
+ spin_unlock_bh(&rdev->mgmt_registrations_lock);
531592
532593 return err;
533594 }
....@@ -538,21 +599,20 @@
538599 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
539600 struct cfg80211_mgmt_registration *reg, *tmp;
540601
541
- spin_lock_bh(&wdev->mgmt_registrations_lock);
602
+ spin_lock_bh(&rdev->mgmt_registrations_lock);
542603
543604 list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
544605 if (reg->nlportid != nlportid)
545606 continue;
546607
547608 list_del(&reg->list);
548
- spin_lock(&rdev->mlme_unreg_lock);
549
- list_add_tail(&reg->list, &rdev->mlme_unreg);
550
- spin_unlock(&rdev->mlme_unreg_lock);
609
+ kfree(reg);
551610
552
- schedule_work(&rdev->mlme_unreg_wk);
611
+ wdev->mgmt_registrations_need_update = 1;
612
+ schedule_work(&rdev->mgmt_registrations_update_wk);
553613 }
554614
555
- spin_unlock_bh(&wdev->mgmt_registrations_lock);
615
+ spin_unlock_bh(&rdev->mgmt_registrations_lock);
556616
557617 if (nlportid && rdev->crit_proto_nlportid == nlportid) {
558618 rdev->crit_proto_nlportid = 0;
....@@ -566,14 +626,17 @@
566626 void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
567627 {
568628 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
629
+ struct cfg80211_mgmt_registration *reg, *tmp;
569630
570
- spin_lock_bh(&wdev->mgmt_registrations_lock);
571
- spin_lock(&rdev->mlme_unreg_lock);
572
- list_splice_tail_init(&wdev->mgmt_registrations, &rdev->mlme_unreg);
573
- spin_unlock(&rdev->mlme_unreg_lock);
574
- spin_unlock_bh(&wdev->mgmt_registrations_lock);
631
+ spin_lock_bh(&rdev->mgmt_registrations_lock);
632
+ list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
633
+ list_del(&reg->list);
634
+ kfree(reg);
635
+ }
636
+ wdev->mgmt_registrations_need_update = 1;
637
+ spin_unlock_bh(&rdev->mgmt_registrations_lock);
575638
576
- cfg80211_process_mlme_unregistrations(rdev);
639
+ cfg80211_mgmt_registrations_update(wdev);
577640 }
578641
579642 int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
....@@ -692,8 +755,8 @@
692755 return rdev_mgmt_tx(rdev, wdev, params, cookie);
693756 }
694757
695
-bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_dbm,
696
- const u8 *buf, size_t len, u32 flags)
758
+bool cfg80211_rx_mgmt_khz(struct wireless_dev *wdev, int freq, int sig_dbm,
759
+ const u8 *buf, size_t len, u32 flags)
697760 {
698761 struct wiphy *wiphy = wdev->wiphy;
699762 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
....@@ -719,7 +782,7 @@
719782 data = buf + ieee80211_hdrlen(mgmt->frame_control);
720783 data_len = len - ieee80211_hdrlen(mgmt->frame_control);
721784
722
- spin_lock_bh(&wdev->mgmt_registrations_lock);
785
+ spin_lock_bh(&rdev->mgmt_registrations_lock);
723786
724787 list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
725788 if (reg->frame_type != ftype)
....@@ -743,12 +806,12 @@
743806 break;
744807 }
745808
746
- spin_unlock_bh(&wdev->mgmt_registrations_lock);
809
+ spin_unlock_bh(&rdev->mgmt_registrations_lock);
747810
748811 trace_cfg80211_return_bool(result);
749812 return result;
750813 }
751
-EXPORT_SYMBOL(cfg80211_rx_mgmt);
814
+EXPORT_SYMBOL(cfg80211_rx_mgmt_khz);
752815
753816 void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev)
754817 {
....@@ -888,7 +951,7 @@
888951 sizeof(struct cfg80211_chan_def));
889952 queue_work(cfg80211_wq, &rdev->propagate_cac_done_wk);
890953 cfg80211_sched_dfs_chan_update(rdev);
891
- /* fall through */
954
+ fallthrough;
892955 case NL80211_RADAR_CAC_ABORTED:
893956 wdev->cac_started = false;
894957 break;