00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "OSPFRouter.h"
00019 #include "RoutingTableAccess.h"
00020
00025 OSPF::Router::Router(OSPF::RouterID id, cSimpleModule* containingModule) :
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 }
00036
00037
00042 OSPF::Router::~Router(void)
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 }
00060
00061
00065 void OSPF::Router::AddWatches(void)
00066 {
00067 WATCH(routerID);
00068 WATCH_PTRVECTOR(areas);
00069 WATCH_PTRVECTOR(asExternalLSAs);
00070 }
00071
00072
00077 void OSPF::Router::AddArea(OSPF::Area* area)
00078 {
00079
00080 area->SetRouter(this);
00081 areasByID[area->GetAreaID()] = area;
00082 areas.push_back(area);
00083 }
00084
00085
00091 OSPF::Area* OSPF::Router::GetArea(OSPF::AreaID areaID)
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 }
00101
00102
00108 OSPF::Area* OSPF::Router::GetArea(OSPF::IPv4Address address)
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 }
00118
00119
00125 OSPF::Interface* OSPF::Router::GetNonVirtualInterface(unsigned char ifIndex)
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 }
00136
00137
00146 bool OSPF::Router::InstallLSA(OSPFLSA* lsa, OSPF::AreaID areaID )
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 }
00189
00190
00198 bool OSPF::Router::InstallASExternalLSA(OSPFASExternalLSA* lsa)
00199 {
00217
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) &&
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 }
00273
00274
00283 OSPFLSA* OSPF::Router::FindLSA(LSAType lsaType, OSPF::LSAKeyType lsaKey, OSPF::AreaID areaID)
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 }
00322
00323
00329 OSPF::ASExternalLSA* OSPF::Router::FindASExternalLSA(OSPF::LSAKeyType lsaKey)
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 }
00338
00339
00345 const OSPF::ASExternalLSA* OSPF::Router::FindASExternalLSA(OSPF::LSAKeyType lsaKey) const
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 }
00354
00355
00361 void OSPF::Router::AgeDatabase(void)
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);
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);
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 }
00464
00465
00471 bool OSPF::Router::HasAnyNeighborInStates(int states) const
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 }
00481
00482
00488 void OSPF::Router::RemoveFromAllRetransmissionLists(OSPF::LSAKeyType lsaKey)
00489 {
00490 long areaCount = areas.size();
00491 for (long i = 0; i < areaCount; i++) {
00492 areas[i]->RemoveFromAllRetransmissionLists(lsaKey);
00493 }
00494 }
00495
00496
00502 bool OSPF::Router::IsOnAnyRetransmissionList(OSPF::LSAKeyType lsaKey) const
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 }
00512
00513
00523 bool OSPF::Router::FloodLSA(OSPFLSA* lsa, OSPF::AreaID areaID , OSPF::Interface* intf , OSPF::Neighbor* neighbor )
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 }
00547
00548
00554 bool OSPF::Router::IsLocalAddress(OSPF::IPv4Address address) const
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 }
00564
00565
00571 bool OSPF::Router::HasAddressRange(OSPF::IPv4AddressRange addressRange) const
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 }
00581
00582
00588 OSPF::ASExternalLSA* OSPF::Router::OriginateASExternalLSA(OSPF::ASExternalLSA* lsa)
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 }
00603
00604
00609 bool OSPF::Router::IsDestinationUnreachable(OSPFLSA* lsa) const
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
00618 if (routerLSA != NULL) {
00619 OSPF::RoutingInfo* routingInfo = check_and_cast<OSPF::RoutingInfo*> (routerLSA);
00620 if (routerLSA->getHeader().getLinkStateID() == routerID) {
00621 return false;
00622 }
00623
00624
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
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
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 }
00721
00722
00730 OSPF::RoutingTableEntry* OSPF::Router::Lookup(IPAddress destination, std::vector<OSPF::RoutingTableEntry*>* table ) const
00731 {
00732 const std::vector<OSPF::RoutingTableEntry*>& rTable = (table == NULL) ? routingTable : (*table);
00733 unsigned long dest = destination.getInt();
00734 unsigned long routingTableSize = rTable.size();
00735 bool unreachable = false;
00736 std::vector<OSPF::RoutingTableEntry*> discard;
00737 unsigned long i;
00738
00739 unsigned long areaCount = areas.size();
00740 for (i = 0; i < areaCount; i++) {
00741 unsigned int addressRangeCount = areas[i]->GetAddressRangeCount();
00742 for (unsigned int j = 0; j < addressRangeCount; j++) {
00743 OSPF::IPv4AddressRange range = areas[i]->GetAddressRange(j);
00744
00745 for (unsigned int k = 0; k < routingTableSize; k++) {
00746 OSPF::RoutingTableEntry* entry = rTable[k];
00747
00748 if (entry->GetDestinationType() != OSPF::RoutingTableEntry::NetworkDestination) {
00749 continue;
00750 }
00751 if (((entry->GetDestinationID().getInt() & entry->GetAddressMask().getInt() & ULongFromIPv4Address(range.mask)) == ULongFromIPv4Address(range.address & range.mask)) &&
00752 (entry->GetPathType() == OSPF::RoutingTableEntry::IntraArea))
00753 {
00754
00755 OSPF::RoutingTableEntry* discardEntry = new OSPF::RoutingTableEntry;
00756 discardEntry->SetDestinationID(ULongFromIPv4Address(range.address));
00757 discardEntry->SetAddressMask(ULongFromIPv4Address(range.mask));
00758 discardEntry->SetDestinationType(OSPF::RoutingTableEntry::NetworkDestination);
00759 discardEntry->SetPathType(OSPF::RoutingTableEntry::InterArea);
00760 discardEntry->SetArea(areas[i]->GetAreaID());
00761 discard.push_back(discardEntry);
00762 break;
00763 }
00764 }
00765 }
00766 }
00767
00768 OSPF::RoutingTableEntry* bestMatch = NULL;
00769 unsigned long longestMatch = 0;
00770
00771 for (i = 0; i < routingTableSize; i++) {
00772 if (rTable[i]->GetDestinationType() == OSPF::RoutingTableEntry::NetworkDestination) {
00773 OSPF::RoutingTableEntry* entry = rTable[i];
00774 unsigned long entryAddress = entry->GetDestinationID().getInt();
00775 unsigned long entryMask = entry->GetAddressMask().getInt();
00776
00777 if ((entryAddress & entryMask) == (dest & entryMask)) {
00778 if ((dest & entryMask) > longestMatch) {
00779 longestMatch = (dest & entryMask);
00780 bestMatch = entry;
00781 }
00782 }
00783 }
00784 }
00785
00786 unsigned int discardCount = discard.size();
00787 if (bestMatch == NULL) {
00788 unreachable = true;
00789 } else {
00790 for (i = 0; i < discardCount; i++) {
00791 OSPF::RoutingTableEntry* entry = discard[i];
00792 unsigned long entryAddress = entry->GetDestinationID().getInt();
00793 unsigned long entryMask = entry->GetAddressMask().getInt();
00794
00795 if ((entryAddress & entryMask) == (dest & entryMask)) {
00796 if ((dest & entryMask) > longestMatch) {
00797 unreachable = true;
00798 break;
00799 }
00800 }
00801 }
00802 }
00803
00804 for (i = 0; i < discardCount; i++) {
00805 delete discard[i];
00806 }
00807
00808 if (unreachable) {
00809 return NULL;
00810 } else {
00811 return bestMatch;
00812 }
00813 }
00814
00815
00820 void OSPF::Router::RebuildRoutingTable(void)
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
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
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
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 }
00904
00905
00912 bool OSPF::Router::HasRouteToASBoundaryRouter(const std::vector<OSPF::RoutingTableEntry*>& inRoutingTable, OSPF::RouterID asbrRouterID) const
00913 {
00914 long routeCount = inRoutingTable.size();
00915 for (long i = 0; i < routeCount; i++) {
00916 OSPF::RoutingTableEntry* routingEntry = inRoutingTable[i];
00917 if (((routingEntry->GetDestinationType() & OSPF::RoutingTableEntry::ASBoundaryRouterDestination) != 0) &&
00918 (routingEntry->GetDestinationID().getInt() == asbrRouterID))
00919 {
00920 return true;
00921 }
00922 }
00923 return false;
00924 }
00925
00926
00934 std::vector<OSPF::RoutingTableEntry*> OSPF::Router::GetRoutesToASBoundaryRouter(const std::vector<OSPF::RoutingTableEntry*>& fromRoutingTable, OSPF::RouterID asbrRouterID) const
00935 {
00936 std::vector<OSPF::RoutingTableEntry*> results;
00937 long routeCount = fromRoutingTable.size();
00938
00939 for (long i = 0; i < routeCount; i++) {
00940 OSPF::RoutingTableEntry* routingEntry = fromRoutingTable[i];
00941 if (((routingEntry->GetDestinationType() & OSPF::RoutingTableEntry::ASBoundaryRouterDestination) != 0) &&
00942 (routingEntry->GetDestinationID().getInt() == asbrRouterID))
00943 {
00944 results.push_back(routingEntry);
00945 }
00946 }
00947 return results;
00948 }
00949
00950
00957 void OSPF::Router::PruneASBoundaryRouterEntries(std::vector<OSPF::RoutingTableEntry*>& asbrEntries) const
00958 {
00959 bool hasNonBackboneIntraAreaPath = false;
00960 for (std::vector<OSPF::RoutingTableEntry*>::iterator it = asbrEntries.begin(); it != asbrEntries.end(); it++) {
00961 OSPF::RoutingTableEntry* routingEntry = *it;
00962 if ((routingEntry->GetPathType() == OSPF::RoutingTableEntry::IntraArea) &&
00963 (routingEntry->GetArea() != OSPF::BackboneAreaID))
00964 {
00965 hasNonBackboneIntraAreaPath = true;
00966 break;
00967 }
00968 }
00969
00970 if (hasNonBackboneIntraAreaPath) {
00971 std::vector<OSPF::RoutingTableEntry*>::iterator it = asbrEntries.begin();
00972 while (it != asbrEntries.end()) {
00973 if (((*it)->GetPathType() != OSPF::RoutingTableEntry::IntraArea) ||
00974 ((*it)->GetArea() == OSPF::BackboneAreaID))
00975 {
00976 it = asbrEntries.erase(it);
00977 } else {
00978 it++;
00979 }
00980 }
00981 }
00982 }
00983
00984
00991 OSPF::RoutingTableEntry* OSPF::Router::SelectLeastCostRoutingEntry(std::vector<OSPF::RoutingTableEntry*>& entries) const
00992 {
00993 if (entries.empty()) {
00994 return NULL;
00995 }
00996
00997 OSPF::RoutingTableEntry* leastCostEntry = entries[0];
00998 Metric leastCost = leastCostEntry->GetCost();
00999 long routeCount = entries.size();
01000
01001 for (long i = 1; i < routeCount; i++) {
01002 Metric currentCost = entries[i]->GetCost();
01003 if ((currentCost < leastCost) ||
01004 ((currentCost == leastCost) && (entries[i]->GetArea() > leastCostEntry->GetArea())))
01005 {
01006 leastCostEntry = entries[i];
01007 leastCost = currentCost;
01008 }
01009 }
01010
01011 return leastCostEntry;
01012 }
01013
01014
01033 OSPF::RoutingTableEntry* OSPF::Router::GetPreferredEntry(const OSPFLSA& lsa, bool skipSelfOriginated, std::vector<OSPF::RoutingTableEntry*>* fromRoutingTable )
01034 {
01035 if (fromRoutingTable == NULL) {
01036 fromRoutingTable = &routingTable;
01037 }
01038
01039 const OSPFLSAHeader& lsaHeader = lsa.getHeader();
01040 const OSPFASExternalLSA* asExternalLSA = dynamic_cast<const OSPFASExternalLSA*> (&lsa);
01041 unsigned long externalCost = (asExternalLSA != NULL) ? asExternalLSA->getContents().getRouteCost() : 0;
01042 unsigned short lsAge = lsaHeader.getLsAge();
01043 OSPF::RouterID originatingRouter = lsaHeader.getAdvertisingRouter().getInt();
01044 bool selfOriginated = (originatingRouter == routerID);
01045 IPAddress forwardingAddress;
01046
01047 if (asExternalLSA != NULL) {
01048 forwardingAddress = asExternalLSA->getContents().getForwardingAddress();
01049 }
01050
01051 if ((externalCost == LS_INFINITY) || (lsAge == MAX_AGE) || (skipSelfOriginated && selfOriginated)) {
01052 return NULL;
01053 }
01054
01055 if (!HasRouteToASBoundaryRouter(*fromRoutingTable, originatingRouter)) {
01056 return NULL;
01057 }
01058
01059 if (forwardingAddress.isUnspecified()) {
01060 std::vector<OSPF::RoutingTableEntry*> asbrEntries = GetRoutesToASBoundaryRouter(*fromRoutingTable, originatingRouter);
01061 if (!rfc1583Compatibility) {
01062 PruneASBoundaryRouterEntries(asbrEntries);
01063 }
01064 return SelectLeastCostRoutingEntry(asbrEntries);
01065 } else {
01066 OSPF::RoutingTableEntry* forwardEntry = Lookup(forwardingAddress, fromRoutingTable);
01067
01068 if (forwardEntry == NULL) {
01069 return NULL;
01070 }
01071
01072 if ((forwardEntry->GetPathType() != OSPF::RoutingTableEntry::IntraArea) &&
01073 (forwardEntry->GetPathType() != OSPF::RoutingTableEntry::InterArea))
01074 {
01075 return NULL;
01076 }
01077
01078 return forwardEntry;
01079 }
01080
01081 return NULL;
01082 }
01083
01084
01092 void OSPF::Router::CalculateASExternalRoutes(std::vector<OSPF::RoutingTableEntry*>& newRoutingTable)
01093 {
01094 unsigned long lsaCount = asExternalLSAs.size();
01095 unsigned long i;
01096
01097 for (i = 0; i < lsaCount; i++) {
01098 OSPF::ASExternalLSA* currentLSA = asExternalLSAs[i];
01099 OSPFLSAHeader& currentHeader = currentLSA->getHeader();
01100 unsigned short externalCost = currentLSA->getContents().getRouteCost();
01101 OSPF::RouterID originatingRouter = currentHeader.getAdvertisingRouter().getInt();
01102
01103 OSPF::RoutingTableEntry* preferredEntry = GetPreferredEntry(*currentLSA, true, &newRoutingTable);
01104 if (preferredEntry == NULL) {
01105 continue;
01106 }
01107
01108 IPAddress destination = currentHeader.getLinkStateID() & currentLSA->getContents().getNetworkMask().getInt();
01109
01110 Metric preferredCost = preferredEntry->GetCost();
01111 OSPF::RoutingTableEntry* destinationEntry = Lookup(destination, &newRoutingTable);
01112 if (destinationEntry == NULL) {
01113 bool type2ExternalMetric = currentLSA->getContents().getE_ExternalMetricType();
01114 unsigned int nextHopCount = preferredEntry->GetNextHopCount();
01115 OSPF::RoutingTableEntry* newEntry = new OSPF::RoutingTableEntry;
01116
01117 newEntry->SetDestinationID(destination);
01118 newEntry->SetAddressMask(currentLSA->getContents().getNetworkMask().getInt());
01119 newEntry->SetArea(preferredEntry->GetArea());
01120 newEntry->SetPathType(type2ExternalMetric ? OSPF::RoutingTableEntry::Type2External : OSPF::RoutingTableEntry::Type1External);
01121 if (type2ExternalMetric) {
01122 newEntry->SetCost(preferredCost);
01123 newEntry->SetType2Cost(externalCost);
01124 } else {
01125 newEntry->SetCost(preferredCost + externalCost);
01126 }
01127 newEntry->SetDestinationType(OSPF::RoutingTableEntry::NetworkDestination);
01128 newEntry->SetOptionalCapabilities(currentHeader.getLsOptions());
01129 newEntry->SetLinkStateOrigin(currentLSA);
01130
01131 for (unsigned int j = 0; j < nextHopCount; j++) {
01132 NextHop nextHop = preferredEntry->GetNextHop(j);
01133
01134 nextHop.advertisingRouter = originatingRouter;
01135 newEntry->AddNextHop(nextHop);
01136 }
01137
01138 newRoutingTable.push_back(newEntry);
01139 } else {
01140 OSPF::RoutingTableEntry::RoutingPathType destinationPathType = destinationEntry->GetPathType();
01141 bool type2ExternalMetric = currentLSA->getContents().getE_ExternalMetricType();
01142 unsigned int nextHopCount = preferredEntry->GetNextHopCount();
01143
01144 if ((destinationPathType == OSPF::RoutingTableEntry::IntraArea) ||
01145 (destinationPathType == OSPF::RoutingTableEntry::InterArea))
01146 {
01147 continue;
01148 }
01149
01150 if (((destinationPathType == OSPF::RoutingTableEntry::Type1External) &&
01151 (type2ExternalMetric)) ||
01152 ((destinationPathType == OSPF::RoutingTableEntry::Type2External) &&
01153 (type2ExternalMetric) &&
01154 (destinationEntry->GetType2Cost() < externalCost)))
01155 {
01156 continue;
01157 }
01158
01159 OSPF::RoutingTableEntry* destinationPreferredEntry = GetPreferredEntry(*(destinationEntry->GetLinkStateOrigin()), false, &newRoutingTable);
01160 if ((!rfc1583Compatibility) &&
01161 (destinationPreferredEntry->GetPathType() == OSPF::RoutingTableEntry::IntraArea) &&
01162 (destinationPreferredEntry->GetArea() != OSPF::BackboneAreaID) &&
01163 ((preferredEntry->GetPathType() != OSPF::RoutingTableEntry::IntraArea) ||
01164 (preferredEntry->GetArea() == OSPF::BackboneAreaID)))
01165 {
01166 continue;
01167 }
01168
01169 if ((((destinationPathType == OSPF::RoutingTableEntry::Type1External) &&
01170 (!type2ExternalMetric) &&
01171 (destinationEntry->GetCost() < preferredCost + externalCost))) ||
01172 ((destinationPathType == OSPF::RoutingTableEntry::Type2External) &&
01173 (type2ExternalMetric) &&
01174 (destinationEntry->GetType2Cost() == externalCost) &&
01175 (destinationPreferredEntry->GetCost() < preferredCost)))
01176 {
01177 continue;
01178 }
01179
01180 if (((destinationPathType == OSPF::RoutingTableEntry::Type1External) &&
01181 (!type2ExternalMetric) &&
01182 (destinationEntry->GetCost() == (preferredCost + externalCost))) ||
01183 ((destinationPathType == OSPF::RoutingTableEntry::Type2External) &&
01184 (type2ExternalMetric) &&
01185 (destinationEntry->GetType2Cost() == externalCost) &&
01186 (destinationPreferredEntry->GetCost() == preferredCost)))
01187 {
01188 for (unsigned int j = 0; j < nextHopCount; j++) {
01189
01190 NextHop nextHop = preferredEntry->GetNextHop(j);
01191
01192 nextHop.advertisingRouter = originatingRouter;
01193 destinationEntry->AddNextHop(nextHop);
01194 }
01195 continue;
01196 }
01197
01198
01199 destinationEntry->SetArea(preferredEntry->GetArea());
01200 destinationEntry->SetPathType(type2ExternalMetric ? OSPF::RoutingTableEntry::Type2External : OSPF::RoutingTableEntry::Type1External);
01201 if (type2ExternalMetric) {
01202 destinationEntry->SetCost(preferredCost);
01203 destinationEntry->SetType2Cost(externalCost);
01204 } else {
01205 destinationEntry->SetCost(preferredCost + externalCost);
01206 }
01207 destinationEntry->SetDestinationType(OSPF::RoutingTableEntry::NetworkDestination);
01208 destinationEntry->SetOptionalCapabilities(currentHeader.getLsOptions());
01209 destinationEntry->ClearNextHops();
01210
01211 for (unsigned int j = 0; j < nextHopCount; j++) {
01212 NextHop nextHop = preferredEntry->GetNextHop(j);
01213
01214 nextHop.advertisingRouter = originatingRouter;
01215 destinationEntry->AddNextHop(nextHop);
01216 }
01217 }
01218 }
01219 }
01220
01221
01231 OSPF::IPv4AddressRange OSPF::Router::GetContainingAddressRange(OSPF::IPv4AddressRange addressRange, bool* advertise ) const
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 }
01245
01246
01262 OSPF::LinkStateID OSPF::Router::GetUniqueLinkStateID(OSPF::IPv4AddressRange destination,
01263 OSPF::Metric destinationCost,
01264 OSPF::ASExternalLSA*& lsaToReoriginate,
01265 bool externalMetricIsType2 ) const
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);
01297
01298 lsaToReoriginate = asExternalLSA;
01299
01300 return (lsaKey.linkStateID | (~(ULongFromIPv4Address(existingMask))));
01301 }
01302 }
01303 }
01304
01305
01314
01315 void OSPF::Router::NotifyAboutRoutingTableChanges(std::vector<OSPF::RoutingTableEntry*>& oldRoutingTable)
01316 {
01317 if (areas.size() <= 1) {
01318 return;
01319 }
01320
01321 unsigned long routeCount = oldRoutingTable.size();
01322 std::map<unsigned long, RoutingTableEntry*> oldTableMap;
01323 std::map<unsigned long, RoutingTableEntry*> newTableMap;
01324 unsigned long i, j, k;
01325
01326 for (i = 0; i < routeCount; i++) {
01327 unsigned long destination = oldRoutingTable[i]->GetDestinationID().getInt() & oldRoutingTable[i]->GetAddressMask().getInt();
01328 oldTableMap[destination] = oldRoutingTable[i];
01329 }
01330
01331 routeCount = routingTable.size();
01332 for (i = 0; i < routeCount; i++) {
01333 unsigned long destination = routingTable[i]->GetDestinationID().getInt() & routingTable[i]->GetAddressMask().getInt();
01334 newTableMap[destination] = routingTable[i];
01335 }
01336
01337 unsigned long areaCount = areas.size();
01338 for (i = 0; i < areaCount; i++) {
01339 std::map<OSPF::LSAKeyType, bool, OSPF::LSAKeyType_Less> originatedLSAMap;
01340 std::map<OSPF::LSAKeyType, bool, OSPF::LSAKeyType_Less> deletedLSAMap;
01341 OSPF::LSAKeyType lsaKey;
01342
01343 routeCount = routingTable.size();
01344 for (j = 0; j < routeCount; j++) {
01345 unsigned long destination = routingTable[j]->GetDestinationID().getInt() & routingTable[j]->GetAddressMask().getInt();
01346 std::map<unsigned long, RoutingTableEntry*>::iterator destIt = oldTableMap.find(destination);
01347 if (destIt == oldTableMap.end()) {
01348 OSPF::SummaryLSA* lsaToReoriginate = NULL;
01349 OSPF::SummaryLSA* newLSA = areas[i]->OriginateSummaryLSA(routingTable[j], originatedLSAMap, lsaToReoriginate);
01350
01351 if (newLSA != NULL) {
01352 if (lsaToReoriginate != NULL) {
01353 areas[i]->InstallSummaryLSA(lsaToReoriginate);
01354
01355 FloodLSA(lsaToReoriginate, areas[i]->GetAreaID());
01356
01357 lsaKey.linkStateID = lsaToReoriginate->getHeader().getLinkStateID();
01358 lsaKey.advertisingRouter = routerID;
01359 originatedLSAMap[lsaKey] = true;
01360
01361 delete lsaToReoriginate;
01362 }
01363
01364 areas[i]->InstallSummaryLSA(newLSA);
01365
01366 FloodLSA(newLSA, areas[i]->GetAreaID());
01367
01368 lsaKey.linkStateID = newLSA->getHeader().getLinkStateID();
01369 lsaKey.advertisingRouter = routerID;
01370 originatedLSAMap[lsaKey] = true;
01371
01372 delete newLSA;
01373 }
01374 } else {
01375 if (*(routingTable[j]) != *(destIt->second)) {
01376 OSPF::SummaryLSA* lsaToReoriginate = NULL;
01377 OSPF::SummaryLSA* newLSA = areas[i]->OriginateSummaryLSA(routingTable[j], originatedLSAMap, lsaToReoriginate);
01378
01379 if (newLSA != NULL) {
01380 if (lsaToReoriginate != NULL) {
01381 areas[i]->InstallSummaryLSA(lsaToReoriginate);
01382
01383 FloodLSA(lsaToReoriginate, areas[i]->GetAreaID());
01384
01385 lsaKey.linkStateID = lsaToReoriginate->getHeader().getLinkStateID();
01386 lsaKey.advertisingRouter = routerID;
01387 originatedLSAMap[lsaKey] = true;
01388
01389 delete lsaToReoriginate;
01390 }
01391
01392 areas[i]->InstallSummaryLSA(newLSA);
01393
01394 FloodLSA(newLSA, areas[i]->GetAreaID());
01395
01396 lsaKey.linkStateID = newLSA->getHeader().getLinkStateID();
01397 lsaKey.advertisingRouter = routerID;
01398 originatedLSAMap[lsaKey] = true;
01399
01400 delete newLSA;
01401 } else {
01402 OSPF::IPv4AddressRange destinationAddressRange;
01403
01404 destinationAddressRange.address = IPv4AddressFromULong(routingTable[j]->GetDestinationID().getInt());
01405 destinationAddressRange.mask = IPv4AddressFromULong(routingTable[j]->GetAddressMask().getInt());
01406
01407 if ((routingTable[j]->GetDestinationType() == OSPF::RoutingTableEntry::NetworkDestination) &&
01408 ((routingTable[j]->GetPathType() == OSPF::RoutingTableEntry::IntraArea) ||
01409 (routingTable[j]->GetPathType() == OSPF::RoutingTableEntry::InterArea)))
01410 {
01411 OSPF::IPv4AddressRange containingAddressRange = GetContainingAddressRange(destinationAddressRange);
01412 if (containingAddressRange != OSPF::NullIPv4AddressRange) {
01413 destinationAddressRange = containingAddressRange;
01414 }
01415 }
01416
01417 Metric maxRangeCost = 0;
01418 Metric oneLessCost = 0;
01419
01420 for (k = 0; k < routeCount; k++) {
01421 if ((routingTable[k]->GetDestinationType() == OSPF::RoutingTableEntry::NetworkDestination) &&
01422 (routingTable[k]->GetPathType() == OSPF::RoutingTableEntry::IntraArea) &&
01423 ((routingTable[k]->GetDestinationID().getInt() & routingTable[k]->GetAddressMask().getInt() & ULongFromIPv4Address(destinationAddressRange.mask)) ==
01424 ULongFromIPv4Address(destinationAddressRange.address & destinationAddressRange.mask)) &&
01425 (routingTable[k]->GetCost() > maxRangeCost))
01426 {
01427 oneLessCost = maxRangeCost;
01428 maxRangeCost = routingTable[k]->GetCost();
01429 }
01430 }
01431
01432 if (maxRangeCost == routingTable[j]->GetCost()) {
01433 lsaKey.linkStateID = ULongFromIPv4Address(destinationAddressRange.address);
01434 lsaKey.advertisingRouter = routerID;
01435
01436 OSPF::SummaryLSA* summaryLSA = areas[i]->FindSummaryLSA(lsaKey);
01437
01438 if (summaryLSA != NULL) {
01439 if (oneLessCost != 0) {
01440 summaryLSA->setRouteCost(oneLessCost);
01441
01442 FloodLSA(summaryLSA, areas[i]->GetAreaID());
01443
01444 originatedLSAMap[lsaKey] = true;
01445 } else {
01446 std::map<OSPF::LSAKeyType, bool, OSPF::LSAKeyType_Less>::const_iterator deletedIt = deletedLSAMap.find(lsaKey);
01447 if (deletedIt == deletedLSAMap.end()) {
01448 summaryLSA->getHeader().setLsAge(MAX_AGE);
01449
01450 FloodLSA(summaryLSA, areas[i]->GetAreaID());
01451
01452 deletedLSAMap[lsaKey] = true;
01453 }
01454 }
01455 }
01456 }
01457 }
01458 }
01459 }
01460 }
01461
01462 routeCount = oldRoutingTable.size();
01463 for (j = 0; j < routeCount; j++) {
01464 unsigned long destination = oldRoutingTable[j]->GetDestinationID().getInt() & oldRoutingTable[j]->GetAddressMask().getInt();
01465 std::map<unsigned long, RoutingTableEntry*>::iterator destIt = newTableMap.find(destination);
01466 if (destIt == newTableMap.end()) {
01467 OSPF::IPv4AddressRange destinationAddressRange;
01468
01469 destinationAddressRange.address = IPv4AddressFromULong(oldRoutingTable[j]->GetDestinationID().getInt());
01470 destinationAddressRange.mask = IPv4AddressFromULong(oldRoutingTable[j]->GetAddressMask().getInt());
01471
01472 if ((oldRoutingTable[j]->GetDestinationType() == OSPF::RoutingTableEntry::NetworkDestination) &&
01473 ((oldRoutingTable[j]->GetPathType() == OSPF::RoutingTableEntry::IntraArea) ||
01474 (oldRoutingTable[j]->GetPathType() == OSPF::RoutingTableEntry::InterArea)))
01475 {
01476 OSPF::IPv4AddressRange containingAddressRange = GetContainingAddressRange(destinationAddressRange);
01477 if (containingAddressRange != OSPF::NullIPv4AddressRange) {
01478 destinationAddressRange = containingAddressRange;
01479 }
01480 }
01481
01482 Metric maxRangeCost = 0;
01483
01484 unsigned long newRouteCount = routingTable.size();
01485 for (k = 0; k < newRouteCount; k++) {
01486 if ((routingTable[k]->GetDestinationType() == OSPF::RoutingTableEntry::NetworkDestination) &&
01487 (routingTable[k]->GetPathType() == OSPF::RoutingTableEntry::IntraArea) &&
01488 ((routingTable[k]->GetDestinationID().getInt() & routingTable[k]->GetAddressMask().getInt() & ULongFromIPv4Address(destinationAddressRange.mask)) ==
01489 ULongFromIPv4Address(destinationAddressRange.address & destinationAddressRange.mask)) &&
01490 (routingTable[k]->GetCost() > maxRangeCost))
01491 {
01492 maxRangeCost = routingTable[k]->GetCost();
01493 }
01494 }
01495
01496 if (maxRangeCost < oldRoutingTable[j]->GetCost()) {
01497 lsaKey.linkStateID = ULongFromIPv4Address(destinationAddressRange.address);
01498 lsaKey.advertisingRouter = routerID;
01499
01500 OSPF::SummaryLSA* summaryLSA = areas[i]->FindSummaryLSA(lsaKey);
01501
01502 if (summaryLSA != NULL) {
01503 if (maxRangeCost > 0) {
01504 summaryLSA->setRouteCost(maxRangeCost);
01505 FloodLSA(summaryLSA, OSPF::BackboneAreaID);
01506
01507 originatedLSAMap[lsaKey] = true;
01508 } else {
01509 std::map<OSPF::LSAKeyType, bool, OSPF::LSAKeyType_Less>::const_iterator deletedIt = deletedLSAMap.find(lsaKey);
01510 if (deletedIt == deletedLSAMap.end()) {
01511 summaryLSA->getHeader().setLsAge(MAX_AGE);
01512 FloodLSA(summaryLSA, OSPF::BackboneAreaID);
01513
01514 deletedLSAMap[lsaKey] = true;
01515 }
01516 }
01517 }
01518 }
01519 }
01520 }
01521 }
01522 }
01523
01524
01532 void OSPF::Router::UpdateExternalRoute(OSPF::IPv4Address networkAddress, const OSPFASExternalLSAContents& externalRouteContents, int ifIndex)
01533 {
01534 OSPF::ASExternalLSA* asExternalLSA = new OSPF::ASExternalLSA;
01535 OSPFLSAHeader& lsaHeader = asExternalLSA->getHeader();
01536 OSPFOptions lsaOptions;
01537
01538
01539 IRoutingTable* simRoutingTable = RoutingTableAccess().get();
01540 unsigned long routingEntryNumber = simRoutingTable->getNumRoutes();
01541 bool inRoutingTable = false;
01542
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);
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));
01568 lsaHeader.setAdvertisingRouter(routerID);
01569 lsaHeader.setLsSequenceNumber(INITIAL_SEQUENCE_NUMBER);
01570
01571 asExternalLSA->setContents(externalRouteContents);
01572
01573 lsaHeader.setLsChecksum(0);
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 }
01587
01588
01594 void OSPF::Router::RemoveExternalRoute(OSPF::IPv4Address networkAddress)
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 }