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: 34d35b4edb ("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 <acassen@corp.free.fr>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20261021193222.1318333-2-acassen@corp.free.fr
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Alexandre Cassen 2026-10-21 21:32:18 +02:00 committed by Jakub Kicinski
parent dacb77e32e
commit 9463e8d8c6

View File

@ -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)