All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH RFC 0/5] Network traffic dumping via netfilter
@ 2015-08-27  2:33 Thomas Huth
  2015-08-27  2:33 ` [Qemu-devel] [PATCH RFC 1/5] net/dump: Add support for receive_iov function Thomas Huth
                   ` (5 more replies)
  0 siblings, 6 replies; 10+ messages in thread
From: Thomas Huth @ 2015-08-27  2:33 UTC (permalink / raw)
  To: Stefan Hajnoczi, Jason Wang, qemu-devel, yanghy
  Cc: Markus Armbruster, Michael S. Tsirkin

The "-net dump" option only works with the "-net" option. So far, it
is not possible to dump network traffic with the "-netdev" option yet.
This patch series now fixes this ugliness by enabling dumping for the
netdev devices via the new netfilter infrastructure. It can be used
like this for example:

 qemu-system-ppc64 -nographic -vga none -device virtio-net,netdev=mynet \
   -netdev user,id=mynet,tftp=/tmp/tftp,bootfile=zImage -boot n \
   -netfilter dump,id=f0,netdev=mynet,file=/tmp/filterdump.dat

This series is based on v8 of Yang Hongyang's netfilter patches
(i.e. these have to be applied before the dumping patches can be
used). Since these netfilter patches are not upstream yet and still
might change the API in future versions, I'm sending my patches as
"RFC" (but since the integration with the current netfilter patches
was pretty easy already, they should be ready as normal patches very
soon after the netfilter patches have been finalized).

Thomas Huth (5):
  net/dump: Add support for receive_iov function
  net/dump: Rework net-dump init functions
  net/dump: Separate the NetClientState from the DumpState
  net/dump: Provide the dumping facility as a net filter
  net/dump: Add documentation

 net/dump.c       | 152 ++++++++++++++++++++++++++++++++++++++++++++-----------
 net/filter.c     |   1 +
 net/filters.h    |   2 +
 qapi-schema.json |  20 +++++++-
 qemu-options.hx  |  15 ++++--
 5 files changed, 155 insertions(+), 35 deletions(-)

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH RFC 1/5] net/dump: Add support for receive_iov function
  2015-08-27  2:33 [Qemu-devel] [PATCH RFC 0/5] Network traffic dumping via netfilter Thomas Huth
@ 2015-08-27  2:33 ` Thomas Huth
  2015-08-27  2:33 ` [Qemu-devel] [PATCH RFC 2/5] net/dump: Rework net-dump init functions Thomas Huth
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Thomas Huth @ 2015-08-27  2:33 UTC (permalink / raw)
  To: Stefan Hajnoczi, Jason Wang, qemu-devel, yanghy
  Cc: Markus Armbruster, Michael S. Tsirkin

Adding a proper receive_iov function to the net dump module.
This will make it easier to support the dump filter feature for
the -netdev option in later patches.

Signed-off-by: Thomas Huth <thuth@redhat.com>
---
 net/dump.c | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/net/dump.c b/net/dump.c
index 02c8064..f8afb83 100644
--- a/net/dump.c
+++ b/net/dump.c
@@ -25,6 +25,7 @@
 #include "clients.h"
 #include "qemu-common.h"
 #include "qemu/error-report.h"
+#include "qemu/iov.h"
 #include "qemu/log.h"
 #include "qemu/timer.h"
 #include "hub.h"
@@ -57,12 +58,15 @@ struct pcap_sf_pkthdr {
     uint32_t len;
 };
 
-static ssize_t dump_receive(NetClientState *nc, const uint8_t *buf, size_t size)
+static ssize_t dump_receive_iov(NetClientState *nc, const struct iovec *iov,
+                                int cnt)
 {
     DumpState *s = DO_UPCAST(DumpState, nc, nc);
     struct pcap_sf_pkthdr hdr;
     int64_t ts;
     int caplen;
+    size_t size = iov_size(iov, cnt);
+    struct iovec dumpiov[cnt + 1];
 
     /* Early return in case of previous error. */
     if (s->fd < 0) {
@@ -76,8 +80,12 @@ static ssize_t dump_receive(NetClientState *nc, const uint8_t *buf, size_t size)
     hdr.ts.tv_usec = ts % 1000000;
     hdr.caplen = caplen;
     hdr.len = size;
-    if (write(s->fd, &hdr, sizeof(hdr)) != sizeof(hdr) ||
-        write(s->fd, buf, caplen) != caplen) {
+
+    dumpiov[0].iov_base = &hdr;
+    dumpiov[0].iov_len = sizeof(hdr);
+    cnt = iov_copy(&dumpiov[1], cnt, iov, cnt, 0, caplen);
+
+    if (writev(s->fd, dumpiov, cnt + 1) != sizeof(hdr) + caplen) {
         qemu_log("-net dump write error - stop dump\n");
         close(s->fd);
         s->fd = -1;
@@ -86,6 +94,15 @@ static ssize_t dump_receive(NetClientState *nc, const uint8_t *buf, size_t size)
     return size;
 }
 
+static ssize_t dump_receive(NetClientState *nc, const uint8_t *buf, size_t size)
+{
+    struct iovec iov = {
+        .iov_base = (void *)buf,
+        .iov_len = size
+    };
+    return dump_receive_iov(nc, &iov, 1);
+}
+
 static void dump_cleanup(NetClientState *nc)
 {
     DumpState *s = DO_UPCAST(DumpState, nc, nc);
@@ -97,6 +114,7 @@ static NetClientInfo net_dump_info = {
     .type = NET_CLIENT_OPTIONS_KIND_DUMP,
     .size = sizeof(DumpState),
     .receive = dump_receive,
+    .receive_iov = dump_receive_iov,
     .cleanup = dump_cleanup,
 };
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH RFC 2/5] net/dump: Rework net-dump init functions
  2015-08-27  2:33 [Qemu-devel] [PATCH RFC 0/5] Network traffic dumping via netfilter Thomas Huth
  2015-08-27  2:33 ` [Qemu-devel] [PATCH RFC 1/5] net/dump: Add support for receive_iov function Thomas Huth
@ 2015-08-27  2:33 ` Thomas Huth
  2015-08-27  2:33 ` [Qemu-devel] [PATCH RFC 3/5] net/dump: Separate the NetClientState from the DumpState Thomas Huth
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Thomas Huth @ 2015-08-27  2:33 UTC (permalink / raw)
  To: Stefan Hajnoczi, Jason Wang, qemu-devel, yanghy
  Cc: Markus Armbruster, Michael S. Tsirkin

Move the creation of the dump client from net_dump_init() into
net_init_dump(), so we can later use the former function for
dump via netfilter, too. Also rename net_dump_init() to
net_dump_state_init() to make it easier distinguishable from
net_init_dump().

Signed-off-by: Thomas Huth <thuth@redhat.com>
---
 net/dump.c | 27 +++++++++++++--------------
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/net/dump.c b/net/dump.c
index f8afb83..27083d4 100644
--- a/net/dump.c
+++ b/net/dump.c
@@ -118,13 +118,10 @@ static NetClientInfo net_dump_info = {
     .cleanup = dump_cleanup,
 };
 
-static int net_dump_init(NetClientState *peer, const char *device,
-                         const char *name, const char *filename, int len,
-                         Error **errp)
+static int net_dump_state_init(DumpState *s, const char *filename,
+                               int len, Error **errp)
 {
     struct pcap_file_hdr hdr;
-    NetClientState *nc;
-    DumpState *s;
     struct tm tm;
     int fd;
 
@@ -148,13 +145,6 @@ static int net_dump_init(NetClientState *peer, const char *device,
         return -1;
     }
 
-    nc = qemu_new_net_client(&net_dump_info, peer, device, name);
-
-    snprintf(nc->info_str, sizeof(nc->info_str),
-             "dump to %s (len=%d)", filename, len);
-
-    s = DO_UPCAST(DumpState, nc, nc);
-
     s->fd = fd;
     s->pcap_caplen = len;
 
@@ -167,10 +157,11 @@ static int net_dump_init(NetClientState *peer, const char *device,
 int net_init_dump(const NetClientOptions *opts, const char *name,
                   NetClientState *peer, Error **errp)
 {
-    int len;
+    int len, rc;
     const char *file;
     char def_file[128];
     const NetdevDumpOptions *dump;
+    NetClientState *nc;
 
     assert(opts->kind == NET_CLIENT_OPTIONS_KIND_DUMP);
     dump = opts->dump;
@@ -200,5 +191,13 @@ int net_init_dump(const NetClientOptions *opts, const char *name,
         len = 65536;
     }
 
-    return net_dump_init(peer, "dump", name, file, len, errp);
+    nc = qemu_new_net_client(&net_dump_info, peer, "dump", name);
+    snprintf(nc->info_str, sizeof(nc->info_str),
+             "dump to %s (len=%d)", file, len);
+
+    rc = net_dump_state_init(DO_UPCAST(DumpState, nc, nc), file, len, errp);
+    if (rc) {
+        qemu_del_net_client(nc);
+    }
+    return rc;
 }
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH RFC 3/5] net/dump: Separate the NetClientState from the DumpState
  2015-08-27  2:33 [Qemu-devel] [PATCH RFC 0/5] Network traffic dumping via netfilter Thomas Huth
  2015-08-27  2:33 ` [Qemu-devel] [PATCH RFC 1/5] net/dump: Add support for receive_iov function Thomas Huth
  2015-08-27  2:33 ` [Qemu-devel] [PATCH RFC 2/5] net/dump: Rework net-dump init functions Thomas Huth
@ 2015-08-27  2:33 ` Thomas Huth
  2015-08-27  2:33 ` [Qemu-devel] [PATCH RFC 4/5] net/dump: Provide the dumping facility as a net filter Thomas Huth
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Thomas Huth @ 2015-08-27  2:33 UTC (permalink / raw)
  To: Stefan Hajnoczi, Jason Wang, qemu-devel, yanghy
  Cc: Markus Armbruster, Michael S. Tsirkin

With the upcoming dumping-via-netfilter patch, the DumpState
should not be related to NetClientState anymore, so move the
related information to a new struct called DumpNetClient.

Signed-off-by: Thomas Huth <thuth@redhat.com>
---
 net/dump.c | 73 +++++++++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 48 insertions(+), 25 deletions(-)

diff --git a/net/dump.c b/net/dump.c
index 27083d4..8317102 100644
--- a/net/dump.c
+++ b/net/dump.c
@@ -31,7 +31,6 @@
 #include "hub.h"
 
 typedef struct DumpState {
-    NetClientState nc;
     int64_t start_ts;
     int fd;
     int pcap_caplen;
@@ -58,10 +57,8 @@ struct pcap_sf_pkthdr {
     uint32_t len;
 };
 
-static ssize_t dump_receive_iov(NetClientState *nc, const struct iovec *iov,
-                                int cnt)
+static ssize_t dump_receive_iov(DumpState *s, const struct iovec *iov, int cnt)
 {
-    DumpState *s = DO_UPCAST(DumpState, nc, nc);
     struct pcap_sf_pkthdr hdr;
     int64_t ts;
     int caplen;
@@ -94,30 +91,12 @@ static ssize_t dump_receive_iov(NetClientState *nc, const struct iovec *iov,
     return size;
 }
 
-static ssize_t dump_receive(NetClientState *nc, const uint8_t *buf, size_t size)
+static void dump_cleanup(DumpState *s)
 {
-    struct iovec iov = {
-        .iov_base = (void *)buf,
-        .iov_len = size
-    };
-    return dump_receive_iov(nc, &iov, 1);
-}
-
-static void dump_cleanup(NetClientState *nc)
-{
-    DumpState *s = DO_UPCAST(DumpState, nc, nc);
-
     close(s->fd);
+    s->fd = -1;
 }
 
-static NetClientInfo net_dump_info = {
-    .type = NET_CLIENT_OPTIONS_KIND_DUMP,
-    .size = sizeof(DumpState),
-    .receive = dump_receive,
-    .receive_iov = dump_receive_iov,
-    .cleanup = dump_cleanup,
-};
-
 static int net_dump_state_init(DumpState *s, const char *filename,
                                int len, Error **errp)
 {
@@ -154,6 +133,48 @@ static int net_dump_state_init(DumpState *s, const char *filename,
     return 0;
 }
 
+/* Dumping via VLAN netclient */
+
+typedef struct DumpNetClient {
+    NetClientState nc;
+    DumpState ds;
+} DumpNetClient;
+
+static ssize_t dumpclient_receive(NetClientState *nc, const uint8_t *buf,
+                                  size_t size)
+{
+    DumpNetClient *dc = DO_UPCAST(DumpNetClient, nc, nc);
+    struct iovec iov = {
+        .iov_base = (void *)buf,
+        .iov_len = size
+    };
+
+    return dump_receive_iov(&dc->ds, &iov, 1);
+}
+
+static ssize_t dumpclient_receive_iov(NetClientState *nc,
+                                      const struct iovec *iov, int cnt)
+{
+    DumpNetClient *dc = DO_UPCAST(DumpNetClient, nc, nc);
+
+    return dump_receive_iov(&dc->ds, iov, cnt);
+}
+
+static void dumpclient_cleanup(NetClientState *nc)
+{
+    DumpNetClient *dc = DO_UPCAST(DumpNetClient, nc, nc);
+
+    dump_cleanup(&dc->ds);
+}
+
+static NetClientInfo net_dump_info = {
+    .type = NET_CLIENT_OPTIONS_KIND_DUMP,
+    .size = sizeof(DumpNetClient),
+    .receive = dumpclient_receive,
+    .receive_iov = dumpclient_receive_iov,
+    .cleanup = dumpclient_cleanup,
+};
+
 int net_init_dump(const NetClientOptions *opts, const char *name,
                   NetClientState *peer, Error **errp)
 {
@@ -162,6 +183,7 @@ int net_init_dump(const NetClientOptions *opts, const char *name,
     char def_file[128];
     const NetdevDumpOptions *dump;
     NetClientState *nc;
+    DumpNetClient *dnc;
 
     assert(opts->kind == NET_CLIENT_OPTIONS_KIND_DUMP);
     dump = opts->dump;
@@ -195,7 +217,8 @@ int net_init_dump(const NetClientOptions *opts, const char *name,
     snprintf(nc->info_str, sizeof(nc->info_str),
              "dump to %s (len=%d)", file, len);
 
-    rc = net_dump_state_init(DO_UPCAST(DumpState, nc, nc), file, len, errp);
+    dnc = DO_UPCAST(DumpNetClient, nc, nc);
+    rc = net_dump_state_init(&dnc->ds, file, len, errp);
     if (rc) {
         qemu_del_net_client(nc);
     }
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH RFC 4/5] net/dump: Provide the dumping facility as a net filter
  2015-08-27  2:33 [Qemu-devel] [PATCH RFC 0/5] Network traffic dumping via netfilter Thomas Huth
                   ` (2 preceding siblings ...)
  2015-08-27  2:33 ` [Qemu-devel] [PATCH RFC 3/5] net/dump: Separate the NetClientState from the DumpState Thomas Huth
@ 2015-08-27  2:33 ` Thomas Huth
  2015-08-27  3:03   ` Yang Hongyang
  2015-09-01 19:52   ` Eric Blake
  2015-08-27  2:33 ` [Qemu-devel] [PATCH RFC 5/5] net/dump: Add documentation Thomas Huth
  2015-08-27  3:29 ` [Qemu-devel] [PATCH RFC 0/5] Network traffic dumping via netfilter Jason Wang
  5 siblings, 2 replies; 10+ messages in thread
From: Thomas Huth @ 2015-08-27  2:33 UTC (permalink / raw)
  To: Stefan Hajnoczi, Jason Wang, qemu-devel, yanghy
  Cc: Markus Armbruster, Michael S. Tsirkin

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(-)

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

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH RFC 5/5] net/dump: Add documentation
  2015-08-27  2:33 [Qemu-devel] [PATCH RFC 0/5] Network traffic dumping via netfilter Thomas Huth
                   ` (3 preceding siblings ...)
  2015-08-27  2:33 ` [Qemu-devel] [PATCH RFC 4/5] net/dump: Provide the dumping facility as a net filter Thomas Huth
@ 2015-08-27  2:33 ` Thomas Huth
  2015-08-27  3:29 ` [Qemu-devel] [PATCH RFC 0/5] Network traffic dumping via netfilter Jason Wang
  5 siblings, 0 replies; 10+ messages in thread
From: Thomas Huth @ 2015-08-27  2:33 UTC (permalink / raw)
  To: Stefan Hajnoczi, Jason Wang, qemu-devel, yanghy
  Cc: Markus Armbruster, Michael S. Tsirkin

Add a short description for the command line options.

Signed-off-by: Thomas Huth <thuth@redhat.com>
---
 qemu-options.hx | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/qemu-options.hx b/qemu-options.hx
index 390e055..21cf129 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1578,7 +1578,10 @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
 DEF("netfilter", HAS_ARG, QEMU_OPTION_netfilter,
     "-netfilter buffer,id=str,netdev=str[,chain=in|out|all,interval=n]\n"
     "                buffer netdev in/out packets. if interval provided, will release\n"
-    "                packets by interval. interval scale: microsecond\n", QEMU_ARCH_ALL)
+    "                packets by interval. interval scale: microsecond\n"
+    "-netfilter dump,id=str,netdev=str,file=f[,maxlen=n,chain=in|out|all]\n"
+    "                dump network traffic to file 'f' (max n bytes per packet)\n",
+                     QEMU_ARCH_ALL)
 STEXI
 @item -net nic[,vlan=@var{n}][,macaddr=@var{mac}][,model=@var{type}] [,name=@var{name}][,addr=@var{addr}][,vectors=@var{v}]
 @findex -net
@@ -1984,10 +1987,12 @@ qemu -m 512 -object memory-backend-file,id=mem,size=512M,mem-path=/hugetlbfs,sha
      -device virtio-net-pci,netdev=net0
 @end example
 
-@item -net dump[,vlan=@var{n}][,file=@var{file}][,len=@var{len}]
-Dump network traffic on VLAN @var{n} to file @var{file} (@file{qemu-vlan0.pcap} by default).
-At most @var{len} bytes (64k by default) per packet are stored. The file format is
-libpcap, so it can be analyzed with tools such as tcpdump or Wireshark.
+@item -netfilter dump,id=@var{idstr},netdev=@var{dev},file=@var{file}[,maxlen=@var{len},chain=in|out|all]
+@itemx -net dump[,vlan=@var{n}][,file=@var{file}][,len=@var{len}]
+Dump network traffic on netdev @var{dev} (or VLAN @var{n} reciprocally) to
+file @var{file} (@file{qemu-vlan0.pcap} for '-net dump' by default).
+At most @var{len} bytes (64k by default) per packet are stored. The file format
+is libpcap, so it can be analyzed with tools such as tcpdump or Wireshark.
 
 @item -net none
 Indicate that no network devices should be configured. It is used to
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH RFC 4/5] net/dump: Provide the dumping facility as a net filter
  2015-08-27  2:33 ` [Qemu-devel] [PATCH RFC 4/5] net/dump: Provide the dumping facility as a net filter Thomas Huth
@ 2015-08-27  3:03   ` Yang Hongyang
  2015-09-01 19:52   ` Eric Blake
  1 sibling, 0 replies; 10+ messages in thread
From: Yang Hongyang @ 2015-08-27  3:03 UTC (permalink / raw)
  To: Thomas Huth, Stefan Hajnoczi, Jason Wang, qemu-devel
  Cc: Markus Armbruster, Michael S. Tsirkin

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
>

-- 
Thanks,
Yang.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH RFC 0/5] Network traffic dumping via netfilter
  2015-08-27  2:33 [Qemu-devel] [PATCH RFC 0/5] Network traffic dumping via netfilter Thomas Huth
                   ` (4 preceding siblings ...)
  2015-08-27  2:33 ` [Qemu-devel] [PATCH RFC 5/5] net/dump: Add documentation Thomas Huth
@ 2015-08-27  3:29 ` Jason Wang
  5 siblings, 0 replies; 10+ messages in thread
From: Jason Wang @ 2015-08-27  3:29 UTC (permalink / raw)
  To: Thomas Huth, Stefan Hajnoczi, qemu-devel, yanghy
  Cc: Markus Armbruster, Michael S. Tsirkin



On 08/27/2015 10:33 AM, Thomas Huth wrote:
> The "-net dump" option only works with the "-net" option. So far, it
> is not possible to dump network traffic with the "-netdev" option yet.
> This patch series now fixes this ugliness by enabling dumping for the
> netdev devices via the new netfilter infrastructure. It can be used
> like this for example:
>
>  qemu-system-ppc64 -nographic -vga none -device virtio-net,netdev=mynet \
>    -netdev user,id=mynet,tftp=/tmp/tftp,bootfile=zImage -boot n \
>    -netfilter dump,id=f0,netdev=mynet,file=/tmp/filterdump.dat
>
> This series is based on v8 of Yang Hongyang's netfilter patches
> (i.e. these have to be applied before the dumping patches can be
> used). Since these netfilter patches are not upstream yet and still
> might change the API in future versions, I'm sending my patches as
> "RFC" (but since the integration with the current netfilter patches
> was pretty easy already, they should be ready as normal patches very
> soon after the netfilter patches have been finalized).
>
> Thomas Huth (5):
>   net/dump: Add support for receive_iov function
>   net/dump: Rework net-dump init functions
>   net/dump: Separate the NetClientState from the DumpState
>   net/dump: Provide the dumping facility as a net filter
>   net/dump: Add documentation
>
>  net/dump.c       | 152 ++++++++++++++++++++++++++++++++++++++++++++-----------
>  net/filter.c     |   1 +
>  net/filters.h    |   2 +
>  qapi-schema.json |  20 +++++++-
>  qemu-options.hx  |  15 ++++--
>  5 files changed, 155 insertions(+), 35 deletions(-)
>

Looks good to me.

Thanks

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH RFC 4/5] net/dump: Provide the dumping facility as a net filter
  2015-08-27  2:33 ` [Qemu-devel] [PATCH RFC 4/5] net/dump: Provide the dumping facility as a net filter Thomas Huth
  2015-08-27  3:03   ` Yang Hongyang
@ 2015-09-01 19:52   ` Eric Blake
  2015-09-01 21:19     ` Thomas Huth
  1 sibling, 1 reply; 10+ messages in thread
From: Eric Blake @ 2015-09-01 19:52 UTC (permalink / raw)
  To: Thomas Huth, Stefan Hajnoczi, Jason Wang, qemu-devel, yanghy
  Cc: Markus Armbruster, Michael S. Tsirkin

[-- Attachment #1: Type: text/plain, Size: 1586 bytes --]

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.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH RFC 4/5] net/dump: Provide the dumping facility as a net filter
  2015-09-01 19:52   ` Eric Blake
@ 2015-09-01 21:19     ` Thomas Huth
  0 siblings, 0 replies; 10+ messages in thread
From: Thomas Huth @ 2015-09-01 21:19 UTC (permalink / raw)
  To: Eric Blake, Stefan Hajnoczi, Jason Wang, qemu-devel, yanghy
  Cc: Markus Armbruster, Michael S. Tsirkin

[-- Attachment #1: Type: text/plain, Size: 1720 bytes --]

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




[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2015-09-01 21:19 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-27  2:33 [Qemu-devel] [PATCH RFC 0/5] Network traffic dumping via netfilter Thomas Huth
2015-08-27  2:33 ` [Qemu-devel] [PATCH RFC 1/5] net/dump: Add support for receive_iov function Thomas Huth
2015-08-27  2:33 ` [Qemu-devel] [PATCH RFC 2/5] net/dump: Rework net-dump init functions Thomas Huth
2015-08-27  2:33 ` [Qemu-devel] [PATCH RFC 3/5] net/dump: Separate the NetClientState from the DumpState Thomas Huth
2015-08-27  2:33 ` [Qemu-devel] [PATCH RFC 4/5] net/dump: Provide the dumping facility as a net filter Thomas Huth
2015-08-27  3:03   ` Yang Hongyang
2015-09-01 19:52   ` Eric Blake
2015-09-01 21:19     ` Thomas Huth
2015-08-27  2:33 ` [Qemu-devel] [PATCH RFC 5/5] net/dump: Add documentation Thomas Huth
2015-08-27  3:29 ` [Qemu-devel] [PATCH RFC 0/5] Network traffic dumping via netfilter Jason Wang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.