summaryrefslogtreecommitdiffstats
path: root/iptables/xtables-restore.c
diff options
context:
space:
mode:
Diffstat (limited to 'iptables/xtables-restore.c')
-rw-r--r--iptables/xtables-restore.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c
index f9392457..5c0ae98e 100644
--- a/iptables/xtables-restore.c
+++ b/iptables/xtables-restore.c
@@ -16,6 +16,7 @@
#include "libiptc/libiptc.h"
#include "xtables-multi.h"
#include "nft.h"
+#include "nft-bridge.h"
#include <libnftnl/chain.h>
#ifdef DEBUG
@@ -581,3 +582,116 @@ int xtables_ip6_restore_main(int argc, char *argv[])
return xtables_restore_main(NFPROTO_IPV6, "ip6tables-restore",
argc, argv);
}
+
+static const char *ebt_parse_table_name(const char *input)
+{
+ if (!strcmp(input, "broute"))
+ xtables_error(PARAMETER_PROBLEM, "broute table not supported");
+ else if (!strcmp(input, "filter"))
+ return "filter";
+ else if (!strcmp(input, "nat"))
+ return "nat";
+
+ xtables_error(PARAMETER_PROBLEM, "table '%s' not recognized", input);
+}
+
+static const char *ebt_parse_policy_name(const char *input)
+{
+ int i;
+
+ for (i = 0; i < NUM_STANDARD_TARGETS; i++) {
+ if (!strcmp(input, ebt_standard_targets[i])) {
+ int policy = -i - 1;
+
+ if (policy == EBT_CONTINUE)
+ i = NUM_STANDARD_TARGETS;
+ break;
+ }
+ }
+ if (i == NUM_STANDARD_TARGETS)
+ xtables_error(PARAMETER_PROBLEM, "invalid policy specified");
+ return ebt_standard_targets[i];
+}
+
+static const struct option ebt_restore_options[] = {
+ {.name = "noflush", .has_arg = 0, .val = 'n'},
+ { 0 }
+};
+
+int xtables_eb_restore_main(int argc, char *argv[])
+{
+ char buffer[10240];
+ int i, ret, c, flush = 1;
+ const char *table = NULL;
+ struct nft_handle h;
+
+ nft_init_eb(&h);
+
+ while ((c = getopt_long(argc, argv, "n",
+ ebt_restore_options, NULL)) != -1) {
+ switch(c) {
+ case 'n':
+ flush = 0;
+ break;
+ default:
+ fprintf(stderr,
+ "Usage: ebtables-restore [ --noflush ]\n");
+ exit(1);
+ break;
+ }
+ }
+
+ while (fgets(buffer, sizeof(buffer), stdin)) {
+ if (buffer[0] == '#' || buffer[0] == '\n')
+ continue;
+ if (buffer[0] == '*') {
+ table = ebt_parse_table_name(buffer + 1);
+ if (flush)
+ nft_table_flush(&h, table);
+ continue;
+ } else if (!table) {
+ xtables_error(PARAMETER_PROBLEM, "no table specified");
+ }
+ if (buffer[0] == ':') {
+ char *ch, *chain = buffer;
+ const char *policy;
+
+ if (!(ch = strchr(buffer, ' ')))
+ xtables_error(PARAMETER_PROBLEM, "no policy specified");
+ *ch = '\0';
+ policy = ebt_parse_policy_name(ch + 1);
+
+ /* No need to check chain name for consistency, since
+ * we're supposed to be reading an automatically generated
+ * file. */
+ if (ebt_get_current_chain(chain) < 0)
+ nft_chain_user_add(&h, chain, table);
+ ret = nft_chain_set(&h, table, chain, policy, NULL);
+ if (ret < 0)
+ xtables_error(PARAMETER_PROBLEM, "Wrong policy");
+ continue;
+ }
+
+ newargc = 0;
+ add_argv("ebtables");
+ add_argv("-t");
+ add_argv(table);
+ add_param_to_argv(buffer);
+
+ DEBUGP("calling do_commandeb(%u, argv, &%s, handle):\n",
+ newargc, table);
+
+ for (i = 0; i < newargc; i++)
+ DEBUGP("argv[%u]: %s\n", i, newargv[i]);
+
+ optind = 0; /* Setting optind = 1 causes serious annoyances */
+ if (!do_commandeb(&h, newargc, newargv, &newargv[2]))
+ return 1;
+ }
+
+ if (!nft_commit(&h)) {
+ fprintf(stderr, "%s\n", nft_strerror(errno));
+ return 1;
+ }
+ return 0;
+}