From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46525) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZOjGo-0007Op-NW for qemu-devel@nongnu.org; Mon, 10 Aug 2015 05:21:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZOjGk-0005EU-Cq for qemu-devel@nongnu.org; Mon, 10 Aug 2015 05:21:26 -0400 Received: from mx1.redhat.com ([209.132.183.28]:53236) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZOjGk-0005EJ-5i for qemu-devel@nongnu.org; Mon, 10 Aug 2015 05:21:22 -0400 Message-ID: <55C86D0B.7010106@redhat.com> Date: Mon, 10 Aug 2015 17:21:15 +0800 From: Jason Wang MIME-Version: 1.0 References: <1438915585-30367-1-git-send-email-yanghy@cn.fujitsu.com> <1438915585-30367-9-git-send-email-yanghy@cn.fujitsu.com> In-Reply-To: <1438915585-30367-9-git-send-email-yanghy@cn.fujitsu.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH v6 08/10] netfilter: add a netbuffer filter List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Yang Hongyang , qemu-devel@nongnu.org Cc: thuth@redhat.com, mrhines@linux.vnet.ibm.com, stefanha@redhat.com, zhang.zhanghailiang@huawei.com, lizhijian@cn.fujitsu.com On 08/07/2015 10:46 AM, Yang Hongyang wrote: > This filter is to buffer/release packets, this feature can be used > when using MicroCheckpointing, or other Remus like VM FT solutions, you > can also use it to simulate the network delay. > It has an interval option, if supplied, this filter will release > packets by interval. > > Usage: > -netdev tap,id=bn0 > -netfilter buffer,id=f0,netdev=bn0,chain=in,interval=1000 > > NOTE: > the scale of interval is microsecond. > > Signed-off-by: Yang Hongyang > --- > v6: move the interval check earlier and some comment adjust > v5: remove dummy sent_cb > change interval type from int64 to uint32 > check interval!=0 when initialise > rename FILTERBUFFERState to FilterBufferState > v4: remove bh > pass the packet to next filter instead of receiver > v3: check packet's sender and sender->peer when flush it > --- > net/Makefile.objs | 1 + > net/filter-buffer.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > net/filter.c | 2 + > net/filters.h | 17 +++++++ > qapi-schema.json | 18 +++++++- > 5 files changed, 163 insertions(+), 1 deletion(-) > create mode 100644 net/filter-buffer.c > create mode 100644 net/filters.h > > diff --git a/net/Makefile.objs b/net/Makefile.objs > index 914aec0..5fa2f97 100644 > --- a/net/Makefile.objs > +++ b/net/Makefile.objs > @@ -14,3 +14,4 @@ common-obj-$(CONFIG_SLIRP) += slirp.o > common-obj-$(CONFIG_VDE) += vde.o > common-obj-$(CONFIG_NETMAP) += netmap.o > common-obj-y += filter.o > +common-obj-y += filter-buffer.o > diff --git a/net/filter-buffer.c b/net/filter-buffer.c > new file mode 100644 > index 0000000..f26276c > --- /dev/null > +++ b/net/filter-buffer.c > @@ -0,0 +1,126 @@ > +/* > + * Copyright (c) 2015 FUJITSU LIMITED > + * Author: Yang Hongyang > + * > + * 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/queue.h" > +#include "filters.h" > +#include "qemu-common.h" > +#include "qemu/timer.h" > +#include "qemu/iov.h" > +#include "qapi/qmp/qerror.h" > + > +typedef struct FilterBufferState { > + NetFilterState nf; > + NetQueue *incoming_queue; > + uint32_t interval; > + QEMUTimer release_timer; > +} FilterBufferState; > + > +static void filter_buffer_flush(NetFilterState *nf) > +{ > + FilterBufferState *s = DO_UPCAST(FilterBufferState, nf, nf); > + NetQueue *queue = s->incoming_queue; > + NetPacket *packet; > + > + while (queue && !QTAILQ_EMPTY(&queue->packets)) { Looks like no need to check queue here. And then you can switch to use QTAILQ_FOREACH_SAFE() to save one line of QTAILF_FIRST(). > + packet = QTAILQ_FIRST(&queue->packets); > + QTAILQ_REMOVE(&queue->packets, packet, entry); > + queue->nq_count--; > + > + if (packet->sender && packet->sender->peer) { > + qemu_netfilter_pass_to_next(nf, packet); > + } > + > + /* > + * now that we have passed the packet to next filter (or there's > + * no receiver). If it's queued by receiver's incoming_queue, there > + * will be a copy of the packet->data, so simply free this packet > + * now. > + */ > + g_free(packet); In the future, we may consider to avoid the extra copy. This could be done on top of this series.