aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Hooper <wsh@wshooper.org>2024-01-06 14:35:46 -0800
committerPhilippe Mathieu-Daudé <philmd@linaro.org>2024-12-31 21:21:34 +0100
commit79b6a98587c65c8b8fdde8eb778396f1fc98a852 (patch)
tree354465284fbf512e6af3fd72a8e6fb198e867738
parent67e908c936b5f568b2ee913c1558e0235cd96293 (diff)
downloadqemu-79b6a98587c65c8b8fdde8eb778396f1fc98a852.zip
qemu-79b6a98587c65c8b8fdde8eb778396f1fc98a852.tar.gz
qemu-79b6a98587c65c8b8fdde8eb778396f1fc98a852.tar.bz2
net/vmnet: Pad short Ethernet frames
At least on macOS 12.7.2, vmnet doesn't pad Ethernet frames, such as the host's ARP replies, to the minimum size (60 bytes before the frame check sequence) defined in IEEE Std 802.3-2022, so guests' Ethernet device drivers may drop them with "frame too short" errors. This patch calls eth_pad_short_frame() to add padding, as in net/tap.c and net/slirp.c. Thanks to Bin Meng, Philippe Mathieu-Daudé, and Phil Dennis-Jordan for reviewing earlier versions. Signed-off-by: William Hooper <wsh@wshooper.org> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2058 Reviewed-by: Phil Dennis-Jordan <phil@philjordan.eu> Message-ID: <20241102205653.30476-1-wsh@wshooper.org> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
-rw-r--r--net/vmnet-common.m23
1 files changed, 20 insertions, 3 deletions
diff --git a/net/vmnet-common.m b/net/vmnet-common.m
index dba5b5b..54d900b 100644
--- a/net/vmnet-common.m
+++ b/net/vmnet-common.m
@@ -18,6 +18,7 @@
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "system/runstate.h"
+#include "net/eth.h"
#include <vmnet/vmnet.h>
#include <dispatch/dispatch.h>
@@ -147,10 +148,26 @@ static int vmnet_read_packets(VmnetState *s)
*/
static void vmnet_write_packets_to_qemu(VmnetState *s)
{
+ uint8_t *pkt;
+ size_t pktsz;
+ uint8_t min_pkt[ETH_ZLEN];
+ size_t min_pktsz;
+ ssize_t size;
+
while (s->packets_send_current_pos < s->packets_send_end_pos) {
- ssize_t size = qemu_send_packet_async(&s->nc,
- s->iov_buf[s->packets_send_current_pos].iov_base,
- s->packets_buf[s->packets_send_current_pos].vm_pkt_size,
+ pkt = s->iov_buf[s->packets_send_current_pos].iov_base;
+ pktsz = s->packets_buf[s->packets_send_current_pos].vm_pkt_size;
+
+ if (net_peer_needs_padding(&s->nc)) {
+ min_pktsz = sizeof(min_pkt);
+
+ if (eth_pad_short_frame(min_pkt, &min_pktsz, pkt, pktsz)) {
+ pkt = min_pkt;
+ pktsz = min_pktsz;
+ }
+ }
+
+ size = qemu_send_packet_async(&s->nc, pkt, pktsz,
vmnet_send_completed);
if (size == 0) {