OSDN Git Service

nl80211: Allow set network namespace by fd
authorVadim Kochan <vadim4j@gmail.com>
Mon, 12 Jan 2015 14:34:05 +0000 (16:34 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 23 Jan 2015 09:25:25 +0000 (10:25 +0100)
Added new NL80211_ATTR_NETNS_FD which allows to
set namespace via nl80211 by fd.

Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/uapi/linux/nl80211.h
net/core/net_namespace.c
net/wireless/nl80211.c

index f52797a..f68532b 100644 (file)
@@ -2098,6 +2098,8 @@ enum nl80211_attrs {
 
        NL80211_ATTR_SURVEY_RADIO_STATS,
 
+       NL80211_ATTR_NETNS_FD,
+
        /* add attributes here, update the policy in nl80211.c */
 
        __NL80211_ATTR_AFTER_LAST,
index 7f15517..5d5ee8f 100644 (file)
@@ -361,6 +361,7 @@ struct net *get_net_ns_by_fd(int fd)
        return ERR_PTR(-EINVAL);
 }
 #endif
+EXPORT_SYMBOL_GPL(get_net_ns_by_fd);
 
 struct net *get_net_ns_by_pid(pid_t pid)
 {
index c5661c5..c64100e 100644 (file)
@@ -397,6 +397,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
        [NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 },
        [NL80211_ATTR_MAC_MASK] = { .len = ETH_ALEN },
        [NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG },
+       [NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 },
 };
 
 /* policy for the key attributes */
@@ -7762,14 +7763,19 @@ static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
        struct cfg80211_registered_device *rdev = info->user_ptr[0];
        struct net *net;
        int err;
-       u32 pid;
 
-       if (!info->attrs[NL80211_ATTR_PID])
-               return -EINVAL;
+       if (info->attrs[NL80211_ATTR_PID]) {
+               u32 pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]);
+
+               net = get_net_ns_by_pid(pid);
+       } else if (info->attrs[NL80211_ATTR_NETNS_FD]) {
+               u32 fd = nla_get_u32(info->attrs[NL80211_ATTR_NETNS_FD]);
 
-       pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]);
+               net = get_net_ns_by_fd(fd);
+       } else {
+               return -EINVAL;
+       }
 
-       net = get_net_ns_by_pid(pid);
        if (IS_ERR(net))
                return PTR_ERR(net);