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;
 }
 

Reply via email to