]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
xtables: Implement arptables-{save,restore}
authorPhil Sutter <phil@nwl.cc>
Mon, 6 Aug 2018 15:21:57 +0000 (17:21 +0200)
committerFlorian Westphal <fw@strlen.de>
Mon, 6 Aug 2018 16:17:39 +0000 (18:17 +0200)
This adds C implementations for arptables-save and -restore in compat
layer based on the two perl scripts in legacy arptables repository.

To share common code, introduce nft_init_arp() analogous to
nft_init_eb() introduced earlier.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Florian Westphal <fw@strlen.de>
iptables/Makefile.am
iptables/nft-arp.c
iptables/nft.h
iptables/xtables-arp-standalone.c
iptables/xtables-arp.c
iptables/xtables-multi.h
iptables/xtables-nft-multi.c
iptables/xtables-restore.c
iptables/xtables-save.c

index 2cbd586128140234e056ee7c07baaf73e9519f1f..d0218ddc8048703c6db12a207e6023d759834371 100644 (file)
@@ -81,6 +81,8 @@ x_sbin_links  = iptables-nft iptables-nft-restore iptables-nft-save \
                iptables-translate ip6tables-translate \
                iptables-restore-translate ip6tables-restore-translate \
                arptables-nft arptables \
+               arptables-nft-restore arptables-restore \
+               arptables-nft-save arptables-save \
                ebtables-nft ebtables \
                ebtables-nft-restore ebtables-restore \
                ebtables-nft-save ebtables-save \
index 570a2589747cac3cefde7bb209f42ea3e7f3fe86..f58109e5e013c1da0df4c889e2436be2c66947f0 100644 (file)
@@ -436,7 +436,7 @@ static void nft_arp_print_header(unsigned int format, const char *chain,
        }
 }
 
-static void nft_arp_print_rule_details(struct arpt_entry *fw,
+static void nft_arp_print_rule_details(const struct arpt_entry *fw,
                                       unsigned int format)
 {
        char buf[BUFSIZ];
@@ -580,35 +580,48 @@ after_devdst:
 }
 
 static void
-nft_arp_print_rule(struct nftnl_rule *r, unsigned int num, unsigned int format)
+__nft_arp_save_rule(const void *data, unsigned int format)
 {
-       struct iptables_command_state cs = {};
-
-       nft_arp_rule_to_cs(r, &cs);
-
-       if (format & FMT_LINENUMBERS)
-               printf("%u ", num);
+       const struct iptables_command_state *cs = data;
 
-       nft_arp_print_rule_details(&cs.arp, format);
+       nft_arp_print_rule_details(&cs->arp, format);
 
-       if (cs.jumpto != NULL && strcmp(cs.jumpto, "") != 0) {
-               printf("-j %s", cs.jumpto);
-       } else if (cs.target) {
-               printf("-j %s", cs.target->name);
-               cs.target->print(&cs.arp, cs.target->t, format & FMT_NUMERIC);
+       if (cs->jumpto != NULL && strcmp(cs->jumpto, "") != 0) {
+               printf("-j %s", cs->jumpto);
+       } else if (cs->target) {
+               printf("-j %s", cs->target->name);
+               cs->target->print(&cs->arp, cs->target->t, format & FMT_NUMERIC);
        }
 
        if (!(format & FMT_NOCOUNTS)) {
                printf(", pcnt=");
-               xtables_print_num(cs.arp.counters.pcnt, format);
+               xtables_print_num(cs->arp.counters.pcnt, format);
                printf("-- bcnt=");
-               xtables_print_num(cs.arp.counters.bcnt, format);
+               xtables_print_num(cs->arp.counters.bcnt, format);
        }
 
        if (!(format & FMT_NONEWLINE))
                fputc('\n', stdout);
 }
 
+static void
+nft_arp_save_rule(const void *data, unsigned int format)
+{
+       __nft_arp_save_rule(data, format | FMT_NUMERIC);
+}
+
+static void
+nft_arp_print_rule(struct nftnl_rule *r, unsigned int num, unsigned int format)
+{
+       struct iptables_command_state cs = {};
+
+       if (format & FMT_LINENUMBERS)
+               printf("%u ", num);
+
+       nft_arp_rule_to_cs(r, &cs);
+       __nft_arp_save_rule(&cs, format);
+}
+
 static bool nft_arp_is_same(const void *data_a,
                            const void *data_b)
 {
@@ -656,6 +669,13 @@ static bool nft_arp_rule_find(struct nft_family_ops *ops, struct nftnl_rule *r,
        return true;
 }
 
+static void nft_arp_save_chain(const struct nftnl_chain *c, const char *policy)
+{
+       const char *chain = nftnl_chain_get_str(c, NFTNL_CHAIN_NAME);
+
+       printf(":%s %s\n", chain, policy ?: "-");
+}
+
 struct nft_family_ops nft_family_ops_arp = {
        .add                    = nft_arp_add,
        .is_same                = nft_arp_is_same,
@@ -665,8 +685,9 @@ struct nft_family_ops nft_family_ops_arp = {
        .parse_immediate        = nft_arp_parse_immediate,
        .print_header           = nft_arp_print_header,
        .print_rule             = nft_arp_print_rule,
-       .save_rule              = NULL,
+       .save_rule              = nft_arp_save_rule,
        .save_counters          = NULL,
+       .save_chain             = nft_arp_save_chain,
        .post_parse             = NULL,
        .rule_to_cs             = nft_arp_rule_to_cs,
        .clear_cs               = NULL,
index d16ded09ca1819db3c34aacf6007828af74b802b..eb14e908ab9249def1590cb761cef8cab12904e3 100644 (file)
@@ -145,7 +145,8 @@ const char *nft_strerror(int err);
 /* For xtables.c */
 int do_commandx(struct nft_handle *h, int argc, char *argv[], char **table, bool restore);
 /* For xtables-arptables.c */
-int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table);
+int nft_init_arp(struct nft_handle *h, const char *pname);
+int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table, bool restore);
 /* For xtables-eb.c */
 int nft_init_eb(struct nft_handle *h, const char *pname);
 int ebt_get_current_chain(const char *chain);
index 6553d28f6d95ddc28c10aca07cabecea2482cb02..eca7bb979b967b86b98ed9ca5c4ddee97dcac0aa 100644 (file)
@@ -47,24 +47,11 @@ int xtables_arp_main(int argc, char *argv[])
 {
        int ret;
        char *table = "filter";
-       struct nft_handle h = {
-               .family = NFPROTO_ARP,
-       };
+       struct nft_handle h;
 
-       arptables_globals.program_name = "arptables";
-       ret = xtables_init_all(&arptables_globals, NFPROTO_ARP);
-       if (ret < 0) {
-               fprintf(stderr, "%s/%s Failed to initialize arptables-compat\n",
-                       arptables_globals.program_name,
-                       arptables_globals.program_version);
-               exit(1);
-       }
+       nft_init_arp(&h, "arptables");
 
-#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
-       init_extensionsa();
-#endif
-
-       ret = do_commandarp(&h, argc, argv, &table);
+       ret = do_commandarp(&h, argc, argv, &table, false);
        if (ret)
                ret = nft_commit(&h);
 
index 62282f42d00f490879199fac229113f9784327c1..a457ea30ad68535c3fd12c6dd3281b7f5e438baf 100644 (file)
@@ -928,7 +928,36 @@ delete_entry(const char *chain,
        return ret;
 }
 
-int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table)
+int nft_init_arp(struct nft_handle *h, const char *pname)
+{
+       arptables_globals.program_name = pname;
+       if (xtables_init_all(&arptables_globals, NFPROTO_ARP) < 0) {
+               fprintf(stderr, "%s/%s Failed to initialize arptables-compat\n",
+                       arptables_globals.program_name,
+                       arptables_globals.program_version);
+               exit(1);
+       }
+
+#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS)
+       init_extensionsa();
+#endif
+
+       memset(h, 0, sizeof(*h));
+       h->family = NFPROTO_ARP;
+
+       if (nft_init(h, xtables_arp) < 0)
+               xtables_error(OTHER_PROBLEM,
+                             "Could not initialize nftables layer.");
+
+       h->ops = nft_family_ops_lookup(h->family);
+       if (h->ops == NULL)
+               xtables_error(PARAMETER_PROBLEM, "Unknown family");
+
+       return 0;
+}
+
+int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table,
+                 bool restore)
 {
        struct iptables_command_state cs = {
                .jumpto = "",
@@ -1356,14 +1385,6 @@ int do_commandarp(struct nft_handle *h, int argc, char *argv[], char **table)
                                "chain name `%s' too long (must be under %i chars)",
                                chain, ARPT_FUNCTION_MAXNAMELEN);
 
-       if (nft_init(h, xtables_arp) < 0)
-               xtables_error(OTHER_PROBLEM,
-                             "Could not initialize nftables layer.");
-
-       h->ops = nft_family_ops_lookup(h->family);
-       if (h->ops == NULL)
-               xtables_error(PARAMETER_PROBLEM, "Unknown family");
-
        if (command == CMD_APPEND
            || command == CMD_DELETE
            || command == CMD_INSERT
index 8445761849aa190d0ac21a028b656a541221f5e6..0fedb430e1a28477c699317a7af9f3456e02a1fc 100644 (file)
@@ -15,6 +15,8 @@ extern int xtables_eb_xlate_main(int, char **);
 extern int xtables_ip4_xlate_restore_main(int, char **);
 extern int xtables_ip6_xlate_restore_main(int, char **);
 extern int xtables_arp_main(int, char **);
+extern int xtables_arp_restore_main(int, char **);
+extern int xtables_arp_save_main(int, char **);
 extern int xtables_eb_main(int, char **);
 extern int xtables_eb_restore_main(int, char **);
 extern int xtables_eb_save_main(int, char **);
index d9cca088f27a896fbeac2fb20fbbe8c174b4d95b..e2b7c641f85dd958763a3a277d2230edb51f33bf 100644 (file)
@@ -32,6 +32,10 @@ static const struct subcommand multi_subcommands[] = {
        {"ip6tables-restore-translate", xtables_ip6_xlate_restore_main},
        {"arptables",                   xtables_arp_main},
        {"arptables-nft",               xtables_arp_main},
+       {"arptables-restore",           xtables_arp_restore_main},
+       {"arptables-nft-restore",       xtables_arp_restore_main},
+       {"arptables-save",              xtables_arp_save_main},
+       {"arptables-nft-save",          xtables_arp_save_main},
        {"ebtables-translate",          xtables_eb_xlate_main},
        {"ebtables",                    xtables_eb_main},
        {"ebtables-restore",            xtables_eb_restore_main},
index a76acfd4b6cbd937095c64977c63953c677aad51..d2b7920869344c0651c837b2bd07e6b62ee275a5 100644 (file)
@@ -529,3 +529,29 @@ int xtables_eb_restore_main(int argc, char *argv[])
 
        return 0;
 }
+
+struct nft_xt_restore_cb arp_restore_cb = {
+       .chain_list     = get_chain_list,
+       .commit         = nft_commit,
+       .table_new      = nft_table_new,
+       .table_flush    = nft_table_flush,
+       .chain_user_flush = nft_chain_user_flush,
+       .chain_del      = chain_delete,
+       .do_command     = do_commandarp,
+       .chain_set      = nft_chain_set,
+       .chain_user_add = nft_chain_user_add,
+};
+
+int xtables_arp_restore_main(int argc, char *argv[])
+{
+       struct nft_xt_restore_parse p = {
+               .in = stdin,
+       };
+       struct nft_handle h;
+
+       nft_init_arp(&h, "arptables-restore");
+       xtables_restore_parse(&h, &p, &arp_restore_cb, argc, argv);
+       nft_fini(&h);
+
+       return 0;
+}
index c9df51d55327feb3ac0c3e20efa437f3da258b7f..fc51fcfeb5815749d081ece9bee0ce7ada8e743c 100644 (file)
@@ -287,3 +287,42 @@ int xtables_eb_save_main(int argc_, char *argv_[])
        nft_for_each_table(&h, __ebt_save, !!ctr);
        return 0;
 }
+
+int xtables_arp_save_main(int argc, char **argv)
+{
+       struct nft_handle h = {
+               .family = NFPROTO_ARP,
+       };
+       int c;
+
+       xtables_globals.program_name = "arptables-save";
+       c = xtables_init_all(&xtables_globals, h.family);
+       if (c < 0) {
+               fprintf(stderr, "%s/%s Failed to initialize xtables\n",
+                               xtables_globals.program_name,
+                               xtables_globals.program_version);
+               exit(1);
+       }
+
+       if (nft_init(&h, xtables_arp) < 0) {
+               fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
+                               xtables_globals.program_name,
+                               xtables_globals.program_version,
+                               strerror(errno));
+               exit(EXIT_FAILURE);
+       }
+
+       if (!nft_table_find(&h, "filter"))
+               return 0;
+
+       if (!nft_is_table_compatible(&h, "filter")) {
+               printf("# Table `filter' is incompatible, use 'nft' tool.\n");
+               return 0;
+       }
+
+       printf("*filter\n");
+       nft_chain_save(&h, nft_chain_dump(&h), "filter");
+       nft_rule_save(&h, "filter", FMT_NOCOUNTS);
+       printf("\n");
+       return 0;
+}