[1/2] net: add nftables c/r

Submitted by Alexander Mikhalitsyn on Nov. 11, 2019, 4:31 p.m.

Details

Message ID 20191111163036.19945-1-alexander.mikhalitsyn@virtuozzo.com
State New
Series "Series without cover letter"
Headers show

Commit Message

Alexander Mikhalitsyn Nov. 11, 2019, 4:31 p.m.
From: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>

After Centos-8 nft used instead of iptables. But we had never supported nft rules in
CRIU, and after c/r all rules are flushed.

Path to nft tool can be changed via CR_NFTABLES environment variable
similar to CR_IPTABLES.

These requires nft package on host.

Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Signed-off-by: Alexander Mikhalitsyn <alexander.mikhalitsyn@virtuozzo.com>
Signed-off-by: Alexander Mikhalitsyn <alexander@mihalicyn.com>
---
 criu/image-desc.c         |  1 +
 criu/include/image-desc.h |  1 +
 criu/include/magic.h      |  1 +
 criu/net.c                | 50 +++++++++++++++++++++++++++++++++++++--
 4 files changed, 51 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/image-desc.c b/criu/image-desc.c
index 81cd0748..ae5d817f 100644
--- a/criu/image-desc.c
+++ b/criu/image-desc.c
@@ -76,6 +76,7 @@  struct cr_fd_desc_tmpl imgset_template[CR_FD_MAX] = {
 	FD_ENTRY_F(RULE,	"rule-%u", O_NOBUF),
 	FD_ENTRY_F(IPTABLES,	"iptables-%u", O_NOBUF),
 	FD_ENTRY_F(IP6TABLES,	"ip6tables-%u", O_NOBUF),
+	FD_ENTRY_F(NFTABLES,	"nftables-%u", O_NOBUF),
 	FD_ENTRY_F(TMPFS_IMG,	"tmpfs-%u.tar.gz", O_NOBUF),
 	FD_ENTRY_F(TMPFS_DEV,	"tmpfs-dev-%u.tar.gz", O_NOBUF),
 	FD_ENTRY_F(AUTOFS,	"autofs-%u", O_NOBUF),
diff --git a/criu/include/image-desc.h b/criu/include/image-desc.h
index fea80a71..6db8bf94 100644
--- a/criu/include/image-desc.h
+++ b/criu/include/image-desc.h
@@ -42,6 +42,7 @@  enum {
 	CR_FD_RULE,
 	CR_FD_IPTABLES,
 	CR_FD_IP6TABLES,
+	CR_FD_NFTABLES,
 	CR_FD_NETNS,
 	CR_FD_NETNF_CT,
 	CR_FD_NETNF_EXP,
diff --git a/criu/include/magic.h b/criu/include/magic.h
index 05101f43..1a583f4e 100644
--- a/criu/include/magic.h
+++ b/criu/include/magic.h
@@ -103,6 +103,7 @@ 
 #define TMPFS_DEV_MAGIC		RAW_IMAGE_MAGIC
 #define IPTABLES_MAGIC		RAW_IMAGE_MAGIC
 #define IP6TABLES_MAGIC		RAW_IMAGE_MAGIC
+#define NFTABLES_MAGIC		RAW_IMAGE_MAGIC
 #define NETNF_CT_MAGIC		RAW_IMAGE_MAGIC
 #define NETNF_EXP_MAGIC		RAW_IMAGE_MAGIC
 
diff --git a/criu/net.c b/criu/net.c
index fe9b51ad..7079aa90 100644
--- a/criu/net.c
+++ b/criu/net.c
@@ -1739,12 +1739,12 @@  static int run_ip_tool(char *arg1, char *arg2, char *arg3, char *arg4, int fdin,
 	return 0;
 }
 
-static int run_iptables_tool(char *def_cmd, int fdin, int fdout)
+static int run_tool(const char *env_var, char *def_cmd, int fdin, int fdout)
 {
 	int ret;
 	char *cmd;
 
-	cmd = getenv("CR_IPTABLES");
+	cmd = getenv(env_var);
 	if (!cmd)
 		cmd = def_cmd;
 	pr_debug("\tRunning %s for %s\n", cmd, def_cmd);
@@ -1755,6 +1755,16 @@  static int run_iptables_tool(char *def_cmd, int fdin, int fdout)
 	return ret;
 }
 
+static int run_iptables_tool(char *def_cmd, int fdin, int fdout)
+{
+	return run_tool("CR_IPTABLES", def_cmd, fdin, fdout);
+}
+
+static int run_nftables_tool(char *def_cmd, int fdin, int fdout)
+{
+	return run_tool("CR_NFTABLES", def_cmd, fdin, fdout);
+}
+
 static inline int dump_ifaddr(struct cr_imgset *fds)
 {
 	struct cr_img *img = img_from_set(fds, CR_FD_IFADDR);
@@ -1818,6 +1828,17 @@  static inline int dump_iptables(struct cr_imgset *fds)
 	return 0;
 }
 
+static inline int dump_nftables(struct cr_imgset *fds)
+{
+	struct cr_img *img;
+
+	img = img_from_set(fds, CR_FD_NFTABLES);
+	if (run_nftables_tool("nft list ruleset", -1, img_raw_fd(img)))
+		return -1;
+
+	return 0;
+}
+
 static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds)
 {
 	void *buf, *o_buf;
@@ -2082,6 +2103,27 @@  out:
 	return ret;
 }
 
+static inline int restore_nftables(int pid)
+{
+	int ret = -1;
+	struct cr_img *img;
+
+	img = open_image(CR_FD_NFTABLES, O_RSTR, pid);
+	if (img == NULL)
+		return -1;
+	if (empty_image(img)) {
+		/* Backward compatibility */
+		pr_info("Skipping nft restore, no image");
+		ret = 0;
+		goto out;
+	}
+
+	ret = run_nftables_tool("nft -f /proc/self/fd/0", img_raw_fd(img), -1);
+out:
+	close_image(img);
+	return ret;
+}
+
 int read_net_ns_img(void)
 {
 	struct ns_id *ns;
@@ -2299,6 +2341,8 @@  int dump_net_ns(struct ns_id *ns)
 			ret = dump_rule(fds);
 		if (!ret)
 			ret = dump_iptables(fds);
+		if (!ret)
+			ret = dump_nftables(fds);
 		if (!ret)
 			ret = dump_netns_conf(ns, fds);
 	} else if (ns->type != NS_ROOT) {
@@ -2392,6 +2436,8 @@  static int prepare_net_ns_second_stage(struct ns_id *ns)
 			ret = restore_rule(nsid);
 		if (!ret)
 			ret = restore_iptables(nsid);
+		if (!ret)
+			ret = restore_nftables(nsid);
 	}
 
 	if (!ret)