| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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_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>
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
"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>
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
| |
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
| |
Pass handle and element list as parameters to allow for code reuse.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
| |
Not used by anyone anymore, remove it.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
| |
This allows to identify the set elements that reside in the kernel.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
| |
No functional change intended.
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
time_t may be 32 bit on some platforms and thus can't fit a timestamp
with nanoseconds resolution. This causes overflows and ultimatively
breaks meta time expressions on such platforms.
Fix this by using uint64_t instead.
Closes: https://bugzilla.netfilter.org/show_bug.cgi?id=1567
Fixes: f8f32deda31df ("meta: Introduce new conditions 'time', 'day' and 'hour'")
Signed-off-by: Lukas Straub <lukasstraub2@web.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
|
| |
This patch reverts d0f14b5337e7 ("optimize: do not merge raw payload
expressions") after adding support for concatenation with variable
length TYPE_INTEGER.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Header fields such as udp length cannot be used in concatenations because
it is using the generic integer_type:
test.nft:3:10-19: Error: can not use variable sized data types (integer) in concat expressions
typeof udp length . @th,32,32
^^^^^^^^^^~~~~~~~~~~~~
This patch slightly extends ("src: allow to use typeof of raw expressions in
set declaration") to set on NFTNL_UDATA_SET_KEY_PAYLOAD_LEN in userdata if
TYPE_INTEGER is used.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Use the dynamic datatype to allocate an instance of TYPE_INTEGER and set
length and byteorder. Add missing information to the set userdata area
for raw payload expressions which allows to rebuild the set typeof from
the listing path.
A few examples:
- With anonymous sets:
nft add rule x y ip saddr . @ih,32,32 { 1.1.1.1 . 0x14, 2.2.2.2 . 0x1e }
- With named sets:
table x {
set y {
typeof ip saddr . @ih,32,32
elements = { 1.1.1.1 . 0x14 }
}
}
Incremental updates are also supported, eg.
nft add element x y { 3.3.3.3 . 0x28 }
expr_evaluate_concat() is used to evaluate both set key definitions
and set key values, using two different function might help to simplify
this code in the future.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Otherwise listing breaks showing [invalid type] notice.
# nft list ruleset
table inet x {
map y {
typeof ip saddr : verdict
elements = { 1.1.1.1 : 0x1010101 [invalid type] }
}
}
Update tests to cover this usecase.
Fixes: 4ab1e5e60779 ("src: allow use of 'verdict' in typeof definitions")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
|
|
|
| |
without this test fails with:
W: [FAILED] tests/shell/testcases/maps/anon_objmap_concat: got 134
BUG: invalid range expression type concat
nft: expression.c:1452: range_expr_value_low: Assertion `0' failed.
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Phil Sutter says:
"When trying to add a rule which contains an anonymous chain to a
non-existent chain, string_misspell_update() is called with a NULL
string because the anonymous chain has no name. Avoid this by making the
function NULL-pointer tolerant."
Fixes: c330152b7f777 ("src: support for implicit chain bindings")
Reported-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
| |
else, this will segfault when trying to print the
"table 'x' doesn't exist" error message.
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
| |
... log prefix might not be present in log statements.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
| |
Only value, range, prefix, set and list are supported at this stage.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
| |
assert(1) is noop, this should be assert(0) instead.
Fixes: 561aa3cfa8da ("optimize: merge verdict maps with same lookup key")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Check expressions that are expected on the rhs rather than using a
catch-all default case.
Actually, lists and sets need to be their own routine, because this
needs the set element key expression to be merged.
This is a follow up to 99eb46969f3d ("optimize: fix vmap with anonymous
sets").
Fixes: 1542082e259b ("optimize: merge same selector with different verdict into verdict map")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The following example ruleset crashes:
table inet a {
chain b {
tcp dport { 1 } accept
tcp dport 2-3 drop
}
}
because handling for EXPR_SET is missing.
Fixes: 1542082e259b ("optimize: merge same selector with different verdict into verdict map")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
|
| |
Due to lookahead, "addr" keyword is still found in IP/IP6 scope, not
STMT_NAT one.
Fixes: a67fce7ffe7e4 ("scanner: nat: Move to own scope")
Signed-off-by: Phil Sutter <phil@nwl.cc>
|