]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blobdiff - net/mac80211/rx.c
mac80211: use driver-indicated transmitter STA only for data frames
[mirror_ubuntu-zesty-kernel.git] / net / mac80211 / rx.c
index 3090dd4342f6eee6f2d3bdba67493849622ac1a7..1109e60e9121c00b729b4ae95d5d27261f60df85 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
  * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
  * Copyright 2013-2014  Intel Mobile Communications GmbH
- * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
+ * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -1034,6 +1034,18 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata
        buf_size = tid_agg_rx->buf_size;
        head_seq_num = tid_agg_rx->head_seq_num;
 
+       /*
+        * If the current MPDU's SN is smaller than the SSN, it shouldn't
+        * be reordered.
+        */
+       if (unlikely(!tid_agg_rx->started)) {
+               if (ieee80211_sn_less(mpdu_seq_num, head_seq_num)) {
+                       ret = false;
+                       goto out;
+               }
+               tid_agg_rx->started = true;
+       }
+
        /* frame with out of date sequence number */
        if (ieee80211_sn_less(mpdu_seq_num, head_seq_num)) {
                dev_kfree_skb(skb);
@@ -4077,15 +4089,17 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
                     ieee80211_is_beacon(hdr->frame_control)))
                ieee80211_scan_rx(local, skb);
 
-       if (pubsta) {
-               rx.sta = container_of(pubsta, struct sta_info, sta);
-               rx.sdata = rx.sta->sdata;
-               if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
-                       return;
-               goto out;
-       } else if (ieee80211_is_data(fc)) {
+       if (ieee80211_is_data(fc)) {
                struct sta_info *sta, *prev_sta;
 
+               if (pubsta) {
+                       rx.sta = container_of(pubsta, struct sta_info, sta);
+                       rx.sdata = rx.sta->sdata;
+                       if (ieee80211_prepare_and_rx_handle(&rx, skb, true))
+                               return;
+                       goto out;
+               }
+
                prev_sta = NULL;
 
                for_each_sta_info(local, hdr->addr2, sta, tmp) {