#include <OSPFRouter.h>
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 |
MessageHandler * | GetMessageHandler (void) |
unsigned long | GetASExternalLSACount (void) const |
ASExternalLSA * | GetASExternalLSA (unsigned long i) |
const ASExternalLSA * | GetASExternalLSA (unsigned long i) const |
bool | GetASBoundaryRouter (void) const |
unsigned long | GetRoutingTableEntryCount (void) const |
RoutingTableEntry * | GetRoutingTableEntry (unsigned long i) |
const RoutingTableEntry * | GetRoutingTableEntry (unsigned long i) const |
void | AddRoutingTableEntry (RoutingTableEntry *entry) |
void | AddWatches (void) |
void | AddArea (Area *area) |
Area * | GetArea (AreaID areaID) |
Area * | GetArea (IPv4Address address) |
Interface * | GetNonVirtualInterface (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 |
RoutingTableEntry * | Lookup (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) |
RoutingTableEntry * | GetPreferredEntry (const OSPFLSA &lsa, bool skipSelfOriginated, std::vector< RoutingTableEntry * > *fromRoutingTable=NULL) |
Private Member Functions | |
bool | InstallASExternalLSA (OSPFASExternalLSA *lsa) |
ASExternalLSA * | FindASExternalLSA (LSAKeyType lsaKey) |
const ASExternalLSA * | FindASExternalLSA (LSAKeyType lsaKey) const |
ASExternalLSA * | OriginateASExternalLSA (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 |
RoutingTableEntry * | SelectLeastCostRoutingEntry (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. | |
MessageHandler * | messageHandler |
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. |
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 }
RouterID OSPF::Router::GetRouterID | ( | void | ) | const [inline] |
Referenced by OSPF::LinkStateUpdateHandler::AcknowledgeLSA(), OSPF::Area::AgeDatabase(), OSPF::InterfaceState::CalculateDesignatedRouter(), OSPF::Area::CalculateNextHops(), OSPF::NeighborState::ChangeState(), OSPF::InterfaceState::ChangeState(), OSPF::Interface::CreateUpdatePacket(), OSPF::Area::GetUniqueLinkStateID(), OSPFRouting::LoadConfigFromXML(), OSPF::MessageHandler::MessageReceived(), OSPF::Neighbor::NeedAdjacency(), OSPF::Area::OriginateNetworkLSA(), OSPF::Area::OriginateRouterLSA(), OSPF::LinkStateUpdateHandler::ProcessPacket(), OSPF::HelloHandler::ProcessPacket(), OSPF::DatabaseDescriptionHandler::ProcessPacket(), OSPF::Neighbor::RetransmitUpdatePacket(), OSPF::Neighbor::SendDatabaseDescriptionPacket(), OSPF::Interface::SendDelayedAcknowledgements(), OSPF::Interface::SendHelloPacket(), OSPF::Neighbor::SendLinkStateRequestPacket(), and OSPF::Interface::SendLSAcknowledgement().
00055 { return routerID; }
void OSPF::Router::SetRFC1583Compatibility | ( | bool | compatibility | ) | [inline] |
bool OSPF::Router::GetRFC1583Compatibility | ( | void | ) | const [inline] |
unsigned long OSPF::Router::GetAreaCount | ( | void | ) | const [inline] |
Referenced by OSPF::Area::OriginateRouterLSA(), and OSPF::MessageHandler::ProcessPacket().
00058 { return areas.size(); }
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] |
ASExternalLSA* OSPF::Router::GetASExternalLSA | ( | unsigned long | i | ) | [inline] |
const ASExternalLSA* OSPF::Router::GetASExternalLSA | ( | unsigned long | i | ) | const [inline] |
bool OSPF::Router::GetASBoundaryRouter | ( | void | ) | const [inline] |
unsigned long OSPF::Router::GetRoutingTableEntryCount | ( | void | ) | const [inline] |
RoutingTableEntry* OSPF::Router::GetRoutingTableEntry | ( | unsigned long | i | ) | [inline] |
const RoutingTableEntry* OSPF::Router::GetRoutingTableEntry | ( | unsigned long | i | ) | const [inline] |
void OSPF::Router::AddRoutingTableEntry | ( | RoutingTableEntry * | entry | ) | [inline] |
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 | ) |
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.
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.
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.
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.
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. |
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.
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. |
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).
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.
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.
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.
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.
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. |
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.
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.
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.
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 |
Referenced by IsDestinationUnreachable().
void OSPF::Router::RebuildRoutingTable | ( | void | ) |
Rebuilds the routing table from scratch(based on the LSA database).
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.
addressRange | [in] The address range to look for. | |
advertise | [out] Whether the advertise flag is set in the returned preconfigured address range. |
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.
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.
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.)
lsa | [in] The LSA to install. It will be copied into the database. |
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.
lsaKey | [in] Look for the AS External LSA which is identified by this key. |
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.
lsaKey | [in] Look for the AS External LSA which is identified by this key. |
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.
lsa | [in] The LSA whose contents should be copied into 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).
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. |
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] |
RouterID OSPF::Router::routerID [private] |
The router ID assigned by the IP layer.
Referenced by AddWatches(), AgeDatabase(), GetRouterID(), GetUniqueLinkStateID(), InstallASExternalLSA(), IsDestinationUnreachable(), RemoveExternalRoute(), SetRouterID(), and UpdateExternalRoute().
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 list of the contained areas.
Referenced by AddArea(), AddWatches(), AgeDatabase(), FloodLSA(), GetArea(), GetAreaCount(), GetContainingAddressRange(), GetNonVirtualInterface(), HasAddressRange(), HasAnyNeighborInStates(), InstallASExternalLSA(), IsLocalAddress(), IsOnAnyRetransmissionList(), RebuildRoutingTable(), RemoveFromAllRetransmissionLists(), and ~Router().
std::map<LSAKeyType, ASExternalLSA*, LSAKeyType_Less> OSPF::Router::asExternalLSAsByID [private] |
A map of the ASExternalLSAs advertised by this router.
Referenced by AgeDatabase(), FindASExternalLSA(), InstallASExternalLSA(), and RemoveExternalRoute().
std::vector<ASExternalLSA*> OSPF::Router::asExternalLSAs [private] |
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] |
std::vector<RoutingTableEntry*> OSPF::Router::routingTable [private] |
The OSPF routing table - contains more information than the one in the IP layer.
Referenced by AddRoutingTableEntry(), GetRoutingTableEntry(), GetRoutingTableEntryCount(), InstallASExternalLSA(), RebuildRoutingTable(), and ~Router().
MessageHandler* OSPF::Router::messageHandler [private] |
The message dispatcher class.
Referenced by AgeDatabase(), GetMessageHandler(), Router(), and ~Router().
bool OSPF::Router::rfc1583Compatibility [private] |
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().