Commit 1c954ab8 authored by Pavel Tikhomirov's avatar Pavel Tikhomirov Committed by Pavel Emelyanov

net/sysctl: fix ipv4 forwarding

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
v2:quirk accept_redirects instead of duplicate entries in devconfs
Signed-off-by: 's avatarPavel Tikhomirov <ptikhomirov@virtuozzo.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent 3166032e
......@@ -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;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment