[pve-devel] [PATCH] bridge: disable igmp querier by default

Alexandre Derumier aderumier at odiso.com
Tue Mar 12 06:12:42 CET 2013


and reenable multicast_snooping  module

Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
---
 0001-bridge-disable-querier.patch |   54 ++++++++++++++++
 0002-bridge-disable-querier.patch |   60 ++++++++++++++++++
 0003-bridge-disable-querier.patch |  125 +++++++++++++++++++++++++++++++++++++
 0004-bridge-disable-querier.patch |   42 +++++++++++++
 Makefile                          |    4 ++
 config-2.6.32.diff                |    3 +-
 6 files changed, 286 insertions(+), 2 deletions(-)
 create mode 100644 0001-bridge-disable-querier.patch
 create mode 100644 0002-bridge-disable-querier.patch
 create mode 100644 0003-bridge-disable-querier.patch
 create mode 100644 0004-bridge-disable-querier.patch

diff --git a/0001-bridge-disable-querier.patch b/0001-bridge-disable-querier.patch
new file mode 100644
index 0000000..5f9465e
--- /dev/null
+++ b/0001-bridge-disable-querier.patch
@@ -0,0 +1,54 @@
+From 748572162a2bc3ce6f0b215e25ad601c3ec33e77 Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert at gondor.apana.org.au>
+Date: Fri, 13 Apr 2012 02:37:42 +0000
+Subject: bridge: Add br_multicast_start_querier
+
+This patch adds the helper br_multicast_start_querier so that
+the code which starts the queriers in br_multicast_toggle can
+be reused elsewhere.
+
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
+index 3253107..0385584 100644
+--- a/net/bridge/br_multicast.c
++++ b/net/bridge/br_multicast.c
+@@ -1740,6 +1740,21 @@ unlock:
+ 	return err;
+ }
+ 
++static void br_multicast_start_querier(struct net_bridge *br)
++{
++	struct net_bridge_port *port;
++
++	br_multicast_open(br);
++
++	list_for_each_entry(port, &br->port_list, list) {
++		if (port->state == BR_STATE_DISABLED ||
++		    port->state == BR_STATE_BLOCKING)
++			continue;
++
++		__br_multicast_enable_port(port);
++	}
++}
++
+ int br_multicast_toggle(struct net_bridge *br, unsigned long val)
+ {
+ 	struct net_bridge_port *port;
+@@ -1771,14 +1786,7 @@ rollback:
+ 			goto rollback;
+ 	}
+ 
+-	br_multicast_open(br);
+-	list_for_each_entry(port, &br->port_list, list) {
+-		if (port->state == BR_STATE_DISABLED ||
+-		    port->state == BR_STATE_BLOCKING)
+-			continue;
+-
+-		__br_multicast_enable_port(port);
+-	}
++	br_multicast_start_querier(br);
+ 
+ unlock:
+ 	spin_unlock(&br->multicast_lock);
diff --git a/0002-bridge-disable-querier.patch b/0002-bridge-disable-querier.patch
new file mode 100644
index 0000000..7c5ea0f
--- /dev/null
+++ b/0002-bridge-disable-querier.patch
@@ -0,0 +1,60 @@
+From c83b8fab06fc8c80d6440649f117bb7541df5fd0 Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert at gondor.apana.org.au>
+Date: Fri, 13 Apr 2012 02:37:42 +0000
+Subject: bridge: Restart queries when last querier expires
+
+As it stands when we discover that a real querier (one that queries
+with a non-zero source address) we stop querying.  However, even
+after said querier has fallen off the edge of the earth, we will
+never restart querying (unless the bridge itself is restarted).
+
+This patch fixes this by kicking our own querier into gear when
+the timer for other queriers expire.
+
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
+index 0385584..656b77c 100644
+--- a/net/bridge/br_multicast.c
++++ b/net/bridge/br_multicast.c
+@@ -33,6 +33,8 @@
+ 
+ #include "br_private.h"
+ 
++static void br_multicast_start_querier(struct net_bridge *br);
++
+ #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+ static inline int ipv6_is_transient_multicast(const struct in6_addr *addr)
+ {
+@@ -802,6 +804,21 @@ static void br_multicast_local_router_expired(unsigned long data)
+ {
+ }
+ 
++static void br_multicast_querier_expired(unsigned long data)
++{
++	struct net_bridge_port *port = (void *)data;
++	struct net_bridge *br = port->br;
++
++	spin_lock(&br->multicast_lock);
++	if (!netif_running(br->dev) || br->multicast_disabled)
++		goto out;
++
++	br_multicast_start_querier(br);
++
++out:
++	spin_unlock(&br->multicast_lock);
++}
++
+ static void __br_multicast_send_query(struct net_bridge *br,
+ 				      struct net_bridge_port *port,
+ 				      struct br_ip *ip)
+@@ -1612,7 +1629,7 @@ void br_multicast_init(struct net_bridge *br)
+ 	setup_timer(&br->multicast_router_timer,
+ 		    br_multicast_local_router_expired, 0);
+ 	setup_timer(&br->multicast_querier_timer,
+-		    br_multicast_local_router_expired, 0);
++		    br_multicast_querier_expired, 0);
+ 	setup_timer(&br->multicast_query_timer, br_multicast_query_expired,
+ 		    (unsigned long)br);
+ }
diff --git a/0003-bridge-disable-querier.patch b/0003-bridge-disable-querier.patch
new file mode 100644
index 0000000..9615545
--- /dev/null
+++ b/0003-bridge-disable-querier.patch
@@ -0,0 +1,125 @@
+From c5c23260594c5701af66ef754916775ba6a46bbc Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert at gondor.apana.org.au>
+Date: Fri, 13 Apr 2012 02:37:42 +0000
+Subject: bridge: Add multicast_querier toggle and disable queries by default
+
+Sending general queries was implemented as an optimisation to speed
+up convergence on start-up.  In order to prevent interference with
+multicast routers a zero source address has to be used.
+
+Unfortunately these packets appear to cause some multicast-aware
+switches to misbehave, e.g., by disrupting multicast packets to us.
+
+Since the multicast snooping feature still functions without sending
+our own queries, this patch will change the default to not send
+queries.
+
+For those that need queries in order to speed up convergence on start-up,
+a toggle is provided to restore the previous behaviour.
+
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
+index b3647d0..708e84f 100644
+--- a/net/bridge/br_multicast.c
++++ b/net/bridge/br_multicast.c
+@@ -783,6 +783,7 @@ static void br_multicast_send_query(struct net_bridge *br,
+ 	struct br_ip br_group;
+ 
+ 	if (!netif_running(br->dev) || br->multicast_disabled ||
++	    !br->multicast_querier ||
+ 	    timer_pending(&br->multicast_querier_timer))
+ 		return;
+ 
+@@ -1565,6 +1566,7 @@ void br_multicast_init(struct net_bridge *br)
+ 	br->hash_max = 512;
+ 
+ 	br->multicast_router = 1;
++	br->multicast_querier = 0;
+ 	br->multicast_last_member_count = 2;
+ 	br->multicast_startup_query_count = 2;
+ 
+@@ -1760,6 +1762,24 @@ unlock:
+ 	return err;
+ }
+ 
++int br_multicast_set_querier(struct net_bridge *br, unsigned long val)
++{
++	val = !!val;
++
++	spin_lock_bh(&br->multicast_lock);
++	if (br->multicast_querier == val)
++		goto unlock;
++
++	br->multicast_querier = val;
++	if (val)
++		br_multicast_start_querier(br);
++
++unlock:
++	spin_unlock_bh(&br->multicast_lock);
++
++	return 0;
++}
++
+ int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val)
+ {
+ 	int err = -ENOENT;
+diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
+index e1d8822..f8ffd8c 100644
+--- a/net/bridge/br_private.h
++++ b/net/bridge/br_private.h
+@@ -224,6 +224,7 @@ struct net_bridge
+ 	unsigned char			multicast_router;
+ 
+ 	u8				multicast_disabled:1;
++	u8				multicast_querier:1;
+ 
+ 	u32				hash_elasticity;
+ 	u32				hash_max;
+@@ -417,6 +418,7 @@ extern int br_multicast_set_router(struct net_bridge *br, unsigned long val);
+ extern int br_multicast_set_port_router(struct net_bridge_port *p,
+ 					unsigned long val);
+ extern int br_multicast_toggle(struct net_bridge *br, unsigned long val);
++extern int br_multicast_set_querier(struct net_bridge *br, unsigned long val);
+ extern int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val);
+ 
+ static inline bool br_multicast_is_router(struct net_bridge *br)
+diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
+index 766fd7f..c5c0593 100644
+--- a/net/bridge/br_sysfs_br.c
++++ b/net/bridge/br_sysfs_br.c
+@@ -379,6 +379,23 @@ static ssize_t store_multicast_snooping(struct device *d,
+ static DEVICE_ATTR(multicast_snooping, S_IRUGO | S_IWUSR,
+ 		   show_multicast_snooping, store_multicast_snooping);
+ 
++static ssize_t show_multicast_querier(struct device *d,
++				      struct device_attribute *attr,
++				      char *buf)
++{
++	struct net_bridge *br = to_bridge(d);
++	return sprintf(buf, "%d\n", br->multicast_querier);
++}
++
++static ssize_t store_multicast_querier(struct device *d,
++				       struct device_attribute *attr,
++				       const char *buf, size_t len)
++{
++	return store_bridge_parm(d, buf, len, br_multicast_set_querier);
++}
++static DEVICE_ATTR(multicast_querier, S_IRUGO | S_IWUSR,
++		   show_multicast_querier, store_multicast_querier);
++
+ static ssize_t show_hash_elasticity(struct device *d,
+ 				    struct device_attribute *attr, char *buf)
+ {
+@@ -702,6 +719,7 @@ static struct attribute *bridge_attrs[] = {
+ #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
+ 	&dev_attr_multicast_router.attr,
+ 	&dev_attr_multicast_snooping.attr,
++	&dev_attr_multicast_querier.attr,
+ 	&dev_attr_hash_elasticity.attr,
+ 	&dev_attr_hash_max.attr,
+ 	&dev_attr_multicast_last_member_count.attr,
+--
+cgit v0.9.1
diff --git a/0004-bridge-disable-querier.patch b/0004-bridge-disable-querier.patch
new file mode 100644
index 0000000..e8074e3
--- /dev/null
+++ b/0004-bridge-disable-querier.patch
@@ -0,0 +1,42 @@
+From bb63f1f8a08cf8028564ad04831ebd7a8ffb9cba Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert at gondor.apana.org.au>
+Date: Mon, 30 Apr 2012 00:22:56 +0000
+Subject: bridge: Fix fatal typo in setup of multicast_querier_expired
+
+Unfortunately it seems that I didn't properly test the case of
+an expired external querier in the recent multicast bridge series.
+
+The setup of the timer in that case is completely broken and leads
+to a NULL-pointer dereference.  This patch fixes it.
+
+Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
+Acked-by: Stephen Hemminger <shemminger at vyatta.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+(limited to 'net/bridge/br_multicast.c')
+
+diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
+index 708e84f..5ca4c50 100644
+--- a/net/bridge/br_multicast.c
++++ b/net/bridge/br_multicast.c
+@@ -744,8 +744,7 @@ static void br_multicast_local_router_expired(unsigned long data)
+ 
+ static void br_multicast_querier_expired(unsigned long data)
+ {
+-	struct net_bridge_port *port = (void *)data;
+-	struct net_bridge *br = port->br;
++	struct net_bridge *br = (void *)data;
+ 
+ 	spin_lock(&br->multicast_lock);
+ 	if (!netif_running(br->dev) || br->multicast_disabled)
+@@ -1581,7 +1580,7 @@ void br_multicast_init(struct net_bridge *br)
+ 	setup_timer(&br->multicast_router_timer,
+ 		    br_multicast_local_router_expired, 0);
+ 	setup_timer(&br->multicast_querier_timer,
+-		    br_multicast_querier_expired, 0);
++		    br_multicast_querier_expired, (unsigned long)br);
+ 	setup_timer(&br->multicast_query_timer, br_multicast_query_expired,
+ 		    (unsigned long)br);
+ }
+--
+cgit v0.9.1
diff --git a/Makefile b/Makefile
index 7a89cf0..ab79e1e 100644
--- a/Makefile
+++ b/Makefile
@@ -144,6 +144,10 @@ ${KERNEL_SRC}/README: ${KERNEL_SRC}.org/README
 	cd ${KERNEL_SRC}; patch -p1 <../${RHKERSRCDIR}/patch-042stab074
 	cd ${KERNEL_SRC}; patch -p1 <../do-not-use-barrier-on-ext3.patch
 	cd ${KERNEL_SRC}; patch -p1 <../bridge-patch.diff
+	cd ${KERNEL_SRC}; patch -p1 <../0001-bridge-disable-querier.patch
+	cd ${KERNEL_SRC}; patch -p1 <../0002-bridge-disable-querier.patch
+	cd ${KERNEL_SRC}; patch -p1 <../0003-bridge-disable-querier.patch
+	cd ${KERNEL_SRC}; patch -p1 <../0004-bridge-disable-querier.patch
 	cd ${KERNEL_SRC}; patch -p1 <../fix-aspm-policy.patch
 	#cd ${KERNEL_SRC}; patch -p1 <../optimize-cfq-parameters.patch
 	sed -i ${KERNEL_SRC}/Makefile -e 's/^EXTRAVERSION.*$$/EXTRAVERSION=${EXTRAVERSION}/'
diff --git a/config-2.6.32.diff b/config-2.6.32.diff
index 5c7ed94..e5f52c7 100644
--- a/config-2.6.32.diff
+++ b/config-2.6.32.diff
@@ -14,9 +14,8 @@
  CONFIG_STP=m
  CONFIG_GARP=m
 -CONFIG_BRIDGE=m
--CONFIG_BRIDGE_IGMP_SNOOPING=y
 +CONFIG_BRIDGE=y
-+# CONFIG_BRIDGE_IGMP_SNOOPING is not set
+ CONFIG_BRIDGE_IGMP_SNOOPING=y
  CONFIG_NET_DSA=y
  CONFIG_NET_DSA_TAG_DSA=y
  CONFIG_NET_DSA_TAG_EDSA=y
-- 
1.7.10.4



More information about the pve-devel mailing list