diff mbox

[RFC,4/5] net/dump: Provide the dumping facility as a net filter

Message ID 1440642804-29001-5-git-send-email-thuth@redhat.com
State New
Headers show

Commit Message

Thomas Huth Aug. 27, 2015, 2:33 a.m. UTC
Add glue code to use the dumping functions as a netdev
filter, too.

Signed-off-by: Thomas Huth <thuth@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(-)

Comments

Yang Hongyang Aug. 27, 2015, 3:03 a.m. UTC | #1
On 08/27/2015 10:33 AM, Thomas Huth wrote:
> Add glue code to use the dumping functions as a netdev
> filter, too.

Overall looks good to me, thanks.

Note that the QAPI part might change later, so there might be some rebase
work later, thanks again!

>
> Signed-off-by: Thomas Huth <thuth@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);

wrong alignment.

>
>   #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
>
Eric Blake Sept. 1, 2015, 7:52 p.m. UTC | #2
On 08/26/2015 08:33 PM, Thomas Huth wrote:
> Add glue code to use the dumping functions as a netdev
> filter, too.
> 
> Signed-off-by: Thomas Huth <thuth@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(-)
> 

> +++ 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);

Indentation is off.

>  
>  #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
> +#

Otherwise, the interface looks clean. I can't tell from this patch
whether the file is opened by qemu_open() (probably in
net_dump_state_init() in an earlier patch of the series); but if not,
you should fix that.  That way, I can pass '/dev/fdset/XXX' as the name
for an fd passed in by an earlier 'add-fd' even if qemu is restricted
from open()ing files directly.
Thomas Huth Sept. 1, 2015, 9:19 p.m. UTC | #3
On 01/09/15 21:52, Eric Blake wrote:
> On 08/26/2015 08:33 PM, Thomas Huth wrote:
>> Add glue code to use the dumping functions as a netdev
>> filter, too.
>>
>> Signed-off-by: Thomas Huth <thuth@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(-)
>>
> 
>> +++ 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);
> 
> Indentation is off.
> 
>>  
>>  #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
>> +#
> 
> Otherwise, the interface looks clean. I can't tell from this patch
> whether the file is opened by qemu_open() (probably in
> net_dump_state_init() in an earlier patch of the series); but if not,
> you should fix that.  That way, I can pass '/dev/fdset/XXX' as the name
> for an fd passed in by an earlier 'add-fd' even if qemu is restricted
> from open()ing files directly.

The current (old) code opens the dump file with open() ... but I can
certainly add an additional patch that uses qemu_open() instead.

 Thomas
diff mbox

Patch

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