iwlwifi: mvm: drop UNKNOWN security type frames
authorSara Sharon <sara.sharon@intel.com>
Mon, 26 Mar 2018 10:07:03 +0000 (13:07 +0300)
committerLuca Coelho <luciano.coelho@intel.com>
Wed, 30 May 2018 06:08:06 +0000 (09:08 +0300)
In some cases we may get from FW errored frames with
UNKNOWN security type.

This may happen in unsecured aggregation flow, where
the first packet had a CRC error in the WEP bit, which
was followed by a failure to decrypt and was dropped.

The next frames in the aggregation "inherit" the bad metadata
of the first packet.

Make sure to drop such frames since RADA and other offloads
will not operate correctly which may have unexpected results.

In case of AP it also causes to TX AMSDU frames to the peers,
resulting with assert 0x104B.

Signed-off-by: Sara Sharon <sara.sharon@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c

index e7565f37ece987610adb8bdef0f4cd4e7dede1fa..7e570c4a9df0ed0d396165ca804d7896088d07e6 100644 (file)
@@ -295,6 +295,7 @@ enum iwl_rx_mpdu_status {
        IWL_RX_MPDU_STATUS_MIC_OK               = BIT(6),
        IWL_RX_MPDU_RES_STATUS_TTAK_OK          = BIT(7),
        IWL_RX_MPDU_STATUS_SEC_MASK             = 0x7 << 8,
+       IWL_RX_MPDU_STATUS_SEC_UNKNOWN          = IWL_RX_MPDU_STATUS_SEC_MASK,
        IWL_RX_MPDU_STATUS_SEC_NONE             = 0x0 << 8,
        IWL_RX_MPDU_STATUS_SEC_WEP              = 0x1 << 8,
        IWL_RX_MPDU_STATUS_SEC_CCM              = 0x2 << 8,
index bb63e75a9b7f37911f89cf6320bd2987fa7d02a5..2b1f0dc73c253417a84dccdf363e101f660d7875 100644 (file)
@@ -227,12 +227,24 @@ static void iwl_mvm_get_signal_strength(struct iwl_mvm *mvm,
 }
 
 static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
-                            struct ieee80211_rx_status *stats,
-                            struct iwl_rx_mpdu_desc *desc, u32 pkt_flags,
-                            int queue, u8 *crypt_len)
+                            struct ieee80211_rx_status *stats, u16 phy_info,
+                            struct iwl_rx_mpdu_desc *desc,
+                            u32 pkt_flags, int queue, u8 *crypt_len)
 {
        u16 status = le16_to_cpu(desc->status);
 
+       /*
+        * Drop UNKNOWN frames in aggregation, unless in monitor mode
+        * (where we don't have the keys).
+        * We limit this to aggregation because in TKIP this is a valid
+        * scenario, since we may not have the (correct) TTAK (phase 1
+        * key) in the firmware.
+        */
+       if (phy_info & IWL_RX_MPDU_PHY_AMPDU &&
+           (status & IWL_RX_MPDU_STATUS_SEC_MASK) ==
+           IWL_RX_MPDU_STATUS_SEC_UNKNOWN && !mvm->monitor_on)
+               return -1;
+
        if (!ieee80211_has_protected(hdr->frame_control) ||
            (status & IWL_RX_MPDU_STATUS_SEC_MASK) ==
            IWL_RX_MPDU_STATUS_SEC_NONE)
@@ -870,7 +882,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
 
        rx_status = IEEE80211_SKB_RXCB(skb);
 
-       if (iwl_mvm_rx_crypto(mvm, hdr, rx_status, desc,
+       if (iwl_mvm_rx_crypto(mvm, hdr, rx_status, phy_info, desc,
                              le32_to_cpu(pkt->len_n_flags), queue,
                              &crypt_len)) {
                kfree_skb(skb);