OSPF::Router Class Reference

#include <OSPFRouter.h>

List of all members.


Detailed Description

Represents the full OSPF datastructure as laid out in RFC2328.

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.

Constructor & Destructor Documentation

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

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

00025                                                                    :
00026     routerID(id),
00027     rfc1583Compatibility(false)
00028 {
00029     messageHandler = new OSPF::MessageHandler(this, containingModule);
00030     ageTimer = new OSPFTimer;
00031     ageTimer->setTimerKind(DatabaseAgeTimer);
00032     ageTimer->setContextPointer(this);
00033     ageTimer->setName("OSPF::Router::DatabaseAgeTimer");
00034     messageHandler->StartTimer(ageTimer, 1.0);
00035 }

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

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

00043 {
00044     long areaCount = areas.size();
00045     for (long i = 0; i < areaCount; i++) {
00046         delete areas[i];
00047     }
00048     long lsaCount = asExternalLSAs.size();
00049     for (long j = 0; j < lsaCount; j++) {
00050         delete asExternalLSAs[j];
00051     }
00052     long routeCount = routingTable.size();
00053     for (long k = 0; k < routeCount; k++) {
00054         delete routingTable[k];
00055     }
00056     messageHandler->ClearTimer(ageTimer);
00057     delete ageTimer;
00058     delete messageHandler;
00059 }


Member Function Documentation

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

00054 { routerID = id; }

RouterID OSPF::Router::GetRouterID ( void   )  const [inline]

void OSPF::Router::SetRFC1583Compatibility ( bool  compatibility  )  [inline]

Referenced by OSPFRouting::LoadConfigFromXML().

00056 { rfc1583Compatibility = compatibility; }

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

00057 { return rfc1583Compatibility; }

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

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

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().

00060 { return messageHandler; }

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

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

00062 { return asExternalLSAs.size(); }

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

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

00063 { return asExternalLSAs[i]; }

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

00064 { return asExternalLSAs[i]; }

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

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

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

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

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

00067 { return routingTable.size(); }

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

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

00068 { return routingTable[i]; }

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

00069 { return routingTable[i]; }

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

00070 { 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.

Referenced by OSPFRouting::initialize().

00066 {
00067     WATCH(routerID);
00068     WATCH_PTRVECTOR(areas);
00069     WATCH_PTRVECTOR(asExternalLSAs);
00070 }

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

Adds a new Area to the Area list.

Parameters:
area [in] The Area to add.

Referenced by OSPFRouting::LoadAreaFromXML().

00078 {
00079 
00080     area->SetRouter(this);
00081     areasByID[area->GetAreaID()] = area;
00082     areas.push_back(area);
00083 }

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.

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

00092 {
00093     std::map<OSPF::AreaID, OSPF::Area*>::iterator areaIt = areasByID.find(areaID);
00094     if (areaIt != areasByID.end()) {
00095         return (areaIt->second);
00096     }
00097     else {
00098         return NULL;
00099     }
00100 }

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.
00109 {
00110     long areaCount = areas.size();
00111     for (long i = 0; i < areaCount; i++) {
00112         if (areas[i]->ContainsAddress(address)) {
00113             return areas[i];
00114         }
00115     }
00116     return NULL;
00117 }

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.
00126 {
00127     long areaCount = areas.size();
00128     for (long i = 0; i < areaCount; i++) {
00129         OSPF::Interface* intf = areas[i]->GetInterface(ifIndex);
00130         if (intf != NULL) {
00131             return intf;
00132         }
00133     }
00134     return NULL;
00135 }

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.

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

00147 {
00148     switch (lsa->getHeader().getLsType()) {
00149         case RouterLSAType:
00150             {
00151                 std::map<OSPF::AreaID, OSPF::Area*>::iterator areaIt = areasByID.find(areaID);
00152                 if (areaIt != areasByID.end()) {
00153                     OSPFRouterLSA* ospfRouterLSA = check_and_cast<OSPFRouterLSA*> (lsa);
00154                     return areaIt->second->InstallRouterLSA(ospfRouterLSA);
00155                 }
00156             }
00157             break;
00158         case NetworkLSAType:
00159             {
00160                 std::map<OSPF::AreaID, OSPF::Area*>::iterator areaIt = areasByID.find(areaID);
00161                 if (areaIt != areasByID.end()) {
00162                     OSPFNetworkLSA* ospfNetworkLSA = check_and_cast<OSPFNetworkLSA*> (lsa);
00163                     return areaIt->second->InstallNetworkLSA(ospfNetworkLSA);
00164                 }
00165             }
00166             break;
00167         case SummaryLSA_NetworksType:
00168         case SummaryLSA_ASBoundaryRoutersType:
00169             {
00170                 std::map<OSPF::AreaID, OSPF::Area*>::iterator areaIt = areasByID.find(areaID);
00171                 if (areaIt != areasByID.end()) {
00172                     OSPFSummaryLSA* ospfSummaryLSA = check_and_cast<OSPFSummaryLSA*> (lsa);
00173                     return areaIt->second->InstallSummaryLSA(ospfSummaryLSA);
00174                 }
00175             }
00176             break;
00177         case ASExternalLSAType:
00178             {
00179                 OSPFASExternalLSA* ospfASExternalLSA = check_and_cast<OSPFASExternalLSA*> (lsa);
00180                 return InstallASExternalLSA(ospfASExternalLSA);
00181             }
00182             break;
00183         default:
00184             ASSERT(false);
00185             break;
00186     }
00187     return false;
00188 }

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.

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

00284 {
00285     switch (lsaType) {
00286         case RouterLSAType:
00287             {
00288                 std::map<OSPF::AreaID, OSPF::Area*>::iterator areaIt = areasByID.find(areaID);
00289                 if (areaIt != areasByID.end()) {
00290                     return areaIt->second->FindRouterLSA(lsaKey.linkStateID);
00291                 }
00292             }
00293             break;
00294         case NetworkLSAType:
00295             {
00296                 std::map<OSPF::AreaID, OSPF::Area*>::iterator areaIt = areasByID.find(areaID);
00297                 if (areaIt != areasByID.end()) {
00298                     return areaIt->second->FindNetworkLSA(lsaKey.linkStateID);
00299                 }
00300             }
00301             break;
00302         case SummaryLSA_NetworksType:
00303         case SummaryLSA_ASBoundaryRoutersType:
00304             {
00305                 std::map<OSPF::AreaID, OSPF::Area*>::iterator areaIt = areasByID.find(areaID);
00306                 if (areaIt != areasByID.end()) {
00307                     return areaIt->second->FindSummaryLSA(lsaKey);
00308                 }
00309             }
00310             break;
00311         case ASExternalLSAType:
00312             {
00313                 return FindASExternalLSA(lsaKey);
00314             }
00315             break;
00316         default:
00317             ASSERT(false);
00318             break;
00319     }
00320     return NULL;
00321 }

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.

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

00362 {
00363     long lsaCount            = asExternalLSAs.size();
00364     bool rebuildRoutingTable = false;
00365 
00366     for (long i = 0; i < lsaCount; i++) {
00367         unsigned short       lsAge          = asExternalLSAs[i]->getHeader().getLsAge();
00368         bool                 selfOriginated = (asExternalLSAs[i]->getHeader().getAdvertisingRouter().getInt() == routerID);
00369         bool                 unreachable    = IsDestinationUnreachable(asExternalLSAs[i]);
00370         OSPF::ASExternalLSA* lsa            = asExternalLSAs[i];
00371 
00372         if ((selfOriginated && (lsAge < (LS_REFRESH_TIME - 1))) || (!selfOriginated && (lsAge < (MAX_AGE - 1)))) {
00373             lsa->getHeader().setLsAge(lsAge + 1);
00374             if ((lsAge + 1) % CHECK_AGE == 0) {
00375                 if (!lsa->ValidateLSChecksum()) {
00376                     EV << "Invalid LS checksum. Memory error detected!\n";
00377                 }
00378             }
00379             lsa->IncrementInstallTime();
00380         }
00381         if (selfOriginated && (lsAge == (LS_REFRESH_TIME - 1))) {
00382             if (unreachable) {
00383                 lsa->getHeader().setLsAge(MAX_AGE);
00384                 FloodLSA(lsa, OSPF::BackboneAreaID);
00385                 lsa->IncrementInstallTime();
00386             } else {
00387                 long sequenceNumber = lsa->getHeader().getLsSequenceNumber();
00388                 if (sequenceNumber == MAX_SEQUENCE_NUMBER) {
00389                     lsa->getHeader().setLsAge(MAX_AGE);
00390                     FloodLSA(lsa, OSPF::BackboneAreaID);
00391                     lsa->IncrementInstallTime();
00392                 } else {
00393                     OSPF::ASExternalLSA* newLSA = OriginateASExternalLSA(lsa);
00394 
00395                     newLSA->getHeader().setLsSequenceNumber(sequenceNumber + 1);
00396                     newLSA->getHeader().setLsChecksum(0);    // TODO: calculate correct LS checksum
00397                     rebuildRoutingTable |= lsa->Update(newLSA);
00398                     delete newLSA;
00399 
00400                     FloodLSA(lsa, OSPF::BackboneAreaID);
00401                 }
00402             }
00403         }
00404         if (!selfOriginated && (lsAge == MAX_AGE - 1)) {
00405             lsa->getHeader().setLsAge(MAX_AGE);
00406             FloodLSA(lsa, OSPF::BackboneAreaID);
00407             lsa->IncrementInstallTime();
00408         }
00409         if (lsAge == MAX_AGE) {
00410             OSPF::LSAKeyType lsaKey;
00411 
00412             lsaKey.linkStateID       = lsa->getHeader().getLinkStateID();
00413             lsaKey.advertisingRouter = lsa->getHeader().getAdvertisingRouter().getInt();
00414 
00415             if (!IsOnAnyRetransmissionList(lsaKey) &&
00416                 !HasAnyNeighborInStates(OSPF::Neighbor::ExchangeState | OSPF::Neighbor::LoadingState))
00417             {
00418                 if (!selfOriginated || unreachable) {
00419                     asExternalLSAsByID.erase(lsaKey);
00420                     delete lsa;
00421                     asExternalLSAs[i] = NULL;
00422                     rebuildRoutingTable = true;
00423                 } else {
00424                     if (lsa->GetPurgeable()) {
00425                         asExternalLSAsByID.erase(lsaKey);
00426                         delete lsa;
00427                         asExternalLSAs[i] = NULL;
00428                         rebuildRoutingTable = true;
00429                     } else {
00430                         OSPF::ASExternalLSA* newLSA              = OriginateASExternalLSA(lsa);
00431                         long                 sequenceNumber      = lsa->getHeader().getLsSequenceNumber();
00432 
00433                         newLSA->getHeader().setLsSequenceNumber((sequenceNumber == MAX_SEQUENCE_NUMBER) ? INITIAL_SEQUENCE_NUMBER : sequenceNumber + 1);
00434                         newLSA->getHeader().setLsChecksum(0);    // TODO: calculate correct LS checksum
00435                         rebuildRoutingTable |= lsa->Update(newLSA);
00436                         delete newLSA;
00437 
00438                         FloodLSA(lsa, OSPF::BackboneAreaID);
00439                     }
00440                 }
00441             }
00442         }
00443     }
00444 
00445     std::vector<ASExternalLSA*>::iterator it = asExternalLSAs.begin();
00446     while (it != asExternalLSAs.end()) {
00447         if ((*it) == NULL) {
00448             it = asExternalLSAs.erase(it);
00449         } else {
00450             it++;
00451         }
00452     }
00453 
00454     long areaCount = areas.size();
00455     for (long j = 0; j < areaCount; j++) {
00456         areas[j]->AgeDatabase();
00457     }
00458     messageHandler->StartTimer(ageTimer, 1.0);
00459 
00460     if (rebuildRoutingTable) {
00461         RebuildRoutingTable();
00462     }
00463 }

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.

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

00472 {
00473     long areaCount = areas.size();
00474     for (long i = 0; i < areaCount; i++) {
00475         if (areas[i]->HasAnyNeighborInStates(states)) {
00476             return true;
00477         }
00478     }
00479     return false;
00480 }

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.

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

00489 {
00490     long areaCount = areas.size();
00491     for (long i = 0; i < areaCount; i++) {
00492         areas[i]->RemoveFromAllRetransmissionLists(lsaKey);
00493     }
00494 }

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.

Referenced by AgeDatabase().

00503 {
00504     long areaCount = areas.size();
00505     for (long i = 0; i < areaCount; i++) {
00506         if (areas[i]->IsOnAnyRetransmissionList(lsaKey)) {
00507             return true;
00508         }
00509     }
00510     return false;
00511 }

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.

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

00524 {
00525     bool floodedBackOut = false;
00526 
00527     if (lsa != NULL) {
00528         if (lsa->getHeader().getLsType() == ASExternalLSAType) {
00529             long areaCount = areas.size();
00530             for (long i = 0; i < areaCount; i++) {
00531                 if (areas[i]->GetExternalRoutingCapability()) {
00532                     if (areas[i]->FloodLSA(lsa, intf, neighbor)) {
00533                         floodedBackOut = true;
00534                     }
00535                 }
00536             }
00537         } else {
00538             std::map<OSPF::AreaID, OSPF::Area*>::iterator areaIt = areasByID.find(areaID);
00539             if (areaIt != areasByID.end()) {
00540                 floodedBackOut = areaIt->second->FloodLSA(lsa, intf, neighbor);
00541             }
00542         }
00543     }
00544 
00545     return floodedBackOut;
00546 }

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.

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

00555 {
00556     long areaCount = areas.size();
00557     for (long i = 0; i < areaCount; i++) {
00558         if (areas[i]->IsLocalAddress(address)) {
00559             return true;
00560         }
00561     }
00562     return false;
00563 }

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.
00572 {
00573     long areaCount = areas.size();
00574     for (long i = 0; i < areaCount; i++) {
00575         if (areas[i]->HasAddressRange(addressRange)) {
00576             return true;
00577         }
00578     }
00579     return false;
00580 }

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.

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

00610 {
00611     IPAddress destination = lsa->getHeader().getLinkStateID();
00612 
00613     OSPFRouterLSA* routerLSA         = dynamic_cast<OSPFRouterLSA*> (lsa);
00614     OSPFNetworkLSA* networkLSA       = dynamic_cast<OSPFNetworkLSA*> (lsa);
00615     OSPFSummaryLSA* summaryLSA       = dynamic_cast<OSPFSummaryLSA*> (lsa);
00616     OSPFASExternalLSA* asExternalLSA = dynamic_cast<OSPFASExternalLSA*> (lsa);
00617     // TODO: verify
00618     if (routerLSA != NULL) {
00619         OSPF::RoutingInfo* routingInfo = check_and_cast<OSPF::RoutingInfo*> (routerLSA);
00620         if (routerLSA->getHeader().getLinkStateID() == routerID) { // this is spfTreeRoot
00621             return false;
00622         }
00623 
00624         // get the interface address pointing backwards on the shortest path tree
00625         unsigned int     linkCount   = routerLSA->getLinksArraySize();
00626         OSPF::RouterLSA* toRouterLSA = dynamic_cast<OSPF::RouterLSA*> (routingInfo->GetParent());
00627         if (toRouterLSA != NULL) {
00628             bool      destinationFound           = false;
00629             bool      unnumberedPointToPointLink = false;
00630             IPAddress firstNumberedIfAddress;
00631 
00632             for (unsigned int i = 0; i < linkCount; i++) {
00633                 Link& link = routerLSA->getLinks(i);
00634 
00635                 if (link.getType() == PointToPointLink) {
00636                     if (link.getLinkID() == toRouterLSA->getHeader().getLinkStateID()) {
00637                         if ((link.getLinkData() & 0xFF000000) == 0) {
00638                             unnumberedPointToPointLink = true;
00639                             if (!firstNumberedIfAddress.isUnspecified()) {
00640                                 break;
00641                             }
00642                         } else {
00643                             destination = link.getLinkData();
00644                             destinationFound = true;
00645                             break;
00646                         }
00647                     } else {
00648                         if (((link.getLinkData() & 0xFF000000) != 0) &&
00649                              firstNumberedIfAddress.isUnspecified())
00650                         {
00651                             firstNumberedIfAddress = link.getLinkData();
00652                         }
00653                     }
00654                 } else if (link.getType() == TransitLink) {
00655                     if (firstNumberedIfAddress.isUnspecified()) {
00656                         firstNumberedIfAddress = link.getLinkData();
00657                     }
00658                 } else if (link.getType() == VirtualLink) {
00659                     if (link.getLinkID() == toRouterLSA->getHeader().getLinkStateID()) {
00660                         destination = link.getLinkData();
00661                         destinationFound = true;
00662                         break;
00663                     } else {
00664                         if (firstNumberedIfAddress.isUnspecified()) {
00665                             firstNumberedIfAddress = link.getLinkData();
00666                         }
00667                     }
00668                 }
00669                 // There's no way to get an interface address for the router from a StubLink
00670             }
00671             if (unnumberedPointToPointLink) {
00672                 if (!firstNumberedIfAddress.isUnspecified()) {
00673                     destination = firstNumberedIfAddress;
00674                 } else {
00675                     return true;
00676                 }
00677             }
00678             if (!destinationFound) {
00679                 return true;
00680             }
00681         } else {
00682             OSPF::NetworkLSA* toNetworkLSA = dynamic_cast<OSPF::NetworkLSA*> (routingInfo->GetParent());
00683             if (toNetworkLSA != NULL) {
00684                 // get the interface address pointing backwards on the shortest path tree
00685                 bool destinationFound = false;
00686                 for (unsigned int i = 0; i < linkCount; i++) {
00687                     Link& link = routerLSA->getLinks(i);
00688 
00689                     if ((link.getType() == TransitLink) &&
00690                         (link.getLinkID() == toNetworkLSA->getHeader().getLinkStateID()))
00691                     {
00692                         destination = link.getLinkData();
00693                         destinationFound = true;
00694                         break;
00695                     }
00696                 }
00697                 if (!destinationFound) {
00698                     return true;
00699                 }
00700             } else {
00701                 return true;
00702             }
00703         }
00704     }
00705     if (networkLSA != NULL) {
00706         destination = networkLSA->getHeader().getLinkStateID() & networkLSA->getNetworkMask().getInt();
00707     }
00708     if ((summaryLSA != NULL) && (summaryLSA->getHeader().getLsType() == SummaryLSA_NetworksType)) {
00709         destination = summaryLSA->getHeader().getLinkStateID() & summaryLSA->getNetworkMask().getInt();
00710     }
00711     if (asExternalLSA != NULL) {
00712         destination = asExternalLSA->getHeader().getLinkStateID() & asExternalLSA->getContents().getNetworkMask().getInt();
00713     }
00714 
00715     if (Lookup(destination) == NULL) {
00716         return true;
00717     } else {
00718         return false;
00719     }
00720 }

RoutingTableEntry* OSPF::Router::Lookup ( IPAddress  destination,
std::vector< RoutingTableEntry * > *  table = NULL 
) const

void OSPF::Router::RebuildRoutingTable ( void   ) 

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

See also:
RFC2328 Section 16.

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

00821 {
00822     unsigned long                         areaCount       = areas.size();
00823     bool                                  hasTransitAreas = false;
00824     std::vector<OSPF::RoutingTableEntry*> newTable;
00825     unsigned long                         i;
00826 
00827     EV << "Rebuilding routing table:\n";
00828 
00829     for (i = 0; i < areaCount; i++) {
00830         areas[i]->CalculateShortestPathTree(newTable);
00831         if (areas[i]->GetTransitCapability()) {
00832             hasTransitAreas = true;
00833         }
00834     }
00835     if (areaCount > 1) {
00836         OSPF::Area* backbone = GetArea(OSPF::BackboneAreaID);
00837         if (backbone != NULL) {
00838             backbone->CalculateInterAreaRoutes(newTable);
00839         }
00840     } else {
00841         if (areaCount == 1) {
00842             areas[0]->CalculateInterAreaRoutes(newTable);
00843         }
00844     }
00845     if (hasTransitAreas) {
00846         for (i = 0; i < areaCount; i++) {
00847             if (areas[i]->GetTransitCapability()) {
00848                 areas[i]->ReCheckSummaryLSAs(newTable);
00849             }
00850         }
00851     }
00852     CalculateASExternalRoutes(newTable);
00853 
00854     // backup the routing table
00855     unsigned long                         routeCount = routingTable.size();
00856     std::vector<OSPF::RoutingTableEntry*> oldTable;
00857 
00858     oldTable.assign(routingTable.begin(), routingTable.end());
00859     routingTable.clear();
00860     routingTable.assign(newTable.begin(), newTable.end());
00861 
00862     RoutingTableAccess         routingTableAccess;
00863     std::vector<const IPRoute*> eraseEntries;
00864     IRoutingTable*              simRoutingTable    = routingTableAccess.get();
00865     unsigned long              routingEntryNumber = simRoutingTable->getNumRoutes();
00866     // remove entries from the IP routing table inserted by the OSPF module
00867     for (i = 0; i < routingEntryNumber; i++) {
00868         const IPRoute *entry = simRoutingTable->getRoute(i);
00869         const OSPF::RoutingTableEntry* ospfEntry = dynamic_cast<const OSPF::RoutingTableEntry*>(entry);
00870         if (ospfEntry != NULL) {
00871             eraseEntries.push_back(entry);
00872         }
00873     }
00874 
00875     unsigned int eraseCount = eraseEntries.size();
00876     for (i = 0; i < eraseCount; i++) {
00877         simRoutingTable->deleteRoute(eraseEntries[i]);
00878     }
00879 
00880     // add the new routing entries
00881     routeCount = routingTable.size();
00882     for (i = 0; i < routeCount; i++) {
00883         if (routingTable[i]->GetDestinationType() == OSPF::RoutingTableEntry::NetworkDestination) {
00884             simRoutingTable->addRoute(new OSPF::RoutingTableEntry(*(routingTable[i])));
00885         }
00886     }
00887 
00888     NotifyAboutRoutingTableChanges(oldTable);
00889 
00890     routeCount = oldTable.size();
00891     for (i = 0; i < routeCount; i++) {
00892         delete(oldTable[i]);
00893     }
00894 
00895     EV << "Routing table was rebuilt.\n"
00896        << "Results:\n";
00897 
00898     routeCount = routingTable.size();
00899     for (i = 0; i < routeCount; i++) {
00900         EV << *routingTable[i]
00901            << "\n";
00902     }
00903 }

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.
01232 {
01233     unsigned long areaCount = areas.size();
01234     for (unsigned long i = 0; i < areaCount; i++) {
01235         OSPF::IPv4AddressRange containingAddressRange = areas[i]->GetContainingAddressRange(addressRange, advertise);
01236         if (containingAddressRange != OSPF::NullIPv4AddressRange) {
01237             return containingAddressRange;
01238         }
01239     }
01240     if (advertise != NULL) {
01241         *advertise = false;
01242     }
01243     return OSPF::NullIPv4AddressRange;
01244 }

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]

Referenced by OSPFRouting::LoadExternalRoute().

01533 {
01534     OSPF::ASExternalLSA* asExternalLSA = new OSPF::ASExternalLSA;
01535     OSPFLSAHeader&       lsaHeader     = asExternalLSA->getHeader();
01536     OSPFOptions          lsaOptions;
01537     //OSPF::LSAKeyType     lsaKey;
01538 
01539     IRoutingTable*      simRoutingTable    = RoutingTableAccess().get();
01540     unsigned long      routingEntryNumber = simRoutingTable->getNumRoutes();
01541     bool               inRoutingTable     = false;
01542     // add the external route to the routing table if it was not added by another module
01543     for (unsigned long i = 0; i < routingEntryNumber; i++) {
01544         const IPRoute *entry = simRoutingTable->getRoute(i);
01545         if ((entry->getHost().getInt() & entry->getNetmask().getInt()) ==
01546             (ULongFromIPv4Address(networkAddress) & externalRouteContents.getNetworkMask().getInt()))
01547         {
01548             inRoutingTable = true;
01549         }
01550     }
01551     if (!inRoutingTable) {
01552         IPRoute* entry = new IPRoute;
01553         entry->setHost(ULongFromIPv4Address(networkAddress));
01554         entry->setNetmask(externalRouteContents.getNetworkMask());
01555         entry->setInterface(InterfaceTableAccess().get()->getInterfaceById(ifIndex));
01556         entry->setType(IPRoute::REMOTE);
01557         entry->setSource(IPRoute::MANUAL);
01558         entry->setMetric(externalRouteContents.getRouteCost());
01559         simRoutingTable->addRoute(entry);   // IRoutingTable deletes entry pointer
01560     }
01561 
01562     lsaHeader.setLsAge(0);
01563     memset(&lsaOptions, 0, sizeof(OSPFOptions));
01564     lsaOptions.E_ExternalRoutingCapability = true;
01565     lsaHeader.setLsOptions(lsaOptions);
01566     lsaHeader.setLsType(ASExternalLSAType);
01567     lsaHeader.setLinkStateID(ULongFromIPv4Address(networkAddress));   // TODO: get unique LinkStateID
01568     lsaHeader.setAdvertisingRouter(routerID);
01569     lsaHeader.setLsSequenceNumber(INITIAL_SEQUENCE_NUMBER);
01570 
01571     asExternalLSA->setContents(externalRouteContents);
01572 
01573     lsaHeader.setLsChecksum(0);    // TODO: calculate correct LS checksum
01574 
01575     asExternalLSA->SetSource(OSPF::LSATrackingInfo::Originated);
01576 
01577     externalRoutes[networkAddress] = externalRouteContents;
01578 
01579     bool rebuild = InstallASExternalLSA(asExternalLSA);
01580     FloodLSA(asExternalLSA, OSPF::BackboneAreaID);
01581     delete asExternalLSA;
01582 
01583     if (rebuild) {
01584         RebuildRoutingTable();
01585     }
01586 }

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.
01595 {
01596     OSPF::LSAKeyType     lsaKey;
01597 
01598     lsaKey.linkStateID = ULongFromIPv4Address(networkAddress);
01599     lsaKey.advertisingRouter = routerID;
01600 
01601     std::map<OSPF::LSAKeyType, OSPF::ASExternalLSA*, OSPF::LSAKeyType_Less>::iterator lsaIt = asExternalLSAsByID.find(lsaKey);
01602     if (lsaIt != asExternalLSAsByID.end()) {
01603         lsaIt->second->getHeader().setLsAge(MAX_AGE);
01604         lsaIt->second->SetPurgeable();
01605         FloodLSA(lsaIt->second, OSPF::BackboneAreaID);
01606     }
01607 
01608     std::map<OSPF::IPv4Address, OSPFASExternalLSAContents, OSPF::IPv4Address_Less>::iterator externalIt = externalRoutes.find(networkAddress);
01609     if (externalIt != externalRoutes.end()) {
01610         externalRoutes.erase(externalIt);
01611     }
01612 }

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

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...

Referenced by InstallLSA(), and UpdateExternalRoute().

00199 {
00217      // TODO: how to solve this problem?
00218 
00219     OSPF::RouterID advertisingRouter = lsa->getHeader().getAdvertisingRouter().getInt();
00220     bool           reachable         = false;
00221     unsigned int   routeCount        = routingTable.size();
00222 
00223     for (unsigned int i = 0; i < routeCount; i++) {
00224         if ((((routingTable[i]->GetDestinationType() & OSPF::RoutingTableEntry::AreaBorderRouterDestination) != 0) ||
00225              ((routingTable[i]->GetDestinationType() & OSPF::RoutingTableEntry::ASBoundaryRouterDestination) != 0)) &&
00226             (routingTable[i]->GetDestinationID().getInt() == advertisingRouter))
00227         {
00228             reachable = true;
00229             break;
00230         }
00231     }
00232 
00233     bool             ownLSAFloodedOut = false;
00234     OSPF::LSAKeyType lsaKey;
00235 
00236     lsaKey.linkStateID = lsa->getHeader().getLinkStateID();
00237     lsaKey.advertisingRouter = routerID;
00238 
00239     std::map<OSPF::LSAKeyType, OSPF::ASExternalLSA*, OSPF::LSAKeyType_Less>::iterator lsaIt = asExternalLSAsByID.find(lsaKey);
00240     if ((lsaIt != asExternalLSAsByID.end()) &&
00241         reachable &&
00242         (lsaIt->second->getContents().getE_ExternalMetricType() == lsa->getContents().getE_ExternalMetricType()) &&
00243         (lsaIt->second->getContents().getRouteCost() == lsa->getContents().getRouteCost()) &&
00244         (lsa->getContents().getForwardingAddress().getInt() != 0) &&   // forwarding address != 0.0.0.0
00245         (lsaIt->second->getContents().getForwardingAddress() == lsa->getContents().getForwardingAddress()))
00246     {
00247         if (routerID > advertisingRouter) {
00248             return false;
00249         } else {
00250             lsaIt->second->getHeader().setLsAge(MAX_AGE);
00251             FloodLSA(lsaIt->second, OSPF::BackboneAreaID);
00252             lsaIt->second->IncrementInstallTime();
00253             ownLSAFloodedOut = true;
00254         }
00255     }
00256 
00257     lsaKey.advertisingRouter = advertisingRouter;
00258 
00259     lsaIt = asExternalLSAsByID.find(lsaKey);
00260     if (lsaIt != asExternalLSAsByID.end()) {
00261         unsigned long areaCount = areas.size();
00262         for (unsigned long i = 0; i < areaCount; i++) {
00263             areas[i]->RemoveFromAllRetransmissionLists(lsaKey);
00264         }
00265         return ((lsaIt->second->Update(lsa)) | ownLSAFloodedOut);
00266     } else {
00267         OSPF::ASExternalLSA* lsaCopy = new OSPF::ASExternalLSA(*lsa);
00268         asExternalLSAsByID[lsaKey] = lsaCopy;
00269         asExternalLSAs.push_back(lsaCopy);
00270         return true;
00271     }
00272 }

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.

Referenced by FindLSA(), and GetUniqueLinkStateID().

00330 {
00331     std::map<OSPF::LSAKeyType, OSPF::ASExternalLSA*, OSPF::LSAKeyType_Less>::iterator lsaIt = asExternalLSAsByID.find(lsaKey);
00332     if (lsaIt != asExternalLSAsByID.end()) {
00333         return lsaIt->second;
00334     } else {
00335         return NULL;
00336     }
00337 }

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.
00346 {
00347     std::map<OSPF::LSAKeyType, OSPF::ASExternalLSA*, OSPF::LSAKeyType_Less>::const_iterator lsaIt = asExternalLSAsByID.find(lsaKey);
00348     if (lsaIt != asExternalLSAsByID.end()) {
00349         return lsaIt->second;
00350     } else {
00351         return NULL;
00352     }
00353 }

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.

Referenced by AgeDatabase().

00589 {
00590     OSPF::ASExternalLSA* asExternalLSA = new OSPF::ASExternalLSA(*lsa);
00591     OSPFLSAHeader& lsaHeader = asExternalLSA->getHeader();
00592     OSPFOptions    lsaOptions;
00593 
00594     lsaHeader.setLsAge(0);
00595     memset(&lsaOptions, 0, sizeof(OSPFOptions));
00596     lsaOptions.E_ExternalRoutingCapability = true;
00597     lsaHeader.setLsOptions(lsaOptions);
00598     lsaHeader.setLsSequenceNumber(INITIAL_SEQUENCE_NUMBER);
00599     asExternalLSA->SetSource(OSPF::LSATrackingInfo::Originated);
00600 
00601     return asExternalLSA;
00602 }

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

01266 {
01267     if (lsaToReoriginate != NULL) {
01268         delete lsaToReoriginate;
01269         lsaToReoriginate = NULL;
01270     }
01271 
01272     OSPF::LSAKeyType lsaKey;
01273 
01274     lsaKey.linkStateID = ULongFromIPv4Address(destination.address);
01275     lsaKey.advertisingRouter = routerID;
01276 
01277     const OSPF::ASExternalLSA* foundLSA = FindASExternalLSA(lsaKey);
01278 
01279     if (foundLSA == NULL) {
01280         return lsaKey.linkStateID;
01281     } else {
01282         OSPF::IPv4Address existingMask = IPv4AddressFromULong(foundLSA->getContents().getNetworkMask().getInt());
01283 
01284         if (destination.mask >= existingMask) {
01285             return (lsaKey.linkStateID | (~(ULongFromIPv4Address(destination.mask))));
01286         } else {
01287             OSPF::ASExternalLSA* asExternalLSA = new OSPF::ASExternalLSA(*foundLSA);
01288 
01289             long sequenceNumber = asExternalLSA->getHeader().getLsSequenceNumber();
01290 
01291             asExternalLSA->getHeader().setLsAge(0);
01292             asExternalLSA->getHeader().setLsSequenceNumber((sequenceNumber == MAX_SEQUENCE_NUMBER) ? INITIAL_SEQUENCE_NUMBER : sequenceNumber + 1);
01293             asExternalLSA->getContents().setNetworkMask(ULongFromIPv4Address(destination.mask));
01294             asExternalLSA->getContents().setE_ExternalMetricType(externalMetricIsType2);
01295             asExternalLSA->getContents().setRouteCost(destinationCost);
01296             asExternalLSA->getHeader().setLsChecksum(0);    // TODO: calculate correct LS checksum
01297 
01298             lsaToReoriginate = asExternalLSA;
01299 
01300             return (lsaKey.linkStateID | (~(ULongFromIPv4Address(existingMask))));
01301         }
01302     }
01303 }

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

Referenced by RebuildRoutingTable().

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

Referenced by RebuildRoutingTable().

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

std::vector<RoutingTableEntry*> OSPF::Router::GetRoutesToASBoundaryRouter ( const std::vector< RoutingTableEntry * > &  fromRoutingTable,
OSPF::RouterID  routerID 
) const [private]

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

RoutingTableEntry* OSPF::Router::SelectLeastCostRoutingEntry ( std::vector< RoutingTableEntry * > &  entries  )  const [private]


Member Data Documentation

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

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

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

std::vector<Area*> OSPF::Router::areas [private]

A map of the ASExternalLSAs advertised by this router.

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

A list of the ASExternalLSAs advertised by this router.

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

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

A map of the external route advertised by this router.

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

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

Database age timer - fires every second.

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

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

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

The message dispatcher class.

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.

Referenced by GetRFC1583Compatibility(), and SetRFC1583Compatibility().


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

Generated on Fri Mar 20 18:51:24 2009 for INET Framework for OMNeT++/OMNEST by  doxygen 1.5.5