summaryrefslogtreecommitdiffstats
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
* 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>
* evaluate: relax type-checking for integer arguments in mark statementsPablo Neira Ayuso2023-03-281-2/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In order to be able to set ct and meta marks to values derived from payload expressions, we need to relax the requirement that the type of the statement argument must match that of the statement key. Instead, we require that the base-type of the argument is integer and that the argument is small enough to fit. Moreover, swap expression byteorder before to make it compatible with the statement byteorder, to ensure rulesets are portable. # nft --debug=netlink add rule ip t c 'meta mark set ip saddr' ip t c [ payload load 4b @ network header + 12 => reg 1 ] [ byteorder reg 1 = ntoh(reg 1, 4, 4) ] <----------- byteorder swap [ meta set mark with reg 1 ] Based on original work from Jeremy Sowden. The following patches are required for this to work: evaluate: get length from statement instead of lhs expression evaluate: don't eval unary arguments evaluate: support shifts larger than the width of the left operand netlink_delinearize: correct type and byte-order of shifts evaluate: insert byte-order conversions for expressions between 9 and 15 bits Add one testcase for tests/py. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: don't eval unary argumentsJeremy Sowden2023-03-281-4/+2
| | | | | | | | | | | | When a unary expression is inserted to implement a byte-order conversion, the expression being converted has already been evaluated and so `expr_evaluate_unary` doesn't need to do so. This is required by {ct|meta} statements with bitwise operations, which might result in byteorder conversion of the expression. Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: support shifts larger than the width of the left operandPablo Neira Ayuso2023-03-282-20/+46
| | | | | | | | | | | | | | | | | | | | | | | | | If we want to left-shift a value of narrower type and assign the result to a variable of a wider type, we are constrained to only shifting up to the width of the narrower type. Thus: add rule t c meta mark set ip dscp << 2 works, but: add rule t c meta mark set ip dscp << 8 does not, even though the lvalue is large enough to accommodate the result. Upgrade the maximum length based on the statement datatype length, which is provided via context, if it is larger than expression lvalue. Update netlink_delinearize.c to handle the case where the length of a shift expression does not match that of its left-hand operand. Based on patch from Jeremy Sowden. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* meta: don't crash if meta key isn't knownFlorian Westphal2023-03-272-11/+24
| | | | | | | If older nft version is used for dumping, 'key' might be outside of the range of known templates. Signed-off-by: Florian Westphal <fw@strlen.de>
* evaluate: insert byte-order conversions for expressions between 9 and 15 bitsJeremy Sowden2023-03-221-1/+1
| | | | | | | | | | | Round up expression lengths when determining whether to insert a byte-order conversion. For example, if one is masking a network header which spans a byte boundary, the mask will span two bytes and so it will need to be in NBO. Fixes: bb03cbcd18a1 ("evaluate: no need to swap byte-order for values of fewer than 16 bits.") Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* Avoid a memleak with 'reset rules' commandPhil Sutter2023-03-201-5/+0
| | | | | | | | | | | | | | | | | | | Like other 'reset' commands, 'reset rules' also lists the (part of the) ruleset which was affected to give users a chance to store the zeroed values. Therefore do_command_reset() calls do_command_list(). This in turn calls do_list_ruleset() for CMD_OBJ_RULES which wasn't prepared for values stored in cmd->handle other than a possible family value and thus freely reused the pointers as scratch area for the do_list_table() call whiich in the past fetched each table's data directly from kernel. Meanwhile ruleset listing code has been integrated into the common caching logic, the 'cmd' pointer became unused by do_list_table(). The temporary cmd->handle manipulation is not needed anymore, dropping it prevents a memleak caused by overwriting of allocated table name pointer. Fixes: 1694df2de79f3 ("Implement 'reset rule' and 'reset rules' commands") Signed-off-by: Phil Sutter <phil@nwl.cc>
* Reduce signature of do_list_table()Phil Sutter2023-03-201-4/+3
| | | | | | | | | Since commit 16fac7d11bdf5 ("src: use cache infrastructure for rule objects"), the function does not use the passed 'cmd' object anymore. Remove it to affirm correctness of a follow-up fix and simplification in do_list_ruleset(). Signed-off-by: Phil Sutter <phil@nwl.cc>
* parser_bison: simplify reset syntaxPablo Neira Ayuso2023-03-151-0/+20
| | | | | | | | | | | | | | | | | | | | | | | | | Simplify: *reset rules* *chain* ['family'] 'table' ['chain]' to *reset rules* ['family'] 'table' 'chain' *reset rules* *table* ['family'] 'table' to *reset rules* ['family'] 'table' *reset counters* ['family'] *table* 'table' to *reset counters* ['family'] 'table' *reset quotas* ['family'] *table* 'table' to *reset quotas* ['family'] 'table' Previous syntax remains in place for backward compatibility. Acked-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* Revert "evaluate: relax type-checking for integer arguments in mark statements"Pablo Neira Ayuso2023-03-141-6/+2
| | | | | | | | | | | This patch reverts eab3eb7f146c ("evaluate: relax type-checking for integer arguments in mark statements") since it might cause ruleset portability issues when moving a ruleset from little to big endian host (and vice-versa). Let's revert this until we agree on what to do in this case. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: fix a couple of typo's in commentsJeremy Sowden2023-03-121-1/+1
| | | | | Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Florian Westphal <fw@strlen.de>
* cmd: move command functions to src/cmd.cPablo Neira Ayuso2023-03-113-206/+207
| | | | | | Move several command functions to src/cmd.c to debloat src/rule.c Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: improve error reporting for unsupported chain typePablo Neira Ayuso2023-03-112-9/+36
| | | | | | | | | | | | | | | | 8c75d3a16960 ("Reject invalid chain priority values in user space") provides error reporting from the evaluation phase. Instead, this patch infers the error after the kernel reports EOPNOTSUPP. test.nft:3:28-40: Error: Chains of type "nat" must have a priority value above -200 type nat hook prerouting priority -300; ^^^^^^^^^^^^^ This patch also adds another common issue for users compiling their own kernels if they forget to enable CONFIG_NFT_NAT in their .config file. Acked-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* Reject invalid chain priority values in user spacePhil Sutter2023-03-101-0/+9
| | | | | | | | The kernel doesn't accept nat type chains with a priority of -200 or below. Catch this and provide a better error message than the kernel's EOPNOTSUPP. Signed-off-by: Phil Sutter <phil@nwl.cc>
* xt: Fix fallback printing for extensions matching keywordsPhil Sutter2023-03-102-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | Yet another Bison workaround: Instead of the fancy error message, an incomprehensible syntax error is emitted: | # iptables-nft -A FORWARD -p tcp -m osf --genre linux | # nft list ruleset | nft -f - | # Warning: table ip filter is managed by iptables-nft, do not touch! | /dev/stdin:4:29-31: Error: syntax error, unexpected osf, expecting string | meta l4proto tcp xt match osf counter packets 0 bytes 0 | ^^^ Avoid this by quoting the extension name when printing: | # nft list ruleset | sudo ./src/nft -f - | # Warning: table ip filter is managed by iptables-nft, do not touch! | /dev/stdin:4:20-33: Error: unsupported xtables compat expression, use iptables-nft with this ruleset | meta l4proto tcp xt match "osf" counter packets 0 bytes 0 | ^^^^^^^^^^^^^^ Fixes: 79195a8cc9e9d ("xt: Rewrite unsupported compat expression dumping") Fixes: e41c53ca5b043 ("xt: Fall back to generic printing from translation") Signed-off-by: Phil Sutter <phil@nwl.cc>
* cache: fetch more objects when resetting rulePablo Neira Ayuso2023-03-011-0/+1
| | | | | | | | | | | | | | | | If the ruleset contains a reference to object, listing fails. The existing test for the new reset command displays the following error: # ./run-tests.sh testcases/rule_management/0011reset_0 I: using nft command: ./../../src/nft W: [FAILED] testcases/rule_management/0011reset_0: got 2 loading ruleset resetting specific rule netlink: Error: Unknown set 's' in dynset statement Fixes: 1694df2de79f ("Implement 'reset rule' and 'reset rules' commands") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* parser_bison: allow to use quota in setsPablo Neira Ayuso2023-03-011-0/+16
| | | | | | | | | | | | | | | | | | | | | | | | src: support for restoring element quota This patch allows you to restore quota in dynamic sets. table ip x { set y { type ipv4_addr size 65535 flags dynamic,timeout counter quota 500 bytes timeout 1h elements = { 8.8.8.8 counter packets 9 bytes 756 quota 500 bytes used 500 bytes timeout 1h expires 56m57s47ms } } chain z { type filter hook output priority filter; policy accept; update @y { ip daddr } counter packets 6 bytes 507 } } Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add last statementPablo Neira Ayuso2023-02-286-3/+102
| | | | | | | | | | | | | | | | | | | | | This new statement allows you to know how long ago there was a matching packet. # nft list ruleset table ip x { chain y { [...] ip protocol icmp last used 49m54s884ms counter packets 1 bytes 64 } } if this statement never sees a packet, then the listing says: ip protocol icmp last used never counter packets 0 bytes 0 Add tests/py in this patch too. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: expand value to range when nat mapping contains intervalsPablo Neira Ayuso2023-02-281-2/+45
| | | | | | | | | | | | | | | | | | | | | | | | | If the data in the mapping contains a range, then upgrade value to range. Otherwise, the following error is displayed: /dev/stdin:11:57-75: Error: Could not process rule: Invalid argument dnat ip to iifname . ip saddr map { enp2s0 . 10.1.1.136 : 1.1.2.69, enp2s0 . 10.1.1.1-10.1.1.135 : 1.1.2.66-1.84.236.78 } ^^^^^^^^^^^^^^^^^^^ The kernel rejects this command because userspace sends a single value while the kernel expects the range that represents the min and the max IP address to be used for NAT. The upgrade is also done when concatenation with intervals is used in the rhs of the mapping. For anonymous sets, expansion cannot be done from expr_evaluate_mapping() because the EXPR_F_INTERVAL flag is inferred from the elements. For explicit sets, this can be done from expr_evaluate_mapping() because the user already specifies the interval flag in the rhs of the map definition. Update tests/shell and tests/py to improve testing coverage in this case. Fixes: 9599d9d25a6b ("src: NAT support for intervals in maps") Fixes: 66746e7dedeb ("src: support for nat with interval concatenation") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: expand table command before evaluationPablo Neira Ayuso2023-02-243-41/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The nested syntax notation results in one single table command which includes all other objects. This differs from the flat notation where there is usually one command per object. This patch adds a previous step to the evaluation phase to expand the objects that are contained in the table into independent commands, so both notations have similar representations. Remove the code to evaluate the nested representation in the evaluation phase since commands are independently evaluated after the expansion. The commands are expanded after the set element collapse step, in case that there is a long list of singleton element commands to be added to the set, to shorten the command list iteration. This approach also avoids interference with the object cache that is populated in the evaluation, which might refer to objects coming in the existing command list that is being processed. There is still a post_expand phase to detach the elements from the set which could be consolidated by updating the evaluation step to handle the CMD_OBJ_SETELEMS command type. This patch fixes 27c753e4a8d4 ("rule: expand standalone chain that contains rules") which broke rule addition/insertion by index because the expansion code after the evaluation messes up the cache. Fixes: 27c753e4a8d4 ("rule: expand standalone chain that contains rules") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* parser_bison: missing close scope in destroy start conditionPablo Neira Ayuso2023-02-221-1/+1
| | | | | | | base_cmd production is missing this, add it. Fixes: f79c7a531744 ("src: use start condition with new destroy command") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: use start condition with new destroy commandPablo Neira Ayuso2023-02-212-1/+5
| | | | | | | | | | | | | tests/py reports the following problem: any/ct.t: ERROR: line 116: add rule ip test-ip4 output ct event set new | related | destroy | label: This rule should not have failed. any/ct.t: ERROR: line 117: add rule ip test-ip4 output ct event set new,related,destroy,label: This rule should not have failed. any/ct.t: ERROR: line 118: add rule ip test-ip4 output ct event set new,destroy: This rule should not have failed. Use start condition and update parser to handle 'destroy' keyword. Fixes: e1dfd5cc4c46 ("src: add support to command "destroy") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: infer family for nat mappingPablo Neira Ayuso2023-02-211-2/+21
| | | | | | | | | | | | | | | Infer family from key in nat mapping, otherwise nat mapping via merge breaks since family is not specified. Merging: fw-test-bug2.nft:4:9-78: iifname enp2s0 ip daddr 72.2.3.66 tcp dport 53122 dnat to 10.1.1.10:22 fw-test-bug2.nft:5:9-77: iifname enp2s0 ip daddr 72.2.3.66 tcp dport 443 dnat to 10.1.1.52:443 fw-test-bug2.nft:6:9-75: iifname enp2s0 ip daddr 72.2.3.70 tcp dport 80 dnat to 10.1.1.52:80 into: dnat ip to iifname . ip daddr . tcp dport map { enp2s0 . 72.2.3.66 . 53122 : 10.1.1.10 . 22, enp2s0 . 72.2.3.66 . 443 : 10.1.1.52 . 443, enp2s0 . 72.2.3.70 . 80 : 10.1.1.52 . 80 } Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1657 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: infer family from mappingPablo Neira Ayuso2023-02-211-5/+40
| | | | | | | If the key in the nat mapping is either ip or ip6, then set the nat family accordingly, no need for explicit family in the nat statement. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: print error on missing family in nat statementPablo Neira Ayuso2023-02-211-3/+29
| | | | | | | | | | | Print error message in case family cannot be inferred, before this patch, $? shows 1 after nft execution but no error message was printed. While at it, update error reporting for consistency in similar use cases. Fixes: e5c9c8fe0bcc ("evaluate: stmt_evaluate_nat_map() only if stmt->nat.ipportmap == true") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* netlink_delinearize: Sanitize concat data element decodingPhil Sutter2023-02-211-1/+1
| | | | | | | | | The call to netlink_get_register() might return NULL, catch this before dereferencing the pointer. Fixes: db59a5c1204c9 ("netlink_delinearize: fix decoding of concat data element") Signed-off-by: Phil Sutter <phil@nwl.cc> Acked-by: Florian Westphal <fw@strlen.de>
* evaluate: relax type-checking for integer arguments in mark statementsJeremy Sowden2023-02-071-2/+6
| | | | | | | | | | | | In order to be able to set ct and meta marks to values derived from payload expressions, we need to relax the requirement that the type of the statement argument must match that of the statement key. Instead, we require that the base-type of the argument is integer and that the argument is small enough to fit. Add one testcase for tests/py. Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
* netlink_delinearize: add postprocessing for payload binopsJeremy Sowden2023-02-071-0/+39
| | | | | | | | | | If a user uses a payload expression as a statement argument: nft add rule t c meta mark set ip dscp lshift 2 or 0x10 we may need to undo munging during delinearization. Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
* optimize: ignore existing nat mappingPablo Neira Ayuso2023-02-071-0/+7
| | | | | | | | | | | | | | | | User might be already using a nat mapping in their ruleset, use the unsupported statement when collecting statements in this case. # nft -c -o -f ruleset.nft nft: optimize.c:443: rule_build_stmt_matrix_stmts: Assertion `k >= 0' failed. Aborted The -o/--optimize feature only cares about linear rulesets at this stage, but do not hit assert() in this case. Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1656 Fixes: 0a6dbfce6dc3 ("optimize: merge nat rules with same selectors into map") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* rule: expand standalone chain that contains rulesPablo Neira Ayuso2023-02-071-3/+12
| | | | | | | | | | | | | | | | Otherwise rules that this chain contains are ignored when expressed using the following syntax: chain inet filter input2 { type filter hook input priority filter; policy accept; ip saddr 1.2.3.4 tcp dport { 22, 443, 123 } drop } When expanding the chain, remove the rule so the new CMD_OBJ_CHAIN case does not expand it again. Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1655 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* rule: add helper function to expand chain rules into commandsPablo Neira Ayuso2023-02-071-17/+22
| | | | | | | This patch adds a helper function to expand chain rules into commands. This comes in preparation for the follow up patch. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: select merge criteria based on candidates rulesPablo Neira Ayuso2023-02-061-11/+11
| | | | | | | | | | | | | Select the merge criteria based on the statements that are used in the candidate rules, instead of using the list of statements in the given chain. Update tests to include a rule with a verdict, which triggers the bug described in the bugzilla ticket. Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1657 Fixes: 0a6dbfce6dc3 ("optimize: merge nat rules with same selectors into map") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add support to command "destroy"Fernando F. Mancera2023-02-067-19/+124
| | | | | | | | | | | | | | | | | | | | | | | | | "destroy" command performs a deletion as "delete" command but does not fail if the object does not exist. As there is no NLM_F_* flag for ignoring such error, it needs to be ignored directly on error handling. Example of use: # nft list ruleset table ip filter { chain output { } } # nft destroy table ip missingtable # echo $? 0 # nft list ruleset table ip filter { chain output { } } Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: fix incorrect expansion into concatenation with verdict mapPablo Neira Ayuso2023-02-021-11/+22
| | | | | | | | | | | | | | | | | | # nft -c -o -f ruleset.nft Merging: ruleset.nft:3:3-53: meta pkttype broadcast udp dport { 67, 547 } accept ruleset.nft:4:17-58: meta pkttype multicast udp dport 1900 drop into: meta pkttype . udp dport vmap { broadcast . { 67, 547 } : accept, multicast . 1900 : drop } ruleset.nft:3:38-39: Error: invalid data type, expected concatenation of (packet type, internet network service) meta pkttype broadcast udp dport { 67, 547 } accept ^^ Similar to 187c6d01d357 ("optimize: expand implicit set element when merging into concatenation") but for verdict maps. Reported-by: Simon G. Trajkovski <neur0armitage@proton.me> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: wrap code to build concatenation in helper functionPablo Neira Ayuso2023-02-021-7/+15
| | | | | | | | | Move code to build concatenations into helper function, this routine includes support for expansion of implicit sets containing singleton values. This is preparation work to reuse existing code in a follow up patch. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: set eval ctx for add/update statements with integer constantsFlorian Westphal2023-01-261-2/+30
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Eric reports that nft asserts when using integer basetype constants with 'typeof' sets. Example: table netdev t { set s { typeof ether saddr . vlan id flags dynamic,timeout } chain c { } } loads fine. But adding a rule with add/update statement fails: nft 'add rule netdev t c set update ether saddr . 0 @s' nft: netlink_linearize.c:867: netlink_gen_expr: Assertion `dreg < ctx->reg_low' failed. When the 'ether saddr . 0' concat expression is processed, there is no set definition available anymore to deduce the required size of the integer constant. nft eval step then derives the required length using the data types. '0' has integer basetype, so the deduced length is 0. The assertion triggers because serialization step finds that it needs one more register. 2 are needed to store the ethernet address, another register is needed for the vlan id. Update eval step to make the expression context store the set key information when processing the preceeding set reference, then let stmt_evaluate_set() preserve the existing context instead of zeroing it again via stmt_evaluate_arg(). This makes concat expression evaluation compute the total size needed based on the sets key definition. Reported-by: Eric Garver <eric@garver.life> Signed-off-by: Florian Westphal <fw@strlen.de>
* Implement 'reset rule' and 'reset rules' commandsPhil Sutter2023-01-189-11/+164
| | | | | | | | Reset rule counters and quotas in kernel, i.e. without having to reload them. Requires respective kernel patch to support NFT_MSG_GETRULE_RESET message type. Signed-off-by: Phil Sutter <phil@nwl.cc>
* intervals: restrict check missing elements fix to sets with no auto-mergePablo Neira Ayuso2023-01-151-5/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If auto-merge is enabled, skip check for element mismatch introduced by 6d1ee9267e7e ("intervals: check for EXPR_F_REMOVE in case of element mismatch"), which is only relevant to sets with no auto-merge. The interval adjustment routine for auto-merge already checks for unexisting intervals in that case. Uncovered via ASAN: ==11946==ERROR: AddressSanitizer: heap-use-after-free on address 0x60d00000021c at pc 0x559ae160d5b3 bp 0x7ffc37bcb800 sp 0x7ffc37bcb7f8 READ of size 4 at 0x60d00000021c thread T0 #0 0x559ae160d5b2 in 0? /builddir/build/BUILD/nftables-1.0.6/src/intervals.c:424 #1 0x559ae15cb05a in interval_set_eval.lto_priv.0 (/usr/lib64/libnftables.so.1+0xaf05a) #2 0x559ae15e1c0d in setelem_evaluate.lto_priv.0 (/usr/lib64/libnftables.so.1+0xc5c0d) #3 0x559ae166b715 in nft_evaluate (/usr/lib64/libnftables.so.1+0x14f715) #4 0x559ae16749b4 in nft_run_cmd_from_buffer (/usr/lib64/libnftables.so.1+0x1589b4) #5 0x559ae20c0e7e in main (/usr/bin/nft+0x8e7e) #6 0x559ae1341146 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 #7 0x559ae1341204 in __libc_start_main_impl ../csu/libc-start.c:381 #8 0x559ae20c1420 in _start ../sysdeps/x86_64/start.S:115 0x60d00000021c is located 60 bytes inside of 144-byte region [0x60d0000001e0,0x60d000000270) freed by thread T0 here: #0 0x559ae18ea618 in __interceptor_free ../../../../gcc-12.2.0/libsanitizer/asan/asan_malloc_linux.cpp:52 #1 0x559ae160c315 in 4 /builddir/build/BUILD/nftables-1.0.6/src/intervals.c:349 #2 0x559ae160c315 in 0? /builddir/build/BUILD/nftables-1.0.6/src/intervals.c:420 previously allocated by thread T0 here: #0 0x559ae18eb927 in __interceptor_calloc ../../../../gcc-12.2.0/libsanitizer/asan/asan_malloc_linux.cpp:77 #1 0x559ae15c5076 in set_elem_expr_alloc (/usr/lib64/libnftables.so.1+0xa9076) Fixes: 6d1ee9267e7e ("intervals: check for EXPR_F_REMOVE in case of element mismatch") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* mnl: dump_nf_hooks() leaks memory in error pathPhil Sutter2023-01-131-2/+9
| | | | | | | Have to free the basehook object before returning to caller. Fixes: 4694f7230195b ("src: add support for base hook dumping") Signed-off-by: Phil Sutter <phil@nwl.cc>
* meta: parse_iso_date() returns booleanPhil Sutter2023-01-131-1/+1
| | | | | | | | Returning ts if 'ts == (time_t) -1' signals success to caller despite failure. Fixes: 4460b839b945a ("meta: fix compiler warning in date_type_parse()") Signed-off-by: Phil Sutter <phil@nwl.cc>
* netlink: Fix for potential NULL-pointer derefPhil Sutter2023-01-131-1/+2
| | | | | | | | | | If memory allocation fails, calloc() returns NULL which was not checked for. The code seems to expect zero array size though, so simply replacing this call by one of the x*calloc() ones won't work. So guard the call also by a check for 'len'. Fixes: db0697ce7f602 ("src: support for flowtable listing") Signed-off-by: Phil Sutter <phil@nwl.cc>
* optimize: Do not return garbage from stackPhil Sutter2023-01-131-1/+1
| | | | | | | | | If input does not contain a single 'add' command (unusual, but possible), 'ret' value was not initialized by nft_optimize() before returning its value. Fixes: fb298877ece27 ("src: add ruleset optimization infrastructure") Signed-off-by: Phil Sutter <phil@nwl.cc>
* optimize: Clarify chain_optimize() array allocationsPhil Sutter2023-01-131-3/+4
| | | | | | | | | | | | Arguments passed to sizeof() where deemed suspicious by covscan due to the different type. Consistently specify size of an array 'a' using 'sizeof(*a) * nmemb'. For the statement arrays in stmt_matrix, even use xzalloc_array() since the item count is fixed and therefore can't be zero. Fixes: fb298877ece27 ("src: add ruleset optimization infrastructure") Signed-off-by: Phil Sutter <phil@nwl.cc>
* optimize: payload expression requires inner_desc comparisonPablo Neira Ayuso2023-01-041-0/+2
| | | | | | | | | | | Since 772892a018b4 ("src: add vxlan matching support"), payload expressions have an inner_desc field that provides the description for the outer tunnel header. When searching for common mergeable selectors, compare the inner description too. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add gretap supportPablo Neira Ayuso2023-01-024-3/+33
| | | | Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add geneve matching supportPablo Neira Ayuso2023-01-023-3/+59
| | | | | | Add support for GENEVE vni and (ether) type header field. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add gre supportPablo Neira Ayuso2023-01-026-17/+188
| | | | | | | | | | | | | GRE has a number of fields that are conditional based on flags, which requires custom dependency code similar to icmp and icmpv6. Matching on optional fields is not supported at this stage. Since this is a layer 3 tunnel protocol, an implicit dependency on NFT_META_L4PROTO for IPPROTO_GRE is generated. To achieve this, this patch adds new infrastructure to remove an outer dependency based on the inner protocol from delinearize path. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>