[CRIU] [PATCH 1/2 v2] net/sysctl: fix ipv4 forwarding

Pavel Tikhomirov ptikhomirov at virtuozzo.com
Thu Jun 16 00:46:21 PDT 2016


Restore all/accept_redirects and default/forwarding after
all/forwarding as the last can influence the former two.
(see inet_forward_change in kernel)

# sysctl -w net.ipv4.conf.all.forwarding=1
net.ipv4.conf.all.forwarding = 1
# sysctl -w net.ipv4.conf.default.forwarding=1
net.ipv4.conf.default.forwarding = 1
# sysctl -w net.ipv4.conf.all.forwarding=0
net.ipv4.conf.all.forwarding = 0
# sysctl net.ipv4.conf.default.forwarding
net.ipv4.conf.default.forwarding = 0

Trigered with netns-dev test in VZ7CT with vzlinux-6-x86_64 template
https://jira.sw.ru/browse/PSBM-47355

v2:quirk accept_redirects instead of duplicate entries in devconfs

Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
---
 criu/net.c | 31 ++++++++++++++++++++++++++-----
 1 file changed, 26 insertions(+), 5 deletions(-)

diff --git a/criu/net.c b/criu/net.c
index d57e0aa..a6d5f00 100644
--- a/criu/net.c
+++ b/criu/net.c
@@ -163,7 +163,7 @@ static int net_conf_op(char *tgt, SysctlEntry **conf, int n, int op, char *proto
 		struct sysctl_req *req, char (*path)[MAX_CONF_OPT_PATH], int size,
 		char **devconfs, SysctlEntry **def_conf)
 {
-	int i, ri;
+	int i, ri, ar = -1;
 	int ret, flags = op == CTL_READ ? CTL_FLAGS_OPTIONAL : 0;
 	SysctlEntry **rconf;
 
@@ -190,6 +190,15 @@ static int net_conf_op(char *tgt, SysctlEntry **conf, int n, int op, char *proto
 			continue;
 		}
 
+		/*
+		 * Make "accept_redirects" go last on write(it should
+		 * restore after forwarding to be correct)
+		 */
+		if (op == CTL_WRITE && !strcmp(devconfs[i], "accept_redirects")) {
+			ar = i;
+			continue;
+		}
+
 		snprintf(path[i], MAX_CONF_OPT_PATH, CONF_OPT_PATH, proto, tgt, devconfs[i]);
 		req[ri].name = path[i];
 		switch (conf[i]->type) {
@@ -221,6 +230,18 @@ static int net_conf_op(char *tgt, SysctlEntry **conf, int n, int op, char *proto
 		ri++;
 	}
 
+	if (ar != -1
+	    && conf[ar]->type == SYSCTL_TYPE__CTL_32
+	    && conf[ar]->has_iarg) {
+		snprintf(path[ar], MAX_CONF_OPT_PATH, CONF_OPT_PATH, proto, tgt, devconfs[ar]);
+		req[ri].name = path[ar];
+		req[ri].type = CTL_32;
+		req[ri].arg = &conf[ar]->iarg;
+		req[ri].flags = flags;
+		rconf[ri] = conf[ar];
+		ri++;
+	}
+
 	ret = sysctl_op(req, ri, op, CLONE_NEWNET);
 	if (ret < 0) {
 		pr_err("Failed to %s %s/<confs>\n", (op == CTL_READ)?"read":"write", tgt);
@@ -1327,18 +1348,18 @@ static int restore_netns_conf(int pid, NetnsEntry **netns)
 	}
 
 	if ((*netns)->def_conf4) {
-		ret = ipv4_conf_op("default", (*netns)->def_conf4, (*netns)->n_def_conf4, CTL_WRITE, NULL);
+		ret = ipv4_conf_op("all", (*netns)->all_conf4, (*netns)->n_all_conf4, CTL_WRITE, NULL);
 		if (ret)
 			goto out;
-		ret = ipv4_conf_op("all", (*netns)->all_conf4, (*netns)->n_all_conf4, CTL_WRITE, NULL);
+		ret = ipv4_conf_op("default", (*netns)->def_conf4, (*netns)->n_def_conf4, CTL_WRITE, NULL);
 		if (ret)
 			goto out;
 	} else if ((*netns)->def_conf) {
 		/* Backward compatibility */
-		ret = ipv4_conf_op_old("default", (*netns)->def_conf, (*netns)->n_def_conf, CTL_WRITE, NULL);
+		ret = ipv4_conf_op_old("all", (*netns)->all_conf, (*netns)->n_all_conf, CTL_WRITE, NULL);
 		if (ret)
 			goto out;
-		ret = ipv4_conf_op_old("all", (*netns)->all_conf, (*netns)->n_all_conf, CTL_WRITE, NULL);
+		ret = ipv4_conf_op_old("default", (*netns)->def_conf, (*netns)->n_def_conf, CTL_WRITE, NULL);
 		if (ret)
 			goto out;
 	}
-- 
2.5.5



More information about the CRIU mailing list