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 | ||
