aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
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
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')
-rw-r--r--net/wireless/core.c75
-rw-r--r--net/wireless/core.h5
-rw-r--r--net/wireless/nl80211.c202
-rw-r--r--net/wireless/scan.c22
-rw-r--r--net/wireless/sme.c3
5 files changed, 224 insertions, 83 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 6891cd0e38d5..442c9f389799 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -106,7 +106,7 @@ __cfg80211_rdev_from_info(struct genl_info *info)
106 106
107 if (info->attrs[NL80211_ATTR_IFINDEX]) { 107 if (info->attrs[NL80211_ATTR_IFINDEX]) {
108 ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]); 108 ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
109 dev = dev_get_by_index(&init_net, ifindex); 109 dev = dev_get_by_index(genl_info_net(info), ifindex);
110 if (dev) { 110 if (dev) {
111 if (dev->ieee80211_ptr) 111 if (dev->ieee80211_ptr)
112 byifidx = 112 byifidx =
@@ -151,13 +151,13 @@ cfg80211_get_dev_from_info(struct genl_info *info)
151} 151}
152 152
153struct cfg80211_registered_device * 153struct cfg80211_registered_device *
154cfg80211_get_dev_from_ifindex(int ifindex) 154cfg80211_get_dev_from_ifindex(struct net *net, int ifindex)
155{ 155{
156 struct cfg80211_registered_device *rdev = ERR_PTR(-ENODEV); 156 struct cfg80211_registered_device *rdev = ERR_PTR(-ENODEV);
157 struct net_device *dev; 157 struct net_device *dev;
158 158
159 mutex_lock(&cfg80211_mutex); 159 mutex_lock(&cfg80211_mutex);
160 dev = dev_get_by_index(&init_net, ifindex); 160 dev = dev_get_by_index(net, ifindex);
161 if (!dev) 161 if (!dev)
162 goto out; 162 goto out;
163 if (dev->ieee80211_ptr) { 163 if (dev->ieee80211_ptr) {
@@ -222,6 +222,42 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
222 return 0; 222 return 0;
223} 223}
224 224
225int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
226 struct net *net)
227{
228 struct wireless_dev *wdev;
229 int err = 0;
230
231 if (!rdev->wiphy.netnsok)
232 return -EOPNOTSUPP;
233
234 list_for_each_entry(wdev, &rdev->netdev_list, list) {
235 wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL;
236 err = dev_change_net_namespace(wdev->netdev, net, "wlan%d");
237 if (err)
238 break;
239 wdev->netdev->features |= NETIF_F_NETNS_LOCAL;
240 }
241
242 if (err) {
243 /* failed -- clean up to old netns */
244 net = wiphy_net(&rdev->wiphy);
245
246 list_for_each_entry_continue_reverse(wdev, &rdev->netdev_list,
247 list) {
248 wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL;
249 err = dev_change_net_namespace(wdev->netdev, net,
250 "wlan%d");
251 WARN_ON(err);
252 wdev->netdev->features |= NETIF_F_NETNS_LOCAL;
253 }
254 }
255
256 wiphy_net_set(&rdev->wiphy, net);
257
258 return err;
259}
260
225static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data) 261static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data)
226{ 262{
227 struct cfg80211_registered_device *rdev = data; 263 struct cfg80211_registered_device *rdev = data;
@@ -375,6 +411,8 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
375 rdev->wiphy.dev.class = &ieee80211_class; 411 rdev->wiphy.dev.class = &ieee80211_class;
376 rdev->wiphy.dev.platform_data = rdev; 412 rdev->wiphy.dev.platform_data = rdev;
377 413
414 wiphy_net_set(&rdev->wiphy, &init_net);
415
378 rdev->rfkill_ops.set_block = cfg80211_rfkill_set_block; 416 rdev->rfkill_ops.set_block = cfg80211_rfkill_set_block;
379 rdev->rfkill = rfkill_alloc(dev_name(&rdev->wiphy.dev), 417 rdev->rfkill = rfkill_alloc(dev_name(&rdev->wiphy.dev),
380 &rdev->wiphy.dev, RFKILL_TYPE_WLAN, 418 &rdev->wiphy.dev, RFKILL_TYPE_WLAN,
@@ -615,6 +653,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
615 spin_lock_init(&wdev->event_lock); 653 spin_lock_init(&wdev->event_lock);
616 mutex_lock(&rdev->devlist_mtx); 654 mutex_lock(&rdev->devlist_mtx);
617 list_add(&wdev->list, &rdev->netdev_list); 655 list_add(&wdev->list, &rdev->netdev_list);
656 /* can only change netns with wiphy */
657 dev->features |= NETIF_F_NETNS_LOCAL;
658
618 if (sysfs_create_link(&dev->dev.kobj, &rdev->wiphy.dev.kobj, 659 if (sysfs_create_link(&dev->dev.kobj, &rdev->wiphy.dev.kobj,
619 "phy80211")) { 660 "phy80211")) {
620 printk(KERN_ERR "wireless: failed to add phy80211 " 661 printk(KERN_ERR "wireless: failed to add phy80211 "
@@ -705,10 +746,32 @@ static struct notifier_block cfg80211_netdev_notifier = {
705 .notifier_call = cfg80211_netdev_notifier_call, 746 .notifier_call = cfg80211_netdev_notifier_call,
706}; 747};
707 748
708static int cfg80211_init(void) 749static void __net_exit cfg80211_pernet_exit(struct net *net)
750{
751 struct cfg80211_registered_device *rdev;
752
753 rtnl_lock();
754 mutex_lock(&cfg80211_mutex);
755 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
756 if (net_eq(wiphy_net(&rdev->wiphy), net))
757 WARN_ON(cfg80211_switch_netns(rdev, &init_net));
758 }
759 mutex_unlock(&cfg80211_mutex);
760 rtnl_unlock();
761}
762
763static struct pernet_operations cfg80211_pernet_ops = {
764 .exit = cfg80211_pernet_exit,
765};
766
767static int __init cfg80211_init(void)
709{ 768{
710 int err; 769 int err;
711 770
771 err = register_pernet_device(&cfg80211_pernet_ops);
772 if (err)
773 goto out_fail_pernet;
774
712 err = wiphy_sysfs_init(); 775 err = wiphy_sysfs_init();
713 if (err) 776 if (err)
714 goto out_fail_sysfs; 777 goto out_fail_sysfs;
@@ -736,9 +799,10 @@ out_fail_nl80211:
736out_fail_notifier: 799out_fail_notifier:
737 wiphy_sysfs_exit(); 800 wiphy_sysfs_exit();
738out_fail_sysfs: 801out_fail_sysfs:
802 unregister_pernet_device(&cfg80211_pernet_ops);
803out_fail_pernet:
739 return err; 804 return err;
740} 805}
741
742subsys_initcall(cfg80211_init); 806subsys_initcall(cfg80211_init);
743 807
744static void cfg80211_exit(void) 808static void cfg80211_exit(void)
@@ -748,5 +812,6 @@ static void cfg80211_exit(void)
748 unregister_netdevice_notifier(&cfg80211_netdev_notifier); 812 unregister_netdevice_notifier(&cfg80211_netdev_notifier);
749 wiphy_sysfs_exit(); 813 wiphy_sysfs_exit();
750 regulatory_exit(); 814 regulatory_exit();
815 unregister_pernet_device(&cfg80211_pernet_ops);
751} 816}
752module_exit(cfg80211_exit); 817module_exit(cfg80211_exit);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 2ec8ddbe57de..4276b70cd975 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -170,7 +170,10 @@ struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx);
170 170
171/* identical to cfg80211_get_dev_from_info but only operate on ifindex */ 171/* identical to cfg80211_get_dev_from_info but only operate on ifindex */
172extern struct cfg80211_registered_device * 172extern struct cfg80211_registered_device *
173cfg80211_get_dev_from_ifindex(int ifindex); 173cfg80211_get_dev_from_ifindex(struct net *net, int ifindex);
174
175int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
176 struct net *net);
174 177
175static inline void cfg80211_lock_rdev(struct cfg80211_registered_device *rdev) 178static inline void cfg80211_lock_rdev(struct cfg80211_registered_device *rdev)
176{ 179{
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index da450ef1fc7e..7880a9c4cdda 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -14,8 +14,10 @@
14#include <linux/rtnetlink.h> 14#include <linux/rtnetlink.h>
15#include <linux/netlink.h> 15#include <linux/netlink.h>
16#include <linux/etherdevice.h> 16#include <linux/etherdevice.h>
17#include <net/net_namespace.h>
17#include <net/genetlink.h> 18#include <net/genetlink.h>
18#include <net/cfg80211.h> 19#include <net/cfg80211.h>
20#include <net/sock.h>
19#include "core.h" 21#include "core.h"
20#include "nl80211.h" 22#include "nl80211.h"
21#include "reg.h" 23#include "reg.h"
@@ -27,24 +29,26 @@ static struct genl_family nl80211_fam = {
27 .hdrsize = 0, /* no private header */ 29 .hdrsize = 0, /* no private header */
28 .version = 1, /* no particular meaning now */ 30 .version = 1, /* no particular meaning now */
29 .maxattr = NL80211_ATTR_MAX, 31 .maxattr = NL80211_ATTR_MAX,
32 .netnsok = true,
30}; 33};
31 34
32/* internal helper: get rdev and dev */ 35/* internal helper: get rdev and dev */
33static int get_rdev_dev_by_info_ifindex(struct nlattr **attrs, 36static int get_rdev_dev_by_info_ifindex(struct genl_info *info,
34 struct cfg80211_registered_device **rdev, 37 struct cfg80211_registered_device **rdev,
35 struct net_device **dev) 38 struct net_device **dev)
36{ 39{
40 struct nlattr **attrs = info->attrs;
37 int ifindex; 41 int ifindex;
38 42
39 if (!attrs[NL80211_ATTR_IFINDEX]) 43 if (!attrs[NL80211_ATTR_IFINDEX])
40 return -EINVAL; 44 return -EINVAL;
41 45
42 ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]); 46 ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
43 *dev = dev_get_by_index(&init_net, ifindex); 47 *dev = dev_get_by_index(genl_info_net(info), ifindex);
44 if (!*dev) 48 if (!*dev)
45 return -ENODEV; 49 return -ENODEV;
46 50
47 *rdev = cfg80211_get_dev_from_ifindex(ifindex); 51 *rdev = cfg80211_get_dev_from_ifindex(genl_info_net(info), ifindex);
48 if (IS_ERR(*rdev)) { 52 if (IS_ERR(*rdev)) {
49 dev_put(*dev); 53 dev_put(*dev);
50 return PTR_ERR(*rdev); 54 return PTR_ERR(*rdev);
@@ -133,6 +137,7 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
133 [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG }, 137 [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG },
134 [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 }, 138 [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 },
135 [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 }, 139 [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
140 [NL80211_ATTR_PID] = { .type = NLA_U32 },
136}; 141};
137 142
138/* policy for the attributes */ 143/* policy for the attributes */
@@ -532,6 +537,10 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
532 CMD(deauth, DEAUTHENTICATE); 537 CMD(deauth, DEAUTHENTICATE);
533 CMD(disassoc, DISASSOCIATE); 538 CMD(disassoc, DISASSOCIATE);
534 CMD(join_ibss, JOIN_IBSS); 539 CMD(join_ibss, JOIN_IBSS);
540 if (dev->wiphy.netnsok) {
541 i++;
542 NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS);
543 }
535 544
536#undef CMD 545#undef CMD
537 546
@@ -562,6 +571,8 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
562 571
563 mutex_lock(&cfg80211_mutex); 572 mutex_lock(&cfg80211_mutex);
564 list_for_each_entry(dev, &cfg80211_rdev_list, list) { 573 list_for_each_entry(dev, &cfg80211_rdev_list, list) {
574 if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk)))
575 continue;
565 if (++idx <= start) 576 if (++idx <= start)
566 continue; 577 continue;
567 if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).pid, 578 if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).pid,
@@ -867,6 +878,8 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
867 878
868 mutex_lock(&cfg80211_mutex); 879 mutex_lock(&cfg80211_mutex);
869 list_for_each_entry(dev, &cfg80211_rdev_list, list) { 880 list_for_each_entry(dev, &cfg80211_rdev_list, list) {
881 if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk)))
882 continue;
870 if (wp_idx < wp_start) { 883 if (wp_idx < wp_start) {
871 wp_idx++; 884 wp_idx++;
872 continue; 885 continue;
@@ -907,7 +920,7 @@ static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
907 struct net_device *netdev; 920 struct net_device *netdev;
908 int err; 921 int err;
909 922
910 err = get_rdev_dev_by_info_ifindex(info->attrs, &dev, &netdev); 923 err = get_rdev_dev_by_info_ifindex(info, &dev, &netdev);
911 if (err) 924 if (err)
912 return err; 925 return err;
913 926
@@ -975,7 +988,7 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
975 988
976 rtnl_lock(); 989 rtnl_lock();
977 990
978 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 991 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
979 if (err) 992 if (err)
980 goto unlock_rtnl; 993 goto unlock_rtnl;
981 994
@@ -1098,26 +1111,25 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
1098static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) 1111static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
1099{ 1112{
1100 struct cfg80211_registered_device *rdev; 1113 struct cfg80211_registered_device *rdev;
1101 int ifindex, err; 1114 int err;
1102 struct net_device *dev; 1115 struct net_device *dev;
1103 1116
1104 rtnl_lock(); 1117 rtnl_lock();
1105 1118
1106 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1119 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1107 if (err) 1120 if (err)
1108 goto unlock_rtnl; 1121 goto unlock_rtnl;
1109 ifindex = dev->ifindex;
1110 dev_put(dev);
1111 1122
1112 if (!rdev->ops->del_virtual_intf) { 1123 if (!rdev->ops->del_virtual_intf) {
1113 err = -EOPNOTSUPP; 1124 err = -EOPNOTSUPP;
1114 goto out; 1125 goto out;
1115 } 1126 }
1116 1127
1117 err = rdev->ops->del_virtual_intf(&rdev->wiphy, ifindex); 1128 err = rdev->ops->del_virtual_intf(&rdev->wiphy, dev);
1118 1129
1119 out: 1130 out:
1120 cfg80211_unlock_rdev(rdev); 1131 cfg80211_unlock_rdev(rdev);
1132 dev_put(dev);
1121 unlock_rtnl: 1133 unlock_rtnl:
1122 rtnl_unlock(); 1134 rtnl_unlock();
1123 return err; 1135 return err;
@@ -1195,7 +1207,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
1195 1207
1196 rtnl_lock(); 1208 rtnl_lock();
1197 1209
1198 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1210 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1199 if (err) 1211 if (err)
1200 goto unlock_rtnl; 1212 goto unlock_rtnl;
1201 1213
@@ -1274,7 +1286,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
1274 1286
1275 rtnl_lock(); 1287 rtnl_lock();
1276 1288
1277 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1289 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1278 if (err) 1290 if (err)
1279 goto unlock_rtnl; 1291 goto unlock_rtnl;
1280 1292
@@ -1333,7 +1345,7 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
1333 1345
1334 rtnl_lock(); 1346 rtnl_lock();
1335 1347
1336 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1348 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1337 if (err) 1349 if (err)
1338 goto unlock_rtnl; 1350 goto unlock_rtnl;
1339 1351
@@ -1380,7 +1392,7 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
1380 1392
1381 rtnl_lock(); 1393 rtnl_lock();
1382 1394
1383 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1395 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1384 if (err) 1396 if (err)
1385 goto unlock_rtnl; 1397 goto unlock_rtnl;
1386 1398
@@ -1429,7 +1441,7 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1429 1441
1430 rtnl_lock(); 1442 rtnl_lock();
1431 1443
1432 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1444 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1433 if (err) 1445 if (err)
1434 goto unlock_rtnl; 1446 goto unlock_rtnl;
1435 1447
@@ -1516,7 +1528,7 @@ static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
1516 1528
1517 rtnl_lock(); 1529 rtnl_lock();
1518 1530
1519 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1531 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1520 if (err) 1532 if (err)
1521 goto unlock_rtnl; 1533 goto unlock_rtnl;
1522 1534
@@ -1726,13 +1738,13 @@ static int nl80211_dump_station(struct sk_buff *skb,
1726 1738
1727 rtnl_lock(); 1739 rtnl_lock();
1728 1740
1729 netdev = __dev_get_by_index(&init_net, ifidx); 1741 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
1730 if (!netdev) { 1742 if (!netdev) {
1731 err = -ENODEV; 1743 err = -ENODEV;
1732 goto out_rtnl; 1744 goto out_rtnl;
1733 } 1745 }
1734 1746
1735 dev = cfg80211_get_dev_from_ifindex(ifidx); 1747 dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
1736 if (IS_ERR(dev)) { 1748 if (IS_ERR(dev)) {
1737 err = PTR_ERR(dev); 1749 err = PTR_ERR(dev);
1738 goto out_rtnl; 1750 goto out_rtnl;
@@ -1791,7 +1803,7 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
1791 1803
1792 rtnl_lock(); 1804 rtnl_lock();
1793 1805
1794 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1806 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1795 if (err) 1807 if (err)
1796 goto out_rtnl; 1808 goto out_rtnl;
1797 1809
@@ -1829,14 +1841,16 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
1829/* 1841/*
1830 * Get vlan interface making sure it is on the right wiphy. 1842 * Get vlan interface making sure it is on the right wiphy.
1831 */ 1843 */
1832static int get_vlan(struct nlattr *vlanattr, 1844static int get_vlan(struct genl_info *info,
1833 struct cfg80211_registered_device *rdev, 1845 struct cfg80211_registered_device *rdev,
1834 struct net_device **vlan) 1846 struct net_device **vlan)
1835{ 1847{
1848 struct nlattr *vlanattr = info->attrs[NL80211_ATTR_STA_VLAN];
1836 *vlan = NULL; 1849 *vlan = NULL;
1837 1850
1838 if (vlanattr) { 1851 if (vlanattr) {
1839 *vlan = dev_get_by_index(&init_net, nla_get_u32(vlanattr)); 1852 *vlan = dev_get_by_index(genl_info_net(info),
1853 nla_get_u32(vlanattr));
1840 if (!*vlan) 1854 if (!*vlan)
1841 return -ENODEV; 1855 return -ENODEV;
1842 if (!(*vlan)->ieee80211_ptr) 1856 if (!(*vlan)->ieee80211_ptr)
@@ -1891,11 +1905,11 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
1891 1905
1892 rtnl_lock(); 1906 rtnl_lock();
1893 1907
1894 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1908 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1895 if (err) 1909 if (err)
1896 goto out_rtnl; 1910 goto out_rtnl;
1897 1911
1898 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], rdev, &params.vlan); 1912 err = get_vlan(info, rdev, &params.vlan);
1899 if (err) 1913 if (err)
1900 goto out; 1914 goto out;
1901 1915
@@ -2004,11 +2018,11 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
2004 2018
2005 rtnl_lock(); 2019 rtnl_lock();
2006 2020
2007 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2021 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2008 if (err) 2022 if (err)
2009 goto out_rtnl; 2023 goto out_rtnl;
2010 2024
2011 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], rdev, &params.vlan); 2025 err = get_vlan(info, rdev, &params.vlan);
2012 if (err) 2026 if (err)
2013 goto out; 2027 goto out;
2014 2028
@@ -2079,7 +2093,7 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
2079 2093
2080 rtnl_lock(); 2094 rtnl_lock();
2081 2095
2082 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2096 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2083 if (err) 2097 if (err)
2084 goto out_rtnl; 2098 goto out_rtnl;
2085 2099
@@ -2185,13 +2199,13 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
2185 2199
2186 rtnl_lock(); 2200 rtnl_lock();
2187 2201
2188 netdev = __dev_get_by_index(&init_net, ifidx); 2202 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
2189 if (!netdev) { 2203 if (!netdev) {
2190 err = -ENODEV; 2204 err = -ENODEV;
2191 goto out_rtnl; 2205 goto out_rtnl;
2192 } 2206 }
2193 2207
2194 dev = cfg80211_get_dev_from_ifindex(ifidx); 2208 dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
2195 if (IS_ERR(dev)) { 2209 if (IS_ERR(dev)) {
2196 err = PTR_ERR(dev); 2210 err = PTR_ERR(dev);
2197 goto out_rtnl; 2211 goto out_rtnl;
@@ -2255,7 +2269,7 @@ static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
2255 2269
2256 rtnl_lock(); 2270 rtnl_lock();
2257 2271
2258 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2272 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2259 if (err) 2273 if (err)
2260 goto out_rtnl; 2274 goto out_rtnl;
2261 2275
@@ -2314,7 +2328,7 @@ static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
2314 2328
2315 rtnl_lock(); 2329 rtnl_lock();
2316 2330
2317 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2331 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2318 if (err) 2332 if (err)
2319 goto out_rtnl; 2333 goto out_rtnl;
2320 2334
@@ -2362,7 +2376,7 @@ static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
2362 2376
2363 rtnl_lock(); 2377 rtnl_lock();
2364 2378
2365 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2379 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2366 if (err) 2380 if (err)
2367 goto out_rtnl; 2381 goto out_rtnl;
2368 2382
@@ -2404,7 +2418,7 @@ static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
2404 2418
2405 rtnl_lock(); 2419 rtnl_lock();
2406 2420
2407 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2421 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2408 if (err) 2422 if (err)
2409 goto out_rtnl; 2423 goto out_rtnl;
2410 2424
@@ -2455,7 +2469,7 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
2455 2469
2456 rtnl_lock(); 2470 rtnl_lock();
2457 2471
2458 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2472 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2459 if (err) 2473 if (err)
2460 goto out_rtnl; 2474 goto out_rtnl;
2461 2475
@@ -2574,7 +2588,7 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
2574 rtnl_lock(); 2588 rtnl_lock();
2575 2589
2576 /* Look up our device */ 2590 /* Look up our device */
2577 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2591 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2578 if (err) 2592 if (err)
2579 goto out_rtnl; 2593 goto out_rtnl;
2580 2594
@@ -2691,7 +2705,7 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
2691 2705
2692 rtnl_lock(); 2706 rtnl_lock();
2693 2707
2694 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2708 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2695 if (err) 2709 if (err)
2696 goto out_rtnl; 2710 goto out_rtnl;
2697 2711
@@ -2947,7 +2961,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2947 2961
2948 rtnl_lock(); 2962 rtnl_lock();
2949 2963
2950 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2964 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2951 if (err) 2965 if (err)
2952 goto out_rtnl; 2966 goto out_rtnl;
2953 2967
@@ -3069,14 +3083,16 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3069 request->ie_len); 3083 request->ie_len);
3070 } 3084 }
3071 3085
3072 request->ifidx = dev->ifindex; 3086 request->dev = dev;
3073 request->wiphy = &rdev->wiphy; 3087 request->wiphy = &rdev->wiphy;
3074 3088
3075 rdev->scan_req = request; 3089 rdev->scan_req = request;
3076 err = rdev->ops->scan(&rdev->wiphy, dev, request); 3090 err = rdev->ops->scan(&rdev->wiphy, dev, request);
3077 3091
3078 if (!err) 3092 if (!err) {
3079 nl80211_send_scan_start(rdev, dev); 3093 nl80211_send_scan_start(rdev, dev);
3094 dev_hold(dev);
3095 }
3080 3096
3081 out_free: 3097 out_free:
3082 if (err) { 3098 if (err) {
@@ -3198,11 +3214,11 @@ static int nl80211_dump_scan(struct sk_buff *skb,
3198 cb->args[0] = ifidx; 3214 cb->args[0] = ifidx;
3199 } 3215 }
3200 3216
3201 dev = dev_get_by_index(&init_net, ifidx); 3217 dev = dev_get_by_index(sock_net(skb->sk), ifidx);
3202 if (!dev) 3218 if (!dev)
3203 return -ENODEV; 3219 return -ENODEV;
3204 3220
3205 rdev = cfg80211_get_dev_from_ifindex(ifidx); 3221 rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
3206 if (IS_ERR(rdev)) { 3222 if (IS_ERR(rdev)) {
3207 err = PTR_ERR(rdev); 3223 err = PTR_ERR(rdev);
3208 goto out_put_netdev; 3224 goto out_put_netdev;
@@ -3312,7 +3328,7 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
3312 3328
3313 rtnl_lock(); 3329 rtnl_lock();
3314 3330
3315 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 3331 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3316 if (err) 3332 if (err)
3317 goto unlock_rtnl; 3333 goto unlock_rtnl;
3318 3334
@@ -3448,7 +3464,7 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
3448 3464
3449 rtnl_lock(); 3465 rtnl_lock();
3450 3466
3451 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 3467 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3452 if (err) 3468 if (err)
3453 goto unlock_rtnl; 3469 goto unlock_rtnl;
3454 3470
@@ -3531,7 +3547,7 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
3531 3547
3532 rtnl_lock(); 3548 rtnl_lock();
3533 3549
3534 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 3550 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3535 if (err) 3551 if (err)
3536 goto unlock_rtnl; 3552 goto unlock_rtnl;
3537 3553
@@ -3593,7 +3609,7 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
3593 3609
3594 rtnl_lock(); 3610 rtnl_lock();
3595 3611
3596 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 3612 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3597 if (err) 3613 if (err)
3598 goto unlock_rtnl; 3614 goto unlock_rtnl;
3599 3615
@@ -3666,7 +3682,7 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
3666 3682
3667 rtnl_lock(); 3683 rtnl_lock();
3668 3684
3669 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 3685 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3670 if (err) 3686 if (err)
3671 goto unlock_rtnl; 3687 goto unlock_rtnl;
3672 3688
@@ -3739,7 +3755,7 @@ static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
3739 3755
3740 rtnl_lock(); 3756 rtnl_lock();
3741 3757
3742 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 3758 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3743 if (err) 3759 if (err)
3744 goto unlock_rtnl; 3760 goto unlock_rtnl;
3745 3761
@@ -3924,7 +3940,7 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
3924 return err; 3940 return err;
3925 rtnl_lock(); 3941 rtnl_lock();
3926 3942
3927 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 3943 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3928 if (err) 3944 if (err)
3929 goto unlock_rtnl; 3945 goto unlock_rtnl;
3930 3946
@@ -4000,7 +4016,7 @@ static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
4000 4016
4001 rtnl_lock(); 4017 rtnl_lock();
4002 4018
4003 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 4019 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4004 if (err) 4020 if (err)
4005 goto unlock_rtnl; 4021 goto unlock_rtnl;
4006 4022
@@ -4024,6 +4040,47 @@ unlock_rtnl:
4024 return err; 4040 return err;
4025} 4041}
4026 4042
4043static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
4044{
4045 struct cfg80211_registered_device *rdev;
4046 struct net *net;
4047 int err;
4048 u32 pid;
4049
4050 if (!info->attrs[NL80211_ATTR_PID])
4051 return -EINVAL;
4052
4053 pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]);
4054
4055 rtnl_lock();
4056
4057 rdev = cfg80211_get_dev_from_info(info);
4058 if (IS_ERR(rdev)) {
4059 err = PTR_ERR(rdev);
4060 goto out;
4061 }
4062
4063 net = get_net_ns_by_pid(pid);
4064 if (IS_ERR(net)) {
4065 err = PTR_ERR(net);
4066 goto out;
4067 }
4068
4069 err = 0;
4070
4071 /* check if anything to do */
4072 if (net_eq(wiphy_net(&rdev->wiphy), net))
4073 goto out_put_net;
4074
4075 err = cfg80211_switch_netns(rdev, net);
4076 out_put_net:
4077 put_net(net);
4078 out:
4079 cfg80211_unlock_rdev(rdev);
4080 rtnl_unlock();
4081 return err;
4082}
4083
4027static struct genl_ops nl80211_ops[] = { 4084static struct genl_ops nl80211_ops[] = {
4028 { 4085 {
4029 .cmd = NL80211_CMD_GET_WIPHY, 4086 .cmd = NL80211_CMD_GET_WIPHY,
@@ -4257,6 +4314,12 @@ static struct genl_ops nl80211_ops[] = {
4257 .policy = nl80211_policy, 4314 .policy = nl80211_policy,
4258 .flags = GENL_ADMIN_PERM, 4315 .flags = GENL_ADMIN_PERM,
4259 }, 4316 },
4317 {
4318 .cmd = NL80211_CMD_SET_WIPHY_NETNS,
4319 .doit = nl80211_wiphy_netns,
4320 .policy = nl80211_policy,
4321 .flags = GENL_ADMIN_PERM,
4322 },
4260}; 4323};
4261static struct genl_multicast_group nl80211_mlme_mcgrp = { 4324static struct genl_multicast_group nl80211_mlme_mcgrp = {
4262 .name = "mlme", 4325 .name = "mlme",
@@ -4288,7 +4351,8 @@ void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
4288 return; 4351 return;
4289 } 4352 }
4290 4353
4291 genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL); 4354 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4355 nl80211_config_mcgrp.id, GFP_KERNEL);
4292} 4356}
4293 4357
4294static int nl80211_add_scan_req(struct sk_buff *msg, 4358static int nl80211_add_scan_req(struct sk_buff *msg,
@@ -4365,7 +4429,8 @@ void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
4365 return; 4429 return;
4366 } 4430 }
4367 4431
4368 genlmsg_multicast(msg, 0, nl80211_scan_mcgrp.id, GFP_KERNEL); 4432 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4433 nl80211_scan_mcgrp.id, GFP_KERNEL);
4369} 4434}
4370 4435
4371void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, 4436void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
@@ -4383,7 +4448,8 @@ void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
4383 return; 4448 return;
4384 } 4449 }
4385 4450
4386 genlmsg_multicast(msg, 0, nl80211_scan_mcgrp.id, GFP_KERNEL); 4451 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4452 nl80211_scan_mcgrp.id, GFP_KERNEL);
4387} 4453}
4388 4454
4389void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, 4455void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
@@ -4401,7 +4467,8 @@ void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
4401 return; 4467 return;
4402 } 4468 }
4403 4469
4404 genlmsg_multicast(msg, 0, nl80211_scan_mcgrp.id, GFP_KERNEL); 4470 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4471 nl80211_scan_mcgrp.id, GFP_KERNEL);
4405} 4472}
4406 4473
4407/* 4474/*
@@ -4450,7 +4517,10 @@ void nl80211_send_reg_change_event(struct regulatory_request *request)
4450 return; 4517 return;
4451 } 4518 }
4452 4519
4453 genlmsg_multicast(msg, 0, nl80211_regulatory_mcgrp.id, GFP_KERNEL); 4520 rtnl_lock();
4521 genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id,
4522 GFP_KERNEL);
4523 rtnl_unlock();
4454 4524
4455 return; 4525 return;
4456 4526
@@ -4486,7 +4556,8 @@ static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
4486 return; 4556 return;
4487 } 4557 }
4488 4558
4489 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp); 4559 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4560 nl80211_mlme_mcgrp.id, gfp);
4490 return; 4561 return;
4491 4562
4492 nla_put_failure: 4563 nla_put_failure:
@@ -4553,7 +4624,8 @@ static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
4553 return; 4624 return;
4554 } 4625 }
4555 4626
4556 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp); 4627 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4628 nl80211_mlme_mcgrp.id, gfp);
4557 return; 4629 return;
4558 4630
4559 nla_put_failure: 4631 nla_put_failure:
@@ -4611,7 +4683,8 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
4611 return; 4683 return;
4612 } 4684 }
4613 4685
4614 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp); 4686 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4687 nl80211_mlme_mcgrp.id, gfp);
4615 return; 4688 return;
4616 4689
4617 nla_put_failure: 4690 nla_put_failure:
@@ -4651,7 +4724,8 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
4651 return; 4724 return;
4652 } 4725 }
4653 4726
4654 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp); 4727 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4728 nl80211_mlme_mcgrp.id, gfp);
4655 return; 4729 return;
4656 4730
4657 nla_put_failure: 4731 nla_put_failure:
@@ -4691,7 +4765,8 @@ void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
4691 return; 4765 return;
4692 } 4766 }
4693 4767
4694 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_KERNEL); 4768 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4769 nl80211_mlme_mcgrp.id, GFP_KERNEL);
4695 return; 4770 return;
4696 4771
4697 nla_put_failure: 4772 nla_put_failure:
@@ -4726,7 +4801,8 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
4726 return; 4801 return;
4727 } 4802 }
4728 4803
4729 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp); 4804 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4805 nl80211_mlme_mcgrp.id, gfp);
4730 return; 4806 return;
4731 4807
4732 nla_put_failure: 4808 nla_put_failure:
@@ -4766,7 +4842,8 @@ void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
4766 return; 4842 return;
4767 } 4843 }
4768 4844
4769 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp); 4845 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4846 nl80211_mlme_mcgrp.id, gfp);
4770 return; 4847 return;
4771 4848
4772 nla_put_failure: 4849 nla_put_failure:
@@ -4819,7 +4896,10 @@ void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
4819 return; 4896 return;
4820 } 4897 }
4821 4898
4822 genlmsg_multicast(msg, 0, nl80211_regulatory_mcgrp.id, GFP_ATOMIC); 4899 rcu_read_lock();
4900 genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id,
4901 GFP_ATOMIC);
4902 rcu_read_unlock();
4823 4903
4824 return; 4904 return;
4825 4905
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);
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 82de2d9795f4..a19741097989 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -86,7 +86,7 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev)
86 wdev->conn->params.ssid_len); 86 wdev->conn->params.ssid_len);
87 request->ssids[0].ssid_len = wdev->conn->params.ssid_len; 87 request->ssids[0].ssid_len = wdev->conn->params.ssid_len;
88 88
89 request->ifidx = wdev->netdev->ifindex; 89 request->dev = wdev->netdev;
90 request->wiphy = &rdev->wiphy; 90 request->wiphy = &rdev->wiphy;
91 91
92 rdev->scan_req = request; 92 rdev->scan_req = request;
@@ -95,6 +95,7 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev)
95 if (!err) { 95 if (!err) {
96 wdev->conn->state = CFG80211_CONN_SCANNING; 96 wdev->conn->state = CFG80211_CONN_SCANNING;
97 nl80211_send_scan_start(rdev, wdev->netdev); 97 nl80211_send_scan_start(rdev, wdev->netdev);
98 dev_hold(wdev->netdev);
98 } else { 99 } else {
99 rdev->scan_req = NULL; 100 rdev->scan_req = NULL;
100 kfree(request); 101 kfree(request);