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

📄 spfarea.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 implementing OSPF area support. * Includes adding interfaces to areas, adding area border * routers to areas, and the area constructor and destructor. */#include "ospfinc.h"#include "ifcfsm.h"#include "system.h"#include "nbrfsm.h"/* Constructor for an OSPF area. */SpfArea::SpfArea(aid_t area_no) : a_id(area_no){    a_stub = false;    a_dfcst = 1;    a_import = true;    next = ospf->areas;    ospf->areas = this;    db_xsum = 0;    wo_donotage = 0;    dna_indications = 0;    self_indicating = false;    dna_change = false;    mylsa = 0;    a_ifcs = 0;    n_active_if = 0;    n_routers = 0;    n_VLs = 0;    a_transit = false;    was_transit = false;    ifmap = 0;    ifmap_valid = true;    sz_ifmap = 0;    n_ifmap = 0;    size_mospf_incoming = 0;    mospf_in_phys = 0;    mospf_in_count = 0;    a_helping = 0;    cancel_help_sessions = false;}/* Find an area data structure, given its Area ID. */SpfArea *OSPF::FindArea(aid_t id) const{    SpfArea *a;    for (a = areas; a; a = a->next)	if (a->a_id == id)	    break;    return(a);}/* Find the area whose ID is next greatest. */SpfArea *OSPF::NextArea(aid_t & id) const{    SpfArea *a;    SpfArea *best;    for (a = areas, best = 0; a; a = a->next) {	if (a->a_id <= id)	    continue;	if (!best)	    best = a;	else if (best->a_id > a->a_id)	    best = a;    }    if (best)	id = best->a_id;    return(best);}/* Add or modify a given area. * We don't bother to delete areas, as they are esentially * deleted when they lose all interfaces. * If an area's stub status has changed, then: *  a) the area database must be deleted *  b) all the interfaces to the area must be disabled. * The second action will automatically cause a new * router-LSA to be originated. * It may be that you shouldn't have any AS-externals in * your database anymore either, but these won't be used * in a stub area and will eventually age out. * When "import summaries" status changes, a Dijkstra is * forced in order to cause all summaries to be reexamined. */void OSPF::cfgArea(CfgArea *msg, int status){    SpfArea *ap;    if (!(ap = ospf->FindArea(msg->area_id))) {	ap = new SpfArea(msg->area_id);	if (spflog(CFG_ADD_AREA, 5))	    log(ap);    }    if (status == DELETE_ITEM) {	delete ap;	return;    }    if ((msg->stub != 0) != ap->a_stub) {	ap->a_stub = (msg->stub != 0);	ap->a_dfcst = msg->dflt_cost;	ap->a_import = (msg->import_summs != 0);	ap->reinitialize();    }    else if (msg->stub != 0) {	if ((msg->import_summs != 0) != ap->a_import) {	    ap->a_import = (msg->import_summs != 0);	    ap->a_dfcst = msg->dflt_cost;	    ap->generate_summaries();	}	else if (msg->dflt_cost != ap->a_dfcst) {	    ap->a_dfcst = msg->dflt_cost;	    ap->sl_orig(default_route);	}    }    ap->updated = true;}/* Transfer area parameters */static void area_to_cfg(const SpfArea& sa, struct CfgArea& msg){    msg.area_id = sa.id();    msg.stub = sa.is_stub();    msg.dflt_cost = sa.default_cost();    msg.import_summs = sa.import();}/* Query Area */bool OSPF::qryArea(struct CfgArea& msg, aid_t area_id) const{    SpfArea *ap;    if (!(ap = ospf->FindArea(area_id))) {	return false;    }    area_to_cfg(*ap, msg);    return true;}/* Get all areas */void OSPF::getAreas(std::list<CfgArea>& l) const{    AreaIterator a_iter(ospf);    SpfArea *ap;    while ((ap = a_iter.get_next())) {	    CfgArea msg;	    area_to_cfg(*ap, msg);	    l.push_back(msg);    }}/* Delete an area. */SpfArea::~SpfArea(){    IfcIterator if_iter(this);    AVLsearch abr_iter(&abr_tbl);    AVLsearch aggr_iter(&ranges);    SpfIfc *ip;    RTRrte *abr;    Range *aggr;    SpfArea *ptr;    SpfArea **app;    if (ospf->spflog(CFG_DEL_AREA, 5))	ospf->log(this);    // Delete component interfaces    while ((ip = if_iter.get_next()))	delete ip;    // Delete database    delete_lsdb();    // Remove ABRs    while ((abr = (RTRrte *) abr_iter.next())) {	abr_tbl.remove(abr);	delete abr;    }    // Remove area aggregates    while ((aggr = (Range *) aggr_iter.next())) {	ranges.remove(aggr);	delete aggr;    }    // Delete iterface map    delete [] ifmap;    // Free associated packets    ospf->ospf_freepkt(&a_update);    ospf->ospf_freepkt(&a_demand_upd);    // Delete area from global list    for (app = &ospf->areas; (ptr = *app); app = &ptr->next) {	if (ptr == this) {	    *app = next;	    break;	}    }}/* Area not mentioned explicitly in a reconfig. Delete (virtual * link simulates configuration). */void SpfArea::clear_config(){    delete this;}/* Remove an interface from an area. It is assumed that * the interface is already down, so that we don't have to adjust * the count of active interfaces to the area. */void SpfArea::RemoveIfc(class SpfIfc *ip){    SpfIfc **ipp;    SpfIfc *ptr;    if (ip->state() != IFS_DOWN)	sys->halt(HALT_IFCRM, "Remove operational interface");    for (ipp = &a_ifcs; (ptr = *ipp) != 0; ipp = &ptr->anext) {	if (ip == ptr) {	    *ipp = ptr->anext;	    break;	}    }    // Delete from interface map    ospf->delete_from_ifmap(ip);}/* An interface to the area has gone up or down. Adjust the * count of active interfaces, reoriginating summary-LSAs if * this is the first interface. If this is the last interface, * flush the entire area database. * * Also, recalculate the MTU values used for the area and * globally for OSPF, when flooding packets out all interfaces. */void SpfArea::IfcChange(int increment){    int oldifcs;    SpfIfc *ip;    IfcIterator *iiter;        oldifcs = n_active_if;    n_active_if += increment;    ospf->calc_my_addr();    if (oldifcs == 0)	ospf->n_area++;    else if (n_active_if == 0)	ospf->n_area--;    // Area MTU calculation    // and Global MTU calculation    // and summary area assignment    iiter = new IfcIterator(ospf);    a_mtu = 0xffff;    ospf->ospf_mtu = 0xffff;    ospf->summary_area = 0;    ospf->first_area = 0;    while ((ip = iiter->get_next())) {	if (ip->state() == IFS_DOWN)	    continue;	if (ip->area() == this && ip->if_mtu < a_mtu)	    a_mtu = ip->if_mtu;	if (ip->if_mtu < ospf->ospf_mtu)	    ospf->ospf_mtu = ip->if_mtu;	if (ip->area()->id() == BACKBONE ||	    ospf->n_area == 1)	    ospf->summary_area = ip->area();	if (ip->area()->n_active_if != 0 &&	    ospf->first_area == 0)	    ospf->first_area = ip->area();    }    delete iiter;    if (oldifcs == 0) {	ospf->rl_orig();	generate_summaries();    }    else if (n_active_if == 0) {	ospf->rl_orig();	delete_lsdb();    }}/* Generate all summary-LSAs into a given area. Either the * area has become newly attached, or the import policies * for the area have changed. */void SpfArea::generate_summaries(){    INrte *rte;    INiterator iter(inrttbl);    ASBRrte *rrte;    while ((rte = iter.nextrte())) {	if (rte->intra_AS())	    sl_orig(rte);	else if (rte->is_range())	    sl_orig(rte);    }    // Originate ASBR-summary-LSAs    for (rrte = ospf->ASBRs; rrte; rrte = rrte->next())        asbr_orig(rrte);    // Originate default route into stub areas.    if (a_stub)	sl_orig(default_route);}/* Reinitialize OSPF support in a given area. * Disable all interfaces to the area. * Then flush all the area's LSAs. * Finally, reenable all interfaces that are physically * operational. */void SpfArea::reinitialize(){    SpfIfc *ip;    IfcIterator iter(this);    // Take down interfaces to area    while ((ip = iter.get_next()))	ip->run_fsm(IFE_DOWN);    // Delete entire link-state database    delete_lsdb();    // Bring up interfaces that are physically operational    // This will re-create the area's link-state database    iter.reset();    while ((ip = iter.get_next())) {	if (sys->phy_operational(ip->if_phyint))	    ip->run_fsm(IFE_UP);    }}/* Add and area border router to the area. If * one exists, simply return it. Otherwise, allocate one * and add it to the area class. * * Always add the area border routers to an ASBR entry, even * if the router is NOT and ASBR. */RTRrte *SpfArea::add_abr(uns32 rtrid){    RTRrte *rte;    ASBRrte *asbr;    if ((rte = (RTRrte *) abr_tbl.find(rtrid)))	return(rte);    rte = new RTRrte(rtrid, this);    abr_tbl.add(rte);    // Add to ASBR entry    asbr = ospf->add_asbr(rtrid);    rte->asbr_link = asbr->parts;    asbr->parts = rte;    rte->asbr = asbr;    return(rte);}/* Constructor for the area border router class. */RTRrte::RTRrte(uns32 id, SpfArea *a) : RTE(id, 0)

⌨️ 快捷键说明

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