aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/tx.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-07-13 18:33:34 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-07-27 15:24:06 -0400
commit5061b0c2b9066de426fbc63f1278d2210e789412 (patch)
tree4658cb1a75c2ac37e2eebb3dd67cb3c975297b1f /net/mac80211/tx.c
parent70034918930d2e5b68c09bced637228c50d9561a (diff)
mac80211: cooperate more with network namespaces
There are still two places in mac80211 that hardcode the initial net namespace (init_net). One of them is mandated by cfg80211 and will be removed by a separate patch, the other one is used for finding the network device of a pending packet via its ifindex. Remove the latter use by keeping track of the device pointer itself, via the vif pointer, and avoid it going stale by dropping pending frames for a given interface when the interface is removed. To keep track of the vif pointer for the correct interface, change the info->control.vif pointer's internal use to always be the correct vif, and only move it to the vif the driver expects (or NULL for monitor interfaces and injected packets) right before giving the packet to the driver. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r--net/mac80211/tx.c75
1 files changed, 30 insertions, 45 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 2572509d5568..ffd3b10f2696 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -400,6 +400,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
400 sta_info_set_tim_bit(sta); 400 sta_info_set_tim_bit(sta);
401 401
402 info->control.jiffies = jiffies; 402 info->control.jiffies = jiffies;
403 info->control.vif = &tx->sdata->vif;
403 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; 404 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
404 skb_queue_tail(&sta->ps_tx_buf, tx->skb); 405 skb_queue_tail(&sta->ps_tx_buf, tx->skb);
405 return TX_QUEUED; 406 return TX_QUEUED;
@@ -696,7 +697,7 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
696 * number, if we have no matching interface then we 697 * number, if we have no matching interface then we
697 * neither assign one ourselves nor ask the driver to. 698 * neither assign one ourselves nor ask the driver to.
698 */ 699 */
699 if (unlikely(!info->control.vif)) 700 if (unlikely(info->control.vif->type == NL80211_IFTYPE_MONITOR))
700 return TX_CONTINUE; 701 return TX_CONTINUE;
701 702
702 if (unlikely(ieee80211_is_ctl(hdr->frame_control))) 703 if (unlikely(ieee80211_is_ctl(hdr->frame_control)))
@@ -1092,6 +1093,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
1092 } else if (*state != HT_AGG_STATE_IDLE) { 1093 } else if (*state != HT_AGG_STATE_IDLE) {
1093 /* in progress */ 1094 /* in progress */
1094 queued = true; 1095 queued = true;
1096 info->control.vif = &sdata->vif;
1095 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; 1097 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
1096 __skb_queue_tail(&tid_tx->pending, skb); 1098 __skb_queue_tail(&tid_tx->pending, skb);
1097 } 1099 }
@@ -1143,6 +1145,7 @@ static int __ieee80211_tx(struct ieee80211_local *local,
1143{ 1145{
1144 struct sk_buff *skb = *skbp, *next; 1146 struct sk_buff *skb = *skbp, *next;
1145 struct ieee80211_tx_info *info; 1147 struct ieee80211_tx_info *info;
1148 struct ieee80211_sub_if_data *sdata;
1146 unsigned long flags; 1149 unsigned long flags;
1147 int ret, len; 1150 int ret, len;
1148 bool fragm = false; 1151 bool fragm = false;
@@ -1167,7 +1170,24 @@ static int __ieee80211_tx(struct ieee80211_local *local,
1167 1170
1168 next = skb->next; 1171 next = skb->next;
1169 len = skb->len; 1172 len = skb->len;
1173
1174 sdata = vif_to_sdata(info->control.vif);
1175
1176 switch (sdata->vif.type) {
1177 case NL80211_IFTYPE_MONITOR:
1178 info->control.vif = NULL;
1179 break;
1180 case NL80211_IFTYPE_AP_VLAN:
1181 info->control.vif = &container_of(sdata->bss,
1182 struct ieee80211_sub_if_data, u.ap)->vif;
1183 break;
1184 default:
1185 /* keep */
1186 break;
1187 }
1188
1170 ret = drv_tx(local, skb); 1189 ret = drv_tx(local, skb);
1190 info->control.vif = &sdata->vif;
1171 if (WARN_ON(ret != NETDEV_TX_OK && skb->len != len)) { 1191 if (WARN_ON(ret != NETDEV_TX_OK && skb->len != len)) {
1172 dev_kfree_skb(skb); 1192 dev_kfree_skb(skb);
1173 ret = NETDEV_TX_OK; 1193 ret = NETDEV_TX_OK;
@@ -1386,11 +1406,6 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
1386 struct ieee80211_sub_if_data *tmp_sdata; 1406 struct ieee80211_sub_if_data *tmp_sdata;
1387 int headroom; 1407 int headroom;
1388 bool may_encrypt; 1408 bool may_encrypt;
1389 enum {
1390 NOT_MONITOR,
1391 FOUND_SDATA,
1392 UNKNOWN_ADDRESS,
1393 } monitor_iface = NOT_MONITOR;
1394 1409
1395 dev_hold(sdata->dev); 1410 dev_hold(sdata->dev);
1396 1411
@@ -1424,7 +1439,6 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
1424 u16 len_rthdr; 1439 u16 len_rthdr;
1425 1440
1426 info->flags |= IEEE80211_TX_CTL_INJECTED; 1441 info->flags |= IEEE80211_TX_CTL_INJECTED;
1427 monitor_iface = UNKNOWN_ADDRESS;
1428 1442
1429 len_rthdr = ieee80211_get_radiotap_len(skb->data); 1443 len_rthdr = ieee80211_get_radiotap_len(skb->data);
1430 hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr); 1444 hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr);
@@ -1454,7 +1468,6 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
1454 dev_hold(tmp_sdata->dev); 1468 dev_hold(tmp_sdata->dev);
1455 dev_put(sdata->dev); 1469 dev_put(sdata->dev);
1456 sdata = tmp_sdata; 1470 sdata = tmp_sdata;
1457 monitor_iface = FOUND_SDATA;
1458 break; 1471 break;
1459 } 1472 }
1460 } 1473 }
@@ -1476,13 +1489,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
1476 return; 1489 return;
1477 } 1490 }
1478 1491
1479 tmp_sdata = sdata; 1492 info->control.vif = &sdata->vif;
1480 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
1481 tmp_sdata = container_of(sdata->bss,
1482 struct ieee80211_sub_if_data,
1483 u.ap);
1484 if (likely(monitor_iface != UNKNOWN_ADDRESS))
1485 info->control.vif = &tmp_sdata->vif;
1486 1493
1487 ieee80211_select_queue(local, skb); 1494 ieee80211_select_queue(local, skb);
1488 ieee80211_tx(sdata, skb, false); 1495 ieee80211_tx(sdata, skb, false);
@@ -1534,9 +1541,6 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb,
1534 if (unlikely(skb->len < len_rthdr)) 1541 if (unlikely(skb->len < len_rthdr))
1535 goto fail; /* skb too short for claimed rt header extent */ 1542 goto fail; /* skb too short for claimed rt header extent */
1536 1543
1537 /* needed because we set skb device to master */
1538 skb->iif = dev->ifindex;
1539
1540 /* 1544 /*
1541 * fix up the pointers accounting for the radiotap 1545 * fix up the pointers accounting for the radiotap
1542 * header still being in there. We are being given 1546 * header still being in there. We are being given
@@ -1810,8 +1814,6 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1810 nh_pos += hdrlen; 1814 nh_pos += hdrlen;
1811 h_pos += hdrlen; 1815 h_pos += hdrlen;
1812 1816
1813 skb->iif = dev->ifindex;
1814
1815 dev->stats.tx_packets++; 1817 dev->stats.tx_packets++;
1816 dev->stats.tx_bytes += skb->len; 1818 dev->stats.tx_bytes += skb->len;
1817 1819
@@ -1856,32 +1858,13 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local,
1856 struct ieee80211_sub_if_data *sdata; 1858 struct ieee80211_sub_if_data *sdata;
1857 struct sta_info *sta; 1859 struct sta_info *sta;
1858 struct ieee80211_hdr *hdr; 1860 struct ieee80211_hdr *hdr;
1859 struct net_device *dev;
1860 int ret; 1861 int ret;
1861 bool result = true; 1862 bool result = true;
1862 1863
1863 /* does interface still exist? */ 1864 sdata = vif_to_sdata(info->control.vif);
1864 dev = dev_get_by_index(&init_net, skb->iif);
1865 if (!dev) {
1866 dev_kfree_skb(skb);
1867 return true;
1868 }
1869
1870 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1871 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
1872 sdata = container_of(sdata->bss,
1873 struct ieee80211_sub_if_data,
1874 u.ap);
1875
1876 if (unlikely(info->control.vif && info->control.vif != &sdata->vif)) {
1877 dev_kfree_skb(skb);
1878 result = true;
1879 goto out;
1880 }
1881 1865
1882 if (info->flags & IEEE80211_TX_INTFL_NEED_TXPROCESSING) { 1866 if (info->flags & IEEE80211_TX_INTFL_NEED_TXPROCESSING) {
1883 /* do not use sdata, it may have been changed above */ 1867 ieee80211_tx(sdata, skb, true);
1884 ieee80211_tx(IEEE80211_DEV_TO_SUB_IF(dev), skb, true);
1885 } else { 1868 } else {
1886 hdr = (struct ieee80211_hdr *)skb->data; 1869 hdr = (struct ieee80211_hdr *)skb->data;
1887 sta = sta_info_get(local, hdr->addr1); 1870 sta = sta_info_get(local, hdr->addr1);
@@ -1891,9 +1874,6 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local,
1891 result = false; 1874 result = false;
1892 } 1875 }
1893 1876
1894 out:
1895 dev_put(dev);
1896
1897 return result; 1877 return result;
1898} 1878}
1899 1879
@@ -1921,10 +1901,16 @@ void ieee80211_tx_pending(unsigned long data)
1921 1901
1922 while (!skb_queue_empty(&local->pending[i])) { 1902 while (!skb_queue_empty(&local->pending[i])) {
1923 struct sk_buff *skb = __skb_dequeue(&local->pending[i]); 1903 struct sk_buff *skb = __skb_dequeue(&local->pending[i]);
1904 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1905 struct ieee80211_sub_if_data *sdata;
1906
1907 sdata = vif_to_sdata(info->control.vif);
1908 dev_hold(sdata->dev);
1924 spin_unlock_irqrestore(&local->queue_stop_reason_lock, 1909 spin_unlock_irqrestore(&local->queue_stop_reason_lock,
1925 flags); 1910 flags);
1926 1911
1927 txok = ieee80211_tx_pending_skb(local, skb); 1912 txok = ieee80211_tx_pending_skb(local, skb);
1913 dev_put(sdata->dev);
1928 if (!txok) 1914 if (!txok)
1929 __skb_queue_head(&local->pending[i], skb); 1915 __skb_queue_head(&local->pending[i], skb);
1930 spin_lock_irqsave(&local->queue_stop_reason_lock, 1916 spin_lock_irqsave(&local->queue_stop_reason_lock,
@@ -2234,7 +2220,6 @@ void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
2234 skb_set_network_header(skb, 0); 2220 skb_set_network_header(skb, 0);
2235 skb_set_transport_header(skb, 0); 2221 skb_set_transport_header(skb, 0);
2236 2222
2237 skb->iif = sdata->dev->ifindex;
2238 if (!encrypt) 2223 if (!encrypt)
2239 info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 2224 info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
2240 2225