]> git.ipfire.org Git - thirdparty/nftables.git/log
thirdparty/nftables.git
2 years agodoc: add nat examples
Florian Westphal [Mon, 1 May 2023 10:10:09 +0000 (12:10 +0200)] 
doc: add nat examples

nftables nat is much more capable than what the existing
documentation describes.

In particular, nftables can fully emulate iptables
NETMAP target and can perform n:m address mapping.

Add a new example section extracted from commit log
messages when those features got added.

Cc: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
2 years agodoc: list set/map flag keywords in a table
Florian Westphal [Mon, 1 May 2023 10:09:44 +0000 (12:09 +0200)] 
doc: list set/map flag keywords in a table

add descriptions of the set/map flags.

Signed-off-by: Florian Westphal <fw@strlen.de>
2 years agometa: introduce meta broute support
Sriram Yagnaraman [Sun, 26 Feb 2023 09:52:04 +0000 (10:52 +0100)] 
meta: introduce meta broute support

Can be used in bridge prerouting hook to divert a packet
to the ip stack for routing.

This is a replacement for "ebtables -t broute" functionality.

Link: https://patchwork.ozlabs.org/project/netfilter-devel/patch/20230224095251.11249-1-sriram.yagnaraman@est.tech/
Signed-off-by: Sriram Yagnaraman <sriram.yagnaraman@est.tech>
Signed-off-by: Florian Westphal <fw@strlen.de>
2 years agodoc: correct NAT statement description
Jeremy Sowden [Sun, 5 Mar 2023 10:14:16 +0000 (10:14 +0000)] 
doc: correct NAT statement description

Specifying a port specifies that a port, not an address, should be
modified.

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
2 years agojson: formatting fixes
Jeremy Sowden [Sun, 5 Mar 2023 10:14:14 +0000 (10:14 +0000)] 
json: formatting fixes

A few indentation tweaks for the JSON parser.

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
2 years agosrc: fix enum/integer mismatches
Florian Westphal [Sat, 29 Apr 2023 13:48:09 +0000 (15:48 +0200)] 
src: fix enum/integer mismatches

gcc 13 complains about type confusion:
cache.c:1178:5: warning: conflicting types for 'nft_cache_update' due to enum/integer mismatch;
have 'int(struct nft_ctx *, unsigned int,  struct list_head *, const struct nft_cache_filter *)' [-Wenum-int-mismatch]
cache.h:74:5: note: previous declaration of 'nft_cache_update' with type 'int(struct nft_ctx *, enum cmd_ops,  struct list_head *, const struct nft_cache_filter *)'

Same for:
rule.c:1915:13: warning: conflicting types for 'obj_type_name' due to enum/integer mismatch; have 'const char *(enum stmt_types)' [-Wenum-int-mismatch]
 1915 | const char *obj_type_name(enum stmt_types type)
      |             ^~~~~~~~~~~~~
expression.c:1543:24: warning: conflicting types for 'expr_ops_by_type' due to enum/integer mismatch; have 'const struct expr_ops *(uint32_t)' {aka 'const struct expr_ops *(unsigned int)'} [-Wenum-int-mismatch]
 1543 | const struct expr_ops *expr_ops_by_type(uint32_t value)
      |                        ^~~~~~~~~~~~~~~~

Convert to the stricter type (enum) where possible.

Signed-off-by: Florian Westphal <fw@strlen.de>
2 years agotests: py: missing json updates on ct and meta mark payload expression
Pablo Neira Ayuso [Tue, 25 Apr 2023 16:14:07 +0000 (18:14 +0200)] 
tests: py: missing json updates on ct and meta mark payload expression

Add json output, it is missing in the original tests/py update.

Fixes: 8221d86e616b ("tests: py: add test-cases for ct and packet mark payload expressions")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agomnl: incomplete extended error reporting for singleton device in chain
Pablo Neira Ayuso [Tue, 25 Apr 2023 10:37:15 +0000 (12:37 +0200)] 
mnl: incomplete extended error reporting for singleton device in chain

Fix error reporting when single device is specifies in chain:

 # nft add chain netdev filter ingress '{ devices = { x }; }'
 add chain netdev filter ingress { devices = { x }; }
                                               ^

Fixes: a66b5ad9540d ("src: allow for updating devices on existing netdev chain")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agomnl: handle singleton element in netdevice set
Pablo Neira Ayuso [Tue, 25 Apr 2023 09:48:52 +0000 (11:48 +0200)] 
mnl: handle singleton element in netdevice set

expr_evaluate_set() turns sets with singleton element into value,
nft_dev_add() expects a list of expression, so it crashes.

Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1676
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agojson: allow to specify comment on chain
Pablo Neira Ayuso [Tue, 25 Apr 2023 08:33:22 +0000 (10:33 +0200)] 
json: allow to specify comment on chain

Allow users to add a comment when declaring a chain.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agojson: allow to specify comment on table
Pablo Neira Ayuso [Mon, 24 Apr 2023 21:17:50 +0000 (23:17 +0200)] 
json: allow to specify comment on table

Allow users to add a comment when declaring a table:

 # sudo nft add table inet test3 '{comment "this is a comment";}'
 # nft list ruleset
 table inet test3 {
        comment "this is a comment"
 }
 # nft -j list ruleset
 {"nftables": [{"metainfo": {"version": "1.0.7", "release_name": "Old Doc Yak", "json_schema_version": 1}}, {"table": {"family": "inet", "name": "test3", "handle": 3, "comment": "this is a comment"}}]}
 # nft -j list ruleset > test.json
 # nft flush ruleset
 # nft -j -f test.json
 # nft -j list ruleset
 {"nftables": [{"metainfo": {"version": "1.0.7", "release_name": "Old Doc Yak", "json_schema_version": 1}}, {"table": {"family": "inet", "name": "test3", "handle": 4, "comment": "this is a comment"}}]}

Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1670
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agometa: skip protocol context update for nfproto with same table family
Pablo Neira Ayuso [Mon, 24 Apr 2023 20:07:44 +0000 (22:07 +0200)] 
meta: skip protocol context update for nfproto with same table family

Inefficient bytecode crashes ruleset listing:

[ meta load nfproto => reg 1 ]
[ cmp eq reg 1 0x00000002 ] <-- this specifies NFPROTO_IPV4 but table family is IPv4!
[ payload load 4b @ network header + 12 => reg 1 ]
[ cmp gte reg 1 0x1000000a ]
[ cmp lte reg 1 0x1f00000a ]
[ masq ]

This IPv4 table obviously only see IPv4 traffic, but bytecode specifies
a redundant match on NFPROTO_IPV4.

After this patch, listing works:

 # nft list ruleset
 table ip crash {
        chain crash {
                type nat hook postrouting priority srcnat; policy accept;
                ip saddr 10.0.0.16-10.0.0.31 masquerade
        }
 }

Skip protocol context update in case that this information is redundant.

Fixes: https://bugzilla.netfilter.org/show_bug.cgi?id=1562
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agoevaluate: bail out if new flowtable does not specify hook and priority
Pablo Neira Ayuso [Thu, 20 Apr 2023 22:37:07 +0000 (00:37 +0200)] 
evaluate: bail out if new flowtable does not specify hook and priority

If user forgets to specify the hook and priority and the flowtable does
not exist, then bail out:

 # cat flowtable-incomplete.nft
 table t {
  flowtable f {
   devices = { lo }
  }
 }
 # nft -f /tmp/k
 flowtable-incomplete.nft:2:12-12: Error: missing hook and priority in flowtable declaration
 flowtable f {
           ^

Update one existing tests/shell to specify a hook and priority.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agosrc: allow for updating devices on existing netdev chain
Pablo Neira Ayuso [Wed, 19 Apr 2023 09:50:01 +0000 (11:50 +0200)] 
src: allow for updating devices on existing netdev chain

This patch allows you to add/remove devices to an existing chain:

 # cat ruleset.nft
 table netdev x {
chain y {
type filter hook ingress devices = { eth0 } priority 0; policy accept;
}
 }
 # nft -f ruleset.nft
 # nft add chain netdev x y '{ devices = { eth1 };  }'
 # nft list ruleset
 table netdev x {
chain y {
type filter hook ingress devices = { eth0, eth1 } priority 0; policy accept;
}
 }
 # nft delete chain netdev x y '{ devices = { eth0 }; }'
 # nft list ruleset
 table netdev x {
chain y {
type filter hook ingress devices = { eth1 } priority 0; policy accept;
}
 }

This feature allows for creating an empty netdev chain, with no devices.
In such case, no packets are seen until a device is registered.

This patch includes extended netlink error reporting:

 # nft add chain netdev x y '{ devices = { x } ; }'
 Error: Could not process rule: No such file or directory
 add chain netdev x y { devices = { x } ; }
                                    ^

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agomnl: flowtable support for extended netlink error reporting
Pablo Neira Ayuso [Wed, 19 Apr 2023 13:38:04 +0000 (15:38 +0200)] 
mnl: flowtable support for extended netlink error reporting

This patch extends existing flowtable support to improve error
reporting:

 # nft add flowtable inet x y '{ devices = { x } ; }'
 Error: Could not process rule: No such file or directory
 add flowtable inet x y { devices = { x } ; }
                                      ^
 # nft delete flowtable inet x y '{ devices = { x } ; }'
 Error: Could not process rule: No such file or directory
 delete flowtable inet x y { devices = { x } ; }
                                         ^
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agomnl: set SO_SNDBUF before SO_SNDBUFFORCE
Pablo Neira Ayuso [Fri, 7 Apr 2023 22:21:57 +0000 (16:21 -0600)] 
mnl: set SO_SNDBUF before SO_SNDBUFFORCE

Set SO_SNDBUF before SO_SNDBUFFORCE: Unpriviledged user namespace does
not have CAP_NET_ADMIN on the host (user_init_ns) namespace.

SO_SNDBUF always succeeds in Linux, always try SO_SNDBUFFORCE after it.

Moreover, suggest the user to bump socket limits if EMSGSIZE after
having see EPERM previously, when calling SO_SNDBUFFORCE.

Provide a hint to the user too:

 # nft -f test.nft
 netlink: Error: Could not process rule: Message too long
 Please, rise /proc/sys/net/core/wmem_max on the host namespace. Hint: 4194304 bytes

Dave Pfike says:

 Prior to this patch, nft inside a systemd-nspawn container was failing
 to install my ruleset (which includes a large-ish map), with the error

 netlink: Error: Could not process rule: Message too long

 strace reveals:

 setsockopt(3, SOL_SOCKET, SO_SNDBUFFORCE, [524288], 4) = -1 EPERM (Operation not permitted)

 This is despite the nspawn process supposedly having CAP_NET_ADMIN.

 A web search reveals at least one other user having the same issue:

 https://old.reddit.com/r/Proxmox/comments/scnoav/lxc_container_debian_11_nftables_geoblocking/

Reported-by: Dave Pifke <dave@pifke.org>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agotests: shell: Fix for unstable sets/0043concatenated_ranges_0
Phil Sutter [Thu, 20 Apr 2023 15:39:27 +0000 (17:39 +0200)] 
tests: shell: Fix for unstable sets/0043concatenated_ranges_0

On my (slow?) testing VM, The test tends to fail when doing a full run
(i.e., calling run-test.sh without arguments) and tends to pass when run
individually.

The problem seems to be the 1s element timeout which in some cases may
pass before element deletion occurs. Simply fix this by doubling the
timeout. It has to pass just once, so shouldn't hurt too much.

Fixes: 618393c6b3f25 ("tests: Introduce test for set with concatenated ranges")
Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 years agomain: Error out when combining -i/--interactive and -f/--file
Pablo Neira Ayuso [Sat, 8 Apr 2023 18:16:07 +0000 (20:16 +0200)] 
main: Error out when combining -i/--interactive and -f/--file

These two options are mutually exclusive, display error in that case:

 # nft -i -f test.nft
 Error: -i/--interactive and -f/--file options cannot be combined

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agooptimize: support for redirect and masquerade
Pablo Neira Ayuso [Tue, 4 Apr 2023 13:30:21 +0000 (15:30 +0200)] 
optimize: support for redirect and masquerade

The redirect and masquerade statements can be handled as verdicts:

- if redirect statement specifies no ports.
- masquerade statement, in any case.

Exceptions to the rule: If redirect statement specifies ports, then nat
map transformation can be used iif both statements specify ports.

Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1668
Fixes: 0a6dbfce6dc3 ("optimize: merge nat rules with same selectors into map")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agonetlink_delinearize: do not reset protocol context for nat protocol expression
Pablo Neira Ayuso [Tue, 4 Apr 2023 13:34:05 +0000 (15:34 +0200)] 
netlink_delinearize: do not reset protocol context for nat protocol expression

This patch reverts 403b46ada490 ("netlink_delinearize: kill dependency
before eval of 'redirect' stmt"). Since ("evaluate: bogus missing
transport protocol"), this workaround is not required anymore.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agoevaluate: bogus missing transport protocol
Pablo Neira Ayuso [Tue, 4 Apr 2023 13:30:20 +0000 (15:30 +0200)] 
evaluate: bogus missing transport protocol

Users have to specify a transport protocol match such as

meta l4proto tcp

before the redirect statement, even if the redirect statement already
implicitly refers to the transport protocol, for instance:

test.nft:3:16-53: Error: transport protocol mapping is only valid after transport protocol match
                redirect to :tcp dport map { 83 : 8083, 84 : 8084 }
                ~~~~~~~~     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Evaluate the redirect expression before the mandatory check for the
transport protocol match, so protocol context already provides a
transport protocol.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agooptimize: assert nat type on nat statement helper
Pablo Neira Ayuso [Tue, 4 Apr 2023 13:30:16 +0000 (15:30 +0200)] 
optimize: assert nat type on nat statement helper

Add assert() to helper function to expression from NAT statement.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agoxt: Fix translation error path
Phil Sutter [Tue, 28 Mar 2023 11:46:10 +0000 (13:46 +0200)] 
xt: Fix translation error path

If xtables support was compiled in but the required libxtables DSO is
not found, nft prints an error message and leaks memory:

| counter packets 0 bytes 0 XT target MASQUERADE not found

This is not as bad as it seems, the output combines stdout and stderr.
Dropping stderr produces an incomplete ruleset listing, though. While
this seemingly inline output can't easily be avoided, fix a few things:

* Respect octx->error_fp, libnftables might have been configured to
  redirect stderr somewhere else.
* Align error message formatting with others.
* Don't return immediately, but free allocated memory and fall back to
  printing the expression in "untranslated" form.

Fixes: 5c30feeee5cfe ("xt: Delay libxtables access until translation")
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 years agonetlink_delinearize: correct type and byte-order of shifts
Jeremy Sowden [Thu, 23 Mar 2023 16:58:44 +0000 (17:58 +0100)] 
netlink_delinearize: correct type and byte-order of shifts

Downgrade to base type integer instead of the specific type from the
expression that is used in the shift operation.

Without this, listing a rule like:

  ct mark set ip dscp lshift 2 or 0x10

will return:

  ct mark set ip dscp << 2 | cs2

because the type of the OR's right operand will be transitively derived
from `ip dscp`.  However, this is not valid syntax:

  # nft add rule t c ct mark set ip dscp '<<' 2 '|' cs2
  Error: Could not parse integer
  add rule t c ct mark set ip dscp << 2 | cs2
                                          ^^^

Use xinteger_type to print the output in hexadecimal.

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agointervals: use expression location when translating to intervals
Pablo Neira Ayuso [Mon, 27 Mar 2023 14:36:31 +0000 (16:36 +0200)] 
intervals: use expression location when translating to intervals

Otherwise, internal location reports:

 # nft -f ruleset.nft
 internal:0:0-0: Error: Could not process rule: File exists

after this patch:

 # nft -f ruleset.nft
 ruleset.nft:402:1-16: Error: Could not process rule: File exists
 1.2.3.0/30,
 ^^^^^^^^^^^

Fixes: 81e36530fcac ("src: replace interval segment tree overlap and automerge")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agopayload: set byteorder when completing expression
Pablo Neira Ayuso [Thu, 23 Mar 2023 09:42:58 +0000 (10:42 +0100)] 
payload: set byteorder when completing expression

Otherwise payload expression remains in invalid byteorder which is
handled as network byteorder for historical reason.

No functional change is intended.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agotests: py: extend test-cases for mark statements with bitwise expressions
Pablo Neira Ayuso [Thu, 23 Mar 2023 12:50:35 +0000 (13:50 +0100)] 
tests: py: extend test-cases for mark statements with bitwise expressions

Add more tests to cover bitwise operation. Shift operations are used on
constant value which are reduced at evaluation time.

Shift takes precendence over AND and OR operations, otherwise use parens
to override this.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agotests: shell: add test-cases for ct and packet mark payload expressions
Jeremy Sowden [Fri, 17 Mar 2023 09:16:54 +0000 (10:16 +0100)] 
tests: shell: add test-cases for ct and packet mark payload expressions

Add new test-cases to verify that defining a rule that sets the ct or
packet mark to a value derived from a payload works correctly.

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agotests: shell: rename and move bitwise test-cases
Jeremy Sowden [Fri, 17 Mar 2023 09:16:50 +0000 (10:16 +0100)] 
tests: shell: rename and move bitwise test-cases

The `0040mark_shift_?` tests are testing not just shifts, but binops
more generally, so name them accordingly.

Move them to a new folder specifically for bitwise operations.

Change the priorities of the chains to match the type.

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agotests: py: add test-cases for ct and packet mark payload expressions
Jeremy Sowden [Fri, 17 Mar 2023 09:16:48 +0000 (10:16 +0100)] 
tests: py: add test-cases for ct and packet mark payload expressions

Add new test-cases to verify that defining a rule that sets the ct or
packet mark to a value derived from a payload works correctly.

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agonetlink_delinerize: incorrect byteorder in mark statement listing
Pablo Neira Ayuso [Thu, 23 Mar 2023 12:23:34 +0000 (13:23 +0100)] 
netlink_delinerize: incorrect byteorder in mark statement listing

When using ip dscp in combination with bitwise operation:

 # nft --debug=netlink add rule ip x y 'ct mark set ip dscp | 0x4'
 ip x y
   [ payload load 1b @ network header + 1 => reg 1 ]
   [ bitwise reg 1 = ( reg 1 & 0x000000fc ) ^ 0x00000000 ]
   [ bitwise reg 1 = ( reg 1 >> 0x00000002 ) ]
   [ bitwise reg 1 = ( reg 1 & 0xfffffffb ) ^ 0x00000004 ]
   [ ct set mark with reg 1 ]

the listing is showing in the incorrect byteorder:

 # nft list ruleset
 table ip x {
        chain y {
ct mark set ip dscp | 0x4000000
}
 }

handle and and or operations in host byteorder.

The following command:

 # nft --debug=netlink add rule ip6 x y 'ct mark set ip6 dscp | 0x4'
 ip6 x y
   [ payload load 2b @ network header + 0 => reg 1 ]
   [ bitwise reg 1 = ( reg 1 & 0x0000c00f ) ^ 0x00000000 ]
   [ bitwise reg 1 = ( reg 1 >> 0x00000006 ) ]
   [ byteorder reg 1 = ntoh(reg 1, 2, 1) ]
   [ bitwise reg 1 = ( reg 1 & 0xfffffffb ) ^ 0x00000004 ]
   [ ct set mark with reg 1 ]

works fine (without requiring this patch) because there is an explicit
byteorder expression.

However, ip dscp takes only 1-byte, so it does not require the byteorder
expression. Use host byteorder if the rhs of bitwise AND OR is larger
than lhs payload expression and such expression is equal or less than
1-byte.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agoevaluate: honor statement length in bitwise evaluation
Pablo Neira Ayuso [Fri, 17 Mar 2023 09:16:45 +0000 (10:16 +0100)] 
evaluate: honor statement length in bitwise evaluation

Get length from statement, instead infering it from the expression that
is used to set the value. In the particular case of {ct|meta} mark, this
is 32 bits.

Otherwise, bytecode generation is not correct:

 # nft -c --debug=netlink 'add rule ip6 x y ct mark set ip6 dscp << 2 | 0x10'
  [ payload load 2b @ network header + 0 => reg 1 ]
  [ bitwise reg 1 = ( reg 1 & 0x0000c00f ) ^ 0x00000000 ]
  [ bitwise reg 1 = ( reg 1 >> 0x00000006 ) ]
  [ byteorder reg 1 = ntoh(reg 1, 2, 1) ]
  [ bitwise reg 1 = ( reg 1 << 0x00000002 ) ]
  [ bitwise reg 1 = ( reg 1 & 0x00000fef ) ^ 0x00000010 ]    <--- incorrect!
  [ ct set mark with reg 1 ]

the previous bitwise shift already upgraded to 32-bits (not visible from
the netlink debug output above).

After this patch, the last | 0x10 uses 32-bits:

 [ bitwise reg 1 = ( reg 1 & 0xffffffef ) ^ 0x00000010 ]

note that mask 0xffffffef is used instead of 0x00000fef.

Patch ("evaluate: support shifts larger than the width of the left operand")
provides the statement length through eval context. Use it to evaluate the
bitwise expression accordingly, otherwise bytecode is incorrect:

 # nft --debug=netlink add rule ip x y 'ct mark set ip dscp & 0x0f << 1 | 0xff000000'
 ip x y
  [ payload load 1b @ network header + 1 => reg 1 ]
  [ bitwise reg 1 = ( reg 1 & 0x000000fc ) ^ 0x00000000 ]
  [ bitwise reg 1 = ( reg 1 >> 0x00000002 ) ]
  [ bitwise reg 1 = ( reg 1 & 0x1e000000 ) ^ 0x000000ff ]  <-- incorrect byteorder for OR
  [ byteorder reg 1 = ntoh(reg 1, 4, 4) ]    <-- no needed for single ip dscp byte
  [ ct set mark with reg 1 ]

Correct bytecode:

 # nft --debug=netlink add rule ip x y 'ct mark set ip dscp & 0x0f << 1 | 0xff000000
 ip x y
  [ payload load 1b @ network header + 1 => reg 1 ]
  [ bitwise reg 1 = ( reg 1 & 0x000000fc ) ^ 0x00000000 ]
  [ bitwise reg 1 = ( reg 1 >> 0x00000002 ) ]
  [ bitwise reg 1 = ( reg 1 & 0x0000001e ) ^ 0xff000000 ]
  [ ct set mark with reg 1 ]

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agoevaluate: honor statement length in integer evaluation
Pablo Neira Ayuso [Thu, 23 Mar 2023 11:52:39 +0000 (12:52 +0100)] 
evaluate: honor statement length in integer evaluation

Otherwise, bogus error is reported:

 # nft --debug=netlink add rule ip x y 'ct mark set ip dscp & 0x0f << 1 | 0xff000000'
 Error: Value 4278190080 exceeds valid range 0-63
 add rule ip x y ct mark set ip dscp & 0x0f << 1 | 0xff000000
                                                   ^^^^^^^^^^

Use the statement length as the maximum value in the mark statement
expression.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agoevaluate: set up integer type to shift expression
Pablo Neira Ayuso [Thu, 23 Mar 2023 11:36:08 +0000 (12:36 +0100)] 
evaluate: set up integer type to shift expression

Otherwise expr_evaluate_value() fails with invalid datatype:

 # nft --debug=netlink add rule ip x y 'ct mark set ip dscp & 0x0f << 1'
 BUG: invalid basetype invalid
 nft: evaluate.c:440: expr_evaluate_value: Assertion `0' failed.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agoevaluate: relax type-checking for integer arguments in mark statements
Pablo Neira Ayuso [Fri, 17 Mar 2023 09:16:46 +0000 (10:16 +0100)] 
evaluate: relax type-checking for integer arguments in mark statements

In order to be able to set ct and meta marks to values derived from
payload expressions, we need to relax the requirement that the type of
the statement argument must match that of the statement key.  Instead,
we require that the base-type of the argument is integer and that the
argument is small enough to fit.

Moreover, swap expression byteorder before to make it compatible with
the statement byteorder, to ensure rulesets are portable.

 # nft --debug=netlink add rule ip t c 'meta mark set ip saddr'
 ip t c
  [ payload load 4b @ network header + 12 => reg 1 ]
  [ byteorder reg 1 = ntoh(reg 1, 4, 4) ] <----------- byteorder swap
  [ meta set mark with reg 1 ]

Based on original work from Jeremy Sowden.

The following patches are required for this to work:

evaluate: get length from statement instead of lhs expression
evaluate: don't eval unary arguments
evaluate: support shifts larger than the width of the left operand
netlink_delinearize: correct type and byte-order of shifts
evaluate: insert byte-order conversions for expressions between 9 and 15 bits

Add one testcase for tests/py.

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agoevaluate: don't eval unary arguments
Jeremy Sowden [Fri, 17 Mar 2023 09:16:43 +0000 (10:16 +0100)] 
evaluate: don't eval unary arguments

When a unary expression is inserted to implement a byte-order
conversion, the expression being converted has already been evaluated
and so `expr_evaluate_unary` doesn't need to do so.

This is required by {ct|meta} statements with bitwise operations, which
might result in byteorder conversion of the expression.

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agoevaluate: support shifts larger than the width of the left operand
Pablo Neira Ayuso [Fri, 17 Mar 2023 09:16:40 +0000 (10:16 +0100)] 
evaluate: support shifts larger than the width of the left operand

If we want to left-shift a value of narrower type and assign the result
to a variable of a wider type, we are constrained to only shifting up to
the width of the narrower type.  Thus:

  add rule t c meta mark set ip dscp << 2

works, but:

  add rule t c meta mark set ip dscp << 8

does not, even though the lvalue is large enough to accommodate the
result.

Upgrade the maximum length based on the statement datatype length, which
is provided via context, if it is larger than expression lvalue.

Update netlink_delinearize.c to handle the case where the length of a
shift expression does not match that of its left-hand operand.

Based on patch from Jeremy Sowden.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agometa: don't crash if meta key isn't known
Florian Westphal [Wed, 15 Mar 2023 12:57:38 +0000 (13:57 +0100)] 
meta: don't crash if meta key isn't known

If older nft version is used for dumping, 'key' might be
outside of the range of known templates.

Signed-off-by: Florian Westphal <fw@strlen.de>
2 years agoevaluate: insert byte-order conversions for expressions between 9 and 15 bits
Jeremy Sowden [Fri, 17 Mar 2023 09:16:36 +0000 (10:16 +0100)] 
evaluate: insert byte-order conversions for expressions between 9 and 15 bits

Round up expression lengths when determining whether to insert a
byte-order conversion.  For example, if one is masking a network header
which spans a byte boundary, the mask will span two bytes and so it will
need to be in NBO.

Fixes: bb03cbcd18a1 ("evaluate: no need to swap byte-order for values of fewer than 16 bits.")
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agoAvoid a memleak with 'reset rules' command
Phil Sutter [Mon, 20 Mar 2023 09:03:13 +0000 (10:03 +0100)] 
Avoid a memleak with 'reset rules' command

Like other 'reset' commands, 'reset rules' also lists the (part of the)
ruleset which was affected to give users a chance to store the zeroed
values. Therefore do_command_reset() calls do_command_list(). This in
turn calls do_list_ruleset() for CMD_OBJ_RULES which wasn't prepared for
values stored in cmd->handle other than a possible family value and thus
freely reused the pointers as scratch area for the do_list_table() call
whiich in the past fetched each table's data directly from kernel.

Meanwhile ruleset listing code has been integrated into the common
caching logic, the 'cmd' pointer became unused by do_list_table(). The
temporary cmd->handle manipulation is not needed anymore, dropping it
prevents a memleak caused by overwriting of allocated table name
pointer.

Fixes: 1694df2de79f3 ("Implement 'reset rule' and 'reset rules' commands")
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 years agoReduce signature of do_list_table()
Phil Sutter [Mon, 20 Mar 2023 08:58:29 +0000 (09:58 +0100)] 
Reduce signature of do_list_table()

Since commit 16fac7d11bdf5 ("src: use cache infrastructure for rule
objects"), the function does not use the passed 'cmd' object anymore.
Remove it to affirm correctness of a follow-up fix and simplification in
do_list_ruleset().

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 years agopy: replace distutils with setuptools
Jose M. Guisado Gomez [Wed, 22 Feb 2023 10:20:55 +0000 (11:20 +0100)] 
py: replace distutils with setuptools

Removes a deprecation warning when using distutils and python >=3.10.

Python distutils module is formally marked as deprecated since python
3.10 and will be removed from the standard library from Python 3.12.
(https://peps.python.org/pep-0632/)

From https://setuptools.pypa.io/en/latest/setuptools.html

"""
Packages built and distributed using setuptools look to the user like
ordinary Python packages based on the distutils.
"""

Signed-off-by: Jose M. Guisado Gomez <guigom@riseup.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
2 years agoparser_bison: simplify reset syntax
Pablo Neira Ayuso [Tue, 14 Mar 2023 13:56:18 +0000 (14:56 +0100)] 
parser_bison: simplify reset syntax

Simplify:

*reset rules* *chain* ['family'] 'table' ['chain]'
to
*reset rules* ['family'] 'table' 'chain'

*reset rules* *table* ['family'] 'table'
to
*reset rules* ['family'] 'table'

*reset counters* ['family'] *table* 'table'
to
*reset counters* ['family'] 'table'

*reset quotas* ['family'] *table* 'table'
to
*reset quotas* ['family'] 'table'

Previous syntax remains in place for backward compatibility.

Acked-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agoRevert "evaluate: relax type-checking for integer arguments in mark statements"
Pablo Neira Ayuso [Tue, 14 Mar 2023 09:29:59 +0000 (10:29 +0100)] 
Revert "evaluate: relax type-checking for integer arguments in mark statements"

This patch reverts eab3eb7f146c ("evaluate: relax type-checking for
integer arguments in mark statements") since it might cause ruleset
portability issues when moving a ruleset from little to big endian
host (and vice-versa).

Let's revert this until we agree on what to do in this case.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agobuild: Bump version to 1.0.7 v1.0.7
Pablo Neira Ayuso [Mon, 13 Mar 2023 13:58:58 +0000 (14:58 +0100)] 
build: Bump version to 1.0.7

Update dependency on libnftnl >= 1.2.5 which contains support for inner
header matching.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agosrc: fix a couple of typo's in comments
Jeremy Sowden [Sun, 12 Mar 2023 20:27:10 +0000 (20:27 +0000)] 
src: fix a couple of typo's in comments

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
2 years agocmd: move command functions to src/cmd.c
Pablo Neira Ayuso [Fri, 10 Mar 2023 18:40:34 +0000 (19:40 +0100)] 
cmd: move command functions to src/cmd.c

Move several command functions to src/cmd.c to debloat src/rule.c

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agosrc: improve error reporting for unsupported chain type
Pablo Neira Ayuso [Fri, 10 Mar 2023 18:20:50 +0000 (19:20 +0100)] 
src: improve error reporting for unsupported chain type

8c75d3a16960 ("Reject invalid chain priority values in user space")
provides error reporting from the evaluation phase. Instead, this patch
infers the error after the kernel reports EOPNOTSUPP.

test.nft:3:28-40: Error: Chains of type "nat" must have a priority value above -200
                type nat hook prerouting priority -300;
                                         ^^^^^^^^^^^^^

This patch also adds another common issue for users compiling their own
kernels if they forget to enable CONFIG_NFT_NAT in their .config file.

Acked-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agoReject invalid chain priority values in user space
Phil Sutter [Thu, 9 Mar 2023 23:52:15 +0000 (00:52 +0100)] 
Reject invalid chain priority values in user space

The kernel doesn't accept nat type chains with a priority of -200 or
below. Catch this and provide a better error message than the kernel's
EOPNOTSUPP.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 years agoxt: Fix fallback printing for extensions matching keywords
Phil Sutter [Thu, 9 Mar 2023 13:31:31 +0000 (14:31 +0100)] 
xt: Fix fallback printing for extensions matching keywords

Yet another Bison workaround: Instead of the fancy error message, an
incomprehensible syntax error is emitted:

| # iptables-nft -A FORWARD -p tcp -m osf --genre linux
| # nft list ruleset | nft -f -
| # Warning: table ip filter is managed by iptables-nft, do not touch!
| /dev/stdin:4:29-31: Error: syntax error, unexpected osf, expecting string
|  meta l4proto tcp xt match osf counter packets 0 bytes 0
|                            ^^^

Avoid this by quoting the extension name when printing:

| # nft list ruleset | sudo ./src/nft -f -
| # Warning: table ip filter is managed by iptables-nft, do not touch!
| /dev/stdin:4:20-33: Error: unsupported xtables compat expression, use iptables-nft with this ruleset
|  meta l4proto tcp xt match "osf" counter packets 0 bytes 0
|                   ^^^^^^^^^^^^^^

Fixes: 79195a8cc9e9d ("xt: Rewrite unsupported compat expression dumping")
Fixes: e41c53ca5b043 ("xt: Fall back to generic printing from translation")
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 years agodoc: nft.8: Document lower priority limit for nat type chains
Phil Sutter [Thu, 9 Mar 2023 13:44:21 +0000 (14:44 +0100)] 
doc: nft.8: Document lower priority limit for nat type chains

Users can't know the magic limit.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 years agotests: shell: use bash in 0011reset_0
Pablo Neira Ayuso [Wed, 1 Mar 2023 10:59:32 +0000 (11:59 +0100)] 
tests: shell: use bash in 0011reset_0

One of my boxes does not use bash as /bin/sh, update this test to
explicitly use bash, otherwise I hit:

  testcases/rule_management/0011reset_0: 71: Syntax error: "(" unexpected

Fixes: 1694df2de79f ("Implement 'reset rule' and 'reset rules' commands")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agocache: fetch more objects when resetting rule
Pablo Neira Ayuso [Wed, 1 Mar 2023 10:58:22 +0000 (11:58 +0100)] 
cache: fetch more objects when resetting rule

If the ruleset contains a reference to object, listing fails. The
existing test for the new reset command displays the following error:

 # ./run-tests.sh testcases/rule_management/0011reset_0
 I: using nft command: ./../../src/nft

 W: [FAILED]     testcases/rule_management/0011reset_0: got 2
 loading ruleset
 resetting specific rule
 netlink: Error: Unknown set 's' in dynset statement

Fixes: 1694df2de79f ("Implement 'reset rule' and 'reset rules' commands")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agoparser_bison: allow to use quota in sets
Pablo Neira Ayuso [Wed, 1 Mar 2023 10:12:20 +0000 (11:12 +0100)] 
parser_bison: allow to use quota in sets

src: support for restoring element quota

This patch allows you to restore quota in dynamic sets.

 table ip x {
        set y {
                type ipv4_addr
                size 65535
                flags dynamic,timeout
                counter quota 500 bytes
                timeout 1h
                elements = { 8.8.8.8 counter packets 9 bytes 756 quota 500 bytes used 500 bytes timeout 1h expires 56m57s47ms }
        }

        chain z {
                type filter hook output priority filter; policy accept;
                update @y { ip daddr } counter packets 6 bytes 507
        }
 }

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agosrc: add last statement
Pablo Neira Ayuso [Tue, 28 Feb 2023 15:23:25 +0000 (16:23 +0100)] 
src: add last statement

This new statement allows you to know how long ago there was a matching
packet.

 # nft list ruleset
 table ip x {
        chain y {
[...]
                ip protocol icmp last used 49m54s884ms counter packets 1 bytes 64
}
 }

if this statement never sees a packet, then the listing says:

 ip protocol icmp last used never counter packets 0 bytes 0

Add tests/py in this patch too.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agoevaluate: expand value to range when nat mapping contains intervals
Pablo Neira Ayuso [Fri, 17 Feb 2023 14:10:44 +0000 (15:10 +0100)] 
evaluate: expand value to range when nat mapping contains intervals

If the data in the mapping contains a range, then upgrade value to range.
Otherwise, the following error is displayed:

/dev/stdin:11:57-75: Error: Could not process rule: Invalid argument
dnat ip to iifname . ip saddr map { enp2s0 . 10.1.1.136 : 1.1.2.69, enp2s0 . 10.1.1.1-10.1.1.135 : 1.1.2.66-1.84.236.78 }
                                    ^^^^^^^^^^^^^^^^^^^

The kernel rejects this command because userspace sends a single value
while the kernel expects the range that represents the min and the max
IP address to be used for NAT. The upgrade is also done when concatenation
with intervals is used in the rhs of the mapping.

For anonymous sets, expansion cannot be done from expr_evaluate_mapping()
because the EXPR_F_INTERVAL flag is inferred from the elements. For
explicit sets, this can be done from expr_evaluate_mapping() because the
user already specifies the interval flag in the rhs of the map definition.

Update tests/shell and tests/py to improve testing coverage in this case.

Fixes: 9599d9d25a6b ("src: NAT support for intervals in maps")
Fixes: 66746e7dedeb ("src: support for nat with interval concatenation")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agosrc: expand table command before evaluation
Pablo Neira Ayuso [Thu, 23 Feb 2023 18:55:39 +0000 (19:55 +0100)] 
src: expand table command before evaluation

The nested syntax notation results in one single table command which
includes all other objects. This differs from the flat notation where
there is usually one command per object.

This patch adds a previous step to the evaluation phase to expand the
objects that are contained in the table into independent commands, so
both notations have similar representations.

Remove the code to evaluate the nested representation in the evaluation
phase since commands are independently evaluated after the expansion.

The commands are expanded after the set element collapse step, in case
that there is a long list of singleton element commands to be added to
the set, to shorten the command list iteration.

This approach also avoids interference with the object cache that is
populated in the evaluation, which might refer to objects coming in the
existing command list that is being processed.

There is still a post_expand phase to detach the elements from the set
which could be consolidated by updating the evaluation step to handle
the CMD_OBJ_SETELEMS command type.

This patch fixes 27c753e4a8d4 ("rule: expand standalone chain that
contains rules") which broke rule addition/insertion by index because
the expansion code after the evaluation messes up the cache.

Fixes: 27c753e4a8d4 ("rule: expand standalone chain that contains rules")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agotests: shell: cover rule insertion by index
Pablo Neira Ayuso [Thu, 23 Feb 2023 19:36:43 +0000 (20:36 +0100)] 
tests: shell: cover rule insertion by index

Original patch including this feature did not include a test, add it.

Fixes: 816d8c7659c1 ("Support 'add/insert rule index <IDX>'")
Reported-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agoparser_bison: missing close scope in destroy start condition
Pablo Neira Ayuso [Wed, 22 Feb 2023 13:40:51 +0000 (14:40 +0100)] 
parser_bison: missing close scope in destroy start condition

base_cmd production is missing this, add it.

Fixes: f79c7a531744 ("src: use start condition with new destroy command")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agosrc: use start condition with new destroy command
Pablo Neira Ayuso [Thu, 16 Feb 2023 20:22:39 +0000 (21:22 +0100)] 
src: use start condition with new destroy command

tests/py reports the following problem:

any/ct.t: ERROR: line 116: add rule ip test-ip4 output ct event set new | related | destroy | label: This rule should not have failed.
any/ct.t: ERROR: line 117: add rule ip test-ip4 output ct event set new,related,destroy,label: This rule should not have failed.
any/ct.t: ERROR: line 118: add rule ip test-ip4 output ct event set new,destroy: This rule should not have failed.

Use start condition and update parser to handle 'destroy' keyword.

Fixes: e1dfd5cc4c46 ("src: add support to command "destroy")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agooptimize: infer family for nat mapping
Pablo Neira Ayuso [Wed, 15 Feb 2023 18:20:22 +0000 (19:20 +0100)] 
optimize: infer family for nat mapping

Infer family from key in nat mapping, otherwise nat mapping via merge
breaks since family is not specified.

Merging:
fw-test-bug2.nft:4:9-78:         iifname enp2s0 ip daddr 72.2.3.66 tcp dport 53122 dnat to 10.1.1.10:22
fw-test-bug2.nft:5:9-77:         iifname enp2s0 ip daddr 72.2.3.66 tcp dport 443 dnat to 10.1.1.52:443
fw-test-bug2.nft:6:9-75:         iifname enp2s0 ip daddr 72.2.3.70 tcp dport 80 dnat to 10.1.1.52:80
into:
        dnat ip to iifname . ip daddr . tcp dport map { enp2s0 . 72.2.3.66 . 53122 : 10.1.1.10 . 22, enp2s0 . 72.2.3.66 . 443 : 10.1.1.52 . 443, enp2s0 . 72.2.3.70 . 80 : 10.1.1.52 . 80 }

Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1657
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agoevaluate: infer family from mapping
Pablo Neira Ayuso [Thu, 16 Feb 2023 14:41:30 +0000 (15:41 +0100)] 
evaluate: infer family from mapping

If the key in the nat mapping is either ip or ip6, then set the nat
family accordingly, no need for explicit family in the nat statement.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agoevaluate: print error on missing family in nat statement
Pablo Neira Ayuso [Thu, 16 Feb 2023 14:49:11 +0000 (15:49 +0100)] 
evaluate: print error on missing family in nat statement

Print error message in case family cannot be inferred, before this
patch, $? shows 1 after nft execution but no error message was printed.

While at it, update error reporting for consistency in similar use
cases.

Fixes: e5c9c8fe0bcc ("evaluate: stmt_evaluate_nat_map() only if stmt->nat.ipportmap == true")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agonetlink_delinearize: Sanitize concat data element decoding
Phil Sutter [Tue, 21 Feb 2023 17:36:01 +0000 (18:36 +0100)] 
netlink_delinearize: Sanitize concat data element decoding

The call to netlink_get_register() might return NULL, catch this before
dereferencing the pointer.

Fixes: db59a5c1204c9 ("netlink_delinearize: fix decoding of concat data element")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Acked-by: Florian Westphal <fw@strlen.de>
2 years agoevaluate: relax type-checking for integer arguments in mark statements
Jeremy Sowden [Mon, 4 Apr 2022 12:13:52 +0000 (13:13 +0100)] 
evaluate: relax type-checking for integer arguments in mark statements

In order to be able to set ct and meta marks to values derived from
payload expressions, we need to relax the requirement that the type of
the statement argument must match that of the statement key.  Instead,
we require that the base-type of the argument is integer and that the
argument is small enough to fit.

Add one testcase for tests/py.

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
2 years agonetlink_delinearize: add postprocessing for payload binops
Jeremy Sowden [Mon, 4 Apr 2022 12:13:47 +0000 (13:13 +0100)] 
netlink_delinearize: add postprocessing for payload binops

If a user uses a payload expression as a statement argument:

  nft add rule t c meta mark set ip dscp lshift 2 or 0x10

we may need to undo munging during delinearization.

Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
2 years agooptimize: ignore existing nat mapping
Pablo Neira Ayuso [Tue, 7 Feb 2023 09:53:41 +0000 (10:53 +0100)] 
optimize: ignore existing nat mapping

User might be already using a nat mapping in their ruleset, use the
unsupported statement when collecting statements in this case.

 # nft -c -o -f ruleset.nft
 nft: optimize.c:443: rule_build_stmt_matrix_stmts: Assertion `k >= 0' failed.
 Aborted

The -o/--optimize feature only cares about linear rulesets at this
stage, but do not hit assert() in this case.

Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1656
Fixes: 0a6dbfce6dc3 ("optimize: merge nat rules with same selectors into map")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agorule: expand standalone chain that contains rules
Pablo Neira Ayuso [Mon, 6 Feb 2023 14:28:41 +0000 (15:28 +0100)] 
rule: expand standalone chain that contains rules

Otherwise rules that this chain contains are ignored when expressed
using the following syntax:

chain inet filter input2 {
       type filter hook input priority filter; policy accept;
       ip saddr 1.2.3.4 tcp dport { 22, 443, 123 } drop
}

When expanding the chain, remove the rule so the new CMD_OBJ_CHAIN
case does not expand it again.

Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1655
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agorule: add helper function to expand chain rules into commands
Pablo Neira Ayuso [Mon, 6 Feb 2023 14:28:40 +0000 (15:28 +0100)] 
rule: add helper function to expand chain rules into commands

This patch adds a helper function to expand chain rules into commands.
This comes in preparation for the follow up patch.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agooptimize: select merge criteria based on candidates rules
Pablo Neira Ayuso [Mon, 6 Feb 2023 13:18:10 +0000 (14:18 +0100)] 
optimize: select merge criteria based on candidates rules

Select the merge criteria based on the statements that are used
in the candidate rules, instead of using the list of statements
in the given chain.

Update tests to include a rule with a verdict, which triggers
the bug described in the bugzilla ticket.

Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1657
Fixes: 0a6dbfce6dc3 ("optimize: merge nat rules with same selectors into map")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agosrc: add support to command "destroy"
Fernando F. Mancera [Mon, 6 Feb 2023 10:06:42 +0000 (11:06 +0100)] 
src: add support to command "destroy"

"destroy" command performs a deletion as "delete" command but does not fail
if the object does not exist. As there is no NLM_F_* flag for ignoring such
error, it needs to be ignored directly on error handling.

Example of use:

# nft list ruleset
        table ip filter {
                chain output {
                }
        }
        # nft destroy table ip missingtable
# echo $?
0
        # nft list ruleset
        table ip filter {
                chain output {
                }
        }

Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agooptimize: fix incorrect expansion into concatenation with verdict map
Pablo Neira Ayuso [Thu, 2 Feb 2023 20:47:56 +0000 (21:47 +0100)] 
optimize: fix incorrect expansion into concatenation with verdict map

 # nft -c -o -f ruleset.nft
 Merging:
 ruleset.nft:3:3-53:          meta pkttype broadcast udp dport { 67, 547 } accept
 ruleset.nft:4:17-58:         meta pkttype multicast udp dport 1900 drop
 into:
        meta pkttype . udp dport vmap { broadcast . { 67, 547 } : accept, multicast . 1900 : drop }
 ruleset.nft:3:38-39: Error: invalid data type, expected concatenation of (packet type, internet network service)
                meta pkttype broadcast udp dport { 67, 547 } accept
                                                   ^^

Similar to 187c6d01d357 ("optimize: expand implicit set element when
merging into concatenation") but for verdict maps.

Reported-by: Simon G. Trajkovski <neur0armitage@proton.me>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agooptimize: wrap code to build concatenation in helper function
Pablo Neira Ayuso [Thu, 2 Feb 2023 17:15:22 +0000 (18:15 +0100)] 
optimize: wrap code to build concatenation in helper function

Move code to build concatenations into helper function, this routine
includes support for expansion of implicit sets containing singleton
values. This is preparation work to reuse existing code in a follow up
patch.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agoevaluate: set eval ctx for add/update statements with integer constants
Florian Westphal [Mon, 23 Jan 2023 18:03:28 +0000 (19:03 +0100)] 
evaluate: set eval ctx for add/update statements with integer constants

Eric reports that nft asserts when using integer basetype constants with
'typeof' sets.  Example:
table netdev t {
set s {
typeof ether saddr . vlan id
flags dynamic,timeout
}

chain c { }
}

loads fine.  But adding a rule with add/update statement fails:
nft 'add rule netdev t c set update ether saddr . 0 @s'
nft: netlink_linearize.c:867: netlink_gen_expr: Assertion `dreg < ctx->reg_low' failed.

When the 'ether saddr . 0' concat expression is processed, there is
no set definition available anymore to deduce the required size of the
integer constant.

nft eval step then derives the required length using the data types.
'0' has integer basetype, so the deduced length is 0.

The assertion triggers because serialization step finds that it
needs one more register.

2 are needed to store the ethernet address, another register is
needed for the vlan id.

Update eval step to make the expression context store the set key
information when processing the preceeding set reference, then
let stmt_evaluate_set() preserve the  existing context instead of
zeroing it again via stmt_evaluate_arg().

This makes concat expression evaluation compute the total size
needed based on the sets key definition.

Reported-by: Eric Garver <eric@garver.life>
Signed-off-by: Florian Westphal <fw@strlen.de>
2 years agotests: shell: extend runtime set element automerge to cover partial deletions
Pablo Neira Ayuso [Sun, 15 Jan 2023 19:17:50 +0000 (20:17 +0100)] 
tests: shell: extend runtime set element automerge to cover partial deletions

Perform partial deletions of an existing interval and check that the
set remains in consistent state.

Before the follow kernel fixes:

 netfilter: nft_set_rbtree: skip elements in transaction from garbage collection
 netfilter: nft_set_rbtree: Switch to node list walk for overlap detection

without these patches, this test fails with bogus overlap reports.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agoImplement 'reset rule' and 'reset rules' commands
Phil Sutter [Fri, 14 Oct 2022 21:19:22 +0000 (23:19 +0200)] 
Implement 'reset rule' and 'reset rules' commands

Reset rule counters and quotas in kernel, i.e. without having to reload
them. Requires respective kernel patch to support NFT_MSG_GETRULE_RESET
message type.

Signed-off-by: Phil Sutter <phil@nwl.cc>
2 years agointervals: restrict check missing elements fix to sets with no auto-merge
Pablo Neira Ayuso [Thu, 12 Jan 2023 20:46:41 +0000 (21:46 +0100)] 
intervals: restrict check missing elements fix to sets with no auto-merge

If auto-merge is enabled, skip check for element mismatch introduced by
6d1ee9267e7e ("intervals: check for EXPR_F_REMOVE in case of element
mismatch"), which is only relevant to sets with no auto-merge.

The interval adjustment routine for auto-merge already checks for
unexisting intervals in that case.

Uncovered via ASAN:

==11946==ERROR: AddressSanitizer: heap-use-after-free on address
0x60d00000021c at pc 0x559ae160d5b3 bp 0x7ffc37bcb800 sp 0x7ffc37bcb7f8
READ of size 4 at 0x60d00000021c thread T0
    #0 0x559ae160d5b2 in 0? /builddir/build/BUILD/nftables-1.0.6/src/intervals.c:424
    #1 0x559ae15cb05a in interval_set_eval.lto_priv.0 (/usr/lib64/libnftables.so.1+0xaf05a)
    #2 0x559ae15e1c0d in setelem_evaluate.lto_priv.0 (/usr/lib64/libnftables.so.1+0xc5c0d)
    #3 0x559ae166b715 in nft_evaluate (/usr/lib64/libnftables.so.1+0x14f715)
    #4 0x559ae16749b4 in nft_run_cmd_from_buffer (/usr/lib64/libnftables.so.1+0x1589b4)
    #5 0x559ae20c0e7e in main (/usr/bin/nft+0x8e7e)
    #6 0x559ae1341146 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #7 0x559ae1341204 in __libc_start_main_impl ../csu/libc-start.c:381
    #8 0x559ae20c1420 in _start ../sysdeps/x86_64/start.S:115

0x60d00000021c is located 60 bytes inside of 144-byte region [0x60d0000001e0,0x60d000000270) freed by thread T0 here:
    #0 0x559ae18ea618 in __interceptor_free ../../../../gcc-12.2.0/libsanitizer/asan/asan_malloc_linux.cpp:52
    #1 0x559ae160c315 in 4 /builddir/build/BUILD/nftables-1.0.6/src/intervals.c:349
    #2 0x559ae160c315 in 0? /builddir/build/BUILD/nftables-1.0.6/src/intervals.c:420

previously allocated by thread T0 here:
    #0 0x559ae18eb927 in __interceptor_calloc ../../../../gcc-12.2.0/libsanitizer/asan/asan_malloc_linux.cpp:77
    #1 0x559ae15c5076 in set_elem_expr_alloc (/usr/lib64/libnftables.so.1+0xa9076)

Fixes: 6d1ee9267e7e ("intervals: check for EXPR_F_REMOVE in case of element mismatch")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agomnl: dump_nf_hooks() leaks memory in error path
Phil Sutter [Wed, 11 Jan 2023 11:28:15 +0000 (12:28 +0100)] 
mnl: dump_nf_hooks() leaks memory in error path

Have to free the basehook object before returning to caller.

Fixes: 4694f7230195b ("src: add support for base hook dumping")
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 years agometa: parse_iso_date() returns boolean
Phil Sutter [Wed, 11 Jan 2023 10:26:41 +0000 (11:26 +0100)] 
meta: parse_iso_date() returns boolean

Returning ts if 'ts == (time_t) -1' signals success to caller despite
failure.

Fixes: 4460b839b945a ("meta: fix compiler warning in date_type_parse()")
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 years agonetlink: Fix for potential NULL-pointer deref
Phil Sutter [Tue, 10 Jan 2023 21:36:58 +0000 (22:36 +0100)] 
netlink: Fix for potential NULL-pointer deref

If memory allocation fails, calloc() returns NULL which was not checked
for. The code seems to expect zero array size though, so simply
replacing this call by one of the x*calloc() ones won't work. So guard
the call also by a check for 'len'.

Fixes: db0697ce7f602 ("src: support for flowtable listing")
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 years agooptimize: Do not return garbage from stack
Phil Sutter [Fri, 13 Jan 2023 16:09:53 +0000 (17:09 +0100)] 
optimize: Do not return garbage from stack

If input does not contain a single 'add' command (unusual, but
possible), 'ret' value was not initialized by nft_optimize() before
returning its value.

Fixes: fb298877ece27 ("src: add ruleset optimization infrastructure")
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 years agooptimize: Clarify chain_optimize() array allocations
Phil Sutter [Tue, 10 Jan 2023 21:13:44 +0000 (22:13 +0100)] 
optimize: Clarify chain_optimize() array allocations

Arguments passed to sizeof() where deemed suspicious by covscan due to
the different type. Consistently specify size of an array 'a' using
'sizeof(*a) * nmemb'.

For the statement arrays in stmt_matrix, even use xzalloc_array() since
the item count is fixed and therefore can't be zero.

Fixes: fb298877ece27 ("src: add ruleset optimization infrastructure")
Signed-off-by: Phil Sutter <phil@nwl.cc>
2 years agooptimize: payload expression requires inner_desc comparison
Pablo Neira Ayuso [Wed, 4 Jan 2023 10:25:07 +0000 (11:25 +0100)] 
optimize: payload expression requires inner_desc comparison

Since 772892a018b4 ("src: add vxlan matching support"), payload
expressions have an inner_desc field that provides the description for
the outer tunnel header.

When searching for common mergeable selectors, compare the inner
description too.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agodoc: add gretap matching expression
Pablo Neira Ayuso [Mon, 2 Jan 2023 14:36:50 +0000 (15:36 +0100)] 
doc: add gretap matching expression

Document new gretap matching expression. This includes support for
matching the encapsulated ethernet frame layer 2, 3 and 4 headers
within the gre header.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agotests: py: add gretap tests
Pablo Neira Ayuso [Mon, 2 Jan 2023 14:36:46 +0000 (15:36 +0100)] 
tests: py: add gretap tests

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agosrc: add gretap support
Pablo Neira Ayuso [Mon, 2 Jan 2023 14:36:44 +0000 (15:36 +0100)] 
src: add gretap support

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agodoc: add geneve matching expression
Pablo Neira Ayuso [Mon, 2 Jan 2023 14:36:42 +0000 (15:36 +0100)] 
doc: add geneve matching expression

Document new geneve matching expression. This includes support for
matching the encapsulated ethernet frame layer 2, 3 and 4 headers.

2 years agotests: py: add geneve tests
Pablo Neira Ayuso [Mon, 2 Jan 2023 14:36:40 +0000 (15:36 +0100)] 
tests: py: add geneve tests

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agosrc: add geneve matching support
Pablo Neira Ayuso [Mon, 2 Jan 2023 14:36:39 +0000 (15:36 +0100)] 
src: add geneve matching support

Add support for GENEVE vni and (ether) type header field.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agodoc: add gre matching expression
Pablo Neira Ayuso [Mon, 2 Jan 2023 14:36:37 +0000 (15:36 +0100)] 
doc: add gre matching expression

Document new vxlan matching expression. This includes support for
matching the encapsulated ethernet frame layer 3 and 4 headers.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agotests: py: add gre tests
Pablo Neira Ayuso [Mon, 2 Jan 2023 14:36:35 +0000 (15:36 +0100)] 
tests: py: add gre tests

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agosrc: add gre support
Pablo Neira Ayuso [Mon, 2 Jan 2023 14:36:33 +0000 (15:36 +0100)] 
src: add gre support

GRE has a number of fields that are conditional based on flags,
which requires custom dependency code similar to icmp and icmpv6.
Matching on optional fields is not supported at this stage.

Since this is a layer 3 tunnel protocol, an implicit dependency on
NFT_META_L4PROTO for IPPROTO_GRE is generated. To achieve this, this
patch adds new infrastructure to remove an outer dependency based on
the inner protocol from delinearize path.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agosrc: display (inner) tag in --debug=proto-ctx
Pablo Neira Ayuso [Mon, 2 Jan 2023 14:36:31 +0000 (15:36 +0100)] 
src: display (inner) tag in --debug=proto-ctx

For easier debugging, add decoration on protocol context:

 # nft --debug=proto-ctx add rule netdev x y udp dport 4789 vxlan ip protocol icmp counter
 update link layer protocol context (inner):
  link layer          : netdev <-
  network layer       : none
  transport layer     : none
  payload data        : none

 update network layer protocol context (inner):
  link layer          : netdev
  network layer       : ip <-
  transport layer     : none
  payload data        : none

 update network layer protocol context (inner):
  link layer          : netdev
  network layer       : ip <-
  transport layer     : none
  payload data        : none

 update transport layer protocol context (inner):
  link layer          : netdev
  network layer       : ip
  transport layer     : icmp <-
  payload data        : none

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agodoc: add vxlan matching expression
Pablo Neira Ayuso [Mon, 2 Jan 2023 14:36:30 +0000 (15:36 +0100)] 
doc: add vxlan matching expression

Document new vxlan matching expression. This includes support for
matching the encapsulated ethernet frame layer 2, 3 and 4 headers.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agotests: shell: add vxlan set tests
Pablo Neira Ayuso [Mon, 2 Jan 2023 14:36:28 +0000 (15:36 +0100)] 
tests: shell: add vxlan set tests

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agotests: py: add vxlan tests
Pablo Neira Ayuso [Mon, 2 Jan 2023 14:36:26 +0000 (15:36 +0100)] 
tests: py: add vxlan tests

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agosrc: add vxlan matching support
Pablo Neira Ayuso [Mon, 2 Jan 2023 14:36:25 +0000 (15:36 +0100)] 
src: add vxlan matching support

This patch adds the initial infrastructure to support for inner header
tunnel matching and its first user: vxlan.

A new struct proto_desc field for payload and meta expression to specify
that the expression refers to inner header matching is used.

The existing codebase to generate bytecode is fully reused, allowing for
reusing existing supported layer 2, 3 and 4 protocols.

Syntax requires to specify vxlan before the inner protocol field:

... vxlan ip protocol udp
... vxlan ip saddr 1.2.3.0/24

This also works with concatenations and anonymous sets, eg.

... vxlan ip saddr . vxlan ip daddr { 1.2.3.4 . 4.3.2.1 }

You have to restrict vxlan matching to udp traffic, otherwise it
complains on missing transport protocol dependency, e.g.

... udp dport 4789 vxlan ip daddr 1.2.3.4

The bytecode that is generated uses the new inner expression:

 # nft --debug=netlink add rule netdev x y udp dport 4789 vxlan ip saddr 1.2.3.4
 netdev x y
  [ meta load l4proto => reg 1 ]
  [ cmp eq reg 1 0x00000011 ]
  [ payload load 2b @ transport header + 2 => reg 1 ]
  [ cmp eq reg 1 0x0000b512 ]
  [ inner type 1 hdrsize 8 flags f [ meta load protocol => reg 1 ] ]
  [ cmp eq reg 1 0x00000008 ]
  [ inner type 1 hdrsize 8 flags f [ payload load 4b @ network header + 12 => reg 1 ] ]
  [ cmp eq reg 1 0x04030201 ]

JSON support is not included in this patch.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agosrc: add dl_proto_ctx()
Pablo Neira Ayuso [Mon, 2 Jan 2023 14:36:23 +0000 (15:36 +0100)] 
src: add dl_proto_ctx()

Add dl_proto_ctx() to access protocol context (struct proto_ctx and
struct payload_dep_ctx) from the delinearize path.

This patch comes in preparation for supporting outer and inner
protocol context.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agosrc: add eval_proto_ctx()
Pablo Neira Ayuso [Mon, 2 Jan 2023 14:36:20 +0000 (15:36 +0100)] 
src: add eval_proto_ctx()

Add eval_proto_ctx() to access protocol context (struct proto_ctx).
Rename struct proto_ctx field to _pctx to highlight that this field
is internal and the helper function should be used.

This patch comes in preparation for supporting outer and inner
protocol context.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
2 years agosrc: Add GPLv2+ header to .c files of recent creation
Pablo Neira Ayuso [Wed, 7 Dec 2022 15:08:15 +0000 (16:08 +0100)] 
src: Add GPLv2+ header to .c files of recent creation

This patch comes after a proposal of mine at NFWS 2022 that resulted in
agreement to license recent .c files under GPLv2+ by the attendees at this
meeting:

- Stefano Brivio
- Fernando F. Mancera
- Phil Sutter
- Jozsef Kadlecsik
- Florian Westphal
- Laura Garcia
- Arturo Borrero
- Pablo Neira

It has already happened that one of the external library dependencies
was moved to GPLv3+ (libreadline), resulting in a change to libedit by
default in b4dded0ca78d ("configure: default to libedit for cli").

I have added the GPLv2+ header to the following files:

                        Authors
                        -------
src/cmd.c               Pablo
src/fib.c               Florian
src/hash.c              Pablo
src/iface.c             Pablo
src/json.c              Phil + fixes from occasional contributors
src/libnftables.c       Eric Leblond and Phil
src/mergesort.c         Elise Lenion
src/misspell.c          Pablo
src/mnl.c               Pablo + fixes from occasional contributors
src/monitor.c           Arturo
src/numgen.c            Pablo
src/osf.c               Fernando
src/owner.c             Pablo
src/parser_json.c       Phil + fixes from occasional contributors
src/print.c             Phil
src/xfrm.c              Florian
src/xt.c                Pablo

Eric Leblond and Elise Lennion did not attend NFWS 2022, but they
acknowledged this license update already in the past when I proposed
this to them in private emails.

Update COPYING file too to refer that we are now moving towards GPLv2 or
any later.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>