2424#include "wme.h"
2525
2626static 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 )
2829{
2930 struct ieee80211_link_data * link ;
3031
3132 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 )
3339 return ERR_PTR (- EINVAL );
3440
3541 return & sdata -> deflink ;
@@ -456,6 +462,8 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
456462 const u8 * mac_addr , struct key_params * params )
457463{
458464 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);
459467 struct ieee80211_local * local = sdata -> local ;
460468 struct sta_info * sta = NULL ;
461469 struct ieee80211_key * key ;
@@ -464,6 +472,9 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
464472 if (!ieee80211_sdata_running (sdata ))
465473 return - ENETDOWN ;
466474
475+ if (IS_ERR (link ))
476+ return PTR_ERR (link );
477+
467478 if (pairwise && params -> mode == NL80211_KEY_SET_TX )
468479 return ieee80211_set_tx (sdata , mac_addr , key_idx );
469480
@@ -472,6 +483,8 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
472483 case WLAN_CIPHER_SUITE_WEP40 :
473484 case WLAN_CIPHER_SUITE_TKIP :
474485 case WLAN_CIPHER_SUITE_WEP104 :
486+ if (link_id >= 0 )
487+ return - EINVAL ;
475488 if (WARN_ON_ONCE (fips_enabled ))
476489 return - EINVAL ;
477490 break ;
@@ -484,6 +497,8 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
484497 if (IS_ERR (key ))
485498 return PTR_ERR (key );
486499
500+ key -> conf .link_id = link_id ;
501+
487502 if (pairwise )
488503 key -> conf .flags |= IEEE80211_KEY_FLAG_PAIRWISE ;
489504
@@ -545,7 +560,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
545560 break ;
546561 }
547562
548- err = ieee80211_key_link (key , sdata , sta );
563+ err = ieee80211_key_link (key , link , sta );
549564
550565 out_unlock :
551566 mutex_unlock (& local -> sta_mtx );
@@ -554,18 +569,37 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
554569}
555570
556571static 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 ,
558573 u8 key_idx , bool pairwise , const u8 * mac_addr )
559574{
560575 struct ieee80211_local * local = sdata -> local ;
576+ struct ieee80211_link_data * link = & sdata -> deflink ;
561577 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+ }
563585
564586 if (mac_addr ) {
587+ struct sta_info * sta ;
588+ struct link_sta_info * link_sta ;
589+
565590 sta = sta_info_get_bss (sdata , mac_addr );
566591 if (!sta )
567592 return NULL ;
568593
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+
569603 if (pairwise && key_idx < NUM_DEFAULT_KEYS )
570604 return rcu_dereference_check_key_mtx (local ,
571605 sta -> ptk [key_idx ]);
@@ -575,7 +609,7 @@ ieee80211_lookup_key(struct ieee80211_sub_if_data *sdata,
575609 NUM_DEFAULT_MGMT_KEYS +
576610 NUM_DEFAULT_BEACON_KEYS )
577611 return rcu_dereference_check_key_mtx (local ,
578- sta -> deflink . gtk [key_idx ]);
612+ link_sta -> gtk [key_idx ]);
579613
580614 return NULL ;
581615 }
@@ -584,7 +618,7 @@ ieee80211_lookup_key(struct ieee80211_sub_if_data *sdata,
584618 return rcu_dereference_check_key_mtx (local ,
585619 sdata -> keys [key_idx ]);
586620
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 ]);
588622 if (key )
589623 return key ;
590624
@@ -607,7 +641,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
607641 mutex_lock (& local -> sta_mtx );
608642 mutex_lock (& local -> key_mtx );
609643
610- key = ieee80211_lookup_key (sdata , key_idx , pairwise , mac_addr );
644+ key = ieee80211_lookup_key (sdata , link_id , key_idx , pairwise , mac_addr );
611645 if (!key ) {
612646 ret = - ENOENT ;
613647 goto out_unlock ;
@@ -643,7 +677,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
643677
644678 rcu_read_lock ();
645679
646- key = ieee80211_lookup_key (sdata , key_idx , pairwise , mac_addr );
680+ key = ieee80211_lookup_key (sdata , link_id , key_idx , pairwise , mac_addr );
647681 if (!key )
648682 goto out ;
649683
@@ -734,8 +768,13 @@ static int ieee80211_config_default_key(struct wiphy *wiphy,
734768 bool multi )
735769{
736770 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);
737773
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 );
739778
740779 return 0 ;
741780}
@@ -745,8 +784,13 @@ static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy,
745784 int link_id , u8 key_idx )
746785{
747786 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);
748789
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 );
750794
751795 return 0 ;
752796}
@@ -756,8 +800,13 @@ static int ieee80211_config_default_beacon_key(struct wiphy *wiphy,
756800 int link_id , u8 key_idx )
757801{
758802 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 );
759808
760- ieee80211_set_default_beacon_key (sdata , key_idx );
809+ ieee80211_set_default_beacon_key (link , key_idx );
761810
762811 return 0 ;
763812}
@@ -2588,7 +2637,7 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
25882637 struct ieee80211_local * local = wiphy_priv (wiphy );
25892638 struct ieee80211_sub_if_data * sdata = IEEE80211_DEV_TO_SUB_IF (dev );
25902639 struct ieee80211_link_data * link =
2591- ieee80211_link_or_deflink (sdata , params -> link_id );
2640+ ieee80211_link_or_deflink (sdata , params -> link_id , true );
25922641 struct ieee80211_tx_queue_params p ;
25932642
25942643 if (!local -> ops -> conf_tx )
0 commit comments