summaryrefslogtreecommitdiff
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
authorThomas Pedersen <thomas@cozybit.com>2011-11-03 21:11:11 -0700
committerJohn W. Linville <linville@tuxdriver.com>2011-11-09 16:05:48 -0500
commit6cc00d545a21ed26696f3bda865ebf11eccbf2b5 (patch)
treee048b70728f9fcb8dac02b72b421c037d03c1e5d /net/mac80211/rx.c
parentf3011cf9deb689bd68279c728c501a4166983c19 (diff)
mac80211: QoS multicast frames have No Ack policy
Previously QoS multicast frames had the Normal Acknowledgment QoS control bits set. This would cause broadcast frames to be discarded by peers with which we have a BA session, since their sequence number would fall outside the allowed range. Set No Ack QoS control bits on multicast QoS frames and filter these in de-aggregation code. Signed-off-by: Thomas Pedersen <thomas@cozybit.com> v2: Use proper QoS Ack Policy ctl field mask (Christian) v3: Clean up conditional (Johannes) Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 3173dcfc2136..72c1eb4eb451 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -747,7 +747,7 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx)
struct sta_info *sta = rx->sta;
struct tid_ampdu_rx *tid_agg_rx;
u16 sc;
- int tid;
+ u8 tid, ack_policy;
if (!ieee80211_is_data_qos(hdr->frame_control))
goto dont_reorder;
@@ -760,6 +760,8 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx)
if (!sta)
goto dont_reorder;
+ ack_policy = *ieee80211_get_qos_ctl(hdr) &
+ IEEE80211_QOS_CTL_ACK_POLICY_MASK;
tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]);
@@ -770,6 +772,11 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx)
if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC)))
goto dont_reorder;
+ /* not part of a BA session */
+ if (ack_policy != IEEE80211_QOS_CTL_ACK_POLICY_BLOCKACK &&
+ ack_policy != IEEE80211_QOS_CTL_ACK_POLICY_NORMAL)
+ goto dont_reorder;
+
/* new, potentially un-ordered, ampdu frame - process it */
/* reset session timer */