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

📄 rtrlsa.c

📁 BCAST Implementation for NS2
💻 C
📖 第 1 页 / 共 2 页
字号:
	SpfArea *ap;	while ((ap = aiter.get_next())) {	    if (ap->n_active_if == 0)	        rlp = ap->rl_insert_hosts(this, rtrhdr, rlp);	}    }    // Finish (re)origination    length = ((byte *) rlp) - ((byte *) hdr);    hdr->ls_length = hton16(length);    rtrhdr->nlinks = hton16(rtrhdr->nlinks);    /* If we can't originate for some reason, we will need     * to delete the interface map so that the routing     * calculation won't get confused during initialization.     * This situation only occurs during hitless restart.     */    if (ospf->lsa_reorig(0, this, olsap, hdr, forced) == 0 &&	olsap &&	ospf->in_hitless_restart()) {        LShdr *dbcopy;	int size;	RTRhdr *rhdr;		RTRhdr *dbrhdr;	rhdr = (RTRhdr *)(hdr + 1);	dbcopy = ospf->BuildLSA(olsap);	dbrhdr = (RTRhdr *)(dbcopy + 1);	// Compare body of advertisements	size = olsap->lsa_length - sizeof(LShdr) - sizeof(RTRhdr);	if (hdr->ls_length != dbcopy->ls_length ||	    memcmp((rhdr + 1), (dbrhdr + 1), size) != 0) {	    delete [] ifmap;	    ifmap = 0;	    sz_ifmap = 0;	}	else	    ospf->full_sched = true;    }    ospf->free_orig_buffer(hdr);}/* Add an area's configured hosts to a router-LSA. */RtrLink *SpfArea::rl_insert_hosts(SpfArea *home, RTRhdr *rtrhdr, RtrLink *rlp){    AVLsearch h_iter(&hosts);	    HostAddr *hp;    // Add a stub link for each host record in the area    while ((hp = (HostAddr *)h_iter.next())) {	rlp->link_id = hton32(hp->r_rte->net());	rlp->link_data = hton32(hp->r_rte->mask());	rlp->link_type = LT_STUB;	rlp->n_tos = 0;	rlp->metric = hton16(hp->r_cost);	home->add_to_ifmap(hp->ip);	rlp++;	rtrhdr->nlinks++;    }    return(rlp);}/* Add to the interface map, so that next hops can be easily * calculated during Dijkstra. */void SpfArea::add_to_ifmap(SpfIfc *ip){    ifmap[n_ifmap++] = ip;}/* When an interface is deleted, it must be removed * from the interface map - it may be up to 5 seconds * before the router-LSA is updated and the interface * map along with it. */void OSPF::delete_from_ifmap(SpfIfc *ip){    AreaIterator iter(this);    SpfArea *ap;    while ((ap = iter.get_next())) {	int i;	for (i= 0; i < ap->n_ifmap; i++)            if (ap->ifmap[i] == ip) {	        ap->ifmap[i] = 0;		ap->ifmap_valid = false;	    }    }}/* Reoriginate a router-LSA. Force a router-LSA to be * rebuilt for the given area. */void rtrLSA::reoriginate(int forced){    lsa_ap->rl_orig(forced);}/* Parse a received router-LSA. * Can be called repeatedly without an intervening unparse, * which is why we don't check the parsed bit. */void rtrLSA::parse(LShdr *hdr){    RTRhdr  *rhdr;    RtrLink *rtlp;    Link *lp;    Link **lpp;    byte *end;    int i;    Link *nextl;    TOSmetric *mp;        rhdr = (RTRhdr *) (hdr+1);    rtlp = (RtrLink *) (rhdr+1);    n_links = ntoh16(rhdr->nlinks);    end = ((byte *) hdr) + ntoh16(hdr->ls_length);    rtype = rhdr->rtype;    t_dest = lsa_ap->add_abr(ls_id());    // Virtual link address calculation might change    t_dest->changed = true;    if (rhdr->zero != 0)	exception = true;    lpp = &t_links;    for (i = 0; i < n_links; i++) {	if (((byte *) rtlp) > end) {	    exception = true;	    break;	}	// (re)allocate link. if necessary	if ((!(lp = *lpp)) || lp->l_ltype != rtlp->link_type) {	    Link *nextl;	    nextl = lp;	    if (rtlp->link_type == LT_STUB)		lp = new SLink;	    else		lp = new TLink;	    // Link into list	    *lpp = lp;	    lp->l_next = nextl;	}	// Fill in link parameters	lp->l_ltype = rtlp->link_type;	lp->l_id = ntoh32(rtlp->link_id);	lp->l_fwdcst = ntoh16(rtlp->metric);	lp->l_data = ntoh32(rtlp->link_data);	switch (rtlp->link_type) {	    INrte *srte;	    TLink *tlp;	  case LT_STUB:	    srte = inrttbl->add(lp->l_id, lp->l_data);	    ((SLink *) lp)->sl_rte = srte;	    break;	  case LT_PP:	  case LT_TNET:	  case LT_VL:	    tlp = (TLink *) lp;	    tlp->tl_nbr = 0;	    tlp->tl_rvcst = MAX_COST;	    // Link into database	    tlp_link(tlp);	    break;	  default:	    break;	}	// If TOS metrics, must keep unparsed form	if (rtlp->n_tos)	    exception = true;	// Advance link pointer	lpp = &lp->l_next;	// Step over non-zero TOS metrics	mp = (TOSmetric *)(rtlp+1);	mp += rtlp->n_tos;	rtlp = (RtrLink *)mp;    }    // Need to keep LSA, or rebuild from parsed copy?    if (((byte *) rtlp) != end)	exception = true;    // Clean up unused transit links    lp = *lpp;    // Null terminate list    *lpp = 0;    for (; lp; lp = nextl) {	nextl = lp->l_next;	delete lp;    }}/* Link a transit link into the link-state database by setting * pointers to and from neighboring LSAs. */void TNode::tlp_link(TLink *tlp){    TNode *nbr;    uns32 nbr_id;    Link *nlp;    nbr_id = tlp->l_id;    if (tlp->l_ltype == LT_TNET) {	nbr = (TNode *) lsa_ap->netLSAs.previous(nbr_id+1);	if (nbr == 0 || nbr->ls_id() != nbr_id)	    return;    }    else if (!(nbr = (TNode *) lsa_ap->rtrLSAs.find(nbr_id, nbr_id)))	return;    // Neighbor must be parsed also    if (!nbr->parsed)	return;    // Virtual link address calculation might change    if (nbr->ls_type() == LST_RTR)        nbr->t_dest->changed = true;    // Check for bidirectionality    for (nlp = nbr->t_links; nlp; nlp = nlp->l_next) {	TLink *ntlp;	if (nlp->l_ltype == LT_STUB)	    continue;	if (nlp->l_id != ls_id())	    continue;	if (nlp->l_ltype == LT_TNET && lsa_type != LST_NET)	    continue;	if (nlp->l_ltype != LT_TNET && lsa_type == LST_NET)	    continue;	// Fill in link pointers	ntlp = (TLink *) nlp;	tlp->tl_nbr = nbr;	ntlp->tl_nbr = this;	if (ntlp->l_fwdcst < tlp->tl_rvcst)	    tlp->tl_rvcst = ntlp->l_fwdcst;	if (tlp->l_fwdcst < ntlp->tl_rvcst)	    ntlp->tl_rvcst = tlp->l_fwdcst;    }}/* Unparse a router-LSA. Simply unlink it from its neighbors * in the link-state database. */void rtrLSA::unparse(){    unlink();}/* Unlink a transit node (router or network-LSA) from its * neighbors. */void TNode::unlink(){    Link *lp;    for (lp = t_links; lp; lp = lp->l_next) {	TLink *tlp;	TNode *nbr;	Link *nlp;	if (lp->l_ltype == LT_STUB)	    continue;	tlp = (TLink *) lp;	// Reset neighbor pointers	if (!(nbr = tlp->tl_nbr))	    continue;	// Virtual link address calculation might change	if (nbr->ls_type() == LST_RTR)	    nbr->t_dest->changed = true;	for (nlp = nbr->t_links; nlp; nlp = nlp->l_next) {	    TLink *ntlp;	    if (nlp->l_ltype == LT_STUB)		continue;	    ntlp = (TLink *) nlp;	    if (ntlp->l_id != ls_id())		continue;	    if (ntlp->l_ltype == LT_TNET && lsa_type != LST_NET)		continue;	    if (ntlp->l_ltype != LT_TNET && lsa_type == LST_NET)		continue;	    // Reset neighbor pointer	    ntlp->tl_nbr = 0;	    ntlp->tl_rvcst = MAX_COST;	}	// Reset own pointer	tlp->tl_nbr = 0;    }}/* Destructor for transit nodes. Must return all the transit * and stub links to the heap. */TNode::~TNode(){    Link *lp;    Link *nextl;    for (lp = t_links; lp; lp = nextl) {	nextl = lp->l_next;	delete lp;    }}/* Build a router-LSA in network format, based on the internal * parsed version. Only called if "exception" not set, meaning that * there was nothing unusual about the router-LSA. * Link state header, including length, has already been filled * in by the caller. */void rtrLSA::build(LShdr *hdr){    RTRhdr *rtrhdr;    RtrLink *rtrlink;    Link *lp;        rtrhdr = (RTRhdr *) (hdr + 1);    // Fill router type    rtrhdr->rtype = rtype;    rtrhdr->zero = 0;    rtrhdr->nlinks = hton16(n_links);    // Fill in links    rtrlink = (RtrLink *) (rtrhdr + 1);    for (lp = t_links; lp; lp = lp->l_next, rtrlink++) {	rtrlink->link_id = hton32(lp->l_id);;	rtrlink->link_data = hton32(lp->l_data);	rtrlink->link_type = lp->l_ltype;	rtrlink->n_tos = 0;	rtrlink->metric = hton16(lp->l_fwdcst);    }}

⌨️ 快捷键说明

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