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

📄 spfvl.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 implementing OSPF's virtual link * functionality. */#include "ospfinc.h"#include "ifcfsm.h"#include "nbrfsm.h"/* Add, modify, or delete a virtual link. * When a virtual link is added, the routing calculation * is scheduled so that the state of the virtual link will * get updated. */void OSPF::cfgVL(struct CfgVL *m, int status){    VLIfc *ip;    SpfArea *tap;    RTRrte *endpt;    SpfArea *bb;    // Don't allow virtual links to self    if (m->nbr_id == my_id())        return;    /* Find virtual link by looking up transit area,     * and then the other endpoint's routing table     * entry.     * Allocate new area, if necessary     */    if (!(tap = ospf->FindArea(m->transit_area)))	tap = new SpfArea(m->transit_area);    if (!(endpt = tap->find_abr(m->nbr_id)))	endpt = tap->add_abr(m->nbr_id);    ip = endpt->VL;    // If delete, free to heap    if (status == DELETE_ITEM) {	if (ip)	    delete ip;	return;    }    // Allocate new virtual link, if necessary    if (!ip)	ip = new VLIfc(tap, endpt);    // Change timers, if need be    if (m->hello_int != ip->if_hint) {	ip->if_hint = m->hello_int;	ip->restart_hellos();    }    // Set new parameters    ip->if_xdelay = m->xmt_dly;	// Transit delay (seconds)    ip->if_rxmt = m->rxmt_int;	// Retransmission interval (seconds)    ip->if_hint = m->hello_int;	// Hello interval (seconds)    ip->if_dint = m->dead_int;	// Router dead interval (seconds)    ip->if_autype = m->auth_type; // Authentication type    ip->if_passive = 0;    memcpy(ip->if_passwd, m->auth_key, 8);// Auth key    ip->updated = true;    tap->updated = true;    bb = FindArea(BACKBONE);    bb->updated = true;    // If endpoint reachable, bring up the link    ip->update(endpt);}/* Copy virtual link info to configuration structure. */static void vl_to_cfg(const VLIfc& ip, struct CfgVL& msg){    msg.transit_area = ip.transit_area()->id();    msg.nbr_id = ip.nbr_id();    msg.xmt_dly = ip.xmt_delay();    msg.rxmt_int = ip.rxmt_interval();    msg.hello_int = ip.hello_int();    msg.dead_int = ip.dead_int();    msg.auth_type = ip.autype();    memcpy(msg.auth_key, ip.passwd(), sizeof(msg.auth_key));}/* Query virtual link information */bool OSPF::qryVL(struct CfgVL& msg, aid_t transit_id, rtid_t nbr_id) const{    SpfArea *tap = ospf->FindArea(transit_id);    if (tap == 0) return false;    RTRrte *endpt = tap->find_abr(nbr_id);    if (endpt == 0) return false;        vl_to_cfg(*endpt->VL, msg);    return true;}/* Get all virtual links  */void OSPF::getVLs(std::list<CfgVL>& l, aid_t transit_id) const{    SpfArea* tap = FindArea(transit_id);    if (tap == 0) return;        AVLsearch aiter(&tap->abr_tbl);    RTRrte* rre;    while ((rre = (RTRrte*) aiter.next())) {	if (rre->VL == 0) continue; // possible ???	CfgVL msg;	vl_to_cfg(*rre->VL, msg);	l.push_back(msg);    }}/* Constructor for a virtual link. Link together * the virtual interface, endpoint routing table entry, * and transit area classes. Then link the virtual link * into the backbone area's interface list. */VLIfc::VLIfc(SpfArea *tap, RTRrte *endpt) : PPIfc(0, 0){    SpfArea *bb;    if_type = IFT_VL;    if_tap = tap;	// Transit area    if_nbrid = endpt->rtrid();// Configured neighbor ID    if_rmtaddr = 0;	// IP address of other end (learned dynamically)    endpt->VL = this;    if_phyint = -1;    if_mtu = VL_MTU;    // Queue into global interface list    next = ospf->ifcs;    ospf->ifcs = this;    // Add to backbone area    if (!(bb = ospf->FindArea(BACKBONE)))	bb = new SpfArea(BACKBONE);    if_area = bb;    anext = bb->a_ifcs;    bb->a_ifcs = this;}/* Destructor for the virtual interface. Simply unlink from * the endpoint's routing table entry; the interface * destructor will do the rest. */VLIfc::~VLIfc(){    RTRrte *endpt;    if ((endpt = if_tap->find_abr(if_nbrid)))	endpt->VL = 0;}/* The state of the ABR endpoint of a virtual link has * changed. Invoke the up or down interface events, or just * change the virtual link's cost. * Called from the routing calculation. In particular, the parent * pointer in the endpoint's router-LSA is assumed to correctly * point up the tree, enabling calculation of the remote IP * address. */void VLIfc::update(class RTRrte *endpt){    SpfArea *ap;    ap = endpt->ap;    // Must have intra-area route through    // a non-stub area    if (endpt->type() != RT_SPF || ap->is_stub()) {        if_cost = 0xffff;	run_fsm(IFE_DOWN);	return;    }    // Try to find the source and destination    // addresses for the virtual link. If    // they can't be found, must declare the    // virtual link down also.    if_addr = endpt->ifc()->if_addr;    if (byte0(if_addr) == 0)        if_addr = ap->id_to_addr(ospf->my_id());    if_rmtaddr = ap->id_to_addr(endpt->rtrid());    if (byte0(if_addr) == 0 || byte0(if_rmtaddr) == 0) {        if_cost = 0xffff;	run_fsm(IFE_DOWN);	return;    }    // Set cost equal to the cost of the intra-area    // path, and then declare    // the virtual link "up"    if (if_cost != endpt->cost) {	SpfArea	*a;	a = ospf->FindArea(BACKBONE);	if_cost = endpt->cost;	a->rl_orig(0);    }    run_fsm(IFE_UP);}/* Find an IP address to associate with a router-ID, allowing * us to choose the source and destination addresses * for a vitual link. * Prefer the address belonging to the closest * interface (discovered by routing), but if that's not * available, take any address in the associated * router-LSA. */InAddr SpfArea::id_to_addr(rtid_t id){    InAddr addr;    TNode *V;    Link *lp;    addr = 0;    if (!(V = (TNode *) ospf->FindLSA(0, this, LST_RTR, id, id)))        return(addr);    for (lp = V->t_links; lp != 0; lp = lp->l_next) {	TLink *tlp;	if (lp->l_ltype == LT_STUB) {	    if (lp->l_data == 0xffffffff && addr == 0 && lp->l_fwdcst == 0)	        addr = lp->l_id;	    continue;	}	tlp = (TLink *) lp;	if (tlp->tl_nbr == 0)	    continue;	if (byte0(tlp->l_data) == 0)	    continue;	addr = tlp->l_data;	if (tlp->tl_nbr == V->t_parent)	    break;    }    return(addr);}

⌨️ 快捷键说明

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