summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* tests/shell: support --keep-logs option (NFT_TEST_KEEP_LOGS=y) to preserve ↵Thomas Haller2023-09-071-3/+19
| | | | | | | | | | | test output The test output is now all collected in the temporary directory. On success, that directory is deleted. Add an option to always preserve that directory. Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Florian Westphal <fw@strlen.de>
* tests/shell: interpret an exit code of 77 from scripts as "skipped"Thomas Haller2023-09-072-1/+12
| | | | | | | | | | | | Allow scripts to indicate that a test could not run by exiting 77. "77" is chosen as exit code from automake's testsuites ([1]). Compare to git-bisect which chooses 125 to indicate skipped. [1] https://www.gnu.org/software/automake/manual/html_node/Scripts_002dbased-Testsuites.html Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Florian Westphal <fw@strlen.de>
* tests/shell: run each test in separate namespace and allow rootlessThomas Haller2023-09-072-17/+130
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Don't unshare the entire shell script. Instead, call unshare each test separately. That means, all tests use now a different sandbox and will also allow (with further changes) to run them in parallel. Also, allow to run rootless/unprivileged. The script first tries to run a separate PID+USER+NET namespace. If that fails, it downgrades to USER+NET. If that fails, it downgrades to a separate NET namespace. If unshare still fails, the script fails entirely. That differs from before, where the script would proceed without sandboxing. The script will now always require that unsharing works, unless the user opts-out. If the user cannot unshare, they can set NFT_TEST_UNSHARE_CMD to the command used for unsharing. It may be empty for no unshare. The command line arguments -U/--no-unshare are a shortcut for setting NFT_TEST_UNSHARE_CMD="". If we are able to create a separate USER namespace, then this mode allows to run the test as rootless/unprivileged. We no longer require [ `id -u` = 0 ]. Some tests may not work as rootless. For example, the socket buffers is limited by /proc/sys/net/core/{wmem_max,rmem_max} which real-root can override, but rootless tests cannot. Such tests should check for [ "$NFT_TEST_HAS_REALROOT" != y ] and skip gracefully. Usually, the user doesn't need to tell the script whether they have real-root. The script will autodetect it via [ `id -u` = 0 ]. But that won't work when run inside a rootless container already. In that case, the user would want to tell the script that there is no real-root. They can do so via the -R/--without-root option or NFT_TEST_HAS_REALROOT=n. If tests wish, the can know whether they run inside "unshare" environment by checking for [ "$NFT_TEST_HAS_UNSHARED" = y ]. When setting NFT_TEST_UNSHARE_CMD to override the unshare command, users may want to also set NFT_TEST_HAS_UNSHARED= and NFT_TEST_HAS_REALROOT= correctly. As we run each test in a separate unshare environment, we need a wrapper "tests/shell/helpers/test-wrapper.sh" around the test, which executes inside the tested environment. Also, each test gets its own temp directory prepared in NFT_TEST_TESTTMPDIR. This is also the place, where test artifacts and results will be collected. Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Florian Westphal <fw@strlen.de>
* tests/shell: print test configurationThomas Haller2023-09-071-5/+10
| | | | | | | | | As the script can be configured via environment variables or command line option, it's useful to show the environment variables that we received or set during the test setup. Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Florian Westphal <fw@strlen.de>
* tests/shell: normalize boolean configuration in environment variablesThomas Haller2023-09-071-4/+15
| | | | | | | | | | | | Previously, we would honor "y" as opt-in, and all other values meant false. - accept alternatives to "y", like "1" or "true". - normalize the value, to either be "y" or "n". Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Florian Westphal <fw@strlen.de>
* tests/shell: export NFT_TEST_BASEDIR and NFT_TEST_TMPDIR for testsThomas Haller2023-09-071-24/+39
| | | | | | | | | | | | | | | | | | | | | | | | | | | Let the test wrapper prepare and export two environment variables for the test: - "$NFT_TEST_BASEDIR" is just the top directory where the test scripts lie. - "$NFT_TEST_TMPDIR" is a `mktemp` directory created by "run-tests.sh" and removed at the end. Tests may use that to leave data there. This directory will be used for various things, like the "nft" wrapper in valgrind mode, the results of the tests and possibly as cache for feature detection. The "$NFT_TEST_TMPDIR" was already used before with the "VALGRIND=y" mode. It's only renamed and got an extended purpose. Also drop the unnecessary first detection of "$DIFF" and the "$SRC_NFT" variable. Also, note that the mktemp creates the temporary directory under /tmp. Which is commonly a tempfs. The user can override that by exporting TMPDIR. Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Florian Westphal <fw@strlen.de>
* tests/shell: check test names before start and support directoriesThomas Haller2023-09-071-0/+12
| | | | | | | | | | | Check for valid test names early. That's useful because we treat any unrecognized options as test names. We should detect a mistake early. While at it, also support specifying directory names instead of executable files. Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Florian Westphal <fw@strlen.de>
* tests/shell: rework finding tests and add "--list-tests" optionThomas Haller2023-09-071-28/+30
| | | | | | | | | | | | | | Cleanup finding the test files. Also add a "--list-tests" option to see which tests are found and would run. Also get rid of the FIND="$(which find)" detection. Which system doesn't have a working find? Also, we can just fail when we try to use find, and don't need a check first. This is still after "unshare", which will be addressed next. Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Florian Westphal <fw@strlen.de>
* tests/shell: rework command line parsing in "run-tests.sh"Thomas Haller2023-09-071-30/+68
| | | | | | | | | | | | Parse the arguments in a loop, so that their order does not matter. Also, soon more command line arguments will be added, and this way of parsing seems more maintainable and flexible. Currently this is still after the is-root check and after unshare. That will be addressed later. Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Florian Westphal <fw@strlen.de>
* tests: shell: 0043concatenated_ranges_0: re-enable all testsFlorian Westphal2023-09-061-6/+1
| | | | | | | | This script suppressed a few tests when ran via run-tests.sh, don't do that, it would have caught the previous 'get' bug years ago. Signed-off-by: Florian Westphal <fw@strlen.de>
* evaluate: fix get element for concatenated setFlorian Westphal2023-09-061-4/+7
| | | | | | | | | | | | | | | | | | | | | | | | given: table ip filter { set test { type ipv4_addr . ether_addr . mark flags interval elements = { 198.51.100.0/25 . 00:0b:0c:ca:cc:10-c1:a0:c1:cc:10:00 . 0x0000006f, } } } We get lookup failure: nft get element ip filter test { 198.51.100.1 . 00:0b:0c:ca:cc:10 . 0x6f } Error: Could not process rule: No such file or directory Its possible to work around this via dummy range somewhere in the key, e.g. nft get element ip filter test { 198.51.100.1 . 00:0b:0c:ca:cc:10 . 0x6f-0x6f } but that shouldn't be needed, so make sure the INTERVAL flag is enabled for the queried element if the set is of interval type. Signed-off-by: Florian Westphal <fw@strlen.de>
* doc: describe behaviour of {ip,ip6} lengthPablo Neira Ayuso2023-09-031-0/+16
| | | | | | | | This field exposes internal kernel GRO/GSO packet aggregation implementation details to userspace, provide a hint to the user to understand better when matching on this field. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: revisit anonymous set with single element optimizationPablo Neira Ayuso2023-09-021-20/+40
| | | | | | | | | | | | | | | | | | | | | This patch reworks it to perform this optimization from the evaluation step of the relational expression. Hence, when optimizing for protocol flags, use OP_EQ instead of OP_IMPLICIT, that is: tcp flags { syn } becomes (to represent an exact match): tcp flags == syn given OP_IMPLICIT and OP_EQ are not equivalent for flags. 01167c393a12 ("evaluate: do not remove anonymous set with protocol flags and single element") disabled this optimization, which is enabled again after this patch. Fixes: 01167c393a12 ("evaluate: do not remove anonymous set with protocol flags and single element") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: place byteorder conversion after numgen for IP address datatypesJorge Ortiz2023-09-015-0/+77
| | | | | | | | | | | | | | | | | | | | | | | | The numgen extension generates numbers in little-endian. This can be very tricky when trying to combine it with IP addresses, which use big endian. This change adds a new byteorder operation to convert data type endianness. Before this patch: $ sudo nft -d netlink add rule nat snat_chain snat to numgen inc mod 7 offset 0x0a000001 ip nat snat_chain [ numgen reg 1 = inc mod 7 offset 167772161 ] [ nat snat ip addr_min reg 1 ] After this patch: $ sudo nft -d netlink add rule nat snat_chain snat to numgen inc mod 7 offset 0x0a000001 ip nat snat_chain [ numgen reg 1 = inc mod 7 offset 167772161 ] [ byteorder reg 1 = hton(reg 1, 4, 4) ] [ nat snat ip addr_min reg 1 ] Regression tests have been modified to include these new cases. Signed-off-by: Jorge Ortiz Escribano <jorge.ortiz.escribano@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* rule: set internal_location for table and chainPablo Neira Ayuso2023-08-311-0/+2
| | | | | | | JSON parser does not seem to set on this, better provide a default location. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: simplify chain_alloc()Pablo Neira Ayuso2023-08-316-9/+9
| | | | | | | Remove parameter to set the chain name which is only used from netlink path. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: remove check for NULL before calling expr_free()Pablo Neira Ayuso2023-08-312-4/+3
| | | | | | expr_free() already handles NULL pointer, remove redundant check. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: use internal_location for unspecified location at allocation timePablo Neira Ayuso2023-08-313-12/+19
| | | | | | | Set location to internal_location instead of NULL to ensure this is always set. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* xt: avoid "-Wmissing-field-initializers" for "original_opts"Thomas Haller2023-08-301-1/+1
| | | | | | | | | | | | | | | | | | Avoid this warning with clang: CC src/xt.lo src/xt.c:353:9: error: missing field 'has_arg' initializer [-Werror,-Wmissing-field-initializers] { NULL }, ^ The warning seems not very useful, because it's well understood that specifying only some initializers leaves the remaining fields initialized with the default. However, as this warning is only hit once in the code base, it doesn't seem that we violate this style frequently. Hence, fix it instead of disabling the warning. Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: silence "implicit-fallthrough" warningsThomas Haller2023-08-302-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | | Gcc with "-Wextra" warns: CC segtree.lo segtree.c: In function 'get_set_interval_find': segtree.c:129:28: error: this statement may fall through [-Werror=implicit-fallthrough=] 129 | if (expr_basetype(i->key)->type != TYPE_STRING) | ^ segtree.c:134:17: note: here 134 | case EXPR_PREFIX: | ^~~~ CC optimize.lo optimize.c: In function 'rule_collect_stmts': optimize.c:396:28: error: this statement may fall through [-Werror=implicit-fallthrough=] 396 | if (stmt->expr->left->etype == EXPR_CONCAT) { | ^ optimize.c:400:17: note: here 400 | case STMT_VERDICT: | ^~~~ Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* utils: call abort() after BUG() macroThomas Haller2023-08-301-1/+2
| | | | | | | | | | | | | | | | | | | | | | | Otherwise, we get spurious warnings. The compiler should be aware that there is no return from BUG(). Call abort() there, which is marked as __attribute__ ((__noreturn__)). In file included from ./include/nftables.h:6, from ./include/rule.h:4, from src/payload.c:26: src/payload.c: In function 'icmp_dep_to_type': ./include/utils.h:39:34: error: this statement may fall through [-Werror=implicit-fallthrough=] 39 | #define BUG(fmt, arg...) ({ fprintf(stderr, "BUG: " fmt, ##arg); assert(0); }) | ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/payload.c:791:17: note: in expansion of macro 'BUG' 791 | BUG("Invalid map for simple dependency"); | ^~~ src/payload.c:792:9: note: here 792 | case PROTO_ICMP_ECHO: return ICMP_ECHO; | ^~~~ Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* rule: fix "const static" declarationThomas Haller2023-08-301-2/+2
| | | | | | | | | | | | | | Gcc warns against this with "-Wextra": src/rule.c:869:1: error: static is not at beginning of declaration [-Werror=old-style-declaration] 869 | const static struct prio_tag std_prios[] = { | ^~~~~ src/rule.c:878:1: error: static is not at beginning of declaration [-Werror=old-style-declaration] 878 | const static struct prio_tag bridge_std_prios[] = { | ^~~~~ Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: py: debloat frag.t.payload.netdevPablo Neira Ayuso2023-08-301-1990/+36
| | | | | | This bytecode output file contains many duplicated entries, remove them. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: py: extend ip frag-off coveragePablo Neira Ayuso2023-08-306-0/+156
| | | | | | Cover matching on DF and MF bits and fragments. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* proto: use hexadecimal to display ip frag-off fieldPablo Neira Ayuso2023-08-307-37/+39
| | | | | | | | | | | | | The ip frag-off field in the protocol definition is 16-bits long and it contains the DF (0x2000) and MF (0x4000) bits too. iptables-translate also suggests: ip frag-off & 0x1ffff != 0 to match on fragments. Use hexadecimal for listing this header field. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: do not remove anonymous set with protocol flags and single elementPablo Neira Ayuso2023-08-301-1/+6
| | | | | | | | | | | | | | | | | | | | | | | | | Set lookups with flags search for an exact match, however: tcp flags { syn } gets transformed into: tcp flags syn which is matching on the syn flag only (non-exact match). This optimization is safe for ct state though, because only one bit is ever set on in the ct state bitmask. Since protocol flags allow for combining flags, skip this optimization to retain exact match semantics. Another possible solution is to turn OP_IMPLICIT into OP_EQ for exact flag match to re-introduce this optimization and deal with this corner case. Fixes: fee6bda06403 ("evaluate: remove anon sets with exactly one element") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* include: drop "format" attribute from nft_gmp_print()Thomas Haller2023-08-291-2/+1
| | | | | | | | | | | | | | | | | | | | | | | | nft_gmp_print() passes the format string and arguments to gmp_vfprintf(). Note that the format string is then interpreted by gmp, which also understand special specifiers like "%Zx". Note that with clang we get various compiler warnings: datatype.c:299:26: error: invalid conversion specifier 'Z' [-Werror,-Wformat-invalid-specifier] nft_gmp_print(octx, "0x%Zx [invalid type]", expr->value); ~^ gcc doesn't warn, because to gcc 'Z' is a deprecated alias for 'z' and because the 3rd argument of the attribute((format())) is zero (so gcc doesn't validate the arguments). But Z specifier in gmp expects a "mpz_t" value and not a size_t. It's really not the same thing. The correct solution is not to mark the function to accept a printf format string. Fixes: 2535ba7006f2 ('src: get rid of printf') Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: suppress "-Wunused-but-set-variable" warning with "parser_bison.c"Thomas Haller2023-08-291-0/+1
| | | | | | | | | | | | | | Clang warns: parser_bison.c:7606:9: error: variable 'nft_nerrs' set but not used [-Werror,-Wunused-but-set-variable] int yynerrs = 0; ^ parser_bison.c:72:25: note: expanded from macro 'yynerrs' #define yynerrs nft_nerrs ^ Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: don't needlessly clear full string buffer in ↵Thomas Haller2023-08-291-1/+4
| | | | | | | stmt_evaluate_log_prefix() Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: rework SNPRINTF_BUFFER_SIZE() and handle truncationThomas Haller2023-08-293-17/+37
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Before, the macro asserts against truncation. This is despite the callers still checked for truncation and tried to handle it. Probably for good reason. With stmt_evaluate_log_prefix() it's not clear that the code ensures that truncation cannot happen, so we must not assert against it, but handle it. Also, - wrap the macro in "do { ... } while(0)" to make it more function-like. - evaluate macro arguments exactly once, to make it more function-like. - take pointers to the arguments that are being modified. - use assert() instead of abort(). - use size_t type for arguments related to the buffer size. - drop "size". It was mostly redundant to "offset". We can know everything we want based on "len" and "offset" alone. - "offset" previously was incremented before checking for truncation. So it would point somewhere past the buffer. This behavior does not seem useful. Instead, on truncation "len" will be zero (as before) and "offset" will point one past the buffer (one past the terminating NUL). Thereby, also fix a warning from clang: evaluate.c:4134:9: error: variable 'size' set but not used [-Werror,-Wunused-but-set-variable] size_t size = 0; ^ meta.c:1006:9: error: variable 'size' set but not used [-Werror,-Wunused-but-set-variable] size_t size; ^ Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: fix check for truncation in stmt_evaluate_log_prefix()Thomas Haller2023-08-291-1/+1
| | | | | | | | | | | | | | | | | | | Otherwise, nft crashes with prefix longer than 127 bytes: # nft add rule x y log prefix \"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\" ==159385==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffed5bf4a10 at pc 0x7f3134839269 bp 0x7ffed5bf48b0 sp 0x7ffed5bf4060 WRITE of size 129 at 0x7ffed5bf4a10 thread T0 #0 0x7f3134839268 in __interceptor_memset ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:778 #1 0x7f3133e3074e in __mpz_export_data /tmp/nftables/src/gmputil.c:110 #2 0x7f3133d21d3c in expr_to_string /tmp/nftables/src/expression.c:192 #3 0x7f3133ded103 in netlink_gen_log_stmt /tmp/nftables/src/netlink_linearize.c:1148 #4 0x7f3133df33a1 in netlink_gen_stmt /tmp/nftables/src/netlink_linearize.c:1682 [...] Fixes: e76bb3794018 ('src: allow for variables in the log prefix string') Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* datatype: avoid cast-align warning with struct sockaddr result from ↵Thomas Haller2023-08-291-3/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | getaddrinfo() With CC=clang we get datatype.c:625:11: error: cast from 'struct sockaddr *' to 'struct sockaddr_in *' increases required alignment from 2 to 4 [-Werror,-Wcast-align] addr = ((struct sockaddr_in *)ai->ai_addr)->sin_addr; ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ datatype.c:690:11: error: cast from 'struct sockaddr *' to 'struct sockaddr_in6 *' increases required alignment from 2 to 4 [-Werror,-Wcast-align] addr = ((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr; ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ datatype.c:826:11: error: cast from 'struct sockaddr *' to 'struct sockaddr_in *' increases required alignment from 2 to 4 [-Werror,-Wcast-align] port = ((struct sockaddr_in *)ai->ai_addr)->sin_port; ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Fix that by casting to (void*) first. Also, add an assertion that the type is as expected. For inet_service_type_parse(), differentiate between AF_INET and AF_INET6. It might not have been a problem in practice, because the struct offsets of sin_port/sin6_port are identical. Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* netlink: avoid "-Wenum-conversion" warning in parser_bison.yThomas Haller2023-08-291-2/+2
| | | | | | | | | | | | | | Clang warns: parser_bison.y:3658:83: error: implicit conversion from enumeration type 'enum nft_nat_types' to different enumeration type 'enum nft_nat_etypes' [-Werror,-Wenum-conversion] { (yyval.stmt) = nat_stmt_alloc(&(yyloc), NFT_NAT_SNAT); } ~~~~~~~~~~~~~~ ^~~~~~~~~~~~ parser_bison.y:3659:83: error: implicit conversion from enumeration type 'enum nft_nat_types' to different enumeration type 'enum nft_nat_etypes' [-Werror,-Wenum-conversion] { (yyval.stmt) = nat_stmt_alloc(&(yyloc), NFT_NAT_DNAT); } ~~~~~~~~~~~~~~ ^~~~~~~~~~~~ Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* netlink: avoid "-Wenum-conversion" warning in dtype_map_from_kernel()Thomas Haller2023-08-291-1/+1
| | | | | | | | | | | Clang warns: netlink.c:806:26: error: implicit conversion from enumeration type 'enum nft_data_types' to different enumeration type 'enum datatypes' [-Werror,-Wenum-conversion] return datatype_lookup(type); ~~~~~~~~~~~~~~~ ^~~~ Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests/shell: expand vmap test case to also cause batch abortFlorian Westphal2023-08-292-6/+22
| | | | | | | | | | Let the last few batches also push an update that contains elements twice. This is expected to cause the batch to be aborted, which increases code coverage on kernel side. Signed-off-by: Florian Westphal <fw@strlen.de>
* parser: permit gc-interval in map declarationsFlorian Westphal2023-08-291-0/+5
| | | | | | | Maps support timeouts, so allow to set the gc interval as well. Fixes: 949cc39eb93f ("parser: support of maps with timeout") Signed-off-by: Florian Westphal <fw@strlen.de>
* tests: monitor: Fix for wrong ordering in expected JSON outputPhil Sutter2023-08-291-1/+1
| | | | | | | | Adjust JSON for delete before add for replace after respective kernel fix, too. Fixes: ba786ac758fba ("tests: monitor: update insert and replace commands") Signed-off-by: Phil Sutter <phil@nwl.cc>
* tests: monitor: Fix for wrong syntax in set-interval.tPhil Sutter2023-08-291-1/+1
| | | | | | | Expected JSON output must be prefixed 'J'. Fixes: 7ab453a033c9a ("monitor: do not call interval_map_decompose() for concat intervals") Signed-off-by: Phil Sutter <phil@nwl.cc>
* tests: monitor: Fix time format in ct timeout testPhil Sutter2023-08-291-1/+1
| | | | | | | | | The old "plain" numbers are still accepted (and assumed to be in seconds), but output will use units which is unexpected due to 'O -'. Adjust input instead of adding this subtly different output line. Fixes: 5c25c5a35cbd2 ("parser: allow ct timeouts to use time_spec values") Signed-off-by: Phil Sutter <phil@nwl.cc>
* tests: monitor: Fix monitor JSON output for insert commandPhil Sutter2023-08-291-1/+1
| | | | | | | | Looks like commit ba786ac758fba ("tests: monitor: update insert and replace commands") missed to also fix expected JSON output. Fixes: 48d20b8cf162e ("monitor: honor NLM_F_APPEND flag for rules") Signed-off-by: Phil Sutter <phil@nwl.cc>
* evaluate: Drop dead code from expr_evaluate_mapping()Phil Sutter2023-08-291-11/+8
| | | | | | | | | | | | | Since commit 343a51702656a ("src: store expr, not dtype to track data in sets"), set->data is allocated for object maps in set_evaluate(), all other map types have set->data initialized by the parser already, set_evaluate() also checks that. Drop the confusing check, later in the function set->data is dereferenced unconditionally. Fixes: 343a51702656a ("src: store expr, not dtype to track data in sets") Signed-off-by: Phil Sutter <phil@nwl.cc>
* configure: drop AM_PROG_CC_C_O autoconf checkThomas Haller2023-08-251-1/+0
| | | | | | | | | | | | This macro is obsolete since automake 1.14 (2013). It might have been unnecessary even before, in practice only gcc/clang are supported compilers. [1] https://www.gnu.org/software/automake/manual/html_node/Public-Macros.html#index-AM_005fPROG_005fCC_005fC_005fO [2] https://lists.gnu.org/archive/html/info-gnu/2013-06/msg00009.html Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* include: include <std{bool,int}.h> via <nft.h>Thomas Haller2023-08-2524-24/+3
| | | | | | | | | | | | | | | | | | | | There is a minimum base that all our sources will end up needing. This is what <nft.h> provides. Add <stdbool.h> and <stdint.h> there. It's unlikely that we want to implement anything, without having "bool" and "uint32_t" types available. Yes, this means the internal headers are not self-contained, with respect to what <nft.h> provides. This is the exception to the rule, and our internal headers should rely to have <nft.h> included for them. They should not include <nft.h> themselves, because <nft.h> needs always be included as first. So when an internal header would include <nft.h> it would be unnecessary, because the header is *always* included already. Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* configure: use AC_USE_SYSTEM_EXTENSIONS to get _GNU_SOURCEThomas Haller2023-08-252-2/+3
| | | | | | | | | | | | | | | | | Let "configure" detect which features are available. Also, nftables is a Linux project, so portability beyond gcc/clang and glibc/musl is less relevant. And even if it were, then feature detection by "configure" would still be preferable. Use AC_USE_SYSTEM_EXTENSIONS ([1]). Available since autoconf 2.60, from 2006 ([2]). [1] https://www.gnu.org/software/autoconf/manual/autoconf-2.67/html_node/Posix-Variants.html#index-AC_005fUSE_005fSYSTEM_005fEXTENSIONS-1046 [2] https://lists.gnu.org/archive/html/autoconf/2006-06/msg00111.html Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* include: don't define _GNU_SOURCE in public headerThomas Haller2023-08-251-1/+0
| | | | | | | | | | | | | | _GNU_SOURCE is supposed to be defined as first thing, before including any libc headers. Defining it in the public header of nftables is wrong, because it would only (somewhat) work if the user includes the nftables header as first thing too. But that is not what users commonly would do, in particular with autotools projects, where users would include <config.h> first. It's also unnecessary. Nothing in "nftables/libnftables.h" itself requires _GNU_SOURCE. Drop it. Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add <nft.h> header and include it as firstThomas Haller2023-08-2554-13/+108
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | <config.h> is generated by the configure script. As it contains our feature detection, it want to use it everywhere. Likewise, in some of our sources, we define _GNU_SOURCE. This defines the C variant we want to use. Such a define need to come before anything else, and it would be confusing if different source files adhere to a different C variant. It would be good to use autoconf's AC_USE_SYSTEM_EXTENSIONS, in which case we would also need to ensure that <config.h> is always included as first. Instead of going through all source files and include <config.h> as first, add a new header "include/nft.h", which is supposed to be included in all our sources (and as first). This will also allow us later to prepare some common base, like include <stdbool.h> everywhere. We aim that headers are self-contained, so that they can be included in any order. Which, by the way, already didn't work because some headers define _GNU_SOURCE, which would only work if the header gets included as first. <nft.h> is however an exception to the rule: everything we compile shall rely on having <nft.h> header included as first. This applies to source files (which explicitly include <nft.h>) and to internal header files (which are only compiled indirectly, by being included from a source file). Note that <config.h> has no include guards, which is at least ugly to include multiple times. It doesn't cause problems in practice, because it only contains defines and the compiler doesn't warn about redefining a macro with the same value. Still, <nft.h> also ensures to include <config.h> exactly once. Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* meta: define _GNU_SOURCE to get strptime() from <time.h>Thomas Haller2023-08-251-4/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | To use `strptime()`, the documentation indicates #define _XOPEN_SOURCE #include <time.h> However, previously this was done wrongly. For example, when building with musl we got a warning: CC meta.lo meta.c:40: warning: "_XOPEN_SOURCE" redefined 40 | #define _XOPEN_SOURCE | In file included from /usr/include/errno.h:8, from meta.c:13: /usr/include/features.h:16: note: this is the location of the previous definition 16 | #define _XOPEN_SOURCE 700 | Defining "__USE_XOPEN" is wrong. This is a glibc internal define not for the user. Note that if we just set _XOPEN_SOURCE (or _XOPEN_SOURCE=700), we won't get other things like "struct tm.tm_gmtoff". Instead, we already define _GNU_SOURCE at other places. Do that here too, it will give us strptime() and all is good. Also, those directives should be defined as first thing (or via "-D" command line). See [1]. This is also important, because to use "time_t" in a header, we would need to include <time.h>. That only works, if we get the feature test macros right. That is, define the _?_SOURCE macro as first thing. [1] https://www.gnu.org/software/libc/manual/html_node/Feature-Test-Macros.html Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: 30s-stress: add failslab and abort phase testsFlorian Westphal2023-08-241-15/+375
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Pablo suggested to also cover abort phase by intentionally deleting non-existent or adding clashing keys. While at it: add rules with anon sets and jumps to anonymous chains and a few constant sets. Pick different key sizes so there is a higher chance kernel picks different backend storages such as bitmap or hash_fast. add failslab support, this also covers unlikely or "impossible" cases like failing GFP_KERNEL allocations. randomly spawn 'nft monitor' in the background for a random duration to cover notification path. Try to randomly delete a set or chain from control plane. Randomly set a table as dormant (and back to normal). Allow to pass the test runtime as argument, so one can now do ./30s-stress 3600 to have the test run for one hour. For such long test durations, make sure the ruleset gets regenerated periodically. Signed-off-by: Florian Westphal <fw@strlen.de>
* py: add Nftables.{get,set}_input_flags() APIThomas Haller2023-08-241-0/+43
| | | | | | | | | | | | | | | Similar to the existing Nftables.{get,set}_debug() API. Only notable (internal) difference is that nft_ctx_input_set_flags() returns the old value already, so we don't need to call Nftables.get_input_flags() first. The benefit of this API, is that it follows the existing API for debug flags. Also, when future flags are added it requires few changes to the python code. Signed-off-by: Thomas Haller <thaller@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* py: extract flags helper functions for set_debug()/get_debug()Thomas Haller2023-08-241-21/+31
| | | | | | | | | | | | | | | | | | | | | | | | | Will be re-used for nft_ctx_input_set_flags() and nft_ctx_input_get_flags(). There are changes in behavior here. - when passing an unrecognized string (e.g. `ctx.set_debug('foo')` or `ctx.set_debug(['foo'])`), a ValueError is now raised instead of a KeyError. - when passing an out-of-range integer, now a ValueError is no raised. Previously the integer was truncated to 32bit. Changing the exception is an API change, but most likely nobody will care or try to catch a KeyError to find out whether a flag is supported. Especially, since such a check would be better performed via `'foo' in ctx.debug_flags`. In other cases, a TypeError is raised as before. Signed-off-by: Thomas Haller <thaller@redhat.com> Reviewed-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>