diff options
author | Felix Fietkau <nbd@openwrt.org> | 2010-01-31 15:56:25 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-02-01 15:40:08 -0500 |
commit | 17ad353b8d9843731258b5d23556667b764939e9 (patch) | |
tree | 26c84253888ded3b008c7b1d8c29763646b673bf /net/mac80211 | |
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')
-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 14c70452c245..e7b1cdc7651b 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1108,7 +1108,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, | |||
1108 | tx->flags |= IEEE80211_TX_FRAGMENTED; | 1108 | tx->flags |= IEEE80211_TX_FRAGMENTED; |
1109 | 1109 | ||
1110 | /* process and remove the injection radiotap header */ | 1110 | /* process and remove the injection radiotap header */ |
1111 | if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) { | 1111 | if (unlikely(info->flags & IEEE80211_TX_INTFL_HAS_RADIOTAP)) { |
1112 | if (!__ieee80211_parse_tx_radiotap(tx, skb)) | 1112 | if (!__ieee80211_parse_tx_radiotap(tx, skb)) |
1113 | return TX_DROP; | 1113 | return TX_DROP; |
1114 | 1114 | ||
@@ -1117,6 +1117,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, | |||
1117 | * the radiotap header that was present and pre-filled | 1117 | * the radiotap header that was present and pre-filled |
1118 | * 'tx' with tx control information. | 1118 | * 'tx' with tx control information. |
1119 | */ | 1119 | */ |
1120 | info->flags &= ~IEEE80211_TX_INTFL_HAS_RADIOTAP; | ||
1120 | } | 1121 | } |
1121 | 1122 | ||
1122 | /* | 1123 | /* |
@@ -1499,7 +1500,8 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1499 | int hdrlen; | 1500 | int hdrlen; |
1500 | u16 len_rthdr; | 1501 | u16 len_rthdr; |
1501 | 1502 | ||
1502 | info->flags |= IEEE80211_TX_CTL_INJECTED; | 1503 | info->flags |= IEEE80211_TX_CTL_INJECTED | |
1504 | IEEE80211_TX_INTFL_HAS_RADIOTAP; | ||
1503 | 1505 | ||
1504 | len_rthdr = ieee80211_get_radiotap_len(skb->data); | 1506 | len_rthdr = ieee80211_get_radiotap_len(skb->data); |
1505 | hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr); | 1507 | hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr); |