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.c110
1 files changed, 79 insertions, 31 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 735bf41c654a..811d3517fce0 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -540,31 +540,38 @@ static inline struct sk_buff *tun_alloc_skb(struct tun_struct *tun,
540 540
541/* Get packet from user space buffer */ 541/* Get packet from user space buffer */
542static __inline__ ssize_t tun_get_user(struct tun_struct *tun, 542static __inline__ ssize_t tun_get_user(struct tun_struct *tun,
543 struct iovec *iv, size_t count, 543 const struct iovec *iv, size_t count,
544 int noblock) 544 int noblock)
545{ 545{
546 struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) }; 546 struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) };
547 struct sk_buff *skb; 547 struct sk_buff *skb;
548 size_t len = count, align = 0; 548 size_t len = count, align = 0;
549 struct virtio_net_hdr gso = { 0 }; 549 struct virtio_net_hdr gso = { 0 };
550 int offset = 0;
550 551
551 if (!(tun->flags & TUN_NO_PI)) { 552 if (!(tun->flags & TUN_NO_PI)) {
552 if ((len -= sizeof(pi)) > count) 553 if ((len -= sizeof(pi)) > count)
553 return -EINVAL; 554 return -EINVAL;
554 555
555 if(memcpy_fromiovec((void *)&pi, iv, sizeof(pi))) 556 if (memcpy_fromiovecend((void *)&pi, iv, 0, sizeof(pi)))
556 return -EFAULT; 557 return -EFAULT;
558 offset += sizeof(pi);
557 } 559 }
558 560
559 if (tun->flags & TUN_VNET_HDR) { 561 if (tun->flags & TUN_VNET_HDR) {
560 if ((len -= sizeof(gso)) > count) 562 if ((len -= sizeof(gso)) > count)
561 return -EINVAL; 563 return -EINVAL;
562 564
563 if (memcpy_fromiovec((void *)&gso, iv, sizeof(gso))) 565 if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso)))
564 return -EFAULT; 566 return -EFAULT;
565 567
568 if ((gso.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) &&
569 gso.csum_start + gso.csum_offset + 2 > gso.hdr_len)
570 gso.hdr_len = gso.csum_start + gso.csum_offset + 2;
571
566 if (gso.hdr_len > len) 572 if (gso.hdr_len > len)
567 return -EINVAL; 573 return -EINVAL;
574 offset += sizeof(gso);
568 } 575 }
569 576
570 if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) { 577 if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) {
@@ -581,7 +588,7 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun,
581 return PTR_ERR(skb); 588 return PTR_ERR(skb);
582 } 589 }
583 590
584 if (skb_copy_datagram_from_iovec(skb, 0, iv, len)) { 591 if (skb_copy_datagram_from_iovec(skb, 0, iv, offset, len)) {
585 tun->dev->stats.rx_dropped++; 592 tun->dev->stats.rx_dropped++;
586 kfree_skb(skb); 593 kfree_skb(skb);
587 return -EFAULT; 594 return -EFAULT;
@@ -673,7 +680,7 @@ static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv,
673 680
674 DBG(KERN_INFO "%s: tun_chr_write %ld\n", tun->dev->name, count); 681 DBG(KERN_INFO "%s: tun_chr_write %ld\n", tun->dev->name, count);
675 682
676 result = tun_get_user(tun, (struct iovec *)iv, iov_length(iv, count), 683 result = tun_get_user(tun, iv, iov_length(iv, count),
677 file->f_flags & O_NONBLOCK); 684 file->f_flags & O_NONBLOCK);
678 685
679 tun_put(tun); 686 tun_put(tun);
@@ -683,7 +690,7 @@ static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv,
683/* Put packet to the user space buffer */ 690/* Put packet to the user space buffer */
684static __inline__ ssize_t tun_put_user(struct tun_struct *tun, 691static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
685 struct sk_buff *skb, 692 struct sk_buff *skb,
686 struct iovec *iv, int len) 693 const struct iovec *iv, int len)
687{ 694{
688 struct tun_pi pi = { 0, skb->protocol }; 695 struct tun_pi pi = { 0, skb->protocol };
689 ssize_t total = 0; 696 ssize_t total = 0;
@@ -697,7 +704,7 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
697 pi.flags |= TUN_PKT_STRIP; 704 pi.flags |= TUN_PKT_STRIP;
698 } 705 }
699 706
700 if (memcpy_toiovec(iv, (void *) &pi, sizeof(pi))) 707 if (memcpy_toiovecend(iv, (void *) &pi, 0, sizeof(pi)))
701 return -EFAULT; 708 return -EFAULT;
702 total += sizeof(pi); 709 total += sizeof(pi);
703 } 710 }
@@ -730,14 +737,15 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
730 gso.csum_offset = skb->csum_offset; 737 gso.csum_offset = skb->csum_offset;
731 } /* else everything is zero */ 738 } /* else everything is zero */
732 739
733 if (unlikely(memcpy_toiovec(iv, (void *)&gso, sizeof(gso)))) 740 if (unlikely(memcpy_toiovecend(iv, (void *)&gso, total,
741 sizeof(gso))))
734 return -EFAULT; 742 return -EFAULT;
735 total += sizeof(gso); 743 total += sizeof(gso);
736 } 744 }
737 745
738 len = min_t(int, skb->len, len); 746 len = min_t(int, skb->len, len);
739 747
740 skb_copy_datagram_iovec(skb, 0, iv, len); 748 skb_copy_datagram_const_iovec(skb, 0, iv, total, len);
741 total += len; 749 total += len;
742 750
743 tun->dev->stats.tx_packets++; 751 tun->dev->stats.tx_packets++;
@@ -792,7 +800,7 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
792 } 800 }
793 netif_wake_queue(tun->dev); 801 netif_wake_queue(tun->dev);
794 802
795 ret = tun_put_user(tun, skb, (struct iovec *) iv, len); 803 ret = tun_put_user(tun, skb, iv, len);
796 kfree_skb(skb); 804 kfree_skb(skb);
797 break; 805 break;
798 } 806 }
@@ -840,12 +848,12 @@ static void tun_sock_write_space(struct sock *sk)
840 if (!sock_writeable(sk)) 848 if (!sock_writeable(sk))
841 return; 849 return;
842 850
843 if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
844 wake_up_interruptible_sync(sk->sk_sleep);
845
846 if (!test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags)) 851 if (!test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags))
847 return; 852 return;
848 853
854 if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
855 wake_up_interruptible_sync(sk->sk_sleep);
856
849 tun = container_of(sk, struct tun_sock, sk)->tun; 857 tun = container_of(sk, struct tun_sock, sk)->tun;
850 kill_fasync(&tun->fasync, SIGIO, POLL_OUT); 858 kill_fasync(&tun->fasync, SIGIO, POLL_OUT);
851} 859}
@@ -861,6 +869,52 @@ static struct proto tun_proto = {
861 .obj_size = sizeof(struct tun_sock), 869 .obj_size = sizeof(struct tun_sock),
862}; 870};
863 871
872static int tun_flags(struct tun_struct *tun)
873{
874 int flags = 0;
875
876 if (tun->flags & TUN_TUN_DEV)
877 flags |= IFF_TUN;
878 else
879 flags |= IFF_TAP;
880
881 if (tun->flags & TUN_NO_PI)
882 flags |= IFF_NO_PI;
883
884 if (tun->flags & TUN_ONE_QUEUE)
885 flags |= IFF_ONE_QUEUE;
886
887 if (tun->flags & TUN_VNET_HDR)
888 flags |= IFF_VNET_HDR;
889
890 return flags;
891}
892
893static ssize_t tun_show_flags(struct device *dev, struct device_attribute *attr,
894 char *buf)
895{
896 struct tun_struct *tun = netdev_priv(to_net_dev(dev));
897 return sprintf(buf, "0x%x\n", tun_flags(tun));
898}
899
900static ssize_t tun_show_owner(struct device *dev, struct device_attribute *attr,
901 char *buf)
902{
903 struct tun_struct *tun = netdev_priv(to_net_dev(dev));
904 return sprintf(buf, "%d\n", tun->owner);
905}
906
907static ssize_t tun_show_group(struct device *dev, struct device_attribute *attr,
908 char *buf)
909{
910 struct tun_struct *tun = netdev_priv(to_net_dev(dev));
911 return sprintf(buf, "%d\n", tun->group);
912}
913
914static DEVICE_ATTR(tun_flags, 0444, tun_show_flags, NULL);
915static DEVICE_ATTR(owner, 0444, tun_show_owner, NULL);
916static DEVICE_ATTR(group, 0444, tun_show_group, NULL);
917
864static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) 918static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
865{ 919{
866 struct sock *sk; 920 struct sock *sk;
@@ -870,6 +924,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
870 924
871 dev = __dev_get_by_name(net, ifr->ifr_name); 925 dev = __dev_get_by_name(net, ifr->ifr_name);
872 if (dev) { 926 if (dev) {
927 if (ifr->ifr_flags & IFF_TUN_EXCL)
928 return -EBUSY;
873 if ((ifr->ifr_flags & IFF_TUN) && dev->netdev_ops == &tun_netdev_ops) 929 if ((ifr->ifr_flags & IFF_TUN) && dev->netdev_ops == &tun_netdev_ops)
874 tun = netdev_priv(dev); 930 tun = netdev_priv(dev);
875 else if ((ifr->ifr_flags & IFF_TAP) && dev->netdev_ops == &tap_netdev_ops) 931 else if ((ifr->ifr_flags & IFF_TAP) && dev->netdev_ops == &tap_netdev_ops)
@@ -944,6 +1000,11 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
944 if (err < 0) 1000 if (err < 0)
945 goto err_free_sk; 1001 goto err_free_sk;
946 1002
1003 if (device_create_file(&tun->dev->dev, &dev_attr_tun_flags) ||
1004 device_create_file(&tun->dev->dev, &dev_attr_owner) ||
1005 device_create_file(&tun->dev->dev, &dev_attr_group))
1006 printk(KERN_ERR "Failed to create tun sysfs files\n");
1007
947 sk->sk_destruct = tun_sock_destruct; 1008 sk->sk_destruct = tun_sock_destruct;
948 1009
949 err = tun_attach(tun, file); 1010 err = tun_attach(tun, file);
@@ -996,21 +1057,7 @@ static int tun_get_iff(struct net *net, struct file *file, struct ifreq *ifr)
996 1057
997 strcpy(ifr->ifr_name, tun->dev->name); 1058 strcpy(ifr->ifr_name, tun->dev->name);
998 1059
999 ifr->ifr_flags = 0; 1060 ifr->ifr_flags = tun_flags(tun);
1000
1001 if (ifr->ifr_flags & TUN_TUN_DEV)
1002 ifr->ifr_flags |= IFF_TUN;
1003 else
1004 ifr->ifr_flags |= IFF_TAP;
1005
1006 if (tun->flags & TUN_NO_PI)
1007 ifr->ifr_flags |= IFF_NO_PI;
1008
1009 if (tun->flags & TUN_ONE_QUEUE)
1010 ifr->ifr_flags |= IFF_ONE_QUEUE;
1011
1012 if (tun->flags & TUN_VNET_HDR)
1013 ifr->ifr_flags |= IFF_VNET_HDR;
1014 1061
1015 tun_put(tun); 1062 tun_put(tun);
1016 return 0; 1063 return 0;
@@ -1275,21 +1322,22 @@ static int tun_chr_open(struct inode *inode, struct file * file)
1275static int tun_chr_close(struct inode *inode, struct file *file) 1322static int tun_chr_close(struct inode *inode, struct file *file)
1276{ 1323{
1277 struct tun_file *tfile = file->private_data; 1324 struct tun_file *tfile = file->private_data;
1278 struct tun_struct *tun = __tun_get(tfile); 1325 struct tun_struct *tun;
1279 1326
1280 1327
1328 rtnl_lock();
1329 tun = __tun_get(tfile);
1281 if (tun) { 1330 if (tun) {
1282 DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name); 1331 DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name);
1283 1332
1284 rtnl_lock();
1285 __tun_detach(tun); 1333 __tun_detach(tun);
1286 1334
1287 /* If desireable, unregister the netdevice. */ 1335 /* If desireable, unregister the netdevice. */
1288 if (!(tun->flags & TUN_PERSIST)) 1336 if (!(tun->flags & TUN_PERSIST))
1289 unregister_netdevice(tun->dev); 1337 unregister_netdevice(tun->dev);
1290 1338
1291 rtnl_unlock();
1292 } 1339 }
1340 rtnl_unlock();
1293 1341
1294 tun = tfile->tun; 1342 tun = tfile->tun;
1295 if (tun) 1343 if (tun)