Re: [Qemu-devel] [PATCH] net/filter-redirector:Add filter-redirector

2016-03-01 Thread Jason Wang


On 02/29/2016 08:33 PM, Zhang Chen wrote:
>
>
> On 02/29/2016 03:11 PM, Jason Wang wrote:
>>
>> On 02/24/2016 05:03 PM, Zhang Chen wrote:
>>> If queue=rx, filter-redirector will get the packet that guest send,
>>> then redirect
>>> to outdev(if none, do nothing). but queue=rx/tx/all not related to
>>> indev. please
>>> look the flow chart below. queue=xxx just work for one
>>> way(filter->outdev).
>>>
>>>filter
>>>  +
>>>  |
>>>  |
>>> redirector   |
>>>  +-+
>>>  |   | |
>>>  |   | |
>>>  |   | |
>>> indev ++ +>  outdev
>>>  | |   |
>>>  | |   |
>>>  | |   |
>>>  +-+
>>>|
>>>|
>>>v
>>> filter
>>>
>>>|
>>>
>>>|
>>>
>>>v
>>> filter  filter .. guest
>>>
>> This looks a violation on the assumption of current filter behavior.
>> Each filter should only talk to the 'next' or 'prev' filter on the chain
>> (depends on the direction) or netdev when queue=rx or netdev's peer when
>> queue=tx.
>>
>> And in fact there's subtle differences with your patch:
>>
>> When queue='all' since you force nf->netdev as sender, direction is
>> NET_FILTER_DIRECTION_TX, the packet will be passed to 'next' filter on
>> the chain.
>> When queue='rx', direction is NET_FILTER_DIRECTION_RX, the packet will
>> be pass to 'prev' filter on the chain.
>>
>> So as you can see, 'all' is ambiguous here. I think we should keep
>> current behavior by redirecting traffic to netdev when queue='rx'. For
>> queue='all', maybe we need redirect the traffic to both netdev and
>> netdev's peer.
>>
>>
>
> OK, I will change usage to :
>
> -filter-redirector,id=r0,netdev=hn0,queue=tx/rx/all,outdev=s1,indev=s0,in_direction=tx/rx
>
> How about this?

Looks like in_direction complicates the issue and is unnecessary. In
fact, it could be achieved by having another redirector.

>
> I will fix it in V3.
>
> Thanks
> zhangchen 




Re: [Qemu-devel] [PATCH] net/filter-redirector:Add filter-redirector

2016-02-29 Thread Zhang Chen



On 02/29/2016 03:11 PM, Jason Wang wrote:


On 02/24/2016 05:03 PM, Zhang Chen wrote:

If queue=rx, filter-redirector will get the packet that guest send,
then redirect
to outdev(if none, do nothing). but queue=rx/tx/all not related to
indev. please
look the flow chart below. queue=xxx just work for one
way(filter->outdev).

   filter
 +
 |
 |
redirector   |
 +-+
 |   | |
 |   | |
 |   | |
indev ++ +>  outdev
 | |   |
 | |   |
 | |   |
 +-+
   |
   |
   v
filter

   |

   |

   v
filter  filter .. guest


This looks a violation on the assumption of current filter behavior.
Each filter should only talk to the 'next' or 'prev' filter on the chain
(depends on the direction) or netdev when queue=rx or netdev's peer when
queue=tx.

And in fact there's subtle differences with your patch:

When queue='all' since you force nf->netdev as sender, direction is
NET_FILTER_DIRECTION_TX, the packet will be passed to 'next' filter on
the chain.
When queue='rx', direction is NET_FILTER_DIRECTION_RX, the packet will
be pass to 'prev' filter on the chain.

So as you can see, 'all' is ambiguous here. I think we should keep
current behavior by redirecting traffic to netdev when queue='rx'. For
queue='all', maybe we need redirect the traffic to both netdev and
netdev's peer.




OK, I will change usage to :

-filter-redirector,id=r0,netdev=hn0,queue=tx/rx/all,outdev=s1,indev=s0,in_direction=tx/rx
How about this?

I will fix it in V3.

Thanks
zhangchen




.



--
Thanks
zhangchen






Re: [Qemu-devel] [PATCH] net/filter-redirector:Add filter-redirector

2016-02-28 Thread Jason Wang


On 02/24/2016 05:03 PM, Zhang Chen wrote:
>
> If queue=rx, filter-redirector will get the packet that guest send,
> then redirect
> to outdev(if none, do nothing). but queue=rx/tx/all not related to
> indev. please
> look the flow chart below. queue=xxx just work for one
> way(filter->outdev).
>
>   filter
> +
> |
> |
>redirector   |
> +-+
> |   | |
> |   | |
> |   | |
>indev ++ +>  outdev
> | |   |
> | |   |
> | |   |
> +-+
>   |
>   |
>   v
>filter
>
>   |
>
>   |
>
>   v
>filter  filter .. guest
>

This looks a violation on the assumption of current filter behavior. 
Each filter should only talk to the 'next' or 'prev' filter on the chain
(depends on the direction) or netdev when queue=rx or netdev's peer when
queue=tx.

And in fact there's subtle differences with your patch:

When queue='all' since you force nf->netdev as sender, direction is
NET_FILTER_DIRECTION_TX, the packet will be passed to 'next' filter on
the chain.
When queue='rx', direction is NET_FILTER_DIRECTION_RX, the packet will
be pass to 'prev' filter on the chain.

So as you can see, 'all' is ambiguous here. I think we should keep
current behavior by redirecting traffic to netdev when queue='rx'. For
queue='all', maybe we need redirect the traffic to both netdev and
netdev's peer.






Re: [Qemu-devel] [PATCH] net/filter-redirector:Add filter-redirector

2016-02-24 Thread Zhang Chen



On 02/24/2016 11:39 AM, Jason Wang wrote:


On 02/18/2016 03:50 PM, Zhang Chen wrote:


On 02/18/2016 10:41 AM, Jason Wang wrote:

On 02/05/2016 02:50 PM, Zhang Chen wrote:

From: ZhangChen 

Filter-redirector is a netfilter plugin.
It gives qemu the ability to redirect net packet.
redirector can redirect filter's net packet to outdev.
and redirect indev's packet to filter.

   filter
 +
 |
 |
redirector   |
 +-+
 |   | |
 |   | |
 |   | |
indev ++ +>  outdev
 | |   |
 | |   |
 | |   |
 +-+
   |
   |
   v
filter

   v

change it to   filter  filter .. guest
It's may more clearly expressed.


usage:

-netdev tap,id=hn0
-chardev socket,id=s0,host=ip_primary,port=X,server,nowait
-chardev socket,id=s1,host=ip_primary,port=Y,server,nowait
-filter-redirector,id=r0,netdev=hn0,queue=tx/rx/all,indev=s0,outdev=s1

Signed-off-by: ZhangChen 
Signed-off-by: Wen Congyang 
---

Thanks a lot for the patch. Like mirror, let's design a unit-test for
this. And what's more, is there any chance to unify the codes? (At least
parts of the codes could be reused).

We can make filter-redirector based on filter-mirror.
if you want to use redirector ,you must open mirror before.
like this:

-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,redirector=on,outdev=mirror0

-filter-redirector,id=r0,netdev=hn0,queue=tx/rx/all,indev=s0

How about this?

This looks like a burden for user who just want to use redirector. Maybe
we can do :

- Still two type of filters but sharing a single state.
- Using a internal flag to differ mirrors from redirectors?


Good idea~ I will change it in next version.






   net/Makefile.objs   |   1 +
   net/filter-redirector.c | 245

   qemu-options.hx |   6 ++
   vl.c|   3 +-
   4 files changed, 254 insertions(+), 1 deletion(-)
   create mode 100644 net/filter-redirector.c

diff --git a/net/Makefile.objs b/net/Makefile.objs
index 5fa2f97..f4290a5 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-redirector.o
diff --git a/net/filter-redirector.c b/net/filter-redirector.c
new file mode 100644
index 000..364e463
--- /dev/null
+++ b/net/filter-redirector.c
@@ -0,0 +1,245 @@
+/*
+ * 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_REDIRECTOR(obj) \
+OBJECT_CHECK(RedirectorState, (obj), TYPE_FILTER_REDIRECTOR)
+
+#define TYPE_FILTER_REDIRECTOR "filter-redirector"
+#define REDIRECT_HEADER_LEN sizeof(uint32_t)
+
+typedef struct RedirectorState {
+NetFilterState parent_obj;
+NetQueue *incoming_queue;/* guest normal net queue */

The comment looks unless and maybe even wrong when queue=rx?

We design redirector that indev's data always be passed to guest finally.
so, It's no relation between the queue=rx/tx/all. just related to
indev = xxx.
we need incoming_queue to inject packet from indev.

So what happens if queue=rx or you want to forbid queue=rx for redirector?



If queue=rx, filter-redirector will get the packet that guest send, then 
redirect
to outdev(if none, do nothing). but queue=rx/tx/all not related to 
indev. please

look the flow chart below. queue=xxx just work for one way(filter->outdev).

  filter
+
|
|
   redirector   |
+-+
|   |  

Re: [Qemu-devel] [PATCH] net/filter-redirector:Add filter-redirector

2016-02-23 Thread Jason Wang


On 02/18/2016 03:50 PM, Zhang Chen wrote:
>
>
> On 02/18/2016 10:41 AM, Jason Wang wrote:
>>
>> On 02/05/2016 02:50 PM, Zhang Chen wrote:
>>> From: ZhangChen 
>>>
>>> Filter-redirector is a netfilter plugin.
>>> It gives qemu the ability to redirect net packet.
>>> redirector can redirect filter's net packet to outdev.
>>> and redirect indev's packet to filter.
>>>
>>>   filter
>>> +
>>> |
>>> |
>>>redirector   |
>>> +-+
>>> |   | |
>>> |   | |
>>> |   | |
>>>indev ++ +>  outdev
>>> | |   |
>>> | |   |
>>> | |   |
>>> +-+
>>>   |
>>>   |
>>>   v
>>>filter
>
>   v
>
> change it to   filter  filter .. guest
> It's may more clearly expressed.
>
>>> usage:
>>>
>>> -netdev tap,id=hn0
>>> -chardev socket,id=s0,host=ip_primary,port=X,server,nowait
>>> -chardev socket,id=s1,host=ip_primary,port=Y,server,nowait
>>> -filter-redirector,id=r0,netdev=hn0,queue=tx/rx/all,indev=s0,outdev=s1
>>>
>>> Signed-off-by: ZhangChen 
>>> Signed-off-by: Wen Congyang 
>>> ---
>> Thanks a lot for the patch. Like mirror, let's design a unit-test for
>> this. And what's more, is there any chance to unify the codes? (At least
>> parts of the codes could be reused).
>
> We can make filter-redirector based on filter-mirror.
> if you want to use redirector ,you must open mirror before.
> like this:
>
> -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,redirector=on,outdev=mirror0
>
> -filter-redirector,id=r0,netdev=hn0,queue=tx/rx/all,indev=s0
>
> How about this?

This looks like a burden for user who just want to use redirector. Maybe
we can do :

- Still two type of filters but sharing a single state.
- Using a internal flag to differ mirrors from redirectors?

>
>
>>>   net/Makefile.objs   |   1 +
>>>   net/filter-redirector.c | 245
>>> 
>>>   qemu-options.hx |   6 ++
>>>   vl.c|   3 +-
>>>   4 files changed, 254 insertions(+), 1 deletion(-)
>>>   create mode 100644 net/filter-redirector.c
>>>
>>> diff --git a/net/Makefile.objs b/net/Makefile.objs
>>> index 5fa2f97..f4290a5 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-redirector.o
>>> diff --git a/net/filter-redirector.c b/net/filter-redirector.c
>>> new file mode 100644
>>> index 000..364e463
>>> --- /dev/null
>>> +++ b/net/filter-redirector.c
>>> @@ -0,0 +1,245 @@
>>> +/*
>>> + * 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_REDIRECTOR(obj) \
>>> +OBJECT_CHECK(RedirectorState, (obj), TYPE_FILTER_REDIRECTOR)
>>> +
>>> +#define TYPE_FILTER_REDIRECTOR "filter-redirector"
>>> +#define REDIRECT_HEADER_LEN sizeof(uint32_t)
>>> +
>>> +typedef struct RedirectorState {
>>> +NetFilterState parent_obj;
>>> +NetQueue *incoming_queue;/* guest normal net queue */
>> The comment looks unless and maybe even wrong when queue=rx?
>
> We design redirector that indev's data always be passed to guest finally.
> so, It's no relation between the queue=rx/tx/all. just related to
> indev = xxx.
> we need incoming_queue to inject packet from indev.

So what happens if queue=rx or you want to forbid queue=rx for redirector?




Re: [Qemu-devel] [PATCH] net/filter-redirector:Add filter-redirector

2016-02-17 Thread Zhang Chen



On 02/18/2016 10:41 AM, Jason Wang wrote:


On 02/05/2016 02:50 PM, Zhang Chen wrote:

From: ZhangChen 

Filter-redirector is a netfilter plugin.
It gives qemu the ability to redirect net packet.
redirector can redirect filter's net packet to outdev.
and redirect indev's packet to filter.

  filter
+
|
|
   redirector   |
+-+
|   | |
|   | |
|   | |
   indev ++ +>  outdev
| |   |
| |   |
| |   |
+-+
  |
  |
  v
   filter


  v

change it to   filter  filter .. guest
It's may more clearly expressed.


usage:

-netdev tap,id=hn0
-chardev socket,id=s0,host=ip_primary,port=X,server,nowait
-chardev socket,id=s1,host=ip_primary,port=Y,server,nowait
-filter-redirector,id=r0,netdev=hn0,queue=tx/rx/all,indev=s0,outdev=s1

Signed-off-by: ZhangChen 
Signed-off-by: Wen Congyang 
---

Thanks a lot for the patch. Like mirror, let's design a unit-test for
this. And what's more, is there any chance to unify the codes? (At least
parts of the codes could be reused).


We can make filter-redirector based on filter-mirror.
if you want to use redirector ,you must open mirror before.
like this:

-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,redirector=on,outdev=mirror0
-filter-redirector,id=r0,netdev=hn0,queue=tx/rx/all,indev=s0

How about this?



  net/Makefile.objs   |   1 +
  net/filter-redirector.c | 245 
  qemu-options.hx |   6 ++
  vl.c|   3 +-
  4 files changed, 254 insertions(+), 1 deletion(-)
  create mode 100644 net/filter-redirector.c

diff --git a/net/Makefile.objs b/net/Makefile.objs
index 5fa2f97..f4290a5 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-redirector.o
diff --git a/net/filter-redirector.c b/net/filter-redirector.c
new file mode 100644
index 000..364e463
--- /dev/null
+++ b/net/filter-redirector.c
@@ -0,0 +1,245 @@
+/*
+ * 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_REDIRECTOR(obj) \
+OBJECT_CHECK(RedirectorState, (obj), TYPE_FILTER_REDIRECTOR)
+
+#define TYPE_FILTER_REDIRECTOR "filter-redirector"
+#define REDIRECT_HEADER_LEN sizeof(uint32_t)
+
+typedef struct RedirectorState {
+NetFilterState parent_obj;
+NetQueue *incoming_queue;/* guest normal net queue */

The comment looks unless and maybe even wrong when queue=rx?


We design redirector that indev's data always be passed to guest finally.
so, It's no relation between the queue=rx/tx/all. just related to indev 
= xxx.

we need incoming_queue to inject packet from indev.



+char *indev;
+char *outdev;
+CharDriverState *chr_in;
+CharDriverState *chr_out;
+} RedirectorState;
+
+static ssize_t filter_redirector_send(NetFilterState *nf,
+   const struct iovec *iov,
+   int iovcnt)
+{
+RedirectorState *s = FILTER_REDIRECTOR(nf);
+ssize_t ret = 0;
+ssize_t size = 0;
+uint32_t len =  0;
+char *buf;
+
+size = iov_size(iov, iovcnt);
+len = htonl(size);
+if (!size) {
+return 0;
+}
+
+buf = g_malloc0(size);
+iov_to_buf(iov, iovcnt, 0, buf, size);
+ret = qemu_chr_fe_write_all(s->chr_out, (uint8_t *), sizeof(len));
+if (ret < 0) {

Similar to mirror, need check the return value against sizeof(len). And
the code could be simplified with something like:

goto out;

...

out:
 g_free(buf);
 return ret;

And you can see another advantages of unifying the codes 

Re: [Qemu-devel] [PATCH] net/filter-redirector:Add filter-redirector

2016-02-17 Thread Jason Wang


On 02/05/2016 02:50 PM, Zhang Chen wrote:
> From: ZhangChen 
>
> Filter-redirector is a netfilter plugin.
> It gives qemu the ability to redirect net packet.
> redirector can redirect filter's net packet to outdev.
> and redirect indev's packet to filter.
>
>  filter
>+
>|
>|
>   redirector   |
>+-+
>|   | |
>|   | |
>|   | |
>   indev ++ +>  outdev
>| |   |
>| |   |
>| |   |
>+-+
>  |
>  |
>  v
>   filter
>
> usage:
>
> -netdev tap,id=hn0
> -chardev socket,id=s0,host=ip_primary,port=X,server,nowait
> -chardev socket,id=s1,host=ip_primary,port=Y,server,nowait
> -filter-redirector,id=r0,netdev=hn0,queue=tx/rx/all,indev=s0,outdev=s1
>
> Signed-off-by: ZhangChen 
> Signed-off-by: Wen Congyang 
> ---

Thanks a lot for the patch. Like mirror, let's design a unit-test for
this. And what's more, is there any chance to unify the codes? (At least
parts of the codes could be reused).

>  net/Makefile.objs   |   1 +
>  net/filter-redirector.c | 245 
> 
>  qemu-options.hx |   6 ++
>  vl.c|   3 +-
>  4 files changed, 254 insertions(+), 1 deletion(-)
>  create mode 100644 net/filter-redirector.c
>
> diff --git a/net/Makefile.objs b/net/Makefile.objs
> index 5fa2f97..f4290a5 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-redirector.o
> diff --git a/net/filter-redirector.c b/net/filter-redirector.c
> new file mode 100644
> index 000..364e463
> --- /dev/null
> +++ b/net/filter-redirector.c
> @@ -0,0 +1,245 @@
> +/*
> + * 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_REDIRECTOR(obj) \
> +OBJECT_CHECK(RedirectorState, (obj), TYPE_FILTER_REDIRECTOR)
> +
> +#define TYPE_FILTER_REDIRECTOR "filter-redirector"
> +#define REDIRECT_HEADER_LEN sizeof(uint32_t)
> +
> +typedef struct RedirectorState {
> +NetFilterState parent_obj;
> +NetQueue *incoming_queue;/* guest normal net queue */

The comment looks unless and maybe even wrong when queue=rx?

> +char *indev;
> +char *outdev;
> +CharDriverState *chr_in;
> +CharDriverState *chr_out;
> +} RedirectorState;
> +
> +static ssize_t filter_redirector_send(NetFilterState *nf,
> +   const struct iovec *iov,
> +   int iovcnt)
> +{
> +RedirectorState *s = FILTER_REDIRECTOR(nf);
> +ssize_t ret = 0;
> +ssize_t size = 0;
> +uint32_t len =  0;
> +char *buf;
> +
> +size = iov_size(iov, iovcnt);
> +len = htonl(size);
> +if (!size) {
> +return 0;
> +}
> +
> +buf = g_malloc0(size);
> +iov_to_buf(iov, iovcnt, 0, buf, size);
> +ret = qemu_chr_fe_write_all(s->chr_out, (uint8_t *), sizeof(len));
> +if (ret < 0) {

Similar to mirror, need check the return value against sizeof(len). And
the code could be simplified with something like:

goto out;

...

out:
g_free(buf);
return ret;

And you can see another advantages of unifying the codes here, avoid
duplicating bugx/fixes.

> +g_free(buf);
> +return ret;
> +}
> +
> +ret = qemu_chr_fe_write_all(s->chr_out, (uint8_t *)buf, size);
> +g_free(buf);
> +return ret;
> +}
> +
> +static ssize_t filter_redirector_receive_iov(NetFilterState *nf,
> + NetClientState *sender,
> + unsigned flags,
> + const struct iovec *iov,
> + int iovcnt,
> + 

[Qemu-devel] [PATCH] net/filter-redirector:Add filter-redirector

2016-02-04 Thread Zhang Chen
From: ZhangChen 

Filter-redirector is a netfilter plugin.
It gives qemu the ability to redirect net packet.
redirector can redirect filter's net packet to outdev.
and redirect indev's packet to filter.

 filter
   +
   |
   |
  redirector   |
   +-+
   |   | |
   |   | |
   |   | |
  indev ++ +>  outdev
   | |   |
   | |   |
   | |   |
   +-+
 |
 |
 v
  filter

usage:

-netdev tap,id=hn0
-chardev socket,id=s0,host=ip_primary,port=X,server,nowait
-chardev socket,id=s1,host=ip_primary,port=Y,server,nowait
-filter-redirector,id=r0,netdev=hn0,queue=tx/rx/all,indev=s0,outdev=s1

Signed-off-by: ZhangChen 
Signed-off-by: Wen Congyang 
---
 net/Makefile.objs   |   1 +
 net/filter-redirector.c | 245 
 qemu-options.hx |   6 ++
 vl.c|   3 +-
 4 files changed, 254 insertions(+), 1 deletion(-)
 create mode 100644 net/filter-redirector.c

diff --git a/net/Makefile.objs b/net/Makefile.objs
index 5fa2f97..f4290a5 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-redirector.o
diff --git a/net/filter-redirector.c b/net/filter-redirector.c
new file mode 100644
index 000..364e463
--- /dev/null
+++ b/net/filter-redirector.c
@@ -0,0 +1,245 @@
+/*
+ * 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_REDIRECTOR(obj) \
+OBJECT_CHECK(RedirectorState, (obj), TYPE_FILTER_REDIRECTOR)
+
+#define TYPE_FILTER_REDIRECTOR "filter-redirector"
+#define REDIRECT_HEADER_LEN sizeof(uint32_t)
+
+typedef struct RedirectorState {
+NetFilterState parent_obj;
+NetQueue *incoming_queue;/* guest normal net queue */
+char *indev;
+char *outdev;
+CharDriverState *chr_in;
+CharDriverState *chr_out;
+} RedirectorState;
+
+static ssize_t filter_redirector_send(NetFilterState *nf,
+   const struct iovec *iov,
+   int iovcnt)
+{
+RedirectorState *s = FILTER_REDIRECTOR(nf);
+ssize_t ret = 0;
+ssize_t size = 0;
+uint32_t len =  0;
+char *buf;
+
+size = iov_size(iov, iovcnt);
+len = htonl(size);
+if (!size) {
+return 0;
+}
+
+buf = g_malloc0(size);
+iov_to_buf(iov, iovcnt, 0, buf, size);
+ret = qemu_chr_fe_write_all(s->chr_out, (uint8_t *), sizeof(len));
+if (ret < 0) {
+g_free(buf);
+return ret;
+}
+
+ret = qemu_chr_fe_write_all(s->chr_out, (uint8_t *)buf, size);
+g_free(buf);
+return ret;
+}
+
+static ssize_t filter_redirector_receive_iov(NetFilterState *nf,
+ NetClientState *sender,
+ unsigned flags,
+ const struct iovec *iov,
+ int iovcnt,
+ NetPacketSent *sent_cb)
+{
+RedirectorState *s = FILTER_REDIRECTOR(nf);
+ssize_t ret = 0;
+
+if (s->chr_out) {
+ret = filter_redirector_send(nf, iov, iovcnt);
+if (ret < 0) {
+error_report("filter_redirector_send failed");
+}
+}
+return iov_size(iov, iovcnt);
+}
+
+static void filter_redirector_cleanup(NetFilterState *nf)
+{
+RedirectorState *s = FILTER_REDIRECTOR(nf);
+
+if (s->chr_in) {
+qemu_chr_fe_release(s->chr_in);
+}
+if (s->chr_out) {
+qemu_chr_fe_release(s->chr_out);
+}
+}
+
+static int redirector_chr_can_read(void *opaque)
+{
+return REDIRECT_HEADER_LEN;
+}
+
+static void redirector_chr_read(void *opaque, const uint8_t *buf, int size)
+{
+NetFilterState *nf = opaque;
+