⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bridgestp.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
		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 + -