[Devel] [PATCH CRIU] dump/restore: Supported ipset
Alexander Mikhalitsyn
alexander.mikhalitsyn at virtuozzo.com
Thu Jan 30 11:56:20 MSK 2020
On Wed, 29 Jan 2020 20:04:15 +0300
Valeriy Vdovin <valeriy.vdovin at virtuozzo.com> wrote:
> https://jira.sw.ru/browse/PSBM-100083
>
> Added ipset dump/restore functionality. At dump operation it calls
> 'ipset save' and stores result into raw text image. At restore
> it restores ipset by calling 'ipset restore'. This is done prior
> to restoring iptables.
>
> Signed-off-by: Valeriy Vdovin <valeriy.vdovin at virtuozzo.com>
> ---
> criu/image-desc.c | 1 +
> criu/include/image-desc.h | 1 +
> criu/include/magic.h | 1 +
> criu/net.c | 43 +++++++++++++++++++++++++++++++++++
> test/zdtm/static/Makefile | 1 +
> test/zdtm/static/netns-ipset.c | 51 ++++++++++++++++++++++++++++++++++++++++++
> 6 files changed, 98 insertions(+)
> create mode 100644 test/zdtm/static/netns-ipset.c
>
> diff --git a/criu/image-desc.c b/criu/image-desc.c
> index 04e827d..475d176 100644
> --- a/criu/image-desc.c
> +++ b/criu/image-desc.c
> @@ -74,6 +74,7 @@ struct cr_fd_desc_tmpl imgset_template[CR_FD_MAX] = {
> FD_ENTRY_F(ROUTE, "route-%u", O_NOBUF),
> FD_ENTRY_F(ROUTE6, "route6-%u", O_NOBUF),
> FD_ENTRY_F(RULE, "rule-%u", O_NOBUF),
> + FD_ENTRY_F(IPSET, "ipset-%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),
> diff --git a/criu/include/image-desc.h b/criu/include/image-desc.h
> index 1015191..d875722 100644
> --- a/criu/include/image-desc.h
> +++ b/criu/include/image-desc.h
> @@ -40,6 +40,7 @@ enum {
> CR_FD_ROUTE,
> CR_FD_ROUTE6,
> CR_FD_RULE,
> + CR_FD_IPSET,
> CR_FD_IPTABLES,
> CR_FD_IP6TABLES,
> CR_FD_NFTABLES,
> diff --git a/criu/include/magic.h b/criu/include/magic.h
> index 1a583f4..32421ed 100644
> --- a/criu/include/magic.h
> +++ b/criu/include/magic.h
> @@ -101,6 +101,7 @@
> #define RULE_MAGIC RAW_IMAGE_MAGIC
> #define TMPFS_IMG_MAGIC RAW_IMAGE_MAGIC
> #define TMPFS_DEV_MAGIC RAW_IMAGE_MAGIC
> +#define IPSET_MAGIC RAW_IMAGE_MAGIC
> #define IPTABLES_MAGIC RAW_IMAGE_MAGIC
> #define IP6TABLES_MAGIC RAW_IMAGE_MAGIC
> #define NFTABLES_MAGIC RAW_IMAGE_MAGIC
> diff --git a/criu/net.c b/criu/net.c
> index 8ee560c..dccc491 100644
> --- a/criu/net.c
> +++ b/criu/net.c
> @@ -1775,6 +1775,26 @@ static int restore_links()
> return 0;
> }
>
> +static int run_ipset_tool(char *arg1, char *arg2, char *arg3, int fdin, int fdout)
> +{
> + char *cmd;
> + int ret;
> +
> + pr_debug("\tRunning ipset %s %s %s \n", arg1, arg2, arg3 ? : "");
> +
> + cmd = getenv("CR_IPSET_TOOL");
> + if (!cmd)
> + cmd = "ipset";
> +
> + ret = cr_system(fdin, fdout, -1, cmd,
> + (char *[]) { cmd, arg1, arg2, arg3, NULL }, 0);
> + if (ret) {
> + pr_err("ipset tool failed on %s %s %s \n", arg1, arg2, arg3 ? : "");
> + return -1;
> + }
> +
> + return 0;
> +}
>
> static int run_ip_tool(char *arg1, char *arg2, char *arg3, char *arg4, int fdin, int fdout, unsigned flags)
> {
> @@ -1845,6 +1865,7 @@ static int iptables_tool_dump(char *def_cmd, int fdin, int fdout)
> return run_iptables_tool(def_cmd, fdin, fdout);
> }
>
> +
is it needed here?
> static inline int dump_ifaddr(struct cr_imgset *fds)
> {
> struct cr_img *img = img_from_set(fds, CR_FD_IFADDR);
> @@ -1891,6 +1912,13 @@ static inline int dump_rule(struct cr_imgset *fds)
> return 0;
> }
>
> +static inline int dump_ipset(struct cr_imgset *fds)
> +{
> + struct cr_img *img;
> + img = img_from_set(fds, CR_FD_IPSET);
> + return run_ipset_tool("save", 0, 0, -1, img_raw_fd(img));
> +}
> +
> static inline int dump_iptables(struct cr_imgset *fds)
> {
> struct cr_img *img;
> @@ -2129,6 +2157,17 @@ static int prepare_xtable_lock()
> return 0;
> }
>
> +static inline int restore_ipset(int pid)
> +{
> + struct cr_img *img;
> + img = open_image(CR_FD_IPSET, O_RSTR, pid);
> + if (img == NULL)
> + return -1;
> + if (empty_image(img))
close_image(img) ?
> + return 0;
> + return run_ipset_tool("restore", 0, 0, img_raw_fd(img), -1);
here, you also need to close_image(img).
> +}
> +
> static inline int restore_iptables(int pid)
> {
> int ret = -1;
> @@ -2446,6 +2485,8 @@ int dump_net_ns(struct ns_id *ns)
> if (!ret)
> ret = dump_rule(fds);
> if (!ret)
> + ret = dump_ipset(fds);
> + if (!ret)
> ret = dump_iptables(fds);
> if (!ret)
> ret = dump_nftables(fds);
> @@ -2541,6 +2582,8 @@ static int prepare_net_ns_second_stage(struct ns_id *ns)
> if (!ret)
> ret = restore_rule(nsid);
> if (!ret)
> + ret = restore_ipset(nsid);
> + if (!ret)
> ret = restore_iptables(nsid);
> if (!ret)
> ret = restore_nftables(nsid);
> diff --git a/test/zdtm/static/Makefile b/test/zdtm/static/Makefile
> index 28717b1..bdef4d0 100644
> --- a/test/zdtm/static/Makefile
> +++ b/test/zdtm/static/Makefile
> @@ -143,6 +143,7 @@ TST_NOFILE := \
> poll \
> mountpoints \
> netns \
> + netns-ipset \
> netns-dev \
> session01 \
> session02 \
> diff --git a/test/zdtm/static/netns-ipset.c b/test/zdtm/static/netns-ipset.c
> new file mode 100644
> index 0000000..2650685
> --- /dev/null
> +++ b/test/zdtm/static/netns-ipset.c
> @@ -0,0 +1,51 @@
> +#include <string.h>
> +#include <unistd.h>
> +#include <stdlib.h>
> +#include <stdio.h>
> +
> +#include "zdtmtst.h"
> +
> +const char *test_doc = "Check that ipset are dumped and restored correctly";
> +
> +#define RUN_OR_ERR(cmd, failmsg) if (system(cmd)) { pr_perror(failmsg); return -1; }
> +#define RUN_OR_FAIL(cmd, failmsg) if (system(cmd)) { fail(failmsg); return -1; }
> +
> +int main(int argc, char **argv)
> +{
> + char dump_ipset_old[] = "ipset save > ipset.old";
> + char dump_ipset_new[] = "ipset save > ipset.new";
> + char dump_iptables_old[] = "iptables -L INPUT 1 > iptables.old";
> + char dump_iptables_new[] = "iptables -L INPUT 1 > iptables.new";
> + char cmp_ipset[] = "diff ipset.old ipset.new";
> + char cmp_iptables[] = "diff iptables.old iptables.new";
> +
> + test_init(argc, argv);
> +
> + /* create ipset group and add some ip addresses to it */
> + RUN_OR_ERR("ipset create testgroup nethash", "Can't create test ipset");
> + RUN_OR_ERR("ipset add testgroup 127.0.0.1/8", "Can't add ip addresses to ipset group");
what about ipv6?
> +
> + /* Use testgroup in iptables rule */
> + RUN_OR_ERR("iptables -I INPUT 1 -p tcp -m set --match-set testgroup src,dst -j ACCEPT",
> + "Failed to setup iptables rule with ipset group");
> +
> + /* dump ipset and iptables states to text files */
> + RUN_OR_ERR(dump_iptables_old, "Can't save iptables rules.");
> + RUN_OR_ERR(dump_ipset_old , "Can't save ipset list.");
> +
> + test_daemon();
> + test_waitsig();
> +
> + /* again dump ipset and iptables states to other text files */
> + RUN_OR_ERR(dump_iptables_new, "Can't dump restored iptables rules.");
> + RUN_OR_ERR(dump_ipset_new , "Can't save restored ipset list to file.");
> +
> + /* compare original and restored iptables rules */
> + RUN_OR_FAIL(cmp_iptables, "iptables rules differ");
> +
> + /* compare original and restored ipset rules */
> + RUN_OR_FAIL(cmp_ipset, "ipset lists differ");
> +
> + pass();
> + return 0;
> +}
> --
> 1.8.3.1
>
More information about the Devel
mailing list