From: Li Zhijian <lizhijian@cn.fujitsu.com>
To: Jason Wang <jasowang@redhat.com>,
Zhang Chen <zhangchen.fnst@cn.fujitsu.com>,
qemu devel <qemu-devel@nongnu.org>
Cc: zhanghailiang <zhang.zhanghailiang@huawei.com>,
Gui jianfeng <guijianfeng@cn.fujitsu.com>,
"eddie.dong" <eddie.dong@intel.com>,
"Dr. David Alan Gilbert" <dgilbert@redhat.com>,
Yang Hongyang <hongyang.yang@easystack.cn>
Subject: Re: [Qemu-devel] [PATCH V3 2/3] net/filter-mirror:Add filter-redirector func
Date: Mon, 7 Mar 2016 17:57:56 +0800 [thread overview]
Message-ID: <56DD50A4.6020002@cn.fujitsu.com> (raw)
In-Reply-To: <56DD4543.1060808@redhat.com>
On 03/07/2016 05:09 PM, Jason Wang wrote:
>
>
> On 03/07/2016 04:26 PM, Li Zhijian wrote:
>>
>>
>> On 03/07/2016 03:56 PM, Jason Wang wrote:
>>>
>>>
>>> On 03/04/2016 08:01 PM, Zhang Chen wrote:
>>>> 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 user,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: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
>>>> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
>>>> ---
>>>> net/filter-mirror.c | 211
>>>> ++++++++++++++++++++++++++++++++++++++++++++++++++++
>>>> qemu-options.hx | 8 ++
>>>> vl.c | 3 +-
>>>> 3 files changed, 221 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/net/filter-mirror.c b/net/filter-mirror.c
>>>> index 4ff7619..d137168 100644
>>>> --- a/net/filter-mirror.c
>>>> +++ b/net/filter-mirror.c
>>>> @@ -25,11 +25,19 @@
>>>> #define FILTER_MIRROR(obj) \
>>>> OBJECT_CHECK(MirrorState, (obj), TYPE_FILTER_MIRROR)
>>>>
>>>> +#define FILTER_REDIRECTOR(obj) \
>>>> + OBJECT_CHECK(MirrorState, (obj), TYPE_FILTER_REDIRECTOR)
>>>> +
>>>> #define TYPE_FILTER_MIRROR "filter-mirror"
>>>> +#define TYPE_FILTER_REDIRECTOR "filter-redirector"
>>>> +#define REDIRECT_HEADER_LEN sizeof(uint32_t)
>>>>
>>>> typedef struct MirrorState {
>>>> NetFilterState parent_obj;
>>>> + NetQueue *incoming_queue;
>>>> + char *indev;
>>>> char *outdev;
>>>> + CharDriverState *chr_in;
>>>> CharDriverState *chr_out;
>>>> } MirrorState;
>>>>
>>>> @@ -67,6 +75,68 @@ err:
>>>> return ret < 0 ? ret : -EIO;
>>>> }
>>>>
>>>> +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;
>>>> + MirrorState *s = FILTER_REDIRECTOR(nf);
>>>> + uint32_t len;
>>>> + int ret = 0;
>>>> + uint8_t *recv_buf;
>>>> +
>>>> + memcpy(&len, buf, size);
>>>
>>> stack overflow if size > sizeof(len)?
>> IIUC, it seems never happend because the 'size' will never greater
>> than the return value of
>> redirector_chr_can_read() which will always return REDIRECT_HEADER_LEN ?
>
> Right, so it's safe.
>
>>
>>
>>>
>>>> + if (size < REDIRECT_HEADER_LEN) {
>>>> + ret = qemu_chr_fe_read_all(s->chr_in, ((uint8_t *)&len) +
>>>> size,
>>>> + REDIRECT_HEADER_LEN - size);
>>>
>>> There maybe some misunderstanding for my previous reply. You can have a
>>> look at net_socket_send() for reference. You could
>>>
>>> - use a buffer for storing len
>>> - each time when you receive partial len, store them in the buffer and
>>> advance the pointer until you receive at least sizeof(len) bytes.
>> qemu_chr_fe_read_all() seem have done this work.
>
> Not the same. qemu_chr_fe_read_all() will do loop reading and usleep
> which is suboptimal. My proposal does not have this issue. It will make
> redirector_chr_read() can handle arbitrary length of data and won't do
> any busy reading.
>
>> Do you mean that
>> we implement a similar code to do that instead of qemu_chr_fe_read_all()
>
> Nope, if you have a look at net_socket_send() it won't do any usleep and
> loop reading, it will return immediately when it does not get sufficient
> data. But it's really your call, not a must but worth to be optimized on
> top in the future.
>
Thanks for you explain.
Is it just like bellow code(not completed) ?
#define REDIRECTOR_MAX_LEN NET_BUFSIZE
typedef struct MirrorState {
NetFilterState parent_obj;
char *indev;
char *outdev;
CharDriverState *chr_in;
CharDriverState *chr_out;
+ int state; /* 0 = getting length, 1 = getting data */
+ unsigned int index;
+ unsigned int packet_len;
+ uint8_t buf[REDIRECTOR_MAX_LEN];
} MirrorState;
static int redirector_chr_can_read(void *opaque)
{
return REDIRECTOR_MAX_LEN;
}
static void redirector_chr_read(void *opaque, const uint8_t *buf, int size)
{
NetFilterState *nf = opaque;
MirrorState *s = FILTER_REDIRECTOR(nf);
unsigned int l;
while (size > 0) {
/* reassemble a packet from the network */
switch (s->state) {
case 0:
l = 4 - s->index;
if (l > size) {
l = size;
}
memcpy(s->buf + s->index, buf, l);
buf += l;
size -= l;
s->index += l;
if (s->index == 4) {
/* got length */
s->packet_len = ntohl(*(uint32_t *)s->buf);
s->index = 0;
s->state = 1;
}
break;
case 1:
l = s->packet_len - s->index;
if (l > size) {
l = size;
}
if (s->index + l <= sizeof(s->buf)) {
memcpy(s->buf + s->index, buf, l);
} else {
fprintf(stderr, "serious error: oversized packet received,"
"connection terminated.\n");
s->state = 0;
/* TODO: do something
*/
}
s->index += l;
buf += l;
size -= l;
if (s->index >= s->packet_len) {
s->index = 0;
s->state = 0;
/*
* TODO: pass packet to next filter
*/
}
break;
}
}
}
Thanks
Li Zhijian
next prev parent reply other threads:[~2016-03-07 9:58 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-03-04 12:01 [Qemu-devel] [PATCH V3 0/3] Introduce filter-redirector Zhang Chen
2016-03-04 12:01 ` [Qemu-devel] [PATCH V3 1/3] net/filter-mirror: Change filter_mirror_send interface Zhang Chen
2016-03-07 7:29 ` Jason Wang
2016-03-07 8:13 ` Zhang Chen
2016-03-04 12:01 ` [Qemu-devel] [PATCH V3 2/3] net/filter-mirror:Add filter-redirector func Zhang Chen
2016-03-07 7:56 ` Jason Wang
2016-03-07 8:26 ` Li Zhijian
2016-03-07 9:09 ` Jason Wang
2016-03-07 9:57 ` Li Zhijian [this message]
2016-03-07 9:17 ` Zhang Chen
2016-03-04 12:01 ` [Qemu-devel] [PATCH V3 3/3] tests/test-filter-redirector: Add unit test for filter-redirector Zhang Chen
2016-03-07 8:10 ` Jason Wang
2016-03-07 9:17 ` 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=56DD50A4.6020002@cn.fujitsu.com \
--to=lizhijian@cn.fujitsu.com \
--cc=dgilbert@redhat.com \
--cc=eddie.dong@intel.com \
--cc=guijianfeng@cn.fujitsu.com \
--cc=hongyang.yang@easystack.cn \
--cc=jasowang@redhat.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).