]> git.ipfire.org Git - thirdparty/nftables.git/log
thirdparty/nftables.git
15 hours agomain: consolidate EPERM to non-root users master
Pablo Neira Ayuso [Wed, 8 Apr 2026 11:05:18 +0000 (13:05 +0200)] 
main: consolidate EPERM to non-root users

Move the check added by 3cfb9e4b3e40 ("src: report EPERM for non-root users")
to the main function.

EPERM is also possible when removing a ruleset that is owned by a
process, tone it down to suggest that root is maybe needed.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
15 hours agodoc: ct count should be restricted via new
Florian Westphal [Thu, 9 Apr 2026 11:57:53 +0000 (13:57 +0200)] 
doc: ct count should be restricted via new

Not doing it will affect existing flows, which is likely not wanted.

Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 weeks agomnl: Fix ordering of hooks in 'list hooks' output
Phil Sutter [Fri, 20 Mar 2026 12:30:52 +0000 (13:30 +0100)] 
mnl: Fix ordering of hooks in 'list hooks' output

Hooks with same family, basehook and priority were inadvertently
inserted into the list in reverse ordering, fix that.

Suggested-by: Florian Westphal <fw@strlen.de>
Fixes: b98fee20bfe23 ("mnl: revisit hook listing")
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 weeks agosegtree: Fix for variable-sized object may not be initialized
Phil Sutter [Wed, 18 Mar 2026 21:05:34 +0000 (22:05 +0100)] 
segtree: Fix for variable-sized object may not be initialized

Seen with gcc-11.5.0 on an aarch64 machine, build failed. Looking at the
code, r1len (or r1->len, actually) really seems variable. So use
memset() and fix build for that older compiler version at least.

Fixes: e8b17865833b8 ("segtree: Fix range aggregation on Big Endian")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Acked-by: Florian Westphal <fw@strlen.de>
2 weeks agoparser: Support table spec in 'list chains' command
Phil Sutter [Thu, 12 Mar 2026 11:17:37 +0000 (12:17 +0100)] 
parser: Support table spec in 'list chains' command

Make it possible for users to list all chains in a given table.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Acked-by: Florian Westphal <fw@strlen.de>
3 weeks agocache: Filter for table when listing flowtables
Phil Sutter [Wed, 25 Feb 2026 20:07:32 +0000 (21:07 +0100)] 
cache: Filter for table when listing flowtables

Respect an optionally specified table name to filter listed flowtables
to by populating the filter accordingly.

Fixes: a1a6b0a5c3c4 ("cache: finer grain cache population for list commands")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
Tested-by: Eric Garver <eric@garver.life>
3 weeks agocache: Filter for table when listing sets or maps
Phil Sutter [Sat, 14 Feb 2026 14:02:04 +0000 (15:02 +0100)] 
cache: Filter for table when listing sets or maps

Respect an optionally specified table name to filter listed sets or maps
to by populating the filter accordingly.

Fixes: a1a6b0a5c3c4 ("cache: finer grain cache population for list commands")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
Tested-by: Eric Garver <eric@garver.life>
3 weeks agocache: Relax chain_cache_dump filter application
Phil Sutter [Fri, 6 Mar 2026 16:02:17 +0000 (17:02 +0100)] 
cache: Relax chain_cache_dump filter application

While populating chain cache, a filter was only effective if it limited
fetching to both a table and a chain. Make it apply to 'list chains'
command as well which at most specifies a family and table.

Since the code is OK with filter->list fields being NULL, merely check
for filter to be non-NULL (which is the case if nft_cache_update() is
called by nft_cmd_enoent_chain()).

Fixes: 17297d1acbbf ("cache: Filter chain list on kernel side")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
Tested-by: Eric Garver <eric@garver.life>
3 weeks agocache: Respect family in all list commands
Phil Sutter [Sat, 14 Feb 2026 13:58:03 +0000 (14:58 +0100)] 
cache: Respect family in all list commands

Some list commands did not set filter->list.family even if one was given
on command line, fix this.

Fixes: b3ed8fd8c9f33 ("cache: missing family in cache filtering")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
Tested-by: Eric Garver <eric@garver.life>
3 weeks agocache: Include chains, flowtables and objects in netlink debug output
Phil Sutter [Wed, 25 Feb 2026 19:16:57 +0000 (20:16 +0100)] 
cache: Include chains, flowtables and objects in netlink debug output

In order to test cache filter effectiveness, netlink debug output is
useful as it shows what is actually received from the kernel and maybe
discarded immediately by user space. Therefore add dump calls for these
rule set elements as well.

While at it, move the netlink_dump_rule() call to an earlier spot,
namely into the nft_mnl_talk() callback to match other netlink dump
calls.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Tested-by: Eric Garver <eric@garver.life>
3 weeks agoparser_bison: add range check for synproxy wscale
Florian Westphal [Wed, 11 Mar 2026 17:52:31 +0000 (18:52 +0100)] 
parser_bison: add range check for synproxy wscale

After: nft -f wscale
Error: wscale must be in range 0-14
 wscale 15
        ^^

As-is the bogus value makes it to the kernel. Upcoming nf-next patch
adds futher checks to value attributes and will reject this.

Also catch this from parser and fix the single_flag test case.

Signed-off-by: Florian Westphal <fw@strlen.de>
3 weeks agobetter reload tests for rbtree, pipapo
Florian Westphal [Sat, 7 Mar 2026 19:55:36 +0000 (20:55 +0100)] 
better reload tests for rbtree, pipapo

3 weeks agoRevert "tests: py: use `os.unshare` Python function"
Phil Sutter [Fri, 13 Mar 2026 10:36:20 +0000 (11:36 +0100)] 
Revert "tests: py: use `os.unshare` Python function"

This reverts commit c29407ab300f8ed54b5ca27cf4837c0aab920760.

This change breaks 'time' expression tests in py test suite. It looks
like with os.unshare, modifications to os.environ are lost. Neither
unshare module nor unshare command suffer from this problem.

Fixes: c29407ab300f8 ("tests: py: use `os.unshare` Python function")
Suggested-by: Jeremy Sowden <jeremy@azazel.net>
Suggested-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Phil Sutter <phil@nwl.cc>
4 weeks agotests: shell: add rbtree reload test case
Florian Westphal [Mon, 9 Mar 2026 15:40:52 +0000 (16:40 +0100)] 
tests: shell: add rbtree reload test case

Generate a random interval set, then flush and reload it a few times.
Note that this test fails with several up-to-date distros that lack
nft commit e83e32c8d1cd ("mnl: restore create element command with large batches").

This hints that we will likely need to revert
648946966a08 ("netfilter: nft_set_rbtree: validate open interval overlap") soon,
or risk major breakage in most current distros .

Signed-off-by: Florian Westphal <fw@strlen.de>
5 weeks agotests: py: use `os.unshare` Python function
Jeremy Sowden [Thu, 5 Mar 2026 17:53:58 +0000 (17:53 +0000)] 
tests: py: use `os.unshare` Python function

Since Python 3.12 the standard library has included an `os.unshare` function.
Use it if it is available.

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Phil Sutter <phil@nwl.cc>
6 weeks agomnl: restore nft monitor to working state
Florian Westphal [Wed, 25 Feb 2026 11:05:40 +0000 (12:05 +0100)] 
mnl: restore nft monitor to working state

monitor tests are currently broken:
./run-tests.sh: line 60:  6490 Aborted                    $nft -nn monitor $monitor_args > $monitor_output
*** bit out of range 0 - FD_SETSIZE on fd_set ***: terminated

Fixes: 868040f89223 ("configure: Implement --enable-profiling option")
Signed-off-by: Florian Westphal <fw@strlen.de>
6 weeks agoRevert "main: refuse to run under file capabilities"
Florian Westphal [Mon, 23 Feb 2026 22:42:12 +0000 (23:42 +0100)] 
Revert "main: refuse to run under file capabilities"

This reverts commit badb2474ca8bd6427255cf0a9886cdca49a5c3b7.

The new iptables 1.8.12 release is broken on docker, pinpointed to the
getauxval() change that apparently can be nonzero in presence of LSMs.

That makes getauxval() useless for the purpose of detecting a setcap
binary.  As nftables contains a change just like iptables, it is safe to
assume nftables is broken as well.

So revert this.

Bugzilla: https://bugzilla.netfilter.org/show_bug.cgi?id=1830
Signed-off-by: Florian Westphal <fw@strlen.de>
7 weeks agoTree-wide use of python3
Pablo Neira Ayuso [Mon, 16 Feb 2026 17:23:35 +0000 (18:23 +0100)] 
Tree-wide use of python3

It seems that unversioned Python shebangs are discouraged these days:

- See the lintian web on Debian:
  https://lintian.debian.org/tags/script-uses-unversioned-python-in-shebang.html

- Also, see "Finalizing Fedora's Switch to Python3":
  https://fedoraproject.org/wiki/FinalizingFedoraSwitchtoPython3

Replace them all tree-wide.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
7 weeks agojson: complete multi-statement set element support
Pablo Neira Ayuso [Mon, 16 Feb 2026 11:26:45 +0000 (12:26 +0100)] 
json: complete multi-statement set element support

Remove artificial limitation on the maximum number of statements per
element in listings.

Moreover, update tests/shell which are currently incorrect.

Fixes: e6d1d0d61195 ("src: add set element multi-statement support")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
7 weeks agotests: shell: set_flush_add_atomic_rbtree: tweak test to make it fail again
Florian Westphal [Mon, 16 Feb 2026 16:17:40 +0000 (17:17 +0100)] 
tests: shell: set_flush_add_atomic_rbtree: tweak test to make it fail again

Test for kernel commit
7e43e0a1141d ("netfilter: nft_set_rbtree: translate rbtree to array for binary search").

Rbtree rebalance might cause datapath to miss an existing interval.

Signed-off-by: Florian Westphal <fw@strlen.de>
7 weeks agotests: shell: extend interval overlap test
Florian Westphal [Mon, 16 Feb 2026 16:17:40 +0000 (17:17 +0100)] 
tests: shell: extend interval overlap test

Extend this with cases covered in kernel commit
7711f4bb4b36 ("netfilter: nft_set_pipapo: fix range overlap detection").

Signed-off-by: Florian Westphal <fw@strlen.de>
7 weeks agotests: shell: add regression test for catchall chain count restore
Florian Westphal [Wed, 4 Feb 2026 18:36:23 +0000 (19:36 +0100)] 
tests: shell: add regression test for catchall chain count restore

When deleting a map that has a catchall element that jumps to a chain,
the chain use counter is decremented.  In case this drops the use
counter to 0, the chain can be queued for removal.

This decrement has to be un-done in case the transaction is aborted.

Otherwise the chain use counter in this test remains at 0 and the
deletion of the live/in-use chain will work, even though its referenced
from the catchall element.

This results in a use-after-free.

Reported-by: Andrew Fasano <andrew.fasano@nist.gov>
Signed-off-by: Florian Westphal <fw@strlen.de>
7 weeks agomain: refuse to run under file capabilities
Alan Ross [Fri, 13 Feb 2026 22:53:23 +0000 (17:53 -0500)] 
main: refuse to run under file capabilities

Extend the existing setuid guard in main() to also detect
file capabilities via getauxval(AT_SECURE).

Some container runtimes and minimal distributions grant cap_net_admin
via file capabilities (setcap cap_net_admin+ep /usr/sbin/nft)
rather than running through sudo.  In that configuration the kernel
sets AT_SECURE and the dynamic linker strips LD_PRELOAD, but
getuid() == geteuid() so the existing setuid check passes.

CAP_NET_ADMIN is quite powerful; even without dlopen(), we should not
sanction setcap-installations — a control flow bug could still be
exploited as the capability-elevated user.

getauxval(AT_SECURE) is nonzero whenever the kernel has set AT_SECURE
in the auxiliary vector — this covers both classic setuid/setgid and
file capabilities.  Exit with status 111, matching the existing
setuid behavior.

Signed-off-by: Alan Ross <alan@sleuthco.ai>
Signed-off-by: Florian Westphal <fw@strlen.de>
7 weeks agoconfigure: Implement --enable-profiling option
Phil Sutter [Fri, 23 Jan 2026 00:38:20 +0000 (01:38 +0100)] 
configure: Implement --enable-profiling option

This will set compiler flag --coverage so code coverage may be inspected
using gcov.

In order to successfully profile processes which are killed or
interrupted as well, add a signal handler for those cases which calls
exit(). This is relevant for test cases invoking nft monitor.

Signed-off-by: Phil Sutter <phil@nwl.cc>
8 weeks agoMakefile: Pass PKG_CONFIG_PATH to internal builds
Phil Sutter [Thu, 5 Feb 2026 14:38:17 +0000 (15:38 +0100)] 
Makefile: Pass PKG_CONFIG_PATH to internal builds

When building nftables git HEAD, I use a script which also builds libmnl
and libnftnl in their respective repositories and populates
PKG_CONFIG_PATH variable so nftables is linked against them instead of
host libraries. This is mandatory as host-installed libraries are
chronically outdated and linking against them would fail.

Pass this variable to build test suite as well as the VPATH build
performed by distcheck target based on the presumption that if a custom
PKG_CONFIG_PATH was needed for the main build, these derived builds will
need it as well.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agoevaluate: skip EXPR_SET_ELEM in error path of set statements
Pablo Neira Ayuso [Thu, 5 Feb 2026 02:41:29 +0000 (03:41 +0100)] 
evaluate: skip EXPR_SET_ELEM in error path of set statements

Use the key value directly, skip EXPR_SET_ELEM indirection.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agoevaluate: remove check for constant expression in set/map statement
Pablo Neira Ayuso [Thu, 5 Feb 2026 02:41:28 +0000 (03:41 +0100)] 
evaluate: remove check for constant expression in set/map statement

a8260c056a69 ("tests: add dynmap datapath add/delete test case") proves
this is indeed supported, remove these checks.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agosegtree: use set->key->byteorder instead of expr->byteorder
Pablo Neira Ayuso [Thu, 5 Feb 2026 02:41:27 +0000 (03:41 +0100)] 
segtree: use set->key->byteorder instead of expr->byteorder

For consistency, use the set key byteorder in get_set_intervals().

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agosegtree: consolidate calls to expr_value() to fetch the element key
Pablo Neira Ayuso [Thu, 5 Feb 2026 02:41:26 +0000 (03:41 +0100)] 
segtree: consolidate calls to expr_value() to fetch the element key

Consolidate calls to expr_value() so the key is fetched only once.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agosegtree: replace default case by specific types in get_set_intervals()
Pablo Neira Ayuso [Thu, 5 Feb 2026 02:41:25 +0000 (03:41 +0100)] 
segtree: replace default case by specific types in get_set_intervals()

Use specific types, so default case can be left for catching bugs.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agosegtree: disentangle concat_range_aggregate()
Pablo Neira Ayuso [Thu, 5 Feb 2026 02:41:24 +0000 (03:41 +0100)] 
segtree: disentangle concat_range_aggregate()

Consolidate calls to expr_value() in concat_range_aggregate() to
simplify this code.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agosegtree: remove dead code in set_expr_add_splice()
Pablo Neira Ayuso [Thu, 5 Feb 2026 02:41:23 +0000 (03:41 +0100)] 
segtree: remove dead code in set_expr_add_splice()

If get_set_interval_find() always returns EXPR_SET_ELEM, then,
set_expr_add_splice() always takes EXPR_SET_ELEM.

This reworks:

  2b164aec4295 ("src: fix reset element support for interval set type")

which does _not_ seem to have a tests/shell unit.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agosegtree: more assert on EXPR_SET_ELEM
Pablo Neira Ayuso [Thu, 5 Feb 2026 02:41:22 +0000 (03:41 +0100)] 
segtree: more assert on EXPR_SET_ELEM

More EXPR_SET_ELEM validation, for correctness, to prepare the removal
of this expression.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agosegtree: remove EXPR_VALUE from expr_value()
Pablo Neira Ayuso [Thu, 5 Feb 2026 02:41:21 +0000 (03:41 +0100)] 
segtree: remove EXPR_VALUE from expr_value()

Rework the following commit:

 7e6be917987c ("segtree: fix decomposition of unclosed intervals containing address prefixes")

this allows to add an assert(expr->etype == EXPR_SET_ELEM), in order to
normalize the input.

The closed flag tells us if this interval is represented with two
element or only one (as an open interval).

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agosrc: move __set_expr_add() to src/intervals.c
Pablo Neira Ayuso [Thu, 5 Feb 2026 02:41:20 +0000 (03:41 +0100)] 
src: move __set_expr_add() to src/intervals.c

Where this is only used.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agointervals: remove interval_expr_key()
Pablo Neira Ayuso [Thu, 5 Feb 2026 02:41:19 +0000 (03:41 +0100)] 
intervals: remove interval_expr_key()

Since ("src: normalize set element with EXPR_MAPPING"), this became an
empty shim function, remove it.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agosrc: use key location to prepare removal of EXPR_SET_ELEM
Pablo Neira Ayuso [Thu, 5 Feb 2026 02:41:18 +0000 (03:41 +0100)] 
src: use key location to prepare removal of EXPR_SET_ELEM

Again, to prepare for the removal of EXPR_SET_ELEM, use the key
location instead.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agosrc: remove EXPR_SET_ELEM in range_expr_value_{low,high}()
Pablo Neira Ayuso [Thu, 5 Feb 2026 02:41:17 +0000 (03:41 +0100)] 
src: remove EXPR_SET_ELEM in range_expr_value_{low,high}()

Call range_expr_value_{low,high}() with the key instead to skip one
level of indirection.

This is to prepare for the future removal of EXPR_SET_ELEM.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agosrc: move flags from EXPR_SET_ELEM to key
Pablo Neira Ayuso [Thu, 5 Feb 2026 02:41:16 +0000 (03:41 +0100)] 
src: move flags from EXPR_SET_ELEM to key

This is to prepare to replace EXPR_SET_ELEM by struct set_elem.

Check that expr->flags for EXPR_SET_ELEM are zero from
set_elem_expr_destroy() to validate that there are no more users.

Only EXPR_F_KERNEL is taken in interval.c when converting to constant,
prefix and range in __setelem_expr_to_range().

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agosegtree: rename set_elem_add() to set_elem_expr_add()
Pablo Neira Ayuso [Thu, 5 Feb 2026 02:41:15 +0000 (03:41 +0100)] 
segtree: rename set_elem_add() to set_elem_expr_add()

Just a clean up, to prepare for the introduction of struct set_elem
that will provide a set_elem_add() function again.

Rename it now to leave room for such future change.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agoevaluate: clean up expr_evaluate_set()
Pablo Neira Ayuso [Thu, 5 Feb 2026 02:41:14 +0000 (03:41 +0100)] 
evaluate: clean up expr_evaluate_set()

Remove redundant check for elem->etype == EXPR_SET_ELEM, assert()
already validates this at the beginning of the loop.

Remove redundant pointer to set element, use iterator index instead.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agoevaluate: simplify sets as set elems evaluation
Pablo Neira Ayuso [Thu, 5 Feb 2026 02:41:13 +0000 (03:41 +0100)] 
evaluate: simplify sets as set elems evaluation

After normalizing set element representation for EXPR_MAPPING, it is
possible to simplify:

  a6b75b837f5e ("evaluate: set: Allow for set elems to be sets")

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agosrc: assert on EXPR_SET only contains EXPR_SET_ELEM in the expressions list
Pablo Neira Ayuso [Thu, 5 Feb 2026 02:41:12 +0000 (03:41 +0100)] 
src: assert on EXPR_SET only contains EXPR_SET_ELEM in the expressions list

Add assert() to validate that expression lists contain EXPR_SET_ELEM.
This allows to detect potential subtle bugs when dereferencing struct
expr.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agosrc: allocate EXPR_SET_ELEM for EXPR_SET in embedded set declaration in sets
Pablo Neira Ayuso [Thu, 5 Feb 2026 02:41:11 +0000 (03:41 +0100)] 
src: allocate EXPR_SET_ELEM for EXPR_SET in embedded set declaration in sets

Normalize the representation so the expressions list in EXPR_SET always
contains EXPR_SET_ELEM. Add assert() to validate this.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agosrc: normalize set element with EXPR_MAPPING
Pablo Neira Ayuso [Thu, 5 Feb 2026 02:41:10 +0000 (03:41 +0100)] 
src: normalize set element with EXPR_MAPPING

EXPR_SET_ELEM provides the timeout, expiration, comment and list of
statements, this is a shim expression.

Currently, expr_set(x)->expressions can have either:

- EXPR_SET_ELEM

        EXPR_SET_ELEM -> EXPR_VALUE

- EXPR_MAPPING, which contains EXPR_SET_ELEM in the lhs.

                      EXPR_SET_ELEM -> EXPR_VALUE
                     /
EXPR_MAPPING |
                     \
                      EXPR_VALUE

This patch normalizes the expression for mappings:

                                       EXPR_VALUE
                                      /
EXPR_SET_ELEM -> EXPR_MAPPING |
                                      \
                                       EXPR_VALUE

The previous representation makes it natural for expr_print() to print the
timeout, expiration, statements and comments.

1.1.1.1 counter packets 1 bytes 564 : 0x00000001,

This patch adds an exception for expr_mapping_print() to stick to the
existing representation.

The JSON representation provides this set element information too in the
lhs, which is does not really belong there because it is exposing
transparently the syntax tree for set elements. A workaround to retain
compatibility is included in this patch.

The end goal is to replace EXPR_SET_ELEM by a smaller shim object, to
further reduce memory consumption in set elements in userspace.

This is preparation work that is required to reduce memory footprint
with sets and maps.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
8 weeks agotest: shell: run-test.sh: introduce NFT_TEST_EXCLUDES
Yi Chen [Wed, 4 Feb 2026 14:49:40 +0000 (22:49 +0800)] 
test: shell: run-test.sh: introduce NFT_TEST_EXCLUDES

Introduce the NFT_TEST_EXCLUDES environment variable to allow excluding
one or more specific test cases.

Some patches may be considered too aggressive to backport to
downstream releases.  For example,

  tests/shell/testcases/packetpath/reject_loopback

... fails on all downstream kernels that lack
"netfilter: nf_reject: don't reply to ICMP error messages", but such patch
might be considered too intrusive for some distributions.

This allows downstream CI to just skip these tests without local modifications.

It also allows to exclude all known and expected SKIP subtests which
allows to detect newly introduced SKIP items, which may indicate new bugs.

Signed-off-by: Yi Chen <yiche@redhat.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
2 months agotests: shell: Add a basic test for src/xt.c
Phil Sutter [Fri, 23 Jan 2026 17:29:02 +0000 (18:29 +0100)] 
tests: shell: Add a basic test for src/xt.c

The feature test introduced in this patch checks iptables-nft presence
and usability as well as translation support presence in nft (as it may
not be compiled in).

The actual test case will optionally call ip6tables-nft and ebtables-nft
as well.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agoxt: Print comment match data as well
Phil Sutter [Fri, 23 Jan 2026 00:21:21 +0000 (01:21 +0100)] 
xt: Print comment match data as well

In order to translate comment matches into the single nftables rule
comment, libxtables does not immediately (maybe mid-rule) print a
comment match's string but instead stores it into struct
xt_xlate::comment array for later.

Since xt_stmt_xlate() is called by a statement's .print callback which
can't communicate data back to caller, nftables has to print it right
away.

Since parser_bison accepts rule comments only at end of line though, the
output from above can't be restored anymore. Which is a bad idea to
begin with so accept this quirk and avoid refactoring the statement
printing API.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agotests: shell: Add a simple test for nftrace
Phil Sutter [Wed, 21 Jan 2026 20:43:43 +0000 (21:43 +0100)] 
tests: shell: Add a simple test for nftrace

The test suites did not cover src/trace.c at all. This test touches over
90% of its lines.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agodoc: nft.8: Describe iface_type data type
Phil Sutter [Thu, 18 Dec 2025 12:55:23 +0000 (13:55 +0100)] 
doc: nft.8: Describe iface_type data type

An entry in data-types.txt offers space for a name-value table. Even if
one would refer to ARPHRD_*, some names are not derived from the
respective macro name and thus not intuitive.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agotests: shell: double chain update with same device
Pablo Neira Ayuso [Thu, 5 Feb 2026 02:31:18 +0000 (03:31 +0100)] 
tests: shell: double chain update with same device

For Linux kernel patch:

  cf5fb87fcdaa ("netfilter: nf_tables: reject duplicate device on updates")

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
2 months agotests: py: Adjust payloads to changed userdata printing
Phil Sutter [Thu, 29 Jan 2026 13:49:17 +0000 (14:49 +0100)] 
tests: py: Adjust payloads to changed userdata printing

libnftnl no longer prints userdata content but merely its size and a sum
of all bytes.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agotests: shell: named_limits: minor tweak to ease debugging
Florian Westphal [Fri, 30 Jan 2026 12:29:39 +0000 (13:29 +0100)] 
tests: shell: named_limits: minor tweak to ease debugging

Make it easier to see where this test failed and dump the
ruleset on error.

Signed-off-by: Florian Westphal <fw@strlen.de>
2 months agotests: shell: add test case for interval set with timeout and aborted transaction
Florian Westphal [Wed, 28 Jan 2026 23:07:18 +0000 (00:07 +0100)] 
tests: shell: add test case for interval set with timeout and aborted transaction

Add a regression test for rbtree+bsearch getting out-of-sync in
nf-next kernel.

This covers the syzkaller reproducer from
https://syzkaller.appspot.com/bug?extid=d417922a3e7935517ef6
which triggers abort with earlier gc at insert time and additional corner
case where transaction passes without recording a relevant change in the set
(i.e. no call to either abort or commit).

This test passes even on buggy kernels unless KASAN is enabled.

Signed-off-by: Florian Westphal <fw@strlen.de>
2 months agobuild: support `SOURCE_DATE_EPOCH` for build time-stamp
Jeremy Sowden [Wed, 28 Jan 2026 18:31:07 +0000 (18:31 +0000)] 
build: support `SOURCE_DATE_EPOCH` for build time-stamp

In order to support reproducible builds, set the build time-stamp to the value
of the environment variable, `SOURCE_DATE_EPOCH`, if set, and fall back to
calling `date`, otherwise.

Link: https://reproducible-builds.org/docs/source-date-epoch/
Fixes: 64c07e38f049 ("table: Embed creating nft version into userdata")
Reported-by: Arnout Engelen <arnout@bzzt.net>
Closes: https://github.com/NixOS/nixpkgs/issues/478048
Suggested-by: Philipp Bartsch <phil@grmr.de>
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agobuild: generate build time-stamp once at configure
Jeremy Sowden [Wed, 28 Jan 2026 18:31:06 +0000 (18:31 +0000)] 
build: generate build time-stamp once at configure

The existing implementation tries to generate a time-stamp once when make is
run.  However, it doesn't work and generates one for every compilation.  Getting
this right portably in automake is not straightforward.  Instead, do it when
configure is run.

Rename the time-stamp variable since it is no longer generated by make.

Fixes: 64c07e38f049 ("table: Embed creating nft version into userdata")
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agobuild: simplify the instantation of nftversion.h
Jeremy Sowden [Wed, 28 Jan 2026 18:31:05 +0000 (18:31 +0000)] 
build: simplify the instantation of nftversion.h

Add an nftversion.h.in autoconf input file which configure uses to instantiate
nftversion.h in the usual way.

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agotests: shell: add open interval overlap tests
Pablo Neira Ayuso [Wed, 28 Jan 2026 02:12:19 +0000 (03:12 +0100)] 
tests: shell: add open interval overlap tests

Extend coverage with corner cases with open interval overlaps.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
2 months agoMakefile.am: Drop pointless per-project AM_CPPFLAGS
Phil Sutter [Thu, 4 Dec 2025 13:37:54 +0000 (14:37 +0100)] 
Makefile.am: Drop pointless per-project AM_CPPFLAGS

These are redundant, the common AM_CPPFLAGS variable has it already.

Fixes: c96e0a17f3699 ("build: no recursive make for "examples/Makefile.am"")
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agoutils: Introduce expr_print_debug()
Phil Sutter [Wed, 22 Oct 2025 13:26:36 +0000 (15:26 +0200)] 
utils: Introduce expr_print_debug()

A simple function to call in random places when debugging
expression-related code.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agotests: py: Update payload records
Phil Sutter [Thu, 16 Oct 2025 12:31:46 +0000 (14:31 +0200)] 
tests: py: Update payload records

This is the bulk change of py test suite payload records with improved
data reg printing in libnftnl using data (component) size and byteorder
collected in nftables.

Aside from printing values in the right byte order and padded with
zeroes to match their actual size, this patch also exposes the improved
set element dump format:
* No '[end]' marker, 'element' clearly separates elements
* No semi-colon for non-map elements
* 'flags' value printed only if non-zero and prefixed by 'flags' to
  distinguish from element data

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agotests: py: tools: Add regen_payloads.sh
Phil Sutter [Wed, 24 Nov 2021 16:29:04 +0000 (17:29 +0100)] 
tests: py: tools: Add regen_payloads.sh

Use this script to recreate all payload records.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agonetlink: Make use of nftnl_{expr,set_elem}_set_imm()
Phil Sutter [Wed, 8 Oct 2025 20:15:15 +0000 (22:15 +0200)] 
netlink: Make use of nftnl_{expr,set_elem}_set_imm()

Pass the previously collected byteorder (and sizes) to libnftnl for
improved netlink debug output.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agonetlink: Introduce struct nft_data_linearize::sizes
Phil Sutter [Fri, 17 Oct 2025 15:06:10 +0000 (17:06 +0200)] 
netlink: Introduce struct nft_data_linearize::sizes

This array holds each concat component's actual length in bytes. It is
crucial because component data is padded to match register lengths and
if libnftnl has to print data "in reverse" (to print Little Endian
values byte-by-byte), it will print extra leading zeroes with odd data
lengths and thus indicate number of printed bytes does no longer
correctly reflect actual data length.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agonetlink: Introduce struct nft_data_linearize::byteorder
Phil Sutter [Thu, 13 Nov 2025 16:11:15 +0000 (17:11 +0100)] 
netlink: Introduce struct nft_data_linearize::byteorder

Bits in this field indicate data is in host byte order and thus may need
conversion when being printed "byte-by-byte" in libnftnl.

With regular immediate values, this field's value has boolean properties
(if non-zero, data is in host byte order). Concatenations may contain
components in different byte order, so with them each bit (at index N)
indicates whether a component (at the same index) is in host byte order.

Communicate a possible byte order conversion in
__netlink_gen_concat_key() back to caller since this has to be respected
when setting 'byteorder' field in struct nft_data_linearize.

String-based values are special: While defined as being in host byte
order in nftables, libnftnl shall print them without prior conversion
like Big Endian values.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agoexpression: Set range expression 'len' field
Phil Sutter [Thu, 16 Oct 2025 16:57:20 +0000 (18:57 +0200)] 
expression: Set range expression 'len' field

The length value is needed for netlink debug output of concatenated
ranges. Set it to one of the inner elements' lengths (which should be
identical).

Since the inner element length may not be set initially, set it in
eval phase again. This covers at least all cases in tests/py.

Without this, netlink_gen_concat_key() et al. would have to inspect
element types and extract lengths accordingly, this is much easier.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agointervals: Convert byte order implicitly
Phil Sutter [Thu, 13 Nov 2025 15:36:01 +0000 (16:36 +0100)] 
intervals: Convert byte order implicitly

When converting ranges to intervals, the latter's high and low values
must be in network byte order. Instead of creating the low/high constant
expressions with host byte order and converting the value, create them
with Big Endian and keep the value as is. Upon export, Little Endian MPZ
values will be byte-swapped by mpz_export_data() if BYTEORDER_BIG_ENDIAN
is passed.

The benefit of this is that value's byteorder may be communicated to
libnftnl later by looking at struct expr::byteorder field. By the time
this information is required during netlink serialization, there is no
other indicator for data byte order available.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agomergesort: Align concatenation sort order with Big Endian
Phil Sutter [Wed, 12 Nov 2025 23:14:43 +0000 (00:14 +0100)] 
mergesort: Align concatenation sort order with Big Endian

By exporting all concat components in a way independent from host
byteorder and importing that blob of data in the same way aligns sort
order between hosts of different Endianness.

Fixes: 741a06ac15d2b ("mergesort: find base value expression type via recursion")
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agomergesort: Fix sorting of string values
Phil Sutter [Wed, 12 Nov 2025 23:03:37 +0000 (00:03 +0100)] 
mergesort: Fix sorting of string values

Sorting order was obviously wrong, e.g. "ppp0" ordered before "eth1".
Moreover, this happened on Little Endian only so sorting order actually
depended on host's byteorder. By reimporting string values as Big
Endian, both issues are fixed: On one hand, GMP-internal byteorder no
longer depends on host's byteorder, on the other comparing strings
really starts with the first character, not the last.

Fixes: 14ee0a979b622 ("src: sort set elements in netlink_get_setelems()")
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agosegtree: Fix range aggregation on Big Endian
Phil Sutter [Tue, 21 Oct 2025 16:36:10 +0000 (18:36 +0200)] 
segtree: Fix range aggregation on Big Endian

Interface name wildcards are received as ranges from prefix with zero
padding to prefix with ones padding. E.g. with "abcd*" (in hex):

61626364000000000000000000000000 - 61626364ffffffffffffffffffffffff

The faulty code tries to export the prefix from the lower boundary (r1)
into a buffer, append "*" and allocate a constant expression from the
resulting string. This does not work on Big Endian though:
mpz_export_data() seems to zero-pad data upon export and not necessarily
respect the passed length value. Moreover, this padding appears in the
first bytes of the buffer. The amount of padding seems illogical, too:
While a 6B prefix causes 2B padding and 8B prefix no padding, 10B prefix
causes 4B padding and 12B prefix even 8B padding.

Work around the odd behaviour by exporting the full data into a larger
buffer.

A similar issue is caused by increasing the constant expression's length
to match the upper boundary data length: Data export when printing puts
the padding upfront, so the resulting string starts with NUL-chars.
Since this length adjustment seems not to have any effect in practice,
just drop it.

Fixes: 88b2345a215ef ("segtree: add pretty-print support for wildcard strings in concatenated sets")
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agomonitor: fix memleak in setelem cb
Florian Westphal [Wed, 21 Jan 2026 13:33:21 +0000 (14:33 +0100)] 
monitor: fix memleak in setelem cb

since 4521732ebbf3 ("monitor: missing cache and set handle initialization")
these fields are set via handle_merge(), so don't clobber those
fields in json output case:

==31877==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 16 byte(s) in 2 object(s) allocated from:
 #0 0x7f0cb9f29d4b in strdup asan/asan_interceptors.cpp:593
 #1 0x7f0cb9b584fd in xstrdup src/utils.c:80
 #2 0x7f0cb9b355b3 in handle_merge src/rule.c:127
 #3 0x7f0cb9ae12b8 in netlink_events_setelem_cb src/monitor.c:457

Seen when running tests/monitor with asan enabled.

Fixes: 4521732ebbf3 ("monitor: missing cache and set handle initialization")
Signed-off-by: Florian Westphal <fw@strlen.de>
2 months agodoc: clarify JSON rule positioning with handle field
Alexandre Knecht [Thu, 6 Nov 2025 09:16:09 +0000 (10:16 +0100)] 
doc: clarify JSON rule positioning with handle field

The existing documentation briefly mentioned that the handle field can be
used for positioning, but the behavior was ambiguous. This commit clarifies:

- ADD with handle: inserts rule AFTER the specified handle
- INSERT with handle: inserts rule BEFORE the specified handle
- Multiple rules added at the same handle are positioned relative to the
  original rule, not to previously inserted rules
- Explicit commands (with command wrapper) use handle for positioning
- Implicit commands (without command wrapper, used in export/import)
  ignore handle for portability

This clarification helps users understand the correct behavior and avoid
confusion when using the JSON API for rule management.

Signed-off-by: Alexandre Knecht <knecht.alexandre@gmail.com>
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agotests: json_echo: Drop rule handle before multi-add
Phil Sutter [Tue, 20 Jan 2026 21:47:02 +0000 (22:47 +0100)] 
tests: json_echo: Drop rule handle before multi-add

Now that JSON parser respects rule handles in explicit add commands, the
still present rule handle causes an error since the old rule does not
exist anymore.

Fixes: 50b5b71ebeee3 ("parser_json: Rewrite echo support")
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agotests: shell: add JSON test for handle-based rule positioning
Alexandre Knecht [Tue, 20 Jan 2026 19:53:03 +0000 (20:53 +0100)] 
tests: shell: add JSON test for handle-based rule positioning

Add comprehensive test for JSON handle-based rule positioning to verify
the handle field correctly positions rules with explicit add/insert
commands while being ignored in implicit format.

Test coverage:
1. ADD with handle positions AFTER the specified handle
2. INSERT with handle positions BEFORE the specified handle
3. INSERT without handle positions at beginning
4. Multiple commands in single transaction (batch behavior)
5. Implicit format ignores handle field for portability

The test uses sed for handle extraction and nft -f format for setup
as suggested in code review. Final state is a table with two rules
from the implicit format test.

Signed-off-by: Alexandre Knecht <knecht.alexandre@gmail.com>
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agotests: shell: add JSON test for all object types
Alexandre Knecht [Tue, 20 Jan 2026 19:53:02 +0000 (20:53 +0100)] 
tests: shell: add JSON test for all object types

Add comprehensive test for JSON add/insert/delete/replace/create
operations on all object types to ensure the handle field changes
don't break non-rule objects.

Tests coverage:
- ADD operations: table, chain, rule, set, counter, quota
- INSERT operations: rule positioning
- REPLACE operations: rule modification
- CREATE operations: table creation with conflict detection
- DELETE operations: rule, set, chain, table

The test verifies that all object types work correctly with JSON
commands and validates intermediate states. Final state is an empty
table from the CREATE test.

Signed-off-by: Alexandre Knecht <knecht.alexandre@gmail.com>
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agoparser_json: support handle for rule positioning in explicit JSON format
Alexandre Knecht [Tue, 20 Jan 2026 19:53:01 +0000 (20:53 +0100)] 
parser_json: support handle for rule positioning in explicit JSON format

This patch enables handle-based rule positioning for JSON add/insert
commands by using a context flag to distinguish between explicit and
implicit command formats.

When processing JSON:
- Explicit commands like {"add": {"rule": ...}} set no flag, allowing
  handle fields to be converted to position for rule placement
- Implicit format (bare objects like {"rule": ...}, used in export/import)
  sets CTX_F_IMPLICIT flag, causing handles to be ignored for portability

This approach ensures that:
- Explicit rule adds with handles work for positioning
- Non-rule objects (tables, chains, sets, etc.) are unaffected
- Export/import remains compatible (handles ignored)

The semantics for explicit rule commands are:
  ADD with handle:    inserts rule AFTER the specified handle
  INSERT with handle: inserts rule BEFORE the specified handle

Implementation details:
- CTX_F_IMPLICIT flag (bit 10) marks implicit add commands
- CTX_F_EXPR_MASK uses inverse mask for future-proof expression flag filtering
- Handle-to-position conversion in json_parse_cmd_add_rule()
- Variables declared at function start per project style

Link: https://patchwork.ozlabs.org/project/netfilter-devel/patch/20251029224530.1962783-2-knecht.alexandre@gmail.com/
Suggested-by: Phil Sutter <phil@nwl.cc>
Suggested-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Alexandre Knecht <knecht.alexandre@gmail.com>
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 months agoparser: move qualified meta expression parsing to flex/bison
Florian Westphal [Tue, 20 Jan 2026 13:02:28 +0000 (14:02 +0100)] 
parser: move qualified meta expression parsing to flex/bison

The meta keyword currently accepts 'STRING' arguments.
This was originally done to avoid pollution the global token namespace.

However, nowadays we do have flex scopes to avoid this.
Add the tokens currently handled implciitly via STRING within
META flex scope.

SECPATH is a compatibility alias, map this to IPSEC token.
IBRPORT/OBRPORT are also compatibility aliases, remove those tokens
and handle this directly in scanner.l.

This also avoids nft from printing tokens in help texts that are only
there for compatibility with old rulesets.

meta_key_parse() is retained for json input parser.

Signed-off-by: Florian Westphal <fw@strlen.de>
Acked-by: Phil Sutter <phil@nwl.cc>
2 months agoparser_bison: on syntax errors, output expected tokens
Jan Kończak [Thu, 4 Dec 2025 21:54:48 +0000 (22:54 +0100)] 
parser_bison: on syntax errors, output expected tokens

Now, on syntax errors, e.g., 'nft create fable filter', the user sees:
 Error: syntax error, unexpected string
 create fable filter
          ^^^^^
The patch builds an error message that lists what the parser expects
to see, in that case it would print:
 Error: syntax error, unexpected string
 expected any of: synproxy, table, chain, set, element, map,
 flowtable, ct, counter, limit, quota, secmark
 create fable filter
        ^^^^^
The obvious purpose of this is to help people who learn nft syntax.

The messages are still not as explanatory as one wishes, for it may
list parser token names such as 'string', but it's still better than
no hints at all.

Heed that the list of possible items on the parser's side is not
always consistent with expectations.

For instance, lexer/parser recognizes 'l4proto' in this command:
nft add rule ip F I meta l4proto tcp
as a generic '%token <string> STRING', while 'iifname' in
   nft add rule ip F I meta iifname eth0

is recognized as a '%token IIFNAME'

In such case the parser is only able to say that right after 'meta'
it expects 'iifname' or 'string', rather than 'iifname' and 'l4proto'.

This 'meta STRING' is a historic wart and can be resolved in
a followup patch.

[ fw@strlen.de: minor coding style changes and rewordings ]

Signed-off-by: Jan Kończak <jan.konczak@cs.put.poznan.pl>
Signed-off-by: Florian Westphal <fw@strlen.de>
2 months agoscanner: Introduce SCANSTATE_RATE
Phil Sutter [Tue, 5 Aug 2025 20:25:25 +0000 (22:25 +0200)] 
scanner: Introduce SCANSTATE_RATE

This is a first exclusive start condition, i.e. one which rejects
unscoped tokens. When tokenizing, flex all too easily falls back into
treating something as STRING when it could be split into tokens instead.
Via an exclusive start condition, the string-fallback can be disabled as
needed.

With rates in typical formatting <NUM><bytes-unit>/<time-unit>,
tokenizer result depended on whitespace placement. SCANSTATE_RATE forces
flex to split the string into tokens and fall back to JUNK upon failure.
For this to work, tokens which shall still be recognized must be enabled
in SCANSTATE_RATE (or all scopes denoted by '*'). This includes any
tokens possibly following SCANSTATE_RATE to please the parser's
lookahead behaviour.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Florian Westphal <fw@strlen.de>
2 months agoparser_bison: Introduce bytes_unit
Phil Sutter [Tue, 13 Aug 2024 18:54:07 +0000 (20:54 +0200)] 
parser_bison: Introduce bytes_unit

Introduce scoped tokens for "kbytes" and "mbytes", completing already
existing "bytes" one. Then generalize the unit for byte values and
replace both quota_unit and limit_bytes by a combination of NUM and
bytes_unit.

With this in place, data_unit_parse() is not called outside of
datatype.c, so make it static.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Florian Westphal <fw@strlen.de>
2 months agoparser_bison: Introduce tokens for log levels
Phil Sutter [Fri, 21 Nov 2025 16:49:02 +0000 (17:49 +0100)] 
parser_bison: Introduce tokens for log levels

Since log statement is scoped already, it's just a matter of declaring
the tokens in that scope and using them. This eliminates the redundant
copy of log level string parsing in parser_bison.y - the remaining one,
namely log_level_parse() in statement.c is used by JSON parser.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Florian Westphal <fw@strlen.de>
2 months agoparser_bison: Introduce tokens for osf ttl values
Phil Sutter [Fri, 21 Nov 2025 16:14:26 +0000 (17:14 +0100)] 
parser_bison: Introduce tokens for osf ttl values

Eliminate the open-coded string parsing and error handling.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Florian Westphal <fw@strlen.de>
2 months agoparser_bison: Introduce tokens for chain types
Phil Sutter [Fri, 21 Nov 2025 15:53:35 +0000 (16:53 +0100)] 
parser_bison: Introduce tokens for chain types

Use the already existing SCANSTATE_TYPE for keyword scoping.
This is a bit of back-n-forth from string to token and back to string
but it eliminates the helper function and also takes care of error
handling.

Note that JSON parser does not validate the type string at all but
relies upon the kernel to reject wrong ones.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Florian Westphal <fw@strlen.de>
2 months agoparser_bison: Introduce tokens for monitor events
Phil Sutter [Fri, 21 Nov 2025 13:02:36 +0000 (14:02 +0100)] 
parser_bison: Introduce tokens for monitor events

There already is a start condition for "monitor" keyword and also a
DESTROY token. So just add the missing one and get rid of the
intermediate string buffer.

Keep checking the struct monitor::event value in eval phase just to be
on the safe side.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Florian Westphal <fw@strlen.de>
2 months agotests: shell: add small packetpath test for hash and rbtree types
Florian Westphal [Tue, 13 Jan 2026 22:26:47 +0000 (23:26 +0100)] 
tests: shell: add small packetpath test for hash and rbtree types

Add tests to exercise packet path for rbtree and hash set types.
We check both positive (added address is matched) and negative
matches (set doesn't indicate match for deleted address).

For ranges, also validate that addresses preceeding or trailing
a range do not match.

Pipapo has no test to avoid duplicating what is already in
kernel kselftest (nft_concat_range.sh).

Signed-off-by: Florian Westphal <fw@strlen.de>
2 months agotests: shell: add small packetpath test for bitmap set type
Florian Westphal [Thu, 15 Jan 2026 08:50:05 +0000 (09:50 +0100)] 
tests: shell: add small packetpath test for bitmap set type

bitmap sets don't support 'counter' flag, so we can only check
'match' vs 'no match', but we can't tell which set element has
matched.

Static test, counter validation via dumps.

Signed-off-by: Florian Westphal <fw@strlen.de>
2 months agomnl: restore create element command with large batches
Pablo Neira Ayuso [Mon, 12 Jan 2026 11:59:26 +0000 (12:59 +0100)] 
mnl: restore create element command with large batches

The rework to reduce memory consumption has introduced a bug that result
in spurious EEXIST with large batches.

The code that tracks the start and end elements of the interval can add
the same element twice to the batch. This works with the add element
command, since it ignores EEXIST error, but it breaks the the create
element command.

Update this codepath to ensure both sides of the interval fit into the
netlink message, otherwise, trim the netlink message to remove them.
So the next netlink message includes the elements that represent the
interval that could not fit.

Fixes: 91dc281a82ea ("src: rework singleton interval transformation to reduce memory consumption")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 months agotests: shell: cover for large interval sets with create command
Pablo Neira Ayuso [Mon, 12 Jan 2026 10:51:50 +0000 (11:51 +0100)] 
tests: shell: cover for large interval sets with create command

commit 91dc281a82ea ("src: rework singleton interval transformation to
reduce memory consumption") duplicates singleton interval elements when
the netlink message gets full, this results in spurious EEXIST errors
when creating many elements in a set.

This patch extends the existing test to cover for this bug.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
3 months agotests: monitor: Fix for out-of-path call
Phil Sutter [Tue, 16 Dec 2025 14:36:23 +0000 (15:36 +0100)] 
tests: monitor: Fix for out-of-path call

When called from another directory without specifying test cases, an
incorrect regexp was used to glob all tests and no test was run at all:

| # ./tests/monitor/run-tests.sh
| echo: running tests from file *.t
| ./tests/monitor/run-tests.sh: line 201: testcases/*.t: No such file or directory
| monitor: running tests from file *.t
| ./tests/monitor/run-tests.sh: line 201: testcases/*.t: No such file or directory
| json-echo: running tests from file *.t
| ./tests/monitor/run-tests.sh: line 201: testcases/*.t: No such file or directory
| json-monitor: running tests from file *.t
| ./tests/monitor/run-tests.sh: line 201: testcases/*.t: No such file or directory

Fixes: 83eaf50c36fe8 ("tests: monitor: Become $PWD agnostic")
Signed-off-by: Phil Sutter <phil@nwl.cc>
4 months agodoc: fix typo in man-page
Jeremy Sowden [Sat, 6 Dec 2025 21:53:36 +0000 (21:53 +0000)] 
doc: fix typo in man-page

"interally" -> "internally"

Fixes: f34381547094 ("doc: minor improvements the `reject` statement")
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
4 months agobuild: fix ./configure with non-bash shell
Jan Palus [Fri, 5 Dec 2025 23:43:58 +0000 (00:43 +0100)] 
build: fix ./configure with non-bash shell

 CONFIG_SHELL=/bin/dash ./configure

breaks with:

 ./config.status: 2044: Syntax error: Bad for loop variable

Fixes: 64c07e38f049 ("table: Embed creating nft version into userdata")
Signed-off-by: Jan Palus <jpalus@fastmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agotests: shell: bad_rule_graphs: add chain linked from different hooks
Florian Westphal [Tue, 25 Nov 2025 13:03:33 +0000 (14:03 +0100)] 
tests: shell: bad_rule_graphs: add chain linked from different hooks

On a kernel with broken (never upstreamed) patch this fails with:

Accepted bad ruleset with jump from filter type to masquerade (3)
and
Accepted bad ruleset with jump from prerouting to masquerade

... because bogus optimisation suppresses re-validation of 'n2', even
though it becomes reachable from an invalid base chain (filter, but n2
has nat-only masquerade expression).

Another broken corner-case is validation of the different hook types:
When it becomes reachable from nat:prerouting in addition to the allowed
nat:postrouting the validation step must fail.

Improve test coverage to ensure future optimisations catch this.

Signed-off-by: Florian Westphal <fw@strlen.de>
4 months agotests: shell: Added SNAT/DNAT only cases for nat_ftp
Andrii Melnychenko [Thu, 30 Oct 2025 14:57:31 +0000 (15:57 +0100)] 
tests: shell: Added SNAT/DNAT only cases for nat_ftp

Added cases for SNAT or DNAT only for active and passive modes.

Signed-off-by: Andrii Melnychenko <a.melnychenko@vyos.io>
Signed-off-by: Florian Westphal <fw@strlen.de>
4 months agotests: shell: Refactored nat_ftp, added rulesets and testcase functions
Andrii Melnychenko [Thu, 30 Oct 2025 14:57:30 +0000 (15:57 +0100)] 
tests: shell: Refactored nat_ftp, added rulesets and testcase functions

Refactored the setup of nft rulesets, now it is possible to set up an
SNAT or DNAT-only ruleset for future tests.
Presented the testcase function to test passive or active modes.

Signed-off-by: Andrii Melnychenko <a.melnychenko@vyos.io>
Signed-off-by: Florian Westphal <fw@strlen.de>
4 months agobuild: Bump version to 1.1.6 v1.1.6
Pablo Neira Ayuso [Wed, 3 Dec 2025 21:20:52 +0000 (21:20 +0000)] 
build: Bump version to 1.1.6

This requires libnftnl 1.3.1 which includes new tunnel API.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 months agobuild: unbreak 'make distcheck'
Florian Westphal [Wed, 3 Dec 2025 22:12:01 +0000 (23:12 +0100)] 
build: unbreak 'make distcheck'

Pablo reports 'make distcheck' got broken due to a bogus source file
added in the afl split:

  make *** No rule to make target '-I./include', needed by 'distdir-am'.  Stop.

Get rid of this line.

Fixes: 32c994f84904 ("src: move fuzzer functionality to separate tool")
Reported-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
4 months agotests: shell: refer to python3 in json prettify script
Pablo Neira Ayuso [Mon, 17 Nov 2025 21:55:45 +0000 (21:55 +0000)] 
tests: shell: refer to python3 in json prettify script

Some distros only refer to python3, update it.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
4 months agotests: shell: add device to sets/0075tunnel_0 to support older kernels
Pablo Neira Ayuso [Mon, 17 Nov 2025 21:55:44 +0000 (21:55 +0000)] 
tests: shell: add device to sets/0075tunnel_0 to support older kernels

Older kernels do not support netdev basechain without device, add it so
this works.

Alternative is to skip it by adding:

 # NFT_TEST_REQUIRES(NFT_TEST_HAVE_netdev_chain_without_device)

but it seems easier to support it.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
4 months agotests: shell: add packetpath test for meta time expression.
Yi Chen [Thu, 13 Nov 2025 07:28:51 +0000 (15:28 +0800)] 
tests: shell: add packetpath test for meta time expression.

v2:
 - Switched to range syntax instead of two matches as suggested by Phil.

Signed-off-by: Yi Chen <yiche@redhat.com>
Reviewed-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Florian Westphal <fw@strlen.de>
4 months agorule: skip CMD_OBJ_SETELEMS with no elements after set flush
Pablo Neira Ayuso [Wed, 19 Nov 2025 23:41:13 +0000 (00:41 +0100)] 
rule: skip CMD_OBJ_SETELEMS with no elements after set flush

Set declaration + set flush results in a crash because CMD_OBJ_SETELEMS
does not expect no elements. This internal command only shows up if set
contains elements, however, evaluation flushes set content after the set
expansion. Skip this command CMD_OBJ_SETELEMS if set is empty.

Fixes: d3c8051cb767 ("rule: rework CMD_OBJ_SETELEMS logic")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>