summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--net.c8
-rw-r--r--net/tap.c29
-rw-r--r--qemu-options.hx4
3 files changed, 40 insertions, 1 deletions
diff --git a/net.c b/net.c
index 1092bdcaa5..3ede738cac 100644
--- a/net.c
+++ b/net.c
@@ -976,6 +976,14 @@ static const struct {
.name = "vnet_hdr",
.type = QEMU_OPT_BOOL,
.help = "enable the IFF_VNET_HDR flag on the tap interface"
+ }, {
+ .name = "vhost",
+ .type = QEMU_OPT_BOOL,
+ .help = "enable vhost-net network accelerator",
+ }, {
+ .name = "vhostfd",
+ .type = QEMU_OPT_STRING,
+ .help = "file descriptor of an already opened vhost net device",
},
#endif /* _WIN32 */
{ /* end of list */ }
diff --git a/net/tap.c b/net/tap.c
index c19740b584..740665f5b6 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -42,6 +42,8 @@
#include "net/tap-linux.h"
+#include "hw/vhost_net.h"
+
/* Maximum GSO packet size (64k) plus plenty of room for
* the ethernet and virtio_net headers
*/
@@ -58,6 +60,7 @@ typedef struct TAPState {
unsigned int has_vnet_hdr : 1;
unsigned int using_vnet_hdr : 1;
unsigned int has_ufo: 1;
+ VHostNetState *vhost_net;
} TAPState;
static int launch_script(const char *setup_script, const char *ifname, int fd);
@@ -253,6 +256,10 @@ static void tap_cleanup(VLANClientState *nc)
{
TAPState *s = DO_UPCAST(TAPState, nc, nc);
+ if (s->vhost_net) {
+ vhost_net_cleanup(s->vhost_net);
+ }
+
qemu_purge_queued_packets(nc);
if (s->down_script[0])
@@ -308,6 +315,7 @@ static TAPState *net_tap_fd_init(VLANState *vlan,
s->has_ufo = tap_probe_has_ufo(s->fd);
tap_set_offload(&s->nc, 0, 0, 0, 0, 0);
tap_read_poll(s, 1);
+ s->vhost_net = NULL;
return s;
}
@@ -457,5 +465,26 @@ int net_init_tap(QemuOpts *opts, Monitor *mon, const char *name, VLANState *vlan
}
}
+ if (qemu_opt_get_bool(opts, "vhost", !!qemu_opt_get(opts, "vhostfd"))) {
+ int vhostfd, r;
+ if (qemu_opt_get(opts, "vhostfd")) {
+ r = net_handle_fd_param(mon, qemu_opt_get(opts, "vhostfd"));
+ if (r == -1) {
+ return -1;
+ }
+ vhostfd = r;
+ } else {
+ vhostfd = -1;
+ }
+ s->vhost_net = vhost_net_init(&s->nc, vhostfd);
+ if (!s->vhost_net) {
+ error_report("vhost-net requested but could not be initialized");
+ return -1;
+ }
+ } else if (qemu_opt_get(opts, "vhostfd")) {
+ error_report("vhostfd= is not valid without vhost");
+ return -1;
+ }
+
return 0;
}
diff --git a/qemu-options.hx b/qemu-options.hx
index 719cbda83c..f4b3bfe90f 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -892,7 +892,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][,vnet_hdr=on|off]\n"
+ "-net tap[,vlan=n][,name=str][,fd=h][,ifname=name][,script=file][,downscript=dfile][,sndbuf=nbytes][,vnet_hdr=on|off][,vhost=on|off][,vhostfd=h]\n"
" connect the host TAP network interface to VLAN 'n' and use the\n"
" network scripts 'file' (default=" DEFAULT_NETWORK_SCRIPT ")\n"
" and 'dfile' (default=" DEFAULT_NETWORK_DOWN_SCRIPT ")\n"
@@ -902,6 +902,8 @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
" default of 'sndbuf=1048576' can be disabled using 'sndbuf=0')\n"
" use vnet_hdr=off to avoid enabling the IFF_VNET_HDR tap flag\n"
" use vnet_hdr=on to make the lack of IFF_VNET_HDR support an error condition\n"
+ " use vhost=on to enable experimental in kernel accelerator\n"
+ " use 'vhostfd=h' to connect to an already opened vhost net device\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"