diff options
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r-- | drivers/net/tun.c | 10 |
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 | ||
90 | struct tun_file { | 90 | struct tun_file { |
91 | struct tun_struct *tun; | 91 | struct tun_struct *tun; |
92 | struct net *net; | ||
92 | }; | 93 | }; |
93 | 94 | ||
94 | struct tun_struct { | 95 | struct 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) | |||
936 | static int tun_chr_ioctl(struct inode *inode, struct file *file, | 935 | static 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; |