aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/iface.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/iface.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/iface.c')
-rw-r--r--net/mac80211/iface.c16
1 files changed, 15 insertions, 1 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);