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.c55
1 files changed, 40 insertions, 15 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 43265207d463..97b25533e5fb 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -109,6 +109,9 @@ struct tun_struct {
109 109
110 struct tap_filter txflt; 110 struct tap_filter txflt;
111 struct socket socket; 111 struct socket socket;
112 struct socket_wq wq;
113
114 int vnet_hdr_sz;
112 115
113#ifdef TUN_DEBUG 116#ifdef TUN_DEBUG
114 int debug; 117 int debug;
@@ -323,7 +326,7 @@ static void tun_net_uninit(struct net_device *dev)
323 /* Inform the methods they need to stop using the dev. 326 /* Inform the methods they need to stop using the dev.
324 */ 327 */
325 if (tfile) { 328 if (tfile) {
326 wake_up_all(&tun->socket.wait); 329 wake_up_all(&tun->wq.wait);
327 if (atomic_dec_and_test(&tfile->count)) 330 if (atomic_dec_and_test(&tfile->count))
328 __tun_detach(tun); 331 __tun_detach(tun);
329 } 332 }
@@ -393,12 +396,11 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
393 396
394 /* Enqueue packet */ 397 /* Enqueue packet */
395 skb_queue_tail(&tun->socket.sk->sk_receive_queue, skb); 398 skb_queue_tail(&tun->socket.sk->sk_receive_queue, skb);
396 dev->trans_start = jiffies;
397 399
398 /* Notify and wake up reader process */ 400 /* Notify and wake up reader process */
399 if (tun->flags & TUN_FASYNC) 401 if (tun->flags & TUN_FASYNC)
400 kill_fasync(&tun->fasync, SIGIO, POLL_IN); 402 kill_fasync(&tun->fasync, SIGIO, POLL_IN);
401 wake_up_interruptible_poll(&tun->socket.wait, POLLIN | 403 wake_up_interruptible_poll(&tun->wq.wait, POLLIN |
402 POLLRDNORM | POLLRDBAND); 404 POLLRDNORM | POLLRDBAND);
403 return NETDEV_TX_OK; 405 return NETDEV_TX_OK;
404 406
@@ -415,7 +417,6 @@ static void tun_net_mclist(struct net_device *dev)
415 * _rx_ path and has nothing to do with the _tx_ path. 417 * _rx_ path and has nothing to do with the _tx_ path.
416 * In rx path we always accept everything userspace gives us. 418 * In rx path we always accept everything userspace gives us.
417 */ 419 */
418 return;
419} 420}
420 421
421#define MIN_MTU 68 422#define MIN_MTU 68
@@ -498,7 +499,7 @@ static unsigned int tun_chr_poll(struct file *file, poll_table * wait)
498 499
499 DBG(KERN_INFO "%s: tun_chr_poll\n", tun->dev->name); 500 DBG(KERN_INFO "%s: tun_chr_poll\n", tun->dev->name);
500 501
501 poll_wait(file, &tun->socket.wait, wait); 502 poll_wait(file, &tun->wq.wait, wait);
502 503
503 if (!skb_queue_empty(&sk->sk_receive_queue)) 504 if (!skb_queue_empty(&sk->sk_receive_queue))
504 mask |= POLLIN | POLLRDNORM; 505 mask |= POLLIN | POLLRDNORM;
@@ -563,7 +564,7 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun,
563 } 564 }
564 565
565 if (tun->flags & TUN_VNET_HDR) { 566 if (tun->flags & TUN_VNET_HDR) {
566 if ((len -= sizeof(gso)) > count) 567 if ((len -= tun->vnet_hdr_sz) > count)
567 return -EINVAL; 568 return -EINVAL;
568 569
569 if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso))) 570 if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso)))
@@ -575,7 +576,7 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun,
575 576
576 if (gso.hdr_len > len) 577 if (gso.hdr_len > len)
577 return -EINVAL; 578 return -EINVAL;
578 offset += sizeof(gso); 579 offset += tun->vnet_hdr_sz;
579 } 580 }
580 581
581 if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) { 582 if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) {
@@ -718,7 +719,7 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
718 719
719 if (tun->flags & TUN_VNET_HDR) { 720 if (tun->flags & TUN_VNET_HDR) {
720 struct virtio_net_hdr gso = { 0 }; /* no info leak */ 721 struct virtio_net_hdr gso = { 0 }; /* no info leak */
721 if ((len -= sizeof(gso)) < 0) 722 if ((len -= tun->vnet_hdr_sz) < 0)
722 return -EINVAL; 723 return -EINVAL;
723 724
724 if (skb_is_gso(skb)) { 725 if (skb_is_gso(skb)) {
@@ -749,7 +750,7 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
749 if (unlikely(memcpy_toiovecend(iv, (void *)&gso, total, 750 if (unlikely(memcpy_toiovecend(iv, (void *)&gso, total,
750 sizeof(gso)))) 751 sizeof(gso))))
751 return -EFAULT; 752 return -EFAULT;
752 total += sizeof(gso); 753 total += tun->vnet_hdr_sz;
753 } 754 }
754 755
755 len = min_t(int, skb->len, len); 756 len = min_t(int, skb->len, len);
@@ -773,7 +774,7 @@ static ssize_t tun_do_read(struct tun_struct *tun,
773 774
774 DBG(KERN_INFO "%s: tun_chr_read\n", tun->dev->name); 775 DBG(KERN_INFO "%s: tun_chr_read\n", tun->dev->name);
775 776
776 add_wait_queue(&tun->socket.wait, &wait); 777 add_wait_queue(&tun->wq.wait, &wait);
777 while (len) { 778 while (len) {
778 current->state = TASK_INTERRUPTIBLE; 779 current->state = TASK_INTERRUPTIBLE;
779 780
@@ -804,7 +805,7 @@ static ssize_t tun_do_read(struct tun_struct *tun,
804 } 805 }
805 806
806 current->state = TASK_RUNNING; 807 current->state = TASK_RUNNING;
807 remove_wait_queue(&tun->socket.wait, &wait); 808 remove_wait_queue(&tun->wq.wait, &wait);
808 809
809 return ret; 810 return ret;
810} 811}
@@ -861,6 +862,7 @@ static struct rtnl_link_ops tun_link_ops __read_mostly = {
861static void tun_sock_write_space(struct sock *sk) 862static void tun_sock_write_space(struct sock *sk)
862{ 863{
863 struct tun_struct *tun; 864 struct tun_struct *tun;
865 wait_queue_head_t *wqueue;
864 866
865 if (!sock_writeable(sk)) 867 if (!sock_writeable(sk))
866 return; 868 return;
@@ -868,8 +870,9 @@ static void tun_sock_write_space(struct sock *sk)
868 if (!test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags)) 870 if (!test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags))
869 return; 871 return;
870 872
871 if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) 873 wqueue = sk_sleep(sk);
872 wake_up_interruptible_sync_poll(sk->sk_sleep, POLLOUT | 874 if (wqueue && waitqueue_active(wqueue))
875 wake_up_interruptible_sync_poll(wqueue, POLLOUT |
873 POLLWRNORM | POLLWRBAND); 876 POLLWRNORM | POLLWRBAND);
874 877
875 tun = tun_sk(sk)->tun; 878 tun = tun_sk(sk)->tun;
@@ -1033,13 +1036,15 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
1033 tun->dev = dev; 1036 tun->dev = dev;
1034 tun->flags = flags; 1037 tun->flags = flags;
1035 tun->txflt.count = 0; 1038 tun->txflt.count = 0;
1039 tun->vnet_hdr_sz = sizeof(struct virtio_net_hdr);
1036 1040
1037 err = -ENOMEM; 1041 err = -ENOMEM;
1038 sk = sk_alloc(net, AF_UNSPEC, GFP_KERNEL, &tun_proto); 1042 sk = sk_alloc(net, AF_UNSPEC, GFP_KERNEL, &tun_proto);
1039 if (!sk) 1043 if (!sk)
1040 goto err_free_dev; 1044 goto err_free_dev;
1041 1045
1042 init_waitqueue_head(&tun->socket.wait); 1046 tun->socket.wq = &tun->wq;
1047 init_waitqueue_head(&tun->wq.wait);
1043 tun->socket.ops = &tun_socket_ops; 1048 tun->socket.ops = &tun_socket_ops;
1044 sock_init_data(&tun->socket, sk); 1049 sock_init_data(&tun->socket, sk);
1045 sk->sk_write_space = tun_sock_write_space; 1050 sk->sk_write_space = tun_sock_write_space;
@@ -1174,6 +1179,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
1174 struct sock_fprog fprog; 1179 struct sock_fprog fprog;
1175 struct ifreq ifr; 1180 struct ifreq ifr;
1176 int sndbuf; 1181 int sndbuf;
1182 int vnet_hdr_sz;
1177 int ret; 1183 int ret;
1178 1184
1179 if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89) 1185 if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89)
@@ -1319,6 +1325,25 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
1319 tun->socket.sk->sk_sndbuf = sndbuf; 1325 tun->socket.sk->sk_sndbuf = sndbuf;
1320 break; 1326 break;
1321 1327
1328 case TUNGETVNETHDRSZ:
1329 vnet_hdr_sz = tun->vnet_hdr_sz;
1330 if (copy_to_user(argp, &vnet_hdr_sz, sizeof(vnet_hdr_sz)))
1331 ret = -EFAULT;
1332 break;
1333
1334 case TUNSETVNETHDRSZ:
1335 if (copy_from_user(&vnet_hdr_sz, argp, sizeof(vnet_hdr_sz))) {
1336 ret = -EFAULT;
1337 break;
1338 }
1339 if (vnet_hdr_sz < (int)sizeof(struct virtio_net_hdr)) {
1340 ret = -EINVAL;
1341 break;
1342 }
1343
1344 tun->vnet_hdr_sz = vnet_hdr_sz;
1345 break;
1346
1322 case TUNATTACHFILTER: 1347 case TUNATTACHFILTER:
1323 /* Can be set only for TAPs */ 1348 /* Can be set only for TAPs */
1324 ret = -EINVAL; 1349 ret = -EINVAL;
@@ -1342,7 +1367,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
1342 default: 1367 default:
1343 ret = -EINVAL; 1368 ret = -EINVAL;
1344 break; 1369 break;
1345 }; 1370 }
1346 1371
1347unlock: 1372unlock:
1348 rtnl_unlock(); 1373 rtnl_unlock();