mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 11:03:43 +02:00
wifi: iwlwifi: mld: track BIGTK per link
We track the BIGTKs installed for beacon protection purposes. But in MLO we will have a different BIGTK per link. Track the BIGTK per-link and not per-vif. Reviewed-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Link: https://patch.msgid.link/20250821204455.0392769d3abb.I5d8e232d663e3ca8fc23de12dd8534cb076cabb9@changeid
This commit is contained in:
parent
33d958b39a
commit
8925c7876c
|
|
@ -11,6 +11,7 @@
|
|||
#include "mcc.h"
|
||||
#include "sta.h"
|
||||
#include "mlo.h"
|
||||
#include "key.h"
|
||||
|
||||
#include "fw/api/d3.h"
|
||||
#include "fw/api/offload.h"
|
||||
|
|
@ -825,12 +826,8 @@ iwl_mld_add_mcast_rekey(struct ieee80211_vif *vif,
|
|||
}
|
||||
|
||||
/* Also keep track of the new BIGTK */
|
||||
if ((key_config->keyidx == 6 || key_config->keyidx == 7) &&
|
||||
vif->type == NL80211_IFTYPE_STATION) {
|
||||
struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
|
||||
|
||||
rcu_assign_pointer(mld_vif->bigtks[key_config->keyidx - 6], key_config);
|
||||
}
|
||||
if (key_config->keyidx == 6 || key_config->keyidx == 7)
|
||||
iwl_mld_track_bigtk(mld, vif, key_config, true);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -125,8 +125,6 @@ struct iwl_mld_emlsr {
|
|||
* @ap_sta: pointer to AP sta, for easier access to it.
|
||||
* Relevant only for STA vifs.
|
||||
* @authorized: indicates the AP station was set to authorized
|
||||
* @bigtks: BIGTKs of the AP, for beacon protection.
|
||||
* Only valid for STA. (FIXME: needs to be per link)
|
||||
* @num_associated_stas: number of associated STAs. Relevant only for AP mode.
|
||||
* @ap_ibss_active: whether the AP/IBSS was started
|
||||
* @cca_40mhz_workaround: When we are connected in 2.4 GHz and 40 MHz, and the
|
||||
|
|
@ -158,7 +156,6 @@ struct iwl_mld_vif {
|
|||
struct iwl_mld_session_protect session_protect;
|
||||
struct ieee80211_sta *ap_sta;
|
||||
bool authorized;
|
||||
struct ieee80211_key_conf __rcu *bigtks[2];
|
||||
u8 num_associated_stas;
|
||||
bool ap_ibss_active;
|
||||
enum iwl_mld_cca_40mhz_wa_status cca_40mhz_workaround;
|
||||
|
|
|
|||
|
|
@ -368,3 +368,29 @@ int iwl_mld_update_sta_keys(struct iwl_mld *mld,
|
|||
&data);
|
||||
return data.err;
|
||||
}
|
||||
|
||||
void iwl_mld_track_bigtk(struct iwl_mld *mld,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_key_conf *key, bool add)
|
||||
{
|
||||
struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif);
|
||||
struct iwl_mld_link *link;
|
||||
|
||||
if (vif->type != NL80211_IFTYPE_STATION)
|
||||
return;
|
||||
|
||||
if (WARN_ON(key->keyidx < 6 || key->keyidx > 7))
|
||||
return;
|
||||
|
||||
if (WARN_ON(key->link_id < 0))
|
||||
return;
|
||||
|
||||
link = iwl_mld_link_dereference_check(mld_vif, key->link_id);
|
||||
if (WARN_ON(!link))
|
||||
return;
|
||||
|
||||
if (add)
|
||||
rcu_assign_pointer(link->bigtks[key->keyidx - 6], key);
|
||||
else
|
||||
RCU_INIT_POINTER(link->bigtks[key->keyidx - 6], NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,4 +36,8 @@ iwl_mld_cleanup_keys_iter(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
|||
key->hw_key_idx = STA_KEY_IDX_INVALID;
|
||||
}
|
||||
|
||||
void iwl_mld_track_bigtk(struct iwl_mld *mld,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_key_conf *key, bool add);
|
||||
|
||||
#endif /* __iwl_mld_key_h__ */
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ struct iwl_probe_resp_data {
|
|||
* @he_ru_2mhz_block: 26-tone RU OFDMA transmissions should be blocked.
|
||||
* @igtk: fw can only have one IGTK at a time, whereas mac80211 can have two.
|
||||
* This tracks the one IGTK that currently exists in FW.
|
||||
* @bigtks: BIGTKs of the AP. Only valid for STA mode.
|
||||
* @bcast_sta: station used for broadcast packets. Used in AP, GO and IBSS.
|
||||
* @mcast_sta: station used for multicast packets. Used in AP, GO and IBSS.
|
||||
* @mon_sta: station used for TX injection in monitor interface.
|
||||
|
|
@ -59,6 +60,7 @@ struct iwl_mld_link {
|
|||
struct ieee80211_chanctx_conf __rcu *chan_ctx;
|
||||
bool he_ru_2mhz_block;
|
||||
struct ieee80211_key_conf *igtk;
|
||||
struct ieee80211_key_conf __rcu *bigtks[2];
|
||||
);
|
||||
/* And here fields that survive a fw restart */
|
||||
struct iwl_mld_int_sta bcast_sta;
|
||||
|
|
|
|||
|
|
@ -2065,9 +2065,8 @@ static int iwl_mld_set_key_add(struct iwl_mld *mld,
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_STATION &&
|
||||
(keyidx == 6 || keyidx == 7))
|
||||
rcu_assign_pointer(mld_vif->bigtks[keyidx - 6], key);
|
||||
if (keyidx == 6 || keyidx == 7)
|
||||
iwl_mld_track_bigtk(mld, vif, key, true);
|
||||
|
||||
/* After exiting from RFKILL, hostapd configures GTK/ITGK before the
|
||||
* AP is started, but those keys can't be sent to the FW before the
|
||||
|
|
@ -2116,9 +2115,8 @@ static void iwl_mld_set_key_remove(struct iwl_mld *mld,
|
|||
sta ? iwl_mld_sta_from_mac80211(sta) : NULL;
|
||||
int keyidx = key->keyidx;
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_STATION &&
|
||||
(keyidx == 6 || keyidx == 7))
|
||||
RCU_INIT_POINTER(mld_vif->bigtks[keyidx - 6], NULL);
|
||||
if (keyidx == 6 || keyidx == 7)
|
||||
iwl_mld_track_bigtk(mld, vif, key, false);
|
||||
|
||||
if (mld_sta && key->flags & IEEE80211_KEY_FLAG_PAIRWISE &&
|
||||
(key->cipher == WLAN_CIPHER_SUITE_CCMP ||
|
||||
|
|
|
|||
|
|
@ -1619,12 +1619,14 @@ static int iwl_mld_rx_mgmt_prot(struct ieee80211_sta *sta,
|
|||
u32 mpdu_status,
|
||||
u32 mpdu_len)
|
||||
{
|
||||
struct iwl_mld_link *link;
|
||||
struct wireless_dev *wdev;
|
||||
struct iwl_mld_sta *mld_sta;
|
||||
struct iwl_mld_vif *mld_vif;
|
||||
u8 keyidx;
|
||||
struct ieee80211_key_conf *key;
|
||||
const u8 *frame = (void *)hdr;
|
||||
u8 link_id;
|
||||
|
||||
if ((mpdu_status & IWL_RX_MPDU_STATUS_SEC_MASK) ==
|
||||
IWL_RX_MPDU_STATUS_SEC_NONE)
|
||||
|
|
@ -1657,12 +1659,17 @@ static int iwl_mld_rx_mgmt_prot(struct ieee80211_sta *sta,
|
|||
return 0;
|
||||
}
|
||||
|
||||
link_id = rx_status->link_valid ? rx_status->link_id : 0;
|
||||
link = rcu_dereference(mld_vif->link[link_id]);
|
||||
if (WARN_ON_ONCE(!link))
|
||||
return -1;
|
||||
|
||||
/* both keys will have the same cipher and MIC length, use
|
||||
* whichever one is available
|
||||
*/
|
||||
key = rcu_dereference(mld_vif->bigtks[0]);
|
||||
key = rcu_dereference(link->bigtks[0]);
|
||||
if (!key) {
|
||||
key = rcu_dereference(mld_vif->bigtks[1]);
|
||||
key = rcu_dereference(link->bigtks[1]);
|
||||
if (!key)
|
||||
goto report;
|
||||
}
|
||||
|
|
@ -1680,7 +1687,7 @@ static int iwl_mld_rx_mgmt_prot(struct ieee80211_sta *sta,
|
|||
if (keyidx != 6 && keyidx != 7)
|
||||
return -1;
|
||||
|
||||
key = rcu_dereference(mld_vif->bigtks[keyidx - 6]);
|
||||
key = rcu_dereference(link->bigtks[keyidx - 6]);
|
||||
if (!key)
|
||||
goto report;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user