netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Phil Sutter <phil@nwl.cc>
To: netfilter-devel@vger.kernel.org
Subject: [iptables PATCH] nft: Fix for broken recover_rule_compat()
Date: Tue, 27 Feb 2024 19:40:57 +0100	[thread overview]
Message-ID: <20240227184057.6017-1-phil@nwl.cc> (raw)

When IPv4 rule generator was changed to emit payload instead of
meta expressions for l4proto matches, the code reinserting
NFTNL_RULE_COMPAT_* attributes into rules being reused for counter
zeroing was broken by accident.

Make rule compat recovery aware of the alternative match, basically
reinstating the effect of commit 7a373f6683afb ("nft: Fix -Z for rules
with NFTA_RULE_COMPAT") but add a test case this time to make sure
things stay intact.

Fixes: 69278f9602b43 ("nft: use payload matching for layer 4 protocol")
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 iptables/nft.c                                | 27 ++++++++++++++++---
 .../nft-only/0011-zero-needs-compat_0         | 12 +++++++++
 2 files changed, 35 insertions(+), 4 deletions(-)
 create mode 100755 iptables/tests/shell/testcases/nft-only/0011-zero-needs-compat_0

diff --git a/iptables/nft.c b/iptables/nft.c
index dae6698d3234a..ee63c3dc42ed4 100644
--- a/iptables/nft.c
+++ b/iptables/nft.c
@@ -3750,6 +3750,27 @@ const char *nft_strerror(int err)
 	return strerror(err);
 }
 
+static int l4proto_expr_get_dreg(struct nftnl_expr *e, uint32_t *dregp)
+{
+	const char *name = nftnl_expr_get_str(e, NFTNL_EXPR_NAME);
+	uint32_t poff = offsetof(struct iphdr, protocol);
+	uint32_t pbase = NFT_PAYLOAD_NETWORK_HEADER;
+
+	if (!strcmp(name, "payload") &&
+	    nftnl_expr_get_u32(e, NFTNL_EXPR_PAYLOAD_BASE) == pbase &&
+	    nftnl_expr_get_u32(e, NFTNL_EXPR_PAYLOAD_OFFSET) == poff &&
+	    nftnl_expr_get_u32(e, NFTNL_EXPR_PAYLOAD_LEN) == sizeof(uint8_t)) {
+		*dregp = nftnl_expr_get_u32(e, NFTNL_EXPR_PAYLOAD_DREG);
+		return 0;
+	}
+	if (!strcmp(name, "meta") &&
+	    nftnl_expr_get_u32(e, NFTNL_EXPR_META_KEY) == NFT_META_L4PROTO) {
+		*dregp = nftnl_expr_get_u32(e, NFTNL_EXPR_META_DREG);
+		return 0;
+	}
+	return -1;
+}
+
 static int recover_rule_compat(struct nftnl_rule *r)
 {
 	struct nftnl_expr_iter *iter;
@@ -3766,12 +3787,10 @@ static int recover_rule_compat(struct nftnl_rule *r)
 	if (!e)
 		goto out;
 
-	if (strcmp("meta", nftnl_expr_get_str(e, NFTNL_EXPR_NAME)) ||
-	    nftnl_expr_get_u32(e, NFTNL_EXPR_META_KEY) != NFT_META_L4PROTO)
+	/* may be 'ip protocol' or 'meta l4proto' with identical RHS */
+	if (l4proto_expr_get_dreg(e, &reg) < 0)
 		goto next_expr;
 
-	reg = nftnl_expr_get_u32(e, NFTNL_EXPR_META_DREG);
-
 	e = nftnl_expr_iter_next(iter);
 	if (!e)
 		goto out;
diff --git a/iptables/tests/shell/testcases/nft-only/0011-zero-needs-compat_0 b/iptables/tests/shell/testcases/nft-only/0011-zero-needs-compat_0
new file mode 100755
index 0000000000000..e276a953234cf
--- /dev/null
+++ b/iptables/tests/shell/testcases/nft-only/0011-zero-needs-compat_0
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+[[ $XT_MULTI == *xtables-nft-multi ]] || { echo "skip $XT_MULTI"; exit 0; }
+
+set -e
+
+rule="-p tcp -m tcp --dport 27374 -c 23 42 -j TPROXY --on-port 50080"
+for cmd in iptables ip6tables; do
+	$XT_MULTI $cmd -t mangle -A PREROUTING $rule
+	$XT_MULTI $cmd -t mangle -Z
+	$XT_MULTI $cmd -t mangle -v -S | grep -q -- "${rule/23 42/0 0}"
+done
-- 
2.43.0


             reply	other threads:[~2024-02-27 19:02 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-27 18:40 Phil Sutter [this message]
2024-02-28 12:21 ` [iptables PATCH] nft: Fix for broken recover_rule_compat() Phil Sutter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240227184057.6017-1-phil@nwl.cc \
    --to=phil@nwl.cc \
    --cc=netfilter-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).