Search Linux Wireless

[PATCH] mac80211: Fix frame classification in AP mode for relayed frames

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When mac80211 relays a frame from STA1 to STA2 in AP mode it will get
re-classified in the tx path. Unfortunately the frame protocol field
is always set to ETH_P_8023 while the classification only kicks in
for ETH_P_IP. Hence, a high priority frame from STA1 will be send to
STA2 as best effort.

To allow proper re-classification of received frames, set the
skb->protocol field to the correct value without using eth_type_trans
as that would pull of the ethernet header. Also, set the network
header position correctly as otherwise the classification code won't
find the IP header.

This means that every frame relayed by a mac80211 AP will be
re-classified and might change its traffic class when the associated
STA and mac80211 use different 802.1d <-> TID mappings.

Signed-off-by: Helmut Schaa <helmut.schaa@xxxxxxxxxxxxxx>
---

We could also reuse the TID used by the source STA but I guess we should
always classify frames according to our own mapping instead of relying
on the associated STAs to do the right thing.

 net/mac80211/rx.c |   19 ++++++++++++++++---
 1 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index bf07d08..8418f66 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1827,10 +1827,23 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
 	}
 
 	if (xmit_skb) {
-		/* send to wireless media */
-		xmit_skb->protocol = htons(ETH_P_802_3);
-		skb_reset_network_header(xmit_skb);
+		/*
+		 * Send to wireless media
+		 *
+		 * Set protocol field according to the ethernet header
+		 * to allow reclassification of this frame in the tx path.
+		 *
+		 * Don't use eth_type_trans here since it will pull the
+		 * eth header and because we are sure to have an ethernet
+		 * header here.
+		 */
+		ehdr = (struct ethhdr *) xmit_skb->data;
+		if (ntohs(ehdr->h_proto) >= 1536)
+			xmit_skb->protocol = ehdr->h_proto;
+		else
+			xmit_skb->protocol = htons(ETH_P_802_3);
 		skb_reset_mac_header(xmit_skb);
+		skb_set_network_header(xmit_skb, sizeof(struct ethhdr));
 		dev_queue_xmit(xmit_skb);
 	}
 }
-- 
1.7.7

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux