Re: [Qemu-devel] [PATCH] net/filter-redirector:Add filter-redirector
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
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
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
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: ZhangChenFilter-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
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
On 02/18/2016 10:41 AM, Jason Wang wrote: On 02/05/2016 02:50 PM, Zhang Chen wrote: From: ZhangChenFilter-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
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
From: ZhangChenFilter-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; +