Commit d0f09804144fd9471a13cf4d80e66842c7fa114f
Committed by
John W. Linville
1 parent
0ccd58fc03
Exists in
master
and in
7 other branches
mac80211: partially fix skb->cb use
This patch fixes mac80211 to not use the skb->cb over the queue step from virtual interfaces to the master. The patch also, for now, disables aggregation because that would still require requeuing, will fix that in a separate patch. There are two other places (software requeue and powersaving stations) where requeue can happen, but that is not currently used by any drivers/not possible to use respectively. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Showing 13 changed files with 40 additions and 52 deletions Side-by-side Diff
- drivers/net/wireless/ath5k/base.c
- drivers/net/wireless/b43/xmit.c
- drivers/net/wireless/b43legacy/xmit.c
- drivers/net/wireless/iwlwifi/iwl-tx.c
- drivers/net/wireless/iwlwifi/iwl3945-base.c
- drivers/net/wireless/rt2x00/rt2x00mac.c
- include/linux/skbuff.h
- include/net/mac80211.h
- net/core/skbuff.c
- net/mac80211/main.c
- net/mac80211/mlme.c
- net/mac80211/tx.c
- net/mac80211/wme.c
drivers/net/wireless/ath5k/base.c
drivers/net/wireless/b43/xmit.c
... | ... | @@ -192,7 +192,7 @@ |
192 | 192 | const struct b43_phy *phy = &dev->phy; |
193 | 193 | const struct ieee80211_hdr *wlhdr = |
194 | 194 | (const struct ieee80211_hdr *)fragment_data; |
195 | - int use_encryption = (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT)); | |
195 | + int use_encryption = !!info->control.hw_key; | |
196 | 196 | __le16 fctl = wlhdr->frame_control; |
197 | 197 | struct ieee80211_rate *fbrate; |
198 | 198 | u8 rate, rate_fb; |
drivers/net/wireless/b43legacy/xmit.c
... | ... | @@ -192,7 +192,7 @@ |
192 | 192 | u16 cookie) |
193 | 193 | { |
194 | 194 | const struct ieee80211_hdr *wlhdr; |
195 | - int use_encryption = (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT)); | |
195 | + int use_encryption = !!info->control.hw_key; | |
196 | 196 | u16 fctl; |
197 | 197 | u8 rate; |
198 | 198 | struct ieee80211_rate *rate_fb; |
drivers/net/wireless/iwlwifi/iwl-tx.c
... | ... | @@ -906,7 +906,7 @@ |
906 | 906 | * first entry */ |
907 | 907 | iwl_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len); |
908 | 908 | |
909 | - if (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT)) | |
909 | + if (info->control.hw_key) | |
910 | 910 | iwl_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id); |
911 | 911 | |
912 | 912 | /* Set up TFD's 2nd entry to point directly to remainder of skb, |
drivers/net/wireless/iwlwifi/iwl3945-base.c
... | ... | @@ -2667,7 +2667,7 @@ |
2667 | 2667 | * first entry */ |
2668 | 2668 | iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len); |
2669 | 2669 | |
2670 | - if (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT)) | |
2670 | + if (info->control.hw_key) | |
2671 | 2671 | iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, 0); |
2672 | 2672 | |
2673 | 2673 | /* Set up TFD's 2nd entry to point directly to remainder of skb, |
drivers/net/wireless/rt2x00/rt2x00mac.c
... | ... | @@ -63,7 +63,7 @@ |
63 | 63 | */ |
64 | 64 | memcpy(skb->cb, frag_skb->cb, sizeof(skb->cb)); |
65 | 65 | rts_info = IEEE80211_SKB_CB(skb); |
66 | - rts_info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; | |
66 | + rts_info->control.hw_key = NULL; | |
67 | 67 | rts_info->flags &= ~IEEE80211_TX_CTL_USE_RTS_CTS; |
68 | 68 | rts_info->flags &= ~IEEE80211_TX_CTL_USE_CTS_PROTECT; |
69 | 69 | rts_info->flags &= ~IEEE80211_TX_CTL_REQ_TX_STATUS; |
include/linux/skbuff.h
... | ... | @@ -316,7 +316,10 @@ |
316 | 316 | #ifdef CONFIG_IPV6_NDISC_NODETYPE |
317 | 317 | __u8 ndisc_nodetype:2; |
318 | 318 | #endif |
319 | - /* 14 bit hole */ | |
319 | +#if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE) | |
320 | + __u8 do_not_encrypt:1; | |
321 | +#endif | |
322 | + /* 0/13/14 bit hole */ | |
320 | 323 | |
321 | 324 | #ifdef CONFIG_NET_DMA |
322 | 325 | dma_cookie_t dma_cookie; |
include/net/mac80211.h
... | ... | @@ -206,8 +206,6 @@ |
206 | 206 | * These flags are used with the @flags member of &ieee80211_tx_info. |
207 | 207 | * |
208 | 208 | * @IEEE80211_TX_CTL_REQ_TX_STATUS: request TX status callback for this frame. |
209 | - * @IEEE80211_TX_CTL_DO_NOT_ENCRYPT: send this frame without encryption; | |
210 | - * e.g., for EAPOL frame | |
211 | 209 | * @IEEE80211_TX_CTL_USE_RTS_CTS: use RTS-CTS before sending frame |
212 | 210 | * @IEEE80211_TX_CTL_USE_CTS_PROTECT: use CTS protection for the frame (e.g., |
213 | 211 | * for combined 802.11g / 802.11b networks) |
... | ... | @@ -220,7 +218,6 @@ |
220 | 218 | * @IEEE80211_TX_CTL_SHORT_PREAMBLE: TBD |
221 | 219 | * @IEEE80211_TX_CTL_LONG_RETRY_LIMIT: this frame should be send using the |
222 | 220 | * through set_retry_limit configured long retry value |
223 | - * @IEEE80211_TX_CTL_EAPOL_FRAME: internal to mac80211 | |
224 | 221 | * @IEEE80211_TX_CTL_SEND_AFTER_DTIM: send this frame after DTIM beacon |
225 | 222 | * @IEEE80211_TX_CTL_AMPDU: this frame should be sent as part of an A-MPDU |
226 | 223 | * @IEEE80211_TX_CTL_OFDM_HT: this frame can be sent in HT OFDM rates. number |
... | ... | @@ -253,7 +250,6 @@ |
253 | 250 | */ |
254 | 251 | enum mac80211_tx_control_flags { |
255 | 252 | IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0), |
256 | - IEEE80211_TX_CTL_DO_NOT_ENCRYPT = BIT(1), | |
257 | 253 | IEEE80211_TX_CTL_USE_RTS_CTS = BIT(2), |
258 | 254 | IEEE80211_TX_CTL_USE_CTS_PROTECT = BIT(3), |
259 | 255 | IEEE80211_TX_CTL_NO_ACK = BIT(4), |
... | ... | @@ -263,7 +259,6 @@ |
263 | 259 | IEEE80211_TX_CTL_FIRST_FRAGMENT = BIT(8), |
264 | 260 | IEEE80211_TX_CTL_SHORT_PREAMBLE = BIT(9), |
265 | 261 | IEEE80211_TX_CTL_LONG_RETRY_LIMIT = BIT(10), |
266 | - IEEE80211_TX_CTL_EAPOL_FRAME = BIT(11), | |
267 | 262 | IEEE80211_TX_CTL_SEND_AFTER_DTIM = BIT(12), |
268 | 263 | IEEE80211_TX_CTL_AMPDU = BIT(13), |
269 | 264 | IEEE80211_TX_CTL_OFDM_HT = BIT(14), |
... | ... | @@ -323,7 +318,6 @@ |
323 | 318 | struct ieee80211_vif *vif; |
324 | 319 | struct ieee80211_key_conf *hw_key; |
325 | 320 | unsigned long jiffies; |
326 | - int ifindex; | |
327 | 321 | u16 aid; |
328 | 322 | s8 rts_cts_rate_idx, alt_retry_rate_idx; |
329 | 323 | u8 retry_limit; |
net/core/skbuff.c
net/mac80211/main.c
... | ... | @@ -1233,18 +1233,12 @@ |
1233 | 1233 | /* Remove added headers (e.g., QoS control), encryption header/MIC, etc. to |
1234 | 1234 | * make a prepared TX frame (one that has been given to hw) to look like brand |
1235 | 1235 | * new IEEE 802.11 frame that is ready to go through TX processing again. |
1236 | - * Also, tx_packet_data in cb is restored from tx_control. */ | |
1236 | + */ | |
1237 | 1237 | static void ieee80211_remove_tx_extra(struct ieee80211_local *local, |
1238 | 1238 | struct ieee80211_key *key, |
1239 | 1239 | struct sk_buff *skb) |
1240 | 1240 | { |
1241 | 1241 | int hdrlen, iv_len, mic_len; |
1242 | - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | |
1243 | - | |
1244 | - info->flags &= IEEE80211_TX_CTL_REQ_TX_STATUS | | |
1245 | - IEEE80211_TX_CTL_DO_NOT_ENCRYPT | | |
1246 | - IEEE80211_TX_CTL_REQUEUE | | |
1247 | - IEEE80211_TX_CTL_EAPOL_FRAME; | |
1248 | 1242 | |
1249 | 1243 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); |
1250 | 1244 |
net/mac80211/mlme.c
... | ... | @@ -606,7 +606,6 @@ |
606 | 606 | int encrypt) |
607 | 607 | { |
608 | 608 | struct ieee80211_sub_if_data *sdata; |
609 | - struct ieee80211_tx_info *info; | |
610 | 609 | |
611 | 610 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
612 | 611 | skb->dev = sdata->local->mdev; |
... | ... | @@ -614,11 +613,8 @@ |
614 | 613 | skb_set_network_header(skb, 0); |
615 | 614 | skb_set_transport_header(skb, 0); |
616 | 615 | |
617 | - info = IEEE80211_SKB_CB(skb); | |
618 | - memset(info, 0, sizeof(struct ieee80211_tx_info)); | |
619 | - info->control.ifindex = sdata->dev->ifindex; | |
620 | - if (!encrypt) | |
621 | - info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; | |
616 | + skb->iif = sdata->dev->ifindex; | |
617 | + skb->do_not_encrypt = !encrypt; | |
622 | 618 | |
623 | 619 | dev_queue_xmit(skb); |
624 | 620 | } |
net/mac80211/tx.c
... | ... | @@ -439,14 +439,14 @@ |
439 | 439 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); |
440 | 440 | u16 fc = tx->fc; |
441 | 441 | |
442 | - if (unlikely(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT)) | |
442 | + if (unlikely(tx->skb->do_not_encrypt)) | |
443 | 443 | tx->key = NULL; |
444 | 444 | else if (tx->sta && (key = rcu_dereference(tx->sta->key))) |
445 | 445 | tx->key = key; |
446 | 446 | else if ((key = rcu_dereference(tx->sdata->default_key))) |
447 | 447 | tx->key = key; |
448 | 448 | else if (tx->sdata->drop_unencrypted && |
449 | - !(info->flags & IEEE80211_TX_CTL_EAPOL_FRAME) && | |
449 | + (tx->skb->protocol != cpu_to_be16(ETH_P_PAE)) && | |
450 | 450 | !(info->flags & IEEE80211_TX_CTL_INJECTED)) { |
451 | 451 | I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); |
452 | 452 | return TX_DROP; |
... | ... | @@ -476,7 +476,7 @@ |
476 | 476 | } |
477 | 477 | |
478 | 478 | if (!tx->key || !(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) |
479 | - info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; | |
479 | + tx->skb->do_not_encrypt = 1; | |
480 | 480 | |
481 | 481 | return TX_CONTINUE; |
482 | 482 | } |
... | ... | @@ -732,6 +732,7 @@ |
732 | 732 | memcpy(skb_put(frag, copylen), pos, copylen); |
733 | 733 | memcpy(frag->cb, first->cb, sizeof(frag->cb)); |
734 | 734 | skb_copy_queue_mapping(frag, first); |
735 | + frag->do_not_encrypt = first->do_not_encrypt; | |
735 | 736 | |
736 | 737 | pos += copylen; |
737 | 738 | left -= copylen; |
... | ... | @@ -852,7 +853,7 @@ |
852 | 853 | |
853 | 854 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; |
854 | 855 | |
855 | - info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; | |
856 | + skb->do_not_encrypt = 1; | |
856 | 857 | info->flags |= IEEE80211_TX_CTL_INJECTED; |
857 | 858 | tx->flags &= ~IEEE80211_TX_FRAGMENTED; |
858 | 859 | |
... | ... | @@ -925,8 +926,7 @@ |
925 | 926 | skb_trim(skb, skb->len - FCS_LEN); |
926 | 927 | } |
927 | 928 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP) |
928 | - info->flags &= | |
929 | - ~IEEE80211_TX_CTL_DO_NOT_ENCRYPT; | |
929 | + tx->skb->do_not_encrypt = 0; | |
930 | 930 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG) |
931 | 931 | tx->flags |= IEEE80211_TX_FRAGMENTED; |
932 | 932 | break; |
933 | 933 | |
... | ... | @@ -1042,10 +1042,9 @@ |
1042 | 1042 | struct sk_buff *skb, |
1043 | 1043 | struct net_device *mdev) |
1044 | 1044 | { |
1045 | - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | |
1046 | 1045 | struct net_device *dev; |
1047 | 1046 | |
1048 | - dev = dev_get_by_index(&init_net, info->control.ifindex); | |
1047 | + dev = dev_get_by_index(&init_net, skb->iif); | |
1049 | 1048 | if (unlikely(dev && !is_ieee80211_device(dev, mdev))) { |
1050 | 1049 | dev_put(dev); |
1051 | 1050 | dev = NULL; |
... | ... | @@ -1306,8 +1305,8 @@ |
1306 | 1305 | bool may_encrypt; |
1307 | 1306 | int ret; |
1308 | 1307 | |
1309 | - if (info->control.ifindex) | |
1310 | - odev = dev_get_by_index(&init_net, info->control.ifindex); | |
1308 | + if (skb->iif) | |
1309 | + odev = dev_get_by_index(&init_net, skb->iif); | |
1311 | 1310 | if (unlikely(odev && !is_ieee80211_device(odev, dev))) { |
1312 | 1311 | dev_put(odev); |
1313 | 1312 | odev = NULL; |
1314 | 1313 | |
... | ... | @@ -1321,9 +1320,13 @@ |
1321 | 1320 | return 0; |
1322 | 1321 | } |
1323 | 1322 | |
1323 | + memset(info, 0, sizeof(*info)); | |
1324 | + | |
1325 | + info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; | |
1326 | + | |
1324 | 1327 | osdata = IEEE80211_DEV_TO_SUB_IF(odev); |
1325 | 1328 | |
1326 | - may_encrypt = !(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT); | |
1329 | + may_encrypt = !skb->do_not_encrypt; | |
1327 | 1330 | |
1328 | 1331 | headroom = osdata->local->tx_headroom; |
1329 | 1332 | if (may_encrypt) |
... | ... | @@ -1348,7 +1351,6 @@ |
1348 | 1351 | struct net_device *dev) |
1349 | 1352 | { |
1350 | 1353 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
1351 | - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | |
1352 | 1354 | struct ieee80211_radiotap_header *prthdr = |
1353 | 1355 | (struct ieee80211_radiotap_header *)skb->data; |
1354 | 1356 | u16 len_rthdr; |
1355 | 1357 | |
... | ... | @@ -1371,11 +1373,11 @@ |
1371 | 1373 | skb->dev = local->mdev; |
1372 | 1374 | |
1373 | 1375 | /* needed because we set skb device to master */ |
1374 | - info->control.ifindex = dev->ifindex; | |
1376 | + skb->iif = dev->ifindex; | |
1375 | 1377 | |
1376 | - info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; | |
1377 | - /* Interfaces should always request a status report */ | |
1378 | - info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; | |
1378 | + /* sometimes we do encrypt injected frames, will be fixed | |
1379 | + * up in radiotap parser if not wanted */ | |
1380 | + skb->do_not_encrypt = 0; | |
1379 | 1381 | |
1380 | 1382 | /* |
1381 | 1383 | * fix up the pointers accounting for the radiotap |
... | ... | @@ -1419,7 +1421,6 @@ |
1419 | 1421 | struct net_device *dev) |
1420 | 1422 | { |
1421 | 1423 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
1422 | - struct ieee80211_tx_info *info; | |
1423 | 1424 | struct ieee80211_sub_if_data *sdata; |
1424 | 1425 | int ret = 1, head_need; |
1425 | 1426 | u16 ethertype, hdrlen, meshhdrlen = 0; |
1426 | 1427 | |
... | ... | @@ -1645,15 +1646,8 @@ |
1645 | 1646 | nh_pos += hdrlen; |
1646 | 1647 | h_pos += hdrlen; |
1647 | 1648 | |
1648 | - info = IEEE80211_SKB_CB(skb); | |
1649 | - memset(info, 0, sizeof(*info)); | |
1650 | - info->control.ifindex = dev->ifindex; | |
1651 | - if (ethertype == ETH_P_PAE) | |
1652 | - info->flags |= IEEE80211_TX_CTL_EAPOL_FRAME; | |
1649 | + skb->iif = dev->ifindex; | |
1653 | 1650 | |
1654 | - /* Interfaces should always request a status report */ | |
1655 | - info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; | |
1656 | - | |
1657 | 1651 | skb->dev = local->mdev; |
1658 | 1652 | dev->stats.tx_packets++; |
1659 | 1653 | dev->stats.tx_bytes += skb->len; |
... | ... | @@ -1922,6 +1916,8 @@ |
1922 | 1916 | |
1923 | 1917 | info = IEEE80211_SKB_CB(skb); |
1924 | 1918 | |
1919 | + skb->do_not_encrypt = 1; | |
1920 | + | |
1925 | 1921 | info->band = band; |
1926 | 1922 | rate_control_get_rate(local->mdev, sband, skb, &rsel); |
1927 | 1923 | |
... | ... | @@ -1940,7 +1936,6 @@ |
1940 | 1936 | info->tx_rate_idx = rsel.rate_idx; |
1941 | 1937 | |
1942 | 1938 | info->flags |= IEEE80211_TX_CTL_NO_ACK; |
1943 | - info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; | |
1944 | 1939 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; |
1945 | 1940 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; |
1946 | 1941 | if (sdata->bss_conf.use_short_preamble && |
net/mac80211/wme.c