Add glue code to use the dumping functions as a netdev filter, too. Signed-off-by: Thomas Huth <th...@redhat.com> --- 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 -- 1.8.3.1