diff options
author | Linus Lüssing <linus.luessing@web.de> | 2014-07-07 05:41:17 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-07-08 16:12:53 -0700 |
commit | c34963e21685659eb513e1c4d847f81d8a8f13f3 (patch) | |
tree | d4247dfb6ac918beb7b515cac71c6f334635a486 /net/bridge | |
parent | f941a6d9a9e0612eb807af822b0d1ac004da8175 (diff) |
bridge: export knowledge about the presence of IGMP/MLD queriers
With this patch other modules are able to ask the bridge whether an
IGMP or MLD querier exists on the according, bridged link layer.
Multicast snooping can only be performed if a valid, selected querier
exists on a link.
Just like the bridge only enables its multicast snooping if a querier
exists, e.g. batman-adv too can only activate its multicast
snooping in bridged scenarios if a querier is present.
For instance this export avoids having to reimplement IGMP/MLD
querier message snooping and parsing in e.g. batman-adv, when
multicast optimizations for bridged scenarios are added in the
future.
Signed-off-by: Linus Lüssing <linus.luessing@web.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge')
-rw-r--r-- | net/bridge/br_multicast.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index abfa0b65a111..b4845f4b2bb4 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -2216,6 +2216,43 @@ unlock: EXPORT_SYMBOL_GPL(br_multicast_list_adjacent); /** + * br_multicast_has_querier_anywhere - Checks for a querier on a bridge + * @dev: The bridge port providing the bridge on which to check for a querier + * @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 valid querier exists anywhere on the bridged link layer. + * Otherwise returns false. + */ +bool br_multicast_has_querier_anywhere(struct net_device *dev, int proto) +{ + struct net_bridge *br; + struct net_bridge_port *port; + struct ethhdr eth; + bool ret = false; + + rcu_read_lock(); + if (!br_port_exists(dev)) + goto unlock; + + port = br_port_get_rcu(dev); + if (!port || !port->br) + goto unlock; + + br = port->br; + + memset(ð, 0, sizeof(eth)); + eth.h_proto = htons(proto); + + ret = br_multicast_querier_exists(br, ð); + +unlock: + rcu_read_unlock(); + return ret; +} +EXPORT_SYMBOL_GPL(br_multicast_has_querier_anywhere); + +/** * br_multicast_has_querier_adjacent - Checks for a querier behind a bridge port * @dev: The bridge port adjacent to which to check for a querier * @proto: The protocol family to check for: IGMP -> ETH_P_IP, MLD -> ETH_P_IPV6 |