]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/mac80211/tx.c
mac80211: 802.11w - CCMP for management frames
[karo-tx-linux.git] / net / mac80211 / tx.c
index cd6bc87eec737eddb1bc01a69d51c65a773d6fdc..50c6c4fabea51d8f81d1f5fa030a3f2be0eef1bc 100644 (file)
@@ -330,6 +330,22 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)
        return TX_CONTINUE;
 }
 
+static int ieee80211_use_mfp(__le16 fc, struct sta_info *sta,
+                            struct sk_buff *skb)
+{
+       if (!ieee80211_is_mgmt(fc))
+               return 0;
+
+       if (sta == NULL || !test_sta_flags(sta, WLAN_STA_MFP))
+               return 0;
+
+       if (!ieee80211_is_robust_mgmt_frame((struct ieee80211_hdr *)
+                                           skb->data))
+               return 0;
+
+       return 1;
+}
+
 static ieee80211_tx_result
 ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
 {
@@ -428,10 +444,15 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
                        if (ieee80211_is_auth(hdr->frame_control))
                                break;
                case ALG_TKIP:
-               case ALG_CCMP:
                        if (!ieee80211_is_data_present(hdr->frame_control))
                                tx->key = NULL;
                        break;
+               case ALG_CCMP:
+                       if (!ieee80211_is_data_present(hdr->frame_control) &&
+                           !ieee80211_use_mfp(hdr->frame_control, tx->sta,
+                                              tx->skb))
+                               tx->key = NULL;
+                       break;
                }
        }