summaryrefslogtreecommitdiffstats
path: root/src/xt.c
Commit message (Collapse)AuthorAgeFilesLines
* src: remove xfree() and use plain free()Thomas Haller2023-11-091-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | xmalloc() (and similar x-functions) are used for allocation. They wrap malloc()/realloc() but will abort the program on ENOMEM. The meaning of xmalloc() is that it wraps malloc() but aborts on failure. I don't think x-functions should have the notion, that this were potentially a different memory allocator that must be paired with a particular xfree(). Even if the original intent was that the allocator is abstracted (and possibly not backed by standard malloc()/free()), then that doesn't seem a good idea. Nowadays libc allocators are pretty good, and we would need a very special use cases to switch to something else. In other words, it will never happen that xmalloc() is not backed by malloc(). Also there were a few places, where a xmalloc() was already "wrongly" paired with free() (for example, iface_cache_release(), exit_cookie(), nft_run_cmd_from_buffer()). Or note how pid2name() returns an allocated string from fscanf(), which needs to be freed with free() (and not xfree()). This requirement bubbles up the callers portid2name() and name_by_portid(). This case was actually handled correctly and the buffer was freed with free(). But it shows that mixing different allocators is cumbersome to get right. Of course, we don't actually have different allocators and whether to use free() or xfree() makes no different. The point is that xfree() serves no actual purpose except raising irrelevant questions about whether x-functions are correctly paired with xfree(). Note that xfree() also used to accept const pointers. It is bad to unconditionally for all deallocations. Instead prefer to use plain free(). To free a const pointer use free_const() which obviously wraps free, as indicated by the name. Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add free_const() and use it instead of xfree()Thomas Haller2023-11-091-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Almost everywhere xmalloc() and friends is used instead of malloc(). This is almost everywhere paired with xfree(). xfree() has two problems. First, it brings the wrong notion that xmalloc() should be paired with xfree(), as if xmalloc() would not use the plain malloc() allocator. In practices, xfree() just wraps free(), and it wouldn't make sense any other way. xfree() should go away. This will be addressed in the next commit. The problem addressed by this commit is that xfree() accepts a const pointer. Paired with the practice of almost always using xfree() instead of free(), all our calls to xfree() cast away constness of the pointer, regardless whether that is necessary. Declaring a pointer as const should help us to catch wrong uses. If the xfree() function always casts aways const, the compiler doesn't help. There are many places that rightly cast away const during free. But not all of them. Add a free_const() macro, which is like free(), but accepts const pointers. We should always make an intentional choice whether to use free() or free_const(). Having a free_const() macro makes this very common choice clearer, instead of adding a (void*) cast at many places. Note that we now pair xmalloc() allocations with a free() call (instead of xfree(). That inconsistency will be resolved in the next commit. Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* include: include <string.h> in <nft.h>Thomas Haller2023-09-281-1/+0
| | | | | | | | <string.h> provides strcmp(), as such it's very basic and used everywhere. Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* libnftables: move init-once guard inside xt_init()Thomas Haller2023-09-191-2/+13
| | | | | | | | | | | | | | | | A library should not restrict being used by multiple threads or make assumptions about how it's being used. Hence a "init_once" pattern without no locking is racy, a code smell and should be avoided. Note that libxtables is full of global variables and when linking against it, libnftables cannot be used from multiple threads either. That is not easy to fix. Move the ugliness of "init_once" away from nft_ctx_new(), so that the problem is concentrated closer to libxtables. Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* include: include <stdlib.h> in <nft.h>Thomas Haller2023-09-111-1/+0
| | | | | | | | | | | | | | It provides malloc()/free(), which is so basic that we need it everywhere. Include via <nft.h>. The ultimate purpose is to define more things in <nft.h>. While it has not corresponding C sources, <nft.h> can contain macros and static inline functions, and is a good place for things that we shall have everywhere. Since <stdlib.h> provides malloc()/free() and size_t, that is a very basic dependency, that will be needed for that. Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xt: avoid "-Wmissing-field-initializers" for "original_opts"Thomas Haller2023-08-301-1/+1
| | | | | | | | | | | | | | | | | | Avoid this warning with clang: CC src/xt.lo src/xt.c:353:9: error: missing field 'has_arg' initializer [-Werror,-Wmissing-field-initializers] { NULL }, ^ The warning seems not very useful, because it's well understood that specifying only some initializers leaves the remaining fields initialized with the default. However, as this warning is only hit once in the code base, it doesn't seem that we violate this style frequently. Hence, fix it instead of disabling the warning. Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add <nft.h> header and include it as firstThomas Haller2023-08-251-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | <config.h> is generated by the configure script. As it contains our feature detection, it want to use it everywhere. Likewise, in some of our sources, we define _GNU_SOURCE. This defines the C variant we want to use. Such a define need to come before anything else, and it would be confusing if different source files adhere to a different C variant. It would be good to use autoconf's AC_USE_SYSTEM_EXTENSIONS, in which case we would also need to ensure that <config.h> is always included as first. Instead of going through all source files and include <config.h> as first, add a new header "include/nft.h", which is supposed to be included in all our sources (and as first). This will also allow us later to prepare some common base, like include <stdbool.h> everywhere. We aim that headers are self-contained, so that they can be included in any order. Which, by the way, already didn't work because some headers define _GNU_SOURCE, which would only work if the header gets included as first. <nft.h> is however an exception to the rule: everything we compile shall rely on having <nft.h> header included as first. This applies to source files (which explicitly include <nft.h>) and to internal header files (which are only compiled indirectly, by being included from a source file). Note that <config.h> has no include guards, which is at least ugly to include multiple times. It doesn't cause problems in practice, because it only contains defines and the compiler doesn't warn about redefining a macro with the same value. Still, <nft.h> also ensures to include <config.h> exactly once. Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xt: Fix translation error pathPhil Sutter2023-03-291-4/+6
| | | | | | | | | | | | | | | | | | | | If xtables support was compiled in but the required libxtables DSO is not found, nft prints an error message and leaks memory: | counter packets 0 bytes 0 XT target MASQUERADE not found This is not as bad as it seems, the output combines stdout and stderr. Dropping stderr produces an incomplete ruleset listing, though. While this seemingly inline output can't easily be avoided, fix a few things: * Respect octx->error_fp, libnftables might have been configured to redirect stderr somewhere else. * Align error message formatting with others. * Don't return immediately, but free allocated memory and fall back to printing the expression in "untranslated" form. Fixes: 5c30feeee5cfe ("xt: Delay libxtables access until translation") Signed-off-by: Phil Sutter <phil@nwl.cc>
* xt: Fix fallback printing for extensions matching keywordsPhil Sutter2023-03-101-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | Yet another Bison workaround: Instead of the fancy error message, an incomprehensible syntax error is emitted: | # iptables-nft -A FORWARD -p tcp -m osf --genre linux | # nft list ruleset | nft -f - | # Warning: table ip filter is managed by iptables-nft, do not touch! | /dev/stdin:4:29-31: Error: syntax error, unexpected osf, expecting string | meta l4proto tcp xt match osf counter packets 0 bytes 0 | ^^^ Avoid this by quoting the extension name when printing: | # nft list ruleset | sudo ./src/nft -f - | # Warning: table ip filter is managed by iptables-nft, do not touch! | /dev/stdin:4:20-33: Error: unsupported xtables compat expression, use iptables-nft with this ruleset | meta l4proto tcp xt match "osf" counter packets 0 bytes 0 | ^^^^^^^^^^^^^^ Fixes: 79195a8cc9e9d ("xt: Rewrite unsupported compat expression dumping") Fixes: e41c53ca5b043 ("xt: Fall back to generic printing from translation") Signed-off-by: Phil Sutter <phil@nwl.cc>
* src: add dl_proto_ctx()Pablo Neira Ayuso2023-01-021-2/+4
| | | | | | | | | | Add dl_proto_ctx() to access protocol context (struct proto_ctx and struct payload_dep_ctx) from the delinearize path. This patch comes in preparation for supporting outer and inner protocol context. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: Add GPLv2+ header to .c files of recent creationPablo Neira Ayuso2023-01-021-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch comes after a proposal of mine at NFWS 2022 that resulted in agreement to license recent .c files under GPLv2+ by the attendees at this meeting: - Stefano Brivio - Fernando F. Mancera - Phil Sutter - Jozsef Kadlecsik - Florian Westphal - Laura Garcia - Arturo Borrero - Pablo Neira It has already happened that one of the external library dependencies was moved to GPLv3+ (libreadline), resulting in a change to libedit by default in b4dded0ca78d ("configure: default to libedit for cli"). I have added the GPLv2+ header to the following files: Authors ------- src/cmd.c Pablo src/fib.c Florian src/hash.c Pablo src/iface.c Pablo src/json.c Phil + fixes from occasional contributors src/libnftables.c Eric Leblond and Phil src/mergesort.c Elise Lenion src/misspell.c Pablo src/mnl.c Pablo + fixes from occasional contributors src/monitor.c Arturo src/numgen.c Pablo src/osf.c Fernando src/owner.c Pablo src/parser_json.c Phil + fixes from occasional contributors src/print.c Phil src/xfrm.c Florian src/xt.c Pablo Eric Leblond and Elise Lennion did not attend NFWS 2022, but they acknowledged this license update already in the past when I proposed this to them in private emails. Update COPYING file too to refer that we are now moving towards GPLv2 or any later. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xt: Fall back to generic printing from translationPhil Sutter2022-12-131-18/+13
| | | | | | | | If translation is not available or fails, print the generic format instead of calling the print callback (which does not respect output_fp) or silently failing. Signed-off-by: Phil Sutter <phil@nwl.cc>
* xt: Rewrite unsupported compat expression dumpingPhil Sutter2022-12-131-1/+7
| | | | | | | | | Choose a format which provides more information and is easily parseable. Then teach parsers about it and make it explicitly reject the ruleset giving a meaningful explanation. Also update the man pages with some more details. Signed-off-by: Phil Sutter <phil@nwl.cc>
* xt: Purify enum nft_xt_typePhil Sutter2022-12-131-2/+0
| | | | | | Remove NFT_XT_MAX from the enum, it is not a valid xt type. Signed-off-by: Phil Sutter <phil@nwl.cc>
* xt: Delay libxtables access until translationPhil Sutter2022-12-131-116/+76
| | | | | | | | | | | | | | | | | | There is no point in spending efforts setting up the xt match/target when it is not printed afterwards. So just store the statement data from libnftnl in struct xt_stmt and perform the extension lookup from xt_stmt_xlate() instead. This means some data structures are only temporarily allocated for the sake of passing to libxtables callbacks, no need to drag them around. Also no need to clone the looked up extension, it is needed only to call the functions it provides. While being at it, select numeric output in xt_xlate_*_params - otherwise there will be reverse DNS lookups which should not happen by default. Signed-off-by: Phil Sutter <phil@nwl.cc>
* Warn for tables with compat expressions in rulesPhil Sutter2022-11-181-0/+2
| | | | | | | | | | | | | | | | | | While being able to "look inside" compat expressions using nft is a nice feature, it is also (yet another) pitfall for unaware users, deceiving them into assuming interchangeability (or at least compatibility) between iptables-nft and nft. In reality, which involves 'nft list ruleset | nft -f -', any correctly translated compat expressions will turn into native nftables ones not understood by (the version of) iptables-nft which created them in the first place. Other compat expressions will vanish, potentially compromising the firewall ruleset. Emit a warning (as comment) to give users a chance to stop and reconsider before shooting their own foot. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nftables: xt: fix misprint in nft_xt_compatible_revisionPavel Tikhomirov2021-03-091-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The rev variable is used here instead of opt obviously by mistake. Please see iptables:nft_compatible_revision() for an example how it should be. This breaks revision compatibility checks completely when reading compat-target rules from nft utility. That's why nftables can't work on "old" kernels which don't support new revisons. That's a problem for containers. E.g.: 0 and 1 is supported but not 2: https://git.sw.ru/projects/VZS/repos/vzkernel/browse/net/netfilter/xt_nat.c#111 Reproduce of the problem on Virtuozzo 7 kernel 3.10.0-1160.11.1.vz7.172.18 in centos 8 container: iptables-nft -t nat -N TEST iptables-nft -t nat -A TEST -j DNAT --to-destination 172.19.0.2 nft list ruleset > nft.ruleset nft -f - < nft.ruleset #/dev/stdin:19:67-81: Error: Range has zero or negative size # meta l4proto tcp tcp dport 81 counter packets 0 bytes 0 dnat to 3.0.0.0-0.0.0.0 # ^^^^^^^^^^^^^^^ nft -v #nftables v0.9.3 (Topsy) iptables-nft -v #iptables v1.8.7 (nf_tables) Kernel returns ip range in rev 0 format: crash> p *((struct nf_nat_ipv4_multi_range_compat *) 0xffff8ca2fabb3068) $5 = { rangesize = 1, range = {{ flags = 3, min_ip = 33559468, max_ip = 33559468, But nft reads this as rev 2 format (nf_nat_range2) which does not have rangesize, and thus flugs 3 is treated as ip 3.0.0.0, which is wrong and can't be restored later. (Should probably be the same on Centos 7 kernel 3.10.0-1160.11.1) Fixes: fbc0768cb696 ("nftables: xt: don't use hard-coded AF_INET") Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add rule_stmt_append() and use itPablo Neira Ayuso2020-05-051-2/+2
| | | | | | | This helper function adds a statement at the end of the rule statement list and it updates the rule statement counter. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: fix double free on xt stmt destructionFlorian Westphal2019-05-011-1/+1
| | | | | | | | | | | | 'nft monitor' dies with: *** Error in `/sbin/nft': double free or corruption (fasttop): 0x000055f8ba57b750 *** ... when the iptables-nft test suite is running in parallel, because xfree(stmt->xt.name) gets called twice. Fixes: 4ac11b890fe870 ("src: missing destroy function in statement definitions") Signed-off-by: Florian Westphal <fw@strlen.de> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: missing destroy function in statement definitionsPablo Neira Ayuso2019-04-051-0/+1
| | | | Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xt: fix build with --with-xtablesFlorian Westphal2018-12-291-3/+4
| | | | | | | | | | | | The previous change is bonkers, it fixes build when libxtables isn't even installed, but broke build when --with-xtables is provided to configure. Reason is that the include guard comes too early, so xtables.h is never included, causing build to fail because no libxtables function prototypes and definitions are available. Fixes: 9e84f3f083bb ("xt: fix build when libxtables is not installed") Signed-off-by: Florian Westphal <fw@strlen.de>
* xt: fix build when libxtables is not installedFlorian Westphal2018-12-041-0/+5
| | | | | | | | | | | | If libxtables is not even installed, build fails due to to missing include file. ifdef LIBXTABLES guard fixes the first error, but results in two followup failures: 1. missing IFNAMSIZ definition 2. dereference of unknown struct. Signed-off-by: Florian Westphal <fw@strlen.de>
* xt: always build with a minimal support for xt match/target decodeFlorian Westphal2018-11-121-0/+22
| | | | | | | | | | When building without libxtables, nft would just silently omit any presence of nft_compat in the output. This adds ifdef-ry to at least print name of target/match involved when libxtables isn't available for decoding. Signed-off-by: Florian Westphal <fw@strlen.de>
* xt: pass octx to translate functionFlorian Westphal2018-11-121-3/+3
| | | | | | | We can't use it when no translation is available as libxtables will use plain printf(), but when translation is available we can. Signed-off-by: Florian Westphal <fw@strlen.de>
* src: remove opts field from struct xt_stmtPablo Neira Ayuso2018-10-171-6/+2
| | | | | | | | This is never used, ie. always NULL. Reported-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Acked-by: Phil Sutter <phil@nwl.cc>
* nftables: xt: don't use hard-coded AF_INETFlorian Westphal2018-05-141-4/+20
| | | | | | | | | | We need to check which revision type is requested (match, target) and wheter its ipv4 or ipv6, then set family based on that. This allows nft ipv6 family to display compat entries if a translation is available. Signed-off-by: Florian Westphal <fw@strlen.de>
* xt: don't BUG if we can't find an extensionsFlorian Westphal2018-05-081-6/+8
| | | | | | it seems a bit harsh to just exit. Signed-off-by: Florian Westphal <fw@strlen.de>
* Revert ("src: Remove xt_stmt_() functions").Pablo Neira Ayuso2018-01-201-2/+74
| | | | | | | | | Revert commit bce55916b51ec1a4c23322781e3b0c698ecc9561, we need this code in place to properly make translation when iptables-compat loads rules. Reported-by: Duncan Roe <duncan_roe@optusnet.com.au> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: Initialize struct stmt in _match and _target functions.Varsha Rao2017-08-241-0/+2
| | | | | | | | | | Initialize structure stmt with stmt_alloc in netlink_parse_target and netlink_parse_match functions. This patch fixes the gcc warning: ‘stmt’ may be used uninitialized in this function. Signed-off-by: Varsha Rao <rvarsha016@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: Remove xt_stmt_() functions.Varsha Rao2017-08-171-74/+0
| | | | | | | | | Remove functions xt_stmt_alloc(), xt_stmt_release(), xt_stmt_xlate(), xt_stmt_print(), xt_stmt_destroy() as they are not used. Similarly, remove structure xt_stmt_ops. Signed-off-by: Varsha Rao <rvarsha016@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: Remove __init and __exit macro definitions.Varsha Rao2017-07-171-1/+1
| | | | | | | | | | | | Add nft_init and nft_exit functions, which calls _init and _exit functions in main.c file. Remove __init and __exit macro definitions as libnftables library will be created soon. Rename realm_table_init() and realm_table_exit() functions to avoid ambiguity as realm_table_rt_init(), realm_table_meta_init, realm_table_rt_exit() and realm_table_meta_exit() in rt.c and meta.c files. Signed-off-by: Varsha Rao <rvarsha016@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xt: use NFTNL_* definitionsPablo Neira Ayuso2016-12-201-6/+6
| | | | | | Do not use obsolete definitions in libnftnl. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xt: update Arturo Borrero Gonzalez email addressArturo Borrero Gonzalez2016-11-091-1/+1
| | | | | | | Update email address to a new one in the copyright notice. Signed-off-by: Arturo Borrero Gonzalez <arturo@debian.org> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xt: use struct xt_xlate_{mt,tg}_paramsPablo Neira Ayuso2016-07-251-5/+15
| | | | | | | Adapt this code to the new interface that introduces struct xt_xlate_{mt,tg}_params. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add xt compat supportPablo Neira Ayuso2016-07-131-0/+348
At compilation time, you have to pass this option. # ./configure --with-xtables And libxtables needs to be installed in your system. This patch allows to list a ruleset containing xt extensions loaded through iptables-compat-restore tool. Example: $ iptables-save > ruleset $ cat ruleset *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] -A INPUT -p tcp -m multiport --dports 80,81 -j REJECT COMMIT $ sudo iptables-compat-restore ruleset $ sudo nft list rulseset table ip filter { chain INPUT { type filter hook input priority 0; policy accept; ip protocol tcp tcp dport { 80,81} counter packets 0 bytes 0 reject } chain FORWARD { type filter hook forward priority 0; policy drop; } chain OUTPUT { type filter hook output priority 0; policy accept; } } A translation of the extension is shown if this is available. In other case, match or target definition is preceded by a hash. For example, classify target has not translation: $ sudo nft list chain mangle POSTROUTING table ip mangle { chain POSTROUTING { type filter hook postrouting priority -150; policy accept; ip protocol tcp tcp dport 80 counter packets 0 bytes 0 # CLASSIFY set 20:10 ^^^ } } If the whole ruleset is translatable, the users can (re)load it using "nft -f" and get nft native support for all their rules. This patch is joint work by the authors listed below. Signed-off-by: Arturo Borrero Gonzalez <arturo.borrero.glez@gmail.com> Signed-off-by: Pablo M. Bermudo Garay <pablombg@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>