Skip to content

Commit f014fd0

Browse files
committed
add workaround for the port-fowarding performance issue w/ kernel 4.20
The kernel 4.20 bumped up the default value of `/proc/sys/net/ipv4/tcp_rmem` from 87380 to 131072. torvalds/linux@a337531 This is known to slow down slirp4netns port forwarding: rootless-containers#128 As a workaround, it is recommended to modify `/proc/sys/net/ipv4/tcp_rmem` inside the namespace. The file is automatically modified when running with `--configure`. Update rootless-containers#128 Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
1 parent bbd6f25 commit f014fd0

File tree

3 files changed

+90
-0
lines changed

3 files changed

+90
-0
lines changed

main.c

+51
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <getopt.h>
2020
#include <stdbool.h>
2121
#include <regex.h>
22+
#include <glib.h>
2223
#include "slirp4netns.h"
2324

2425
#define DEFAULT_MTU (1500)
@@ -120,6 +121,54 @@ static int sendfd(int sock, int fd)
120121
return rc;
121122
}
122123

124+
125+
/*
126+
kernel 4.20 bumped up the default value of /proc/sys/net/ipv4/tcp_rmem from
127+
87380 to 131072. This is known to slow down slirp4netns port forwarding. See
128+
https://github.com/rootless-containers/slirp4netns/issues/128 See
129+
https://github.com/torvalds/linux/commit/a337531b942bd8a03e7052444d7e36972aac2d92
130+
*/
131+
static void try_configure_kernel420_net_ipv4_tcp_rmem()
132+
{
133+
gchar *contents = NULL;
134+
gsize length = 0;
135+
gchar **tokenv = NULL;
136+
int nfd = -1;
137+
if (!g_file_get_contents("/proc/sys/net/ipv4/tcp_rmem", &contents, &length,
138+
NULL)) {
139+
goto ret;
140+
}
141+
tokenv = g_strsplit_set(contents, " \t\r\n", 4);
142+
if (g_strv_length(tokenv) != 4) {
143+
goto ret;
144+
}
145+
/* when running with kernel < 4.20, tokenv is like {"4096", "87380",
146+
* "6291456", ""} (preferred) */
147+
/* when running with kernel >= 4.20, tokenv is like {"4096", "131072",
148+
* "6291456", ""} (not preferred) */
149+
if (g_strcmp0(tokenv[1], "87380") == 0) {
150+
/* no need to adjust */
151+
goto ret;
152+
}
153+
/* g_file_set_contents() can't be used as it attempts to create
154+
* /proc/sys/net/ipv4/tcp_rmem.RANDOMSTR */
155+
nfd = open("/proc/sys/net/ipv4/tcp_rmem", O_WRONLY);
156+
if (nfd < 0) {
157+
goto ret;
158+
}
159+
if (dprintf(nfd, "%s\t%s\t%s%s\n", tokenv[0], "87380",
160+
g_strcmp0(tokenv[2], "131072") == 0 ? "87380" : tokenv[2],
161+
tokenv[3]) > 0) {
162+
printf("configure: Adjusted the value of /proc/sys/net/ipv4/tcp_rmem "
163+
"inside the namespace (131072 -> 87380)\n");
164+
}
165+
ret:
166+
if (nfd >= 0)
167+
close(nfd);
168+
g_strfreev(tokenv);
169+
g_free(contents);
170+
}
171+
123172
static int configure_network(const char *tapname,
124173
struct slirp4netns_config *cfg)
125174
{
@@ -191,6 +240,8 @@ static int configure_network(const char *tapname,
191240
perror("set route");
192241
return -1;
193242
}
243+
244+
try_configure_kernel420_net_ipv4_tcp_rmem();
194245
return 0;
195246
}
196247

slirp4netns.1

+24
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ IPv6 DNS: fd00::3
4545
\fB\-c\fP, \fB\-\-configure\fP
4646
bring up the TAP interface. IP will be set to 10.0.2.100 (network address + 100) by default. IPv6 will be set to a random address.
4747
Starting with v0.4.0, the loopback interface (\fBlo\fP) is brought up as well.
48+
Starting with v0.4.0, \fB/proc/sys/net/ipv4/tcp\_rmem\fP in the namespace is adjusted when running with kernel >= 4.20.
49+
This adjustment may differ in the future releases. (See BUGS)
4850

4951
.PP
5052
\fB\-e\fP, \fB\-\-exit\-fd=FD\fP
@@ -328,6 +330,28 @@ $ slirp4netns \-\-netns\-type=path \-\-userns\-path=/path/to/userns /path/to/net
328330
.RE
329331

330332

333+
.SH BUGS
334+
.PP
335+
Kernel 4.20 bumped up the default value of \fB/proc/sys/net/ipv4/tcp\_rmem\fP from 87380 to 131072.
336+
This is known to slow down slirp4netns port forwarding: \fBhttps://github.com/rootless\-containers/slirp4netns/issues/128\fP\&.
337+
338+
.PP
339+
As a workaround, you can adjust the value of \fB/proc/sys/net/ipv4/tcp\_rmem\fP inside the namespace.
340+
No real root privilege is needed to modify the file since kernel 4.15.
341+
342+
.PP
343+
.RS
344+
345+
.nf
346+
unshared$ c=$(cat /proc/sys/net/ipv4/tcp\_rmem); echo $c | sed \-e s/131072/87380/g > /proc/sys/net/ipv4/tcp\_rmem
347+
348+
.fi
349+
.RE
350+
351+
.PP
352+
Since slirp4netns v0.4.0, the value is automatically adjusted when running with \fB\-\-configure\fP\&.
353+
354+
331355
.SH SEE ALSO
332356
.PP
333357
\fBnetwork\_namespaces\fP(7), \fBuser\_namespaces\fP(7), \fBveth\fP(4)

slirp4netns.1.md

+15
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ Default configuration:
3030
**-c**, **--configure**
3131
bring up the TAP interface. IP will be set to 10.0.2.100 (network address + 100) by default. IPv6 will be set to a random address.
3232
Starting with v0.4.0, the loopback interface (**lo**) is brought up as well.
33+
Starting with v0.4.0, **/proc/sys/net/ipv4/tcp_rmem** in the namespace is adjusted when running with kernel >= 4.20.
34+
This adjustment may differ in the future releases. (See BUGS)
3335

3436
**-e**, **--exit-fd=FD**
3537
specify the FD for terminating slirp4netns.
@@ -206,6 +208,19 @@ Additionally, a **--userns-path=PATH** argument can be included to override any
206208
```console
207209
$ slirp4netns --netns-type=path --userns-path=/path/to/userns /path/to/netns tap0
208210
```
211+
# BUGS
212+
213+
Kernel 4.20 bumped up the default value of **/proc/sys/net/ipv4/tcp_rmem** from 87380 to 131072.
214+
This is known to slow down slirp4netns port forwarding: **https://github.com/rootless-containers/slirp4netns/issues/128**.
215+
216+
As a workaround, you can adjust the value of **/proc/sys/net/ipv4/tcp_rmem** inside the namespace.
217+
No real root privilege is needed to modify the file since kernel 4.15.
218+
219+
```console
220+
unshared$ c=$(cat /proc/sys/net/ipv4/tcp_rmem); echo $c | sed -e s/131072/87380/g > /proc/sys/net/ipv4/tcp_rmem
221+
```
222+
223+
Since slirp4netns v0.4.0, the value is automatically adjusted when running with **--configure**.
209224

210225
# SEE ALSO
211226

0 commit comments

Comments
 (0)