};
 
 /* internal helper: get rdev and dev */
-static int get_rdev_dev_by_info_ifindex(struct genl_info *info,
-                                      struct cfg80211_registered_device **rdev,
-                                      struct net_device **dev)
+static int get_rdev_dev_by_ifindex(struct net *netns, struct nlattr **attrs,
+                                  struct cfg80211_registered_device **rdev,
+                                  struct net_device **dev)
 {
-       struct nlattr **attrs = info->attrs;
        int ifindex;
 
        if (!attrs[NL80211_ATTR_IFINDEX])
                return -EINVAL;
 
        ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
-       *dev = dev_get_by_index(genl_info_net(info), ifindex);
+       *dev = dev_get_by_index(netns, ifindex);
        if (!*dev)
                return -ENODEV;
 
-       *rdev = cfg80211_get_dev_from_ifindex(genl_info_net(info), ifindex);
+       *rdev = cfg80211_get_dev_from_ifindex(netns, ifindex);
        if (IS_ERR(*rdev)) {
                dev_put(*dev);
                return PTR_ERR(*rdev);
 static int nl80211_testmode_dump(struct sk_buff *skb,
                                 struct netlink_callback *cb)
 {
-       struct cfg80211_registered_device *dev;
+       struct cfg80211_registered_device *rdev;
        int err;
        long phy_idx;
        void *data = NULL;
                                  nl80211_policy);
                if (err)
                        return err;
-               if (!nl80211_fam.attrbuf[NL80211_ATTR_WIPHY])
-                       return -EINVAL;
-               phy_idx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_WIPHY]);
+               if (nl80211_fam.attrbuf[NL80211_ATTR_WIPHY]) {
+                       phy_idx = nla_get_u32(
+                               nl80211_fam.attrbuf[NL80211_ATTR_WIPHY]);
+               } else {
+                       struct net_device *netdev;
+
+                       err = get_rdev_dev_by_ifindex(sock_net(skb->sk),
+                                                     nl80211_fam.attrbuf,
+                                                     &rdev, &netdev);
+                       if (err)
+                               return err;
+                       dev_put(netdev);
+                       phy_idx = rdev->wiphy_idx;
+                       cfg80211_unlock_rdev(rdev);
+               }
                if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA])
                        cb->args[1] =
                                (long)nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA];
        }
 
        mutex_lock(&cfg80211_mutex);
-       dev = cfg80211_rdev_by_wiphy_idx(phy_idx);
-       if (!dev) {
+       rdev = cfg80211_rdev_by_wiphy_idx(phy_idx);
+       if (!rdev) {
                mutex_unlock(&cfg80211_mutex);
                return -ENOENT;
        }
-       cfg80211_lock_rdev(dev);
+       cfg80211_lock_rdev(rdev);
        mutex_unlock(&cfg80211_mutex);
 
-       if (!dev->ops->testmode_dump) {
+       if (!rdev->ops->testmode_dump) {
                err = -EOPNOTSUPP;
                goto out_err;
        }
                                           NL80211_CMD_TESTMODE);
                struct nlattr *tmdata;
 
-               if (nla_put_u32(skb, NL80211_ATTR_WIPHY, dev->wiphy_idx) < 0) {
+               if (nla_put_u32(skb, NL80211_ATTR_WIPHY, phy_idx) < 0) {
                        genlmsg_cancel(skb, hdr);
                        break;
                }
                        genlmsg_cancel(skb, hdr);
                        break;
                }
-               err = dev->ops->testmode_dump(&dev->wiphy, skb, cb,
-                                             data, data_len);
+               err = rdev->ops->testmode_dump(&rdev->wiphy, skb, cb,
+                                              data, data_len);
                nla_nest_end(skb, tmdata);
 
                if (err == -ENOBUFS || err == -ENOENT) {
        /* see above */
        cb->args[0] = phy_idx + 1;
  out_err:
-       cfg80211_unlock_rdev(dev);
+       cfg80211_unlock_rdev(rdev);
        return err;
 }
 
                }
                info->user_ptr[0] = rdev;
        } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
-               err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
+               err = get_rdev_dev_by_ifindex(genl_info_net(info), info->attrs,
+                                             &rdev, &dev);
                if (err) {
                        if (rtnl)
                                rtnl_unlock();