]> git.ipfire.org Git - thirdparty/nftables.git/log
thirdparty/nftables.git
39 hours agotests: packetpath: add check for drop policy master
Florian Westphal [Wed, 3 Apr 2024 10:28:12 +0000 (12:28 +0200)] 
tests: packetpath: add check for drop policy

check that policy can be changed from accept to drop and that the kernel
acts on this.

Signed-off-by: Florian Westphal <fw@strlen.de>
2 days agodoc: nft.8: Highlight "hook" in flowtable description
Phil Sutter [Wed, 24 Apr 2024 21:48:56 +0000 (23:48 +0200)] 
doc: nft.8: Highlight "hook" in flowtable description

Lacking an explicit description of possible hook values, emphasising the
word in the description text should draw readers' attention in the right
direction.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 days agodoc: nft.8: Fix markup in ct expectation synopsis
Phil Sutter [Wed, 24 Apr 2024 21:46:11 +0000 (23:46 +0200)] 
doc: nft.8: Fix markup in ct expectation synopsis

Just a missing asterisk somewhere.

Fixes: 1dd08fcfa07a4 ("src: add ct expectations support")
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 days agotests: shell: Fix for maps/typeof_maps_add_delete with ASAN
Phil Sutter [Wed, 24 Apr 2024 21:41:59 +0000 (23:41 +0200)] 
tests: shell: Fix for maps/typeof_maps_add_delete with ASAN

With both KASAN and ASAN enabled, my VM is too slow so the ping-induced
set entry times out before the test checks its existence. Increase its
timeout to 2s, seems to do the trick.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 days agojson: Fix for memleak in __binop_expr_json
Phil Sutter [Wed, 24 Apr 2024 21:35:00 +0000 (23:35 +0200)] 
json: Fix for memleak in __binop_expr_json

When merging the JSON arrays generated for LHS and RHS of nested binop
expressions, the emptied array objects leak if their reference is not
decremented.

Fix this and tidy up other spots which did it right already by
introducing a json_array_extend wrapper.

Reported-by: Pablo Neira Ayuso <pablo@netfilter.org>
Fixes: 0ac39384fd9e4 ("json: Accept more than two operands in binary expressions")
Signed-off-by: Phil Sutter <phil@nwl.cc>
7 days agoAdd support for table's persist flag
Phil Sutter [Fri, 15 Dec 2023 00:10:39 +0000 (01:10 +0100)] 
Add support for table's persist flag

Bison parser lacked support for passing multiple flags, JSON parser
did not support table flags at all.

Document also 'owner' flag (and describe their relationship in nft.8.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 weeks agotests: shell: Avoid escape chars when printing to non-terminals
Phil Sutter [Sat, 23 Mar 2024 02:09:41 +0000 (03:09 +0100)] 
tests: shell: Avoid escape chars when printing to non-terminals

Print the 'EXECUTING' status line only if stdout is a terminal, the
mandatory following escape sequence to delete it messes up log file
contents.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 weeks agotests: py: Drop needless recorded JSON outputs
Phil Sutter [Fri, 22 Mar 2024 14:18:50 +0000 (15:18 +0100)] 
tests: py: Drop needless recorded JSON outputs

These match the input already, no need to track them.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 weeks agotests: py: Warn if recorded JSON output matches the input
Phil Sutter [Fri, 22 Mar 2024 14:04:40 +0000 (15:04 +0100)] 
tests: py: Warn if recorded JSON output matches the input

Actively support spring-cleaning by nagging callers.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 weeks agotests: py: Fix some JSON equivalents
Phil Sutter [Fri, 22 Mar 2024 13:00:26 +0000 (14:00 +0100)] 
tests: py: Fix some JSON equivalents

Make sure they match the standard syntax input as much as possible.

For some reason inet/tcp.t.json was using plain arrays in place of
binary OR expressions in many cases. These arrays are interpreted as
list expressions, which seems to be semantically identical but the goal
here is to present an accurate equivalent to the rule in standard
syntax.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 weeks agomergesort: Avoid accidental set element reordering
Phil Sutter [Fri, 22 Mar 2024 12:31:10 +0000 (13:31 +0100)] 
mergesort: Avoid accidental set element reordering

In corner cases, expr_msort_cmp() may return 0 for two non-identical
elements. An example are ORed tcp flags: 'syn' and 'syn | ack' are
considered the same value since expr_msort_value() reduces the latter to
its LHS.

Keeping the above in mind and looking at how list_expr_sort() works: The
list in 'head' is cut in half, the first half put into the temporary
list 'list' and finally 'list' is merged back into 'head' considering
each element's position. Shall expr_msort_cmp() return 0 for two
elements, the one from 'list' ends up after the one in 'head', thus
reverting their previous ordering.

The practical implication is that output never matches input for the
sample set '{ syn, syn | ack }' as the sorting after delinearization in
netlink_list_setelems() keeps swapping the elements. Out of coincidence,
the commit this fixes itself illustrates the use-case this breaks,
namely tracking a ruleset in git: Each ruleset reload will trigger an
update to the stored dump.

This change breaks interval set element deletion because __set_delete()
implicitly relies upon this reordering of duplicate entries by inserting
a clone of the one to delete into the start (via list_move()) and after
sorting assumes the clone will end up right behind the original. Fix
this by calling list_move_tail() instead.

Fixes: 14ee0a979b622 ("src: sort set elements in netlink_get_setelems()")
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 weeks agojson: Accept more than two operands in binary expressions
Phil Sutter [Wed, 20 Mar 2024 14:54:54 +0000 (15:54 +0100)] 
json: Accept more than two operands in binary expressions

The most common use case is ORing flags like

| syn | ack | rst

but nft seems to be fine with less intuitive stuff like

| meta mark set ip dscp << 2 << 3

so support all of them.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 weeks agodoc: nft.8: Two minor synopsis fixups
Phil Sutter [Thu, 21 Mar 2024 13:57:41 +0000 (14:57 +0100)] 
doc: nft.8: Two minor synopsis fixups

The curly braces in 'add table' are to be put literally, so need to be
bold. Also, they are optional unless either one (or both) of 'comment'
and 'flags' are specified.

The 'add chain' synopsis contained a stray tick, messing up the
following markup.

Fixes: 7fd67ce121f86 ("doc: fix synopsis of named counter, quota and ct {helper,timeout,expect}")
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 weeks agotests: shell: check for reset tcp options support
Pablo Neira Ayuso [Mon, 8 Apr 2024 21:05:28 +0000 (23:05 +0200)] 
tests: shell: check for reset tcp options support

Fixes: 59a33d08ab3a ("parser: tcpopt: fix tcp option parsing with NUM + length field")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 weeks agotests: shell: maps/{vmap_unary,named_limits} require pipapo set backend
Pablo Neira Ayuso [Mon, 8 Apr 2024 20:56:00 +0000 (22:56 +0200)] 
tests: shell: maps/{vmap_unary,named_limits} require pipapo set backend

... sets/typeof_sets_concat needs it too.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 weeks agotests: shell: chains/{netdev_netns_gone,netdev_chain_dev_gone} require inet/ingress...
Pablo Neira Ayuso [Mon, 8 Apr 2024 20:50:06 +0000 (22:50 +0200)] 
tests: shell: chains/{netdev_netns_gone,netdev_chain_dev_gone} require inet/ingress support

Fixes: 6847a7ce0fc9 ("tests: shell: cover netns removal for netdev and inet/ingress basechains")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 weeks agotests: shell: payload matching requires egress support
Pablo Neira Ayuso [Mon, 8 Apr 2024 18:25:12 +0000 (20:25 +0200)] 
tests: shell: payload matching requires egress support

Older kernels do not support for egress hook.

Fixes: 84da729e067a ("tests: shell: add test to cover payload transport match and mangle")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 weeks agotests: py: complete icmp and icmpv6 update
Pablo Neira Ayuso [Thu, 4 Apr 2024 11:56:39 +0000 (13:56 +0200)] 
tests: py: complete icmp and icmpv6 update

Update json update and leftover payload update to complete
5fecd2a6ef61 ("src: disentangle ICMP code types").

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 weeks agosrc: disentangle ICMP code types
Pablo Neira Ayuso [Mon, 1 Apr 2024 22:28:24 +0000 (00:28 +0200)] 
src: disentangle ICMP code types

Currently, ICMP{v4,v6,inet} code datatypes only describe those that are
supported by the reject statement, but they can also be used for icmp
code matching. Moreover, ICMP code types go hand-to-hand with ICMP
types, that is, ICMP code symbols depend on the ICMP type.

Thus, the output of:

  nft describe icmp_code

look confusing because that only displays the values that are supported
by the reject statement.

Disentangle this by adding internal datatypes for the reject statement
to handle the ICMP code symbol conversion to value as well as ruleset
listing.

The existing icmp_code, icmpv6_code and icmpx_code remain in place. For
backward compatibility, a parser function is defined in case an existing
ruleset relies on these symbols.

As for the manpage, move existing ICMP code tables from the DATA TYPES
section to the REJECT STATEMENT section, where this really belongs to.
But the icmp_code and icmpv6_code table stubs remain in the DATA TYPES
section because that describe that this is an 8-bit integer field.

After this patch:

 # nft describe icmp_code
 datatype icmp_code (icmp code) (basetype integer), 8 bits
 # nft describe icmpv6_code
 datatype icmpv6_code (icmpv6 code) (basetype integer), 8 bits
 # nft describe icmpx_code
 datatype icmpx_code (icmpx code) (basetype integer), 8 bits

do not display the symbol table of the reject statement anymore.

icmpx_code_type is not used anymore, but keep it in place for backward
compatibility reasons.

And update tests/shell accordingly.

Fixes: 5fdd0b6a0600 ("nft: complete reject support")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 weeks agonetlink_delinearize: unused code in reverse cross-day meta hour range
Pablo Neira Ayuso [Wed, 27 Mar 2024 17:42:53 +0000 (18:42 +0100)] 
netlink_delinearize: unused code in reverse cross-day meta hour range

f8f32deda31d ("meta: Introduce new conditions 'time', 'day' and 'hour'")
reverses a cross-day range expressed as "22:00"-"02:00" UTC time into
!= "02:00"-"22:00" so meta hour ranges works.

Listing is however confusing, hence, 44d144cd593e ("netlink_delinearize:
reverse cross-day meta hour range") introduces code to reverse a cross-day.

However, it also adds code to reverse a range in == to-from form
(assuming OP_IMPLICIT) which is never exercised from the listing path
because the range expression is not currently used, instead two
instructions (cmp gte and cmp lte) are used to represent the range.
Remove this branch otherwise a reversed notation will be used to display
meta hour ranges once the range instruction is to represent this.

Add test for cross-day scenario in EADT timezone.

Fixes: 44d144cd593e ("netlink_delinearize: reverse cross-day meta hour range")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 weeks agotests: shell: packetpath/flowtables: open all temporary files in /tmp
Jeremy Sowden [Sun, 24 Mar 2024 14:59:08 +0000 (14:59 +0000)] 
tests: shell: packetpath/flowtables: open all temporary files in /tmp

The test used to do I/O over a named pipe in $PWD, until Phil changed it
to create the pipe in /tmp.  However, he missed one `socat` command.
Update that too.

Fixes: 3a9f29e21726 ("tests: shell: packetpath/flowtables: Avoid spurious EPERM")
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 weeks agotests: meta_time: fix dump validation failure
Florian Westphal [Tue, 2 Apr 2024 13:31:19 +0000 (15:31 +0200)] 
tests: meta_time: fix dump validation failure

[DUMP FAIL]  1/1 tests/shell/testcases/listing/meta_time

This dump file validates only correctly for TZ=UTC-1 (i.e., CET).
Time dumps cannot be validated in a portable way, the dump depends on TZ.

As the test already does dump valiation with different TZ values, remove
the dump file again.

Signed-off-by: Florian Westphal <fw@strlen.de>
3 weeks agotests: shell: add regression test for double-free crash bug
Florian Westphal [Fri, 8 Mar 2024 19:57:26 +0000 (20:57 +0100)] 
tests: shell: add regression test for double-free crash bug

BUG: KASAN: slab-use-after-free in nf_tables_set_elem_destroy+0x55/0x160
Call Trace:
 nf_tables_set_elem_destroy+0x55/0x160
 nf_tables_set_elem_destroy+0x55/0x160
 nft_pipapo_destroy+0x3b4/0x5a0
 nft_set_destroy+0x118/0x3a0
 nf_tables_trans_destroy_work+0x4f2/0xa80

This is a test case for the bug fiex with kernel commit
b0e256f3dd2b ("netfilter: nft_set_pipapo: release elements in clone only from destroy path").

Reported-by: lonial con <kongln9170@gmail.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
5 weeks agodatatype: use DTYPE_F_PREFIX only for IP address datatype
Pablo Neira Ayuso [Thu, 21 Mar 2024 11:40:53 +0000 (12:40 +0100)] 
datatype: use DTYPE_F_PREFIX only for IP address datatype

DTYPE_F_PREFIX flag provides a hint to the netlink delinearize path to
use prefix notation.

It seems use of prefix notation in meta mark causes confusion, users
expect to see prefix in the listing only in IP address datatypes.

Untoggle this flag so (more lengthy) binop output such as:

  meta mark & 0xffffff00 == 0xffffff00

is used instead.

Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1739
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
5 weeks agoevaluate: display "Range negative size" error
Pablo Neira Ayuso [Tue, 19 Mar 2024 18:50:00 +0000 (19:50 +0100)] 
evaluate: display "Range negative size" error

zero length ranges now allowed, therefore, update error message to refer
to negative ranges which are not possible.

Fixes: 7a6e16040d65 ("evaluate: allow for zero length ranges")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
5 weeks agonetlink_delinearize: reverse cross-day meta hour range
Pablo Neira Ayuso [Tue, 19 Mar 2024 18:21:04 +0000 (19:21 +0100)] 
netlink_delinearize: reverse cross-day meta hour range

f8f32deda31d ("meta: Introduce new conditions 'time', 'day' and 'hour'")
reverses the hour range in case that a cross-day range is used, eg.

  meta hour "03:00"-"14:00" counter accept

which results in (Sidney, Australia AEDT time):

  meta hour != "14:00"-"03:00" counter accept

kernel handles time in UTC, therefore, cross-day range may not be
obvious according to local time.

The ruleset listing above is not very intuitive to the reader depending
on their timezone, therefore, complete netlink delinearize path to
reverse the cross-day meta range.

Update manpage to recommend to use a range expression when matching meta
hour range. Recommend range expression for meta time and meta day too.

Extend testcases/listing/meta_time to cover for this scenario.

Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1737
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
5 weeks agonetlink_delinearize: restore binop syntax when listing ruleset for flags
Pablo Neira Ayuso [Mon, 18 Mar 2024 12:10:55 +0000 (13:10 +0100)] 
netlink_delinearize: restore binop syntax when listing ruleset for flags

c3d57114f119 ("parser_bison: add shortcut syntax for matching flags
without binary operations") provides a similar syntax to iptables using
a prefix representation for flag matching.

Restore original representation using binop when listing the ruleset.
The parser still accepts the prefix notation for backward compatibility.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
5 weeks agosrc: do not merge a set with a erroneous one
Florian Westphal [Fri, 12 Jan 2024 12:19:26 +0000 (13:19 +0100)] 
src: do not merge a set with a erroneous one

The included sample causes a crash because we attempt to
range-merge a prefix expression with a symbolic expression.

The first set is evaluated, the symbol expression evaluation fails
and nft queues an error message ("Could not resolve hostname").

However, nft continues evaluation.

nft then encounters the same set definition again and merges the
new content with the preceeding one.

But the first set structure is dodgy, it still contains the
unresolved symbolic expression.

That then makes nft crash (assert) in the set internals.

There are various different incarnations of this issue, but the low
level set processing code does not allow for any partially transformed
expressions to still remain.

Before:
nft --check -f tests/shell/testcases/bogons/nft-f/invalid_range_expr_type_binop
BUG: invalid range expression type binop
nft: src/expression.c:1479: range_expr_value_low: Assertion `0' failed.

After:
nft --check -f tests/shell/testcases/bogons/nft-f/invalid_range_expr_type_binop
invalid_range_expr_type_binop:4:18-25: Error: Could not resolve hostname: Name or service not known
elements = { 1&.141.0.1 - 192.168.0.2}
             ^^^^^^^^

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
5 weeks agodoc: libnftables-json: Drop invalid ops from match expression
Phil Sutter [Fri, 22 Sep 2023 16:43:11 +0000 (18:43 +0200)] 
doc: libnftables-json: Drop invalid ops from match expression

These make no sense there and are listed again in BINARY OPERATION.

Fixes: 872f373dc50f7 ("doc: Add JSON schema documentation")
Signed-off-by: Phil Sutter <phil@nwl.cc>
5 weeks agotests: shell: Fix one json-nft dump for reordered output
Phil Sutter [Wed, 20 Mar 2024 14:34:34 +0000 (15:34 +0100)] 
tests: shell: Fix one json-nft dump for reordered output

Missed this one when regenerating all dumps.

Fixes: 2a0fe52eca32a ("tests: shell: Regenerate all json-nft dumps")
Signed-off-by: Phil Sutter <phil@nwl.cc>
5 weeks agotests: shell: Add missing json-nft dumps
Phil Sutter [Fri, 8 Mar 2024 23:26:07 +0000 (00:26 +0100)] 
tests: shell: Add missing json-nft dumps

Given that a bunch of issues got fixed, add some more dumps.

Also add tests/shell/testcases/owner/dumps/0002-persist.nft while at it,
even though it's really small.

Signed-off-by: Phil Sutter <phil@nwl.cc>
5 weeks agoparser: json: Support for synproxy objects
Phil Sutter [Fri, 8 Mar 2024 23:29:36 +0000 (00:29 +0100)] 
parser: json: Support for synproxy objects

Parsing code was there already, merely the entry in json_parse_cmd_add()
missing.

To support maps with synproxy target, an entry in string_to_nft_object()
is required. While being at it, add other missing entries as well.

Signed-off-by: Phil Sutter <phil@nwl.cc>
5 weeks agojson: Support maps with concatenated data
Phil Sutter [Fri, 8 Mar 2024 23:27:38 +0000 (00:27 +0100)] 
json: Support maps with concatenated data

Dump such maps with an array of types in "map" property, make the parser
aware of this.

Signed-off-by: Phil Sutter <phil@nwl.cc>
5 weeks agotests: shell: Regenerate all json-nft dumps
Phil Sutter [Fri, 8 Mar 2024 19:22:37 +0000 (20:22 +0100)] 
tests: shell: Regenerate all json-nft dumps

Ordering of 'nft -j list ruleset' output has changed, Regenerate
existing json-nft dumps. No functional change intended, merely the
position of chain objects should have moved up in the "nftables" array.

Signed-off-by: Phil Sutter <phil@nwl.cc>
5 weeks agojson: Order output like nft_cmd_expand()
Phil Sutter [Thu, 7 Mar 2024 17:40:12 +0000 (18:40 +0100)] 
json: Order output like nft_cmd_expand()

Print empty chain add commands early in list so following verdict maps
and rules referring to them won't cause spurious errors when loading the
resulting ruleset dump.

Signed-off-by: Phil Sutter <phil@nwl.cc>
5 weeks agotests: shell: packetpath/flowtables: Avoid spurious EPERM
Phil Sutter [Fri, 8 Mar 2024 14:21:30 +0000 (15:21 +0100)] 
tests: shell: packetpath/flowtables: Avoid spurious EPERM

On my system for testing, called socat is not allowed to create the pipe
file in local directory (probably due to sshfs). Specify a likely unique
path in /tmp to avoid such problems.

Fixes: 419c0199774c6 ("tests: shell: add test to cover ct offload by using nft flowtables")
Signed-off-by: Phil Sutter <phil@nwl.cc>
6 weeks agotests: py: move meter tests to tests/shell
Pablo Neira Ayuso [Wed, 13 Mar 2024 16:08:43 +0000 (17:08 +0100)] 
tests: py: move meter tests to tests/shell

Userspace performs an translation to dynamic set which does not fit well
into tests/py, move them to tests/shell.

Fixes: b8f8ddfff733 ("evaluate: translate meter into dynamic set")
Acked-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
6 weeks agosrc: remove utf-8 character in printf lines
Florian Westphal [Wed, 13 Mar 2024 13:17:55 +0000 (14:17 +0100)] 
src: remove utf-8 character in printf lines

replace "‘" (UTF-8, 0xe280 0x98) with "'" (ASCII 0x27).

Signed-off-by: Florian Westphal <fw@strlen.de>
6 weeks agotests: py: add payload merging test cases
Florian Westphal [Fri, 8 Mar 2024 13:40:12 +0000 (14:40 +0100)] 
tests: py: add payload merging test cases

Add a test case that would fail without preceeding fix.

Signed-off-by: Florian Westphal <fw@strlen.de>
6 weeks agonftables: do mot merge payloads on negation
Sriram Rajagopalan [Wed, 13 Mar 2024 08:32:42 +0000 (01:32 -0700)] 
nftables: do mot merge payloads on negation

else, a rule like
  tcp sport != 22 tcp dport != 23

will match even if the destination is 23 as long as sport is != 22.
(or vice versa).

Signed-off-by: Sriram Rajagopalan <sriramr@arista.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
6 weeks agoevaluate: translate meter into dynamic set
Pablo Neira Ayuso [Wed, 6 Mar 2024 16:48:58 +0000 (17:48 +0100)] 
evaluate: translate meter into dynamic set

129f9d153279 ("nft: migrate man page examples with `meter` directive to
sets") already replaced meters by dynamic sets.

This patch removes NFT_SET_ANONYMOUS flag from the implicit set that is
instantiated via meter, so the listing shows a dynamic set instead which
is the recommended approach these days.

Therefore, a batch like this:

 add table t
 add chain t c
 add rule t c tcp dport 80 meter m size 128 { ip saddr timeout 1s limit rate 10/second }

gets translated to a dynamic set:

 table ip t {
        set m {
                type ipv4_addr
                size 128
                flags dynamic,timeout
        }

        chain c {
                tcp dport 80 update @m { ip saddr timeout 1s limit rate 10/second burst 5 packets }
        }
 }

Check for NFT_SET_ANONYMOUS flag is also relaxed for list and flush
meter commands:

 # nft list meter ip t m
 table ip t {
        set m {
                type ipv4_addr
                size 128
                flags dynamic,timeout
        }
 }
 # nft flush meter ip t m

As a side effect the legacy 'list meter' and 'flush meter' commands allow
to flush a dynamic set to retain backward compatibility.

This patch updates testcases/sets/0022type_selective_flush_0 and
testcases/sets/0038meter_list_0 as well as the json output which now
uses the dynamic set representation.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
7 weeks agoMakefile: mkdir $(builddir}/doc
Neels Hofmeyr [Thu, 7 Mar 2024 23:42:50 +0000 (00:42 +0100)] 
Makefile: mkdir $(builddir}/doc

When building separately from the source tree (as in ../src/configure),
the 'doc' dir is not present from just the source tree. Create the dir
before calling a2x.

Signed-off-by: Neels Hofmeyr <nhofmeyr@sysmocom.de>
Signed-off-by: Phil Sutter <phil@nwl.cc>
7 weeks agotests: add test case for named ct objects
Florian Westphal [Fri, 1 Mar 2024 12:59:38 +0000 (13:59 +0100)] 
tests: add test case for named ct objects

Add a dedicated test for named conntrack objects:
timeouts, helpers and expectations.

A json dump file is not added because the json input
code does not support "typeof" declarations for sets/maps.

Signed-off-by: Florian Westphal <fw@strlen.de>
7 weeks agoparser: allow to define maps that contain ct helpers
Florian Westphal [Fri, 1 Mar 2024 12:59:37 +0000 (13:59 +0100)] 
parser: allow to define maps that contain ct helpers

Its currently not possible to use ct helpers in objref maps.

Simply adding "CT HELPER" to "map_block_obj_type" does not work
due to a conflict with the "ct helper" ct_expr block.

  map m {
    type ipv4_addr : ct helper ..

... declares a map storing ip addresses and conntrack helper names
(string type).  This does not make sense, there is no way
to use the associated value (the names) in any sensible way:

ct helper "ftp" - this matches if the packet has a conntrack entry that
was accepted via the "ftp" conntrack helper. In nft vm terms, this is
translated to:

 [ ct load helper => reg 1 ]
 [ cmp eq reg 1 0x00707466 0x00000000 0x00000000 0x00000000 ]

Or one can query a set, e.g. 'ct helper { "ftp", "sip" }'.
"ftp" and "sip" are the kernel-defined names of these connection
tracking helpers.

ct helper set "ftp" is something else, however:

This is used to assign a *userspace defined helper objrect reference*.
Nftables will translate this to:

 [ objref type 3 name ftp ]

.. where "ftp" is a arbitrary user-chosen name.

  ct helper "ftp" {
    type "ftp" protocol tcp
    l3proto ip
  }

IOW, "ct helper" is ambiguous.  Without the "set" keyword (first case),
it places the kernel-defined name of the active connection tracking helper
in the chosen register (or it will cancel rule evaluation if no helper was
active).

With the set keyword (second case), the expected argument is a user-defined
object reference which will then tell the connection tracking engine to
monitor all further packets of the new flow with the given helper template.

This change makes it so that

  map m {
    type ipv4_addr : ct helper ..

declares a map storing ct helper object references suitable for
'ct helper set'.

The better alternative would be to resolve the ambiguity
by adding an additional postfix keyword, for example

 ct helper name (case one)
 ct helper object (case two).

But this needs a kernel change that adds
NFT_CT_HELPER_NAME and NFT_CT_HELPER_OBJECT to enum nft_ct_keys.

While a new kernel could handle old nftables binaries that still use
NFT_CT_HELPER key, new nftables would need to probe support first.

Furthermore,

 ct helper name set "foo"

... would make no sense, as the kernel-defined helper names are
readonly.

 ct helper object "foo"

... would make no sense, unless we extend the kernel to store
the nftables userspace-defined name in a well-known location
in the kernel.  Userdata area cannot work for this, because the
nft conntrack expression in the kernel would need to know how to
retrieve this info again.

Also, I cannot think of a sensible use case for this.
So the only remaining, useful commands are:

ct helper name "ftp"
ct helper object set "foo"

... which is identical to what we already support, just with
extra keyword.

So a much simpler solution that does not need any kernel changes
is make "ct helper" have different meaning depending on wheter it
is placed on the key side, i.e.:

    "typeof ct helper", "typeof ct helper : $value"

versus when its on placed on the data (value) side of maps:

    "typeof $key : ct helper".

Signed-off-by: Florian Westphal <fw@strlen.de>
7 weeks agoparser: allow to define maps that contain timeouts and expectations
Florian Westphal [Fri, 1 Mar 2024 12:59:36 +0000 (13:59 +0100)] 
parser: allow to define maps that contain timeouts and expectations

Its currently not possible to use ct timeouts/expectations/helpers
in objref maps, bison parser lacks the relevant keywords.

This change adds support for timeouts and expectations.
Ct helpers are more problematic, this will come in a different change.

Support is only added for the "typeof" keyword, otherwise we'd
need to add pseudo-datatypes as well, but making "ct expectation"
available as "type" as well might be confusing.

Signed-off-by: Florian Westphal <fw@strlen.de>
7 weeks agorule: fix ASAN errors in chain priority to textual names
Pablo Neira Ayuso [Thu, 29 Feb 2024 15:50:37 +0000 (16:50 +0100)] 
rule: fix ASAN errors in chain priority to textual names

ASAN reports several errors when listing this ruleset:

 table ip x {
        chain y {
                type filter hook input priority -2147483648; policy accept;
        }
 }

src/rule.c:1002:8: runtime error: negation of -2147483648 cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself
src/rule.c:1001:11: runtime error: signed integer overflow: -2147483648 - 50 cannot be represented in type 'int'

Use int64_t for the offset to avoid an underflow when calculating
closest existing priority definition.

Use llabs() because abs() is undefined with INT32_MIN.

Fixes: c8a0e8c90e2d ("src: Set/print standard chain prios with textual names")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
8 weeks agotests: move test case to "maps" directory
Florian Westphal [Wed, 28 Feb 2024 23:13:27 +0000 (00:13 +0100)] 
tests: move test case to "maps" directory

This tests named object maps, so this should reside in maps/
not sets/ directory.

Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agotests: maps: add a test case for "limit" objref map
Florian Westphal [Thu, 29 Feb 2024 10:41:25 +0000 (11:41 +0100)] 
tests: maps: add a test case for "limit" objref map

check add, delete and removal operations for objref maps.

Also check type vs. typeof declarations and use both
interval and interval+concatenation (rbtree, pipapo).

Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agonetlink: allow typeof keywords with objref maps during listing
Florian Westphal [Thu, 29 Feb 2024 10:41:24 +0000 (11:41 +0100)] 
netlink: allow typeof keywords with objref maps during listing

Without this,

  typeof meta l4proto . ip saddr . tcp sport : limit

... is shown as

  type inet_proto . ipv4_addr . inet_service : limit

The "data" element is a value (the object type number).
It doesn't support userinfo data.

There is no reason to add it, the value is the object type
number that the object-reference map stores.

So, if we have an objref map, DO NOT discard the key part,
as we do for normal maps.

For normal maps, we support either typeof notation, i.e.:

  typeof meta l4proto . ip saddr . tcp sport : ip saddr

or the data type version:
  type inet_proto . ipv4_addr . inet_service : ipv4_addr

... but not a mix, a hyptothetical

  typeof meta l4proto . ip saddr . tcp sport : ipv4_addr

... does not work.

If nft finds no udata attached to the data element, for normal
map case, it has to fall back to the "type" form.

But for objref maps this is expected, udata for key but not for data.
Hence, for objref case, keep the typeof part if its valid.

Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agoparser: allow typeof in objref maps
Florian Westphal [Thu, 29 Feb 2024 10:41:23 +0000 (11:41 +0100)] 
parser: allow typeof in objref maps

Its currently not possible to declare a map that
stores object references with the "typeof" keyword, e.g.

map m {
type ipv4_addr : limit

will work, but

map m {
typeof ip saddr : limit

will give a syntax error ("unexpected limit").
Followup pach will add support for listing side too.

Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agoparser: compact type/typeof set rules
Florian Westphal [Tue, 27 Feb 2024 14:53:19 +0000 (15:53 +0100)] 
parser: compact type/typeof set rules

Set/maps keys can be declared either by 'type' or 'typeof' keyword.

Compact this to use a common block for both cases.

The datatype_set call is redundant, remove it:
at this point $3 == $1->key, so this is a no-op.

Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agoparser: compact interval typeof rules
Florian Westphal [Tue, 27 Feb 2024 14:50:05 +0000 (15:50 +0100)] 
parser: compact interval typeof rules

There are two nearly identical blocks for typeof maps:
one with INTERVAL keyword present and one without.

Compact this into a single block.

Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agosrc: improve error reporting for destroy command
谢致邦 (XIE Zhibang) [Wed, 21 Feb 2024 15:17:09 +0000 (15:17 +0000)] 
src: improve error reporting for destroy command

Example for older kernels (<6.3):
nft destroy table ip missingtable

Before:
Error: Could not process rule: Invalid argument

After:
Error: "destroy" command is not supported, perhaps kernel support is
missing?

Fixes: e1dfd5cc4c46 ("src: add support to command "destroy"")
Signed-off-by: 谢致邦 (XIE Zhibang) <Yeking@Red54.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agoparser_json: allow 0 offsets again
Florian Westphal [Mon, 26 Feb 2024 09:34:59 +0000 (10:34 +0100)] 
parser_json: allow 0 offsets again

Its valid in case of tcp option removal:

[ {
   "reset": {
     "tcp option": {
       "base": 123,
       "len": 0,
       "offset": 0
   }

This makes nft-test.py -j pass again.

Fixes: e08627257ecf ("parser: reject raw payload expressions with 0 length")
Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agotests: shell: add more json dumps
Florian Westphal [Mon, 26 Feb 2024 09:35:16 +0000 (10:35 +0100)] 
tests: shell: add more json dumps

Those are expected to be stable, so add them.
Some are not 100% correct, as "typeof" is misprinted as "type" (json output
and input parser lack support for this), but for these files the "type"
is valid too.

This will allow better validation once proper "typeof" support is
added to json.c and json-parser.c.

Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agotests: py: add missing json.output data
Florian Westphal [Mon, 26 Feb 2024 08:45:43 +0000 (09:45 +0100)] 
tests: py: add missing json.output data

Fixes: bridge/vlan.t: WARNING: line 56: ...
Fixes: 8b9ae77598b4 ("tests: never merge across non-expression statements redux 2")
Signed-off-by: Florian Westphal <fw@strlen.de>
2 months agotests: shell: add regression test for catchall double-delete
Florian Westphal [Sun, 18 Feb 2024 11:12:46 +0000 (12:12 +0100)] 
tests: shell: add regression test for catchall double-delete

Test case for:
 b1db244ffd04 ("netfilter: nf_tables: check if catch-all set element is active in next generation")

Reported-by: lonial con <kongln9170@gmail.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
2 months agotests: shell: permit use of host-endian constant values in set lookup keys
Florian Westphal [Wed, 14 Feb 2024 10:41:30 +0000 (11:41 +0100)] 
tests: shell: permit use of host-endian constant values in set lookup keys

extend an existing test case with the afl input to cover in/output.

A new test case is added to test linearization, delinearization and
matching

Fixes: c0080feb0d03 ("evaluate: permit use of host-endian constant values in set lookup keys")
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 months agoexpression: missing line in describe command with invalid expression
Pablo Neira Ayuso [Tue, 13 Feb 2024 16:09:20 +0000 (17:09 +0100)] 
expression: missing line in describe command with invalid expression

Before:

 duh@testbed:~# nft describe blah
 symbol expression, datatype invalid (invalid)duh@testbed:#

After:

 duh@testbed:~# nft describe blah
 symbol expression, datatype invalid (invalid)
 duh@testbed:#

Fixes: 48aca2de80a7 ("iptopt: fix crash with invalid field/type combo")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 months agoevaluate: permit use of host-endian constant values in set lookup keys
Pablo Neira Ayuso [Mon, 12 Feb 2024 15:46:29 +0000 (16:46 +0100)] 
evaluate: permit use of host-endian constant values in set lookup keys

AFL found following crash:

table ip filter {
map ipsec_in {
typeof ipsec in reqid . iif : verdict
flags interval
}

chain INPUT {
type filter hook input priority filter; policy drop;
ipsec in reqid . 100 @ipsec_in
}
}

Which yields:
nft: evaluate.c:1213: expr_evaluate_unary: Assertion `!expr_is_constant(arg)' failed.

All existing test cases with constant values use big endian values, but
"iif" expects host endian values.

As raw values were not supported before, concat byteorder conversion
doesn't handle constants.

Fix this:

1. Add constant handling so that the number is converted in-place,
   without unary expression.

2. Add the inverse handling on delinearization for non-interval set
   types.
   When dissecting the concat data soup, watch for integer constants where
   the datatype indicates host endian integer.

Last, extend an existing test case with the afl input to cover
in/output.

A new test case is added to test linearization, delinearization and
matching.

Based on original patch from Florian Westphal, patch subject and
description wrote by him.

Fixes: b422b07ab2f9 ("src: permit use of constant values in set lookup keys")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 months agonetlink_delinearize: move concat and value postprocessing to helpers
Florian Westphal [Fri, 19 Jan 2024 12:47:08 +0000 (13:47 +0100)] 
netlink_delinearize: move concat and value postprocessing to helpers

No functional changes intended.

Signed-off-by: Florian Westphal <fw@strlen.de>
2 months agocache: Always set NFT_CACHE_TERSE for list cmd with --terse
Phil Sutter [Thu, 8 Feb 2024 01:10:48 +0000 (02:10 +0100)] 
cache: Always set NFT_CACHE_TERSE for list cmd with --terse

This fixes at least 'nft -t list table ...' and 'nft -t list set ...'.

Note how --terse handling for 'list sets/maps' remains in place since
setting NFT_CACHE_TERSE does not fully undo NFT_CACHE_SETELEM: setting
both enables fetching of anonymous sets which is pointless for that
command.

Reported-by: anton.khazan@gmail.com
Link: https://bugzilla.netfilter.org/show_bug.cgi?id=1735
Suggested-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agonetlink_linearize: add assertion to catch for buggy byteorder
Pablo Neira Ayuso [Thu, 8 Feb 2024 12:20:43 +0000 (13:20 +0100)] 
netlink_linearize: add assertion to catch for buggy byteorder

Add assertion to catch buggy bytecode where unary expression is present
with 1-byte selectors, where no byteorder conversion is required.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 months agoevaluate: skip byteorder conversion for selector smaller than 2 bytes
Pablo Neira Ayuso [Wed, 7 Feb 2024 22:53:32 +0000 (23:53 +0100)] 
evaluate: skip byteorder conversion for selector smaller than 2 bytes

Add unary expression to trigger byteorder conversion for host byteorder
selectors only if selectors length is larger or equal than 2 bytes.

 # cat test.nft
 table ip x {
        set test {
                type ipv4_addr . ether_addr . inet_proto
                flags interval
        }

        chain y {
                ip saddr . ether saddr . meta l4proto @test counter
        }
 }

 # nft -f test.nft
 ip x y
  [ meta load iiftype => reg 1 ]
  [ cmp eq reg 1 0x00000001 ]
  [ payload load 4b @ network header + 12 => reg 1 ]
  [ payload load 6b @ link header + 6 => reg 9 ]
  [ meta load l4proto => reg 11 ]
  [ byteorder reg 11 = hton(reg 11, 2, 1) ] <--- should not be here
  [ lookup reg 1 set test ]
  [ counter pkts 0 bytes 0 ]

Fixes: 1017d323cafa ("src: support for selectors with different byteorder with interval concatenations")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 months agotests/shell: no longer support unprettified ".json-nft" files
Thomas Haller [Fri, 9 Feb 2024 12:10:39 +0000 (13:10 +0100)] 
tests/shell: no longer support unprettified ".json-nft" files

By now, all ".json-nft" files are prettified and will be generated in
that form.

Drop the fallback code that accepts them in the previous form.

Signed-off-by: Thomas Haller <thaller@redhat.com>
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agotests: shell: Pretty-print all *.json-nft dumps
Phil Sutter [Thu, 8 Feb 2024 13:30:17 +0000 (14:30 +0100)] 
tests: shell: Pretty-print all *.json-nft dumps

The problem with single line output as produced by 'nft -j list ruleset'
is its incompatibility to unified diff format as any change in this
single line will produce a diff which contains the old and new lines in
total. This is not just unreadable but will blow up patches which may
exceed mailinglists' mail size limits.

Convert them all at once by feeding their contents to
tests/shell/helpers/json-pretty.sh.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agotests/shell: have .json-nft dumps prettified to wrap lines
Thomas Haller [Thu, 7 Dec 2023 09:08:50 +0000 (10:08 +0100)] 
tests/shell: have .json-nft dumps prettified to wrap lines

Previously, the .json-nft file in git contains the output of `nft -j
list ruleset`. This is one long line and makes diffs harder to review.

Instead, have the prettified .json-nft file committed to git.

- the diff now operates on the prettified version. That means, it
  compares essentially

     - `nft -j list ruleset | json-sanitize-ruleset.sh | json-pretty.sh`
     - `cat "$TEST.json-nft" | json-pretty.sh`

  The script "json-diff-pretty.sh" is no longer used. It is kept
  however, because it might be a useful for manual comparing files.

  Note that "json-sanitize-ruleset.sh" and "json-pretty.sh" are still
  two separate scripts and called at different times. They also do
  something different. The former mangles the JSON to account for changes
  that are not stable (in the JSON data itself), while the latter only
  pretty prints it.

- when generating a new .json-nft dump file, the file will be updated to
  use the new, prettified format, unless the file is in the old format
  and needs no update. This means, with DUMPGEN=y, old style is preserved
  unless an update becomes necessary.

This requires "json-pretty.sh" having stable output, as those files are
committed to git. This is probably fine.

Signed-off-by: Thomas Haller <thaller@redhat.com>
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agotests: shell: missing auto-merge in json output
Pablo Neira Ayuso [Wed, 7 Feb 2024 21:24:05 +0000 (22:24 +0100)] 
tests: shell: missing auto-merge in json output

Several tests reports DUMP_FAILED because it was missing the auto-merge
flag. That is, the original json dump was not correct. Update tests
accordingly now that json support provides an automerge flag.

Fixes: a4034c66b03e ("json: Support sets' auto-merge option")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 months agocache: Optimize caching for 'list tables' command
Phil Sutter [Tue, 6 Feb 2024 18:26:57 +0000 (19:26 +0100)] 
cache: Optimize caching for 'list tables' command

No point in fetching anything other than existing tables from kernel:
'list tables' merely prints existing table names, no contents.

Also populate filter's family field to reduce overhead when listing
tables in one family with many tables in another one. It works without
further adjustments because nftnl_nlmsg_build_hdr() will use the value
for nfgen_family.

Reported-by: anton.khazan@gmail.com
Link: https://bugzilla.netfilter.org/show_bug.cgi?id=1735
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agoMakefile.am: don't silence -Wimplicit-function-declaration
Sam James [Wed, 7 Feb 2024 02:12:35 +0000 (02:12 +0000)] 
Makefile.am: don't silence -Wimplicit-function-declaration

This becomes an error in GCC 14 and Clang 16. It's a common
misconception that these warnings are invalid or simply noise for
Bison/parser files, but even if that were true, we'd need to handle it
somehow anyway. Silencing them does nothing, so stop doing that.

Further, I don't actually get any warnings to fix with bison-3.8.2. This
mirrors changes we've done in other netfilter.org projects.

Signed-off-by: Sam James <sam@gentoo.org>
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agoevaluate: fix check for unknown in cmd_op_to_name
谢致邦 (XIE Zhibang) [Wed, 7 Feb 2024 15:10:20 +0000 (15:10 +0000)] 
evaluate: fix check for unknown in cmd_op_to_name

Example:
nft --debug=all destroy table ip missingtable

Before:
Evaluate unknown

After:
Evaluate destroy

Fixes: e1dfd5cc4c46 ("src: add support to command "destroy"")
Signed-off-by: 谢致邦 (XIE Zhibang) <Yeking@Red54.com>
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agoevaluate: don't assert on net/transport header conflict
Florian Westphal [Tue, 16 Jan 2024 14:21:00 +0000 (15:21 +0100)] 
evaluate: don't assert on net/transport header conflict

before:
nft: evaluate.c:467: conflict_resolution_gen_dependency: Assertion `expr->payload.base == PROTO_BASE_LL_HDR' failed.
Aborted (core dumped)

conflict_resolution_gen_dependency() can only handle linklayer
conflicts, hence the assert.

Rename it accordingly.  Also rename resolve_protocol_conflict, it doesn't
do anything for != PROTO_BASE_LL_HDR and extend the assertion to that
function too.

Callers now enforce PROTO_BASE_LL_HDR prerequisite.

after:
Error: conflicting transport layer protocols specified: comp vs. udp
 ip6 nexthdr comp udp dport 4789
                  ^^^^^^^^^

Signed-off-by: Florian Westphal <fw@strlen.de>
2 months agodatatype: display 0s time datatype
Pablo Neira Ayuso [Thu, 25 Jan 2024 16:31:45 +0000 (17:31 +0100)] 
datatype: display 0s time datatype

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 months agotests: shell: cover netns removal for netdev and inet/ingress basechains
Pablo Neira Ayuso [Thu, 18 Jan 2024 21:58:02 +0000 (22:58 +0100)] 
tests: shell: cover netns removal for netdev and inet/ingress basechains

Add two tests to exercise netns removal with netdev and inet/ingress
basechains.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 months agotests: shell: netdevice removal for inet family
Pablo Neira Ayuso [Thu, 18 Jan 2024 21:30:12 +0000 (22:30 +0100)] 
tests: shell: netdevice removal for inet family

cover netdevice removal when such netdevice belongs to basechain.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 months agojson: Support sets' auto-merge option
Phil Sutter [Wed, 31 Jan 2024 16:30:24 +0000 (17:30 +0100)] 
json: Support sets' auto-merge option

If enabled, list the option as additional attribute with boolean value.

Fixes: e70354f53e9f6 ("libnftables: Implement JSON output support")
Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1734
Signed-off-by: Phil Sutter <phil@nwl.cc>
3 months agotests: shell: add test to cover ct offload by using nft flowtables
Yi Chen [Mon, 22 Jan 2024 16:26:40 +0000 (00:26 +0800)] 
tests: shell: add test to cover ct offload by using nft flowtables

To cover kernel patch ("netfilter: nf_tables: set transport offset from mac header for netdev/egress").

Signed-off-by: Yi Chen <yiche@redhat.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agotests: py: remove huge-limit test cases
Florian Westphal [Thu, 18 Jan 2024 12:24:04 +0000 (13:24 +0100)] 
tests: py: remove huge-limit test cases

These tests will fail once the kernel checks for overflow
in the internal token bucken counter, so drop them.

Signed-off-by: Florian Westphal <fw@strlen.de>
3 months agorule: fix sym refcount assertion
Florian Westphal [Mon, 15 Jan 2024 13:27:15 +0000 (14:27 +0100)] 
rule: fix sym refcount assertion

Scope release must happen last.
afl provided a reproducer where policy is a define, because
scope is released too early we get:
nft: src/rule.c:559: scope_release: Assertion `sym->refcnt == 1' failed.

... because chain->policy is EXPR_SYMBOL.

Fixes: 627c451b2351 ("src: allow variables in the chain priority specification")
Signed-off-by: Florian Westphal <fw@strlen.de>
3 months agoevaluate: error out when store needs more than one 128bit register of align fixup
Florian Westphal [Mon, 15 Jan 2024 13:11:17 +0000 (14:11 +0100)] 
evaluate: error out when store needs more than one 128bit register of align fixup

Else this gives:
nft: evaluate.c:2983: stmt_evaluate_payload: Assertion `sizeof(data) * BITS_PER_BYTE >= masklen' failed.

For loads, this is already prevented via expr_evaluate_bits() which has:

  if (masklen > NFT_REG_SIZE * BITS_PER_BYTE)
      return expr_error(ctx->msgs, expr, "mask length %u exceeds allowed maximum of %u\n",
                        masklen, NFT_REG_SIZE * BITS_PER_BYTE);

But for the store path this isn't called.
The reproducer asks to store a 128 bit integer at bit offset 1, i.e.
17 bytes would need to be munged, but we can only handle up to 16 bytes
(one pseudo-register).

Fixes: 78936d50f306 ("evaluate: add support to set IPv6 non-byte header fields")
Signed-off-by: Florian Westphal <fw@strlen.de>
3 months agoparser: reject raw payload expressions with 0 length
Florian Westphal [Fri, 12 Jan 2024 12:27:23 +0000 (13:27 +0100)] 
parser: reject raw payload expressions with 0 length

Reject this at parser stage.  Fix up the json input side too, else
reproducer gives:
nft: src/netlink.c:243: netlink_gen_raw_data: Assertion `len > 0' failed.

Signed-off-by: Florian Westphal <fw@strlen.de>
3 months agopayload: only assert if l2 header base has no length
Florian Westphal [Thu, 11 Jan 2024 12:11:22 +0000 (13:11 +0100)] 
payload: only assert if l2 header base has no length

nftables will assert in some cases because the sanity check is done even
for network and transport header bases.

However, stacked headers are only supported for the link layer.
Move the assertion around and add a test case for this.

Signed-off-by: Florian Westphal <fw@strlen.de>
3 months agoevaluate: release mpz type in expr_evaluate_list() error path
Pablo Neira Ayuso [Thu, 11 Jan 2024 21:14:34 +0000 (22:14 +0100)] 
evaluate: release mpz type in expr_evaluate_list() error path

Detected when running:

 # nft -f tests/shell/testcases/bogons/nft-f/no_integer_basetype_crash
 ==383222==ERROR: LeakSanitizer: detected memory leaks

 Direct leak of 8 byte(s) in 1 object(s) allocated from:
    #0 0x7fe7b54a9e8f in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
    #1 0x7fe7b538b9a9 in __gmp_default_allocate (/lib/x86_64-linux-gnu/libgmp.so.10+0xc9a9)

Fixes: 3671c4897003 ("evaluate: guard against NULL basetype")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agoevaluate: release key expression in error path of implicit map with unknown datatype
Pablo Neira Ayuso [Thu, 11 Jan 2024 21:04:27 +0000 (22:04 +0100)] 
evaluate: release key expression in error path of implicit map with unknown datatype

Detected when running:

 # nft -f tests/shell/testcases/bogons/nft-f/mapping_with_invalid_datatype_crash
 ==382584==ERROR: LeakSanitizer: detected memory leaks

 Direct leak of 144 byte(s) in 1 object(s) allocated from:
    #0 0x7fde06ca9e8f in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
    #1 0x7fde062924af in xmalloc src/utils.c:31
    #2 0x7fde0629266c in xzalloc src/utils.c:70
    #3 0x7fde06167299 in expr_alloc src/expression.c:46
    #4 0x7fde0616b014 in constant_expr_alloc src/expression.c:420
    #5 0x7fde06128e43 in expr_evaluate_map src/evaluate.c:2027
    #6 0x7fde06137b06 in expr_evaluate src/evaluate.c:2891
    #7 0x7fde06132417 in expr_evaluate_relational src/evaluate.c:2497
    #8 0x7fde06137b36 in expr_evaluate src/evaluate.c:2895
    #9 0x7fde06137d5f in stmt_evaluate_expr src/evaluate.c:2914
    #10 0x7fde061524c8 in stmt_evaluate src/evaluate.c:4646
    #11 0x7fde0615c9ee in rule_evaluate src/evaluate.c:5202
    #12 0x7fde061600c7 in cmd_evaluate_add src/evaluate.c:5422

Fixes: 70054e6e1c87 ("evaluate: catch implicit map expressions without known datatype")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agoevaluate: bail out if anonymous concat set defines a non concat expression
Pablo Neira Ayuso [Wed, 10 Jan 2024 18:05:35 +0000 (19:05 +0100)] 
evaluate: bail out if anonymous concat set defines a non concat expression

Iterate over the element list in the anonymous set to validate that all
expressions are concatenations, otherwise bail out.

  ruleset.nft:3:46-53: Error: expression is not a concatenation
               ip protocol . th dport vmap { tcp / 22 : accept, tcp . 80 : drop}
                                             ^^^^^^^^

This is based on a patch from Florian Westphal.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agoevaluate: do not fetch next expression on runaway number of concatenation components
Pablo Neira Ayuso [Wed, 10 Jan 2024 17:20:47 +0000 (18:20 +0100)] 
evaluate: do not fetch next expression on runaway number of concatenation components

If this is the last expression, then the runaway flag is set on and
evaluation bails in the next iteration, do not fetch next list element
which refers to the list head.

I found this by code inspection, I could not trigger any crash with this
one.

Fixes: ae1d54d1343f ("evaluate: do not crash on runaway number of concatenation components")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agoevaluate: skip anonymous set optimization for concatenations
Pablo Neira Ayuso [Wed, 10 Jan 2024 17:18:50 +0000 (18:18 +0100)] 
evaluate: skip anonymous set optimization for concatenations

Concatenation is only supported with sets. Moreover, stripping of the
set leads to broken ruleset listing, therefore, skip this optimization
for the concatenations.

Fixes: fa17b17ea74a ("evaluate: revisit anonymous set with single element optimization")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agoevaluate: add missing range checks for dup,fwd and payload statements
Florian Westphal [Thu, 11 Jan 2024 17:14:16 +0000 (18:14 +0100)] 
evaluate: add missing range checks for dup,fwd and payload statements

Else we assert with:
BUG: unknown expression type range
nft: src/netlink_linearize.c:912: netlink_gen_expr: Assertion `0' failed.

While at it, condense meta and exthdr to reuse the same helper.

Signed-off-by: Florian Westphal <fw@strlen.de>
3 months agoevaluate: tproxy: move range error checks after arg evaluation
Florian Westphal [Thu, 11 Jan 2024 17:14:15 +0000 (18:14 +0100)] 
evaluate: tproxy: move range error checks after arg evaluation

Testing for range before evaluation will still crash us later during
netlink linearization, prefixes turn into ranges, symbolic expression
might hide a range/prefix.

So move this after the argument has been evaluated.

Signed-off-by: Florian Westphal <fw@strlen.de>
3 months agoevaluate: error out when expression has no datatype
Florian Westphal [Thu, 11 Jan 2024 15:57:28 +0000 (16:57 +0100)] 
evaluate: error out when expression has no datatype

add rule ip6 f i rt2 addr . ip6 daddr  { dead:: . dead:: }

... will cause a segmentation fault, we assume expr->dtype is always
set.

rt2 support is incomplete, the template is uninitialised.

This could be fixed up, but rt2 (a subset of the deperecated type 0),
like all other routing headers, lacks correct dependency tracking.

Currently such routing headers are always assumed to be segment routing
headers, we would need to add dependency on 'Routing Type' field in the
routing header, similar to icmp type/code.

Signed-off-by: Florian Westphal <fw@strlen.de>
3 months agodoc: clarify reject is supported at prerouting stage
Quan Tian [Wed, 10 Jan 2024 04:30:59 +0000 (04:30 +0000)] 
doc: clarify reject is supported at prerouting stage

It's supported since kernel commit f53b9b0bdc59 ("netfilter: introduce
support for reject at prerouting stage").

Reported-by: Dan Winship <danwinship@redhat.com>
Signed-off-by: Quan Tian <tianquan23@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agodoc: incorrect datatype description for icmpv6_type and icmpvx_code
Pablo Neira Ayuso [Tue, 9 Jan 2024 11:42:20 +0000 (12:42 +0100)] 
doc: incorrect datatype description for icmpv6_type and icmpvx_code

Fix incorrect description in manpage:

 ICMPV6 TYPE TYPE is icmpv6_type
 ICMPVX CODE TYPE is icmpx_code

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agotests: shell: extend coverage for netdevice removal
Pablo Neira Ayuso [Thu, 4 Jan 2024 23:48:33 +0000 (00:48 +0100)] 
tests: shell: extend coverage for netdevice removal

Add two extra tests to exercise netdevice removal path.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agotests: add a test case for double-flush bug in pipapo
Florian Westphal [Fri, 1 Dec 2023 14:49:18 +0000 (15:49 +0100)] 
tests: add a test case for double-flush bug in pipapo

Test for
'netfilter: nft_set_pipapo: skip inactive elements during set walk'.

Reported-by: Xingyuan Mo <hdthky0@gmail.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
3 months agodatatype: do not assert when value exceeds expected width
Florian Westphal [Fri, 22 Dec 2023 14:30:09 +0000 (15:30 +0100)] 
datatype: do not assert when value exceeds expected width

Inputs:
ip protocol . th dport { tcp / 22,  }'
or
th dport . ip protocol { tcp / 22,  }'

are not rejected at this time. 'list ruleset' yields:
 ip protocol & nft: src/gmputil.c:77: mpz_get_uint8: Assertion `cnt <= 1' failed.
or
 th dport & nft: src/gmputil.c:87: mpz_get_be16: Assertion `cnt <= 1' failed.

While this should be caught at input too, the print path should be more
robust, e.g. when there are direct nfnetlink users.

After this patch, the print functions fall back to
'integer_type_print' which can handle large numbers too.

Note that the output printed this way cannot be read back by nft;
it will dump something like:

  tcp dport & 18446739675663040512 . ip protocol 0 . 0

but thats better than assert().

v2: same problem exists for service too.

Signed-off-by: Florian Westphal <fw@strlen.de>
3 months agotests: shell: prefer project nft to system-wide nft
Florian Westphal [Sat, 6 Jan 2024 12:23:24 +0000 (13:23 +0100)] 
tests: shell: prefer project nft to system-wide nft

Use $NFT (src/nft, in-tree binary), not the one installed by the distro.
Else we may not find newly added bugs unless user did "make install" or
bug has propagated to release.

Signed-off-by: Florian Westphal <fw@strlen.de>
3 months agodatatype: Describe rt symbol tables
Phil Sutter [Fri, 22 Dec 2023 16:00:44 +0000 (17:00 +0100)] 
datatype: Describe rt symbol tables

Implement a symbol_table_print() wrapper for the run-time populated
rt_symbol_tables which formats output similar to expr_describe() and
includes the data source.

Since these tables reside in struct output_ctx there is no implicit
connection between data type and therefore providing callbacks for
relevant datat types which feed the data into said wrapper is a simpler
solution than extending expr_describe() itself.

Signed-off-by: Phil Sutter <phil@nwl.cc>
3 months agodatatype: Initialize rt_symbol_tables' base field
Phil Sutter [Fri, 22 Dec 2023 15:53:14 +0000 (16:53 +0100)] 
datatype: Initialize rt_symbol_tables' base field

It is unconditionally accessed in symbol_table_print() so make sure it
is initialized to either BASE_DECIMAL (arbitrary) for empty or
non-existent source files or a proper value depending on entry number
format.

Signed-off-by: Phil Sutter <phil@nwl.cc>
3 months agodatatype: rt_symbol_table_init() to search for iproute2 configs
Phil Sutter [Fri, 15 Dec 2023 20:59:44 +0000 (21:59 +0100)] 
datatype: rt_symbol_table_init() to search for iproute2 configs

There is an ongoing effort among various distributions to tidy up in
/etc. The idea is to reduce contents to just what the admin manually
inserted to customize the system, anything else shall move out to /usr
(or so). The various files in /etc/iproute2 fall in that category as
they are seldomly modified.

The crux is though that iproute2 project seems not quite sure yet where
the files should go. While v6.6.0 installs them into /usr/lib/iproute2,
current mast^Wmain branch uses /usr/share/iproute2. Assume this is going
to stay as /(usr/)lib does not seem right for such files.

Note that rt_symbol_table_init() is not just used for
iproute2-maintained configs but also for connlabel.conf - so retain the
old behaviour when passed an absolute path.

Signed-off-by: Phil Sutter <phil@nwl.cc>
4 months agoparser_bison: ensure all timeout policy names are released
Florian Westphal [Tue, 12 Dec 2023 12:32:24 +0000 (13:32 +0100)] 
parser_bison: ensure all timeout policy names are released

We need to add a custom destructor for this structure, it
contains the dynamically allocated names.

a:5:55-55: Error: syntax error, unexpected '}', expecting string
policy = { estabQisheestablished : 2m3s, cd : 2m3s, }

==562373==ERROR: LeakSanitizer: detected memory leaks

Indirect leak of 160 byte(s) in 2 object(s) allocated from:
    #1 0x5a565b in xmalloc src/utils.c:31:8
    #2 0x5a565b in xzalloc src/utils.c:70:8
    #3 0x3d9352 in nft_parse_bison_filename src/libnftables.c:520:8
[..]

Fixes: c7c94802679c ("src: add ct timeout support")
Signed-off-by: Florian Westphal <fw@strlen.de>