aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tun.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r--drivers/net/tun.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index d3a665d2f7b8..dfbf58659771 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -89,6 +89,7 @@ struct tap_filter {
89 89
90struct tun_file { 90struct tun_file {
91 struct tun_struct *tun; 91 struct tun_struct *tun;
92 struct net *net;
92}; 93};
93 94
94struct tun_struct { 95struct tun_struct {
@@ -131,7 +132,6 @@ static int tun_attach(struct tun_struct *tun, struct file *file)
131 132
132 tfile->tun = tun; 133 tfile->tun = tun;
133 tun->tfile = tfile; 134 tun->tfile = tfile;
134 get_net(dev_net(tun->dev));
135 135
136 return 0; 136 return 0;
137} 137}
@@ -143,7 +143,6 @@ static void __tun_detach(struct tun_struct *tun)
143 /* Detach from net device */ 143 /* Detach from net device */
144 tfile->tun = NULL; 144 tfile->tun = NULL;
145 tun->tfile = NULL; 145 tun->tfile = NULL;
146 put_net(dev_net(tun->dev));
147 146
148 /* Drop read queue */ 147 /* Drop read queue */
149 skb_queue_purge(&tun->readq); 148 skb_queue_purge(&tun->readq);
@@ -936,6 +935,7 @@ static int set_offload(struct net_device *dev, unsigned long arg)
936static int tun_chr_ioctl(struct inode *inode, struct file *file, 935static int tun_chr_ioctl(struct inode *inode, struct file *file,
937 unsigned int cmd, unsigned long arg) 936 unsigned int cmd, unsigned long arg)
938{ 937{
938 struct tun_file *tfile = file->private_data;
939 struct tun_struct *tun; 939 struct tun_struct *tun;
940 void __user* argp = (void __user*)arg; 940 void __user* argp = (void __user*)arg;
941 struct ifreq ifr; 941 struct ifreq ifr;
@@ -954,14 +954,14 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
954 (unsigned int __user*)argp); 954 (unsigned int __user*)argp);
955 } 955 }
956 956
957 tun = tun_get(file); 957 tun = __tun_get(tfile);
958 if (cmd == TUNSETIFF && !tun) { 958 if (cmd == TUNSETIFF && !tun) {
959 int err; 959 int err;
960 960
961 ifr.ifr_name[IFNAMSIZ-1] = '\0'; 961 ifr.ifr_name[IFNAMSIZ-1] = '\0';
962 962
963 rtnl_lock(); 963 rtnl_lock();
964 err = tun_set_iff(current->nsproxy->net_ns, file, &ifr); 964 err = tun_set_iff(tfile->net, file, &ifr);
965 rtnl_unlock(); 965 rtnl_unlock();
966 966
967 if (err) 967 if (err)
@@ -1125,6 +1125,7 @@ static int tun_chr_open(struct inode *inode, struct file * file)
1125 if (!tfile) 1125 if (!tfile)
1126 return -ENOMEM; 1126 return -ENOMEM;
1127 tfile->tun = NULL; 1127 tfile->tun = NULL;
1128 tfile->net = get_net(current->nsproxy->net_ns);
1128 file->private_data = tfile; 1129 file->private_data = tfile;
1129 return 0; 1130 return 0;
1130} 1131}
@@ -1148,6 +1149,7 @@ static int tun_chr_close(struct inode *inode, struct file *file)
1148 rtnl_unlock(); 1149 rtnl_unlock();
1149 } 1150 }
1150 1151
1152 put_net(tfile->net);
1151 kfree(tfile); 1153 kfree(tfile);
1152 1154
1153 return 0; 1155 return 0;