diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2008-07-29 05:32:07 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-07-29 16:55:08 -0400 |
commit | d0f09804144fd9471a13cf4d80e66842c7fa114f (patch) | |
tree | 4a1f0f78bad7e5be4ad400397a19d4b8d6fbbdcd /net | |
parent | 0ccd58fc03f40529f66190b1a41e92a732d2bda8 (diff) |
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>
Diffstat (limited to 'net')
-rw-r--r-- | net/core/skbuff.c | 3 | ||||
-rw-r--r-- | net/mac80211/main.c | 8 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 8 | ||||
-rw-r--r-- | net/mac80211/tx.c | 47 | ||||
-rw-r--r-- | net/mac80211/wme.c | 3 |
5 files changed, 30 insertions, 39 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 4e0c92274189..84640172d65d 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -485,6 +485,9 @@ static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb) | |||
485 | C(head); | 485 | C(head); |
486 | C(data); | 486 | C(data); |
487 | C(truesize); | 487 | C(truesize); |
488 | #if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE) | ||
489 | C(do_not_encrypt); | ||
490 | #endif | ||
488 | atomic_set(&n->users, 1); | 491 | atomic_set(&n->users, 1); |
489 | 492 | ||
490 | atomic_inc(&(skb_shinfo(skb)->dataref)); | 493 | atomic_inc(&(skb_shinfo(skb)->dataref)); |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index b5830f7055cf..a4c5b90de769 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -1233,18 +1233,12 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
1233 | /* Remove added headers (e.g., QoS control), encryption header/MIC, etc. to | 1233 | /* Remove added headers (e.g., QoS control), encryption header/MIC, etc. to |
1234 | * make a prepared TX frame (one that has been given to hw) to look like brand | 1234 | * make a prepared TX frame (one that has been given to hw) to look like brand |
1235 | * new IEEE 802.11 frame that is ready to go through TX processing again. | 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 | static void ieee80211_remove_tx_extra(struct ieee80211_local *local, | 1237 | static void ieee80211_remove_tx_extra(struct ieee80211_local *local, |
1238 | struct ieee80211_key *key, | 1238 | struct ieee80211_key *key, |
1239 | struct sk_buff *skb) | 1239 | struct sk_buff *skb) |
1240 | { | 1240 | { |
1241 | int hdrlen, iv_len, mic_len; | 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 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 1243 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); |
1250 | 1244 | ||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index d7c371e36bf0..35eb767cbcbe 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -606,7 +606,6 @@ void ieee80211_sta_tx(struct net_device *dev, struct sk_buff *skb, | |||
606 | int encrypt) | 606 | int encrypt) |
607 | { | 607 | { |
608 | struct ieee80211_sub_if_data *sdata; | 608 | struct ieee80211_sub_if_data *sdata; |
609 | struct ieee80211_tx_info *info; | ||
610 | 609 | ||
611 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 610 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
612 | skb->dev = sdata->local->mdev; | 611 | skb->dev = sdata->local->mdev; |
@@ -614,11 +613,8 @@ void ieee80211_sta_tx(struct net_device *dev, struct sk_buff *skb, | |||
614 | skb_set_network_header(skb, 0); | 613 | skb_set_network_header(skb, 0); |
615 | skb_set_transport_header(skb, 0); | 614 | skb_set_transport_header(skb, 0); |
616 | 615 | ||
617 | info = IEEE80211_SKB_CB(skb); | 616 | skb->iif = sdata->dev->ifindex; |
618 | memset(info, 0, sizeof(struct ieee80211_tx_info)); | 617 | skb->do_not_encrypt = !encrypt; |
619 | info->control.ifindex = sdata->dev->ifindex; | ||
620 | if (!encrypt) | ||
621 | info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; | ||
622 | 618 | ||
623 | dev_queue_xmit(skb); | 619 | dev_queue_xmit(skb); |
624 | } | 620 | } |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index c5f78059c6ca..69019e943873 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -439,14 +439,14 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
439 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | 439 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); |
440 | u16 fc = tx->fc; | 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 | tx->key = NULL; | 443 | tx->key = NULL; |
444 | else if (tx->sta && (key = rcu_dereference(tx->sta->key))) | 444 | else if (tx->sta && (key = rcu_dereference(tx->sta->key))) |
445 | tx->key = key; | 445 | tx->key = key; |
446 | else if ((key = rcu_dereference(tx->sdata->default_key))) | 446 | else if ((key = rcu_dereference(tx->sdata->default_key))) |
447 | tx->key = key; | 447 | tx->key = key; |
448 | else if (tx->sdata->drop_unencrypted && | 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 | !(info->flags & IEEE80211_TX_CTL_INJECTED)) { | 450 | !(info->flags & IEEE80211_TX_CTL_INJECTED)) { |
451 | I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); | 451 | I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); |
452 | return TX_DROP; | 452 | return TX_DROP; |
@@ -476,7 +476,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
476 | } | 476 | } |
477 | 477 | ||
478 | if (!tx->key || !(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) | 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 | return TX_CONTINUE; | 481 | return TX_CONTINUE; |
482 | } | 482 | } |
@@ -732,6 +732,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
732 | memcpy(skb_put(frag, copylen), pos, copylen); | 732 | memcpy(skb_put(frag, copylen), pos, copylen); |
733 | memcpy(frag->cb, first->cb, sizeof(frag->cb)); | 733 | memcpy(frag->cb, first->cb, sizeof(frag->cb)); |
734 | skb_copy_queue_mapping(frag, first); | 734 | skb_copy_queue_mapping(frag, first); |
735 | frag->do_not_encrypt = first->do_not_encrypt; | ||
735 | 736 | ||
736 | pos += copylen; | 737 | pos += copylen; |
737 | left -= copylen; | 738 | left -= copylen; |
@@ -852,7 +853,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
852 | 853 | ||
853 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; | 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 | info->flags |= IEEE80211_TX_CTL_INJECTED; | 857 | info->flags |= IEEE80211_TX_CTL_INJECTED; |
857 | tx->flags &= ~IEEE80211_TX_FRAGMENTED; | 858 | tx->flags &= ~IEEE80211_TX_FRAGMENTED; |
858 | 859 | ||
@@ -925,8 +926,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
925 | skb_trim(skb, skb->len - FCS_LEN); | 926 | skb_trim(skb, skb->len - FCS_LEN); |
926 | } | 927 | } |
927 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP) | 928 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP) |
928 | info->flags &= | 929 | tx->skb->do_not_encrypt = 0; |
929 | ~IEEE80211_TX_CTL_DO_NOT_ENCRYPT; | ||
930 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG) | 930 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG) |
931 | tx->flags |= IEEE80211_TX_FRAGMENTED; | 931 | tx->flags |= IEEE80211_TX_FRAGMENTED; |
932 | break; | 932 | break; |
@@ -1042,10 +1042,9 @@ static int ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | |||
1042 | struct sk_buff *skb, | 1042 | struct sk_buff *skb, |
1043 | struct net_device *mdev) | 1043 | struct net_device *mdev) |
1044 | { | 1044 | { |
1045 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1046 | struct net_device *dev; | 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 | if (unlikely(dev && !is_ieee80211_device(dev, mdev))) { | 1048 | if (unlikely(dev && !is_ieee80211_device(dev, mdev))) { |
1050 | dev_put(dev); | 1049 | dev_put(dev); |
1051 | dev = NULL; | 1050 | dev = NULL; |
@@ -1306,8 +1305,8 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, | |||
1306 | bool may_encrypt; | 1305 | bool may_encrypt; |
1307 | int ret; | 1306 | int ret; |
1308 | 1307 | ||
1309 | if (info->control.ifindex) | 1308 | if (skb->iif) |
1310 | odev = dev_get_by_index(&init_net, info->control.ifindex); | 1309 | odev = dev_get_by_index(&init_net, skb->iif); |
1311 | if (unlikely(odev && !is_ieee80211_device(odev, dev))) { | 1310 | if (unlikely(odev && !is_ieee80211_device(odev, dev))) { |
1312 | dev_put(odev); | 1311 | dev_put(odev); |
1313 | odev = NULL; | 1312 | odev = NULL; |
@@ -1321,9 +1320,13 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, | |||
1321 | return 0; | 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 | osdata = IEEE80211_DEV_TO_SUB_IF(odev); | 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 | headroom = osdata->local->tx_headroom; | 1331 | headroom = osdata->local->tx_headroom; |
1329 | if (may_encrypt) | 1332 | if (may_encrypt) |
@@ -1348,7 +1351,6 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb, | |||
1348 | struct net_device *dev) | 1351 | struct net_device *dev) |
1349 | { | 1352 | { |
1350 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1353 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
1351 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1352 | struct ieee80211_radiotap_header *prthdr = | 1354 | struct ieee80211_radiotap_header *prthdr = |
1353 | (struct ieee80211_radiotap_header *)skb->data; | 1355 | (struct ieee80211_radiotap_header *)skb->data; |
1354 | u16 len_rthdr; | 1356 | u16 len_rthdr; |
@@ -1371,11 +1373,11 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb, | |||
1371 | skb->dev = local->mdev; | 1373 | skb->dev = local->mdev; |
1372 | 1374 | ||
1373 | /* needed because we set skb device to master */ | 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; | 1378 | /* sometimes we do encrypt injected frames, will be fixed |
1377 | /* Interfaces should always request a status report */ | 1379 | * up in radiotap parser if not wanted */ |
1378 | info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; | 1380 | skb->do_not_encrypt = 0; |
1379 | 1381 | ||
1380 | /* | 1382 | /* |
1381 | * fix up the pointers accounting for the radiotap | 1383 | * fix up the pointers accounting for the radiotap |
@@ -1419,7 +1421,6 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1419 | struct net_device *dev) | 1421 | struct net_device *dev) |
1420 | { | 1422 | { |
1421 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1423 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
1422 | struct ieee80211_tx_info *info; | ||
1423 | struct ieee80211_sub_if_data *sdata; | 1424 | struct ieee80211_sub_if_data *sdata; |
1424 | int ret = 1, head_need; | 1425 | int ret = 1, head_need; |
1425 | u16 ethertype, hdrlen, meshhdrlen = 0; | 1426 | u16 ethertype, hdrlen, meshhdrlen = 0; |
@@ -1645,14 +1646,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1645 | nh_pos += hdrlen; | 1646 | nh_pos += hdrlen; |
1646 | h_pos += hdrlen; | 1647 | h_pos += hdrlen; |
1647 | 1648 | ||
1648 | info = IEEE80211_SKB_CB(skb); | 1649 | skb->iif = dev->ifindex; |
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; | ||
1653 | |||
1654 | /* Interfaces should always request a status report */ | ||
1655 | info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; | ||
1656 | 1650 | ||
1657 | skb->dev = local->mdev; | 1651 | skb->dev = local->mdev; |
1658 | dev->stats.tx_packets++; | 1652 | dev->stats.tx_packets++; |
@@ -1922,6 +1916,8 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1922 | 1916 | ||
1923 | info = IEEE80211_SKB_CB(skb); | 1917 | info = IEEE80211_SKB_CB(skb); |
1924 | 1918 | ||
1919 | skb->do_not_encrypt = 1; | ||
1920 | |||
1925 | info->band = band; | 1921 | info->band = band; |
1926 | rate_control_get_rate(local->mdev, sband, skb, &rsel); | 1922 | rate_control_get_rate(local->mdev, sband, skb, &rsel); |
1927 | 1923 | ||
@@ -1940,7 +1936,6 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1940 | info->tx_rate_idx = rsel.rate_idx; | 1936 | info->tx_rate_idx = rsel.rate_idx; |
1941 | 1937 | ||
1942 | info->flags |= IEEE80211_TX_CTL_NO_ACK; | 1938 | info->flags |= IEEE80211_TX_CTL_NO_ACK; |
1943 | info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; | ||
1944 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; | 1939 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; |
1945 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; | 1940 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; |
1946 | if (sdata->bss_conf.use_short_preamble && | 1941 | if (sdata->bss_conf.use_short_preamble && |
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 07edda0b8a5c..28437f0001db 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c | |||
@@ -188,6 +188,9 @@ int ieee80211_ht_agg_queue_add(struct ieee80211_local *local, | |||
188 | { | 188 | { |
189 | int i; | 189 | int i; |
190 | 190 | ||
191 | /* XXX: currently broken due to cb/requeue use */ | ||
192 | return -EPERM; | ||
193 | |||
191 | /* prepare the filter and save it for the SW queue | 194 | /* prepare the filter and save it for the SW queue |
192 | * matching the received HW queue */ | 195 | * matching the received HW queue */ |
193 | 196 | ||