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 <lulu@redhat.com>
---
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