summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* src: add json support for last statementPablo Neira Ayuso2023-06-205-0/+49
| | | | | | | | | | This patch adds json support for the last statement, it works for me here. However, tests/py still displays a warning: any/last.t: WARNING: line 12: '{"nftables": [{"add": {"rule": {"family": "ip", "table": "test-ip4", "chain": "input", "expr": [{"last": {"used": 300000}}]}}}]}': '[{"last": {"used": 300000}}]' mismatches '[{"last": null}]' Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* cache: include set elements in "nft set list"Florian Westphal2023-06-192-7/+3
| | | | | | | | | | | | | | | | | Make "nft list sets" include set elements in listing by default. In nftables 1.0.0, "nft list sets" did not include the set elements, but with "--json" they were included. 1.0.1 and newer never include them. This causes a problem for people updating from 1.0.0 and relying on the presence of the set elements. Change nftables to always include the set elements. The "--terse" option is honored to get the "no elements" behaviour. Fixes: a1a6b0a5c3c4 ("cache: finer grain cache population for list commands") Link: https://marc.info/?l=netfilter&m=168704941828372&w=2 Signed-off-by: Florian Westphal <fw@strlen.de>
* tests: shell: bogus EBUSY errors in transactionsPablo Neira Ayuso2023-06-191-0/+121
| | | | | | | | | | | | | | | Make sure reference tracking during transaction update is correct by checking for bogus EBUSY error. For example, when deleting map with chain reference X, followed by a delete chain X command. This test is covering the following paths: - prepare + abort (via -c/--check option) - prepare + commit - release (when netns is destroyed) Reported-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: shell: add test case for chain-in-use-splatFlorian Westphal2023-06-161-0/+19
| | | | | | | | | | | | | | | | | | | WARNING [.]: at net/netfilter/nf_tables_api.c:1885 6.3.4-201.fc38.x86_64 #1 nft_immediate_destroy+0xc1/0xd0 [nf_tables] __nf_tables_abort+0x4b9/0xb20 [nf_tables] nf_tables_abort+0x39/0x50 [nf_tables] nfnetlink_rcv_batch+0x47c/0x8e0 [nfnetlink] nfnetlink_rcv+0x179/0x1a0 [nfnetlink] netlink_unicast+0x19e/0x290 This is because of chain->use underflow, at time destroy function is called, ->use has wrapped back to -1. Fixed via "netfilter: nf_tables: fix chain binding transaction logic". Signed-off-by: Florian Westphal <fw@strlen.de>
* tests: shell: fix spurious errors in terse listing in jsonPablo Neira Ayuso2023-06-111-1/+1
| | | | | | | Sometimes table handle becomes 192, which makes this test fail. Check for 192.168 instead to make sure terse listing works fine instead. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* exthdr: add boolean DCCP option matchingJeremy Sowden2023-06-0116-0/+445
| | | | | | | | | | Iptables supports the matching of DCCP packets based on the presence or absence of DCCP options. Extend exthdr expressions to add this functionality to nftables. Link: https://bugzilla.netfilter.org/show_bug.cgi?id=930 Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: extend tests for destroy commandFernando Fernandez Mancera2023-06-0118-0/+74
| | | | | | | | | Extend tests to cover destroy command for chains, flowtables, sets, maps. In addition rename a destroy command test for rules with a duplicated number. Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: permit use of constant values in set lookup keysFlorian Westphal2023-05-244-0/+37
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Something like: Given: set s { type ipv4_addr . ipv4_addr . inet_service .. } something like add rule ip saddr . 1.2.3.4 . 80 @s goto c1 fails with: "Error: Can't parse symbolic invalid expressions". This fails because the relational expression first evaluates the left hand side, so when concat evaluation sees '1.2.3.4' no key context is available. Check if the RHS is a set reference, and, if so, evaluate the right hand side. This sets a pointer to the set key in the evaluation context structure which then makes the concat evaluation step parse 1.2.3.4 and 80 as ipv4 address and 16bit port number. On delinearization, extend relop postprocessing to copy the datatype from the rhs (set reference, has proper datatype according to set->key) to the lhs (concat expression). Signed-off-by: Florian Westphal <fw@strlen.de>
* mnl: support bpf id decode in nft list hooksFlorian Westphal2023-05-222-3/+61
| | | | | | | | | | | This allows 'nft list hooks' to also display the bpf program id attached. Example: hook input { -0000000128 nf_hook_run_bpf id 6 .. Signed-off-by: Florian Westphal <fw@strlen.de>
* evaluate: set NFT_SET_EVAL flag if dynamic set already existsPablo Neira Ayuso2023-05-181-0/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | nft reports EEXIST when reading an existing set whose NFT_SET_EVAL has been previously inferred from the ruleset. # cat test.nft table ip test { set dlist { type ipv4_addr size 65535 } chain output { type filter hook output priority filter; policy accept; udp dport 1234 update @dlist { ip daddr } counter packets 0 bytes 0 } } # nft -f test.nft # nft -f test.nft test.nft:2:6-10: Error: Could not process rule: File exists set dlist { ^^^^^ Phil Sutter says: In the first call, the set lacking 'dynamic' flag does not exist and is therefore added to the cache. Consequently, both the 'add set' command and the set statement point at the same set object. In the second call, a set with same name exists already, so the object created for 'add set' command is not added to cache and consequently not updated with the missing flag. The kernel thus rejects the NEWSET request as the existing set differs from the new one. Set on the NFT_SET_EVAL flag if the existing set sets it on. Fixes: 8d443adfcc8c1 ("evaluate: attempt to set_eval flag if dynamic updates requested") Tested-by: Eric Garver <eric@garver.life> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* datatype: add hint error handlerPablo Neira Ayuso2023-05-112-2/+40
| | | | | | | | | | | | | | | | | | | | | | | If user provides a symbol that cannot be parsed and the datatype provides an error handler, provide a hint through the misspell infrastructure. For instance: # cat test.nft table ip x { map y { typeof ip saddr : verdict elements = { 1.2.3.4 : filter_server1 } } } # nft -f test.nft test.nft:4:26-39: Error: Could not parse netfilter verdict; did you mean `jump filter_server1'? elements = { 1.2.3.4 : filter_server1 } ^^^^^^^^^^^^^^ While at it, normalize error to "Could not parse symbolic %s expression". Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* datatype: misspell support with symbol table parser for error reportingPablo Neira Ayuso2023-05-111-2/+48
| | | | | | | | | | | | | | | | | | Some datatypes provide a symbol table that is parsed as an integer. Improve error reporting by using the misspell infrastructure, to provide a hint to the user, whenever possible. If base datatype, usually the integer datatype, fails to parse the symbol, then try a fuzzy match on the symbol table to provide a hint in case the user has mistype it. For instance: test.nft:3:11-14: Error: Could not parse Differentiated Services Code Point expression; did you you mean `cs0`? ip dscp ccs0 ^^^^ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: do not remove counter in verdict mapsPablo Neira Ayuso2023-05-103-7/+51
| | | | | | | | | | | | | Add counter to set element instead of dropping it: # nft -c -o -f test.nft Merging: test.nft:6:3-50: ip saddr 1.1.1.1 ip daddr 2.2.2.2 counter accept test.nft:7:3-48: ip saddr 1.1.1.2 ip daddr 3.3.3.3 counter drop into: ip daddr . ip saddr vmap { 2.2.2.2 . 1.1.1.1 counter : accept, 3.3.3.3 . 1.1.1.2 counter : drop } Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: skip optimization if anonymous set uses stateful statementPablo Neira Ayuso2023-05-103-1/+5
| | | | | | | | fee6bda06403 ("evaluate: remove anon sets with exactly one element") introduces an optimization to remove use of sets with single element. Skip this optimization if set element contains stateful statements. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: allow stateful statements with anonymous verdict mapsPablo Neira Ayuso2023-05-103-3/+4
| | | | | | | | | | | | | | Evaluation fails to accept stateful statements in verdict maps, relax the following check for anonymous sets: test.nft:4:29-35: Error: missing statement in map declaration ip saddr vmap { 127.0.0.1 counter : drop, * counter : accept } ^^^^^^^ The existing code generates correctly the counter in the anonymous verdict map. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* netlink: restore typeof interval map data typeFlorian Westphal2023-05-022-3/+8
| | | | | | | | | | | | | When "typeof ... : interval ..." gets used, existing logic failed to validate the expressions. "interval" means that kernel reserves twice the size, so consider this when validating and restoring. Also fix up the dump file of the existing test case to be symmetrical. Signed-off-by: Florian Westphal <fw@strlen.de>
* doc: add nat examplesFlorian Westphal2023-05-021-2/+51
| | | | | | | | | | | | | | nftables nat is much more capable than what the existing documentation describes. In particular, nftables can fully emulate iptables NETMAP target and can perform n:m address mapping. Add a new example section extracted from commit log messages when those features got added. Cc: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Florian Westphal <fw@strlen.de>
* doc: list set/map flag keywords in a tableFlorian Westphal2023-05-021-3/+18
| | | | | | add descriptions of the set/map flags. Signed-off-by: Florian Westphal <fw@strlen.de>
* meta: introduce meta broute supportSriram Yagnaraman2023-04-297-1/+31
| | | | | | | | | | | Can be used in bridge prerouting hook to divert a packet to the ip stack for routing. This is a replacement for "ebtables -t broute" functionality. Link: https://patchwork.ozlabs.org/project/netfilter-devel/patch/20230224095251.11249-1-sriram.yagnaraman@est.tech/ Signed-off-by: Sriram Yagnaraman <sriram.yagnaraman@est.tech> Signed-off-by: Florian Westphal <fw@strlen.de>
* doc: correct NAT statement descriptionJeremy Sowden2023-04-291-1/+1
| | | | | | | | Specifying a port specifies that a port, not an address, should be modified. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
* json: formatting fixesJeremy Sowden2023-04-291-21/+20
| | | | | | | A few indentation tweaks for the JSON parser. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
* src: fix enum/integer mismatchesFlorian Westphal2023-04-294-5/+5
| | | | | | | | | | | | | | | | | | | gcc 13 complains about type confusion: cache.c:1178:5: warning: conflicting types for 'nft_cache_update' due to enum/integer mismatch; have 'int(struct nft_ctx *, unsigned int, struct list_head *, const struct nft_cache_filter *)' [-Wenum-int-mismatch] cache.h:74:5: note: previous declaration of 'nft_cache_update' with type 'int(struct nft_ctx *, enum cmd_ops, struct list_head *, const struct nft_cache_filter *)' Same for: rule.c:1915:13: warning: conflicting types for 'obj_type_name' due to enum/integer mismatch; have 'const char *(enum stmt_types)' [-Wenum-int-mismatch] 1915 | const char *obj_type_name(enum stmt_types type) | ^~~~~~~~~~~~~ expression.c:1543:24: warning: conflicting types for 'expr_ops_by_type' due to enum/integer mismatch; have 'const struct expr_ops *(uint32_t)' {aka 'const struct expr_ops *(unsigned int)'} [-Wenum-int-mismatch] 1543 | const struct expr_ops *expr_ops_by_type(uint32_t value) | ^~~~~~~~~~~~~~~~ Convert to the stricter type (enum) where possible. Signed-off-by: Florian Westphal <fw@strlen.de>
* tests: py: missing json updates on ct and meta mark payload expressionPablo Neira Ayuso2023-04-251-0/+59
| | | | | | | Add json output, it is missing in the original tests/py update. Fixes: 8221d86e616b ("tests: py: add test-cases for ct and packet mark payload expressions") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* mnl: incomplete extended error reporting for singleton device in chainPablo Neira Ayuso2023-04-251-0/+1
| | | | | | | | | | | Fix error reporting when single device is specifies in chain: # nft add chain netdev filter ingress '{ devices = { x }; }' add chain netdev filter ingress { devices = { x }; } ^ Fixes: a66b5ad9540d ("src: allow for updating devices on existing netdev chain") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* mnl: handle singleton element in netdevice setPablo Neira Ayuso2023-04-253-14/+40
| | | | | | | | expr_evaluate_set() turns sets with singleton element into value, nft_dev_add() expects a list of expression, so it crashes. Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1676 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* json: allow to specify comment on chainPablo Neira Ayuso2023-04-252-7/+20
| | | | | | Allow users to add a comment when declaring a chain. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* json: allow to specify comment on tablePablo Neira Ayuso2023-04-242-5/+18
| | | | | | | | | | | | | | | | | | | | Allow users to add a comment when declaring a table: # sudo nft add table inet test3 '{comment "this is a comment";}' # nft list ruleset table inet test3 { comment "this is a comment" } # nft -j list ruleset {"nftables": [{"metainfo": {"version": "1.0.7", "release_name": "Old Doc Yak", "json_schema_version": 1}}, {"table": {"family": "inet", "name": "test3", "handle": 3, "comment": "this is a comment"}}]} # nft -j list ruleset > test.json # nft flush ruleset # nft -j -f test.json # nft -j list ruleset {"nftables": [{"metainfo": {"version": "1.0.7", "release_name": "Old Doc Yak", "json_schema_version": 1}}, {"table": {"family": "inet", "name": "test3", "handle": 4, "comment": "this is a comment"}}]} Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1670 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* meta: skip protocol context update for nfproto with same table familyPablo Neira Ayuso2023-04-241-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Inefficient bytecode crashes ruleset listing: [ meta load nfproto => reg 1 ] [ cmp eq reg 1 0x00000002 ] <-- this specifies NFPROTO_IPV4 but table family is IPv4! [ payload load 4b @ network header + 12 => reg 1 ] [ cmp gte reg 1 0x1000000a ] [ cmp lte reg 1 0x1f00000a ] [ masq ] This IPv4 table obviously only see IPv4 traffic, but bytecode specifies a redundant match on NFPROTO_IPV4. After this patch, listing works: # nft list ruleset table ip crash { chain crash { type nat hook postrouting priority srcnat; policy accept; ip saddr 10.0.0.16-10.0.0.31 masquerade } } Skip protocol context update in case that this information is redundant. Fixes: https://bugzilla.netfilter.org/show_bug.cgi?id=1562 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: bail out if new flowtable does not specify hook and priorityPablo Neira Ayuso2023-04-242-1/+7
| | | | | | | | | | | | | | | | | | | | If user forgets to specify the hook and priority and the flowtable does not exist, then bail out: # cat flowtable-incomplete.nft table t { flowtable f { devices = { lo } } } # nft -f /tmp/k flowtable-incomplete.nft:2:12-12: Error: missing hook and priority in flowtable declaration flowtable f { ^ Update one existing tests/shell to specify a hook and priority. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: allow for updating devices on existing netdev chainPablo Neira Ayuso2023-04-247-63/+140
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch allows you to add/remove devices to an existing chain: # cat ruleset.nft table netdev x { chain y { type filter hook ingress devices = { eth0 } priority 0; policy accept; } } # nft -f ruleset.nft # nft add chain netdev x y '{ devices = { eth1 }; }' # nft list ruleset table netdev x { chain y { type filter hook ingress devices = { eth0, eth1 } priority 0; policy accept; } } # nft delete chain netdev x y '{ devices = { eth0 }; }' # nft list ruleset table netdev x { chain y { type filter hook ingress devices = { eth1 } priority 0; policy accept; } } This feature allows for creating an empty netdev chain, with no devices. In such case, no packets are seen until a device is registered. This patch includes extended netlink error reporting: # nft add chain netdev x y '{ devices = { x } ; }' Error: Could not process rule: No such file or directory add chain netdev x y { devices = { x } ; } ^ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* mnl: flowtable support for extended netlink error reportingPablo Neira Ayuso2023-04-241-60/+82
| | | | | | | | | | | | | | | This patch extends existing flowtable support to improve error reporting: # nft add flowtable inet x y '{ devices = { x } ; }' Error: Could not process rule: No such file or directory add flowtable inet x y { devices = { x } ; } ^ # nft delete flowtable inet x y '{ devices = { x } ; }' Error: Could not process rule: No such file or directory delete flowtable inet x y { devices = { x } ; } ^ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* mnl: set SO_SNDBUF before SO_SNDBUFFORCEPablo Neira Ayuso2023-04-245-5/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Set SO_SNDBUF before SO_SNDBUFFORCE: Unpriviledged user namespace does not have CAP_NET_ADMIN on the host (user_init_ns) namespace. SO_SNDBUF always succeeds in Linux, always try SO_SNDBUFFORCE after it. Moreover, suggest the user to bump socket limits if EMSGSIZE after having see EPERM previously, when calling SO_SNDBUFFORCE. Provide a hint to the user too: # nft -f test.nft netlink: Error: Could not process rule: Message too long Please, rise /proc/sys/net/core/wmem_max on the host namespace. Hint: 4194304 bytes Dave Pfike says: Prior to this patch, nft inside a systemd-nspawn container was failing to install my ruleset (which includes a large-ish map), with the error netlink: Error: Could not process rule: Message too long strace reveals: setsockopt(3, SOL_SOCKET, SO_SNDBUFFORCE, [524288], 4) = -1 EPERM (Operation not permitted) This is despite the nspawn process supposedly having CAP_NET_ADMIN. A web search reveals at least one other user having the same issue: https://old.reddit.com/r/Proxmox/comments/scnoav/lxc_container_debian_11_nftables_geoblocking/ Reported-by: Dave Pifke <dave@pifke.org> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: shell: Fix for unstable sets/0043concatenated_ranges_0Phil Sutter2023-04-201-2/+2
| | | | | | | | | | | | | | On my (slow?) testing VM, The test tends to fail when doing a full run (i.e., calling run-test.sh without arguments) and tends to pass when run individually. The problem seems to be the 1s element timeout which in some cases may pass before element deletion occurs. Simply fix this by doubling the timeout. It has to pass just once, so shouldn't hurt too much. Fixes: 618393c6b3f25 ("tests: Introduce test for set with concatenated ranges") Reviewed-by: Stefano Brivio <sbrivio@redhat.com> Signed-off-by: Phil Sutter <phil@nwl.cc>
* main: Error out when combining -i/--interactive and -f/--filePablo Neira Ayuso2023-04-181-0/+10
| | | | | | | | | These two options are mutually exclusive, display error in that case: # nft -i -f test.nft Error: -i/--interactive and -f/--file options cannot be combined Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: support for redirect and masqueradePablo Neira Ayuso2023-04-053-32/+130
| | | | | | | | | | | | | | The redirect and masquerade statements can be handled as verdicts: - if redirect statement specifies no ports. - masquerade statement, in any case. Exceptions to the rule: If redirect statement specifies ports, then nat map transformation can be used iif both statements specify ports. Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1668 Fixes: 0a6dbfce6dc3 ("optimize: merge nat rules with same selectors into map") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* netlink_delinearize: do not reset protocol context for nat protocol expressionPablo Neira Ayuso2023-04-057-35/+9
| | | | | | | | This patch reverts 403b46ada490 ("netlink_delinearize: kill dependency before eval of 'redirect' stmt"). Since ("evaluate: bogus missing transport protocol"), this workaround is not required anymore. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: bogus missing transport protocolPablo Neira Ayuso2023-04-051-3/+8
| | | | | | | | | | | | | | | | | | | Users have to specify a transport protocol match such as meta l4proto tcp before the redirect statement, even if the redirect statement already implicitly refers to the transport protocol, for instance: test.nft:3:16-53: Error: transport protocol mapping is only valid after transport protocol match redirect to :tcp dport map { 83 : 8083, 84 : 8084 } ~~~~~~~~ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Evaluate the redirect expression before the mandatory check for the transport protocol match, so protocol context already provides a transport protocol. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: assert nat type on nat statement helperPablo Neira Ayuso2023-04-051-0/+4
| | | | | | Add assert() to helper function to expression from NAT statement. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xt: Fix translation error pathPhil Sutter2023-03-291-4/+6
| | | | | | | | | | | | | | | | | | | | If xtables support was compiled in but the required libxtables DSO is not found, nft prints an error message and leaks memory: | counter packets 0 bytes 0 XT target MASQUERADE not found This is not as bad as it seems, the output combines stdout and stderr. Dropping stderr produces an incomplete ruleset listing, though. While this seemingly inline output can't easily be avoided, fix a few things: * Respect octx->error_fp, libnftables might have been configured to redirect stderr somewhere else. * Align error message formatting with others. * Don't return immediately, but free allocated memory and fall back to printing the expression in "untranslated" form. Fixes: 5c30feeee5cfe ("xt: Delay libxtables access until translation") Signed-off-by: Phil Sutter <phil@nwl.cc>
* netlink_delinearize: correct type and byte-order of shiftsJeremy Sowden2023-03-281-2/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | Downgrade to base type integer instead of the specific type from the expression that is used in the shift operation. Without this, listing a rule like: ct mark set ip dscp lshift 2 or 0x10 will return: ct mark set ip dscp << 2 | cs2 because the type of the OR's right operand will be transitively derived from `ip dscp`. However, this is not valid syntax: # nft add rule t c ct mark set ip dscp '<<' 2 '|' cs2 Error: Could not parse integer add rule t c ct mark set ip dscp << 2 | cs2 ^^^ Use xinteger_type to print the output in hexadecimal. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* intervals: use expression location when translating to intervalsPablo Neira Ayuso2023-03-281-2/+2
| | | | | | | | | | | | | | | | | Otherwise, internal location reports: # nft -f ruleset.nft internal:0:0-0: Error: Could not process rule: File exists after this patch: # nft -f ruleset.nft ruleset.nft:402:1-16: Error: Could not process rule: File exists 1.2.3.0/30, ^^^^^^^^^^^ Fixes: 81e36530fcac ("src: replace interval segment tree overlap and automerge") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* payload: set byteorder when completing expressionPablo Neira Ayuso2023-03-281-0/+1
| | | | | | | | | Otherwise payload expression remains in invalid byteorder which is handled as network byteorder for historical reason. No functional change is intended. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: py: extend test-cases for mark statements with bitwise expressionsPablo Neira Ayuso2023-03-286-0/+234
| | | | | | | | | | Add more tests to cover bitwise operation. Shift operations are used on constant value which are reduced at evaluation time. Shift takes precendence over AND and OR operations, otherwise use parens to override this. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: shell: add test-cases for ct and packet mark payload expressionsJeremy Sowden2023-03-2816-0/+136
| | | | | | | | Add new test-cases to verify that defining a rule that sets the ct or packet mark to a value derived from a payload works correctly. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: shell: rename and move bitwise test-casesJeremy Sowden2023-03-284-4/+4
| | | | | | | | | | | | The `0040mark_shift_?` tests are testing not just shifts, but binops more generally, so name them accordingly. Move them to a new folder specifically for bitwise operations. Change the priorities of the chains to match the type. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: py: add test-cases for ct and packet mark payload expressionsJeremy Sowden2023-03-2812-0/+483
| | | | | | | | Add new test-cases to verify that defining a rule that sets the ct or packet mark to a value derived from a payload works correctly. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* netlink_delinerize: incorrect byteorder in mark statement listingPablo Neira Ayuso2023-03-281-4/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When using ip dscp in combination with bitwise operation: # nft --debug=netlink add rule ip x y 'ct mark set ip dscp | 0x4' ip x y [ payload load 1b @ network header + 1 => reg 1 ] [ bitwise reg 1 = ( reg 1 & 0x000000fc ) ^ 0x00000000 ] [ bitwise reg 1 = ( reg 1 >> 0x00000002 ) ] [ bitwise reg 1 = ( reg 1 & 0xfffffffb ) ^ 0x00000004 ] [ ct set mark with reg 1 ] the listing is showing in the incorrect byteorder: # nft list ruleset table ip x { chain y { ct mark set ip dscp | 0x4000000 } } handle and and or operations in host byteorder. The following command: # nft --debug=netlink add rule ip6 x y 'ct mark set ip6 dscp | 0x4' ip6 x y [ payload load 2b @ network header + 0 => reg 1 ] [ bitwise reg 1 = ( reg 1 & 0x0000c00f ) ^ 0x00000000 ] [ bitwise reg 1 = ( reg 1 >> 0x00000006 ) ] [ byteorder reg 1 = ntoh(reg 1, 2, 1) ] [ bitwise reg 1 = ( reg 1 & 0xfffffffb ) ^ 0x00000004 ] [ ct set mark with reg 1 ] works fine (without requiring this patch) because there is an explicit byteorder expression. However, ip dscp takes only 1-byte, so it does not require the byteorder expression. Use host byteorder if the rhs of bitwise AND OR is larger than lhs payload expression and such expression is equal or less than 1-byte. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: honor statement length in bitwise evaluationPablo Neira Ayuso2023-03-281-4/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Get length from statement, instead infering it from the expression that is used to set the value. In the particular case of {ct|meta} mark, this is 32 bits. Otherwise, bytecode generation is not correct: # nft -c --debug=netlink 'add rule ip6 x y ct mark set ip6 dscp << 2 | 0x10' [ payload load 2b @ network header + 0 => reg 1 ] [ bitwise reg 1 = ( reg 1 & 0x0000c00f ) ^ 0x00000000 ] [ bitwise reg 1 = ( reg 1 >> 0x00000006 ) ] [ byteorder reg 1 = ntoh(reg 1, 2, 1) ] [ bitwise reg 1 = ( reg 1 << 0x00000002 ) ] [ bitwise reg 1 = ( reg 1 & 0x00000fef ) ^ 0x00000010 ] <--- incorrect! [ ct set mark with reg 1 ] the previous bitwise shift already upgraded to 32-bits (not visible from the netlink debug output above). After this patch, the last | 0x10 uses 32-bits: [ bitwise reg 1 = ( reg 1 & 0xffffffef ) ^ 0x00000010 ] note that mask 0xffffffef is used instead of 0x00000fef. Patch ("evaluate: support shifts larger than the width of the left operand") provides the statement length through eval context. Use it to evaluate the bitwise expression accordingly, otherwise bytecode is incorrect: # nft --debug=netlink add rule ip x y 'ct mark set ip dscp & 0x0f << 1 | 0xff000000' ip x y [ payload load 1b @ network header + 1 => reg 1 ] [ bitwise reg 1 = ( reg 1 & 0x000000fc ) ^ 0x00000000 ] [ bitwise reg 1 = ( reg 1 >> 0x00000002 ) ] [ bitwise reg 1 = ( reg 1 & 0x1e000000 ) ^ 0x000000ff ] <-- incorrect byteorder for OR [ byteorder reg 1 = ntoh(reg 1, 4, 4) ] <-- no needed for single ip dscp byte [ ct set mark with reg 1 ] Correct bytecode: # nft --debug=netlink add rule ip x y 'ct mark set ip dscp & 0x0f << 1 | 0xff000000 ip x y [ payload load 1b @ network header + 1 => reg 1 ] [ bitwise reg 1 = ( reg 1 & 0x000000fc ) ^ 0x00000000 ] [ bitwise reg 1 = ( reg 1 >> 0x00000002 ) ] [ bitwise reg 1 = ( reg 1 & 0x0000001e ) ^ 0xff000000 ] [ ct set mark with reg 1 ] Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: honor statement length in integer evaluationPablo Neira Ayuso2023-03-281-2/+8
| | | | | | | | | | | | | | Otherwise, bogus error is reported: # nft --debug=netlink add rule ip x y 'ct mark set ip dscp & 0x0f << 1 | 0xff000000' Error: Value 4278190080 exceeds valid range 0-63 add rule ip x y ct mark set ip dscp & 0x0f << 1 | 0xff000000 ^^^^^^^^^^ Use the statement length as the maximum value in the mark statement expression. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: set up integer type to shift expressionPablo Neira Ayuso2023-03-281-0/+1
| | | | | | | | | | Otherwise expr_evaluate_value() fails with invalid datatype: # nft --debug=netlink add rule ip x y 'ct mark set ip dscp & 0x0f << 1' BUG: invalid basetype invalid nft: evaluate.c:440: expr_evaluate_value: Assertion `0' failed. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>