📄 bridgestp.c
字号:
else {
STPLOG (("%s:%s ..(dis). \n", __FUNCTION__, bif->ifp->if_xname));
bstp_disable_port(sc, bif);
}
}
bstp_port_state_selection(sc);
bstp_config_bpdu_generation(sc);
bstp_timer_start(&sc->sc_hello_timer, 0);
}
void
bstp_stop(sc)
struct bridge_softc *sc;
{
struct bridge_iflist *bif;
STPLOG ((" %s\n", __FUNCTION__));
LIST_FOREACH(bif, &sc->sc_iflist, next) {
bstp_set_port_state(bif, BSTP_IFSTATE_DISABLED);
bstp_timer_stop(&bif->bif_hold_timer);
bstp_timer_stop(&bif->bif_message_age_timer);
bstp_timer_stop(&bif->bif_forward_delay_timer);
}
#ifdef __ECOS
if (bstp_init_done) {
STPLOG (("##### untimeout ##### loc 1\n"));
untimeout(bstp_tick, sc);
bstp_init_done = 0;
}
#else
if (timeout_initialized(&sc->sc_bstptimeout) &&
timeout_pending(&sc->sc_bstptimeout))
timeout_del(&sc->sc_bstptimeout);
#endif //__ECOS
bstp_timer_stop(&sc->sc_topology_change_timer);
bstp_timer_stop(&sc->sc_tcn_timer);
bstp_timer_stop(&sc->sc_hello_timer);
}
void
bstp_initialize_port(sc, bif)
struct bridge_softc *sc;
struct bridge_iflist *bif;
{
bstp_become_designated_port(sc, bif);
bstp_set_port_state(bif, BSTP_IFSTATE_BLOCKING);
bif->bif_topology_change_acknowledge = 0;
bif->bif_config_pending = 0;
bstp_enable_change_detection(bif);
bstp_timer_stop(&bif->bif_message_age_timer);
bstp_timer_stop(&bif->bif_forward_delay_timer);
bstp_timer_stop(&bif->bif_hold_timer);
}
void
bstp_enable_port(sc, bif)
struct bridge_softc *sc;
struct bridge_iflist *bif;
{
bstp_initialize_port(sc, bif);
bstp_port_state_selection(sc);
}
void
bstp_disable_port(sc, bif)
struct bridge_softc *sc;
struct bridge_iflist *bif;
{
int root;
root = bstp_root_bridge(sc);
bstp_become_designated_port(sc, bif);
bstp_set_port_state(bif, BSTP_IFSTATE_DISABLED);
bif->bif_topology_change_acknowledge = 0;
bif->bif_config_pending = 0;
bstp_timer_stop(&bif->bif_message_age_timer);
bstp_timer_stop(&bif->bif_forward_delay_timer);
bstp_configuration_update(sc);
bridge_rtdelete(sc, bif->ifp, 1);
if (bstp_root_bridge(sc) && (!root)) {
sc->sc_max_age = sc->sc_bridge_max_age;
sc->sc_hello_time = sc->sc_bridge_hello_time;
sc->sc_forward_delay = sc->sc_bridge_forward_delay;
bstp_topology_change_detection(sc);
bstp_timer_stop(&sc->sc_tcn_timer);
bstp_config_bpdu_generation(sc);
bstp_timer_start(&sc->sc_hello_timer, 0);
}
}
void
bstp_set_bridge_priority(sc, new_bridge_id)
struct bridge_softc *sc;
u_int64_t new_bridge_id;
{
int root;
struct bridge_iflist *bif;
root = bstp_root_bridge(sc);
LIST_FOREACH(bif, &sc->sc_iflist, next) {
if (!(bif->bif_flags & IFBIF_STP))
continue;
if (bstp_designated_port(sc, bif))
bif->bif_designated_bridge = new_bridge_id;
}
sc->sc_bridge_id = new_bridge_id;
bstp_configuration_update(sc);
bstp_port_state_selection(sc);
if (bstp_root_bridge(sc) && (!root)) {
sc->sc_max_age = sc->sc_bridge_max_age;
sc->sc_hello_time = sc->sc_bridge_hello_time;
sc->sc_forward_delay = sc->sc_bridge_forward_delay;
bstp_topology_change_detection(sc);
bstp_timer_stop(&sc->sc_tcn_timer);
bstp_config_bpdu_generation(sc);
bstp_timer_start(&sc->sc_hello_timer, 0);
}
}
void
bstp_set_port_priority(sc, bif, new_port_id)
struct bridge_softc *sc;
struct bridge_iflist *bif;
u_int16_t new_port_id;
{
if (bstp_designated_port(sc, bif))
bif->bif_designated_port = new_port_id;
bif->bif_port_id = new_port_id;
if ((sc->sc_bridge_id == bif->bif_designated_bridge) &&
(bif->bif_port_id < bif->bif_designated_port)) {
bstp_become_designated_port(sc, bif);
bstp_port_state_selection(sc);
}
}
void
bstp_set_path_cost(sc, bif, path_cost)
struct bridge_softc *sc;
struct bridge_iflist *bif;
u_int32_t path_cost;
{
bif->bif_path_cost = path_cost;
bstp_configuration_update(sc);
bstp_port_state_selection(sc);
}
void
bstp_enable_change_detection(bif)
struct bridge_iflist *bif;
{
bif->bif_change_detection_enabled = 1;
}
void
bstp_disable_change_detection(bif)
struct bridge_iflist *bif;
{
bif->bif_change_detection_enabled = 0;
}
void
bstp_ifupdstatus(sc, bif)
struct bridge_softc *sc;
struct bridge_iflist *bif;
{
struct ifnet *ifp = bif->ifp;
#ifndef __ECOS
struct ifmediareq ifmr;
#endif
int err = EOPNOTSUPP;
if (ifp->if_flags & IFF_UP) {
#ifndef __ECOS
ifmr.ifm_count = 0;
err = (*ifp->if_ioctl)(ifp, SIOCGIFMEDIA, (caddr_t)&ifmr);
#endif
if (err) {
if (bif->bif_state == BSTP_IFSTATE_DISABLED)
bstp_enable_port(sc, bif);
STPLOG (("<%s:%s> ", bif->ifp->if_xname, stp_port_state(bif->bif_state)));
return;
}
#ifndef __ECOS
if (!(ifmr.ifm_status & IFM_AVALID)) {
if (bif->bif_state == BSTP_IFSTATE_DISABLED)
bstp_enable_port(sc, bif);
return;
}
if (ifmr.ifm_status & IFM_ACTIVE) {
if (bif->bif_state == BSTP_IFSTATE_DISABLED)
bstp_enable_port(sc, bif);
return;
}
#endif
if (bif->bif_state != BSTP_IFSTATE_DISABLED) {
bstp_disable_port(sc, bif);
}
return;
}
if (bif->bif_state != BSTP_IFSTATE_DISABLED)
bstp_disable_port(sc, bif);
}
void
bstp_tick(vsc)
void *vsc;
{
struct bridge_softc *sc = vsc;
struct bridge_iflist *bif;
int s;
s = splnet();
STPLOG (("Port Status: "));
LIST_FOREACH(bif, &sc->sc_iflist, next) {
if (!(bif->bif_flags & IFBIF_STP))
continue;
bstp_ifupdstatus(sc, bif);
}
STPLOG (("\n"));
if (bstp_timer_expired(&sc->sc_hello_timer, sc->sc_hello_time))
bstp_hello_timer_expiry(sc);
if (bstp_timer_expired(&sc->sc_tcn_timer, sc->sc_bridge_hello_time))
bstp_tcn_timer_expiry(sc);
if (bstp_timer_expired(&sc->sc_topology_change_timer,
sc->sc_topology_change_time))
bstp_topology_change_timer_expiry(sc);
LIST_FOREACH(bif, &sc->sc_iflist, next) {
if (!(bif->bif_flags & IFBIF_STP))
continue;
if (bstp_timer_expired(&bif->bif_message_age_timer,
sc->sc_max_age))
bstp_message_age_timer_expiry(sc, bif);
}
LIST_FOREACH(bif, &sc->sc_iflist, next) {
if (!(bif->bif_flags & IFBIF_STP))
continue;
if (bstp_timer_expired(&bif->bif_forward_delay_timer,
sc->sc_forward_delay))
bstp_forward_delay_timer_expiry(sc, bif);
if (bstp_timer_expired(&bif->bif_hold_timer,
sc->sc_hold_time))
bstp_hold_timer_expiry(sc, bif);
}
#ifdef __ECOS
if (sc->sc_if.if_flags & IFF_RUNNING) {
timeout (bstp_tick, sc, hz);
}
#else
if (sc->sc_if.if_flags & IFF_RUNNING)
timeout_add(&sc->sc_bstptimeout, hz);
#endif //__ECOS
splx(s);
}
void
bstp_timer_start(t, v)
struct bridge_timer *t;
u_int16_t v;
{
t->value = v;
t->active = 1;
}
void
bstp_timer_stop(t)
struct bridge_timer *t;
{
t->value = 0;
t->active = 0;
}
int
bstp_timer_expired(t, v)
struct bridge_timer *t;
u_int16_t v;
{
if (!t->active)
return (0);
t->value += BSTP_TICK_VAL;
if (t->value >= v) {
bstp_timer_stop(t);
return (1);
}
return (0);
}
int
bstp_ioctl(ifp, cmd, data)
struct ifnet *ifp;
u_long cmd;
caddr_t data;
{
struct ifbrparam *bp = (struct ifbrparam *)data;
struct bridge_softc *sc = (struct bridge_softc *)ifp;
int r = 0, err = 0;
switch (cmd) {
case SIOCBRDGGPRI:
bp->ifbrp_prio = sc->sc_bridge_priority;
break;
case SIOCBRDGGMA:
bp->ifbrp_maxage = sc->sc_bridge_max_age >> 8;
break;
case SIOCBRDGGHT:
bp->ifbrp_hellotime = sc->sc_bridge_hello_time >> 8;
break;
case SIOCBRDGGFD:
bp->ifbrp_fwddelay = sc->sc_bridge_forward_delay >> 8;
break;
case SIOCBRDGSPRI:
sc->sc_bridge_priority = bp->ifbrp_prio;
r = 1;
break;
case SIOCBRDGSMA:
if (bp->ifbrp_maxage == 0) {
err = EINVAL;
break;
}
sc->sc_bridge_max_age = bp->ifbrp_maxage << 8;
r = 1;
break;
case SIOCBRDGSHT:
if (bp->ifbrp_hellotime == 0) {
err = EINVAL;
break;
}
sc->sc_bridge_hello_time = bp->ifbrp_hellotime << 8;
r = 1;
break;
case SIOCBRDGSFD:
if (bp->ifbrp_fwddelay == 0) {
err = EINVAL;
break;
}
sc->sc_bridge_forward_delay = bp->ifbrp_fwddelay << 8;
r = 1;
break;
case SIOCBRDGSIFCOST:
case SIOCBRDGSIFPRIO:
case SIOCBRDGSIFFLGS:
case SIOCBRDGADD:
case SIOCBRDGDEL:
r = 1;
break;
default:
break;
}
if (r)
bstp_initialization(sc);
return (err);
}
#endif /* NBRIDGE */
#endif /* CYGPKG_NET_BRIDGE_STP_CODE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -