[v9,8/9] check: add a feature test for netns id manipulation

Submitted by Tycho Andersen on Oct. 19, 2016, 4:15 p.m.

Details

Message ID 1476893715-24058-9-git-send-email-tycho.andersen@canonical.com
State Superseded
Series "Series without cover letter"
Headers show

Commit Message

Tycho Andersen Oct. 19, 2016, 4:15 p.m.
Signed-off-by: Tycho Andersen <tycho.andersen@canonical.com>
---
 criu/cr-check.c    | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 criu/include/net.h | 11 +++++++++++
 criu/net.c         | 11 -----------
 3 files changed, 68 insertions(+), 11 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/cr-check.c b/criu/cr-check.c
index bb4d978..5945b0a 100644
--- a/criu/cr-check.c
+++ b/criu/cr-check.c
@@ -1,5 +1,6 @@ 
 #include <unistd.h>
 #include <linux/netlink.h>
+#include <linux/rtnetlink.h>
 #include <sys/socket.h>
 #include <sys/types.h>
 #include <sys/eventfd.h>
@@ -41,6 +42,8 @@ 
 #include "namespaces.h"
 #include "pstree.h"
 #include "cr_options.h"
+#include "libnetlink.h"
+#include "net.h"
 
 static char *feature_name(int (*func)());
 
@@ -933,6 +936,58 @@  static int check_tcp_window(void)
 	return 0;
 }
 
+static int nsid_manip_cb(struct nlmsghdr *hdr, void *arg)
+{
+	return 0;
+}
+
+static int check_nsid_manip(void)
+{
+	int parent = -1, ret = -1, nlsk = -1;
+	struct {
+		struct nlmsghdr n;
+		struct rtgenmsg g;
+		char buf[1024];
+	} req;
+
+	parent = open("/proc/self/ns/net", O_RDONLY);
+	if (parent < 0) {
+		pr_perror("open");
+		return -1;
+	}
+
+	if (unshare(CLONE_NEWNET) < 0) {
+		pr_perror("unshare");
+		goto out;
+	}
+
+	nlsk = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+	if (nlsk < 0) {
+		pr_perror("socket");
+		goto out;
+	}
+
+	memset(&req, 0, sizeof(req));
+
+	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.g));
+	req.n.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK;
+	req.n.nlmsg_type = RTM_GETNSID;
+	req.n.nlmsg_seq = CR_NLMSG_SEQ;
+
+	addattr_l(&req.n, sizeof(req), NETNSA_FD, &parent, sizeof(parent));
+	ret = do_rtnl_req(nlsk, &req, req.n.nlmsg_len, nsid_manip_cb, NULL, NULL);
+	if (ret < 0)
+		pr_err("can't manipulate netns ids\n");
+out:
+	if (nlsk > 0)
+		close(nlsk);
+	if (setns(parent, CLONE_NEWNET) < 0)
+		pr_warn("couldn't setns back to parent");
+	if (parent > 0)
+		close(parent);
+	return ret;
+}
+
 static int (*chk_feature)(void);
 
 /*
@@ -1031,6 +1086,7 @@  int cr_check(void)
 		ret |= check_clone_parent_vs_pid();
 		ret |= check_cgroupns();
 		ret |= check_tcp_window();
+		ret |= check_nsid_manip();
 	}
 
 	/*
@@ -1110,6 +1166,7 @@  static struct feature_list feature_list[] = {
 	{ "loginuid", check_loginuid },
 	{ "cgroupns", check_cgroupns },
 	{ "autofs", check_autofs },
+	{ "nsid_manip", check_nsid_manip },
 	{ NULL, NULL },
 };
 
diff --git a/criu/include/net.h b/criu/include/net.h
index d621da1..035a2d3 100644
--- a/criu/include/net.h
+++ b/criu/include/net.h
@@ -6,6 +6,17 @@ 
 #include "list.h"
 #include "external.h"
 
+#ifdef CONFIG_HAS_NET_NAMESPACE_H
+#include <linux/net_namespace.h>
+#else
+#define NETNSA_NSID	1
+#define NETNSA_FD	3
+#endif
+
+#ifndef RTM_GETNSID
+#define RTM_GETNSID		90
+#endif
+
 struct cr_imgset;
 extern int dump_net_ns(int ns_id);
 extern int prepare_net_ns(int pid);
diff --git a/criu/net.c b/criu/net.c
index 2456169..b28b5ec 100644
--- a/criu/net.c
+++ b/criu/net.c
@@ -35,13 +35,6 @@ 
 #include "protobuf.h"
 #include "images/netdev.pb-c.h"
 
-#ifdef CONFIG_HAS_NET_NAMESPACE_H
-#include <linux/net_namespace.h>
-#else
-#define NETNSA_NSID	1
-#define NETNSA_FD	3
-#endif
-
 #ifndef IFLA_LINK_NETNSID
 #define IFLA_LINK_NETNSID	37
 #endif
@@ -50,10 +43,6 @@ 
 #define RTM_NEWNSID		88
 #endif
 
-#ifndef RTM_GETNSID
-#define RTM_GETNSID		90
-#endif
-
 #ifndef IFLA_MACVLAN_FLAGS
 #define IFLA_MACVLAN_FLAGS 2
 #endif