[BRIDGE]: fix crash in STP
authorStephen Hemminger <shemminger@osdl.org>
Sat, 4 Mar 2006 01:14:51 +0000 (17:14 -0800)
committerDavid S. Miller <davem@sunset.davemloft.net>
Sun, 5 Mar 2006 05:06:19 +0000 (21:06 -0800)
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>
net/bridge/br_if.c

index 7fa3a5a9971f29ecf1ff422f1b29fddae87a4f97..8b38c839d539e68e5c6538fd08f17c9f37caceee 100644 (file)
@@ -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();