mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-22 01:51:51 +00:00
net/sysctl: c/r ipv4/ping_group_range value
It is per net namespace, we need it to allow creation of unprivileged ICMP sockets. Note: in case this sysctl was disabled after unprivileged ICMP socket was created we still need to somehow handle it on restore. Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
This commit is contained in:
parent
7f35e46e9d
commit
f38e58836a
103
criu/net.c
103
criu/net.c
@ -2128,6 +2128,79 @@ nft_ctx_free_out:
|
||||
}
|
||||
#endif
|
||||
|
||||
static const char *ipv4_sysctl_entries[] = {
|
||||
"ping_group_range",
|
||||
};
|
||||
|
||||
#define IPV4_SYSCTL_BASE "net/ipv4"
|
||||
#define IPV4_SYSCTL_FMT IPV4_SYSCTL_BASE"/%s"
|
||||
#define MAX_IPV4_SYSCTL_OPT 32
|
||||
#define MAX_IPV4_SYSCTL_PATH (sizeof(IPV4_SYSCTL_FMT) + MAX_IPV4_SYSCTL_OPT - 2)
|
||||
#define MAX_STR_IPV4_SYSCTL_LEN 200
|
||||
|
||||
static int ipv4_sysctls_op(SysctlEntry ***rsysctl, size_t *pn, int op)
|
||||
{
|
||||
int i, ret = -1, flags = 0;
|
||||
char path[ARRAY_SIZE(ipv4_sysctl_entries)][MAX_IPV4_SYSCTL_PATH] = {};
|
||||
struct sysctl_req req[ARRAY_SIZE(ipv4_sysctl_entries)] = {};
|
||||
SysctlEntry **sysctl = *rsysctl;
|
||||
size_t n = *pn;
|
||||
|
||||
if (n != ARRAY_SIZE(ipv4_sysctl_entries)) {
|
||||
pr_err("unix: Unexpected entries in sysctlig (%zu %zu)\n", n, ARRAY_SIZE(ipv4_sysctl_entries));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (opts.weak_sysctls || op == CTL_READ)
|
||||
flags = CTL_FLAGS_OPTIONAL;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
snprintf(path[i], MAX_IPV4_SYSCTL_PATH, IPV4_SYSCTL_FMT, ipv4_sysctl_entries[i]);
|
||||
req[i].name = path[i];
|
||||
req[i].flags = flags;
|
||||
|
||||
switch (sysctl[i]->type) {
|
||||
case SYSCTL_TYPE__CTL_STR:
|
||||
req[i].type = CTL_STR(MAX_STR_IPV4_SYSCTL_LEN);
|
||||
|
||||
/* skip write if have no value */
|
||||
if (op == CTL_WRITE && !sysctl[i]->sarg)
|
||||
continue;
|
||||
|
||||
req[i].arg = sysctl[i]->sarg;
|
||||
break;
|
||||
default:
|
||||
pr_err("ipv4: Unknown sysctl type %d\n", sysctl[i]->type);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ret = sysctl_op(req, n, op, CLONE_NEWNET);
|
||||
if (ret < 0) {
|
||||
pr_err("unix: Failed to %s %s/<sysctls>\n", (op == CTL_READ) ? "read" : "write", IPV4_SYSCTL_BASE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (op == CTL_READ) {
|
||||
bool has_entries = false;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (req[i].flags & CTL_FLAGS_HAS) {
|
||||
sysctl[i]->has_iarg = true;
|
||||
if (!has_entries)
|
||||
has_entries = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_entries) {
|
||||
*pn = 0;
|
||||
*rsysctl = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds)
|
||||
{
|
||||
void *buf, *o_buf;
|
||||
@ -2142,6 +2215,9 @@ static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds)
|
||||
int size6 = ARRAY_SIZE(devconfs6);
|
||||
char def_stable_secret[MAX_STR_CONF_LEN + 1] = {};
|
||||
char all_stable_secret[MAX_STR_CONF_LEN + 1] = {};
|
||||
SysctlEntry *ipv4_sysctls = NULL;
|
||||
size_t ipv4_sysctl_size = ARRAY_SIZE(ipv4_sysctl_entries);
|
||||
char ping_group_range[MAX_STR_IPV4_SYSCTL_LEN + 1] = {};
|
||||
NetnsId *ids;
|
||||
struct netns_id *p;
|
||||
|
||||
@ -2157,7 +2233,7 @@ static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds)
|
||||
* arrays and then finally save them into images.
|
||||
*/
|
||||
o_buf = buf = xmalloc(i * (sizeof(NetnsId *) + sizeof(NetnsId)) +
|
||||
(size4 * 2 + size6 * 2 + sizex) *
|
||||
(2 * size4 + 2 * size6 + sizex + ipv4_sysctl_size) *
|
||||
(sizeof(SysctlEntry *) + sizeof(SysctlEntry)));
|
||||
if (!buf)
|
||||
goto out;
|
||||
@ -2223,6 +2299,21 @@ static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds)
|
||||
netns.unix_conf[i]->type = SYSCTL_TYPE__CTL_32;
|
||||
}
|
||||
|
||||
netns.n_ipv4_sysctl = ipv4_sysctl_size;
|
||||
netns.ipv4_sysctl = xptr_pull_s(&buf, ipv4_sysctl_size * sizeof(SysctlEntry *));
|
||||
ipv4_sysctls = xptr_pull_s(&buf, ipv4_sysctl_size * sizeof(SysctlEntry));
|
||||
for (i = 0; i < ipv4_sysctl_size; i++) {
|
||||
sysctl_entry__init(&ipv4_sysctls[i]);
|
||||
netns.ipv4_sysctl[i] = &ipv4_sysctls[i];
|
||||
if (!strcmp(ipv4_sysctl_entries[i], "ping_group_range")) {
|
||||
netns.ipv4_sysctl[i]->type = SYSCTL_TYPE__CTL_STR;
|
||||
netns.ipv4_sysctl[i]->sarg = ping_group_range;
|
||||
} else {
|
||||
/* Need to handle this case when we have more sysctls */
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
ret = ipv4_conf_op("default", netns.def_conf4, size4, CTL_READ, NULL);
|
||||
if (ret < 0)
|
||||
goto err_free;
|
||||
@ -2241,6 +2332,10 @@ static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds)
|
||||
if (ret < 0)
|
||||
goto err_free;
|
||||
|
||||
ret = ipv4_sysctls_op(&netns.ipv4_sysctl, &netns.n_ipv4_sysctl, CTL_READ);
|
||||
if (ret < 0)
|
||||
goto err_free;
|
||||
|
||||
ret = pb_write_one(img_from_set(fds, CR_FD_NETNS), &netns, PB_NETNS);
|
||||
err_free:
|
||||
xfree(o_buf);
|
||||
@ -2593,6 +2688,12 @@ static int restore_netns_conf(struct ns_id *ns)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((netns)->ipv4_sysctl) {
|
||||
ret = ipv4_sysctls_op(&(netns)->ipv4_sysctl, &(netns)->n_ipv4_sysctl, CTL_WRITE);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ns->net.netns = netns;
|
||||
out:
|
||||
return ret;
|
||||
|
@ -74,4 +74,5 @@ message netns_entry {
|
||||
repeated netns_id nsids = 7;
|
||||
optional string ext_key = 8;
|
||||
repeated sysctl_entry unix_conf = 9;
|
||||
repeated sysctl_entry ipv4_sysctl = 10;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user