Add helper functions for sending packets through the AF_PACKET out socket or the chardev backend, and add netdev RX/TX packet and byte counters to MirrorState.
The follow-up receive-path changes use these helpers and expose the new statistics via filter_redirector_get_stats(). Signed-off-by: Cindy Lu <[email protected]> --- net/filter-mirror.c | 70 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/net/filter-mirror.c b/net/filter-mirror.c index 915f2f8b35..e57fbc94b8 100644 --- a/net/filter-mirror.c +++ b/net/filter-mirror.c @@ -64,6 +64,11 @@ struct MirrorState { uint64_t indev_bytes; uint64_t outdev_packets; uint64_t outdev_bytes; + /* netdev replay/capture statistics for filter-redirector */ + uint64_t netdev_rx_packets; + uint64_t netdev_rx_bytes; + uint64_t netdev_tx_packets; + uint64_t netdev_tx_bytes; }; typedef struct FilterSendCo { @@ -175,6 +180,59 @@ static int filter_send(MirrorState *s, return data.ret; } +static ssize_t filter_redirector_send_netdev_packet(MirrorState *s, + const struct iovec *iov, + int iovcnt) +{ + ssize_t size = iov_size(iov, iovcnt); + g_autofree uint8_t *buf = NULL; + + if (s->out_netfd < 0) { + return -ENODEV; + } + if (size > NET_BUFSIZE) { + return -EINVAL; + } + + buf = g_malloc(size); + iov_to_buf(iov, iovcnt, 0, buf, size); + + ssize_t ret = send(s->out_netfd, buf, size, 0); + if (ret < 0) { + return -errno; + } + if (ret > 0) { + s->netdev_tx_packets++; + s->netdev_tx_bytes += ret; + } + return ret; +} +static ssize_t filter_redirector_send_chardev_iov(MirrorState *s, + const struct iovec *iov, + int iovcnt) +{ + if (!s->outdev) { + return -ENODEV; + } + + if (!qemu_chr_fe_backend_connected(&s->chr_out)) { + return 0; + } + + return filter_send(s, iov, iovcnt); +} + +static ssize_t filter_redirector_send_netdev_iov(MirrorState *s, + const struct iovec *iov, + int iovcnt) +{ + if (s->out_netfd < 0) { + return -ENODEV; + } + + return filter_redirector_send_netdev_packet(s, iov, iovcnt); +} + static void redirector_to_filter(NetFilterState *nf, const uint8_t *buf, int len) @@ -763,6 +821,18 @@ static GList *filter_redirector_get_stats(NetFilterState *nf) counter->bytes = s->outdev_bytes; list = g_list_append(list, counter); + counter = g_new0(NetFilterCounter, 1); + counter->name = g_strdup("netdev_rx"); + counter->packets = s->netdev_rx_packets; + counter->bytes = s->netdev_rx_bytes; + list = g_list_append(list, counter); + + counter = g_new0(NetFilterCounter, 1); + counter->name = g_strdup("netdev_tx"); + counter->packets = s->netdev_tx_packets; + counter->bytes = s->netdev_tx_bytes; + list = g_list_append(list, counter); + return list; } -- 2.52.0
