[Qemu-devel] [PATCH V8 1/2] net/filter-mirror:Add filter-mirror

2016-03-09 Thread Zhang Chen
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)
+{
+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

2016-03-09 Thread Zhang Chen



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 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
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

2016-03-09 Thread Wen Congyang
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

2016-03-09 Thread Zhang Chen
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)
+{
+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