realtek: dsa: tc: offload flower rules of chain 0 only

The PIE path never looks at the chain of a flower rule: a rule in
chain 1 goes into hardware as if it were in chain 0. No goto chain is
offloaded, so in software such a rule only runs after a goto chain
action jumps there, while in hardware it sees every frame of its port.

Refuse rules outside chain 0 on the PIE path. The port policer already
takes only rules of chain 0, in otto_tc_flower_matches_all(). Families
without pie_cls_flower never reach the check.

On an HPE 1920-48G (RTL8393), a dst_ip drop rule in chain 1 went into
hardware on main and dropped 8 of 8 echo requests, with skip_sw and
without. With this change tc refuses it with skip_sw, keeps it in
software (not_in_hw) without, and the 8 pass in both cases. Not tested
on RTL930x hardware, which shares this path.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Gennaro Cimmino <gcimmino@rayonra.net>
Link: https://github.com/openwrt/openwrt/pull/25906
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
This commit is contained in:
Gennaro Cimmino authored and Markus Stockhausen committed 2026-10-14 21:13:47 +02:00
1 parent de24245e08
commit 8bd2d79d7d
1 file changed
+8
@@ -624,6 +624,14 @@ static int otto_tc_pie_cls_flower_add(struct rtl838x_switch_priv *priv, int port
if (!ingress || !priv->r->pie_cls_flower)
return -EOPNOTSUPP;
/* No goto chain is offloaded, so in hardware a rule of another chain
* would see frames that never reach it in software.
*/
if (cls->common.chain_index) {
NL_SET_ERR_MSG_MOD(cls->common.extack, "only chain 0 is offloaded");
return -EOPNOTSUPP;
}
return otto_tc_configure_flower(priv, cls, port);
}