summaryrefslogtreecommitdiff
path: root/qemu_patches/0002-slirp-allow-custom-MTU.patch
blob: c67923837465dbea7d8122a79bcfabe1547fe160 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
From a9af0f1d11b3ab12da9749d1f858dafb06c67bd8 Mon Sep 17 00:00:00 2001
From: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
Date: Wed, 6 Mar 2019 16:15:37 +0900
Subject: [PATCH 2/3] slirp: allow custom MTU

From slirp4netns project:
* https://github.com/rootless-containers/slirp4netns/commit/ea630a7e945cf538184ff1b1b4bd7b8ddc01993e
* https://github.com/rootless-containers/slirp4netns/commit/1508a66c93c223555f08651592dde3d2d708b166
* https://github.com/rootless-containers/slirp4netns/commit/19f3f41df4066d6103e6f882500e24db7ea7d9e1
* https://github.com/rootless-containers/slirp4netns/commit/a11abedafcc627ef0657999e63b211b0f26d4c02
* https://github.com/rootless-containers/slirp4netns/commit/2adbd7c449944d3b837164c86eedd3dcabbba1a6

Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
---
 slirp/src/dhcpv6.c    |  2 +-
 slirp/src/if.h        |  6 ++++--
 slirp/src/ip6_icmp.c  |  4 ++--
 slirp/src/ip6_input.c |  2 +-
 slirp/src/ip_output.c |  4 ++--
 slirp/src/libslirp.h  |  4 ++++
 slirp/src/mbuf.c      |  8 ++++----
 slirp/src/slirp.c     | 11 ++++++++++-
 slirp/src/slirp.h     |  3 +++
 slirp/src/tcp.h       | 18 +++---------------
 slirp/src/tcp_input.c |  6 +++---
 slirp/src/tcp_subr.c  |  2 +-
 12 files changed, 38 insertions(+), 32 deletions(-)

diff --git a/slirp/src/dhcpv6.c b/slirp/src/dhcpv6.c
index 3c8f420912..53bb90b541 100644
--- a/slirp/src/dhcpv6.c
+++ b/slirp/src/dhcpv6.c
@@ -177,7 +177,7 @@ static void dhcpv6_info_request(Slirp *slirp, struct sockaddr_in6 *srcsas,
 
         *resp++ = OPTION_BOOTFILE_URL >> 8;     /* option-code high byte */
         *resp++ = OPTION_BOOTFILE_URL;          /* option-code low byte */
-        smaxlen = (uint8_t *)m->m_data + IF_MTU - (resp + 2);
+        smaxlen = (uint8_t *)m->m_data + slirp->if_mtu - (resp + 2);
         slen = snprintf((char *)resp + 2, smaxlen,
                         "tftp://[%02x%02x:%02x%02x:%02x%02x:%02x%02x:"
                                 "%02x%02x:%02x%02x:%02x%02x:%02x%02x]/%s",
diff --git a/slirp/src/if.h b/slirp/src/if.h
index b71c37d6ea..7a47a12ab2 100644
--- a/slirp/src/if.h
+++ b/slirp/src/if.h
@@ -11,8 +11,10 @@
 #define IF_AUTOCOMP	0x04	/* Autodetect (default) */
 #define IF_NOCIDCOMP	0x08	/* CID compression */
 
-#define IF_MTU 1500
-#define IF_MRU 1500
+#define IF_MTU_DEFAULT 1500
+#define IF_MTU_MAX 65521
+#define IF_MRU_DEFAULT 1500
+#define IF_MRU_MAX 65521
 #define	IF_COMP IF_AUTOCOMP	/* Flags for compression */
 
 /* 2 for alignment, 14 for ethernet */
diff --git a/slirp/src/ip6_icmp.c b/slirp/src/ip6_icmp.c
index 5642457fdd..dcace933a9 100644
--- a/slirp/src/ip6_icmp.c
+++ b/slirp/src/ip6_icmp.c
@@ -93,7 +93,7 @@ void icmp6_send_error(struct mbuf *m, uint8_t type, uint8_t code)
 
     rip->ip_nh = IPPROTO_ICMPV6;
     const int error_data_len = MIN(m->m_len,
-            IF_MTU - (sizeof(struct ip6) + ICMP6_ERROR_MINLEN));
+            slirp->if_mtu - (sizeof(struct ip6) + ICMP6_ERROR_MINLEN));
     rip->ip_pl = htons(ICMP6_ERROR_MINLEN + error_data_len);
     t->m_len = sizeof(struct ip6) + ntohs(rip->ip_pl);
 
@@ -110,7 +110,7 @@ void icmp6_send_error(struct mbuf *m, uint8_t type, uint8_t code)
         ricmp->icmp6_err.unused = 0;
         break;
     case ICMP6_TOOBIG:
-        ricmp->icmp6_err.mtu = htonl(IF_MTU);
+        ricmp->icmp6_err.mtu = htonl(slirp->if_mtu);
         break;
     case ICMP6_PARAMPROB:
         /* TODO: Handle this case */
diff --git a/slirp/src/ip6_input.c b/slirp/src/ip6_input.c
index d9d2b7e9cd..dfcbfd6a78 100644
--- a/slirp/src/ip6_input.c
+++ b/slirp/src/ip6_input.c
@@ -44,7 +44,7 @@ void ip6_input(struct mbuf *m)
         goto bad;
     }
 
-    if (ntohs(ip6->ip_pl) > IF_MTU) {
+    if (ntohs(ip6->ip_pl) > slirp->if_mtu) {
         icmp6_send_error(m, ICMP6_TOOBIG, 0);
         goto bad;
     }
diff --git a/slirp/src/ip_output.c b/slirp/src/ip_output.c
index 8560197cf6..cd2ea7c72d 100644
--- a/slirp/src/ip_output.c
+++ b/slirp/src/ip_output.c
@@ -73,7 +73,7 @@ ip_output(struct socket *so, struct mbuf *m0)
 	/*
 	 * If small enough for interface, can just send directly.
 	 */
-	if ((uint16_t)ip->ip_len <= IF_MTU) {
+	if ((uint16_t)ip->ip_len <= slirp->if_mtu) {
 		ip->ip_len = htons((uint16_t)ip->ip_len);
 		ip->ip_off = htons((uint16_t)ip->ip_off);
 		ip->ip_sum = 0;
@@ -92,7 +92,7 @@ ip_output(struct socket *so, struct mbuf *m0)
 		goto bad;
 	}
 
-	len = (IF_MTU - hlen) &~ 7;       /* ip databytes per packet */
+	len = (slirp->if_mtu - hlen) &~ 7;       /* ip databytes per packet */
 	if (len < 8) {
 		error = -1;
 		goto bad;
diff --git a/slirp/src/libslirp.h b/slirp/src/libslirp.h
index bd141964ff..4e2d4ee6c7 100644
--- a/slirp/src/libslirp.h
+++ b/slirp/src/libslirp.h
@@ -83,6 +83,10 @@ typedef struct SlirpConfig{
     struct in6_addr vnameserver6;
     const char **vdnssearch;
     const char *vdomainname;
+    /* Default: IF_MTU_DEFAULT */
+    int if_mtu;
+    /* Default: IF_MRU_DEFAULT */
+    int if_mru;
 } SlirpConfig;
 
 Slirp *slirp_initx(const SlirpConfig *cfg, const SlirpCb *callbacks, void *opaque);
diff --git a/slirp/src/mbuf.c b/slirp/src/mbuf.c
index 800406ca9e..b1ac229b7b 100644
--- a/slirp/src/mbuf.c
+++ b/slirp/src/mbuf.c
@@ -20,8 +20,8 @@
 /*
  * Find a nice value for msize
  */
-#define SLIRP_MSIZE\
-    (offsetof(struct mbuf, m_dat) + IF_MAXLINKHDR + TCPIPHDR_DELTA + IF_MTU)
+#define SLIRP_MSIZE(mtu)\
+    (offsetof(struct mbuf, m_dat) + IF_MAXLINKHDR + TCPIPHDR_DELTA + (mtu))
 
 void
 m_init(Slirp *slirp)
@@ -68,7 +68,7 @@ m_get(Slirp *slirp)
 	DEBUG_CALL("m_get");
 
 	if (slirp->m_freelist.qh_link == &slirp->m_freelist) {
-                m = g_malloc(SLIRP_MSIZE);
+                m = g_malloc(SLIRP_MSIZE(slirp->if_mtu));
 		slirp->mbuf_alloced++;
 		if (slirp->mbuf_alloced > MBUF_THRESH)
 			flags = M_DOFREE;
@@ -83,7 +83,7 @@ m_get(Slirp *slirp)
 	m->m_flags = (flags | M_USEDLIST);
 
 	/* Initialise it */
-	m->m_size = SLIRP_MSIZE - offsetof(struct mbuf, m_dat);
+	m->m_size = SLIRP_MSIZE(slirp->if_mtu) - offsetof(struct mbuf, m_dat);
 	m->m_data = m->m_dat;
 	m->m_len = 0;
         m->m_nextpkt = NULL;
diff --git a/slirp/src/slirp.c b/slirp/src/slirp.c
index ee5833e18b..8c02913769 100644
--- a/slirp/src/slirp.c
+++ b/slirp/src/slirp.c
@@ -276,6 +276,13 @@ Slirp *slirp_initx(const SlirpConfig *cfg, const SlirpCb *callbacks, void *opaqu
     if (cfg == NULL) {
         return NULL;
     }
+    if (cfg->if_mtu > IF_MTU_MAX) {
+        return NULL;
+    }
+    if (cfg->if_mru > IF_MRU_MAX) {
+        return NULL;
+    }
+
     slirp = g_malloc0(sizeof(Slirp));
 
     slirp_init_once();
@@ -316,6 +323,8 @@ Slirp *slirp_initx(const SlirpConfig *cfg, const SlirpCb *callbacks, void *opaqu
     if (cfg->vdnssearch) {
         translate_dnssearch(slirp, cfg->vdnssearch);
     }
+    slirp->if_mtu = cfg->if_mtu == 0 ? IF_MTU_DEFAULT : cfg->if_mtu;
+    slirp->if_mru = cfg->if_mru == 0 ? IF_MRU_DEFAULT : cfg->if_mru;
 
     return slirp;
 }
@@ -924,7 +933,7 @@ static int if_encap6(Slirp *slirp, struct mbuf *ifm, struct ethhdr *eh,
  */
 int if_encap(Slirp *slirp, struct mbuf *ifm)
 {
-    uint8_t buf[1600];
+    uint8_t buf[IF_MTU_MAX+100];
     struct ethhdr *eh = (struct ethhdr *)buf;
     uint8_t ethaddr[ETH_ALEN];
     const struct ip *iph = (const struct ip *)ifm->m_data;
diff --git a/slirp/src/slirp.h b/slirp/src/slirp.h
index 39580934f3..1c485be36f 100644
--- a/slirp/src/slirp.h
+++ b/slirp/src/slirp.h
@@ -146,6 +146,9 @@ struct Slirp {
     int restricted;
     struct gfwd_list *guestfwd_list;
 
+    int if_mtu;
+    int if_mru;
+
     /* mbuf states */
     struct quehead m_freelist;
     struct quehead m_usedlist;
diff --git a/slirp/src/tcp.h b/slirp/src/tcp.h
index 79d3251bb5..fca5c13db5 100644
--- a/slirp/src/tcp.h
+++ b/slirp/src/tcp.h
@@ -41,8 +41,9 @@ typedef	uint32_t tcp_seq;
 #define      PR_SLOWHZ       2               /* 2 slow timeouts per second (approx) */
 #define      PR_FASTHZ       5               /* 5 fast timeouts per second (not important) */
 
-#define TCP_SNDSPACE 8192
-#define TCP_RCVSPACE 8192
+#define TCP_SNDSPACE 1024*128
+#define TCP_RCVSPACE 1024*128
+#define TCP_MAXSEG_MAX 32768
 
 /*
  * TCP header.
@@ -99,19 +100,6 @@ struct tcphdr {
 #define    TCPOLEN_TSTAMP_APPA		(TCPOLEN_TIMESTAMP+2) /* appendix A */
 #endif
 
-/*
- * Default maximum segment size for TCP.
- * With an IP MSS of 576, this is 536,
- * but 512 is probably more convenient.
- * This should be defined as MIN(512, IP_MSS - sizeof (struct tcpiphdr)).
- *
- * We make this 1460 because we only care about Ethernet in the qemu context.
- */
-#undef TCP_MSS
-#define	TCP_MSS	1460
-#undef TCP6_MSS
-#define TCP6_MSS 1440
-
 #undef TCP_MAXWIN
 #define	TCP_MAXWIN	65535	/* largest value for (unscaled) window */
 
diff --git a/slirp/src/tcp_input.c b/slirp/src/tcp_input.c
index 50a1145ec9..14a489e61a 100644
--- a/slirp/src/tcp_input.c
+++ b/slirp/src/tcp_input.c
@@ -1522,11 +1522,11 @@ tcp_mss(struct tcpcb *tp, unsigned offer)
 
 	switch (so->so_ffamily) {
 	case AF_INET:
-            mss = MIN(IF_MTU, IF_MRU) - sizeof(struct tcphdr)
+            mss = MIN(so->slirp->if_mtu, so->slirp->if_mru) - sizeof(struct tcphdr)
 	                              - sizeof(struct ip);
 	    break;
 	case AF_INET6:
-            mss = MIN(IF_MTU, IF_MRU) - sizeof(struct tcphdr)
+            mss = MIN(so->slirp->if_mtu, so->slirp->if_mru) - sizeof(struct tcphdr)
 	                              - sizeof(struct ip6);
 	    break;
 	default:
@@ -1537,7 +1537,7 @@ tcp_mss(struct tcpcb *tp, unsigned offer)
             mss = MIN(mss, offer);
         mss = MAX(mss, 32);
 	if (mss < tp->t_maxseg || offer != 0)
-	   tp->t_maxseg = mss;
+        tp->t_maxseg = MIN(mss, TCP_MAXSEG_MAX);
 
 	tp->snd_cwnd = mss;
 
diff --git a/slirp/src/tcp_subr.c b/slirp/src/tcp_subr.c
index fde9207b0c..e88e51e39c 100644
--- a/slirp/src/tcp_subr.c
+++ b/slirp/src/tcp_subr.c
@@ -259,7 +259,7 @@ tcp_newtcpcb(struct socket *so)
 
 	memset((char *) tp, 0, sizeof(struct tcpcb));
 	tp->seg_next = tp->seg_prev = (struct tcpiphdr*)tp;
-	tp->t_maxseg = (so->so_ffamily == AF_INET) ? TCP_MSS : TCP6_MSS;
+	tp->t_maxseg = MIN(so->slirp->if_mtu - ((so->so_ffamily == AF_INET) ? 40 : 60), TCP_MAXSEG_MAX);
 
 	tp->t_flags = TCP_DO_RFC1323 ? (TF_REQ_SCALE|TF_REQ_TSTMP) : 0;
 	tp->t_socket = so;
-- 
2.20.1