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
