path: root/iptables/nft-cache.h
Commit message (Collapse)AuthorAgeFilesLines
* nft: cache: Sort chains on demand onlyPhil Sutter2021-04-061-0/+1
| | | | | | | | | Mandatory sorted insert of chains into cache significantly slows down restoring of large rulesets. Since the sorted list of user-defined chains is needed for listing and verbose output only, introduce nft_cache_sort_chains() and call it where needed. Signed-off-by: Phil Sutter <>
* nft: Introduce struct nft_chainPhil Sutter2020-12-211-2/+3
| | | | | | | | | 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 <>
* nft: cache: Move nft_chain_find() overPhil Sutter2020-12-211-0/+3
| | | | | | It is basically just a cache lookup, hence fits better in here. Signed-off-by: Phil Sutter <>
* nft: Implement nft_chain_foreach()Phil Sutter2020-12-211-2/+0
| | | | | | | | | | | | | | 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 <>
* nft: cache: Introduce nft_cache_add_chain()Phil Sutter2020-12-211-0/+3
| | | | | | | 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 <>
* nft: Eliminate table list from cachePhil Sutter2020-07-311-9/+0
| | | | | | | | | | | | | | 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 <>
* iptables: replace libnftnl table list by linux listPablo Neira Ayuso2020-07-271-1/+9
| | | | | | | | 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 <>
* nft-cache: Fetch cache per tablePhil Sutter2020-05-111-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | 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 <>
* nft: cache: Improve fake cache integrationPhil Sutter2020-05-111-1/+0
| | | | | | | | With NFT_CL_FAKE being highest cache level while at the same time __nft_build_cache() treating it equal to NFT_CL_TABLES, no special handling for fake cache is required anymore. Signed-off-by: Phil Sutter <>
* nft: remove cache build callsPablo Neira Ayuso2020-05-111-1/+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 <> Signed-off-by: Phil Sutter <>
* nft: calculate cache requirements from list of commandsPablo Neira Ayuso2020-05-111-0/+2
| | | | | | | | | | | | | | | | | | | | 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 <> Signed-off-by: Phil Sutter <>
* nft: Introduce NFT_CL_SETS cache levelPhil Sutter2019-11-251-0/+2
| | | | | | | | | | In order to support anonymous sets, introduce an intermediate cache level between NFT_CL_CHAINS and NFT_CL_RULES. Actually chains are not needed to fetch sets, but given that sets are only needed for rules, put it late to not slow down fetching chains. Signed-off-by: Phil Sutter <> Acked-by: Pablo Neira Ayuso <>
* nft: Optimize flushing all chains of a tablePhil Sutter2019-10-171-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | Leverage nftables' support for flushing all chains of a table by omitting NFTNL_RULE_CHAIN attribute in NFT_MSG_DELRULE payload. The only caveat is with verbose output, as that still requires to have a list of (existing) chains to iterate over. Apart from that, implementing this shortcut is pretty straightforward: Don't retrieve a chain list and just call __nft_rule_flush() directly which doesn't set above attribute if chain name pointer is NULL. A bigger deal is keeping rule cache consistent: Instead of just clearing rule list for each flushed chain, flush_rule_cache() is updated to iterate over all cached chains of the given table, clearing their rule lists if not called for a specific chain. While being at it, sort local variable declarations in nft_rule_flush() from longest to shortest and drop the loop-local 'chain_name' variable (but instead use 'chain' function parameter which is not used at that point). Signed-off-by: Phil Sutter <> Acked-by: Pablo Neira Ayuso <>
* nft-cache: Support partial rule cache per chainPhil Sutter2019-10-171-3/+3
| | | | | | | | | | | | | | | | | Accept an additional chain name pointer in __nft_build_cache() and pass it along to fetch only that specific chain and its rules. Enhance nft_build_cache() to take an optional nftnl_chain pointer to fetch rules for. Enhance nft_chain_list_get() to take an optional chain name. If cache level doesn't include chains already, it will fetch only the specified chain from kernel (if existing) and add that to table's chain list which is returned. This keeps operations for all chains of a table or a specific one within the same code path in nft.c. Signed-off-by: Phil Sutter <> Acked-by: Pablo Neira Ayuso <>
* nft: Extract cache routines into nft-cache.cPhil Sutter2019-10-101-0/+17
The amount of code dealing with caching only is considerable and hence deserves an own source file. Signed-off-by: Phil Sutter <> Acked-by: Pablo Neira Ayuso <>