Commit 36b50bab authored by Eric W. Biederman's avatar Eric W. Biederman Committed by David S. Miller

tun: Grab the netns in open.

Grabbing namespaces in open, and putting them in close always seems to
be the cleanest approach with the fewest surprises.

So now that we have tun_file so we have somepleace to put the network
namespace, let's grab the network namespace on file open and put on
file close.
Signed-off-by: default avatarEric W. Biederman <ebiederm@aristanetworks.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 631ab46b
...@@ -89,6 +89,7 @@ struct tap_filter { ...@@ -89,6 +89,7 @@ struct tap_filter {
struct tun_file { struct tun_file {
struct tun_struct *tun; struct tun_struct *tun;
struct net *net;
}; };
struct tun_struct { struct tun_struct {
...@@ -131,7 +132,6 @@ static int tun_attach(struct tun_struct *tun, struct file *file) ...@@ -131,7 +132,6 @@ static int tun_attach(struct tun_struct *tun, struct file *file)
tfile->tun = tun; tfile->tun = tun;
tun->tfile = tfile; tun->tfile = tfile;
get_net(dev_net(tun->dev));
return 0; return 0;
} }
...@@ -143,7 +143,6 @@ static void __tun_detach(struct tun_struct *tun) ...@@ -143,7 +143,6 @@ static void __tun_detach(struct tun_struct *tun)
/* Detach from net device */ /* Detach from net device */
tfile->tun = NULL; tfile->tun = NULL;
tun->tfile = NULL; tun->tfile = NULL;
put_net(dev_net(tun->dev));
/* Drop read queue */ /* Drop read queue */
skb_queue_purge(&tun->readq); skb_queue_purge(&tun->readq);
...@@ -936,6 +935,7 @@ static int set_offload(struct net_device *dev, unsigned long arg) ...@@ -936,6 +935,7 @@ static int set_offload(struct net_device *dev, unsigned long arg)
static int tun_chr_ioctl(struct inode *inode, struct file *file, static int tun_chr_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
struct tun_file *tfile = file->private_data;
struct tun_struct *tun; struct tun_struct *tun;
void __user* argp = (void __user*)arg; void __user* argp = (void __user*)arg;
struct ifreq ifr; struct ifreq ifr;
...@@ -954,14 +954,14 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file, ...@@ -954,14 +954,14 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
(unsigned int __user*)argp); (unsigned int __user*)argp);
} }
tun = tun_get(file); tun = __tun_get(tfile);
if (cmd == TUNSETIFF && !tun) { if (cmd == TUNSETIFF && !tun) {
int err; int err;
ifr.ifr_name[IFNAMSIZ-1] = '\0'; ifr.ifr_name[IFNAMSIZ-1] = '\0';
rtnl_lock(); rtnl_lock();
err = tun_set_iff(current->nsproxy->net_ns, file, &ifr); err = tun_set_iff(tfile->net, file, &ifr);
rtnl_unlock(); rtnl_unlock();
if (err) if (err)
...@@ -1125,6 +1125,7 @@ static int tun_chr_open(struct inode *inode, struct file * file) ...@@ -1125,6 +1125,7 @@ static int tun_chr_open(struct inode *inode, struct file * file)
if (!tfile) if (!tfile)
return -ENOMEM; return -ENOMEM;
tfile->tun = NULL; tfile->tun = NULL;
tfile->net = get_net(current->nsproxy->net_ns);
file->private_data = tfile; file->private_data = tfile;
return 0; return 0;
} }
...@@ -1148,6 +1149,7 @@ static int tun_chr_close(struct inode *inode, struct file *file) ...@@ -1148,6 +1149,7 @@ static int tun_chr_close(struct inode *inode, struct file *file)
rtnl_unlock(); rtnl_unlock();
} }
put_net(tfile->net);
kfree(tfile); kfree(tfile);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment