[CRIU] [PATCHv2 1/2] net: add nftables c/r
Alexander Mikhalitsyn
alexander.mikhalitsyn at virtuozzo.com
Tue Nov 12 19:06:42 MSK 2019
From: Pavel Tikhomirov <ptikhomirov at 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.
Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
Signed-off-by: Alexander Mikhalitsyn <alexander.mikhalitsyn at virtuozzo.com>
Signed-off-by: Alexander Mikhalitsyn <alexander at mihalicyn.com>
---
criu/image-desc.c | 1 +
criu/include/image-desc.h | 1 +
criu/include/magic.h | 1 +
criu/include/util.h | 2 ++
criu/net.c | 65 +++++++++++++++++++++++++++++++++++++--
criu/util.c | 39 +++++++++++++++++++++++
6 files changed, 107 insertions(+), 2 deletions(-)
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/include/util.h b/criu/include/util.h
index a14be722..57b46dcc 100644
--- a/criu/include/util.h
+++ b/criu/include/util.h
@@ -252,6 +252,8 @@ static inline bool issubpath(const char *path, const char *sub_path)
(end == '/' || end == '\0');
}
+int check_cmd_exists(const char *cmd);
+
/*
* mkdir -p
*/
diff --git a/criu/net.c b/criu/net.c
index fe9b51ad..4737b604 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,21 @@ static inline int dump_iptables(struct cr_imgset *fds)
return 0;
}
+static inline int dump_nftables(struct cr_imgset *fds)
+{
+ struct cr_img *img;
+
+ /* we not dump nftables if nft utility isn't present */
+ if (!check_cmd_exists("nft"))
+ return 0;
+
+ 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 +2107,38 @@ 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;
+ }
+
+ /*
+ * At this point we already know, that image may contain nftables info,
+ * if nft utility not present we need to warn user about possible
+ * problems
+ */
+ if (!check_cmd_exists("nft")) {
+ pr_warn("Skipping nft restore, no nft utility");
+ 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 +2356,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 +2451,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)
diff --git a/criu/util.c b/criu/util.c
index 2a3d7abc..b4b1564f 100644
--- a/criu/util.c
+++ b/criu/util.c
@@ -795,6 +795,45 @@ struct vma_area *alloc_vma_area(void)
return p;
}
+static int __check_cmd_exists(const char *path)
+{
+ return (access(path, F_OK) == 0);
+}
+
+int check_cmd_exists(const char *cmd)
+{
+ int ret = 0;
+ char buf[255];
+ char *env_path, *dup, *s, *p;
+
+ env_path = getenv("PATH");
+
+ /* ok, the simply __check_cmd_exists */
+ if (!env_path || cmd[0] == '/')
+ return __check_cmd_exists(cmd);
+
+ dup = strdup(env_path);
+
+ /* let's try to find program in PATH */
+ s = dup;
+ p = NULL;
+ do {
+ p = strchr(s, ':');
+ if (p != NULL)
+ p[0] = 0;
+
+ sprintf(buf, "%s/%s", s, cmd);
+ if ((ret = __check_cmd_exists(buf)))
+ goto free;
+
+ s = p + 1;
+ } while (p != NULL);
+
+free:
+ free(dup);
+ return ret;
+}
+
int mkdirpat(int fd, const char *path, int mode)
{
size_t i;
--
2.17.1
More information about the CRIU
mailing list