summary refs log tree commit diff
path: root/net/bridge
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2006-03-03 17:14:51 -0800
committerDavid S. Miller <davem@sunset.davemloft.net>2006-03-04 21:06:19 -0800
commit6e86b89084a60355f0e1fb876ca0cfbca62ee85c (patch)
tree076b621fad864de984661a9a15bd526bc068776b /net/bridge
parent501f74f29498543c27f4f9697f5c1e980dd2de0d (diff)
downloadlinux-6e86b89084a60355f0e1fb876ca0cfbca62ee85c.tar.gz
[BRIDGE]: fix crash in STP
Bridge would crash because of uninitailized timer if STP is used and
device was inserted into a bridge before bridge was up. This got
introduced when the delayed port checking was added.  Fix is to not
enable STP on port unless bridge is up.

Bugzilla: http://bugzilla.kernel.org/show_bug.cgi?id=6140
Dup:      http://bugzilla.kernel.org/show_bug.cgi?id=6156

Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge')
-rw-r--r--net/bridge/br_if.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 7fa3a5a9971f..8b38c839d539 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -81,26 +81,27 @@ static void port_carrier_check(void *arg)
 {
 	struct net_device *dev = arg;
 	struct net_bridge_port *p;
+	struct net_bridge *br;
 
 	rtnl_lock();
 	p = dev->br_port;
 	if (!p)
 		goto done;
-
-	if (netif_carrier_ok(p->dev)) {
-		u32 cost = port_cost(p->dev);
-
-		spin_lock_bh(&p->br->lock);
-		if (p->state == BR_STATE_DISABLED) {
-			p->path_cost = cost;
-			br_stp_enable_port(p);
+	br = p->br;
+
+	if (netif_carrier_ok(dev))
+		p->path_cost = port_cost(dev);
+
+	if (br->dev->flags & IFF_UP) {
+		spin_lock_bh(&br->lock);
+		if (netif_carrier_ok(dev)) {
+			if (p->state == BR_STATE_DISABLED)
+				br_stp_enable_port(p);
+		} else {
+			if (p->state != BR_STATE_DISABLED)
+				br_stp_disable_port(p);
 		}
-		spin_unlock_bh(&p->br->lock);
-	} else {
-		spin_lock_bh(&p->br->lock);
-		if (p->state != BR_STATE_DISABLED)
-			br_stp_disable_port(p);
-		spin_unlock_bh(&p->br->lock);
+		spin_unlock_bh(&br->lock);
 	}
 done:
 	rtnl_unlock();