From dd04013007ce383b62a4aaf22bcfb72924f78bd8 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Sat, 4 Aug 2007 21:09:04 +0000 Subject: - Ensure the path cost does not exceed 65535 in legacy STP mode. - If the path cost is calculated when the link is down, set a pending flag so it is calculated again when it comes back up. - To not use 00:00:00:00:00:00 as the bridge id, all interfaces are scanned and the lowest number wins. All zeros is too low. Approved by: re (rwatson) --- sys/net/bridgestp.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'sys/net/bridgestp.c') diff --git a/sys/net/bridgestp.c b/sys/net/bridgestp.c index 7d3d3c737e7e..dcb258f0d37b 100644 --- a/sys/net/bridgestp.c +++ b/sys/net/bridgestp.c @@ -1331,6 +1331,9 @@ bstp_set_port_proto(struct bstp_port *bp, int proto) bstp_timer_stop(&bp->bp_migrate_delay_timer); /* clear unsupported features */ bp->bp_operedge = 0; + /* STP compat mode only uses 16 bits of the 32 */ + if (bp->bp_path_cost > 65535) + bp->bp_path_cost = 65535; break; case BSTP_PROTO_RSTP: @@ -1617,6 +1620,10 @@ bstp_set_path_cost(struct bstp_port *bp, uint32_t path_cost) if (path_cost > BSTP_MAX_PATH_COST) return (EINVAL); + /* STP compat mode only uses 16 bits of the 32 */ + if (bp->bp_protover == BSTP_PROTO_STP && path_cost > 65535) + path_cost = 65535; + BSTP_LOCK(bs); if (path_cost == 0) { /* use auto */ @@ -1701,6 +1708,12 @@ bstp_calc_path_cost(struct bstp_port *bp) if (bp->bp_flags & BSTP_PORT_ADMCOST) return bp->bp_path_cost; + if (ifp->if_link_state == LINK_STATE_DOWN) { + /* Recalc when the link comes up again */ + bp->bp_flags |= BSTP_PORT_PNDCOST; + return (BSTP_DEFAULT_PATH_COST); + } + if (ifp->if_baudrate < 1000) return (BSTP_DEFAULT_PATH_COST); @@ -1809,6 +1822,12 @@ bstp_ifupdstatus(struct bstp_state *bs, struct bstp_port *bp) ifmr.ifm_active & IFM_FDX ? 1 : 0; } + /* Calc the cost if the link was down previously */ + if (bp->bp_flags & BSTP_PORT_PNDCOST) { + bp->bp_path_cost = bstp_calc_path_cost(bp); + bp->bp_flags &= ~BSTP_PORT_PNDCOST; + } + if (bp->bp_role == BSTP_ROLE_DISABLED) bstp_enable_port(bs, bp); } else { @@ -1999,6 +2018,7 @@ bstp_reinit(struct bstp_state *bs) struct bstp_port *bp; struct ifnet *ifp, *mif; u_char *e_addr; + static const u_char llzero[ETHER_ADDR_LEN]; /* 00:00:00:00:00:00 */ BSTP_LOCK_ASSERT(bs); @@ -2012,14 +2032,16 @@ bstp_reinit(struct bstp_state *bs) * Search through the Ethernet adapters and find the one with the * lowest value. The adapter which we take the MAC address from does * not need to be part of the bridge, it just needs to be a unique - * value. It is not possible for mif to be null, at this point we have - * at least one stp port and hence at least one NIC. + * value. */ IFNET_RLOCK(); TAILQ_FOREACH(ifp, &ifnet, if_link) { if (ifp->if_type != IFT_ETHER) continue; + if (bstp_addr_cmp(IF_LLADDR(ifp), llzero) == 0) + continue; + if (mif == NULL) { mif = ifp; continue; @@ -2031,6 +2053,12 @@ bstp_reinit(struct bstp_state *bs) } IFNET_RUNLOCK(); + /* Can only happen if all interfaces have a zero MAC address */ + if (mif == NULL) { + callout_stop(&bs->bs_bstpcallout); + return; + } + e_addr = IF_LLADDR(mif); bs->bs_bridge_pv.pv_dbridge_id = (((uint64_t)bs->bs_bridge_priority) << 48) | -- cgit v1.2.3