Public Member Functions | Private Member Functions | Private Attributes

OSPF::Router Class Reference

#include <OSPFRouter.h>

List of all members.

Public Member Functions

 Router (RouterID id, cSimpleModule *containingModule)
virtual ~Router (void)
void SetRouterID (RouterID id)
RouterID GetRouterID (void) const
void SetRFC1583Compatibility (bool compatibility)
bool GetRFC1583Compatibility (void) const
unsigned long GetAreaCount (void) const
MessageHandlerGetMessageHandler (void)
unsigned long GetASExternalLSACount (void) const
ASExternalLSAGetASExternalLSA (unsigned long i)
const ASExternalLSAGetASExternalLSA (unsigned long i) const
bool GetASBoundaryRouter (void) const
unsigned long GetRoutingTableEntryCount (void) const
RoutingTableEntryGetRoutingTableEntry (unsigned long i)
const RoutingTableEntryGetRoutingTableEntry (unsigned long i) const
void AddRoutingTableEntry (RoutingTableEntry *entry)
void AddWatches (void)
void AddArea (Area *area)
AreaGetArea (AreaID areaID)
AreaGetArea (IPv4Address address)
InterfaceGetNonVirtualInterface (unsigned char ifIndex)
bool InstallLSA (OSPFLSA *lsa, AreaID areaID=BackboneAreaID)
OSPFLSA * FindLSA (LSAType lsaType, LSAKeyType lsaKey, AreaID areaID)
void AgeDatabase (void)
bool HasAnyNeighborInStates (int states) const
void RemoveFromAllRetransmissionLists (LSAKeyType lsaKey)
bool IsOnAnyRetransmissionList (LSAKeyType lsaKey) const
bool FloodLSA (OSPFLSA *lsa, AreaID areaID=BackboneAreaID, Interface *intf=NULL, Neighbor *neighbor=NULL)
bool IsLocalAddress (IPv4Address address) const
bool HasAddressRange (IPv4AddressRange addressRange) const
bool IsDestinationUnreachable (OSPFLSA *lsa) const
RoutingTableEntryLookup (IPAddress destination, std::vector< RoutingTableEntry * > *table=NULL) const
void RebuildRoutingTable (void)
IPv4AddressRange GetContainingAddressRange (IPv4AddressRange addressRange, bool *advertise=NULL) const
void UpdateExternalRoute (IPv4Address networkAddress, const OSPFASExternalLSAContents &externalRouteContents, int ifIndex)
void RemoveExternalRoute (IPv4Address networkAddress)
RoutingTableEntryGetPreferredEntry (const OSPFLSA &lsa, bool skipSelfOriginated, std::vector< RoutingTableEntry * > *fromRoutingTable=NULL)

Private Member Functions

bool InstallASExternalLSA (OSPFASExternalLSA *lsa)
ASExternalLSAFindASExternalLSA (LSAKeyType lsaKey)
const ASExternalLSAFindASExternalLSA (LSAKeyType lsaKey) const
ASExternalLSAOriginateASExternalLSA (ASExternalLSA *lsa)
LinkStateID GetUniqueLinkStateID (IPv4AddressRange destination, Metric destinationCost, OSPF::ASExternalLSA *&lsaToReoriginate, bool externalMetricIsType2=false) const
void CalculateASExternalRoutes (std::vector< RoutingTableEntry * > &newRoutingTable)
void NotifyAboutRoutingTableChanges (std::vector< RoutingTableEntry * > &oldRoutingTable)
bool HasRouteToASBoundaryRouter (const std::vector< RoutingTableEntry * > &inRoutingTable, OSPF::RouterID routerID) const
std::vector< RoutingTableEntry * > GetRoutesToASBoundaryRouter (const std::vector< RoutingTableEntry * > &fromRoutingTable, OSPF::RouterID routerID) const
void PruneASBoundaryRouterEntries (std::vector< RoutingTableEntry * > &asbrEntries) const
RoutingTableEntrySelectLeastCostRoutingEntry (std::vector< RoutingTableEntry * > &entries) const

Private Attributes

RouterID routerID
 The router ID assigned by the IP layer.
std::map< AreaID, Area * > areasByID
 A map of the contained areas with the AreaID as key.
std::vector< Area * > areas
 A list of the contained areas.
std::map< LSAKeyType,
ASExternalLSA
*, LSAKeyType_Less
asExternalLSAsByID
 A map of the ASExternalLSAs advertised by this router.
std::vector< ASExternalLSA * > asExternalLSAs
 A list of the ASExternalLSAs advertised by this router.
std::map< IPv4Address,
OSPFASExternalLSAContents,
IPv4Address_Less
externalRoutes
 A map of the external route advertised by this router.
OSPFTimer * ageTimer
 Database age timer - fires every second.
std::vector< RoutingTableEntry * > routingTable
 The OSPF routing table - contains more information than the one in the IP layer.
MessageHandlermessageHandler
 The message dispatcher class.
bool rfc1583Compatibility
 Decides whether to handle the preferred routing table entry to an AS boundary router as defined in RFC1583 or not.

Detailed Description

Represents the full OSPF datastructure as laid out in RFC2328.

Definition at line 37 of file OSPFRouter.h.


Constructor & Destructor Documentation

OSPF::Router::Router ( OSPF::RouterID  id,
cSimpleModule *  containingModule 
)

Constructor. Initializes internal variables, adds a MessageHandler and starts the Database Age timer.

Definition at line 25 of file OSPFRouter.cc.

                                                                   :
    routerID(id),
    rfc1583Compatibility(false)
{
    messageHandler = new OSPF::MessageHandler(this, containingModule);
    ageTimer = new OSPFTimer;
    ageTimer->setTimerKind(DatabaseAgeTimer);
    ageTimer->setContextPointer(this);
    ageTimer->setName("OSPF::Router::DatabaseAgeTimer");
    messageHandler->StartTimer(ageTimer, 1.0);
}

OSPF::Router::~Router ( void   )  [virtual]

Destructor. Clears all LSA lists and kills the Database Age timer.

Definition at line 42 of file OSPFRouter.cc.

{
    long areaCount = areas.size();
    for (long i = 0; i < areaCount; i++) {
        delete areas[i];
    }
    long lsaCount = asExternalLSAs.size();
    for (long j = 0; j < lsaCount; j++) {
        delete asExternalLSAs[j];
    }
    long routeCount = routingTable.size();
    for (long k = 0; k < routeCount; k++) {
        delete routingTable[k];
    }
    messageHandler->ClearTimer(ageTimer);
    delete ageTimer;
    delete messageHandler;
}


Member Function Documentation

void OSPF::Router::AddArea ( OSPF::Area area  ) 

Adds a new Area to the Area list.

Parameters:
area [in] The Area to add.

Definition at line 77 of file OSPFRouter.cc.

Referenced by OSPFRouting::LoadAreaFromXML().

{

    area->SetRouter(this);
    areasByID[area->GetAreaID()] = area;
    areas.push_back(area);
}

void OSPF::Router::AddRoutingTableEntry ( RoutingTableEntry entry  )  [inline]

Definition at line 70 of file OSPFRouter.h.

{ routingTable.push_back(entry); }

void OSPF::Router::AddWatches ( void   ) 

Adds OMNeT++ watches for the routerID, the list of Areas and the list of AS External LSAs.

Definition at line 65 of file OSPFRouter.cc.

Referenced by OSPFRouting::initialize().

{
    WATCH(routerID);
    WATCH_PTRVECTOR(areas);
    WATCH_PTRVECTOR(asExternalLSAs);
}

void OSPF::Router::AgeDatabase ( void   ) 

Ages the LSAs in the Router's database. This method is called on every firing of the DatabaseAgeTimer(every second).

See also:
RFC2328 Section 14.

Definition at line 361 of file OSPFRouter.cc.

Referenced by OSPF::MessageHandler::HandleTimer().

{
    long lsaCount            = asExternalLSAs.size();
    bool rebuildRoutingTable = false;

    for (long i = 0; i < lsaCount; i++) {
        unsigned short       lsAge          = asExternalLSAs[i]->getHeader().getLsAge();
        bool                 selfOriginated = (asExternalLSAs[i]->getHeader().getAdvertisingRouter().getInt() == routerID);
        bool                 unreachable    = IsDestinationUnreachable(asExternalLSAs[i]);
        OSPF::ASExternalLSA* lsa            = asExternalLSAs[i];

        if ((selfOriginated && (lsAge < (LS_REFRESH_TIME - 1))) || (!selfOriginated && (lsAge < (MAX_AGE - 1)))) {
            lsa->getHeader().setLsAge(lsAge + 1);
            if ((lsAge + 1) % CHECK_AGE == 0) {
                if (!lsa->ValidateLSChecksum()) {
                    EV << "Invalid LS checksum. Memory error detected!\n";
                }
            }
            lsa->IncrementInstallTime();
        }
        if (selfOriginated && (lsAge == (LS_REFRESH_TIME - 1))) {
            if (unreachable) {
                lsa->getHeader().setLsAge(MAX_AGE);
                FloodLSA(lsa, OSPF::BackboneAreaID);
                lsa->IncrementInstallTime();
            } else {
                long sequenceNumber = lsa->getHeader().getLsSequenceNumber();
                if (sequenceNumber == MAX_SEQUENCE_NUMBER) {
                    lsa->getHeader().setLsAge(MAX_AGE);
                    FloodLSA(lsa, OSPF::BackboneAreaID);
                    lsa->IncrementInstallTime();
                } else {
                    OSPF::ASExternalLSA* newLSA = OriginateASExternalLSA(lsa);

                    newLSA->getHeader().setLsSequenceNumber(sequenceNumber + 1);
                    newLSA->getHeader().setLsChecksum(0);    // TODO: calculate correct LS checksum
                    rebuildRoutingTable |= lsa->Update(newLSA);
                    delete newLSA;

                    FloodLSA(lsa, OSPF::BackboneAreaID);
                }
            }
        }
        if (!selfOriginated && (lsAge == MAX_AGE - 1)) {
            lsa->getHeader().setLsAge(MAX_AGE);
            FloodLSA(lsa, OSPF::BackboneAreaID);
            lsa->IncrementInstallTime();
        }
        if (lsAge == MAX_AGE) {
            OSPF::LSAKeyType lsaKey;

            lsaKey.linkStateID       = lsa->getHeader().getLinkStateID();
            lsaKey.advertisingRouter = lsa->getHeader().getAdvertisingRouter().getInt();

            if (!IsOnAnyRetransmissionList(lsaKey) &&
                !HasAnyNeighborInStates(OSPF::Neighbor::ExchangeState | OSPF::Neighbor::LoadingState))
            {
                if (!selfOriginated || unreachable) {
                    asExternalLSAsByID.erase(lsaKey);
                    delete lsa;
                    asExternalLSAs[i] = NULL;
                    rebuildRoutingTable = true;
                } else {
                    if (lsa->GetPurgeable()) {
                        asExternalLSAsByID.erase(lsaKey);
                        delete lsa;
                        asExternalLSAs[i] = NULL;
                        rebuildRoutingTable = true;
                    } else {
                        OSPF::ASExternalLSA* newLSA              = OriginateASExternalLSA(lsa);
                        long                 sequenceNumber      = lsa->getHeader().getLsSequenceNumber();

                        newLSA->getHeader().setLsSequenceNumber((sequenceNumber == MAX_SEQUENCE_NUMBER) ? INITIAL_SEQUENCE_NUMBER : sequenceNumber + 1);
                        newLSA->getHeader().setLsChecksum(0);    // TODO: calculate correct LS checksum
                        rebuildRoutingTable |= lsa->Update(newLSA);
                        delete newLSA;

                        FloodLSA(lsa, OSPF::BackboneAreaID);
                    }
                }
            }
        }
    }

    std::vector<ASExternalLSA*>::iterator it = asExternalLSAs.begin();
    while (it != asExternalLSAs.end()) {
        if ((*it) == NULL) {
            it = asExternalLSAs.erase(it);
        } else {
            it++;
        }
    }

    long areaCount = areas.size();
    for (long j = 0; j < areaCount; j++) {
        areas[j]->AgeDatabase();
    }
    messageHandler->StartTimer(ageTimer, 1.0);

    if (rebuildRoutingTable) {
        RebuildRoutingTable();
    }
}

void OSPF::Router::CalculateASExternalRoutes ( std::vector< RoutingTableEntry * > &  newRoutingTable  )  [private]

Referenced by RebuildRoutingTable().

OSPF::ASExternalLSA * OSPF::Router::FindASExternalLSA ( OSPF::LSAKeyType  lsaKey  )  [private]

Find the AS External LSA identified by the input lsaKey in the database.

Parameters:
lsaKey [in] Look for the AS External LSA which is identified by this key.
Returns:
The pointer to the AS External LSA if it was found, NULL otherwise.

Definition at line 329 of file OSPFRouter.cc.

Referenced by FindLSA(), and GetUniqueLinkStateID().

{
    std::map<OSPF::LSAKeyType, OSPF::ASExternalLSA*, OSPF::LSAKeyType_Less>::iterator lsaIt = asExternalLSAsByID.find(lsaKey);
    if (lsaIt != asExternalLSAsByID.end()) {
        return lsaIt->second;
    } else {
        return NULL;
    }
}

const OSPF::ASExternalLSA * OSPF::Router::FindASExternalLSA ( OSPF::LSAKeyType  lsaKey  )  const [private]

Find the AS External LSA identified by the input lsaKey in the database.

Parameters:
lsaKey [in] Look for the AS External LSA which is identified by this key.
Returns:
The const pointer to the AS External LSA if it was found, NULL otherwise.

Definition at line 345 of file OSPFRouter.cc.

{
    std::map<OSPF::LSAKeyType, OSPF::ASExternalLSA*, OSPF::LSAKeyType_Less>::const_iterator lsaIt = asExternalLSAsByID.find(lsaKey);
    if (lsaIt != asExternalLSAsByID.end()) {
        return lsaIt->second;
    } else {
        return NULL;
    }
}

OSPFLSA * OSPF::Router::FindLSA ( LSAType  lsaType,
OSPF::LSAKeyType  lsaKey,
OSPF::AreaID  areaID 
)

Find the LSA identified by the input lsaKey in the database.

Parameters:
lsaType [in] Look for an LSA of this type.
lsaKey [in] Look for the LSA which is identified by this key.
areaID [in] In case of Router, Network and Summary LSAs, look in the Area's database identified by this parameter.
Returns:
The pointer to the LSA if it was found, NULL otherwise.

Definition at line 283 of file OSPFRouter.cc.

Referenced by OSPF::DatabaseDescriptionHandler::ProcessDDPacket(), OSPF::LinkStateUpdateHandler::ProcessPacket(), and OSPF::LinkStateRequestHandler::ProcessPacket().

{
    switch (lsaType) {
        case RouterLSAType:
            {
                std::map<OSPF::AreaID, OSPF::Area*>::iterator areaIt = areasByID.find(areaID);
                if (areaIt != areasByID.end()) {
                    return areaIt->second->FindRouterLSA(lsaKey.linkStateID);
                }
            }
            break;
        case NetworkLSAType:
            {
                std::map<OSPF::AreaID, OSPF::Area*>::iterator areaIt = areasByID.find(areaID);
                if (areaIt != areasByID.end()) {
                    return areaIt->second->FindNetworkLSA(lsaKey.linkStateID);
                }
            }
            break;
        case SummaryLSA_NetworksType:
        case SummaryLSA_ASBoundaryRoutersType:
            {
                std::map<OSPF::AreaID, OSPF::Area*>::iterator areaIt = areasByID.find(areaID);
                if (areaIt != areasByID.end()) {
                    return areaIt->second->FindSummaryLSA(lsaKey);
                }
            }
            break;
        case ASExternalLSAType:
            {
                return FindASExternalLSA(lsaKey);
            }
            break;
        default:
            ASSERT(false);
            break;
    }
    return NULL;
}

bool OSPF::Router::FloodLSA ( OSPFLSA *  lsa,
OSPF::AreaID  areaID = BackboneAreaID,
OSPF::Interface intf = NULL,
OSPF::Neighbor neighbor = NULL 
)

Floods out the input lsa on a set of Interfaces.

See also:
RFC2328 Section 13.3.
Parameters:
lsa [in] The LSA to be flooded out.
areaID [in] If the lsa is a Router, Network or Summary LSA, then flood it only in this Area.
intf [in] The Interface this LSA arrived on.
neighbor [in] The Nieghbor this LSA arrived from.
Returns:
True if the LSA was floooded back out on the receiving Interface, false otherwise.

Definition at line 523 of file OSPFRouter.cc.

Referenced by AgeDatabase(), InstallASExternalLSA(), OSPF::LinkStateUpdateHandler::ProcessPacket(), RemoveExternalRoute(), and UpdateExternalRoute().

{
    bool floodedBackOut = false;

    if (lsa != NULL) {
        if (lsa->getHeader().getLsType() == ASExternalLSAType) {
            long areaCount = areas.size();
            for (long i = 0; i < areaCount; i++) {
                if (areas[i]->GetExternalRoutingCapability()) {
                    if (areas[i]->FloodLSA(lsa, intf, neighbor)) {
                        floodedBackOut = true;
                    }
                }
            }
        } else {
            std::map<OSPF::AreaID, OSPF::Area*>::iterator areaIt = areasByID.find(areaID);
            if (areaIt != areasByID.end()) {
                floodedBackOut = areaIt->second->FloodLSA(lsa, intf, neighbor);
            }
        }
    }

    return floodedBackOut;
}

OSPF::Area * OSPF::Router::GetArea ( OSPF::IPv4Address  address  ) 

Returns the Area pointer from the Area list which contains the input IP address, NULL if there's no such area connected to the Router.

Parameters:
address [in] The IP address whose containing Area we're looking for.

Definition at line 108 of file OSPFRouter.cc.

{
    long areaCount = areas.size();
    for (long i = 0; i < areaCount; i++) {
        if (areas[i]->ContainsAddress(address)) {
            return areas[i];
        }
    }
    return NULL;
}

OSPF::Area * OSPF::Router::GetArea ( OSPF::AreaID  areaID  ) 

Returns the pointer to the Area identified by the input areaID, if it's on the Area list, NULL otherwise.

Parameters:
areaID [in] The Area identifier.

Definition at line 91 of file OSPFRouter.cc.

Referenced by OSPFRouting::LoadHostRoute(), OSPFRouting::LoadInterfaceParameters(), OSPFRouting::LoadVirtualLink(), OSPF::Area::OriginateRouterLSA(), OSPF::MessageHandler::ProcessPacket(), OSPF::LinkStateUpdateHandler::ProcessPacket(), and RebuildRoutingTable().

{
    std::map<OSPF::AreaID, OSPF::Area*>::iterator areaIt = areasByID.find(areaID);
    if (areaIt != areasByID.end()) {
        return (areaIt->second);
    }
    else {
        return NULL;
    }
}

unsigned long OSPF::Router::GetAreaCount ( void   )  const [inline]

Definition at line 58 of file OSPFRouter.h.

Referenced by OSPF::Area::OriginateRouterLSA(), and OSPF::MessageHandler::ProcessPacket().

{ return areas.size(); }

bool OSPF::Router::GetASBoundaryRouter ( void   )  const [inline]

Definition at line 65 of file OSPFRouter.h.

Referenced by OSPF::Area::OriginateRouterLSA().

{ return (externalRoutes.size() > 0); }

const ASExternalLSA* OSPF::Router::GetASExternalLSA ( unsigned long  i  )  const [inline]

Definition at line 64 of file OSPFRouter.h.

{ return asExternalLSAs[i]; }

ASExternalLSA* OSPF::Router::GetASExternalLSA ( unsigned long  i  )  [inline]

Definition at line 63 of file OSPFRouter.h.

Referenced by OSPF::Neighbor::CreateDatabaseSummary().

{ return asExternalLSAs[i]; }

unsigned long OSPF::Router::GetASExternalLSACount ( void   )  const [inline]

Definition at line 62 of file OSPFRouter.h.

Referenced by OSPF::Neighbor::CreateDatabaseSummary().

{ return asExternalLSAs.size(); }

OSPF::IPv4AddressRange OSPF::Router::GetContainingAddressRange ( OSPF::IPv4AddressRange  addressRange,
bool *  advertise = NULL 
) const

Scans through the router's areas' preconfigured address ranges and returns the one containing the input addressRange.

Parameters:
addressRange [in] The address range to look for.
advertise [out] Whether the advertise flag is set in the returned preconfigured address range.
Returns:
The containing preconfigured address range if found, OSPF::NullIPv4AddressRange otherwise.

Definition at line 1231 of file OSPFRouter.cc.

{
    unsigned long areaCount = areas.size();
    for (unsigned long i = 0; i < areaCount; i++) {
        OSPF::IPv4AddressRange containingAddressRange = areas[i]->GetContainingAddressRange(addressRange, advertise);
        if (containingAddressRange != OSPF::NullIPv4AddressRange) {
            return containingAddressRange;
        }
    }
    if (advertise != NULL) {
        *advertise = false;
    }
    return OSPF::NullIPv4AddressRange;
}

MessageHandler* OSPF::Router::GetMessageHandler ( void   )  [inline]

Definition at line 60 of file OSPFRouter.h.

Referenced by OSPF::LinkStateUpdateHandler::AcknowledgeLSA(), OSPF::Neighbor::ClearRequestRetransmissionTimer(), OSPF::Neighbor::ClearUpdateRetransmissionTimer(), OSPF::Interface::FloodLSA(), OSPFRouting::handleMessage(), OSPF::NeighborStateTwoWay::ProcessEvent(), OSPF::NeighborStateLoading::ProcessEvent(), OSPF::NeighborStateInit::ProcessEvent(), OSPF::NeighborStateFull::ProcessEvent(), OSPF::NeighborStateExchangeStart::ProcessEvent(), OSPF::NeighborStateExchange::ProcessEvent(), OSPF::NeighborStateDown::ProcessEvent(), OSPF::NeighborStateAttempt::ProcessEvent(), OSPF::InterfaceStateWaiting::ProcessEvent(), OSPF::InterfaceStatePointToPoint::ProcessEvent(), OSPF::InterfaceStateNotDesignatedRouter::ProcessEvent(), OSPF::InterfaceStateDown::ProcessEvent(), OSPF::InterfaceStateDesignatedRouter::ProcessEvent(), OSPF::InterfaceStateBackup::ProcessEvent(), OSPF::LinkStateUpdateHandler::ProcessPacket(), OSPF::LinkStateRequestHandler::ProcessPacket(), OSPF::LinkStateAcknowledgementHandler::ProcessPacket(), OSPF::HelloHandler::ProcessPacket(), OSPF::DatabaseDescriptionHandler::ProcessPacket(), OSPF::Neighbor::Reset(), OSPF::Interface::Reset(), OSPF::Neighbor::RetransmitDatabaseDescriptionPacket(), OSPF::Neighbor::RetransmitUpdatePacket(), OSPF::Neighbor::SendDatabaseDescriptionPacket(), OSPF::Interface::SendDelayedAcknowledgements(), OSPF::Interface::SendHelloPacket(), OSPF::Neighbor::SendLinkStateRequestPacket(), OSPF::Interface::SendLSAcknowledgement(), OSPF::Neighbor::StartRequestRetransmissionTimer(), OSPF::Neighbor::StartUpdateRetransmissionTimer(), OSPF::Interface::~Interface(), and OSPF::Neighbor::~Neighbor().

{ return messageHandler; }

OSPF::Interface * OSPF::Router::GetNonVirtualInterface ( unsigned char  ifIndex  ) 

Returns the pointer of the physical Interface identified by the input interface index, NULL if the Router doesn't have such an interface.

Parameters:
ifIndex [in] The interface index to look for.

Definition at line 125 of file OSPFRouter.cc.

{
    long areaCount = areas.size();
    for (long i = 0; i < areaCount; i++) {
        OSPF::Interface* intf = areas[i]->GetInterface(ifIndex);
        if (intf != NULL) {
            return intf;
        }
    }
    return NULL;
}

RoutingTableEntry* OSPF::Router::GetPreferredEntry ( const OSPFLSA &  lsa,
bool  skipSelfOriginated,
std::vector< RoutingTableEntry * > *  fromRoutingTable = NULL 
)
bool OSPF::Router::GetRFC1583Compatibility ( void   )  const [inline]

Definition at line 57 of file OSPFRouter.h.

RouterID OSPF::Router::GetRouterID ( void   )  const [inline]
std::vector<RoutingTableEntry*> OSPF::Router::GetRoutesToASBoundaryRouter ( const std::vector< RoutingTableEntry * > &  fromRoutingTable,
OSPF::RouterID  routerID 
) const [private]
RoutingTableEntry* OSPF::Router::GetRoutingTableEntry ( unsigned long  i  )  [inline]

Definition at line 68 of file OSPFRouter.h.

Referenced by OSPF::Area::OriginateSummaryLSA().

{ return routingTable[i]; }

const RoutingTableEntry* OSPF::Router::GetRoutingTableEntry ( unsigned long  i  )  const [inline]

Definition at line 69 of file OSPFRouter.h.

{ return routingTable[i]; }

unsigned long OSPF::Router::GetRoutingTableEntryCount ( void   )  const [inline]

Definition at line 67 of file OSPFRouter.h.

Referenced by OSPF::Area::OriginateSummaryLSA().

{ return routingTable.size(); }

OSPF::LinkStateID OSPF::Router::GetUniqueLinkStateID ( OSPF::IPv4AddressRange  destination,
OSPF::Metric  destinationCost,
OSPF::ASExternalLSA *&  lsaToReoriginate,
bool  externalMetricIsType2 = false 
) const [private]

Generates a unique LinkStateID for a given destination. This may require the reorigination of an LSA already in the database(with a different LinkStateID).

Parameters:
destination [in] The destination for which a unique LinkStateID is required.
destinationCost [in] The path cost to the destination.
lsaToReoriginate [out] The LSA to reoriginate(which was already in the database, and had to be changed).
externalMetricIsType2 [in] True if the destinationCost is given as a Type2 external metric.
Returns:
the LinkStateID for the destination.
See also:
RFC2328 Appendix E.
OSPF::Area::GetUniqueLinkStateID

Definition at line 1262 of file OSPFRouter.cc.

{
    if (lsaToReoriginate != NULL) {
        delete lsaToReoriginate;
        lsaToReoriginate = NULL;
    }

    OSPF::LSAKeyType lsaKey;

    lsaKey.linkStateID = ULongFromIPv4Address(destination.address);
    lsaKey.advertisingRouter = routerID;

    const OSPF::ASExternalLSA* foundLSA = FindASExternalLSA(lsaKey);

    if (foundLSA == NULL) {
        return lsaKey.linkStateID;
    } else {
        OSPF::IPv4Address existingMask = IPv4AddressFromULong(foundLSA->getContents().getNetworkMask().getInt());

        if (destination.mask >= existingMask) {
            return (lsaKey.linkStateID | (~(ULongFromIPv4Address(destination.mask))));
        } else {
            OSPF::ASExternalLSA* asExternalLSA = new OSPF::ASExternalLSA(*foundLSA);

            long sequenceNumber = asExternalLSA->getHeader().getLsSequenceNumber();

            asExternalLSA->getHeader().setLsAge(0);
            asExternalLSA->getHeader().setLsSequenceNumber((sequenceNumber == MAX_SEQUENCE_NUMBER) ? INITIAL_SEQUENCE_NUMBER : sequenceNumber + 1);
            asExternalLSA->getContents().setNetworkMask(ULongFromIPv4Address(destination.mask));
            asExternalLSA->getContents().setE_ExternalMetricType(externalMetricIsType2);
            asExternalLSA->getContents().setRouteCost(destinationCost);
            asExternalLSA->getHeader().setLsChecksum(0);    // TODO: calculate correct LS checksum

            lsaToReoriginate = asExternalLSA;

            return (lsaKey.linkStateID | (~(ULongFromIPv4Address(existingMask))));
        }
    }
}

bool OSPF::Router::HasAddressRange ( OSPF::IPv4AddressRange  addressRange  )  const

Returns true if one of the Router's Areas the same IP address range configured as the input IP address range, false otherwise.

Parameters:
addressRange [in] The IP address range to look for.

Definition at line 571 of file OSPFRouter.cc.

{
    long areaCount = areas.size();
    for (long i = 0; i < areaCount; i++) {
        if (areas[i]->HasAddressRange(addressRange)) {
            return true;
        }
    }
    return false;
}

bool OSPF::Router::HasAnyNeighborInStates ( int  states  )  const

Returns true if any Neighbor on any Interface in any of the Router's Areas is in any of the input states, false otherwise.

Parameters:
states [in] A bitfield combination of NeighborStateType values.

Definition at line 471 of file OSPFRouter.cc.

Referenced by AgeDatabase(), and OSPF::LinkStateUpdateHandler::ProcessPacket().

{
    long areaCount = areas.size();
    for (long i = 0; i < areaCount; i++) {
        if (areas[i]->HasAnyNeighborInStates(states)) {
            return true;
        }
    }
    return false;
}

bool OSPF::Router::HasRouteToASBoundaryRouter ( const std::vector< RoutingTableEntry * > &  inRoutingTable,
OSPF::RouterID  routerID 
) const [private]
bool OSPF::Router::InstallASExternalLSA ( OSPFASExternalLSA *  lsa  )  [private]

Installs a new AS External LSA into the Router's database. It tries to install keep one of multiple functionally equivalent AS External LSAs in the database. (See the comment in the method implementation.)

Parameters:
lsa [in] The LSA to install. It will be copied into the database.
Returns:
True if the routing table needs to be updated, false otherwise.

From RFC2328 Section 12.4.4.1.: "If two routers, both reachable from one another, originate functionally equivalent AS-External-LSAs(i.e., same destination, cost and non-zero forwarding address), then the LSA originated by the router having the highest OSPF Router ID is used. The router having the lower OSPF Router ID can then flush its LSA." The problem is: how do we tell whether two routers are reachable from one another based on a Link State Update packet? 0. We can assume that if this LSA reached this router, then this router is reachable from the other router. But what about the other direction? 1. The update packet is most likely not sent by the router originating the functionally equivalent AS-External-LSA, so we cannot use the IP packet source address. 2. The AS-External-LSA contains only the Router ID of the advertising router, so we can only look up "router" type routing entries in the routing table(these contain the Router ID as their Destination ID). However these entries are only inserted into the routing table for intra-area routers...

Definition at line 198 of file OSPFRouter.cc.

Referenced by InstallLSA(), and UpdateExternalRoute().

{
     // TODO: how to solve this problem?

    OSPF::RouterID advertisingRouter = lsa->getHeader().getAdvertisingRouter().getInt();
    bool           reachable         = false;
    unsigned int   routeCount        = routingTable.size();

    for (unsigned int i = 0; i < routeCount; i++) {
        if ((((routingTable[i]->GetDestinationType() & OSPF::RoutingTableEntry::AreaBorderRouterDestination) != 0) ||
             ((routingTable[i]->GetDestinationType() & OSPF::RoutingTableEntry::ASBoundaryRouterDestination) != 0)) &&
            (routingTable[i]->GetDestinationID().getInt() == advertisingRouter))
        {
            reachable = true;
            break;
        }
    }

    bool             ownLSAFloodedOut = false;
    OSPF::LSAKeyType lsaKey;

    lsaKey.linkStateID = lsa->getHeader().getLinkStateID();
    lsaKey.advertisingRouter = routerID;

    std::map<OSPF::LSAKeyType, OSPF::ASExternalLSA*, OSPF::LSAKeyType_Less>::iterator lsaIt = asExternalLSAsByID.find(lsaKey);
    if ((lsaIt != asExternalLSAsByID.end()) &&
        reachable &&
        (lsaIt->second->getContents().getE_ExternalMetricType() == lsa->getContents().getE_ExternalMetricType()) &&
        (lsaIt->second->getContents().getRouteCost() == lsa->getContents().getRouteCost()) &&
        (lsa->getContents().getForwardingAddress().getInt() != 0) &&   // forwarding address != 0.0.0.0
        (lsaIt->second->getContents().getForwardingAddress() == lsa->getContents().getForwardingAddress()))
    {
        if (routerID > advertisingRouter) {
            return false;
        } else {
            lsaIt->second->getHeader().setLsAge(MAX_AGE);
            FloodLSA(lsaIt->second, OSPF::BackboneAreaID);
            lsaIt->second->IncrementInstallTime();
            ownLSAFloodedOut = true;
        }
    }

    lsaKey.advertisingRouter = advertisingRouter;

    lsaIt = asExternalLSAsByID.find(lsaKey);
    if (lsaIt != asExternalLSAsByID.end()) {
        unsigned long areaCount = areas.size();
        for (unsigned long i = 0; i < areaCount; i++) {
            areas[i]->RemoveFromAllRetransmissionLists(lsaKey);
        }
        return ((lsaIt->second->Update(lsa)) | ownLSAFloodedOut);
    } else {
        OSPF::ASExternalLSA* lsaCopy = new OSPF::ASExternalLSA(*lsa);
        asExternalLSAsByID[lsaKey] = lsaCopy;
        asExternalLSAs.push_back(lsaCopy);
        return true;
    }
}

bool OSPF::Router::InstallLSA ( OSPFLSA *  lsa,
OSPF::AreaID  areaID = BackboneAreaID 
)

Installs a new LSA into the Router database. Checks the input LSA's type and installs it into either the selected Area's database, or if it's an AS External LSA then into the Router's common asExternalLSAs list.

Parameters:
lsa [in] The LSA to install. It will be copied into the database.
areaID [in] Identifies the input Router, Network and Summary LSA's Area.
Returns:
True if the routing table needs to be updated, false otherwise.

Definition at line 146 of file OSPFRouter.cc.

Referenced by OSPF::LinkStateUpdateHandler::ProcessPacket().

{
    switch (lsa->getHeader().getLsType()) {
        case RouterLSAType:
            {
                std::map<OSPF::AreaID, OSPF::Area*>::iterator areaIt = areasByID.find(areaID);
                if (areaIt != areasByID.end()) {
                    OSPFRouterLSA* ospfRouterLSA = check_and_cast<OSPFRouterLSA*> (lsa);
                    return areaIt->second->InstallRouterLSA(ospfRouterLSA);
                }
            }
            break;
        case NetworkLSAType:
            {
                std::map<OSPF::AreaID, OSPF::Area*>::iterator areaIt = areasByID.find(areaID);
                if (areaIt != areasByID.end()) {
                    OSPFNetworkLSA* ospfNetworkLSA = check_and_cast<OSPFNetworkLSA*> (lsa);
                    return areaIt->second->InstallNetworkLSA(ospfNetworkLSA);
                }
            }
            break;
        case SummaryLSA_NetworksType:
        case SummaryLSA_ASBoundaryRoutersType:
            {
                std::map<OSPF::AreaID, OSPF::Area*>::iterator areaIt = areasByID.find(areaID);
                if (areaIt != areasByID.end()) {
                    OSPFSummaryLSA* ospfSummaryLSA = check_and_cast<OSPFSummaryLSA*> (lsa);
                    return areaIt->second->InstallSummaryLSA(ospfSummaryLSA);
                }
            }
            break;
        case ASExternalLSAType:
            {
                OSPFASExternalLSA* ospfASExternalLSA = check_and_cast<OSPFASExternalLSA*> (lsa);
                return InstallASExternalLSA(ospfASExternalLSA);
            }
            break;
        default:
            ASSERT(false);
            break;
    }
    return false;
}

bool OSPF::Router::IsDestinationUnreachable ( OSPFLSA *  lsa  )  const

Returns true if the destination described by the input lsa is in the routing table, false otherwise.

Parameters:
lsa [in] The LSA which describes the destination to look for.

Definition at line 609 of file OSPFRouter.cc.

Referenced by AgeDatabase(), and OSPF::Area::AgeDatabase().

{
    IPAddress destination = lsa->getHeader().getLinkStateID();

    OSPFRouterLSA* routerLSA         = dynamic_cast<OSPFRouterLSA*> (lsa);
    OSPFNetworkLSA* networkLSA       = dynamic_cast<OSPFNetworkLSA*> (lsa);
    OSPFSummaryLSA* summaryLSA       = dynamic_cast<OSPFSummaryLSA*> (lsa);
    OSPFASExternalLSA* asExternalLSA = dynamic_cast<OSPFASExternalLSA*> (lsa);
    // TODO: verify
    if (routerLSA != NULL) {
        OSPF::RoutingInfo* routingInfo = check_and_cast<OSPF::RoutingInfo*> (routerLSA);
        if (routerLSA->getHeader().getLinkStateID() == routerID) { // this is spfTreeRoot
            return false;
        }

        // get the interface address pointing backwards on the shortest path tree
        unsigned int     linkCount   = routerLSA->getLinksArraySize();
        OSPF::RouterLSA* toRouterLSA = dynamic_cast<OSPF::RouterLSA*> (routingInfo->GetParent());
        if (toRouterLSA != NULL) {
            bool      destinationFound           = false;
            bool      unnumberedPointToPointLink = false;
            IPAddress firstNumberedIfAddress;

            for (unsigned int i = 0; i < linkCount; i++) {
                Link& link = routerLSA->getLinks(i);

                if (link.getType() == PointToPointLink) {
                    if (link.getLinkID() == toRouterLSA->getHeader().getLinkStateID()) {
                        if ((link.getLinkData() & 0xFF000000) == 0) {
                            unnumberedPointToPointLink = true;
                            if (!firstNumberedIfAddress.isUnspecified()) {
                                break;
                            }
                        } else {
                            destination = link.getLinkData();
                            destinationFound = true;
                            break;
                        }
                    } else {
                        if (((link.getLinkData() & 0xFF000000) != 0) &&
                             firstNumberedIfAddress.isUnspecified())
                        {
                            firstNumberedIfAddress = link.getLinkData();
                        }
                    }
                } else if (link.getType() == TransitLink) {
                    if (firstNumberedIfAddress.isUnspecified()) {
                        firstNumberedIfAddress = link.getLinkData();
                    }
                } else if (link.getType() == VirtualLink) {
                    if (link.getLinkID() == toRouterLSA->getHeader().getLinkStateID()) {
                        destination = link.getLinkData();
                        destinationFound = true;
                        break;
                    } else {
                        if (firstNumberedIfAddress.isUnspecified()) {
                            firstNumberedIfAddress = link.getLinkData();
                        }
                    }
                }
                // There's no way to get an interface address for the router from a StubLink
            }
            if (unnumberedPointToPointLink) {
                if (!firstNumberedIfAddress.isUnspecified()) {
                    destination = firstNumberedIfAddress;
                } else {
                    return true;
                }
            }
            if (!destinationFound) {
                return true;
            }
        } else {
            OSPF::NetworkLSA* toNetworkLSA = dynamic_cast<OSPF::NetworkLSA*> (routingInfo->GetParent());
            if (toNetworkLSA != NULL) {
                // get the interface address pointing backwards on the shortest path tree
                bool destinationFound = false;
                for (unsigned int i = 0; i < linkCount; i++) {
                    Link& link = routerLSA->getLinks(i);

                    if ((link.getType() == TransitLink) &&
                        (link.getLinkID() == toNetworkLSA->getHeader().getLinkStateID()))
                    {
                        destination = link.getLinkData();
                        destinationFound = true;
                        break;
                    }
                }
                if (!destinationFound) {
                    return true;
                }
            } else {
                return true;
            }
        }
    }
    if (networkLSA != NULL) {
        destination = networkLSA->getHeader().getLinkStateID() & networkLSA->getNetworkMask().getInt();
    }
    if ((summaryLSA != NULL) && (summaryLSA->getHeader().getLsType() == SummaryLSA_NetworksType)) {
        destination = summaryLSA->getHeader().getLinkStateID() & summaryLSA->getNetworkMask().getInt();
    }
    if (asExternalLSA != NULL) {
        destination = asExternalLSA->getHeader().getLinkStateID() & asExternalLSA->getContents().getNetworkMask().getInt();
    }

    if (Lookup(destination) == NULL) {
        return true;
    } else {
        return false;
    }
}

bool OSPF::Router::IsLocalAddress ( OSPF::IPv4Address  address  )  const

Returns true if the input IP address falls into any of the Router's Areas' configured IP address ranges, false otherwise.

Parameters:
address [in] The IP address to look for.

Definition at line 554 of file OSPFRouter.cc.

Referenced by OSPF::LinkStateUpdateHandler::ProcessPacket().

{
    long areaCount = areas.size();
    for (long i = 0; i < areaCount; i++) {
        if (areas[i]->IsLocalAddress(address)) {
            return true;
        }
    }
    return false;
}

bool OSPF::Router::IsOnAnyRetransmissionList ( OSPF::LSAKeyType  lsaKey  )  const

Returns true if there's at least one LSA on any Neighbor's retransmission list identified by the input lsaKey, false otherwise.

Parameters:
lsaKey [in] Identifies the LSAs to look for on the retransmission lists.

Definition at line 502 of file OSPFRouter.cc.

Referenced by AgeDatabase().

{
    long areaCount = areas.size();
    for (long i = 0; i < areaCount; i++) {
        if (areas[i]->IsOnAnyRetransmissionList(lsaKey)) {
            return true;
        }
    }
    return false;
}

RoutingTableEntry* OSPF::Router::Lookup ( IPAddress  destination,
std::vector< RoutingTableEntry * > *  table = NULL 
) const
void OSPF::Router::NotifyAboutRoutingTableChanges ( std::vector< RoutingTableEntry * > &  oldRoutingTable  )  [private]

Referenced by RebuildRoutingTable().

OSPF::ASExternalLSA * OSPF::Router::OriginateASExternalLSA ( OSPF::ASExternalLSA lsa  )  [private]

Originates a new AS External LSA based on the input lsa.

Parameters:
lsa [in] The LSA whose contents should be copied into the newly originated LSA.
Returns:
The newly originated LSA.

Definition at line 588 of file OSPFRouter.cc.

Referenced by AgeDatabase().

{
    OSPF::ASExternalLSA* asExternalLSA = new OSPF::ASExternalLSA(*lsa);
    OSPFLSAHeader& lsaHeader = asExternalLSA->getHeader();
    OSPFOptions    lsaOptions;

    lsaHeader.setLsAge(0);
    memset(&lsaOptions, 0, sizeof(OSPFOptions));
    lsaOptions.E_ExternalRoutingCapability = true;
    lsaHeader.setLsOptions(lsaOptions);
    lsaHeader.setLsSequenceNumber(INITIAL_SEQUENCE_NUMBER);
    asExternalLSA->SetSource(OSPF::LSATrackingInfo::Originated);

    return asExternalLSA;
}

void OSPF::Router::PruneASBoundaryRouterEntries ( std::vector< RoutingTableEntry * > &  asbrEntries  )  const [private]
void OSPF::Router::RebuildRoutingTable ( void   ) 

Rebuilds the routing table from scratch(based on the LSA database).

See also:
RFC2328 Section 16.

Definition at line 820 of file OSPFRouter.cc.

Referenced by AgeDatabase(), OSPF::Area::AgeDatabase(), OSPF::NeighborState::ChangeState(), OSPF::InterfaceState::ChangeState(), OSPF::LinkStateUpdateHandler::ProcessPacket(), OSPF::HelloHandler::ProcessPacket(), and UpdateExternalRoute().

{
    unsigned long                         areaCount       = areas.size();
    bool                                  hasTransitAreas = false;
    std::vector<OSPF::RoutingTableEntry*> newTable;
    unsigned long                         i;

    EV << "Rebuilding routing table:\n";

    for (i = 0; i < areaCount; i++) {
        areas[i]->CalculateShortestPathTree(newTable);
        if (areas[i]->GetTransitCapability()) {
            hasTransitAreas = true;
        }
    }
    if (areaCount > 1) {
        OSPF::Area* backbone = GetArea(OSPF::BackboneAreaID);
        if (backbone != NULL) {
            backbone->CalculateInterAreaRoutes(newTable);
        }
    } else {
        if (areaCount == 1) {
            areas[0]->CalculateInterAreaRoutes(newTable);
        }
    }
    if (hasTransitAreas) {
        for (i = 0; i < areaCount; i++) {
            if (areas[i]->GetTransitCapability()) {
                areas[i]->ReCheckSummaryLSAs(newTable);
            }
        }
    }
    CalculateASExternalRoutes(newTable);

    // backup the routing table
    unsigned long                         routeCount = routingTable.size();
    std::vector<OSPF::RoutingTableEntry*> oldTable;

    oldTable.assign(routingTable.begin(), routingTable.end());
    routingTable.clear();
    routingTable.assign(newTable.begin(), newTable.end());

    RoutingTableAccess         routingTableAccess;
    std::vector<const IPRoute*> eraseEntries;
    IRoutingTable*              simRoutingTable    = routingTableAccess.get();
    unsigned long              routingEntryNumber = simRoutingTable->getNumRoutes();
    // remove entries from the IP routing table inserted by the OSPF module
    for (i = 0; i < routingEntryNumber; i++) {
        const IPRoute *entry = simRoutingTable->getRoute(i);
        const OSPF::RoutingTableEntry* ospfEntry = dynamic_cast<const OSPF::RoutingTableEntry*>(entry);
        if (ospfEntry != NULL) {
            eraseEntries.push_back(entry);
        }
    }

    unsigned int eraseCount = eraseEntries.size();
    for (i = 0; i < eraseCount; i++) {
        simRoutingTable->deleteRoute(eraseEntries[i]);
    }

    // add the new routing entries
    routeCount = routingTable.size();
    for (i = 0; i < routeCount; i++) {
        if (routingTable[i]->GetDestinationType() == OSPF::RoutingTableEntry::NetworkDestination) {
            simRoutingTable->addRoute(new OSPF::RoutingTableEntry(*(routingTable[i])));
        }
    }

    NotifyAboutRoutingTableChanges(oldTable);

    routeCount = oldTable.size();
    for (i = 0; i < routeCount; i++) {
        delete(oldTable[i]);
    }

    EV << "Routing table was rebuilt.\n"
       << "Results:\n";

    routeCount = routingTable.size();
    for (i = 0; i < routeCount; i++) {
        EV << *routingTable[i]
           << "\n";
    }
}

void OSPF::Router::RemoveExternalRoute ( OSPF::IPv4Address  networkAddress  ) 

Removes an AS External Route from the database.

Parameters:
networkAddress [in] The network address of the external route which needs to be removed.

Definition at line 1594 of file OSPFRouter.cc.

{
    OSPF::LSAKeyType     lsaKey;

    lsaKey.linkStateID = ULongFromIPv4Address(networkAddress);
    lsaKey.advertisingRouter = routerID;

    std::map<OSPF::LSAKeyType, OSPF::ASExternalLSA*, OSPF::LSAKeyType_Less>::iterator lsaIt = asExternalLSAsByID.find(lsaKey);
    if (lsaIt != asExternalLSAsByID.end()) {
        lsaIt->second->getHeader().setLsAge(MAX_AGE);
        lsaIt->second->SetPurgeable();
        FloodLSA(lsaIt->second, OSPF::BackboneAreaID);
    }

    std::map<OSPF::IPv4Address, OSPFASExternalLSAContents, OSPF::IPv4Address_Less>::iterator externalIt = externalRoutes.find(networkAddress);
    if (externalIt != externalRoutes.end()) {
        externalRoutes.erase(externalIt);
    }
}

void OSPF::Router::RemoveFromAllRetransmissionLists ( OSPF::LSAKeyType  lsaKey  ) 

Removes all LSAs from all Neighbor's retransmission lists which are identified by the input lsaKey.

Parameters:
lsaKey [in] Identifies the LSAs to remove from the retransmission lists.

Definition at line 488 of file OSPFRouter.cc.

Referenced by OSPF::LinkStateUpdateHandler::ProcessPacket().

{
    long areaCount = areas.size();
    for (long i = 0; i < areaCount; i++) {
        areas[i]->RemoveFromAllRetransmissionLists(lsaKey);
    }
}

RoutingTableEntry* OSPF::Router::SelectLeastCostRoutingEntry ( std::vector< RoutingTableEntry * > &  entries  )  const [private]
void OSPF::Router::SetRFC1583Compatibility ( bool  compatibility  )  [inline]

Definition at line 56 of file OSPFRouter.h.

Referenced by OSPFRouting::LoadConfigFromXML().

{ rfc1583Compatibility = compatibility; }

void OSPF::Router::SetRouterID ( RouterID  id  )  [inline]

Definition at line 54 of file OSPFRouter.h.

{ routerID = id; }

void OSPF::Router::UpdateExternalRoute ( OSPF::IPv4Address  networkAddress,
const OSPFASExternalLSAContents &  externalRouteContents,
int  ifIndex 
)

Stores information on an AS External Route in externalRoutes and intalls(or updates) a new ASExternalLSA into the database.

Parameters:
networkAddress [in] The external route's network address.
externalRouteContents [in] Route configuration data for the external route.
ifIndex [in]

Definition at line 1532 of file OSPFRouter.cc.

Referenced by OSPFRouting::LoadExternalRoute().

{
    OSPF::ASExternalLSA* asExternalLSA = new OSPF::ASExternalLSA;
    OSPFLSAHeader&       lsaHeader     = asExternalLSA->getHeader();
    OSPFOptions          lsaOptions;
    //OSPF::LSAKeyType     lsaKey;

    IRoutingTable*      simRoutingTable    = RoutingTableAccess().get();
    unsigned long      routingEntryNumber = simRoutingTable->getNumRoutes();
    bool               inRoutingTable     = false;
    // add the external route to the routing table if it was not added by another module
    for (unsigned long i = 0; i < routingEntryNumber; i++) {
        const IPRoute *entry = simRoutingTable->getRoute(i);
        if ((entry->getHost().getInt() & entry->getNetmask().getInt()) ==
            (ULongFromIPv4Address(networkAddress) & externalRouteContents.getNetworkMask().getInt()))
        {
            inRoutingTable = true;
        }
    }
    if (!inRoutingTable) {
        IPRoute* entry = new IPRoute;
        entry->setHost(ULongFromIPv4Address(networkAddress));
        entry->setNetmask(externalRouteContents.getNetworkMask());
        entry->setInterface(InterfaceTableAccess().get()->getInterfaceById(ifIndex));
        entry->setType(IPRoute::REMOTE);
        entry->setSource(IPRoute::MANUAL);
        entry->setMetric(externalRouteContents.getRouteCost());
        simRoutingTable->addRoute(entry);   // IRoutingTable deletes entry pointer
    }

    lsaHeader.setLsAge(0);
    memset(&lsaOptions, 0, sizeof(OSPFOptions));
    lsaOptions.E_ExternalRoutingCapability = true;
    lsaHeader.setLsOptions(lsaOptions);
    lsaHeader.setLsType(ASExternalLSAType);
    lsaHeader.setLinkStateID(ULongFromIPv4Address(networkAddress));   // TODO: get unique LinkStateID
    lsaHeader.setAdvertisingRouter(routerID);
    lsaHeader.setLsSequenceNumber(INITIAL_SEQUENCE_NUMBER);

    asExternalLSA->setContents(externalRouteContents);

    lsaHeader.setLsChecksum(0);    // TODO: calculate correct LS checksum

    asExternalLSA->SetSource(OSPF::LSATrackingInfo::Originated);

    externalRoutes[networkAddress] = externalRouteContents;

    bool rebuild = InstallASExternalLSA(asExternalLSA);
    FloodLSA(asExternalLSA, OSPF::BackboneAreaID);
    delete asExternalLSA;

    if (rebuild) {
        RebuildRoutingTable();
    }
}


Member Data Documentation

OSPFTimer* OSPF::Router::ageTimer [private]

Database age timer - fires every second.

Definition at line 45 of file OSPFRouter.h.

Referenced by AgeDatabase(), Router(), and ~Router().

std::vector<Area*> OSPF::Router::areas [private]
std::map<AreaID, Area*> OSPF::Router::areasByID [private]

A map of the contained areas with the AreaID as key.

Definition at line 40 of file OSPFRouter.h.

Referenced by AddArea(), FindLSA(), FloodLSA(), GetArea(), and InstallLSA().

A list of the ASExternalLSAs advertised by this router.

Definition at line 43 of file OSPFRouter.h.

Referenced by AddWatches(), AgeDatabase(), GetASExternalLSA(), GetASExternalLSACount(), InstallASExternalLSA(), and ~Router().

A map of the ASExternalLSAs advertised by this router.

Definition at line 42 of file OSPFRouter.h.

Referenced by AgeDatabase(), FindASExternalLSA(), InstallASExternalLSA(), and RemoveExternalRoute().

std::map<IPv4Address, OSPFASExternalLSAContents, IPv4Address_Less> OSPF::Router::externalRoutes [private]

A map of the external route advertised by this router.

Definition at line 44 of file OSPFRouter.h.

Referenced by GetASBoundaryRouter(), RemoveExternalRoute(), and UpdateExternalRoute().

The message dispatcher class.

Definition at line 47 of file OSPFRouter.h.

Referenced by AgeDatabase(), GetMessageHandler(), Router(), and ~Router().

Decides whether to handle the preferred routing table entry to an AS boundary router as defined in RFC1583 or not.

Definition at line 48 of file OSPFRouter.h.

Referenced by GetRFC1583Compatibility(), and SetRFC1583Compatibility().

The OSPF routing table - contains more information than the one in the IP layer.

Definition at line 46 of file OSPFRouter.h.

Referenced by AddRoutingTableEntry(), GetRoutingTableEntry(), GetRoutingTableEntryCount(), InstallASExternalLSA(), RebuildRoutingTable(), and ~Router().


The documentation for this class was generated from the following files: