diff options
Diffstat (limited to 'net/core/net_namespace.c')
| -rw-r--r-- | net/core/net_namespace.c | 65 | 
1 files changed, 65 insertions, 0 deletions
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 2e2dce6583e..6c6b86d0da1 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -8,6 +8,8 @@  #include <linux/idr.h>  #include <linux/rculist.h>  #include <linux/nsproxy.h> +#include <linux/proc_fs.h> +#include <linux/file.h>  #include <net/net_namespace.h>  #include <net/netns/generic.h> @@ -302,6 +304,28 @@ void __put_net(struct net *net)  }  EXPORT_SYMBOL_GPL(__put_net); +struct net *get_net_ns_by_fd(int fd) +{ +	struct proc_inode *ei; +	struct file *file; +	struct net *net; + +	net = ERR_PTR(-EINVAL); +	file = proc_ns_fget(fd); +	if (!file) +		goto out; + +	ei = PROC_I(file->f_dentry->d_inode); +	if (ei->ns_ops != &netns_operations) +		goto out; + +	net = get_net(ei->ns); +out: +	if (file) +		fput(file); +	return net; +} +  #else  struct net *copy_net_ns(unsigned long flags, struct net *old_net)  { @@ -309,6 +333,11 @@ struct net *copy_net_ns(unsigned long flags, struct net *old_net)  		return ERR_PTR(-EINVAL);  	return old_net;  } + +struct net *get_net_ns_by_fd(int fd) +{ +	return ERR_PTR(-EINVAL); +}  #endif  struct net *get_net_ns_by_pid(pid_t pid) @@ -561,3 +590,39 @@ void unregister_pernet_device(struct pernet_operations *ops)  	mutex_unlock(&net_mutex);  }  EXPORT_SYMBOL_GPL(unregister_pernet_device); + +#ifdef CONFIG_NET_NS +static void *netns_get(struct task_struct *task) +{ +	struct net *net = NULL; +	struct nsproxy *nsproxy; + +	rcu_read_lock(); +	nsproxy = task_nsproxy(task); +	if (nsproxy) +		net = get_net(nsproxy->net_ns); +	rcu_read_unlock(); + +	return net; +} + +static void netns_put(void *ns) +{ +	put_net(ns); +} + +static int netns_install(struct nsproxy *nsproxy, void *ns) +{ +	put_net(nsproxy->net_ns); +	nsproxy->net_ns = get_net(ns); +	return 0; +} + +const struct proc_ns_operations netns_operations = { +	.name		= "net", +	.type		= CLONE_NEWNET, +	.get		= netns_get, +	.put		= netns_put, +	.install	= netns_install, +}; +#endif  |