X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fbridge%2Fbr_stp_if.c;h=d294224592db0455e0bd31d7f04ab6a290abc21e;hb=a2f44b27303a5353859d77a3e96a1d3f33f56ab7;hp=80452970b6d92536cdd63b37ab4eaa23321e0408;hpb=daddc0d38b3571bed170afa273a49a0eba090c1e;p=linux-2.6.git diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index 80452970b..d29422459 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c @@ -15,6 +15,8 @@ #include #include +#include +#include #include "br_private.h" #include "br_private_stp.h" @@ -38,8 +40,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 +49,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 +66,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,17 +75,19 @@ 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 */ void br_stp_enable_port(struct net_bridge_port *p) { br_init_port(p); + br_ifinfo_notify(RTM_NEWLINK, p); br_port_state_selection(p->br); } @@ -97,6 +101,8 @@ void br_stp_disable_port(struct net_bridge_port *p) printk(KERN_INFO "%s: port %i(%s) entering %s state\n", br->dev->name, p->port_no, p->dev->name, "disabled"); + br_ifinfo_notify(RTM_DELLINK, p); + wasroot = br_is_root_bridge(br); br_become_designated_port(p); p->state = BR_STATE_DISABLED; @@ -107,6 +113,8 @@ void br_stp_disable_port(struct net_bridge_port *p) del_timer(&p->forward_delay_timer); del_timer(&p->hold_timer); + br_fdb_delete_by_port(br, p, 0); + br_configuration_update(br); br_port_state_selection(br); @@ -116,8 +124,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 +137,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 +166,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 +219,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]); +}