diff options
author | Phil Sutter <phil@nwl.cc> | 2018-07-19 18:32:09 +0200 |
---|---|---|
committer | Florian Westphal <fw@strlen.de> | 2018-07-19 23:13:02 +0200 |
commit | 922508e9156327ccb8e35243781cf85f5787ee40 (patch) | |
tree | ba9f497f248cb16216ae69972b694f162d602424 /iptables/xtables-save.c | |
parent | 25ef90814a991e80384d4369565c6decadfcd409 (diff) |
xtables: implement ebtables-{save,restore}
The code for ebtables-restore was derived from legacy code,
ebtables-save is actually a new implementation using the existing
infrastructure and trying to adhere to legacy perl script output
formatting as much as possible.
This introduces a new format flag (FMT_EBT_SAVE) to allow
nft_bridge_save_rule() to distinguish between ruleset listing (i.e.,
ebtables -L) and saving via ebtables-save - the two differ in how
counters are being formatted. Odd, but that's how it is.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Florian Westphal <fw@strlen.de>
Diffstat (limited to 'iptables/xtables-save.c')
-rw-r--r-- | iptables/xtables-save.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c index e6bad32f..c9df51d5 100644 --- a/iptables/xtables-save.c +++ b/iptables/xtables-save.c @@ -220,3 +220,70 @@ int xtables_ip6_save_main(int argc, char *argv[]) { return xtables_save_main(NFPROTO_IPV6, "ip6tables-save", argc, argv); } + +static int __ebt_save(struct nft_handle *h, const char *tablename, bool counters) +{ + struct nftnl_chain_list *chain_list; + static bool first = true; + 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_dump(h); + + if (first) { + now = time(NULL); + printf("# Generated by ebtables-save v%s on %s", + IPTABLES_VERSION, ctime(&now)); + first = false; + } + printf("*%s\n", tablename); + + /* 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)); + printf("\n"); + return 0; +} + +int xtables_eb_save_main(int argc_, char *argv_[]) +{ + const char *ctr = getenv("EBTABLES_SAVE_COUNTER"); + struct nft_handle h = { + .family = NFPROTO_BRIDGE, + }; + int c; + + if (ctr && strcmp(ctr, "yes")) + ctr = NULL; + + xtables_globals.program_name = "ebtables-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_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); + } + + nft_for_each_table(&h, __ebt_save, !!ctr); + return 0; +} |