* [PATCH net v3 0/3] net: dsa: motorcomm: ACL fixup
@ 2026-11-06 7:37 David Yang
2026-11-06 7:38 ` [PATCH net v3 1/3] net: dsa: motorcomm: Fix extack message on unsupported TC actions David Yang
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: David Yang @ 2026-11-06 7:37 UTC (permalink / raw)
To: netdev
Cc: David Yang, Andrew Lunn, Vladimir Oltean, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, linux-kernel
Various ACL defects. Found by LLM and manually verified (on YT9215).
v3:
- also unset `reason` initializer
- fix action resolver again
v2: https://lore.kernel.org/r/20261103095514.338700-1-mmyangfl@gmail.com
- withdraw patch 2 as it needs another test run on the device
- fix patch 3 to align with software behavior
v1: https://lore.kernel.org/r/20261102071119.3435180-1-mmyangfl@gmail.com
David Yang (3):
net: dsa: motorcomm: Fix extack message on unsupported TC actions
net: dsa: motorcomm: Resolve the flower action list to one ACL verdict
net: dsa: motorcomm: Delete the ACL rule of the port being unbound
drivers/net/dsa/motorcomm/tc.c | 90 ++++++++++++++++++----------------
1 file changed, 49 insertions(+), 41 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH net v3 1/3] net: dsa: motorcomm: Fix extack message on unsupported TC actions
2026-11-06 7:37 [PATCH net v3 0/3] net: dsa: motorcomm: ACL fixup David Yang
@ 2026-11-06 7:38 ` David Yang
2026-11-06 7:38 ` [PATCH net v3 2/3] net: dsa: motorcomm: Resolve the flower action list to one ACL verdict David Yang
2026-11-06 7:38 ` [PATCH net v3 3/3] net: dsa: motorcomm: Delete the ACL rule of the port being unbound David Yang
2 siblings, 0 replies; 5+ messages in thread
From: David Yang @ 2026-11-06 7:38 UTC (permalink / raw)
To: netdev
Cc: David Yang, Andrew Lunn, Vladimir Oltean, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, linux-kernel
No extack reasons were given to unsupported TC actions. Set a reason on
the default path before falling back, and drop the now-redundant
initializer of `reason`, so the compiler warns on any future path that
uses it without assigning one.
Fixes: 8eb9e7520b17 ("net: dsa: yt921x: Add ACL support")
Signed-off-by: David Yang <mmyangfl@gmail.com>
---
drivers/net/dsa/motorcomm/tc.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dsa/motorcomm/tc.c b/drivers/net/dsa/motorcomm/tc.c
index 9dbd61e48fee..90b017a11a1b 100644
--- a/drivers/net/dsa/motorcomm/tc.c
+++ b/drivers/net/dsa/motorcomm/tc.c
@@ -1034,8 +1034,8 @@ yt921x_acl_rule_ext_parse_flow_action(struct yt921x_acl_rule_ext *ruleext,
const struct flow_action_entry *act;
u32 *action = ruleext->r.action;
bool seen_priority = false;
- const char *reason = NULL;
bool seen_police = false;
+ const char *reason;
unsigned int i;
int res;
@@ -1122,6 +1122,7 @@ yt921x_acl_rule_ext_parse_flow_action(struct yt921x_acl_rule_ext *ruleext,
break;
}
default:
+ reason = "Unsupported by HW";
fallback:
if (cls->common.skip_sw) {
NL_SET_ERR_MSG_FMT_MOD(extack,
--
2.53.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH net v3 2/3] net: dsa: motorcomm: Resolve the flower action list to one ACL verdict
2026-11-06 7:37 [PATCH net v3 0/3] net: dsa: motorcomm: ACL fixup David Yang
2026-11-06 7:38 ` [PATCH net v3 1/3] net: dsa: motorcomm: Fix extack message on unsupported TC actions David Yang
@ 2026-11-06 7:38 ` David Yang
2026-11-10 8:11 ` netdev-bot+sashiko
2026-11-06 7:38 ` [PATCH net v3 3/3] net: dsa: motorcomm: Delete the ACL rule of the port being unbound David Yang
2 siblings, 1 reply; 5+ messages in thread
From: David Yang @ 2026-11-06 7:38 UTC (permalink / raw)
To: netdev
Cc: David Yang, Andrew Lunn, Vladimir Oltean, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, linux-kernel
The hardware resolves one forward decision per ACL rule, but the
translation accumulated every action, so a later action silently changed
the verdict of the ones before it: an `action drop action trap` filter
with skip_sw trapped packets to the CPU instead of dropping them.
Resolve the list against its first terminal action. Only a drop can
follow a redirect: a drop is an empty destination set, so the software
verdict is the same whichever control the redirect carries, while a
second redirect would only extend it if software continued past the
first one, and the flow action entry carries no mirred control verdict
to tell that. An action asking for a second decision is rejected when
skip_sw is set and left to the software path otherwise.
Fixes: 8eb9e7520b17 ("net: dsa: yt921x: Add ACL support")
Signed-off-by: David Yang <mmyangfl@gmail.com>
---
drivers/net/dsa/motorcomm/tc.c | 74 ++++++++++++++++++----------------
1 file changed, 39 insertions(+), 35 deletions(-)
diff --git a/drivers/net/dsa/motorcomm/tc.c b/drivers/net/dsa/motorcomm/tc.c
index 90b017a11a1b..5c82719e461f 100644
--- a/drivers/net/dsa/motorcomm/tc.c
+++ b/drivers/net/dsa/motorcomm/tc.c
@@ -1030,55 +1030,56 @@ yt921x_acl_rule_ext_parse_flow_action(struct yt921x_acl_rule_ext *ruleext,
const struct flow_rule *rule = flow_cls_offload_flow_rule(cls);
const struct flow_action *flow_action = &rule->action;
struct netlink_ext_ack *extack = cls->common.extack;
- enum flow_action_id redir_act = NUM_FLOW_ACTIONS;
const struct flow_action_entry *act;
u32 *action = ruleext->r.action;
bool seen_priority = false;
bool seen_police = false;
+ bool terminal = false;
+ bool redir = false;
const char *reason;
unsigned int i;
int res;
memset(action, 0, 3 * sizeof(*action));
- flow_action_for_each(i, act, flow_action)
+ flow_action_for_each(i, act, flow_action) {
+ /* Only a drop can follow a redirect: a drop is an empty
+ * destination set, so the software verdict is the same
+ * whichever control the redirect carries. A second redirect
+ * would only extend it if software continued past the first
+ * one, and the flow action entry carries no mirred control
+ * verdict to tell that.
+ */
+ if (redir && act->id != FLOW_ACTION_DROP) {
+ reason = "Action after redirect";
+ goto fallback;
+ }
+
switch (act->id) {
case FLOW_ACTION_ACCEPT:
+ action[2] |= YT921X_ACL_ACTc_FWD_EN |
+ YT921X_ACL_ACTc_FWD_FWD;
+ terminal = true;
+ break;
case FLOW_ACTION_DROP:
- case FLOW_ACTION_REDIRECT:
- if (redir_act != NUM_FLOW_ACTIONS &&
- redir_act != act->id) {
- reason = "Different redirect actions";
+ action[2] |= YT921X_ACL_ACTc_FWD_EN |
+ YT921X_ACL_ACTc_FWD_REDIR;
+ terminal = true;
+ break;
+ case FLOW_ACTION_REDIRECT: {
+ struct dsa_port *to_dp;
+
+ to_dp = dsa_port_from_netdev(act->dev);
+ if (IS_ERR(to_dp) || to_dp->ds != &priv->ds) {
+ reason = "Redirect to non-local port";
goto fallback;
}
- redir_act = act->id;
-
- switch (act->id) {
- case FLOW_ACTION_ACCEPT:
- action[2] |= YT921X_ACL_ACTc_FWD_EN |
- YT921X_ACL_ACTc_FWD_FWD;
- break;
- case FLOW_ACTION_DROP:
- action[2] |= YT921X_ACL_ACTc_FWD_EN |
- YT921X_ACL_ACTc_FWD_REDIR;
- break;
- case FLOW_ACTION_REDIRECT: {
- struct dsa_port *to_dp;
- to_dp = dsa_port_from_netdev(act->dev);
- if (IS_ERR(to_dp) || to_dp->ds != &priv->ds) {
- reason = "Redirect to non-local port";
- goto fallback;
- }
-
- action[2] |= YT921X_ACL_ACTc_FWD_EN |
- YT921X_ACL_ACTc_FWD_REDIR |
- YT921X_ACL_ACTc_FWD_REDIR_DPORTn(to_dp->index);
- break;
- }
- default:
- break;
- }
+ action[2] |= YT921X_ACL_ACTc_FWD_EN |
+ YT921X_ACL_ACTc_FWD_REDIR |
+ YT921X_ACL_ACTc_FWD_REDIR_DPORTn(to_dp->index);
+ redir = true;
break;
+ }
case FLOW_ACTION_PRIORITY:
if (seen_priority) {
action[0] &= ~YT921X_ACL_ACTa_PRIO_EN;
@@ -1132,15 +1133,18 @@ yt921x_acl_rule_ext_parse_flow_action(struct yt921x_acl_rule_ext *ruleext,
}
fallthrough;
case FLOW_ACTION_TRAP:
- redir_act = FLOW_ACTION_TRAP;
-
action[2] &= ~YT921X_ACL_ACTc_FWD_REDIR_DPORTS_M &
~YT921X_ACL_ACTc_FWD_M;
action[2] |= YT921X_ACL_ACTc_FWD_EN |
YT921X_ACL_ACTc_FWD_TRAP;
+ terminal = true;
break;
}
+ if (terminal)
+ break;
+ }
+
ruleext->r.sw_assisted = !cls->common.skip_sw;
return 0;
}
--
2.53.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH net v3 3/3] net: dsa: motorcomm: Delete the ACL rule of the port being unbound
2026-11-06 7:37 [PATCH net v3 0/3] net: dsa: motorcomm: ACL fixup David Yang
2026-11-06 7:38 ` [PATCH net v3 1/3] net: dsa: motorcomm: Fix extack message on unsupported TC actions David Yang
2026-11-06 7:38 ` [PATCH net v3 2/3] net: dsa: motorcomm: Resolve the flower action list to one ACL verdict David Yang
@ 2026-11-06 7:38 ` David Yang
2 siblings, 0 replies; 5+ messages in thread
From: David Yang @ 2026-11-06 7:38 UTC (permalink / raw)
To: netdev
Cc: David Yang, Andrew Lunn, Vladimir Oltean, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, linux-kernel
A flower filter on a block shared across ports is offloaded as one
hardware rule per port, all carrying the same classifier cookie.
Deletion looked a rule up by cookie alone and could take another
port's copy: with skip_sw, a filter silently stopped being enforced
on a still-bound port, while the detached port kept enforcing it.
Delete the rule matching the port being unbound instead.
Fixes: 8eb9e7520b17 ("net: dsa: yt921x: Add ACL support")
Signed-off-by: David Yang <mmyangfl@gmail.com>
---
drivers/net/dsa/motorcomm/tc.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/drivers/net/dsa/motorcomm/tc.c b/drivers/net/dsa/motorcomm/tc.c
index 5c82719e461f..6192aa9f05be 100644
--- a/drivers/net/dsa/motorcomm/tc.c
+++ b/drivers/net/dsa/motorcomm/tc.c
@@ -1228,7 +1228,7 @@ static u16 yt921x_acl_activated_ports(const struct yt921x_priv *priv)
static unsigned int
yt921x_acl_find(const struct yt921x_priv *priv, enum tc_setup_type type,
- unsigned long tag)
+ unsigned long tag, u16 ports_mask)
{
for (unsigned int blkid = 0; blkid < YT921X_ACL_BLK_NUM; blkid++) {
const struct yt921x_acl_blk *aclblk = priv->acl_blks[blkid];
@@ -1238,7 +1238,10 @@ yt921x_acl_find(const struct yt921x_priv *priv, enum tc_setup_type type,
for (unsigned int i = 0; i < YT921X_ACL_ENT_PER_BLK; i++)
if (aclblk->rules[i] && aclblk->rules[i]->tag == tag &&
- aclblk->rules[i]->type == type)
+ aclblk->rules[i]->type == type &&
+ FIELD_GET(YT921X_ACL_KEYb_SPORTS_M,
+ aclblk->rules[i]->entries[0].key[1]) ==
+ ports_mask)
return YT921X_ACL_ENT_PER_BLK * blkid + i;
}
@@ -1366,7 +1369,7 @@ yt921x_acl_commit(struct yt921x_priv *priv, unsigned int entid, u8 entsmask)
static int
yt921x_acl_del(struct yt921x_priv *priv, enum tc_setup_type type,
- unsigned long tag)
+ unsigned long tag, u16 ports_mask)
{
struct yt921x_acl_rule *aclrule;
struct yt921x_acl_blk *aclblk;
@@ -1380,7 +1383,7 @@ yt921x_acl_del(struct yt921x_priv *priv, enum tc_setup_type type,
int res;
int ret;
- entid = yt921x_acl_find(priv, type, tag);
+ entid = yt921x_acl_find(priv, type, tag, ports_mask);
if (entid == UINT_MAX)
return -ENOENT;
@@ -1555,7 +1558,7 @@ yt921x_dsa_cls_flower_del(struct dsa_switch *ds, int port,
int res;
mutex_lock(&priv->reg_lock);
- res = yt921x_acl_del(priv, TC_SETUP_CLSFLOWER, cls->cookie);
+ res = yt921x_acl_del(priv, TC_SETUP_CLSFLOWER, cls->cookie, BIT(port));
mutex_unlock(&priv->reg_lock);
return res;
--
2.53.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net v3 2/3] net: dsa: motorcomm: Resolve the flower action list to one ACL verdict
2026-11-06 7:38 ` [PATCH net v3 2/3] net: dsa: motorcomm: Resolve the flower action list to one ACL verdict David Yang
@ 2026-11-10 8:11 ` netdev-bot+sashiko
0 siblings, 0 replies; 5+ messages in thread
From: netdev-bot+sashiko @ 2026-11-10 8:11 UTC (permalink / raw)
To: mmyangfl
Cc: netdev, andrew, olteanv, davem, edumazet, kuba, pabeni, linux-kernel
Thank you for your contribution! Sashiko AI review found 1 potential
issue(s) to consider.
Critical: 0 · High: 0 · Medium: 1 · Low: 0
If you believe none of the issues are legitimate, please reply to each
issue of Medium severity or higher and explain why the AI is wrong.
If any of them are legitimate and you plan to respin, please let patchwork
know by including "pw-bot: cr" as a separate line at the end of your reply
(one such reply per series is enough).
- [Medium] This patch adds a claim to both the commit message and a new
comment in yt921x_acl_rule_ext_parse_flow_action()…
--
net: dsa: motorcomm: Resolve the flower action list to one ACL verdict
This commit changes yt921x_acl_rule_ext_parse_flow_action() so the flower
action list resolves to its first terminal action. Before, every action was
accumulated into the ACL verdict. After a redirect only a drop is allowed.
Any other action after a redirect falls back to a CPU trap, or is rejected
when skip_sw is set.
> diff --git a/drivers/net/dsa/motorcomm/tc.c b/drivers/net/dsa/motorcomm/tc.c
> index 90b017a11a1b1..5c82719e461f3 100644
> --- a/drivers/net/dsa/motorcomm/tc.c
> +++ b/drivers/net/dsa/motorcomm/tc.c
> @@ -1030,55 +1030,56 @@ yt921x_acl_rule_ext_parse_flow_action(struct yt921x_acl_rule_ext *ruleext,
[ ... ]
> memset(action, 0, 3 * sizeof(*action));
> - flow_action_for_each(i, act, flow_action)
> + flow_action_for_each(i, act, flow_action) {
> + /* Only a drop can follow a redirect: a drop is an empty
> + * destination set, so the software verdict is the same
> + * whichever control the redirect carries. A second redirect
> + * would only extend it if software continued past the first
> + * one, and the flow action entry carries no mirred control
> + * verdict to tell that.
> + */
> + if (redir && act->id != FLOW_ACTION_DROP) {
> + reason = "Action after redirect";
> + goto fallback;
> + }
> +
> switch (act->id) {
> case FLOW_ACTION_ACCEPT:
> + action[2] |= YT921X_ACL_ACTc_FWD_EN |
> + YT921X_ACL_ACTc_FWD_FWD;
> + terminal = true;
> + break;
> case FLOW_ACTION_DROP:
> - case FLOW_ACTION_REDIRECT:
> - if (redir_act != NUM_FLOW_ACTIONS &&
> - redir_act != act->id) {
> - reason = "Different redirect actions";
> + action[2] |= YT921X_ACL_ACTc_FWD_EN |
> + YT921X_ACL_ACTc_FWD_REDIR;
> + terminal = true;
> + break;
[Severity: Medium]
Is the software verdict really the same "whichever control the redirect
carries"? The commit message makes the same claim:
Only a drop can follow a redirect: a drop is an empty
destination set, so the software verdict is the same
whichever control the redirect carries
This seems to hold for pipe, and for the controls that
tcf_mirred_can_reinsert() accepts (shot, stolen, queued, trap). For pass,
continue, reclassify, goto chain and jump, software looks different.
In net/sched/act_mirred.c:tcf_mirred_to_dev():
dont_clone = skb_at_tc_ingress(skb) && is_redirect &&
tcf_mirred_can_reinsert(retval);
if (!dont_clone) {
skb_to_send = skb_clone(skb, GFP_ATOMIC);
With these controls a clone is redirected and the control is returned
unchanged. Then net/sched/act_api.c:tcf_action_exec() ends the action list:
if (ret != TC_ACT_PIPE)
break;
So the trailing drop never runs in software. A jump control skips over it.
Take a rule like this:
flower ... action mirred egress redirect dev swp1 pass action drop
Software sends a copy to swp1, and the original frame continues into the
stack or on to the next filter. In hardware, the FLOW_ACTION_DROP case keeps
FWD_REDIR together with the DPORTn bit set by the redirect. The rule is
therefore programmed as a pure redirect, and the original frame is only
forwarded to swp1.
Before this patch, this action list hit the "Different redirect actions"
fallback. It was trapped to the CPU, or rejected under skip_sw. Does the
patch now offload a combination where hardware and software behave
differently?
A standalone redirect with one of these controls already had a similar
mismatch, as the second half of the comment says. But
tcf_mirred_offload_act_setup() only fills in entry->id =
FLOW_ACTION_REDIRECT and the device, not the mirred control. That means the
driver cannot check the equivalence this gate relies on.
Should a drop after a redirect go through the fallback path as well? And
could the comment and the commit message be narrowed to the controls where
the equivalence actually holds?
[ ... ]
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261106073806.112122-1-mmyangfl%40gmail.com
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-11-10 8:11 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-06 7:37 [PATCH net v3 0/3] net: dsa: motorcomm: ACL fixup David Yang
2026-11-06 7:38 ` [PATCH net v3 1/3] net: dsa: motorcomm: Fix extack message on unsupported TC actions David Yang
2026-11-06 7:38 ` [PATCH net v3 2/3] net: dsa: motorcomm: Resolve the flower action list to one ACL verdict David Yang
2026-11-10 8:11 ` netdev-bot+sashiko
2026-11-06 7:38 ` [PATCH net v3 3/3] net: dsa: motorcomm: Delete the ACL rule of the port being unbound David Yang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®