| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
| |
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>
|
|
|
|
|
|
|
|
|
| |
In order to prepare for rules containing set references, nft handle has
to be passed to nft_rule_to_iptables_command_state() in order to let it
access the set in cache.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
| |
Seems like a trivial copy'n'paste bug.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Type used for 'mask' and 'xor' parameters was wrong, 'int' is four bytes
on 32 or 64 bit architectures. After casting a uint16_t to int, on Big
Endian the first two bytes of data are (the leading) zero which libnftnl
then copies instead of the actual value.
This problem was noticed when using '--fragment' option:
| # iptables-nft -A FORWARD --fragment -j ACCEPT
| # nft list ruleset | grep frag-off
| ip frag-off & 0 != 0 counter packets 0 bytes 0 accept
With this fix in place, the resulting nft rule is correct:
| ip frag-off & 8191 != 0 counter packets 0 bytes 0 accept
Fixes: 2f1fbab671576 ("iptables: nft: add -f support")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
|
|
|
|
|
|
| |
If this rule attribute is present but does not contain a comment,
get_comment() returns NULL which is then fed into strncpy() causing a
crash.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Florian Westphal <fw@strlen.de>
|