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


Reply via email to