[Qemu-devel] [PATCH V8 1/2] net/filter-mirror:Add filter-mirror
Filter-mirror is a netfilter plugin. It gives qemu the ability to mirror packets to a chardev. usage: -netdev tap,id=hn0 -chardev socket,id=mirror0,host=ip_primary,port=X,server,nowait -filter-mirror,id=m0,netdev=hn0,queue=tx/rx/all,outdev=mirror0 Signed-off-by: Zhang ChenSigned-off-by: Wen Congyang Reviewed-by: Yang Hongyang Reviewed-by: zhanghailiang --- net/Makefile.objs | 1 + net/filter-mirror.c | 181 qemu-options.hx | 5 ++ vl.c| 3 +- 4 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 net/filter-mirror.c diff --git a/net/Makefile.objs b/net/Makefile.objs index 5fa2f97..b7c22fd 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 += filter-mirror.o diff --git a/net/filter-mirror.c b/net/filter-mirror.c new file mode 100644 index 000..ee13d94 --- /dev/null +++ b/net/filter-mirror.c @@ -0,0 +1,181 @@ +/* + * 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" +#include "qemu/sockets.h" + +#define FILTER_MIRROR(obj) \ +OBJECT_CHECK(MirrorState, (obj), TYPE_FILTER_MIRROR) + +#define TYPE_FILTER_MIRROR "filter-mirror" + +typedef struct MirrorState { +NetFilterState parent_obj; +char *outdev; +CharDriverState *chr_out; +} MirrorState; + +static int filter_mirror_send(NetFilterState *nf, + const struct iovec *iov, + int iovcnt) +{ +MirrorState *s = FILTER_MIRROR(nf); +int ret = 0; +ssize_t size = 0; +uint32_t len = 0; +char *buf; + +size = iov_size(iov, iovcnt); +if (!size) { +return 0; +} + +len = htonl(size); +ret = qemu_chr_fe_write_all(s->chr_out, (uint8_t *), sizeof(len)); +if (ret != sizeof(len)) { +goto err; +} + +buf = g_malloc(size); +iov_to_buf(iov, iovcnt, 0, buf, size); +ret = qemu_chr_fe_write_all(s->chr_out, (uint8_t *)buf, size); +g_free(buf); +if (ret != size) { +goto err; +} + +return 0; + +err: +return ret < 0 ? ret : -EIO; +} + +static ssize_t filter_mirror_receive_iov(NetFilterState *nf, + NetClientState *sender, + unsigned flags, + const struct iovec *iov, + int iovcnt, + NetPacketSent *sent_cb) +{ +int ret; + +ret = filter_mirror_send(nf, iov, iovcnt); +if (ret) { +error_report("filter_mirror_send failed(%s)", strerror(-ret)); +} + +/* + * we don't hope this error interrupt the normal + * path of net packet, so we always return zero. + */ +return 0; +} + +static void filter_mirror_cleanup(NetFilterState *nf) +{ +MirrorState *s = FILTER_MIRROR(nf); + +if (s->chr_out) { +qemu_chr_fe_release(s->chr_out); +} +} + +static void filter_mirror_setup(NetFilterState *nf, Error **errp) +{ +MirrorState *s = FILTER_MIRROR(nf); + +if (!s->outdev) { +error_setg(errp, "filter filter mirror needs 'outdev' " +"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 filter_mirror_class_init(ObjectClass *oc, void *data) +{ +NetFilterClass *nfc = NETFILTER_CLASS(oc); + +nfc->setup = filter_mirror_setup; +nfc->cleanup = filter_mirror_cleanup; +nfc->receive_iov = filter_mirror_receive_iov; +} + +static char *filter_mirror_get_outdev(Object *obj, Error **errp) +{ +MirrorState *s = FILTER_MIRROR(obj); + +return g_strdup(s->outdev); +} + +static void +filter_mirror_set_outdev(Object *obj, const char *value, Error **errp) +{ +MirrorState *s = FILTER_MIRROR(obj); + +g_free(s->outdev); +s->outdev = g_strdup(value); +if
Re: [Qemu-devel] [PATCH V8 1/2] net/filter-mirror:Add filter-mirror
On 03/09/2016 05:40 PM, Wen Congyang wrote: On 03/09/2016 05:07 PM, Zhang Chen wrote: Filter-mirror is a netfilter plugin. It gives qemu the ability to mirror packets to a chardev. usage: -netdev tap,id=hn0 -chardev socket,id=mirror0,host=ip_primary,port=X,server,nowait -filter-mirror,id=m0,netdev=hn0,queue=tx/rx/all,outdev=mirror0 Signed-off-by: Zhang ChenSigned-off-by: Wen Congyang Reviewed-by: Yang Hongyang Reviewed-by: zhanghailiang --- net/Makefile.objs | 1 + net/filter-mirror.c | 181 qemu-options.hx | 5 ++ vl.c| 3 +- 4 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 net/filter-mirror.c diff --git a/net/Makefile.objs b/net/Makefile.objs index 5fa2f97..b7c22fd 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 += filter-mirror.o diff --git a/net/filter-mirror.c b/net/filter-mirror.c new file mode 100644 index 000..ee13d94 --- /dev/null +++ b/net/filter-mirror.c @@ -0,0 +1,181 @@ +/* + * 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" +#include "qemu/sockets.h" + +#define FILTER_MIRROR(obj) \ +OBJECT_CHECK(MirrorState, (obj), TYPE_FILTER_MIRROR) + +#define TYPE_FILTER_MIRROR "filter-mirror" + +typedef struct MirrorState { +NetFilterState parent_obj; +char *outdev; +CharDriverState *chr_out; +} MirrorState; + +static int filter_mirror_send(NetFilterState *nf, + const struct iovec *iov, + int iovcnt) Please change the indent. Thanks fix it~~ Thanks Wen Congyang +{ +MirrorState *s = FILTER_MIRROR(nf); +int ret = 0; +ssize_t size = 0; +uint32_t len = 0; +char *buf; + +size = iov_size(iov, iovcnt); +if (!size) { +return 0; +} + +len = htonl(size); +ret = qemu_chr_fe_write_all(s->chr_out, (uint8_t *), sizeof(len)); +if (ret != sizeof(len)) { +goto err; +} + +buf = g_malloc(size); +iov_to_buf(iov, iovcnt, 0, buf, size); +ret = qemu_chr_fe_write_all(s->chr_out, (uint8_t *)buf, size); +g_free(buf); +if (ret != size) { +goto err; +} + +return 0; + +err: +return ret < 0 ? ret : -EIO; +} + +static ssize_t filter_mirror_receive_iov(NetFilterState *nf, + NetClientState *sender, + unsigned flags, + const struct iovec *iov, + int iovcnt, + NetPacketSent *sent_cb) +{ +int ret; + +ret = filter_mirror_send(nf, iov, iovcnt); +if (ret) { +error_report("filter_mirror_send failed(%s)", strerror(-ret)); +} + +/* + * we don't hope this error interrupt the normal + * path of net packet, so we always return zero. + */ +return 0; +} + +static void filter_mirror_cleanup(NetFilterState *nf) +{ +MirrorState *s = FILTER_MIRROR(nf); + +if (s->chr_out) { +qemu_chr_fe_release(s->chr_out); +} +} + +static void filter_mirror_setup(NetFilterState *nf, Error **errp) +{ +MirrorState *s = FILTER_MIRROR(nf); + +if (!s->outdev) { +error_setg(errp, "filter filter mirror needs 'outdev' " +"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 filter_mirror_class_init(ObjectClass *oc, void *data) +{ +NetFilterClass *nfc = NETFILTER_CLASS(oc); + +nfc->setup = filter_mirror_setup; +nfc->cleanup = filter_mirror_cleanup; +nfc->receive_iov = filter_mirror_receive_iov; +} + +static char *filter_mirror_get_outdev(Object *obj, Error **errp) +{ +MirrorState *s = FILTER_MIRROR(obj); + +return g_strdup(s->outdev); +} + +static void
Re: [Qemu-devel] [PATCH V8 1/2] net/filter-mirror:Add filter-mirror
On 03/09/2016 05:07 PM, Zhang Chen wrote: > Filter-mirror is a netfilter plugin. > It gives qemu the ability to mirror > packets to a chardev. > > usage: > > -netdev tap,id=hn0 > -chardev socket,id=mirror0,host=ip_primary,port=X,server,nowait > -filter-mirror,id=m0,netdev=hn0,queue=tx/rx/all,outdev=mirror0 > > Signed-off-by: Zhang Chen> Signed-off-by: Wen Congyang > Reviewed-by: Yang Hongyang > Reviewed-by: zhanghailiang > --- > net/Makefile.objs | 1 + > net/filter-mirror.c | 181 > > qemu-options.hx | 5 ++ > vl.c| 3 +- > 4 files changed, 189 insertions(+), 1 deletion(-) > create mode 100644 net/filter-mirror.c > > diff --git a/net/Makefile.objs b/net/Makefile.objs > index 5fa2f97..b7c22fd 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 += filter-mirror.o > diff --git a/net/filter-mirror.c b/net/filter-mirror.c > new file mode 100644 > index 000..ee13d94 > --- /dev/null > +++ b/net/filter-mirror.c > @@ -0,0 +1,181 @@ > +/* > + * 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" > +#include "qemu/sockets.h" > + > +#define FILTER_MIRROR(obj) \ > +OBJECT_CHECK(MirrorState, (obj), TYPE_FILTER_MIRROR) > + > +#define TYPE_FILTER_MIRROR "filter-mirror" > + > +typedef struct MirrorState { > +NetFilterState parent_obj; > +char *outdev; > +CharDriverState *chr_out; > +} MirrorState; > + > +static int filter_mirror_send(NetFilterState *nf, > + const struct iovec *iov, > + int iovcnt) Please change the indent. Thanks Wen Congyang > +{ > +MirrorState *s = FILTER_MIRROR(nf); > +int ret = 0; > +ssize_t size = 0; > +uint32_t len = 0; > +char *buf; > + > +size = iov_size(iov, iovcnt); > +if (!size) { > +return 0; > +} > + > +len = htonl(size); > +ret = qemu_chr_fe_write_all(s->chr_out, (uint8_t *), sizeof(len)); > +if (ret != sizeof(len)) { > +goto err; > +} > + > +buf = g_malloc(size); > +iov_to_buf(iov, iovcnt, 0, buf, size); > +ret = qemu_chr_fe_write_all(s->chr_out, (uint8_t *)buf, size); > +g_free(buf); > +if (ret != size) { > +goto err; > +} > + > +return 0; > + > +err: > +return ret < 0 ? ret : -EIO; > +} > + > +static ssize_t filter_mirror_receive_iov(NetFilterState *nf, > + NetClientState *sender, > + unsigned flags, > + const struct iovec *iov, > + int iovcnt, > + NetPacketSent *sent_cb) > +{ > +int ret; > + > +ret = filter_mirror_send(nf, iov, iovcnt); > +if (ret) { > +error_report("filter_mirror_send failed(%s)", strerror(-ret)); > +} > + > +/* > + * we don't hope this error interrupt the normal > + * path of net packet, so we always return zero. > + */ > +return 0; > +} > + > +static void filter_mirror_cleanup(NetFilterState *nf) > +{ > +MirrorState *s = FILTER_MIRROR(nf); > + > +if (s->chr_out) { > +qemu_chr_fe_release(s->chr_out); > +} > +} > + > +static void filter_mirror_setup(NetFilterState *nf, Error **errp) > +{ > +MirrorState *s = FILTER_MIRROR(nf); > + > +if (!s->outdev) { > +error_setg(errp, "filter filter mirror needs 'outdev' " > +"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 filter_mirror_class_init(ObjectClass *oc, void *data) > +{ > +NetFilterClass *nfc = NETFILTER_CLASS(oc); > + > +nfc->setup = filter_mirror_setup; > +nfc->cleanup =
[Qemu-devel] [PATCH V8 1/2] net/filter-mirror:Add filter-mirror
Filter-mirror is a netfilter plugin. It gives qemu the ability to mirror packets to a chardev. usage: -netdev tap,id=hn0 -chardev socket,id=mirror0,host=ip_primary,port=X,server,nowait -filter-mirror,id=m0,netdev=hn0,queue=tx/rx/all,outdev=mirror0 Signed-off-by: Zhang ChenSigned-off-by: Wen Congyang Reviewed-by: Yang Hongyang Reviewed-by: zhanghailiang --- net/Makefile.objs | 1 + net/filter-mirror.c | 181 qemu-options.hx | 5 ++ vl.c| 3 +- 4 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 net/filter-mirror.c diff --git a/net/Makefile.objs b/net/Makefile.objs index 5fa2f97..b7c22fd 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 += filter-mirror.o diff --git a/net/filter-mirror.c b/net/filter-mirror.c new file mode 100644 index 000..ee13d94 --- /dev/null +++ b/net/filter-mirror.c @@ -0,0 +1,181 @@ +/* + * 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" +#include "qemu/sockets.h" + +#define FILTER_MIRROR(obj) \ +OBJECT_CHECK(MirrorState, (obj), TYPE_FILTER_MIRROR) + +#define TYPE_FILTER_MIRROR "filter-mirror" + +typedef struct MirrorState { +NetFilterState parent_obj; +char *outdev; +CharDriverState *chr_out; +} MirrorState; + +static int filter_mirror_send(NetFilterState *nf, + const struct iovec *iov, + int iovcnt) +{ +MirrorState *s = FILTER_MIRROR(nf); +int ret = 0; +ssize_t size = 0; +uint32_t len = 0; +char *buf; + +size = iov_size(iov, iovcnt); +if (!size) { +return 0; +} + +len = htonl(size); +ret = qemu_chr_fe_write_all(s->chr_out, (uint8_t *), sizeof(len)); +if (ret != sizeof(len)) { +goto err; +} + +buf = g_malloc(size); +iov_to_buf(iov, iovcnt, 0, buf, size); +ret = qemu_chr_fe_write_all(s->chr_out, (uint8_t *)buf, size); +g_free(buf); +if (ret != size) { +goto err; +} + +return 0; + +err: +return ret < 0 ? ret : -EIO; +} + +static ssize_t filter_mirror_receive_iov(NetFilterState *nf, + NetClientState *sender, + unsigned flags, + const struct iovec *iov, + int iovcnt, + NetPacketSent *sent_cb) +{ +int ret; + +ret = filter_mirror_send(nf, iov, iovcnt); +if (ret) { +error_report("filter_mirror_send failed(%s)", strerror(-ret)); +} + +/* + * we don't hope this error interrupt the normal + * path of net packet, so we always return zero. + */ +return 0; +} + +static void filter_mirror_cleanup(NetFilterState *nf) +{ +MirrorState *s = FILTER_MIRROR(nf); + +if (s->chr_out) { +qemu_chr_fe_release(s->chr_out); +} +} + +static void filter_mirror_setup(NetFilterState *nf, Error **errp) +{ +MirrorState *s = FILTER_MIRROR(nf); + +if (!s->outdev) { +error_setg(errp, "filter filter mirror needs 'outdev' " +"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 filter_mirror_class_init(ObjectClass *oc, void *data) +{ +NetFilterClass *nfc = NETFILTER_CLASS(oc); + +nfc->setup = filter_mirror_setup; +nfc->cleanup = filter_mirror_cleanup; +nfc->receive_iov = filter_mirror_receive_iov; +} + +static char *filter_mirror_get_outdev(Object *obj, Error **errp) +{ +MirrorState *s = FILTER_MIRROR(obj); + +return g_strdup(s->outdev); +} + +static void +filter_mirror_set_outdev(Object *obj, const char *value, Error **errp) +{ +MirrorState *s = FILTER_MIRROR(obj); + +g_free(s->outdev); +s->outdev = g_strdup(value); +if