From c80cd6bb9c20ef518c56319ce44d2971171e677d Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Wed, 17 Jun 2015 15:23:44 +0200 Subject: tap: add VNET_LE/VNET_BE operations The linux tap and macvtap backends can be told to parse vnet headers according to little or big endian. This is done through the TUNSETVNETLE and TUNSETVNETBE ioctls. This patch brings all the plumbing for QEMU to use these APIs. Signed-off-by: Greg Kurz Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- net/net.c | 18 ++++++++++++++++++ net/tap-linux.c | 34 ++++++++++++++++++++++++++++++++++ net/tap-linux.h | 2 ++ net/tap.c | 16 ++++++++++++++++ net/tap_int.h | 2 ++ 5 files changed, 72 insertions(+) (limited to 'net') diff --git a/net/net.c b/net/net.c index db6be12..5148aac 100644 --- a/net/net.c +++ b/net/net.c @@ -510,6 +510,24 @@ void qemu_set_vnet_hdr_len(NetClientState *nc, int len) nc->info->set_vnet_hdr_len(nc, len); } +int qemu_set_vnet_le(NetClientState *nc, bool is_le) +{ + if (!nc || !nc->info->set_vnet_le) { + return -ENOSYS; + } + + return nc->info->set_vnet_le(nc, is_le); +} + +int qemu_set_vnet_be(NetClientState *nc, bool is_be) +{ + if (!nc || !nc->info->set_vnet_be) { + return -ENOSYS; + } + + return nc->info->set_vnet_be(nc, is_be); +} + int qemu_can_send_packet(NetClientState *sender) { int vm_running = runstate_is_running(); diff --git a/net/tap-linux.c b/net/tap-linux.c index 6c3caef..394f2a6 100644 --- a/net/tap-linux.c +++ b/net/tap-linux.c @@ -198,6 +198,40 @@ void tap_fd_set_vnet_hdr_len(int fd, int len) } } +int tap_fd_set_vnet_le(int fd, int is_le) +{ + int arg = is_le ? 1 : 0; + + if (!ioctl(fd, TUNSETVNETLE, &arg)) { + return 0; + } + + /* Check if our kernel supports TUNSETVNETLE */ + if (errno == EINVAL) { + return -errno; + } + + error_report("TUNSETVNETLE ioctl() failed: %s.\n", strerror(errno)); + abort(); +} + +int tap_fd_set_vnet_be(int fd, int is_be) +{ + int arg = is_be ? 1 : 0; + + if (!ioctl(fd, TUNSETVNETBE, &arg)) { + return 0; + } + + /* Check if our kernel supports TUNSETVNETBE */ + if (errno == EINVAL) { + return -errno; + } + + error_report("TUNSETVNETBE ioctl() failed: %s.\n", strerror(errno)); + abort(); +} + void tap_fd_set_offload(int fd, int csum, int tso4, int tso6, int ecn, int ufo) { diff --git a/net/tap-linux.h b/net/tap-linux.h index 1cf35d4..01dc6f8 100644 --- a/net/tap-linux.h +++ b/net/tap-linux.h @@ -30,6 +30,8 @@ #define TUNGETVNETHDRSZ _IOR('T', 215, int) #define TUNSETVNETHDRSZ _IOW('T', 216, int) #define TUNSETQUEUE _IOW('T', 217, int) +#define TUNSETVNETLE _IOW('T', 220, int) +#define TUNSETVNETBE _IOW('T', 222, int) #endif diff --git a/net/tap.c b/net/tap.c index d1ca314..ec12dfd 100644 --- a/net/tap.c +++ b/net/tap.c @@ -275,6 +275,20 @@ static void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr) s->using_vnet_hdr = using_vnet_hdr; } +static int tap_set_vnet_le(NetClientState *nc, bool is_le) +{ + TAPState *s = DO_UPCAST(TAPState, nc, nc); + + return tap_fd_set_vnet_le(s->fd, is_le); +} + +static int tap_set_vnet_be(NetClientState *nc, bool is_be) +{ + TAPState *s = DO_UPCAST(TAPState, nc, nc); + + return tap_fd_set_vnet_be(s->fd, is_be); +} + static void tap_set_offload(NetClientState *nc, int csum, int tso4, int tso6, int ecn, int ufo) { @@ -341,6 +355,8 @@ static NetClientInfo net_tap_info = { .using_vnet_hdr = tap_using_vnet_hdr, .set_offload = tap_set_offload, .set_vnet_hdr_len = tap_set_vnet_hdr_len, + .set_vnet_le = tap_set_vnet_le, + .set_vnet_be = tap_set_vnet_be, }; static TAPState *net_tap_fd_init(NetClientState *peer, diff --git a/net/tap_int.h b/net/tap_int.h index d12a409..2378021 100644 --- a/net/tap_int.h +++ b/net/tap_int.h @@ -40,6 +40,8 @@ int tap_probe_vnet_hdr_len(int fd, int len); int tap_probe_has_ufo(int fd); void tap_fd_set_offload(int fd, int csum, int tso4, int tso6, int ecn, int ufo); void tap_fd_set_vnet_hdr_len(int fd, int len); +int tap_fd_set_vnet_le(int fd, int vnet_is_le); +int tap_fd_set_vnet_be(int fd, int vnet_is_be); int tap_fd_enable(int fd); int tap_fd_disable(int fd); int tap_fd_get_ifname(int fd, char *ifname); -- cgit v1.1 From 4ee9b43be9a6e4ae161a1e6322bfef90818589f6 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Thu, 18 Jun 2015 16:52:23 +0200 Subject: tap: fix non-linux build tap_fd_set_vnet_le/tap_fd_set_vnet_be was missing, fix it up. Signed-off-by: Michael S. Tsirkin Reviewed-by: Thomas Huth Reviewed-by: Greg Kurz --- net/tap-aix.c | 10 ++++++++++ net/tap-bsd.c | 10 ++++++++++ net/tap-haiku.c | 10 ++++++++++ net/tap-solaris.c | 10 ++++++++++ net/tap-win32.c | 10 ++++++++++ 5 files changed, 50 insertions(+) (limited to 'net') diff --git a/net/tap-aix.c b/net/tap-aix.c index 18fdbf3..e84fc39 100644 --- a/net/tap-aix.c +++ b/net/tap-aix.c @@ -55,6 +55,16 @@ void tap_fd_set_vnet_hdr_len(int fd, int len) { } +int tap_fd_set_vnet_le(int fd, int is_le) +{ + return -EINVAL; +} + +int tap_fd_set_vnet_be(int fd, int is_be) +{ + return -EINVAL; +} + void tap_fd_set_offload(int fd, int csum, int tso4, int tso6, int ecn, int ufo) { diff --git a/net/tap-bsd.c b/net/tap-bsd.c index 5889920..7028d9b 100644 --- a/net/tap-bsd.c +++ b/net/tap-bsd.c @@ -196,6 +196,16 @@ void tap_fd_set_vnet_hdr_len(int fd, int len) { } +int tap_fd_set_vnet_le(int fd, int is_le) +{ + return -EINVAL; +} + +int tap_fd_set_vnet_be(int fd, int is_be) +{ + return -EINVAL; +} + void tap_fd_set_offload(int fd, int csum, int tso4, int tso6, int ecn, int ufo) { diff --git a/net/tap-haiku.c b/net/tap-haiku.c index d18590c..2e738ec 100644 --- a/net/tap-haiku.c +++ b/net/tap-haiku.c @@ -55,6 +55,16 @@ void tap_fd_set_vnet_hdr_len(int fd, int len) { } +int tap_fd_set_vnet_le(int fd, int is_le) +{ + return -EINVAL; +} + +int tap_fd_set_vnet_be(int fd, int is_be) +{ + return -EINVAL; +} + void tap_fd_set_offload(int fd, int csum, int tso4, int tso6, int ecn, int ufo) { diff --git a/net/tap-solaris.c b/net/tap-solaris.c index 90b2fd1..0f60f78 100644 --- a/net/tap-solaris.c +++ b/net/tap-solaris.c @@ -223,6 +223,16 @@ void tap_fd_set_vnet_hdr_len(int fd, int len) { } +int tap_fd_set_vnet_le(int fd, int is_le) +{ + return -EINVAL; +} + +int tap_fd_set_vnet_be(int fd, int is_be) +{ + return -EINVAL; +} + void tap_fd_set_offload(int fd, int csum, int tso4, int tso6, int ecn, int ufo) { diff --git a/net/tap-win32.c b/net/tap-win32.c index f6fc961..625d53c 100644 --- a/net/tap-win32.c +++ b/net/tap-win32.c @@ -688,6 +688,16 @@ void tap_fd_set_vnet_hdr_len(int fd, int len) { } +int tap_fd_set_vnet_le(int fd, int is_le) +{ + return -EINVAL; +} + +int tap_fd_set_vnet_be(int fd, int is_be) +{ + return -EINVAL; +} + static void tap_using_vnet_hdr(NetClientState *nc, bool using_vnet_hdr) { } -- cgit v1.1 From 1e7398a140f7a6bd9f5a438e7ad0f1ef50990e25 Mon Sep 17 00:00:00 2001 From: Pankaj Gupta Date: Tue, 16 Jun 2015 13:48:59 +0530 Subject: vhost: enable vhost without without MSI-X We use vhostforce to enable vhost even if Guests don't have MSI-X support and we fall back to QEMU virtio-net. This gives a very small performance gain, but the disadvantage is that guest now controls which virtio code is running (qemu or vhost) so our attack surface is doubled. This patch will enable vhost unconditionally whenever it's requested. For compatibility, enable vhost when vhostforce is set, as well. Signed-off-by: Pankaj Gupta Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Jason Wang --- net/tap.c | 1 - net/vhost-user.c | 1 - 2 files changed, 2 deletions(-) (limited to 'net') diff --git a/net/tap.c b/net/tap.c index ec12dfd..3a3f522 100644 --- a/net/tap.c +++ b/net/tap.c @@ -671,7 +671,6 @@ static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, options.backend_type = VHOST_BACKEND_TYPE_KERNEL; options.net_backend = &s->nc; - options.force = tap->has_vhostforce && tap->vhostforce; if (tap->has_vhostfd || tap->has_vhostfds) { vhostfd = monitor_fd_param(cur_mon, vhostfdname, &err); diff --git a/net/vhost-user.c b/net/vhost-user.c index 8d26728..f1df26d 100644 --- a/net/vhost-user.c +++ b/net/vhost-user.c @@ -50,7 +50,6 @@ static int vhost_user_start(VhostUserState *s) options.backend_type = VHOST_BACKEND_TYPE_USER; options.net_backend = &s->nc; options.opaque = s->chr; - options.force = true; s->vhost_net = vhost_net_init(&options); -- cgit v1.1