From 384958620abab397062b67fb2763e813b63f74f0 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 27 Sep 2012 19:12:53 +0200 Subject: use nf_tables and nf_tables compatibility interface This patch adds the following utilities: * xtables * xtables-restore * xtables-save * xtables-config They all use Patrick's nf_tables infrastructure plus my compatibility layer. xtables, xtables-restore and xtables-save are syntax compatible with ip[6]tables, ip[6]tables-restore and ip[6]tables-save. Semantics aims to be similar, still the main exception is that there is no commit operation. Thus, we incrementally add/delete rules without entire table locking. The following options are also not yet implemented: -Z (this requires adding expr->ops->reset(...) so nft_counters can reset internal state of expressions while dumping it) -R and -E (this requires adding this feature to nf_tables) -f (can be implemented with expressions: payload 6 (2-bytes) + bitwise a&b^!b + cmp neq 0) -IPv6 support. But those are a matter of time to get them done. A new utility, xtables-config, is available to register tables and chains. By default there is a configuration file that adds backward compatible tables and chains under iptables/etc/xtables.conf. You have to call this utility first to register tables and chains. However, it would be possible to automagically register tables and chains while using xtables and xtables-restore to get similar operation than with iptables. Signed-off-by: Pablo Neira Ayuso --- iptables/xtables-restore.c | 417 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 417 insertions(+) create mode 100644 iptables/xtables-restore.c (limited to 'iptables/xtables-restore.c') diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c new file mode 100644 index 00000000..09922a0c --- /dev/null +++ b/iptables/xtables-restore.c @@ -0,0 +1,417 @@ +/* Code to restore the iptables state, from file by iptables-save. + * (C) 2000-2002 by Harald Welte + * based on previous code from Rusty Russell + * + * This code is distributed under the terms of GNU GPL v2 + */ + +#include +#include +#include +#include +#include +#include +#include "iptables.h" +#include "xtables.h" +#include "libiptc/libiptc.h" +#include "xtables-multi.h" +#include "nft.h" + +#ifdef DEBUG +#define DEBUGP(x, args...) fprintf(stderr, x, ## args) +#else +#define DEBUGP(x, args...) +#endif + +static int binary = 0, counters = 0, verbose = 0, noflush = 0; + +/* Keeping track of external matches and targets. */ +static const struct option options[] = { + {.name = "binary", .has_arg = false, .val = 'b'}, + {.name = "counters", .has_arg = false, .val = 'c'}, + {.name = "verbose", .has_arg = false, .val = 'v'}, + {.name = "test", .has_arg = false, .val = 't'}, + {.name = "help", .has_arg = false, .val = 'h'}, + {.name = "noflush", .has_arg = false, .val = 'n'}, + {.name = "modprobe", .has_arg = true, .val = 'M'}, + {.name = "table", .has_arg = true, .val = 'T'}, + {NULL}, +}; + +static void print_usage(const char *name, const char *version) __attribute__((noreturn)); + +#define prog_name xtables_globals.program_name + +static void print_usage(const char *name, const char *version) +{ + fprintf(stderr, "Usage: %s [-b] [-c] [-v] [-t] [-h]\n" + " [ --binary ]\n" + " [ --counters ]\n" + " [ --verbose ]\n" + " [ --test ]\n" + " [ --help ]\n" + " [ --noflush ]\n" + " [ --table= ]\n" + " [ --modprobe=]\n", name); + + exit(1); +} + +static int parse_counters(char *string, struct xt_counters *ctr) +{ + unsigned long long pcnt, bcnt; + int ret; + + ret = sscanf(string, "[%llu:%llu]", &pcnt, &bcnt); + ctr->pcnt = pcnt; + ctr->bcnt = bcnt; + return ret == 2; +} + +/* global new argv and argc */ +static char *newargv[255]; +static int newargc; + +/* function adding one argument to newargv, updating newargc + * returns true if argument added, false otherwise */ +static int add_argv(char *what) { + DEBUGP("add_argv: %s\n", what); + if (what && newargc + 1 < ARRAY_SIZE(newargv)) { + newargv[newargc] = strdup(what); + newargv[++newargc] = NULL; + return 1; + } else { + xtables_error(PARAMETER_PROBLEM, + "Parser cannot handle more arguments\n"); + return 0; + } +} + +static void free_argv(void) { + int i; + + for (i = 0; i < newargc; i++) + free(newargv[i]); +} + +static void add_param_to_argv(char *parsestart) +{ + int quote_open = 0, escaped = 0, param_len = 0; + char param_buffer[1024], *curchar; + + /* After fighting with strtok enough, here's now + * a 'real' parser. According to Rusty I'm now no + * longer a real hacker, but I can live with that */ + + for (curchar = parsestart; *curchar; curchar++) { + if (quote_open) { + if (escaped) { + param_buffer[param_len++] = *curchar; + escaped = 0; + continue; + } else if (*curchar == '\\') { + escaped = 1; + continue; + } else if (*curchar == '"') { + quote_open = 0; + *curchar = ' '; + } else { + param_buffer[param_len++] = *curchar; + continue; + } + } else { + if (*curchar == '"') { + quote_open = 1; + continue; + } + } + + if (*curchar == ' ' + || *curchar == '\t' + || * curchar == '\n') { + if (!param_len) { + /* two spaces? */ + continue; + } + + param_buffer[param_len] = '\0'; + + /* check if table name specified */ + if (!strncmp(param_buffer, "-t", 2) + || !strncmp(param_buffer, "--table", 8)) { + xtables_error(PARAMETER_PROBLEM, + "The -t option (seen in line %u) cannot be " + "used in xtables-restore.\n", line); + exit(1); + } + + add_argv(param_buffer); + param_len = 0; + } else { + /* regular character, copy to buffer */ + param_buffer[param_len++] = *curchar; + + if (param_len >= sizeof(param_buffer)) + xtables_error(PARAMETER_PROBLEM, + "Parameter too long!"); + } + } +} + +int +xtables_restore_main(int argc, char *argv[]) +{ + struct nft_handle h; + char buffer[10240]; + int c; + char curtable[XT_TABLE_MAXNAMELEN + 1]; + FILE *in; + int in_table = 0, testing = 0; + const char *tablename = NULL; + const struct xtc_ops *ops = &iptc_ops; + + line = 0; + + xtables_globals.program_name = "xtables-restore"; + c = xtables_init_all(&xtables_globals, NFPROTO_IPV4); + if (c < 0) { + fprintf(stderr, "%s/%s Failed to initialize xtables\n", + xtables_globals.program_name, + xtables_globals.program_version); + exit(1); + } +#if defined(ALL_INCLUSIVE) || defined(NO_SHARED_LIBS) + init_extensions(); + init_extensions4(); +#endif + + nft_init(&h); + + while ((c = getopt_long(argc, argv, "bcvthnM:T:", options, NULL)) != -1) { + switch (c) { + case 'b': + binary = 1; + break; + case 'c': + counters = 1; + break; + case 'v': + verbose = 1; + break; + case 't': + testing = 1; + break; + case 'h': + print_usage("xtables-restore", + IPTABLES_VERSION); + break; + case 'n': + noflush = 1; + break; + case 'M': + xtables_modprobe_program = optarg; + break; + case 'T': + tablename = optarg; + break; + } + } + + if (optind == argc - 1) { + in = fopen(argv[optind], "re"); + if (!in) { + fprintf(stderr, "Can't open %s: %s\n", argv[optind], + strerror(errno)); + exit(1); + } + } + else if (optind < argc) { + fprintf(stderr, "Unknown arguments found on commandline\n"); + exit(1); + } + else in = stdin; + + /* Grab standard input. */ + while (fgets(buffer, sizeof(buffer), in)) { + int ret = 0; + + line++; + if (buffer[0] == '\n') + continue; + else if (buffer[0] == '#') { + if (verbose) + fputs(buffer, stdout); + continue; + } else if ((strcmp(buffer, "COMMIT\n") == 0) && (in_table)) { + /* FIXME commit/testing operation not supported */ + if (!testing) { + DEBUGP("Calling commit\n"); + ret = 1; + } else { + DEBUGP("Not calling commit, testing\n"); + ret = 1; + } + in_table = 0; + } else if ((buffer[0] == '*') && (!in_table)) { + /* New table */ + char *table; + + table = strtok(buffer+1, " \t\n"); + DEBUGP("line %u, table '%s'\n", line, table); + if (!table) { + xtables_error(PARAMETER_PROBLEM, + "%s: line %u table name invalid\n", + xt_params->program_name, line); + exit(1); + } + strncpy(curtable, table, XT_TABLE_MAXNAMELEN); + curtable[XT_TABLE_MAXNAMELEN] = '\0'; + + if (tablename && (strcmp(tablename, table) != 0)) + continue; + + if (noflush == 0) { + DEBUGP("Cleaning all chains of table '%s'\n", + table); + nft_rule_flush(&h, NULL, table); + + DEBUGP("Deleting all user-defined chains " + "of table '%s'\n", table); + nft_chain_user_del(&h, NULL, table); + } + + ret = 1; + in_table = 1; + + } else if ((buffer[0] == ':') && (in_table)) { + /* New chain. */ + char *policy, *chain = NULL; + struct xt_counters count = {}; + + chain = strtok(buffer+1, " \t\n"); + DEBUGP("line %u, chain '%s'\n", line, chain); + if (!chain) { + xtables_error(PARAMETER_PROBLEM, + "%s: line %u chain name invalid\n", + xt_params->program_name, line); + exit(1); + } + + if (strlen(chain) >= XT_EXTENSION_MAXNAMELEN) + xtables_error(PARAMETER_PROBLEM, + "Invalid chain name `%s' " + "(%u chars max)", + chain, XT_EXTENSION_MAXNAMELEN - 1); + + policy = strtok(NULL, " \t\n"); + DEBUGP("line %u, policy '%s'\n", line, policy); + if (!policy) { + xtables_error(PARAMETER_PROBLEM, + "%s: line %u policy invalid\n", + xt_params->program_name, line); + exit(1); + } + + if (strcmp(policy, "-") != 0) { + if (counters) { + char *ctrs; + ctrs = strtok(NULL, " \t\n"); + + if (!ctrs || !parse_counters(ctrs, &count)) + xtables_error(PARAMETER_PROBLEM, + "invalid policy counters " + "for chain '%s'\n", chain); + + } + + DEBUGP("Setting policy of chain %s to %s\n", + chain, policy); + } + + if (nft_chain_set(&h, curtable, chain, policy, &count) < 0) { + xtables_error(OTHER_PROBLEM, + "Can't set policy `%s'" + " on `%s' line %u: %s\n", + policy, chain, line, + ops->strerror(errno)); + } + + ret = 1; + + } else if (in_table) { + int a; + char *ptr = buffer; + char *pcnt = NULL; + char *bcnt = NULL; + char *parsestart; + + /* reset the newargv */ + newargc = 0; + + if (buffer[0] == '[') { + /* we have counters in our input */ + ptr = strchr(buffer, ']'); + if (!ptr) + xtables_error(PARAMETER_PROBLEM, + "Bad line %u: need ]\n", + line); + + pcnt = strtok(buffer+1, ":"); + if (!pcnt) + xtables_error(PARAMETER_PROBLEM, + "Bad line %u: need :\n", + line); + + bcnt = strtok(NULL, "]"); + if (!bcnt) + xtables_error(PARAMETER_PROBLEM, + "Bad line %u: need ]\n", + line); + + /* start command parsing after counter */ + parsestart = ptr + 1; + } else { + /* start command parsing at start of line */ + parsestart = buffer; + } + + add_argv(argv[0]); + add_argv("-t"); + add_argv(curtable); + + if (counters && pcnt && bcnt) { + add_argv("--set-counters"); + add_argv((char *) pcnt); + add_argv((char *) bcnt); + } + + add_param_to_argv(parsestart); + + DEBUGP("calling do_command4(%u, argv, &%s, handle):\n", + newargc, curtable); + + for (a = 0; a < newargc; a++) + DEBUGP("argv[%u]: %s\n", a, newargv[a]); + + ret = do_commandx(&h, newargc, newargv, &newargv[2]); + + free_argv(); + fflush(stdout); + } + if (tablename && (strcmp(tablename, curtable) != 0)) + continue; + if (!ret) { + fprintf(stderr, "%s: line %u failed\n", + xt_params->program_name, line); + exit(1); + } + } + if (in_table) { + fprintf(stderr, "%s: COMMIT expected at line %u\n", + xt_params->program_name, line + 1); + exit(1); + } + + fclose(in); + return 0; +} -- cgit v1.2.3 From 5705ea1f4e3c9cd3d5d9cbcf84b9733ce1f07e57 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 19 Nov 2012 15:32:18 +0100 Subject: xtables-restore: add support for dormant tables This patch adds support for dormant tables for xtables-restore. Signed-off-by: Pablo Neira Ayuso --- iptables/xtables-restore.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'iptables/xtables-restore.c') diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c index 09922a0c..30ea813c 100644 --- a/iptables/xtables-restore.c +++ b/iptables/xtables-restore.c @@ -243,11 +243,16 @@ xtables_restore_main(int argc, char *argv[]) fputs(buffer, stdout); continue; } else if ((strcmp(buffer, "COMMIT\n") == 0) && (in_table)) { - /* FIXME commit/testing operation not supported */ if (!testing) { + if (nft_table_wake_dormant(&h, curtable) < 0) { + fprintf(stderr, "Failed to wake up " + "dormant table `%s'\n", + curtable); + } DEBUGP("Calling commit\n"); ret = 1; } else { + /* FIXME -t needs to be fixed */ DEBUGP("Not calling commit, testing\n"); ret = 1; } @@ -270,6 +275,7 @@ xtables_restore_main(int argc, char *argv[]) if (tablename && (strcmp(tablename, table) != 0)) continue; + nft_table_set_dormant(&h, table); if (noflush == 0) { DEBUGP("Cleaning all chains of table '%s'\n", table); -- cgit v1.2.3 From 0391677c1a0b28c14d01febd9628a543e8e5fd62 Mon Sep 17 00:00:00 2001 From: Tomasz Bursztyka Date: Sun, 13 Jan 2013 16:42:11 +0100 Subject: xtables: add IPv6 support Summary of changes to add IPv6 support to the xtables utility: * modify all commands (add, delete, replace, check and listing) to support IPv6 addresses. And for the internal nft library: * add family to struct nft_handle and modify all caller to use this family instead of the hardcoded AF_INET. * move code that we can re-use for IPv4 and IPv6 into helper functions. * add IPv6 rule printing support. * add support to parse IPv6 address. Pablo added several improvements to this patch: * added basic xtables-save and xtables-restore support (so it defaults to IPv4) * fixed a couple of bugs found while testing * added reference when -f is used to point to -m frag (until we can make this consistent with IPv4). Note that we use one single xtables binary utility for IPv4 and IPv6. Signed-off-by: Tomasz Bursztyka Signed-off-by: Pablo Neira Ayuso --- iptables/xtables-restore.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'iptables/xtables-restore.c') diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c index 30ea813c..e83eacc3 100644 --- a/iptables/xtables-restore.c +++ b/iptables/xtables-restore.c @@ -161,7 +161,9 @@ static void add_param_to_argv(char *parsestart) int xtables_restore_main(int argc, char *argv[]) { - struct nft_handle h; + struct nft_handle h = { + .family = AF_INET, /* default to IPv4 */ + }; char buffer[10240]; int c; char curtable[XT_TABLE_MAXNAMELEN + 1]; -- cgit v1.2.3 From 3bbe7c1a0a2a3bab261aeb00cf4c5adcc96bf109 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 20 Jan 2013 20:18:02 +0100 Subject: xtables-restore: fix custom user chain restoration Signed-off-by: Pablo Neira Ayuso --- iptables/xtables-restore.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'iptables/xtables-restore.c') diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c index e83eacc3..f6009776 100644 --- a/iptables/xtables-restore.c +++ b/iptables/xtables-restore.c @@ -331,20 +331,29 @@ xtables_restore_main(int argc, char *argv[]) "for chain '%s'\n", chain); } - + if (nft_chain_set(&h, curtable, chain, policy, &count) < 0) { + xtables_error(OTHER_PROBLEM, + "Can't set policy `%s'" + " on `%s' line %u: %s\n", + policy, chain, line, + ops->strerror(errno)); + } DEBUGP("Setting policy of chain %s to %s\n", - chain, policy); - } + chain, policy); + ret = 1; - if (nft_chain_set(&h, curtable, chain, policy, &count) < 0) { - xtables_error(OTHER_PROBLEM, - "Can't set policy `%s'" - " on `%s' line %u: %s\n", - policy, chain, line, - ops->strerror(errno)); - } + } else { + if (nft_chain_user_add(&h, chain, curtable) < 0) { + if (errno == EEXIST) + continue; - ret = 1; + xtables_error(PARAMETER_PROBLEM, + "cannot create chain " + "'%s' (%s)\n", chain, + strerror(errno)); + } + continue; + } } else if (in_table) { int a; -- cgit v1.2.3 From 0aad20f3979e3b6becd40e4ed5bba8d09d90706e Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 20 Jan 2013 22:32:43 +0100 Subject: xtables: purge out user-define chains from the kernel xtables-restore has to purge out user-defined chains that are not defined in the configuration file. Signed-off-by: Pablo Neira Ayuso --- iptables/xtables-restore.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'iptables/xtables-restore.c') diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c index f6009776..9778a9f7 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 #ifdef DEBUG #define DEBUGP(x, args...) fprintf(stderr, x, ## args) @@ -171,6 +172,8 @@ xtables_restore_main(int argc, char *argv[]) int in_table = 0, testing = 0; const char *tablename = NULL; const struct xtc_ops *ops = &iptc_ops; + struct nft_chain_list *chain_list; + struct nft_chain *chain_obj; line = 0; @@ -233,6 +236,10 @@ xtables_restore_main(int argc, char *argv[]) } else in = stdin; + chain_list = nft_chain_dump(&h); + if (chain_list == NULL) + xtables_error(OTHER_PROBLEM, "cannot retrieve chain list\n"); + /* Grab standard input. */ while (fgets(buffer, sizeof(buffer), in)) { int ret = 0; @@ -259,6 +266,10 @@ xtables_restore_main(int argc, char *argv[]) ret = 1; } in_table = 0; + + /* Purge out unused chains in this table */ + nft_table_purge_chains(&h, curtable, chain_list); + } else if ((buffer[0] == '*') && (!in_table)) { /* New table */ char *table; @@ -282,10 +293,6 @@ xtables_restore_main(int argc, char *argv[]) DEBUGP("Cleaning all chains of table '%s'\n", table); nft_rule_flush(&h, NULL, table); - - DEBUGP("Deleting all user-defined chains " - "of table '%s'\n", table); - nft_chain_user_del(&h, NULL, table); } ret = 1; @@ -305,6 +312,14 @@ xtables_restore_main(int argc, char *argv[]) exit(1); } + chain_obj = nft_chain_list_find(&h, chain_list, + curtable, chain); + /* This chain has been found, delete from list. Later + * on, unvisited chains will be purged out. + */ + if (chain_obj != NULL) + nft_chain_list_del(chain_obj); + if (strlen(chain) >= XT_EXTENSION_MAXNAMELEN) xtables_error(PARAMETER_PROBLEM, "Invalid chain name `%s' " -- cgit v1.2.3 From 9e62dc8637f210cdeaed784396fecab9b6e5f043 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 20 Jan 2013 20:19:20 +0100 Subject: xtables-restore: support atomic commit Use new services in nf_tables to support atomic commit. Commit per table, although we support global commit at once, call commit for each table to emulate iptables-restore behaviour by now. Keep table dormant/wake up code in iptables/nft.c as it can be used in the future. Signed-off-by: Pablo Neira Ayuso --- iptables/xtables-restore.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'iptables/xtables-restore.c') diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c index 9778a9f7..ca9e0c05 100644 --- a/iptables/xtables-restore.c +++ b/iptables/xtables-restore.c @@ -164,6 +164,7 @@ xtables_restore_main(int argc, char *argv[]) { struct nft_handle h = { .family = AF_INET, /* default to IPv4 */ + .commit = true, }; char buffer[10240]; int c; @@ -253,10 +254,14 @@ xtables_restore_main(int argc, char *argv[]) continue; } else if ((strcmp(buffer, "COMMIT\n") == 0) && (in_table)) { if (!testing) { - if (nft_table_wake_dormant(&h, curtable) < 0) { - fprintf(stderr, "Failed to wake up " - "dormant table `%s'\n", - curtable); + /* Commit per table, although we support + * global commit at once, stick by now to + * the existing behaviour. + */ + if (nft_commit(&h)) { + fprintf(stderr, "Failed to commit " + "table %s\n", + curtable); } DEBUGP("Calling commit\n"); ret = 1; @@ -288,7 +293,6 @@ xtables_restore_main(int argc, char *argv[]) if (tablename && (strcmp(tablename, table) != 0)) continue; - nft_table_set_dormant(&h, table); if (noflush == 0) { DEBUGP("Cleaning all chains of table '%s'\n", table); @@ -426,6 +430,14 @@ xtables_restore_main(int argc, char *argv[]) DEBUGP("argv[%u]: %s\n", a, newargv[a]); ret = do_commandx(&h, newargc, newargv, &newargv[2]); + if (ret < 0) { + ret = nft_abort(&h); + if (ret < 0) { + fprintf(stderr, "failed to abort " + "commit operation\n"); + } + exit(1); + } free_argv(); fflush(stdout); -- cgit v1.2.3 From 18af813cabf7b574dec86beedf0a335e5928eaaa Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 20 Jan 2013 23:23:29 +0100 Subject: xtables-restore: support test option `-t' You can now test if a rule-set is correct. Signed-off-by: Pablo Neira Ayuso --- iptables/xtables-restore.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'iptables/xtables-restore.c') diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c index ca9e0c05..c62b0a9a 100644 --- a/iptables/xtables-restore.c +++ b/iptables/xtables-restore.c @@ -266,14 +266,20 @@ xtables_restore_main(int argc, char *argv[]) DEBUGP("Calling commit\n"); ret = 1; } else { - /* FIXME -t needs to be fixed */ + if (nft_abort(&h)) { + xtables_error(OTHER_PROBLEM, + "Failed to abort " + "commit in table %s\n", + curtable); + } DEBUGP("Not calling commit, testing\n"); ret = 1; } in_table = 0; /* Purge out unused chains in this table */ - nft_table_purge_chains(&h, curtable, chain_list); + if (!testing) + nft_table_purge_chains(&h, curtable, chain_list); } else if ((buffer[0] == '*') && (!in_table)) { /* New table */ -- cgit v1.2.3 From 3f7877e6be987bb94897c03a45945725389a6f5c Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 23 Feb 2013 18:27:08 +0100 Subject: xtables-restore: add -4 and -6 support Now you can specify: xtables-restore -6 < my-ip6tables-ruleset to restore the IPv6 rule-set. Signed-off-by: Pablo Neira Ayuso --- iptables/xtables-restore.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'iptables/xtables-restore.c') diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c index c62b0a9a..3b14a9f7 100644 --- a/iptables/xtables-restore.c +++ b/iptables/xtables-restore.c @@ -36,6 +36,8 @@ static const struct option options[] = { {.name = "noflush", .has_arg = false, .val = 'n'}, {.name = "modprobe", .has_arg = true, .val = 'M'}, {.name = "table", .has_arg = true, .val = 'T'}, + {.name = "ipv4", .has_arg = false, .val = '4'}, + {.name = "ipv6", .has_arg = false, .val = '6'}, {NULL}, }; @@ -193,7 +195,7 @@ xtables_restore_main(int argc, char *argv[]) nft_init(&h); - while ((c = getopt_long(argc, argv, "bcvthnM:T:", options, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "bcvthnM:T:46", options, NULL)) != -1) { switch (c) { case 'b': binary = 1; @@ -220,6 +222,12 @@ xtables_restore_main(int argc, char *argv[]) case 'T': tablename = optarg; break; + case '4': + h.family = AF_INET; + break; + case '6': + h.family = AF_INET6; + break; } } -- cgit v1.2.3 From f041efe3c26e3059df1ac8f1775f77423d4be5f6 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Fri, 31 May 2013 16:21:04 +0200 Subject: xtables-restore: output the same error message that iptables-restore uses Signed-off-by: Pablo Neira Ayuso --- iptables/xtables-restore.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) (limited to 'iptables/xtables-restore.c') diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c index 3b14a9f7..4f196fc6 100644 --- a/iptables/xtables-restore.c +++ b/iptables/xtables-restore.c @@ -266,22 +266,11 @@ xtables_restore_main(int argc, char *argv[]) * global commit at once, stick by now to * the existing behaviour. */ - if (nft_commit(&h)) { - fprintf(stderr, "Failed to commit " - "table %s\n", - curtable); - } DEBUGP("Calling commit\n"); - ret = 1; + ret = nft_commit(&h); } else { - if (nft_abort(&h)) { - xtables_error(OTHER_PROBLEM, - "Failed to abort " - "commit in table %s\n", - curtable); - } DEBUGP("Not calling commit, testing\n"); - ret = 1; + ret = nft_abort(&h); } in_table = 0; -- cgit v1.2.3 From 9283066f1216276116b3f4f85abf18bd673a7b11 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 25 Jun 2013 11:56:55 +0200 Subject: xtables: do not proceed if nft_init fails Fix a crash if nft_init fails, it happens if nfnetlink support is not available in your Linux kernel. Signed-off-by: Pablo Neira Ayuso --- iptables/xtables-restore.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'iptables/xtables-restore.c') diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c index 4f196fc6..a5d2a65d 100644 --- a/iptables/xtables-restore.c +++ b/iptables/xtables-restore.c @@ -193,7 +193,13 @@ xtables_restore_main(int argc, char *argv[]) init_extensions4(); #endif - nft_init(&h); + if (nft_init(&h) < 0) { + fprintf(stderr, "%s/%s Failed to initialize nft: %s\n", + xtables_globals.program_name, + xtables_globals.program_version, + strerror(errno)); + exit(EXIT_FAILURE); + } while ((c = getopt_long(argc, argv, "bcvthnM:T:46", options, NULL)) != -1) { switch (c) { -- cgit v1.2.3 From 457819b952418501918b6e906bf5e21e3b4f9af8 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 30 Jun 2013 12:34:36 +0200 Subject: xtables: fix missing afinfo configuration I noticed that the iprange match in IPv6 was broken, fix it by overriding the default family (IPv4) if -6 is passed. Signed-off-by: Pablo Neira Ayuso --- iptables/xtables-restore.c | 1 + 1 file changed, 1 insertion(+) (limited to 'iptables/xtables-restore.c') diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c index a5d2a65d..e66f10cd 100644 --- a/iptables/xtables-restore.c +++ b/iptables/xtables-restore.c @@ -233,6 +233,7 @@ xtables_restore_main(int argc, char *argv[]) break; case '6': h.family = AF_INET6; + xtables_set_nfproto(AF_INET6); break; } } -- cgit v1.2.3 From e127d223d01aaa0886c7f279110ac36651b9a057 Mon Sep 17 00:00:00 2001 From: Tomasz Bursztyka Date: Tue, 16 Jul 2013 22:07:22 +0200 Subject: xtables: Remove useless parameter to nft_chain_list_find Signed-off-by: Tomasz Bursztyka Signed-off-by: Pablo Neira Ayuso --- iptables/xtables-restore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'iptables/xtables-restore.c') diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c index e66f10cd..8469ba1a 100644 --- a/iptables/xtables-restore.c +++ b/iptables/xtables-restore.c @@ -326,7 +326,7 @@ xtables_restore_main(int argc, char *argv[]) exit(1); } - chain_obj = nft_chain_list_find(&h, chain_list, + chain_obj = nft_chain_list_find(chain_list, curtable, chain); /* This chain has been found, delete from list. Later * on, unvisited chains will be purged out. -- cgit v1.2.3 From afae1f841bc2c4b39a38fa97d271f3877d00bf3a Mon Sep 17 00:00:00 2001 From: Giuseppe Longo Date: Fri, 26 Jul 2013 13:05:15 +0200 Subject: nft: associate table configuration to handle via nft_init We need family dependent built-in table/chain configuration. This patch is a step forward making nft family independent in order to support arptables and ebtables compatibility layers. Signed-off-by: Giuseppe Longo Signed-off-by: Pablo Neira Ayuso --- iptables/xtables-restore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'iptables/xtables-restore.c') diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c index 8469ba1a..608e189b 100644 --- a/iptables/xtables-restore.c +++ b/iptables/xtables-restore.c @@ -193,7 +193,7 @@ xtables_restore_main(int argc, char *argv[]) init_extensions4(); #endif - if (nft_init(&h) < 0) { + if (nft_init(&h, xtables_ipv4) < 0) { fprintf(stderr, "%s/%s Failed to initialize nft: %s\n", xtables_globals.program_name, xtables_globals.program_version, -- cgit v1.2.3 From d6a127cd5710f8c60e95bfd0378ca352c07140a9 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 18 Sep 2013 17:00:18 +0200 Subject: xtables: batch rule-set updates into one single netlink message With this patch, all rule-set updates are put in one single batch of netlink messages that is sent to user-space using the new nfnetlink batch infrastructure. Signed-off-by: Pablo Neira Ayuso --- iptables/xtables-restore.c | 1 - 1 file changed, 1 deletion(-) (limited to 'iptables/xtables-restore.c') diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c index 608e189b..06053f62 100644 --- a/iptables/xtables-restore.c +++ b/iptables/xtables-restore.c @@ -166,7 +166,6 @@ xtables_restore_main(int argc, char *argv[]) { struct nft_handle h = { .family = AF_INET, /* default to IPv4 */ - .commit = true, }; char buffer[10240]; int c; -- cgit v1.2.3 From a4e1098169a67716a81316c36ce22ddcb33df1c0 Mon Sep 17 00:00:00 2001 From: Tomasz Bursztyka Date: Mon, 20 Jan 2014 17:56:41 +0200 Subject: nft: Use new libnftnl library name against former libnftables Adapt the current code to use the new library name libnftnl. Signed-off-by: Tomasz Bursztyka Signed-off-by: Pablo Neira Ayuso --- iptables/xtables-restore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'iptables/xtables-restore.c') diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c index 06053f62..9a80f1ef 100644 --- a/iptables/xtables-restore.c +++ b/iptables/xtables-restore.c @@ -16,7 +16,7 @@ #include "libiptc/libiptc.h" #include "xtables-multi.h" #include "nft.h" -#include +#include #ifdef DEBUG #define DEBUGP(x, args...) fprintf(stderr, x, ## args) -- cgit v1.2.3 From 43bb2819c5b7b783cbaceffd0e6d4b6e502a0fb5 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 4 Feb 2014 16:18:55 +0100 Subject: xtables-restore: remove dependency with libip4tc Add a new operation structure, we don't actually need the libip4tc definition. Signed-off-by: Pablo Neira Ayuso --- iptables/xtables-restore.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'iptables/xtables-restore.c') diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c index 9a80f1ef..230894cd 100644 --- a/iptables/xtables-restore.c +++ b/iptables/xtables-restore.c @@ -161,6 +161,10 @@ static void add_param_to_argv(char *parsestart) } } +static const struct xtc_ops xtc_ops = { + .strerror = nft_strerror, +}; + int xtables_restore_main(int argc, char *argv[]) { @@ -173,7 +177,7 @@ xtables_restore_main(int argc, char *argv[]) FILE *in; int in_table = 0, testing = 0; const char *tablename = NULL; - const struct xtc_ops *ops = &iptc_ops; + const struct xtc_ops *ops = &xtc_ops; struct nft_chain_list *chain_list; struct nft_chain *chain_obj; -- cgit v1.2.3 From 4cffe00557b40dfe8c3236746797b24c4074c95e Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 4 Feb 2014 16:21:18 +0100 Subject: xtables: add xtables-compat-multi for the nftables compatibility layer This patch should allow distributors to switch to the iptables over nftables compatibility layer in a transparent way by updating symbolic links from: lrwxrwxrwx 1 root root 13 feb 4 15:35 iptables -> xtables-multi to: lrwxrwxrwx 1 root root 13 feb 4 15:35 iptables -> xtables-compat-multi Same thing with iptables-save, iptables-restore, ip6tables, ip6tables-save, ip6tables-restore and arptables. Note that, after this patch, the following new symlinks are installed: * iptables-compat * iptables-compat-save * iptables-compat-restore * ip6tables-compat * ip6tables-compat-save * ip6tables-compat-restore * arptables-compat which point to the new binary xtables-compat-multi. The idea is to keep both native and compatibility tools installed in the system, which should also make it easier for testing purposes. The iptables over nftables compatibility layer is enabled by default and it requires the libmnl and libnftnl libraries. If you don't want to compile the compatibility layer, you can still disable it through --disable-nftables. This patch also includes changes to adapt the existing code to this approach. Signed-off-by: Pablo Neira Ayuso --- iptables/xtables-restore.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'iptables/xtables-restore.c') diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c index 230894cd..c4af2c5d 100644 --- a/iptables/xtables-restore.c +++ b/iptables/xtables-restore.c @@ -165,11 +165,11 @@ static const struct xtc_ops xtc_ops = { .strerror = nft_strerror, }; -int -xtables_restore_main(int argc, char *argv[]) +static int +xtables_restore_main(int family, const char *progname, int argc, char *argv[]) { struct nft_handle h = { - .family = AF_INET, /* default to IPv4 */ + .family = family, }; char buffer[10240]; int c; @@ -183,8 +183,8 @@ xtables_restore_main(int argc, char *argv[]) line = 0; - xtables_globals.program_name = "xtables-restore"; - c = xtables_init_all(&xtables_globals, NFPROTO_IPV4); + xtables_globals.program_name = progname; + c = xtables_init_all(&xtables_globals, family); if (c < 0) { fprintf(stderr, "%s/%s Failed to initialize xtables\n", xtables_globals.program_name, @@ -472,3 +472,15 @@ xtables_restore_main(int argc, char *argv[]) fclose(in); return 0; } + +int xtables_ip4_restore_main(int argc, char *argv[]) +{ + return xtables_restore_main(NFPROTO_IPV4, "iptables-restore", + argc, argv); +} + +int xtables_ip6_restore_main(int argc, char *argv[]) +{ + return xtables_restore_main(NFPROTO_IPV6, "ip6tables-restore", + argc, argv); +} -- cgit v1.2.3 From 7851975e5055381d30f0788d90671485695928e1 Mon Sep 17 00:00:00 2001 From: Tomasz Bursztyka Date: Tue, 11 Feb 2014 12:46:44 +0200 Subject: xtables: Add backward compatibility with -w option Just to keep aligned with iptables legacy tool. Signed-off-by: Tomasz Bursztyka Signed-off-by: Pablo Neira Ayuso --- iptables/xtables-restore.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'iptables/xtables-restore.c') diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c index c4af2c5d..730800ff 100644 --- a/iptables/xtables-restore.c +++ b/iptables/xtables-restore.c @@ -442,7 +442,8 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[]) for (a = 0; a < newargc; a++) DEBUGP("argv[%u]: %s\n", a, newargv[a]); - ret = do_commandx(&h, newargc, newargv, &newargv[2]); + ret = do_commandx(&h, newargc, newargv, + &newargv[2], true); if (ret < 0) { ret = nft_abort(&h); if (ret < 0) { -- cgit v1.2.3 From 690ea18fdd6f8bc12322a729a2f7c97d8e731c43 Mon Sep 17 00:00:00 2001 From: Tomasz Bursztyka Date: Tue, 11 Feb 2014 18:36:43 +0200 Subject: nft: A builtin chain might be created when restoring nft_chain_set() is directly used in xtables-restore.c, however at that point no builtin chains have been created yet thus the need to request to build it relevantly. Signed-off-by: Tomasz Bursztyka Signed-off-by: Pablo Neira Ayuso --- iptables/xtables-restore.c | 1 + 1 file changed, 1 insertion(+) (limited to 'iptables/xtables-restore.c') diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c index 730800ff..f7850bb2 100644 --- a/iptables/xtables-restore.c +++ b/iptables/xtables-restore.c @@ -170,6 +170,7 @@ xtables_restore_main(int family, const char *progname, int argc, char *argv[]) { struct nft_handle h = { .family = family, + .restore = true, }; char buffer[10240]; int c; -- cgit v1.2.3