aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.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/nl80211.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/nl80211.c')
-rw-r--r--net/wireless/nl80211.c202
1 files changed, 141 insertions, 61 deletions
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