From: Yang Hongyang <hongyang.yang@easystack.cn>
To: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>,
qemu devel <qemu-devel@nongnu.org>,
Jason Wang <jasowang@redhat.com>
Cc: Gui jianfeng <guijianfeng@cn.fujitsu.com>,
"eddie.dong" <eddie.dong@intel.com>,
"Dr. David Alan Gilbert" <dgilbert@redhat.com>,
Li Zhijian <lizhijian@cn.fujitsu.com>,
zhanghailiang <zhang.zhanghailiang@huawei.com>
Subject: Re: [Qemu-devel] [PATCH] net/traffic-mirrorer:Add traffic-mirroer
Date: Tue, 26 Jan 2016 22:13:49 +0800 [thread overview]
Message-ID: <56A77F1D.4040004@easystack.cn> (raw)
In-Reply-To: <1453798787-7453-1-git-send-email-zhangchen.fnst@cn.fujitsu.com>
On 01/26/2016 04:59 PM, Zhang Chen wrote:
> From: ZhangChen <zhangchen.fnst@cn.fujitsu.com>
>
> Traffic-mirrorer is a plugin of netfilter.
netfilter plugin
> It make qemu has ability to copy and mirror guest's
s/make/makes/ has the ability
> net packet. we output packet to chardev.
there seems no 'mirrorer' in english, I think the plugin name
'traffic-mirror' is enough.
>
> 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 <zhangchen.fnst@cn.fujitsu.com>
> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
The code looks good overall, so:
Reviewed-by: Yang Hongyang <hongyang.yang@easystack.cn>
> ---
> 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 <zhangchen.fnst@cn.fujitsu.com>
> + *
> + * 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
next prev parent reply other threads:[~2016-01-26 14:14 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-26 8:59 [Qemu-devel] [PATCH] net/traffic-mirrorer:Add traffic-mirroer Zhang Chen
2016-01-26 14:13 ` Yang Hongyang [this message]
2016-01-26 19:46 ` Dr. David Alan Gilbert
2016-01-27 1:42 ` Zhang Chen
2016-01-27 0:44 ` Hailiang Zhang
2016-01-27 1:32 ` Zhang Chen
2016-01-27 16:10 ` Eric Blake
2016-01-28 1:22 ` Zhang Chen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=56A77F1D.4040004@easystack.cn \
--to=hongyang.yang@easystack.cn \
--cc=dgilbert@redhat.com \
--cc=eddie.dong@intel.com \
--cc=guijianfeng@cn.fujitsu.com \
--cc=jasowang@redhat.com \
--cc=lizhijian@cn.fujitsu.com \
--cc=qemu-devel@nongnu.org \
--cc=zhang.zhanghailiang@huawei.com \
--cc=zhangchen.fnst@cn.fujitsu.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.