Skip to content

Commit 805adcd

Browse files
ss141309Snorch
authored andcommitted
sk-inet: Add support for checkpoint/restore of ICMP sockets
Currently there is no option to checkpoint/restore programs that use ICMP sockets, such as `ping`. This patch adds support for the same. Fixes #2557 Signed-off-by: समीर सिंह Sameer Singh <[email protected]>
1 parent 14b5268 commit 805adcd

File tree

2 files changed

+37
-4
lines changed

2 files changed

+37
-4
lines changed

criu/sk-inet.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ static int can_dump_ipproto(unsigned int ino, int proto, int type)
130130
case IPPROTO_TCP:
131131
case IPPROTO_UDP:
132132
case IPPROTO_UDPLITE:
133+
case IPPROTO_ICMP:
134+
case IPPROTO_ICMPV6:
133135
break;
134136
default:
135137
pr_err("Unsupported proto %d for socket %x\n", proto, ino);
@@ -922,8 +924,9 @@ static int open_inet_sk(struct file_desc *d, int *new_fd)
922924
}
923925

924926
if (ie->src_port) {
925-
if (inet_bind(sk, ii))
926-
goto err;
927+
if (ie->proto != IPPROTO_ICMP && ie->proto != IPPROTO_ICMPV6)
928+
if (inet_bind(sk, ii))
929+
goto err;
927930
}
928931

929932
/*

criu/sockets.c

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ const char *socket_proto_name(unsigned int proto, char *nm, size_t size)
6565
[IPPROTO_IPV6] = __stringify_1(IPPROTO_IPV6), [IPPROTO_RSVP] = __stringify_1(IPPROTO_RSVP),
6666
[IPPROTO_GRE] = __stringify_1(IPPROTO_GRE), [IPPROTO_ESP] = __stringify_1(IPPROTO_ESP),
6767
[IPPROTO_AH] = __stringify_1(IPPROTO_AH), [IPPROTO_UDPLITE] = __stringify_1(IPPROTO_UDPLITE),
68-
[IPPROTO_RAW] = __stringify_1(IPPROTO_RAW),
68+
[IPPROTO_RAW] = __stringify_1(IPPROTO_RAW), [IPPROTO_ICMPV6] = __stringify_1(IPPROTO_ICMPV6),
6969
};
7070
return __socket_const_name(nm, size, protos, ARRAY_SIZE(protos), proto);
7171
}
@@ -131,10 +131,12 @@ enum socket_cl_bits {
131131
INET_UDP_CL_BIT,
132132
INET_UDPLITE_CL_BIT,
133133
INET_RAW_CL_BIT,
134+
INET_ICMP_CL_BIT,
134135
INET6_TCP_CL_BIT,
135136
INET6_UDP_CL_BIT,
136137
INET6_UDPLITE_CL_BIT,
137138
INET6_RAW_CL_BIT,
139+
INET6_ICMP_CL_BIT,
138140
UNIX_CL_BIT,
139141
PACKET_CL_BIT,
140142
_MAX_CL_BIT,
@@ -161,6 +163,8 @@ static inline enum socket_cl_bits get_collect_bit_nr(unsigned int family, unsign
161163
return INET_UDPLITE_CL_BIT;
162164
if (proto == IPPROTO_RAW)
163165
return INET_RAW_CL_BIT;
166+
if (proto == IPPROTO_ICMP)
167+
return INET_ICMP_CL_BIT;
164168
}
165169
if (family == AF_INET6) {
166170
if (proto == IPPROTO_TCP)
@@ -171,6 +175,8 @@ static inline enum socket_cl_bits get_collect_bit_nr(unsigned int family, unsign
171175
return INET6_UDPLITE_CL_BIT;
172176
if (proto == IPPROTO_RAW)
173177
return INET6_RAW_CL_BIT;
178+
if (proto == IPPROTO_ICMPV6)
179+
return INET6_ICMP_CL_BIT;
174180
}
175181

176182
pr_err("Unknown pair family %d proto %d\n", family, proto);
@@ -282,6 +288,12 @@ void preload_socket_modules(void)
282288
req.r.i.sdiag_protocol = IPPROTO_RAW;
283289
probe_diag(nl, &req, -ENOENT);
284290

291+
req.r.i.sdiag_protocol = IPPROTO_ICMP;
292+
probe_diag(nl, &req, -ENOENT);
293+
294+
req.r.i.sdiag_protocol = IPPROTO_ICMPV6;
295+
probe_diag(nl, &req, -ENOENT);
296+
285297
close(nl);
286298
pr_info("Done probing\n");
287299
}
@@ -773,6 +785,10 @@ static int inet_receive_one(struct nlmsghdr *h, struct ns_id *ns, void *arg)
773785
case IPPROTO_RAW:
774786
type = SOCK_RAW;
775787
break;
788+
case IPPROTO_ICMP:
789+
case IPPROTO_ICMPV6:
790+
type = SOCK_DGRAM;
791+
break;
776792
default:
777793
BUG_ON(1);
778794
return -1;
@@ -797,7 +813,7 @@ static int collect_err(int err, struct ns_id *ns, void *arg)
797813
char family[32], proto[32];
798814
char msg[256];
799815

800-
snprintf(msg, sizeof(msg), "Sockects collect procedure family %s proto %s",
816+
snprintf(msg, sizeof(msg), "Sockets collect procedure family %s proto %s",
801817
socket_family_name(gr->family, family, sizeof(family)),
802818
socket_proto_name(gr->protocol, proto, sizeof(proto)));
803819

@@ -905,6 +921,13 @@ int collect_sockets(struct ns_id *ns)
905921
if (tmp)
906922
err = tmp;
907923

924+
/* Collect IPv4 ICMP sockets */
925+
req.r.i.sdiag_family = AF_INET;
926+
req.r.i.sdiag_protocol = IPPROTO_ICMP;
927+
req.r.i.idiag_ext = 0;
928+
req.r.i.idiag_states = -1; /* All */
929+
set_collect_bit(req.r.n.sdiag_family, req.r.n.sdiag_protocol);
930+
908931
/* Collect IPv6 TCP sockets */
909932
req.r.i.sdiag_family = AF_INET6;
910933
req.r.i.sdiag_protocol = IPPROTO_TCP;
@@ -944,6 +967,13 @@ int collect_sockets(struct ns_id *ns)
944967
if (tmp)
945968
err = tmp;
946969

970+
/* Collect IPv6 ICMP sockets */
971+
req.r.i.sdiag_family = AF_INET6;
972+
req.r.i.sdiag_protocol = IPPROTO_ICMPV6;
973+
req.r.i.idiag_ext = 0;
974+
req.r.i.idiag_states = -1; /* All */
975+
set_collect_bit(req.r.n.sdiag_family, req.r.n.sdiag_protocol);
976+
947977
req.r.p.sdiag_family = AF_PACKET;
948978
req.r.p.sdiag_protocol = 0;
949979
req.r.p.pdiag_show = PACKET_SHOW_INFO | PACKET_SHOW_MCLIST | PACKET_SHOW_FANOUT | PACKET_SHOW_RING_CFG;

0 commit comments

Comments
 (0)