From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41734) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aOF7i-0000Px-5W for qemu-devel@nongnu.org; Tue, 26 Jan 2016 20:42:19 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aOF7d-0007sy-1T for qemu-devel@nongnu.org; Tue, 26 Jan 2016 20:42:18 -0500 Received: from [59.151.112.132] (port=8034 helo=heian.cn.fujitsu.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aOF7c-0007sM-4U for qemu-devel@nongnu.org; Tue, 26 Jan 2016 20:42:12 -0500 References: <1453798787-7453-1-git-send-email-zhangchen.fnst@cn.fujitsu.com> <56A77F1D.4040004@easystack.cn> <20160126194623.GG2426@work-vm> From: Zhang Chen Message-ID: <56A82086.9090306@cn.fujitsu.com> Date: Wed, 27 Jan 2016 09:42:30 +0800 MIME-Version: 1.0 In-Reply-To: <20160126194623.GG2426@work-vm> Content-Type: text/plain; charset="utf-8"; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH] net/traffic-mirrorer:Add traffic-mirroer List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: "Dr. David Alan Gilbert" , Yang Hongyang Cc: zhanghailiang , Li Zhijian , Gui jianfeng , Jason Wang , "eddie.dong" , qemu devel On 01/27/2016 03:46 AM, Dr. David Alan Gilbert wrote: > * Yang Hongyang (hongyang.yang@easystack.cn) wrote: >> >> On 01/26/2016 04:59 PM, Zhang Chen wrote: >>> From: ZhangChen >>> >>> Traffic-mirrorer is a plugin of netfilter. >> netfilter plugin fix >>> It make qemu has ability to copy and mirror guest's >> s/make/makes/ has the ability > Not quite. > 'It gives qemu the ability to...' > > (Sorry, I can't explain why!). I will fix it in next version. >>> net packet. we output packet to chardev. >> there seems no 'mirrorer' in english, I think the plugin name >> 'traffic-mirror' is enough. > Agreed. I will fix it in next version. Thanks for review~~ zhangchen > Dave > >>> usage: >>> >>> -netdev tap,id=hn0 >>> -chardev socket,id=mirrorer0,host=ip_primary,port=X,server,nowait >>> -traffic-mirrorer,id=m0,netdev=hn0,queue=tx,outdev=mirrorer0 >>> >>> Signed-off-by: ZhangChen >>> Signed-off-by: Wen Congyang >> The code looks good overall, so: >> Reviewed-by: Yang Hongyang Thank you Yang~~~ >>> --- >>> net/Makefile.objs | 1 + >>> net/traffic-mirrorer.c | 173 +++++++++++++++++++++++++++++++++++++++++++++++++ >>> qemu-options.hx | 5 ++ >>> vl.c | 3 +- >>> 4 files changed, 181 insertions(+), 1 deletion(-) >>> create mode 100644 net/traffic-mirrorer.c >>> >>> diff --git a/net/Makefile.objs b/net/Makefile.objs >>> index 5fa2f97..6466764 100644 >>> --- a/net/Makefile.objs >>> +++ b/net/Makefile.objs >>> @@ -15,3 +15,4 @@ common-obj-$(CONFIG_VDE) += vde.o >>> common-obj-$(CONFIG_NETMAP) += netmap.o >>> common-obj-y += filter.o >>> common-obj-y += filter-buffer.o >>> +common-obj-y += traffic-mirrorer.o >>> diff --git a/net/traffic-mirrorer.c b/net/traffic-mirrorer.c >>> new file mode 100644 >>> index 0000000..3b0da82 >>> --- /dev/null >>> +++ b/net/traffic-mirrorer.c >>> @@ -0,0 +1,173 @@ >>> +/* >>> + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD. >>> + * Copyright (c) 2016 FUJITSU LIMITED >>> + * Copyright (c) 2016 Intel Corporation >>> + * >>> + * Author: Zhang Chen >>> + * >>> + * This work is licensed under the terms of the GNU GPL, version 2 or >>> + * later. See the COPYING file in the top-level directory. >>> + */ >>> + >>> +#include "net/filter.h" >>> +#include "net/net.h" >>> +#include "qemu-common.h" >>> +#include "qapi/qmp/qerror.h" >>> +#include "qapi-visit.h" >>> +#include "qom/object.h" >>> +#include "qemu/main-loop.h" >>> +#include "qemu/error-report.h" >>> +#include "trace.h" >>> +#include "sysemu/char.h" >>> +#include "qemu/iov.h" >>> + >>> +#define FILTER_TRAFFIC_MIRRORER(obj) \ >>> + OBJECT_CHECK(MirrorerState, (obj), TYPE_FILTER_TRAFFIC_MIRRORER) >>> + >>> +#define TYPE_FILTER_TRAFFIC_MIRRORER "traffic-mirrorer" >>> + >>> +typedef struct MirrorerState { >>> + NetFilterState parent_obj; >>> + char *outdev; >>> + CharDriverState *chr_out; >>> + >>> +} MirrorerState; >>> + >>> +static ssize_t traffic_mirrorer_send(NetFilterState *nf, >>> + const struct iovec *iov, >>> + int iovcnt) >>> +{ >>> + MirrorerState *s = FILTER_TRAFFIC_MIRRORER(nf); >>> + ssize_t ret = 0; >>> + ssize_t size = 0; >>> + char *buf; >>> + >>> + size = iov_size(iov, iovcnt); >>> + if (!size) { >>> + return 0; >>> + } >>> + >>> + buf = g_malloc0(size); >>> + iov_to_buf(iov, iovcnt, 0, buf, size); >>> + ret = qemu_chr_fe_write(s->chr_out, (uint8_t *)&size, sizeof(size)); >>> + if (ret < 0) { >>> + g_free(buf); >>> + return ret; >>> + } >>> + >>> + ret = qemu_chr_fe_write(s->chr_out, (uint8_t *)buf, size); >>> + g_free(buf); >>> + return ret; >>> +} >>> + >>> +static ssize_t traffic_mirrorer_receive_iov(NetFilterState *nf, >>> + NetClientState *sender, >>> + unsigned flags, >>> + const struct iovec *iov, >>> + int iovcnt, >>> + NetPacketSent *sent_cb) >>> +{ >>> + /* >>> + * We copy and mirror packet to outdev, >>> + * then put back the packet. >>> + */ >>> + ssize_t ret = 0; >>> + >>> + ret = traffic_mirrorer_send(nf, iov, iovcnt); >>> + if (ret < 0) { >>> + error_report("traffic_mirrorer_send failed"); >>> + } >>> + >>> + return 0; >>> +} >>> + >>> +static void traffic_mirrorer_cleanup(NetFilterState *nf) >>> +{ >>> + MirrorerState *s = FILTER_TRAFFIC_MIRRORER(nf); >>> + >>> + if (s->chr_out) { >>> + qemu_chr_fe_release(s->chr_out); >>> + } >>> +} >>> + >>> +static void traffic_mirrorer_setup(NetFilterState *nf, Error **errp) >>> +{ >>> + MirrorerState *s = FILTER_TRAFFIC_MIRRORER(nf); >>> + >>> + if (!s->outdev) { >>> + error_setg(errp, "filter traffic mirrorer needs 'outdev' property set!" >>> + "property set!"); >>> + return; >>> + } >>> + >>> + s->chr_out = qemu_chr_find(s->outdev); >>> + if (s->chr_out == NULL) { >>> + error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, >>> + "Device '%s' not found", s->outdev); >>> + return; >>> + } >>> + >>> + if (qemu_chr_fe_claim(s->chr_out) != 0) { >>> + error_setg(errp, QERR_DEVICE_IN_USE, s->outdev); >>> + return; >>> + } >>> +} >>> + >>> +static void traffic_mirrorer_class_init(ObjectClass *oc, void *data) >>> +{ >>> + NetFilterClass *nfc = NETFILTER_CLASS(oc); >>> + >>> + nfc->setup = traffic_mirrorer_setup; >>> + nfc->cleanup = traffic_mirrorer_cleanup; >>> + nfc->receive_iov = traffic_mirrorer_receive_iov; >>> +} >>> + >>> +static char *traffic_mirrorer_get_outdev(Object *obj, Error **errp) >>> +{ >>> + MirrorerState *s = FILTER_TRAFFIC_MIRRORER(obj); >>> + >>> + return g_strdup(s->outdev); >>> +} >>> + >>> +static void >>> +traffic_mirrorer_set_outdev(Object *obj, const char *value, Error **errp) >>> +{ >>> + MirrorerState *s = FILTER_TRAFFIC_MIRRORER(obj); >>> + >>> + g_free(s->outdev); >>> + s->outdev = g_strdup(value); >>> + if (!s->outdev) { >>> + error_setg(errp, "filter traffic mirrorer needs 'outdev' " >>> + "property set!"); >>> + return; >>> + } >>> +} >>> + >>> +static void traffic_mirrorer_init(Object *obj) >>> +{ >>> + object_property_add_str(obj, "outdev", traffic_mirrorer_get_outdev, >>> + traffic_mirrorer_set_outdev, NULL); >>> +} >>> + >>> +static void traffic_mirrorer_fini(Object *obj) >>> +{ >>> + MirrorerState *s = FILTER_TRAFFIC_MIRRORER(obj); >>> + >>> + g_free(s->outdev); >>> +} >>> + >>> +static const TypeInfo traffic_mirrorer_info = { >>> + .name = TYPE_FILTER_TRAFFIC_MIRRORER, >>> + .parent = TYPE_NETFILTER, >>> + .class_init = traffic_mirrorer_class_init, >>> + .instance_init = traffic_mirrorer_init, >>> + .instance_finalize = traffic_mirrorer_fini, >>> + .instance_size = sizeof(MirrorerState), >>> +}; >>> + >>> +static void register_types(void) >>> +{ >>> + type_register_static(&traffic_mirrorer_info); >>> +} >>> + >>> +type_init(register_types); >>> diff --git a/qemu-options.hx b/qemu-options.hx >>> index 0eea4ee..ecfa297 100644 >>> --- a/qemu-options.hx >>> +++ b/qemu-options.hx >>> @@ -3670,6 +3670,11 @@ queue @var{all|rx|tx} is an option that can be applied to any netfilter. >>> @option{tx}: the filter is attached to the transmit queue of the netdev, >>> where it will receive packets sent by the netdev. >>> >>> +@item -object traffic-mirrorer,id=@var{id},netdev=@var{netdevid},outdev=@var{chardevid}[,queue=@var{all|rx|tx}] >>> + >>> +traffic-mirrorer on netdev @var{netdevid},mirror net packet to outdev. >>> +queue @var{all|rx|tx} is an option that can be applied to traffic-mirrorer. >>> + >>> @item -object filter-dump,id=@var{id},netdev=@var{dev},file=@var{filename}][,maxlen=@var{len}] >>> >>> Dump the network traffic on netdev @var{dev} to the file specified by >>> diff --git a/vl.c b/vl.c >>> index 8dc34ce..4fe01bc 100644 >>> --- a/vl.c >>> +++ b/vl.c >>> @@ -2838,7 +2838,8 @@ static bool object_create_initial(const char *type) >>> * they depend on netdevs already existing >>> */ >>> if (g_str_equal(type, "filter-buffer") || >>> - g_str_equal(type, "filter-dump")) { >>> + g_str_equal(type, "filter-dump") || >>> + g_str_equal(type, "traffic-mirrorer")) { >>> return false; >>> } >>> >>> >> -- >> Thanks, >> Yang > -- > Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK > > > . > -- Thanks zhangchen