Hello, As usual, several things here.
Chris Heinze, le mar. 03 sept. 2019 17:02:15 +0200, a ecrit: > root@guest:~# tcpdump -ni eth0 port 19003 > tcpdump: verbose output suppressed, use -v or -vv for full protocol decode > listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes > 16:49:39.430959 IP 10.0.2.2.33294 > 10.0.2.15.19003: UDP, bad length 9000 > > 1472 tcpdump seems to be showing dumb output here. The packet is fragmented by slirp, which makes tcpdump confused and show only the first fragment. If you let tcpdump print everything, you will see the other fragments. In reality, everything is going fine here. > i tried to change slirp/src/if.h to: > > #define IF_MTU 9000 > #define IF_MRU 9000 > > but the resulting qemu-system-x86_64 binary did not behave differently. Did you explicitly remove the qemu-system-x86_64 binary? As mentioned previously on the list, there seems to be a missing Makefile dependency. Now, with MTU set to 9000, the packets just don't go at all. Could you try the attached patch? The lowest layer of slirp was indeed limited to 1600-byte frames for no good reason. With this and the virtio driver, I could exchange 9000-byte packets. Samuel
diff --git a/src/slirp.c b/src/slirp.c index b0194cb..3fd6f68 100644 --- a/src/slirp.c +++ b/src/slirp.c @@ -890,20 +890,22 @@ static int if_encap6(Slirp *slirp, struct mbuf *ifm, struct ethhdr *eh, */ int if_encap(Slirp *slirp, struct mbuf *ifm) { - uint8_t buf[1600]; - struct ethhdr *eh = (struct ethhdr *)buf; + uint8_t *buf; + struct ethhdr *eh; uint8_t ethaddr[ETH_ALEN]; const struct ip *iph = (const struct ip *)ifm->m_data; int ret; - if (ifm->m_len + ETH_HLEN > sizeof(buf)) { - return 1; - } + buf = g_malloc(ifm->m_len + ETH_HLEN); + if (!buf) + return 0; + eh = (struct ethhdr *)buf; switch (iph->ip_v) { case IPVERSION: ret = if_encap4(slirp, ifm, eh, ethaddr); if (ret < 2) { + g_free(buf); return ret; } break; @@ -911,6 +913,7 @@ int if_encap(Slirp *slirp, struct mbuf *ifm) case IP6VERSION: ret = if_encap6(slirp, ifm, eh, ethaddr); if (ret < 2) { + g_free(buf); return ret; } break; @@ -929,6 +932,7 @@ int if_encap(Slirp *slirp, struct mbuf *ifm) eh->h_dest[5]); memcpy(buf + sizeof(struct ethhdr), ifm->m_data, ifm->m_len); slirp_send_packet_all(slirp, buf, ifm->m_len + ETH_HLEN); + g_free(buf); return 1; }