On Wed, 24 Jun 2026 at 07:57, Bin Meng <[email protected]> wrote:
>
> Hi Peter,
>
> On Tue, Jun 23, 2026 at 6:56 PM Peter Maydell <[email protected]> 
> wrote:
> >
> > What is the general design principle for QEMU's handling of "short"
> > packets, which are less than the 60 byte ethernet frame minimum?
> >
> > In commit 969e50b61a285b0 ("net: Pad short frames to minimum size
> > before sending from SLiRP/TAP") we made the slirp and tap backends
> > add padding to short packets before feeding them into the net
> > code via qemu_send_packet() and friends, with the idea that we could
> > then remove (often buggy) code from network device emulation that
> > tried to handle the short-packet in its receive path.
> >
> > In commit 79b6a985 we realized we also needed to do this for the vmnet
> > backend. The issue https://gitlab.com/qemu-project/qemu/-/work_items/2362
> > reports that we also need to do this for socket and dgram and similar
> > backends.
> >
> > I'm trying to identify what the underlying logic here is. My current
> > best guess is:
> >  - we should always pad before feeding in a packet which is going
> >    to be sent to an ethernet device model (unless that device model
> >    has explicitly opted in via do_not_pad, e.g. because it really does
> >    want to faithfully model the card's handling of short packets
> >    and it's gone to the trouble of getting it right)
> >  - we should not pad before feeding in a packet which is going to
> >    be sent to a network backend (i.e. where the guest is sending out
> >    to slirp/tap/etc)
> >
>
> Yes, your two bullets match the intent of the original series.
>
> The do_not_pad flag was intended to describe a property of the
> destination. Packets delivered to an Ethernet device model should
> normally be padded, unless that model explicitly wants to handle short
> frames itself. In the other direction, a backend should receive what
> the device model actually transmitted, since TX padding behaviour is
> part of the device being modelled.

Mmm. Something I thought of yesterday after I sent it is that we're
kind of trying to do two things here, though:

(1) we would like to have network devices have to opt in to "I can
deal with processing short packets", for simplicity and to avoid
bugs

(2) some backends emit packets which are not actually off a
piece of ethernet and so nobody has padded them out to the
frame length

So even if a device wants to opt-in to handling short packets
so it can report to the guest "I received and discarded 42
short packets", backends like slirp and socket that aren't
getting real pre-padded ethernet packets still do need to
do the padding.

That seems to me to suggest that the source of a packet should
also have a say in whether or not it ought to be padded, not
just the destination.

I guess I'm not totally sure whether the length of a packet is
supposed to be its payload length, or the ethernet frame length.
(i.e. if you get a 40 byte packet from QEMU, are you supposed
to assume that it's actually a valid ethernet frame and should
be implicitly treated as if it were zero-padded?)

> > Could we do this by having qemu_send_packet() etc always pad, and
> > have the slirp/tap/etc backends set the do_not_pad flag on their
> > NetClientState structs to suppress this? Would that be better than
> > having all the backends do "and pad this" for their sending code?
> >
>
> I agree that centralizing this in the net core is preferable to adding
> padding separately to every backend. I would also consider making
> do_not_pad the default for qemu_new_net_client() users, since those
> are the backends and hub ports, while qemu_new_nic() users would
> retain the default padding policy. That avoids repeating the same
> omission for new backends.

That's basically the conclusion I came to (I have some draft
patches at https://gitlab.com/pm215/qemu/-/commits/short-packets
that do it that way).

> > At the moment the only user of do_not_pad is the virtio-net device.
> > commit d4c6293041 just says "there is no need to pad" and doesn't
> > give rationale. Why is this particular network device a special case?
> >
>
> virtio-net was made an exception because it is a length-delimited
> paravirtual interface rather than a physical MAC. Its receive path can
> deliver a short Ethernet packet such as a 42-byte ARP packet directly
> to the guest, so padding it is unnecessary and changes the packet
> length visible to the guest.
>
> > Are there any special cases where code calls qemu_send_packet
> > or qemu_sendv_packet which aren't either "a network device"
> > or "a backend"? There's net/hub.c -- I guess that should set
> > do_not_pad for its inputs, so it faithfully passes through
> > short packets and lets the destinations decide whether they want
> > them padded or not. Anything else?
> >
>
> Yep, there are a few things to take care of:
>
> * qemu_sendv_packet*() needs the same handling as qemu_send_packet*().
> * qemu_receive_packet() bypasses the send path for device loopback.
> Its current net_peer_needs_padding(nc) check would become wrong once
> backends or hub ports set do_not_pad: the receiver there is nc itself,
> not nc->peer.

Thanks -- I'll check this bit.

I think we also have some loopback implementations that don't
go via qemu_receive_packet(), but I forget the details.

> * Hub ports should opt out on the ingress side, allowing each
> destination to make its own padding decision.

Yep. The hub calls qeum_new_net_client() so this happens
automatically.

-- PMM

Reply via email to