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 <address@hidden>
---
v3: check packet's sender and sender->peer when flush it
---
net/Makefile.objs | 1 +
net/filter-buffer.c | 162
++++++++++++++++++++++++++++++++++++++++++++++++++++
net/filter.c | 2 +
net/filters.h | 17 ++++++
qapi-schema.json | 18 +++++-
5 files changed, 199 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..1547765
--- /dev/null
+++ b/net/filter-buffer.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2015 FUJITSU LIMITED
+ * Author: Yang Hongyang <address@hidden>
+ *
+ * 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/error-report.h"
+#include "qemu/main-loop.h"
+#include "qemu/timer.h"
+#include "qemu/iov.h"
+
+typedef struct FILTERBUFFERState {
+ NetFilterState nf;
+ NetQueue *incoming_queue;
+ NetQueue *inflight_queue;
+ QEMUBH *flush_bh;
+ int64_t interval;
+ QEMUTimer release_timer;
+} FILTERBUFFERState;
+
+static void packet_send_completed(NetClientState *nc, ssize_t len)
+{
+ return;
+}
+
+static void filter_buffer_flush(NetFilterState *nf)
+{
+ FILTERBUFFERState *s = DO_UPCAST(FILTERBUFFERState, nf, nf);
+ NetQueue *queue = s->inflight_queue;
+ NetPacket *packet;
+
+ while (queue && !QTAILQ_EMPTY(&queue->packets)) {
+ packet = QTAILQ_FIRST(&queue->packets);
+ QTAILQ_REMOVE(&queue->packets, packet, entry);
+ queue->nq_count--;
+
+ if (packet->sender && packet->sender->peer) {
+ qemu_net_queue_send(packet->sender->peer->incoming_queue,
+ packet->sender,
+ packet->flags,
+ packet->data,
+ packet->size,
+ packet->sent_cb);
+ }
+
+ /*
+ * now that we pass the packet to
sender->peer->incoming_queue, we
+ * don't care the reture value here, because the peer's
queue will
+ * take care of this packet
+ */
+ g_free(packet);