aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-05-06 03:26:49 -0400
committerDavid S. Miller <davem@davemloft.net>2010-05-06 03:26:49 -0400
commit58544feb67eac49d55cc3408aea1ae42521af90d (patch)
tree6559cbeda7bcba3f722caf736d3dd4bb5367553b /drivers
parent2873957df0ead5b53fa00fddfb52ca3df38af4a9 (diff)
parent55afbd0810922afe456f9e4e3abc84d69d3f8a15 (diff)
Merge branch 'vhost' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/macvtap.c27
-rw-r--r--drivers/net/tun.c32
2 files changed, 51 insertions, 8 deletions
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c
index 1c4110df343e..a8a94e2f6ddc 100644
--- a/drivers/net/macvtap.c
+++ b/drivers/net/macvtap.c
@@ -38,6 +38,7 @@ struct macvtap_queue {
38 struct sock sk; 38 struct sock sk;
39 struct socket sock; 39 struct socket sock;
40 struct socket_wq wq; 40 struct socket_wq wq;
41 int vnet_hdr_sz;
41 struct macvlan_dev *vlan; 42 struct macvlan_dev *vlan;
42 struct file *file; 43 struct file *file;
43 unsigned int flags; 44 unsigned int flags;
@@ -285,6 +286,7 @@ static int macvtap_open(struct inode *inode, struct file *file)
285 sock_init_data(&q->sock, &q->sk); 286 sock_init_data(&q->sock, &q->sk);
286 q->sk.sk_write_space = macvtap_sock_write_space; 287 q->sk.sk_write_space = macvtap_sock_write_space;
287 q->flags = IFF_VNET_HDR | IFF_NO_PI | IFF_TAP; 288 q->flags = IFF_VNET_HDR | IFF_NO_PI | IFF_TAP;
289 q->vnet_hdr_sz = sizeof(struct virtio_net_hdr);
288 290
289 err = macvtap_set_queue(dev, file, q); 291 err = macvtap_set_queue(dev, file, q);
290 if (err) 292 if (err)
@@ -445,14 +447,14 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q,
445 int vnet_hdr_len = 0; 447 int vnet_hdr_len = 0;
446 448
447 if (q->flags & IFF_VNET_HDR) { 449 if (q->flags & IFF_VNET_HDR) {
448 vnet_hdr_len = sizeof(vnet_hdr); 450 vnet_hdr_len = q->vnet_hdr_sz;
449 451
450 err = -EINVAL; 452 err = -EINVAL;
451 if ((len -= vnet_hdr_len) < 0) 453 if ((len -= vnet_hdr_len) < 0)
452 goto err; 454 goto err;
453 455
454 err = memcpy_fromiovecend((void *)&vnet_hdr, iv, 0, 456 err = memcpy_fromiovecend((void *)&vnet_hdr, iv, 0,
455 vnet_hdr_len); 457 sizeof(vnet_hdr));
456 if (err < 0) 458 if (err < 0)
457 goto err; 459 goto err;
458 if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && 460 if ((vnet_hdr.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) &&
@@ -534,7 +536,7 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q,
534 536
535 if (q->flags & IFF_VNET_HDR) { 537 if (q->flags & IFF_VNET_HDR) {
536 struct virtio_net_hdr vnet_hdr; 538 struct virtio_net_hdr vnet_hdr;
537 vnet_hdr_len = sizeof (vnet_hdr); 539 vnet_hdr_len = q->vnet_hdr_sz;
538 if ((len -= vnet_hdr_len) < 0) 540 if ((len -= vnet_hdr_len) < 0)
539 return -EINVAL; 541 return -EINVAL;
540 542
@@ -542,7 +544,7 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q,
542 if (ret) 544 if (ret)
543 return ret; 545 return ret;
544 546
545 if (memcpy_toiovecend(iv, (void *)&vnet_hdr, 0, vnet_hdr_len)) 547 if (memcpy_toiovecend(iv, (void *)&vnet_hdr, 0, sizeof(vnet_hdr)))
546 return -EFAULT; 548 return -EFAULT;
547 } 549 }
548 550
@@ -627,6 +629,8 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
627 struct ifreq __user *ifr = argp; 629 struct ifreq __user *ifr = argp;
628 unsigned int __user *up = argp; 630 unsigned int __user *up = argp;
629 unsigned int u; 631 unsigned int u;
632 int __user *sp = argp;
633 int s;
630 int ret; 634 int ret;
631 635
632 switch (cmd) { 636 switch (cmd) {
@@ -672,6 +676,21 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd,
672 q->sk.sk_sndbuf = u; 676 q->sk.sk_sndbuf = u;
673 return 0; 677 return 0;
674 678
679 case TUNGETVNETHDRSZ:
680 s = q->vnet_hdr_sz;
681 if (put_user(s, sp))
682 return -EFAULT;
683 return 0;
684
685 case TUNSETVNETHDRSZ:
686 if (get_user(s, sp))
687 return -EFAULT;
688 if (s < (int)sizeof(struct virtio_net_hdr))
689 return -EINVAL;
690
691 q->vnet_hdr_sz = s;
692 return 0;
693
675 case TUNSETOFFLOAD: 694 case TUNSETOFFLOAD:
676 /* let the user check for future flags */ 695 /* let the user check for future flags */
677 if (arg & ~(TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 | 696 if (arg & ~(TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index e525a6cf5587..6b150c072a41 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -110,6 +110,9 @@ struct tun_struct {
110 struct tap_filter txflt; 110 struct tap_filter txflt;
111 struct socket socket; 111 struct socket socket;
112 struct socket_wq wq; 112 struct socket_wq wq;
113
114 int vnet_hdr_sz;
115
113#ifdef TUN_DEBUG 116#ifdef TUN_DEBUG
114 int debug; 117 int debug;
115#endif 118#endif
@@ -563,7 +566,7 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun,
563 } 566 }
564 567
565 if (tun->flags & TUN_VNET_HDR) { 568 if (tun->flags & TUN_VNET_HDR) {
566 if ((len -= sizeof(gso)) > count) 569 if ((len -= tun->vnet_hdr_sz) > count)
567 return -EINVAL; 570 return -EINVAL;
568 571
569 if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso))) 572 if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso)))
@@ -575,7 +578,7 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun,
575 578
576 if (gso.hdr_len > len) 579 if (gso.hdr_len > len)
577 return -EINVAL; 580 return -EINVAL;
578 offset += sizeof(gso); 581 offset += tun->vnet_hdr_sz;
579 } 582 }
580 583
581 if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) { 584 if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) {
@@ -718,7 +721,7 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
718 721
719 if (tun->flags & TUN_VNET_HDR) { 722 if (tun->flags & TUN_VNET_HDR) {
720 struct virtio_net_hdr gso = { 0 }; /* no info leak */ 723 struct virtio_net_hdr gso = { 0 }; /* no info leak */
721 if ((len -= sizeof(gso)) < 0) 724 if ((len -= tun->vnet_hdr_sz) < 0)
722 return -EINVAL; 725 return -EINVAL;
723 726
724 if (skb_is_gso(skb)) { 727 if (skb_is_gso(skb)) {
@@ -749,7 +752,7 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
749 if (unlikely(memcpy_toiovecend(iv, (void *)&gso, total, 752 if (unlikely(memcpy_toiovecend(iv, (void *)&gso, total,
750 sizeof(gso)))) 753 sizeof(gso))))
751 return -EFAULT; 754 return -EFAULT;
752 total += sizeof(gso); 755 total += tun->vnet_hdr_sz;
753 } 756 }
754 757
755 len = min_t(int, skb->len, len); 758 len = min_t(int, skb->len, len);
@@ -1035,6 +1038,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
1035 tun->dev = dev; 1038 tun->dev = dev;
1036 tun->flags = flags; 1039 tun->flags = flags;
1037 tun->txflt.count = 0; 1040 tun->txflt.count = 0;
1041 tun->vnet_hdr_sz = sizeof(struct virtio_net_hdr);
1038 1042
1039 err = -ENOMEM; 1043 err = -ENOMEM;
1040 sk = sk_alloc(net, AF_UNSPEC, GFP_KERNEL, &tun_proto); 1044 sk = sk_alloc(net, AF_UNSPEC, GFP_KERNEL, &tun_proto);
@@ -1177,6 +1181,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
1177 struct sock_fprog fprog; 1181 struct sock_fprog fprog;
1178 struct ifreq ifr; 1182 struct ifreq ifr;
1179 int sndbuf; 1183 int sndbuf;
1184 int vnet_hdr_sz;
1180 int ret; 1185 int ret;
1181 1186
1182 if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89) 1187 if (cmd == TUNSETIFF || _IOC_TYPE(cmd) == 0x89)
@@ -1322,6 +1327,25 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
1322 tun->socket.sk->sk_sndbuf = sndbuf; 1327 tun->socket.sk->sk_sndbuf = sndbuf;
1323 break; 1328 break;
1324 1329
1330 case TUNGETVNETHDRSZ:
1331 vnet_hdr_sz = tun->vnet_hdr_sz;
1332 if (copy_to_user(argp, &vnet_hdr_sz, sizeof(vnet_hdr_sz)))
1333 ret = -EFAULT;
1334 break;
1335
1336 case TUNSETVNETHDRSZ:
1337 if (copy_from_user(&vnet_hdr_sz, argp, sizeof(vnet_hdr_sz))) {
1338 ret = -EFAULT;
1339 break;
1340 }
1341 if (vnet_hdr_sz < (int)sizeof(struct virtio_net_hdr)) {
1342 ret = -EINVAL;
1343 break;
1344 }
1345
1346 tun->vnet_hdr_sz = vnet_hdr_sz;
1347 break;
1348
1325 case TUNATTACHFILTER: 1349 case TUNATTACHFILTER:
1326 /* Can be set only for TAPs */ 1350 /* Can be set only for TAPs */
1327 ret = -EINVAL; 1351 ret = -EINVAL;