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

📄 asexlsa.c

📁 BCAST Implementation for NS2
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (lsap->adv_rtr() == ospf->my_id())	    return(lsap);    }    return(0);}/* Parse an AS-external-LSA. */void ASextLSA::parse(LShdr *hdr){    ASEhdr *ase;    uns32 netno;    uns32 mask;    ase = (ASEhdr *) (hdr + 1);    mask = ntoh32(ase->mask);    netno = ls_id() & mask;    if (!(rte = inrttbl->add(netno, mask))) {	exception = true;	return;    }    if ((ase->tos & ~E_Bit) != 0)	exception = true;    else if (lsa_length != sizeof(LShdr) + sizeof(ASEhdr))	exception = true;    adv_cost = (ase->hibyte << 16) + ntoh16(ase->metric);    if (ase->faddr) {	fwd_addr = fa_tbl->add(ntoh32(ase->faddr));	fwd_addr->resolve();    }    else	fwd_addr = 0;    e_bit = (ase->tos & E_Bit) != 0;    adv_tag = ntoh32(ase->rtag);    // Link into routing table entry    link = rte->ases;    rte->ases = this;    // Should we enter overflow state?    if (rte != default_route && ++(ospf->n_exlsas) == ospf->ExtLsdbLimit)	ospf->EnterOverflowState();}/* Unparse the AS-external-LSA. * Remove from the list in the routing table entry. */void ASextLSA::unparse(){    ASextLSA *ptr;    ASextLSA **prev;    if (!rte)	return;    if (rte != default_route)	ospf->n_exlsas--;    // Unlink from list in routing table    for (prev = &rte->ases; (ptr = *prev); prev = (ASextLSA **)&ptr->link)	if (*prev == this) {	    *prev = (ASextLSA *)link;	    break;	}}/* Enter the overflow state. Flush all locall-originated, * non-default ASEs. If configured, start the timer to exit * overflow state at a later time. */void OSPF::EnterOverflowState(){    if (OverflowState)	return;    // Enter overflow state    OverflowState = true;    // Flush locally-originated LSAs    reoriginate_ASEs();    // Start exit overflow timer    if (ExitOverflowInterval)	oflwtim.start(ExitOverflowInterval*Timer::SECOND);}/* Exit overflow state. Go through the database of local ASE * origination directives, reoriginating all ASEs. * This will also reoriginate the default route, which * is harmless. */void ExitOverflowTimer::action(){    if (ospf->n_exlsas >= ospf->ExtLsdbLimit)	return;    ospf->OverflowState = false;    stop();    // Reoriginate AS-external-LSAs    // by rerunning AS-external routing calculations    ospf->reoriginate_ASEs();}/* Reoriginate all the AS-external-LSAs. This is * performed when the overflow state changes, and * we are forced to withdraw or reinstate our * AS-external-LSAs. */void OSPF::reoriginate_ASEs(){    INrte *rte;    INiterator iter(inrttbl);    while ((rte = iter.nextrte())) {        if (rte->type() == RT_STATIC)	    ase_schedule(rte->exdata);    }}/* Build an AS-external-LSA ready for flooding, from an * internally parsed version. */void ASextLSA::build(LShdr *hdr){    ASEhdr *ase;    ase = (ASEhdr *) (hdr + 1);    ase->mask = hton32(rte->mask());    ase->tos = (e_bit ? E_Bit : 0);    ase->hibyte = adv_cost >> 16;    ase->metric = hton16(adv_cost & 0xffff);    ase->faddr = (fwd_addr ? hton32(fwd_addr->address()) : 0);    ase->rtag = hton32(adv_tag);}/* Recalculate the best path to an ASBR. For the moment, we * always assume that RFC1583Compatibility is set to false. * If there is an intra-area route to the ASBR, choose * the best, preferring non-zero areas and using cost as * tie-breaker. The consider summaries, if either no intra-area * route is found or the intra-area route is on Area 0. * Finally, Area 0 routes may be modified by transit areas. */void ASBRrte::run_calculation(){    RTRrte *abr;    aid_t oa;    byte otype;    bool preferred;    save_state();    oa = area();    otype = r_type;    r_type = RT_NONE;    cost = Infinity;    preferred = false;    // Check for intra-area paths    for (abr = parts; abr; abr = abr->asbr_link) {	SpfArea *ap;	// Is it reachable?	if (abr->type() != RT_SPF)	    continue;	// Is it an ASBR?	// Can't have ASBRs in stub areas	if (!abr->e_bit())	    continue;	if (!(ap = ospf->FindArea(abr->area())))	    continue;	if (ap->is_stub())	    continue;	// Best path so far?	if (preferred && abr->area() == BACKBONE)	    continue;	else if (preferred) {	    if (abr->cost > cost)	        continue;	    if (abr->cost == cost && abr->area() < area())	        continue;	}	// Install new best	update(abr->r_mpath);	cost = abr->cost;	set_area(abr->area());	r_type = RT_SPF;	preferred = (abr->area() != BACKBONE);    }    // Possibly look at summary-LSAs    if (r_type != RT_SPF)	run_inter_area();    // Adjust for virtual links    if (intra_AS() && area() == BACKBONE)	run_transit_areas(summs);    // Failed virtual next hop resolution?    if (intra_AS() && r_mpath == 0)	declare_unreachable();    // If the ASBR has changed, redo type-4 summary-LSAs    if (state_changed() || otype != r_type || oa != area() ||	ospf->exiting_htl_restart) {	ospf->ase_sched = true;	ospf->asbr_orig(this);    }}/* Look through type-4 summary LSAs, to see whether there is * a better inter-area route to the ASBR. * It's assumed that the tie-breakers have already been executed, * and that we can simply compare routes based on cost. */void ASBRrte::run_inter_area(){    asbrLSA *lsap;    SpfArea *summ_ap;    summ_ap = ospf->SummaryArea();    // Go through list of summary-LSAs    for (lsap = summs; lsap; lsap = (asbrLSA *) lsap->link) {	RTRrte	*rtr;	uns32 new_cost;	MPath *newnh;	if (lsap->area() != summ_ap)	    continue;	// Ignore self-originated	if (lsap->adv_rtr() == ospf->my_id())	    continue;	// Check that router is reachable	rtr = (RTRrte *) lsap->source;	if (!rtr || rtr->type() != RT_SPF)	    continue;	// And that a reachable cost is being advertised	if (lsap->adv_cost == LSInfinity)	    continue;	// Compare cost to current best	new_cost = lsap->adv_cost + rtr->cost;	if (cost < new_cost)	    continue;	else if (cost == new_cost)	    newnh = MPath::merge(r_mpath, rtr->r_mpath);	else	    newnh = rtr->r_mpath;	// Install as current best cost	update(newnh);	cost = new_cost;	set_area(rtr->area());	r_type = RT_SPFIA;    }}/* For a given routing table entry, go through all the * ASEs to see whether we should install an external route * in the routing table. * The one case that we don't handle nicely is when one * or our AS-external-LSAs is overwritten by an internal * route -- we just let the AS-external-LSA hang in that * case. This should only generate at most a small extra * number of AS-external-LSAs. * Information on directly attached interfaces not running * OSPF is also considered to be external information, and we * handle this first. */void INrte::run_external(){    bool best_type2;    bool best_preferred;    MPath *best_path;    ASextLSA *lsap;    uns32 best_cost;    uns32 best_t2cost;    uns32 best_tag;    byte new_type;    ExRtData *e;    exdata = 0;    new_type = RT_NONE;    best_tag = 0;    best_type2 = true;    best_path = 0;    best_preferred = false;    best_t2cost = Infinity;    best_cost = Infinity;    // First install any direct or static routes    for (e = exlist; e; e = e->sll_rte) {	uns32 new_cost;	uns32 new_t2cost;	RTE *egress;	bool preferred;	// Valid next hop or outgoing interface?        if ((!e->faddr || !e->faddr->valid()) &&	    !sys->phy_operational(e->phyint))	    continue;	if (e->cost == LSInfinity)	    continue;	// Install direct route?	if (e->direct) {	    if (r_type != RT_DIRECT || r_mpath != e->mpath) {	        r_type = RT_DIRECT;		update(e->mpath);		cost = 0;		sys_install();	    }	    return;	}	// Intra-AS routes take precedence	if (intra_AS())	    continue;	// Better static route?	if (e->faddr && e->faddr->valid()) {	    egress = e->faddr;	    preferred = e->faddr->area() != BACKBONE;	}	else {	    egress = 0;	    preferred = true;	}	if (e->type2) {	    new_t2cost = e->cost;	    new_cost = (egress ? egress->cost : 0);	}	else {	    new_t2cost = Infinity;	    new_cost = e->cost;	    new_cost += (egress ? egress->cost : 0);	}	// Compare against present route	if (!e->type2 && best_type2)	    goto install_static;	else if (e->type2 && !best_type2)	    continue;	else if (new_t2cost < best_t2cost)	    goto install_static;	else if (new_t2cost > best_t2cost)	    continue;	else if (preferred && !best_preferred)	    goto install_static;	else if (!preferred && best_preferred)	    continue;	else if (new_cost < best_cost)	    goto install_static;	else if (new_cost > best_cost)	    continue;	/* Record a better static route	 */      install_static:	best_t2cost = new_t2cost;	best_cost = new_cost;	best_type2 = e->type2;	best_preferred = preferred;	best_tag = e->tag;        new_type = RT_STATIC;	best_path = egress ? egress->r_mpath : e->mpath;	exdata = e;    }    // Get rid of old direct routes    if (r_type == RT_DIRECT) {        declare_unreachable();	sys_install();    }    // Intra-AS routes take precedence    if (intra_AS())	return;    for (lsap = ases; lsap; lsap = (ASextLSA *) lsap->link) {	uns32 new_cost;	uns32 new_t2cost;	RTE *egress;	bool preferred;	// Check LSA's validity	if (!lsap->source->valid())	    continue;	// TODO: Install multicast sources	if (lsap->adv_cost == LSInfinity)	    continue;	// External data accounted for above	if (lsap->adv_rtr() == ospf->my_id())	    continue;	if (lsap->fwd_addr) {	    if (!lsap->fwd_addr->valid())		continue;	    egress = lsap->fwd_addr;	}	else	    egress = lsap->source;	/* Calculate type 1 and type two costs	 */	if (lsap->e_bit != 0) {	    new_t2cost = lsap->adv_cost;	    new_cost = egress->cost;	}	else {	    new_t2cost = Infinity;	    new_cost = lsap->adv_cost + egress->cost;	}	preferred = egress->area() != BACKBONE;	/* Now check to see if we have an equal-cost	 * or better path. Tiebreakers are:	 * 1) type 1 metrics over type 2	 * 2) type 2 cost	 * 3) non-backbone paths	 * 4) type 1 cost	 */	if (new_type == RT_NONE)	    goto install_path;	else if (!lsap->e_bit && best_type2)	    goto install_path;	else if (lsap->e_bit && !best_type2)	    continue;	else if (new_t2cost < best_t2cost)	    goto install_path;	else if (new_t2cost > best_t2cost)	    continue;	else if (preferred && !best_preferred)	    goto install_path;	else if (!preferred && best_preferred)	    continue;	else if (new_cost < best_cost)	    goto install_path;	else if (new_cost > best_cost)	    continue;	else if (new_type == RT_STATIC) {	    if (egress->r_mpath == best_path &&	        lsap->adv_rtr() < ospf->my_id())	        continue;	    else		goto install_path;	}	// Equal-cost logic        else {	    best_path = MPath::merge(best_path, egress->r_mpath);	    continue;	}	/* Record a new better path	 */      install_path:	best_t2cost = new_t2cost;	best_cost = new_cost;	best_type2 = (lsap->e_bit != 0);	best_preferred = preferred;	best_tag = lsap->adv_tag;        new_type = (best_type2 ? RT_EXTT2 : RT_EXTT1);	best_path = egress->r_mpath;	exdata = 0;    }    // Delete or install new path    if (new_type == RT_NONE) {	if (r_type != RT_NONE) {	    declare_unreachable();	    sys_install();	}    }    else if (best_path != r_mpath ||	new_type != r_type ||	best_cost != cost ||	best_t2cost != t2cost ||	     best_tag != tag ||	     ospf->exiting_htl_restart) {	update(best_path);	r_type = new_type;	cost = best_cost;	t2cost = best_t2cost;	tag = best_tag;	sys_install();    }    else if (new_type == RT_STATIC && exdata->forced) {	if (ospf->spflog(LOG_IMPORT, 4))	    ospf->log(this);	ospf->ase_schedule(exdata);    }}

⌨️ 快捷键说明

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