wifi: iwlwifi: mvm: remove only link-specific AP keys
authorJohannes Berg <johannes.berg@intel.com>
Wed, 29 Mar 2023 07:05:24 +0000 (10:05 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Thu, 30 Mar 2023 10:08:40 +0000 (12:08 +0200)
When we remove the AP station, we iterate over the links
and remove all the keys, however, the key iteration will
return all keys for all links, so skip the ones that we
don't need based on the link ID.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230329100039.e724878f502e.I66870d4629244b4b309be79e11cbbd384bdf93be@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/mld-key.c
drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
drivers/net/wireless/intel/iwlwifi/mvm/sta.c

index 1fd7e5bf594d0f40e4a61d43486954fdc0e89d07..98c9402716485d58e7f8c2a643863648acadde1e 100644 (file)
@@ -2722,7 +2722,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
                                      &mvm->status)) {
                                /* first remove remaining keys */
                                iwl_mvm_sec_key_remove_ap(mvm, vif,
-                                                         &mvmvif->deflink);
+                                                         &mvmvif->deflink, 0);
 
                                /*
                                 * Remove AP station now that
index 44206e3e1a8724e1322e56dde5f14bc12c6c9f99..f4785c0a0b846e9d9e475cd86fd2c097694b9db0 100644 (file)
@@ -195,6 +195,7 @@ static void iwl_mvm_sec_key_remove_ap_iter(struct ieee80211_hw *hw,
                                           void *data)
 {
        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+       unsigned int link_id = (uintptr_t)data;
 
        if (key->hw_key_idx == STA_KEY_IDX_INVALID)
                return;
@@ -202,13 +203,17 @@ static void iwl_mvm_sec_key_remove_ap_iter(struct ieee80211_hw *hw,
        if (sta)
                return;
 
+       if (key->link_id >= 0 && key->link_id != link_id)
+               return;
+
        _iwl_mvm_sec_key_del(mvm, vif, NULL, key, CMD_ASYNC);
        key->hw_key_idx = STA_KEY_IDX_INVALID;
 }
 
 void iwl_mvm_sec_key_remove_ap(struct iwl_mvm *mvm,
                               struct ieee80211_vif *vif,
-                              struct iwl_mvm_vif_link_info *link)
+                              struct iwl_mvm_vif_link_info *link,
+                              unsigned int link_id)
 {
        u32 sec_key_id = WIDE_ID(DATA_PATH_GROUP, SEC_KEY_CMD);
        u8 sec_key_ver = iwl_fw_lookup_cmd_ver(mvm->fw, sec_key_id, 0);
@@ -222,5 +227,5 @@ void iwl_mvm_sec_key_remove_ap(struct iwl_mvm *mvm,
 
        ieee80211_iter_keys_rcu(mvm->hw, vif,
                                iwl_mvm_sec_key_remove_ap_iter,
-                               NULL);
+                               (void *)(uintptr_t)link_id);
 }
index e475d0daf512e8c6a2a40a1a3df3b607d6b256e9..1a97bf92581732ae92694539727cc6aaffdcecf0 100644 (file)
@@ -544,7 +544,7 @@ static void iwl_mvm_mld_vif_delete_all_stas(struct iwl_mvm *mvm,
                if (!link)
                        continue;
 
-               iwl_mvm_sec_key_remove_ap(mvm, vif, link);
+               iwl_mvm_sec_key_remove_ap(mvm, vif, link, i);
                ret = iwl_mvm_mld_rm_sta_id(mvm, vif, link->ap_sta_id);
                if (ret)
                        IWL_ERR(mvm, "failed to remove AP station\n");
index a7a7018edd2bf28eeb8b3056d854e345c6dd6813..23d797247915f26157a4f47b95b4df55faf78ded 100644 (file)
@@ -2328,7 +2328,8 @@ int iwl_mvm_sec_key_del(struct iwl_mvm *mvm,
                        struct ieee80211_key_conf *keyconf);
 void iwl_mvm_sec_key_remove_ap(struct iwl_mvm *mvm,
                               struct ieee80211_vif *vif,
-                              struct iwl_mvm_vif_link_info *link);
+                              struct iwl_mvm_vif_link_info *link,
+                              unsigned int link_id);
 
 int iwl_rfi_send_config_cmd(struct iwl_mvm *mvm,
                            struct iwl_rfi_lut_entry *rfi_table);
index f9f512a85ef12918a0ba5f18005495713ecf5ec8..9a3a7eabded8a7a826b43a7d76cf90463bcd470b 100644 (file)
@@ -2022,7 +2022,7 @@ bool iwl_mvm_sta_del(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
                        return true;
 
                /* first remove remaining keys */
-               iwl_mvm_sec_key_remove_ap(mvm, vif, &mvmvif->deflink);
+               iwl_mvm_sec_key_remove_ap(mvm, vif, &mvmvif->deflink, 0);
 
                /* unassoc - go ahead - remove the AP STA now */
                mvmvif->deflink.ap_sta_id = IWL_MVM_INVALID_STA;