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.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 93c5d72711b0..2d7601dd6660 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -359,7 +359,7 @@ static void tun_free_netdev(struct net_device *dev)
359{ 359{
360 struct tun_struct *tun = netdev_priv(dev); 360 struct tun_struct *tun = netdev_priv(dev);
361 361
362 sock_put(tun->socket.sk); 362 sk_release_kernel(tun->socket.sk);
363} 363}
364 364
365/* Net device open. */ 365/* Net device open. */
@@ -980,10 +980,18 @@ static int tun_recvmsg(struct kiocb *iocb, struct socket *sock,
980 return ret; 980 return ret;
981} 981}
982 982
983static int tun_release(struct socket *sock)
984{
985 if (sock->sk)
986 sock_put(sock->sk);
987 return 0;
988}
989
983/* Ops structure to mimic raw sockets with tun */ 990/* Ops structure to mimic raw sockets with tun */
984static const struct proto_ops tun_socket_ops = { 991static const struct proto_ops tun_socket_ops = {
985 .sendmsg = tun_sendmsg, 992 .sendmsg = tun_sendmsg,
986 .recvmsg = tun_recvmsg, 993 .recvmsg = tun_recvmsg,
994 .release = tun_release,
987}; 995};
988 996
989static struct proto tun_proto = { 997static struct proto tun_proto = {
@@ -1110,10 +1118,11 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
1110 tun->vnet_hdr_sz = sizeof(struct virtio_net_hdr); 1118 tun->vnet_hdr_sz = sizeof(struct virtio_net_hdr);
1111 1119
1112 err = -ENOMEM; 1120 err = -ENOMEM;
1113 sk = sk_alloc(net, AF_UNSPEC, GFP_KERNEL, &tun_proto); 1121 sk = sk_alloc(&init_net, AF_UNSPEC, GFP_KERNEL, &tun_proto);
1114 if (!sk) 1122 if (!sk)
1115 goto err_free_dev; 1123 goto err_free_dev;
1116 1124
1125 sk_change_net(sk, net);
1117 tun->socket.wq = &tun->wq; 1126 tun->socket.wq = &tun->wq;
1118 init_waitqueue_head(&tun->wq.wait); 1127 init_waitqueue_head(&tun->wq.wait);
1119 tun->socket.ops = &tun_socket_ops; 1128 tun->socket.ops = &tun_socket_ops;
@@ -1174,7 +1183,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
1174 return 0; 1183 return 0;
1175 1184
1176 err_free_sk: 1185 err_free_sk:
1177 sock_put(sk); 1186 tun_free_netdev(dev);
1178 err_free_dev: 1187 err_free_dev:
1179 free_netdev(dev); 1188 free_netdev(dev);
1180 failed: 1189 failed: