aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2009-01-20 06:01:48 -0500
committerDavid S. Miller <davem@davemloft.net>2009-01-21 19:00:45 -0500
commit36b50bab53207daf34be63ca62fb8b0b08dc6e6b (patch)
tree6363b239732a1ad8d9fd516993c8c6c093dc63a2 /drivers
parent631ab46b79559d6fed784fd7883c0cda4d8cfcfa (diff)
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: Eric W. Biederman <ebiederm@aristanetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-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;