Commit 65db391d authored by Johannes Berg's avatar Johannes Berg Committed by Kalle Valo

iwlwifi: mvm: fix beacon protection checks

Unfortunately, since beacon protection isn't fully available
yet, we didn't notice that there are problems with it and
that the replay detection isn't working correctly. We were
relying only on mac80211, since iwl_mvm_rx_crypto() exits
when !ieee80211_has_protected(), which is of course true for
protected (but not encrypted) management frames.

Fix this to properly detect protected (but not encrypted)
management frames and handle them - we continue to only care
about beacons since for others everything can and will be
checked in mac80211.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Fixes: b1fdc250 ("iwlwifi: mvm: advertise BIGTK client support if available")
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/iwlwifi.20210326125611.23c990843369.I09c262a8f6f9852cc8f513cdcb31a7f8f87dd8af@changeid
parent 39fb06f7
...@@ -272,10 +272,10 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm, ...@@ -272,10 +272,10 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm,
rx_status->chain_signal[2] = S8_MIN; rx_status->chain_signal[2] = S8_MIN;
} }
static int iwl_mvm_rx_mgmt_crypto(struct ieee80211_sta *sta, static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta,
struct ieee80211_hdr *hdr, struct ieee80211_hdr *hdr,
struct iwl_rx_mpdu_desc *desc, struct iwl_rx_mpdu_desc *desc,
u32 status) u32 status)
{ {
struct iwl_mvm_sta *mvmsta; struct iwl_mvm_sta *mvmsta;
struct iwl_mvm_vif *mvmvif; struct iwl_mvm_vif *mvmvif;
...@@ -285,6 +285,9 @@ static int iwl_mvm_rx_mgmt_crypto(struct ieee80211_sta *sta, ...@@ -285,6 +285,9 @@ static int iwl_mvm_rx_mgmt_crypto(struct ieee80211_sta *sta,
u32 len = le16_to_cpu(desc->mpdu_len); u32 len = le16_to_cpu(desc->mpdu_len);
const u8 *frame = (void *)hdr; const u8 *frame = (void *)hdr;
if ((status & IWL_RX_MPDU_STATUS_SEC_MASK) == IWL_RX_MPDU_STATUS_SEC_NONE)
return 0;
/* /*
* For non-beacon, we don't really care. But beacons may * For non-beacon, we don't really care. But beacons may
* be filtered out, and we thus need the firmware's replay * be filtered out, and we thus need the firmware's replay
...@@ -356,6 +359,10 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_sta *sta, ...@@ -356,6 +359,10 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
IWL_RX_MPDU_STATUS_SEC_UNKNOWN && !mvm->monitor_on) IWL_RX_MPDU_STATUS_SEC_UNKNOWN && !mvm->monitor_on)
return -1; return -1;
if (unlikely(ieee80211_is_mgmt(hdr->frame_control) &&
!ieee80211_has_protected(hdr->frame_control)))
return iwl_mvm_rx_mgmt_prot(sta, hdr, desc, status);
if (!ieee80211_has_protected(hdr->frame_control) || if (!ieee80211_has_protected(hdr->frame_control) ||
(status & IWL_RX_MPDU_STATUS_SEC_MASK) == (status & IWL_RX_MPDU_STATUS_SEC_MASK) ==
IWL_RX_MPDU_STATUS_SEC_NONE) IWL_RX_MPDU_STATUS_SEC_NONE)
...@@ -411,7 +418,7 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_sta *sta, ...@@ -411,7 +418,7 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
stats->flag |= RX_FLAG_DECRYPTED; stats->flag |= RX_FLAG_DECRYPTED;
return 0; return 0;
case RX_MPDU_RES_STATUS_SEC_CMAC_GMAC_ENC: case RX_MPDU_RES_STATUS_SEC_CMAC_GMAC_ENC:
return iwl_mvm_rx_mgmt_crypto(sta, hdr, desc, status); break;
default: default:
/* /*
* Sometimes we can get frames that were not decrypted * Sometimes we can get frames that were not decrypted
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment