summaryrefslogtreecommitdiffstats
path: root/iptables/nft.c
Commit message (Collapse)AuthorAgeFilesLines
* xtables: Fix error message for chain renamingPhil Sutter2019-02-131-1/+7
| | | | | | | | | If the new name already exists, legacy iptables prints "File exists.". This is a bit exotic, but more appropriate than "No chain/target/match by that name." printed by iptables-nft without this patch. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xtables: Fix error messages in commands with rule numberPhil Sutter2019-02-131-6/+6
| | | | | | | | | | | | Use E2BIG if rule identified by given number is not found. ENOENT is used if referenced chain is not found. Without this, a command specifying a non-existing chain in combination with a rule number like e.g.: 'iptables-nft -I nonexist 23 -j ACCEPT' returns "Index of insertion too big." instead of "No chain/target/match by that name." like legacy iptables does. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xtables: Move new chain check to where it belongsPhil Sutter2019-02-131-0/+5
| | | | | | | | Instead of checking chain existence in xtables.c, do it in nft_chain_user_add() and reuse predefined error message. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xtables: Fix error message when zeroing a non-existent chainPhil Sutter2019-02-131-1/+3
| | | | | | | | | | | | | Previously, error message was a bit misleading: | # iptables-nft -Z noexist | iptables: Incompatible with this kernel. Set errno value so that the typical "No chain/target/match by that name." is printed instead. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: Eliminate dead code in __nft_rule_listPhil Sutter2019-02-111-12/+1
| | | | | | | | | | | If passed a rulenum > 0, the function uses nftnl_rule_lookup_byindex() and returns early. Negative rulenum values are not supposed to happen, so the remaining code which iterates over the full list of rules does not need to respect rulenum anymore. Fixes: 039b048965210 ("nft: Make use of nftnl_rule_lookup_byindex()") Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Florian Westphal <fw@strlen.de>
* ebtables-nft: Support user-defined chain policiesPhil Sutter2019-02-081-2/+226
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Legacy ebtables supports policies for user-defined chains - and what's worse, they default to ACCEPT unlike anywhere else. So lack of support for this braindead feature in ebtables-nft is actually a change of behaviour which very likely affects all ebtables users out there. The solution implemented here uses an implicit (and transparent) last rule in all user-defined ebtables-nft chains with policy other than RETURN. This rule is identified by an nft comment "XTABLES_EB_INTERNAL_POLICY_RULE" (since commit ccf154d7420c0 ("xtables: Don't use native nftables comments") nft comments are not used otherwise). To minimize interference with existing code, this policy rule is removed from chains during cache population and the policy is saved in NFTNL_CHAIN_POLICY attribute. When committing changes to the kernel, nft_commit() traverses through the list of chains and (re-)creates policy rules if required. In ebtables-nft-restore, table flushes are problematic. To avoid weird kernel error responses, introduce a custom 'table_flush' callback which removes any pending policy rule add/remove jobs prior to creating the NFT_COMPAT_TABLE_FLUSH one. I've hidden all this mess behind checks for h->family, so hopefully impact on {ip,ip6,arp}tables-nft should be negligible. Signed-off-by: Phil Sutter <phil@nwl.cc> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Florian Westphal <fw@strlen.de>
* nft: Introduce UDATA_TYPE_EBTABLES_POLICYPhil Sutter2019-02-081-0/+3
| | | | | | | | | This will be used later to identify ebtables user-defined chain policy rules. Signed-off-by: Phil Sutter <phil@nwl.cc> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Florian Westphal <fw@strlen.de>
* xtables: Catch errors when zeroing rule rountersPhil Sutter2019-02-011-1/+3
| | | | | | | Covscan complained about call to batch_rule_add() not being checked. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Florian Westphal <fw@strlen.de>
* xtables: Speed up chain deletion in large rulesetsPhil Sutter2019-01-291-0/+2
| | | | | | | | | | Kernel prefers to identify chain by handle if it was given which causes manual traversal of the chain list. In contrast, chain lookup by name in kernel makes use of a hash table so is considerably faster. Force this code path by removing the cached chain's handle when removing it. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xtables: Fix for inserting rule at wrong positionPhil Sutter2019-01-281-10/+20
| | | | | | | | | | | | | | | | | | | iptables-restore allows to insert rules at a certain position which is problematic for iptables-nft to realize since rule position is not determined by number but handle of previous or following rule and in case the rules surrounding the new one are new as well, they don't have a handle to refer to yet. Fix this by making use of NFTNL_RULE_POSITION_ID attribute: When inserting before a rule which does not have a handle, refer to it using its NFTNL_RULE_ID value. If the latter doesn't exist either, assign a new one to it. The last used rule ID value is tracked in a new field of struct nft_handle which is incremented before each use. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xtables: Fix position of replaced rules in cachePhil Sutter2019-01-181-17/+17
| | | | | | | | | | | When replacing a rule, the replacement was simply appended to the chain's rule list. Instead, insert it where the rule it replaces was. This also fixes for zero counters command to remove the old rule from cache. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: Add new builtin chains to cache immediatelyPhil Sutter2019-01-181-21/+9
| | | | | | | | | | | | Newly created builtin chains missing from cache was the sole reason for the immediate calls to nft_commit(). With nft_chain_builtin_add() inserting the new chain into the table's chain list, this is not needed anymore. Just make sure batch_obj_del() doesn't free the payload of NFT_COMPAT_CHAIN_ADD jobs since it contains the new chain which has been added to cache. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xtables: Set errno in nft_rule_check() if chain not foundPhil Sutter2019-01-111-5/+7
| | | | | | | | | | | | With this, the explicit check for chain existence can be removed from xtables.c since all related commands do this now. Note that this effectively changes the error message printed by iptables-nft when given a non-existing chain, but the new error message(s) conform with those printed by legacy iptables. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: Simplify flush_chain_cache()Phil Sutter2019-01-091-13/+11
| | | | | | | | | | | | With all the checks for 'tablename' being non-NULL, this code was rather stupid and really hard to read. And the fix is indeed quite simple: If a table name was given, use nft_table_builtin_find() and just flush its chain cache. Otherwise iterate over all builtin tables without any conditionals for 'tablename'. Fixes: d4b0d248cc057 ("nft: Reduce indenting level in flush_chain_cache()") Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: Simplify nft_is_chain_compatible()Phil Sutter2019-01-091-25/+9
| | | | | | | | | | Make use of nft_{table,chain}_builtin_find() instead of open-coding the list traversal. Since code is pretty obvious now, drop the comments added earlier. Fixes: e774b15299c27 ("nft: Review is_*_compatible() routines") Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: Make use of nftnl_rule_lookup_byindex()Phil Sutter2018-12-271-13/+18
| | | | | | | | Use the function where suitable to potentially speedup rule cache lookup by rule number. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xtables: Optimize list rules command with given chainPhil Sutter2018-12-271-50/+43
| | | | | | | | | | | If a chain name was given, make use of nftnl_chain_list_lookup_byname(). Likewise in nftnl_rule_list_chain_save(), but introduce __nftnl_rule_list_chain_save() suitable for passing to nftnl_chain_list_foreach(). Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xtables: Optimize list command with given chainPhil Sutter2018-12-271-46/+32
| | | | | | | | | Make use of nftnl_chain_list_lookup_byname() even if not listing a specific rule. Introduce __nft_print_header() to consolidate chain value extraction for printing with ops->print_header(). Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xtables: Optimize user-defined chain deletionPhil Sutter2018-12-271-43/+46
| | | | | | | | | Make use of nftnl_chain_list_lookup_byname() if a chain name was given. Move the actual chain deleting code into a callback suitable for passing to nftnl_chain_list_foreach(). Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xtables: Optimize nft_chain_zero_counters()Phil Sutter2018-12-271-36/+36
| | | | | | | | | | | | | If a chain name was given, make use of nftnl_chain_list_lookup_byname(). Streamline nft_chain_zero_rule_counters() to be suitable for calling from nftnl_chain_list_foreach(). There is an unrelated optimization in here, too: Add batch job NFT_COMPAT_CHAIN_ZERO only if it is a base chain. Since user-defined chains don't have counters, there is no need to do anything for them. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xtables: Optimize flushing a specific chainPhil Sutter2018-12-271-13/+17
| | | | | | | | If a chain name is given to nft_rule_flush(), make use of nftnl_chain_list_lookup_byname(). Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: Drop nft_chain_list_find()Phil Sutter2018-12-271-29/+2
| | | | | | | | Replace the function by nftnl_chain_list_lookup_byname() as provided by libnftnl. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xtables: Implement per chain rule cachePhil Sutter2018-12-271-221/+165
| | | | | | | | | | | | | | | Use recently introduced support for rules inside chains in libnftnl to introduce a rule cache per chain instead of a global one. A tricky bit is to decide if cache should be updated or not. Previously, the global rule cache was populated just once and then reused unless being flushed completely (via call to flush_rule_cache() with NULL-pointer table argument). Resemble this behaviour by introducing a boolean indicating cache status and fetch rules for all chains when updating the chain cache in nft_chain_list_get(). Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* 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>