summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--iptables/nft-bridge.c38
-rw-r--r--iptables/xtables-save.c60
2 files changed, 81 insertions, 17 deletions
diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c
index 92e3f3b6..8c69a236 100644
--- a/iptables/nft-bridge.c
+++ b/iptables/nft-bridge.c
@@ -21,6 +21,8 @@
#include "nft-bridge.h"
#include "nft.h"
+static bool ebt_legacy_counter_fmt;
+
void ebt_cs_clean(struct iptables_command_state *cs)
{
struct ebt_match *m, *nm;
@@ -410,6 +412,22 @@ static void print_protocol(uint16_t ethproto, bool invert, unsigned int bitmask)
printf("%s ", ent->e_name);
}
+static void nft_bridge_save_counters(const void *data)
+{
+ const char *ctr;
+
+ if (ebt_legacy_counter_fmt)
+ return;
+
+ ctr = getenv("EBTABLES_SAVE_COUNTER");
+ if (ctr) {
+ ebt_legacy_counter_fmt = true;
+ return;
+ }
+
+ save_counters(data);
+}
+
static void nft_bridge_save_rule(const void *data, unsigned int format)
{
const struct iptables_command_state *cs = data;
@@ -446,18 +464,10 @@ static void nft_bridge_save_rule(const void *data, unsigned int format)
cs->target->print(&cs->fw, cs->target->t, format & FMT_NUMERIC);
}
- if (!(format & FMT_NOCOUNTS)) {
- const char *counter_fmt;
-
- if (format & FMT_EBT_SAVE)
- counter_fmt = " -c %"PRIu64" %"PRIu64"";
- else
- counter_fmt = " , pcnt = %"PRIu64" -- bcnt = %"PRIu64"";
-
- printf(counter_fmt,
+ if (format & FMT_EBT_SAVE)
+ printf(" -c %"PRIu64" %"PRIu64"",
(uint64_t)cs->counters.pcnt,
(uint64_t)cs->counters.bcnt);
- }
if (!(format & FMT_NONEWLINE))
fputc('\n', stdout);
@@ -472,7 +482,11 @@ static void nft_bridge_print_rule(struct nftnl_rule *r, unsigned int num,
printf("%d ", num);
nft_rule_to_ebtables_command_state(r, &cs);
- nft_bridge_save_rule(&cs, format);
+ nft_bridge_save_rule(&cs, format & ~FMT_EBT_SAVE);
+ if (!(format & FMT_NOCOUNTS))
+ printf(" , pcnt = %"PRIu64" -- bcnt = %"PRIu64"",
+ (uint64_t)cs.counters.pcnt,
+ (uint64_t)cs.counters.bcnt);
ebt_cs_clean(&cs);
}
@@ -734,7 +748,7 @@ struct nft_family_ops nft_family_ops_bridge = {
.print_header = nft_bridge_print_header,
.print_rule = nft_bridge_print_rule,
.save_rule = nft_bridge_save_rule,
- .save_counters = NULL,
+ .save_counters = nft_bridge_save_counters,
.save_chain = nft_bridge_save_chain,
.post_parse = NULL,
.rule_to_cs = nft_rule_to_ebtables_command_state,
diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c
index 87b299c5..28711720 100644
--- a/iptables/xtables-save.c
+++ b/iptables/xtables-save.c
@@ -43,6 +43,16 @@ static const struct option options[] = {
{NULL},
};
+static const struct option ebt_save_options[] = {
+ {.name = "counters", .has_arg = false, .val = 'c'},
+ {.name = "version", .has_arg = false, .val = 'V'},
+ {.name = "table", .has_arg = true, .val = 't'},
+ {.name = "modprobe", .has_arg = true, .val = 'M'},
+ {NULL},
+};
+
+static bool ebt_legacy_counter_format;
+
static int
__do_output(struct nft_handle *h, const char *tablename, bool counters)
{
@@ -226,6 +236,7 @@ int xtables_ip6_save_main(int argc, char *argv[])
static int __ebt_save(struct nft_handle *h, const char *tablename, bool counters)
{
struct nftnl_chain_list *chain_list;
+ unsigned int format = FMT_NOCOUNTS;
static bool first = true;
time_t now;
@@ -249,25 +260,40 @@ static int __ebt_save(struct nft_handle *h, const char *tablename, bool counters
}
printf("*%s\n", tablename);
+ if (counters)
+ format = ebt_legacy_counter_format ? FMT_EBT_SAVE : 0;
+
/* Dump out chain names first,
* thereby preventing dependency conflicts */
nft_chain_save(h, chain_list, tablename);
- nft_rule_save(h, tablename,
- FMT_EBT_SAVE | (counters ? 0 : FMT_NOCOUNTS));
+ nft_rule_save(h, tablename, format);
printf("\n");
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 && strcmp(ctr, "yes"))
- ctr = NULL;
+ if (ctr) {
+ if (strcmp(ctr, "yes") == 0) {
+ ebt_legacy_counter_format = true;
+ show_counters = true;
+ }
+ }
xtables_globals.program_name = "ebtables-save";
c = xtables_init_all(&xtables_globals, h.family);
@@ -278,6 +304,30 @@ int xtables_eb_save_main(int argc_, char *argv_[])
exit(1);
}
+ while ((c = getopt_long(argc_, argv_, "ct:M:V", 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 `xtables-save.8' for more information.\n");
+ exit(1);
+ }
+ }
+
if (nft_init(&h, xtables_bridge) < 0) {
fprintf(stderr, "%s/%s Failed to initialize nft: %s\n",
xtables_globals.program_name,
@@ -286,7 +336,7 @@ int xtables_eb_save_main(int argc_, char *argv_[])
exit(EXIT_FAILURE);
}
- nft_for_each_table(&h, __ebt_save, !!ctr);
+ ebt_save(&h, tablename, show_counters);
nft_fini(&h);
return 0;
}