aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c39
1 files changed, 9 insertions, 30 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index c8166adcd600..10bbbd33b314 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -228,7 +228,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
228{ 228{
229 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(origskb); 229 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(origskb);
230 struct ieee80211_sub_if_data *sdata; 230 struct ieee80211_sub_if_data *sdata;
231 int needed_headroom = 0; 231 int needed_headroom;
232 struct sk_buff *skb, *skb2; 232 struct sk_buff *skb, *skb2;
233 struct net_device *prev_dev = NULL; 233 struct net_device *prev_dev = NULL;
234 int present_fcs_len = 0; 234 int present_fcs_len = 0;
@@ -2544,16 +2544,10 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
2544{ 2544{
2545 struct ieee80211_sub_if_data *sdata; 2545 struct ieee80211_sub_if_data *sdata;
2546 struct ieee80211_local *local = rx->local; 2546 struct ieee80211_local *local = rx->local;
2547 struct ieee80211_rtap_hdr {
2548 struct ieee80211_radiotap_header hdr;
2549 u8 flags;
2550 u8 rate_or_pad;
2551 __le16 chan_freq;
2552 __le16 chan_flags;
2553 } __packed *rthdr;
2554 struct sk_buff *skb = rx->skb, *skb2; 2547 struct sk_buff *skb = rx->skb, *skb2;
2555 struct net_device *prev_dev = NULL; 2548 struct net_device *prev_dev = NULL;
2556 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 2549 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
2550 int needed_headroom;
2557 2551
2558 /* 2552 /*
2559 * If cooked monitor has been processed already, then 2553 * If cooked monitor has been processed already, then
@@ -2567,30 +2561,15 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
2567 if (!local->cooked_mntrs) 2561 if (!local->cooked_mntrs)
2568 goto out_free_skb; 2562 goto out_free_skb;
2569 2563
2570 if (skb_headroom(skb) < sizeof(*rthdr) && 2564 /* room for the radiotap header based on driver features */
2571 pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) 2565 needed_headroom = ieee80211_rx_radiotap_len(local, status);
2572 goto out_free_skb;
2573
2574 rthdr = (void *)skb_push(skb, sizeof(*rthdr));
2575 memset(rthdr, 0, sizeof(*rthdr));
2576 rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr));
2577 rthdr->hdr.it_present =
2578 cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
2579 (1 << IEEE80211_RADIOTAP_CHANNEL));
2580 2566
2581 if (rate) { 2567 if (skb_headroom(skb) < needed_headroom &&
2582 rthdr->rate_or_pad = rate->bitrate / 5; 2568 pskb_expand_head(skb, needed_headroom, 0, GFP_ATOMIC))
2583 rthdr->hdr.it_present |= 2569 goto out_free_skb;
2584 cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE);
2585 }
2586 rthdr->chan_freq = cpu_to_le16(status->freq);
2587 2570
2588 if (status->band == IEEE80211_BAND_5GHZ) 2571 /* prepend radiotap information */
2589 rthdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_OFDM | 2572 ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom);
2590 IEEE80211_CHAN_5GHZ);
2591 else
2592 rthdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_DYN |
2593 IEEE80211_CHAN_2GHZ);
2594 2573
2595 skb_set_mac_header(skb, 0); 2574 skb_set_mac_header(skb, 0);
2596 skb->ip_summed = CHECKSUM_UNNECESSARY; 2575 skb->ip_summed = CHECKSUM_UNNECESSARY;