From: Victor Nogueira <victor@mojatatu.com>
To: davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, jhs@mojatatu.com, jiri@resnulli.us
Cc: horms@kernel.org, vega@nebusec.ai, netdev@vger.kernel.org
Subject: [PATCH net v2 3/4] net/sched: cls_route: Fix in-place replace
Date: Mon, 7 Sep 2026 16:21:32 -0300 [thread overview]
Message-ID: <20260907192133.2639067-4-victor@mojatatu.com> (raw)
In-Reply-To: <20260907192133.2639067-1-victor@mojatatu.com>
Building on the previous patch, route4_set_parms rejects a duplicate by
scanning the destination chain for nhandle, but the scan doesn't exclude
the older version it is replacing, so an in-place replace will match
the older version's handle and fail.
Fix this by passing the older filter as a parameter to route4_set_parms
(replacing "new") and skipping it in the scan.
Excluding the older version is not enough on its own. nhandle is built
out of TCA_ROUTE4_TO, TCA_ROUTE4_FROM and TCA_ROUTE4_IIF alone, while the
0x7F00 bits, which only tell apart filters sharing one key, are folded in
on the create path. Letting the replace through would therefore rename
the filter it replaces: replacing handle 0x10101 stored it back as
0x10001, and a sibling at 0x10201 could then no longer be replaced at
all, since its own nhandle collided with the renamed filter.
tc filter add ... handle 0x10101 route from 1 to 1 classid 1:1
tc filter add ... handle 0x10201 route from 1 to 1 classid 1:2
tc filter replace ... handle 0x10101 route from 1 to 1 classid 1:9
... fh 0x00010001 flowid 1:9 to 1 from 1
... fh 0x00010201 flowid 1:2 to 1 from 1
tc filter replace ... handle 0x10201 route from 1 to 1 classid 1:8
Error: Handle 10001 is already in use.
So carry those bits over when the key the request builds is the key the
older filter already has. An in-place replace then keeps the handle
userspace named the filter by, while a request that does change the key
still renames it, as it did before.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260829205422.854785-1-victor%40mojatatu.com
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Victor Nogueira <victor@mojatatu.com>
---
net/sched/cls_route.c | 27 +++++++++++++--------------
1 file changed, 13 insertions(+), 14 deletions(-)
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index 9710b77d379c..0f211f030fd9 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -393,8 +393,9 @@ static const struct nla_policy route4_policy[TCA_ROUTE4_MAX + 1] = {
static int route4_set_parms(struct net *net, struct tcf_proto *tp,
unsigned long base, struct route4_filter *f,
u32 handle, struct route4_head *head,
- struct nlattr **tb, struct nlattr *est, int new,
- u32 flags, struct netlink_ext_ack *extack)
+ struct nlattr **tb, struct nlattr *est,
+ struct route4_filter *fold, u32 flags,
+ struct netlink_ext_ack *extack)
{
u32 id = 0, to = 0, nhandle = 0x8000;
struct route4_filter *fp;
@@ -407,7 +408,7 @@ static int route4_set_parms(struct net *net, struct tcf_proto *tp,
return err;
if (tb[TCA_ROUTE4_TO]) {
- if (new && handle & 0x8000) {
+ if (!fold && handle & 0x8000) {
NL_SET_ERR_MSG(extack, "Invalid handle");
return -EINVAL;
}
@@ -430,14 +431,14 @@ static int route4_set_parms(struct net *net, struct tcf_proto *tp,
} else
nhandle |= 0xFFFF << 16;
- if (handle && new) {
+ if (handle && (!fold || nhandle == (handle & ~0x7F00)))
nhandle |= handle & 0x7F00;
- if (nhandle != handle) {
- NL_SET_ERR_MSG_FMT(extack,
- "Handle mismatch constructed: %x (expected: %x)",
- handle, nhandle);
- return -EINVAL;
- }
+
+ if (handle && !fold && nhandle != handle) {
+ NL_SET_ERR_MSG_FMT(extack,
+ "Handle mismatch constructed: %x (expected: %x)",
+ handle, nhandle);
+ return -EINVAL;
}
if (!nhandle) {
@@ -460,7 +461,7 @@ static int route4_set_parms(struct net *net, struct tcf_proto *tp,
for (fp = rtnl_dereference(b->ht[h2]);
fp;
fp = rtnl_dereference(fp->next))
- if (fp->handle == nhandle) {
+ if (fp != fold && fp->handle == nhandle) {
NL_SET_ERR_MSG_FMT(extack,
"Handle %x is already in use",
nhandle);
@@ -502,7 +503,6 @@ static int route4_change(struct net *net, struct sk_buff *in_skb,
struct nlattr *tb[TCA_ROUTE4_MAX + 1];
unsigned int h;
int err;
- bool new = true;
if (!handle) {
NL_SET_ERR_MSG(extack, "Creating with handle of 0 is invalid");
@@ -539,11 +539,10 @@ static int route4_change(struct net *net, struct sk_buff *in_skb,
f->tp = fold->tp;
f->bkt = fold->bkt;
- new = false;
}
err = route4_set_parms(net, tp, base, f, handle, head, tb,
- tca[TCA_RATE], new, flags, extack);
+ tca[TCA_RATE], fold, flags, extack);
if (err < 0)
goto errout;
--
2.55.0
next prev parent reply other threads:[~2026-09-07 19:21 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-07 19:21 [PATCH net v2 0/4] net/sched: cls_route: fix bucket retention and handle recomputation Victor Nogueira
2026-09-07 19:21 ` [PATCH net v2 1/4] net/sched: cls_route: free emptied bucket on filter move Victor Nogueira
2026-09-07 19:21 ` [PATCH net v2 2/4] net/sched: cls_route: Reject handle aliasing Victor Nogueira
2026-09-09 10:22 ` netdev-bot+sashiko
2026-09-10 9:27 ` Paolo Abeni
2026-09-10 12:59 ` Victor Nogueira
2026-09-07 19:21 ` Victor Nogueira [this message]
2026-09-07 19:21 ` [PATCH net v2 4/4] selftests/tc-testing: Add cls_route bucket move and change tests Victor Nogueira
2026-09-10 9:30 ` [PATCH net v2 0/4] net/sched: cls_route: fix bucket retention and handle recomputation patchwork-bot+netdevbpf
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=20260907192133.2639067-4-victor@mojatatu.com \
--to=victor@mojatatu.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=jhs@mojatatu.com \
--cc=jiri@resnulli.us \
--cc=kuba@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=vega@nebusec.ai \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.