summaryrefslogtreecommitdiffstats
path: root/iptables/nft.c
Commit message (Collapse)AuthorAgeFilesLines
* nft: Do not combine inverted payload matchesHEADmasterSriram Rajagopalan10 days1-4/+2
| | | | | | | | Fixed the issue with combining the payload in case of invert filter for tcp src and dst ports. Signed-off-by: Sriram Rajagopalan <sriramr@arista.com> Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Fix for broken recover_rule_compat()Phil Sutter2024-02-271-4/+23
| | | | | | | | | | | | | | | When IPv4 rule generator was changed to emit payload instead of meta expressions for l4proto matches, the code reinserting NFTNL_RULE_COMPAT_* attributes into rules being reused for counter zeroing was broken by accident. Make rule compat recovery aware of the alternative match, basically reinstating the effect of commit 7a373f6683afb ("nft: Fix -Z for rules with NFTA_RULE_COMPAT") but add a test case this time to make sure things stay intact. Fixes: 69278f9602b43 ("nft: use payload matching for layer 4 protocol") Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Do not omit full ranges if invertedPhil Sutter2024-02-021-2/+2
| | | | | | | Otherwise this turns a never matching rule into an always matching one. Fixes: c034cf31dd1a9 ("nft: prefer native expressions instead of udp match") Signed-off-by: Phil Sutter <phil@nwl.cc>
* iptables: Add missing error codesJacek Tomasiak2024-01-241-3/+9
| | | | | | | | | | Without these, commands like `iptables -n -L CHAIN` sometimes print "Incompatible with this kernel" instead of "No chain/target/match by that name". Signed-off-by: Jacek Tomasiak <jacek.tomasiak@gmail.com> Signed-off-by: Jacek Tomasiak <jtomasiak@arista.com> Signed-off-by: Phil Sutter <phil@nwl.cc>
* ebtables: Implement --change-counters commandPhil Sutter2023-11-231-0/+65
| | | | | | | | Treat it like --replace against the same rule with changed counters. The operation is obviously not atomic, so rule counters may change in kernel while the rule is fetched, modified and replaced. Signed-off-by: Phil Sutter <phil@nwl.cc>
* Revert --compat option related commitsPhil Sutter2023-09-011-11/+8
| | | | | | | | | | | | | | | | | | | This reverts the following commits: b14c971db6db0 ("tests: Test compat mode") 11c464ed015b5 ("Add --compat option to *tables-nft and *-nft-restore commands") ca709b5784c98 ("nft: Introduce and use bool nft_handle::compat") 402b9b3c07c81 ("nft: Pass nft_handle to add_{target,action}()") This implementation of a compatibility mode implements rules using xtables extensions if possible and thus relies upon existence of those in kernel space. Assuming no viable replacement for the internal mechanics of this mode will be found in foreseeable future, it will effectively block attempts at deprecating and removing of these xtables extensions in favor of nftables expressions and thus hinder upstream's future plans for iptables. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Introduce and use bool nft_handle::compatPhil Sutter2023-08-111-4/+6
| | | | | | | | If set, create rules using compat expressions where possible and disable the bitwise expression avoidance introduced in 323259001d617 ("nft: Optimize class-based IP prefix matches"). Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Pass nft_handle to add_{target,action}()Phil Sutter2023-08-111-4/+5
| | | | | | Prepare for varying rule content based on a global flag. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Create builtin chains with counters enabledPhil Sutter2023-08-101-6/+8
| | | | | | | | | | | | | | The kernel enables policy counters for nftables chains only if NFTA_CHAIN_COUNTERS attribute is present. For this to be generated, one has to set NFTNL_CHAIN_PACKETS and NFTNL_CHAIN_BYTES attributes in the allocated nftnl_chain object. The above happened for base chains only with iptables-nft-restore if called with --counters flag. Since this is very unintuitive to users, fix the situation by adding counters to base chains in any case. Fixes: 384958620abab ("use nf_tables and nf_tables compatibility interface") Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: move processing logic out of assertsJan Palus2023-08-051-2/+5
| | | | | | | | | | [Phil: Introduce assert_nft_restart() to keep things clean, also add fallback returns to nft_action() and nft_prepare(), sanitizing things at least a bit.] Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1487 Signed-off-by: Jan Palus <atler@pld-linux.org> Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Include sets in debug outputPhil Sutter2023-07-281-0/+6
| | | | | | | Rules referencing them are incomplete without, so add debug output on the same level as for rules. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Do not pass nft_rule_ctx to add_nft_among()Phil Sutter2023-07-281-6/+5
| | | | | | | | It is not used, must be a left-over from an earlier version of the fixed commit. Fixes: 4e95200ded923 ("nft-bridge: pass context structure to ops->add() to improve anonymous set support") Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft-bridge: pass context structure to ops->add() to improve anonymous set ↵Pablo Neira Ayuso2023-07-121-19/+35
| | | | | | | | | | | | | | | | | support Add context structure to improve bridge among support which creates an anonymous set. This context structure specifies the command and it allows to optionally store a anonymous set. Use this context to generate native bytecode only if this is an add/insert/replace command. This fixes a dangling anonymous set that is created on rule removal. Fixes: 26753888720d ("nft: bridge: Rudimental among extension support") Reported-and-tested-by: Igor Raits <igor@gooddata.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* iptables: Fix handling of non-existent chainsJacek Tomasiak2023-06-211-1/+1
| | | | | | | | | | | | | | | | | Since 694612adf87 the "compatibility" check considers non-existent chains as "incompatible". This broke some scripts which used calls like `iptables -L CHAIN404` to test for chain existence and expect "No chain/target/match by that name." in the output. This patch changes the logic of `nft_is_table_compatible()` to report non-existent chains as "compatible" which restores the old behavior. Fixes: 694612adf87 ("nft: Fix selective chain compatibility checks") Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1648 Signed-off-by: Jacek Tomasiak <jtomasiak@arista.com> Signed-off-by: Jacek Tomasiak <jacek.tomasiak@gmail.com> Signed-off-by: Phil Sutter <phil@nwl.cc>
* ebtables-nft: add broute table emulationFlorian Westphal2023-04-041-0/+13
| | | | | | | | | | | | | | Use new 'meta broute set 1' to emulate -t broute. If '-t broute' is given, automatically translate -j DROP to 'meta broute set 1 accept' internally. Reverse translation zaps the broute and pretends verdict was DROP. Note that BROUTING is internally handled via PREROUTING, i.e. 'redirect' and 'nat' targets are not available, they will need to be emulated via nft expressions. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Phil Sutter <phil@nwl.cc>
* iptables-nft: make builtin tables staticFlorian Westphal2023-03-141-3/+3
| | | | | | Only used in nft.c. Signed-off-by: Florian Westphal <fw@strlen.de>
* nft-restore: Fix for deletion of new, referenced rulePhil Sutter2023-03-011-1/+2
| | | | | | | | | | | | | | | | | | Combining multiple corner-cases here: * Insert a rule before another new one which is not the first. Triggers NFTNL_RULE_ID assignment of the latter. * Delete the referenced new rule in the same batch again. Causes overwriting of the previously assigned RULE_ID. Consequently, iptables-nft-restore fails during *insert*, because the reference is dangling. Reported-by: Eric Garver <eric@garver.life> Fixes: 760b35b46e4cc ("nft: Fix for add and delete of same rule in single batch") Signed-off-by: Phil Sutter <phil@nwl.cc> Tested-by: Eric Garver <eric@garver.life>
* nft: Reject tcp/udp extension without proper protocol matchPhil Sutter2022-12-221-0/+6
| | | | | | | | | Internally, 'th' expression is used, which works but matches both protocols. Since users won't expect '-m tcp --dport 1' to match UDP packets, catch missing/wrong '-p' argument. Fixes: c034cf31dd1a9 ("nft: prefer native expressions instead of udp match") Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Plug memleak in nft_rule_zero_counters()Phil Sutter2022-12-021-2/+3
| | | | | | | | | | | | | | | | | | | | | | | When zeroing a specific rule, valgrind reports: 40 bytes in 1 blocks are definitely lost in loss record 1 of 1 at 0x484659F: calloc (vg_replace_malloc.c:1328) by 0x48DE128: xtables_calloc (xtables.c:434) by 0x11C7C6: nft_parse_immediate (nft-shared.c:1071) by 0x11C7C6: nft_rule_to_iptables_command_state (nft-shared.c:1236) by 0x119AF5: nft_rule_zero_counters (nft.c:2877) by 0x11A3CA: nft_prepare (nft.c:3445) by 0x11A7A8: nft_commit (nft.c:3479) by 0x114258: xtables_main.isra.0 (xtables-standalone.c:94) by 0x1142D9: xtables_ip6_main (xtables-standalone.c:118) by 0x49F2349: (below main) (in /lib64/libc.so.6) Have to free the matches/target in populated iptables_command_state object again. While being at it, call the proper family_ops callbacks since this is family-agnostic code. Fixes: a69cc575295ee ("xtables: allow to reset the counters of an existing rule") Signed-off-by: Phil Sutter <phil@nwl.cc>
* iptables-nft: exit nonzero when iptables-save cannot decode all expressionsFlorian Westphal2022-11-231-6/+20
| | | | | | | | | | | | We always return 0, even if we printed some error message half-way. Increment an error counter whenever an error message was printed so that the chain-loop can exit with an error if this counter is nonzero. Another effect is that iptables-save will no longer print the COMMIT line anmore. Reported-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Florian Westphal <fw@strlen.de> Acked-by: Phil Sutter <phil@nwl.cc>
* nft: replace nftnl_.*_nlmsg_build_hdr() by nftnl_nlmsg_build_hdr()Pablo Neira Ayuso2022-11-151-6/+6
| | | | | | | Replace alias to real nftnl_nlmsg_build_hdr() function call. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Phil Sutter <phil@nwl.cc>
* Drop extra newline from xtables_error() callsPhil Sutter2022-11-151-1/+1
| | | | | | | | | | Since basic_exit_err() appends a newline to the message itself, drop explicit ones. While being at it, fix indentation and join texts split over multiple lines. Signed-off-by: Phil Sutter <phil@nwl.cc>
* ebtables: Fix among matchPhil Sutter2022-09-281-4/+2
| | | | | | | | | | | | | | | | | | Fixed commit broke among match in two ways: 1) The two lookup sizes are 12 and 6, not 12 and 4 - among supports either ether+IP or ether only, not IP only. 2) Adding two to sreg_count to get the second register is too simple: It works only for four byte regs, not the 16 byte ones. The first register is always a 16 byte one, though. Fixing (1) is trivial, fix (2) by introduction of nft_get_next_reg() doing the right thing. For consistency, use it for among match creation, too. Fixes: f315af1cf8871 ("nft: track each register individually") Signed-off-by: Phil Sutter <phil@nwl.cc>
* Revert "nft: prefer payload to ttl/hl module"/'meta pkttype' match.Florian Westphal2022-09-221-65/+0
| | | | | | | | | | | | | | | | This reverts commit 8acaccf69c22fb195a0b88e28489792304728245. This reverts commit 793caef9076cceb24336b6cbb8f55107de49f269. As per ongoing discussion, keep the dissection side but keep using nft_compat mode for now until we've figured out how to handle backwards compatibility with older iptables-nft binaries dumping the ruleset. Furthermore, "nft: prefer native 'meta pkttype' instead of xt match" broke ebtables: it has its own, incompatible pkttype match and needs special handling. Signed-off-by: Florian Westphal <fw@strlen.de>
* nft: un-break among match with concatenationFlorian Westphal2022-09-221-1/+1
| | | | | | | | | | The kernel commit 88cccd908d51 ("netfilter: nf_tables: NFTA_SET_ELEM_KEY_END requires concat and interval flags") breaks ebtables-nft 'among' emulation, it sets NFTA_SET_ELEM_KEY_END but doesn't set the CONCAT flag. Update uapi header and also set CONCAT. Signed-off-by: Florian Westphal <fw@strlen.de>
* nft: prefer payload to ttl/hl moduleFlorian Westphal2022-09-131-0/+43
| | | | | Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Phil Sutter <phil@nwl.cc>
* nft: prefer native 'meta pkttype' instead of xt matchFlorian Westphal2022-09-081-0/+22
| | | | | Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Phil Sutter <phil@nwl.cc>
* nft: Expand extended error reporting to nft_cmd, tooPhil Sutter2022-08-261-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Introduce the same embedded 'error' struct in nft_cmd and initialize it with the current value from nft_handle. Then in preparation phase, update nft_handle's error.lineno with the value from the current nft_cmd. This serves two purposes: * Allocated batch objects (obj_update) get the right lineno value instead of the COMMIT one. * Any error during preparation may be reported with line number. Do this and change the relevant fprintf() call to use nft_handle's lineno instead of the global 'line' variable. With this change, cryptic iptables-nft-restore error messages should finally be gone: | # iptables-nft-restore <<EOF | *filter | -A nonexist | COMMIT | EOF | iptables-nft-restore: line 2 failed: No chain/target/match by that name. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: fix ebtables among match when mac+ip addresses are usedFlorian Westphal2022-08-021-2/+2
| | | | | | | | | | | When matching mac and ip addresses, the ip address needs to be placed into then 2nd 32bit register, the switch to dynamic register allocation instead re-uses reg1, this partially clobbers the mac address, so set lookup comes up empty even though it should find a match. Fixes: 7e38890c6b4fb ("nft: prepare for dynamic register allocation") Reported-by: Yi Chen <yiche@redhat.com> Signed-off-by: Florian Westphal <fw@strlen.de>
* nft: Fix EPERM handling for extensions without rev 0Phil Sutter2022-05-111-4/+7
| | | | | | | | | | Treating revision 0 as compatible in EPERM case works fine as long as there is a revision 0 of that extension defined in DSO. Fix the code for others: Extend the EPERM handling to all revisions and keep the existing warning for revision 0. Fixes: 17534cb18ed0a ("Improve error messages for unsupported extensions") Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: split gen_payload() to allocate register and initialize expressionPablo Neira Ayuso2022-05-021-4/+14
| | | | | | Add __gen_payload(), in preparation for the dynamic register allocation. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: prepare for dynamic register allocationPablo Neira Ayuso2022-05-021-31/+39
| | | | | | | | | Store the register that has been allocated and pass it on to the next expression. NFT_REG_1 is still used. No functional changes are expected. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: pass handle to helper functions to build netlink payloadPablo Neira Ayuso2022-05-021-13/+13
| | | | | | | Pass struct nft_handle to helper functions in preparation for the dynamic register allocation. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: native mark matching supportPablo Neira Ayuso2022-05-021-0/+23
| | | | | | Use meta mark + bitwise + cmp instead of nft_compat mark match. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: Don't pass command state opaque to family ops callbacksPhil Sutter2022-03-101-2/+2
| | | | | | | | | | | There are no family-specific versions of struct iptables_command_state anymore, so no need to hide it behind void pointer. Pass the type as-is and save a few casts. While at it, drop unused callbacks parse_bitwise and parse_cmp. Signed-off-by: Phil Sutter <phil@nwl.cc> Acked-by: Florian Westphal <fw@strlen.de>
* Improve error messages for unsupported extensionsPhil Sutter2022-03-021-3/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If a given extension was not supported by the kernel, iptables would print a rather confusing error message if extension parameters were given: | # rm /lib/modules/$(uname -r)/kernel/net/netfilter/xt_LOG.ko | # iptables -A FORWARD -j LOG --log-prefix foo | iptables v1.8.7 (legacy): unknown option "--log-prefix" Avoid this by pretending extension revision 0 is always supported. It is the same hack as used to successfully print extension help texts as unprivileged user, extended to all error codes to serve privileged ones as well. In addition, print a warning if kernel rejected revision 0 and it's not a permissions problem. This helps users find out which extension in a rule the kernel didn't like. Finally, the above commands result in these messages: | Warning: Extension LOG revision 0 not supported, missing kernel module? | iptables: No chain/target/match by that name. Or, for iptables-nft: | Warning: Extension LOG revision 0 not supported, missing kernel module? | iptables v1.8.7 (nf_tables): RULE_APPEND failed (No such file or directory): rule in chain FORWARD Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Add debug output to table creationPhil Sutter2022-02-081-0/+15
| | | | | | | This at least allows to inspect how tables are created on demand. Also requires setting NFTNL_TABLE_FAMILY for clean output. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Set NFTNL_CHAIN_FAMILY in new chainsPhil Sutter2022-02-081-4/+8
| | | | | | | | | | | | | | | | | | | | | | Kernel doesn't need it, but debug output improves significantly. Before this patch: | # iptables-nft -vv -A INPUT | [...] | unknown filter INPUT use 0 type filter hook unknown prio 0 policy accept packets 0 bytes 0 | [...] and after: | # iptables-nft -vv -A INPUT | [...] | ip filter INPUT use 0 type filter hook input prio 0 policy accept packets 0 bytes 0 | [...] While being at it, make nft_chain_builtin_alloc() take only the builtin table's name as parameter - it's the only field it accesses. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Use verbose flag to toggle debug outputPhil Sutter2022-02-041-18/+20
| | | | | | | | | | | Copy legacy iptables' behaviour, printing debug output if verbose flag is given more than once. Since nft debug output applies to netlink messages which are not created until nft_action() phase, carrying verbose value is non-trivial - introduce a field in struct nft_handle for that. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: add support for native tcp flag matchingFlorian Westphal2022-01-291-2/+29
| | | | | | prefer payload + bitwise + cmp to nft_compat match. Signed-off-by: Florian Westphal <fw@strlen.de>
* nft: prefer native expressions instead of tcp matchFlorian Westphal2022-01-291-0/+32
| | | | | | | | | | | | | | Instead of using nft_compat+xtables tcp match, prefer to emit payload+cmp or payload+range expression. Unlike udp, tcp has flag bits that can be matched too but we have to fall back to the xt expression for now. We also don't support tcp option match, but thats a rarely used feature anyway. Delinearization support for ports was added in previous patches. Signed-off-by: Florian Westphal <fw@strlen.de>
* nft: prefer native expressions instead of udp matchFlorian Westphal2022-01-291-0/+122
| | | | | | | | | Instead of using nft_compat+xtables udp match, prefer to emit payload+cmp or payload+range expression. Delinearization support was added in previous patches. Signed-off-by: Florian Westphal <fw@strlen.de>
* nft-shared: support native tcp port range delinearizeFlorian Westphal2022-01-291-0/+1
| | | | | | | adds support for nft ... tcp dport != min-max Signed-off-by: Florian Westphal <fw@strlen.de>
* xshared: Fix response to unprivileged usersPhil Sutter2022-01-201-0/+5
| | | | | | | | | | | | | | | | | | | | | Expected behaviour in both variants is: * Print help without error, append extension help if -m and/or -j options are present * Indicate lack of permissions in an error message for anything else With iptables-nft, this was broken basically from day 1. Shared use of do_parse() then somewhat broke legacy: it started complaining about inability to create a lock file. Fix this by making iptables-nft assume extension revision 0 is present if permissions don't allow to verify. This is consistent with legacy. Second part is to exit directly after printing help - this avoids having to make the following code "nop-aware" to prevent privileged actions. Signed-off-by: Phil Sutter <phil@nwl.cc> Reviewed-by: Florian Westphal <fw@strlen.de>
* extensions: libxt_NFLOG: don't truncate log prefix on print/saveKyle Bowman2022-01-181-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | When parsing the rule, use a struct with a layout compatible to that of struct xt_nflog_info, but with a buffer large enough to contain the whole 128-character nft prefix. We always send the nflog-group to the kernel since, for nft, log and nflog targets are handled by the same kernel module, and are distinguished by whether they define an nflog-group. Therefore, we must send the group even if it is zero, or the kernel will configure the target as a log, not an nflog. Changes to nft_is_expr_compatible were made since only targets which have an `nflog-group` are compatible. Since nflog targets are distinguished by having an nflog-group, we ignore targets without one. We also set the copy-len flag if the snap-len is set since without this, iptables will mistake `nflog-size` for `nflog-range`. Signed-off-by: Kyle Bowman <kbowman@cloudflare.com> Signed-off-by: Alex Forster <aforster@cloudflare.com> Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
* extensions: libxt_NFLOG: use nft built-in logging instead of xt_NFLOGKyle Bowman2022-01-181-0/+28
| | | | | | | | | | | | | | | Replaces the use of xt_NFLOG with the nft built-in log statement. This additionally adds support for using longer log prefixes of 128 characters in size. Until now NFLOG has truncated the log-prefix to the 64-character limit supported by iptables-legacy. We now use the struct xtables_target's udata member to store the longer 128-character prefix supported by iptables-nft. Signed-off-by: Kyle Bowman <kbowman@cloudflare.com> Signed-off-by: Alex Forster <aforster@cloudflare.com> Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
* nft: fix indentation error.Jeremy Sowden2022-01-151-21/+21
| | | | | | | `add_action` was indented with 7 spaces. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
* xshared: Share print_header() with legacy iptablesPhil Sutter2021-11-231-3/+3
| | | | | | | | | | | | | | | Legacy iptables fetches the relevant data via libiptc before calling the shared routine which merely prints data as requested. Drop the 'basechain' parameter, instead make sure a policy name is passed only with base chains. Since the function is not shared with ebtables (which uses a very rudimental header instead), this is safe. In order to support legacy iptables' checking of iptc_get_references() return code (printing an error message instead of the reference count), make refs parameter signed and print the error message if it's negative. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Change whitespace printing in save_rule callbackPhil Sutter2021-11-231-2/+2
| | | | | | | This aligns whitespace printing with legacy iptables' print_rule4() in order to prepare for further code-sharing. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Introduce builtin_tables_lookup()Phil Sutter2021-10-201-2/+17
| | | | | | | The set of builtin tables to use is fully determined by the given family so just look it up instead of having callers pass it explicitly. Signed-off-by: Phil Sutter <phil@nwl.cc>