From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56619) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Wtzfq-0001I6-Gv for qemu-devel@nongnu.org; Mon, 09 Jun 2014 09:31:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Wtzfl-00075m-He for qemu-devel@nongnu.org; Mon, 09 Jun 2014 09:31:42 -0400 Received: from mx1.redhat.com ([209.132.183.28]:18996) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Wtzfk-00075P-S8 for qemu-devel@nongnu.org; Mon, 09 Jun 2014 09:31:37 -0400 Date: Mon, 9 Jun 2014 16:31:59 +0300 From: "Michael S. Tsirkin" Message-ID: <20140609133159.GB6239@redhat.com> References: <20140527120050.15172.94908.stgit@3820> <20140527120638.15172.80806.stgit@3820> <20140605103710.1246d6c3@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline In-Reply-To: Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [snabb-devel] Re: [PATCH v10 15/18] Add the vhost-user netdev backend to the command line List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Nikolay Nikolaev Cc: "snabb-devel@googlegroups.com" , qemu-devel , Luke Gorrie , Antonios Motakis , VirtualOpenSystems Technical Team On Mon, Jun 09, 2014 at 04:28:23PM +0300, Nikolay Nikolaev wrote: > Hello, >=20 >=20 > On Thu, Jun 5, 2014 at 5:37 PM, Luiz Capitulino wrote: >=20 > On Tue, 27 May 2014 15:06:43 +0300 > Nikolay Nikolaev wrote: >=20 > > The supplied chardev id will be inspected for supported options. = Only > > a socket backend, with a set path (i.e. a Unix socket) and option= ally > > the server parameter set, will be allowed. Other options (nowait,= telnet) > > will make the chardev unusable and the netdev will not be initial= ised. > > > > Additional checks for validity: > > =A0 - requires `-numa node,memdev=3D..` > > =A0 - requires `-device virtio-net-*` > > > > The `vhostforce` option is used to force vhost-net when we deal w= ith > > non-MSIX guests. > > > > Signed-off-by: Antonios Motakis > > Signed-off-by: Nikolay Nikolaev >=20 > I gave a quick review and apart from some minor comments below it s= eems > good to me, but I think it would be good to have Eric's review too: >=20 > Acked-by: Luiz Capitulino >=20 > Thanks! >=20 >=20 > > --- > > =A0hmp-commands.hx =A0 =A0| =A0 =A04 +- > > =A0hw/net/vhost_net.c | =A0 =A04 ++ > > =A0net/hub.c =A0 =A0 =A0 =A0 =A0| =A0 =A01 > > =A0net/net.c =A0 =A0 =A0 =A0 =A0| =A0 25 ++++++----- > > =A0net/vhost-user.c =A0 | =A0114 > +++++++++++++++++++++++++++++++++++++++++++++++++++- > > =A0qapi-schema.json =A0 | =A0 19 ++++++++- > > =A0qemu-options.hx =A0 =A0| =A0 18 ++++++++ > > =A07 files changed, 169 insertions(+), 16 deletions(-) > > > > diff --git a/hmp-commands.hx b/hmp-commands.hx > > index 8971f1b..ef3782c 100644 > > --- a/hmp-commands.hx > > +++ b/hmp-commands.hx > > @@ -1205,7 +1205,7 @@ ETEXI > > =A0 =A0 =A0{ > > =A0 =A0 =A0 =A0 =A0.name =A0 =A0 =A0 =3D "host_net_add", > > =A0 =A0 =A0 =A0 =A0.args_type =A0=3D "device:s,opts:s?", > > - =A0 =A0 =A0 =A0.params =A0 =A0 =3D "tap|user|socket|vde|netmap|= dump [options]", > > + =A0 =A0 =A0 =A0.params =A0 =A0 =3D "tap|user|socket|vde|netmap|= vhost-user|dump > [options]", > > =A0 =A0 =A0 =A0 =A0.help =A0 =A0 =A0 =3D "add host VLAN client", > > =A0 =A0 =A0 =A0 =A0.mhandler.cmd =3D net_host_device_add, > > =A0 =A0 =A0}, > > @@ -1233,7 +1233,7 @@ ETEXI > > =A0 =A0 =A0{ > > =A0 =A0 =A0 =A0 =A0.name =A0 =A0 =A0 =3D "netdev_add", > > =A0 =A0 =A0 =A0 =A0.args_type =A0=3D "netdev:O", > > - =A0 =A0 =A0 =A0.params =A0 =A0 =3D "[user|tap|socket|hubport|ne= tmap],id=3Dstr[,prop=3D > value][,...]", > > + =A0 =A0 =A0 =A0.params =A0 =A0 =3D "[user|tap|socket|hubport|ne= tmap|vhost-user],id=3D > str[,prop=3Dvalue][,...]", > > =A0 =A0 =A0 =A0 =A0.help =A0 =A0 =A0 =3D "add host network device= ", > > =A0 =A0 =A0 =A0 =A0.mhandler.cmd =3D hmp_netdev_add, > > =A0 =A0 =A0}, > > diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c > > index 5f06736..7ac7c21 100644 > > --- a/hw/net/vhost_net.c > > +++ b/hw/net/vhost_net.c > > @@ -15,6 +15,7 @@ > > > > =A0#include "net/net.h" > > =A0#include "net/tap.h" > > +#include "net/vhost-user.h" > > > > =A0#include "hw/virtio/virtio-net.h" > > =A0#include "net/vhost_net.h" > > @@ -360,6 +361,9 @@ VHostNetState *get_vhost_net(NetClientState *= nc) > > =A0 =A0 =A0case NET_CLIENT_OPTIONS_KIND_TAP: > > =A0 =A0 =A0 =A0 =A0vhost_net =3D tap_get_vhost_net(nc); > > =A0 =A0 =A0 =A0 =A0break; > > + =A0 =A0case NET_CLIENT_OPTIONS_KIND_VHOST_USER: > > + =A0 =A0 =A0 =A0vhost_net =3D vhost_user_get_vhost_net(nc); > > + =A0 =A0 =A0 =A0break; > > =A0 =A0 =A0default: > > =A0 =A0 =A0 =A0 =A0break; > > =A0 =A0 =A0} > > diff --git a/net/hub.c b/net/hub.c > > index 33a99c9..7e0f2d6 100644 > > --- a/net/hub.c > > +++ b/net/hub.c > > @@ -322,6 +322,7 @@ void net_hub_check_clients(void) > > =A0 =A0 =A0 =A0 =A0 =A0 =A0case NET_CLIENT_OPTIONS_KIND_TAP: > > =A0 =A0 =A0 =A0 =A0 =A0 =A0case NET_CLIENT_OPTIONS_KIND_SOCKET: > > =A0 =A0 =A0 =A0 =A0 =A0 =A0case NET_CLIENT_OPTIONS_KIND_VDE: > > + =A0 =A0 =A0 =A0 =A0 =A0case NET_CLIENT_OPTIONS_KIND_VHOST_USER: > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0has_host_dev =3D 1; > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break; > > =A0 =A0 =A0 =A0 =A0 =A0 =A0default: > > diff --git a/net/net.c b/net/net.c > > index 9db4dba..907f679 100644 > > --- a/net/net.c > > +++ b/net/net.c > > @@ -769,23 +769,24 @@ static int (* const net_client_init_fun > [NET_CLIENT_OPTIONS_KIND_MAX])( > > =A0 =A0 =A0const NetClientOptions *opts, > > =A0 =A0 =A0const char *name, > > =A0 =A0 =A0NetClientState *peer) =3D { > > - =A0 =A0 =A0 =A0[NET_CLIENT_OPTIONS_KIND_NIC] =A0 =A0 =A0 =3D ne= t_init_nic, > > + =A0 =A0 =A0 =A0[NET_CLIENT_OPTIONS_KIND_NIC] =A0 =A0 =A0 =A0 =A0= =3D net_init_nic, > > =A0#ifdef CONFIG_SLIRP > > - =A0 =A0 =A0 =A0[NET_CLIENT_OPTIONS_KIND_USER] =A0 =A0 =A0=3D ne= t_init_slirp, > > + =A0 =A0 =A0 =A0[NET_CLIENT_OPTIONS_KIND_USER] =A0 =A0 =A0 =A0 =A0= =3D net_init_slirp, > > =A0#endif > > - =A0 =A0 =A0 =A0[NET_CLIENT_OPTIONS_KIND_TAP] =A0 =A0 =A0 =3D ne= t_init_tap, > > - =A0 =A0 =A0 =A0[NET_CLIENT_OPTIONS_KIND_SOCKET] =A0 =A0=3D net_= init_socket, > > + =A0 =A0 =A0 =A0[NET_CLIENT_OPTIONS_KIND_TAP] =A0 =A0 =A0 =A0 =A0= =3D net_init_tap, > > + =A0 =A0 =A0 =A0[NET_CLIENT_OPTIONS_KIND_SOCKET] =A0 =A0 =A0 =A0= =3D net_init_socket, > > =A0#ifdef CONFIG_VDE > > - =A0 =A0 =A0 =A0[NET_CLIENT_OPTIONS_KIND_VDE] =A0 =A0 =A0 =3D ne= t_init_vde, > > + =A0 =A0 =A0 =A0[NET_CLIENT_OPTIONS_KIND_VDE] =A0 =A0 =A0 =A0 =A0= =3D net_init_vde, > > =A0#endif > > =A0#ifdef CONFIG_NETMAP > > - =A0 =A0 =A0 =A0[NET_CLIENT_OPTIONS_KIND_NETMAP] =A0 =A0=3D net_= init_netmap, > > + =A0 =A0 =A0 =A0[NET_CLIENT_OPTIONS_KIND_NETMAP] =A0 =A0 =A0 =A0= =3D net_init_netmap, > > =A0#endif > > - =A0 =A0 =A0 =A0[NET_CLIENT_OPTIONS_KIND_DUMP] =A0 =A0 =A0=3D ne= t_init_dump, > > + =A0 =A0 =A0 =A0[NET_CLIENT_OPTIONS_KIND_DUMP] =A0 =A0 =A0 =A0 =A0= =3D net_init_dump, > > =A0#ifdef CONFIG_NET_BRIDGE > > - =A0 =A0 =A0 =A0[NET_CLIENT_OPTIONS_KIND_BRIDGE] =A0 =A0=3D net_= init_bridge, > > + =A0 =A0 =A0 =A0[NET_CLIENT_OPTIONS_KIND_BRIDGE] =A0 =A0 =A0 =A0= =3D net_init_bridge, >=20 > These changes are unrelated. >=20 > OK. Removing them. >=20 >=20 > > =A0#endif > > - =A0 =A0 =A0 =A0[NET_CLIENT_OPTIONS_KIND_HUBPORT] =A0 =3D net_in= it_hubport, > > + =A0 =A0 =A0 =A0[NET_CLIENT_OPTIONS_KIND_HUBPORT] =A0 =A0 =A0 =3D= net_init_hubport, > > + =A0 =A0 =A0 =A0[NET_CLIENT_OPTIONS_KIND_VHOST_USER] =A0 =A0=3D = net_init_vhost_user, > > =A0}; > > > > > > @@ -819,6 +820,7 @@ static int net_client_init1(const void *objec= t, int > is_netdev, Error **errp) > > =A0 =A0 =A0 =A0 =A0case NET_CLIENT_OPTIONS_KIND_BRIDGE: > > =A0#endif > > =A0 =A0 =A0 =A0 =A0case NET_CLIENT_OPTIONS_KIND_HUBPORT: > > + =A0 =A0 =A0 =A0case NET_CLIENT_OPTIONS_KIND_VHOST_USER: > > =A0 =A0 =A0 =A0 =A0 =A0 =A0break; > > > > =A0 =A0 =A0 =A0 =A0default: > > @@ -902,11 +904,12 @@ static int net_host_check_device(const char > *device) > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 , "bridge" > > =A0#endif > > =A0#ifdef CONFIG_SLIRP > > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 ,"user" > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 , "user" > > =A0#endif > > =A0#ifdef CONFIG_VDE > > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 ,"vde" > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 , "vde" > > =A0#endif > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 , "vhost-user" > > =A0 =A0 =A0}; > > =A0 =A0 =A0for (i =3D 0; i < ARRAY_SIZE(valid_param_list); i++) { > > =A0 =A0 =A0 =A0 =A0if (!strncmp(valid_param_list[i], device, > > diff --git a/net/vhost-user.c b/net/vhost-user.c > > index 4bdd19d..69a5eb4 100644 > > --- a/net/vhost-user.c > > +++ b/net/vhost-user.c > > @@ -12,6 +12,7 @@ > > =A0#include "net/vhost_net.h" > > =A0#include "net/vhost-user.h" > > =A0#include "sysemu/char.h" > > +#include "qemu/config-file.h" > > =A0#include "qemu/error-report.h" > > > > =A0typedef struct VhostUserState { > > @@ -21,9 +22,17 @@ typedef struct VhostUserState { > > =A0 =A0 =A0VHostNetState *vhost_net; > > =A0} VhostUserState; > > > > +typedef struct VhostUserChardevProps { > > + =A0 =A0bool is_socket; > > + =A0 =A0bool is_unix; > > + =A0 =A0bool is_server; > > + =A0 =A0bool has_unsupported; > > +} VhostUserChardevProps; > > + > > =A0VHostNetState *vhost_user_get_vhost_net(NetClientState *nc) > > =A0{ > > =A0 =A0 =A0VhostUserState *s =3D DO_UPCAST(VhostUserState, nc, nc= ); > > + =A0 =A0assert(nc->info->type =3D=3D NET_CLIENT_OPTIONS_KIND_VHO= ST_USER); > > =A0 =A0 =A0return s->vhost_net; > > =A0} > > > > @@ -82,7 +91,7 @@ static bool vhost_user_has_ufo(NetClientState *= nc) > > =A0} > > > > =A0static NetClientInfo net_vhost_user_info =3D { > > - =A0 =A0 =A0 =A0.type =3D 0, > > + =A0 =A0 =A0 =A0.type =3D NET_CLIENT_OPTIONS_KIND_VHOST_USER, > > =A0 =A0 =A0 =A0 =A0.size =3D sizeof(VhostUserState), > > =A0 =A0 =A0 =A0 =A0.cleanup =3D vhost_user_cleanup, > > =A0 =A0 =A0 =A0 =A0.has_vnet_hdr =3D vhost_user_has_vnet_hdr, > > @@ -148,8 +157,109 @@ static int net_vhost_user_init(NetClientSta= te > *peer, const char *device, > > =A0 =A0 =A0return 0; > > =A0} > > > > +static int net_vhost_chardev_opts(const char *name, const char *= value, > > + =A0 =A0 =A0 =A0void *opaque) > > +{ > > + =A0 =A0VhostUserChardevProps *props =3D opaque; > > + > > + =A0 =A0if (strcmp(name, "backend") =3D=3D 0 && strcmp(value, "s= ocket") =3D=3D 0) { > > + =A0 =A0 =A0 =A0props->is_socket =3D 1; > > + =A0 =A0} else if (strcmp(name, "path") =3D=3D 0) { > > + =A0 =A0 =A0 =A0props->is_unix =3D 1; > > + =A0 =A0} else if (strcmp(name, "server") =3D=3D 0) { > > + =A0 =A0 =A0 =A0props->is_server =3D 1; > > + =A0 =A0} else { > > + =A0 =A0 =A0 =A0error_report("vhost-user does not support a char= dev" > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 " with the following op= tion:\n %s =3D %s", > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 name, value); > > + =A0 =A0 =A0 =A0props->has_unsupported =3D 1; > > + =A0 =A0 =A0 =A0return -1; > > + =A0 =A0} > > + =A0 =A0return 0; > > +} > > + > > +static CharDriverState *net_vhost_parse_chardev( > > + =A0 =A0 =A0 =A0const NetdevVhostUserOptions *opts) > > +{ > > + =A0 =A0CharDriverState *chr =3D qemu_chr_find(opts->chardev); > > + =A0 =A0VhostUserChardevProps props; > > + > > + =A0 =A0if (chr =3D=3D NULL) { > > + =A0 =A0 =A0 =A0error_report("chardev \"%s\" not found\n", opts-= >chardev); > > + =A0 =A0 =A0 =A0return 0; > > + =A0 =A0} > > + > > + =A0 =A0/* inspect chardev opts */ > > + =A0 =A0memset(&props, 0, sizeof(props)); > > + =A0 =A0qemu_opt_foreach(chr->opts, net_vhost_chardev_opts, &pro= ps, false); > > + > > + =A0 =A0if (!props.is_socket || !props.is_unix) { > > + =A0 =A0 =A0 =A0error_report("chardev \"%s\" is not a unix socke= t\n", > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 opts->chardev); > > + =A0 =A0 =A0 =A0return 0; > > + =A0 =A0} > > + > > + =A0 =A0if (props.has_unsupported) { > > + =A0 =A0 =A0 =A0error_report("chardev \"%s\" has an unsupported = option\n", > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0opts->chardev); > > + =A0 =A0 =A0 =A0return 0; > > + =A0 =A0} > > + > > + =A0 =A0qemu_chr_fe_claim_no_fail(chr); > > + > > + =A0 =A0return chr; > > +} > > + > > +static int net_vhost_check_net(QemuOpts *opts, void *opaque) > > +{ > > + =A0 =A0const char *name =3D opaque; > > + =A0 =A0const char *driver, *netdev; > > + =A0 =A0const char virtio_name[] =3D "virtio-net-"; > > + > > + =A0 =A0driver =3D qemu_opt_get(opts, "driver"); > > + =A0 =A0netdev =3D qemu_opt_get(opts, "netdev"); > > + > > + =A0 =A0if (!driver || !netdev) { > > + =A0 =A0 =A0 =A0return 0; > > + =A0 =A0} > > + > > + =A0 =A0if ((strcmp(netdev, name) =3D=3D 0) > > + =A0 =A0 =A0 =A0 =A0 =A0&& (strncmp(driver, virtio_name, strlen(= virtio_name)) !=3D 0)) > { > > + =A0 =A0 =A0 =A0error_report("vhost-user requires frontend drive= r > virtio-net-*"); > > + =A0 =A0 =A0 =A0return -1; > > + =A0 =A0} > > + > > + =A0 =A0return 0; > > +} > > + > > =A0int net_init_vhost_user(const NetClientOptions *opts, const ch= ar *name, > > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 NetClientState *peer) > > =A0{ > > - =A0 =A0return net_vhost_user_init(peer, "vhost_user", 0, 0, 0); > > + =A0 =A0const NetdevVhostUserOptions *vhost_user_opts; > > + =A0 =A0CharDriverState *chr; > > + =A0 =A0bool vhostforce; > > + > > + =A0 =A0assert(opts->kind =3D=3D NET_CLIENT_OPTIONS_KIND_VHOST_U= SER); > > + =A0 =A0vhost_user_opts =3D opts->vhost_user; > > + > > + =A0 =A0chr =3D net_vhost_parse_chardev(vhost_user_opts); > > + =A0 =A0if (!chr) { > > + =A0 =A0 =A0 =A0error_report("No suitable chardev found\n"); > > + =A0 =A0 =A0 =A0return -1; > > + =A0 =A0} > > + > > + =A0 =A0/* verify net frontend */ > > + =A0 =A0if (qemu_opts_foreach(qemu_find_opts("device"), net_vhos= t_check_net, > > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0(void *)name= , true) =3D=3D -1) { > > + =A0 =A0 =A0 =A0return -1; > > + =A0 =A0} > > + > > + =A0 =A0/* vhostforce for non-MSIX */ > > + =A0 =A0if (vhost_user_opts->has_vhostforce) { > > + =A0 =A0 =A0 =A0vhostforce =3D vhost_user_opts->vhostforce; > > + =A0 =A0} else { > > + =A0 =A0 =A0 =A0vhostforce =3D false; > > + =A0 =A0} > > + > > + =A0 =A0return net_vhost_user_init(peer, "vhost_user", name, chr= , > vhostforce); > > =A0} > > diff --git a/qapi-schema.json b/qapi-schema.json > > index 1f28177..f458dd8 100644 > > --- a/qapi-schema.json > > +++ b/qapi-schema.json > > @@ -3264,6 +3264,22 @@ > > =A0 =A0 =A0'*devname': =A0 =A0'str' } } > > > > =A0## > > +# @NetdevVhostUserOptions > > +# > > +# Vhost-user network backend > > +# > > +# @path: control socket path > > +# > > +# @vhostforce: #optional vhost on for non-MSIX virtio guests (de= fault: > false). > > +# > > +# Since 2.1 > > +## > > +{ 'type': 'NetdevVhostUserOptions', > > + =A0'data': { > > + =A0 =A0'chardev': =A0 =A0 =A0 =A0'str', >=20 > chardev or path? >=20 > Right, it's chardev. >=20 >=20 > > + =A0 =A0'*vhostforce': =A0 =A0'bool' } } > > + > > +## > > =A0# @NetClientOptions > > =A0# > > =A0# A discriminated record of network device traits. > > @@ -3281,7 +3297,8 @@ > > =A0 =A0 =A0'dump': =A0 =A0 'NetdevDumpOptions', > > =A0 =A0 =A0'bridge': =A0 'NetdevBridgeOptions', > > =A0 =A0 =A0'hubport': =A0'NetdevHubPortOptions', > > - =A0 =A0'netmap': =A0 'NetdevNetmapOptions' } } > > + =A0 =A0'netmap': =A0 'NetdevNetmapOptions', > > + =A0 =A0'vhost-user': 'NetdevVhostUserOptions' } } > > > > =A0## > > =A0# @NetLegacy > > diff --git a/qemu-options.hx b/qemu-options.hx > > index 7f4ab83..2514264 100644 > > --- a/qemu-options.hx > > +++ b/qemu-options.hx > > @@ -1459,6 +1459,7 @@ DEF("netdev", HAS_ARG, QEMU_OPTION_netdev, > > =A0#ifdef CONFIG_NETMAP > > =A0 =A0 =A0"netmap|" > > =A0#endif > > + =A0 =A0"vhost-user|" > > =A0 =A0 =A0"socket|" > > =A0 =A0 =A0"hubport],id=3Dstr[,option][,option][,...]\n", QEMU_AR= CH_ALL) > > =A0STEXI > > @@ -1790,6 +1791,23 @@ The hubport netdev lets you connect a NIC = to a > QEMU "vlan" instead of a single > > =A0netdev. =A0@code{-net} and @code{-device} with parameter @opti= on{vlan} > create the > > =A0required hub automatically. > > > > +@item -netdev vhost-user,chardev=3D@var{id}[,vhostforce=3Don|off= ] > > + > > +Establish a vhost-user netdev, backed by a chardev @var{id}. The= chardev > should > > +be a unix domain socket backed one. The vhost-user uses a specif= ically > defined > > +protocol to pass vhost ioctl replacement messages to an applicat= ion on > the other > > +end of the socket. On non-MSIX guests, the feature can be forced= with > > +@var{vhostforce}. > > + > > +Example: > > +@example > > +qemu -m 512 -object memory-file,id=3Dmem,size=3D512M,mem-path=3D= / > hugetlbfs,share=3Don \ > > + =A0 =A0 -numa node,memdev=3Dmem \ > > + =A0 =A0 -chardev socket,path=3D/path/to/socket \ > > + =A0 =A0 -netdev type=3Dvhost-user,id=3Dnet0,chardev=3Dchr0 \ > > + =A0 =A0 -device virtio-net-pci,netdev=3Dnet0 > > +@end example > > + > > =A0@item -net dump[,vlan=3D@var{n}][,file=3D@var{file}][,len=3D@v= ar{len}] > > =A0Dump network traffic on VLAN @var{n} to file @var{file} (@file > {qemu-vlan0.pcap} by default). > > =A0At most @var{len} bytes (64k by default) per packet are stored= . The file > format is > > > > >=20 > -- > You received this message because you are subscribed to the Google = Groups > "Snabb Switch development" group. > To unsubscribe from this group and stop receiving emails from it, s= end an > email to snabb-devel+unsubscribe@googlegroups.com. > To post to this group, send an email to snabb-devel@googlegroups.co= m. > Visit this group at http://groups.google.com/group/snabb-devel. >=20 >=20 > regards, > Nikolay Nikolaev Pls remember to base on top of vhost branch in my tree, this way you will not need to re-post merged patches. If you want me to drop some merged patch from my tree, include a revert and I'll figure it out. --=20 MST