Signed-off-by: Thomas Huth <address@hidden>
---
net/dump.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
net/filter.c | 1 +
net/filters.h | 2 ++
qapi-schema.json | 20 +++++++++++++++++++-
4 files changed, 76 insertions(+), 1 deletion(-)
diff --git a/net/dump.c b/net/dump.c
index 8317102..b09d2b9 100644
--- a/net/dump.c
+++ b/net/dump.c
@@ -28,7 +28,9 @@
#include "qemu/iov.h"
#include "qemu/log.h"
#include "qemu/timer.h"
+#include "net/filter.h"
#include "hub.h"
+#include "filters.h"
typedef struct DumpState {
int64_t start_ts;
@@ -224,3 +226,55 @@ int net_init_dump(const NetClientOptions *opts, const char
*name,
}
return rc;
}
+
+/* Dumping via filter */
+
+typedef struct NetFilterDumpState {
+ NetFilterState nf;
+ DumpState ds;
+} NetFilterDumpState;
+
+static ssize_t filter_dump_receive_iov(NetFilterState *nf, NetClientState
*sndr,
+ unsigned flags,
+ const struct iovec *iov, int iovcnt,
+ NetPacketSent *sent_cb)
+{
+ NetFilterDumpState *nfds = DO_UPCAST(NetFilterDumpState, nf, nf);
+
+ dump_receive_iov(&nfds->ds, iov, iovcnt);
+ return 0;
+}
+
+static void filter_dump_cleanup(NetFilterState *nf)
+{
+ NetFilterDumpState *nfds = DO_UPCAST(NetFilterDumpState, nf, nf);
+
+ dump_cleanup(&nfds->ds);
+}
+
+static NetFilterInfo net_filter_dump_info = {
+ .type = NET_FILTER_OPTIONS_KIND_DUMP,
+ .size = sizeof(NetFilterDumpState),
+ .receive_iov = filter_dump_receive_iov,
+ .cleanup = filter_dump_cleanup,
+};
+
+int net_init_filter_dump(const NetFilterOptions *opts, const char *name,
+ int chain, NetClientState *netdev, Error **errp)
+{
+ NetFilterState *nf;
+ NetFilterDumpState *nfds;
+ const NetFilterDumpOptions *dumpopt;
+ int dump_len = 65536;
+
+ assert(opts->kind == NET_FILTER_OPTIONS_KIND_DUMP);
+ dumpopt = opts->dump;
+ if (dumpopt->has_maxlen) {
+ dump_len = dumpopt->maxlen;
+ }
+
+ nf = qemu_new_net_filter(&net_filter_dump_info, netdev, name, chain);
+ nfds = DO_UPCAST(NetFilterDumpState, nf, nf);
+
+ return net_dump_state_init(&nfds->ds, dumpopt->file, dump_len, errp);
+}
diff --git a/net/filter.c b/net/filter.c
index f23fc7f..536d236 100644
--- a/net/filter.c
+++ b/net/filter.c
@@ -216,6 +216,7 @@ typedef int (NetFilterInit)(const NetFilterOptions *opts,
static
NetFilterInit * const net_filter_init_fun[NET_FILTER_OPTIONS_KIND_MAX] = {
[NET_FILTER_OPTIONS_KIND_BUFFER] = net_init_filter_buffer,
+ [NET_FILTER_OPTIONS_KIND_DUMP] = net_init_filter_dump,
};
static int net_filter_init1(const NetFilter *netfilter, Error **errp)
diff --git a/net/filters.h b/net/filters.h
index 3b546db..f63bde1 100644
--- a/net/filters.h
+++ b/net/filters.h
@@ -13,5 +13,7 @@
int net_init_filter_buffer(const NetFilterOptions *opts, const char *name,
int chain, NetClientState *netdev, Error **errp);
+int net_init_filter_dump(const NetFilterOptions *opts, const char *name,
+ int chain, NetClientState *netdev, Error **errp);
#endif /* QEMU_NET_FILTERS_H */
diff --git a/qapi-schema.json b/qapi-schema.json
index 7882641..71caca9 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2599,6 +2599,23 @@
'*interval': 'uint32' } }
##
+# @NetFilterDumpOptions
+#
+# a dumping filter for network backends.
+#
+# @file: Name of the file where the dump data should be written into.
+#
+# @maxlen: Crop big packets to this size before writing them into the
+# dump file.
+#
+# Since 2.5
+##
+{ 'struct': 'NetFilterDumpOptions',
+ 'data': {
+ 'file': 'str',
+ '*maxlen': 'int32' } }
+
+##
# @NetFilterOptions
#
# A discriminated record of network filters.
@@ -2608,7 +2625,8 @@
##
{ 'union': 'NetFilterOptions',
'data': {
- 'buffer': 'NetFilterBufferOptions'} }
+ 'buffer': 'NetFilterBufferOptions',
+ 'dump': 'NetFilterDumpOptions' } }
##
# @NetFilter