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:
committed by
Andrei Vagin
parent
17c4a8b245
commit
e1c4871759
@@ -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
|
||||
|
@@ -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),
|
||||
|
@@ -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,
|
||||
|
@@ -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
|
||||
|
||||
|
115
criu/net.c
115
criu/net.c
@@ -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)
|
||||
|
@@ -14,6 +14,7 @@ RUN apk update && apk add \
|
||||
libcap-dev \
|
||||
libnet-dev \
|
||||
libnl3-dev \
|
||||
nftables \
|
||||
pkgconfig \
|
||||
protobuf-c-dev \
|
||||
protobuf-dev \
|
||||
|
@@ -10,6 +10,8 @@ RUN dnf install -y \
|
||||
gnutls-devel \
|
||||
iproute \
|
||||
iptables \
|
||||
nftables \
|
||||
nftables-devel \
|
||||
libaio-devel \
|
||||
libasan \
|
||||
libcap-devel \
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user