On 09/05/2021 22:45, Linus Lüssing wrote:
To properly support routable multicast addresses in batman-adv in a group-aware way, a batman-adv node needs to know if it serves multicast routers.
This adds a function to the bridge to export this so that batman-adv can then make full use of the Multicast Router Discovery capability of the bridge.
Signed-off-by: Linus Lüssing linus.luessing@c0d3.blue
net/bridge/br_multicast.c | 58 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+)
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index b625fd6..e963de5 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -4061,6 +4061,64 @@ unlock: } EXPORT_SYMBOL_GPL(br_multicast_has_querier_adjacent);
+/**
- br_multicast_has_router_adjacent - Checks for a router behind a bridge port
- @dev: The bridge port adjacent to which to check for a multicast router
- @proto: The protocol family to check for: IGMP -> ETH_P_IP, MLD -> ETH_P_IPV6
- Checks whether the given interface has a bridge on top and if so returns
- true if a multicast router is behind one of the other ports of this
- bridge. Otherwise returns false.
- */
+bool br_multicast_has_router_adjacent(struct net_device *dev, int proto) +{
- struct net_bridge_port *port, *p;
- bool ret = false;
- rcu_read_lock();
- if (!netif_is_bridge_port(dev))
goto unlock;
- port = br_port_get_rcu(dev);
You can combine both of netif_is_bridge_port and br_port_get_rcu() checks and use br_port_get_check_rcu(). Then you can also drop the port->br check.
- if (!port || !port->br)
goto unlock;
- switch (proto) {
- case ETH_P_IP:
hlist_for_each_entry_rcu(p, &port->br->ip4_mc_router_list,
ip4_rlist) {
if (p == port)
continue;
ret = true;
goto unlock;
}
break;
+#if IS_ENABLED(CONFIG_IPV6)
- case ETH_P_IPV6:
hlist_for_each_entry_rcu(p, &port->br->ip6_mc_router_list,
ip6_rlist) {
if (p == port)
continue;
ret = true;
goto unlock;
}
break;
+#endif
- default:
/* when compiled without IPv6 support, be conservative and
* always assume presence of an IPv6 multicast router
*/
ret = true;
- }
+unlock:
- rcu_read_unlock();
- return ret;
+} +EXPORT_SYMBOL_GPL(br_multicast_has_router_adjacent);
static void br_mcast_stats_add(struct bridge_mcast_stats __percpu *stats, const struct sk_buff *skb, u8 type, u8 dir) {