aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2010-01-16 19:47:59 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-01-19 16:25:21 -0500
commitc6fcf6bcfc3cfc1c00cc7fd9610cfa2b1a18041f (patch)
tree301713d3f65f3cc9cb99e374c655d6f8bf99c741 /net
parent813d76694043d00b59475baa1fbfaf54a2eb7fad (diff)
mac80211: re-enable re-transmission of filtered frames
In an earlier commit, mac80211: disable software retry for now Pavel Roskin reported a problem that seems to be due to software retry of already transmitted frames. It turns out that we've never done that correctly, but due to some recent changes it now crashes in the TX code. I've added a comment in the patch that explains the problem better and also points to possible solutions -- which I can't implement right now. I disabled software retry of failed/filtered frames because it was broken. With the work of the previous patches, it now becomes fairly easy to re-enable it by adding a flag indicating that the frame shouldn't be modified, but still running it through the transmit handlers to populate the control information. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/status.c32
-rw-r--r--net/mac80211/tx.c7
2 files changed, 11 insertions, 28 deletions
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,
1285static int invoke_tx_handlers(struct ieee80211_tx_data *tx) 1285static 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! */