* [PATCH v4 2/4] mac80211: QoS multicast frames have No Ack policy
2011-11-04 4:11 [PATCH v4 1/4] mac80211: Avoid filling up mesh preq queue with redundant requests Thomas Pedersen
@ 2011-11-04 4:11 ` Thomas Pedersen
2011-11-04 4:11 ` [PATCH v4 3/4] mac80211: check if frame is really part of this BA Thomas Pedersen
2011-11-04 4:11 ` [PATCH v4 4/4] mac80211: simplify mesh frame queue mapping and QoS Thomas Pedersen
2 siblings, 0 replies; 4+ messages in thread
From: Thomas Pedersen @ 2011-11-04 4:11 UTC (permalink / raw)
To: linux-wireless; +Cc: Thomas Pedersen, johannes, linville
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)
---
include/linux/ieee80211.h | 1 +
net/mac80211/rx.c | 9 ++++++++-
net/mac80211/wme.c | 3 ++-
3 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 48363c3..bc61e69 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -128,6 +128,7 @@
#define IEEE80211_QOS_CTL_ACK_POLICY_NOACK 0x0020
#define IEEE80211_QOS_CTL_ACK_POLICY_NO_EXPL 0x0040
#define IEEE80211_QOS_CTL_ACK_POLICY_BLOCKACK 0x0060
+#define IEEE80211_QOS_CTL_ACK_POLICY_MASK 0x0060
/* A-MSDU 802.11n */
#define IEEE80211_QOS_CTL_A_MSDU_PRESENT 0x0080
/* Mesh Control 802.11s */
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index b867bd5..bbe7b50 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 */
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index fd52e69..a440a4a 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -147,7 +147,8 @@ void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata,
tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
- if (unlikely(sdata->local->wifi_wme_noack_test))
+ if (unlikely(sdata->local->wifi_wme_noack_test) ||
+ is_multicast_ether_addr(hdr->addr1))
ack_policy |= IEEE80211_QOS_CTL_ACK_POLICY_NOACK;
/* qos header is 2 bytes */
*p++ = ack_policy | tid;
--
1.7.5.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v4 3/4] mac80211: check if frame is really part of this BA
2011-11-04 4:11 [PATCH v4 1/4] mac80211: Avoid filling up mesh preq queue with redundant requests Thomas Pedersen
2011-11-04 4:11 ` [PATCH v4 2/4] mac80211: QoS multicast frames have No Ack policy Thomas Pedersen
@ 2011-11-04 4:11 ` Thomas Pedersen
2011-11-04 4:11 ` [PATCH v4 4/4] mac80211: simplify mesh frame queue mapping and QoS Thomas Pedersen
2 siblings, 0 replies; 4+ messages in thread
From: Thomas Pedersen @ 2011-11-04 4:11 UTC (permalink / raw)
To: linux-wireless; +Cc: Thomas Pedersen, johannes, linville
There was an an implicit assumption that any QoS data frame received
from a STA/TID with an active BA session was sent to this vif as part of
a BA. This is not true if IFF_PROMISC is enabled and the frame was
destined for a different peer, for example. Don't treat these frames as
part of a BA from the sending STA.
Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
---
v3: use RX_RA_MATCH instead of checking the address directly (Johannes)
net/mac80211/rx.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index bbe7b50..45ace14 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -744,6 +744,7 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx)
struct ieee80211_local *local = rx->local;
struct ieee80211_hw *hw = &local->hw;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
struct sta_info *sta = rx->sta;
struct tid_ampdu_rx *tid_agg_rx;
u16 sc;
@@ -777,6 +778,10 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx)
ack_policy != IEEE80211_QOS_CTL_ACK_POLICY_NORMAL)
goto dont_reorder;
+ /* not actually part of this BA session */
+ if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
+ goto dont_reorder;
+
/* new, potentially un-ordered, ampdu frame - process it */
/* reset session timer */
--
1.7.5.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v4 4/4] mac80211: simplify mesh frame queue mapping and QoS
2011-11-04 4:11 [PATCH v4 1/4] mac80211: Avoid filling up mesh preq queue with redundant requests Thomas Pedersen
2011-11-04 4:11 ` [PATCH v4 2/4] mac80211: QoS multicast frames have No Ack policy Thomas Pedersen
2011-11-04 4:11 ` [PATCH v4 3/4] mac80211: check if frame is really part of this BA Thomas Pedersen
@ 2011-11-04 4:11 ` Thomas Pedersen
2 siblings, 0 replies; 4+ messages in thread
From: Thomas Pedersen @ 2011-11-04 4:11 UTC (permalink / raw)
To: linux-wireless; +Cc: Javier Cardona, Thomas Pedersen, johannes, linville
From: Javier Cardona <javier@cozybit.com>
We only need to set the skb queue twice:
1. by the netdev, on local TX.
2. when forwarding a mesh frame.
We only need to set the qos header twice:
1. by mac80211, on local TX.
2. when putting a frame on the mpath->frame_queue
We also don't need the RA in order to set the proper queue mapping since
all mesh STAs are QoS, indicate this and do it once when the frame is
received. Also fixes an issue where the QoS header and queue mapping was not
set for unicast forwarded frames.
Signed-off-by: Javier Cardona <javier@cozybit.com>
Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
---
v4: simplify skb_set_queue and set_qos_hdr calls (Thomas)
I'm sneaking this revision in since John hasn't applied these yet. Sorry for
any inconvenince, but I figured this would be better than submitting a
different patch later which reverts 80% of v3. These
changes take this patch from 14 insertions(+), 4 deletions(-) to:
net/mac80211/mesh_hwmp.c | 1 +
net/mac80211/mesh_pathtbl.c | 3 ---
net/mac80211/rx.c | 5 ++---
net/mac80211/wme.c | 2 +-
4 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index b22b223..a7afb2d 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -1043,6 +1043,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
skb_to_free = skb_dequeue(&mpath->frame_queue);
info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
+ ieee80211_set_qos_hdr(sdata, skb);
skb_queue_tail(&mpath->frame_queue, skb);
if (skb_to_free)
mesh_path_discard_frame(skb_to_free, sdata);
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 332b5ff1..a861652 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -213,7 +213,6 @@ void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta)
struct ieee80211_hdr *hdr;
struct sk_buff_head tmpq;
unsigned long flags;
- struct ieee80211_sub_if_data *sdata = mpath->sdata;
rcu_assign_pointer(mpath->next_hop, sta);
@@ -224,8 +223,6 @@ void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta)
while ((skb = __skb_dequeue(&mpath->frame_queue)) != NULL) {
hdr = (struct ieee80211_hdr *) skb->data;
memcpy(hdr->addr1, sta->sta.addr, ETH_ALEN);
- skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, skb));
- ieee80211_set_qos_hdr(sdata, skb);
__skb_queue_tail(&tmpq, skb);
}
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 45ace14..8f11888 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1941,6 +1941,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
compare_ether_addr(sdata->vif.addr, hdr->addr3) == 0)
return RX_CONTINUE;
+ skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, skb));
mesh_hdr->ttl--;
if (status->rx_flags & IEEE80211_RX_RA_MATCH) {
@@ -1965,12 +1966,10 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
memset(info, 0, sizeof(*info));
info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
info->control.vif = &rx->sdata->vif;
+ info->control.jiffies = jiffies;
if (is_multicast_ether_addr(fwd_hdr->addr1)) {
IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
fwded_mcast);
- skb_set_queue_mapping(fwd_skb,
- ieee80211_select_queue(sdata, fwd_skb));
- ieee80211_set_qos_hdr(sdata, fwd_skb);
} else {
int err;
/*
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index a440a4a..c6c5ee8 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -83,7 +83,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
break;
#ifdef CONFIG_MAC80211_MESH
case NL80211_IFTYPE_MESH_POINT:
- ra = skb->data;
+ qos = true;
break;
#endif
case NL80211_IFTYPE_STATION:
--
1.7.5.4
^ permalink raw reply related [flat|nested] 4+ messages in thread