diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-07-13 18:33:35 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-07-27 15:24:07 -0400 |
commit | 463d018323851a608eef52a9427b0585005c647f (patch) | |
tree | b5ad2ee6115e6b780c264022cbc20b36d22fe80c /net/wireless/scan.c | |
parent | 5061b0c2b9066de426fbc63f1278d2210e789412 (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.c | 22 |
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 | ||
67 | void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted) | 64 | void 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 | } |
81 | EXPORT_SYMBOL(cfg80211_scan_done); | 71 | EXPORT_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); |