From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48839) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dDltU-0006xX-8m for qemu-devel@nongnu.org; Thu, 25 May 2017 02:05:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dDltP-0002sv-EM for qemu-devel@nongnu.org; Thu, 25 May 2017 02:05:08 -0400 Received: from mx1.redhat.com ([209.132.183.28]:55708) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dDltP-0002rk-6I for qemu-devel@nongnu.org; Thu, 25 May 2017 02:05:03 -0400 References: <1495549241-23380-1-git-send-email-zhangchen.fnst@cn.fujitsu.com> <1495549241-23380-3-git-send-email-zhangchen.fnst@cn.fujitsu.com> From: Jason Wang Message-ID: <838b8626-c5e4-86d5-a318-ab957bc9bcbe@redhat.com> Date: Thu, 25 May 2017 14:04:55 +0800 MIME-Version: 1.0 In-Reply-To: <1495549241-23380-3-git-send-email-zhangchen.fnst@cn.fujitsu.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [PATCH V5 2/9] net/filter-mirror.c: Make filter mirror support vnet support. List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Zhang Chen , qemu devel Cc: zhanghailiang , weifuqiang , "eddie . dong" , bian naimeng , Li Zhijian On 2017=E5=B9=B405=E6=9C=8823=E6=97=A5 22:20, Zhang Chen wrote: > We add the vnet_hdr option for filter-mirror, default is disable. > If you use virtio-net-pci net driver, please enable it. > You can use it for example: > -object filter-mirror,id=3Dm0,netdev=3Dhn0,queue=3Dtx,outdev=3Dmirror0,= vnet_hdr=3Don > > If vnet_hdr=3Don we change the send packet format from > struct {int size; const uint8_t buf[];} to {int size; int vnet_hdr_len;= const uint8_t buf[];}. > make other module(like colo-compare) know how to parse net packet corre= ctly. > > Signed-off-by: Zhang Chen > --- > net/filter-mirror.c | 73 ++++++++++++++++++++++++++++++++++++++++++++= +++++---- > qemu-options.hx | 5 ++-- > 2 files changed, 70 insertions(+), 8 deletions(-) > > diff --git a/net/filter-mirror.c b/net/filter-mirror.c > index 72fa7c2..8df0be6 100644 > --- a/net/filter-mirror.c > +++ b/net/filter-mirror.c > @@ -38,15 +38,17 @@ typedef struct MirrorState { > NetFilterState parent_obj; > char *indev; > char *outdev; > + bool vnet_hdr; > CharBackend chr_in; > CharBackend chr_out; > SocketReadState rs; > } MirrorState; > =20 > -static int filter_mirror_send(CharBackend *chr_out, > +static int filter_mirror_send(MirrorState *s, > const struct iovec *iov, > int iovcnt) > { > + NetFilterState *nf =3D NETFILTER(s); > int ret =3D 0; > ssize_t size =3D 0; > uint32_t len =3D 0; > @@ -58,14 +60,42 @@ static int filter_mirror_send(CharBackend *chr_out, > } > =20 > len =3D htonl(size); > - ret =3D qemu_chr_fe_write_all(chr_out, (uint8_t *)&len, sizeof(len= )); > + ret =3D qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof= (len)); > if (ret !=3D sizeof(len)) { > goto err; > } > =20 > + if (s->vnet_hdr) { > + /* > + * If vnet_hdr =3D on, we send vnet header len to make other > + * module(like colo-compare) know how to parse net > + * packet correctly. > + */ > + ssize_t vnet_hdr_len; > + > + /* > + * In anytime, nf->netdev and nf->netdev->peer both have a vne= t_hdr_len, > + * Here we just find out which is we need. When filter set RX = or TX > + * that the real vnet_hdr_len are different. > + */ > + if (nf->netdev->using_vnet_hdr) { > + vnet_hdr_len =3D nf->netdev->vnet_hdr_len; > + } else if (nf->netdev->peer->using_vnet_hdr) { > + vnet_hdr_len =3D nf->netdev->peer->vnet_hdr_len; Rethink about this, looks like what we really want is: - For tx direction, only check nf->netdev->vnet_hdr_len, - For rx direction, only check nf->netdev->peer->vnet_hdr_len Thanks > + } else { > + return 0; > + } > + > + len =3D htonl(vnet_hdr_len); > + ret =3D qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, si= zeof(len)); > + if (ret !=3D sizeof(len)) { > + goto err; > + } > + } > + > buf =3D g_malloc(size); > iov_to_buf(iov, iovcnt, 0, buf, size); > - ret =3D qemu_chr_fe_write_all(chr_out, (uint8_t *)buf, size); > + ret =3D qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)buf, size); > g_free(buf); > if (ret !=3D size) { > goto err; > @@ -141,7 +171,7 @@ static ssize_t filter_mirror_receive_iov(NetFilterS= tate *nf, > MirrorState *s =3D FILTER_MIRROR(nf); > int ret; > =20 > - ret =3D filter_mirror_send(&s->chr_out, iov, iovcnt); > + ret =3D filter_mirror_send(s, iov, iovcnt); > if (ret) { > error_report("filter_mirror_send failed(%s)", strerror(-ret))= ; > } > @@ -164,7 +194,7 @@ static ssize_t filter_redirector_receive_iov(NetFil= terState *nf, > int ret; > =20 > if (qemu_chr_fe_get_driver(&s->chr_out)) { > - ret =3D filter_mirror_send(&s->chr_out, iov, iovcnt); > + ret =3D filter_mirror_send(s, iov, iovcnt); > if (ret) { > error_report("filter_mirror_send failed(%s)", strerror(-r= et)); > } > @@ -308,6 +338,13 @@ static char *filter_mirror_get_outdev(Object *obj,= Error **errp) > return g_strdup(s->outdev); > } > =20 > +static char *filter_mirror_get_vnet_hdr(Object *obj, Error **errp) > +{ > + MirrorState *s =3D FILTER_MIRROR(obj); > + > + return s->vnet_hdr ? g_strdup("on") : g_strdup("off"); > +} > + > static void > filter_mirror_set_outdev(Object *obj, const char *value, Error **errp= ) > { > @@ -322,6 +359,21 @@ filter_mirror_set_outdev(Object *obj, const char *= value, Error **errp) > } > } > =20 > +static void filter_mirror_set_vnet_hdr(Object *obj, > + const char *value, > + Error **errp) > +{ > + MirrorState *s =3D FILTER_MIRROR(obj); > + > + if (strcmp(value, "on") && strcmp(value, "off")) { > + error_setg(errp, "Invalid value for filter-mirror vnet_hdr, " > + "should be 'on' or 'off'"); > + return; > + } > + > + s->vnet_hdr =3D !strcmp(value, "on"); > +} > + > static char *filter_redirector_get_outdev(Object *obj, Error **errp) > { > MirrorState *s =3D FILTER_REDIRECTOR(obj); > @@ -340,8 +392,19 @@ filter_redirector_set_outdev(Object *obj, const ch= ar *value, Error **errp) > =20 > static void filter_mirror_init(Object *obj) > { > + MirrorState *s =3D FILTER_MIRROR(obj); > + > object_property_add_str(obj, "outdev", filter_mirror_get_outdev, > filter_mirror_set_outdev, NULL); > + > + /* > + * The vnet_hdr is disabled by default, if you want to enable > + * this option, you must enable all the option on related modules > + * (like other filter or colo-compare). > + */ > + s->vnet_hdr =3D false; > + object_property_add_str(obj, "vnet_hdr", filter_mirror_get_vnet_hd= r, > + filter_mirror_set_vnet_hdr, NULL); > } > =20 > static void filter_redirector_init(Object *obj) > diff --git a/qemu-options.hx b/qemu-options.hx > index 70c0ded..81fb96b 100644 > --- a/qemu-options.hx > +++ b/qemu-options.hx > @@ -4024,10 +4024,9 @@ queue @var{all|rx|tx} is an option that can be a= pplied to any netfilter. > @option{tx}: the filter is attached to the transmit queue of the netd= ev, > where it will receive packets sent by the netdev. > =20 > -@item -object filter-mirror,id=3D@var{id},netdev=3D@var{netdevid},outd= ev=3D@var{chardevid}[,queue=3D@var{all|rx|tx}] > +@item -object filter-mirror,id=3D@var{id},netdev=3D@var{netdevid},outd= ev=3D@var{chardevid},vnet_hdr=3D@var{on|off}[,queue=3D@var{all|rx|tx}] > =20 > -filter-mirror on netdev @var{netdevid},mirror net packet to chardev > -@var{chardevid} > +filter-mirror on netdev @var{netdevid},mirror net packet to chardev@va= r{chardevid}, if vnet_hdr =3D on, filter-mirror will mirror packet with v= net_hdr_len. > =20 > @item -object filter-redirector,id=3D@var{id},netdev=3D@var{netdevid}= ,indev=3D@var{chardevid}, > outdev=3D@var{chardevid}[,queue=3D@var{all|rx|tx}]