summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* build: Bump version to 1.0.4v1.0.4Pablo Neira Ayuso2022-06-071-3/+3
| | | | | | Bump libnftnl dependency to fix --debug with new TCP reset support. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: shell: remove leftover modules on cleanupPablo Neira Ayuso2022-06-021-0/+1
| | | | | | After ./run-tests.sh no nf_tables modules are left in place. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: reset ctx->set after set interval evaluationPablo Neira Ayuso2022-06-013-4/+34
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Otherwise bogus error reports on set datatype mismatch might occur, such as: Error: datatype mismatch, expected Internet protocol, expression has type IPv4 address meta l4proto { tcp, udp } th dport 443 dnat to 10.0.0.1 ~~~~~~~~~~~~ ^^^^^^^^^^^^ with an unrelated set declaration. table ip test { set set_with_interval { type ipv4_addr flags interval } chain prerouting { type nat hook prerouting priority dstnat; policy accept; meta l4proto { tcp, udp } th dport 443 dnat to 10.0.0.1 } } This bug has been introduced in the evaluation step. Reported-by: Roman Petrov <nwhisper@gmail.com> Fixes: 81e36530fcac ("src: replace interval segment tree overlap and automerge)" Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: shell: sets_with_ifnames release netns on exitPablo Neira Ayuso2022-06-011-0/+1
| | | | | | | Missing ip netns del call from cleanup() Fixes: d6fdb0d8d482 ("sets_with_ifnames: add test case for concatenated range") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: segfault when releasing unsupported statementPablo Neira Ayuso2022-06-013-1/+13
| | | | | | | | | Call xfree() instead since stmt_alloc() does not initialize the statement type fields. Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1609 Fixes: ea1f1c9ff608 ("optimize: memleak in statement matrix") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* build: Bump version to 1.0.3v1.0.3Pablo Neira Ayuso2022-05-311-2/+2
| | | | | | Still requires libnftnl 1.2.1 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* nft: simplify chain lookup in do_list_chainChander Govindarajan2022-05-311-6/+2
| | | | | | | | use the chain_cache_find function for faster lookup of chain instead of iterating over all chains in table Signed-off-by: ChanderG <mail@chandergovind.org> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* intervals: fix compilation --with-mini-gmpPablo Neira Ayuso2022-05-301-6/+6
| | | | | | | | | | | | Use pr_gmp_debug() instead to compile with minigmp. intervals.c: In function ‘set_delete’: intervals.c:489:25: warning: implicit declaration of function ‘gmp_printf’; did you mean ‘gmp_vfprintf’? [-Wimplicit-function-declaration] 489 | gmp_printf("remove: [%Zx-%Zx]\n", | ^~~~~~~~~~ | gmp_vfprintf Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* json: update json output ordering to place rules after chainsChander Govindarajan2022-05-241-2/+5
| | | | | | | | | | | | | | | | | | Currently the json output of `nft -j list ruleset` interleaves rules with chains. As reported in this bug: https://bugzilla.netfilter.org/show_bug.cgi?id=1580 the json cannot be fed into `nft -j -f <file>` since rules may reference chains that are created later Instead create rules after all chains are output. Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1580 Signed-off-by: ChanderG <mail@chandergovind.org> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* netlink_delinearize: release last register on exitPablo Neira Ayuso2022-05-161-1/+1
| | | | | | | | | | | | | | netlink_release_registers() does not release the expression in the last 32-bit register. struct netlink_parse_ctx { ... struct expr *registers[MAX_REGS + 1]; This array is MAX_REGS + 1 (verdict register + 16 32-bit registers). Fixes: 371c3a0bc3c2 ("netlink_delinearize: release expressions in context registers") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* sets_with_ifnames: add test case for concatenated rangeFlorian Westphal2022-05-092-24/+94
| | | | | | | Refactor existing test case for simple interace name ranges (without concatenations) to also cover "addr . ifname". Signed-off-by: Florian Westphal <fw@strlen.de>
* segtree: add pretty-print support for wildcard strings in concatenated setsFlorian Westphal2022-05-091-2/+36
| | | | | | | | | | For concat ranges, something like 'ppp*' is translated as a range from 'ppp\0\0\0...' to 'ppp\ff\ff\ff...'. In order to display this properly, check for presence of string base type and convert to symbolic expression, with appended '*' character. Signed-off-by: Florian Westphal <fw@strlen.de>
* netlink: swap byteorder for host-endian concat dataFlorian Westphal2022-05-091-0/+4
| | | | | | | | | | | All data must be passed in network byte order, else matching won't work respectively kernel will reject the interval because it thinks that start is after end This is needed to allow use of 'ppp*' in interval sets with concatenations. Signed-off-by: Florian Westphal <fw@strlen.de>
* intervals: deletion should adjust range not yet in the kernelPablo Neira Ayuso2022-05-071-3/+0
| | | | | | | | | | | | | | | Do not remove the range if it does not exists yet in the kernel, adjust it instead. Uncovered by use-after-free error. ==276702==ERROR: AddressSanitizer: heap-use-after-free on address 0x60d00190663c at pc 0x7ff310ab526f bp 0x7fffeb76f750 sp 0x7fffeb76f748 READ of size 4 at 0x60d00190663c thread T0 #0 0x7ff310ab526e in __adjust_elem_right .../nftables/src/intervals.c:300 #1 0x7ff310ab59a7 in adjust_elem_right .../nftables/src/intervals.c:311 #2 0x7ff310ab6daf in setelem_adjust .../nftables/src/intervals.c:354 #3 0x7ff310ab783a in setelem_delete .../nftables/src/intervals.c:411 #4 0x7ff310ab80e6 in __set_delete .../nftables/src/intervals.c:451 Fixes: 3e8d934e4f72 ("intervals: support to partial deletion with automerge") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: memleak in statement matrixPablo Neira Ayuso2022-05-041-0/+1
| | | | | | | Release clone object in case this statement is not supported. Fixes: 743b0e81371f ("optimize: do not clone unsupported statement") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: merge nat rules with same selectors into mapPablo Neira Ayuso2022-05-033-10/+253
| | | | | | | | | | | | | | | | | | | | | | | Verdict and nat are mutually exclusive, no need to support for this combination. # cat ruleset.nft table ip x { chain y { type nat hook postrouting priority srcnat; policy drop; ip saddr 1.1.1.1 tcp dport 8000 snat to 4.4.4.4:80 ip saddr 2.2.2.2 tcp dport 8001 snat to 5.5.5.5:90 } } # nft -o -c -f ruleset.nft Merging: ruleset.nft:4:3-52: ip saddr 1.1.1.1 tcp dport 8000 snat to 4.4.4.4:80 ruleset.nft:5:3-52: ip saddr 2.2.2.2 tcp dport 8001 snat to 5.5.5.5:90 into: snat to ip saddr . tcp dport map { 1.1.1.1 . 8000 : 4.4.4.4 . 80, 2.2.2.2 . 8001 : 5.5.5.5 . 90 } Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: do not clone unsupported statementPablo Neira Ayuso2022-05-031-1/+1
| | | | | | | | Skip unsupported statements when building the statement matrix, otherwise clone remains uninitialized. Fixes: fb298877ece2 ("src: add ruleset optimization infrastructure") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* optimize: incorrect logic in verdict comparisonPablo Neira Ayuso2022-05-032-5/+7
| | | | | | | | Keep inspecting rule verdicts before assuming they are equal. Update existing test to catch this bug. Fixes: 1542082e259b ("optimize: merge same selector with different verdict into verdict map") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: fix always-true assertionsFlorian Westphal2022-04-262-3/+4
| | | | | | | assert(1) is a no-op, this should be assert(0). Use BUG() instead. Add missing CATCHALL to avoid BUG(). Signed-off-by: Florian Westphal <fw@strlen.de>
* intervals: set on EXPR_F_KERNEL flag for new elements in set cachePablo Neira Ayuso2022-04-181-0/+3
| | | | | | | | | So follow up command in this batch that update the set assumes this element is already in the kernel. Fixes: 3da9643fb9ff ("intervals: add support to automerge with kernel elements") Fixes: 3ed9fadaab95 ("intervals: build list of elements to be added from cache") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: add concat test case with integer base type subkeyFlorian Westphal2022-04-184-0/+30
| | | | Signed-off-by: Florian Westphal <fw@strlen.de>
* src: allow use of base integer types as set keys in concatenationsFlorian Westphal2022-04-181-7/+17
| | | | | | | | | | | | | | | | "typeof ip saddr . ipsec in reqid" won't work because reqid uses integer type, i.e. dtype->size is 0. With "typeof", the size can be derived from the expression length, via set->key. This computes the concat length based either on dtype->size or expression length. It also updates concat evaluation to permit a zero datatype size if the subkey expression has nonzero length (i.e., typeof was used). Signed-off-by: Florian Westphal <fw@strlen.de>
* intervals: build list of elements to be added from cachePablo Neira Ayuso2022-04-181-40/+30
| | | | | | | | | | | Loop over the set cache and add elements that have no EXPR_F_KERNEL, meaning that these are new elements in the set that have resulted from adjusting/split existing ranges. This fixes several partial deletions of the same interval in one command. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* intervals: fix deletion of multiple ranges with automergePablo Neira Ayuso2022-04-181-12/+22
| | | | | | | | | Iterate over the list of elements to be deleted, then splice one EXPR_F_REMOVE element at a time to update the list of existing sets incrementally. Fixes: 3e8d934e4f722 ("intervals: support to partial deletion with automerge") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* intervals: add elements with EXPR_F_KERNEL to purge list onlyPablo Neira Ayuso2022-04-181-3/+7
| | | | | | | | Do not add elements to purge list which are not in the kernel, otherwise, bogus ENOENT is reported. Fixes: 3e8d934e4f722 ("intervals: support to partial deletion with automerge") Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* netlink: remove unused argument from helper functionFlorian Westphal2022-04-181-3/+3
| | | | Signed-off-by: Florian Westphal <fw@strlen.de>
* intervals: Simplify element sanity checksPhil Sutter2022-04-141-16/+10
| | | | | | | | | | Since setelem_delete() assigns to 'prev' pointer only if it doesn't have EXPR_F_REMOVE flag set, there is no need to check that flag in called functions. Fixes: 3e8d934e4f722 ("intervals: support to partial deletion with automerge") Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* intervals: unset EXPR_F_KERNEL for adjusted elementsPablo Neira Ayuso2022-04-131-3/+3
| | | | | | | | | | | | | | | | This element is adjusted, reset the EXPR_F_KERNEL flag, this is a new element and the old is purged from the kernel. The existing list of elements in the kernel is spliced to the elements to be removed, then merge-sorted. The EXPR_F_REMOVE flag specifies that this element represents a deletion. The EXPR_F_REMOVE and EXPR_F_KERNEL allows to track objects: whether element is in the kernel (EXPR_F_KERNEL), element is new (no flag) or element represents a removal (EXPR_F_REMOVE). Reported-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: restore interval sets work with string datatypesPablo Neira Ayuso2022-04-132-6/+8
| | | | | | | | | | | Switch byteorder of string datatypes to host byteorder. Partial revert of ("src: make interval sets work with string datatypes") otherwise new interval code complains with conflicting intervals. testcases/sets/sets_with_ifnames passes fine again. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* intervals: support to partial deletion with automergePablo Neira Ayuso2022-04-135-3/+257
| | | | | | | | | | | | | | | | | | | | | | | | Splice the existing set element cache with the elements to be deleted and merge sort it. The elements to be deleted are identified by the EXPR_F_REMOVE flag. The set elements to be deleted is automerged in first place if the automerge flag is set on. There are four possible deletion scenarios: - Exact match, eg. delete [a-b] and there is a [a-b] range in the kernel set. - Adjust left side of range, eg. delete [a-b] from range [a-x] where x > b. - Adjust right side of range, eg. delete [a-b] from range [x-b] where x < a. - Split range, eg. delete [a-b] from range [x-y] where x < a and b < y. Update nft_evaluate() to use the safe list variant since new commands are dynamically registered to the list to update ranges. This patch also restores the set element existence check for Linux kernels <= 5.7. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: allow for zero length rangesPablo Neira Ayuso2022-04-131-1/+1
| | | | | | | | | Allow for ranges such as, eg. 30-30. This is required by the new intervals.c code, which normalize constant, prefix set elements to all ranges. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* intervals: add support to automerge with kernel elementsPablo Neira Ayuso2022-04-137-40/+168
| | | | | | | | | | | | | | | | | | Extend the interval codebase to support for merging elements in the kernel with userspace element updates. Add a list of elements to be purged to cmd and set objects. These elements representing outdated intervals are deleted before adding the updated ranges. This routine splices the list of userspace and kernel elements, then it mergesorts to identify overlapping and contiguous ranges. This splice operation is undone so the set userspace cache remains consistent. Incrementally update the elements in the cache, this allows to remove dd44081d91ce ("segtree: Fix add and delete of element in same batch"). Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* mnl: update mnl_nft_setelem_del() to allow for more reusePablo Neira Ayuso2022-04-133-5/+6
| | | | | | Pass handle and element list as parameters to allow for code reuse. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: remove rbtree datastructurePablo Neira Ayuso2022-04-134-488/+0
| | | | | | Not used by anyone anymore, remove it. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: replace interval segment tree overlap and automergePablo Neira Ayuso2022-04-1310-667/+477
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is a rewrite of the segtree interval codebase. This patch now splits the original set_to_interval() function in three routines: - add set_automerge() to merge overlapping and contiguous ranges. The elements, expressed either as single value, prefix and ranges are all first normalized to ranges. This elements expressed as ranges are mergesorted. Then, there is a linear list inspection to check for merge candidates. This code only merges elements in the same batch, ie. it does not merge elements in the kernela and the userspace batch. - add set_overlap() to check for overlapping set elements. Linux kernel >= 5.7 already checks for overlaps, older kernels still needs this code. This code checks for two conflict types: 1) between elements in this batch. 2) between elements in this batch and kernelspace. The elements in the kernel are temporarily merged into the list of elements in the batch to check for this overlaps. The EXPR_F_KERNEL flag allows us to restore the set cache after the overlap check has been performed. - set_to_interval() now only transforms set elements, expressed as range e.g. [a,b], to individual set elements using the EXPR_F_INTERVAL_END flag notation to represent e.g. [a,b+1), where b+1 has the EXPR_F_INTERVAL_END flag set on. More relevant updates: - The overlap and automerge routines are now performed in the evaluation phase. - The userspace set object representation now stores a reference to the existing kernel set object (in case there is already a set with this same name in the kernel). This is required by the new overlap and automerge approach. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: add EXPR_F_KERNEL to identify expression in the kernelPablo Neira Ayuso2022-04-133-1/+7
| | | | | | This allows to identify the set elements that reside in the kernel. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* segtree: add support for get element with sets that contain ifnamesFlorian Westphal2022-04-132-15/+65
| | | | | | | | | | | | | | | | nft get element inet filter s { bla, prefixfoo } table inet filter { set s { type ifname flags interval elements = { "prefixfoo*", "bla" } } Also add test cases for this. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* segtree: use correct byte order for 'element get'Florian Westphal2022-04-131-1/+2
| | | | | | | | Fails when the argument / set contains strings: we need to use host byte order if element has string base type. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: add testcases for interface names in setsFlorian Westphal2022-04-132-0/+111
| | | | | | | | | | | | | Add initial test case, sets with names and interfaces, anonymous and named ones. Check match+no-match. netns with ppp1 and ppq veth, send packets via both interfaces. Rule counters should have incremented on the three rules. (that match on set that have "abcdef1" or "abcdef*" strings in them). Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* segtree: add string "range" reversal supportFlorian Westphal2022-04-131-6/+41
| | | | | | | | | | | | | | | | | | | | Previous commits allows to use set key as a range, i.e. key ifname flags interval elements = { eth* } and then have it match on any interface starting with 'eth'. Listing is broken however, we need to reverse-translate the (128bit) number back to a string. 'eth*' is stored as interval 00687465 0000000 .. 00697465 0000000, i.e. "eth-eti", this adds the needed endianess fixups. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* src: make interval sets work with string datatypesFlorian Westphal2022-04-132-6/+32
| | | | | | | | | | | | | | | | | | | Allows to interface names in interval sets: table inet filter { set s { type ifname flags interval elements = { eth*, foo } } Concatenations are not yet supported, also, listing is broken, those strings will not be printed back because the values will remain in big-endian order. Followup patch will extend segtree to translate this back to host byte order. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: string prefix expression must retain original lengthFlorian Westphal2022-04-131-1/+3
| | | | | | | | | | | | | | | | To make something like "eth*" work for interval sets (match eth0, eth1, and so on...) we must treat the string as a 128 bit integer. Without this, segtree will do the wrong thing when applying the prefix, because we generate the prefix based on 'eth*' as input, with a length of 3. The correct import needs to be done on "eth\0\0\0\0\0\0\0...", i.e., if the input buffer were an ipv6 address, it should look like "eth\0::", not "::eth". Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* segtree: split prefix and range creation to a helper functionFlorian Westphal2022-04-131-43/+52
| | | | | | | No functional change intended. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: keep prefix expression lengthFlorian Westphal2022-04-132-0/+2
| | | | | | | | | | | | | Else, range_expr_value_high() will see a 0 length when doing: mpz_init_bitmask(tmp, expr->len - expr->prefix_len); This wasn't a problem so far because prefix expressions generated from "string*" were never passed down to the prefix->range conversion functions. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* evaluate: make byteorder conversion on string base type a no-opFlorian Westphal2022-04-131-2/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Prerequisite for support of interface names in interval sets: table inet filter { set s { type ifname flags interval elements = { "foo" } } chain input { type filter hook input priority filter; policy accept; iifname @s counter } } Will yield: "Byteorder mismatch: meta expected big endian, got host endian". This is because of: /* Data for range lookups needs to be in big endian order */ if (right->set->flags & NFT_SET_INTERVAL && byteorder_conversion(ctx, &rel->left, BYTEORDER_BIG_ENDIAN) < 0) It doesn't make sense to me to add checks to all callers of byteorder_conversion(), so treat this similar to EXPR_CONCAT and turn TYPE_STRING byteorder change into a no-op. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: py: Add meta time tests without 'meta' keywordMartin Gignac2022-04-103-0/+52
| | | | | | | | | v1.0.2 of 'nft' fails on 'time < "2022-07-01 11:00:00"' but succeeds when 'meta' is specified ('meta time < "2022-07-01 11:00:00"'). This extends coverage by testing 'time' without 'meta'. Signed-off-by: Martin Gignac <martin.gignac@gmail.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* tests: py: Don't colorize output if stderr is redirectedPhil Sutter2022-04-081-1/+1
| | | | | | | | Cover for calls with '2>/tmp/log' and avoid printing escape sequences to that file. One could still keep colored output on stdout, but that required a printing routine for non-errors. Signed-off-by: Phil Sutter <phil@nwl.cc>
* tests: monitor: Hide temporary file names from error outputPhil Sutter2022-04-081-2/+2
| | | | | | | | Make error output deterministic by passing input to nft via stdin. This way error messages will contain "/dev/stdin" instead of the temporary file name. Signed-off-by: Phil Sutter <phil@nwl.cc>
* tests: py: extend meta time coveragePablo Neira Ayuso2022-04-083-0/+52
| | | | | | Add meta time tests using < and > operands. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
* meta: fix compiler warning in date_type_parse()Lukas Straub2022-04-051-4/+6
| | | | | | | | | | | | | After commit 0210097879 ("meta: time: use uint64_t instead of time_t") there is a compiler warning due to comparison of the return value from parse_iso_date with -1, which is now implicitly cast to uint64_t. Fix this by making parse_iso_date take a pointer to the tstamp and return bool instead. Fixes: 0210097879 ("meta: time: use uint64_t instead of time_t") Signed-off-by: Lukas Straub <lukasstraub2@web.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>