diff options
-rw-r--r-- | include/net/mac80211.h | 4 | ||||
-rw-r--r-- | net/mac80211/status.c | 32 | ||||
-rw-r--r-- | net/mac80211/tx.c | 7 |
3 files changed, 15 insertions, 28 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index c90047de4428..f03f97b627fe 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -271,6 +271,9 @@ struct ieee80211_bss_conf { | |||
271 | * transmit function after the current frame, this can be used | 271 | * transmit function after the current frame, this can be used |
272 | * by drivers to kick the DMA queue only if unset or when the | 272 | * by drivers to kick the DMA queue only if unset or when the |
273 | * queue gets full. | 273 | * queue gets full. |
274 | * @IEEE80211_TX_INTFL_RETRANSMISSION: This frame is being retransmitted | ||
275 | * after TX status because the destination was asleep, it must not | ||
276 | * be modified again (no seqno assignment, crypto, etc.) | ||
274 | */ | 277 | */ |
275 | enum mac80211_tx_control_flags { | 278 | enum mac80211_tx_control_flags { |
276 | IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0), | 279 | IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0), |
@@ -291,6 +294,7 @@ enum mac80211_tx_control_flags { | |||
291 | IEEE80211_TX_INTFL_DONT_ENCRYPT = BIT(16), | 294 | IEEE80211_TX_INTFL_DONT_ENCRYPT = BIT(16), |
292 | IEEE80211_TX_CTL_PSPOLL_RESPONSE = BIT(17), | 295 | IEEE80211_TX_CTL_PSPOLL_RESPONSE = BIT(17), |
293 | IEEE80211_TX_CTL_MORE_FRAMES = BIT(18), | 296 | IEEE80211_TX_CTL_MORE_FRAMES = BIT(18), |
297 | IEEE80211_TX_INTFL_RETRANSMISSION = BIT(19), | ||
294 | }; | 298 | }; |
295 | 299 | ||
296 | /** | 300 | /** |
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 9e171b178276..800b6777e0ed 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -45,37 +45,16 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
45 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 45 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
46 | 46 | ||
47 | /* | 47 | /* |
48 | * XXX: This is temporary! | ||
49 | * | ||
50 | * The problem here is that when we get here, the driver will | ||
51 | * quite likely have pretty much overwritten info->control by | ||
52 | * using info->driver_data or info->rate_driver_data. Thus, | ||
53 | * when passing out the frame to the driver again, we would be | ||
54 | * passing completely bogus data since the driver would then | ||
55 | * expect a properly filled info->control. In mac80211 itself | ||
56 | * the same problem occurs, since we need info->control.vif | ||
57 | * internally. | ||
58 | * | ||
59 | * To fix this, we should send the frame through TX processing | ||
60 | * again. However, it's not that simple, since the frame will | ||
61 | * have been software-encrypted (if applicable) already, and | ||
62 | * encrypting it again doesn't do much good. So to properly do | ||
63 | * that, we not only have to skip the actual 'raw' encryption | ||
64 | * (key selection etc. still has to be done!) but also the | ||
65 | * sequence number assignment since that impacts the crypto | ||
66 | * encapsulation, of course. | ||
67 | * | ||
68 | * Hence, for now, fix the bug by just dropping the frame. | ||
69 | */ | ||
70 | goto drop; | ||
71 | |||
72 | /* | ||
73 | * This skb 'survived' a round-trip through the driver, and | 48 | * This skb 'survived' a round-trip through the driver, and |
74 | * hopefully the driver didn't mangle it too badly. However, | 49 | * hopefully the driver didn't mangle it too badly. However, |
75 | * we can definitely not rely on the the control information | 50 | * we can definitely not rely on the the control information |
76 | * being correct. Clear it so we don't get junk there. | 51 | * being correct. Clear it so we don't get junk there, and |
52 | * indicate that it needs new processing, but must not be | ||
53 | * modified/encrypted again. | ||
77 | */ | 54 | */ |
78 | memset(&info->control, 0, sizeof(info->control)); | 55 | memset(&info->control, 0, sizeof(info->control)); |
56 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING | | ||
57 | IEEE80211_TX_INTFL_RETRANSMISSION; | ||
79 | 58 | ||
80 | sta->tx_filtered_count++; | 59 | sta->tx_filtered_count++; |
81 | 60 | ||
@@ -130,7 +109,6 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
130 | return; | 109 | return; |
131 | } | 110 | } |
132 | 111 | ||
133 | drop: | ||
134 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 112 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
135 | if (net_ratelimit()) | 113 | if (net_ratelimit()) |
136 | printk(KERN_DEBUG "%s: dropped TX filtered frame, " | 114 | printk(KERN_DEBUG "%s: dropped TX filtered frame, " |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index e3d8ff533ee6..da557b0d0114 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1285,6 +1285,7 @@ static int __ieee80211_tx(struct ieee80211_local *local, | |||
1285 | static int invoke_tx_handlers(struct ieee80211_tx_data *tx) | 1285 | static int invoke_tx_handlers(struct ieee80211_tx_data *tx) |
1286 | { | 1286 | { |
1287 | struct sk_buff *skb = tx->skb; | 1287 | struct sk_buff *skb = tx->skb; |
1288 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1288 | ieee80211_tx_result res = TX_DROP; | 1289 | ieee80211_tx_result res = TX_DROP; |
1289 | 1290 | ||
1290 | #define CALL_TXH(txh) \ | 1291 | #define CALL_TXH(txh) \ |
@@ -1299,9 +1300,13 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) | |||
1299 | CALL_TXH(ieee80211_tx_h_ps_buf); | 1300 | CALL_TXH(ieee80211_tx_h_ps_buf); |
1300 | CALL_TXH(ieee80211_tx_h_select_key); | 1301 | CALL_TXH(ieee80211_tx_h_select_key); |
1301 | CALL_TXH(ieee80211_tx_h_sta); | 1302 | CALL_TXH(ieee80211_tx_h_sta); |
1302 | CALL_TXH(ieee80211_tx_h_michael_mic_add); | ||
1303 | if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)) | 1303 | if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)) |
1304 | CALL_TXH(ieee80211_tx_h_rate_ctrl); | 1304 | CALL_TXH(ieee80211_tx_h_rate_ctrl); |
1305 | |||
1306 | if (unlikely(info->flags & IEEE80211_TX_INTFL_RETRANSMISSION)) | ||
1307 | goto txh_done; | ||
1308 | |||
1309 | CALL_TXH(ieee80211_tx_h_michael_mic_add); | ||
1305 | CALL_TXH(ieee80211_tx_h_sequence); | 1310 | CALL_TXH(ieee80211_tx_h_sequence); |
1306 | CALL_TXH(ieee80211_tx_h_fragment); | 1311 | CALL_TXH(ieee80211_tx_h_fragment); |
1307 | /* handlers after fragment must be aware of tx info fragmentation! */ | 1312 | /* handlers after fragment must be aware of tx info fragmentation! */ |