summaryrefslogtreecommitdiffstats
path: root/iptables/xtables-save.c
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2018-07-19 18:32:09 +0200
committerFlorian Westphal <fw@strlen.de>2018-07-19 23:13:02 +0200
commit922508e9156327ccb8e35243781cf85f5787ee40 (patch)
treeba9f497f248cb16216ae69972b694f162d602424 /iptables/xtables-save.c
parent25ef90814a991e80384d4369565c6decadfcd409 (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.c67
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;
+}