On Sat, Feb 7, 2026 at 9:49 PM Cindy Lu <[email protected]> wrote: > > Packets injected from the redirector chardev are raw Ethernet frames without a > vnet_hdr prefix.
This may not be true as it could be the traffic from a remote redirector that is redirecting virtio-net traffic? Thanks > Mark them as RAW so downstream filters (e.g. dump) do not skip > vnet_hdr_len bytes, and strip the vnet_hdr prefix only when vnet_hdr_support > is > enabled and a valid prefix is present. > > Signed-off-by: Cindy Lu <[email protected]> > --- > net/filter-mirror.c | 30 +++++++++++++++++++++++++----- > 1 file changed, 25 insertions(+), 5 deletions(-) > > diff --git a/net/filter-mirror.c b/net/filter-mirror.c > index c1b9dabacd..de32028246 100644 > --- a/net/filter-mirror.c > +++ b/net/filter-mirror.c > @@ -146,6 +146,7 @@ static int filter_send(MirrorState *s, > } > > static void redirector_to_filter(NetFilterState *nf, > + unsigned flags, > const uint8_t *buf, > int len) > { > @@ -156,13 +157,13 @@ static void redirector_to_filter(NetFilterState *nf, > > if (nf->direction == NET_FILTER_DIRECTION_ALL || > nf->direction == NET_FILTER_DIRECTION_TX) { > - qemu_netfilter_pass_to_next(nf->netdev, 0, &iov, 1, nf); > + qemu_netfilter_pass_to_next(nf->netdev, flags, &iov, 1, nf); > } > > if (nf->direction == NET_FILTER_DIRECTION_ALL || > nf->direction == NET_FILTER_DIRECTION_RX) { > - qemu_netfilter_pass_to_next(nf->netdev->peer, 0, &iov, 1, nf); > - } > + qemu_netfilter_pass_to_next(nf->netdev->peer, flags, &iov, 1, nf); > + } > } > > static int redirector_chr_can_read(void *opaque) > @@ -294,12 +295,31 @@ static void redirector_rs_finalize(SocketReadState *rs) > { > MirrorState *s = container_of(rs, MirrorState, rs); > NetFilterState *nf = NETFILTER(s); > + const uint8_t *buf = rs->buf; > + int len = rs->packet_len; > > /* Update indev statistics */ > s->indev_packets++; > - s->indev_bytes += rs->packet_len; > + s->indev_bytes += len; > + > + /* > + * If the sender enables vnet_hdr_support, received data includes a > + * vnet_hdr prefix. Skip vnet_hdr_len bytes and pass the Ethernet frame. > + */ > + if (s->vnet_hdr) { > + if (rs->vnet_hdr_len <= 0 || rs->vnet_hdr_len >= len) { > + return; > + } > + buf += rs->vnet_hdr_len; > + len -= rs->vnet_hdr_len; > + } > > - redirector_to_filter(nf, rs->buf, rs->packet_len); > + /* > + * Packets injected from the chardev are raw Ethernet frames without a > + * vnet_hdr prefix. Mark them as RAW so downstream filters (e.g. dump) > + * won't try to skip a vnet_hdr_len. > + */ > + redirector_to_filter(nf, QEMU_NET_PACKET_FLAG_RAW, buf, len); > } > > static void filter_redirector_vm_state_change(void *opaque, bool running, > -- > 2.52.0 >
