Re: [PATCH net-next v6 2/4] net: dsa: add bridge member iteration macro and port mask helper
From: Daniel Golle <daniel@makrotopia.org>
Date: 2026-03-23 02:29:54
Also in:
lkml
Subsystem:
networking [dsa], networking [general], the rest · Maintainers:
Andrew Lunn, Vladimir Oltean, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
On Sun, Mar 22, 2026 at 12:19:06AM +0000, Daniel Golle wrote:
quoted hunk ↗ jump to hunk
Drivers that offload bridges need to iterate over the ports that are members of a given bridge, for example to rebuild per-port forwarding bitmaps when membership changes. Currently each driver must open-code this by combining dsa_switch_for_each_user_port() with a dsa_port_offloads_bridge() check, or cache bridge membership within the driver. Add dsa_bridge_for_each_member() to express this pattern directly, and a dsa_bridge_ports() helper that returns a bitmask of member ports, matching the existing dsa_user_ports() and dsa_cpu_ports() helpers. [...]diff --git a/include/net/dsa.h b/include/net/dsa.h index 1c6f6c3b88e86..4f43d518f3de3 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h@@ -838,6 +838,22 @@ static inline bool dsa_port_tree_same(const struct dsa_port *a, return a->ds->dst == b->ds->dst; } +#define dsa_bridge_for_each_member(_dp, _ds, _bridge) \ + dsa_switch_for_each_user_port((_dp), (_ds)) \ + if (dsa_port_offloads_bridge((_dp), (_bridge))) + +static inline u32 dsa_bridge_ports(struct dsa_switch *ds, + const struct dsa_bridge *bridge) +{
I wasn't aware of the similar and equally named function in yt921x.c[1] Patchwork CI has loudly uncovered it and I've learned my lesson to always test an all-y build when changing even the most innocent looking things which technically may affect other drivers. I'll move that function as-is, in a dedicated commit, to include/net/dsa.h as an inline function instead of the helper suggested here. A second commit will introduce the new helper macro dsa_switch_for_each_bridge_member (modified to use (struct net_device *) as parameter instead of (struct dsa_bridge *), and make use of it in dsa_bridge_ports(). I'm also planning to introduce dsa_bridge_for_each_member macro in addition to that which works on (struct dsa_bridge *) and uses dsa_switch_for_each_bridge_member. [1]: https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/tree/drivers/net/dsa/yt921x.c?id=fb78a629b4f0eb399b413f6c093a3da177b3a4eb#n2158 In code, it's going to look like this:
diff --git a/include/net/dsa.h b/include/net/dsa.h
index b43fa7a708c72..c10f05f3e96ed 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h@@ -832,15 +832,21 @@ dsa_tree_offloads_bridge_dev(struct dsa_switch_tree *dst, return false; } +#define dsa_switch_for_each_bridge_member(_dp, _ds, _bdev) \ + dsa_switch_for_each_user_port(_dp, _ds) \ + if (dsa_port_offloads_bridge_dev(_dp, _bdev)) + +#define dsa_bridge_for_each_member(_dp, _ds, _db) \ + dsa_switch_for_each_bridge_member(_dp, _ds, (_db)->dev) + static inline u32 dsa_bridge_ports(struct dsa_switch *ds, const struct net_device *bdev) { struct dsa_port *dp; u32 mask = 0; - dsa_switch_for_each_user_port(dp, ds) - if (dsa_port_offloads_bridge_dev(dp, bdev)) - mask |= BIT(dp->index); + dsa_switch_for_each_bridge_member(dp, ds, bdev) + mask |= BIT(dp->index); return mask; }
Please let me know if any objections you may have.