[CRIU] [PATCH 02/10] inet: raw -- Check for kernel diag module support

Cyrill Gorcunov gorcunov at gmail.com
Thu Mar 22 01:10:54 MSK 2018


To collect raw sockets we need the kernel to support raw_diag module.

Signed-off-by: Cyrill Gorcunov <gorcunov at gmail.com>
---
 criu/cr-check.c |  9 +++++++++
 criu/sockets.c  | 33 +++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/criu/cr-check.c b/criu/cr-check.c
index 793ec6486094..c1b63a83bab5 100644
--- a/criu/cr-check.c
+++ b/criu/cr-check.c
@@ -1070,6 +1070,13 @@ static int check_sk_netns(void)
 	return 0;
 }
 
+static int check_net_diag_raw(void)
+{
+	check_sock_diag();
+	return (socket_test_collect_bit(AF_INET, IPPROTO_RAW) &&
+		socket_test_collect_bit(AF_INET6, IPPROTO_RAW)) ? 0 : -1;
+}
+
 static int check_ns_pid(void)
 {
 	if (!kdat.has_nspid)
@@ -1209,6 +1216,7 @@ int cr_check(void)
 		ret |= check_uffd();
 		ret |= check_uffd_noncoop();
 		ret |= check_sk_netns();
+		ret |= check_net_diag_raw();
 		ret |= check_ns_pid();
 		ret |= check_ns_get_userns();
 		ret |= check_ns_get_parent();
@@ -1294,6 +1302,7 @@ static struct feature_list feature_list[] = {
 	{ "uffd-noncoop", check_uffd_noncoop },
 	{ "can_map_vdso", check_can_map_vdso},
 	{ "sk_ns", check_sk_netns },
+	{ "net_diag_raw", check_net_diag_raw },
 	{ "nsid", check_nsid },
 	{ "link_nsid", check_link_nsid},
 	{ "ns_pid", check_ns_pid},
diff --git a/criu/sockets.c b/criu/sockets.c
index f8504d9c5050..618213929938 100644
--- a/criu/sockets.c
+++ b/criu/sockets.c
@@ -61,9 +61,11 @@ enum socket_cl_bits
 	INET_TCP_CL_BIT,
 	INET_UDP_CL_BIT,
 	INET_UDPLITE_CL_BIT,
+	INET_RAW_CL_BIT,
 	INET6_TCP_CL_BIT,
 	INET6_UDP_CL_BIT,
 	INET6_UDPLITE_CL_BIT,
+	INET6_RAW_CL_BIT,
 	UNIX_CL_BIT,
 	PACKET_CL_BIT,
 	_MAX_CL_BIT,
@@ -89,6 +91,8 @@ enum socket_cl_bits get_collect_bit_nr(unsigned int family, unsigned int proto)
 			return INET_UDP_CL_BIT;
 		if (proto == IPPROTO_UDPLITE)
 			return INET_UDPLITE_CL_BIT;
+		if (proto == IPPROTO_RAW)
+			return INET_RAW_CL_BIT;
 	}
 	if (family == AF_INET6) {
 		if (proto == IPPROTO_TCP)
@@ -97,6 +101,8 @@ enum socket_cl_bits get_collect_bit_nr(unsigned int family, unsigned int proto)
 			return INET6_UDP_CL_BIT;
 		if (proto == IPPROTO_UDPLITE)
 			return INET6_UDPLITE_CL_BIT;
+		if (proto == IPPROTO_RAW)
+			return INET6_RAW_CL_BIT;
 	}
 
 	pr_err("Unknown pair family %d proto %d\n", family, proto);
@@ -606,6 +612,9 @@ static int inet_receive_one(struct nlmsghdr *h, struct ns_id *ns, void *arg)
 	case IPPROTO_UDPLITE:
 		type = SOCK_DGRAM;
 		break;
+	case IPPROTO_RAW:
+		type = SOCK_RAW;
+		break;
 	default:
 		BUG_ON(1);
 		return -1;
@@ -681,6 +690,18 @@ int collect_sockets(struct ns_id *ns)
 	if (tmp)
 		err = tmp;
 
+	/* Collect IPv4 RAW sockets */
+	req.r.i.sdiag_family	= AF_INET;
+	req.r.i.sdiag_protocol	= IPPROTO_RAW;
+	req.r.i.idiag_ext	= 0;
+	req.r.i.idiag_states	= -1; /* All */
+	tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, ns, &req.r.i);
+	if (tmp) {
+		pr_warn("The current kernel doesn't support ipv4 raw_diag module");
+		if (tmp != -ENOENT)
+			err = tmp;
+	}
+
 	/* Collect IPv6 TCP sockets */
 	req.r.i.sdiag_family	= AF_INET6;
 	req.r.i.sdiag_protocol	= IPPROTO_TCP;
@@ -712,6 +733,18 @@ int collect_sockets(struct ns_id *ns)
 	if (tmp)
 		err = tmp;
 
+	/* Collect IPv6 RAW sockets */
+	req.r.i.sdiag_family	= AF_INET6;
+	req.r.i.sdiag_protocol	= IPPROTO_RAW;
+	req.r.i.idiag_ext	= 0;
+	req.r.i.idiag_states	= -1; /* All */
+	tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, ns, &req.r.i);
+	if (tmp) {
+		pr_warn("The current kernel doesn't support ipv6 raw_diag module");
+		if (tmp != -ENOENT)
+			err = tmp;
+	}
+
 	req.r.p.sdiag_family	= AF_PACKET;
 	req.r.p.sdiag_protocol	= 0;
 	req.r.p.pdiag_show	= PACKET_SHOW_INFO | PACKET_SHOW_MCLIST |
-- 
2.14.3



More information about the CRIU mailing list