📄 rtrlsa.c
字号:
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 + -