wifi: iwlwifi: mvm: report beacon protection failures
authorJohannes Berg <johannes.berg@intel.com>
Sun, 28 Jan 2024 06:53:48 +0000 (08:53 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 2 Feb 2024 12:47:45 +0000 (13:47 +0100)
Andrei reports that we just silently drop beacons after we
report the key counters, but never report to userspace, so
wpa_supplicant cannot send the WNM action frame. Fix that.

Fixes: b1fdc2505abc ("iwlwifi: mvm: advertise BIGTK client support if available")
Reported-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Reviewed-by: Gregory Greenman <gregory.greenman@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20240128084842.7d855442cdce.Iba90b26f893dc8c49bfb8be65373cd0a138af12c@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c

index 886d000..451af50 100644 (file)
@@ -282,6 +282,7 @@ static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta,
                                u32 status,
                                struct ieee80211_rx_status *stats)
 {
+       struct wireless_dev *wdev;
        struct iwl_mvm_sta *mvmsta;
        struct iwl_mvm_vif *mvmvif;
        u8 keyid;
@@ -303,9 +304,15 @@ static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta,
        if (!ieee80211_is_beacon(hdr->frame_control))
                return 0;
 
+       if (!sta)
+               return -1;
+
+       mvmsta = iwl_mvm_sta_from_mac80211(sta);
+       mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif);
+
        /* key mismatch - will also report !MIC_OK but we shouldn't count it */
        if (!(status & IWL_RX_MPDU_STATUS_KEY_VALID))
-               return -1;
+               goto report;
 
        /* good cases */
        if (likely(status & IWL_RX_MPDU_STATUS_MIC_OK &&
@@ -314,13 +321,6 @@ static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta,
                return 0;
        }
 
-       if (!sta)
-               return -1;
-
-       mvmsta = iwl_mvm_sta_from_mac80211(sta);
-
-       mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif);
-
        /*
         * both keys will have the same cipher and MIC length, use
         * whichever one is available
@@ -329,11 +329,11 @@ static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta,
        if (!key) {
                key = rcu_dereference(mvmvif->bcn_prot.keys[1]);
                if (!key)
-                       return -1;
+                       goto report;
        }
 
        if (len < key->icv_len + IEEE80211_GMAC_PN_LEN + 2)
-               return -1;
+               goto report;
 
        /* get the real key ID */
        keyid = frame[len - key->icv_len - IEEE80211_GMAC_PN_LEN - 2];
@@ -347,7 +347,7 @@ static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta,
                        return -1;
                key = rcu_dereference(mvmvif->bcn_prot.keys[keyid - 6]);
                if (!key)
-                       return -1;
+                       goto report;
        }
 
        /* Report status to mac80211 */
@@ -355,6 +355,10 @@ static int iwl_mvm_rx_mgmt_prot(struct ieee80211_sta *sta,
                ieee80211_key_mic_failure(key);
        else if (status & IWL_RX_MPDU_STATUS_REPLAY_ERROR)
                ieee80211_key_replay(key);
+report:
+       wdev = ieee80211_vif_to_wdev(mvmsta->vif);
+       if (wdev->netdev)
+               cfg80211_rx_unprot_mlme_mgmt(wdev->netdev, (void *)hdr, len);
 
        return -1;
 }