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); + 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) {