summaryrefslogtreecommitdiffstats
path: root/iptables/nft.c
Commit message (Collapse)AuthorAgeFilesLines
...
* nft: Move nft_rule_list_get() above nft_chain_list_get()Phil Sutter2018-12-271-55/+55
| | | | | | | | | | Later when introducing per chain rule caches, nft_rule_list_get() will be removed. But nftnl_rule_list_cb() which it uses will be reused to update each chain's rule cache from inside nftnl_chain_list_get(), so move both into position. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: Introduce fetch_chain_cache()Phil Sutter2018-12-271-10/+17
| | | | | | | | Move chain cache population from nft_chain_list_get() into a dedicated function. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: Simplify nft_rule_insert() a bitPhil Sutter2018-12-271-4/+1
| | | | | | | Fetch rule list right on top instead of in each branch separately. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: Simplify per table chain cache updatePhil Sutter2018-12-271-10/+13
| | | | | | | | | | | | | | | | | | Previously, each table's chain cache was potentially unallocated until nftnl_chain_list_cb() saw a chain for it. This means such callback had to check the chain_cache pointer for each chain belonging to that table. In addition to the above, nft_chain_list_get() had to cover for the possibility that a given table didn't have any chains at all in kernel, so check requested table's chain cache once more and allocate it if NULL. Instead, simply iterate over all tables and preallocate their chain caches prior to requesting the chain list from kernel. The only caveat is to flush the chain cache completely before retrying in case of EINTR. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: Reduce indenting level in flush_chain_cache()Phil Sutter2018-12-271-9/+13
| | | | | | | | | | | | | | | Instead of doing all in one go, make two separate decisions: 1) If table has no chain cache, either continue or return depending on whether we're flushing for a specific table. 2) With chain cache present, flushing strategy once more depends on whether we're flushing for a specific table: If given, just remove all rules and return. If not, free the cache and set to NULL (so that it will be repopulated later), then continue the loop. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: Reduce __nft_rule_del() signaturePhil Sutter2018-12-271-4/+3
| | | | | | | | The function does not use passed struct nftnl_rule_list, so remove it from its parameters. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: Review is_*_compatible() routinesPhil Sutter2018-12-271-98/+55
| | | | | | | | | | | | | | | | - Call to nft_table_builtin_find() in nft_is_table_compatible() is not needed, as it is repeated in the latter call to nft_chain_list_get() by nft_are_chains_compatible(). - Turn nft_is_chain_compatible(), nft_is_rule_compatible() and nft_is_expr_compatible() into callbacks for use with respective foreach functions. - nft_are_chains_compatible() is not needed anymore due to foreach function use. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: Review unclear return pointsPhil Sutter2018-12-261-2/+2
| | | | | | | | | | When converting to per table chain caches, these two error returns were marked for review but apparently forgotten. Make sure error condition is propagated when returning at those points. Fixes: c58ecf9f8bcb7 ("xtables: Introduce per table chain caches") Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: Simplify nftnl_rule_list_chain_save()Phil Sutter2018-12-261-7/+3
| | | | | | | | | Since there are per table chain caches, The chain list passed to that function is comprised of chains belonging to the right table only. Therefore the table name check can safely be skipped. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xtables: Don't use native nftables commentsPhil Sutter2018-11-271-27/+0
| | | | | | | | | | | | | | | The problem with converting libxt_comment into nftables comment is that rules change when parsing from kernel due to comment match being moved to the end of the match list. And since match ordering matters, the rule may not be found anymore when checking or deleting. Apart from that, iptables-nft didn't support multiple comments per rule anymore. This is a compatibility issue without technical reason. Leave conversion from nftables comment to libxt_comment in place so we don't break running systems during an update. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xtables: constify struct builtin_table and struct builtin_chainPablo Neira Ayuso2018-11-191-21/+21
| | | | | | These definitions should be const, propagate this to all existing users. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: move initialize to struct nft_handlePablo Neira Ayuso2018-11-191-4/+10
| | | | | | | Move this to the structure that stores, stateful information. Introduce nft_table_initialized() and use it. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: move chain_cache back to struct nft_handlePablo Neira Ayuso2018-11-191-13/+13
| | | | | | Place this back into the structure that stores the state information. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: add type field to builtin_tablePablo Neira Ayuso2018-11-191-0/+8
| | | | | | | Use enum nft_table_type to set the new type field in the structure that define tables. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xtables: Introduce per table chain cachesPhil Sutter2018-11-171-88/+72
| | | | | | | | | | | | | | | | Being able to omit the previously obligatory table name check when iterating over the chain cache might help restore performance with large rulesets in xtables-save and -restore. There is one subtle quirk in the code: flush_chain_cache() did free the global chain cache if not called with a table name but didn't if a table name was given even if it emptied the chain cache. In other places, chain_cache being non-NULL prevented a cache update from happening, so this patch establishes the same behaviour (for each individual chain cache) since otherwise unexpected cache updates lead to weird problems. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xtables: Fix error return code in nft_chain_user_rename()Phil Sutter2018-11-121-2/+2
| | | | | | | If the chain to rename wasn't found, the function would return -1 which got interpreted as success. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: add NFT_TABLE_* enumerationPablo Neira Ayuso2018-11-121-13/+13
| | | | Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: replace nft_chain_dump() by nft_chain_list_get()Pablo Neira Ayuso2018-11-121-16/+11
| | | | | | So we can remove nft_chain_dump() and replace nftnl_chain_get_list(). Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xtables-nft: make -Z option workFlorian Westphal2018-11-051-2/+79
| | | | | | | | -Z doesn't just zero base counters, it zeroes out all rule counters, or, optionally, all counters of a chain (-Z FOO). Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1286 Signed-off-by: Florian Westphal <fw@strlen.de>
* nft: add missing error stringFlorian Westphal2018-11-031-0/+1
| | | | Signed-off-by: Florian Westphal <fw@strlen.de>
* Fix a few cases of pointless assignmentsPhil Sutter2018-09-241-2/+0
| | | | | | | | This gets rid of a number of assignments which are either redundant or not used afterwards. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Florian Westphal <fw@strlen.de>
* xtables: Remove unused variable in nft_is_table_compatible()Phil Sutter2018-09-241-1/+1
| | | | | | | | This is a leftover from previous cleanup. Fixes: 098ee2e91756c ("xtables-save: Ignore uninteresting tables") Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Florian Westphal <fw@strlen.de>
* xtables: Fix for wrong assert() in __nft_table_flush()Phil Sutter2018-09-241-1/+1
| | | | | | | | | | The code obviously tries to assert that nft_table_builtin_find() returned a valid pointer before dereferencing it, but the wrong argument was given. Assume this is just a typo and insert the missing underscore. Fixes: 9b896224e0bfc ("xtables: rework rule cache logic") Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Florian Westphal <fw@strlen.de>
* xtables-save: Ignore uninteresting tablesPhil Sutter2018-09-181-8/+1
| | | | | | | | | | | | | | | | | | When running iptables-nft-save with other tables present, the dump succeeded but the tool complained about those other tables. In an environment where iptables-nft and nftables are uses in parallel, this is an expected situation, so only complain about incompatible builtin tables. While being at it, move the table existence check from __do_output() into do_output() since the former may be called from nft_for_each_table() in which case the table is guaranteed to exist. Also use nft_table_builtin_find() in nft_is_table_compatible() instead of open-coding the search by name in h->tables. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xtables: Don't check all rules for being compatiblePhil Sutter2018-09-101-0/+6
| | | | | | | | | | | | | Commit f8e29a13fed8d ("xtables: avoid bogus 'is incompatible' warning") fixed for compatibility checking to extend over all chains, not just the relevant ones. This patch does the same for rules: Make sure only rules belonging to the relevant table are being considered. Note that comparing the rule's table name is sufficient here since the table family is already considered when populating the rule cache. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Florian Westphal <fw@strlen.de>
* xtables-restore: Fix flushing referenced custom chainsPhil Sutter2018-09-101-8/+2
| | | | | | | | | | | | | | | | | | | | | | | | The logic to replicate 'iptables-restore --noflush' behaviour of flushing custom chains if listed in the dump was broken for chains being referenced. A minimal dump reproducing the issue is: | *filter | :foobar - [0:0] | -I INPUT -j foobar | -A foobar -j ACCEPT | COMMIT With --noflush, this can be restored just once in iptables-nft-restore. Consecutive attempts return an error since xtables tries to delete the referenced chain and recreate it instead of performing a real flush. Fix this by really flushing the custom chain in 'chain_user_flush' callback and running 'chain_user_add' callback only if the chain doesn't exist already. Fixes: df3d92bec6007 ("xtables-compat-restore: flush user-defined chains with -n") Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Florian Westphal <fw@strlen.de>
* xtables: Align return codes with legacy iptablesPhil Sutter2018-09-011-0/+15
| | | | | | | | Make sure return codes match legacy ones at least for a few selected commands typically used to check ruleset state. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Florian Westphal <fw@strlen.de>
* xtables: Add a few missing exit callsPhil Sutter2018-08-241-2/+6
| | | | | | | | | Mostly to reduce noise from valgrind output, add missing calls to destroy iterators in nft.c and add cleanup for the populated nft_handle in xtables_eb_save_main(). Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xtables: Fix for segfault in iptables-nftPhil Sutter2018-08-171-2/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Trying to set a chain's policy in an invalid table resulted in a segfault. Reproducer was: | # iptables -t broute -P BROUTING ACCEPT Fix this by aborting in nft_chain_new() if nft_table_builtin_find() returned NULL for the given table name. For an illustrative error message, set errno to ENXIO in the above case and add an appropriate Mesage to nft_strerror(). While being at it, improve the error message if an invalid policy was given. Before: | # iptables-nft -t filter -P INPUT ACCEPTdf | iptables: Incompatible with this kernel. After: | # iptables-nft -t filter -P INPUT ACCEPTdf | iptables: Bad policy name. Run `dmesg' for more information. Third unrelated change in this patch: Drop error checking of nft_chain_set() in do_commandx(): The function never returns negative, so that check never yielded true. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Florian Westphal <fw@strlen.de>
* ebtables: Fix entries count in chain listingPhil Sutter2018-08-161-3/+3
| | | | | | | | | | | | | | | The previous fix for reference counts in iptables-nft output wasn't complete: While iptables lists the number of references for each custom chain (i.e., the number of jumps to it), ebtables lists number of entries (i.e., the number of rules contained) for each chain. Both used the same value for it, although they are different metrics. Fix this by passing both numbers separately to the 'print_header' callback so that each tool may print the desired value. Fixes: a0698de9866d2 ("xtables: Do not count rules as chain references") Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xtables: Make 'iptables -S nonexisting' return non-zeroPhil Sutter2018-08-161-11/+5
| | | | | | | | | | | | To be consistent with legacy iptables, calling -S with a non-existing chain should lead to an error message. This is how some scripts find out whether a user-defined chain exists or not. Make sure doing the same for an existing chain does succeed, even if an invalid rule number was given. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* ebtables: Fix for listing of non-existent chainsPhil Sutter2018-08-161-3/+7
| | | | | | | | | | | | | | | | | When trying to list a non-existent chain, ebtables-nft would just print the table header and then exit with a code of zero. In order to be more consistent with legacy ebtables, change the code to: * Print table header only if chosen chain is found and * propagate the error condition if chain was not found to print an error message. Note that this does not establish full parity with legacy ebtables due to the error code being 1 instead of 255 and the error message differing from the legacy one. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xtables: Fix for no output in iptables-nft -SPhil Sutter2018-08-161-0/+17
| | | | | | | | | | | Just like with 'iptables-nft -L', we have to make sure the standard set of chains exist for a given table when listing it using '-S' flag. The added code was just copied over from nft_rule_list() which does the same. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xtables: Use native nftables limit expressionPhil Sutter2018-08-161-4/+49
| | | | | | | | | | | | | | | | | | | | The original issue was that for a rule with limit match added by ebtables-nft, the kernel might attempt to use xt_limit instead of ebt_limit (and fail due to that). This happens if xt_limit.ko is loaded but ebt_limit.ko is not, because the kernel prefers the family-independent variants. There are multiple ways to avoid above issue, but using neither xt_limit nor ebt_limit with nft-variants should be the most effective one. Therefore translate a created limit match in userspace into native nftables code before sending it to kernel and do the reverse translation when listing rules. Apart from the translation routines, this requires slight adjustment of nft_is_expr_compatible() since neither xt_limit nor ebt_limit support byte-based limits or inverted limit match. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xtables: Fix for wrong counter format in -S outputPhil Sutter2018-08-091-2/+8
| | | | | | | | | | | | | | | | | | | | | | Legacy iptables uses '-c PCNT BCNT' format in listed rules, nft-variant used '[PCNT BCNT]' prefix like with iptables-save. In order to pass the counter format preference along, FMT_C_COUNTS is introduced and related 'format' checks adjusted. Since legacy iptables prints the counters between matches and target, this change affects save_matches_and_target() function. In order to get access to the rule counters, it's declaration is adjusted to receive iptables_command_state pointer instead of match, target and jumpto pointers from the same object. While being at it, integrate jump to user-defined chain into it as well since the related code in both callers was almost identical. Though since different rule flags are used between iptables and ip6tables, pass a 'goto_flag' boolean instead of the actual 'flags' bitfield. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Florian Westphal <fw@strlen.de>
* xtables: Fix potential segfault in nft_rule_append()Phil Sutter2018-08-061-1/+3
| | | | | | | | | If batch_rule_add() failed (ENOMEM), nft_rule_append() frees the rule and then tries to add it to the rule cache. Better return 0 (failure) instead of continuing. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Florian Westphal <fw@strlen.de>
* xtables-restore: Improve user-defined chain detectionPhil Sutter2018-08-061-2/+2
| | | | | | | | | | | | Legacy ebtables-save does not use a policy string of '-' to denote user-defined chains but instead lists them with a policy of ACCEPT. In order to use ebtables_restore_parse() for ebtables-save implementation, make use of builtin table definitions to decide whether a given chain is a builtin one or not. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Florian Westphal <fw@strlen.de>
* xtables: Match verbose ip{,6}tables output with legacyPhil Sutter2018-08-041-8/+31
| | | | | | | | | | | | | | Legacy ip{,6}tables prints feedback for various commands if in verbose mode, make sure nft variants do the same. There is one difference, namely when checking a rule (-C command): Legacy ip{,6}tables print the rule in any case, nft variants don't in case the rule wasn't found. Changing this though would require to populate the nftnl_rule object just for printing, which is probably not feasible. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Florian Westphal <fw@strlen.de>
* xtables: Print error when listing non-existent chainsPhil Sutter2018-08-041-2/+5
| | | | | | | | Just like legacy iptables, iptables-nft should not treat the attempt to list a non-existing chain as OK. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Florian Westphal <fw@strlen.de>
* xtables: Fix for no output on first iptables-nft invocationPhil Sutter2018-08-041-1/+3
| | | | | | | | | | | | Fix the same issue commit a4e78370af849 ("iptables-compat: fix empty chains after first invocation of iptables-compat -L") fixed back in 2014. Seems like some changes since then broke it again. This time, existing cache not containing the added table/chains gets into the way, so clear it if nft_commit() was called. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Florian Westphal <fw@strlen.de>
* xtables: Do not count rules as chain referencesPhil Sutter2018-08-041-0/+38
| | | | | | | | | | Unlike iptables, nftables counts rules in a chain as references to that chain. Align output of 'iptables-nft -L' with that of legacy iptables by counting the number of rules in a chain and subtracting that value from reference count before printing the chain header. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Florian Westphal <fw@strlen.de>
* xtables: Use correct built-in chain countPhil Sutter2018-08-041-1/+1
| | | | | | | | | | In nft_chain_builtin_init(), The wrong macro was used for iterating over the built-in chains of a given table. That array's length is defined using NF_INET_NUMHOOKS, not NF_IP_NUMHOOKS. Though this change is rather cosmetic since both macros resolve into the same value. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Florian Westphal <fw@strlen.de>
* xtables: Fix compilation with NLDEBUG definedPhil Sutter2018-08-041-2/+2
| | | | | | | | | In libnftnl-1.0.5, symbol name prefix changed from 'nft_' to 'nftnl_'. This patch fixes for two places forgotten by the relevant commit. Fixes: 742baabd185c3 ("iptables-compat: use new symbols in libnftnl") Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Florian Westphal <fw@strlen.de>
* xtables: Free chains in NFT_COMPAT_CHAIN_ADD jobsPhil Sutter2018-08-041-2/+6
| | | | | | | | | | | | | | Chains in NFT_COMPAT_CHAIN_ADD usually have to be freed because they are not added to the cache. There is one exception though, namely when zeroing counters: nft_chain_zero_counters() adds a chain object it took from chain cache. To distinguish this situation from the others, introduce NFT_COMPAT_CHAIN_ZERO batch object type, which is treated just like NFT_COMPAT_CHAIN_ADD but batch_obj_del() does not free it's chain. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Florian Westphal <fw@strlen.de>
* xtables: Free chains in NFT_COMPAT_CHAIN_USER_DEL jobsPhil Sutter2018-08-041-1/+1
| | | | | | | | These always have to be freed because nft_chain_user_del() removes them from the cache so they are not freed when the chain cache is flushed. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Florian Westphal <fw@strlen.de>
* xtables: Fix for nft_rule_flush() returning garbagePhil Sutter2018-08-041-3/+5
| | | | | | | | | | | | | | Due to variable 'ret' not being initialized in all situations, return code of the function depends on garbage in stack. Fix this by initializing 'ret' to zero upon declaration. While being at it, make nftnl_chain_list_get() failure as well as nftnl_chain_list_iter_create() failure an error condition since both functions should succeed even if the current ruleset does not contain any chains at all. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Florian Westphal <fw@strlen.de>
* xtables: Allocate rule cache just oncePhil Sutter2018-08-041-3/+5
| | | | | | | | | | For each parsed table, xtables-restore calls nft_table_flush() which each time allocates a new rule cache, possibly overwriting the pointer to the previously allocated one. Fix this by checking the pointer value and only allocate if it's NULL. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Florian Westphal <fw@strlen.de>
* nft: don't print rule counters unless verboseEric Garver2018-08-011-1/+1
| | | | | | | | | | | Currently rule counters are always printed, but that's not the desired behavior. We should only print them with the verbose flag. This broke when the arguments of nft_rule_print_save() were changed to accept the format instead of a counters flag. Fixes: cdc78b1d6bd7 ("nft: convert rule into a command state structure") Signed-off-by: Eric Garver <e@erig.me> Signed-off-by: Florian Westphal <fw@strlen.de>
* xtables: avoid bogus 'is incompatible' warningFlorian Westphal2018-07-241-1/+6
| | | | | | | | | | | | | | | | | | | | | | when using custom nft tables + iptables-nft, iptables-nft -L may fail with iptables v1.8.0 (nf_tables): table `filter' is incompatible, use 'nft' tool. even if filter table is compatible. Problem is that the chain cache tracks ALL chains. The "old" compat-check only walked chains in the table to checked (filter in this case), now we will see all other chains including base chains of another table. It seems better to extend the chain cache long-term to track chains per table instead, but for now skip the foreign ones. Reported-by: Eric Garver <e@erig.me> Fixes: 01e25e264a4c4 ("xtables: add chain cache") Signed-off-by: Florian Westphal <fw@strlen.de>
* xtables: pass format to nft_rule_save()Phil Sutter2018-07-191-3/+2
| | | | | | | | Preparing ebtables-save implementation, allow for callers to pass format bits to nft_rule_save() instead of just the 'counters' boolean. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Florian Westphal <fw@strlen.de>