From 9463e8d8c6922a5aa87f7e4fe6deb4f16925d498 Mon Sep 17 00:00:00 2001 From: Alexandre Cassen Date: Wed, 21 Oct 2026 21:32:18 +0200 Subject: [PATCH] net/sched: act_api: inherit filter offload flags only on new actions tcf_action_init() gives the skip_sw and skip_hw flags of a filter to the actions it binds. An action that another filter created gets them too, they then apply to every filter that uses this action. When a skip_sw filter reuses the action of a software filter, the software filter silently stops running it. This happens even when the filter add fails on a later action. A skip_hw filter likewise prevents a later filter without flags from reusing the action. Give the flags only to the actions that the filter creates. The mismatch check still rejects a filter that reuses an action with a flag that the filter does not have. Discovered by manual code inspection after the Sashiko AI review [1] of a tunnel_key patch questioned how actions get the filter flags. Reproduced on netdevsim without kernel changes. The egress filter below runs in software only, since netdevsim offloads only ingress filters. Once the skip_sw filter reuses its drop action, the last command shows skip_sw on this action and the egress filter stops dropping packets: ethtool -K eth0 hw-tc-offload on tc qdisc add dev eth0 clsact tc filter add dev eth0 egress protocol ip flower dst_ip 192.0.2.1 \ action gact drop index 1 tc filter add dev eth0 ingress protocol ip flower skip_sw \ dst_ip 192.0.2.2 action gact drop index 1 tc actions get action gact index 1 Tested with the reproducer and the tc-testing action, matchall and flower tests. Fixes: 34d35b4edbbe ("net/sched: act_api: deny mismatched skip_sw/skip_hw flags for actions created by classifiers") Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261009051930.3619697-1-acassen%40corp.free.fr [1] Signed-off-by: Alexandre Cassen Reviewed-by: Simon Horman Link: https://patch.msgid.link/20261021193222.1318333-2-acassen@corp.free.fr Signed-off-by: Jakub Kicinski --- net/sched/act_api.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 841e4584f0fe..e142d33dc5ef 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -1560,6 +1560,9 @@ int tcf_action_init(struct net *net, struct tcf_proto *tp, struct nlattr *nla, err = -EINVAL; goto err; } + /* Other filters share an existing action */ + if (init_res[i - 1] != ACT_P_CREATED) + continue; if (skip_sw) act->tcfa_flags |= TCA_ACT_FLAGS_SKIP_SW; if (skip_hw)