Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / net / bridge / br_stp_if.c
index 8045297..23dea14 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <linux/kernel.h>
 #include <linux/smp_lock.h>
+#include <linux/etherdevice.h>
 
 #include "br_private.h"
 #include "br_private_stp.h"
@@ -38,8 +39,6 @@ void br_init_port(struct net_bridge_port *p)
        p->state = BR_STATE_BLOCKING;
        p->topology_change_ack = 0;
        p->config_pending = 0;
-
-       br_stp_port_timer_init(p);
 }
 
 /* called under bridge lock */
@@ -49,10 +48,12 @@ void br_stp_enable_bridge(struct net_bridge *br)
 
        spin_lock_bh(&br->lock);
        mod_timer(&br->hello_timer, jiffies + br->hello_time);
+       mod_timer(&br->gc_timer, jiffies + HZ/10);
+       
        br_config_bpdu_generation(br);
 
        list_for_each_entry(p, &br->port_list, list) {
-               if (p->dev->flags & IFF_UP)
+               if ((p->dev->flags & IFF_UP) && netif_carrier_ok(p->dev))
                        br_stp_enable_port(p);
 
        }
@@ -64,7 +65,7 @@ void br_stp_disable_bridge(struct net_bridge *br)
 {
        struct net_bridge_port *p;
 
-       spin_lock(&br->lock);
+       spin_lock_bh(&br->lock);
        list_for_each_entry(p, &br->port_list, list) {
                if (p->state != BR_STATE_DISABLED)
                        br_stp_disable_port(p);
@@ -73,11 +74,12 @@ void br_stp_disable_bridge(struct net_bridge *br)
 
        br->topology_change = 0;
        br->topology_change_detected = 0;
-       spin_unlock(&br->lock);
+       spin_unlock_bh(&br->lock);
 
        del_timer_sync(&br->hello_timer);
        del_timer_sync(&br->topology_change_timer);
        del_timer_sync(&br->tcn_timer);
+       del_timer_sync(&br->gc_timer);
 }
 
 /* called under bridge lock */
@@ -116,8 +118,7 @@ void br_stp_disable_port(struct net_bridge_port *p)
 }
 
 /* called under bridge lock */
-static void br_stp_change_bridge_id(struct net_bridge *br, 
-                                   const unsigned char *addr)
+void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *addr)
 {
        unsigned char oldaddr[6];
        struct net_bridge_port *p;
@@ -130,10 +131,10 @@ static void br_stp_change_bridge_id(struct net_bridge *br,
        memcpy(br->dev->dev_addr, addr, ETH_ALEN);
 
        list_for_each_entry(p, &br->port_list, list) {
-               if (!memcmp(p->designated_bridge.addr, oldaddr, ETH_ALEN))
+               if (!compare_ether_addr(p->designated_bridge.addr, oldaddr))
                        memcpy(p->designated_bridge.addr, addr, ETH_ALEN);
 
-               if (!memcmp(p->designated_root.addr, oldaddr, ETH_ALEN))
+               if (!compare_ether_addr(p->designated_root.addr, oldaddr))
                        memcpy(p->designated_root.addr, addr, ETH_ALEN);
 
        }
@@ -159,7 +160,7 @@ void br_stp_recalculate_bridge_id(struct net_bridge *br)
 
        }
 
-       if (memcmp(br->bridge_id.addr, addr, ETH_ALEN))
+       if (compare_ether_addr(br->bridge_id.addr, addr))
                br_stp_change_bridge_id(br, addr);
 }
 
@@ -212,3 +213,11 @@ void br_stp_set_path_cost(struct net_bridge_port *p, u32 path_cost)
        br_configuration_update(p->br);
        br_port_state_selection(p->br);
 }
+
+ssize_t br_show_bridge_id(char *buf, const struct bridge_id *id)
+{
+       return sprintf(buf, "%.2x%.2x.%.2x%.2x%.2x%.2x%.2x%.2x\n",
+              id->prio[0], id->prio[1],
+              id->addr[0], id->addr[1], id->addr[2],
+              id->addr[3], id->addr[4], id->addr[5]);
+}