[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