* [Qemu-devel] [PATCH 01/19] net: remove unused includes of if_tun.h and if_tap.h
2009-10-22 16:43 [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO Mark McLoughlin
@ 2009-10-22 16:43 ` Mark McLoughlin
2009-10-22 16:43 ` [Qemu-devel] [PATCH 02/19] net: import linux tap ioctl definitions Mark McLoughlin
` (19 subsequent siblings)
20 siblings, 0 replies; 37+ messages in thread
From: Mark McLoughlin @ 2009-10-22 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Mark McLoughlin
Looks like these are just artifacts of vl.c being split up.
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
qemu-char.c | 6 ------
savevm.c | 6 ------
vl.c | 6 ------
3 files changed, 0 insertions(+), 18 deletions(-)
diff --git a/qemu-char.c b/qemu-char.c
index 0fd402c..1625703 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -51,12 +51,6 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
-#ifdef __NetBSD__
-#include <net/if_tap.h>
-#endif
-#ifdef __linux__
-#include <linux/if_tun.h>
-#endif
#include <arpa/inet.h>
#include <dirent.h>
#include <netdb.h>
diff --git a/savevm.c b/savevm.c
index 27a7686..99aa15a 100644
--- a/savevm.c
+++ b/savevm.c
@@ -42,12 +42,6 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
-#if defined(__NetBSD__)
-#include <net/if_tap.h>
-#endif
-#ifdef __linux__
-#include <linux/if_tun.h>
-#endif
#include <arpa/inet.h>
#include <dirent.h>
#include <netdb.h>
diff --git a/vl.c b/vl.c
index eb2744e..7fa7bdc 100644
--- a/vl.c
+++ b/vl.c
@@ -44,12 +44,6 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
-#if defined(__NetBSD__)
-#include <net/if_tap.h>
-#endif
-#ifdef __linux__
-#include <linux/if_tun.h>
-#endif
#include <arpa/inet.h>
#include <dirent.h>
#include <netdb.h>
--
1.6.2.5
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [Qemu-devel] [PATCH 02/19] net: import linux tap ioctl definitions
2009-10-22 16:43 [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO Mark McLoughlin
2009-10-22 16:43 ` [Qemu-devel] [PATCH 01/19] net: remove unused includes of if_tun.h and if_tap.h Mark McLoughlin
@ 2009-10-22 16:43 ` Mark McLoughlin
2009-10-22 16:43 ` [Qemu-devel] [PATCH 03/19] net: make tap_receive() re-use tap_receive_iov() code Mark McLoughlin
` (18 subsequent siblings)
20 siblings, 0 replies; 37+ messages in thread
From: Mark McLoughlin @ 2009-10-22 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Mark McLoughlin
Making features dependent on the availability of newer versions if_tun.h
is going to get seriously clumsy, so let's just import the definitions
we need. It's only a small handful.
If and when we're comfortable depending on 2.6.30 headers, we can remove
this again.
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
net.c | 11 +----------
qemu-options.hx | 8 +-------
tap-linux.h | 29 +++++++++++++++++++++++++++++
3 files changed, 31 insertions(+), 17 deletions(-)
create mode 100644 tap-linux.h
diff --git a/net.c b/net.c
index 4708080..0e3388b 100644
--- a/net.c
+++ b/net.c
@@ -46,7 +46,7 @@
#include <net/if_tap.h>
#endif
#ifdef __linux__
-#include <linux/if_tun.h>
+#include "tap-linux.h"
#endif
#include <arpa/inet.h>
#include <dirent.h>
@@ -1370,7 +1370,6 @@ static void tap_send(void *opaque)
} while (size > 0);
}
-#ifdef TUNSETSNDBUF
/* sndbuf should be set to a value lower than the tx queue
* capacity of any destination network interface.
* Ethernet NICs generally have txqueuelen=1000, so 1Mb is
@@ -1393,12 +1392,6 @@ static int tap_set_sndbuf(TAPState *s, QemuOpts *opts)
}
return 0;
}
-#else
-static int tap_set_sndbuf(TAPState *s, QemuOpts *opts)
-{
- return 0;
-}
-#endif /* TUNSETSNDBUF */
static void tap_cleanup(VLANClientState *vc)
{
@@ -2972,12 +2965,10 @@ static struct {
.name = "downscript",
.type = QEMU_OPT_STRING,
.help = "script to shut down the interface",
-#ifdef TUNSETSNDBUF
}, {
.name = "sndbuf",
.type = QEMU_OPT_SIZE,
.help = "send buffer limit"
-#endif
},
{ /* end of list */ }
},
diff --git a/qemu-options.hx b/qemu-options.hx
index 20aa242..c745e0c 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -810,21 +810,15 @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
"-net tap[,vlan=n][,name=str],ifname=name\n"
" connect the host TAP network interface to VLAN 'n'\n"
#else
- "-net tap[,vlan=n][,name=str][,fd=h][,ifname=name][,script=file][,downscript=dfile]"
-#ifdef TUNSETSNDBUF
- "[,sndbuf=nbytes]"
-#endif
- "\n"
+ "-net tap[,vlan=n][,name=str][,fd=h][,ifname=name][,script=file][,downscript=dfile][,sndbuf=nbytes]\n"
" connect the host TAP network interface to VLAN 'n' and use the\n"
" network scripts 'file' (default=%s)\n"
" and 'dfile' (default=%s);\n"
" use '[down]script=no' to disable script execution;\n"
" use 'fd=h' to connect to an already opened TAP interface\n"
-#ifdef TUNSETSNDBUF
" use 'sndbuf=nbytes' to limit the size of the send buffer; the\n"
" default of 'sndbuf=1048576' can be disabled using 'sndbuf=0'\n"
#endif
-#endif
"-net socket[,vlan=n][,name=str][,fd=h][,listen=[host]:port][,connect=host:port]\n"
" connect the vlan 'n' to another VLAN using a socket connection\n"
"-net socket[,vlan=n][,name=str][,fd=h][,mcast=maddr:port]\n"
diff --git a/tap-linux.h b/tap-linux.h
new file mode 100644
index 0000000..cd07ea8
--- /dev/null
+++ b/tap-linux.h
@@ -0,0 +1,29 @@
+/*
+ * Universal TUN/TAP device driver.
+ * Copyright (C) 1999-2000 Maxim Krasnyansky <max_mk@yahoo.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef QEMU_TAP_H
+#define QEMU_TAP_H
+
+#include <linux/ioctl.h>
+
+/* Ioctl defines */
+#define TUNSETIFF _IOW('T', 202, int)
+#define TUNSETSNDBUF _IOW('T', 212, int)
+
+/* TUNSETIFF ifr flags */
+#define IFF_TAP 0x0002
+#define IFF_NO_PI 0x1000
+
+#endif /* QEMU_TAP_H */
--
1.6.2.5
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [Qemu-devel] [PATCH 03/19] net: make tap_receive() re-use tap_receive_iov() code
2009-10-22 16:43 [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO Mark McLoughlin
2009-10-22 16:43 ` [Qemu-devel] [PATCH 01/19] net: remove unused includes of if_tun.h and if_tap.h Mark McLoughlin
2009-10-22 16:43 ` [Qemu-devel] [PATCH 02/19] net: import linux tap ioctl definitions Mark McLoughlin
@ 2009-10-22 16:43 ` Mark McLoughlin
2009-10-22 16:43 ` [Qemu-devel] [PATCH 04/19] net: enable IFF_VNET_HDR on tap fds if available Mark McLoughlin
` (17 subsequent siblings)
20 siblings, 0 replies; 37+ messages in thread
From: Mark McLoughlin @ 2009-10-22 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Mark McLoughlin
In future we will want to prepend a virtio_net header if the NIC didn't
supply one but IFF_VNET_HDR is enabled on the interface. This is most
easily achived by using writev() in all cases.
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
net.c | 23 +++++++++++++++--------
1 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/net.c b/net.c
index 0e3388b..728941a 100644
--- a/net.c
+++ b/net.c
@@ -1291,10 +1291,8 @@ static void tap_writable(void *opaque)
qemu_flush_queued_packets(s->vc);
}
-static ssize_t tap_receive_iov(VLANClientState *vc, const struct iovec *iov,
- int iovcnt)
+static ssize_t tap_write_packet(TAPState *s, const struct iovec *iov, int iovcnt)
{
- TAPState *s = vc->opaque;
ssize_t len;
do {
@@ -1309,16 +1307,25 @@ static ssize_t tap_receive_iov(VLANClientState *vc, const struct iovec *iov,
return len;
}
+static ssize_t tap_receive_iov(VLANClientState *vc, const struct iovec *iov,
+ int iovcnt)
+{
+ TAPState *s = vc->opaque;
+
+ return tap_write_packet(s, iov, iovcnt);
+}
+
static ssize_t tap_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
{
TAPState *s = vc->opaque;
- ssize_t len;
+ struct iovec iov[1];
+ int iovcnt = 0;
- do {
- len = write(s->fd, buf, size);
- } while (len == -1 && (errno == EINTR || errno == EAGAIN));
+ iov[iovcnt].iov_base = (char *)buf;
+ iov[iovcnt].iov_len = size;
+ iovcnt++;
- return len;
+ return tap_write_packet(s, iov, iovcnt);
}
static int tap_can_send(void *opaque)
--
1.6.2.5
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [Qemu-devel] [PATCH 04/19] net: enable IFF_VNET_HDR on tap fds if available
2009-10-22 16:43 [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO Mark McLoughlin
` (2 preceding siblings ...)
2009-10-22 16:43 ` [Qemu-devel] [PATCH 03/19] net: make tap_receive() re-use tap_receive_iov() code Mark McLoughlin
@ 2009-10-22 16:43 ` Mark McLoughlin
2009-10-22 16:43 ` [Qemu-devel] [PATCH 05/19] net: refactor tap initialization Mark McLoughlin
` (16 subsequent siblings)
20 siblings, 0 replies; 37+ messages in thread
From: Mark McLoughlin @ 2009-10-22 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Mark McLoughlin
For now, we just add an empty header before writing and strip the header
after reading.
We really only want IFF_VNET_HDR when virtio_net is using it, but it
would significantly complicate matters to try and do that. There should
be little or no performance impact with always adding headers.
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
net.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++---------
tap-linux.h | 14 ++++++++++
2 files changed, 84 insertions(+), 13 deletions(-)
diff --git a/net.c b/net.c
index 728941a..356a280 100644
--- a/net.c
+++ b/net.c
@@ -1245,14 +1245,20 @@ void do_info_usernet(Monitor *mon)
#if !defined(_WIN32)
+/* Maximum GSO packet size (64k) plus plenty of room for
+ * the ethernet and virtio_net headers
+ */
+#define TAP_BUFSIZE (4096 + 65536)
+
typedef struct TAPState {
VLANClientState *vc;
int fd;
char down_script[1024];
char down_script_arg[128];
- uint8_t buf[4096];
+ uint8_t buf[TAP_BUFSIZE];
unsigned int read_poll : 1;
unsigned int write_poll : 1;
+ unsigned int has_vnet_hdr : 1;
} TAPState;
static int launch_script(const char *setup_script, const char *ifname, int fd);
@@ -1311,15 +1317,33 @@ static ssize_t tap_receive_iov(VLANClientState *vc, const struct iovec *iov,
int iovcnt)
{
TAPState *s = vc->opaque;
+ const struct iovec *iovp = iov;
+ struct iovec iov_copy[iovcnt + 1];
+ struct virtio_net_hdr hdr = { 0, };
- return tap_write_packet(s, iov, iovcnt);
+ if (s->has_vnet_hdr) {
+ iov_copy[0].iov_base = &hdr;
+ iov_copy[0].iov_len = sizeof(hdr);
+ memcpy(&iov_copy[1], iov, iovcnt * sizeof(*iov));
+ iovp = iov_copy;
+ iovcnt++;
+ }
+
+ return tap_write_packet(s, iovp, iovcnt);
}
static ssize_t tap_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
{
TAPState *s = vc->opaque;
- struct iovec iov[1];
+ struct iovec iov[2];
int iovcnt = 0;
+ struct virtio_net_hdr hdr = { 0, };
+
+ if (s->has_vnet_hdr) {
+ iov[iovcnt].iov_base = &hdr;
+ iov[iovcnt].iov_len = sizeof(hdr);
+ iovcnt++;
+ }
iov[iovcnt].iov_base = (char *)buf;
iov[iovcnt].iov_len = size;
@@ -1365,12 +1389,19 @@ static void tap_send(void *opaque)
int size;
do {
+ uint8_t *buf = s->buf;
+
size = tap_read_packet(s->fd, s->buf, sizeof(s->buf));
if (size <= 0) {
break;
}
- size = qemu_send_packet_async(s->vc, s->buf, size, tap_send_completed);
+ if (s->has_vnet_hdr) {
+ buf += sizeof(struct virtio_net_hdr);
+ size -= sizeof(struct virtio_net_hdr);
+ }
+
+ size = qemu_send_packet_async(s->vc, buf, size, tap_send_completed);
if (size == 0) {
tap_read_poll(s, 0);
}
@@ -1400,6 +1431,18 @@ static int tap_set_sndbuf(TAPState *s, QemuOpts *opts)
return 0;
}
+static int tap_probe_vnet_hdr(int fd)
+{
+ struct ifreq ifr;
+
+ if (ioctl(fd, TUNGETIFF, &ifr) != 0) {
+ qemu_error("TUNGETIFF ioctl() failed: %s\n", strerror(errno));
+ return 0;
+ }
+
+ return ifr.ifr_flags & IFF_VNET_HDR;
+}
+
static void tap_cleanup(VLANClientState *vc)
{
TAPState *s = vc->opaque;
@@ -1420,12 +1463,14 @@ static void tap_cleanup(VLANClientState *vc)
static TAPState *net_tap_fd_init(VLANState *vlan,
const char *model,
const char *name,
- int fd)
+ int fd,
+ int vnet_hdr)
{
TAPState *s;
s = qemu_mallocz(sizeof(TAPState));
s->fd = fd;
+ s->has_vnet_hdr = vnet_hdr != 0;
s->vc = qemu_new_vlan_client(vlan, NULL, model, name, NULL,
tap_receive, tap_receive_iov,
tap_cleanup, s);
@@ -1435,7 +1480,7 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
}
#if defined (CONFIG_BSD) || defined (__FreeBSD_kernel__)
-static int tap_open(char *ifname, int ifname_size)
+static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
{
int fd;
char *dev;
@@ -1577,7 +1622,7 @@ static int tap_alloc(char *dev, size_t dev_size)
return tap_fd;
}
-static int tap_open(char *ifname, int ifname_size)
+static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
{
char dev[10]="";
int fd;
@@ -1590,13 +1635,13 @@ static int tap_open(char *ifname, int ifname_size)
return fd;
}
#elif defined (_AIX)
-static int tap_open(char *ifname, int ifname_size)
+static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
{
fprintf (stderr, "no tap on AIX\n");
return -1;
}
#else
-static int tap_open(char *ifname, int ifname_size)
+static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
{
struct ifreq ifr;
int fd, ret;
@@ -1608,6 +1653,17 @@ static int tap_open(char *ifname, int ifname_size)
}
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+
+ {
+ unsigned int features;
+
+ if (ioctl(fd, TUNGETFEATURES, &features) == 0 &&
+ features & IFF_VNET_HDR) {
+ *vnet_hdr = 1;
+ ifr.ifr_flags |= IFF_VNET_HDR;
+ }
+ }
+
if (ifname[0] != '\0')
pstrcpy(ifr.ifr_name, IFNAMSIZ, ifname);
else
@@ -1673,14 +1729,15 @@ static TAPState *net_tap_init(VLANState *vlan, const char *model,
const char *setup_script, const char *down_script)
{
TAPState *s;
- int fd;
+ int fd, vnet_hdr;
char ifname[128];
if (ifname1 != NULL)
pstrcpy(ifname, sizeof(ifname), ifname1);
else
ifname[0] = '\0';
- TFR(fd = tap_open(ifname, sizeof(ifname)));
+ vnet_hdr = 0;
+ TFR(fd = tap_open(ifname, sizeof(ifname), &vnet_hdr));
if (fd < 0)
return NULL;
@@ -1690,7 +1747,7 @@ static TAPState *net_tap_init(VLANState *vlan, const char *model,
launch_script(setup_script, ifname, fd)) {
return NULL;
}
- s = net_tap_fd_init(vlan, model, name, fd);
+ s = net_tap_fd_init(vlan, model, name, fd, vnet_hdr);
snprintf(s->vc->info_str, sizeof(s->vc->info_str),
"ifname=%s,script=%s,downscript=%s",
ifname, setup_script, down_script);
@@ -2644,7 +2701,7 @@ static int net_init_tap(QemuOpts *opts,
fcntl(fd, F_SETFL, O_NONBLOCK);
- s = net_tap_fd_init(vlan, "tap", name, fd);
+ s = net_tap_fd_init(vlan, "tap", name, fd, tap_probe_vnet_hdr(fd));
if (!s) {
close(fd);
}
diff --git a/tap-linux.h b/tap-linux.h
index cd07ea8..8e75348 100644
--- a/tap-linux.h
+++ b/tap-linux.h
@@ -16,14 +16,28 @@
#ifndef QEMU_TAP_H
#define QEMU_TAP_H
+#include <stdint.h>
#include <linux/ioctl.h>
/* Ioctl defines */
#define TUNSETIFF _IOW('T', 202, int)
+#define TUNGETFEATURES _IOR('T', 207, unsigned int)
+#define TUNGETIFF _IOR('T', 210, unsigned int)
#define TUNSETSNDBUF _IOW('T', 212, int)
/* TUNSETIFF ifr flags */
#define IFF_TAP 0x0002
#define IFF_NO_PI 0x1000
+#define IFF_VNET_HDR 0x4000
+
+struct virtio_net_hdr
+{
+ uint8_t flags;
+ uint8_t gso_type;
+ uint16_t hdr_len;
+ uint16_t gso_size;
+ uint16_t csum_start;
+ uint16_t csum_offset;
+};
#endif /* QEMU_TAP_H */
--
1.6.2.5
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [Qemu-devel] [PATCH 05/19] net: refactor tap initialization
2009-10-22 16:43 [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO Mark McLoughlin
` (3 preceding siblings ...)
2009-10-22 16:43 ` [Qemu-devel] [PATCH 04/19] net: enable IFF_VNET_HDR on tap fds if available Mark McLoughlin
@ 2009-10-22 16:43 ` Mark McLoughlin
2009-10-22 16:43 ` [Qemu-devel] [PATCH 06/19] net: add a vnet_hdr=on|off parameter Mark McLoughlin
` (15 subsequent siblings)
20 siblings, 0 replies; 37+ messages in thread
From: Mark McLoughlin @ 2009-10-22 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Mark McLoughlin
Re-factor things so that there is only one call site for
net_tap_fd_init().
Two concerns about the QemuOpts usage here - firstly, we set the script
arguments to their default value and, secondly, we set the ifname value
to the name allocated by the kernel if none is supplied. Are we okay
with such things ending up in writeconfig output?
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
net.c | 97 +++++++++++++++++++++++++++++++++++------------------------------
1 files changed, 52 insertions(+), 45 deletions(-)
diff --git a/net.c b/net.c
index 356a280..fccabdb 100644
--- a/net.c
+++ b/net.c
@@ -1475,7 +1475,6 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
tap_receive, tap_receive_iov,
tap_cleanup, s);
tap_read_poll(s, 1);
- snprintf(s->vc->info_str, sizeof(s->vc->info_str), "fd=%d", fd);
return s;
}
@@ -1724,38 +1723,34 @@ static int launch_script(const char *setup_script, const char *ifname, int fd)
return -1;
}
-static TAPState *net_tap_init(VLANState *vlan, const char *model,
- const char *name, const char *ifname1,
- const char *setup_script, const char *down_script)
+static int net_tap_init(QemuOpts *opts, int *vnet_hdr)
{
- TAPState *s;
- int fd, vnet_hdr;
- char ifname[128];
+ int fd;
+ char ifname[128] = {0,};
+ const char *setup_script;
- if (ifname1 != NULL)
- pstrcpy(ifname, sizeof(ifname), ifname1);
- else
- ifname[0] = '\0';
- vnet_hdr = 0;
- TFR(fd = tap_open(ifname, sizeof(ifname), &vnet_hdr));
- if (fd < 0)
- return NULL;
+ if (qemu_opt_get(opts, "ifname")) {
+ pstrcpy(ifname, sizeof(ifname), qemu_opt_get(opts, "ifname"));
+ }
- if (!setup_script || !strcmp(setup_script, "no"))
- setup_script = "";
- if (setup_script[0] != '\0' &&
- launch_script(setup_script, ifname, fd)) {
- return NULL;
+ *vnet_hdr = 0;
+ TFR(fd = tap_open(ifname, sizeof(ifname), vnet_hdr));
+ if (fd < 0) {
+ return -1;
}
- s = net_tap_fd_init(vlan, model, name, fd, vnet_hdr);
- snprintf(s->vc->info_str, sizeof(s->vc->info_str),
- "ifname=%s,script=%s,downscript=%s",
- ifname, setup_script, down_script);
- if (down_script && strcmp(down_script, "no")) {
- snprintf(s->down_script, sizeof(s->down_script), "%s", down_script);
- snprintf(s->down_script_arg, sizeof(s->down_script_arg), "%s", ifname);
+
+ setup_script = qemu_opt_get(opts, "script");
+ if (setup_script &&
+ setup_script[0] != '\0' &&
+ strcmp(setup_script, "no") != 0 &&
+ launch_script(setup_script, ifname, fd)) {
+ close(fd);
+ return -1;
}
- return s;
+
+ qemu_opt_set(opts, "ifname", ifname);
+
+ return fd;
}
#endif /* !_WIN32 */
@@ -2683,10 +2678,9 @@ static int net_init_tap(QemuOpts *opts,
VLANState *vlan)
{
TAPState *s;
+ int fd, vnet_hdr;
if (qemu_opt_get(opts, "fd")) {
- int fd;
-
if (qemu_opt_get(opts, "ifname") ||
qemu_opt_get(opts, "script") ||
qemu_opt_get(opts, "downscript")) {
@@ -2701,28 +2695,22 @@ static int net_init_tap(QemuOpts *opts,
fcntl(fd, F_SETFL, O_NONBLOCK);
- s = net_tap_fd_init(vlan, "tap", name, fd, tap_probe_vnet_hdr(fd));
- if (!s) {
- close(fd);
- }
+ vnet_hdr = tap_probe_vnet_hdr(fd);
} else {
- const char *ifname, *script, *downscript;
-
- ifname = qemu_opt_get(opts, "ifname");
- script = qemu_opt_get(opts, "script");
- downscript = qemu_opt_get(opts, "downscript");
-
- if (!script) {
- script = DEFAULT_NETWORK_SCRIPT;
+ if (!qemu_opt_get(opts, "script")) {
+ qemu_opt_set(opts, "script", DEFAULT_NETWORK_SCRIPT);
}
- if (!downscript) {
- downscript = DEFAULT_NETWORK_DOWN_SCRIPT;
+
+ if (!qemu_opt_get(opts, "downscript")) {
+ qemu_opt_set(opts, "downscript", DEFAULT_NETWORK_DOWN_SCRIPT);
}
- s = net_tap_init(vlan, "tap", name, ifname, script, downscript);
+ fd = net_tap_init(opts, &vnet_hdr);
}
+ s = net_tap_fd_init(vlan, "tap", name, fd, vnet_hdr);
if (!s) {
+ close(fd);
return -1;
}
@@ -2730,6 +2718,25 @@ static int net_init_tap(QemuOpts *opts,
return -1;
}
+ if (qemu_opt_get(opts, "fd")) {
+ snprintf(s->vc->info_str, sizeof(s->vc->info_str), "fd=%d", fd);
+ } else {
+ const char *ifname, *script, *downscript;
+
+ ifname = qemu_opt_get(opts, "ifname");
+ script = qemu_opt_get(opts, "script");
+ downscript = qemu_opt_get(opts, "downscript");
+
+ snprintf(s->vc->info_str, sizeof(s->vc->info_str),
+ "ifname=%s,script=%s,downscript=%s",
+ ifname, script, downscript);
+
+ if (strcmp(downscript, "no") != 0) {
+ snprintf(s->down_script, sizeof(s->down_script), "%s", downscript);
+ snprintf(s->down_script_arg, sizeof(s->down_script_arg), "%s", ifname);
+ }
+ }
+
if (vlan) {
vlan->nb_host_devs++;
}
--
1.6.2.5
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [Qemu-devel] [PATCH 06/19] net: add a vnet_hdr=on|off parameter
2009-10-22 16:43 [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO Mark McLoughlin
` (4 preceding siblings ...)
2009-10-22 16:43 ` [Qemu-devel] [PATCH 05/19] net: refactor tap initialization Mark McLoughlin
@ 2009-10-22 16:43 ` Mark McLoughlin
2009-10-22 16:43 ` [Qemu-devel] [PATCH 07/19] net: add a client type code Mark McLoughlin
` (14 subsequent siblings)
20 siblings, 0 replies; 37+ messages in thread
From: Mark McLoughlin @ 2009-10-22 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Mark McLoughlin
This allows people to disable the IFF_VNET_HDR flag, e.g. for debugging
purposes or if they know they may migrate the guest to a machine without
IFF_VNET_HDR support.
It also allows making the lack of IFF_VNET_HDR support an error
condition, e.g. in the case where a guest is being migrated from a host
which does support it.
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
net.c | 42 ++++++++++++++++++++++++++++++++----------
qemu-options.hx | 4 +++-
2 files changed, 35 insertions(+), 11 deletions(-)
diff --git a/net.c b/net.c
index fccabdb..d62ab7b 100644
--- a/net.c
+++ b/net.c
@@ -1479,7 +1479,8 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
}
#if defined (CONFIG_BSD) || defined (__FreeBSD_kernel__)
-static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
+static int tap_open(char *ifname, int ifname_size,
+ int *vnet_hdr, int vnet_hdr_required)
{
int fd;
char *dev;
@@ -1621,7 +1622,8 @@ static int tap_alloc(char *dev, size_t dev_size)
return tap_fd;
}
-static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
+static int tap_open(char *ifname, int ifname_size,
+ int *vnet_hdr, int vnet_hdr_required)
{
char dev[10]="";
int fd;
@@ -1634,13 +1636,15 @@ static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
return fd;
}
#elif defined (_AIX)
-static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
+static int tap_open(char *ifname, int ifname_size,
+ int *vnet_hdr, int vnet_hdr_required)
{
fprintf (stderr, "no tap on AIX\n");
return -1;
}
#else
-static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
+static int tap_open(char *ifname, int ifname_size,
+ int *vnet_hdr, int vnet_hdr_required)
{
struct ifreq ifr;
int fd, ret;
@@ -1653,7 +1657,7 @@ static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
- {
+ if (*vnet_hdr) {
unsigned int features;
if (ioctl(fd, TUNGETFEATURES, &features) == 0 &&
@@ -1661,6 +1665,13 @@ static int tap_open(char *ifname, int ifname_size, int *vnet_hdr)
*vnet_hdr = 1;
ifr.ifr_flags |= IFF_VNET_HDR;
}
+
+ if (vnet_hdr_required && !*vnet_hdr) {
+ qemu_error("vnet_hdr=1 requested, but no kernel "
+ "support for IFF_VNET_HDR available");
+ close(fd);
+ return -1;
+ }
}
if (ifname[0] != '\0')
@@ -1725,7 +1736,7 @@ static int launch_script(const char *setup_script, const char *ifname, int fd)
static int net_tap_init(QemuOpts *opts, int *vnet_hdr)
{
- int fd;
+ int fd, vnet_hdr_required;
char ifname[128] = {0,};
const char *setup_script;
@@ -1733,8 +1744,14 @@ static int net_tap_init(QemuOpts *opts, int *vnet_hdr)
pstrcpy(ifname, sizeof(ifname), qemu_opt_get(opts, "ifname"));
}
- *vnet_hdr = 0;
- TFR(fd = tap_open(ifname, sizeof(ifname), vnet_hdr));
+ *vnet_hdr = qemu_opt_get_bool(opts, "vnet_hdr", 1);
+ if (qemu_opt_get(opts, "vnet_hdr")) {
+ vnet_hdr_required = *vnet_hdr;
+ } else {
+ vnet_hdr_required = 0;
+ }
+
+ TFR(fd = tap_open(ifname, sizeof(ifname), vnet_hdr, vnet_hdr_required));
if (fd < 0) {
return -1;
}
@@ -2683,8 +2700,9 @@ static int net_init_tap(QemuOpts *opts,
if (qemu_opt_get(opts, "fd")) {
if (qemu_opt_get(opts, "ifname") ||
qemu_opt_get(opts, "script") ||
- qemu_opt_get(opts, "downscript")) {
- qemu_error("ifname=, script= and downscript= is invalid with fd=\n");
+ qemu_opt_get(opts, "downscript") ||
+ qemu_opt_get(opts, "vnet_hdr")) {
+ qemu_error("ifname=, script=, downscript= and vnet_hdr= is invalid with fd=\n");
return -1;
}
@@ -3040,6 +3058,10 @@ static struct {
.name = "sndbuf",
.type = QEMU_OPT_SIZE,
.help = "send buffer limit"
+ }, {
+ .name = "vnet_hdr",
+ .type = QEMU_OPT_BOOL,
+ .help = "enable the IFF_VNET_HDR flag on the tap interface"
},
{ /* end of list */ }
},
diff --git a/qemu-options.hx b/qemu-options.hx
index c745e0c..d78b738 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -810,7 +810,7 @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
"-net tap[,vlan=n][,name=str],ifname=name\n"
" connect the host TAP network interface to VLAN 'n'\n"
#else
- "-net tap[,vlan=n][,name=str][,fd=h][,ifname=name][,script=file][,downscript=dfile][,sndbuf=nbytes]\n"
+ "-net tap[,vlan=n][,name=str][,fd=h][,ifname=name][,script=file][,downscript=dfile][,sndbuf=nbytes][,vnet_hdr=on|off]\n"
" connect the host TAP network interface to VLAN 'n' and use the\n"
" network scripts 'file' (default=%s)\n"
" and 'dfile' (default=%s);\n"
@@ -818,6 +818,8 @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
" use 'fd=h' to connect to an already opened TAP interface\n"
" use 'sndbuf=nbytes' to limit the size of the send buffer; the\n"
" default of 'sndbuf=1048576' can be disabled using 'sndbuf=0'\n"
+ " use vnet_hdr=off to avoid enabling the IFF_VNET_HDR tap flag; use\n"
+ " vnet_hdr=on to make the lack of IFF_VNET_HDR support an error condition\n"
#endif
"-net socket[,vlan=n][,name=str][,fd=h][,listen=[host]:port][,connect=host:port]\n"
" connect the vlan 'n' to another VLAN using a socket connection\n"
--
1.6.2.5
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [Qemu-devel] [PATCH 07/19] net: add a client type code
2009-10-22 16:43 [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO Mark McLoughlin
` (5 preceding siblings ...)
2009-10-22 16:43 ` [Qemu-devel] [PATCH 06/19] net: add a vnet_hdr=on|off parameter Mark McLoughlin
@ 2009-10-22 16:43 ` Mark McLoughlin
2009-10-22 16:43 ` [Qemu-devel] [PATCH 08/19] net: add tap_has_vnet_hdr() and tap_using_vnet_hdr() APIs Mark McLoughlin
` (13 subsequent siblings)
20 siblings, 0 replies; 37+ messages in thread
From: Mark McLoughlin @ 2009-10-22 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Mark McLoughlin
This is so as to allow APIs which operate on specific client types
without having to add a function table entry which is only implemented
by a single client type.
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
hw/dp8393x.c | 3 ++-
hw/etraxfs_eth.c | 3 ++-
hw/mcf_fec.c | 3 ++-
hw/mipsnet.c | 3 ++-
hw/qdev.c | 3 ++-
hw/usb-net.c | 3 ++-
hw/xen_nic.c | 3 ++-
net.c | 22 +++++++++++++++-------
net.h | 14 +++++++++++++-
tap-win32.c | 3 ++-
10 files changed, 44 insertions(+), 16 deletions(-)
diff --git a/hw/dp8393x.c b/hw/dp8393x.c
index e4caab0..5622170 100644
--- a/hw/dp8393x.c
+++ b/hw/dp8393x.c
@@ -889,7 +889,8 @@ void dp83932_init(NICInfo *nd, target_phys_addr_t base, int it_shift,
s->watchdog = qemu_new_timer(vm_clock, dp8393x_watchdog, s);
s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux */
- s->vc = nd->vc = qemu_new_vlan_client(nd->vlan, nd->netdev,
+ s->vc = nd->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
+ nd->vlan, nd->netdev,
nd->model, nd->name,
nic_can_receive, nic_receive, NULL,
nic_cleanup, s);
diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c
index a411dab..2a583a3 100644
--- a/hw/etraxfs_eth.c
+++ b/hw/etraxfs_eth.c
@@ -590,7 +590,8 @@ void *etraxfs_eth_init(NICInfo *nd, target_phys_addr_t base, int phyaddr)
eth->ethregs = cpu_register_io_memory(eth_read, eth_write, eth);
cpu_register_physical_memory (base, 0x5c, eth->ethregs);
- eth->vc = nd->vc = qemu_new_vlan_client(nd->vlan, nd->netdev,
+ eth->vc = nd->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
+ nd->vlan, nd->netdev,
nd->model, nd->name,
eth_can_receive, eth_receive,
NULL, eth_cleanup, eth);
diff --git a/hw/mcf_fec.c b/hw/mcf_fec.c
index f9f437a..0567bcd 100644
--- a/hw/mcf_fec.c
+++ b/hw/mcf_fec.c
@@ -462,7 +462,8 @@ void mcf_fec_init(NICInfo *nd, target_phys_addr_t base, qemu_irq *irq)
mcf_fec_writefn, s);
cpu_register_physical_memory(base, 0x400, s->mmio_index);
- s->vc = nd->vc = qemu_new_vlan_client(nd->vlan, nd->netdev,
+ s->vc = nd->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
+ nd->vlan, nd->netdev,
nd->model, nd->name,
mcf_fec_can_receive, mcf_fec_receive,
NULL, mcf_fec_cleanup, s);
diff --git a/hw/mipsnet.c b/hw/mipsnet.c
index ea8b570..d32099f 100644
--- a/hw/mipsnet.c
+++ b/hw/mipsnet.c
@@ -263,7 +263,8 @@ void mipsnet_init (int base, qemu_irq irq, NICInfo *nd)
s->io_base = base;
s->irq = irq;
if (nd) {
- s->vc = nd->vc = qemu_new_vlan_client(nd->vlan, nd->netdev,
+ s->vc = nd->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
+ nd->vlan, nd->netdev,
nd->model, nd->name,
mipsnet_can_receive, mipsnet_receive,
NULL, mipsnet_cleanup, s);
diff --git a/hw/qdev.c b/hw/qdev.c
index 20f931c..bc3a0d5 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -370,7 +370,8 @@ VLANClientState *qdev_get_vlan_client(DeviceState *dev,
{
NICInfo *nd = dev->nd;
assert(nd);
- nd->vc = qemu_new_vlan_client(nd->vlan, nd->netdev,
+ nd->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
+ nd->vlan, nd->netdev,
nd->model, nd->name,
can_receive, receive, receive_iov,
cleanup, opaque);
diff --git a/hw/usb-net.c b/hw/usb-net.c
index 5c753e0..2393812 100644
--- a/hw/usb-net.c
+++ b/hw/usb-net.c
@@ -1460,7 +1460,8 @@ USBDevice *usb_net_init(NICInfo *nd)
memcpy(s->mac, nd->macaddr, 6);
- s->vc = nd->vc = qemu_new_vlan_client(nd->vlan, nd->netdev,
+ s->vc = nd->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
+ nd->vlan, nd->netdev,
nd->model, nd->name,
usbnet_can_receive,
usbnet_receive,
diff --git a/hw/xen_nic.c b/hw/xen_nic.c
index b09b48a..2a179f0 100644
--- a/hw/xen_nic.c
+++ b/hw/xen_nic.c
@@ -301,7 +301,8 @@ static int net_init(struct XenDevice *xendev)
return -1;
vlan = qemu_find_vlan(netdev->xendev.dev, 1);
- netdev->vs = qemu_new_vlan_client(vlan, NULL, "xen", NULL,
+ netdev->vs = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
+ vlan, NULL, "xen", NULL,
net_rx_ok, net_rx_packet, NULL,
NULL, netdev);
snprintf(netdev->vs->info_str, sizeof(netdev->vs->info_str),
diff --git a/net.c b/net.c
index d62ab7b..638ba36 100644
--- a/net.c
+++ b/net.c
@@ -310,7 +310,8 @@ static ssize_t qemu_deliver_packet_iov(VLANClientState *sender,
int iovcnt,
void *opaque);
-VLANClientState *qemu_new_vlan_client(VLANState *vlan,
+VLANClientState *qemu_new_vlan_client(net_client_type type,
+ VLANState *vlan,
VLANClientState *peer,
const char *model,
const char *name,
@@ -324,6 +325,7 @@ VLANClientState *qemu_new_vlan_client(VLANState *vlan,
vc = qemu_mallocz(sizeof(VLANClientState));
+ vc->type = type;
vc->model = qemu_strdup(model);
if (name)
vc->name = qemu_strdup(name);
@@ -865,7 +867,8 @@ static int net_slirp_init(VLANState *vlan, const char *model,
}
#endif
- s->vc = qemu_new_vlan_client(vlan, NULL, model, name, NULL,
+ s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_SLIRP,
+ vlan, NULL, model, name, NULL,
slirp_receive, NULL,
net_slirp_cleanup, s);
snprintf(s->vc->info_str, sizeof(s->vc->info_str),
@@ -1471,7 +1474,8 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
s = qemu_mallocz(sizeof(TAPState));
s->fd = fd;
s->has_vnet_hdr = vnet_hdr != 0;
- s->vc = qemu_new_vlan_client(vlan, NULL, model, name, NULL,
+ s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_TAP,
+ vlan, NULL, model, name, NULL,
tap_receive, tap_receive_iov,
tap_cleanup, s);
tap_read_poll(s, 1);
@@ -1830,7 +1834,8 @@ static int net_vde_init(VLANState *vlan, const char *model,
free(s);
return -1;
}
- s->vc = qemu_new_vlan_client(vlan, NULL, model, name, NULL,
+ s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_VDE,
+ vlan, NULL, model, name, NULL,
vde_receive, NULL,
vde_cleanup, s);
qemu_set_fd_handler(vde_datafd(s->vde), vde_to_qemu, NULL, s);
@@ -2070,7 +2075,8 @@ static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan,
s = qemu_mallocz(sizeof(NetSocketState));
s->fd = fd;
- s->vc = qemu_new_vlan_client(vlan, NULL, model, name, NULL,
+ s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_SOCKET,
+ vlan, NULL, model, name, NULL,
net_socket_receive_dgram, NULL,
net_socket_cleanup, s);
qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
@@ -2099,7 +2105,8 @@ static NetSocketState *net_socket_fd_init_stream(VLANState *vlan,
NetSocketState *s;
s = qemu_mallocz(sizeof(NetSocketState));
s->fd = fd;
- s->vc = qemu_new_vlan_client(vlan, NULL, model, name, NULL,
+ s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_SOCKET,
+ vlan, NULL, model, name, NULL,
net_socket_receive, NULL,
net_socket_cleanup, s);
snprintf(s->vc->info_str, sizeof(s->vc->info_str),
@@ -2381,7 +2388,8 @@ static int net_dump_init(VLANState *vlan, const char *device,
return -1;
}
- s->pcap_vc = qemu_new_vlan_client(vlan, NULL, device, name, NULL,
+ s->pcap_vc = qemu_new_vlan_client(NET_CLIENT_TYPE_DUMP,
+ vlan, NULL, device, name, NULL,
dump_receive, NULL,
net_dump_cleanup, s);
snprintf(s->pcap_vc->info_str, sizeof(s->pcap_vc->info_str),
diff --git a/net.h b/net.h
index 439de2a..aefeef4 100644
--- a/net.h
+++ b/net.h
@@ -9,6 +9,16 @@
/* VLANs support */
+typedef enum {
+ NET_CLIENT_TYPE_NONE,
+ NET_CLIENT_TYPE_NIC,
+ NET_CLIENT_TYPE_SLIRP,
+ NET_CLIENT_TYPE_TAP,
+ NET_CLIENT_TYPE_SOCKET,
+ NET_CLIENT_TYPE_VDE,
+ NET_CLIENT_TYPE_DUMP
+} net_client_type;
+
typedef int (NetCanReceive)(VLANClientState *);
typedef ssize_t (NetReceive)(VLANClientState *, const uint8_t *, size_t);
typedef ssize_t (NetReceiveIOV)(VLANClientState *, const struct iovec *, int);
@@ -16,6 +26,7 @@ typedef void (NetCleanup) (VLANClientState *);
typedef void (LinkStatusChanged)(VLANClientState *);
struct VLANClientState {
+ net_client_type type;
NetReceive *receive;
NetReceiveIOV *receive_iov;
/* Packets may still be sent if this returns zero. It's used to
@@ -43,7 +54,8 @@ struct VLANState {
};
VLANState *qemu_find_vlan(int id, int allocate);
-VLANClientState *qemu_new_vlan_client(VLANState *vlan,
+VLANClientState *qemu_new_vlan_client(net_client_type type,
+ VLANState *vlan,
VLANClientState *peer,
const char *model,
const char *name,
diff --git a/tap-win32.c b/tap-win32.c
index e4fdde8..e2bac3e 100644
--- a/tap-win32.c
+++ b/tap-win32.c
@@ -677,7 +677,8 @@ int tap_win32_init(VLANState *vlan, const char *model,
return -1;
}
- s->vc = qemu_new_vlan_client(vlan, NULL, model, name,
+ s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_TAP,
+ vlan, NULL, model, name,
NULL, tap_receive,
NULL, tap_cleanup, s);
--
1.6.2.5
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [Qemu-devel] [PATCH 08/19] net: add tap_has_vnet_hdr() and tap_using_vnet_hdr() APIs
2009-10-22 16:43 [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO Mark McLoughlin
` (6 preceding siblings ...)
2009-10-22 16:43 ` [Qemu-devel] [PATCH 07/19] net: add a client type code Mark McLoughlin
@ 2009-10-22 16:43 ` Mark McLoughlin
2009-10-22 16:43 ` [Qemu-devel] [PATCH 09/19] net: add flags parameter to packet queue interface Mark McLoughlin
` (12 subsequent siblings)
20 siblings, 0 replies; 37+ messages in thread
From: Mark McLoughlin @ 2009-10-22 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Mark McLoughlin
These lamely named functions allow virtio-net to query whether
IFF_VNET_HDR is enabled on a tap interface and inform the tap code
that virtio-net will supply packets with a vnet header.
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
net.c | 39 +++++++++++++++++++++++++++++++++++----
net.h | 3 +++
2 files changed, 38 insertions(+), 4 deletions(-)
diff --git a/net.c b/net.c
index 638ba36..56d979b 100644
--- a/net.c
+++ b/net.c
@@ -1246,7 +1246,15 @@ void do_info_usernet(Monitor *mon)
#endif /* CONFIG_SLIRP */
-#if !defined(_WIN32)
+#if defined(_WIN32)
+int tap_has_vnet_hdr(VLANClientState *vc)
+{
+ return 0;
+}
+void tap_using_vnet_hdr(VLANClientState *vc, int using_vnet_hdr)
+{
+}
+#else /* !defined(_WIN32) */
/* Maximum GSO packet size (64k) plus plenty of room for
* the ethernet and virtio_net headers
@@ -1262,6 +1270,7 @@ typedef struct TAPState {
unsigned int read_poll : 1;
unsigned int write_poll : 1;
unsigned int has_vnet_hdr : 1;
+ unsigned int using_vnet_hdr : 1;
} TAPState;
static int launch_script(const char *setup_script, const char *ifname, int fd);
@@ -1324,7 +1333,7 @@ static ssize_t tap_receive_iov(VLANClientState *vc, const struct iovec *iov,
struct iovec iov_copy[iovcnt + 1];
struct virtio_net_hdr hdr = { 0, };
- if (s->has_vnet_hdr) {
+ if (s->has_vnet_hdr && !s->using_vnet_hdr) {
iov_copy[0].iov_base = &hdr;
iov_copy[0].iov_len = sizeof(hdr);
memcpy(&iov_copy[1], iov, iovcnt * sizeof(*iov));
@@ -1342,7 +1351,7 @@ static ssize_t tap_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
int iovcnt = 0;
struct virtio_net_hdr hdr = { 0, };
- if (s->has_vnet_hdr) {
+ if (s->has_vnet_hdr && !s->using_vnet_hdr) {
iov[iovcnt].iov_base = &hdr;
iov[iovcnt].iov_len = sizeof(hdr);
iovcnt++;
@@ -1399,7 +1408,7 @@ static void tap_send(void *opaque)
break;
}
- if (s->has_vnet_hdr) {
+ if (s->has_vnet_hdr && !s->using_vnet_hdr) {
buf += sizeof(struct virtio_net_hdr);
size -= sizeof(struct virtio_net_hdr);
}
@@ -1434,6 +1443,27 @@ static int tap_set_sndbuf(TAPState *s, QemuOpts *opts)
return 0;
}
+int tap_has_vnet_hdr(VLANClientState *vc)
+{
+ TAPState *s = vc->opaque;
+
+ assert(vc->type == NET_CLIENT_TYPE_TAP);
+
+ return s->has_vnet_hdr;
+}
+
+void tap_using_vnet_hdr(VLANClientState *vc, int using_vnet_hdr)
+{
+ TAPState *s = vc->opaque;
+
+ using_vnet_hdr = using_vnet_hdr != 0;
+
+ assert(vc->type == NET_CLIENT_TYPE_TAP);
+ assert(s->has_vnet_hdr == using_vnet_hdr);
+
+ s->using_vnet_hdr = using_vnet_hdr;
+}
+
static int tap_probe_vnet_hdr(int fd)
{
struct ifreq ifr;
@@ -1474,6 +1504,7 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
s = qemu_mallocz(sizeof(TAPState));
s->fd = fd;
s->has_vnet_hdr = vnet_hdr != 0;
+ s->using_vnet_hdr = 0;
s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_TAP,
vlan, NULL, model, name, NULL,
tap_receive, tap_receive_iov,
diff --git a/net.h b/net.h
index aefeef4..5f28860 100644
--- a/net.h
+++ b/net.h
@@ -165,4 +165,7 @@ VLANClientState *qdev_get_vlan_client(DeviceState *dev,
NetCleanup *cleanup,
void *opaque);
+int tap_has_vnet_hdr(VLANClientState *vc);
+void tap_using_vnet_hdr(VLANClientState *vc, int using_vnet_hdr);
+
#endif
--
1.6.2.5
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [Qemu-devel] [PATCH 09/19] net: add flags parameter to packet queue interface
2009-10-22 16:43 [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO Mark McLoughlin
` (7 preceding siblings ...)
2009-10-22 16:43 ` [Qemu-devel] [PATCH 08/19] net: add tap_has_vnet_hdr() and tap_using_vnet_hdr() APIs Mark McLoughlin
@ 2009-10-22 16:43 ` Mark McLoughlin
2009-10-22 16:43 ` [Qemu-devel] [PATCH 10/19] net: add an API for 'raw' packets Mark McLoughlin
` (11 subsequent siblings)
20 siblings, 0 replies; 37+ messages in thread
From: Mark McLoughlin @ 2009-10-22 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Mark McLoughlin
This allows for the addition of a raw flag, and leaves the way open
for other flags too.
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
net-queue.c | 26 ++++++++++++++++++--------
net-queue.h | 6 ++++++
net.c | 14 ++++++++++++--
3 files changed, 36 insertions(+), 10 deletions(-)
diff --git a/net-queue.c b/net-queue.c
index 75457f0..f6b01e9 100644
--- a/net-queue.c
+++ b/net-queue.c
@@ -41,6 +41,7 @@
struct NetPacket {
QTAILQ_ENTRY(NetPacket) entry;
VLANClientState *sender;
+ unsigned flags;
int size;
NetPacketSent *sent_cb;
uint8_t data[0];
@@ -89,6 +90,7 @@ void qemu_del_net_queue(NetQueue *queue)
static ssize_t qemu_net_queue_append(NetQueue *queue,
VLANClientState *sender,
+ unsigned flags,
const uint8_t *buf,
size_t size,
NetPacketSent *sent_cb)
@@ -97,6 +99,7 @@ static ssize_t qemu_net_queue_append(NetQueue *queue,
packet = qemu_malloc(sizeof(NetPacket) + size);
packet->sender = sender;
+ packet->flags = flags;
packet->size = size;
packet->sent_cb = sent_cb;
memcpy(packet->data, buf, size);
@@ -108,6 +111,7 @@ static ssize_t qemu_net_queue_append(NetQueue *queue,
static ssize_t qemu_net_queue_append_iov(NetQueue *queue,
VLANClientState *sender,
+ unsigned flags,
const struct iovec *iov,
int iovcnt,
NetPacketSent *sent_cb)
@@ -123,6 +127,7 @@ static ssize_t qemu_net_queue_append_iov(NetQueue *queue,
packet = qemu_malloc(sizeof(NetPacket) + max_len);
packet->sender = sender;
packet->sent_cb = sent_cb;
+ packet->flags = flags;
packet->size = 0;
for (i = 0; i < iovcnt; i++) {
@@ -139,13 +144,14 @@ static ssize_t qemu_net_queue_append_iov(NetQueue *queue,
static ssize_t qemu_net_queue_deliver(NetQueue *queue,
VLANClientState *sender,
+ unsigned flags,
const uint8_t *data,
size_t size)
{
ssize_t ret = -1;
queue->delivering = 1;
- ret = queue->deliver(sender, data, size, queue->opaque);
+ ret = queue->deliver(sender, flags, data, size, queue->opaque);
queue->delivering = 0;
return ret;
@@ -153,13 +159,14 @@ static ssize_t qemu_net_queue_deliver(NetQueue *queue,
static ssize_t qemu_net_queue_deliver_iov(NetQueue *queue,
VLANClientState *sender,
+ unsigned flags,
const struct iovec *iov,
int iovcnt)
{
ssize_t ret = -1;
queue->delivering = 1;
- ret = queue->deliver_iov(sender, iov, iovcnt, queue->opaque);
+ ret = queue->deliver_iov(sender, flags, iov, iovcnt, queue->opaque);
queue->delivering = 0;
return ret;
@@ -167,6 +174,7 @@ static ssize_t qemu_net_queue_deliver_iov(NetQueue *queue,
ssize_t qemu_net_queue_send(NetQueue *queue,
VLANClientState *sender,
+ unsigned flags,
const uint8_t *data,
size_t size,
NetPacketSent *sent_cb)
@@ -174,12 +182,12 @@ ssize_t qemu_net_queue_send(NetQueue *queue,
ssize_t ret;
if (queue->delivering) {
- return qemu_net_queue_append(queue, sender, data, size, NULL);
+ return qemu_net_queue_append(queue, sender, flags, data, size, NULL);
}
- ret = qemu_net_queue_deliver(queue, sender, data, size);
+ ret = qemu_net_queue_deliver(queue, sender, flags, data, size);
if (ret == 0 && sent_cb != NULL) {
- qemu_net_queue_append(queue, sender, data, size, sent_cb);
+ qemu_net_queue_append(queue, sender, flags, data, size, sent_cb);
return 0;
}
@@ -190,6 +198,7 @@ ssize_t qemu_net_queue_send(NetQueue *queue,
ssize_t qemu_net_queue_send_iov(NetQueue *queue,
VLANClientState *sender,
+ unsigned flags,
const struct iovec *iov,
int iovcnt,
NetPacketSent *sent_cb)
@@ -197,12 +206,12 @@ ssize_t qemu_net_queue_send_iov(NetQueue *queue,
ssize_t ret;
if (queue->delivering) {
- return qemu_net_queue_append_iov(queue, sender, iov, iovcnt, NULL);
+ return qemu_net_queue_append_iov(queue, sender, flags, iov, iovcnt, NULL);
}
- ret = qemu_net_queue_deliver_iov(queue, sender, iov, iovcnt);
+ ret = qemu_net_queue_deliver_iov(queue, sender, flags, iov, iovcnt);
if (ret == 0 && sent_cb != NULL) {
- qemu_net_queue_append_iov(queue, sender, iov, iovcnt, sent_cb);
+ qemu_net_queue_append_iov(queue, sender, flags, iov, iovcnt, sent_cb);
return 0;
}
@@ -234,6 +243,7 @@ void qemu_net_queue_flush(NetQueue *queue)
ret = qemu_net_queue_deliver(queue,
packet->sender,
+ packet->flags,
packet->data,
packet->size);
if (ret == 0 && packet->sent_cb != NULL) {
diff --git a/net-queue.h b/net-queue.h
index ea17df6..343760e 100644
--- a/net-queue.h
+++ b/net-queue.h
@@ -32,15 +32,19 @@ typedef struct NetQueue NetQueue;
typedef void (NetPacketSent) (VLANClientState *sender, ssize_t ret);
typedef ssize_t (NetPacketDeliver) (VLANClientState *sender,
+ unsigned flags,
const uint8_t *buf,
size_t size,
void *opaque);
typedef ssize_t (NetPacketDeliverIOV) (VLANClientState *sender,
+ unsigned flags,
const struct iovec *iov,
int iovcnt,
void *opaque);
+#define QEMU_NET_PACKET_FLAG_NONE 0
+
NetQueue *qemu_new_net_queue(NetPacketDeliver *deliver,
NetPacketDeliverIOV *deliver_iov,
void *opaque);
@@ -48,12 +52,14 @@ void qemu_del_net_queue(NetQueue *queue);
ssize_t qemu_net_queue_send(NetQueue *queue,
VLANClientState *sender,
+ unsigned flags,
const uint8_t *data,
size_t size,
NetPacketSent *sent_cb);
ssize_t qemu_net_queue_send_iov(NetQueue *queue,
VLANClientState *sender,
+ unsigned flags,
const struct iovec *iov,
int iovcnt,
NetPacketSent *sent_cb);
diff --git a/net.c b/net.c
index 56d979b..30dc402 100644
--- a/net.c
+++ b/net.c
@@ -302,10 +302,12 @@ static char *assign_name(VLANClientState *vc1, const char *model)
}
static ssize_t qemu_deliver_packet(VLANClientState *sender,
+ unsigned flags,
const uint8_t *data,
size_t size,
void *opaque);
static ssize_t qemu_deliver_packet_iov(VLANClientState *sender,
+ unsigned flags,
const struct iovec *iov,
int iovcnt,
void *opaque);
@@ -450,6 +452,7 @@ int qemu_can_send_packet(VLANClientState *sender)
}
static ssize_t qemu_deliver_packet(VLANClientState *sender,
+ unsigned flags,
const uint8_t *data,
size_t size,
void *opaque)
@@ -464,6 +467,7 @@ static ssize_t qemu_deliver_packet(VLANClientState *sender,
}
static ssize_t qemu_vlan_deliver_packet(VLANClientState *sender,
+ unsigned flags,
const uint8_t *buf,
size_t size,
void *opaque)
@@ -543,7 +547,9 @@ ssize_t qemu_send_packet_async(VLANClientState *sender,
queue = sender->vlan->send_queue;
}
- return qemu_net_queue_send(queue, sender, buf, size, sent_cb);
+ return qemu_net_queue_send(queue, sender,
+ QEMU_NET_PACKET_FLAG_NONE,
+ buf, size, sent_cb);
}
void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size)
@@ -580,6 +586,7 @@ static ssize_t calc_iov_length(const struct iovec *iov, int iovcnt)
}
static ssize_t qemu_deliver_packet_iov(VLANClientState *sender,
+ unsigned flags,
const struct iovec *iov,
int iovcnt,
void *opaque)
@@ -598,6 +605,7 @@ static ssize_t qemu_deliver_packet_iov(VLANClientState *sender,
}
static ssize_t qemu_vlan_deliver_packet_iov(VLANClientState *sender,
+ unsigned flags,
const struct iovec *iov,
int iovcnt,
void *opaque)
@@ -646,7 +654,9 @@ ssize_t qemu_sendv_packet_async(VLANClientState *sender,
queue = sender->vlan->send_queue;
}
- return qemu_net_queue_send_iov(queue, sender, iov, iovcnt, sent_cb);
+ return qemu_net_queue_send_iov(queue, sender,
+ QEMU_NET_PACKET_FLAG_NONE,
+ iov, iovcnt, sent_cb);
}
ssize_t
--
1.6.2.5
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [Qemu-devel] [PATCH 10/19] net: add an API for 'raw' packets
2009-10-22 16:43 [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO Mark McLoughlin
` (8 preceding siblings ...)
2009-10-22 16:43 ` [Qemu-devel] [PATCH 09/19] net: add flags parameter to packet queue interface Mark McLoughlin
@ 2009-10-22 16:43 ` Mark McLoughlin
2009-10-22 16:43 ` [Qemu-devel] [PATCH 11/19] net: add receive_raw parameter to qemu_new_vlan_client() Mark McLoughlin
` (10 subsequent siblings)
20 siblings, 0 replies; 37+ messages in thread
From: Mark McLoughlin @ 2009-10-22 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Mark McLoughlin
In the case where a NIC and backend agree on a packet header format,
this API allows injecting packets which lack the agreed upon header.
We need this for sending our gratuitous ARP.
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
net-queue.h | 1 +
net.c | 37 +++++++++++++++++++++++++++++--------
net.h | 2 ++
3 files changed, 32 insertions(+), 8 deletions(-)
diff --git a/net-queue.h b/net-queue.h
index 343760e..a31958e 100644
--- a/net-queue.h
+++ b/net-queue.h
@@ -44,6 +44,7 @@ typedef ssize_t (NetPacketDeliverIOV) (VLANClientState *sender,
void *opaque);
#define QEMU_NET_PACKET_FLAG_NONE 0
+#define QEMU_NET_PACKET_FLAG_RAW (1<<0)
NetQueue *qemu_new_net_queue(NetPacketDeliver *deliver,
NetPacketDeliverIOV *deliver_iov,
diff --git a/net.c b/net.c
index 30dc402..50d2f83 100644
--- a/net.c
+++ b/net.c
@@ -463,7 +463,10 @@ static ssize_t qemu_deliver_packet(VLANClientState *sender,
return size;
}
- return vc->receive(vc, data, size);
+ if (flags & QEMU_NET_PACKET_FLAG_RAW && vc->receive_raw)
+ return vc->receive_raw(vc, data, size);
+ else
+ return vc->receive(vc, data, size);
}
static ssize_t qemu_vlan_deliver_packet(VLANClientState *sender,
@@ -488,7 +491,10 @@ static ssize_t qemu_vlan_deliver_packet(VLANClientState *sender,
continue;
}
- len = vc->receive(vc, buf, size);
+ if (flags & QEMU_NET_PACKET_FLAG_RAW && vc->receive_raw)
+ len = vc->receive_raw(vc, buf, size);
+ else
+ len = vc->receive(vc, buf, size);
ret = (ret >= 0) ? ret : len;
}
@@ -526,9 +532,10 @@ void qemu_flush_queued_packets(VLANClientState *vc)
qemu_net_queue_flush(queue);
}
-ssize_t qemu_send_packet_async(VLANClientState *sender,
- const uint8_t *buf, int size,
- NetPacketSent *sent_cb)
+static ssize_t qemu_send_packet_async_with_flags(VLANClientState *sender,
+ unsigned flags,
+ const uint8_t *buf, int size,
+ NetPacketSent *sent_cb)
{
NetQueue *queue;
@@ -547,9 +554,15 @@ ssize_t qemu_send_packet_async(VLANClientState *sender,
queue = sender->vlan->send_queue;
}
- return qemu_net_queue_send(queue, sender,
- QEMU_NET_PACKET_FLAG_NONE,
- buf, size, sent_cb);
+ return qemu_net_queue_send(queue, sender, flags, buf, size, sent_cb);
+}
+
+ssize_t qemu_send_packet_async(VLANClientState *sender,
+ const uint8_t *buf, int size,
+ NetPacketSent *sent_cb)
+{
+ return qemu_send_packet_async_with_flags(sender, QEMU_NET_PACKET_FLAG_NONE,
+ buf, size, sent_cb);
}
void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size)
@@ -557,6 +570,12 @@ void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size)
qemu_send_packet_async(vc, buf, size, NULL);
}
+ssize_t qemu_send_packet_raw(VLANClientState *vc, const uint8_t *buf, int size)
+{
+ return qemu_send_packet_async_with_flags(vc, QEMU_NET_PACKET_FLAG_RAW,
+ buf, size, NULL);
+}
+
static ssize_t vc_sendv_compat(VLANClientState *vc, const struct iovec *iov,
int iovcnt)
{
@@ -626,6 +645,8 @@ static ssize_t qemu_vlan_deliver_packet_iov(VLANClientState *sender,
continue;
}
+ assert(!(flags & QEMU_NET_PACKET_FLAG_RAW));
+
if (vc->receive_iov) {
len = vc->receive_iov(vc, iov, iovcnt);
} else {
diff --git a/net.h b/net.h
index 5f28860..53d813c 100644
--- a/net.h
+++ b/net.h
@@ -28,6 +28,7 @@ typedef void (LinkStatusChanged)(VLANClientState *);
struct VLANClientState {
net_client_type type;
NetReceive *receive;
+ NetReceive *receive_raw;
NetReceiveIOV *receive_iov;
/* Packets may still be sent if this returns zero. It's used to
rate-limit the slirp code. */
@@ -72,6 +73,7 @@ ssize_t qemu_sendv_packet(VLANClientState *vc, const struct iovec *iov,
ssize_t qemu_sendv_packet_async(VLANClientState *vc, const struct iovec *iov,
int iovcnt, NetPacketSent *sent_cb);
void qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size);
+ssize_t qemu_send_packet_raw(VLANClientState *vc, const uint8_t *buf, int size);
ssize_t qemu_send_packet_async(VLANClientState *vc, const uint8_t *buf,
int size, NetPacketSent *sent_cb);
void qemu_purge_queued_packets(VLANClientState *vc);
--
1.6.2.5
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [Qemu-devel] [PATCH 11/19] net: add receive_raw parameter to qemu_new_vlan_client()
2009-10-22 16:43 [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO Mark McLoughlin
` (9 preceding siblings ...)
2009-10-22 16:43 ` [Qemu-devel] [PATCH 10/19] net: add an API for 'raw' packets Mark McLoughlin
@ 2009-10-22 16:43 ` Mark McLoughlin
2009-10-22 16:43 ` [Qemu-devel] [PATCH 12/19] net: use qemu_send_packet_raw() in qemu_announce_self() Mark McLoughlin
` (9 subsequent siblings)
20 siblings, 0 replies; 37+ messages in thread
From: Mark McLoughlin @ 2009-10-22 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Mark McLoughlin
Trivial patch to allow supplying a receive_raw function.
A future cleanup should combine this function pointer parameters into a
table.
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
hw/dp8393x.c | 2 +-
hw/etraxfs_eth.c | 2 +-
hw/mcf_fec.c | 2 +-
hw/mipsnet.c | 2 +-
hw/qdev.c | 3 ++-
hw/usb-net.c | 2 +-
hw/xen_nic.c | 2 +-
net.c | 14 ++++++++------
net.h | 1 +
tap-win32.c | 2 +-
10 files changed, 18 insertions(+), 14 deletions(-)
diff --git a/hw/dp8393x.c b/hw/dp8393x.c
index 5622170..ae8b16e 100644
--- a/hw/dp8393x.c
+++ b/hw/dp8393x.c
@@ -892,7 +892,7 @@ void dp83932_init(NICInfo *nd, target_phys_addr_t base, int it_shift,
s->vc = nd->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
nd->vlan, nd->netdev,
nd->model, nd->name,
- nic_can_receive, nic_receive, NULL,
+ nic_can_receive, nic_receive, NULL, NULL,
nic_cleanup, s);
qemu_format_nic_info_str(s->vc, nd->macaddr);
diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c
index 2a583a3..ffe7082 100644
--- a/hw/etraxfs_eth.c
+++ b/hw/etraxfs_eth.c
@@ -594,7 +594,7 @@ void *etraxfs_eth_init(NICInfo *nd, target_phys_addr_t base, int phyaddr)
nd->vlan, nd->netdev,
nd->model, nd->name,
eth_can_receive, eth_receive,
- NULL, eth_cleanup, eth);
+ NULL, NULL, eth_cleanup, eth);
eth->vc->opaque = eth;
eth->vc->link_status_changed = eth_set_link;
diff --git a/hw/mcf_fec.c b/hw/mcf_fec.c
index 0567bcd..9f0d0f4 100644
--- a/hw/mcf_fec.c
+++ b/hw/mcf_fec.c
@@ -466,7 +466,7 @@ void mcf_fec_init(NICInfo *nd, target_phys_addr_t base, qemu_irq *irq)
nd->vlan, nd->netdev,
nd->model, nd->name,
mcf_fec_can_receive, mcf_fec_receive,
- NULL, mcf_fec_cleanup, s);
+ NULL, NULL, mcf_fec_cleanup, s);
memcpy(s->macaddr, nd->macaddr, 6);
qemu_format_nic_info_str(s->vc, s->macaddr);
}
diff --git a/hw/mipsnet.c b/hw/mipsnet.c
index d32099f..65e1d59 100644
--- a/hw/mipsnet.c
+++ b/hw/mipsnet.c
@@ -267,7 +267,7 @@ void mipsnet_init (int base, qemu_irq irq, NICInfo *nd)
nd->vlan, nd->netdev,
nd->model, nd->name,
mipsnet_can_receive, mipsnet_receive,
- NULL, mipsnet_cleanup, s);
+ NULL, NULL, mipsnet_cleanup, s);
} else {
s->vc = NULL;
}
diff --git a/hw/qdev.c b/hw/qdev.c
index bc3a0d5..38ac037 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -373,7 +373,8 @@ VLANClientState *qdev_get_vlan_client(DeviceState *dev,
nd->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
nd->vlan, nd->netdev,
nd->model, nd->name,
- can_receive, receive, receive_iov,
+ can_receive, receive,
+ NULL, receive_iov,
cleanup, opaque);
return nd->vc;
}
diff --git a/hw/usb-net.c b/hw/usb-net.c
index 2393812..9c6549c 100644
--- a/hw/usb-net.c
+++ b/hw/usb-net.c
@@ -1465,7 +1465,7 @@ USBDevice *usb_net_init(NICInfo *nd)
nd->model, nd->name,
usbnet_can_receive,
usbnet_receive,
- NULL,
+ NULL, NULL,
usbnet_cleanup, s);
qemu_format_nic_info_str(s->vc, s->mac);
diff --git a/hw/xen_nic.c b/hw/xen_nic.c
index 2a179f0..75599d6 100644
--- a/hw/xen_nic.c
+++ b/hw/xen_nic.c
@@ -303,7 +303,7 @@ static int net_init(struct XenDevice *xendev)
vlan = qemu_find_vlan(netdev->xendev.dev, 1);
netdev->vs = qemu_new_vlan_client(NET_CLIENT_TYPE_NIC,
vlan, NULL, "xen", NULL,
- net_rx_ok, net_rx_packet, NULL,
+ net_rx_ok, net_rx_packet, NULL, NULL,
NULL, netdev);
snprintf(netdev->vs->info_str, sizeof(netdev->vs->info_str),
"nic: xenbus vif macaddr=%s", netdev->mac);
diff --git a/net.c b/net.c
index 50d2f83..56d9de7 100644
--- a/net.c
+++ b/net.c
@@ -319,6 +319,7 @@ VLANClientState *qemu_new_vlan_client(net_client_type type,
const char *name,
NetCanReceive *can_receive,
NetReceive *receive,
+ NetReceive *receive_raw,
NetReceiveIOV *receive_iov,
NetCleanup *cleanup,
void *opaque)
@@ -335,6 +336,7 @@ VLANClientState *qemu_new_vlan_client(net_client_type type,
vc->name = assign_name(vc, model);
vc->can_receive = can_receive;
vc->receive = receive;
+ vc->receive_raw = receive_raw;
vc->receive_iov = receive_iov;
vc->cleanup = cleanup;
vc->opaque = opaque;
@@ -900,7 +902,7 @@ static int net_slirp_init(VLANState *vlan, const char *model,
s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_SLIRP,
vlan, NULL, model, name, NULL,
- slirp_receive, NULL,
+ slirp_receive, NULL, NULL,
net_slirp_cleanup, s);
snprintf(s->vc->info_str, sizeof(s->vc->info_str),
"net=%s, restricted=%c", inet_ntoa(net), restricted ? 'y' : 'n');
@@ -1538,7 +1540,7 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
s->using_vnet_hdr = 0;
s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_TAP,
vlan, NULL, model, name, NULL,
- tap_receive, tap_receive_iov,
+ tap_receive, NULL, tap_receive_iov,
tap_cleanup, s);
tap_read_poll(s, 1);
return s;
@@ -1898,7 +1900,7 @@ static int net_vde_init(VLANState *vlan, const char *model,
}
s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_VDE,
vlan, NULL, model, name, NULL,
- vde_receive, NULL,
+ vde_receive, NULL, NULL,
vde_cleanup, s);
qemu_set_fd_handler(vde_datafd(s->vde), vde_to_qemu, NULL, s);
snprintf(s->vc->info_str, sizeof(s->vc->info_str), "sock=%s,fd=%d",
@@ -2139,7 +2141,7 @@ static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan,
s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_SOCKET,
vlan, NULL, model, name, NULL,
- net_socket_receive_dgram, NULL,
+ net_socket_receive_dgram, NULL, NULL,
net_socket_cleanup, s);
qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);
@@ -2169,7 +2171,7 @@ static NetSocketState *net_socket_fd_init_stream(VLANState *vlan,
s->fd = fd;
s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_SOCKET,
vlan, NULL, model, name, NULL,
- net_socket_receive, NULL,
+ net_socket_receive, NULL, NULL,
net_socket_cleanup, s);
snprintf(s->vc->info_str, sizeof(s->vc->info_str),
"socket: fd=%d", fd);
@@ -2452,7 +2454,7 @@ static int net_dump_init(VLANState *vlan, const char *device,
s->pcap_vc = qemu_new_vlan_client(NET_CLIENT_TYPE_DUMP,
vlan, NULL, device, name, NULL,
- dump_receive, NULL,
+ dump_receive, NULL, NULL,
net_dump_cleanup, s);
snprintf(s->pcap_vc->info_str, sizeof(s->pcap_vc->info_str),
"dump to %s (len=%d)", filename, len);
diff --git a/net.h b/net.h
index 53d813c..6255e2b 100644
--- a/net.h
+++ b/net.h
@@ -62,6 +62,7 @@ VLANClientState *qemu_new_vlan_client(net_client_type type,
const char *name,
NetCanReceive *can_receive,
NetReceive *receive,
+ NetReceive *receive_raw,
NetReceiveIOV *receive_iov,
NetCleanup *cleanup,
void *opaque);
diff --git a/tap-win32.c b/tap-win32.c
index e2bac3e..7d92df2 100644
--- a/tap-win32.c
+++ b/tap-win32.c
@@ -680,7 +680,7 @@ int tap_win32_init(VLANState *vlan, const char *model,
s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_TAP,
vlan, NULL, model, name,
NULL, tap_receive,
- NULL, tap_cleanup, s);
+ NULL, NULL, tap_cleanup, s);
snprintf(s->vc->info_str, sizeof(s->vc->info_str),
"tap: ifname=%s", ifname);
--
1.6.2.5
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [Qemu-devel] [PATCH 12/19] net: use qemu_send_packet_raw() in qemu_announce_self()
2009-10-22 16:43 [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO Mark McLoughlin
` (10 preceding siblings ...)
2009-10-22 16:43 ` [Qemu-devel] [PATCH 11/19] net: add receive_raw parameter to qemu_new_vlan_client() Mark McLoughlin
@ 2009-10-22 16:43 ` Mark McLoughlin
2009-10-22 16:43 ` [Qemu-devel] [PATCH 13/19] net: implement tap support for receive_raw() Mark McLoughlin
` (8 subsequent siblings)
20 siblings, 0 replies; 37+ messages in thread
From: Mark McLoughlin @ 2009-10-22 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Mark McLoughlin, Gleb Natapov
From: Gleb Natapov <gleb@redhat.com>
Use qemu_send_packet_raw to send gratuitous arp. This will ensure that
vnet header is handled properly.
Also, avoid sending the gratuitous packet to the guest. There doesn't
appear to be any reason for doing that and the code will currently just
crash if the NIC is not associated with a vlan.
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
savevm.c | 7 +------
1 files changed, 1 insertions(+), 6 deletions(-)
diff --git a/savevm.c b/savevm.c
index 99aa15a..ac1ef42 100644
--- a/savevm.c
+++ b/savevm.c
@@ -114,8 +114,6 @@ static int announce_self_create(uint8_t *buf,
static void qemu_announce_self_once(void *opaque)
{
int i, len;
- VLANState *vlan;
- VLANClientState *vc;
uint8_t buf[256];
static int count = SELF_ANNOUNCE_ROUNDS;
QEMUTimer *timer = *(QEMUTimer **)opaque;
@@ -124,10 +122,7 @@ static void qemu_announce_self_once(void *opaque)
if (!nd_table[i].used)
continue;
len = announce_self_create(buf, nd_table[i].macaddr);
- vlan = nd_table[i].vlan;
- QTAILQ_FOREACH(vc, &vlan->clients, next) {
- vc->receive(vc, buf, len);
- }
+ qemu_send_packet_raw(nd_table[i].vc, buf, len);
}
if (count--) {
qemu_mod_timer(timer, qemu_get_clock(rt_clock) + 100);
--
1.6.2.5
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [Qemu-devel] [PATCH 13/19] net: implement tap support for receive_raw()
2009-10-22 16:43 [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO Mark McLoughlin
` (11 preceding siblings ...)
2009-10-22 16:43 ` [Qemu-devel] [PATCH 12/19] net: use qemu_send_packet_raw() in qemu_announce_self() Mark McLoughlin
@ 2009-10-22 16:43 ` Mark McLoughlin
2009-10-22 16:43 ` [Qemu-devel] [PATCH 14/19] virtio-net: add vnet_hdr support Mark McLoughlin
` (7 subsequent siblings)
20 siblings, 0 replies; 37+ messages in thread
From: Mark McLoughlin @ 2009-10-22 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Mark McLoughlin
tap_receive_raw() always prepends a vnet header if IFF_VNET_HDR is
enabled.
tap_receive() only prepends when the a header is required but the NIC
doesn't supply one.
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
net.c | 23 +++++++++++++++++++----
1 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/net.c b/net.c
index 56d9de7..b44495d 100644
--- a/net.c
+++ b/net.c
@@ -1377,14 +1377,14 @@ static ssize_t tap_receive_iov(VLANClientState *vc, const struct iovec *iov,
return tap_write_packet(s, iovp, iovcnt);
}
-static ssize_t tap_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
+static ssize_t tap_receive_raw(VLANClientState *vc, const uint8_t *buf, size_t size)
{
TAPState *s = vc->opaque;
struct iovec iov[2];
int iovcnt = 0;
struct virtio_net_hdr hdr = { 0, };
- if (s->has_vnet_hdr && !s->using_vnet_hdr) {
+ if (s->has_vnet_hdr) {
iov[iovcnt].iov_base = &hdr;
iov[iovcnt].iov_len = sizeof(hdr);
iovcnt++;
@@ -1397,6 +1397,21 @@ static ssize_t tap_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
return tap_write_packet(s, iov, iovcnt);
}
+static ssize_t tap_receive(VLANClientState *vc, const uint8_t *buf, size_t size)
+{
+ TAPState *s = vc->opaque;
+ struct iovec iov[1];
+
+ if (s->has_vnet_hdr && !s->using_vnet_hdr) {
+ return tap_receive_raw(vc, buf, size);
+ }
+
+ iov[0].iov_base = (char *)buf;
+ iov[0].iov_len = size;
+
+ return tap_write_packet(s, iov, 1);
+}
+
static int tap_can_send(void *opaque)
{
TAPState *s = opaque;
@@ -1540,8 +1555,8 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
s->using_vnet_hdr = 0;
s->vc = qemu_new_vlan_client(NET_CLIENT_TYPE_TAP,
vlan, NULL, model, name, NULL,
- tap_receive, NULL, tap_receive_iov,
- tap_cleanup, s);
+ tap_receive, tap_receive_raw,
+ tap_receive_iov, tap_cleanup, s);
tap_read_poll(s, 1);
return s;
}
--
1.6.2.5
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [Qemu-devel] [PATCH 14/19] virtio-net: add vnet_hdr support
2009-10-22 16:43 [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO Mark McLoughlin
` (12 preceding siblings ...)
2009-10-22 16:43 ` [Qemu-devel] [PATCH 13/19] net: implement tap support for receive_raw() Mark McLoughlin
@ 2009-10-22 16:43 ` Mark McLoughlin
2009-10-22 16:43 ` [Qemu-devel] [PATCH 15/19] net: add tap_set_offload() Mark McLoughlin
` (6 subsequent siblings)
20 siblings, 0 replies; 37+ messages in thread
From: Mark McLoughlin @ 2009-10-22 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Mark McLoughlin
With '-netdev tap,id=foo -nic model=virtio,netdev=foo' virtio-net can
detect that its peer (i.e. the tap backend) supports vnet headers
and advertise to the guest that it can send packets with partial
checksums and/or TSO packets.
One complication is that if we're migrating and the source host
supports IFF_VNET_HDR but the destination host doesn't, we can't then
stop the guest from using those features. In this scenario, we just
fail the migration.
[v2:
- add has_vnet_hdr uint32_t field for ease of vmstate conversion
- use qemu_error()
]
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
hw/virtio-net.c | 51 ++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 44 insertions(+), 7 deletions(-)
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 218f985..bb085ae 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -32,6 +32,7 @@ typedef struct VirtIONet
VLANClientState *vc;
QEMUTimer *tx_timer;
int tx_timer_active;
+ uint32_t has_vnet_hdr;
struct {
VirtQueueElement elem;
ssize_t len;
@@ -120,8 +121,22 @@ static void virtio_net_reset(VirtIODevice *vdev)
memset(n->vlans, 0, MAX_VLAN >> 3);
}
+static int peer_has_vnet_hdr(VirtIONet *n)
+{
+ if (!n->vc->peer)
+ return 0;
+
+ if (n->vc->peer->type != NET_CLIENT_TYPE_TAP)
+ return 0;
+
+ n->has_vnet_hdr = tap_has_vnet_hdr(n->vc->peer);
+
+ return n->has_vnet_hdr;
+}
+
static uint32_t virtio_net_get_features(VirtIODevice *vdev)
{
+ VirtIONet *n = to_virtio_net(vdev);
uint32_t features = (1 << VIRTIO_NET_F_MAC) |
(1 << VIRTIO_NET_F_MRG_RXBUF) |
(1 << VIRTIO_NET_F_STATUS) |
@@ -130,6 +145,15 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev)
(1 << VIRTIO_NET_F_CTRL_VLAN) |
(1 << VIRTIO_NET_F_CTRL_RX_EXTRA);
+ if (peer_has_vnet_hdr(n)) {
+ tap_using_vnet_hdr(n->vc->peer, 1);
+
+ features |= (1 << VIRTIO_NET_F_CSUM);
+ features |= (1 << VIRTIO_NET_F_HOST_TSO4);
+ features |= (1 << VIRTIO_NET_F_HOST_TSO6);
+ features |= (1 << VIRTIO_NET_F_HOST_ECN);
+ }
+
return features;
}
@@ -359,6 +383,11 @@ static int receive_header(VirtIONet *n, struct iovec *iov, int iovcnt,
hdr->flags = 0;
hdr->gso_type = VIRTIO_NET_HDR_GSO_NONE;
+ if (n->has_vnet_hdr) {
+ memcpy(hdr, buf, sizeof(*hdr));
+ offset = sizeof(*hdr);
+ }
+
/* We only ever receive a struct virtio_net_hdr from the tapfd,
* but we may be passing along a larger header to the guest.
*/
@@ -378,6 +407,10 @@ static int receive_filter(VirtIONet *n, const uint8_t *buf, int size)
if (n->promisc)
return 1;
+ if (n->has_vnet_hdr) {
+ ptr += sizeof(struct virtio_net_hdr);
+ }
+
if (!memcmp(&ptr[12], vlan, sizeof(vlan))) {
int vid = be16_to_cpup((uint16_t *)(ptr + 14)) & 0xfff;
if (!(n->vlans[vid >> 5] & (1U << (vid & 0x1f))))
@@ -510,7 +543,6 @@ static void virtio_net_tx_complete(VLANClientState *vc, ssize_t len)
static void virtio_net_flush_tx(VirtIONet *n, VirtQueue *vq)
{
VirtQueueElement elem;
- int has_vnet_hdr = 0;
if (!(n->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK))
return;
@@ -537,7 +569,7 @@ static void virtio_net_flush_tx(VirtIONet *n, VirtQueue *vq)
}
/* ignore the header if GSO is not supported */
- if (!has_vnet_hdr) {
+ if (!n->has_vnet_hdr) {
out_num--;
out_sg++;
len += hdr_len;
@@ -610,7 +642,7 @@ static void virtio_net_save(QEMUFile *f, void *opaque)
qemu_put_be32(f, n->mac_table.in_use);
qemu_put_buffer(f, n->mac_table.macs, n->mac_table.in_use * ETH_ALEN);
qemu_put_buffer(f, (uint8_t *)n->vlans, MAX_VLAN >> 3);
- qemu_put_be32(f, 0); /* vnet-hdr placeholder */
+ qemu_put_be32(f, n->has_vnet_hdr);
qemu_put_byte(f, n->mac_table.multi_overflow);
qemu_put_byte(f, n->mac_table.uni_overflow);
qemu_put_byte(f, n->alluni);
@@ -662,10 +694,15 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
if (version_id >= 6)
qemu_get_buffer(f, (uint8_t *)n->vlans, MAX_VLAN >> 3);
- if (version_id >= 7 && qemu_get_be32(f)) {
- fprintf(stderr,
- "virtio-net: saved image requires vnet header support\n");
- exit(1);
+ if (version_id >= 7) {
+ if (qemu_get_be32(f) && !peer_has_vnet_hdr(n)) {
+ qemu_error("virtio-net: saved image requires vnet_hdr=on\n");
+ return -1;
+ }
+
+ if (n->has_vnet_hdr) {
+ tap_using_vnet_hdr(n->vc->peer, 1);
+ }
}
if (version_id >= 9) {
--
1.6.2.5
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [Qemu-devel] [PATCH 15/19] net: add tap_set_offload()
2009-10-22 16:43 [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO Mark McLoughlin
` (13 preceding siblings ...)
2009-10-22 16:43 ` [Qemu-devel] [PATCH 14/19] virtio-net: add vnet_hdr support Mark McLoughlin
@ 2009-10-22 16:43 ` Mark McLoughlin
2009-10-22 16:43 ` [Qemu-devel] [PATCH 16/19] virtio-net: enable tap offload if guest supports it Mark McLoughlin
` (5 subsequent siblings)
20 siblings, 0 replies; 37+ messages in thread
From: Mark McLoughlin @ 2009-10-22 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Mark McLoughlin
This API allows virtio-net to enable various offload features on a
tap interface - e.g. to tell the host kernel it can pass up partial
checksums to userspace.
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
net.c | 24 ++++++++++++++++++++++++
net.h | 1 +
tap-linux.h | 7 +++++++
3 files changed, 32 insertions(+), 0 deletions(-)
diff --git a/net.c b/net.c
index b44495d..746a3d6 100644
--- a/net.c
+++ b/net.c
@@ -1287,6 +1287,9 @@ int tap_has_vnet_hdr(VLANClientState *vc)
void tap_using_vnet_hdr(VLANClientState *vc, int using_vnet_hdr)
{
}
+void tap_set_offload(VLANClientState *vc, int csum, int tso4, int tso6, int ecn)
+{
+}
#else /* !defined(_WIN32) */
/* Maximum GSO packet size (64k) plus plenty of room for
@@ -1524,6 +1527,27 @@ static int tap_probe_vnet_hdr(int fd)
return ifr.ifr_flags & IFF_VNET_HDR;
}
+void tap_set_offload(VLANClientState *vc, int csum, int tso4, int tso6, int ecn)
+{
+ TAPState *s = vc->opaque;
+ unsigned int offload = 0;
+
+ if (csum) {
+ offload |= TUN_F_CSUM;
+ if (tso4)
+ offload |= TUN_F_TSO4;
+ if (tso6)
+ offload |= TUN_F_TSO6;
+ if ((tso4 || tso6) && ecn)
+ offload |= TUN_F_TSO_ECN;
+ }
+
+ if (ioctl(s->fd, TUNSETOFFLOAD, offload) != 0) {
+ fprintf(stderr, "TUNSETOFFLOAD ioctl() failed: %s\n",
+ strerror(errno));
+ }
+}
+
static void tap_cleanup(VLANClientState *vc)
{
TAPState *s = vc->opaque;
diff --git a/net.h b/net.h
index 6255e2b..a0f0359 100644
--- a/net.h
+++ b/net.h
@@ -170,5 +170,6 @@ VLANClientState *qdev_get_vlan_client(DeviceState *dev,
int tap_has_vnet_hdr(VLANClientState *vc);
void tap_using_vnet_hdr(VLANClientState *vc, int using_vnet_hdr);
+void tap_set_offload(VLANClientState *vc, int csum, int tso4, int tso6, int ecn);
#endif
diff --git a/tap-linux.h b/tap-linux.h
index 8e75348..241cf83 100644
--- a/tap-linux.h
+++ b/tap-linux.h
@@ -22,6 +22,7 @@
/* Ioctl defines */
#define TUNSETIFF _IOW('T', 202, int)
#define TUNGETFEATURES _IOR('T', 207, unsigned int)
+#define TUNSETOFFLOAD _IOW('T', 208, unsigned int)
#define TUNGETIFF _IOR('T', 210, unsigned int)
#define TUNSETSNDBUF _IOW('T', 212, int)
@@ -30,6 +31,12 @@
#define IFF_NO_PI 0x1000
#define IFF_VNET_HDR 0x4000
+/* Features for GSO (TUNSETOFFLOAD). */
+#define TUN_F_CSUM 0x01 /* You can hand me unchecksummed packets. */
+#define TUN_F_TSO4 0x02 /* I can handle TSO for IPv4 packets */
+#define TUN_F_TSO6 0x04 /* I can handle TSO for IPv6 packets */
+#define TUN_F_TSO_ECN 0x08 /* I can handle TSO with ECN bits. */
+
struct virtio_net_hdr
{
uint8_t flags;
--
1.6.2.5
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [Qemu-devel] [PATCH 16/19] virtio-net: enable tap offload if guest supports it
2009-10-22 16:43 [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO Mark McLoughlin
` (14 preceding siblings ...)
2009-10-22 16:43 ` [Qemu-devel] [PATCH 15/19] net: add tap_set_offload() Mark McLoughlin
@ 2009-10-22 16:43 ` Mark McLoughlin
2009-10-22 16:43 ` [Qemu-devel] [PATCH 17/19] Work around dhclient brokenness Mark McLoughlin
` (4 subsequent siblings)
20 siblings, 0 replies; 37+ messages in thread
From: Mark McLoughlin @ 2009-10-22 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Mark McLoughlin
We query the guest's feature set to see if it supports offload and,
if so, we enable those features on the tap interface.
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
hw/virtio-net.c | 18 ++++++++++++++++++
1 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index bb085ae..3fb10a2 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -152,6 +152,11 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev)
features |= (1 << VIRTIO_NET_F_HOST_TSO4);
features |= (1 << VIRTIO_NET_F_HOST_TSO6);
features |= (1 << VIRTIO_NET_F_HOST_ECN);
+
+ features |= (1 << VIRTIO_NET_F_GUEST_CSUM);
+ features |= (1 << VIRTIO_NET_F_GUEST_TSO4);
+ features |= (1 << VIRTIO_NET_F_GUEST_TSO6);
+ features |= (1 << VIRTIO_NET_F_GUEST_ECN);
}
return features;
@@ -177,6 +182,14 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
VirtIONet *n = to_virtio_net(vdev);
n->mergeable_rx_bufs = !!(features & (1 << VIRTIO_NET_F_MRG_RXBUF));
+
+ if (n->has_vnet_hdr) {
+ tap_set_offload(n->vc->peer,
+ (features >> VIRTIO_NET_F_GUEST_CSUM) & 1,
+ (features >> VIRTIO_NET_F_GUEST_TSO4) & 1,
+ (features >> VIRTIO_NET_F_GUEST_TSO6) & 1,
+ (features >> VIRTIO_NET_F_GUEST_ECN) & 1);
+ }
}
static int virtio_net_handle_rx_mode(VirtIONet *n, uint8_t cmd,
@@ -702,6 +715,11 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
if (n->has_vnet_hdr) {
tap_using_vnet_hdr(n->vc->peer, 1);
+ tap_set_offload(n->vc->peer,
+ (n->vdev.features >> VIRTIO_NET_F_GUEST_CSUM) & 1,
+ (n->vdev.features >> VIRTIO_NET_F_GUEST_TSO4) & 1,
+ (n->vdev.features >> VIRTIO_NET_F_GUEST_TSO6) & 1,
+ (n->vdev.features >> VIRTIO_NET_F_GUEST_ECN) & 1);
}
}
--
1.6.2.5
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [Qemu-devel] [PATCH 17/19] Work around dhclient brokenness
2009-10-22 16:43 [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO Mark McLoughlin
` (15 preceding siblings ...)
2009-10-22 16:43 ` [Qemu-devel] [PATCH 16/19] virtio-net: enable tap offload if guest supports it Mark McLoughlin
@ 2009-10-22 16:43 ` Mark McLoughlin
2009-10-22 16:43 ` [Qemu-devel] [PATCH 18/19] Enable UFO on virtio-net and tap devices Mark McLoughlin
` (3 subsequent siblings)
20 siblings, 0 replies; 37+ messages in thread
From: Mark McLoughlin @ 2009-10-22 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Mark McLoughlin, Anthony Liguori
From: Anthony Liguori <aliguori@us.ibm.com>
With the latest GSO/csum offload patches, any guest using an unpatched version
of dhclient (any Ubuntu guest, for instance), will no longer be able to get
a DHCP address.
dhclient is actually at fault here. It uses AF_PACKET to receive DHCP responses
but does not check auxdata to see if the packet has a valid csum. This causes
it to throw out the DHCP responses it gets from the virtio interface as there
is not a valid checksum.
Fedora has carried a patch to fix their dhclient (it's needed for Xen too) but
this patch has not made it into a release of dhclient. AFAIK, the patch is in
the dhclient CVS but I cannot confirm since their CVS is not public.
This patch, suggested by Rusty, looks for UDP packets (of a normal MTU) and
explicitly adds a checksum to them if they are missing one.
This allows unpatched dhclients to continue to work without needing to update
the guest kernels.
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
hw/virtio-net.c | 29 +++++++++++++++++++++++++++++
1 files changed, 29 insertions(+), 0 deletions(-)
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 3fb10a2..e00c404 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -372,6 +372,34 @@ static int virtio_net_can_receive(VLANClientState *vc)
return do_virtio_net_can_receive(n, VIRTIO_NET_MAX_BUFSIZE);
}
+/* dhclient uses AF_PACKET but doesn't pass auxdata to the kernel so
+ * it never finds out that the packets don't have valid checksums. This
+ * causes dhclient to get upset. Fedora's carried a patch for ages to
+ * fix this with Xen but it hasn't appeared in an upstream release of
+ * dhclient yet.
+ *
+ * To avoid breaking existing guests, we catch udp packets and add
+ * checksums. This is terrible but it's better than hacking the guest
+ * kernels.
+ *
+ * N.B. if we introduce a zero-copy API, this operation is no longer free so
+ * we should provide a mechanism to disable it to avoid polluting the host
+ * cache.
+ */
+static void work_around_broken_dhclient(struct virtio_net_hdr *hdr,
+ const uint8_t *buf, size_t size)
+{
+ if ((hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) && /* missing csum */
+ (size > 27 && size < 1500) && /* normal sized MTU */
+ (buf[12] == 0x08 && buf[13] == 0x00) && /* ethertype == IPv4 */
+ (buf[23] == 17) && /* ip.protocol == UDP */
+ (buf[34] == 0 && buf[35] == 67)) { /* udp.srcport == bootps */
+ /* FIXME this cast is evil */
+ net_checksum_calculate((uint8_t *)buf, size);
+ hdr->flags &= ~VIRTIO_NET_HDR_F_NEEDS_CSUM;
+ }
+}
+
static int iov_fill(struct iovec *iov, int iovcnt, const void *buf, int count)
{
int offset, i;
@@ -399,6 +427,7 @@ static int receive_header(VirtIONet *n, struct iovec *iov, int iovcnt,
if (n->has_vnet_hdr) {
memcpy(hdr, buf, sizeof(*hdr));
offset = sizeof(*hdr);
+ work_around_broken_dhclient(hdr, buf + offset, size - offset);
}
/* We only ever receive a struct virtio_net_hdr from the tapfd,
--
1.6.2.5
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [Qemu-devel] [PATCH 18/19] Enable UFO on virtio-net and tap devices
2009-10-22 16:43 [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO Mark McLoughlin
` (16 preceding siblings ...)
2009-10-22 16:43 ` [Qemu-devel] [PATCH 17/19] Work around dhclient brokenness Mark McLoughlin
@ 2009-10-22 16:43 ` Mark McLoughlin
2009-10-22 16:43 ` [Qemu-devel] [PATCH 19/19] virtio-net: add tap_has_ufo flag to saved state Mark McLoughlin
` (2 subsequent siblings)
20 siblings, 0 replies; 37+ messages in thread
From: Mark McLoughlin @ 2009-10-22 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Mark McLoughlin, Sridhar Samudrala
From: Sridhar Samudrala <sri@us.ibm.com>
Enable UFO on the host tap device if supported and allow setting UFO
on virtio-net in the guest.
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
hw/virtio-net.c | 11 +++++++++--
net.c | 36 ++++++++++++++++++++++++++++++++----
net.h | 3 ++-
tap-linux.h | 1 +
4 files changed, 44 insertions(+), 7 deletions(-)
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index e00c404..31ac9ef 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -157,6 +157,11 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev)
features |= (1 << VIRTIO_NET_F_GUEST_TSO4);
features |= (1 << VIRTIO_NET_F_GUEST_TSO6);
features |= (1 << VIRTIO_NET_F_GUEST_ECN);
+
+ if (tap_has_ufo(n->vc->peer)) {
+ features |= (1 << VIRTIO_NET_F_GUEST_UFO);
+ features |= (1 << VIRTIO_NET_F_HOST_UFO);
+ }
}
return features;
@@ -188,7 +193,8 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
(features >> VIRTIO_NET_F_GUEST_CSUM) & 1,
(features >> VIRTIO_NET_F_GUEST_TSO4) & 1,
(features >> VIRTIO_NET_F_GUEST_TSO6) & 1,
- (features >> VIRTIO_NET_F_GUEST_ECN) & 1);
+ (features >> VIRTIO_NET_F_GUEST_ECN) & 1,
+ (features >> VIRTIO_NET_F_GUEST_UFO) & 1);
}
}
@@ -748,7 +754,8 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
(n->vdev.features >> VIRTIO_NET_F_GUEST_CSUM) & 1,
(n->vdev.features >> VIRTIO_NET_F_GUEST_TSO4) & 1,
(n->vdev.features >> VIRTIO_NET_F_GUEST_TSO6) & 1,
- (n->vdev.features >> VIRTIO_NET_F_GUEST_ECN) & 1);
+ (n->vdev.features >> VIRTIO_NET_F_GUEST_ECN) & 1,
+ (n->vdev.features >> VIRTIO_NET_F_GUEST_UFO) & 1);
}
}
diff --git a/net.c b/net.c
index 746a3d6..3e54c53 100644
--- a/net.c
+++ b/net.c
@@ -1280,6 +1280,10 @@ void do_info_usernet(Monitor *mon)
#endif /* CONFIG_SLIRP */
#if defined(_WIN32)
+int tap_has_ufo(VLANClientState *vc)
+{
+ return 0;
+}
int tap_has_vnet_hdr(VLANClientState *vc)
{
return 0;
@@ -1287,7 +1291,8 @@ int tap_has_vnet_hdr(VLANClientState *vc)
void tap_using_vnet_hdr(VLANClientState *vc, int using_vnet_hdr)
{
}
-void tap_set_offload(VLANClientState *vc, int csum, int tso4, int tso6, int ecn)
+void tap_set_offload(VLANClientState *vc, int csum, int tso4,
+ int tso6, int ecn, int ufo)
{
}
#else /* !defined(_WIN32) */
@@ -1307,6 +1312,7 @@ typedef struct TAPState {
unsigned int write_poll : 1;
unsigned int has_vnet_hdr : 1;
unsigned int using_vnet_hdr : 1;
+ unsigned int has_ufo: 1;
} TAPState;
static int launch_script(const char *setup_script, const char *ifname, int fd);
@@ -1494,6 +1500,15 @@ static int tap_set_sndbuf(TAPState *s, QemuOpts *opts)
return 0;
}
+int tap_has_ufo(VLANClientState *vc)
+{
+ TAPState *s = vc->opaque;
+
+ assert(vc->type == NET_CLIENT_TYPE_TAP);
+
+ return s->has_ufo;
+}
+
int tap_has_vnet_hdr(VLANClientState *vc)
{
TAPState *s = vc->opaque;
@@ -1527,7 +1542,8 @@ static int tap_probe_vnet_hdr(int fd)
return ifr.ifr_flags & IFF_VNET_HDR;
}
-void tap_set_offload(VLANClientState *vc, int csum, int tso4, int tso6, int ecn)
+void tap_set_offload(VLANClientState *vc, int csum, int tso4,
+ int tso6, int ecn, int ufo)
{
TAPState *s = vc->opaque;
unsigned int offload = 0;
@@ -1540,11 +1556,16 @@ void tap_set_offload(VLANClientState *vc, int csum, int tso4, int tso6, int ecn)
offload |= TUN_F_TSO6;
if ((tso4 || tso6) && ecn)
offload |= TUN_F_TSO_ECN;
+ if (ufo)
+ offload |= TUN_F_UFO;
}
if (ioctl(s->fd, TUNSETOFFLOAD, offload) != 0) {
- fprintf(stderr, "TUNSETOFFLOAD ioctl() failed: %s\n",
- strerror(errno));
+ offload &= ~TUN_F_UFO;
+ if (ioctl(s->fd, TUNSETOFFLOAD, offload) != 0) {
+ fprintf(stderr, "TUNSETOFFLOAD ioctl() failed: %s\n",
+ strerror(errno));
+ }
}
}
@@ -1572,6 +1593,7 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
int vnet_hdr)
{
TAPState *s;
+ unsigned int offload;
s = qemu_mallocz(sizeof(TAPState));
s->fd = fd;
@@ -1581,6 +1603,12 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
vlan, NULL, model, name, NULL,
tap_receive, tap_receive_raw,
tap_receive_iov, tap_cleanup, s);
+ s->has_ufo = 0;
+ /* Check if tap supports UFO */
+ offload = TUN_F_CSUM | TUN_F_UFO;
+ if (ioctl(s->fd, TUNSETOFFLOAD, offload) == 0)
+ s->has_ufo = 1;
+ tap_set_offload(s->vc, 0, 0, 0, 0, 0);
tap_read_poll(s, 1);
return s;
}
diff --git a/net.h b/net.h
index a0f0359..7e6cbf4 100644
--- a/net.h
+++ b/net.h
@@ -168,8 +168,9 @@ VLANClientState *qdev_get_vlan_client(DeviceState *dev,
NetCleanup *cleanup,
void *opaque);
+int tap_has_ufo(VLANClientState *vc);
int tap_has_vnet_hdr(VLANClientState *vc);
void tap_using_vnet_hdr(VLANClientState *vc, int using_vnet_hdr);
-void tap_set_offload(VLANClientState *vc, int csum, int tso4, int tso6, int ecn);
+void tap_set_offload(VLANClientState *vc, int csum, int tso4, int tso6, int ecn, int ufo);
#endif
diff --git a/tap-linux.h b/tap-linux.h
index 241cf83..d81c650 100644
--- a/tap-linux.h
+++ b/tap-linux.h
@@ -36,6 +36,7 @@
#define TUN_F_TSO4 0x02 /* I can handle TSO for IPv4 packets */
#define TUN_F_TSO6 0x04 /* I can handle TSO for IPv6 packets */
#define TUN_F_TSO_ECN 0x08 /* I can handle TSO with ECN bits. */
+#define TUN_F_UFO 0x10 /* I can handle UFO packets */
struct virtio_net_hdr
{
--
1.6.2.5
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [Qemu-devel] [PATCH 19/19] virtio-net: add tap_has_ufo flag to saved state
2009-10-22 16:43 [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO Mark McLoughlin
` (17 preceding siblings ...)
2009-10-22 16:43 ` [Qemu-devel] [PATCH 18/19] Enable UFO on virtio-net and tap devices Mark McLoughlin
@ 2009-10-22 16:43 ` Mark McLoughlin
2009-10-28 14:30 ` Handling merge conflicts [was Re: [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO] Mark McLoughlin
2009-10-30 10:04 ` [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO Juha.Riihimaki
20 siblings, 0 replies; 37+ messages in thread
From: Mark McLoughlin @ 2009-10-22 16:43 UTC (permalink / raw)
To: qemu-devel; +Cc: Mark McLoughlin
If we tell the guest we support UFO and then migrate to host which
doesn't support it, we will find ourselves in grave difficulties.
Prevent this scenario by adding a flag to virtio-net's savevm format
which indicates whether the device requires host UFO support.
[v2:
- add has_ufo uint8_t field for ease of vmstate conversion
- use qemu_error()
]
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
---
hw/virtio-net.c | 23 +++++++++++++++++++++--
1 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 31ac9ef..15b6f45 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -16,7 +16,7 @@
#include "qemu-timer.h"
#include "virtio-net.h"
-#define VIRTIO_NET_VM_VERSION 10
+#define VIRTIO_NET_VM_VERSION 11
#define MAC_TABLE_ENTRIES 64
#define MAX_VLAN (1 << 12) /* Per 802.1Q definition */
@@ -33,6 +33,7 @@ typedef struct VirtIONet
QEMUTimer *tx_timer;
int tx_timer_active;
uint32_t has_vnet_hdr;
+ uint8_t has_ufo;
struct {
VirtQueueElement elem;
ssize_t len;
@@ -134,6 +135,16 @@ static int peer_has_vnet_hdr(VirtIONet *n)
return n->has_vnet_hdr;
}
+static int peer_has_ufo(VirtIONet *n)
+{
+ if (!peer_has_vnet_hdr(n))
+ return 0;
+
+ n->has_ufo = tap_has_ufo(n->vc->peer);
+
+ return n->has_ufo;
+}
+
static uint32_t virtio_net_get_features(VirtIODevice *vdev)
{
VirtIONet *n = to_virtio_net(vdev);
@@ -158,7 +169,7 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev)
features |= (1 << VIRTIO_NET_F_GUEST_TSO6);
features |= (1 << VIRTIO_NET_F_GUEST_ECN);
- if (tap_has_ufo(n->vc->peer)) {
+ if (peer_has_ufo(n)) {
features |= (1 << VIRTIO_NET_F_GUEST_UFO);
features |= (1 << VIRTIO_NET_F_HOST_UFO);
}
@@ -697,6 +708,7 @@ static void virtio_net_save(QEMUFile *f, void *opaque)
qemu_put_byte(f, n->nomulti);
qemu_put_byte(f, n->nouni);
qemu_put_byte(f, n->nobcast);
+ qemu_put_byte(f, n->has_ufo);
}
static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
@@ -771,6 +783,13 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
n->nobcast = qemu_get_byte(f);
}
+ if (version_id >= 11) {
+ if (qemu_get_byte(f) && !peer_has_ufo(n)) {
+ qemu_error("virtio-net: saved image requires TUN_F_UFO support\n");
+ return -1;
+ }
+ }
+
/* Find the first multicast entry in the saved MAC filter */
for (i = 0; i < n->mac_table.in_use; i++) {
if (n->mac_table.macs[i * ETH_ALEN] & 1) {
--
1.6.2.5
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Handling merge conflicts [was Re: [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO]
2009-10-22 16:43 [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO Mark McLoughlin
` (18 preceding siblings ...)
2009-10-22 16:43 ` [Qemu-devel] [PATCH 19/19] virtio-net: add tap_has_ufo flag to saved state Mark McLoughlin
@ 2009-10-28 14:30 ` Mark McLoughlin
2009-10-28 14:57 ` Gerd Hoffmann
2009-10-28 15:26 ` Anthony Liguori
2009-10-30 10:04 ` [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO Juha.Riihimaki
20 siblings, 2 replies; 37+ messages in thread
From: Mark McLoughlin @ 2009-10-28 14:30 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel, Gerd Hoffmann
Hi Anthony,
Thanks for merging this stuff ...
In the process of merging it all into qemu-kvm, I noticed a couple of
problems:
1) bb6e63644 lacked the change to add the type code to
qemu_new_vlan_client() so that and the subsequent 14 commits are
unbuildable
2) 93db6685 references NET_CLIENT_TYPE_NIC and the receive_raw but
these aren't added until bb6e636443 and 70783b9c, so that's 117
unbuildable commits
Neither of these problems existed in the patches Gerd and I posted, so
presumably they came about by trying to merge the two patch sets?
How can we avoid this happening in future? What process could we have
used to avoid it?
Should either Gerd or I have merged the others' changes into our tree
and asked you to pull? Should you just refuse conflicts and ask us to
re-post? Or ...?
Thanks,
Mark.
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Handling merge conflicts [was Re: [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO]
2009-10-28 14:30 ` Handling merge conflicts [was Re: [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO] Mark McLoughlin
@ 2009-10-28 14:57 ` Gerd Hoffmann
2009-10-28 15:28 ` Anthony Liguori
2009-10-28 15:26 ` Anthony Liguori
1 sibling, 1 reply; 37+ messages in thread
From: Gerd Hoffmann @ 2009-10-28 14:57 UTC (permalink / raw)
To: Mark McLoughlin; +Cc: Anthony Liguori, qemu-devel
Hi,
> Should either Gerd or I have merged the others' changes into our tree
> and asked you to pull? Should you just refuse conflicts and ask us to
> re-post? Or ...?
I think the best way to deal with that would be to simply not merge
stuff which doesn't apply. Likewise for stuff which doesn't build.
Pick one patch series, merge it, ask for a rebase of the other series,
i.e. basically offload the conflict resolving to the patch submitter.
Reduces your workload and non-trivial conflicts are better handled by
the submitter anyway.
Problem is that this model doesn't work very well the bulk merges we
have right now, so I'd suggest to also merge smaller batches more
frequently.
cheers,
Gerd
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Handling merge conflicts [was Re: [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO]
2009-10-28 14:57 ` Gerd Hoffmann
@ 2009-10-28 15:28 ` Anthony Liguori
2009-10-28 16:24 ` Avi Kivity
0 siblings, 1 reply; 37+ messages in thread
From: Anthony Liguori @ 2009-10-28 15:28 UTC (permalink / raw)
To: Gerd Hoffmann; +Cc: Mark McLoughlin, Anthony Liguori, qemu-devel
Gerd Hoffmann wrote:
> Hi,
>
>> Should either Gerd or I have merged the others' changes into our tree
>> and asked you to pull? Should you just refuse conflicts and ask us to
>> re-post? Or ...?
>
> I think the best way to deal with that would be to simply not merge
> stuff which doesn't apply. Likewise for stuff which doesn't build.
>
> Pick one patch series, merge it, ask for a rebase of the other series,
> i.e. basically offload the conflict resolving to the patch submitter.
> Reduces your workload and non-trivial conflicts are better handled by
> the submitter anyway.
That would require a series to be merged within a very short time period
which does not allow appropriate review on the list.
> Problem is that this model doesn't work very well the bulk merges we
> have right now, so I'd suggest to also merge smaller batches more
> frequently.
There are certain patches that I could merge more quickly but I don't
think it's reasonable to merge large, potentially controversial series
without letting them sit on the list for a week or so to give people a
chance to review. In this case, these two series definitely fall into
the later category.
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Handling merge conflicts [was Re: [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO]
2009-10-28 15:28 ` Anthony Liguori
@ 2009-10-28 16:24 ` Avi Kivity
2009-10-28 16:35 ` Anthony Liguori
` (2 more replies)
0 siblings, 3 replies; 37+ messages in thread
From: Avi Kivity @ 2009-10-28 16:24 UTC (permalink / raw)
To: Anthony Liguori
Cc: Mark McLoughlin, Anthony Liguori, Gerd Hoffmann, qemu-devel
On 10/28/2009 05:28 PM, Anthony Liguori wrote:
> Gerd Hoffmann wrote:
>> Hi,
>>
>>> Should either Gerd or I have merged the others' changes into our tree
>>> and asked you to pull? Should you just refuse conflicts and ask us to
>>> re-post? Or ...?
>>
>> I think the best way to deal with that would be to simply not merge
>> stuff which doesn't apply. Likewise for stuff which doesn't build.
>>
>> Pick one patch series, merge it, ask for a rebase of the other
>> series, i.e. basically offload the conflict resolving to the patch
>> submitter. Reduces your workload and non-trivial conflicts are better
>> handled by the submitter anyway.
>
> That would require a series to be merged within a very short time
> period which does not allow appropriate review on the list.
>
Why? When you detect the conflict, ask the unlucky second to rebase (on
top of some git branch). The rebased series doesn't need a re-review
unless the submitter says he needed to rework it significantly.
(IOW, the submitter's rebase doesn't need more review than your conflict
resolution)
--
error compiling committee.c: too many arguments to function
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Handling merge conflicts [was Re: [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO]
2009-10-28 16:24 ` Avi Kivity
@ 2009-10-28 16:35 ` Anthony Liguori
2009-10-28 16:36 ` Anthony Liguori
2009-10-28 19:29 ` Gerd Hoffmann
2 siblings, 0 replies; 37+ messages in thread
From: Anthony Liguori @ 2009-10-28 16:35 UTC (permalink / raw)
To: Avi Kivity; +Cc: Mark McLoughlin, Gerd Hoffmann, qemu-devel
Avi Kivity wrote:
> Why? When you detect the conflict, ask the unlucky second to rebase
> (on top of some git branch). The rebased series doesn't need a
> re-review unless the submitter says he needed to rework it significantly.
>
> (IOW, the submitter's rebase doesn't need more review than your
> conflict resolution)
The rebasing is really trivial in most circumstances. It's akin to do a
merge conflict resolution after a git pull.
My mistake here was not in how I handled the conflict resolution but in
how I folded those commits back into the tree.
Basically, the workflow goes like this:
1) apply series
2) resolve conflicts applying series*
3) build
4) when build fails, resolve conflicts by adding new commits*
5) rebase and squash new commits into appropriate old commits
The alternative workflow would be:
1) apply series in branches
2) merge branches, resolving merge conflicts*
3) build
4) when build fails, resolve conflicts by adding new commits
5) squash commits into merge resolution commit
The second workflow eliminates the possibilities of errors in step 5.
If you look at the patch rates on the mailing list, it would be pretty
difficult to pick a series, then asking everyone else to resubmit after
that series is committed. The last thing we need is more submissions of
the same series on the mailing list. We're already practically flooded
with patches.
[*] if at any point in time this is non-trivial, push back to submitter
--
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Handling merge conflicts [was Re: [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO]
2009-10-28 16:24 ` Avi Kivity
2009-10-28 16:35 ` Anthony Liguori
@ 2009-10-28 16:36 ` Anthony Liguori
2009-10-29 8:18 ` Avi Kivity
2009-10-28 19:29 ` Gerd Hoffmann
2 siblings, 1 reply; 37+ messages in thread
From: Anthony Liguori @ 2009-10-28 16:36 UTC (permalink / raw)
To: Avi Kivity; +Cc: Mark McLoughlin, Gerd Hoffmann, qemu-devel
Avi Kivity wrote:
> Why? When you detect the conflict, ask the unlucky second to rebase
> (on top of some git branch). The rebased series doesn't need a
> re-review unless the submitter says he needed to rework it significantly.
>
> (IOW, the submitter's rebase doesn't need more review than your
> conflict resolution)
The rebasing is really trivial in most circumstances. It's akin to do a
merge conflict resolution after a git pull.
My mistake here was not in how I handled the conflict resolution but in
how I folded those commits back into the tree.
Basically, the workflow goes like this:
1) apply series
2) resolve conflicts applying series*
3) build
4) when build fails, resolve conflicts by adding new commits*
5) rebase and squash new commits into appropriate old commits
The alternative workflow would be:
1) apply series in branches
2) merge branches, resolving merge conflicts*
3) build
4) when build fails, resolve conflicts by adding new commits
5) squash commits into merge resolution commit
The second workflow eliminates the possibilities of errors in step 5.
If you look at the patch rates on the mailing list, it would be pretty
difficult to pick a series, then asking everyone else to resubmit after
that series is committed. The last thing we need is more submissions of
the same series on the mailing list. We're already practically flooded
with patches.
[*] if at any point in time this is non-trivial, push back to submitter
--
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Handling merge conflicts [was Re: [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO]
2009-10-28 16:36 ` Anthony Liguori
@ 2009-10-29 8:18 ` Avi Kivity
0 siblings, 0 replies; 37+ messages in thread
From: Avi Kivity @ 2009-10-29 8:18 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Mark McLoughlin, Gerd Hoffmann, qemu-devel
On 10/28/2009 06:36 PM, Anthony Liguori wrote:
> Avi Kivity wrote:
>> Why? When you detect the conflict, ask the unlucky second to rebase
>> (on top of some git branch). The rebased series doesn't need a
>> re-review unless the submitter says he needed to rework it
>> significantly.
>>
>> (IOW, the submitter's rebase doesn't need more review than your
>> conflict resolution)
>
> The rebasing is really trivial in most circumstances. It's akin to do a
> merge conflict resolution after a git pull.
>
> My mistake here was not in how I handled the conflict resolution but in
> how I folded those commits back into the tree.
Well, if it's just an error I don't see a need for a change in
procedure. FWIW, I do a lot of rebasing too (for different reasons -
not introduce a bug and its fix in the same pull, cross-arch compile
fixes, fold reverts and incremental fixes). To ensure I don't screw
things up, I always compare the result of the rebase with the original
(git diff should show nothing), and build-test every revision on every
arch. With ccache it's fairly reasonable, even on s390.
--
Do not meddle in the internals of kernels, for they are subtle and quick to panic.
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Handling merge conflicts [was Re: [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO]
2009-10-28 16:24 ` Avi Kivity
2009-10-28 16:35 ` Anthony Liguori
2009-10-28 16:36 ` Anthony Liguori
@ 2009-10-28 19:29 ` Gerd Hoffmann
2 siblings, 0 replies; 37+ messages in thread
From: Gerd Hoffmann @ 2009-10-28 19:29 UTC (permalink / raw)
To: Avi Kivity; +Cc: Mark McLoughlin, Anthony Liguori, qemu-devel
On 10/28/09 17:24, Avi Kivity wrote:
>> That would require a series to be merged within a very short time
>> period which does not allow appropriate review on the list.
>
> Why? When you detect the conflict, ask the unlucky second to rebase (on
> top of some git branch). The rebased series doesn't need a re-review
> unless the submitter says he needed to rework it significantly.
I fully agree here. For a new version of a patch (series) where the
only change is rebasing and resolving conflicts I don't see the point in
requiring another full week for review.
cheers
Gerd
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Handling merge conflicts [was Re: [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO]
2009-10-28 14:30 ` Handling merge conflicts [was Re: [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO] Mark McLoughlin
2009-10-28 14:57 ` Gerd Hoffmann
@ 2009-10-28 15:26 ` Anthony Liguori
2009-10-28 16:29 ` Mark McLoughlin
2009-10-28 19:19 ` Gerd Hoffmann
1 sibling, 2 replies; 37+ messages in thread
From: Anthony Liguori @ 2009-10-28 15:26 UTC (permalink / raw)
To: Mark McLoughlin; +Cc: Anthony Liguori, qemu-devel, Gerd Hoffmann
Mark McLoughlin wrote:
> Hi Anthony,
> Thanks for merging this stuff ...
>
> In the process of merging it all into qemu-kvm, I noticed a couple of
> problems:
>
> 1) bb6e63644 lacked the change to add the type code to
> qemu_new_vlan_client() so that and the subsequent 14 commits are
> unbuildable
>
> 2) 93db6685 references NET_CLIENT_TYPE_NIC and the receive_raw but
> these aren't added until bb6e636443 and 70783b9c, so that's 117
> unbuildable commits
>
> Neither of these problems existed in the patches Gerd and I posted, so
> presumably they came about by trying to merge the two patch sets?
>
It means I squashed the resolutions incorrectly. I could add a
bisectability test but that would take a long time to run...
> How can we avoid this happening in future? What process could we have
> used to avoid it?
>
There are a few ways. This was all sitting in staging for quite some
time so poking at staging proactively could have helped.
Alternatively, cooperating among each other to stagger submissions could
help.
> Should either Gerd or I have merged the others' changes into our tree
> and asked you to pull? Should you just refuse conflicts and ask us to
> re-post? Or ...?
>
Everything conflicts. This isn't obvious because 99% of the time, I
resolve it without any trouble. If the merge isn't trivially
resolvable, then I do push back on the submitter.
In this case, it was easily resolvable but I just squashed wrong. The
best way to address this from a git perspective would be for change the
way I merge things such that I merge series into separate branches
against master, then merge the branches together. The result would be
much more obvious merges and no chance of something like this
happening. On the flip side, history would get much worse to read.
If people feel strongly one way or another, I'm happy to adjust. This
was just a mistake on my part.
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Handling merge conflicts [was Re: [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO]
2009-10-28 15:26 ` Anthony Liguori
@ 2009-10-28 16:29 ` Mark McLoughlin
2009-10-28 16:51 ` Anthony Liguori
2009-10-28 19:25 ` Gerd Hoffmann
2009-10-28 19:19 ` Gerd Hoffmann
1 sibling, 2 replies; 37+ messages in thread
From: Mark McLoughlin @ 2009-10-28 16:29 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel, Gerd Hoffmann
On Wed, 2009-10-28 at 10:26 -0500, Anthony Liguori wrote:
> Mark McLoughlin wrote:
> > Hi Anthony,
> > Thanks for merging this stuff ...
> >
> > In the process of merging it all into qemu-kvm, I noticed a couple of
> > problems:
> >
> > 1) bb6e63644 lacked the change to add the type code to
> > qemu_new_vlan_client() so that and the subsequent 14 commits are
> > unbuildable
> >
> > 2) 93db6685 references NET_CLIENT_TYPE_NIC and the receive_raw but
> > these aren't added until bb6e636443 and 70783b9c, so that's 117
> > unbuildable commits
> >
> > Neither of these problems existed in the patches Gerd and I posted, so
> > presumably they came about by trying to merge the two patch sets?
> >
>
> It means I squashed the resolutions incorrectly.
Ah, okay; both series applied fine, but the result didn't build, so you
fixed up as a separate commit and then squashed that back into Gerd's
series rather than mine. Makes sense now.
> I could add a
> bisectability test but that would take a long time to run...
Testing that each commit builds could be easily automated and quick to
run. I try to do that before sending a series.
> > How can we avoid this happening in future? What process could we have
> > used to avoid it?
> >
>
> There are a few ways. This was all sitting in staging for quite some
> time so poking at staging proactively could have helped.
Okay. A "Thanks, applied to staging" reply on-list could help trigger
the submitter into action.
> Alternatively, cooperating among each other to stagger submissions could
> help.
Given the lag between submission and pushing, waiting until the first
series is pushed probably isn't what we want.
One way I tried solving this before was pulling conflicting patches into
my tree, re-basing on top of them and then asking you to pull from my
tree, but that was ignored.
I'd have been happy to re-base my series on-top of Gerd's and re-send to
the list, but I fear you might then have tried to apply my series first
and then dropped it. Also, I hate spamming the list with large series of
patches that have only trivially been changed.
How about a simple "I've merged Gerd's into staging, yours conflicts,
please re-base" on-list? Then I could reply with "Cool, re-base pushed
to vnet-hdr.v2 in my tree" and you could merge that?
> > Should either Gerd or I have merged the others' changes into our tree
> > and asked you to pull? Should you just refuse conflicts and ask us to
> > re-post? Or ...?
> >
>
> Everything conflicts. This isn't obvious because 99% of the time, I
> resolve it without any trouble. If the merge isn't trivially
> resolvable, then I do push back on the submitter.
>
> In this case, it was easily resolvable but I just squashed wrong. The
> best way to address this from a git perspective would be for change the
> way I merge things such that I merge series into separate branches
> against master, then merge the branches together. The result would be
> much more obvious merges and no chance of something like this
> happening. On the flip side, history would get much worse to read.
>
> If people feel strongly one way or another, I'm happy to adjust. This
> was just a mistake on my part.
Personally, I prefer a linear history but this implies re-basing series.
A conflicting re-base should be usually be done by the submitter,
though.
However, if you are to resolve a conflict, it probably should be done as
a merge commit rather than as a re-base.
Cheers,
Mark.
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Handling merge conflicts [was Re: [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO]
2009-10-28 16:29 ` Mark McLoughlin
@ 2009-10-28 16:51 ` Anthony Liguori
2009-10-28 19:25 ` Gerd Hoffmann
1 sibling, 0 replies; 37+ messages in thread
From: Anthony Liguori @ 2009-10-28 16:51 UTC (permalink / raw)
To: Mark McLoughlin; +Cc: qemu-devel, Gerd Hoffmann
Mark McLoughlin wrote:
>> I could add a
>> bisectability test but that would take a long time to run...
>>
>
> Testing that each commit builds could be easily automated and quick to
> run. I try to do that before sending a series.
>
It's certainly doable. I used to do that as part of my regular process.
>> Alternatively, cooperating among each other to stagger submissions could
>> help.
>>
>
> Given the lag between submission and pushing, waiting until the first
> series is pushed probably isn't what we want.
>
> One way I tried solving this before was pulling conflicting patches into
> my tree, re-basing on top of them and then asking you to pull from my
> tree, but that was ignored.
>
My process is really optimized to avoid losing patches. It gets
difficult to maintain this fidelity when dealing with subtree pulls
unless there's an absolute clear set of rules about what patches can be
dropped from my normal process.
Subtree pulls have worked great for linux-user because I can drop
linux-user patches very easily and they never touch anything else.
Riku also batches linux-user patches on the mailing list which is
helpful when dealing with subtrees.
As we get better at modularity and some of these touch everything series
slow down, I think we'll be able to more sanely do subtree pulls.
> I'd have been happy to re-base my series on-top of Gerd's and re-send to
> the list, but I fear you might then have tried to apply my series first
> and then dropped it. Also, I hate spamming the list with large series of
> patches that have only trivially been changed.
>
> How about a simple "I've merged Gerd's into staging, yours conflicts,
> please re-base" on-list? Then I could reply with "Cool, re-base pushed
> to vnet-hdr.v2 in my tree" and you could merge that?
>
I do this for non-trivial rebases. It would slow things down
considerably to do this for everything because as I've said before,
everything conflicts in some way. It offers little value to the process
too. This was a simple conflict resolution that a trained monkey would
have been capable of resolving :-)
The big problem is squashing the commits. It gets challenging because
it requires every change to be an individual commit and then it often
takes a lot of manual tinkering to find the right commits to squash
with. Using git branch merging would really simplify my life here and
it's something I've been considering for some time now.
It also helps with review because it demonstrates exactly what I did to
resolve the conflict.
> Personally, I prefer a linear history but this implies re-basing series.
> A conflicting re-base should be usually be done by the submitter,
> though.
>
> However, if you are to resolve a conflict, it probably should be done as
> a merge commit rather than as a re-base.
>
Yeah, I've been leaning toward something like this for a while and I
think I might take a stab at it. We'll lose a linear history anyway
once we start using sub trees more so it's not a huge loss.
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Handling merge conflicts [was Re: [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO]
2009-10-28 16:29 ` Mark McLoughlin
2009-10-28 16:51 ` Anthony Liguori
@ 2009-10-28 19:25 ` Gerd Hoffmann
1 sibling, 0 replies; 37+ messages in thread
From: Gerd Hoffmann @ 2009-10-28 19:25 UTC (permalink / raw)
To: Mark McLoughlin; +Cc: qemu-devel
Hi,
> How about a simple "I've merged Gerd's into staging, yours conflicts,
> please re-base" on-list? Then I could reply with "Cool, re-base pushed
> to vnet-hdr.v2 in my tree" and you could merge that?
Problem with that is that staging is a moving target (i.e. rebases
frequently). I'll never ever base any of my branches on staging, this
is just asking for trouble.
"I've merged into master, please rebase" would work for me though.
cheers,
Gerd
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: Handling merge conflicts [was Re: [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO]
2009-10-28 15:26 ` Anthony Liguori
2009-10-28 16:29 ` Mark McLoughlin
@ 2009-10-28 19:19 ` Gerd Hoffmann
1 sibling, 0 replies; 37+ messages in thread
From: Gerd Hoffmann @ 2009-10-28 19:19 UTC (permalink / raw)
To: Anthony Liguori; +Cc: Mark McLoughlin, Anthony Liguori, qemu-devel
>> Neither of these problems existed in the patches Gerd and I posted, so
>> presumably they came about by trying to merge the two patch sets?
>
> It means I squashed the resolutions incorrectly. I could add a
> bisectability test but that would take a long time to run...
Indeed.
>> How can we avoid this happening in future? What process could we have
>> used to avoid it?
>
> There are a few ways. This was all sitting in staging for quite some
> time so poking at staging proactively could have helped.
I stopped looking at staging. You stuff almost everything you find on
the list into staging, so seeing patches queued up there doesn't
indicate anything ...
cheers,
Gerd
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO
2009-10-22 16:43 [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO Mark McLoughlin
` (19 preceding siblings ...)
2009-10-28 14:30 ` Handling merge conflicts [was Re: [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO] Mark McLoughlin
@ 2009-10-30 10:04 ` Juha.Riihimaki
2009-10-30 16:59 ` Mark McLoughlin
20 siblings, 1 reply; 37+ messages in thread
From: Juha.Riihimaki @ 2009-10-30 10:04 UTC (permalink / raw)
To: markmc; +Cc: qemu-devel
On Oct 22, 2009, at 19:43, ext Mark McLoughlin wrote:
> Hey,
> Over a year ago we added some code to qemu-kvm.git which takes
> advantage of the recent tun/tap IFF_VNET_HDR feature in order to allow
> virtio-net to send and receive packets with partial checksums and
> segmentation offloaded:
>
> http://article.gmane.org/gmane.comp.emulators.kvm.devel/20440
>
> "This allows us to pass larger packets and packets with
> partial checkums between the guest and the host, greatly
> increasing the achievable bandwidth."
>
> Unfortunately, that implementation was quite hacky as it
> made some assumptions that would break if e.g. you added another
> network client to a vlan where the feature had enabled.
>
> Now that we have the -netdev parameter, we can more safely
> pair the NIC and backend, allowing us to negatiate features like
> this.
>
> What follows is a somewhat cleaned up version of the code
> from qemu-kvm.git. Further cleanups are probably possible, but I
> think this much is mergeable. Some points of discussion:
I think this patch set has broken the QEMU build on OS X. The reason
is that there are some definitions in tap-linux.h which only gets
included in net.c if __linux__ is defined but the other parts of net.c
which utilize definitions from tap-linux.h get compiled in
nevertheless. It compiles if all definitions (except for the extra
includes) from tap-linux.h are included for OS X as well. I've
attached below a sample of the compiler output.
Regards,
Juha
---
[...]
CC net.o
net.c: In function ‘tap_receive_iov’:
net.c:1391: error: variable ‘hdr’ has initializer but incomplete type
net.c:1391: warning: excess elements in struct initializer
net.c:1391: warning: (near initialization for ‘hdr’)
net.c:1391: error: storage size of ‘hdr’ isn’t known
net.c:1391: warning: unused variable ‘hdr’
net.c: In function ‘tap_receive_raw’:
net.c:1409: error: variable ‘hdr’ has initializer but incomplete type
net.c:1409: warning: excess elements in struct initializer
net.c:1409: warning: (near initialization for ‘hdr’)
net.c:1409: error: storage size of ‘hdr’ isn’t known
net.c:1409: warning: unused variable ‘hdr’
net.c: In function ‘tap_send’:
net.c:1484: error: invalid application of ‘sizeof’ to incomplete type
‘struct virtio_net_hdr’
net.c:1485: error: invalid application of ‘sizeof’ to incomplete type
‘struct virtio_net_hdr’
net.c: In function ‘tap_set_sndbuf’:
net.c:1511: error: ‘TUNSETSNDBUF’ undeclared (first use in this
function)
net.c:1511: error: (Each undeclared identifier is reported only once
net.c:1511: error: for each function it appears in.)
net.c: In function ‘tap_probe_vnet_hdr’:
net.c:1552: error: ‘TUNGETIFF’ undeclared (first use in this function)
net.c:1557: error: ‘IFF_VNET_HDR’ undeclared (first use in this
function)
net.c: In function ‘tap_set_offload’:
net.c:1567: error: ‘TUN_F_CSUM’ undeclared (first use in this function)
net.c:1569: error: ‘TUN_F_TSO4’ undeclared (first use in this function)
net.c:1571: error: ‘TUN_F_TSO6’ undeclared (first use in this function)
net.c:1573: error: ‘TUN_F_TSO_ECN’ undeclared (first use in this
function)
net.c:1575: error: ‘TUN_F_UFO’ undeclared (first use in this function)
net.c:1578: error: ‘TUNSETOFFLOAD’ undeclared (first use in this
function)
net.c: In function ‘net_tap_fd_init’:
net.c:1623: error: ‘TUN_F_CSUM’ undeclared (first use in this function)
net.c:1623: error: ‘TUN_F_UFO’ undeclared (first use in this function)
net.c:1624: error: ‘TUNSETOFFLOAD’ undeclared (first use in this
function)
make[1]: *** [net.o] Error 1
make: *** [build-all] Error 2
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO
2009-10-30 10:04 ` [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO Juha.Riihimaki
@ 2009-10-30 16:59 ` Mark McLoughlin
2009-10-30 21:10 ` Alexander Graf
0 siblings, 1 reply; 37+ messages in thread
From: Mark McLoughlin @ 2009-10-30 16:59 UTC (permalink / raw)
To: Juha.Riihimaki; +Cc: qemu-devel
Hi,
On Fri, 2009-10-30 at 11:04 +0100, Juha.Riihimaki@nokia.com wrote:
> On Oct 22, 2009, at 19:43, ext Mark McLoughlin wrote:
>
> > Hey,
> > Over a year ago we added some code to qemu-kvm.git which takes
> > advantage of the recent tun/tap IFF_VNET_HDR feature in order to allow
> > virtio-net to send and receive packets with partial checksums and
> > segmentation offloaded:
> >
> > http://article.gmane.org/gmane.comp.emulators.kvm.devel/20440
> >
> > "This allows us to pass larger packets and packets with
> > partial checkums between the guest and the host, greatly
> > increasing the achievable bandwidth."
> >
> > Unfortunately, that implementation was quite hacky as it
> > made some assumptions that would break if e.g. you added another
> > network client to a vlan where the feature had enabled.
> >
> > Now that we have the -netdev parameter, we can more safely
> > pair the NIC and backend, allowing us to negatiate features like
> > this.
> >
> > What follows is a somewhat cleaned up version of the code
> > from qemu-kvm.git. Further cleanups are probably possible, but I
> > think this much is mergeable. Some points of discussion:
>
> I think this patch set has broken the QEMU build on OS X. The reason
> is that there are some definitions in tap-linux.h which only gets
> included in net.c if __linux__ is defined but the other parts of net.c
> which utilize definitions from tap-linux.h get compiled in
> nevertheless. It compiles if all definitions (except for the extra
> includes) from tap-linux.h are included for OS X as well. I've
> attached below a sample of the compiler output.
It doesn't look like this is still a problem anymore with latest git?
Could you try again?
There are probably other problems now :-)
Thanks,
Mark.
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [Qemu-devel] [PATCH 00/19 v2] Add virtio-net/tap support for partial csums and GSO
2009-10-30 16:59 ` Mark McLoughlin
@ 2009-10-30 21:10 ` Alexander Graf
0 siblings, 0 replies; 37+ messages in thread
From: Alexander Graf @ 2009-10-30 21:10 UTC (permalink / raw)
To: Mark McLoughlin; +Cc: Juha.Riihimaki, qemu-devel
On 30.10.2009, at 17:59, Mark McLoughlin wrote:
> Hi,
>
> On Fri, 2009-10-30 at 11:04 +0100, Juha.Riihimaki@nokia.com wrote:
>> On Oct 22, 2009, at 19:43, ext Mark McLoughlin wrote:
>>
>>> Hey,
>>> Over a year ago we added some code to qemu-kvm.git which takes
>>> advantage of the recent tun/tap IFF_VNET_HDR feature in order to
>>> allow
>>> virtio-net to send and receive packets with partial checksums and
>>> segmentation offloaded:
>>>
>>> http://article.gmane.org/gmane.comp.emulators.kvm.devel/20440
>>>
>>> "This allows us to pass larger packets and packets with
>>> partial checkums between the guest and the host, greatly
>>> increasing the achievable bandwidth."
>>>
>>> Unfortunately, that implementation was quite hacky as it
>>> made some assumptions that would break if e.g. you added another
>>> network client to a vlan where the feature had enabled.
>>>
>>> Now that we have the -netdev parameter, we can more safely
>>> pair the NIC and backend, allowing us to negatiate features like
>>> this.
>>>
>>> What follows is a somewhat cleaned up version of the code
>>> from qemu-kvm.git. Further cleanups are probably possible, but I
>>> think this much is mergeable. Some points of discussion:
>>
>> I think this patch set has broken the QEMU build on OS X. The reason
>> is that there are some definitions in tap-linux.h which only gets
>> included in net.c if __linux__ is defined but the other parts of
>> net.c
>> which utilize definitions from tap-linux.h get compiled in
>> nevertheless. It compiles if all definitions (except for the extra
>> includes) from tap-linux.h are included for OS X as well. I've
>> attached below a sample of the compiler output.
>
> It doesn't look like this is still a problem anymore with latest git?
> Could you try again?
>
> There are probably other problems now :-)
Things are still horribly broken on OS X. I just did a git pull and
realized you were the one responsible :-).
In file included from net/tap.c:34:
/usr/include/net/if.h:264: error: field ‘ifru_addr’ has incomplete type
/usr/include/net/if.h:265: error: field ‘ifru_dstaddr’ has incomplete
type
/usr/include/net/if.h:266: error: field ‘ifru_broadaddr’ has
incomplete type
/usr/include/net/if.h:305: error: field ‘ifra_addr’ has incomplete type
/usr/include/net/if.h:306: error: field ‘ifra_broadaddr’ has
incomplete type
/usr/include/net/if.h:307: error: field ‘ifra_mask’ has incomplete type
/usr/include/net/if.h:379: error: field ‘addr’ has incomplete type
/usr/include/net/if.h:380: error: field ‘dstaddr’ has incomplete type
In file included from net/tap.c:41:
./net/tap-linux.h:20:25: warning: linux/ioctl.h: No such file or
directory
make[1]: *** [net/tap.o] Error 1
make: *** [build-all] Error 2
I'm looking into making OS X work again now ...
Alex
^ permalink raw reply [flat|nested] 37+ messages in thread