|
INET Framework for OMNeT++/OMNEST
|
00001 // 00002 // Copyright (C) 2006 Andras Babos and Andras Varga 00003 // 00004 // This program is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public License 00006 // as published by the Free Software Foundation; either version 2 00007 // of the License, or (at your option) any later version. 00008 // 00009 // This program is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU Lesser General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU Lesser General Public License 00015 // along with this program; if not, see <http://www.gnu.org/licenses/>. 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 /*= BackboneAreaID*/) 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 // TODO: how to solve this problem? 00218 00219 OSPF::RouterID advertisingRouter = lsa->getHeader().getAdvertisingRouter().getInt(); 00220 bool reachable = false; 00221 unsigned int routeCount = routingTable.size(); 00222 00223 for (unsigned int i = 0; i < routeCount; i++) { 00224 if ((((routingTable[i]->GetDestinationType() & OSPF::RoutingTableEntry::AreaBorderRouterDestination) != 0) || 00225 ((routingTable[i]->GetDestinationType() & OSPF::RoutingTableEntry::ASBoundaryRouterDestination) != 0)) && 00226 (routingTable[i]->GetDestinationID().getInt() == advertisingRouter)) 00227 { 00228 reachable = true; 00229 break; 00230 } 00231 } 00232 00233 bool ownLSAFloodedOut = false; 00234 OSPF::LSAKeyType lsaKey; 00235 00236 lsaKey.linkStateID = lsa->getHeader().getLinkStateID(); 00237 lsaKey.advertisingRouter = routerID; 00238 00239 std::map<OSPF::LSAKeyType, OSPF::ASExternalLSA*, OSPF::LSAKeyType_Less>::iterator lsaIt = asExternalLSAsByID.find(lsaKey); 00240 if ((lsaIt != asExternalLSAsByID.end()) && 00241 reachable && 00242 (lsaIt->second->getContents().getE_ExternalMetricType() == lsa->getContents().getE_ExternalMetricType()) && 00243 (lsaIt->second->getContents().getRouteCost() == lsa->getContents().getRouteCost()) && 00244 (lsa->getContents().getForwardingAddress().getInt() != 0) && // forwarding address != 0.0.0.0 00245 (lsaIt->second->getContents().getForwardingAddress() == lsa->getContents().getForwardingAddress())) 00246 { 00247 if (routerID > advertisingRouter) { 00248 return false; 00249 } else { 00250 lsaIt->second->getHeader().setLsAge(MAX_AGE); 00251 FloodLSA(lsaIt->second, OSPF::BackboneAreaID); 00252 lsaIt->second->IncrementInstallTime(); 00253 ownLSAFloodedOut = true; 00254 } 00255 } 00256 00257 lsaKey.advertisingRouter = advertisingRouter; 00258 00259 lsaIt = asExternalLSAsByID.find(lsaKey); 00260 if (lsaIt != asExternalLSAsByID.end()) { 00261 unsigned long areaCount = areas.size(); 00262 for (unsigned long i = 0; i < areaCount; i++) { 00263 areas[i]->RemoveFromAllRetransmissionLists(lsaKey); 00264 } 00265 return ((lsaIt->second->Update(lsa)) | ownLSAFloodedOut); 00266 } else { 00267 OSPF::ASExternalLSA* lsaCopy = new OSPF::ASExternalLSA(*lsa); 00268 asExternalLSAsByID[lsaKey] = lsaCopy; 00269 asExternalLSAs.push_back(lsaCopy); 00270 return true; 00271 } 00272 } 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); // TODO: calculate correct LS checksum 00397 rebuildRoutingTable |= lsa->Update(newLSA); 00398 delete newLSA; 00399 00400 FloodLSA(lsa, OSPF::BackboneAreaID); 00401 } 00402 } 00403 } 00404 if (!selfOriginated && (lsAge == MAX_AGE - 1)) { 00405 lsa->getHeader().setLsAge(MAX_AGE); 00406 FloodLSA(lsa, OSPF::BackboneAreaID); 00407 lsa->IncrementInstallTime(); 00408 } 00409 if (lsAge == MAX_AGE) { 00410 OSPF::LSAKeyType lsaKey; 00411 00412 lsaKey.linkStateID = lsa->getHeader().getLinkStateID(); 00413 lsaKey.advertisingRouter = lsa->getHeader().getAdvertisingRouter().getInt(); 00414 00415 if (!IsOnAnyRetransmissionList(lsaKey) && 00416 !HasAnyNeighborInStates(OSPF::Neighbor::ExchangeState | OSPF::Neighbor::LoadingState)) 00417 { 00418 if (!selfOriginated || unreachable) { 00419 asExternalLSAsByID.erase(lsaKey); 00420 delete lsa; 00421 asExternalLSAs[i] = NULL; 00422 rebuildRoutingTable = true; 00423 } else { 00424 if (lsa->GetPurgeable()) { 00425 asExternalLSAsByID.erase(lsaKey); 00426 delete lsa; 00427 asExternalLSAs[i] = NULL; 00428 rebuildRoutingTable = true; 00429 } else { 00430 OSPF::ASExternalLSA* newLSA = OriginateASExternalLSA(lsa); 00431 long sequenceNumber = lsa->getHeader().getLsSequenceNumber(); 00432 00433 newLSA->getHeader().setLsSequenceNumber((sequenceNumber == MAX_SEQUENCE_NUMBER) ? INITIAL_SEQUENCE_NUMBER : sequenceNumber + 1); 00434 newLSA->getHeader().setLsChecksum(0); // TODO: calculate correct LS checksum 00435 rebuildRoutingTable |= lsa->Update(newLSA); 00436 delete newLSA; 00437 00438 FloodLSA(lsa, OSPF::BackboneAreaID); 00439 } 00440 } 00441 } 00442 } 00443 } 00444 00445 std::vector<ASExternalLSA*>::iterator it = asExternalLSAs.begin(); 00446 while (it != asExternalLSAs.end()) { 00447 if ((*it) == NULL) { 00448 it = asExternalLSAs.erase(it); 00449 } else { 00450 it++; 00451 } 00452 } 00453 00454 long areaCount = areas.size(); 00455 for (long j = 0; j < areaCount; j++) { 00456 areas[j]->AgeDatabase(); 00457 } 00458 messageHandler->StartTimer(ageTimer, 1.0); 00459 00460 if (rebuildRoutingTable) { 00461 RebuildRoutingTable(); 00462 } 00463 } 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 /*= BackboneAreaID*/, OSPF::Interface* intf /*= NULL*/, OSPF::Neighbor* neighbor /*= NULL*/) 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 // TODO: verify 00618 if (routerLSA != NULL) { 00619 OSPF::RoutingInfo* routingInfo = check_and_cast<OSPF::RoutingInfo*> (routerLSA); 00620 if (routerLSA->getHeader().getLinkStateID() == routerID) { // this is spfTreeRoot 00621 return false; 00622 } 00623 00624 // get the interface address pointing backwards on the shortest path tree 00625 unsigned int linkCount = routerLSA->getLinksArraySize(); 00626 OSPF::RouterLSA* toRouterLSA = dynamic_cast<OSPF::RouterLSA*> (routingInfo->GetParent()); 00627 if (toRouterLSA != NULL) { 00628 bool destinationFound = false; 00629 bool unnumberedPointToPointLink = false; 00630 IPAddress firstNumberedIfAddress; 00631 00632 for (unsigned int i = 0; i < linkCount; i++) { 00633 Link& link = routerLSA->getLinks(i); 00634 00635 if (link.getType() == PointToPointLink) { 00636 if (link.getLinkID() == toRouterLSA->getHeader().getLinkStateID()) { 00637 if ((link.getLinkData() & 0xFF000000) == 0) { 00638 unnumberedPointToPointLink = true; 00639 if (!firstNumberedIfAddress.isUnspecified()) { 00640 break; 00641 } 00642 } else { 00643 destination = link.getLinkData(); 00644 destinationFound = true; 00645 break; 00646 } 00647 } else { 00648 if (((link.getLinkData() & 0xFF000000) != 0) && 00649 firstNumberedIfAddress.isUnspecified()) 00650 { 00651 firstNumberedIfAddress = link.getLinkData(); 00652 } 00653 } 00654 } else if (link.getType() == TransitLink) { 00655 if (firstNumberedIfAddress.isUnspecified()) { 00656 firstNumberedIfAddress = link.getLinkData(); 00657 } 00658 } else if (link.getType() == VirtualLink) { 00659 if (link.getLinkID() == toRouterLSA->getHeader().getLinkStateID()) { 00660 destination = link.getLinkData(); 00661 destinationFound = true; 00662 break; 00663 } else { 00664 if (firstNumberedIfAddress.isUnspecified()) { 00665 firstNumberedIfAddress = link.getLinkData(); 00666 } 00667 } 00668 } 00669 // There's no way to get an interface address for the router from a StubLink 00670 } 00671 if (unnumberedPointToPointLink) { 00672 if (!firstNumberedIfAddress.isUnspecified()) { 00673 destination = firstNumberedIfAddress; 00674 } else { 00675 return true; 00676 } 00677 } 00678 if (!destinationFound) { 00679 return true; 00680 } 00681 } else { 00682 OSPF::NetworkLSA* toNetworkLSA = dynamic_cast<OSPF::NetworkLSA*> (routingInfo->GetParent()); 00683 if (toNetworkLSA != NULL) { 00684 // get the interface address pointing backwards on the shortest path tree 00685 bool destinationFound = false; 00686 for (unsigned int i = 0; i < linkCount; i++) { 00687 Link& link = routerLSA->getLinks(i); 00688 00689 if ((link.getType() == TransitLink) && 00690 (link.getLinkID() == toNetworkLSA->getHeader().getLinkStateID())) 00691 { 00692 destination = link.getLinkData(); 00693 destinationFound = true; 00694 break; 00695 } 00696 } 00697 if (!destinationFound) { 00698 return true; 00699 } 00700 } else { 00701 return true; 00702 } 00703 } 00704 } 00705 if (networkLSA != NULL) { 00706 destination = networkLSA->getHeader().getLinkStateID() & networkLSA->getNetworkMask().getInt(); 00707 } 00708 if ((summaryLSA != NULL) && (summaryLSA->getHeader().getLsType() == SummaryLSA_NetworksType)) { 00709 destination = summaryLSA->getHeader().getLinkStateID() & summaryLSA->getNetworkMask().getInt(); 00710 } 00711 if (asExternalLSA != NULL) { 00712 destination = asExternalLSA->getHeader().getLinkStateID() & asExternalLSA->getContents().getNetworkMask().getInt(); 00713 } 00714 00715 if (Lookup(destination) == NULL) { 00716 return true; 00717 } else { 00718 return false; 00719 } 00720 } 00721 00722 00730 OSPF::RoutingTableEntry* OSPF::Router::Lookup(IPAddress destination, std::vector<OSPF::RoutingTableEntry*>* table /*= NULL*/) 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 // active area address range 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 // backup the routing table 00855 unsigned long routeCount = routingTable.size(); 00856 std::vector<OSPF::RoutingTableEntry*> oldTable; 00857 00858 oldTable.assign(routingTable.begin(), routingTable.end()); 00859 routingTable.clear(); 00860 routingTable.assign(newTable.begin(), newTable.end()); 00861 00862 RoutingTableAccess routingTableAccess; 00863 std::vector<const IPRoute*> eraseEntries; 00864 IRoutingTable* simRoutingTable = routingTableAccess.get(); 00865 unsigned long routingEntryNumber = simRoutingTable->getNumRoutes(); 00866 // remove entries from the IP routing table inserted by the OSPF module 00867 for (i = 0; i < routingEntryNumber; i++) { 00868 const IPRoute *entry = simRoutingTable->getRoute(i); 00869 const OSPF::RoutingTableEntry* ospfEntry = dynamic_cast<const OSPF::RoutingTableEntry*>(entry); 00870 if (ospfEntry != NULL) { 00871 eraseEntries.push_back(entry); 00872 } 00873 } 00874 00875 unsigned int eraseCount = eraseEntries.size(); 00876 for (i = 0; i < eraseCount; i++) { 00877 simRoutingTable->deleteRoute(eraseEntries[i]); 00878 } 00879 00880 // add the new routing entries 00881 routeCount = routingTable.size(); 00882 for (i = 0; i < routeCount; i++) { 00883 if (routingTable[i]->GetDestinationType() == OSPF::RoutingTableEntry::NetworkDestination) { 00884 simRoutingTable->addRoute(new OSPF::RoutingTableEntry(*(routingTable[i]))); 00885 } 00886 } 00887 00888 NotifyAboutRoutingTableChanges(oldTable); 00889 00890 routeCount = oldTable.size(); 00891 for (i = 0; i < routeCount; i++) { 00892 delete(oldTable[i]); 00893 } 00894 00895 EV << "Routing table was rebuilt.\n" 00896 << "Results:\n"; 00897 00898 routeCount = routingTable.size(); 00899 for (i = 0; i < routeCount; i++) { 00900 EV << *routingTable[i] 00901 << "\n"; 00902 } 00903 } 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 /*= NULL*/) 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; // 0.0.0.0 01046 01047 if (asExternalLSA != NULL) { 01048 forwardingAddress = asExternalLSA->getContents().getForwardingAddress(); 01049 } 01050 01051 if ((externalCost == LS_INFINITY) || (lsAge == MAX_AGE) || (skipSelfOriginated && selfOriginated)) { // (1) and(2) 01052 return NULL; 01053 } 01054 01055 if (!HasRouteToASBoundaryRouter(*fromRoutingTable, originatingRouter)) { // (3) 01056 return NULL; 01057 } 01058 01059 if (forwardingAddress.isUnspecified()) { // (3) 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); // (5) 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)) // (6) (a) 01146 { 01147 continue; 01148 } 01149 01150 if (((destinationPathType == OSPF::RoutingTableEntry::Type1External) && 01151 (type2ExternalMetric)) || 01152 ((destinationPathType == OSPF::RoutingTableEntry::Type2External) && 01153 (type2ExternalMetric) && 01154 (destinationEntry->GetType2Cost() < externalCost))) // (6) (b) 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))) // equal cost 01187 { 01188 for (unsigned int j = 0; j < nextHopCount; j++) { 01189 // TODO: merge next hops, not add 01190 NextHop nextHop = preferredEntry->GetNextHop(j); 01191 01192 nextHop.advertisingRouter = originatingRouter; 01193 destinationEntry->AddNextHop(nextHop); 01194 } 01195 continue; 01196 } 01197 01198 // LSA is better 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 /*= NULL*/) 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 /*= false*/) 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); // TODO: calculate correct LS checksum 01297 01298 lsaToReoriginate = asExternalLSA; 01299 01300 return (lsaKey.linkStateID | (~(ULongFromIPv4Address(existingMask)))); 01301 } 01302 } 01303 } 01304 01305 01314 // TODO: review this algorithm + add virtual link changes(RFC2328 Section 16.7.). 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()) { // new routing entry 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 // FloodLSA(lsaToReoriginate, OSPF::BackboneAreaID); 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 // FloodLSA(newLSA, OSPF::BackboneAreaID); 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)) { // modified routing entry 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 // FloodLSA(lsaToReoriginate, OSPF::BackboneAreaID); 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 // FloodLSA(newLSA, OSPF::BackboneAreaID); 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()) { // this entry gives the range's cost 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) { // there's an other entry in this range 01440 summaryLSA->setRouteCost(oneLessCost); 01441 // FloodLSA(summaryLSA, OSPF::BackboneAreaID); 01442 FloodLSA(summaryLSA, areas[i]->GetAreaID()); 01443 01444 originatedLSAMap[lsaKey] = true; 01445 } else { // no more entries in this range -> delete it 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 // FloodLSA(summaryLSA, OSPF::BackboneAreaID); 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()) { // deleted routing entry 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()) { // the range's cost will change 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) { // there's an other entry in this range 01504 summaryLSA->setRouteCost(maxRangeCost); 01505 FloodLSA(summaryLSA, OSPF::BackboneAreaID); 01506 01507 originatedLSAMap[lsaKey] = true; 01508 } else { // no more entries in this range -> delete it 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 //OSPF::LSAKeyType lsaKey; 01538 01539 IRoutingTable* simRoutingTable = RoutingTableAccess().get(); 01540 unsigned long routingEntryNumber = simRoutingTable->getNumRoutes(); 01541 bool inRoutingTable = false; 01542 // add the external route to the routing table if it was not added by another module 01543 for (unsigned long i = 0; i < routingEntryNumber; i++) { 01544 const IPRoute *entry = simRoutingTable->getRoute(i); 01545 if ((entry->getHost().getInt() & entry->getNetmask().getInt()) == 01546 (ULongFromIPv4Address(networkAddress) & externalRouteContents.getNetworkMask().getInt())) 01547 { 01548 inRoutingTable = true; 01549 } 01550 } 01551 if (!inRoutingTable) { 01552 IPRoute* entry = new IPRoute; 01553 entry->setHost(ULongFromIPv4Address(networkAddress)); 01554 entry->setNetmask(externalRouteContents.getNetworkMask()); 01555 entry->setInterface(InterfaceTableAccess().get()->getInterfaceById(ifIndex)); 01556 entry->setType(IPRoute::REMOTE); 01557 entry->setSource(IPRoute::MANUAL); 01558 entry->setMetric(externalRouteContents.getRouteCost()); 01559 simRoutingTable->addRoute(entry); // IRoutingTable deletes entry pointer 01560 } 01561 01562 lsaHeader.setLsAge(0); 01563 memset(&lsaOptions, 0, sizeof(OSPFOptions)); 01564 lsaOptions.E_ExternalRoutingCapability = true; 01565 lsaHeader.setLsOptions(lsaOptions); 01566 lsaHeader.setLsType(ASExternalLSAType); 01567 lsaHeader.setLinkStateID(ULongFromIPv4Address(networkAddress)); // TODO: get unique LinkStateID 01568 lsaHeader.setAdvertisingRouter(routerID); 01569 lsaHeader.setLsSequenceNumber(INITIAL_SEQUENCE_NUMBER); 01570 01571 asExternalLSA->setContents(externalRouteContents); 01572 01573 lsaHeader.setLsChecksum(0); // TODO: calculate correct LS checksum 01574 01575 asExternalLSA->SetSource(OSPF::LSATrackingInfo::Originated); 01576 01577 externalRoutes[networkAddress] = externalRouteContents; 01578 01579 bool rebuild = InstallASExternalLSA(asExternalLSA); 01580 FloodLSA(asExternalLSA, OSPF::BackboneAreaID); 01581 delete asExternalLSA; 01582 01583 if (rebuild) { 01584 RebuildRoutingTable(); 01585 } 01586 } 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 }