On Mon, Feb 9, 2026 at 9:49 AM Jason Wang <[email protected]> wrote: > > 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 > Hi Jason sorry I should make the commit log more clear, in the code. I use the s->vnet_hdr to check the if they use the vnet_hdr, if yes then remove the head. I should rewrite this commit log, what I mean is after this redirector process all the packet would be the marked as RAW Thanks cindy
> > 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 > > >
