Performance difference on sendfile Guest -> Host is close to the noise
(understandable, because we copy anyway).
---
 Documentation/lguest/lguest.c |   16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff -r 72be3d596d31 Documentation/lguest/lguest.c
--- a/Documentation/lguest/lguest.c	Wed Jan 09 15:57:40 2008 +1100
+++ b/Documentation/lguest/lguest.c	Wed Jan 09 16:56:41 2008 +1100
@@ -852,11 +852,13 @@ static void handle_net_output(int fd, st
 	while ((head = get_vq_desc(vq, iov, &out, &in)) != vq->vring.num) {
 		if (in)
 			errx(1, "Input buffers in output queue?");
-		/* Check header, but otherwise ignore it (we told the Guest we
-		 * supported no features, so it shouldn't have anything
-		 * interesting). */
-		(void)convert(&iov[0], struct virtio_net_hdr);
-		len = writev(vq->dev->fd, iov+1, out-1);
+		/* With IFF_GSO_HDR, tap takes the same format header as
+		 * virtio_net, so we just pass it through. */
+		len = writev(vq->dev->fd, iov, out);
+		if (len >= sizeof(struct virtio_net_hdr))
+			len -= sizeof(struct virtio_net_hdr);
+		else
+			len = -1;
 		add_used_and_trigger(fd, vq, head, len);
 	}
 }
@@ -1266,7 +1268,7 @@ static void setup_tun_net(const char *ar
 	 * works now! */
 	netfd = open_or_die("/dev/net/tun", O_RDWR);
 	memset(&ifr, 0, sizeof(ifr));
-	ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+	ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_GSO_HDR;
 	strcpy(ifr.ifr_name, "tap%d");
 	if (ioctl(netfd, TUNSETIFF, &ifr) != 0)
 		err(1, "configuring /dev/net/tun");
@@ -1302,6 +1301,8 @@ static void setup_tun_net(const char *ar
 	/* Tell Guest what MAC address to use. */
 	add_feature(dev, VIRTIO_NET_F_MAC);
 	set_config(dev, sizeof(conf), &conf);
+	/* Tap device can handle no csum. */
+	add_feature(dev, VIRTIO_NET_F_NO_CSUM);
 
 	/* We don't need the socket any more; setup is done. */
 	close(ipfd);
