diff options
-rw-r--r-- | net/mac80211/iface.c | 16 | ||||
-rw-r--r-- | net/mac80211/rx.c | 2 | ||||
-rw-r--r-- | net/mac80211/tx.c | 75 |
3 files changed, 46 insertions, 47 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 2f797a86ced5..559d698369c7 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -335,7 +335,10 @@ static int ieee80211_stop(struct net_device *dev) | |||
335 | struct ieee80211_local *local = sdata->local; | 335 | struct ieee80211_local *local = sdata->local; |
336 | struct ieee80211_if_init_conf conf; | 336 | struct ieee80211_if_init_conf conf; |
337 | struct sta_info *sta; | 337 | struct sta_info *sta; |
338 | unsigned long flags; | ||
339 | struct sk_buff *skb, *tmp; | ||
338 | u32 hw_reconf_flags = 0; | 340 | u32 hw_reconf_flags = 0; |
341 | int i; | ||
339 | 342 | ||
340 | /* | 343 | /* |
341 | * Stop TX on this interface first. | 344 | * Stop TX on this interface first. |
@@ -551,6 +554,18 @@ static int ieee80211_stop(struct net_device *dev) | |||
551 | if (hw_reconf_flags) | 554 | if (hw_reconf_flags) |
552 | ieee80211_hw_config(local, hw_reconf_flags); | 555 | ieee80211_hw_config(local, hw_reconf_flags); |
553 | 556 | ||
557 | spin_lock_irqsave(&local->queue_stop_reason_lock, flags); | ||
558 | for (i = 0; i < IEEE80211_MAX_QUEUES; i++) { | ||
559 | skb_queue_walk_safe(&local->pending[i], skb, tmp) { | ||
560 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
561 | if (info->control.vif == &sdata->vif) { | ||
562 | __skb_unlink(skb, &local->pending[i]); | ||
563 | dev_kfree_skb_irq(skb); | ||
564 | } | ||
565 | } | ||
566 | } | ||
567 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | ||
568 | |||
554 | return 0; | 569 | return 0; |
555 | } | 570 | } |
556 | 571 | ||
@@ -788,7 +803,6 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
788 | 803 | ||
789 | memcpy(ndev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN); | 804 | memcpy(ndev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN); |
790 | SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); | 805 | SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); |
791 | ndev->features |= NETIF_F_NETNS_LOCAL; | ||
792 | 806 | ||
793 | /* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */ | 807 | /* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */ |
794 | sdata = netdev_priv(ndev); | 808 | sdata = netdev_priv(ndev); |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 66c797cc85ce..d9df819eef3b 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1539,7 +1539,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1539 | info = IEEE80211_SKB_CB(fwd_skb); | 1539 | info = IEEE80211_SKB_CB(fwd_skb); |
1540 | memset(info, 0, sizeof(*info)); | 1540 | memset(info, 0, sizeof(*info)); |
1541 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | 1541 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; |
1542 | fwd_skb->iif = rx->dev->ifindex; | 1542 | info->control.vif = &rx->sdata->vif; |
1543 | ieee80211_select_queue(local, fwd_skb); | 1543 | ieee80211_select_queue(local, fwd_skb); |
1544 | if (is_multicast_ether_addr(fwd_hdr->addr3)) | 1544 | if (is_multicast_ether_addr(fwd_hdr->addr3)) |
1545 | memcpy(fwd_hdr->addr1, fwd_hdr->addr3, | 1545 | memcpy(fwd_hdr->addr1, fwd_hdr->addr3, |
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 | ||