From f75f5c6f61b4d34bf92625fcd1131dd58921e1b5 Mon Sep 17 00:00:00 2001 From: Helmut Schaa Date: Mon, 1 Aug 2011 11:32:52 +0200 Subject: [PATCH] mac80211: Fill in skb->protocol information for injected frames Some drivers (ath9k for example) are using skb->protocol to treat EAPOL frames somehow special (disallow aggregation for example). When running in AP mode hostapd injects the EAPOL frames through a monitor interface and thus skb->protocol isn't set at all. Hence, if the injected frame is a data frame and carries a rfc1042 headaer update the skb->protocol field accordingly. Signed-off-by: Helmut Schaa Signed-off-by: John W. Linville --- net/mac80211/tx.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 8cb0d2d0ac6..69fd494f32f 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1608,7 +1608,9 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, struct ieee80211_radiotap_header *prthdr = (struct ieee80211_radiotap_header *)skb->data; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr; u16 len_rthdr; + u8 *payload; /* * Frame injection is not allowed if beaconing is not allowed @@ -1659,6 +1661,24 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, skb_set_network_header(skb, len_rthdr); skb_set_transport_header(skb, len_rthdr); + /* + * Initialize skb->protocol if the injected frame is a data frame + * carrying a rfc1042 header + */ + if (skb->len > len_rthdr + 2) { + hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr); + if (ieee80211_is_data(hdr->frame_control) && + skb->len >= len_rthdr + + ieee80211_hdrlen(hdr->frame_control) + + sizeof(rfc1042_header) + 2) { + payload = (u8 *)hdr + + ieee80211_hdrlen(hdr->frame_control); + if (compare_ether_addr(payload, rfc1042_header) == 0) + skb->protocol = cpu_to_be16((payload[6] << 8) | + payload[7]); + } + } + memset(info, 0, sizeof(*info)); info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; -- 2.43.2