aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/nl80211.c50
1 files changed, 31 insertions, 19 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index ba439664c2e0..4d708cea390f 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -47,22 +47,21 @@ static struct genl_family nl80211_fam = {
47}; 47};
48 48
49/* internal helper: get rdev and dev */ 49/* internal helper: get rdev and dev */
50static int get_rdev_dev_by_info_ifindex(struct genl_info *info, 50static int get_rdev_dev_by_ifindex(struct net *netns, struct nlattr **attrs,
51 struct cfg80211_registered_device **rdev, 51 struct cfg80211_registered_device **rdev,
52 struct net_device **dev) 52 struct net_device **dev)
53{ 53{
54 struct nlattr **attrs = info->attrs;
55 int ifindex; 54 int ifindex;
56 55
57 if (!attrs[NL80211_ATTR_IFINDEX]) 56 if (!attrs[NL80211_ATTR_IFINDEX])
58 return -EINVAL; 57 return -EINVAL;
59 58
60 ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]); 59 ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
61 *dev = dev_get_by_index(genl_info_net(info), ifindex); 60 *dev = dev_get_by_index(netns, ifindex);
62 if (!*dev) 61 if (!*dev)
63 return -ENODEV; 62 return -ENODEV;
64 63
65 *rdev = cfg80211_get_dev_from_ifindex(genl_info_net(info), ifindex); 64 *rdev = cfg80211_get_dev_from_ifindex(netns, ifindex);
66 if (IS_ERR(*rdev)) { 65 if (IS_ERR(*rdev)) {
67 dev_put(*dev); 66 dev_put(*dev);
68 return PTR_ERR(*rdev); 67 return PTR_ERR(*rdev);
@@ -4795,7 +4794,7 @@ static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
4795static int nl80211_testmode_dump(struct sk_buff *skb, 4794static int nl80211_testmode_dump(struct sk_buff *skb,
4796 struct netlink_callback *cb) 4795 struct netlink_callback *cb)
4797{ 4796{
4798 struct cfg80211_registered_device *dev; 4797 struct cfg80211_registered_device *rdev;
4799 int err; 4798 int err;
4800 long phy_idx; 4799 long phy_idx;
4801 void *data = NULL; 4800 void *data = NULL;
@@ -4813,9 +4812,21 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
4813 nl80211_policy); 4812 nl80211_policy);
4814 if (err) 4813 if (err)
4815 return err; 4814 return err;
4816 if (!nl80211_fam.attrbuf[NL80211_ATTR_WIPHY]) 4815 if (nl80211_fam.attrbuf[NL80211_ATTR_WIPHY]) {
4817 return -EINVAL; 4816 phy_idx = nla_get_u32(
4818 phy_idx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_WIPHY]); 4817 nl80211_fam.attrbuf[NL80211_ATTR_WIPHY]);
4818 } else {
4819 struct net_device *netdev;
4820
4821 err = get_rdev_dev_by_ifindex(sock_net(skb->sk),
4822 nl80211_fam.attrbuf,
4823 &rdev, &netdev);
4824 if (err)
4825 return err;
4826 dev_put(netdev);
4827 phy_idx = rdev->wiphy_idx;
4828 cfg80211_unlock_rdev(rdev);
4829 }
4819 if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA]) 4830 if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA])
4820 cb->args[1] = 4831 cb->args[1] =
4821 (long)nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA]; 4832 (long)nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA];
@@ -4827,15 +4838,15 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
4827 } 4838 }
4828 4839
4829 mutex_lock(&cfg80211_mutex); 4840 mutex_lock(&cfg80211_mutex);
4830 dev = cfg80211_rdev_by_wiphy_idx(phy_idx); 4841 rdev = cfg80211_rdev_by_wiphy_idx(phy_idx);
4831 if (!dev) { 4842 if (!rdev) {
4832 mutex_unlock(&cfg80211_mutex); 4843 mutex_unlock(&cfg80211_mutex);
4833 return -ENOENT; 4844 return -ENOENT;
4834 } 4845 }
4835 cfg80211_lock_rdev(dev); 4846 cfg80211_lock_rdev(rdev);
4836 mutex_unlock(&cfg80211_mutex); 4847 mutex_unlock(&cfg80211_mutex);
4837 4848
4838 if (!dev->ops->testmode_dump) { 4849 if (!rdev->ops->testmode_dump) {
4839 err = -EOPNOTSUPP; 4850 err = -EOPNOTSUPP;
4840 goto out_err; 4851 goto out_err;
4841 } 4852 }
@@ -4846,7 +4857,7 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
4846 NL80211_CMD_TESTMODE); 4857 NL80211_CMD_TESTMODE);
4847 struct nlattr *tmdata; 4858 struct nlattr *tmdata;
4848 4859
4849 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, dev->wiphy_idx) < 0) { 4860 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, phy_idx) < 0) {
4850 genlmsg_cancel(skb, hdr); 4861 genlmsg_cancel(skb, hdr);
4851 break; 4862 break;
4852 } 4863 }
@@ -4856,8 +4867,8 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
4856 genlmsg_cancel(skb, hdr); 4867 genlmsg_cancel(skb, hdr);
4857 break; 4868 break;
4858 } 4869 }
4859 err = dev->ops->testmode_dump(&dev->wiphy, skb, cb, 4870 err = rdev->ops->testmode_dump(&rdev->wiphy, skb, cb,
4860 data, data_len); 4871 data, data_len);
4861 nla_nest_end(skb, tmdata); 4872 nla_nest_end(skb, tmdata);
4862 4873
4863 if (err == -ENOBUFS || err == -ENOENT) { 4874 if (err == -ENOBUFS || err == -ENOENT) {
@@ -4875,7 +4886,7 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
4875 /* see above */ 4886 /* see above */
4876 cb->args[0] = phy_idx + 1; 4887 cb->args[0] = phy_idx + 1;
4877 out_err: 4888 out_err:
4878 cfg80211_unlock_rdev(dev); 4889 cfg80211_unlock_rdev(rdev);
4879 return err; 4890 return err;
4880} 4891}
4881 4892
@@ -6110,7 +6121,8 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
6110 } 6121 }
6111 info->user_ptr[0] = rdev; 6122 info->user_ptr[0] = rdev;
6112 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) { 6123 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
6113 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); 6124 err = get_rdev_dev_by_ifindex(genl_info_net(info), info->attrs,
6125 &rdev, &dev);
6114 if (err) { 6126 if (err) {
6115 if (rtnl) 6127 if (rtnl)
6116 rtnl_unlock(); 6128 rtnl_unlock();