Setuptools has had support for declarative configuration for several
years. To quote their documentation:
Setuptools allows using configuration files (usually setup.cfg) to
define a package’s metadata and other options that are normally
supplied to the setup() function (declarative config).
This approach not only allows automation scenarios but also reduces
boilerplate code in some cases.
Additionally, this allows us to introduce support for PEP-517-compatible
build-systems.
Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Separate the actual package source from the build files. In addition
to being a bit tidier, this will prevent setup.py being erroneously
installed when we introduce PEP-517 support in a later commit.
Signed-off-by: Jeremy Sowden <jeremy@azazel.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
The "dnat" command is usable from either "prerouting" or "output", but the
"dstnat" priority is only usable from "prerouting". (Likewise, "snat" is usable
from either "postrouting" or "input", but "srcnat" is only usable from
"postrouting".)
No need to restrict those priorities to pre/postrouting.
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
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>
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>
Synopsis insinuates an IP address argument is mandatory in snat/dnat
statements although specifying ports alone is perfectly fine. Adjust it
accordingly and add a paragraph briefly describing the behaviour.
While at it, update the redirect statement description with more
relevant examples, the current one is wrong: To *only* alter the
destination port, dnat statement must be used, not redirect.
Fixes: 6908a677ba04c ("nft.8: Enhance NAT documentation") Signed-off-by: Phil Sutter <phil@nwl.cc>
When the hook location is invalid we error out but we do leak both
the priority expression and the flowtable name. Example:
valgrind --leak-check=full nft -f flowtable-parser-err-memleak
[..] Error: unknown chain hook
hook enoent priority filter + 10
^^^^^^
[..]
2 bytes in 1 blocks are definitely lost in loss record 1 of 3
at: malloc (vg_replace_malloc.c:446)
by: strdup (in libc.so.6)
by: xstrdup (in libnftables.so.1.1.0)
by: nft_lex (in libnftables.so.1.1.0)
by: nft_parse (in libnftables.so.1.1.0)
by: __nft_run_cmd_from_filename (in libnftables.so.1.1.0)
by: nft_run_cmd_from_filename (in libnftables.so.1.1.0)
First two reports are due to the priority expression: this needs to call
expr_free(). Third report is due to the flowtable name, the destructor
was missing so add one.
After fix:
All heap blocks were freed -- no leaks are possible
Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
This change is similar to 7f4d7fef31bd ("evaluate: check element key vs. set definition")
but this time for data mappings.
The included bogon asserts with:
BUG: invalid data expression type catch-all set element
nft: src/netlink.c:596: __netlink_gen_data: Assertion `0' failed.
after:
internal:0:0-0: Error: Element mapping mismatches map definition, expected packet mark, not 'invalid'
Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
This is a followup to 44ea19364637 ("src: BASECHAIN flag no longer implies presence of priority expression"):
feeding the same bogon file into nft -j we get a very similar crash.
When the json is parsed without returning an error the test
fails. Its supposed to log the name of the failed input which
it does for -f but not for -j -f.
Resolve this by validating that the set element key matches the set key
definition.
After this, loading the bogon file gives:
Error: Element mismatches set definition, expected concatenation of (IPv4 address, integer), not 'ICMP type'
elements = {redirect }
^^^^^^^^
Update test to enclose flowtable device names in quotes, otherwise,
it reports a spurious issue:
@@ -1,2 +1,3 @@
add table ip t
-add flowtable ip t ft { hook ingress priority 0; devices = { lo }; }
+add flowtable ip t ft { hook ingress priority 0; devices = { "lo" }; }
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Its not enough to check for interval flag, this would assert in interval
code due to concat being passed to the interval code:
BUG: unhandled key type 13
After fix:
same_set_name_but_different_keys_assert:8:6-7: Error: set already exists with
different datatype (concatenation of (IPv4 address, network interface index) vs
network interface index)
set s4 {
^^
This also improves error verbosity when mixing datamap and objref maps:
invalid_transcation_merge_map_and_objref_map:9:13-13:
Error: map already exists with different datatype (IPv4 address vs string)
.. instead of 'Cannot merge map with incompatible existing map of same name'.
The 'Cannot merge map with incompatible existing map of same name' check
is kept in place to catch when ruleset contains a set and map with same name
and same key definition.
Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
Reject maps and sets of the same name:
BUG: invalid range expression type catch-all set element
nft: src/expression.c:1704: range_expr_value_low: Assertion `0' failed.
After:
Error: Cannot merge set with existing datamap of same name
set z {
^
v2:
Pablo points out that we shouldn't merge datamaps (plain value) and objref
maps either, catch this too and add another test:
nft --check -f invalid_transcation_merge_map_and_objref_map
invalid_transcation_merge_map_and_objref_map:9:13-13: Error: Cannot merge map with incompatible existing map of same name
We should also make sure that both data (for map case) and
set keys are identical, this is added in a followup patch.
commit 98c51aaac42b ("evaluate: bail out if anonymous concat set defines a non concat expression")
clears set->init to avoid a double-free.
Extend this to also handle object maps.
The included bogon triggers a double-free of set->init expression:
Error: unqualified type invalid specified in map definition. Try "typeof expression" instead of "type datatype".
ct helper set ct saddr map { 1c3:: : "p", dead::beef : "myftp" }
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This might not crash, depending on libc/malloc, but ASAN reports this:
==17728==ERROR: AddressSanitizer: heap-use-after-free on address 0x50b0000005e8 at ..
READ of size 4 at 0x50b0000005e8 thread T0
#0 0x7f1be3cb7526 in expr_free src/expression.c:87
#1 0x7f1be3cbdf29 in map_expr_destroy src/expression.c:1488
#2 0x7f1be3cb74d5 in expr_destroy src/expression.c:80
#3 0x7f1be3cb75c6 in expr_free src/expression.c:96
#4 0x7f1be3d5925e in objref_stmt_destroy src/statement.c:331
#5 0x7f1be3d5831f in stmt_free src/statement.c:56
#6 0x7f1be3d583c2 in stmt_list_free src/statement.c:66
#7 0x7f1be3d42805 in rule_free src/rule.c:495
#8 0x7f1be3d48329 in cmd_free src/rule.c:1417
#9 0x7f1be3cd2c7c in __nft_run_cmd_from_filename src/libnftables.c:759
#10 0x7f1be3cd340c in nft_run_cmd_from_filename src/libnftables.c:847
#11 0x55dcde0440be in main src/main.c:535
Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
There is no guarantee that chain[] is null terminated, so snprintf
can read past chain[] array. ASAN report is:
AddressSanitizer: stack-buffer-overflow on address 0x7ffff5f00520 at ..
READ of size 257 at 0x7ffff5f00520 thread T0
#0 0x00000032ffb6 in printf_common(void*, char const*, __va_list_tag*) (src/nft+0x32ffb6)
#1 0x00000033055d in vsnprintf (src/nft+0x33055d)
#2 0x000000332071 in snprintf (src/nft+0x332071)
#3 0x0000004eef03 in netlink_gen_chain src/netlink.c:454:2
#4 0x0000004eef03 in netlink_gen_verdict src/netlink.c:467:4
Reject chain jumps that exceed 255 characters, which matches the netlink
policy on the kernel side.
The included reproducer fails without asan too because the kernel will
reject the too-long chain name. But that happens after the asan detected
bogus read.
Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
We need to restrict this, included bogon asserts with:
BUG: unknown expression type prefix
nft: src/netlink_linearize.c:940: netlink_gen_expr: Assertion `0' failed.
Prefix expressions are only allowed if the concatenation is used within
a set element, not when specifying the lookup key.
For the former, anything that represents a value is allowed.
For the latter, only what will generate data (fill a register) is
permitted.
At this time we do not have an annotation that tells if the expression
is on the left hand side (lookup key) or right hand side (set element).
Add a new list recursion counter for this. If its 0 then we're building
the lookup key, if its the latter the concatenation is the RHS part
of a relational expression and prefix, ranges and so on are allowed.
IOW, we don't really need a recursion counter, another type of annotation
that would tell if the expression is placed on the left or right hand side
of another expression would work too.
v2: explicitly list all 'illegal' expression types instead of
using a default label for them.
This will raise a compiler warning to remind us to adjust the case
labels in case a new expression type gets added in the future.
The existing recursion counter is used by the binop expression to detect
if we've completely followed all the binops.
We can only chain up to NFT_MAX_EXPR_RECURSION binops, but the evaluation
step can perform constant-folding, so we must recurse until we found the
rightmost (last) binop in the chain.
Then we can check the post-eval chain to see if it is something that can
be serialized later (i.e., if we are within the NFT_MAX_EXPR_RECURSION
after constant folding) or not.
Thus we can't reuse the existing ctx->recursion counter for other
expressions; entering the initial expr_evaluate_binop with
ctx->recursion > 0 would break things.
Therefore rename this to an embedded structure.
This allows us to add a new recursion counter in a followup patch.
Use the defined $NFT variable instead of calling the system nft binary directly.
Add a nat_ftp.nodump file to avoid the following check-tree.sh error:
ERR: "tests/shell/testcases/packetpath/nat_ftp" has no "tests/shell/testcases/packetpath/dumps/nat_ftp.{nft,nodump}" file.
Signed-off-by: Yi Chen <yiche@redhat.com> Signed-off-by: Florian Westphal <fw@strlen.de>
If there is no priority.expr set, assume hook.num is bogus, too.
While this is fixing JSON output, it's hard to tell what commit this is
actually fixing: Before commit 627c451b23513 ("src: allow variables in
the chain priority specification"), there was no way to detect
flowtables missing hook specs (e.g. when printing flowtable delete
monitor event).
Signed-off-by: Phil Sutter <phil@nwl.cc> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
We can't recover from errors here, but we can abort with a more
precise reason than 'segmentation fault', or stack corruptions
that get caught way later, or not at all.
expr->value is going to be read, we can't cope with other expression
types here.
We will copy to stack buffer of IFNAMSIZ size, abort if we would
overflow.
Check there is a NUL byte present too.
This is a preemptive patch, I've seen one crash in this area but
no reproducer yet.
Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
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> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Prepare for calling netlink_io_error() which needs the context pointer.
Trade this in for the cache pointer since no caller uses a special one.
No functional change intended.
Signed-off-by: Phil Sutter <phil@nwl.cc> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Netlink parser tries to keep going despite errors. Faced with an
incompatible ruleset, this is much more user-friendly than exiting the
program upon the first obstacle. This patch fixes three more spots to
support this.
Signed-off-by: Phil Sutter <phil@nwl.cc> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
Print an error message and discard the object instead of returning it to
the caller. At least when trying to print it, we would hit an assert()
in obj_type_name() anyway.
Fixes: 4756d92e517ae ("src: listing of stateful objects") Signed-off-by: Phil Sutter <phil@nwl.cc>
Whenever a new version adds udata support to an expression, then old
versions of nft will crash when trying to list such a ruleset generated
by a more recent version of nftables.
Make fewer assumptions about the underlying integer type of the enum.
Instead, be clear about where we have an untrusted uint32_t from netlink
and an enum. Rename expr_ops_by_type() to expr_ops_by_type_u32() to make
this clearer. Later we might make the enum as packed, when this starts
to matter more.
Also, only the code path expr_ops() wants strict validation and assert
against valid enum values. Move the assertion out of
__expr_ops_by_type(). Then expr_ops_by_type_u32() does not need to
duplicate the handling of EXPR_INVALID. We still need to duplicate the
check against EXPR_MAX, to ensure that the uint32_t value can be cast to
an enum value.
[ Remove cast on EXPR_MAX. --pablo ]
Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
If we have an incomplete rule like "ct original saddr" in inet
family, this function generates an error because it can't determine the required protocol
dependency, hinting at missing ip/ip6 keyword.
We should not go on in this case to avoid a redundant followup error:
nft add rule inet f c ct original saddr 1.2.3.4
Error: cannot determine ip protocol version, use "ip saddr" or "ip6 saddr" instead
add rule inet f c ct original saddr 1.2.3.4
^^^^^^^^^^^^^^^^^
Error: Could not parse symbolic invalid expression
add rule inet f c ct original saddr 1.2.3.4
After this change only the first error is shown.
Fixes: 2b29ea5f3c3e ("src: ct: add eval part to inject dependencies for ct saddr/daddr") Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
When parsing a verdict map json where element jumps to chain represented
as empty string.
internal:0:0-0: Error: Parsing list expression item at index 0 failed.
internal:0:0-0: Error: Invalid set elem at index 0.
internal:0:0-0: Error: Invalid set elem expression.
internal:0:0-0: Error: Parsing command array at index 2 failed.
Just like "ct timeout", "ct expectation" is in need of the same fix,
we get segfault on "nft list ct expectation table t", if table t exists.
This is the exact same pattern as resolved for "ct timeout" in commit 1d2e22fc0521 ("ct timeout: fix 'list object x' vs. 'list objects in table' confusion").
<empty ruleset>
$ nft list ct timeout table t
Error: No such file or directory
list ct timeout table t
^
This is expected to list all 'ct timeout' objects.
The failure is correct, the table 't' does not exist.
But now lets add one:
$ nft add table t
$ nft list ct timeout table t
Segmentation fault (core dumped)
... and thats not expected, nothing should be shown
and nft should exit normally.
Because of missing TIMEOUTS command enum, the backend thinks
it should do an object lookup, but as frontend asked for
'list of objects' rather than 'show this object',
handle.obj.name is NULL, which then results in this crash.
Update the command enums so that backend knows what the
frontend asked for.
The payload statement evaluation pretends that it can handle any
expression for bitfields, but the existing evaluation code only knows
how to handle value expression.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Instead of allocating a lshift expression and relying on the binary
operation transfer propagate this to the mask value, lshift the mask
value immediately.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Blamed commits change output format but did not adjust existing tests:
inet/fib.t: WARNING: line 16: '{"nftables": ..
Fixes: 38f99ee84fe6 ("json: Print single synproxy flags as non-array") Fixes: dbe5c44f2b89 ("json: Print single fib flag as non-array") Signed-off-by: Florian Westphal <fw@strlen.de> Acked-by: Phil Sutter <phil@nwl.cc>
We can't remove 'meta nfproto' dependencies for all cases.
Its removed for ip/ip6 families, this works fine.
But for others, e.g. inet, removal is not as simple.
For example
meta nfproto ipv4 ct protocol tcp
is listed as 'ct protocol tcp', even when this is uses in the inet
table.
Meta L4PROTO removal checks were correct, but refactor this
into a helper function to split meta/ct checks from the common
calling function.
Ct check was lacking, we need to examine ct keys more closely
to figure out if they need to retain the network protocol depenency
or not. Elide for NFT_CT_SRC/DST and its variants, as those imply
the network protocol to use, all others must keep it as-is.
Revert commit d1a7b9e19fe65 ("tests: py: update netdev reject test
file"), the stored JSON equivalents were correct in that they matched
the standard syntax input.
In fact, we missed a .json.output file recording the expected deviation
in JSON output.
Fixes: d1a7b9e19fe65 ("tests: py: update netdev reject test file") Fixes: 7ca3368cd7575 ("reject: Unify inet, netdev and bridge delinearization") Signed-off-by: Phil Sutter <phil@nwl.cc> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
When running a test for which no corresponding *.payload file exists,
the *.payload.got file name was incorrectly constructed due to
'payload_path' variable not being set.
Fixes: 2cfab7a3e10fc ("tests/py: Write dissenting payload into the right file") Signed-off-by: Phil Sutter <phil@nwl.cc>
Make sure they match the standard syntax input as much as possible.
For some reason inet/tcp.t.json was using plain arrays in place of
binary OR expressions in many cases. These arrays are interpreted as
list expressions, which seems to be semantically identical but the goal
here is to present an accurate equivalent to the rule in standard
syntax.
tests/py/any/meta.t.json.got: WARNING: line 2: Wrote JSON equivalent for rule meta mark set vlan id map { 1 : 0x00000001, 4095 : 0x00004095 }
ERROR: did not find JSON equivalent for rule 'meta mark set vlan id map @map1
Fixes: 8d3de823b622 ("evaluate: reset statement length context before evaluating statement") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Originally, the plan was to use tests/shell from git HEAD, but this
does not work well in practise because slight changes in the test
output break checks resulting in lots of [DUMP FAIL] errors.
It is easier to test infrastructure self-contained in this 1.0.6.y
branch.
However, backporting the tests/shell into 1.0.6.y turns out to be more
complicated than expected, so I decided to follow the opposite, which is
to (brute) force a copy of tests/shell from 2a38f458f12bc032dac1b3ba63f95ca5a3c03fbd into this branch.
This also requires a number follow up partial reverts on tests/shell
updates to work with 1.0.6.y.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
The bison parser enforces this implicitly by grammar rules.
Because subkeys have to be conatenated via ".", notation, e.g.
"mark . ip saddr", all concatenation expressions always consist of at
least two elements.
But this doesn't apply to the json frontend which just uses an array:
it can be empty or only contain one element.
The included reproducer makes the eval stage set the "concatenation" flag
on the interval set. This prevents the needed conversion code to turn the
element values into ranges from getting run.