summaryrefslogtreecommitdiffstats
path: root/tests/shell/testcases
Commit message (Collapse)AuthorAgeFilesLines
* tests: shell: Update packetpath/flowtablesYi Chen2025-04-221-27/+50
| | | | | | | | | | | | 1. The socat receiver should not use the pipfile as output where the sender reads data from, this could create an infinite data loop. 2. Sending a packet right after establishing the connection helped uncover a new bug (see kernel commit d2d31ea8cd80, "netfilter: conntrack: fix erronous removal of offload bit"). 3. Optimize test log output Signed-off-by: Yi Chen <yiche@redhat.com> Signed-off-by: Florian Westphal <fw@strlen.de>
* netlink: bogus concatenated set ranges with netlink message overrunPablo Neira Ayuso2025-04-212-0/+741
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When building each component of the set element key, a late byteorder switch is performed to ensure that all components in the interval are represented in big endian, as required by the pipapo backend. In case that the set element does not fit into the netlink message, the byteorder switch happens twice, leading to inserting an element with a bogus component with large sets, so instead: "lo" . 00:11:22:33:44:55 . 10.1.2.3 comment "123456789012345678901234567890" listing reports: 16777216 . 00:11:22:33:44:55 . 10.1.2.3 comment "123456789012345678901234567890" Note that 16777216 is 0x1000000, which should instead be 0x00000001 to represent "lo" as u32. Fix this by switching the value in a temporary variable and use it to set the set element key attribute in the netlink message. Later, revisit this to perform this byteorder switch from evaluation step. Add tests/shell unit to cover for this bug. Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1792 Fixes: 8ac2f3b2fca3 ("src: Add support for concatenated set ranges") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evalute: make vlan pcp updates workFlorian Westphal2025-04-221-0/+2
| | | | | | | | | | | | | | | | On kernel side, nft_payload_set_vlan() requires a 2 or 4 byte write to the vlan header. As-is, nft emits a 1 byte write: [ payload load 1b @ link header + 14 => reg 1 ] [ bitwise reg 1 = ( reg 1 & 0x0000001f ) ^ 0x00000020 ] ... which the kernel doesn't support. Expand all vlan header updates to a 2 or 4 byte write and update the existing vlan id test case. Reported-by: Kevin Vigouroux <ke.vigouroux@laposte.net> Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
* parser_bison: add selector_expr rule to restrict typeof_exprPablo Neira Ayuso2025-04-111-0/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | typeof_expr allows for symbol, constant and bitwise expressions, restrict it to selector expressions. After this patch, input generated by fuzzer is rejected upfront: # nft -f test.nft test.nft:3:53-53: Error: syntax error, unexpected number typeof numgen inc mod 2 : ip daddr . 0 ^ test.nft:2:12-13: Error: set definition does not specify key map t2 { ^^ test.nft:8:65-67: Error: No such file or directory meta l4proto tcp dnat ip to numgen inc mod 2 map @t2 ^^^ test.nft:8:65-67: Error: No such file or directory meta l4proto tcp dnat ip to numgen inc mod 2 map @t2 ^^^ Revisit 4ab1e5e60779 ("src: allow use of 'verdict' in typeof definitions") to handle verdict as string, later a token can be added to the scanner and enable it via flex start conditions. Fixes: 14357cff40ed ("parser: add typeof keyword for declarations") Reported-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: invalidate merge in case of duplicated key in set/mapPablo Neira Ayuso2025-04-091-0/+40
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | -o/--optimize results in EEXIST error when merging two rules that lead to ambiguous set/map, for instance: table ip x { chain v4icmp {} chain v4icmpc {} chain y { ip protocol icmp jump v4icmp ip protocol icmp goto v4icmpc } } which is not possible because duplicated keys are not possible in set/map. This is how it shows when running a test: Merging: testcases/sets/dumps/sets_with_ifnames.nft:56:3-30: ip protocol icmp jump v4icmp testcases/sets/dumps/sets_with_ifnames.nft:57:3-31: ip protocol icmp goto v4icmpc into: ip protocol vmap { icmp : jump v4icmp, icmp : goto v4icmpc } internal:0:0-0: Error: Could not process rule: File exists Add a new step to compare rules that are candidate to be merged to detect colissions in set/map keys in order to skip them in the next final merging step. Add tests/shell unit to improve coverage. Fixes: fb298877ece2 ("src: add ruleset optimization infrastructure") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* parser_json: only allow concatenations with 2 or more expressionsFlorian Westphal2025-04-021-0/+26
| | | | | | | | | | | | | | | | | | | | | | | | | The bison parser enforces this implicitly by grammar rules. Because subkeys have to be conatenated via ".", notation, e.g. "mark . ip saddr", all concatenation expressions always consist of at least two elements. But this doesn't apply to the json frontend which just uses an array: it can be empty or only contain one element. The included reproducer makes the eval stage set the "concatenation" flag on the interval set. This prevents the needed conversion code to turn the element values into ranges from getting run. The reproducer asserts with: nft: src/intervals.c:786: setelem_to_interval: Assertion `key->etype == EXPR_RANGE_VALUE' failed. Convert the assertion to BUG() so we can see what element type got passed to the set interval code in case we have further issues in this area. Reject 0-or-1-element concatenations from the json parser. Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: fix crash when generating reject statement errorFlorian Westphal2025-04-021-0/+32
| | | | | | | | | | | After patch, this gets rejected with: internal:0:0-0: Error: conflicting protocols specified: ip vs ip6 Without patch, we crash with a NULL dereference: we cannot use reject.expr->location unconditionally. Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: expand expression list when merging into concatenationPablo Neira Ayuso2025-04-013-0/+64
| | | | | | | | | | | | | | | | | The following rules: udp dport 137 ct state new,untracked accept udp dport 138 ct state new,untracked accept results in: nft: src/optimize.c:670: __merge_concat: Assertion `0' failed. The logic to expand to the new,untracked list in the concatenation is missing. Fixes: 187c6d01d357 ("optimize: expand implicit set element when merging into concatenation") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* cache: don't crash when filter is NULLFlorian Westphal2025-04-011-0/+1
| | | | | | | | | a delete request will cause a crash in obj_cache_dump, move the deref into the filter block. Fixes: dbff26bfba83 ("cache: consolidate reset command") Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: only allow stateful statements in set and map definitionsFlorian Westphal2025-03-311-0/+34
| | | | | | | | | | | | | | | | The bison parser doesn't allow this to happen due to grammar restrictions, but the json input has no such issues. The bogon input assigns 'notrack' which triggers: BUG: unknown stateful statement type 19 nft: src/netlink_linearize.c:1061: netlink_gen_stmt_stateful: Assertion `0' failed. After patch, we get: Error: map statement must be stateful Fixes: 07958ec53830 ("json: add set statement list support") Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
* expression: don't try to import empty stringFlorian Westphal2025-03-311-0/+38
| | | | | | | | The bogon will trigger the assertion in mpz_import_data: src/expression.c:418: constant_expr_alloc: Assertion `(((len) + (8) - 1) / (8)) > 0' failed. Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
* json: fix error propagation when parsing binop lhs/rhsFlorian Westphal2025-03-311-0/+76
| | | | | | | | | | | | | | | | | | | | Malformed input returns NULL when decoding left/right side of binop. This causes a NULL dereference in expr_evaluate_binop; left/right must point to a valid expression. Fix this in the parser, else would have to sprinkle NULL checks all over the evaluation code. After fix, loading the bogon yields: internal:0:0-0: Error: Malformed object (too many properties): '{}'. internal:0:0-0: Error: could not decode binop rhs, '<<'. internal:0:0-0: Error: Invalid mangle statement value internal:0:0-0: Error: Parsing expr array at index 1 failed. internal:0:0-0: Error: Parsing command array at index 3 failed. Fixes: 0ac39384fd9e ("json: Accept more than two operands in binary expressions") Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: shell: Fix owner/0002-persist on aarch64Phil Sutter2025-03-281-1/+2
| | | | | | | | | | | Not sure if arch-specific, but for some reason src/nft wrapper script would call src/.libs/lt-nft and thus the owner appeared as 'lt-nft' instead of the expected 'nft'. Cover for that by extracting the expected program name from /proc. Fixes: b5205165bd708 ("tests: shell: Extend table persist flag test a bit") Signed-off-by: Phil Sutter <phil@nwl.cc> Acked-by: Florian Westphal <fw@strlen.de>
* tests: shell: Add socat availability feature testPhil Sutter2025-03-286-15/+8
| | | | | | | | | | | Several tests did this manually and skipped if unavail, others just implicitly depended on the tool. Note that for the sake of simplicity, this will skip packetpath/tcp_options test entirely when it did a partial run before. Signed-off-by: Phil Sutter <phil@nwl.cc> Reviewed-by: Florian Westphal <fw@strlen.de>
* json: disallow empty concatenationPablo Neira Ayuso2025-03-271-0/+27
| | | | | | | | | | | | Disallow empty concatenation in set declaration in json. internal:0:0-0: Error: Empty concatenation internal:0:0-0: Error: Invalid set type. internal:0:0-0: Error: Parsing command array at index 1 failed. Joint work with Florian Westphal. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: compact bitmask matching in set/mapPablo Neira Ayuso2025-03-272-0/+40
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Check if right hand side of relational is a bitmask, ie. relational / \ ... or / \ value or / \ value value then, if left hand side is a binop expression, compare left and right hand sides (not only left hand of this binop expression) to check for redundant matches in consecutive rules, ie. relational / \ and ... / \ payload value before this patch, only payload in the binop expression was compared. This allows to compact several rules matching tcp flags in a set/map, eg. # nft -c -o -f ruleset.nft Merging: ruleset.nft:7:17-76: tcp flags & (fin | syn | rst | ack | urg) == fin | ack | urg ruleset.nft:8:17-70: tcp flags & (fin | syn | rst | ack | urg) == fin | ack ruleset.nft:9:17-64: tcp flags & (fin | syn | rst | ack | urg) == fin ruleset.nft:10:17-70: tcp flags & (fin | syn | rst | ack | urg) == syn | ack ruleset.nft:11:17-64: tcp flags & (fin | syn | rst | ack | urg) == syn ruleset.nft:12:17-70: tcp flags & (fin | syn | rst | ack | urg) == rst | ack ruleset.nft:13:17-64: tcp flags & (fin | syn | rst | ack | urg) == rst ruleset.nft:14:17-70: tcp flags & (fin | syn | rst | ack | urg) == ack | urg ruleset.nft:15:17-64: tcp flags & (fin | syn | rst | ack | urg) == ack into: tcp flags & (fin | syn | rst | ack | urg) == { fin | ack | urg, fin | ack, fin, syn | ack, syn, rst | ack, rst, ack | urg, ack } Merging: ruleset.nft:17:17-61: tcp flags & (ack | urg) == ack jump ack_chain ruleset.bft:18:17-61: tcp flags & (ack | urg) == urg jump urg_chain into: tcp flags & (ack | urg) vmap { ack : jump ack_chain, urg : jump urg_chain } Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* json: return error if table does not existFlorian Westphal2025-03-271-0/+3
| | | | | | | | Identical bug and thus same fix as 853d3a2d3cbd ("rule: return error if table does not exist"), but this time for json. Signed-off-by: Florian Westphal <fw@strlen.de>
* tests: shell: missing ct count elements in new set_stmt testPablo Neira Ayuso2025-03-251-0/+4
| | | | | | | | | Add missing entries to dump file. Reported-by: Florian Westphal <fw@strlen.de> Fixes: 1f3d0b9cf9cc ("tests: shell: extend coverage for set element statements") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Florian Westphal <fw@strlen.de>
* evaluate: don't update cache for anonymous chainsFlorian Westphal2025-03-221-0/+8
| | | | | | | | | | | | Chain lookup needs a name, not a numerical id. After patch, loading bogon gives following errors: Error: No symbol type information a b index 1 10.1.26.a v2: Don't return an error, just make it a no-op (Pablo Neira Ayuso) Fixes: c330152b7f77 ("src: support for implicit chain bindings") Signed-off-by: Florian Westphal <fw@strlen.de>
* json: make sure timeout list is initialisedFlorian Westphal2025-03-212-6/+83
| | | | | | | | | | On parser error, obj_free will iterate this list. Included json bogon crashes due to null deref because list head initialisation did not yet happen. Fixes: c82a26ebf7e9 ("json: Add ct timeout support") Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: shell: extend coverage for set element statementsPablo Neira Ayuso2025-03-212-0/+110
| | | | | | Add a test to cover the existing set element statements. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: fix assertion failure with malformed map definitionsFlorian Westphal2025-03-201-0/+6
| | | | | | | | | | | | | | | | | Included bogon triggers: nft: src/evaluate.c:2267: expr_evaluate_mapping: Assertion `set->data != NULL' failed. After this fix, following errors will be shown: Error: unqualified type invalid specified in map definition. Try "typeof expression" instead of "type datatype". map m { ^ map m { ^ Error: map has no mapping data Fixes: 343a51702656 ("src: store expr, not dtype to track data in sets") Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
* rule: return error if table does not existFlorian Westphal2025-03-201-0/+3
| | | | | | | | | | | | | The bogon triggers segfault due to NULL dereference. Error out and set errno to ENOENT; caller uses strerror() in the errmsg. After fix, loading reproducer results in: /tmp/A:2:1-18: Error: Could not process rule: No such file or directory list table inet p ^^^^^^^^^^^^^^^^^^ Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: don't allow nat map with specified protocolFlorian Westphal2025-03-201-0/+5
| | | | | | | | | | | | | | | Included bogon asserts: src/netlink_linearize.c:1305: netlink_gen_nat_stmt: Assertion `stmt->nat.proto == NULL' failed. The comment right above the assertion says: nat_stmt evaluation step doesn't allow STMT_NAT_F_CONCAT && stmt->nat.proto. ... except it does allow it. Disable this. Fixes: c68314dd4263 ("src: infer NAT mapping with concatenation from set") Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
* expression: tolerate named set protocol dependencyFlorian Westphal2025-03-203-0/+91
| | | | | | | | | | | | | | | | | | Included test will fail with: /dev/stdin:8:38-52: Error: Transparent proxy support requires transport protocol match meta l4proto @protos tproxy to :1088 ^^^^^^^^^^^^^^^ Tolerate a set reference too. Because the set can be empty (or there can be removals later), add a fake 0-rhs value. This will make pctx_update assign proto_unknown as the transport protocol in use, Thats enough to avoid 'requires transport protocol' error. v2: restrict it to meta lhs for now (Pablo Neira Ayuso) Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1686 Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
* parser_bison: reject non-serializeable typeof expressionsFlorian Westphal2025-03-201-0/+7
| | | | | | | | | | | | | | | Included bogon asserts with: BUG: unhandled key type 13 nft: src/intervals.c:73: setelem_expr_to_range: Assertion `0' failed. This should be rejected at parser stage, but the check for udata support was only done on the first item in a concatenation. After fix, parser rejects this with: Error: primary expression type 'symbol' lacks typeof serialization Fixes: 6e48df5329ea ("src: add "typeof" build/parse/print support") Signed-off-by: Florian Westphal <fw@strlen.de>
* netlink: fix stack buffer overrun when emitting ranged expressionsFlorian Westphal2025-03-182-1/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Included bogon input generates following Sanitizer splat: AddressSanitizer: dynamic-stack-buffer-overflow on address 0x7... WRITE of size 2 at 0x7fffffffcbe4 thread T0 #0 0x0000003a68b8 in __asan_memset (src/nft+0x3a68b8) (BuildId: 3678ff51a5405c77e3e0492b9a985910efee73b8) #1 0x0000004eb603 in __mpz_export_data src/gmputil.c:108:2 #2 0x0000004eb603 in netlink_export_pad src/netlink.c:256:2 #3 0x0000004eb603 in netlink_gen_range src/netlink.c:471:2 #4 0x0000004ea250 in __netlink_gen_data src/netlink.c:523:10 #5 0x0000004e8ee3 in alloc_nftnl_setelem src/netlink.c:205:3 #6 0x0000004d4541 in mnl_nft_setelem_batch src/mnl.c:1816:11 Problem is that the range end is emitted to the buffer at the *padded* location (rounded up to next register size), but buffer sizing is based of the expression length, not the padded length. Also extend the test script: Capture stderr and if we see AddressSanitizer warning, make it fail. Same bug as the one fixed in 600b84631410 ("netlink: fix stack buffer overflow with sub-reg sized prefixes"), just in a different function. Apply same fix: no dynamic array + add a range check. Joint work with Pablo Neira Ayuso. Signed-off-by: Florian Westphal <fw@strlen.de>
* src: print set element with multi-word description in single one linePablo Neira Ayuso2025-03-1822-523/+1016
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If the set element: - represents a mapping - has a timeout - has a comment - has counter/quota/limit - concatenation (already printed in a single line before this patch) ie. if the set element requires several words, then print it in one single line. Before this patch: table ip x { set y { typeof ip saddr counter elements = { 192.168.10.35 counter packets 0 bytes 0, 192.168.10.101 counter packets 0 bytes 0, 192.168.10.135 counter packets 0 bytes 0 } } } After this patch: table ip x { set y { typeof ip saddr counter elements = { 192.168.10.35 counter packets 0 bytes 0, 192.168.10.101 counter packets 0 bytes 0, 192.168.10.135 counter packets 0 bytes 0 } } } Acked-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: move interval flag compat check after set key evaluationFlorian Westphal2025-03-181-0/+13
| | | | | | | | | | | | | | | Without this, included bogon asserts with: BUG: unhandled key type 13 nft: src/intervals.c:73: setelem_expr_to_range: Assertion `0' failed. ... because we no longer evaluate set->key/data. Move the check to the tail of the function, right before assiging set->existing_set, so that set->key has been evaluated. Fixes: ceab53cee499 ("evaluate: don't allow merging interval set/map with non-interval one") Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: don't allow merging interval set/map with non-interval oneFlorian Westphal2025-03-131-0/+12
| | | | | | | | | | | Included bogon asserts with: BUG: invalid data expression type range_value Pablo says: "Reject because flags interval is lacking". Make it so. Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: fix expression data corruptionFlorian Westphal2025-03-121-0/+2
| | | | | | | | | | | | | | | | | | | | | | | Sometimes nftables will segfault when doing error-unwind of the included afl-generated bogon. The problem is the unconditional write access to expr->set_flags in expr_evaluate_map(): mappings->set_flags |= NFT_SET_MAP; ... but mappings can point to EXPR_VARIABLE (legal), where this will flip a bit in unused, but allocated memory (i.e., has no effect). In case of the bogon, mapping is EXPR_RANGE_SYMBOL, and the store can flip a bit in identifier_range[1], this causes crash when the pointer is freed. We can't use expr->set_flags unconditionally, so rework this to pass set_flags as argument and place all read and write accesses in places where we've made sure we are dealing with EXPR_SET. Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: shell: skip interval size tests on kernel that lack rbtree size fixFlorian Westphal2025-03-122-0/+4
| | | | | | | Skip these tests for older kernels. Signed-off-by: Florian Westphal <fw@strlen.de> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: don't crash if range has same start and end intervalFlorian Westphal2025-03-103-0/+55
| | | | | | | | | | | | | | In this case, evaluation step replaces the range expression with a single value and we'd crash as range->left/right contain garbage values. Simply replace the input expression with the evaluation result. Also add a test case modeled on the afl reproducer. Fixes: fe6cc0ad29cd ("evaluate: consolidate evaluation of symbol range expression") Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: extend reset test case to cover interval set and map typeFlorian Westphal2025-03-071-10/+60
| | | | | | | Make sure segtree processing doesn't drop associated stateful elements. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* segtree: fix string data initialisationFlorian Westphal2025-03-071-0/+62
| | | | | | | | | | | | | | | | | | | | | | | | This uses the wrong length. This must re-use the length of the datatype, not the string length. The added test cases will fail without the fix due to erroneous overlap detection, which in itself is due to incorrect sorting of the elements. Example error: netlink: Error: interval overlaps with an existing one add element inet testifsets simple_wild { "2-1" } failed. table inet testifsets { ... elements = { "1-1", "abcdef*", "othername", "ppp0" } ... but clearly "2-1" doesn't overlap with any existing members. The false detection is because of the "acvdef*" wildcard getting sorted at the beginning of the list which is because its erronously initialised as a 64bit number instead of 128 bits (16 bytes / IFNAMSIZ). Fixes: 5e393ea1fc0a ("segtree: add string "range" reversal support") Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
* netlink_delinearize: also consider exthdr type when trimming binopsFlorian Westphal2025-03-062-0/+29
| | | | | | | | | | | | | | | | | | | | | | | | | This allows trimming the binop for exthdrs, this will make nft render (tcp option mptcp unknown & 240) >> 4 . ip saddr @s1 as tcp option mptcp subtype . ip saddr @s1 Also extend the typeof set tests with a set concatenating a sub-byte-sized exthdr expression with a payload one. The additional call to expr_postprocess() is needed, without this, typeof_sets_0.nft fails because frag frag-off @s4 accept is shown as meta nfproto ipv6 frag frag-off @s4 accept Previouly, EXPR_EXTHDR would cause payload_binop_postprocess() to return false which will then make the caller invoke expr_postprocess(), but after handling EXPR_EXTHDR this doesn't happen anymore. Signed-off-by: Florian Westphal <fw@strlen.de>
* tcpopt: add symbol table for mptcp suboptionsFlorian Westphal2025-03-062-0/+27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | nft can be used t match on specific multipath tcp subtypes: tcp option mptcp subtype 0 However, depending on which subtype to match, users need to look up the type/value to use in rfc8684. Add support for mnemonics and "nft describe tcp option mptcp subtype" to get the subtype list. Because the number of unique 'enum datatypes' is limited by ABI contraints this adds a new mptcp suboption type as integer alias. After this patch, nft supports all of the following: add element t s { mp-capable } add rule t c tcp option mptcp subtype mp-capable add rule t c tcp option mptcp subtype { mp-capable, mp-fail } For the 3rd case, listing will break because unlike for named sets, nft lacks the type information needed to pretty-print the integer values, i.e. nft will print the 3rd rule as 'subtype { 0, 6 }'. This is resolved in a followup patch. Other problematic constructs are: set s1 { typeof tcp option mptcp subtype . ip saddr elements = { mp-fail . 1.2.3.4 } } Followed by: tcp option mptcp subtype . ip saddr @s1 nft will print this as: tcp option mptcp unknown & 240) >> 4 . ip saddr @s1 All of these issues are not related to this patch, however, they also occur with other bit-sized extheader fields. Signed-off-by: Florian Westphal <fw@strlen.de>
* tests: remove temporary fileFlorian Westphal2025-03-061-2/+7
| | | | | | | | | 0002-relative leaves a temporary file in the current working directory, at the time the "trap" argument is expanded, tmpfile2 isn't set. Signed-off-by: Florian Westphal <fw@strlen.de> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: add atomic chain replace testFlorian Westphal2025-03-062-0/+73
| | | | | | | | | Add a test that replaces one base chain and check that no filtered packets make it through, i.e. that the 'old chain' doesn't disappear before new one is active. Acked-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Florian Westphal <fw@strlen.de>
* tests: shell: random interval set with sizePablo Neira Ayuso2025-02-261-0/+113
| | | | | | | Generate a random set with intervals to validate set size, try one that should fit and then subtract one to set size and retry. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: shell: interval sets with sizePablo Neira Ayuso2025-02-261-0/+42
| | | | | | | Exercise size in set with intervals (rbtree), including corner cases such as 0.0.0.0 and 255.255.255.255 (half-open interval). Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* fib: Change data type of fib oifname to "ifname"Xiao Liang2025-02-252-0/+2
| | | | | | | | | | | | | | | Change data type of fib oifname from "string" to "ifname", so that it can be matched against a set of ifnames: set x { type ifname } chain y { fib saddr oifname @x drop } Signed-off-by: Xiao Liang <shaw.leon@gmail.com> Signed-off-by: Florian Westphal <fw@strlen.de>
* tests: shell: delete netdev chain after testPablo Neira Ayuso2025-02-072-0/+3
| | | | | | | | | | This update is needed for kernel patch: ("netfilter: nf_tables: Tolerate chains with no remaining hooks") otherwise this hits DUMP FAILED in newer kernels. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: allow to re-use existing metered setFlorian Westphal2025-01-293-0/+136
| | | | | | | | | | | | | | | | | | | Blamed commit translates old meter syntax (which used to allocate an anonymous set) to dynamic sets. A side effect of this is that re-adding a meter rule after chain was flushed results in an error, unlike anonymous sets named sets are not impacted by the flush. Refine this: if a set of the same name exists and is compatible, then re-use it instead of returning an error. Also pick up the reproducer kindly provided by the reporter and place it in the shell test directory. Fixes: b8f8ddfff733 ("evaluate: translate meter into dynamic set") Reported-by: Yi Chen <yiche@redhat.com> Signed-off-by: Florian Westphal <fw@strlen.de>
* tests: shell: use mount --bind to change cgroupsv2 rootPablo Neira Ayuso2025-01-191-1/+3
| | | | | | | Instead of remount which fails with SKIP in one of my test boxes because cgroupsv2 rootfs is busy. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* rule: make cmd_free(NULL) validFlorian Westphal2025-01-081-0/+20
| | | | | | | | | | | | | | | | | | | | | | | bison uses cmd_free($$) as destructor, but base_cmd can set it to NULL, e.g. | ELEMENT set_spec set_block_expr { if (nft_cmd_collapse_elems(CMD_ADD, state->cmds, &$2, $3)) { handle_free(&$2); expr_free($3); $$ = NULL; // cmd set to NULL break; } $$ = cmd_alloc(CMD_ADD, CMD_OBJ_ELEMENTS, &$2, &@$, $3); expr_free(NULL) is legal, cmd_free() causes crash. So just allow this to avoid cluttering parser_bison.y with "if ($$)". Also add the afl-generated bogon input to the test files. Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: shell: add cgroupv2 socket match test caseFlorian Westphal2025-01-062-0/+143
| | | | | | | | | | | | | | This is a test case for nft_socket cgroupv2 matching, including support for matching inside a cgroupv2 mount space added in kernel commit 7f3287db6543 ("netfilter: nft_socket: make cgroupsv2 matching work with namespaces"). Test is thus run twice, once in the initial namespace and once with a changed cgroupv2 root. In case we can't create a cgroup or the 2nd half (unshared re-run) fails, indicate SKIP. Signed-off-by: Florian Westphal <fw@strlen.de>
* libnftables: include canonical path to avoid duplicatesPablo Neira Ayuso2025-01-022-0/+25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A recent commit adds base directory of -f/--filename to include paths by default to address a silly use of -I/--include to make this work: # nft -I /path/to -f /path/to/main.nft instead users can simply invoke: # nft -f /path/to/main.nft because /path/to/ is added at the end of the list of include paths. This example above assumes main.nft includes more files that are contained in /path/to/. However, globbing can cause duplicates after this recent update, eg. # cat test/main table inet test { chain test { include "include/*"; } } # nft -I /tmp/test/ -f test/main because /tmp/test and test/ twice refer to the same directory and both are added to the list of include path. Use realpath() to canonicalize include paths. Then, search and skip duplicated include paths. Fixes: 302e9f8b3a13 ("libnftables: add base directory of -f/--filename to include path") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: shell: add a test case for netdev ruleset flush + parallel link downFlorian Westphal2025-01-022-0/+48
| | | | | | | Test for bug added with kernel commit c03d278fdf35 ("netfilter: nf_tables: wait for rcu grace period on net_device removal") Signed-off-by: Florian Westphal <fw@strlen.de>
* src: allow binop expressions with variable right-hand operandsJeremy Sowden2024-12-0412-0/+114
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Hitherto, the kernel has required constant values for the `xor` and `mask` attributes of boolean bitwise expressions. This has meant that the right-hand operand of a boolean binop must be constant. Now the kernel has support for AND, OR and XOR operations with right-hand operands passed via registers, we can relax this restriction. Allow non-constant right-hand operands if the left-hand operand is not constant, e.g.: ct mark & 0xffff0000 | meta mark & 0xffff The kernel now supports performing AND, OR and XOR operations directly, on one register and an immediate value or on two registers, so we need to be able to generate and parse bitwise boolean expressions of this form. If a boolean operation has a constant RHS, we continue to send a mask-and-xor expression to the kernel. Add tests for {ct,meta} mark with variable RHS operands. JSON support is also included. This requires Linux kernel >= 6.13-rc. [ Originally posted as patch 1/8 and 6/8 which has been collapsed and simplified to focus on initial {ct,meta} mark support. Tests have been extracted from 8/8 including a tests/py fix to payload output due to incorrect output in original patchset. JSON support has been extracted from patch 7/8 --pablo] Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>