| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
| |
It is just a hack to translate '! -i +' into a never matching nft rule,
but recognize it anyway for completeness' sake and to make xlate replay
test pass.
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
It's actually nonsense since it will never match, but iptables accepts
it and the resulting nftables rule must behave identically. Reuse the
solution implemented into xtables-translate (by commit e179e87a1179e)
and turn the above match into 'iifname INVAL/D'.
The commit this fixes merely ignored the fact that "any interface" match
might be inverted.
Fixes: 0a8635183edd0 ("xtables-compat: ignore '+' interface name")
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
|
|
| |
Since nft adds the interface name as fixed-size string of 16 bytes,
filling a mask based on the length value will not match the mask nft
set.
Fixes: 652b98e793711 ("xtables-compat: fix wildcard detection")
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
|
|
|
| |
This is nft_clear_iptables_command_state() but in a location reachable
by legacy iptables, too.
Changes callers in non-family-specific code to use clear_cs callback
instead of directly calling it - ebtables still has a custom variant.
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
|
|
|
|
|
| |
We always return 0, even if we printed some error message half-way.
Increment an error counter whenever an error message was printed so that
the chain-loop can exit with an error if this counter is nonzero.
Another effect is that iptables-save will no longer print the COMMIT line anmore.
Reported-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Florian Westphal <fw@strlen.de>
Acked-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
| |
Replace nftnl_expr_get_data() alias by real function call.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
| |
The same algorithm was present four times, outsource it. Also use
max()/min() macros for a more readable boundary notation.
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
|
|
|
|
|
| |
The function nft_meta_set_to_target() would always bail since nothing
sets 'sreg->meta_sreg.set' to true. This is obvious, as the immediate
expression "filling" the source register does not indicate its purpose.
The whole source register purpose storing in meta_sreg seems to be
pointless, so drop it altogether.
Fixes: f315af1cf8871 ("nft: track each register individually")
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Fixed commit broke among match in two ways:
1) The two lookup sizes are 12 and 6, not 12 and 4 - among supports
either ether+IP or ether only, not IP only.
2) Adding two to sreg_count to get the second register is too simple: It
works only for four byte regs, not the 16 byte ones. The first
register is always a 16 byte one, though.
Fixing (1) is trivial, fix (2) by introduction of nft_get_next_reg()
doing the right thing. For consistency, use it for among match creation,
too.
Fixes: f315af1cf8871 ("nft: track each register individually")
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
| |
This is an inner function to get_cmp_data() returning the op value as-is
for caller examination.
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Instead of assuming only one register is used, track all 16 regs
individually.
This avoids need for the 'PREV_PAYLOAD' hack and also avoids the need to
clear out old flags:
When we see that register 'x' will be written to, that register state is
reset automatically.
Existing dissector decodes
ip saddr 1.2.3.4 meta l4proto tcp
... as
-s 6.0.0.0 -p tcp
iptables-nft -s 1.2.3.4 -p tcp is decoded correctly because the expressions
are ordered like:
meta l4proto tcp ip saddr 1.2.3.4
|
... and 'meta l4proto' did clear the PAYLOAD flag.
The simpler fix is:
ctx->flags &= ~NFT_XT_CTX_PAYLOAD;
in nft_parse_cmp(), but that breaks dissection of '1-42', because
the second compare ('cmp lte 42') will not find the
payload expression anymore.
Link: https://lore.kernel.org/netfilter-devel/20220922143544.GA22541@breakpoint.cc/T/#t
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
| |
xlate raw "nft ... ttl eq 1" and so on to the ttl/hl matches.
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
| |
Makes iptables-nft-save dump 'nft meta pkttype' rules.
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
|
|
|
| |
In some code-paths, 'reg' pointer remaining uninitialized is used later
so at least minimal error checking is necessary. Given that a call to
nftnl_alloc_expr() with sane argument should never fail, complain and
exit if it happens.
Fixes: 7e38890c6b4fb ("nft: prepare for dynamic register allocation")
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
|
|
| |
Store the register that has been allocated and pass it on to the next
expression. NFT_REG_1 is still used.
No functional changes are expected.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
| |
Pass struct nft_handle to helper functions in preparation for the
dynamic register allocation.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
| |
Use meta mark + bitwise + cmp instead of nft_compat mark match.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
| |
In preparation for native mark match support.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
|
| |
Update the destination register, otherwise nft_parse_cmp() gives up on
interpreting the cmp expression when bitwise sreg != dreg.
Fixes: 2c4a34c30cb4 ("iptables-compat: fix address prefix")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
|
|
|
|
| |
There are no family-specific versions of struct iptables_command_state
anymore, so no need to hide it behind void pointer. Pass the type as-is
and save a few casts.
While at it, drop unused callbacks parse_bitwise and parse_cmp.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Acked-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Parsing of rules which jump to a chain pointlessly causes a call to
xtables_find_target() despite the code already knowing the outcome.
Avoid the significant delay for rulesets with many chain jumps by
performing the (standard) target lookup only for accept/drop/return
verdicts.
From a biased test-case on my VM:
| # iptables-nft-save | grep -c -- '-j'
| 133943
| # time ./old/iptables-nft-save >/dev/null
| real 0m45.566s
| user 0m1.308s
| sys 0m8.430s
| # time ./new/iptables-nft-save >/dev/null
| real 0m3.547s
| user 0m0.762s
| sys 0m2.476s
Signed-off-by: Phil Sutter <phil@nwl.cc>
Acked-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
| |
Implementations of parse_immediate callback are mostly trivial, the only
relevant part is access to family-specific parts of struct
iptables_command_state when setting goto flag for iptables and
ip6tables. Refactor them into simple set_goto_flag callbacks.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Acked-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
| |
Detect payload load of th->flags and convert it to xt tcp match
structure.
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
| |
same as previous patch, but for udp.
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
| |
adds support for
nft ... tcp dport != min-max
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This extends iptables-nft dissector to decode native tcp
port matching. nft ruleset:
table ip filter {
chain INPUT {
type filter hook input priority filter; policy accept;
tcp sport 12345
tcp sport 12345 tcp dport 6789
tcp sport < 1024
tcp dport >= 1024
}
}
$ iptables-nft-save
-A INPUT -p tcp -m tcp --sport 12345
-A INPUT -p tcp -m tcp --sport 12345 --dport 6789
-A INPUT -p tcp -m tcp --sport 0:1023
-A INPUT -p tcp -m tcp --dport 1024:65535
This would allow to extend iptables-nft to prefer
native payload expressions for --sport,dport in the future.
Also, parse_cmp must not clear the "payload" flag, this is because
cmp-based range expressions will contain following sequence:
payload => reg1
cmp reg1 > minv
cmp reg1 < maxv
... so second cmp would work.
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When parsing the rule, use a struct with a layout compatible to that of
struct xt_nflog_info, but with a buffer large enough to contain the
whole 128-character nft prefix.
We always send the nflog-group to the kernel since, for nft, log and
nflog targets are handled by the same kernel module, and are
distinguished by whether they define an nflog-group. Therefore, we must
send the group even if it is zero, or the kernel will configure the
target as a log, not an nflog.
Changes to nft_is_expr_compatible were made since only targets which
have an `nflog-group` are compatible. Since nflog targets are
distinguished by having an nflog-group, we ignore targets without one.
We also set the copy-len flag if the snap-len is set since without this,
iptables will mistake `nflog-size` for `nflog-range`.
Signed-off-by: Kyle Bowman <kbowman@cloudflare.com>
Signed-off-by: Alex Forster <aforster@cloudflare.com>
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
|
|
| |
NFTNL_EXPR_META_DREG equals NFTNL_EXPR_PAYLOAD_BASE, so we set
dreg to the payload base instead.
It "works" because the simple nft rules currently generated via
ipables-nft have base == register-number but this is a
coincidence.
Signed-off-by: Florian Westphal <fw@strlen.de>
|
|
|
|
|
|
|
|
|
| |
The last users vanished back in 2013. There is identical code in
save_rule_details(), but with only a single user there's not much point
in keeping the function.
Fixes: cdc78b1d6bd7b ("nft: convert rule into a command state structure")
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Legacy iptables fetches the relevant data via libiptc before calling the
shared routine which merely prints data as requested.
Drop the 'basechain' parameter, instead make sure a policy name is
passed only with base chains. Since the function is not shared with
ebtables (which uses a very rudimental header instead), this is safe.
In order to support legacy iptables' checking of iptc_get_references()
return code (printing an error message instead of the reference count),
make refs parameter signed and print the error message if it's negative.
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
|
|
|
| |
Have to pass pointer to counters directly since different fields are
being used for some reason.
Since proto_to_name() is not used outside of xshared.c anymore, make it
static.
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
|
|
|
| |
The function combines printing of input and output interfaces and
protocol parameter, all being IP family independent. Extend the function
to print fragment option ('-f'), too if requested. While being at it,
drop unused iptables_command_state parameter and reorder the remaining
ones a bit.
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
|
|
|
|
| |
Merge the three identical copies into one and name it 'save_iface' (as
the printed syntax is for "save"-format). Leave arptables alone for now,
its rather complicated whitespace printing doesn't allow for use of the
shared function. Also keep ebtables' custom implementation, it is used
for the --logical-in/--logical-out long-options, too. Apart from that,
ebtables-nft does not use a mask, at all.
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
| |
This aligns whitespace printing with legacy iptables' print_rule4() in
order to prepare for further code-sharing.
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
| |
Of course there is no such thing as *_tables_names for ebtables, so no
legacy tables checking for ebtables-nft.
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
|
|
|
| |
Share the common proto name lookup code. While being at it, make proto
number variable 16bit, values may exceed 256.
This aligns iptables-nft '-p' argument printing with legacy iptables. In
practice, this should make a difference only in corner cases.
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
|
|
| |
Byte-boundary prefix detection was too sloppy: Any data following the
first zero-byte was ignored. Add a follow-up loop making sure there are
no stray bits in the designated host part.
Fixes: 323259001d617 ("nft: Optimize class-based IP prefix matches")
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
|
|
|
| |
Just like with class-based prefix matches in iptables-nft, optimize
masked MAC address matches if the mask is on a byte-boundary.
To reuse the logic in add_addr(), extend it to accept the payload base
value via parameter.
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
| |
Payload expression works on byte-boundaries, leverage this with suitable
prefix lengths.
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Trying to decide whether a bitwise expression is needed to match parts
of a source or destination address only, add_addr() checks if all bytes
in 'mask' are 0xff or not. The check is apparently broken though as each
byte in 'mask' is cast to a signed char before comparing against 0xff,
therefore the bitwise is always added:
| # ./bad/iptables-nft -A foo -s 10.0.0.1 -j ACCEPT
| # ./good/iptables-nft -A foo -s 10.0.0.2 -j ACCEPT
| # nft --debug=netlink list chain ip filter foo
| ip filter foo 5
| [ payload load 4b @ network header + 12 => reg 1 ]
| [ bitwise reg 1 = (reg=1 & 0xffffffff ) ^ 0x00000000 ]
| [ cmp eq reg 1 0x0100000a ]
| [ counter pkts 0 bytes 0 ]
| [ immediate reg 0 accept ]
|
| ip filter foo 6 5
| [ payload load 4b @ network header + 12 => reg 1 ]
| [ cmp eq reg 1 0x0200000a ]
| [ counter pkts 0 bytes 0 ]
| [ immediate reg 0 accept ]
|
| table ip filter {
| chain foo {
| ip saddr 10.0.0.1 counter packets 0 bytes 0 accept
| ip saddr 10.0.0.2 counter packets 0 bytes 0 accept
| }
| }
Fix the cast, safe an extra op and gain 100% performance in ideal cases.
Fixes: 56859380eb328 ("xtables-compat: avoid unneeded bitwise ops")
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
| |
All families use the same callback function, just fold it into the sole
place it's called.
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
|
|
| |
Both ebtables and arptables are fine with using nft_ipv46_rule_find()
instead of their own implementations. Take the chance and move the
former into nft.c as a static helper since it is used in a single place,
only. Then get rid of the callback from family_ops.
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This patch updates the parser to generate a list of command objects.
This list of commands is then transformed to a list of netlink jobs.
This new command object stores the rule using the nftnl representation
via nft_rule_new().
To reduce the number of updates in this patch, the nft_*_rule_find()
functions have been updated to restore the native representation to
skip the update of the rule comparison code.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
|
|
|
|
|
|
| |
The command_jump() function leaves cs->target unset if the target is not
found. Let's check if the jumpto string mismatches only in this case.
https://bugzilla.netfilter.org/show_bug.cgi?id=1422
Tested-by: Etienne Champetier <etienne.champetier@anevia.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
|
|
| |
Fixed commit missed to update this conditional call to
nft_rule_print_save().
Fixes: 1e8ef6a584754 ("nft: family_ops: Pass nft_handle to 'rule_to_cs' callback")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
|
| |
Add required glue code to support family specific lookup expression
parsers implemented as family_ops callback.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
|
| |
Down to the point where expression parsing happens, the rule's table is
not known anymore but relevant if set lookups are required.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
|
|
| |
Allow for closer inspection by storing payload expression's base and
length values. Also facilitate for two consecutive payload expressions
as LHS of a (cmp/lookup) statement as used with concatenations.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
|
|
| |
Instead of carrying the family value, carry the handle (which contains
the family value) and relieve expression parsers from having to call
nft_family_ops_lookup().
Signed-off-by: Phil Sutter <phil@nwl.cc>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
|
|
|
|
| |
This is the actual callback used to parse nftables rules. Pass
nft_handle to it so it can access the cache (and possible sets therein).
Having to pass nft_handle to nft_rule_print_save() allows to simplify it
a bit since no family ops lookup has to be done anymore.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
|