24
24
#include "wme.h"
25
25
26
26
static struct ieee80211_link_data *
27
- ieee80211_link_or_deflink (struct ieee80211_sub_if_data * sdata , int link_id )
27
+ ieee80211_link_or_deflink (struct ieee80211_sub_if_data * sdata , int link_id ,
28
+ bool require_valid )
28
29
{
29
30
struct ieee80211_link_data * link ;
30
31
31
32
if (link_id < 0 ) {
32
- if (sdata -> vif .valid_links )
33
+ /*
34
+ * For keys, if sdata is not an MLD, we might not use
35
+ * the return value at all (if it's not a pairwise key),
36
+ * so in that case (require_valid==false) don't error.
37
+ */
38
+ if (require_valid && sdata -> vif .valid_links )
33
39
return ERR_PTR (- EINVAL );
34
40
35
41
return & sdata -> deflink ;
@@ -456,6 +462,8 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
456
462
const u8 * mac_addr , struct key_params * params )
457
463
{
458
464
struct ieee80211_sub_if_data * sdata = IEEE80211_DEV_TO_SUB_IF (dev );
465
+ struct ieee80211_link_data * link =
466
+ ieee80211_link_or_deflink (sdata , link_id , false);
459
467
struct ieee80211_local * local = sdata -> local ;
460
468
struct sta_info * sta = NULL ;
461
469
struct ieee80211_key * key ;
@@ -464,6 +472,9 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
464
472
if (!ieee80211_sdata_running (sdata ))
465
473
return - ENETDOWN ;
466
474
475
+ if (IS_ERR (link ))
476
+ return PTR_ERR (link );
477
+
467
478
if (pairwise && params -> mode == NL80211_KEY_SET_TX )
468
479
return ieee80211_set_tx (sdata , mac_addr , key_idx );
469
480
@@ -472,6 +483,8 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
472
483
case WLAN_CIPHER_SUITE_WEP40 :
473
484
case WLAN_CIPHER_SUITE_TKIP :
474
485
case WLAN_CIPHER_SUITE_WEP104 :
486
+ if (link_id >= 0 )
487
+ return - EINVAL ;
475
488
if (WARN_ON_ONCE (fips_enabled ))
476
489
return - EINVAL ;
477
490
break ;
@@ -484,6 +497,8 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
484
497
if (IS_ERR (key ))
485
498
return PTR_ERR (key );
486
499
500
+ key -> conf .link_id = link_id ;
501
+
487
502
if (pairwise )
488
503
key -> conf .flags |= IEEE80211_KEY_FLAG_PAIRWISE ;
489
504
@@ -545,7 +560,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
545
560
break ;
546
561
}
547
562
548
- err = ieee80211_key_link (key , sdata , sta );
563
+ err = ieee80211_key_link (key , link , sta );
549
564
550
565
out_unlock :
551
566
mutex_unlock (& local -> sta_mtx );
@@ -554,18 +569,37 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
554
569
}
555
570
556
571
static struct ieee80211_key *
557
- ieee80211_lookup_key (struct ieee80211_sub_if_data * sdata ,
572
+ ieee80211_lookup_key (struct ieee80211_sub_if_data * sdata , int link_id ,
558
573
u8 key_idx , bool pairwise , const u8 * mac_addr )
559
574
{
560
575
struct ieee80211_local * local = sdata -> local ;
576
+ struct ieee80211_link_data * link = & sdata -> deflink ;
561
577
struct ieee80211_key * key ;
562
- struct sta_info * sta ;
578
+
579
+ if (link_id >= 0 ) {
580
+ link = rcu_dereference_check (sdata -> link [link_id ],
581
+ lockdep_is_held (& sdata -> wdev .mtx ));
582
+ if (!link )
583
+ return NULL ;
584
+ }
563
585
564
586
if (mac_addr ) {
587
+ struct sta_info * sta ;
588
+ struct link_sta_info * link_sta ;
589
+
565
590
sta = sta_info_get_bss (sdata , mac_addr );
566
591
if (!sta )
567
592
return NULL ;
568
593
594
+ if (link_id >= 0 ) {
595
+ link_sta = rcu_dereference_check (sta -> link [link_id ],
596
+ lockdep_is_held (& local -> sta_mtx ));
597
+ if (!link_sta )
598
+ return NULL ;
599
+ } else {
600
+ link_sta = & sta -> deflink ;
601
+ }
602
+
569
603
if (pairwise && key_idx < NUM_DEFAULT_KEYS )
570
604
return rcu_dereference_check_key_mtx (local ,
571
605
sta -> ptk [key_idx ]);
@@ -575,7 +609,7 @@ ieee80211_lookup_key(struct ieee80211_sub_if_data *sdata,
575
609
NUM_DEFAULT_MGMT_KEYS +
576
610
NUM_DEFAULT_BEACON_KEYS )
577
611
return rcu_dereference_check_key_mtx (local ,
578
- sta -> deflink . gtk [key_idx ]);
612
+ link_sta -> gtk [key_idx ]);
579
613
580
614
return NULL ;
581
615
}
@@ -584,7 +618,7 @@ ieee80211_lookup_key(struct ieee80211_sub_if_data *sdata,
584
618
return rcu_dereference_check_key_mtx (local ,
585
619
sdata -> keys [key_idx ]);
586
620
587
- key = rcu_dereference_check_key_mtx (local , sdata -> deflink . gtk [key_idx ]);
621
+ key = rcu_dereference_check_key_mtx (local , link -> gtk [key_idx ]);
588
622
if (key )
589
623
return key ;
590
624
@@ -607,7 +641,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
607
641
mutex_lock (& local -> sta_mtx );
608
642
mutex_lock (& local -> key_mtx );
609
643
610
- key = ieee80211_lookup_key (sdata , key_idx , pairwise , mac_addr );
644
+ key = ieee80211_lookup_key (sdata , link_id , key_idx , pairwise , mac_addr );
611
645
if (!key ) {
612
646
ret = - ENOENT ;
613
647
goto out_unlock ;
@@ -643,7 +677,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
643
677
644
678
rcu_read_lock ();
645
679
646
- key = ieee80211_lookup_key (sdata , key_idx , pairwise , mac_addr );
680
+ key = ieee80211_lookup_key (sdata , link_id , key_idx , pairwise , mac_addr );
647
681
if (!key )
648
682
goto out ;
649
683
@@ -734,8 +768,13 @@ static int ieee80211_config_default_key(struct wiphy *wiphy,
734
768
bool multi )
735
769
{
736
770
struct ieee80211_sub_if_data * sdata = IEEE80211_DEV_TO_SUB_IF (dev );
771
+ struct ieee80211_link_data * link =
772
+ ieee80211_link_or_deflink (sdata , link_id , false);
737
773
738
- ieee80211_set_default_key (sdata , key_idx , uni , multi );
774
+ if (IS_ERR (link ))
775
+ return PTR_ERR (link );
776
+
777
+ ieee80211_set_default_key (link , key_idx , uni , multi );
739
778
740
779
return 0 ;
741
780
}
@@ -745,8 +784,13 @@ static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy,
745
784
int link_id , u8 key_idx )
746
785
{
747
786
struct ieee80211_sub_if_data * sdata = IEEE80211_DEV_TO_SUB_IF (dev );
787
+ struct ieee80211_link_data * link =
788
+ ieee80211_link_or_deflink (sdata , link_id , true);
748
789
749
- ieee80211_set_default_mgmt_key (sdata , key_idx );
790
+ if (IS_ERR (link ))
791
+ return PTR_ERR (link );
792
+
793
+ ieee80211_set_default_mgmt_key (link , key_idx );
750
794
751
795
return 0 ;
752
796
}
@@ -756,8 +800,13 @@ static int ieee80211_config_default_beacon_key(struct wiphy *wiphy,
756
800
int link_id , u8 key_idx )
757
801
{
758
802
struct ieee80211_sub_if_data * sdata = IEEE80211_DEV_TO_SUB_IF (dev );
803
+ struct ieee80211_link_data * link =
804
+ ieee80211_link_or_deflink (sdata , link_id , true);
805
+
806
+ if (IS_ERR (link ))
807
+ return PTR_ERR (link );
759
808
760
- ieee80211_set_default_beacon_key (sdata , key_idx );
809
+ ieee80211_set_default_beacon_key (link , key_idx );
761
810
762
811
return 0 ;
763
812
}
@@ -2588,7 +2637,7 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
2588
2637
struct ieee80211_local * local = wiphy_priv (wiphy );
2589
2638
struct ieee80211_sub_if_data * sdata = IEEE80211_DEV_TO_SUB_IF (dev );
2590
2639
struct ieee80211_link_data * link =
2591
- ieee80211_link_or_deflink (sdata , params -> link_id );
2640
+ ieee80211_link_or_deflink (sdata , params -> link_id , true );
2592
2641
struct ieee80211_tx_queue_params p ;
2593
2642
2594
2643
if (!local -> ops -> conf_tx )
0 commit comments