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

📄 spfnbr.c

📁 BCAST Implementation for NS2
💻 C
字号:
/* *   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 basic OSPF neighbor operations. * Most of the OSPF neighbor manipulation is in * nbrfsm.h. */#include "ospfinc.h"#include "ifcfsm.h"#include "nbrfsm.h"#include "system.h"/* Constructor for an OSPF neighbor. */SpfNbr::SpfNbr(SpfIfc *ip, rtid_t _id, InAddr _addr): n_acttim(this), n_htim(this), n_holdtim(this),  n_ddrxtim(this), n_rqrxtim(this), n_lsarxtim(this),  n_progtim(this), n_helptim(this)    {    n_ifp = ip;    n_id = _id;    n_addr = _addr;    n_state = NBS_DOWN;    md5_seqno = 0;    n_adj_pend = false;    n_rmt_init = false;    n_next_pend = 0;    rxmt_count = 0;    n_rxmt_window = 1;    rq_goal = 0;    n_dr = 0;    n_bdr = 0;    database_sent = false;    rq_suppression = false;    hellos_suppressed = false;    // Link into interface's list of neighbors    next = ip->if_nlst;    ip->if_nlst = this;    ip->if_nnbrs++;}/* Configure a neighbor over a non-broadcast network. * Have to handle the case where a dynamically discovered * neighbor is now configured statically. */void OSPF::cfgNbr(CfgNbr *m, int status){    SpfIfc *ip;    SpfNbr *nbr;    StaticNbr *statnbr;    if (!(ip = find_nbr_ifc(m->nbr_addr)))	return;    if (ip->type() != IFT_NBMA && ip->type() != IFT_P2MP)	return;    // Search for neighbor    NbrIterator niter(ip);    while ((nbr = niter.get_next())) {	if (nbr->addr() == m->nbr_addr)	    break;    }    // If delete, free to heap    if (status == DELETE_ITEM) {	if (nbr && nbr->configured())	    ((StaticNbr *)nbr)->active = false;	nbr->nbr_fsm(NBE_DESTROY);	ospf->delete_down_neighbors();	return;    }    // Add or modify nbr    // If neighbor exists, but not configured, reallocate    if (nbr && !nbr->configured()) {	nbr->nbr_fsm(NBE_DESTROY);	ospf->delete_down_neighbors();	nbr = 0;    }    // If new, allocate and link into list of neighbors    if (!nbr)	statnbr = new StaticNbr(ip, m->nbr_addr);    else	statnbr = (StaticNbr *) nbr;    // Copy in new data    statnbr->_dr_eligible = m->dr_eligible;    // Start sending hellos, if we are DR or BDR    // or if both we and it are DR eligible    if (ip->state() != IFS_DOWN)	statnbr->nbr_fsm(NBE_EVAL);    statnbr->updated = true;}static inline void nbr_to_cfg(const SpfNbr& nbr, struct CfgNbr& msg){    msg.nbr_addr = nbr.addr();    msg.dr_eligible = nbr.dr_eligible();}/* Get Neighbor information. */bool OSPF::qryNbr(struct CfgNbr& msg, InAddr nbr_address) const{    SpfIfc *ip = find_nbr_ifc(nbr_address);    if (ip == 0 || (ip->type() != IFT_NBMA && ip->type() != IFT_P2MP))	return false;    SpfNbr *nbr;    NbrIterator niter(ip);    while ((nbr = niter.get_next())) {	if (nbr->addr() == nbr_address) {	    nbr_to_cfg(*nbr, msg);	    return true;	}    }    return false;}/* Get all neighbor information. */void OSPF::getNbrs(std::list<CfgNbr>& l) const{    IfcIterator iter(this);    SpfIfc *ip;    while ((ip = iter.get_next())) {	if (ip->type() != IFT_NBMA && ip->type() != IFT_P2MP)	    continue;	for (SpfNbr *nbr = ip->if_nlst; nbr != 0; nbr = nbr->next) {	    CfgNbr msg;	    nbr_to_cfg(*nbr, msg);	    l.push_back(msg);	}    }} /* Destructor for a neighbor. Make sure it's state is down, which * will free all the necessary memory, etc. */SpfNbr::~SpfNbr(){    nbr_fsm(NBE_DESTROY);}/* Is the neighbor staticly configured? */bool SpfNbr::configured(){    return(false);}bool StaticNbr::configured(){    return(active);}/* Is the neighbor eligible to become the * Designated Router? */bool SpfNbr::dr_eligible() const{    return(n_pri != 0);}bool StaticNbr::dr_eligible() const{    if (n_state >= NBS_INIT)	return(n_pri != 0);    return(_dr_eligible);}/* Go through the collection of neighbors, dealing those * that are in down state and have been learned dynamically. */void OSPF::delete_down_neighbors(){    IfcIterator iiter(ospf);    SpfIfc *ip;    SpfNbr *np;    SpfNbr **prev;    if (!delete_neighbors)	return;    delete_neighbors = false;    while ((ip = iiter.get_next())) {	prev = &ip->if_nlst;	while ((np = *prev)) {	    if (np->n_state == NBS_DOWN &&		!np->configured() &&		!np->we_are_helping()) {		*prev = np->next;		delete np;		ip->if_nnbrs--;	    }	    else		prev = &np->next;	}    }}/* If a neighbor has not been mentioned on a reconfig, * delete it. */void StaticNbr::clear_config(){    active = false;    nbr_fsm(NBE_DESTROY);    ospf->delete_down_neighbors();}/* Functions that unicast OSPF packets out the given interface * types. In other words, the packets are sent directly to the * neighbor. * Multicast packets are handled by SpfIfc::if_send(). *//* Generic unicast send function, used by broadcast and point-to-point * interfaces. Simply send the IP packet out the correct * physical interface, specifying the destination and next hop * as the neighbor's IP address. */void SpfIfc::nbr_send(Pkt *pdesc, SpfNbr *np){    InPkt *pkt;    if (!pdesc->iphdr)	return;    finish_pkt(pdesc, np->addr());    pkt = pdesc->iphdr;    if (pkt->i_src != 0) {	if (ospf->spflog(LOG_TXPKT, 1)) {	    ospf->log(pdesc);	    ospf->log(this);	}	sys->sendpkt(pkt, if_phyint, np->addr());    }    else if (ospf->spflog(ERR_NOADDR, 5)) {	    ospf->log(pdesc);	    ospf->log(this);	}    ospf->ospf_freepkt(pdesc);}/* Send a unicast packet out a point-to-point link. Packet is * always sent to the AllSPFRouters address. */void PPIfc::nbr_send(Pkt *pdesc, SpfNbr *){    if_send(pdesc, AllSPFRouters);}/* Send a unicast packet out a virtual link. Packet is sent directly * to the IP address of the other end of the link. */void VLIfc::nbr_send(Pkt *pdesc, SpfNbr *np){    InPkt *pkt;    if (!pdesc->iphdr)	return;    finish_pkt(pdesc, np->addr());    pkt = pdesc->iphdr;    if (ospf->spflog(LOG_TXPKT, 1)) {	ospf->log(pdesc);	ospf->log(this);    }    sys->sendpkt(pkt);    ospf->ospf_freepkt(pdesc);}

⌨️ 快捷键说明

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