aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-07-29 05:32:07 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-07-29 16:55:08 -0400
commitd0f09804144fd9471a13cf4d80e66842c7fa114f (patch)
tree4a1f0f78bad7e5be4ad400397a19d4b8d6fbbdcd /net
parent0ccd58fc03f40529f66190b1a41e92a732d2bda8 (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.c3
-rw-r--r--net/mac80211/main.c8
-rw-r--r--net/mac80211/mlme.c8
-rw-r--r--net/mac80211/tx.c47
-rw-r--r--net/mac80211/wme.c3
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 */
1237static void ieee80211_remove_tx_extra(struct ieee80211_local *local, 1237static 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