aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/scan.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-07-13 18:33:35 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-07-27 15:24:07 -0400
commit463d018323851a608eef52a9427b0585005c647f (patch)
treeb5ad2ee6115e6b780c264022cbc20b36d22fe80c /net/wireless/scan.c
parent5061b0c2b9066de426fbc63f1278d2210e789412 (diff)
cfg80211: make aware of net namespaces
In order to make cfg80211/nl80211 aware of network namespaces, we have to do the following things: * del_virtual_intf method takes an interface index rather than a netdev pointer - simply change this * nl80211 uses init_net a lot, it changes to use the sender's network namespace * scan requests use the interface index, hold a netdev pointer and reference instead * we want a wiphy and its associated virtual interfaces to be in one netns together, so - we need to be able to change ns for a given interface, so export dev_change_net_namespace() - for each virtual interface set the NETIF_F_NETNS_LOCAL flag, and clear that flag only when the wiphy changes ns, to disallow breaking this invariant * when a network namespace goes away, we need to reparent the wiphy to init_net * cfg80211 users that support creating virtual interfaces must create them in the wiphy's namespace, currently this affects only mac80211 The end result is that you can now switch an entire wiphy into a different network namespace with the new command iw phy#<idx> set netns <pid> and all virtual interfaces will follow (or the operation fails). Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless/scan.c')
-rw-r--r--net/wireless/scan.c22
1 files changed, 7 insertions, 15 deletions
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index decc59fe0ee8..1b578b8cb1c9 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -32,9 +32,7 @@ void __cfg80211_scan_done(struct work_struct *wk)
32 mutex_lock(&rdev->mtx); 32 mutex_lock(&rdev->mtx);
33 request = rdev->scan_req; 33 request = rdev->scan_req;
34 34
35 dev = dev_get_by_index(&init_net, request->ifidx); 35 dev = request->dev;
36 if (!dev)
37 goto out;
38 36
39 /* 37 /*
40 * This must be before sending the other events! 38 * This must be before sending the other events!
@@ -58,7 +56,6 @@ void __cfg80211_scan_done(struct work_struct *wk)
58 56
59 dev_put(dev); 57 dev_put(dev);
60 58
61 out:
62 cfg80211_unlock_rdev(rdev); 59 cfg80211_unlock_rdev(rdev);
63 wiphy_to_dev(request->wiphy)->scan_req = NULL; 60 wiphy_to_dev(request->wiphy)->scan_req = NULL;
64 kfree(request); 61 kfree(request);
@@ -66,17 +63,10 @@ void __cfg80211_scan_done(struct work_struct *wk)
66 63
67void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted) 64void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
68{ 65{
69 struct net_device *dev = dev_get_by_index(&init_net, request->ifidx);
70 if (WARN_ON(!dev)) {
71 kfree(request);
72 return;
73 }
74
75 WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); 66 WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);
76 67
77 request->aborted = aborted; 68 request->aborted = aborted;
78 schedule_work(&wiphy_to_dev(request->wiphy)->scan_done_wk); 69 schedule_work(&wiphy_to_dev(request->wiphy)->scan_done_wk);
79 dev_put(dev);
80} 70}
81EXPORT_SYMBOL(cfg80211_scan_done); 71EXPORT_SYMBOL(cfg80211_scan_done);
82 72
@@ -592,7 +582,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
592 if (!netif_running(dev)) 582 if (!netif_running(dev))
593 return -ENETDOWN; 583 return -ENETDOWN;
594 584
595 rdev = cfg80211_get_dev_from_ifindex(dev->ifindex); 585 rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex);
596 586
597 if (IS_ERR(rdev)) 587 if (IS_ERR(rdev))
598 return PTR_ERR(rdev); 588 return PTR_ERR(rdev);
@@ -617,7 +607,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
617 } 607 }
618 608
619 creq->wiphy = wiphy; 609 creq->wiphy = wiphy;
620 creq->ifidx = dev->ifindex; 610 creq->dev = dev;
621 creq->ssids = (void *)(creq + 1); 611 creq->ssids = (void *)(creq + 1);
622 creq->channels = (void *)(creq->ssids + 1); 612 creq->channels = (void *)(creq->ssids + 1);
623 creq->n_channels = n_channels; 613 creq->n_channels = n_channels;
@@ -654,8 +644,10 @@ int cfg80211_wext_siwscan(struct net_device *dev,
654 if (err) { 644 if (err) {
655 rdev->scan_req = NULL; 645 rdev->scan_req = NULL;
656 kfree(creq); 646 kfree(creq);
657 } else 647 } else {
658 nl80211_send_scan_start(rdev, dev); 648 nl80211_send_scan_start(rdev, dev);
649 dev_hold(dev);
650 }
659 out: 651 out:
660 cfg80211_unlock_rdev(rdev); 652 cfg80211_unlock_rdev(rdev);
661 return err; 653 return err;
@@ -948,7 +940,7 @@ int cfg80211_wext_giwscan(struct net_device *dev,
948 if (!netif_running(dev)) 940 if (!netif_running(dev))
949 return -ENETDOWN; 941 return -ENETDOWN;
950 942
951 rdev = cfg80211_get_dev_from_ifindex(dev->ifindex); 943 rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex);
952 944
953 if (IS_ERR(rdev)) 945 if (IS_ERR(rdev))
954 return PTR_ERR(rdev); 946 return PTR_ERR(rdev);