diff --git a/image-desc.c b/image-desc.c index 6d9f38c50..d5cc132b4 100644 --- a/image-desc.c +++ b/image-desc.c @@ -74,6 +74,7 @@ struct cr_fd_desc_tmpl imgset_template[CR_FD_MAX] = { FD_ENTRY_F(IFADDR, "ifaddr-%d", O_NOBUF), FD_ENTRY_F(ROUTE, "route-%d", O_NOBUF), FD_ENTRY_F(ROUTE6, "route6-%d", O_NOBUF), + FD_ENTRY_F(RULE, "rule-%d", O_NOBUF), FD_ENTRY_F(IPTABLES, "iptables-%d", O_NOBUF), FD_ENTRY_F(TMPFS_IMG, "tmpfs-%d.tar.gz", O_NOBUF), FD_ENTRY_F(TMPFS_DEV, "tmpfs-dev-%d.tar.gz", O_NOBUF), diff --git a/include/image-desc.h b/include/image-desc.h index a76b48f13..cb45b20e8 100644 --- a/include/image-desc.h +++ b/include/image-desc.h @@ -40,6 +40,7 @@ enum { CR_FD_IFADDR, CR_FD_ROUTE, CR_FD_ROUTE6, + CR_FD_RULE, CR_FD_IPTABLES, CR_FD_NETNS, _CR_FD_NETNS_TO, diff --git a/include/magic.h b/include/magic.h index e7826d1cc..2af614ba5 100644 --- a/include/magic.h +++ b/include/magic.h @@ -93,6 +93,7 @@ #define IFADDR_MAGIC RAW_IMAGE_MAGIC #define ROUTE_MAGIC RAW_IMAGE_MAGIC #define ROUTE6_MAGIC RAW_IMAGE_MAGIC +#define RULE_MAGIC RAW_IMAGE_MAGIC #define TMPFS_IMG_MAGIC RAW_IMAGE_MAGIC #define TMPFS_DEV_MAGIC RAW_IMAGE_MAGIC #define IPTABLES_MAGIC RAW_IMAGE_MAGIC diff --git a/net.c b/net.c index ce4a56029..a08d25d3f 100644 --- a/net.c +++ b/net.c @@ -600,6 +600,27 @@ static inline int dump_route(struct cr_imgset *fds) return 0; } +static inline int dump_rule(struct cr_imgset *fds) +{ + struct cr_img *img; + char *path; + + img = img_from_set(fds, CR_FD_RULE); + path = xstrdup(img->path); + + if (!path) + return -1; + + if (run_ip_tool("rule", "save", NULL, -1, img_raw_fd(img))) { + pr_err("Check if \"ip rule save\" is supported!\n"); + unlinkat(get_service_fd(IMG_FD_OFF), path, 0); + } + + free(path); + + return 0; +} + static inline int dump_iptables(struct cr_imgset *fds) { struct cr_img *img = img_from_set(fds, CR_FD_IPTABLES); @@ -669,6 +690,34 @@ static inline int restore_route(int pid) return 0; } +static inline int restore_rule(int pid) +{ + struct cr_img *img; + int ret = 0; + + img = open_image(CR_FD_RULE, O_RSTR, pid); + if (!img) + goto out; + if (empty_image(img)) { + ret = -1; + goto close; + } + /* + * Delete 3 default rules to prevent duplicates. See kernel's + * function fib_default_rules_init() for the details. + */ + run_ip_tool("rule", "delete", NULL, -1, -1); + run_ip_tool("rule", "delete", NULL, -1, -1); + run_ip_tool("rule", "delete", NULL, -1, -1); + + if (restore_ip_dump(CR_FD_RULE, pid, "rule")) + ret = -1; +close: + close_image(img); +out: + return ret; +} + static inline int restore_iptables(int pid) { int ret = -1; @@ -770,6 +819,8 @@ int dump_net_ns(int ns_id) ret = dump_ifaddr(fds); if (!ret) ret = dump_route(fds); + if (!ret) + ret = dump_rule(fds); if (!ret) ret = dump_iptables(fds); @@ -795,6 +846,8 @@ int prepare_net_ns(int pid) ret = restore_ifaddr(pid); if (!ret) ret = restore_route(pid); + if (!ret) + ret = restore_rule(pid); if (!ret) ret = restore_iptables(pid);