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

📄 bridgestp.c

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	eh.ether_type = htons(sizeof(bpdu));

	bcopy(&eh, m->m_data, sizeof(eh));
	bcopy(&bpdu, m->m_data + sizeof(eh), sizeof(bpdu));

        STPLOG (("        - <%s>: Tx with Port 0x%x; Age %d; Flags %d\n", bif->ifp->if_xname,
                  cu->cu_port_id, cu->cu_message_age, bpdu.cbu_flags));

	IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
	if (error == 0 && (ifp->if_flags & IFF_OACTIVE) == 0)
		(*ifp->if_start)(ifp);
	splx(s);
}

int
bstp_root_bridge(sc)
	struct bridge_softc *sc;
{
	return (sc->sc_designated_root == sc->sc_bridge_id);
}

int
bstp_supersedes_port_info(sc, bif, cu)
	struct bridge_softc *sc;
	struct bridge_iflist *bif;
	struct bstp_config_unit *cu;
{
	if (cu->cu_rootid < bif->bif_designated_root) {
		return (1);
        }
	if (cu->cu_rootid > bif->bif_designated_root) {
		return (0);
        }

	if (cu->cu_root_path_cost < bif->bif_designated_cost) {
		return (1);
        }
	if (cu->cu_root_path_cost > bif->bif_designated_cost) {
		return (0);
        }

	if (cu->cu_bridge_id < bif->bif_designated_bridge) {
		return (1);
        }
	if (cu->cu_bridge_id > bif->bif_designated_bridge) {
		return (0);
        }

	if (sc->sc_bridge_id != cu->cu_bridge_id) {
		return (1);
        }
	if (cu->cu_port_id <= bif->bif_designated_port) {
		return (1); 
        }
	return (0);
}

void
bstp_record_config_information(sc, bif, cu)
	struct bridge_softc *sc;
	struct bridge_iflist *bif;
	struct bstp_config_unit *cu;
{
	bif->bif_designated_root = cu->cu_rootid;
	bif->bif_designated_cost = cu->cu_root_path_cost;
	bif->bif_designated_bridge = cu->cu_bridge_id;
	bif->bif_designated_port = cu->cu_port_id;
	bstp_timer_start(&bif->bif_message_age_timer, cu->cu_message_age);
}

void
bstp_record_config_timeout_values(sc, config)
	struct bridge_softc *sc;
	struct bstp_config_unit *config;
{
	sc->sc_max_age = config->cu_max_age;
	sc->sc_hello_time = config->cu_hello_time;
	sc->sc_forward_delay = config->cu_forward_delay;
	sc->sc_topology_change = config->cu_topology_change;
}

void
bstp_config_bpdu_generation(sc)
	struct bridge_softc *sc;
{
	struct bridge_iflist *bif;

        STPLOG (("STP : Tx Hello BPDU ...\n"));
	LIST_FOREACH(bif, &sc->sc_iflist, next) {
		if (!(bif->bif_flags & IFBIF_STP))
			continue;
		if (bstp_designated_port(sc, bif) &&
		    (bif->bif_state != BSTP_IFSTATE_DISABLED)) {
			bstp_transmit_config(sc, bif);
                } else {
                        STPLOG (("        - <%s>: No Tx\n", bif->ifp->if_xname));
                }
	}
}

int
bstp_designated_port(sc, bif)
	struct bridge_softc *sc;
	struct bridge_iflist *bif;
{
	return ((bif->bif_designated_bridge == sc->sc_bridge_id)
	    && (bif->bif_designated_port == bif->bif_port_id));
}

void
bstp_transmit_tcn(sc)
	struct bridge_softc *sc;
{
	struct bstp_tbpdu bpdu;
	struct bridge_iflist *bif = sc->sc_root_port;
	struct ifnet *ifp = bif->ifp;
	struct arpcom *arp = (struct arpcom *)ifp;
	struct ether_header *eh;
	struct mbuf *m;
	int s, error;

	if ((ifp->if_flags & IFF_RUNNING) == 0)
		return;

	MGETHDR(m, M_DONTWAIT, MT_DATA);
	if (m == NULL)
		return;

        STPLOG (("STP : Tx TCN BPDU on <%s> ...\n", ifp->if_xname));

	m->m_pkthdr.rcvif = ifp;
	m->m_pkthdr.len = sizeof(*eh) + sizeof(bpdu);
	m->m_len = m->m_pkthdr.len;

	eh = mtod(m, struct ether_header *);
	bcopy(arp->ac_enaddr, eh->ether_shost, ETHER_ADDR_LEN);
	bcopy(bstp_etheraddr, eh->ether_dhost, ETHER_ADDR_LEN);
	eh->ether_type = htons(sizeof(bpdu));

	bpdu.tbu_ssap = bpdu.tbu_dsap = LLC_8021D_LSAP;
	bpdu.tbu_ctl = LLC_UI;
	bpdu.tbu_protoid = 0;
	bpdu.tbu_protover = 0;
	bpdu.tbu_bpdutype = BSTP_MSGTYPE_TCN;
	bcopy(&bpdu, m->m_data + sizeof(*eh), sizeof(bpdu));

	s = splimp();
	IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
	if (error == 0 && (ifp->if_flags & IFF_OACTIVE) == 0)
		(*ifp->if_start)(ifp);
	m = NULL;

	splx(s);
	if (m != NULL)
		m_freem(m);
}

void
bstp_configuration_update(sc)
	struct bridge_softc *sc;
{
        STP_OPERATION_LOG (("   %s \n", __FUNCTION__));
	bstp_root_selection(sc);
	bstp_designated_port_selection(sc);
}

void
bstp_root_selection(sc)
	struct bridge_softc *sc;
{
	struct bridge_iflist *root_port = NULL, *bif;

        STP_OPERATION_LOG (("   => Root Port selection ...\n", __FUNCTION__));
	LIST_FOREACH(bif, &sc->sc_iflist, next) {
                STP_OPERATION_LOG (("      - <%s>", bif->ifp->if_xname));
		if (!(bif->bif_flags & IFBIF_STP)) {
                        STP_OPERATION_LOG ((" STP not configured\n"));
			continue;
                }
		if (bstp_designated_port(sc, bif)) {
                        STP_OPERATION_LOG ((" dsgntd port\n"));
			continue;
                }
		if (bif->bif_state == BSTP_IFSTATE_DISABLED) {
                        STP_OPERATION_LOG ((" .. in state DISABLED \n"));
			continue;
                }
		if (bif->bif_designated_root >= sc->sc_bridge_id) {
                        STP_OPERATION_LOG ((" root: ifp dsgntd >= sc\n"));
			continue;
                }
		if (root_port == NULL) {
                        STP_OPERATION_LOG ((" Set as Root Port\n"));
			goto set_port;
                }

		if (bif->bif_designated_root < root_port->bif_designated_root) {
                        STP_OPERATION_LOG ((" ifp dsgntd < root dsgntd; Set as Root Port \n"));
			goto set_port;
                }
		if (bif->bif_designated_root > root_port->bif_designated_root) {
                        STP_OPERATION_LOG ((" root: ifp dsgntd > root dsgntd \n"));
			continue;
                }

		if ((bif->bif_designated_cost + bif->bif_path_cost) <
		    (root_port->bif_designated_cost + root_port->bif_path_cost)) {
                        STP_OPERATION_LOG ((" (dsgntd_cost+path_cost): ifp < root; Set as Root Port \n"));
			goto set_port;
                }
		if ((bif->bif_designated_cost + bif->bif_path_cost) >
		    (root_port->bif_designated_cost + root_port->bif_path_cost)) {
                        STP_OPERATION_LOG ((" (dsgntd_cost+path_cost): ifp > root \n"));
			continue;
                }

		if (bif->bif_designated_bridge < root_port->bif_designated_bridge) {
                        STP_OPERATION_LOG ((" bridge: ifp dsgntd < root dsgntd; Set as Root Port \n"));
			goto set_port;
                }
		if (bif->bif_designated_bridge > root_port->bif_designated_bridge) {
                        STP_OPERATION_LOG ((" bridge: ifp dsgntd > root dsgntd \n"));
			continue;
                }

		if (bif->bif_designated_port < root_port->bif_designated_port) {
                        STP_OPERATION_LOG ((" port: ifp dsgntd (%d) < root dsgntd (%d); Set as Root Port\n",
                                 bif->bif_designated_port, root_port->bif_designated_port));
			goto set_port;
                }
		if (bif->bif_designated_port > root_port->bif_designated_port) {
                        STP_OPERATION_LOG ((" port: ifp dsgntd (%d) > root dsgntd (%d)\n",
                                 bif->bif_designated_port, root_port->bif_designated_port));
			continue;
                }

		if (bif->bif_port_id >= root_port->bif_port_id) {
                        STP_OPERATION_LOG ((" ifp port_id (%d) >= root port_id (%d) 8 \n",
                                 bif->bif_port_id, root_port->bif_port_id));
			continue;
                }
set_port:
		root_port = bif;
	}

	sc->sc_root_port = root_port;
	if (root_port == NULL) {
		sc->sc_designated_root = sc->sc_bridge_id;
		sc->sc_root_path_cost = 0;
                STPLOG (("      Root Port : <SELF ROOT>, Path Cost : 0\n"));
	} else {
		sc->sc_designated_root = root_port->bif_designated_root;
		sc->sc_root_path_cost = root_port->bif_designated_cost +
		    root_port->bif_path_cost;
                STPLOG (("      Root Port : <%s>, Path Cost : 0\n", 
                          root_port->ifp->if_xname, sc->sc_root_path_cost));
	}
}

void
bstp_designated_port_selection(sc)
	struct bridge_softc *sc;
{
	struct bridge_iflist *bif;

        STP_OPERATION_LOG (("   => Designated Port selection ...\n"));
	LIST_FOREACH(bif, &sc->sc_iflist, next) {
		if (!(bif->bif_flags & IFBIF_STP))
			continue;
		if (bstp_designated_port(sc, bif)) {
                        STPLOG (("      - <%s>: already designated \n", bif->ifp->if_xname));
			goto designated;
                }
		if (bif->bif_designated_root != sc->sc_designated_root) {
                        STPLOG (("      - <%s>: becomes designated\n", bif->ifp->if_xname));
			goto designated;
                }

                /* 
                 * PLC network is special, we cannot go as per standards because of
                 * our network topology and behavior
                 *
		if (sc->sc_root_path_cost < bif->bif_designated_cost) {
                        STPLOG (("        - <%s>: becomes designated path cost (1)\n", bif->ifp->if_xname));
			goto designated;
                }
		if (sc->sc_root_path_cost > bif->bif_designated_cost) {
                        STPLOG (("        - <%s>: Cannot be designated; Root cost (%d) > Desig cost (%d) \n", 
                                 bif->ifp->if_xname, sc->sc_root_path_cost, bif->bif_designated_cost));
			continue;
                }
                */

		if (sc->sc_bridge_id < bif->bif_designated_bridge) {
                        STPLOG (("      - <%s>: becomes dsgntd (self-brdgid < dsgntd-brdgid); \n", bif->ifp->if_xname));
			goto designated;
                }
		if (sc->sc_bridge_id > bif->bif_designated_bridge) {
                        STPLOG (("      - <%s>: Cannot be dsgntd (self-brdgid > dsgntd-brdgid); \n", bif->ifp->if_xname));
			continue;
                }

		if (bif->bif_port_id > bif->bif_designated_port) {
                        STPLOG (("      - <%s>: Cannot be dsgntd (self-portid > bsgntd-portid); \n", bif->ifp->if_xname));
			continue;
                }

                /* 
                 * PLC network is special, we cannot go as per standards because of
                 * our network topology and behavior
                 */
		if (sc->sc_root_path_cost < bif->bif_designated_cost) {
                        STPLOG (("      - <%s>: becomes dsgntd path cost (1)\n", bif->ifp->if_xname));
			goto designated;
                }
		if (sc->sc_root_path_cost > bif->bif_designated_cost) {
                        STPLOG (("      - <%s>: Cannot be dsgntd; Root cost (%d) > Desig cost (%d) \n", 
                                 bif->ifp->if_xname, sc->sc_root_path_cost, bif->bif_designated_cost));
			continue;
                }
designated:
		bstp_become_designated_port(sc, bif);
	}
}

void
bstp_become_designated_port(sc, bif)
	struct bridge_softc *sc;
	struct bridge_iflist *bif;
{
	bif->bif_designated_root = sc->sc_designated_root;
	bif->bif_designated_cost = sc->sc_root_path_cost;
	bif->bif_designated_bridge = sc->sc_bridge_id;
	bif->bif_designated_port = bif->bif_port_id;

        STP_OPERATION_LOG (("               => %s values (cost:%d, port:0x%x)\n", 
                            __FUNCTION__, bif->ifp->if_xname, bif->bif_designated_cost, bif->bif_designated_port));
        //STP_OPERATION_LOG (("(cost:%d, port:0x%x)\n", bif->bif_designated_cost, bif->bif_designated_port));
}

void
bstp_port_state_selection(sc)
	struct bridge_softc *sc;
{
	struct bridge_iflist *bif;

	LIST_FOREACH(bif, &sc->sc_iflist, next) {
		if (!(bif->bif_flags & IFBIF_STP))
			continue;
		if (bif == sc->sc_root_port) {
			bif->bif_config_pending = 0;
			bif->bif_topology_change_acknowledge = 0;
			bstp_make_forwarding(sc, bif);
		} else if (bstp_designated_port(sc, bif)) {
			bstp_timer_stop(&bif->bif_message_age_timer);
			bstp_make_forwarding(sc, bif);
		} else {
			bif->bif_config_pending = 0;
			bif->bif_topology_change_acknowledge = 0;
			bstp_make_blocking(sc, bif);
		}
	}
}

void
bstp_make_forwarding(sc, bif)
	struct bridge_softc *sc;
	struct bridge_iflist *bif;
{
	if (bif->bif_state == BSTP_IFSTATE_BLOCKING) {
		bstp_set_port_state(bif, BSTP_IFSTATE_LISTENING);
		bstp_timer_start(&bif->bif_forward_delay_timer, 0);
	}
}

void
bstp_make_blocking(sc, bif)
	struct bridge_softc *sc;
	struct bridge_iflist *bif;
{
	if ((bif->bif_state != BSTP_IFSTATE_DISABLED) &&
	    (bif->bif_state != BSTP_IFSTATE_BLOCKING)) {
		if ((bif->bif_state == BSTP_IFSTATE_FORWARDING) ||
		    (bif->bif_state == BSTP_IFSTATE_LEARNING)) {
			if (bif->bif_change_detection_enabled) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -