From 69c0bf478219b2fbb38fb3c707b220b75bfa4129 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Wed, 26 Jun 2013 07:50:55 -0400 Subject: [PATCH] Add two patches to fix bridge networking issues (rhbz 880035) --- ...the-mdb-entry-when-query-is-received.patch | 159 ++++++++++++++++++ ...d-query-as-soon-as-leave-is-received.patch | 57 +++++++ kernel.spec | 11 ++ 3 files changed, 227 insertions(+) create mode 100644 bridge-only-expire-the-mdb-entry-when-query-is-received.patch create mode 100644 bridge-send-query-as-soon-as-leave-is-received.patch diff --git a/bridge-only-expire-the-mdb-entry-when-query-is-received.patch b/bridge-only-expire-the-mdb-entry-when-query-is-received.patch new file mode 100644 index 000000000..b58b57083 --- /dev/null +++ b/bridge-only-expire-the-mdb-entry-when-query-is-received.patch @@ -0,0 +1,159 @@ +From 9f00b2e7cf241fa389733d41b615efdaa2cb0f5b Mon Sep 17 00:00:00 2001 +From: Cong Wang +Date: Tue, 21 May 2013 21:52:55 +0000 +Subject: bridge: only expire the mdb entry when query is received + +Currently we arm the expire timer when the mdb entry is added, +however, this causes problem when there is no querier sent +out after that. + +So we should only arm the timer when a corresponding query is +received, as suggested by Herbert. + +And he also mentioned "if there is no querier then group +subscriptions shouldn't expire. There has to be at least one querier +in the network for this thing to work. Otherwise it just degenerates +into a non-snooping switch, which is OK." + +Cc: Herbert Xu +Cc: Stephen Hemminger +Cc: "David S. Miller" +Cc: Adam Baker +Signed-off-by: Cong Wang +Acked-by: Herbert Xu +Signed-off-by: David S. Miller +--- +(limited to 'net/bridge') + +diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c +index 2475147..40bda80 100644 +--- a/net/bridge/br_multicast.c ++++ b/net/bridge/br_multicast.c +@@ -617,8 +617,6 @@ rehash: + + mp->br = br; + mp->addr = *group; +- setup_timer(&mp->timer, br_multicast_group_expired, +- (unsigned long)mp); + + hlist_add_head_rcu(&mp->hlist[mdb->ver], &mdb->mhash[hash]); + mdb->size++; +@@ -656,7 +654,6 @@ static int br_multicast_add_group(struct net_bridge *br, + struct net_bridge_mdb_entry *mp; + struct net_bridge_port_group *p; + struct net_bridge_port_group __rcu **pp; +- unsigned long now = jiffies; + int err; + + spin_lock(&br->multicast_lock); +@@ -671,7 +668,6 @@ static int br_multicast_add_group(struct net_bridge *br, + + if (!port) { + mp->mglist = true; +- mod_timer(&mp->timer, now + br->multicast_membership_interval); + goto out; + } + +@@ -679,7 +675,7 @@ static int br_multicast_add_group(struct net_bridge *br, + (p = mlock_dereference(*pp, br)) != NULL; + pp = &p->next) { + if (p->port == port) +- goto found; ++ goto out; + if ((unsigned long)p->port < (unsigned long)port) + break; + } +@@ -690,8 +686,6 @@ static int br_multicast_add_group(struct net_bridge *br, + rcu_assign_pointer(*pp, p); + br_mdb_notify(br->dev, port, group, RTM_NEWMDB); + +-found: +- mod_timer(&p->timer, now + br->multicast_membership_interval); + out: + err = 0; + +@@ -1131,6 +1125,10 @@ static int br_ip4_multicast_query(struct net_bridge *br, + if (!mp) + goto out; + ++ setup_timer(&mp->timer, br_multicast_group_expired, (unsigned long)mp); ++ mod_timer(&mp->timer, now + br->multicast_membership_interval); ++ mp->timer_armed = true; ++ + max_delay *= br->multicast_last_member_count; + + if (mp->mglist && +@@ -1205,6 +1203,10 @@ static int br_ip6_multicast_query(struct net_bridge *br, + if (!mp) + goto out; + ++ setup_timer(&mp->timer, br_multicast_group_expired, (unsigned long)mp); ++ mod_timer(&mp->timer, now + br->multicast_membership_interval); ++ mp->timer_armed = true; ++ + max_delay *= br->multicast_last_member_count; + if (mp->mglist && + (timer_pending(&mp->timer) ? +@@ -1263,7 +1265,7 @@ static void br_multicast_leave_group(struct net_bridge *br, + call_rcu_bh(&p->rcu, br_multicast_free_pg); + br_mdb_notify(br->dev, port, group, RTM_DELMDB); + +- if (!mp->ports && !mp->mglist && ++ if (!mp->ports && !mp->mglist && mp->timer_armed && + netif_running(br->dev)) + mod_timer(&mp->timer, jiffies); + } +@@ -1275,30 +1277,12 @@ static void br_multicast_leave_group(struct net_bridge *br, + br->multicast_last_member_interval; + + if (!port) { +- if (mp->mglist && ++ if (mp->mglist && mp->timer_armed && + (timer_pending(&mp->timer) ? + time_after(mp->timer.expires, time) : + try_to_del_timer_sync(&mp->timer) >= 0)) { + mod_timer(&mp->timer, time); + } +- +- goto out; +- } +- +- for (p = mlock_dereference(mp->ports, br); +- p != NULL; +- p = mlock_dereference(p->next, br)) { +- if (p->port != port) +- continue; +- +- if (!hlist_unhashed(&p->mglist) && +- (timer_pending(&p->timer) ? +- time_after(p->timer.expires, time) : +- try_to_del_timer_sync(&p->timer) >= 0)) { +- mod_timer(&p->timer, time); +- } +- +- break; + } + + out: +@@ -1674,6 +1658,7 @@ void br_multicast_stop(struct net_bridge *br) + hlist_for_each_entry_safe(mp, n, &mdb->mhash[i], + hlist[ver]) { + del_timer(&mp->timer); ++ mp->timer_armed = false; + call_rcu_bh(&mp->rcu, br_multicast_free_group); + } + } +diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h +index e260710..1b0ac95 100644 +--- a/net/bridge/br_private.h ++++ b/net/bridge/br_private.h +@@ -112,6 +112,7 @@ struct net_bridge_mdb_entry + struct timer_list timer; + struct br_ip addr; + bool mglist; ++ bool timer_armed; + }; + + struct net_bridge_mdb_htable +-- +cgit v0.9.2 diff --git a/bridge-send-query-as-soon-as-leave-is-received.patch b/bridge-send-query-as-soon-as-leave-is-received.patch new file mode 100644 index 000000000..8b6652e7e --- /dev/null +++ b/bridge-send-query-as-soon-as-leave-is-received.patch @@ -0,0 +1,57 @@ +From 6b7df111ece130fa979a0c4f58e53674c1e47d3e Mon Sep 17 00:00:00 2001 +From: Cong Wang +Date: Tue, 21 May 2013 21:52:56 +0000 +Subject: bridge: send query as soon as leave is received + +Continue sending queries when leave is received if the user marks +it as a querier. + +Cc: Herbert Xu +Cc: Stephen Hemminger +Cc: "David S. Miller" +Cc: Adam Baker +Signed-off-by: Cong Wang +Acked-by: Herbert Xu +Signed-off-by: David S. Miller +--- +(limited to 'net/bridge') + +diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c +index 40bda80..37a4676 100644 +--- a/net/bridge/br_multicast.c ++++ b/net/bridge/br_multicast.c +@@ -1250,6 +1250,32 @@ static void br_multicast_leave_group(struct net_bridge *br, + if (!mp) + goto out; + ++ if (br->multicast_querier && ++ !timer_pending(&br->multicast_querier_timer)) { ++ __br_multicast_send_query(br, port, &mp->addr); ++ ++ time = jiffies + br->multicast_last_member_count * ++ br->multicast_last_member_interval; ++ mod_timer(port ? &port->multicast_query_timer : ++ &br->multicast_query_timer, time); ++ ++ for (p = mlock_dereference(mp->ports, br); ++ p != NULL; ++ p = mlock_dereference(p->next, br)) { ++ if (p->port != port) ++ continue; ++ ++ if (!hlist_unhashed(&p->mglist) && ++ (timer_pending(&p->timer) ? ++ time_after(p->timer.expires, time) : ++ try_to_del_timer_sync(&p->timer) >= 0)) { ++ mod_timer(&p->timer, time); ++ } ++ ++ break; ++ } ++ } ++ + if (port && (port->flags & BR_MULTICAST_FAST_LEAVE)) { + struct net_bridge_port_group __rcu **pp; + +-- +cgit v0.9.2 diff --git a/kernel.spec b/kernel.spec index 60e7df687..27fd3f20b 100644 --- a/kernel.spec +++ b/kernel.spec @@ -781,6 +781,10 @@ Patch25047: drm-radeon-Disable-writeback-by-default-on-ppc.patch #rhbz 903741 Patch25052: HID-input-return-ENODATA-if-reading-battery-attrs-fails.patch +#rhbz 880035 +Patch25053: bridge-only-expire-the-mdb-entry-when-query-is-received.patch +Patch25054: bridge-send-query-as-soon-as-leave-is-received.patch + # END OF PATCH DEFINITIONS %endif @@ -1490,6 +1494,10 @@ ApplyPatch drm-radeon-Disable-writeback-by-default-on-ppc.patch #rhbz 903741 ApplyPatch HID-input-return-ENODATA-if-reading-battery-attrs-fails.patch +#rhbz 880035 +ApplyPatch bridge-only-expire-the-mdb-entry-when-query-is-received.patch +ApplyPatch bridge-send-query-as-soon-as-leave-is-received.patch + # END OF PATCH APPLICATIONS %endif @@ -2286,6 +2294,9 @@ fi # ||----w | # || || %changelog +* Wed Jun 26 2013 Josh Boyer +- Add two patches to fix bridge networking issues (rhbz 880035) + * Mon Jun 24 2013 Josh Boyer - Fix battery issue with bluetooth keyboards (rhbz 903741)