Skip to content

Commit 140e807

Browse files
ebiedermdavem330
authored andcommitted
tun: Utilize the normal socket network namespace refcounting.
There is no need for tun to do the weird network namespace refcounting. The existing network namespace refcounting in tfile has almost exactly the same lifetime. So rewrite the code to use the struct sock network namespace refcounting and remove the unnecessary hand rolled network namespace refcounting and the unncesary tfile->net. This change allows the tun code to directly call sock_put bypassing sock_release and making SOCK_EXTERNALLY_ALLOCATED unnecessary. Remove the now unncessary tun_release so that if anything tries to use the sock_release code path the kernel will oops, and let us know about the bug. The macvtap code already uses it's internal socket this way. Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 80ba92f commit 140e807

File tree

3 files changed

+4
-24
lines changed

3 files changed

+4
-24
lines changed

drivers/net/tun.c

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,6 @@ struct tun_file {
146146
struct socket socket;
147147
struct socket_wq wq;
148148
struct tun_struct __rcu *tun;
149-
struct net *net;
150149
struct fasync_struct *fasync;
151150
/* only used for fasnyc */
152151
unsigned int flags;
@@ -493,10 +492,7 @@ static void __tun_detach(struct tun_file *tfile, bool clean)
493492
tun->dev->reg_state == NETREG_REGISTERED)
494493
unregister_netdevice(tun->dev);
495494
}
496-
497-
BUG_ON(!test_bit(SOCK_EXTERNALLY_ALLOCATED,
498-
&tfile->socket.flags));
499-
sk_release_kernel(&tfile->sk);
495+
sock_put(&tfile->sk);
500496
}
501497
}
502498

@@ -1492,18 +1488,10 @@ static int tun_recvmsg(struct socket *sock, struct msghdr *m, size_t total_len,
14921488
return ret;
14931489
}
14941490

1495-
static int tun_release(struct socket *sock)
1496-
{
1497-
if (sock->sk)
1498-
sock_put(sock->sk);
1499-
return 0;
1500-
}
1501-
15021491
/* Ops structure to mimic raw sockets with tun */
15031492
static const struct proto_ops tun_socket_ops = {
15041493
.sendmsg = tun_sendmsg,
15051494
.recvmsg = tun_recvmsg,
1506-
.release = tun_release,
15071495
};
15081496

15091497
static struct proto tun_proto = {
@@ -1865,7 +1853,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
18651853
if (cmd == TUNSETIFF && !tun) {
18661854
ifr.ifr_name[IFNAMSIZ-1] = '\0';
18671855

1868-
ret = tun_set_iff(tfile->net, file, &ifr);
1856+
ret = tun_set_iff(sock_net(&tfile->sk), file, &ifr);
18691857

18701858
if (ret)
18711859
goto unlock;
@@ -2154,16 +2142,16 @@ static int tun_chr_fasync(int fd, struct file *file, int on)
21542142

21552143
static int tun_chr_open(struct inode *inode, struct file * file)
21562144
{
2145+
struct net *net = current->nsproxy->net_ns;
21572146
struct tun_file *tfile;
21582147

21592148
DBG1(KERN_INFO, "tunX: tun_chr_open\n");
21602149

2161-
tfile = (struct tun_file *)sk_alloc(&init_net, AF_UNSPEC, GFP_KERNEL,
2150+
tfile = (struct tun_file *)sk_alloc(net, AF_UNSPEC, GFP_KERNEL,
21622151
&tun_proto);
21632152
if (!tfile)
21642153
return -ENOMEM;
21652154
RCU_INIT_POINTER(tfile->tun, NULL);
2166-
tfile->net = get_net(current->nsproxy->net_ns);
21672155
tfile->flags = 0;
21682156
tfile->ifindex = 0;
21692157

@@ -2174,13 +2162,11 @@ static int tun_chr_open(struct inode *inode, struct file * file)
21742162
tfile->socket.ops = &tun_socket_ops;
21752163

21762164
sock_init_data(&tfile->socket, &tfile->sk);
2177-
sk_change_net(&tfile->sk, tfile->net);
21782165

21792166
tfile->sk.sk_write_space = tun_sock_write_space;
21802167
tfile->sk.sk_sndbuf = INT_MAX;
21812168

21822169
file->private_data = tfile;
2183-
set_bit(SOCK_EXTERNALLY_ALLOCATED, &tfile->socket.flags);
21842170
INIT_LIST_HEAD(&tfile->next);
21852171

21862172
sock_set_flag(&tfile->sk, SOCK_ZEROCOPY);
@@ -2191,10 +2177,8 @@ static int tun_chr_open(struct inode *inode, struct file * file)
21912177
static int tun_chr_close(struct inode *inode, struct file *file)
21922178
{
21932179
struct tun_file *tfile = file->private_data;
2194-
struct net *net = tfile->net;
21952180

21962181
tun_detach(tfile, true);
2197-
put_net(net);
21982182

21992183
return 0;
22002184
}

include/linux/net.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ struct net;
3838
#define SOCK_NOSPACE 2
3939
#define SOCK_PASSCRED 3
4040
#define SOCK_PASSSEC 4
41-
#define SOCK_EXTERNALLY_ALLOCATED 5
4241

4342
#ifndef ARCH_HAS_SOCKET_TYPES
4443
/**

net/socket.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -576,9 +576,6 @@ void sock_release(struct socket *sock)
576576
if (rcu_dereference_protected(sock->wq, 1)->fasync_list)
577577
pr_err("%s: fasync list not empty!\n", __func__);
578578

579-
if (test_bit(SOCK_EXTERNALLY_ALLOCATED, &sock->flags))
580-
return;
581-
582579
this_cpu_sub(sockets_in_use, 1);
583580
if (!sock->file) {
584581
iput(SOCK_INODE(sock));

0 commit comments

Comments
 (0)