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

📄 rtrlsa.c

📁 BCAST Implementation for NS2
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *   OSPFD routing daemon *   Copyright (C) 1998 by John T. Moy *    *   This program is free software; you can redistribute it and/or *   modify it under the terms of the GNU General Public License *   as published by the Free Software Foundation; either version 2 *   of the License, or (at your option) any later version. *    *   This program is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   GNU General Public License for more details. *    *   You should have received a copy of the GNU General Public License *   along with this program; if not, write to the Free Software *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *//* Routines dealing with the origination, parsing and unparsing * of router-LSAs. */#include "ospfinc.h"#include "ifcfsm.h"#include "nbrfsm.h"/* Constructor for a router-LSA. */rtrLSA::rtrLSA(SpfArea *a, LShdr *hdr, int blen) : TNode(a, hdr, blen){    rtype = 0;}/* Maximum number of bytes added to a router-LSA by a * single interface. Overloaded when interface type is * point-to-point or point-to-multipoint. */int SpfIfc::rl_size(){    return(sizeof(RtrLink));}// Insert information concerning a virtual link into the// router-LSARtrLink *VLIfc::rl_insert(RTRhdr *rtrhdr, RtrLink *rlp){    SpfNbr *np;    if ((np = if_nlst) && np->adv_as_full()) {	rlp->link_id = hton32(np->id());	rlp->link_data = hton32(if_addr);	rlp->link_type = LT_VL;	rlp->n_tos = 0;	rlp->metric = hton16(if_cost);	if_area->add_to_ifmap(this);	rlp++;	rtrhdr->nlinks++;    }    return(rlp);}/* Insert information concerning a broadcast or NBMA interface * into a router-LSA * if_nfull includes all those neighbors that we * are currently helping through hitless restart. */RtrLink *DRIfc::rl_insert(RTRhdr *rtrhdr, RtrLink *rlp){    if ((if_state == IFS_DR && if_nfull > 0) ||	((if_state == IFS_BACKUP || if_state == IFS_OTHER) &&	 (if_dr_p && if_dr_p->adv_as_full()))) {	rlp->link_id = hton32(if_dr);	rlp->link_data = hton32(if_addr);	rlp->link_type = LT_TNET;	rlp->n_tos = 0;	rlp->metric = hton16(if_cost);	if_area->add_to_ifmap(this);	rlp++;	rtrhdr->nlinks++;    }    else {	rlp->link_id = hton32(if_net);	rlp->link_data = hton32(if_mask);	rlp->link_type = LT_STUB;	rlp->n_tos = 0;	rlp->metric = hton16(if_cost);	if_area->add_to_ifmap(this);	rlp++;	rtrhdr->nlinks++;    }    return(rlp);}// Maximum size added by point-to-point linkint PPIfc::rl_size(){    return(2 * sizeof(RtrLink));}/* How we advertise a point-to-point link's addresses depends * on the interface mask. If set to all ones (0xffffffff) or 0, we * do the traditional thing of advertising the neighbor's * address. If instead the mask is set to something else, we * advertise a route to the entire subnet. */RtrLink *PPIfc::rl_insert(RTRhdr *rtrhdr, RtrLink *rlp){    SpfNbr *np;    if ((np = if_nlst) && np->adv_as_full()) {	PPAdjAggr *adjaggr;	uns16 adv_cost;	adv_cost = if_cost;	adjaggr = (PPAdjAggr *)if_area->AdjAggr.find(np->id(), 0);	if (adjaggr && adjaggr->first_full) {	    if (adjaggr->first_full != this)	        goto adv_stub;	    adv_cost = adjaggr->nbr_cost;	}	rlp->link_id = hton32(np->id());	rlp->link_data = hton32(unnumbered() ? if_IfIndex : if_addr);	rlp->link_type = LT_PP;	rlp->n_tos = 0;	rlp->metric = hton16(adv_cost);	if_area->add_to_ifmap(this);	rlp++;	rtrhdr->nlinks++;    }  adv_stub: // Advertise stub link to neighbor's IP address    if (state() == IFS_PP && !unnumbered() &&	(np || (if_mask != 0xffffffffL && if_mask != 0))) {        if (if_mask != 0xffffffffL && if_mask != 0) {	    rlp->link_id = hton32(if_net);	    rlp->link_data = hton32(if_mask);	}	else {	rlp->link_id = hton32(np->addr());	rlp->link_data = hton32(0xffffffffL);	}	rlp->link_type = LT_STUB;	rlp->n_tos = 0;	rlp->metric = hton16(if_cost);	if_area->add_to_ifmap(this);	rlp++;	rtrhdr->nlinks++;    }    return(rlp);}// Maximum size added by Point-to-MultiPoint interfaceint P2mPIfc::rl_size(){    return((if_nnbrs+1) * sizeof(RtrLink));}RtrLink *P2mPIfc::rl_insert(RTRhdr *rtrhdr, RtrLink *rlp){    NbrIterator iter(this);    SpfNbr *np;    // Add stub link for interface address    rlp->link_id = hton32(if_addr);    rlp->link_data = hton32(0xffffffffL);    rlp->link_type = LT_STUB;    rlp->n_tos = 0;    rlp->metric = hton16(0);    if_area->add_to_ifmap(this);    rlp++;    rtrhdr->nlinks++;    // Then add link for each FULL neighbor    while ((np = iter.get_next())) {	if (!np->adv_as_full())	    continue;	rlp->link_id = hton32(np->id());	rlp->link_data = hton32(if_addr);	rlp->link_type = LT_PP;	rlp->n_tos = 0;	rlp->metric = hton16(if_cost);	if_area->add_to_ifmap(this);	rlp++;	rtrhdr->nlinks++;    }    return(rlp);}/* Build the router-LSAs of all areas at once. This is * done when, for example, our area border router or * ASBR status changes. We laso check whether we now * want to originate default routes into stub areas, * as that logic also needs to be performed when area * border router status changes. */void OSPF::rl_orig(){    AreaIterator iter(this);    SpfArea *ap;    while ((ap = iter.get_next())) {	ap->rl_orig(false);	if (ap->a_stub)	    ap->sl_orig(default_route);    }}/* Build a router LSA. First estimate how big the router-LSA * will be, to verify that we have enough space in the * temporary build area. * * Keep a map of links in our own router-LSA to interfaces (ifmap), * for later use in the Dijkstra calculation. */void SpfArea::rl_orig(int forced){    LSA *olsap;    LShdr *hdr;    RTRhdr *rtrhdr;    int maxlen;    int maxifc;    int length;    SpfIfc *ip;    IfcIterator iiter(this);    seq_t seqno;    RtrLink *rlp;    // If in hitless restart, queue exit check    if (ospf->in_hitless_restart())        ospf->check_htl_termination = true;    // Current LSA in database    olsap = ospf->myLSA(0, this, LST_RTR, ospf->my_id());    // Calculate maximum size for LSA    maxlen = sizeof(LShdr) + sizeof(RTRhdr);    while ((ip = iiter.get_next()))	maxlen += ip->rl_size();    // Add in host records    maxlen += hosts.size() * sizeof(RtrLink);    // If first active area, advertise orphaned hosts    if (this == ospf->first_area) {        AreaIterator aiter(ospf);	SpfArea *ap;	while ((ap = aiter.get_next())) {	    if (ap->n_active_if == 0)	        maxlen += ap->hosts.size() * sizeof(RtrLink);	}    }    // Get sequence number to originate with    seqno = ospf->ospf_get_seqno(LST_RTR, olsap, forced);    if (seqno == InvalidLSSeq)	return;    // Convert bytes to number of links, to make sure    // we have enough room to store interface map    maxifc = maxlen/sizeof(RtrLink);    if (maxifc > sz_ifmap) {	delete [] ifmap;	ifmap = new SpfIfc* [maxifc];	sz_ifmap = maxifc;    }    // Start with empty interface map    n_ifmap = 0;    ifmap_valid = true;    // Build LSA header    hdr = ospf->orig_buffer(maxlen);    hdr->ls_opts = SPO_DC;    if (!a_stub)	hdr->ls_opts |= SPO_EXT;    if (ospf->mospf_enabled())	hdr->ls_opts |= SPO_MC;    hdr->ls_type = LST_RTR;    hdr->ls_id = hton32(ospf->my_id());    hdr->ls_org = hton32(ospf->my_id());    hdr->ls_seqno = (seq_t) hton32((uns32) seqno);    // Router-LSA specific portion    rtrhdr = (RTRhdr *) (hdr+1);    rtrhdr->rtype = 0;    if (ospf->n_area > 1)	rtrhdr->rtype |= RTYPE_B;    if (ospf->n_extImports != 0)	rtrhdr->rtype |= RTYPE_E;    if (n_VLs > 0)	rtrhdr->rtype |= RTYPE_V;    if (ospf->mospf_enabled()) {	if (a_id != 0 && ospf->mc_abr())	    rtrhdr->rtype |= RTYPE_W;	else if (ospf->inter_AS_mc)	    rtrhdr->rtype |= RTYPE_W;    }    rtrhdr->zero = 0;    rtrhdr->nlinks = 0;    // Build body of router-LSA    rlp = (RtrLink *) (rtrhdr+1);    iiter.reset();    while ((ip = iiter.get_next())) {	if (ip->state() == IFS_DOWN)	    continue;	else if (ip->state() == IFS_LOOP) {	    rlp->link_id = hton32(ip->if_addr);	    rlp->link_data = hton32(0xffffffffL);	    rlp->link_type = LT_STUB;	    rlp->n_tos = 0;	    rlp->metric = hton16(ip->cost());	    add_to_ifmap(ip);	    rlp++;	    rtrhdr->nlinks++;	}	else	    rlp = ip->rl_insert(rtrhdr, rlp);    }    // Add area's host routes    if (n_active_if != 0)        rlp = rl_insert_hosts(this, rtrhdr, rlp);    /* If no active interfaces to area, just flush     * LSA. Host addresses will get added to other areas     * automatically.     */    if (rtrhdr->nlinks == 0) {        lsa_flush(olsap);	delete [] ifmap;	ifmap = 0;	sz_ifmap = 0;	ospf->free_orig_buffer(hdr);	return;    }    // If first active area, advertise orphaned hosts    if (this == ospf->first_area) {        AreaIterator aiter(ospf);

⌨️ 快捷键说明

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