diff options
author | thompsa <thompsa@FreeBSD.org> | 2006-03-06 02:28:41 +0000 |
---|---|---|
committer | thompsa <thompsa@FreeBSD.org> | 2006-03-06 02:28:41 +0000 |
commit | 19a0cafcc290a57585d88743e0216bf03d4cb9fb (patch) | |
tree | 58473077b11a316258be2903930f133daee44176 | |
parent | b5d256606ebd454262b0eac9a22b6bb73049325b (diff) | |
download | FreeBSD-src-19a0cafcc290a57585d88743e0216bf03d4cb9fb.zip FreeBSD-src-19a0cafcc290a57585d88743e0216bf03d4cb9fb.tar.gz |
If we miss the LINK_UP event from the network interface then the bridge port
will remain in the disabled state until another link event happens in the
future (if at all). Add a timer to periodically check the interface state and
recover.
Reported by: Nik Lam <freebsdnik j2d.lam.net.au>
MFC after: 3 days
-rw-r--r-- | sys/net/bridgestp.c | 23 | ||||
-rw-r--r-- | sys/net/if_bridgevar.h | 1 |
2 files changed, 11 insertions, 13 deletions
diff --git a/sys/net/bridgestp.c b/sys/net/bridgestp.c index 2dc2028..251a730 100644 --- a/sys/net/bridgestp.c +++ b/sys/net/bridgestp.c @@ -75,6 +75,7 @@ __FBSDID("$FreeBSD$"); #define BSTP_MESSAGE_AGE_INCR (1 * 256) /* in 256ths of a second */ #define BSTP_TICK_VAL (1 * 256) /* in 256ths of a second */ +#define BSTP_LINK_TIMER (BSTP_TICK_VAL * 15) /* * Because BPDU's do not make nicely aligned structures, two different @@ -916,6 +917,7 @@ bstp_initialization(struct bridge_softc *sc) bstp_port_state_selection(sc); bstp_config_bpdu_generation(sc); bstp_timer_start(&sc->sc_hello_timer, 0); + bstp_timer_start(&sc->sc_link_timer, 0); } void @@ -1121,20 +1123,15 @@ bstp_tick(void *arg) BRIDGE_LOCK_ASSERT(sc); -#if 0 - LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { - if ((bif->bif_flags & IFBIF_STP) == 0) - continue; - /* - * XXX This can cause a lag in "link does away" - * XXX and "spanning tree gets updated". We need - * XXX come sort of callback from the link state - * XXX update code to kick spanning tree. - * XXX --thorpej@NetBSD.org - */ - bstp_ifupdstatus(sc, bif); + /* slow timer to catch missed link events */ + if (bstp_timer_expired(&sc->sc_link_timer, BSTP_LINK_TIMER)) { + LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { + if ((bif->bif_flags & IFBIF_STP) == 0) + continue; + bstp_ifupdstatus(sc, bif); + } + bstp_timer_start(&sc->sc_link_timer, 0); } -#endif if (bstp_timer_expired(&sc->sc_hello_timer, sc->sc_hello_time)) bstp_hello_timer_expiry(sc); diff --git a/sys/net/if_bridgevar.h b/sys/net/if_bridgevar.h index c512880..4ac7307 100644 --- a/sys/net/if_bridgevar.h +++ b/sys/net/if_bridgevar.h @@ -301,6 +301,7 @@ struct bridge_softc { LIST_HEAD(, bridge_rtnode) sc_rtlist; /* list version of above */ uint32_t sc_rthash_key; /* key for hash */ LIST_HEAD(, bridge_iflist) sc_spanlist; /* span ports list */ + struct bridge_timer sc_link_timer; }; #define BRIDGE_LOCK_INIT(_sc) do { \ |