2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-09-01 14:55:39 +00:00

net: add nftables c/r

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.

Co-developed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
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>
Signed-off-by: Dmitry Safonov <dima@arista.com>
This commit is contained in:
Alexander Mikhalitsyn
2019-11-11 19:07:52 +03:00
committed by Andrei Vagin
parent 17c4a8b245
commit e1c4871759
8 changed files with 161 additions and 0 deletions

View File

@@ -23,6 +23,23 @@ else
$(info Note: Building without GnuTLS support)
endif
ifeq ($(call pkg-config-check,libnftables),y)
LIB_NFTABLES := $(shell pkg-config --libs libnftables)
ifeq ($(call try-cc,$(FEATURE_TEST_NFTABLES_LIB_API_0),$(LIB_NFTABLES)),true)
LIBS_FEATURES += $(LIB_NFTABLES)
FEATURE_DEFINES += -DCONFIG_HAS_NFTABLES_LIB_API_0
else ifeq ($(call try-cc,$(FEATURE_TEST_NFTABLES_LIB_API_1),$(LIB_NFTABLES)),true)
LIBS_FEATURES += $(LIB_NFTABLES)
FEATURE_DEFINES += -DCONFIG_HAS_NFTABLES_LIB_API_1
else
$(warning Warn: you have libnftables installed but it has incompatible API)
$(warning Warn: Building without nftables support)
endif
else
$(warning Warn: you have no libnftables installed)
$(warning Warn: Building without nftables support)
endif
export LIBS += $(LIBS_FEATURES)
CONFIG_FILE = .config

View File

@@ -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),

View File

@@ -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,

View File

@@ -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

View File

@@ -17,6 +17,10 @@
#include <libnl3/netlink/msg.h>
#include <libnl3/netlink/netlink.h>
#if defined(CONFIG_HAS_NFTABLES_LIB_API_0) || defined(CONFIG_HAS_NFTABLES_LIB_API_1)
#include <nftables/libnftables.h>
#endif
#ifdef CONFIG_HAS_SELINUX
#include <selinux/selinux.h>
#endif
@@ -1897,6 +1901,55 @@ static inline int dump_iptables(struct cr_imgset *fds)
return 0;
}
#if defined(CONFIG_HAS_NFTABLES_LIB_API_0) || defined(CONFIG_HAS_NFTABLES_LIB_API_1)
static inline int dump_nftables(struct cr_imgset *fds)
{
int ret = -1;
struct cr_img *img;
int img_fd;
FILE *fp;
struct nft_ctx *nft;
nft = nft_ctx_new(NFT_CTX_DEFAULT);
if (!nft)
return -1;
img = img_from_set(fds, CR_FD_NFTABLES);
img_fd = dup(img_raw_fd(img));
if (img_fd < 0) {
pr_perror("dup() failed");
goto nft_ctx_free_out;
}
fp = fdopen(img_fd, "w");
if (!fp) {
pr_perror("fdopen() failed");
close(img_fd);
goto nft_ctx_free_out;
}
nft_ctx_set_output(nft, fp);
#define DUMP_NFTABLES_CMD "list ruleset"
#if defined(CONFIG_HAS_NFTABLES_LIB_API_0)
if (nft_run_cmd_from_buffer(nft, DUMP_NFTABLES_CMD, strlen(DUMP_NFTABLES_CMD)))
#elif defined(CONFIG_HAS_NFTABLES_LIB_API_1)
if (nft_run_cmd_from_buffer(nft, DUMP_NFTABLES_CMD))
#else
BUILD_BUG_ON(1);
#endif
goto fp_close_out;
ret = 0;
fp_close_out:
fclose(fp);
nft_ctx_free_out:
nft_ctx_free(nft);
return ret;
}
#endif
static int dump_netns_conf(struct ns_id *ns, struct cr_imgset *fds)
{
void *buf, *o_buf;
@@ -2149,6 +2202,60 @@ out:
return ret;
}
#if defined(CONFIG_HAS_NFTABLES_LIB_API_0) || defined(CONFIG_HAS_NFTABLES_LIB_API_1)
static inline int restore_nftables(int pid)
{
int ret = -1;
struct cr_img *img;
struct nft_ctx *nft;
off_t img_data_size;
char *buf;
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 image_close_out;
}
if ((img_data_size = img_raw_size(img)) < 0)
goto image_close_out;
if (read_img_str(img, &buf, img_data_size) < 0)
goto image_close_out;
nft = nft_ctx_new(NFT_CTX_DEFAULT);
if (!nft)
goto buf_free_out;
if (nft_ctx_buffer_output(nft) || nft_ctx_buffer_error(nft) ||
#if defined(CONFIG_HAS_NFTABLES_LIB_API_0)
nft_run_cmd_from_buffer(nft, buf, strlen(buf)))
#elif defined(CONFIG_HAS_NFTABLES_LIB_API_1)
nft_run_cmd_from_buffer(nft, buf))
#else
{
BUILD_BUG_ON(1);
}
#endif
goto nft_ctx_free_out;
ret = 0;
nft_ctx_free_out:
nft_ctx_free(nft);
buf_free_out:
xfree(buf);
image_close_out:
close_image(img);
return ret;
}
#endif
int read_net_ns_img(void)
{
struct ns_id *ns;
@@ -2380,6 +2487,10 @@ int dump_net_ns(struct ns_id *ns)
ret = dump_rule(fds);
if (!ret)
ret = dump_iptables(fds);
#if defined(CONFIG_HAS_NFTABLES_LIB_API_0) || defined(CONFIG_HAS_NFTABLES_LIB_API_1)
if (!ret)
ret = dump_nftables(fds);
#endif
if (!ret)
ret = dump_netns_conf(ns, fds);
} else if (ns->type != NS_ROOT) {
@@ -2473,6 +2584,10 @@ static int prepare_net_ns_second_stage(struct ns_id *ns)
ret = restore_rule(nsid);
if (!ret)
ret = restore_iptables(nsid);
#if defined(CONFIG_HAS_NFTABLES_LIB_API_0) || defined(CONFIG_HAS_NFTABLES_LIB_API_1)
if (!ret)
ret = restore_nftables(nsid);
#endif
}
if (!ret)

View File

@@ -14,6 +14,7 @@ RUN apk update && apk add \
libcap-dev \
libnet-dev \
libnl3-dev \
nftables \
pkgconfig \
protobuf-c-dev \
protobuf-dev \

View File

@@ -10,6 +10,8 @@ RUN dnf install -y \
gnutls-devel \
iproute \
iptables \
nftables \
nftables-devel \
libaio-devel \
libasan \
libcap-devel \

View File

@@ -147,4 +147,27 @@ int main(void)
return 0;
return 0;
}
endef
define FEATURE_TEST_NFTABLES_LIB_API_0
#include <nftables/libnftables.h>
int main(int argc, char **argv)
{
return nft_run_cmd_from_buffer(nft_ctx_new(NFT_CTX_DEFAULT), \"cmd\", strlen(\"cmd\"));
}
endef
define FEATURE_TEST_NFTABLES_LIB_API_1
#include <nftables/libnftables.h>
int main(int argc, char **argv)
{
return nft_run_cmd_from_buffer(nft_ctx_new(NFT_CTX_DEFAULT), \"cmd\");
}
endef