summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-07-08 16:13:10 -0700
committerDavid S. Miller <davem@davemloft.net>2014-07-08 16:13:10 -0700
commit9274f9f895be561274ac13b37494abbc4243aebc (patch)
treed4247dfb6ac918beb7b515cac71c6f334635a486
parent70452dcb6d401349fbd6db55dfab112fb44639be (diff)
parentc34963e21685659eb513e1c4d847f81d8a8f13f3 (diff)
Merge branch 'bridge_batmanadv_exports'
Linus Lüssing says: ==================== bridge: multicast snooping exports #2 Some people pointed out to me that it might be helpful to add stubs for the newly added multicast exports. That way e.g. batman-adv should continue to be compile and useable without having to have a kernel compiled with bridge code in the future. This is what the first patch is supposed to do. The second patch adds a third multicast export for the bridge which e.g. batman-adv is supposed to use, too, soon: Just like the bridge disables its multicast snooping activities if no querier is present, batman-adv needs to do the same if bridges are involved. These three exports should be the final ones needed to marry the bridge multicast snooping with the batman-adv multicast optimizations recently added for the 3.15 kernel, allowing to use these optimzations in common setups having a bridge on top of e.g. bat0, too. So far these bridged setups would fall back to simple flooding through the batman-adv mesh network for any multicast packet entering bat0. More information about the batman-adv multicast optimizations currently implemented can be found here: http://www.open-mesh.org/projects/batman-adv/wiki/Basic-multicast-optimizations The integration on the batman-adv side could afterwards look like this, for instance (now including the third export): http://git.open-mesh.org/batman-adv.git/commitdiff/61e4f6af4b7a21ed4040f2e711d50c778e5b6d93?hp=6ae4281474675fbca5bedcf768972a32db586eb6 ====================
-rw-r--r--include/linux/if_bridge.h20
-rw-r--r--net/bridge/br_multicast.c37
2 files changed, 57 insertions, 0 deletions
diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h
index fd22789d7b2e..808dcb8cc04f 100644
--- a/include/linux/if_bridge.h
+++ b/include/linux/if_bridge.h
@@ -36,8 +36,28 @@ extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __use
typedef int br_should_route_hook_t(struct sk_buff *skb);
extern br_should_route_hook_t __rcu *br_should_route_hook;
+
+#if IS_ENABLED(CONFIG_BRIDGE) && IS_ENABLED(CONFIG_BRIDGE_IGMP_SNOOPING)
int br_multicast_list_adjacent(struct net_device *dev,
struct list_head *br_ip_list);
+bool br_multicast_has_querier_anywhere(struct net_device *dev, int proto);
bool br_multicast_has_querier_adjacent(struct net_device *dev, int proto);
+#else
+static inline int br_multicast_list_adjacent(struct net_device *dev,
+ struct list_head *br_ip_list)
+{
+ return 0;
+}
+static inline bool br_multicast_has_querier_anywhere(struct net_device *dev,
+ int proto)
+{
+ return false;
+}
+static inline bool br_multicast_has_querier_adjacent(struct net_device *dev,
+ int proto)
+{
+ return false;
+}
+#endif
#endif
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(&eth, 0, sizeof(eth));
+ eth.h_proto = htons(proto);
+
+ ret = br_multicast_querier_exists(br, &eth);
+
+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