summaryrefslogtreecommitdiffstats
path: root/iptables/nft.c
Commit message (Collapse)AuthorAgeFilesLines
* nft: Avoid pointless table/chain creationPhil Sutter2020-12-211-18/+80
| | | | | | | | | | | | | | | | | Accept a chain name in nft_xt_builtin_init() to limit the base chain creation to that specific chain only. Introduce nft_xt_builtin_table_init() to create just the table for situations where no builtin chains are needed but the command may still succeed in an empty ruleset, particularly when creating a custom chain, restoring base chains or adding a set for ebtables among match. Introduce nft_xt_fake_builtin_chains(), a function to call after cache has been populated to fill empty base chain slots. This keeps ruleset listing output intact if some base chains do not exist (or even the whole ruleset is completely empty). Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Introduce a dedicated base chain arrayPhil Sutter2020-12-211-1/+11
| | | | | | | | | Preparing for sorted chain output, introduce a per-table array holding base chains indexed by nf_inet_hooks value. Since the latter is ordered correctly, iterating over the array will return base chains in expected order. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Introduce struct nft_chainPhil Sutter2020-12-211-44/+71
| | | | | | | | | Preparing for ordered output of user-defined chains, introduce a local datatype wrapping nftnl_chain. In order to maintain the chain name hash table, introduce nft_chain_list as well and use it instead of nftnl_chain_list. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: cache: Move nft_chain_find() overPhil Sutter2020-12-211-17/+0
| | | | | | It is basically just a cache lookup, hence fits better in here. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Implement nft_chain_foreach()Phil Sutter2020-12-211-55/+33
| | | | | | | | | | | | | | This is just a fancy wrapper around nftnl_chain_list_foreach() with the added benefit of detecting invalid table names or uninitialized chain lists. This in turn allows to drop the checks in flush_rule_cache() and ignore the return code of nft_chain_foreach() as it fails only if the dropped checks had failed, too. Since this wrapper does the chain list lookup by itself, use of nft_chain_list_get() shrinks down to a single place, namely inside nft_chain_find(). Therefore fold it into the latter. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: cache: Introduce nft_cache_add_chain()Phil Sutter2020-12-211-9/+7
| | | | | | | This is a convenience function for adding a chain to cache, for now just a simple wrapper around nftnl_chain_list_add_tail(). Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Fix selective chain compatibility checksPhil Sutter2020-12-211-0/+6
| | | | | | | | | | | | | | Since commit 80251bc2a56ed ("nft: remove cache build calls"), 'chain' parameter passed to nft_chain_list_get() is no longer effective. Before, it was used to fetch only that single chain from kernel when populating the cache. So the returned list of chains for which compatibility checks are done would contain only that single chain. Re-establish the single chain compat checking by introducing a dedicated code path to nft_is_chain_compatible() doing so. Fixes: 80251bc2a56ed ("nft: remove cache build calls") Signed-off-by: Phil Sutter <phil@nwl.cc>
* ebtables: Fix for broken chain renamingPhil Sutter2020-11-171-3/+0
| | | | | | | | | | Loading extensions pollutes 'errno' value, hence before using it to indicate failure it should be sanitized. This was done by the called function before the parsing/netlink split and not migrated by accident. Move it into calling code to clarify the connection. Fixes: a7f1e208cdf9c ("nft: split parsing from netlink commands") Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Fix for concurrent noflush restore callsPhil Sutter2020-10-131-28/+30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Transaction refresh was broken with regards to nft_chain_restore(): It created a rule flush batch object only if the chain was found in cache and a chain add object only if the chain was not found. Yet with concurrent ruleset updates, one has to expect both situations: * If a chain vanishes, the rule flush job must be skipped and instead the chain add job become active. * If a chain appears, the chain add job must be skipped and instead rules flushed. Change the code accordingly: Create both batch objects and set their 'skip' field depending on the situation in cache and adjust both in nft_refresh_transaction(). As a side-effect, the implicit rule flush becomes explicit and all handling of implicit batch jobs is dropped along with the related field indicating such. Reuse the 'implicit' parameter of __nft_rule_flush() to control the initial 'skip' field value instead. A subtle caveat is vanishing of existing chains: Creating the chain add job based on the chain in cache causes a netlink message containing that chain's handle which the kernel dislikes. Therefore unset the chain's handle in that case. Fixes: 58d7de0181f61 ("xtables: handle concurrent ruleset modifications") Signed-off-by: Phil Sutter <phil@nwl.cc>
* iptables-nft: fix basechain policy configurationPablo Neira Ayuso2020-10-081-1/+5
| | | | | | | | | | Previous to this patch, the basechain policy could not be properly configured if it wasn't explictly set when loading the ruleset, leading to iptables-nft-restore (and ip6tables-nft-restore) trying to send an invalid ruleset to the kernel. Signed-off-by: Arturo Borrero Gonzalez <arturo@netfilter.org> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: Fix error reporting for refreshed transactionsPhil Sutter2020-10-071-2/+3
| | | | | | | | | | | | | | When preparing a batch from the list of batch objects in nft_action(), the sequence number used for each object is stored within that object for later matching against returned error messages. Though if the transaction has to be refreshed, some of those objects may be skipped, other objects take over their sequence number and errors are matched to skipped objects. Avoid this by resetting the skipped object's sequence number to zero. Fixes: 58d7de0181f61 ("xtables: handle concurrent ruleset modifications") Signed-off-by: Phil Sutter <phil@nwl.cc> Reviewed-by: Florian Westphal <fw@strlen.de>
* nft: Make batch_add_chain() return the added batch objectPhil Sutter2020-10-071-18/+17
| | | | | | | | | | Do this so in a later patch the 'skip' field can be adjusted. While being at it, simplify a few callers and eliminate the need for a 'ret' variable. Signed-off-by: Phil Sutter <phil@nwl.cc> Reviewed-by: Florian Westphal <fw@strlen.de>
* nft: Use nft_chain_find() in nft_chain_builtin_init()Phil Sutter2020-08-211-12/+4
| | | | | | The replaced code is basically identical to nft_chain_find()'s body. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Fold nftnl_rule_list_chain_save() into callerPhil Sutter2020-08-211-24/+7
| | | | | | | | | | | Existence of this function was mostly code-duplication: Caller already branches depending on whether 'chain' is NULL or not and even does the chain list lookup. While being at it, simplify __nftnl_rule_list_chain_save function name a bit now that the non-prefixed name is gone. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Extend use of nftnl_chain_list_foreach()Phil Sutter2020-08-211-77/+86
| | | | | | | | | | | | | Make use of the callback-based iterator in nft_rule_list(), nft_rule_list_save(), nft_rule_flush() and nft_rule_save(). Callback code for nft_rule_list() and nft_rule_list_save is pretty similar, so introduce and use a common callback function. For nft_rule_save(), turn nft_chain_save_rules() into a callback - it is not used anywhere else, anyway. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Fix for ruleset flush while restoringPhil Sutter2020-08-141-13/+2
| | | | | | | | | | | | | | | | | | If ruleset is flushed while an instance of iptables-nft-restore is running and has seen a COMMIT line once, it doesn't notice the disappeared table while handling the next COMMIT. This is due to table existence being tracked via 'initialized' boolean which is only reset by nft_table_flush(). To fix this, drop the dedicated 'initialized' boolean and switch users to the recently introduced 'exists' one. As a side-effect, this causes base chain existence being checked for each command calling nft_xt_builtin_init() as the old 'initialized' bit was used to track if that function has been called before or not. Signed-off-by: Phil Sutter <phil@nwl.cc> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: Eliminate table list from cachePhil Sutter2020-07-311-40/+15
| | | | | | | | | | | | | | The full list of tables in kernel is not relevant, only those used by iptables-nft and for those, knowing if they exist or not is sufficient. For holding that information, the already existing 'table' array in nft_cache suits well. Consequently, nft_table_find() merely checks if the new 'exists' boolean is true or not and nft_for_each_table() iterates over the builtin_table array in nft_handle, additionally checking the boolean in cache for whether to skip the entry or not. Signed-off-by: Phil Sutter <phil@nwl.cc>
* iptables: replace libnftnl table list by linux listPablo Neira Ayuso2020-07-271-56/+18
| | | | | | | | This patch removes the libnftnl table list by linux list. This comes with an extra memory allocation to store the nft_table object. Probably, there is no need to cache the entire nftnl_table in the near future. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: Use nft_chain_find() in two more placesPhil Sutter2020-07-241-15/+14
| | | | | | | This doesn't really increase functions' readability but prepares for later changes. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Turn nft_chain_save() into a foreach-callbackPhil Sutter2020-07-241-35/+12
| | | | | | | | Let nftnl_chain_list_foreach() do the chain list iterating instead of open-coding it. While being at it, simplify the policy value selection code as well. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Drop pointless nft_xt_builtin_init() callPhil Sutter2020-07-241-2/+0
| | | | | | | When renaming a chain, either everything is in place already or the command will bail anyway. So just drop this superfluous call. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Be lazy when flushingPhil Sutter2020-07-241-2/+4
| | | | | | | | If neither chain nor verbose flag was specified and the table to flush doesn't exist yet, no action is needed (as there is nothing to flush anyway). Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Make table creation purely implicitPhil Sutter2020-07-241-14/+3
| | | | | | | | | | | | | | | | | | | While asserting a required builtin chain exists, its table is created implicitly if missing. Exploit this from xtables-restore, too: The only actions which need adjustment are chain_new and chain_restore, i.e. when restoring (either builtin or custom) chains. Note: The call to nft_table_builtin_add() wasn't sufficient as it doesn't set the table as initialized and therefore a following call to nft_xt_builtin_init() would override non-default base chain policies. Note2: The 'table_new' callback in 'nft_xt_restore_cb' is left in place as xtables-translate uses it to print an explicit 'add table' command. Note3: nft_table_new() function was already unused since a7f1e208cdf9c ("nft: split parsing from netlink commands"). Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Drop save_counters callback from family_opsPhil Sutter2020-05-181-2/+3
| | | | | | | All families use the same callback function, just fold it into the sole place it's called. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Merge nft_*_rule_find() functionsPhil Sutter2020-05-181-1/+40
| | | | | | | | | Both ebtables and arptables are fine with using nft_ipv46_rule_find() instead of their own implementations. Take the chance and move the former into nft.c as a static helper since it is used in a single place, only. Then get rid of the callback from family_ops. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Fix leak when replacing a rulePhil Sutter2020-05-111-1/+2
| | | | | | | | | | If nft_rule_append() is called with a reference rule, it is supposed to insert the new rule at the reference position and then remove the reference from cache. Instead, it removed the new rule from cache again right after inserting it. Also, it missed to free the removed rule. Fixes: 5ca9acf51adf9 ("xtables: Fix position of replaced rules in cache") Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Fix leak when deleting rulesPhil Sutter2020-05-111-1/+1
| | | | | | | For NFT_COMPAT_RULE_DELETE jobs, batch_obj_del() has to do the rule freeing, they are no longer in cache. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Fix leaks in ebt_add_policy_rule()Phil Sutter2020-05-111-6/+12
| | | | | | | | | | | | | | | | | | The function leaked memory allocated in temporary struct iptables_command_state, clean it immediately after use. In any of the udata-related error cases, allocated nftnl_rule would leak, fix this by introducing a common error path to goto. In regular code path, the allocated nftnl_rule would still leak: batch_obj_del() does not free rules in NFT_COMPAT_RULE_APPEND jobs, as they typically sit in cache as well. Policy rules in turn weren't added to cache: They are created immediately before commit and never referenced from other rules. Add them now so they are freed just like regular rules. Fixes: aff1162b3e4b7 ("ebtables-nft: Support user-defined chain policies") Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Clear all lists in nft_fini()Phil Sutter2020-05-111-3/+9
| | | | | | | | Remove and free any pending entries in obj_list and err_list as well. To get by without having to declare list-specific cursors, use generic list_head types and call list_entry() explicitly. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Fix for '-F' in iptables dumpsPhil Sutter2020-05-111-0/+34
| | | | | | | | | | | When restoring a dump which contains an explicit flush command, previously added rules are removed from cache and the following commit will try to create netlink messages based on freed memory. Fix this by weeding any rule-based commands from obj_list if they address the same chain. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: cache: Optimize caching for flush commandPhil Sutter2020-05-111-0/+6
| | | | | | | | | | | | | | | | | | When flushing all chains and verbose mode is not enabled, nft_rule_flush() uses a shortcut: It doesn't specify a chain name for NFT_MSG_DELRULE, so the kernel will flush all existing chains without user space needing to know which they are. The above allows to avoid a chain cache, but there's a caveat: nft_xt_builtin_init() will create base chains as it assumes they are missing and thereby possibly overrides any non-default chain policies. Solve this by making nft_xt_builtin_init() cache-aware: If a command doesn't need a chain cache, there's no need to bother with creating any non-existing builtin chains, either. For the sake of completeness, also do nothing if cache is not initialized (although that shouldn't happen). Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: cache: Fetch cache for specific chainsPhil Sutter2020-05-111-0/+1
| | | | | | | | | | | | | | | | | Iterate over command list and collect chains to cache. Insert them into a sorted list to pass to __nft_build_cache(). If a command is interested in all chains (e.g., --list), cmd->chain remains unset. To record this case reliably, use a boolean ('all_chains'). Otherwise, it is hard to distinguish between first call to nft_cache_level_set() and previous command with NULL cmd->chain value. When caching only specific chains, manually add builtin ones for the given table as well - otherwise nft_xt_builtin_init() will act as if they don't exist and possibly override non-default chain policies. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft-cache: Fetch cache per tablePhil Sutter2020-05-111-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | Restore per-table operation of cache routines as initially implemented in commit e2883c5531e6e ("nft-cache: Support partial cache per table"). As before, this doesn't limit fetching of tables (their number is supposed to be low) but instead limits fetching of sets, chains and rules to the specified table. For this to behave correctly when restoring without flushing over multiple tables, cache must be freed fully after each commit - otherwise the previous table's cache level is reused for the current one. The exception being fake cache, used for flushing restore: NFT_CL_FAKE is set just once at program startup, so it must stay set otherwise consecutive tables cause pointless cache fetching. The sole use-case requiring a multi-table cache, iptables-save, is indicated by req->table being NULL. Therefore, req->table assignment is a bit sloppy: All calls to nft_cache_level_set() are assumed to set the same table value, collision detection exists merely to catch programming mistakes. Make nft_fini() call nft_release_cache() instead of flush_chain_cache(), the former does a full cache deinit including cache_req contents. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: remove cache build callsPablo Neira Ayuso2020-05-111-21/+0
| | | | | | | | | The cache requirements are now calculated once from the parsing phase. There is no need to call __nft_build_cache() from several spots in the codepath anymore. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: restore among supportPablo Neira Ayuso2020-05-111-0/+15
| | | | | | | Update among support to work again with the new parser and cache logic. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: calculate cache requirements from list of commandsPablo Neira Ayuso2020-05-111-2/+15
| | | | | | | | | | | | | | | | | | | | This patch uses the new list of commands to calculate the cache requirements, the rationale after this updates is the following: #1 Parsing, that builds the list of commands and it also calculates cache level requirements. #2 Cache building. #3 Translate commands to jobs #4 Translate jobs to netlink This patch removes the pre-parsing code in xtables-restore.c to calculate the cache. After this patch, cache is calculated only once, there is no need to cancel and refetch for an in-transit transaction. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: split parsing from netlink commandsPablo Neira Ayuso2020-05-111-59/+199
| | | | | | | | | | | | | | This patch updates the parser to generate a list of command objects. This list of commands is then transformed to a list of netlink jobs. This new command object stores the rule using the nftnl representation via nft_rule_new(). To reduce the number of updates in this patch, the nft_*_rule_find() functions have been updated to restore the native representation to skip the update of the rule comparison code. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Phil Sutter <phil@nwl.cc>
* ebtables-restore: Drop custom table flush routinePhil Sutter2020-05-111-21/+0
| | | | | | | | At least since flushing xtables-restore doesn't fetch chains from kernel anymore, problems with pending policy rule delete jobs can't happen anymore. Signed-off-by: Phil Sutter <phil@nwl.cc>
* xtables: Review nft_init()Phil Sutter2020-02-241-1/+8
| | | | | | | | | | | | | | | | | Move common code into nft_init(), such as: * initial zeroing nft_handle fields * family ops lookup and assignment to 'ops' field * setting of 'family' field This requires minor adjustments in xtables_restore_main() so extra field initialization doesn't happen before nft_init() call. As a side-effect, this fixes segfaulting xtables-monitor binary when printing rules for trace event as in that code-path 'ops' field wasn't initialized. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: Drop pointless assignmentPhil Sutter2020-02-181-1/+0
| | | | | | | | No need to set 'i' to zero here, it is not used before the next assignment. Fixes: 77e6a93d5c9dc ("xtables: add and set "implict" flag on transaction objects") Signed-off-by: Phil Sutter <phil@nwl.cc>
* ebtables: among: Support mixed MAC and MAC/IP entriesPhil Sutter2020-02-181-1/+19
| | | | | | | | | | | | | | Powered by Stefano's support for concatenated ranges, a full among match replacement can be implemented. The trick is to add MAC-only elements as a concatenation of MAC and zero-length prefix, i.e. a range from 0.0.0.0 till 255.255.255.255. Although not quite needed, detection of pure MAC-only matches is left in place. For those, no implicit 'meta protocol' match is added (which is required otherwise at least to keep nft output correct) and no concat type is used for the set. Signed-off-by: Phil Sutter <phil@nwl.cc>
* nft: bridge: Rudimental among extension supportPhil Sutter2019-11-251-0/+149
| | | | | | | | | Support among match as far as possible given the limitations of nftables sets, namely limited to homogeneous MAC address only or MAC and IP address only matches. Signed-off-by: Phil Sutter <phil@nwl.cc> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: Support parsing lookup expressionPhil Sutter2019-11-251-1/+2
| | | | | | | | Add required glue code to support family specific lookup expression parsers implemented as family_ops callback. Signed-off-by: Phil Sutter <phil@nwl.cc> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: Support NFT_COMPAT_SET_ADDPhil Sutter2019-11-251-0/+58
| | | | | | | | Implement the required infrastructure to create sets as part of a batch job commit. Signed-off-by: Phil Sutter <phil@nwl.cc> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: Eliminate pointless calls to nft_family_ops_lookup()Phil Sutter2019-11-251-10/+5
| | | | | | | | | If nft_handle is available, use its 'ops' field instead of performing a new lookup. For the same reason, there is no need to pass ops pointer to __nft_print_header(). Signed-off-by: Phil Sutter <phil@nwl.cc> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: family_ops: Pass nft_handle to 'rule_to_cs' callbackPhil Sutter2019-11-251-10/+8
| | | | | | | | | | | This is the actual callback used to parse nftables rules. Pass nft_handle to it so it can access the cache (and possible sets therein). Having to pass nft_handle to nft_rule_print_save() allows to simplify it a bit since no family ops lookup has to be done anymore. Signed-off-by: Phil Sutter <phil@nwl.cc> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: family_ops: Pass nft_handle to 'print_rule' callbackPhil Sutter2019-11-251-9/+10
| | | | | | | | Prepare for 'rule_to_cs' callback to receive nft_handle pointer so it is able to access cache for set lookups. Signed-off-by: Phil Sutter <phil@nwl.cc> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: family_ops: Pass nft_handle to 'rule_find' callbackPhil Sutter2019-11-251-1/+1
| | | | | | | | | In order to prepare for rules containing set references, nft handle has to be passed to nft_rule_to_iptables_command_state() in order to let it access the set in cache. Signed-off-by: Phil Sutter <phil@nwl.cc> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: family_ops: Pass nft_handle to 'add' callbackPhil Sutter2019-11-251-2/+3
| | | | | | | | | In order for add_match() to create anonymous sets when converting xtables matches it needs access to nft handle. So pass it along from callers of family ops' add callback. Signed-off-by: Phil Sutter <phil@nwl.cc> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: Fix -Z for rules with NFTA_RULE_COMPATPhil Sutter2019-11-151-0/+39
| | | | | | | | | | | | | | | | | | | | | The special nested attribute NFTA_RULE_COMPAT holds information about any present l4proto match (given via '-p' parameter) in input. The match is contained as meta expression as well, but some xtables extensions explicitly check it's value (see e.g. xt_TPROXY). This nested attribute is input only, the information is lost after parsing (and initialization of compat extensions). So in order to feed a rule back to kernel with zeroed counters, the attribute has to be reconstructed based on the rule's expressions. Other code paths are not affected since rule_to_cs() callback will populate respective fields in struct iptables_command_state and 'add' callback (which is the inverse to rule_to_cs()) calls add_compat() in any case. Signed-off-by: Phil Sutter <phil@nwl.cc> Reviewed-by: Florian Westphal <fw@strlen.de> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>