summaryrefslogtreecommitdiffstats
path: root/src/optimize.c
Commit message (Collapse)AuthorAgeFilesLines
* optimize: limit statement is not supported yetPablo Neira Ayuso2022-06-231-12/+0
| | | | | | | | Revert support for limit statement, the limit statement is stateful and it applies a ratelimit per rule, transformation for merging rules with the limit statement needs to use anonymous sets with statements. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: assume verdict is same when rules have no verdictPablo Neira Ayuso2022-06-231-1/+2
| | | | Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: only merge OP_IMPLICIT and OP_EQ relationalPablo Neira Ayuso2022-06-231-0/+10
| | | | | | Add test to cover this case. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: add unsupported statementPablo Neira Ayuso2022-06-231-4/+52
| | | | | | | | | | | | | | | | Do not try to merge rules with unsupported statements. This patch adds a dummy unsupported statement which is included in the statement collection and the rule vs statement matrix. When looking for possible rule mergers, rules using unsupported statements are discarded, otherwise bogus rule mergers might occur. Note that __stmt_type_eq() already returns false for unsupported statements. Add a test using meta mark statement, which is not yet supported. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: add hash expression supportPablo Neira Ayuso2022-06-231-0/+12
| | | | | | Extend expr_cmp() to compare hash expressions used in relational. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: add numgen expression supportPablo Neira Ayuso2022-06-231-0/+8
| | | | | | Extend expr_cmp() to compare numgen expressions used in relational. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: add binop expression supportPablo Neira Ayuso2022-06-231-0/+2
| | | | | | | Do recursive call using left expression in the binop expression tree to search for the primary expression. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: add fib expression supportPablo Neira Ayuso2022-06-231-0/+6
| | | | | | Extend expr_cmp() to compare fib expressions used in relational. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: add xfrm expression supportPablo Neira Ayuso2022-06-231-0/+6
| | | | | | Extend expr_cmp() to compare xfrm expressions used in relational. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: add osf expression supportPablo Neira Ayuso2022-06-231-0/+6
| | | | | | Extend expr_cmp() to compare osf expressions used in relational. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: fix verdict map mergingPablo Neira Ayuso2022-06-231-4/+7
| | | | | | | | | | Skip comparison when collecting the statement and building the rule vs statement matrix. Compare verdict type when merging rules. When infering rule mergers, honor the STMT_VERDICT with map (ie. vmap). Fixes: 561aa3cfa8da ("optimize: merge verdict maps with same lookup key") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: fix reject statementPablo Neira Ayuso2022-06-231-3/+16
| | | | | | | | Add missing code to the statement collection routine. Compare reject expressions when available. Add tests/shell. Fixes: fb298877ece2 ("src: add ruleset optimization infrastructure") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: remove comment after mergingPablo Neira Ayuso2022-06-231-0/+5
| | | | | | | | | Remove rule comment after merging rules, let the user decide if they want to reintroduce the comment in the ruleset file. Update optimizations/merge_stmt test. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: do not print stateful informationPablo Neira Ayuso2022-06-231-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | Do not print stateful information such as counters which are likely set to zero. Before this patch: Merging: packets.conf:10:3-29: ip protocol 4 counter drop packets.conf:11:3-29: ip protocol 41 counter drop packets.conf:12:3-29: ip protocol 47 counter drop into: ip protocol { 4, 41, 47 } counter packets 0 bytes 0 drop ^^^^^^^^^^^^^^^^^ After: Merging: packets.conf:10:3-29: ip protocol 4 counter drop packets.conf:11:3-29: ip protocol 41 counter drop packets.conf:12:3-29: ip protocol 47 counter drop into: ip protocol { 4, 41, 47 } counter drop Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: do not merge rules with set reference in rhsPablo Neira Ayuso2022-06-231-0/+10
| | | | | | | Otherwise set reference ends up included in an anonymous set, as an element, which is not supported. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: do not compare relational expression rhs when collecting statementsPablo Neira Ayuso2022-06-231-18/+21
| | | | | | | | | | | When building the statement matrix, do not compare expression right hand side, otherwise bogus mismatches might occur. The fully compared flag is set on when comparing rules to look for possible mergers. Fixes: 3f36cc6c3dcd ("optimize: do not merge unsupported statement expressions") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: segfault when releasing unsupported statementPablo Neira Ayuso2022-06-011-1/+1
| | | | | | | | | Call xfree() instead since stmt_alloc() does not initialize the statement type fields. Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1609 Fixes: ea1f1c9ff608 ("optimize: memleak in statement matrix") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: memleak in statement matrixPablo Neira Ayuso2022-05-041-0/+1
| | | | | | | Release clone object in case this statement is not supported. Fixes: 743b0e81371f ("optimize: do not clone unsupported statement") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: merge nat rules with same selectors into mapPablo Neira Ayuso2022-05-031-10/+194
| | | | | | | | | | | | | | | | | | | | | | | Verdict and nat are mutually exclusive, no need to support for this combination. # cat ruleset.nft table ip x { chain y { type nat hook postrouting priority srcnat; policy drop; ip saddr 1.1.1.1 tcp dport 8000 snat to 4.4.4.4:80 ip saddr 2.2.2.2 tcp dport 8001 snat to 5.5.5.5:90 } } # nft -o -c -f ruleset.nft Merging: ruleset.nft:4:3-52: ip saddr 1.1.1.1 tcp dport 8000 snat to 4.4.4.4:80 ruleset.nft:5:3-52: ip saddr 2.2.2.2 tcp dport 8001 snat to 5.5.5.5:90 into: snat to ip saddr . tcp dport map { 1.1.1.1 . 8000 : 4.4.4.4 . 80, 2.2.2.2 . 8001 : 5.5.5.5 . 90 } Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: do not clone unsupported statementPablo Neira Ayuso2022-05-031-1/+1
| | | | | | | | Skip unsupported statements when building the statement matrix, otherwise clone remains uninitialized. Fixes: fb298877ece2 ("src: add ruleset optimization infrastructure") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: incorrect logic in verdict comparisonPablo Neira Ayuso2022-05-031-4/+6
| | | | | | | | Keep inspecting rule verdicts before assuming they are equal. Update existing test to catch this bug. Fixes: 1542082e259b ("optimize: merge same selector with different verdict into verdict map") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: Restore optimization for raw payload expressionsPablo Neira Ayuso2022-03-291-3/+0
| | | | | | | | This patch reverts d0f14b5337e7 ("optimize: do not merge raw payload expressions") after adding support for concatenation with variable length TYPE_INTEGER. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: do not assume log prefixPablo Neira Ayuso2022-03-041-3/+12
| | | | | | ... log prefix might not be present in log statements. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: do not merge unsupported statement expressionsPablo Neira Ayuso2022-03-031-0/+21
| | | | | | Only value, range, prefix, set and list are supported at this stage. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: incorrect assert() for unexpected expression typePablo Neira Ayuso2022-03-031-3/+3
| | | | | | | assert(1) is noop, this should be assert(0) instead. Fixes: 561aa3cfa8da ("optimize: merge verdict maps with same lookup key") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: more robust statement merge with vmapPablo Neira Ayuso2022-03-031-2/+16
| | | | | | | | | | | | | | Check expressions that are expected on the rhs rather than using a catch-all default case. Actually, lists and sets need to be their own routine, because this needs the set element key expression to be merged. This is a follow up to 99eb46969f3d ("optimize: fix vmap with anonymous sets"). Fixes: 1542082e259b ("optimize: merge same selector with different verdict into verdict map") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: fix vmap with anonymous setsPablo Neira Ayuso2022-03-031-2/+6
| | | | | | | | | | | | | | | | The following example ruleset crashes: table inet a { chain b { tcp dport { 1 } accept tcp dport 2-3 drop } } because handling for EXPR_SET is missing. Fixes: 1542082e259b ("optimize: merge same selector with different verdict into verdict map") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: do not merge raw payload expressionsPablo Neira Ayuso2022-01-261-0/+3
| | | | | | | | | | | Merging raw expressions results in a valid concatenation which throws: Error: can not use variable sized data types (integer) in concat expressions Disable merging raw expressions until this is supported by skipping raw expressions. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: check for payload base and offset when searching for mergersPablo Neira Ayuso2022-01-261-0/+4
| | | | | | Extend the existing checks to cover the payload base and offset. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: merge verdict maps with same lookup keyPablo Neira Ayuso2022-01-261-12/+93
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Merge two consecutive verdict maps with the same lookup key. For instance, merge the following: table inet x { chain filter_in_tcp { tcp dport vmap { 80 : accept, 81 : accept, 443 : accept, 931 : accept, 5001 : accept, 5201 : accept, } tcp dport vmap { 6800-6999 : accept, 33434-33499 : accept, } } } into: table inet x { chain filter_in_tcp { tcp dport vmap { 80 : accept, 81 : accept, 443 : accept, 931 : accept, 5001 : accept, 5201 : accept, 6800-6999 : accept, 33434-33499 : accept, } } } This patch updates statement comparison routine to inspect the verdict expression type to detect possible merger. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: add __expr_cmp()Pablo Neira Ayuso2022-01-261-46/+52
| | | | | | Add helper function to compare expression to allow for reuse. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: silence compiler warningsFlorian Westphal2022-01-151-1/+1
| | | | | | | | | | | | cache.c:504:22: warning: ‘chain’ may be used uninitialized in this function [-Wmaybe-uninitialized] cache.c:504:22: warning: ‘table’ may be used uninitialized in this function [-Wmaybe-uninitialized] erec.c:128:16: warning: ‘line’ may be used uninitialized in this function [-Wmaybe-uninitialized] optimize.c:524:9: warning: ‘line’ may be used uninitialized in this function [-Wmaybe-uninitialized] Fixes: 8ad4056e9182 ("erec: expose print_location() and line_location()") Fixes: afbd102211dc ("src: do not use the nft_cache_filter object from mnl.c") Fixes: fb298877ece2 ("src: add ruleset optimization infrastructure") Signed-off-by: Florian Westphal <fw@strlen.de>
* optimize: merge several selectors with different verdict into verdict mapPablo Neira Ayuso2022-01-151-1/+56
| | | | | | | | | | | | | Transform: ip saddr 1.1.1.1 ip daddr 2.2.2.2 accept ip saddr 2.2.2.2 ip daddr 3.3.3.3 drop into: ip saddr . ip daddr vmap { 1.1.1.1 . 2.2.2.2 : accept, 2.2.2.2 . 3.3.3.3 : drop } Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: merge same selector with different verdict into verdict mapPablo Neira Ayuso2022-01-151-15/+147
| | | | | | | | | | | | | Transform: ct state invalid drop ct state established,related accept into: ct state vmap { established : accept, related : accept, invalid : drop } Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: merge rules with same selectors into a concatenationPablo Neira Ayuso2022-01-151-1/+43
| | | | | | | | | | | | | | | | | This patch extends the ruleset optimization infrastructure to collapse several rules with the same selectors into a concatenation. Transform: meta iifname eth1 ip saddr 1.1.1.1 ip daddr 2.2.2.3 accept meta iifname eth1 ip saddr 1.1.1.2 ip daddr 2.2.2.5 accept meta iifname eth2 ip saddr 1.1.1.3 ip daddr 2.2.2.6 accept into: meta iifname . ip saddr . ip daddr { eth1 . 1.1.1.1 . 2.2.2.6, eth1 . 1.1.1.2 . 2.2.2.5 , eth1 . 1.1.1.3 . 2.2.2.6 } accept Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add ruleset optimization infrastructurePablo Neira Ayuso2022-01-151-0/+478
This patch adds a new -o/--optimize option to enable ruleset optimization. You can combine this option with the dry run mode (--check) to review the proposed ruleset updates without actually loading the ruleset, e.g. # nft -c -o -f ruleset.test Merging: ruleset.nft:16:3-37: ip daddr 192.168.0.1 counter accept ruleset.nft:17:3-37: ip daddr 192.168.0.2 counter accept ruleset.nft:18:3-37: ip daddr 192.168.0.3 counter accept into: ip daddr { 192.168.0.1, 192.168.0.2, 192.168.0.3 } counter packets 0 bytes 0 accept This infrastructure collects the common statements that are used in rules, then it builds a matrix of rules vs. statements. Then, it looks for common statements in consecutive rules which allows to merge rules. This ruleset optimization always performs an implicit dry run to validate that the original ruleset is correct. Then, on a second pass, it performs the ruleset optimization and add the rules into the kernel (unless --check has been specified by the user). From libnftables perspective, there is a new API to enable this feature: uint32_t nft_ctx_get_optimize(struct nft_ctx *ctx); void nft_ctx_set_optimize(struct nft_ctx *ctx, uint32_t flags); This patch adds support for the first optimization: Collapse a linear list of rules matching on a single selector into a set as exposed in the example above. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>