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.

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

> 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.
* Hub ports should opt out on the ingress side, allowing each
destination to make its own padding decision.

Regards,
Bin

Reply via email to