diff options
author | Felix Fietkau <nbd@openwrt.org> | 2010-01-31 21:56:25 +0100 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-02-01 15:40:08 -0500 |
commit | 17ad353b8d9843731258b5d23556667b764939e9 (patch) | |
tree | 26c84253888ded3b008c7b1d8c29763646b673bf /net/mac80211/tx.c | |
parent | 4754ffd68bc14de8db01451c49bb07adebe1e422 (diff) |
mac80211: fix monitor mode tx radiotap header handling
When an injected frame gets buffered for a powersave STA or filtered
and retransmitted, mac80211 attempts to parse the radiotap header
again, which doesn't work because it's gone at that point.
This patch adds a new flag for checking the availability of a radiotap
header, so that it only attempts to parse it once, reusing the tx info
on the next call to ieee80211_tx().
This fixes severe issues with rekeying in AP mode.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Cc: stable@kernel.org
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r-- | net/mac80211/tx.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 14c70452c24..e7b1cdc7651 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1108,7 +1108,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, tx->flags |= IEEE80211_TX_FRAGMENTED; /* process and remove the injection radiotap header */ - if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) { + if (unlikely(info->flags & IEEE80211_TX_INTFL_HAS_RADIOTAP)) { if (!__ieee80211_parse_tx_radiotap(tx, skb)) return TX_DROP; @@ -1117,6 +1117,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, * the radiotap header that was present and pre-filled * 'tx' with tx control information. */ + info->flags &= ~IEEE80211_TX_INTFL_HAS_RADIOTAP; } /* @@ -1499,7 +1500,8 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, int hdrlen; u16 len_rthdr; - info->flags |= IEEE80211_TX_CTL_INJECTED; + info->flags |= IEEE80211_TX_CTL_INJECTED | + IEEE80211_TX_INTFL_HAS_RADIOTAP; len_rthdr = ieee80211_get_radiotap_len(skb->data); hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr); |