#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 | AnyNeighborInStates (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 | DestinationIsUnreachable (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. |
|
Constructor. Initializes internal variables, adds a MessageHandler and starts the Database Age timer. 00011 : 00012 routerID (id), 00013 rfc1583Compatibility (false) 00014 { 00015 messageHandler = new OSPF::MessageHandler (this, containingModule); 00016 ageTimer = new OSPFTimer; 00017 ageTimer->setTimerKind (DatabaseAgeTimer); 00018 ageTimer->setContextPointer (this); 00019 ageTimer->setName ("OSPF::Router::DatabaseAgeTimer"); 00020 messageHandler->StartTimer (ageTimer, 1.0); 00021 }
|
|
Destructor. Clears all LSA lists and kills the Database Age timer. 00029 { 00030 long areaCount = areas.size (); 00031 for (long i = 0; i < areaCount; i++) { 00032 delete areas[i]; 00033 } 00034 long lsaCount = asExternalLSAs.size (); 00035 for (long j = 0; j < lsaCount; j++) { 00036 delete asExternalLSAs[j]; 00037 } 00038 long routeCount = routingTable.size (); 00039 for (long k = 0; k < routeCount; k++) { 00040 delete routingTable[k]; 00041 } 00042 messageHandler->ClearTimer (ageTimer); 00043 delete ageTimer; 00044 delete messageHandler; 00045 }
|
|
Adds a new Area to the Area list.
00064 { 00065 00066 area->SetRouter (this); 00067 areasByID[area->GetAreaID ()] = area; 00068 areas.push_back (area); 00069 }
|
|
00053 { routingTable.push_back (entry); }
|
|
Adds OMNeT++ watches for the routerID, the list of Areas and the list of AS External LSAs. 00052 { 00053 WATCH (routerID); 00054 WATCH_PTRVECTOR (areas); 00055 WATCH_PTRVECTOR (asExternalLSAs); 00056 }
|
|
Ages the LSAs in the Router's database. This method is called on every firing of the DatabaseAgeTimer (every second).
00348 { 00349 long lsaCount = asExternalLSAs.size (); 00350 bool rebuildRoutingTable = false; 00351 00352 for (long i = 0; i < lsaCount; i++) { 00353 unsigned short lsAge = asExternalLSAs[i]->getHeader ().getLsAge (); 00354 bool selfOriginated = (asExternalLSAs[i]->getHeader ().getAdvertisingRouter ().getInt () == routerID); 00355 bool unreachable = DestinationIsUnreachable (asExternalLSAs[i]); 00356 OSPF::ASExternalLSA* lsa = asExternalLSAs[i]; 00357 00358 if ((selfOriginated && (lsAge < (LS_REFRESH_TIME - 1))) || (!selfOriginated && (lsAge < (MAX_AGE - 1)))) { 00359 lsa->getHeader ().setLsAge (lsAge + 1); 00360 if ((lsAge + 1) % CHECK_AGE == 0) { 00361 if (!lsa->ValidateLSChecksum ()) { 00362 EV << "Invalid LS checksum. Memory error detected!\n"; 00363 } 00364 } 00365 lsa->IncrementInstallTime (); 00366 } 00367 if (selfOriginated && (lsAge == (LS_REFRESH_TIME - 1))) { 00368 if (unreachable) { 00369 lsa->getHeader ().setLsAge (MAX_AGE); 00370 FloodLSA (lsa, OSPF::BackboneAreaID); 00371 lsa->IncrementInstallTime (); 00372 } else { 00373 long sequenceNumber = lsa->getHeader ().getLsSequenceNumber (); 00374 if (sequenceNumber == MAX_SEQUENCE_NUMBER) { 00375 lsa->getHeader ().setLsAge (MAX_AGE); 00376 FloodLSA (lsa, OSPF::BackboneAreaID); 00377 lsa->IncrementInstallTime (); 00378 } else { 00379 OSPF::ASExternalLSA* newLSA = OriginateASExternalLSA (lsa); 00380 00381 newLSA->getHeader ().setLsSequenceNumber (sequenceNumber + 1); 00382 newLSA->getHeader ().setLsChecksum (0); // TODO: calculate correct LS checksum 00383 rebuildRoutingTable |= lsa->Update (newLSA); 00384 delete newLSA; 00385 00386 FloodLSA (lsa, OSPF::BackboneAreaID); 00387 } 00388 } 00389 } 00390 if (!selfOriginated && (lsAge == MAX_AGE - 1)) { 00391 lsa->getHeader ().setLsAge (MAX_AGE); 00392 FloodLSA (lsa, OSPF::BackboneAreaID); 00393 lsa->IncrementInstallTime (); 00394 } 00395 if (lsAge == MAX_AGE) { 00396 OSPF::LSAKeyType lsaKey; 00397 00398 lsaKey.linkStateID = lsa->getHeader ().getLinkStateID (); 00399 lsaKey.advertisingRouter = lsa->getHeader ().getAdvertisingRouter ().getInt (); 00400 00401 if (!IsOnAnyRetransmissionList (lsaKey) && 00402 !AnyNeighborInStates (OSPF::Neighbor::ExchangeState | OSPF::Neighbor::LoadingState)) 00403 { 00404 if (!selfOriginated || unreachable) { 00405 asExternalLSAsByID.erase (lsaKey); 00406 delete lsa; 00407 asExternalLSAs[i] = NULL; 00408 rebuildRoutingTable = true; 00409 } else { 00410 if (lsa->GetPurgeable ()) { 00411 asExternalLSAsByID.erase (lsaKey); 00412 delete lsa; 00413 asExternalLSAs[i] = NULL; 00414 rebuildRoutingTable = true; 00415 } else { 00416 OSPF::ASExternalLSA* newLSA = OriginateASExternalLSA (lsa); 00417 long sequenceNumber = lsa->getHeader ().getLsSequenceNumber (); 00418 00419 newLSA->getHeader ().setLsSequenceNumber ((sequenceNumber == MAX_SEQUENCE_NUMBER) ? INITIAL_SEQUENCE_NUMBER : sequenceNumber + 1); 00420 newLSA->getHeader ().setLsChecksum (0); // TODO: calculate correct LS checksum 00421 rebuildRoutingTable |= lsa->Update (newLSA); 00422 delete newLSA; 00423 00424 FloodLSA (lsa, OSPF::BackboneAreaID); 00425 } 00426 } 00427 } 00428 } 00429 } 00430 00431 std::vector<ASExternalLSA*>::iterator it = asExternalLSAs.begin (); 00432 while (it != asExternalLSAs.end ()) { 00433 if ((*it) == NULL) { 00434 it = asExternalLSAs.erase (it); 00435 } else { 00436 it++; 00437 } 00438 } 00439 00440 long areaCount = areas.size (); 00441 for (long j = 0; j < areaCount; j++) { 00442 areas[j]->AgeDatabase (); 00443 } 00444 messageHandler->StartTimer (ageTimer, 1.0); 00445 00446 if (rebuildRoutingTable) { 00447 RebuildRoutingTable (); 00448 } 00449 }
|
|
Returns true if any Neighbor on any Interface in any of the Router's Areas is in any of the input states, false otherwise.
00458 { 00459 long areaCount = areas.size (); 00460 for (long i = 0; i < areaCount; i++) { 00461 if (areas[i]->AnyNeighborInStates (states)) { 00462 return true; 00463 } 00464 } 00465 return false; 00466 }
|
|
Calculate the AS External Routes from the ASExternalLSAs in the database.
01079 { 01080 unsigned long lsaCount = asExternalLSAs.size (); 01081 unsigned long i; 01082 01083 for (i = 0; i < lsaCount; i++) { 01084 OSPF::ASExternalLSA* currentLSA = asExternalLSAs[i]; 01085 OSPFLSAHeader& currentHeader = currentLSA->getHeader (); 01086 unsigned short externalCost = currentLSA->getContents ().getRouteCost (); 01087 OSPF::RouterID originatingRouter = currentHeader.getAdvertisingRouter ().getInt (); 01088 01089 OSPF::RoutingTableEntry* preferredEntry = GetPreferredEntry (*currentLSA, true, &newRoutingTable); 01090 if (preferredEntry == NULL) { 01091 continue; 01092 } 01093 01094 IPAddress destination = currentHeader.getLinkStateID () & currentLSA->getContents ().getNetworkMask ().getInt (); 01095 01096 Metric preferredCost = preferredEntry->GetCost (); 01097 OSPF::RoutingTableEntry* destinationEntry = Lookup (destination, &newRoutingTable); // (5) 01098 if (destinationEntry == NULL) { 01099 bool type2ExternalMetric = currentLSA->getContents ().getE_ExternalMetricType (); 01100 unsigned int nextHopCount = preferredEntry->GetNextHopCount (); 01101 OSPF::RoutingTableEntry* newEntry = new OSPF::RoutingTableEntry; 01102 01103 newEntry->SetDestinationID (destination); 01104 newEntry->SetAddressMask (currentLSA->getContents ().getNetworkMask ().getInt ()); 01105 newEntry->SetArea (preferredEntry->GetArea ()); 01106 newEntry->SetPathType (type2ExternalMetric ? OSPF::RoutingTableEntry::Type2External : OSPF::RoutingTableEntry::Type1External); 01107 if (type2ExternalMetric) { 01108 newEntry->SetCost (preferredCost); 01109 newEntry->SetType2Cost (externalCost); 01110 } else { 01111 newEntry->SetCost (preferredCost + externalCost); 01112 } 01113 newEntry->SetDestinationType (OSPF::RoutingTableEntry::NetworkDestination); 01114 newEntry->SetOptionalCapabilities (currentHeader.getLsOptions ()); 01115 newEntry->SetLinkStateOrigin (currentLSA); 01116 01117 for (unsigned int j = 0; j < nextHopCount; j++) { 01118 NextHop nextHop = preferredEntry->GetNextHop (j); 01119 01120 nextHop.advertisingRouter = originatingRouter; 01121 newEntry->AddNextHop (nextHop); 01122 } 01123 01124 newRoutingTable.push_back (newEntry); 01125 } else { 01126 OSPF::RoutingTableEntry::RoutingPathType destinationPathType = destinationEntry->GetPathType (); 01127 bool type2ExternalMetric = currentLSA->getContents ().getE_ExternalMetricType (); 01128 unsigned int nextHopCount = preferredEntry->GetNextHopCount (); 01129 01130 if ((destinationPathType == OSPF::RoutingTableEntry::IntraArea) || 01131 (destinationPathType == OSPF::RoutingTableEntry::InterArea)) // (6) (a) 01132 { 01133 continue; 01134 } 01135 01136 if (((destinationPathType == OSPF::RoutingTableEntry::Type1External) && 01137 (type2ExternalMetric)) || 01138 ((destinationPathType == OSPF::RoutingTableEntry::Type2External) && 01139 (type2ExternalMetric) && 01140 (destinationEntry->GetType2Cost () < externalCost))) // (6) (b) 01141 { 01142 continue; 01143 } 01144 01145 OSPF::RoutingTableEntry* destinationPreferredEntry = GetPreferredEntry (*(destinationEntry->GetLinkStateOrigin ()), false, &newRoutingTable); 01146 if ((!rfc1583Compatibility) && 01147 (destinationPreferredEntry->GetPathType () == OSPF::RoutingTableEntry::IntraArea) && 01148 (destinationPreferredEntry->GetArea () != OSPF::BackboneAreaID) && 01149 ((preferredEntry->GetPathType () != OSPF::RoutingTableEntry::IntraArea) || 01150 (preferredEntry->GetArea () == OSPF::BackboneAreaID))) 01151 { 01152 continue; 01153 } 01154 01155 if ((((destinationPathType == OSPF::RoutingTableEntry::Type1External) && 01156 (!type2ExternalMetric) && 01157 (destinationEntry->GetCost () < preferredCost + externalCost))) || 01158 ((destinationPathType == OSPF::RoutingTableEntry::Type2External) && 01159 (type2ExternalMetric) && 01160 (destinationEntry->GetType2Cost () == externalCost) && 01161 (destinationPreferredEntry->GetCost () < preferredCost))) 01162 { 01163 continue; 01164 } 01165 01166 if (((destinationPathType == OSPF::RoutingTableEntry::Type1External) && 01167 (!type2ExternalMetric) && 01168 (destinationEntry->GetCost () == (preferredCost + externalCost))) || 01169 ((destinationPathType == OSPF::RoutingTableEntry::Type2External) && 01170 (type2ExternalMetric) && 01171 (destinationEntry->GetType2Cost () == externalCost) && 01172 (destinationPreferredEntry->GetCost () == preferredCost))) // equal cost 01173 { 01174 for (unsigned int j = 0; j < nextHopCount; j++) { 01175 // TODO: merge next hops, not add 01176 NextHop nextHop = preferredEntry->GetNextHop (j); 01177 01178 nextHop.advertisingRouter = originatingRouter; 01179 destinationEntry->AddNextHop (nextHop); 01180 } 01181 continue; 01182 } 01183 01184 // LSA is better 01185 destinationEntry->SetArea (preferredEntry->GetArea ()); 01186 destinationEntry->SetPathType (type2ExternalMetric ? OSPF::RoutingTableEntry::Type2External : OSPF::RoutingTableEntry::Type1External); 01187 if (type2ExternalMetric) { 01188 destinationEntry->SetCost (preferredCost); 01189 destinationEntry->SetType2Cost (externalCost); 01190 } else { 01191 destinationEntry->SetCost (preferredCost + externalCost); 01192 } 01193 destinationEntry->SetDestinationType (OSPF::RoutingTableEntry::NetworkDestination); 01194 destinationEntry->SetOptionalCapabilities (currentHeader.getLsOptions ()); 01195 destinationEntry->ClearNextHops (); 01196 01197 for (unsigned int j = 0; j < nextHopCount; j++) { 01198 NextHop nextHop = preferredEntry->GetNextHop (j); 01199 01200 nextHop.advertisingRouter = originatingRouter; 01201 destinationEntry->AddNextHop (nextHop); 01202 } 01203 } 01204 } 01205 }
|
|
Returns true if the destination described by the input lsa is in the routing table, false otherwise.
00596 { 00597 IPAddress destination = lsa->getHeader ().getLinkStateID (); 00598 00599 OSPFRouterLSA* routerLSA = dynamic_cast<OSPFRouterLSA*> (lsa); 00600 OSPFNetworkLSA* networkLSA = dynamic_cast<OSPFNetworkLSA*> (lsa); 00601 OSPFSummaryLSA* summaryLSA = dynamic_cast<OSPFSummaryLSA*> (lsa); 00602 OSPFASExternalLSA* asExternalLSA = dynamic_cast<OSPFASExternalLSA*> (lsa); 00603 // TODO: verify 00604 if (routerLSA != NULL) { 00605 OSPF::RoutingInfo* routingInfo = check_and_cast<OSPF::RoutingInfo*> (routerLSA); 00606 if (routerLSA->getHeader ().getLinkStateID () == routerID) { // this is spfTreeRoot 00607 return false; 00608 } 00609 00610 // get the interface address pointing backwards on the shortest path tree 00611 unsigned int linkCount = routerLSA->getLinksArraySize (); 00612 OSPF::RouterLSA* toRouterLSA = dynamic_cast<OSPF::RouterLSA*> (routingInfo->GetParent ()); 00613 if (toRouterLSA != NULL) { 00614 bool destinationFound = false; 00615 bool unnumberedPointToPointLink = false; 00616 IPAddress firstNumberedIfAddress; 00617 00618 for (unsigned int i = 0; i < linkCount; i++) { 00619 Link& link = routerLSA->getLinks (i); 00620 00621 if (link.getType () == PointToPointLink) { 00622 if (link.getLinkID () == toRouterLSA->getHeader ().getLinkStateID ()) { 00623 if ((link.getLinkData () & 0xFF000000) == 0) { 00624 unnumberedPointToPointLink = true; 00625 if (!firstNumberedIfAddress.isUnspecified ()) { 00626 break; 00627 } 00628 } else { 00629 destination = link.getLinkData (); 00630 destinationFound = true; 00631 break; 00632 } 00633 } else { 00634 if (((link.getLinkData () & 0xFF000000) != 0) && 00635 firstNumberedIfAddress.isUnspecified ()) 00636 { 00637 firstNumberedIfAddress = link.getLinkData (); 00638 } 00639 } 00640 } else if (link.getType () == TransitLink) { 00641 if (firstNumberedIfAddress.isUnspecified ()) { 00642 firstNumberedIfAddress = link.getLinkData (); 00643 } 00644 } else if (link.getType () == VirtualLink) { 00645 if (link.getLinkID () == toRouterLSA->getHeader ().getLinkStateID ()) { 00646 destination = link.getLinkData (); 00647 destinationFound = true; 00648 break; 00649 } else { 00650 if (firstNumberedIfAddress.isUnspecified ()) { 00651 firstNumberedIfAddress = link.getLinkData (); 00652 } 00653 } 00654 } 00655 // There's no way to get an interface address for the router from a StubLink 00656 } 00657 if (unnumberedPointToPointLink) { 00658 if (!firstNumberedIfAddress.isUnspecified ()) { 00659 destination = firstNumberedIfAddress; 00660 } else { 00661 return true; 00662 } 00663 } 00664 if (!destinationFound) { 00665 return true; 00666 } 00667 } else { 00668 OSPF::NetworkLSA* toNetworkLSA = dynamic_cast<OSPF::NetworkLSA*> (routingInfo->GetParent ()); 00669 if (toNetworkLSA != NULL) { 00670 // get the interface address pointing backwards on the shortest path tree 00671 bool destinationFound = false; 00672 for (unsigned int i = 0; i < linkCount; i++) { 00673 Link& link = routerLSA->getLinks (i); 00674 00675 if ((link.getType () == TransitLink) && 00676 (link.getLinkID () == toNetworkLSA->getHeader ().getLinkStateID ())) 00677 { 00678 destination = link.getLinkData (); 00679 destinationFound = true; 00680 break; 00681 } 00682 } 00683 if (!destinationFound) { 00684 return true; 00685 } 00686 } else { 00687 return true; 00688 } 00689 } 00690 } 00691 if (networkLSA != NULL) { 00692 destination = networkLSA->getHeader ().getLinkStateID () & networkLSA->getNetworkMask ().getInt (); 00693 } 00694 if ((summaryLSA != NULL) && (summaryLSA->getHeader ().getLsType () == SummaryLSA_NetworksType)) { 00695 destination = summaryLSA->getHeader ().getLinkStateID () & summaryLSA->getNetworkMask ().getInt (); 00696 } 00697 if (asExternalLSA != NULL) { 00698 destination = asExternalLSA->getHeader ().getLinkStateID () & asExternalLSA->getContents ().getNetworkMask ().getInt (); 00699 } 00700 00701 if (Lookup (destination) == NULL) { 00702 return true; 00703 } else { 00704 return false; 00705 } 00706 }
|
|
Find the AS External LSA identified by the input lsaKey in the database.
00332 { 00333 std::map<OSPF::LSAKeyType, OSPF::ASExternalLSA*, OSPF::LSAKeyType_Less>::const_iterator lsaIt = asExternalLSAsByID.find (lsaKey); 00334 if (lsaIt != asExternalLSAsByID.end ()) { 00335 return lsaIt->second; 00336 } else { 00337 return NULL; 00338 } 00339 }
|
|
Find the AS External LSA identified by the input lsaKey in the database.
00316 { 00317 std::map<OSPF::LSAKeyType, OSPF::ASExternalLSA*, OSPF::LSAKeyType_Less>::iterator lsaIt = asExternalLSAsByID.find (lsaKey); 00318 if (lsaIt != asExternalLSAsByID.end ()) { 00319 return lsaIt->second; 00320 } else { 00321 return NULL; 00322 } 00323 }
|
|
Find the LSA identified by the input lsaKey in the database.
00270 { 00271 switch (lsaType) { 00272 case RouterLSAType: 00273 { 00274 std::map<OSPF::AreaID, OSPF::Area*>::iterator areaIt = areasByID.find (areaID); 00275 if (areaIt != areasByID.end ()) { 00276 return areaIt->second->FindRouterLSA (lsaKey.linkStateID); 00277 } 00278 } 00279 break; 00280 case NetworkLSAType: 00281 { 00282 std::map<OSPF::AreaID, OSPF::Area*>::iterator areaIt = areasByID.find (areaID); 00283 if (areaIt != areasByID.end ()) { 00284 return areaIt->second->FindNetworkLSA (lsaKey.linkStateID); 00285 } 00286 } 00287 break; 00288 case SummaryLSA_NetworksType: 00289 case SummaryLSA_ASBoundaryRoutersType: 00290 { 00291 std::map<OSPF::AreaID, OSPF::Area*>::iterator areaIt = areasByID.find (areaID); 00292 if (areaIt != areasByID.end ()) { 00293 return areaIt->second->FindSummaryLSA (lsaKey); 00294 } 00295 } 00296 break; 00297 case ASExternalLSAType: 00298 { 00299 return FindASExternalLSA (lsaKey); 00300 } 00301 break; 00302 default: 00303 ASSERT (false); 00304 break; 00305 } 00306 return NULL; 00307 }
|
|
Floods out the input lsa on a set of Interfaces.
00510 { 00511 bool floodedBackOut = false; 00512 00513 if (lsa != NULL) { 00514 if (lsa->getHeader ().getLsType () == ASExternalLSAType) { 00515 long areaCount = areas.size (); 00516 for (long i = 0; i < areaCount; i++) { 00517 if (areas[i]->GetExternalRoutingCapability ()) { 00518 if (areas[i]->FloodLSA (lsa, intf, neighbor)) { 00519 floodedBackOut = true; 00520 } 00521 } 00522 } 00523 } else { 00524 std::map<OSPF::AreaID, OSPF::Area*>::iterator areaIt = areasByID.find (areaID); 00525 if (areaIt != areasByID.end ()) { 00526 floodedBackOut = areaIt->second->FloodLSA (lsa, intf, neighbor); 00527 } 00528 } 00529 } 00530 00531 return floodedBackOut; 00532 }
|
|
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. 00095 { 00096 long areaCount = areas.size (); 00097 for (long i = 0; i < areaCount; i++) { 00098 if (areas[i]->ContainsAddress (address)) { 00099 return areas[i]; 00100 } 00101 } 00102 return NULL; 00103 }
|
|
Returns the pointer to the Area identified by the input areaID, if it's on the Area list, NULL otherwise.
00078 { 00079 std::map<OSPF::AreaID, OSPF::Area*>::iterator areaIt = areasByID.find (areaID); 00080 if (areaIt != areasByID.end ()) { 00081 return (areaIt->second); 00082 } 00083 else { 00084 return NULL; 00085 } 00086 }
|
|
00041 { return areas.size (); }
|
|
00048 { return (externalRoutes.size () > 0); }
|
|
00047 { return asExternalLSAs[i]; }
|
|
00046 { return asExternalLSAs[i]; }
|
|
00045 { return asExternalLSAs.size (); }
|
|
Scans through the router's areas' preconfigured address ranges and returns the one containing the input addressRange.
01218 { 01219 unsigned long areaCount = areas.size (); 01220 for (unsigned long i = 0; i < areaCount; i++) { 01221 OSPF::IPv4AddressRange containingAddressRange = areas[i]->GetContainingAddressRange (addressRange, advertise); 01222 if (containingAddressRange != OSPF::NullIPv4AddressRange) { 01223 return containingAddressRange; 01224 } 01225 } 01226 if (advertise != NULL) { 01227 *advertise = false; 01228 } 01229 return OSPF::NullIPv4AddressRange; 01230 }
|
|
00043 { return messageHandler; }
|
|
Returns the pointer of the physical Interface identified by the input interface index, NULL if the Router doesn't have such an interface.
00112 { 00113 long areaCount = areas.size (); 00114 for (long i = 0; i < areaCount; i++) { 00115 OSPF::Interface* intf = areas[i]->GetInterface (ifIndex); 00116 if (intf != NULL) { 00117 return intf; 00118 } 00119 } 00120 return NULL; 00121 }
|
|
Selects the preferred routing table entry for the input LSA (which is either an ASExternalLSA or a SummaryLSA) according to the algorithm defined in RFC2328 Section 16.4. points (1) through (3). This method is used when calculating the AS external routes and also when originating an SummaryLSA for an AS Boundary Router.
01020 { 01021 if (fromRoutingTable == NULL) { 01022 fromRoutingTable = &routingTable; 01023 } 01024 01025 const OSPFLSAHeader& lsaHeader = lsa.getHeader (); 01026 const OSPFASExternalLSA* asExternalLSA = dynamic_cast<const OSPFASExternalLSA*> (&lsa); 01027 unsigned long externalCost = (asExternalLSA != NULL) ? asExternalLSA->getContents ().getRouteCost () : 0; 01028 unsigned short lsAge = lsaHeader.getLsAge (); 01029 OSPF::RouterID originatingRouter = lsaHeader.getAdvertisingRouter ().getInt (); 01030 bool selfOriginated = (originatingRouter == routerID); 01031 IPAddress forwardingAddress; // 0.0.0.0 01032 01033 if (asExternalLSA != NULL) { 01034 forwardingAddress = asExternalLSA->getContents ().getForwardingAddress (); 01035 } 01036 01037 if ((externalCost == LS_INFINITY) || (lsAge == MAX_AGE) || (skipSelfOriginated && selfOriginated)) { // (1) and (2) 01038 return NULL; 01039 } 01040 01041 if (!HasRouteToASBoundaryRouter (*fromRoutingTable, originatingRouter)) { // (3) 01042 return NULL; 01043 } 01044 01045 if (forwardingAddress.isUnspecified()) { // (3) 01046 std::vector<OSPF::RoutingTableEntry*> asbrEntries = GetRoutesToASBoundaryRouter (*fromRoutingTable, originatingRouter); 01047 if (!rfc1583Compatibility) { 01048 PruneASBoundaryRouterEntries (asbrEntries); 01049 } 01050 return SelectLeastCostRoutingEntry (asbrEntries); 01051 } else { 01052 OSPF::RoutingTableEntry* forwardEntry = Lookup (forwardingAddress, fromRoutingTable); 01053 01054 if (forwardEntry == NULL) { 01055 return NULL; 01056 } 01057 01058 if ((forwardEntry->GetPathType () != OSPF::RoutingTableEntry::IntraArea) && 01059 (forwardEntry->GetPathType () != OSPF::RoutingTableEntry::InterArea)) 01060 { 01061 return NULL; 01062 } 01063 01064 return forwardEntry; 01065 } 01066 01067 return NULL; 01068 }
|
|
00040 { return rfc1583Compatibility; }
|
|
00038 { return routerID; }
|
|
Returns an std::vector of routes leading to the AS Boundary Router identified by asbrRouterID from the input fromRoutingTable. If there are no routes leading to the AS Boundary Router, the returned std::vector is empty.
00921 { 00922 std::vector<OSPF::RoutingTableEntry*> results; 00923 long routeCount = fromRoutingTable.size (); 00924 00925 for (long i = 0; i < routeCount; i++) { 00926 OSPF::RoutingTableEntry* routingEntry = fromRoutingTable[i]; 00927 if (((routingEntry->GetDestinationType () & OSPF::RoutingTableEntry::ASBoundaryRouterDestination) != 0) && 00928 (routingEntry->GetDestinationID ().getInt () == asbrRouterID)) 00929 { 00930 results.push_back (routingEntry); 00931 } 00932 } 00933 return results; 00934 }
|
|
00052 { return routingTable[i]; }
|
|
00051 { return routingTable[i]; }
|
|
00050 { return routingTable.size (); }
|
|
Generates a unique LinkStateID for a given destination. This may require the reorigination of an LSA already in the database (with a different LinkStateID).
01252 { 01253 if (lsaToReoriginate != NULL) { 01254 delete lsaToReoriginate; 01255 lsaToReoriginate = NULL; 01256 } 01257 01258 OSPF::LSAKeyType lsaKey; 01259 01260 lsaKey.linkStateID = ULongFromIPv4Address (destination.address); 01261 lsaKey.advertisingRouter = routerID; 01262 01263 const OSPF::ASExternalLSA* foundLSA = FindASExternalLSA (lsaKey); 01264 01265 if (foundLSA == NULL) { 01266 return lsaKey.linkStateID; 01267 } else { 01268 OSPF::IPv4Address existingMask = IPv4AddressFromULong (foundLSA->getContents ().getNetworkMask ().getInt ()); 01269 01270 if (destination.mask >= existingMask) { 01271 return (lsaKey.linkStateID | (~(ULongFromIPv4Address (destination.mask)))); 01272 } else { 01273 OSPF::ASExternalLSA* asExternalLSA = new OSPF::ASExternalLSA (*foundLSA); 01274 01275 long sequenceNumber = asExternalLSA->getHeader ().getLsSequenceNumber (); 01276 01277 asExternalLSA->getHeader ().setLsAge (0); 01278 asExternalLSA->getHeader ().setLsSequenceNumber ((sequenceNumber == MAX_SEQUENCE_NUMBER) ? INITIAL_SEQUENCE_NUMBER : sequenceNumber + 1); 01279 asExternalLSA->getContents ().setNetworkMask (ULongFromIPv4Address (destination.mask)); 01280 asExternalLSA->getContents ().setE_ExternalMetricType (externalMetricIsType2); 01281 asExternalLSA->getContents ().setRouteCost (destinationCost); 01282 asExternalLSA->getHeader ().setLsChecksum (0); // TODO: calculate correct LS checksum 01283 01284 lsaToReoriginate = asExternalLSA; 01285 01286 return (lsaKey.linkStateID | (~(ULongFromIPv4Address (existingMask)))); 01287 } 01288 } 01289 }
|
|
Returns true if one of the Router's Areas the same IP address range configured as the input IP address range, false otherwise.
00558 { 00559 long areaCount = areas.size (); 00560 for (long i = 0; i < areaCount; i++) { 00561 if (areas[i]->HasAddressRange (addressRange)) { 00562 return true; 00563 } 00564 } 00565 return false; 00566 }
|
|
Returns true if there is a route to the AS Boundary Router identified by asbrRouterID in the input inRoutingTable, false otherwise.
00899 { 00900 long routeCount = inRoutingTable.size (); 00901 for (long i = 0; i < routeCount; i++) { 00902 OSPF::RoutingTableEntry* routingEntry = inRoutingTable[i]; 00903 if (((routingEntry->GetDestinationType () & OSPF::RoutingTableEntry::ASBoundaryRouterDestination) != 0) && 00904 (routingEntry->GetDestinationID ().getInt () == asbrRouterID)) 00905 { 00906 return true; 00907 } 00908 } 00909 return false; 00910 }
|
|
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.)
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... 00185 { 00203 // TODO: how to solve this problem? 00204 00205 OSPF::RouterID advertisingRouter = lsa->getHeader ().getAdvertisingRouter ().getInt (); 00206 bool reachable = false; 00207 unsigned int routeCount = routingTable.size (); 00208 00209 for (unsigned int i = 0; i < routeCount; i++) { 00210 if ((((routingTable[i]->GetDestinationType () & OSPF::RoutingTableEntry::AreaBorderRouterDestination) != 0) || 00211 ((routingTable[i]->GetDestinationType () & OSPF::RoutingTableEntry::ASBoundaryRouterDestination) != 0)) && 00212 (routingTable[i]->GetDestinationID ().getInt () == advertisingRouter)) 00213 { 00214 reachable = true; 00215 break; 00216 } 00217 } 00218 00219 bool ownLSAFloodedOut = false; 00220 OSPF::LSAKeyType lsaKey; 00221 00222 lsaKey.linkStateID = lsa->getHeader ().getLinkStateID (); 00223 lsaKey.advertisingRouter = routerID; 00224 00225 std::map<OSPF::LSAKeyType, OSPF::ASExternalLSA*, OSPF::LSAKeyType_Less>::iterator lsaIt = asExternalLSAsByID.find (lsaKey); 00226 if ((lsaIt != asExternalLSAsByID.end ()) && 00227 reachable && 00228 (lsaIt->second->getContents ().getE_ExternalMetricType () == lsa->getContents ().getE_ExternalMetricType ()) && 00229 (lsaIt->second->getContents ().getRouteCost () == lsa->getContents ().getRouteCost ()) && 00230 (lsa->getContents ().getForwardingAddress ().getInt () != 0) && // forwarding address != 0.0.0.0 00231 (lsaIt->second->getContents ().getForwardingAddress () == lsa->getContents ().getForwardingAddress ())) 00232 { 00233 if (routerID > advertisingRouter) { 00234 return false; 00235 } else { 00236 lsaIt->second->getHeader ().setLsAge (MAX_AGE); 00237 FloodLSA (lsaIt->second, OSPF::BackboneAreaID); 00238 lsaIt->second->IncrementInstallTime (); 00239 ownLSAFloodedOut = true; 00240 } 00241 } 00242 00243 lsaKey.advertisingRouter = advertisingRouter; 00244 00245 lsaIt = asExternalLSAsByID.find (lsaKey); 00246 if (lsaIt != asExternalLSAsByID.end ()) { 00247 unsigned long areaCount = areas.size (); 00248 for (unsigned long i = 0; i < areaCount; i++) { 00249 areas[i]->RemoveFromAllRetransmissionLists (lsaKey); 00250 } 00251 return ((lsaIt->second->Update (lsa)) | ownLSAFloodedOut); 00252 } else { 00253 OSPF::ASExternalLSA* lsaCopy = new OSPF::ASExternalLSA (*lsa); 00254 asExternalLSAsByID[lsaKey] = lsaCopy; 00255 asExternalLSAs.push_back (lsaCopy); 00256 return true; 00257 } 00258 }
|
|
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.
00133 { 00134 switch (lsa->getHeader ().getLsType ()) { 00135 case RouterLSAType: 00136 { 00137 std::map<OSPF::AreaID, OSPF::Area*>::iterator areaIt = areasByID.find (areaID); 00138 if (areaIt != areasByID.end ()) { 00139 OSPFRouterLSA* ospfRouterLSA = check_and_cast<OSPFRouterLSA*> (lsa); 00140 return areaIt->second->InstallRouterLSA (ospfRouterLSA); 00141 } 00142 } 00143 break; 00144 case NetworkLSAType: 00145 { 00146 std::map<OSPF::AreaID, OSPF::Area*>::iterator areaIt = areasByID.find (areaID); 00147 if (areaIt != areasByID.end ()) { 00148 OSPFNetworkLSA* ospfNetworkLSA = check_and_cast<OSPFNetworkLSA*> (lsa); 00149 return areaIt->second->InstallNetworkLSA (ospfNetworkLSA); 00150 } 00151 } 00152 break; 00153 case SummaryLSA_NetworksType: 00154 case SummaryLSA_ASBoundaryRoutersType: 00155 { 00156 std::map<OSPF::AreaID, OSPF::Area*>::iterator areaIt = areasByID.find (areaID); 00157 if (areaIt != areasByID.end ()) { 00158 OSPFSummaryLSA* ospfSummaryLSA = check_and_cast<OSPFSummaryLSA*> (lsa); 00159 return areaIt->second->InstallSummaryLSA (ospfSummaryLSA); 00160 } 00161 } 00162 break; 00163 case ASExternalLSAType: 00164 { 00165 OSPFASExternalLSA* ospfASExternalLSA = check_and_cast<OSPFASExternalLSA*> (lsa); 00166 return InstallASExternalLSA (ospfASExternalLSA); 00167 } 00168 break; 00169 default: 00170 ASSERT (false); 00171 break; 00172 } 00173 return false; 00174 }
|
|
Returns true if the input IP address falls into any of the Router's Areas' configured IP address ranges, false otherwise.
00541 { 00542 long areaCount = areas.size (); 00543 for (long i = 0; i < areaCount; i++) { 00544 if (areas[i]->IsLocalAddress (address)) { 00545 return true; 00546 } 00547 } 00548 return false; 00549 }
|
|
Returns true if there's at least one LSA on any Neighbor's retransmission list identified by the input lsaKey, false otherwise.
00489 { 00490 long areaCount = areas.size (); 00491 for (long i = 0; i < areaCount; i++) { 00492 if (areas[i]->IsOnAnyRetransmissionList (lsaKey)) { 00493 return true; 00494 } 00495 } 00496 return false; 00497 }
|
|
Do a lookup in either the input OSPF routing table, or if it's NULL then in the Router's own routing table.
00717 { 00718 const std::vector<OSPF::RoutingTableEntry*>& rTable = (table == NULL) ? routingTable : (*table); 00719 unsigned long dest = destination.getInt (); 00720 unsigned long routingTableSize = rTable.size (); 00721 bool unreachable = false; 00722 std::vector<OSPF::RoutingTableEntry*> discard; 00723 unsigned long i; 00724 00725 unsigned long areaCount = areas.size (); 00726 for (i = 0; i < areaCount; i++) { 00727 unsigned int addressRangeCount = areas[i]->GetAddressRangeCount (); 00728 for (unsigned int j = 0; j < addressRangeCount; j++) { 00729 OSPF::IPv4AddressRange range = areas[i]->GetAddressRange (j); 00730 00731 for (unsigned int k = 0; k < routingTableSize; k++) { 00732 OSPF::RoutingTableEntry* entry = rTable[k]; 00733 00734 if (entry->GetDestinationType () != OSPF::RoutingTableEntry::NetworkDestination) { 00735 continue; 00736 } 00737 if (((entry->GetDestinationID ().getInt () & entry->GetAddressMask ().getInt () & ULongFromIPv4Address (range.mask)) == ULongFromIPv4Address (range.address & range.mask)) && 00738 (entry->GetPathType () == OSPF::RoutingTableEntry::IntraArea)) 00739 { 00740 // active area address range 00741 OSPF::RoutingTableEntry* discardEntry = new OSPF::RoutingTableEntry; 00742 discardEntry->SetDestinationID (ULongFromIPv4Address (range.address)); 00743 discardEntry->SetAddressMask (ULongFromIPv4Address (range.mask)); 00744 discardEntry->SetDestinationType (OSPF::RoutingTableEntry::NetworkDestination); 00745 discardEntry->SetPathType (OSPF::RoutingTableEntry::InterArea); 00746 discardEntry->SetArea (areas[i]->GetAreaID ()); 00747 discard.push_back (discardEntry); 00748 break; 00749 } 00750 } 00751 } 00752 } 00753 00754 OSPF::RoutingTableEntry* bestMatch = NULL; 00755 unsigned long longestMatch = 0; 00756 00757 for (i = 0; i < routingTableSize; i++) { 00758 if (rTable[i]->GetDestinationType () == OSPF::RoutingTableEntry::NetworkDestination) { 00759 OSPF::RoutingTableEntry* entry = rTable[i]; 00760 unsigned long entryAddress = entry->GetDestinationID ().getInt (); 00761 unsigned long entryMask = entry->GetAddressMask ().getInt (); 00762 00763 if ((entryAddress & entryMask) == (dest & entryMask)) { 00764 if ((dest & entryMask) > longestMatch) { 00765 longestMatch = (dest & entryMask); 00766 bestMatch = entry; 00767 } 00768 } 00769 } 00770 } 00771 00772 unsigned int discardCount = discard.size (); 00773 if (bestMatch == NULL) { 00774 unreachable = true; 00775 } else { 00776 for (i = 0; i < discardCount; i++) { 00777 OSPF::RoutingTableEntry* entry = discard[i]; 00778 unsigned long entryAddress = entry->GetDestinationID ().getInt (); 00779 unsigned long entryMask = entry->GetAddressMask ().getInt (); 00780 00781 if ((entryAddress & entryMask) == (dest & entryMask)) { 00782 if ((dest & entryMask) > longestMatch) { 00783 unreachable = true; 00784 break; 00785 } 00786 } 00787 } 00788 } 00789 00790 for (i = 0; i < discardCount; i++) { 00791 delete discard[i]; 00792 } 00793 00794 if (unreachable) { 00795 return NULL; 00796 } else { 00797 return bestMatch; 00798 } 00799 }
|
|
After a routing table rebuild the changes in the routing table are identified and new SummaryLSAs are originated or old ones are flooded out in each area as necessary.
01302 { 01303 if (areas.size () <= 1) { 01304 return; 01305 } 01306 01307 unsigned long routeCount = oldRoutingTable.size (); 01308 std::map<unsigned long, RoutingTableEntry*> oldTableMap; 01309 std::map<unsigned long, RoutingTableEntry*> newTableMap; 01310 unsigned long i, j, k; 01311 01312 for (i = 0; i < routeCount; i++) { 01313 unsigned long destination = oldRoutingTable[i]->GetDestinationID ().getInt () & oldRoutingTable[i]->GetAddressMask ().getInt (); 01314 oldTableMap[destination] = oldRoutingTable[i]; 01315 } 01316 01317 routeCount = routingTable.size (); 01318 for (i = 0; i < routeCount; i++) { 01319 unsigned long destination = routingTable[i]->GetDestinationID ().getInt () & routingTable[i]->GetAddressMask ().getInt (); 01320 newTableMap[destination] = routingTable[i]; 01321 } 01322 01323 unsigned long areaCount = areas.size (); 01324 for (i = 0; i < areaCount; i++) { 01325 std::map<OSPF::LSAKeyType, bool, OSPF::LSAKeyType_Less> originatedLSAMap; 01326 std::map<OSPF::LSAKeyType, bool, OSPF::LSAKeyType_Less> deletedLSAMap; 01327 OSPF::LSAKeyType lsaKey; 01328 01329 routeCount = routingTable.size (); 01330 for (j = 0; j < routeCount; j++) { 01331 unsigned long destination = routingTable[j]->GetDestinationID ().getInt () & routingTable[j]->GetAddressMask ().getInt (); 01332 std::map<unsigned long, RoutingTableEntry*>::iterator destIt = oldTableMap.find (destination); 01333 if (destIt == oldTableMap.end ()) { // new routing entry 01334 OSPF::SummaryLSA* lsaToReoriginate = NULL; 01335 OSPF::SummaryLSA* newLSA = areas[i]->OriginateSummaryLSA (routingTable[j], originatedLSAMap, lsaToReoriginate); 01336 01337 if (newLSA != NULL) { 01338 if (lsaToReoriginate != NULL) { 01339 areas[i]->InstallSummaryLSA (lsaToReoriginate); 01340 // FloodLSA (lsaToReoriginate, OSPF::BackboneAreaID); 01341 FloodLSA (lsaToReoriginate, areas[i]->GetAreaID ()); 01342 01343 lsaKey.linkStateID = lsaToReoriginate->getHeader ().getLinkStateID (); 01344 lsaKey.advertisingRouter = routerID; 01345 originatedLSAMap[lsaKey] = true; 01346 01347 delete lsaToReoriginate; 01348 } 01349 01350 areas[i]->InstallSummaryLSA (newLSA); 01351 // FloodLSA (newLSA, OSPF::BackboneAreaID); 01352 FloodLSA (newLSA, areas[i]->GetAreaID ()); 01353 01354 lsaKey.linkStateID = newLSA->getHeader ().getLinkStateID (); 01355 lsaKey.advertisingRouter = routerID; 01356 originatedLSAMap[lsaKey] = true; 01357 01358 delete newLSA; 01359 } 01360 } else { 01361 if (*(routingTable[j]) != *(destIt->second)) { // modified routing entry 01362 OSPF::SummaryLSA* lsaToReoriginate = NULL; 01363 OSPF::SummaryLSA* newLSA = areas[i]->OriginateSummaryLSA (routingTable[j], originatedLSAMap, lsaToReoriginate); 01364 01365 if (newLSA != NULL) { 01366 if (lsaToReoriginate != NULL) { 01367 areas[i]->InstallSummaryLSA (lsaToReoriginate); 01368 // FloodLSA (lsaToReoriginate, OSPF::BackboneAreaID); 01369 FloodLSA (lsaToReoriginate, areas[i]->GetAreaID ()); 01370 01371 lsaKey.linkStateID = lsaToReoriginate->getHeader ().getLinkStateID (); 01372 lsaKey.advertisingRouter = routerID; 01373 originatedLSAMap[lsaKey] = true; 01374 01375 delete lsaToReoriginate; 01376 } 01377 01378 areas[i]->InstallSummaryLSA (newLSA); 01379 // FloodLSA (newLSA, OSPF::BackboneAreaID); 01380 FloodLSA (newLSA, areas[i]->GetAreaID ()); 01381 01382 lsaKey.linkStateID = newLSA->getHeader ().getLinkStateID (); 01383 lsaKey.advertisingRouter = routerID; 01384 originatedLSAMap[lsaKey] = true; 01385 01386 delete newLSA; 01387 } else { 01388 OSPF::IPv4AddressRange destinationAddressRange; 01389 01390 destinationAddressRange.address = IPv4AddressFromULong (routingTable[j]->GetDestinationID ().getInt ()); 01391 destinationAddressRange.mask = IPv4AddressFromULong (routingTable[j]->GetAddressMask ().getInt ()); 01392 01393 if ((routingTable[j]->GetDestinationType () == OSPF::RoutingTableEntry::NetworkDestination) && 01394 ((routingTable[j]->GetPathType () == OSPF::RoutingTableEntry::IntraArea) || 01395 (routingTable[j]->GetPathType () == OSPF::RoutingTableEntry::InterArea))) 01396 { 01397 OSPF::IPv4AddressRange containingAddressRange = GetContainingAddressRange (destinationAddressRange); 01398 if (containingAddressRange != OSPF::NullIPv4AddressRange) { 01399 destinationAddressRange = containingAddressRange; 01400 } 01401 } 01402 01403 Metric maxRangeCost = 0; 01404 Metric oneLessCost = 0; 01405 01406 for (k = 0; k < routeCount; k++) { 01407 if ((routingTable[k]->GetDestinationType () == OSPF::RoutingTableEntry::NetworkDestination) && 01408 (routingTable[k]->GetPathType () == OSPF::RoutingTableEntry::IntraArea) && 01409 ((routingTable[k]->GetDestinationID ().getInt () & routingTable[k]->GetAddressMask ().getInt () & ULongFromIPv4Address (destinationAddressRange.mask)) == 01410 ULongFromIPv4Address (destinationAddressRange.address & destinationAddressRange.mask)) && 01411 (routingTable[k]->GetCost () > maxRangeCost)) 01412 { 01413 oneLessCost = maxRangeCost; 01414 maxRangeCost = routingTable[k]->GetCost (); 01415 } 01416 } 01417 01418 if (maxRangeCost == routingTable[j]->GetCost ()) { // this entry gives the range's cost 01419 lsaKey.linkStateID = ULongFromIPv4Address (destinationAddressRange.address); 01420 lsaKey.advertisingRouter = routerID; 01421 01422 OSPF::SummaryLSA* summaryLSA = areas[i]->FindSummaryLSA (lsaKey); 01423 01424 if (summaryLSA != NULL) { 01425 if (oneLessCost != 0) { // there's an other entry in this range 01426 summaryLSA->setRouteCost (oneLessCost); 01427 // FloodLSA (summaryLSA, OSPF::BackboneAreaID); 01428 FloodLSA (summaryLSA, areas[i]->GetAreaID ()); 01429 01430 originatedLSAMap[lsaKey] = true; 01431 } else { // no more entries in this range -> delete it 01432 std::map<OSPF::LSAKeyType, bool, OSPF::LSAKeyType_Less>::const_iterator deletedIt = deletedLSAMap.find (lsaKey); 01433 if (deletedIt == deletedLSAMap.end ()) { 01434 summaryLSA->getHeader ().setLsAge (MAX_AGE); 01435 // FloodLSA (summaryLSA, OSPF::BackboneAreaID); 01436 FloodLSA (summaryLSA, areas[i]->GetAreaID ()); 01437 01438 deletedLSAMap[lsaKey] = true; 01439 } 01440 } 01441 } 01442 } 01443 } 01444 } 01445 } 01446 } 01447 01448 routeCount = oldRoutingTable.size (); 01449 for (j = 0; j < routeCount; j++) { 01450 unsigned long destination = oldRoutingTable[j]->GetDestinationID ().getInt () & oldRoutingTable[j]->GetAddressMask ().getInt (); 01451 std::map<unsigned long, RoutingTableEntry*>::iterator destIt = newTableMap.find (destination); 01452 if (destIt == newTableMap.end ()) { // deleted routing entry 01453 OSPF::IPv4AddressRange destinationAddressRange; 01454 01455 destinationAddressRange.address = IPv4AddressFromULong (oldRoutingTable[j]->GetDestinationID ().getInt ()); 01456 destinationAddressRange.mask = IPv4AddressFromULong (oldRoutingTable[j]->GetAddressMask ().getInt ()); 01457 01458 if ((oldRoutingTable[j]->GetDestinationType () == OSPF::RoutingTableEntry::NetworkDestination) && 01459 ((oldRoutingTable[j]->GetPathType () == OSPF::RoutingTableEntry::IntraArea) || 01460 (oldRoutingTable[j]->GetPathType () == OSPF::RoutingTableEntry::InterArea))) 01461 { 01462 OSPF::IPv4AddressRange containingAddressRange = GetContainingAddressRange (destinationAddressRange); 01463 if (containingAddressRange != OSPF::NullIPv4AddressRange) { 01464 destinationAddressRange = containingAddressRange; 01465 } 01466 } 01467 01468 Metric maxRangeCost = 0; 01469 01470 unsigned long newRouteCount = routingTable.size (); 01471 for (k = 0; k < newRouteCount; k++) { 01472 if ((routingTable[k]->GetDestinationType () == OSPF::RoutingTableEntry::NetworkDestination) && 01473 (routingTable[k]->GetPathType () == OSPF::RoutingTableEntry::IntraArea) && 01474 ((routingTable[k]->GetDestinationID ().getInt () & routingTable[k]->GetAddressMask ().getInt () & ULongFromIPv4Address (destinationAddressRange.mask)) == 01475 ULongFromIPv4Address (destinationAddressRange.address & destinationAddressRange.mask)) && 01476 (routingTable[k]->GetCost () > maxRangeCost)) 01477 { 01478 maxRangeCost = routingTable[k]->GetCost (); 01479 } 01480 } 01481 01482 if (maxRangeCost < oldRoutingTable[j]->GetCost ()) { // the range's cost will change 01483 lsaKey.linkStateID = ULongFromIPv4Address (destinationAddressRange.address); 01484 lsaKey.advertisingRouter = routerID; 01485 01486 OSPF::SummaryLSA* summaryLSA = areas[i]->FindSummaryLSA (lsaKey); 01487 01488 if (summaryLSA != NULL) { 01489 if (maxRangeCost > 0) { // there's an other entry in this range 01490 summaryLSA->setRouteCost (maxRangeCost); 01491 FloodLSA (summaryLSA, OSPF::BackboneAreaID); 01492 01493 originatedLSAMap[lsaKey] = true; 01494 } else { // no more entries in this range -> delete it 01495 std::map<OSPF::LSAKeyType, bool, OSPF::LSAKeyType_Less>::const_iterator deletedIt = deletedLSAMap.find (lsaKey); 01496 if (deletedIt == deletedLSAMap.end ()) { 01497 summaryLSA->getHeader ().setLsAge (MAX_AGE); 01498 FloodLSA (summaryLSA, OSPF::BackboneAreaID); 01499 01500 deletedLSAMap[lsaKey] = true; 01501 } 01502 } 01503 } 01504 } 01505 } 01506 } 01507 } 01508 }
|
|
Originates a new AS External LSA based on the input lsa.
00575 { 00576 OSPF::ASExternalLSA* asExternalLSA = new OSPF::ASExternalLSA (*lsa); 00577 OSPFLSAHeader& lsaHeader = asExternalLSA->getHeader (); 00578 OSPFOptions lsaOptions; 00579 00580 lsaHeader.setLsAge (0); 00581 memset (&lsaOptions, 0, sizeof (OSPFOptions)); 00582 lsaOptions.E_ExternalRoutingCapability = true; 00583 lsaHeader.setLsOptions (lsaOptions); 00584 lsaHeader.setLsSequenceNumber (INITIAL_SEQUENCE_NUMBER); 00585 asExternalLSA->SetSource (OSPF::LSATrackingInfo::Originated); 00586 00587 return asExternalLSA; 00588 }
|
|
Prunes the input std::vector of RoutingTableEntries according to the RFC2328 Section 16.4.1.
00944 { 00945 bool hasNonBackboneIntraAreaPath = false; 00946 for (std::vector<OSPF::RoutingTableEntry*>::iterator it = asbrEntries.begin (); it != asbrEntries.end (); it++) { 00947 OSPF::RoutingTableEntry* routingEntry = *it; 00948 if ((routingEntry->GetPathType () == OSPF::RoutingTableEntry::IntraArea) && 00949 (routingEntry->GetArea () != OSPF::BackboneAreaID)) 00950 { 00951 hasNonBackboneIntraAreaPath = true; 00952 break; 00953 } 00954 } 00955 00956 if (hasNonBackboneIntraAreaPath) { 00957 std::vector<OSPF::RoutingTableEntry*>::iterator it = asbrEntries.begin (); 00958 while (it != asbrEntries.end ()) { 00959 if (((*it)->GetPathType () != OSPF::RoutingTableEntry::IntraArea) || 00960 ((*it)->GetArea () == OSPF::BackboneAreaID)) 00961 { 00962 it = asbrEntries.erase (it); 00963 } else { 00964 it++; 00965 } 00966 } 00967 } 00968 }
|
|
Rebuilds the routing table from scratch (based on the LSA database).
00807 { 00808 unsigned long areaCount = areas.size (); 00809 bool hasTransitAreas = false; 00810 std::vector<OSPF::RoutingTableEntry*> newTable; 00811 unsigned long i; 00812 00813 EV << "Rebuilding routing table:\n"; 00814 00815 for (i = 0; i < areaCount; i++) { 00816 areas[i]->CalculateShortestPathTree (newTable); 00817 if (areas[i]->GetTransitCapability ()) { 00818 hasTransitAreas = true; 00819 } 00820 } 00821 if (areaCount > 1) { 00822 OSPF::Area* backbone = GetArea (OSPF::BackboneAreaID); 00823 if (backbone != NULL) { 00824 backbone->CalculateInterAreaRoutes (newTable); 00825 } 00826 } else { 00827 if (areaCount == 1) { 00828 areas[0]->CalculateInterAreaRoutes (newTable); 00829 } 00830 } 00831 if (hasTransitAreas) { 00832 for (i = 0; i < areaCount; i++) { 00833 if (areas[i]->GetTransitCapability ()) { 00834 areas[i]->ReCheckSummaryLSAs (newTable); 00835 } 00836 } 00837 } 00838 CalculateASExternalRoutes (newTable); 00839 00840 // backup the routing table 00841 unsigned long routeCount = routingTable.size (); 00842 std::vector<OSPF::RoutingTableEntry*> oldTable; 00843 00844 oldTable.assign (routingTable.begin (), routingTable.end ()); 00845 routingTable.clear (); 00846 routingTable.assign (newTable.begin (), newTable.end ()); 00847 00848 RoutingTableAccess routingTableAccess; 00849 std::vector<RoutingEntry*> eraseEntries; 00850 RoutingTable* simRoutingTable = routingTableAccess.get (); 00851 unsigned long routingEntryNumber = simRoutingTable->numRoutingEntries (); 00852 // remove entries from the IP routing table inserted by the OSPF module 00853 for (i = 0; i < routingEntryNumber; i++) { 00854 RoutingEntry* entry = simRoutingTable->routingEntry (i); 00855 OSPF::RoutingTableEntry* ospfEntry = dynamic_cast<OSPF::RoutingTableEntry*> (entry); 00856 if (ospfEntry != NULL) { 00857 eraseEntries.push_back (entry); 00858 } 00859 } 00860 00861 unsigned int eraseCount = eraseEntries.size (); 00862 for (i = 0; i < eraseCount; i++) { 00863 simRoutingTable->deleteRoutingEntry (eraseEntries[i]); 00864 } 00865 00866 // add the new routing entries 00867 routeCount = routingTable.size (); 00868 for (i = 0; i < routeCount; i++) { 00869 if (routingTable[i]->GetDestinationType () == OSPF::RoutingTableEntry::NetworkDestination) { 00870 simRoutingTable->addRoutingEntry (new OSPF::RoutingTableEntry (*(routingTable[i]))); 00871 } 00872 } 00873 00874 NotifyAboutRoutingTableChanges (oldTable); 00875 00876 routeCount = oldTable.size (); 00877 for (i = 0; i < routeCount; i++) { 00878 delete (oldTable[i]); 00879 } 00880 00881 EV << "Routing table was rebuilt.\n" 00882 << "Results:\n"; 00883 00884 routeCount = routingTable.size (); 00885 for (i = 0; i < routeCount; i++) { 00886 EV << *routingTable[i] 00887 << "\n"; 00888 } 00889 }
|
|
Removes an AS External Route from the database.
01582 { 01583 OSPF::LSAKeyType lsaKey; 01584 01585 lsaKey.linkStateID = ULongFromIPv4Address (networkAddress); 01586 lsaKey.advertisingRouter = routerID; 01587 01588 std::map<OSPF::LSAKeyType, OSPF::ASExternalLSA*, OSPF::LSAKeyType_Less>::iterator lsaIt = asExternalLSAsByID.find (lsaKey); 01589 if (lsaIt != asExternalLSAsByID.end ()) { 01590 lsaIt->second->getHeader ().setLsAge (MAX_AGE); 01591 lsaIt->second->SetPurgeable (); 01592 FloodLSA (lsaIt->second, OSPF::BackboneAreaID); 01593 } 01594 01595 std::map<OSPF::IPv4Address, OSPFASExternalLSAContents, OSPF::IPv4Address_Less>::iterator externalIt = externalRoutes.find (networkAddress); 01596 if (externalIt != externalRoutes.end ()) { 01597 externalRoutes.erase (externalIt); 01598 } 01599 }
|
|
Removes all LSAs from all Neighbor's retransmission lists which are identified by the input lsaKey.
00475 { 00476 long areaCount = areas.size (); 00477 for (long i = 0; i < areaCount; i++) { 00478 areas[i]->RemoveFromAllRetransmissionLists (lsaKey); 00479 } 00480 }
|
|
Selects the least cost RoutingTableEntry from the input std::vector of RoutingTableEntries.
00978 { 00979 if (entries.empty ()) { 00980 return NULL; 00981 } 00982 00983 OSPF::RoutingTableEntry* leastCostEntry = entries[0]; 00984 Metric leastCost = leastCostEntry->GetCost (); 00985 long routeCount = entries.size (); 00986 00987 for (long i = 1; i < routeCount; i++) { 00988 Metric currentCost = entries[i]->GetCost (); 00989 if ((currentCost < leastCost) || 00990 ((currentCost == leastCost) && (entries[i]->GetArea () > leastCostEntry->GetArea ()))) 00991 { 00992 leastCostEntry = entries[i]; 00993 leastCost = currentCost; 00994 } 00995 } 00996 00997 return leastCostEntry; 00998 }
|
|
00039 { rfc1583Compatibility = compatibility; }
|
|
00037 { routerID = id; }
|
|
Stores information on an AS External Route in externalRoutes and intalls (or updates) a new ASExternalLSA into the database.
01519 { 01520 OSPF::ASExternalLSA* asExternalLSA = new OSPF::ASExternalLSA; 01521 OSPFLSAHeader& lsaHeader = asExternalLSA->getHeader (); 01522 OSPFOptions lsaOptions; 01523 //OSPF::LSAKeyType lsaKey; 01524 01525 RoutingTable* simRoutingTable = RoutingTableAccess ().get (); 01526 unsigned long routingEntryNumber = simRoutingTable->numRoutingEntries (); 01527 bool inRoutingTable = false; 01528 // add the external route to the routing table if it was not added by another module 01529 for (unsigned long i = 0; i < routingEntryNumber; i++) { 01530 RoutingEntry* entry = simRoutingTable->routingEntry (i); 01531 if ((entry->host.getInt () & entry->netmask.getInt ()) == 01532 (ULongFromIPv4Address (networkAddress) & externalRouteContents.getNetworkMask ().getInt ())) 01533 { 01534 inRoutingTable = true; 01535 } 01536 } 01537 if (!inRoutingTable) { 01538 RoutingEntry* entry = new RoutingEntry; 01539 entry->host = ULongFromIPv4Address (networkAddress); 01540 entry->netmask = externalRouteContents.getNetworkMask (); 01541 entry->interfacePtr = InterfaceTableAccess ().get ()->interfaceAt (ifIndex); 01542 entry->interfaceName = entry->interfacePtr->name (); 01543 entry->type = RoutingEntry::REMOTE; 01544 entry->source = RoutingEntry::MANUAL; 01545 entry->metric = externalRouteContents.getRouteCost (); 01546 simRoutingTable->addRoutingEntry (entry); // RoutingTable deletes entry pointer 01547 } 01548 01549 lsaHeader.setLsAge (0); 01550 memset (&lsaOptions, 0, sizeof (OSPFOptions)); 01551 lsaOptions.E_ExternalRoutingCapability = true; 01552 lsaHeader.setLsOptions (lsaOptions); 01553 lsaHeader.setLsType (ASExternalLSAType); 01554 lsaHeader.setLinkStateID (ULongFromIPv4Address (networkAddress)); // TODO: get unique LinkStateID 01555 lsaHeader.setAdvertisingRouter (routerID); 01556 lsaHeader.setLsSequenceNumber (INITIAL_SEQUENCE_NUMBER); 01557 01558 asExternalLSA->setContents (externalRouteContents); 01559 01560 lsaHeader.setLsChecksum (0); // TODO: calculate correct LS checksum 01561 01562 asExternalLSA->SetSource (OSPF::LSATrackingInfo::Originated); 01563 01564 externalRoutes[networkAddress] = externalRouteContents; 01565 01566 bool rebuild = InstallASExternalLSA (asExternalLSA); 01567 FloodLSA (asExternalLSA, OSPF::BackboneAreaID); 01568 delete asExternalLSA; 01569 01570 if (rebuild) { 01571 RebuildRoutingTable (); 01572 } 01573 }
|
|
Database age timer - fires every second.
|
|
A list of the contained areas.
|
|
A map of the contained areas with the AreaID as key.
|
|
A list of the ASExternalLSAs advertised by this router.
|
|
A map of the ASExternalLSAs advertised by this router.
|
|
A map of the external route advertised by this router.
|
|
The message dispatcher class.
|
|
Decides whether to handle the preferred routing table entry to an AS boundary router as defined in RFC1583 or not.
|
|
The router ID assigned by the IP layer.
|
|
The OSPF routing table - contains more information than the one in the IP layer.
|