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-save.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 iptables/xtables-save.c (limited to 'iptables/xtables-save.c') diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c new file mode 100644 index 00000000..046c948d --- /dev/null +++ b/iptables/xtables-save.c @@ -0,0 +1,122 @@ +/* Code to save the xtables state, in human readable-form. */ +/* (C) 1999 by Paul 'Rusty' Russell and + * (C) 2000-2002 by Harald Welte + * (C) 2012 by Pablo Neira Ayuso + * + * This code is distributed under the terms of GNU GPL v2 + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "libiptc/libiptc.h" +#include "iptables.h" +#include "xtables-multi.h" +#include "nft.h" + +#include + +#ifndef NO_SHARED_LIBS +#include +#endif + +static bool show_counters = false; + +static const struct option options[] = { + {.name = "counters", .has_arg = false, .val = 'c'}, + {.name = "dump", .has_arg = false, .val = 'd'}, + {.name = "table", .has_arg = true, .val = 't'}, + {.name = "modprobe", .has_arg = true, .val = 'M'}, + {NULL}, +}; + +static int +do_output(struct nft_handle *h, const char *tablename, bool counters) +{ + struct nft_chain_list *chain_list; + + if (!tablename) + return nft_for_each_table(h, do_output, counters); + + if (!nft_table_find(h, tablename)) { + printf("Table `%s' does not exist\n", tablename); + return 0; + } + + chain_list = nft_chain_dump(h); + + time_t now = time(NULL); + + printf("# Generated by xtables-save v%s on %s", + IPTABLES_VERSION, ctime(&now)); + 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, counters); + + now = time(NULL); + printf("COMMIT\n"); + printf("# Completed on %s", ctime(&now)); + + return 1; +} + +/* Format: + * :Chain name POLICY packets bytes + * rule + */ +int +xtables_save_main(int argc, char *argv[]) +{ + const char *tablename = NULL; + struct nft_handle h; + int c; + + xtables_globals.program_name = "xtables-save"; + /* XXX xtables_init_all does several things we don't want */ + 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, "bcdt:", options, NULL)) != -1) { + switch (c) { + case 'c': + show_counters = true; + break; + + case 't': + /* Select specific table. */ + tablename = optarg; + break; + case 'M': + xtables_modprobe_program = optarg; + break; + case 'd': + do_output(&h, tablename, show_counters); + exit(0); + } + } + + if (optind < argc) { + fprintf(stderr, "Unknown arguments found on commandline\n"); + exit(1); + } + + return !do_output(&h, tablename, show_counters); +} -- 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-save.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'iptables/xtables-save.c') diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c index 046c948d..05d06b1e 100644 --- a/iptables/xtables-save.c +++ b/iptables/xtables-save.c @@ -76,7 +76,9 @@ int xtables_save_main(int argc, char *argv[]) { const char *tablename = NULL; - struct nft_handle h; + struct nft_handle h = { + .family = AF_INET, /* default to AF_INET */ + }; int c; xtables_globals.program_name = "xtables-save"; -- cgit v1.2.3 From 6fc6cb2d223da8d7fdf745cd783af8bcbc758b9f Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 23 Feb 2013 18:30:36 +0100 Subject: xtables-save: add -4 and -6 support Now you can specify: xtables-save -6 > my-ip6tables-ruleset to dump the IPv6 rule-set. Signed-off-by: Pablo Neira Ayuso --- iptables/xtables-save.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'iptables/xtables-save.c') diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c index 05d06b1e..111ad4be 100644 --- a/iptables/xtables-save.c +++ b/iptables/xtables-save.c @@ -32,6 +32,8 @@ static const struct option options[] = { {.name = "dump", .has_arg = false, .val = 'd'}, {.name = "table", .has_arg = true, .val = 't'}, {.name = "modprobe", .has_arg = true, .val = 'M'}, + {.name = "ipv4", .has_arg = false, .val = '4'}, + {.name = "ipv6", .has_arg = false, .val = '6'}, {NULL}, }; @@ -96,7 +98,7 @@ xtables_save_main(int argc, char *argv[]) #endif nft_init(&h); - while ((c = getopt_long(argc, argv, "bcdt:", options, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "bcdt:46", options, NULL)) != -1) { switch (c) { case 'c': show_counters = true; @@ -112,6 +114,12 @@ xtables_save_main(int argc, char *argv[]) case 'd': do_output(&h, tablename, show_counters); exit(0); + case '4': + h.family = AF_INET; + break; + case '6': + h.family = AF_INET6; + break; } } -- 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-save.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'iptables/xtables-save.c') diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c index 111ad4be..49b859dd 100644 --- a/iptables/xtables-save.c +++ b/iptables/xtables-save.c @@ -96,7 +96,13 @@ xtables_save_main(int argc, char *argv[]) init_extensions(); 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, "bcdt: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-save.c | 1 + 1 file changed, 1 insertion(+) (limited to 'iptables/xtables-save.c') diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c index 49b859dd..41ceaf51 100644 --- a/iptables/xtables-save.c +++ b/iptables/xtables-save.c @@ -125,6 +125,7 @@ xtables_save_main(int argc, char *argv[]) break; case '6': h.family = AF_INET6; + xtables_set_nfproto(AF_INET6); break; } } -- 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-save.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'iptables/xtables-save.c') diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c index 41ceaf51..db030901 100644 --- a/iptables/xtables-save.c +++ b/iptables/xtables-save.c @@ -96,7 +96,7 @@ xtables_save_main(int argc, char *argv[]) init_extensions(); 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 f8781d3da3943a0fc10212e77cdbcd0697943596 Mon Sep 17 00:00:00 2001 From: Tomasz Bursztyka Date: Wed, 31 Jul 2013 15:18:52 +0300 Subject: xtables: Do not dump before command parsing has been finished On xtables-save.c, -d will not output right away but after the full command line hase been parsed. Signed-off-by: Tomasz Bursztyka Signed-off-by: Pablo Neira Ayuso --- iptables/xtables-save.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'iptables/xtables-save.c') diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c index db030901..990c0fe6 100644 --- a/iptables/xtables-save.c +++ b/iptables/xtables-save.c @@ -78,6 +78,7 @@ int xtables_save_main(int argc, char *argv[]) { const char *tablename = NULL; + bool dump = false; struct nft_handle h = { .family = AF_INET, /* default to AF_INET */ }; @@ -118,8 +119,8 @@ xtables_save_main(int argc, char *argv[]) xtables_modprobe_program = optarg; break; case 'd': - do_output(&h, tablename, show_counters); - exit(0); + dump = true; + break; case '4': h.family = AF_INET; break; @@ -135,5 +136,10 @@ xtables_save_main(int argc, char *argv[]) exit(1); } + if (dump) { + do_output(&h, tablename, show_counters); + exit(0); + } + return !do_output(&h, tablename, show_counters); } -- 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-save.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'iptables/xtables-save.c') diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c index 990c0fe6..77eab149 100644 --- a/iptables/xtables-save.c +++ b/iptables/xtables-save.c @@ -19,7 +19,7 @@ #include "xtables-multi.h" #include "nft.h" -#include +#include #ifndef NO_SHARED_LIBS #include -- 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-save.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'iptables/xtables-save.c') diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c index 77eab149..93065cfc 100644 --- a/iptables/xtables-save.c +++ b/iptables/xtables-save.c @@ -74,17 +74,17 @@ do_output(struct nft_handle *h, const char *tablename, bool counters) * :Chain name POLICY packets bytes * rule */ -int -xtables_save_main(int argc, char *argv[]) +static int +xtables_save_main(int family, const char *progname, int argc, char *argv[]) { const char *tablename = NULL; bool dump = false; struct nft_handle h = { - .family = AF_INET, /* default to AF_INET */ + .family = family, }; int c; - xtables_globals.program_name = "xtables-save"; + xtables_globals.program_name = progname; /* XXX xtables_init_all does several things we don't want */ c = xtables_init_all(&xtables_globals, NFPROTO_IPV4); if (c < 0) { @@ -143,3 +143,13 @@ xtables_save_main(int argc, char *argv[]) return !do_output(&h, tablename, show_counters); } + +int xtables_ip4_save_main(int argc, char *argv[]) +{ + return xtables_save_main(NFPROTO_IPV4, "iptables-save", argc, argv); +} + +int xtables_ip6_save_main(int argc, char *argv[]) +{ + return xtables_save_main(NFPROTO_IPV6, "ip6tables-save", argc, argv); +} -- cgit v1.2.3 From 5cab9c3c8209e9491f0f252e03dd48ae4cb5ab63 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 11 Feb 2014 14:24:06 +0100 Subject: nft-compat: fix wrong protocol context in initialization This fixes matches/targets that are dependent on that IPv4/Ipv6 context, eg. # ip6tables-compat -I INPUT -j REJECT --reject-with icmp6-addr-unreachable # ip6tables-compat-save ... -A INPUT -j REJECT --reject-with icmp6-port-unreachable Signed-off-by: Pablo Neira Ayuso --- iptables/xtables-save.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'iptables/xtables-save.c') diff --git a/iptables/xtables-save.c b/iptables/xtables-save.c index 93065cfc..42d29071 100644 --- a/iptables/xtables-save.c +++ b/iptables/xtables-save.c @@ -85,8 +85,7 @@ xtables_save_main(int family, const char *progname, int argc, char *argv[]) int c; xtables_globals.program_name = progname; - /* XXX xtables_init_all does several things we don't want */ - c = xtables_init_all(&xtables_globals, NFPROTO_IPV4); + c = xtables_init_all(&xtables_globals, family); if (c < 0) { fprintf(stderr, "%s/%s Failed to initialize xtables\n", xtables_globals.program_name, -- cgit v1.2.3