The only thing missing was handling of EBTABLES_SAVE_COUNTER env var,
but that can be done after parsing parameters in bridge-specific code.

Signed-off-by: Phil Sutter <p...@nwl.cc>
---
 iptables/xtables-save.c | 123 +++++-----------------------------------
 1 file changed, 13 insertions(+), 110 deletions(-)

diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c
index 0c294e056c7b5..77b13f7ffbcdd 100644
--- a/iptables/xtables-save.c
+++ b/iptables/xtables-save.c
@@ -31,8 +31,6 @@
 #define prog_name xtables_globals.program_name
 #define prog_vers xtables_globals.program_version
 
-static bool show_counters = false;
-
 static const char *ipt_save_optstring = "bcdt:M:f:46V";
 static const struct option ipt_save_options[] = {
        {.name = "counters", .has_arg = false, .val = 'c'},
@@ -63,8 +61,6 @@ static const struct option ebt_save_options[] = {
        {NULL},
 };
 
-static bool ebt_legacy_counter_format;
-
 struct do_output_data {
        unsigned int format;
        bool commit;
@@ -228,9 +224,18 @@ xtables_save_main(int family, int argc, char *argv[],
        case NFPROTO_ARP:
                tables = xtables_arp;
                break;
-       case NFPROTO_BRIDGE:
+       case NFPROTO_BRIDGE: {
+               const char *ctr = getenv("EBTABLES_SAVE_COUNTER");
+
+               if (!(d.format & FMT_NOCOUNTS)) {
+                       d.format |= FMT_EBT_SAVE;
+               } else if (ctr && !strcmp(ctr, "yes")) {
+                       d.format &= ~FMT_NOCOUNTS;
+                       d.format |= FMT_C_COUNTS | FMT_EBT_SAVE;
+               }
                tables = xtables_bridge;
                break;
+       }
        default:
                fprintf(stderr, "Unknown family %d\n", family);
                return 1;
@@ -264,112 +269,10 @@ int xtables_ip6_save_main(int argc, char *argv[])
                                 ipt_save_optstring, ipt_save_options);
 }
 
-static int __ebt_save(struct nft_handle *h, const char *tablename, void *data)
+int xtables_eb_save_main(int argc, char *argv[])
 {
-       struct nftnl_chain_list *chain_list;
-       unsigned int format = FMT_NOCOUNTS;
-       bool *counters = data;
-       time_t now;
-
-       if (!nft_table_find(h, tablename)) {
-               printf("Table `%s' does not exist\n", tablename);
-               return 1;
-       }
-
-       if (!nft_is_table_compatible(h, tablename)) {
-               printf("# Table `%s' is incompatible, use 'nft' tool.\n", 
tablename);
-               return 0;
-       }
-
-       chain_list = nft_chain_list_get(h, tablename);
-
-       now = time(NULL);
-       printf("# Generated by %s v%s on %s", prog_name,
-              prog_vers, ctime(&now));
-       printf("*%s\n", tablename);
-
-       if (counters)
-               format = FMT_EBT_SAVE |
-                       (ebt_legacy_counter_format ? FMT_C_COUNTS : 0);
-
-       /* Dump out chain names first,
-        * thereby preventing dependency conflicts */
-       nft_chain_save(h, chain_list);
-       nft_rule_save(h, tablename, format);
-       now = time(NULL);
-       printf("# Completed on %s", ctime(&now));
-       return 0;
-}
-
-static int ebt_save(struct nft_handle *h, const char *tablename, bool counters)
-{
-       if (!tablename)
-               return nft_for_each_table(h, __ebt_save, &counters);
-
-       return __ebt_save(h, tablename, &counters);
-}
-
-int xtables_eb_save_main(int argc_, char *argv_[])
-{
-       const char *ctr = getenv("EBTABLES_SAVE_COUNTER");
-       const char *tablename = NULL;
-       struct nft_handle h = {
-               .family = NFPROTO_BRIDGE,
-       };
-       int c;
-
-       if (ctr) {
-               if (strcmp(ctr, "yes") == 0) {
-                       ebt_legacy_counter_format = true;
-                       show_counters = true;
-               }
-       }
-
-       xtables_globals.program_name = basename(*argv_);
-       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);
-       }
-
-       while ((c = getopt_long(argc_, argv_, ebt_save_optstring, 
ebt_save_options, NULL)) != -1) {
-               switch (c) {
-               case 'c':
-                       unsetenv("EBTABLES_SAVE_COUNTER");
-                       show_counters = true;
-                       ebt_legacy_counter_format = false;
-                       break;
-               case 't':
-                       /* Select specific table. */
-                       tablename = optarg;
-                       break;
-               case 'M':
-                       xtables_modprobe_program = optarg;
-                       break;
-               case 'V':
-                       printf("%s v%s (nf_tables)\n", prog_name, prog_vers);
-                       exit(0);
-               default:
-                       fprintf(stderr,
-                               "Look at manual page `%s.8' for more 
information.\n",
-                               prog_name);
-                       exit(1);
-               }
-       }
-
-       if (nft_init(&h, xtables_bridge) < 0) {
-               fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
-                               xtables_globals.program_name,
-                               xtables_globals.program_version,
-                               strerror(errno));
-               exit(EXIT_FAILURE);
-       }
-
-       ebt_save(&h, tablename, show_counters);
-       nft_fini(&h);
-       return 0;
+       return xtables_save_main(NFPROTO_BRIDGE, argc, argv,
+                                ebt_save_optstring, ebt_save_options);
 }
 
 int xtables_arp_save_main(int argc, char *argv[])
-- 
2.22.0

Reply via email to