|
INET Framework for OMNeT++/OMNEST
|
00001 00002 #include "AnsaOSPFArea.h" 00003 #include "AnsaOSPFRouter.h" 00004 #include <memory.h> 00005 00006 AnsaOSPF::Area::Area(AnsaOSPF::AreaID id) : 00007 areaID(id), 00008 transitCapability(false), 00009 externalRoutingCapability(true), 00010 stubDefaultCost(1), 00011 spfTreeRoot(NULL), 00012 parentRouter(NULL) 00013 { 00014 } 00015 00016 AnsaOSPF::Area::~Area(void) 00017 { 00018 int interfaceNum = associatedInterfaces.size(); 00019 for (int i = 0; i < interfaceNum; i++) { 00020 delete(associatedInterfaces[i]); 00021 } 00022 long lsaCount = routerLSAs.size(); 00023 for (long j = 0; j < lsaCount; j++) { 00024 delete routerLSAs[j]; 00025 } 00026 routerLSAs.clear(); 00027 lsaCount = networkLSAs.size(); 00028 for (long k = 0; k < lsaCount; k++) { 00029 delete networkLSAs[k]; 00030 } 00031 networkLSAs.clear(); 00032 lsaCount = summaryLSAs.size(); 00033 for (long m = 0; m < lsaCount; m++) { 00034 delete summaryLSAs[m]; 00035 } 00036 summaryLSAs.clear(); 00037 } 00038 00039 void AnsaOSPF::Area::AddInterface(AnsaOSPF::Interface* intf) 00040 { 00041 intf->SetArea(this); 00042 associatedInterfaces.push_back(intf); 00043 } 00044 00045 void AnsaOSPF::Area::info(char *buffer) 00046 { 00047 std::stringstream out; 00048 char areaString[16]; 00049 out << "areaID: " << AddressStringFromULong(areaString, 16, areaID); 00050 strcpy(buffer, out.str().c_str()); 00051 } 00052 00053 std::string AnsaOSPF::Area::detailedInfo(void) const 00054 { 00055 std::stringstream out; 00056 char addressString[16]; 00057 int i; 00058 out << "\n areaID: " << AddressStringFromULong(addressString, 16, areaID) << ", "; 00059 out << "transitCapability: " << (transitCapability ? "true" : "false") << ", "; 00060 out << "externalRoutingCapability: " << (externalRoutingCapability ? "true" : "false") << ", "; 00061 out << "stubDefaultCost: " << stubDefaultCost << "\n"; 00062 int addressRangeNum = areaAddressRanges.size(); 00063 for (i = 0; i < addressRangeNum; i++) { 00064 out << " addressRanges[" << i << "]: "; 00065 out << AddressStringFromIPv4Address(addressString, 16, areaAddressRanges[i].address); 00066 out << "/" << AddressStringFromIPv4Address(addressString, 16, areaAddressRanges[i].mask) << "\n"; 00067 } 00068 int interfaceNum = associatedInterfaces.size(); 00069 for (i = 0; i < interfaceNum; i++) { 00070 out << " interface[" << i << "]: addressRange: "; 00071 out << AddressStringFromIPv4Address(addressString, 16, associatedInterfaces[i]->GetAddressRange().address); 00072 out << "/" << AddressStringFromIPv4Address(addressString, 16, associatedInterfaces[i]->GetAddressRange().mask) << "\n"; 00073 } 00074 00075 out << "\n"; 00076 out << " Database:\n"; 00077 out << " RouterLSAs:\n"; 00078 long lsaCount = routerLSAs.size(); 00079 for (i = 0; i < lsaCount; i++) { 00080 out << " " << *routerLSAs[i] << "\n"; 00081 } 00082 out << " NetworkLSAs:\n"; 00083 lsaCount = networkLSAs.size(); 00084 for (i = 0; i < lsaCount; i++) { 00085 out << " " << *networkLSAs[i] << "\n"; 00086 } 00087 out << " SummaryLSAs:\n"; 00088 lsaCount = summaryLSAs.size(); 00089 for (i = 0; i < lsaCount; i++) { 00090 out << " " << *summaryLSAs[i] << "\n"; 00091 } 00092 00093 out << "--------------------------------------------------------------------------------"; 00094 00095 return out.str(); 00096 } 00097 00098 bool AnsaOSPF::Area::ContainsAddress(AnsaOSPF::IPv4Address address) const 00099 { 00100 int addressRangeNum = areaAddressRanges.size(); 00101 for (int i = 0; i < addressRangeNum; i++) { 00102 if ((areaAddressRanges[i].address & areaAddressRanges[i].mask) == (address & areaAddressRanges[i].mask)) { 00103 return true; 00104 } 00105 } 00106 return false; 00107 } 00108 00109 bool AnsaOSPF::Area::HasAddressRange(AnsaOSPF::IPv4AddressRange addressRange) const 00110 { 00111 int addressRangeNum = areaAddressRanges.size(); 00112 for (int i = 0; i < addressRangeNum; i++) { 00113 if ((areaAddressRanges[i].address == addressRange.address) && 00114 (areaAddressRanges[i].mask == addressRange.mask)) 00115 { 00116 return true; 00117 } 00118 } 00119 return false; 00120 } 00121 00122 AnsaOSPF::IPv4AddressRange AnsaOSPF::Area::GetContainingAddressRange(AnsaOSPF::IPv4AddressRange addressRange, bool* advertise /*= NULL*/) const 00123 { 00124 int addressRangeNum = areaAddressRanges.size(); 00125 for (int i = 0; i < addressRangeNum; i++) { 00126 if ((areaAddressRanges[i].address & areaAddressRanges[i].mask) == (addressRange.address & areaAddressRanges[i].mask)) { 00127 if (advertise != NULL) { 00128 std::map<AnsaOSPF::IPv4AddressRange, bool, AnsaOSPF::IPv4AddressRange_Less>::const_iterator rangeIt = advertiseAddressRanges.find(areaAddressRanges[i]); 00129 if (rangeIt != advertiseAddressRanges.end()) { 00130 *advertise = rangeIt->second; 00131 } else { 00132 *advertise = true; 00133 } 00134 } 00135 return areaAddressRanges[i]; 00136 } 00137 } 00138 if (advertise != NULL) { 00139 *advertise = false; 00140 } 00141 return NullIPv4AddressRange; 00142 } 00143 00144 AnsaOSPF::Interface* AnsaOSPF::Area::GetInterface(unsigned char ifIndex) 00145 { 00146 int interfaceNum = associatedInterfaces.size(); 00147 for (int i = 0; i < interfaceNum; i++) { 00148 if ((associatedInterfaces[i]->GetType() != AnsaOSPF::Interface::Virtual) && 00149 (associatedInterfaces[i]->GetIfIndex() == ifIndex)) 00150 { 00151 return associatedInterfaces[i]; 00152 } 00153 } 00154 return NULL; 00155 } 00156 00157 AnsaOSPF::Interface* AnsaOSPF::Area::GetInterface(AnsaOSPF::IPv4Address address) 00158 { 00159 int interfaceNum = associatedInterfaces.size(); 00160 for (int i = 0; i < interfaceNum; i++) { 00161 if ((associatedInterfaces[i]->GetType() != AnsaOSPF::Interface::Virtual) && 00162 (associatedInterfaces[i]->GetAddressRange().address == address)) 00163 { 00164 return associatedInterfaces[i]; 00165 } 00166 } 00167 return NULL; 00168 } 00169 00170 bool AnsaOSPF::Area::HasVirtualLink(AnsaOSPF::AreaID withTransitArea) const 00171 { 00172 if ((areaID != AnsaOSPF::BackboneAreaID) || (withTransitArea == AnsaOSPF::BackboneAreaID)) { 00173 return false; 00174 } 00175 00176 int interfaceNum = associatedInterfaces.size(); 00177 for (int i = 0; i < interfaceNum; i++) { 00178 if ((associatedInterfaces[i]->GetType() == AnsaOSPF::Interface::Virtual) && 00179 (associatedInterfaces[i]->GetTransitAreaID() == withTransitArea)) 00180 { 00181 return true; 00182 } 00183 } 00184 return false; 00185 } 00186 00187 00188 AnsaOSPF::Interface* AnsaOSPF::Area::FindVirtualLink(AnsaOSPF::RouterID routerID) 00189 { 00190 int interfaceNum = associatedInterfaces.size(); 00191 for (int i = 0; i < interfaceNum; i++) { 00192 if ((associatedInterfaces[i]->GetType() == AnsaOSPF::Interface::Virtual) && 00193 (associatedInterfaces[i]->GetNeighborByID(routerID) != NULL)) 00194 { 00195 return associatedInterfaces[i]; 00196 } 00197 } 00198 return NULL; 00199 } 00200 00201 bool AnsaOSPF::Area::InstallRouterLSA(OSPFRouterLSA* lsa) 00202 { 00203 AnsaOSPF::LinkStateID linkStateID = lsa->getHeader().getLinkStateID(); 00204 std::map<AnsaOSPF::LinkStateID, AnsaOSPF::RouterLSA*>::iterator lsaIt = routerLSAsByID.find(linkStateID); 00205 if (lsaIt != routerLSAsByID.end()) { 00206 AnsaOSPF::LSAKeyType lsaKey; 00207 00208 lsaKey.linkStateID = lsa->getHeader().getLinkStateID(); 00209 lsaKey.advertisingRouter = lsa->getHeader().getAdvertisingRouter().getInt(); 00210 00211 RemoveFromAllRetransmissionLists(lsaKey); 00212 return lsaIt->second->Update(lsa); 00213 } else { 00214 AnsaOSPF::RouterLSA* lsaCopy = new AnsaOSPF::RouterLSA(*lsa); 00215 routerLSAsByID[linkStateID] = lsaCopy; 00216 routerLSAs.push_back(lsaCopy); 00217 return true; 00218 } 00219 } 00220 00221 bool AnsaOSPF::Area::InstallNetworkLSA(OSPFNetworkLSA* lsa) 00222 { 00223 AnsaOSPF::LinkStateID linkStateID = lsa->getHeader().getLinkStateID(); 00224 std::map<AnsaOSPF::LinkStateID, AnsaOSPF::NetworkLSA*>::iterator lsaIt = networkLSAsByID.find(linkStateID); 00225 if (lsaIt != networkLSAsByID.end()) { 00226 AnsaOSPF::LSAKeyType lsaKey; 00227 00228 lsaKey.linkStateID = lsa->getHeader().getLinkStateID(); 00229 lsaKey.advertisingRouter = lsa->getHeader().getAdvertisingRouter().getInt(); 00230 00231 RemoveFromAllRetransmissionLists(lsaKey); 00232 return lsaIt->second->Update(lsa); 00233 } else { 00234 AnsaOSPF::NetworkLSA* lsaCopy = new AnsaOSPF::NetworkLSA(*lsa); 00235 networkLSAsByID[linkStateID] = lsaCopy; 00236 networkLSAs.push_back(lsaCopy); 00237 return true; 00238 } 00239 } 00240 00241 bool AnsaOSPF::Area::InstallSummaryLSA(OSPFSummaryLSA* lsa) 00242 { 00243 AnsaOSPF::LSAKeyType lsaKey; 00244 00245 lsaKey.linkStateID = lsa->getHeader().getLinkStateID(); 00246 lsaKey.advertisingRouter = lsa->getHeader().getAdvertisingRouter().getInt(); 00247 00248 std::map<AnsaOSPF::LSAKeyType, AnsaOSPF::SummaryLSA*, AnsaOSPF::LSAKeyType_Less>::iterator lsaIt = summaryLSAsByID.find(lsaKey); 00249 if (lsaIt != summaryLSAsByID.end()) { 00250 AnsaOSPF::LSAKeyType lsaKey; 00251 00252 lsaKey.linkStateID = lsa->getHeader().getLinkStateID(); 00253 lsaKey.advertisingRouter = lsa->getHeader().getAdvertisingRouter().getInt(); 00254 00255 RemoveFromAllRetransmissionLists(lsaKey); 00256 return lsaIt->second->Update(lsa); 00257 } else { 00258 AnsaOSPF::SummaryLSA* lsaCopy = new AnsaOSPF::SummaryLSA(*lsa); 00259 summaryLSAsByID[lsaKey] = lsaCopy; 00260 summaryLSAs.push_back(lsaCopy); 00261 return true; 00262 } 00263 } 00264 00265 AnsaOSPF::RouterLSA* AnsaOSPF::Area::FindRouterLSA(AnsaOSPF::LinkStateID linkStateID) 00266 { 00267 std::map<AnsaOSPF::LinkStateID, AnsaOSPF::RouterLSA*>::iterator lsaIt = routerLSAsByID.find(linkStateID); 00268 if (lsaIt != routerLSAsByID.end()) { 00269 return lsaIt->second; 00270 } else { 00271 return NULL; 00272 } 00273 } 00274 00275 const AnsaOSPF::RouterLSA* AnsaOSPF::Area::FindRouterLSA(AnsaOSPF::LinkStateID linkStateID) const 00276 { 00277 std::map<AnsaOSPF::LinkStateID, AnsaOSPF::RouterLSA*>::const_iterator lsaIt = routerLSAsByID.find(linkStateID); 00278 if (lsaIt != routerLSAsByID.end()) { 00279 return lsaIt->second; 00280 } else { 00281 return NULL; 00282 } 00283 } 00284 00285 AnsaOSPF::NetworkLSA* AnsaOSPF::Area::FindNetworkLSA(AnsaOSPF::LinkStateID linkStateID) 00286 { 00287 std::map<AnsaOSPF::LinkStateID, AnsaOSPF::NetworkLSA*>::iterator lsaIt = networkLSAsByID.find(linkStateID); 00288 if (lsaIt != networkLSAsByID.end()) { 00289 return lsaIt->second; 00290 } else { 00291 return NULL; 00292 } 00293 } 00294 00295 const AnsaOSPF::NetworkLSA* AnsaOSPF::Area::FindNetworkLSA(AnsaOSPF::LinkStateID linkStateID) const 00296 { 00297 std::map<AnsaOSPF::LinkStateID, AnsaOSPF::NetworkLSA*>::const_iterator lsaIt = networkLSAsByID.find(linkStateID); 00298 if (lsaIt != networkLSAsByID.end()) { 00299 return lsaIt->second; 00300 } else { 00301 return NULL; 00302 } 00303 } 00304 00305 AnsaOSPF::SummaryLSA* AnsaOSPF::Area::FindSummaryLSA(AnsaOSPF::LSAKeyType lsaKey) 00306 { 00307 std::map<AnsaOSPF::LSAKeyType, AnsaOSPF::SummaryLSA*, AnsaOSPF::LSAKeyType_Less>::iterator lsaIt = summaryLSAsByID.find(lsaKey); 00308 if (lsaIt != summaryLSAsByID.end()) { 00309 return lsaIt->second; 00310 } else { 00311 return NULL; 00312 } 00313 } 00314 00315 const AnsaOSPF::SummaryLSA* AnsaOSPF::Area::FindSummaryLSA(AnsaOSPF::LSAKeyType lsaKey) const 00316 { 00317 std::map<AnsaOSPF::LSAKeyType, AnsaOSPF::SummaryLSA*, AnsaOSPF::LSAKeyType_Less>::const_iterator lsaIt = summaryLSAsByID.find(lsaKey); 00318 if (lsaIt != summaryLSAsByID.end()) { 00319 return lsaIt->second; 00320 } else { 00321 return NULL; 00322 } 00323 } 00324 00325 void AnsaOSPF::Area::RemoveParentFromRoutingInfo(OSPFLSA* parent) 00326 { 00327 long lsaCount = routerLSAs.size(); 00328 long i; 00329 00330 for (i = 0; i < lsaCount; i++) 00331 { 00332 if(routerLSAs[i] != NULL) 00333 { 00334 AnsaOSPF::RouterLSA* routerLSA = routerLSAs[i]; 00335 AnsaOSPF::RoutingInfo* routingInfo = check_and_cast<AnsaOSPF::RoutingInfo*> (routerLSA); 00336 00337 if(routingInfo->GetParent() == parent) 00338 routingInfo->SetParent(NULL); 00339 } 00340 } 00341 00342 lsaCount = networkLSAs.size(); 00343 00344 for (i = 0; i < lsaCount; i++) 00345 { 00346 if(networkLSAs[i] != NULL) 00347 { 00348 AnsaOSPF::NetworkLSA* networkLSA = networkLSAs[i]; 00349 AnsaOSPF::RoutingInfo* routingInfo = check_and_cast<AnsaOSPF::RoutingInfo*> (networkLSA); 00350 00351 if(routingInfo->GetParent() == parent) 00352 routingInfo->SetParent(NULL); 00353 } 00354 } 00355 00356 lsaCount = summaryLSAs.size(); 00357 00358 for (i = 0; i < lsaCount; i++) 00359 { 00360 if(summaryLSAs[i] != NULL) 00361 { 00362 AnsaOSPF::SummaryLSA* summaryLSA = summaryLSAs[i]; 00363 AnsaOSPF::RoutingInfo* routingInfo = check_and_cast<AnsaOSPF::RoutingInfo*> (summaryLSA); 00364 00365 if(routingInfo->GetParent() == parent) 00366 routingInfo->SetParent(NULL); 00367 } 00368 } 00369 } 00370 00371 void AnsaOSPF::Area::AgeDatabase(void) 00372 { 00373 long lsaCount = routerLSAs.size(); 00374 bool rebuildRoutingTable = false; 00375 long i; 00376 00377 IPAddress routerId(GetRouter()->GetRouterID()); 00378 EV << routerId.str(); 00379 00380 00381 for (i = 0; i < lsaCount; i++) { 00382 unsigned short lsAge = routerLSAs[i]->getHeader().getLsAge(); 00383 bool selfOriginated = (routerLSAs[i]->getHeader().getAdvertisingRouter().getInt() == parentRouter->GetRouterID()); 00384 bool unreachable = parentRouter->IsDestinationUnreachable(routerLSAs[i]); 00385 AnsaOSPF::RouterLSA* lsa = routerLSAs[i]; 00386 00387 00388 char addressString[16]; 00389 unsigned int linkCount = lsa->getLinksArraySize(); 00390 for (unsigned int j = 0; j < linkCount; j++) { 00391 const Link& link = lsa->getLinks(j); 00392 EV << " ID=" 00393 << AddressStringFromULong(addressString, sizeof(addressString), link.getLinkID().getInt()) 00394 << ","; 00395 EV << " data=" 00396 << AddressStringFromULong(addressString, sizeof(addressString), link.getLinkData()) 00397 << ", type="; 00398 switch (link.getType()) { 00399 case PointToPointLink: EV << "PointToPoint"; break; 00400 case TransitLink: EV << "Transit"; break; 00401 case StubLink: EV << "Stub"; break; 00402 case VirtualLink: EV << "Virtual"; break; 00403 default: EV << "Unknown"; break; 00404 } 00405 EV << ", cost=" 00406 << link.getLinkCost() 00407 << "\n"; 00408 } 00409 00410 if ((selfOriginated && (lsAge < (LS_REFRESH_TIME - 1))) || (!selfOriginated && (lsAge < (MAX_AGE - 1)))) { 00411 lsa->getHeader().setLsAge(lsAge + 1); 00412 if ((lsAge + 1) % CHECK_AGE == 0) { 00413 if (!lsa->ValidateLSChecksum()) { 00414 EV << "Invalid LS checksum. Memory error detected!\n"; 00415 } 00416 } 00417 lsa->IncrementInstallTime(); 00418 } 00419 if (selfOriginated && (lsAge == (LS_REFRESH_TIME - 1))) { 00420 if (unreachable) { 00421 lsa->getHeader().setLsAge(MAX_AGE); 00422 FloodLSA(lsa); 00423 lsa->IncrementInstallTime(); 00424 } else { 00425 long sequenceNumber = lsa->getHeader().getLsSequenceNumber(); 00426 if (sequenceNumber == MAX_SEQUENCE_NUMBER) { 00427 lsa->getHeader().setLsAge(MAX_AGE); 00428 FloodLSA(lsa); 00429 lsa->IncrementInstallTime(); 00430 } else { 00431 AnsaOSPF::RouterLSA* newLSA = OriginateRouterLSA(); 00432 00433 newLSA->getHeader().setLsSequenceNumber(sequenceNumber + 1); 00434 newLSA->getHeader().setLsChecksum(0); // TODO: calculate correct LS checksum 00435 rebuildRoutingTable |= lsa->Update(newLSA); 00436 delete newLSA; 00437 00438 FloodLSA(lsa); 00439 } 00440 } 00441 } 00442 if (!selfOriginated && (lsAge == MAX_AGE - 1)) { 00443 lsa->getHeader().setLsAge(MAX_AGE); 00444 FloodLSA(lsa); 00445 lsa->IncrementInstallTime(); 00446 } 00447 if (lsAge == MAX_AGE) { 00448 AnsaOSPF::LSAKeyType lsaKey; 00449 00450 lsaKey.linkStateID = lsa->getHeader().getLinkStateID(); 00451 lsaKey.advertisingRouter = lsa->getHeader().getAdvertisingRouter().getInt(); 00452 00453 if (!IsOnAnyRetransmissionList(lsaKey) && 00454 !HasAnyNeighborInStates(AnsaOSPF::Neighbor::ExchangeState | AnsaOSPF::Neighbor::LoadingState)) 00455 { 00456 if (!selfOriginated || unreachable) { 00457 routerLSAsByID.erase(lsa->getHeader().getLinkStateID()); 00458 delete lsa; 00459 routerLSAs[i] = NULL; 00460 rebuildRoutingTable = true; 00461 } else { 00462 AnsaOSPF::RouterLSA* newLSA = OriginateRouterLSA(); 00463 long sequenceNumber = lsa->getHeader().getLsSequenceNumber(); 00464 00465 newLSA->getHeader().setLsSequenceNumber((sequenceNumber == MAX_SEQUENCE_NUMBER) ? INITIAL_SEQUENCE_NUMBER : sequenceNumber + 1); 00466 newLSA->getHeader().setLsChecksum(0); // TODO: calculate correct LS checksum 00467 rebuildRoutingTable |= lsa->Update(newLSA); 00468 delete newLSA; 00469 00470 FloodLSA(lsa); 00471 } 00472 } 00473 } 00474 } 00475 00476 00477 std::vector<RouterLSA*>::iterator routerIt = routerLSAs.begin(); 00478 while (routerIt != routerLSAs.end()) { 00479 if ((*routerIt) == NULL) { 00480 routerIt = routerLSAs.erase(routerIt); 00481 } else { 00482 routerIt++; 00483 } 00484 } 00485 00486 lsaCount = networkLSAs.size(); 00487 for (i = 0; i < lsaCount; i++) { 00488 unsigned short lsAge = networkLSAs[i]->getHeader().getLsAge(); 00489 bool unreachable = parentRouter->IsDestinationUnreachable(networkLSAs[i]); 00490 AnsaOSPF::NetworkLSA* lsa = networkLSAs[i]; 00491 AnsaOSPF::Interface* localIntf = GetInterface(IPv4AddressFromULong(lsa->getHeader().getLinkStateID())); 00492 bool selfOriginated = false; 00493 00494 00495 if ((localIntf != NULL) && 00496 (localIntf->GetState() == AnsaOSPF::Interface::DesignatedRouterState) && 00497 (localIntf->GetNeighborCount() > 0) && 00498 (localIntf->HasAnyNeighborInStates(AnsaOSPF::Neighbor::FullState))) 00499 { 00500 selfOriginated = true; 00501 } 00502 00503 if ((selfOriginated && (lsAge < (LS_REFRESH_TIME - 1))) || (!selfOriginated && (lsAge < (MAX_AGE - 1)))) { 00504 lsa->getHeader().setLsAge(lsAge + 1); 00505 if ((lsAge + 1) % CHECK_AGE == 0) { 00506 if (!lsa->ValidateLSChecksum()) { 00507 EV << "Invalid LS checksum. Memory error detected!\n"; 00508 } 00509 } 00510 lsa->IncrementInstallTime(); 00511 } 00512 if (selfOriginated && (lsAge == (LS_REFRESH_TIME - 1))) { 00513 if (unreachable) { 00514 lsa->getHeader().setLsAge(MAX_AGE); 00515 FloodLSA(lsa); 00516 lsa->IncrementInstallTime(); 00517 } else { 00518 long sequenceNumber = lsa->getHeader().getLsSequenceNumber(); 00519 if (sequenceNumber == MAX_SEQUENCE_NUMBER) { 00520 lsa->getHeader().setLsAge(MAX_AGE); 00521 FloodLSA(lsa); 00522 lsa->IncrementInstallTime(); 00523 } else { 00524 AnsaOSPF::NetworkLSA* newLSA = OriginateNetworkLSA(localIntf); 00525 00526 if (newLSA != NULL) { 00527 newLSA->getHeader().setLsSequenceNumber(sequenceNumber + 1); 00528 newLSA->getHeader().setLsChecksum(0); // TODO: calculate correct LS checksum 00529 rebuildRoutingTable |= lsa->Update(newLSA); 00530 delete newLSA; 00531 } else { // no neighbors on the network -> old NetworkLSA must be flushed 00532 lsa->getHeader().setLsAge(MAX_AGE); 00533 lsa->IncrementInstallTime(); 00534 } 00535 00536 FloodLSA(lsa); 00537 } 00538 } 00539 } 00540 if (!selfOriginated && (lsAge == MAX_AGE - 1)) { 00541 lsa->getHeader().setLsAge(MAX_AGE); 00542 FloodLSA(lsa); 00543 lsa->IncrementInstallTime(); 00544 } 00545 if (lsAge == MAX_AGE) { 00546 AnsaOSPF::LSAKeyType lsaKey; 00547 00548 lsaKey.linkStateID = lsa->getHeader().getLinkStateID(); 00549 lsaKey.advertisingRouter = lsa->getHeader().getAdvertisingRouter().getInt(); 00550 00551 if (!IsOnAnyRetransmissionList(lsaKey) && 00552 !HasAnyNeighborInStates(AnsaOSPF::Neighbor::ExchangeState | AnsaOSPF::Neighbor::LoadingState)) 00553 { 00554 if (!selfOriginated || unreachable) { 00555 networkLSAsByID.erase(lsa->getHeader().getLinkStateID()); 00556 RemoveParentFromRoutingInfo(check_and_cast<OSPFLSA*> (lsa)); 00557 delete lsa; 00558 networkLSAs[i] = NULL; 00559 rebuildRoutingTable = true; 00560 } else { 00561 AnsaOSPF::NetworkLSA* newLSA = OriginateNetworkLSA(localIntf); 00562 long sequenceNumber = lsa->getHeader().getLsSequenceNumber(); 00563 00564 if (newLSA != NULL) { 00565 newLSA->getHeader().setLsSequenceNumber((sequenceNumber == MAX_SEQUENCE_NUMBER) ? INITIAL_SEQUENCE_NUMBER : sequenceNumber + 1); 00566 newLSA->getHeader().setLsChecksum(0); // TODO: calculate correct LS checksum 00567 rebuildRoutingTable |= lsa->Update(newLSA); 00568 delete newLSA; 00569 00570 FloodLSA(lsa); 00571 } else { // no neighbors on the network -> old NetworkLSA must be deleted 00572 delete networkLSAs[i]; 00573 } 00574 } 00575 } 00576 } 00577 } 00578 std::vector<NetworkLSA*>::iterator networkIt = networkLSAs.begin(); 00579 while (networkIt != networkLSAs.end()) { 00580 if ((*networkIt) == NULL) { 00581 networkIt = networkLSAs.erase(networkIt); 00582 } else { 00583 networkIt++; 00584 } 00585 } 00586 00587 lsaCount = summaryLSAs.size(); 00588 for (i = 0; i < lsaCount; i++) { 00589 unsigned short lsAge = summaryLSAs[i]->getHeader().getLsAge(); 00590 bool selfOriginated = (summaryLSAs[i]->getHeader().getAdvertisingRouter().getInt() == parentRouter->GetRouterID()); 00591 bool unreachable = parentRouter->IsDestinationUnreachable(summaryLSAs[i]); 00592 AnsaOSPF::SummaryLSA* lsa = summaryLSAs[i]; 00593 00594 00595 if ((selfOriginated && (lsAge < (LS_REFRESH_TIME - 1))) || (!selfOriginated && (lsAge < (MAX_AGE - 1)))) { 00596 lsa->getHeader().setLsAge(lsAge + 1); 00597 if ((lsAge + 1) % CHECK_AGE == 0) { 00598 if (!lsa->ValidateLSChecksum()) { 00599 EV << "Invalid LS checksum. Memory error detected!\n"; 00600 } 00601 } 00602 lsa->IncrementInstallTime(); 00603 } 00604 if (selfOriginated && (lsAge == (LS_REFRESH_TIME - 1))) { 00605 if (unreachable) { 00606 lsa->getHeader().setLsAge(MAX_AGE); 00607 FloodLSA(lsa); 00608 lsa->IncrementInstallTime(); 00609 } else { 00610 long sequenceNumber = lsa->getHeader().getLsSequenceNumber(); 00611 if (sequenceNumber == MAX_SEQUENCE_NUMBER) { 00612 lsa->getHeader().setLsAge(MAX_AGE); 00613 FloodLSA(lsa); 00614 lsa->IncrementInstallTime(); 00615 } else { 00616 AnsaOSPF::SummaryLSA* newLSA = OriginateSummaryLSA(lsa); 00617 00618 if (newLSA != NULL) { 00619 newLSA->getHeader().setLsSequenceNumber(sequenceNumber + 1); 00620 newLSA->getHeader().setLsChecksum(0); // TODO: calculate correct LS checksum 00621 rebuildRoutingTable |= lsa->Update(newLSA); 00622 delete newLSA; 00623 00624 FloodLSA(lsa); 00625 } else { 00626 lsa->getHeader().setLsAge(MAX_AGE); 00627 FloodLSA(lsa); 00628 lsa->IncrementInstallTime(); 00629 } 00630 } 00631 } 00632 } 00633 if (!selfOriginated && (lsAge == MAX_AGE - 1)) { 00634 lsa->getHeader().setLsAge(MAX_AGE); 00635 FloodLSA(lsa); 00636 lsa->IncrementInstallTime(); 00637 } 00638 if (lsAge == MAX_AGE) { 00639 AnsaOSPF::LSAKeyType lsaKey; 00640 00641 lsaKey.linkStateID = lsa->getHeader().getLinkStateID(); 00642 lsaKey.advertisingRouter = lsa->getHeader().getAdvertisingRouter().getInt(); 00643 00644 if (!IsOnAnyRetransmissionList(lsaKey) && 00645 !HasAnyNeighborInStates(AnsaOSPF::Neighbor::ExchangeState | AnsaOSPF::Neighbor::LoadingState)) 00646 { 00647 if (!selfOriginated || unreachable) { 00648 summaryLSAsByID.erase(lsaKey); 00649 delete lsa; 00650 summaryLSAs[i] = NULL; 00651 rebuildRoutingTable = true; 00652 } else { 00653 AnsaOSPF::SummaryLSA* newLSA = OriginateSummaryLSA(lsa); 00654 if (newLSA != NULL) { 00655 long sequenceNumber = lsa->getHeader().getLsSequenceNumber(); 00656 00657 newLSA->getHeader().setLsSequenceNumber((sequenceNumber == MAX_SEQUENCE_NUMBER) ? INITIAL_SEQUENCE_NUMBER : sequenceNumber + 1); 00658 newLSA->getHeader().setLsChecksum(0); // TODO: calculate correct LS checksum 00659 rebuildRoutingTable |= lsa->Update(newLSA); 00660 delete newLSA; 00661 00662 FloodLSA(lsa); 00663 } else { 00664 summaryLSAsByID.erase(lsaKey); 00665 delete lsa; 00666 summaryLSAs[i] = NULL; 00667 rebuildRoutingTable = true; 00668 } 00669 } 00670 } 00671 } 00672 } 00673 00674 std::vector<SummaryLSA*>::iterator summaryIt = summaryLSAs.begin(); 00675 while (summaryIt != summaryLSAs.end()) { 00676 if ((*summaryIt) == NULL) { 00677 summaryIt = summaryLSAs.erase(summaryIt); 00678 } else { 00679 summaryIt++; 00680 } 00681 } 00682 00683 long interfaceCount = associatedInterfaces.size(); 00684 for (long m = 0; m < interfaceCount; m++) { 00685 associatedInterfaces[m]->AgeTransmittedLSALists(); 00686 } 00687 00688 if (rebuildRoutingTable) { 00689 parentRouter->RebuildRoutingTable(); 00690 } 00691 } 00692 00693 bool AnsaOSPF::Area::HasAnyNeighborInStates(int states) const 00694 { 00695 long interfaceCount = associatedInterfaces.size(); 00696 for (long i = 0; i < interfaceCount; i++) { 00697 if (associatedInterfaces[i]->HasAnyNeighborInStates(states)) { 00698 return true; 00699 } 00700 } 00701 return false; 00702 } 00703 00704 void AnsaOSPF::Area::RemoveFromAllRetransmissionLists(AnsaOSPF::LSAKeyType lsaKey) 00705 { 00706 long interfaceCount = associatedInterfaces.size(); 00707 for (long i = 0; i < interfaceCount; i++) { 00708 associatedInterfaces[i]->RemoveFromAllRetransmissionLists(lsaKey); 00709 } 00710 } 00711 00712 bool AnsaOSPF::Area::IsOnAnyRetransmissionList(AnsaOSPF::LSAKeyType lsaKey) const 00713 { 00714 long interfaceCount = associatedInterfaces.size(); 00715 for (long i = 0; i < interfaceCount; i++) { 00716 if (associatedInterfaces[i]->IsOnAnyRetransmissionList(lsaKey)) { 00717 return true; 00718 } 00719 } 00720 return false; 00721 } 00722 00723 bool AnsaOSPF::Area::FloodLSA(OSPFLSA* lsa, AnsaOSPF::Interface* intf, AnsaOSPF::Neighbor* neighbor) 00724 { 00725 bool floodedBackOut = false; 00726 long interfaceCount = associatedInterfaces.size(); 00727 00728 for (long i = 0; i < interfaceCount; i++) { 00729 if (associatedInterfaces[i]->FloodLSA(lsa, intf, neighbor)) { 00730 floodedBackOut = true; 00731 } 00732 } 00733 00734 return floodedBackOut; 00735 } 00736 00737 bool AnsaOSPF::Area::IsLocalAddress(AnsaOSPF::IPv4Address address) const 00738 { 00739 long interfaceCount = associatedInterfaces.size(); 00740 for (long i = 0; i < interfaceCount; i++) { 00741 if (associatedInterfaces[i]->GetAddressRange().address == address) { 00742 return true; 00743 } 00744 } 00745 return false; 00746 } 00747 00748 AnsaOSPF::RouterLSA* AnsaOSPF::Area::OriginateRouterLSA(void) 00749 { 00750 AnsaOSPF::RouterLSA* routerLSA = new AnsaOSPF::RouterLSA; 00751 OSPFLSAHeader& lsaHeader = routerLSA->getHeader(); 00752 long interfaceCount = associatedInterfaces.size(); 00753 OSPFOptions lsOptions; 00754 long i; 00755 00756 lsaHeader.setLsAge(0); 00757 memset(&lsOptions, 0, sizeof(OSPFOptions)); 00758 lsOptions.E_ExternalRoutingCapability = externalRoutingCapability; 00759 lsaHeader.setLsOptions(lsOptions); 00760 lsaHeader.setLsType(RouterLSAType); 00761 lsaHeader.setLinkStateID(parentRouter->GetRouterID()); 00762 lsaHeader.setAdvertisingRouter(parentRouter->GetRouterID()); 00763 lsaHeader.setLsSequenceNumber(INITIAL_SEQUENCE_NUMBER); 00764 00765 routerLSA->setB_AreaBorderRouter(parentRouter->GetAreaCount() > 1); 00766 routerLSA->setE_ASBoundaryRouter((externalRoutingCapability && parentRouter->GetASBoundaryRouter()) ? true : false); 00767 AnsaOSPF::Area* backbone = parentRouter->GetArea(AnsaOSPF::BackboneAreaID); 00768 routerLSA->setV_VirtualLinkEndpoint((backbone == NULL) ? false : backbone->HasVirtualLink(areaID)); 00769 00770 routerLSA->setNumberOfLinks(0); 00771 routerLSA->setLinksArraySize(0); 00772 for (i = 0; i < interfaceCount; i++) { 00773 AnsaOSPF::Interface* intf = associatedInterfaces[i]; 00774 00775 if (intf->GetState() == AnsaOSPF::Interface::DownState) { 00776 continue; 00777 } 00778 if ((intf->GetState() == AnsaOSPF::Interface::LoopbackState) && 00779 ((intf->GetType() != AnsaOSPF::Interface::PointToPoint) || 00780 (intf->GetAddressRange().address != AnsaOSPF::NullIPv4Address))) 00781 { 00782 Link stubLink; 00783 stubLink.setType(StubLink); 00784 stubLink.setLinkID(ULongFromIPv4Address(intf->GetAddressRange().address)); 00785 stubLink.setLinkData(0xFFFFFFFF); 00786 stubLink.setLinkCost(0); 00787 stubLink.setNumberOfTOS(0); 00788 stubLink.setTosDataArraySize(0); 00789 00790 unsigned short linkIndex = routerLSA->getLinksArraySize(); 00791 routerLSA->setLinksArraySize(linkIndex + 1); 00792 routerLSA->setNumberOfLinks(linkIndex + 1); 00793 routerLSA->setLinks(linkIndex, stubLink); 00794 } 00795 if (intf->GetState() > AnsaOSPF::Interface::LoopbackState) { 00796 switch (intf->GetType()) { 00797 case AnsaOSPF::Interface::PointToPoint: 00798 { 00799 AnsaOSPF::Neighbor* neighbor = (intf->GetNeighborCount() > 0) ? intf->GetNeighbor(0) : NULL; 00800 if (neighbor != NULL) { 00801 if (neighbor->GetState() == AnsaOSPF::Neighbor::FullState) { 00802 Link link; 00803 link.setType(PointToPointLink); 00804 link.setLinkID(neighbor->GetNeighborID()); 00805 if (intf->GetAddressRange().address != AnsaOSPF::NullIPv4Address) { 00806 link.setLinkData(ULongFromIPv4Address(intf->GetAddressRange().address)); 00807 } else { 00808 link.setLinkData(intf->GetIfIndex()); 00809 } 00810 link.setLinkCost(intf->GetOutputCost()); 00811 link.setNumberOfTOS(0); 00812 link.setTosDataArraySize(0); 00813 00814 unsigned short linkIndex = routerLSA->getLinksArraySize(); 00815 routerLSA->setLinksArraySize(linkIndex + 1); 00816 routerLSA->setNumberOfLinks(linkIndex + 1); 00817 routerLSA->setLinks(linkIndex, link); 00818 } 00819 if (intf->GetState() == AnsaOSPF::Interface::PointToPointState) { 00820 if (neighbor->GetAddress() != AnsaOSPF::NullIPv4Address) { 00821 Link stubLink; 00822 stubLink.setType(StubLink); 00823 stubLink.setLinkID(ULongFromIPv4Address(neighbor->GetAddress())); 00824 stubLink.setLinkData(ULongFromIPv4Address(intf->GetAddressRange().mask)); 00825 stubLink.setLinkCost(intf->GetOutputCost()); 00826 stubLink.setNumberOfTOS(0); 00827 stubLink.setTosDataArraySize(0); 00828 00829 unsigned short linkIndex = routerLSA->getLinksArraySize(); 00830 routerLSA->setLinksArraySize(linkIndex + 1); 00831 routerLSA->setNumberOfLinks(linkIndex + 1); 00832 routerLSA->setLinks(linkIndex, stubLink); 00833 } else { 00834 if (ULongFromIPv4Address(intf->GetAddressRange().mask) != 0xFFFFFFFF) { 00835 Link stubLink; 00836 stubLink.setType(StubLink); 00837 stubLink.setLinkID(ULongFromIPv4Address(intf->GetAddressRange().address & 00838 intf->GetAddressRange().mask)); 00839 stubLink.setLinkData(ULongFromIPv4Address(intf->GetAddressRange().mask)); 00840 stubLink.setLinkCost(intf->GetOutputCost()); 00841 stubLink.setNumberOfTOS(0); 00842 stubLink.setTosDataArraySize(0); 00843 00844 unsigned short linkIndex = routerLSA->getLinksArraySize(); 00845 routerLSA->setLinksArraySize(linkIndex + 1); 00846 routerLSA->setNumberOfLinks(linkIndex + 1); 00847 routerLSA->setLinks(linkIndex, stubLink); 00848 } 00849 } 00850 } 00851 } 00852 } 00853 break; 00854 case AnsaOSPF::Interface::Broadcast: 00855 case AnsaOSPF::Interface::NBMA: 00856 { 00857 if (intf->GetState() == AnsaOSPF::Interface::WaitingState) { 00858 Link stubLink; 00859 stubLink.setType(StubLink); 00860 stubLink.setLinkID(ULongFromIPv4Address(intf->GetAddressRange().address & 00861 intf->GetAddressRange().mask)); 00862 stubLink.setLinkData(ULongFromIPv4Address(intf->GetAddressRange().mask)); 00863 stubLink.setLinkCost(intf->GetOutputCost()); 00864 stubLink.setNumberOfTOS(0); 00865 stubLink.setTosDataArraySize(0); 00866 00867 unsigned short linkIndex = routerLSA->getLinksArraySize(); 00868 routerLSA->setLinksArraySize(linkIndex + 1); 00869 routerLSA->setNumberOfLinks(linkIndex + 1); 00870 routerLSA->setLinks(linkIndex, stubLink); 00871 } else { 00872 AnsaOSPF::Neighbor* dRouter = intf->GetNeighborByAddress(intf->GetDesignatedRouter().ipInterfaceAddress); 00873 if (((dRouter != NULL) && (dRouter->GetState() == AnsaOSPF::Neighbor::FullState)) || 00874 ((intf->GetDesignatedRouter().routerID == parentRouter->GetRouterID()) && 00875 (intf->HasAnyNeighborInStates(AnsaOSPF::Neighbor::FullState)))) 00876 { 00877 Link link; 00878 link.setType(TransitLink); 00879 link.setLinkID(ULongFromIPv4Address(intf->GetDesignatedRouter().ipInterfaceAddress)); 00880 link.setLinkData(ULongFromIPv4Address(intf->GetAddressRange().address)); 00881 link.setLinkCost(intf->GetOutputCost()); 00882 link.setNumberOfTOS(0); 00883 link.setTosDataArraySize(0); 00884 00885 unsigned short linkIndex = routerLSA->getLinksArraySize(); 00886 routerLSA->setLinksArraySize(linkIndex + 1); 00887 routerLSA->setNumberOfLinks(linkIndex + 1); 00888 routerLSA->setLinks(linkIndex, link); 00889 } else { 00890 Link stubLink; 00891 stubLink.setType(StubLink); 00892 stubLink.setLinkID(ULongFromIPv4Address(intf->GetAddressRange().address & 00893 intf->GetAddressRange().mask)); 00894 stubLink.setLinkData(ULongFromIPv4Address(intf->GetAddressRange().mask)); 00895 stubLink.setLinkCost(intf->GetOutputCost()); 00896 stubLink.setNumberOfTOS(0); 00897 stubLink.setTosDataArraySize(0); 00898 00899 unsigned short linkIndex = routerLSA->getLinksArraySize(); 00900 routerLSA->setLinksArraySize(linkIndex + 1); 00901 routerLSA->setNumberOfLinks(linkIndex + 1); 00902 routerLSA->setLinks(linkIndex, stubLink); 00903 } 00904 } 00905 } 00906 break; 00907 case AnsaOSPF::Interface::Virtual: 00908 { 00909 AnsaOSPF::Neighbor* neighbor = (intf->GetNeighborCount() > 0) ? intf->GetNeighbor(0) : NULL; 00910 if ((neighbor != NULL) && (neighbor->GetState() == AnsaOSPF::Neighbor::FullState)) { 00911 Link link; 00912 link.setType(VirtualLink); 00913 link.setLinkID(neighbor->GetNeighborID()); 00914 link.setLinkData(ULongFromIPv4Address(intf->GetAddressRange().address)); 00915 link.setLinkCost(intf->GetOutputCost()); 00916 link.setNumberOfTOS(0); 00917 link.setTosDataArraySize(0); 00918 00919 unsigned short linkIndex = routerLSA->getLinksArraySize(); 00920 routerLSA->setLinksArraySize(linkIndex + 1); 00921 routerLSA->setNumberOfLinks(linkIndex + 1); 00922 routerLSA->setLinks(linkIndex, link); 00923 } 00924 } 00925 break; 00926 case AnsaOSPF::Interface::PointToMultiPoint: 00927 { 00928 Link stubLink; 00929 stubLink.setType(StubLink); 00930 stubLink.setLinkID(ULongFromIPv4Address(intf->GetAddressRange().address)); 00931 stubLink.setLinkData(0xFFFFFFFF); 00932 stubLink.setLinkCost(0); 00933 stubLink.setNumberOfTOS(0); 00934 stubLink.setTosDataArraySize(0); 00935 00936 unsigned short linkIndex = routerLSA->getLinksArraySize(); 00937 routerLSA->setLinksArraySize(linkIndex + 1); 00938 routerLSA->setNumberOfLinks(linkIndex + 1); 00939 routerLSA->setLinks(linkIndex, stubLink); 00940 00941 long neighborCount = intf->GetNeighborCount(); 00942 for (long i = 0; i < neighborCount; i++) { 00943 AnsaOSPF::Neighbor* neighbor = intf->GetNeighbor(i); 00944 if (neighbor->GetState() == AnsaOSPF::Neighbor::FullState) { 00945 Link link; 00946 link.setType(PointToPointLink); 00947 link.setLinkID(neighbor->GetNeighborID()); 00948 link.setLinkData(ULongFromIPv4Address(intf->GetAddressRange().address)); 00949 link.setLinkCost(intf->GetOutputCost()); 00950 link.setNumberOfTOS(0); 00951 link.setTosDataArraySize(0); 00952 00953 unsigned short linkIndex = routerLSA->getLinksArraySize(); 00954 routerLSA->setLinksArraySize(linkIndex + 1); 00955 routerLSA->setNumberOfLinks(linkIndex + 1); 00956 routerLSA->setLinks(linkIndex, stubLink); 00957 } 00958 } 00959 } 00960 break; 00961 default: break; 00962 } 00963 } 00964 } 00965 00966 long hostRouteCount = hostRoutes.size(); 00967 for (i = 0; i < hostRouteCount; i++) { 00968 Link stubLink; 00969 stubLink.setType(StubLink); 00970 stubLink.setLinkID(ULongFromIPv4Address(hostRoutes[i].address)); 00971 stubLink.setLinkData(0xFFFFFFFF); 00972 stubLink.setLinkCost(hostRoutes[i].linkCost); 00973 stubLink.setNumberOfTOS(0); 00974 stubLink.setTosDataArraySize(0); 00975 00976 unsigned short linkIndex = routerLSA->getLinksArraySize(); 00977 routerLSA->setLinksArraySize(linkIndex + 1); 00978 routerLSA->setNumberOfLinks(linkIndex + 1); 00979 routerLSA->setLinks(linkIndex, stubLink); 00980 } 00981 00982 lsaHeader.setLsChecksum(0); // TODO: calculate correct LS checksum 00983 00984 routerLSA->SetSource(AnsaOSPF::LSATrackingInfo::Originated); 00985 00986 return routerLSA; 00987 } 00988 00989 AnsaOSPF::NetworkLSA* AnsaOSPF::Area::OriginateNetworkLSA(const AnsaOSPF::Interface* intf) 00990 { 00991 if (intf->HasAnyNeighborInStates(AnsaOSPF::Neighbor::FullState)) { 00992 AnsaOSPF::NetworkLSA* networkLSA = new AnsaOSPF::NetworkLSA; 00993 OSPFLSAHeader& lsaHeader = networkLSA->getHeader(); 00994 long neighborCount = intf->GetNeighborCount(); 00995 OSPFOptions lsOptions; 00996 00997 lsaHeader.setLsAge(0); 00998 memset(&lsOptions, 0, sizeof(OSPFOptions)); 00999 lsOptions.E_ExternalRoutingCapability = externalRoutingCapability; 01000 lsaHeader.setLsOptions(lsOptions); 01001 lsaHeader.setLsType(NetworkLSAType); 01002 lsaHeader.setLinkStateID(ULongFromIPv4Address(intf->GetAddressRange().address)); 01003 lsaHeader.setAdvertisingRouter(parentRouter->GetRouterID()); 01004 lsaHeader.setLsSequenceNumber(INITIAL_SEQUENCE_NUMBER); 01005 01006 networkLSA->setNetworkMask(ULongFromIPv4Address(intf->GetAddressRange().mask)); 01007 01008 for (long j = 0; j < neighborCount; j++) { 01009 const AnsaOSPF::Neighbor* neighbor = intf->GetNeighbor(j); 01010 if (neighbor->GetState() == AnsaOSPF::Neighbor::FullState) { 01011 unsigned short netIndex = networkLSA->getAttachedRoutersArraySize(); 01012 networkLSA->setAttachedRoutersArraySize(netIndex + 1); 01013 networkLSA->setAttachedRouters(netIndex, neighbor->GetNeighborID()); 01014 } 01015 } 01016 unsigned short netIndex = networkLSA->getAttachedRoutersArraySize(); 01017 networkLSA->setAttachedRoutersArraySize(netIndex + 1); 01018 networkLSA->setAttachedRouters(netIndex, parentRouter->GetRouterID()); 01019 01020 lsaHeader.setLsChecksum(0); // TODO: calculate correct LS checksum 01021 01022 return networkLSA; 01023 } else { 01024 return NULL; 01025 } 01026 } 01027 01049 AnsaOSPF::LinkStateID AnsaOSPF::Area::GetUniqueLinkStateID(AnsaOSPF::IPv4AddressRange destination, 01050 AnsaOSPF::Metric destinationCost, 01051 AnsaOSPF::SummaryLSA*& lsaToReoriginate) const 01052 { 01053 if (lsaToReoriginate != NULL) { 01054 delete lsaToReoriginate; 01055 lsaToReoriginate = NULL; 01056 } 01057 01058 AnsaOSPF::LSAKeyType lsaKey; 01059 01060 lsaKey.linkStateID = ULongFromIPv4Address(destination.address); 01061 lsaKey.advertisingRouter = parentRouter->GetRouterID(); 01062 01063 const AnsaOSPF::SummaryLSA* foundLSA = FindSummaryLSA(lsaKey); 01064 01065 if (foundLSA == NULL) { 01066 return lsaKey.linkStateID; 01067 } else { 01068 AnsaOSPF::IPv4Address existingMask = IPv4AddressFromULong(foundLSA->getNetworkMask().getInt()); 01069 01070 if (destination.mask == existingMask) { 01071 return lsaKey.linkStateID; 01072 } else { 01073 if (destination.mask >= existingMask) { 01074 return (lsaKey.linkStateID | (~(ULongFromIPv4Address(destination.mask)))); 01075 } else { 01076 AnsaOSPF::SummaryLSA* summaryLSA = new AnsaOSPF::SummaryLSA(*foundLSA); 01077 01078 long sequenceNumber = summaryLSA->getHeader().getLsSequenceNumber(); 01079 01080 summaryLSA->getHeader().setLsAge(0); 01081 summaryLSA->getHeader().setLsSequenceNumber((sequenceNumber == MAX_SEQUENCE_NUMBER) ? INITIAL_SEQUENCE_NUMBER : sequenceNumber + 1); 01082 summaryLSA->setNetworkMask(ULongFromIPv4Address(destination.mask)); 01083 summaryLSA->setRouteCost(destinationCost); 01084 summaryLSA->getHeader().setLsChecksum(0); // TODO: calculate correct LS checksum 01085 01086 lsaToReoriginate = summaryLSA; 01087 01088 return (lsaKey.linkStateID | (~(ULongFromIPv4Address(existingMask)))); 01089 } 01090 } 01091 } 01092 } 01093 01094 AnsaOSPF::SummaryLSA* AnsaOSPF::Area::OriginateSummaryLSA(const AnsaOSPF::RoutingTableEntry* entry, 01095 const std::map<AnsaOSPF::LSAKeyType, bool, AnsaOSPF::LSAKeyType_Less>& originatedLSAs, 01096 AnsaOSPF::SummaryLSA*& lsaToReoriginate) 01097 { 01098 if (((entry->GetDestinationType() & AnsaOSPF::RoutingTableEntry::AreaBorderRouterDestination) != 0) || 01099 (entry->GetPathType() == AnsaOSPF::RoutingTableEntry::Type1External) || 01100 (entry->GetPathType() == AnsaOSPF::RoutingTableEntry::Type2External) || 01101 (entry->GetArea() == areaID)) 01102 { 01103 return NULL; 01104 } 01105 01106 bool allNextHopsInThisArea = true; 01107 unsigned int nextHopCount = entry->GetNextHopCount(); 01108 01109 for (unsigned int i = 0; i < nextHopCount; i++) { 01110 AnsaOSPF::Interface* nextHopInterface = parentRouter->GetNonVirtualInterface(entry->GetNextHop(i).ifIndex); 01111 if ((nextHopInterface != NULL) && (nextHopInterface->GetAreaID() != areaID)) { 01112 allNextHopsInThisArea = false; 01113 break; 01114 } 01115 } 01116 if ((allNextHopsInThisArea) || (entry->GetCost() >= LS_INFINITY)){ 01117 return NULL; 01118 } 01119 01120 if ((entry->GetDestinationType() & AnsaOSPF::RoutingTableEntry::ASBoundaryRouterDestination) != 0) { 01121 AnsaOSPF::RoutingTableEntry* preferredEntry = parentRouter->GetPreferredEntry(*(entry->GetLinkStateOrigin()), false); 01122 if ((preferredEntry != NULL) && (*preferredEntry == *entry) && (externalRoutingCapability)) { 01123 AnsaOSPF::SummaryLSA* summaryLSA = new AnsaOSPF::SummaryLSA; 01124 OSPFLSAHeader& lsaHeader = summaryLSA->getHeader(); 01125 OSPFOptions lsOptions; 01126 01127 lsaHeader.setLsAge(0); 01128 memset(&lsOptions, 0, sizeof(OSPFOptions)); 01129 lsOptions.E_ExternalRoutingCapability = externalRoutingCapability; 01130 lsaHeader.setLsOptions(lsOptions); 01131 lsaHeader.setLsType(SummaryLSA_ASBoundaryRoutersType); 01132 lsaHeader.setLinkStateID(entry->GetDestinationID().getInt()); 01133 lsaHeader.setAdvertisingRouter(parentRouter->GetRouterID()); 01134 lsaHeader.setLsSequenceNumber(INITIAL_SEQUENCE_NUMBER); 01135 01136 summaryLSA->setNetworkMask(entry->GetAddressMask()); 01137 summaryLSA->setRouteCost(entry->GetCost()); 01138 summaryLSA->setTosDataArraySize(0); 01139 01140 lsaHeader.setLsChecksum(0); // TODO: calculate correct LS checksum 01141 01142 summaryLSA->SetSource(AnsaOSPF::LSATrackingInfo::Originated); 01143 01144 return summaryLSA; 01145 } 01146 } else { // entry->GetDestinationType() == AnsaOSPF::RoutingTableEntry::NetworkDestination 01147 if (entry->GetPathType() == AnsaOSPF::RoutingTableEntry::InterArea) { 01148 AnsaOSPF::IPv4AddressRange destinationRange; 01149 01150 destinationRange.address = IPv4AddressFromULong(entry->GetDestinationID().getInt()); 01151 destinationRange.mask = IPv4AddressFromULong(entry->GetAddressMask().getInt()); 01152 01153 AnsaOSPF::LinkStateID newLinkStateID = GetUniqueLinkStateID(destinationRange, entry->GetCost(), lsaToReoriginate); 01154 01155 if (lsaToReoriginate != NULL) { 01156 AnsaOSPF::LSAKeyType lsaKey; 01157 01158 lsaKey.linkStateID = entry->GetDestinationID().getInt(); 01159 lsaKey.advertisingRouter = parentRouter->GetRouterID(); 01160 01161 std::map<AnsaOSPF::LSAKeyType, AnsaOSPF::SummaryLSA*, AnsaOSPF::LSAKeyType_Less>::iterator lsaIt = summaryLSAsByID.find(lsaKey); 01162 if (lsaIt == summaryLSAsByID.end()) { 01163 delete(lsaToReoriginate); 01164 lsaToReoriginate = NULL; 01165 return NULL; 01166 } else { 01167 AnsaOSPF::SummaryLSA* summaryLSA = new AnsaOSPF::SummaryLSA(*(lsaIt->second)); 01168 OSPFLSAHeader& lsaHeader = summaryLSA->getHeader(); 01169 01170 lsaHeader.setLsAge(0); 01171 lsaHeader.setLsSequenceNumber(INITIAL_SEQUENCE_NUMBER); 01172 lsaHeader.setLinkStateID(newLinkStateID); 01173 lsaHeader.setLsChecksum(0); // TODO: calculate correct LS checksum 01174 01175 return summaryLSA; 01176 } 01177 } else { 01178 AnsaOSPF::SummaryLSA* summaryLSA = new AnsaOSPF::SummaryLSA; 01179 OSPFLSAHeader& lsaHeader = summaryLSA->getHeader(); 01180 OSPFOptions lsOptions; 01181 01182 lsaHeader.setLsAge(0); 01183 memset(&lsOptions, 0, sizeof(OSPFOptions)); 01184 lsOptions.E_ExternalRoutingCapability = externalRoutingCapability; 01185 lsaHeader.setLsOptions(lsOptions); 01186 lsaHeader.setLsType(SummaryLSA_NetworksType); 01187 lsaHeader.setLinkStateID(newLinkStateID); 01188 lsaHeader.setAdvertisingRouter(parentRouter->GetRouterID()); 01189 lsaHeader.setLsSequenceNumber(INITIAL_SEQUENCE_NUMBER); 01190 01191 summaryLSA->setNetworkMask(entry->GetAddressMask()); 01192 summaryLSA->setRouteCost(entry->GetCost()); 01193 summaryLSA->setTosDataArraySize(0); 01194 01195 lsaHeader.setLsChecksum(0); // TODO: calculate correct LS checksum 01196 01197 summaryLSA->SetSource(AnsaOSPF::LSATrackingInfo::Originated); 01198 01199 return summaryLSA; 01200 } 01201 } else { // entry->GetPathType() == AnsaOSPF::RoutingTableEntry::IntraArea 01202 AnsaOSPF::IPv4AddressRange destinationAddressRange; 01203 01204 destinationAddressRange.address = IPv4AddressFromULong(entry->GetDestinationID().getInt()); 01205 destinationAddressRange.mask = IPv4AddressFromULong(entry->GetAddressMask().getInt()); 01206 01207 bool doAdvertise = false; 01208 AnsaOSPF::IPv4AddressRange containingAddressRange = parentRouter->GetContainingAddressRange(destinationAddressRange, &doAdvertise); 01209 if (((entry->GetArea() == AnsaOSPF::BackboneAreaID) && // the backbone's configured ranges should be ignored 01210 (transitCapability)) || // when originating Summary LSAs into transit areas 01211 (containingAddressRange == AnsaOSPF::NullIPv4AddressRange)) 01212 { 01213 AnsaOSPF::LinkStateID newLinkStateID = GetUniqueLinkStateID(destinationAddressRange, entry->GetCost(), lsaToReoriginate); 01214 01215 if (lsaToReoriginate != NULL) { 01216 AnsaOSPF::LSAKeyType lsaKey; 01217 01218 lsaKey.linkStateID = entry->GetDestinationID().getInt(); 01219 lsaKey.advertisingRouter = parentRouter->GetRouterID(); 01220 01221 std::map<AnsaOSPF::LSAKeyType, AnsaOSPF::SummaryLSA*, AnsaOSPF::LSAKeyType_Less>::iterator lsaIt = summaryLSAsByID.find(lsaKey); 01222 if (lsaIt == summaryLSAsByID.end()) { 01223 delete(lsaToReoriginate); 01224 lsaToReoriginate = NULL; 01225 return NULL; 01226 } else { 01227 AnsaOSPF::SummaryLSA* summaryLSA = new AnsaOSPF::SummaryLSA(*(lsaIt->second)); 01228 OSPFLSAHeader& lsaHeader = summaryLSA->getHeader(); 01229 01230 lsaHeader.setLsAge(0); 01231 lsaHeader.setLsSequenceNumber(INITIAL_SEQUENCE_NUMBER); 01232 lsaHeader.setLinkStateID(newLinkStateID); 01233 lsaHeader.setLsChecksum(0); // TODO: calculate correct LS checksum 01234 01235 return summaryLSA; 01236 } 01237 } else { 01238 AnsaOSPF::SummaryLSA* summaryLSA = new AnsaOSPF::SummaryLSA; 01239 OSPFLSAHeader& lsaHeader = summaryLSA->getHeader(); 01240 OSPFOptions lsOptions; 01241 01242 lsaHeader.setLsAge(0); 01243 memset(&lsOptions, 0, sizeof(OSPFOptions)); 01244 lsOptions.E_ExternalRoutingCapability = externalRoutingCapability; 01245 lsaHeader.setLsOptions(lsOptions); 01246 lsaHeader.setLsType(SummaryLSA_NetworksType); 01247 lsaHeader.setLinkStateID(newLinkStateID); 01248 lsaHeader.setAdvertisingRouter(parentRouter->GetRouterID()); 01249 lsaHeader.setLsSequenceNumber(INITIAL_SEQUENCE_NUMBER); 01250 01251 summaryLSA->setNetworkMask(entry->GetAddressMask()); 01252 summaryLSA->setRouteCost(entry->GetCost()); 01253 summaryLSA->setTosDataArraySize(0); 01254 01255 lsaHeader.setLsChecksum(0); // TODO: calculate correct LS checksum 01256 01257 summaryLSA->SetSource(AnsaOSPF::LSATrackingInfo::Originated); 01258 01259 return summaryLSA; 01260 } 01261 } else { 01262 if (doAdvertise) { 01263 Metric maxRangeCost = 0; 01264 unsigned long entryCount = parentRouter->GetRoutingTableEntryCount(); 01265 01266 for (unsigned long i = 0; i < entryCount; i++) { 01267 const AnsaOSPF::RoutingTableEntry* routingEntry = parentRouter->GetRoutingTableEntry(i); 01268 01269 if ((routingEntry->GetDestinationType() == AnsaOSPF::RoutingTableEntry::NetworkDestination) && 01270 (routingEntry->GetPathType() == AnsaOSPF::RoutingTableEntry::IntraArea) && 01271 ((routingEntry->GetDestinationID().getInt() & routingEntry->GetAddressMask().getInt() & ULongFromIPv4Address(containingAddressRange.mask)) == 01272 ULongFromIPv4Address(containingAddressRange.address & containingAddressRange.mask)) && 01273 (routingEntry->GetCost() > maxRangeCost)) 01274 { 01275 maxRangeCost = routingEntry->GetCost(); 01276 } 01277 } 01278 01279 AnsaOSPF::LinkStateID newLinkStateID = GetUniqueLinkStateID(containingAddressRange, maxRangeCost, lsaToReoriginate); 01280 AnsaOSPF::LSAKeyType lsaKey; 01281 01282 if (lsaToReoriginate != NULL) { 01283 lsaKey.linkStateID = lsaToReoriginate->getHeader().getLinkStateID(); 01284 lsaKey.advertisingRouter = parentRouter->GetRouterID(); 01285 01286 std::map<AnsaOSPF::LSAKeyType, bool, AnsaOSPF::LSAKeyType_Less>::const_iterator originatedIt = originatedLSAs.find(lsaKey); 01287 if (originatedIt != originatedLSAs.end()) { 01288 delete(lsaToReoriginate); 01289 lsaToReoriginate = NULL; 01290 return NULL; 01291 } 01292 01293 lsaKey.linkStateID = entry->GetDestinationID().getInt(); 01294 lsaKey.advertisingRouter = parentRouter->GetRouterID(); 01295 01296 std::map<AnsaOSPF::LSAKeyType, AnsaOSPF::SummaryLSA*, AnsaOSPF::LSAKeyType_Less>::iterator lsaIt = summaryLSAsByID.find(lsaKey); 01297 if (lsaIt == summaryLSAsByID.end()) { 01298 delete(lsaToReoriginate); 01299 lsaToReoriginate = NULL; 01300 return NULL; 01301 } 01302 01303 AnsaOSPF::SummaryLSA* summaryLSA = new AnsaOSPF::SummaryLSA(*(lsaIt->second)); 01304 OSPFLSAHeader& lsaHeader = summaryLSA->getHeader(); 01305 01306 lsaHeader.setLsAge(0); 01307 lsaHeader.setLsSequenceNumber(INITIAL_SEQUENCE_NUMBER); 01308 lsaHeader.setLinkStateID(newLinkStateID); 01309 lsaHeader.setLsChecksum(0); // TODO: calculate correct LS checksum 01310 01311 return summaryLSA; 01312 } else { 01313 lsaKey.linkStateID = newLinkStateID; 01314 lsaKey.advertisingRouter = parentRouter->GetRouterID(); 01315 01316 std::map<AnsaOSPF::LSAKeyType, bool, AnsaOSPF::LSAKeyType_Less>::const_iterator originatedIt = originatedLSAs.find(lsaKey); 01317 if (originatedIt != originatedLSAs.end()) { 01318 return NULL; 01319 } 01320 01321 AnsaOSPF::SummaryLSA* summaryLSA = new AnsaOSPF::SummaryLSA; 01322 OSPFLSAHeader& lsaHeader = summaryLSA->getHeader(); 01323 OSPFOptions lsOptions; 01324 01325 lsaHeader.setLsAge(0); 01326 memset(&lsOptions, 0, sizeof(OSPFOptions)); 01327 lsOptions.E_ExternalRoutingCapability = externalRoutingCapability; 01328 lsaHeader.setLsOptions(lsOptions); 01329 lsaHeader.setLsType(SummaryLSA_NetworksType); 01330 lsaHeader.setLinkStateID(newLinkStateID); 01331 lsaHeader.setAdvertisingRouter(parentRouter->GetRouterID()); 01332 lsaHeader.setLsSequenceNumber(INITIAL_SEQUENCE_NUMBER); 01333 01334 summaryLSA->setNetworkMask(entry->GetAddressMask()); 01335 summaryLSA->setRouteCost(entry->GetCost()); 01336 summaryLSA->setTosDataArraySize(0); 01337 01338 lsaHeader.setLsChecksum(0); // TODO: calculate correct LS checksum 01339 01340 summaryLSA->SetSource(AnsaOSPF::LSATrackingInfo::Originated); 01341 01342 return summaryLSA; 01343 } 01344 } 01345 } 01346 } 01347 } 01348 01349 return NULL; 01350 } 01351 01352 AnsaOSPF::SummaryLSA* AnsaOSPF::Area::OriginateSummaryLSA(const AnsaOSPF::SummaryLSA* summaryLSA) 01353 { 01354 const std::map<AnsaOSPF::LSAKeyType, bool, AnsaOSPF::LSAKeyType_Less> emptyMap; 01355 AnsaOSPF::SummaryLSA* dontReoriginate = NULL; 01356 01357 const OSPFLSAHeader& lsaHeader = summaryLSA->getHeader(); 01358 unsigned long entryCount = parentRouter->GetRoutingTableEntryCount(); 01359 01360 for (unsigned long i = 0; i < entryCount; i++) { 01361 const AnsaOSPF::RoutingTableEntry* entry = parentRouter->GetRoutingTableEntry(i); 01362 01363 if ((lsaHeader.getLsType() == SummaryLSA_ASBoundaryRoutersType) && 01364 ((((entry->GetDestinationType() & AnsaOSPF::RoutingTableEntry::AreaBorderRouterDestination) != 0) || 01365 ((entry->GetDestinationType() & AnsaOSPF::RoutingTableEntry::ASBoundaryRouterDestination) != 0)) && 01366 ((entry->GetDestinationID().getInt() == lsaHeader.getLinkStateID()) && 01367 (entry->GetAddressMask() == summaryLSA->getNetworkMask())))) 01368 { 01369 AnsaOSPF::SummaryLSA* returnLSA = OriginateSummaryLSA(entry, emptyMap, dontReoriginate); 01370 if (dontReoriginate != NULL) { 01371 delete dontReoriginate; 01372 } 01373 return returnLSA; 01374 } 01375 01376 unsigned long lsaMask = summaryLSA->getNetworkMask().getInt(); 01377 01378 01379 if ((lsaHeader.getLsType() == SummaryLSA_NetworksType) && 01380 (entry->GetDestinationType() == AnsaOSPF::RoutingTableEntry::NetworkDestination) && 01381 (entry->GetAddressMask().getInt() == lsaMask) && 01382 ((entry->GetDestinationID().getInt() & lsaMask) == (lsaHeader.getLinkStateID() & lsaMask))) 01383 { 01384 AnsaOSPF::SummaryLSA* returnLSA = OriginateSummaryLSA(entry, emptyMap, dontReoriginate); 01385 if (dontReoriginate != NULL) { 01386 delete dontReoriginate; 01387 } 01388 return returnLSA; 01389 } 01390 } 01391 return NULL; 01392 } 01393 01394 void AnsaOSPF::Area::CalculateShortestPathTree(std::vector<AnsaOSPF::RoutingTableEntry*>& newRoutingTable) 01395 { 01396 AnsaOSPF::RouterID routerID = parentRouter->GetRouterID(); 01397 bool finished = false; 01398 std::vector<OSPFLSA*> treeVertices; 01399 OSPFLSA* justAddedVertex; 01400 std::vector<OSPFLSA*> candidateVertices; 01401 unsigned long i, j, k; 01402 unsigned long lsaCount; 01403 01404 if (spfTreeRoot == NULL) { 01405 AnsaOSPF::RouterLSA* newLSA = OriginateRouterLSA(); 01406 01407 InstallRouterLSA(newLSA); 01408 01409 AnsaOSPF::RouterLSA* routerLSA = FindRouterLSA(routerID); 01410 01411 spfTreeRoot = routerLSA; 01412 FloodLSA(newLSA); 01413 delete newLSA; 01414 } 01415 if (spfTreeRoot == NULL) { 01416 return; 01417 } 01418 01419 lsaCount = routerLSAs.size(); 01420 for (i = 0; i < lsaCount; i++) { 01421 routerLSAs[i]->ClearNextHops(); 01422 } 01423 lsaCount = networkLSAs.size(); 01424 for (i = 0; i < lsaCount; i++) { 01425 networkLSAs[i]->ClearNextHops(); 01426 } 01427 spfTreeRoot->SetDistance(0); 01428 treeVertices.push_back(spfTreeRoot); 01429 justAddedVertex = spfTreeRoot; // (1) 01430 01431 do { 01432 LSAType vertexType = static_cast<LSAType> (justAddedVertex->getHeader().getLsType()); 01433 01434 if ((vertexType == RouterLSAType)) { 01435 AnsaOSPF::RouterLSA* routerVertex = check_and_cast<AnsaOSPF::RouterLSA*> (justAddedVertex); 01436 if (routerVertex->getV_VirtualLinkEndpoint()) { // (2) 01437 transitCapability = true; 01438 } 01439 01440 unsigned int linkCount = routerVertex->getLinksArraySize(); 01441 for (i = 0; i < linkCount; i++) { 01442 Link& link = routerVertex->getLinks(i); 01443 LinkType linkType = static_cast<LinkType> (link.getType()); 01444 OSPFLSA* joiningVertex; 01445 LSAType joiningVertexType; 01446 01447 if (linkType == StubLink) { // (2) (a) 01448 continue; 01449 } 01450 01451 if (linkType == TransitLink) { 01452 joiningVertex = FindNetworkLSA(link.getLinkID().getInt()); 01453 joiningVertexType = NetworkLSAType; 01454 } else { 01455 joiningVertex = FindRouterLSA(link.getLinkID().getInt()); 01456 joiningVertexType = RouterLSAType; 01457 } 01458 01459 if ((joiningVertex == NULL) || 01460 (joiningVertex->getHeader().getLsAge() == MAX_AGE) || 01461 (!HasLink(joiningVertex, justAddedVertex))) // (from, to) (2) (b) 01462 { 01463 continue; 01464 } 01465 01466 unsigned int treeSize = treeVertices.size(); 01467 bool alreadyOnTree = false; 01468 01469 for (j = 0; j < treeSize; j++) { 01470 if (treeVertices[j] == joiningVertex) { 01471 alreadyOnTree = true; 01472 break; 01473 } 01474 } 01475 if (alreadyOnTree) { // (2) (c) 01476 continue; 01477 } 01478 01479 unsigned long linkStateCost = routerVertex->GetDistance() + link.getLinkCost(); 01480 unsigned int candidateCount = candidateVertices.size(); 01481 OSPFLSA* candidate = NULL; 01482 01483 for (j = 0; j < candidateCount; j++) { 01484 if (candidateVertices[j] == joiningVertex) { 01485 candidate = candidateVertices[j]; 01486 } 01487 } 01488 if (candidate != NULL) { // (2) (d) 01489 AnsaOSPF::RoutingInfo* routingInfo = check_and_cast<AnsaOSPF::RoutingInfo*> (candidate); 01490 unsigned long candidateDistance = routingInfo->GetDistance(); 01491 01492 if (linkStateCost > candidateDistance) { 01493 continue; 01494 } 01495 if (linkStateCost < candidateDistance) { 01496 routingInfo->SetDistance(linkStateCost); 01497 routingInfo->ClearNextHops(); 01498 } 01499 std::vector<AnsaOSPF::NextHop>* newNextHops = CalculateNextHops(joiningVertex, justAddedVertex); // (destination, parent) 01500 unsigned int nextHopCount = newNextHops->size(); 01501 for (k = 0; k < nextHopCount; k++) { 01502 routingInfo->AddNextHop((*newNextHops)[k]); 01503 } 01504 delete newNextHops; 01505 } else { 01506 if (joiningVertexType == RouterLSAType) { 01507 AnsaOSPF::RouterLSA* joiningRouterVertex = check_and_cast<AnsaOSPF::RouterLSA*> (joiningVertex); 01508 joiningRouterVertex->SetDistance(linkStateCost); 01509 std::vector<AnsaOSPF::NextHop>* newNextHops = CalculateNextHops(joiningVertex, justAddedVertex); // (destination, parent) 01510 unsigned int nextHopCount = newNextHops->size(); 01511 for (k = 0; k < nextHopCount; k++) { 01512 joiningRouterVertex->AddNextHop((*newNextHops)[k]); 01513 } 01514 delete newNextHops; 01515 AnsaOSPF::RoutingInfo* vertexRoutingInfo = check_and_cast<AnsaOSPF::RoutingInfo*> (joiningRouterVertex); 01516 vertexRoutingInfo->SetParent(justAddedVertex); 01517 01518 candidateVertices.push_back(joiningRouterVertex); 01519 } else { 01520 AnsaOSPF::NetworkLSA* joiningNetworkVertex = check_and_cast<AnsaOSPF::NetworkLSA*> (joiningVertex); 01521 joiningNetworkVertex->SetDistance(linkStateCost); 01522 std::vector<AnsaOSPF::NextHop>* newNextHops = CalculateNextHops(joiningVertex, justAddedVertex); // (destination, parent) 01523 unsigned int nextHopCount = newNextHops->size(); 01524 for (k = 0; k < nextHopCount; k++) { 01525 joiningNetworkVertex->AddNextHop((*newNextHops)[k]); 01526 } 01527 delete newNextHops; 01528 AnsaOSPF::RoutingInfo* vertexRoutingInfo = check_and_cast<AnsaOSPF::RoutingInfo*> (joiningNetworkVertex); 01529 vertexRoutingInfo->SetParent(justAddedVertex); 01530 01531 candidateVertices.push_back(joiningNetworkVertex); 01532 } 01533 } 01534 } 01535 } 01536 01537 if ((vertexType == NetworkLSAType)) { 01538 AnsaOSPF::NetworkLSA* networkVertex = check_and_cast<AnsaOSPF::NetworkLSA*> (justAddedVertex); 01539 unsigned int routerCount = networkVertex->getAttachedRoutersArraySize(); 01540 01541 for (i = 0; i < routerCount; i++) { // (2) 01542 AnsaOSPF::RouterLSA* joiningVertex = FindRouterLSA(networkVertex->getAttachedRouters(i).getInt()); 01543 if ((joiningVertex == NULL) || 01544 (joiningVertex->getHeader().getLsAge() == MAX_AGE) || 01545 (!HasLink(joiningVertex, justAddedVertex))) // (from, to) (2) (b) 01546 { 01547 continue; 01548 } 01549 01550 unsigned int treeSize = treeVertices.size(); 01551 bool alreadyOnTree = false; 01552 01553 for (j = 0; j < treeSize; j++) { 01554 if (treeVertices[j] == joiningVertex) { 01555 alreadyOnTree = true; 01556 break; 01557 } 01558 } 01559 if (alreadyOnTree) { // (2) (c) 01560 continue; 01561 } 01562 01563 unsigned long linkStateCost = networkVertex->GetDistance(); // link cost from network to router is always 0 01564 unsigned int candidateCount = candidateVertices.size(); 01565 OSPFLSA* candidate = NULL; 01566 01567 for (j = 0; j < candidateCount; j++) { 01568 if (candidateVertices[j] == joiningVertex) { 01569 candidate = candidateVertices[j]; 01570 } 01571 } 01572 if (candidate != NULL) { // (2) (d) 01573 AnsaOSPF::RoutingInfo* routingInfo = check_and_cast<AnsaOSPF::RoutingInfo*> (candidate); 01574 unsigned long candidateDistance = routingInfo->GetDistance(); 01575 01576 if (linkStateCost > candidateDistance) { 01577 continue; 01578 } 01579 if (linkStateCost < candidateDistance) { 01580 routingInfo->SetDistance(linkStateCost); 01581 routingInfo->ClearNextHops(); 01582 } 01583 std::vector<AnsaOSPF::NextHop>* newNextHops = CalculateNextHops(joiningVertex, justAddedVertex); // (destination, parent) 01584 unsigned int nextHopCount = newNextHops->size(); 01585 for (k = 0; k < nextHopCount; k++) { 01586 routingInfo->AddNextHop((*newNextHops)[k]); 01587 } 01588 delete newNextHops; 01589 } else { 01590 joiningVertex->SetDistance(linkStateCost); 01591 std::vector<AnsaOSPF::NextHop>* newNextHops = CalculateNextHops(joiningVertex, justAddedVertex); // (destination, parent) 01592 unsigned int nextHopCount = newNextHops->size(); 01593 for (k = 0; k < nextHopCount; k++) { 01594 joiningVertex->AddNextHop((*newNextHops)[k]); 01595 } 01596 delete newNextHops; 01597 AnsaOSPF::RoutingInfo* vertexRoutingInfo = check_and_cast<AnsaOSPF::RoutingInfo*> (joiningVertex); 01598 vertexRoutingInfo->SetParent(justAddedVertex); 01599 01600 candidateVertices.push_back(joiningVertex); 01601 } 01602 } 01603 } 01604 01605 if (candidateVertices.empty()) { // (3) 01606 finished = true; 01607 } else { 01608 unsigned int candidateCount = candidateVertices.size(); 01609 unsigned long minDistance = LS_INFINITY; 01610 OSPFLSA* closestVertex = candidateVertices[0]; 01611 01612 for (i = 0; i < candidateCount; i++) { 01613 AnsaOSPF::RoutingInfo* routingInfo = check_and_cast<AnsaOSPF::RoutingInfo*> (candidateVertices[i]); 01614 unsigned long currentDistance = routingInfo->GetDistance(); 01615 01616 if (currentDistance < minDistance) { 01617 closestVertex = candidateVertices[i]; 01618 minDistance = currentDistance; 01619 } else { 01620 if (currentDistance == minDistance) { 01621 if ((closestVertex->getHeader().getLsType() == RouterLSAType) && 01622 (candidateVertices[i]->getHeader().getLsType() == NetworkLSAType)) 01623 { 01624 closestVertex = candidateVertices[i]; 01625 } 01626 } 01627 } 01628 } 01629 01630 treeVertices.push_back(closestVertex); 01631 01632 for (std::vector<OSPFLSA*>::iterator it = candidateVertices.begin(); it != candidateVertices.end(); it++) { 01633 if ((*it) == closestVertex) { 01634 candidateVertices.erase(it); 01635 break; 01636 } 01637 } 01638 01639 if (closestVertex->getHeader().getLsType() == RouterLSAType) { 01640 AnsaOSPF::RouterLSA* routerLSA = check_and_cast<AnsaOSPF::RouterLSA*> (closestVertex); 01641 if (routerLSA->getB_AreaBorderRouter() || routerLSA->getE_ASBoundaryRouter()) { 01642 AnsaOSPF::RoutingTableEntry* entry = new AnsaOSPF::RoutingTableEntry; 01643 AnsaOSPF::RouterID destinationID = routerLSA->getHeader().getLinkStateID(); 01644 unsigned int nextHopCount = routerLSA->GetNextHopCount(); 01645 AnsaOSPF::RoutingTableEntry::RoutingDestinationType destinationType = AnsaOSPF::RoutingTableEntry::NetworkDestination; 01646 01647 entry->SetDestinationID(destinationID); 01648 entry->SetLinkStateOrigin(routerLSA); 01649 entry->SetArea(areaID); 01650 entry->SetPathType(AnsaOSPF::RoutingTableEntry::IntraArea); 01651 entry->SetCost(routerLSA->GetDistance()); 01652 if (routerLSA->getB_AreaBorderRouter()) { 01653 destinationType |= AnsaOSPF::RoutingTableEntry::AreaBorderRouterDestination; 01654 } 01655 if (routerLSA->getE_ASBoundaryRouter()) { 01656 destinationType |= AnsaOSPF::RoutingTableEntry::ASBoundaryRouterDestination; 01657 } 01658 entry->SetDestinationType(destinationType); 01659 entry->SetOptionalCapabilities(routerLSA->getHeader().getLsOptions()); 01660 for (i = 0; i < nextHopCount; i++) { 01661 entry->AddNextHop(routerLSA->GetNextHop(i)); 01662 } 01663 01664 newRoutingTable.push_back(entry); 01665 01666 AnsaOSPF::Area* backbone; 01667 if (areaID != AnsaOSPF::BackboneAreaID) { 01668 backbone = parentRouter->GetArea(AnsaOSPF::BackboneAreaID); 01669 } else { 01670 backbone = this; 01671 } 01672 if (backbone != NULL) { 01673 AnsaOSPF::Interface* virtualIntf = backbone->FindVirtualLink(destinationID); 01674 if ((virtualIntf != NULL) && (virtualIntf->GetTransitAreaID() == areaID)) { 01675 AnsaOSPF::IPv4AddressRange range; 01676 range.address = GetInterface(routerLSA->GetNextHop(0).ifIndex)->GetAddressRange().address; 01677 range.mask = IPv4AddressFromULong(0xFFFFFFFF); 01678 virtualIntf->SetAddressRange(range); 01679 virtualIntf->SetIfIndex(routerLSA->GetNextHop(0).ifIndex); 01680 virtualIntf->SetOutputCost(routerLSA->GetDistance()); 01681 AnsaOSPF::Neighbor* virtualNeighbor = virtualIntf->GetNeighbor(0); 01682 if (virtualNeighbor != NULL) { 01683 unsigned int linkCount = routerLSA->getLinksArraySize(); 01684 AnsaOSPF::RouterLSA* toRouterLSA = dynamic_cast<AnsaOSPF::RouterLSA*> (justAddedVertex); 01685 if (toRouterLSA != NULL) { 01686 for (i = 0; i < linkCount; i++) { 01687 Link& link = routerLSA->getLinks(i); 01688 01689 if ((link.getType() == PointToPointLink) && 01690 (link.getLinkID() == toRouterLSA->getHeader().getLinkStateID()) && 01691 (virtualIntf->GetState() < AnsaOSPF::Interface::WaitingState)) 01692 { 01693 virtualNeighbor->SetAddress(IPv4AddressFromULong(link.getLinkData())); 01694 virtualIntf->ProcessEvent(AnsaOSPF::Interface::InterfaceUp); 01695 break; 01696 } 01697 } 01698 } else { 01699 AnsaOSPF::NetworkLSA* toNetworkLSA = dynamic_cast<AnsaOSPF::NetworkLSA*> (justAddedVertex); 01700 if (toNetworkLSA != NULL) { 01701 for (i = 0; i < linkCount; i++) { 01702 Link& link = routerLSA->getLinks(i); 01703 01704 if ((link.getType() == TransitLink) && 01705 (link.getLinkID() == toNetworkLSA->getHeader().getLinkStateID()) && 01706 (virtualIntf->GetState() < AnsaOSPF::Interface::WaitingState)) 01707 { 01708 virtualNeighbor->SetAddress(IPv4AddressFromULong(link.getLinkData())); 01709 virtualIntf->ProcessEvent(AnsaOSPF::Interface::InterfaceUp); 01710 break; 01711 } 01712 } 01713 } 01714 } 01715 } 01716 } 01717 } 01718 } 01719 } 01720 01721 if (closestVertex->getHeader().getLsType() == NetworkLSAType) { 01722 AnsaOSPF::NetworkLSA* networkLSA = check_and_cast<AnsaOSPF::NetworkLSA*> (closestVertex); 01723 unsigned long destinationID = (networkLSA->getHeader().getLinkStateID() & networkLSA->getNetworkMask().getInt()); 01724 unsigned int nextHopCount = networkLSA->GetNextHopCount(); 01725 bool overWrite = false; 01726 AnsaOSPF::RoutingTableEntry* entry = NULL; 01727 unsigned long routeCount = newRoutingTable.size(); 01728 unsigned long longestMatch = 0; 01729 01730 for (i = 0; i < routeCount; i++) { 01731 if (newRoutingTable[i]->GetDestinationType() == AnsaOSPF::RoutingTableEntry::NetworkDestination) { 01732 AnsaOSPF::RoutingTableEntry* routingEntry = newRoutingTable[i]; 01733 unsigned long entryAddress = routingEntry->GetDestinationID().getInt(); 01734 unsigned long entryMask = routingEntry->GetAddressMask().getInt(); 01735 01736 if ((entryAddress & entryMask) == (destinationID & entryMask)) { 01737 if ((destinationID & entryMask) > longestMatch) { 01738 longestMatch = (destinationID & entryMask); 01739 entry = routingEntry; 01740 } 01741 } 01742 } 01743 } 01744 if (entry != NULL) { 01745 const OSPFLSA* entryOrigin = entry->GetLinkStateOrigin(); 01746 if ((entry->GetCost() != networkLSA->GetDistance()) || 01747 (entryOrigin->getHeader().getLinkStateID() >= networkLSA->getHeader().getLinkStateID())) 01748 { 01749 overWrite = true; 01750 } 01751 } 01752 01753 if ((entry == NULL) || (overWrite)) { 01754 if (entry == NULL) { 01755 entry = new AnsaOSPF::RoutingTableEntry; 01756 } 01757 01758 entry->SetDestinationID(destinationID); 01759 entry->SetAddressMask(networkLSA->getNetworkMask()); 01760 entry->SetLinkStateOrigin(networkLSA); 01761 entry->SetArea(areaID); 01762 entry->SetPathType(AnsaOSPF::RoutingTableEntry::IntraArea); 01763 entry->SetCost(networkLSA->GetDistance()); 01764 entry->SetDestinationType(AnsaOSPF::RoutingTableEntry::NetworkDestination); 01765 entry->SetOptionalCapabilities(networkLSA->getHeader().getLsOptions()); 01766 for (i = 0; i < nextHopCount; i++) { 01767 entry->AddNextHop(networkLSA->GetNextHop(i)); 01768 } 01769 01770 if (!overWrite) { 01771 newRoutingTable.push_back(entry); 01772 } 01773 } 01774 } 01775 01776 justAddedVertex = closestVertex; 01777 } 01778 } while (!finished); 01779 01780 unsigned int treeSize = treeVertices.size(); 01781 for (i = 0; i < treeSize; i++) { 01782 AnsaOSPF::RouterLSA* routerVertex = dynamic_cast<AnsaOSPF::RouterLSA*> (treeVertices[i]); 01783 if (routerVertex == NULL) { 01784 continue; 01785 } 01786 01787 unsigned int linkCount = routerVertex->getLinksArraySize(); 01788 for (j = 0; j < linkCount; j++) { 01789 Link& link = routerVertex->getLinks(j); 01790 if (link.getType() != StubLink) { 01791 continue; 01792 } 01793 01794 unsigned long distance = routerVertex->GetDistance() + link.getLinkCost(); 01795 unsigned long destinationID = (link.getLinkID().getInt() & link.getLinkData()); 01796 AnsaOSPF::RoutingTableEntry* entry = NULL; 01797 unsigned long routeCount = newRoutingTable.size(); 01798 unsigned long longestMatch = 0; 01799 01800 for (k = 0; k < routeCount; k++) { 01801 if (newRoutingTable[k]->GetDestinationType() == AnsaOSPF::RoutingTableEntry::NetworkDestination) { 01802 AnsaOSPF::RoutingTableEntry* routingEntry = newRoutingTable[k]; 01803 unsigned long entryAddress = routingEntry->GetDestinationID().getInt(); 01804 unsigned long entryMask = routingEntry->GetAddressMask().getInt(); 01805 01806 if ((entryAddress & entryMask) == (destinationID & entryMask)) { 01807 if ((destinationID & entryMask) > longestMatch) { 01808 longestMatch = (destinationID & entryMask); 01809 entry = routingEntry; 01810 } 01811 } 01812 } 01813 } 01814 01815 if (entry != NULL) { 01816 Metric entryCost = entry->GetCost(); 01817 01818 if (distance > entryCost) { 01819 continue; 01820 } 01821 if (distance < entryCost) { 01822 //FIXME remove 01823 //if(parentRouter->GetRouterID() == 0xC0A80302) { 01824 // EV << "CHEAPER STUB LINK FOUND TO " << IPAddress(destinationID).str() << "\n"; 01825 //} 01826 entry->SetCost(distance); 01827 entry->ClearNextHops(); 01828 entry->SetLinkStateOrigin(routerVertex); 01829 } 01830 if (distance == entryCost) { 01831 // no const version from check_and_cast 01832 AnsaOSPF::RouterLSA* routerOrigin = check_and_cast<AnsaOSPF::RouterLSA*> (const_cast<OSPFLSA*> (entry->GetLinkStateOrigin())); 01833 if (routerOrigin->getHeader().getLinkStateID() < routerVertex->getHeader().getLinkStateID()) { 01834 entry->SetLinkStateOrigin(routerVertex); 01835 } 01836 } 01837 std::vector<AnsaOSPF::NextHop>* newNextHops = CalculateNextHops(link, routerVertex); // (destination, parent) 01838 unsigned int nextHopCount = newNextHops->size(); 01839 for (k = 0; k < nextHopCount; k++) { 01840 entry->AddNextHop((*newNextHops)[k]); 01841 } 01842 delete newNextHops; 01843 } else { 01844 //FIXME remove 01845 //if(parentRouter->GetRouterID() == 0xC0A80302) { 01846 // EV << "STUB LINK FOUND TO " << IPAddress(destinationID).str() << "\n"; 01847 //} 01848 entry = new AnsaOSPF::RoutingTableEntry; 01849 01850 entry->SetDestinationID(destinationID); 01851 entry->SetAddressMask(link.getLinkData()); 01852 entry->SetLinkStateOrigin(routerVertex); 01853 entry->SetArea(areaID); 01854 entry->SetPathType(AnsaOSPF::RoutingTableEntry::IntraArea); 01855 entry->SetCost(distance); 01856 entry->SetDestinationType(AnsaOSPF::RoutingTableEntry::NetworkDestination); 01857 entry->SetOptionalCapabilities(routerVertex->getHeader().getLsOptions()); 01858 std::vector<AnsaOSPF::NextHop>* newNextHops = CalculateNextHops(link, routerVertex); // (destination, parent) 01859 unsigned int nextHopCount = newNextHops->size(); 01860 for (k = 0; k < nextHopCount; k++) { 01861 entry->AddNextHop((*newNextHops)[k]); 01862 } 01863 delete newNextHops; 01864 01865 newRoutingTable.push_back(entry); 01866 } 01867 } 01868 } 01869 } 01870 01871 std::vector<AnsaOSPF::NextHop>* AnsaOSPF::Area::CalculateNextHops(OSPFLSA* destination, OSPFLSA* parent) const 01872 { 01873 std::vector<AnsaOSPF::NextHop>* hops = new std::vector<AnsaOSPF::NextHop>; 01874 unsigned long i, j; 01875 01876 AnsaOSPF::RouterLSA* routerLSA = dynamic_cast<AnsaOSPF::RouterLSA*> (parent); 01877 if (routerLSA != NULL) { 01878 if (routerLSA != spfTreeRoot) { 01879 unsigned int nextHopCount = routerLSA->GetNextHopCount(); 01880 for (i = 0; i < nextHopCount; i++) { 01881 hops->push_back(routerLSA->GetNextHop(i)); 01882 } 01883 return hops; 01884 } else { 01885 AnsaOSPF::RouterLSA* destinationRouterLSA = dynamic_cast<AnsaOSPF::RouterLSA*> (destination); 01886 if (destinationRouterLSA != NULL) { 01887 unsigned long interfaceNum = associatedInterfaces.size(); 01888 for (i = 0; i < interfaceNum; i++) { 01889 AnsaOSPF::Interface::OSPFInterfaceType intfType = associatedInterfaces[i]->GetType(); 01890 if ((intfType == AnsaOSPF::Interface::PointToPoint) || 01891 ((intfType == AnsaOSPF::Interface::Virtual) && 01892 (associatedInterfaces[i]->GetState() > AnsaOSPF::Interface::LoopbackState))) 01893 { 01894 AnsaOSPF::Neighbor* ptpNeighbor = associatedInterfaces[i]->GetNeighborCount() > 0 ? associatedInterfaces[i]->GetNeighbor(0) : NULL; 01895 if (ptpNeighbor != NULL) { 01896 if (ptpNeighbor->GetNeighborID() == destinationRouterLSA->getHeader().getLinkStateID()) { 01897 NextHop nextHop; 01898 nextHop.ifIndex = associatedInterfaces[i]->GetIfIndex(); 01899 nextHop.hopAddress = ptpNeighbor->GetAddress(); 01900 nextHop.advertisingRouter = destinationRouterLSA->getHeader().getAdvertisingRouter().getInt(); 01901 hops->push_back(nextHop); 01902 break; 01903 } 01904 } 01905 } 01906 if (intfType == AnsaOSPF::Interface::PointToMultiPoint) { 01907 AnsaOSPF::Neighbor* ptmpNeighbor = associatedInterfaces[i]->GetNeighborByID(destinationRouterLSA->getHeader().getLinkStateID()); 01908 if (ptmpNeighbor != NULL) { 01909 unsigned int linkCount = destinationRouterLSA->getLinksArraySize(); 01910 AnsaOSPF::RouterID rootID = parentRouter->GetRouterID(); 01911 for (j = 0; j < linkCount; j++) { 01912 Link& link = destinationRouterLSA->getLinks(j); 01913 if (link.getLinkID() == rootID) { 01914 NextHop nextHop; 01915 nextHop.ifIndex = associatedInterfaces[i]->GetIfIndex(); 01916 nextHop.hopAddress = IPv4AddressFromULong(link.getLinkData()); 01917 nextHop.advertisingRouter = destinationRouterLSA->getHeader().getAdvertisingRouter().getInt(); 01918 hops->push_back(nextHop); 01919 } 01920 } 01921 break; 01922 } 01923 } 01924 } 01925 } else { 01926 AnsaOSPF::NetworkLSA* destinationNetworkLSA = dynamic_cast<AnsaOSPF::NetworkLSA*> (destination); 01927 if (destinationNetworkLSA != NULL) { 01928 AnsaOSPF::IPv4Address networkDesignatedRouter = IPv4AddressFromULong(destinationNetworkLSA->getHeader().getLinkStateID()); 01929 unsigned long interfaceNum = associatedInterfaces.size(); 01930 for (i = 0; i < interfaceNum; i++) { 01931 AnsaOSPF::Interface::OSPFInterfaceType intfType = associatedInterfaces[i]->GetType(); 01932 if (((intfType == AnsaOSPF::Interface::Broadcast) || 01933 (intfType == AnsaOSPF::Interface::NBMA)) && 01934 (associatedInterfaces[i]->GetDesignatedRouter().ipInterfaceAddress == networkDesignatedRouter)) 01935 { 01936 AnsaOSPF::IPv4AddressRange range = associatedInterfaces[i]->GetAddressRange(); 01937 NextHop nextHop; 01938 01939 nextHop.ifIndex = associatedInterfaces[i]->GetIfIndex(); 01940 nextHop.hopAddress = (range.address & range.mask); 01941 nextHop.advertisingRouter = destinationNetworkLSA->getHeader().getAdvertisingRouter().getInt(); 01942 hops->push_back(nextHop); 01943 } 01944 } 01945 } 01946 } 01947 } 01948 } else { 01949 AnsaOSPF::NetworkLSA* networkLSA = dynamic_cast<AnsaOSPF::NetworkLSA*> (parent); 01950 if (networkLSA != NULL) { 01951 if (networkLSA->GetParent() != spfTreeRoot) { 01952 unsigned int nextHopCount = networkLSA->GetNextHopCount(); 01953 for (i = 0; i < nextHopCount; i++) { 01954 hops->push_back(networkLSA->GetNextHop(i)); 01955 } 01956 return hops; 01957 } else { 01958 unsigned long parentLinkStateID = parent->getHeader().getLinkStateID(); 01959 01960 AnsaOSPF::RouterLSA* destinationRouterLSA = dynamic_cast<AnsaOSPF::RouterLSA*> (destination); 01961 if (destinationRouterLSA != NULL) { 01962 AnsaOSPF::RouterID destinationRouterID = destinationRouterLSA->getHeader().getLinkStateID(); 01963 unsigned int linkCount = destinationRouterLSA->getLinksArraySize(); 01964 for (i = 0; i < linkCount; i++) { 01965 Link& link = destinationRouterLSA->getLinks(i); 01966 NextHop nextHop; 01967 01968 if (((link.getType() == TransitLink) && 01969 (link.getLinkID().getInt() == parentLinkStateID)) || 01970 ((link.getType() == StubLink) && 01971 ((link.getLinkID().getInt() & link.getLinkData()) == (parentLinkStateID & networkLSA->getNetworkMask().getInt())))) 01972 { 01973 unsigned long interfaceNum = associatedInterfaces.size(); 01974 for (j = 0; j < interfaceNum; j++) { 01975 AnsaOSPF::Interface::OSPFInterfaceType intfType = associatedInterfaces[j]->GetType(); 01976 if (((intfType == AnsaOSPF::Interface::Broadcast) || 01977 (intfType == AnsaOSPF::Interface::NBMA)) && 01978 (associatedInterfaces[j]->GetDesignatedRouter().ipInterfaceAddress == IPv4AddressFromULong(parentLinkStateID))) 01979 { 01980 AnsaOSPF::Neighbor* nextHopNeighbor = associatedInterfaces[j]->GetNeighborByID(destinationRouterID); 01981 if (nextHopNeighbor != NULL) { 01982 nextHop.ifIndex = associatedInterfaces[j]->GetIfIndex(); 01983 nextHop.hopAddress = nextHopNeighbor->GetAddress(); 01984 nextHop.advertisingRouter = destinationRouterLSA->getHeader().getAdvertisingRouter().getInt(); 01985 hops->push_back(nextHop); 01986 } 01987 } 01988 } 01989 } 01990 } 01991 } 01992 } 01993 } 01994 } 01995 01996 return hops; 01997 } 01998 01999 std::vector<AnsaOSPF::NextHop>* AnsaOSPF::Area::CalculateNextHops(Link& destination, OSPFLSA* parent) const 02000 { 02001 std::vector<AnsaOSPF::NextHop>* hops = new std::vector<AnsaOSPF::NextHop>; 02002 unsigned long i; 02003 02004 AnsaOSPF::RouterLSA* routerLSA = check_and_cast<AnsaOSPF::RouterLSA*> (parent); 02005 if (routerLSA != spfTreeRoot) { 02006 unsigned int nextHopCount = routerLSA->GetNextHopCount(); 02007 for (i = 0; i < nextHopCount; i++) { 02008 hops->push_back(routerLSA->GetNextHop(i)); 02009 } 02010 return hops; 02011 } else { 02012 unsigned long interfaceNum = associatedInterfaces.size(); 02013 for (i = 0; i < interfaceNum; i++) { 02014 AnsaOSPF::Interface::OSPFInterfaceType intfType = associatedInterfaces[i]->GetType(); 02015 02016 if ((intfType == AnsaOSPF::Interface::PointToPoint) || 02017 ((intfType == AnsaOSPF::Interface::Virtual) && 02018 (associatedInterfaces[i]->GetState() > AnsaOSPF::Interface::LoopbackState))) 02019 { 02020 AnsaOSPF::Neighbor* neighbor = (associatedInterfaces[i]->GetNeighborCount() > 0) ? associatedInterfaces[i]->GetNeighbor(0) : NULL; 02021 if (neighbor != NULL) { 02022 AnsaOSPF::IPv4Address neighborAddress = neighbor->GetAddress(); 02023 if (((neighborAddress != AnsaOSPF::NullIPv4Address) && 02024 (ULongFromIPv4Address(neighborAddress) == destination.getLinkID().getInt())) || 02025 ((neighborAddress == AnsaOSPF::NullIPv4Address) && 02026 (ULongFromIPv4Address(associatedInterfaces[i]->GetAddressRange().address) == destination.getLinkID().getInt()) && 02027 (ULongFromIPv4Address(associatedInterfaces[i]->GetAddressRange().mask) == destination.getLinkData()))) 02028 { 02029 NextHop nextHop; 02030 nextHop.ifIndex = associatedInterfaces[i]->GetIfIndex(); 02031 nextHop.hopAddress = neighborAddress; 02032 nextHop.advertisingRouter = parentRouter->GetRouterID(); 02033 hops->push_back(nextHop); 02034 break; 02035 } 02036 } 02037 } 02038 if ((intfType == AnsaOSPF::Interface::Broadcast) || 02039 (intfType == AnsaOSPF::Interface::NBMA)) 02040 { 02041 if ((destination.getLinkID().getInt() == ULongFromIPv4Address(associatedInterfaces[i]->GetAddressRange().address & associatedInterfaces[i]->GetAddressRange().mask)) && 02042 (destination.getLinkData() == ULongFromIPv4Address(associatedInterfaces[i]->GetAddressRange().mask))) 02043 { 02044 NextHop nextHop; 02045 nextHop.ifIndex = associatedInterfaces[i]->GetIfIndex(); 02046 nextHop.hopAddress = IPv4AddressFromULong(destination.getLinkID().getInt()); 02047 nextHop.advertisingRouter = parentRouter->GetRouterID(); 02048 hops->push_back(nextHop); 02049 break; 02050 } 02051 } 02052 if (intfType == AnsaOSPF::Interface::PointToMultiPoint) { 02053 if (destination.getType() == StubLink) { 02054 if (destination.getLinkID().getInt() == ULongFromIPv4Address(associatedInterfaces[i]->GetAddressRange().address)) { 02055 // The link contains the router's own interface address and a full mask, 02056 // so we insert a next hop pointing to the interface itself. Kind of pointless, but 02057 // not much else we could do... 02058 // TODO: check what other OSPF implementations do in this situation 02059 NextHop nextHop; 02060 nextHop.ifIndex = associatedInterfaces[i]->GetIfIndex(); 02061 nextHop.hopAddress = associatedInterfaces[i]->GetAddressRange().address; 02062 nextHop.advertisingRouter = parentRouter->GetRouterID(); 02063 hops->push_back(nextHop); 02064 break; 02065 } 02066 } 02067 if (destination.getType() == PointToPointLink) { 02068 AnsaOSPF::Neighbor* neighbor = associatedInterfaces[i]->GetNeighborByID(destination.getLinkID().getInt()); 02069 if (neighbor != NULL) { 02070 NextHop nextHop; 02071 nextHop.ifIndex = associatedInterfaces[i]->GetIfIndex(); 02072 nextHop.hopAddress = neighbor->GetAddress(); 02073 nextHop.advertisingRouter = parentRouter->GetRouterID(); 02074 hops->push_back(nextHop); 02075 break; 02076 } 02077 } 02078 } 02079 // next hops for virtual links are generated later, after examining transit areas' SummaryLSAs 02080 } 02081 02082 if (hops->size() == 0) { 02083 unsigned long hostRouteCount = hostRoutes.size(); 02084 for (i = 0; i < hostRouteCount; i++) { 02085 if ((destination.getLinkID().getInt() == ULongFromIPv4Address(hostRoutes[i].address)) && 02086 (destination.getLinkData() == 0xFFFFFFFF)) 02087 { 02088 NextHop nextHop; 02089 nextHop.ifIndex = hostRoutes[i].ifIndex; 02090 nextHop.hopAddress = hostRoutes[i].address; 02091 nextHop.advertisingRouter = parentRouter->GetRouterID(); 02092 hops->push_back(nextHop); 02093 break; 02094 } 02095 } 02096 } 02097 } 02098 02099 return hops; 02100 } 02101 02102 bool AnsaOSPF::Area::HasLink(OSPFLSA* fromLSA, OSPFLSA* toLSA) const 02103 { 02104 unsigned int i; 02105 02106 AnsaOSPF::RouterLSA* fromRouterLSA = dynamic_cast<AnsaOSPF::RouterLSA*> (fromLSA); 02107 if (fromRouterLSA != NULL) { 02108 unsigned int linkCount = fromRouterLSA->getLinksArraySize(); 02109 AnsaOSPF::RouterLSA* toRouterLSA = dynamic_cast<AnsaOSPF::RouterLSA*> (toLSA); 02110 if (toRouterLSA != NULL) { 02111 for (i = 0; i < linkCount; i++) { 02112 Link& link = fromRouterLSA->getLinks(i); 02113 LinkType linkType = static_cast<LinkType> (link.getType()); 02114 02115 if (((linkType == PointToPointLink) || 02116 (linkType == VirtualLink)) && 02117 (link.getLinkID().getInt() == toRouterLSA->getHeader().getLinkStateID())) 02118 { 02119 return true; 02120 } 02121 } 02122 } else { 02123 AnsaOSPF::NetworkLSA* toNetworkLSA = dynamic_cast<AnsaOSPF::NetworkLSA*> (toLSA); 02124 if (toNetworkLSA != NULL) { 02125 for (i = 0; i < linkCount; i++) { 02126 Link& link = fromRouterLSA->getLinks(i); 02127 02128 if ((link.getType() == TransitLink) && 02129 (link.getLinkID().getInt() == toNetworkLSA->getHeader().getLinkStateID())) 02130 { 02131 return true; 02132 } 02133 if ((link.getType() == StubLink) && 02134 ((link.getLinkID().getInt() & link.getLinkData()) == (toNetworkLSA->getHeader().getLinkStateID() & toNetworkLSA->getNetworkMask().getInt()))) 02135 { 02136 return true; 02137 } 02138 } 02139 } 02140 } 02141 } else { 02142 AnsaOSPF::NetworkLSA* fromNetworkLSA = dynamic_cast<AnsaOSPF::NetworkLSA*> (fromLSA); 02143 if (fromNetworkLSA != NULL) { 02144 unsigned int routerCount = fromNetworkLSA->getAttachedRoutersArraySize(); 02145 AnsaOSPF::RouterLSA* toRouterLSA = dynamic_cast<AnsaOSPF::RouterLSA*> (toLSA); 02146 if (toRouterLSA != NULL) { 02147 for (i = 0; i < routerCount; i++) { 02148 if (fromNetworkLSA->getAttachedRouters(i).getInt() == toRouterLSA->getHeader().getLinkStateID()) { 02149 return true; 02150 } 02151 } 02152 } 02153 } 02154 } 02155 02156 return false; 02157 } 02158 02164 bool AnsaOSPF::Area::FindSameOrWorseCostRoute(const std::vector<AnsaOSPF::RoutingTableEntry*>& newRoutingTable, 02165 const AnsaOSPF::SummaryLSA& summaryLSA, 02166 unsigned short currentCost, 02167 bool& destinationInRoutingTable, 02168 std::list<AnsaOSPF::RoutingTableEntry*>& sameOrWorseCost) const 02169 { 02170 destinationInRoutingTable = false; 02171 sameOrWorseCost.clear(); 02172 02173 long routeCount = newRoutingTable.size(); 02174 AnsaOSPF::IPv4AddressRange destination; 02175 02176 destination.address = IPv4AddressFromULong(summaryLSA.getHeader().getLinkStateID()); 02177 destination.mask = IPv4AddressFromULong(summaryLSA.getNetworkMask().getInt()); 02178 02179 for (long j = 0; j < routeCount; j++) { 02180 AnsaOSPF::RoutingTableEntry* routingEntry = newRoutingTable[j]; 02181 bool foundMatching = false; 02182 02183 if (summaryLSA.getHeader().getLsType() == SummaryLSA_NetworksType) { 02184 if ((routingEntry->GetDestinationType() == AnsaOSPF::RoutingTableEntry::NetworkDestination) && 02185 (ULongFromIPv4Address(destination.address & destination.mask) == routingEntry->GetDestinationID().getInt())) 02186 { 02187 foundMatching = true; 02188 } 02189 } else { 02190 if ((((routingEntry->GetDestinationType() & AnsaOSPF::RoutingTableEntry::AreaBorderRouterDestination) != 0) || 02191 ((routingEntry->GetDestinationType() & AnsaOSPF::RoutingTableEntry::ASBoundaryRouterDestination) != 0)) && 02192 (ULongFromIPv4Address(destination.address) == routingEntry->GetDestinationID().getInt())) 02193 { 02194 foundMatching = true; 02195 } 02196 } 02197 02198 if (foundMatching) { 02199 destinationInRoutingTable = true; 02200 02201 /* If the matching entry is an IntraArea getRoute(intra-area paths are 02202 * always preferred to other paths of any cost), or it's a cheaper InterArea 02203 * route, then skip this LSA. 02204 */ 02205 if ((routingEntry->GetPathType() == AnsaOSPF::RoutingTableEntry::IntraArea) || 02206 ((routingEntry->GetPathType() == AnsaOSPF::RoutingTableEntry::InterArea) && 02207 (routingEntry->GetCost() < currentCost))) 02208 { 02209 return true; 02210 } else { 02211 // if it's an other InterArea path 02212 if ((routingEntry->GetPathType() == AnsaOSPF::RoutingTableEntry::InterArea) && 02213 (routingEntry->GetCost() >= currentCost)) 02214 { 02215 sameOrWorseCost.push_back(routingEntry); 02216 } // else it's external -> same as if not in the table 02217 } 02218 } 02219 } 02220 return false; 02221 } 02222 02227 AnsaOSPF::RoutingTableEntry* AnsaOSPF::Area::CreateRoutingTableEntryFromSummaryLSA(const AnsaOSPF::SummaryLSA& summaryLSA, 02228 unsigned short entryCost, 02229 const AnsaOSPF::RoutingTableEntry& borderRouterEntry) const 02230 { 02231 AnsaOSPF::IPv4AddressRange destination; 02232 02233 destination.address = IPv4AddressFromULong(summaryLSA.getHeader().getLinkStateID()); 02234 destination.mask = IPv4AddressFromULong(summaryLSA.getNetworkMask().getInt()); 02235 02236 AnsaOSPF::RoutingTableEntry* newEntry = new AnsaOSPF::RoutingTableEntry; 02237 02238 if (summaryLSA.getHeader().getLsType() == SummaryLSA_NetworksType) { 02239 newEntry->SetDestinationID(ULongFromIPv4Address(destination.address & destination.mask)); 02240 newEntry->SetAddressMask(ULongFromIPv4Address(destination.mask)); 02241 newEntry->SetDestinationType(AnsaOSPF::RoutingTableEntry::NetworkDestination); 02242 } else { 02243 newEntry->SetDestinationID(ULongFromIPv4Address(destination.address)); 02244 newEntry->SetAddressMask(0xFFFFFFFF); 02245 newEntry->SetDestinationType(AnsaOSPF::RoutingTableEntry::ASBoundaryRouterDestination); 02246 } 02247 newEntry->SetArea(areaID); 02248 newEntry->SetPathType(AnsaOSPF::RoutingTableEntry::InterArea); 02249 newEntry->SetCost(entryCost); 02250 newEntry->SetOptionalCapabilities(summaryLSA.getHeader().getLsOptions()); 02251 newEntry->SetLinkStateOrigin(&summaryLSA); 02252 02253 unsigned int nextHopCount = borderRouterEntry.GetNextHopCount(); 02254 for (unsigned int j = 0; j < nextHopCount; j++) { 02255 newEntry->AddNextHop(borderRouterEntry.GetNextHop(j)); 02256 } 02257 02258 return newEntry; 02259 } 02260 02267 void AnsaOSPF::Area::CalculateInterAreaRoutes(std::vector<AnsaOSPF::RoutingTableEntry*>& newRoutingTable) 02268 { 02269 unsigned long i = 0; 02270 unsigned long j = 0; 02271 unsigned long lsaCount = summaryLSAs.size(); 02272 02273 for (i = 0; i < lsaCount; i++) { 02274 AnsaOSPF::SummaryLSA* currentLSA = summaryLSAs[i]; 02275 OSPFLSAHeader& currentHeader = currentLSA->getHeader(); 02276 02277 unsigned long routeCost = currentLSA->getRouteCost(); 02278 unsigned short lsAge = currentHeader.getLsAge(); 02279 RouterID originatingRouter = currentHeader.getAdvertisingRouter().getInt(); 02280 bool selfOriginated = (originatingRouter == parentRouter->GetRouterID()); 02281 02282 if ((routeCost == LS_INFINITY) || (lsAge == MAX_AGE) || (selfOriginated)) { // (1) and(2) 02283 continue; 02284 } 02285 02286 char lsType = currentHeader.getLsType(); 02287 unsigned long routeCount = newRoutingTable.size(); 02288 AnsaOSPF::IPv4AddressRange destination; 02289 02290 destination.address = IPv4AddressFromULong(currentHeader.getLinkStateID()); 02291 destination.mask = IPv4AddressFromULong(currentLSA->getNetworkMask().getInt()); 02292 02293 if ((lsType == SummaryLSA_NetworksType) && (parentRouter->HasAddressRange(destination))) { // (3) 02294 bool foundIntraAreaRoute = false; 02295 02296 // look for an "Active" IntraArea route 02297 for (j = 0; j < routeCount; j++) { 02298 AnsaOSPF::RoutingTableEntry* routingEntry = newRoutingTable[j]; 02299 02300 if ((routingEntry->GetDestinationType() == AnsaOSPF::RoutingTableEntry::NetworkDestination) && 02301 (routingEntry->GetPathType() == AnsaOSPF::RoutingTableEntry::IntraArea) && 02302 ((routingEntry->GetDestinationID().getInt() & 02303 routingEntry->GetAddressMask().getInt() & 02304 ULongFromIPv4Address(destination.mask) ) == ULongFromIPv4Address(destination.address & 02305 destination.mask))) 02306 { 02307 foundIntraAreaRoute = true; 02308 break; 02309 } 02310 } 02311 if (foundIntraAreaRoute) { 02312 continue; 02313 } 02314 } 02315 02316 AnsaOSPF::RoutingTableEntry* borderRouterEntry = NULL; 02317 02318 // The routingEntry describes a route to an other area -> look for the border router originating it 02319 for (j = 0; j < routeCount; j++) { // (4) N == destination, BR == borderRouterEntry 02320 AnsaOSPF::RoutingTableEntry* routingEntry = newRoutingTable[j]; 02321 02322 if ((routingEntry->GetArea() == areaID) && 02323 (((routingEntry->GetDestinationType() & AnsaOSPF::RoutingTableEntry::AreaBorderRouterDestination) != 0) || 02324 ((routingEntry->GetDestinationType() & AnsaOSPF::RoutingTableEntry::ASBoundaryRouterDestination) != 0)) && 02325 (routingEntry->GetDestinationID().getInt() == originatingRouter)) 02326 { 02327 borderRouterEntry = routingEntry; 02328 break; 02329 } 02330 } 02331 if (borderRouterEntry == NULL) { 02332 continue; 02333 } else { // (5) 02334 /* "Else, this LSA describes an inter-area path to destination N, 02335 * whose cost is the distance to BR plus the cost specified in the LSA. 02336 * Call the cost of this inter-area path IAC." 02337 */ 02338 bool destinationInRoutingTable = true; 02339 unsigned short currentCost = routeCost + borderRouterEntry->GetCost(); 02340 std::list<AnsaOSPF::RoutingTableEntry*> sameOrWorseCost; 02341 02342 if (FindSameOrWorseCostRoute(newRoutingTable, 02343 *currentLSA, 02344 currentCost, 02345 destinationInRoutingTable, 02346 sameOrWorseCost)) 02347 { 02348 continue; 02349 } 02350 02351 if (destinationInRoutingTable && (sameOrWorseCost.size() > 0)) { 02352 AnsaOSPF::RoutingTableEntry* equalEntry = NULL; 02353 02354 /* Look for an equal cost entry in the sameOrWorseCost list, and 02355 * also clear the more expensive entries from the newRoutingTable. 02356 */ 02357 for (std::list<AnsaOSPF::RoutingTableEntry*>::iterator it = sameOrWorseCost.begin(); it != sameOrWorseCost.end(); it++) { 02358 AnsaOSPF::RoutingTableEntry* checkedEntry = (*it); 02359 02360 if (checkedEntry->GetCost() > currentCost) { 02361 for (std::vector<AnsaOSPF::RoutingTableEntry*>::iterator entryIt = newRoutingTable.begin(); entryIt != newRoutingTable.end(); entryIt++) { 02362 if (checkedEntry == (*entryIt)) { 02363 newRoutingTable.erase(entryIt); 02364 break; 02365 } 02366 } 02367 } else { // EntryCost == currentCost 02368 equalEntry = checkedEntry; // should be only one - if there are more they are ignored 02369 } 02370 } 02371 02372 unsigned long nextHopCount = borderRouterEntry->GetNextHopCount(); 02373 02374 if (equalEntry != NULL) { 02375 /* Add the next hops of the border router advertising this destination 02376 * to the equal entry. 02377 */ 02378 for (unsigned long j = 0; j < nextHopCount; j++) { 02379 equalEntry->AddNextHop(borderRouterEntry->GetNextHop(j)); 02380 } 02381 } else { 02382 AnsaOSPF::RoutingTableEntry* newEntry = CreateRoutingTableEntryFromSummaryLSA(*currentLSA, currentCost, *borderRouterEntry); 02383 ASSERT(newEntry != NULL); 02384 newRoutingTable.push_back(newEntry); 02385 } 02386 } else { 02387 AnsaOSPF::RoutingTableEntry* newEntry = CreateRoutingTableEntryFromSummaryLSA(*currentLSA, currentCost, *borderRouterEntry); 02388 ASSERT(newEntry != NULL); 02389 newRoutingTable.push_back(newEntry); 02390 } 02391 } 02392 } 02393 } 02394 02395 void AnsaOSPF::Area::ReCheckSummaryLSAs(std::vector<AnsaOSPF::RoutingTableEntry*>& newRoutingTable) 02396 { 02397 unsigned long i = 0; 02398 unsigned long j = 0; 02399 unsigned long lsaCount = summaryLSAs.size(); 02400 02401 for (i = 0; i < lsaCount; i++) { 02402 AnsaOSPF::SummaryLSA* currentLSA = summaryLSAs[i]; 02403 OSPFLSAHeader& currentHeader = currentLSA->getHeader(); 02404 02405 unsigned long routeCost = currentLSA->getRouteCost(); 02406 unsigned short lsAge = currentHeader.getLsAge(); 02407 RouterID originatingRouter = currentHeader.getAdvertisingRouter().getInt(); 02408 bool selfOriginated = (originatingRouter == parentRouter->GetRouterID()); 02409 02410 if ((routeCost == LS_INFINITY) || (lsAge == MAX_AGE) || (selfOriginated)) { // (1) and(2) 02411 continue; 02412 } 02413 02414 unsigned long routeCount = newRoutingTable.size(); 02415 char lsType = currentHeader.getLsType(); 02416 AnsaOSPF::RoutingTableEntry* destinationEntry = NULL; 02417 AnsaOSPF::IPv4AddressRange destination; 02418 02419 destination.address = IPv4AddressFromULong(currentHeader.getLinkStateID()); 02420 destination.mask = IPv4AddressFromULong(currentLSA->getNetworkMask().getInt()); 02421 02422 for (j = 0; j < routeCount; j++) { // (3) 02423 AnsaOSPF::RoutingTableEntry* routingEntry = newRoutingTable[j]; 02424 bool foundMatching = false; 02425 02426 if (lsType == SummaryLSA_NetworksType) { 02427 if ((routingEntry->GetDestinationType() == AnsaOSPF::RoutingTableEntry::NetworkDestination) && 02428 (ULongFromIPv4Address(destination.address & destination.mask) == routingEntry->GetDestinationID().getInt())) 02429 { 02430 foundMatching = true; 02431 } 02432 } else { 02433 if ((((routingEntry->GetDestinationType() & AnsaOSPF::RoutingTableEntry::AreaBorderRouterDestination) != 0) || 02434 ((routingEntry->GetDestinationType() & AnsaOSPF::RoutingTableEntry::ASBoundaryRouterDestination) != 0)) && 02435 (ULongFromIPv4Address(destination.address) == routingEntry->GetDestinationID().getInt())) 02436 { 02437 foundMatching = true; 02438 } 02439 } 02440 02441 if (foundMatching) { 02442 AnsaOSPF::RoutingTableEntry::RoutingPathType pathType = routingEntry->GetPathType(); 02443 02444 if ((pathType == AnsaOSPF::RoutingTableEntry::Type1External) || 02445 (pathType == AnsaOSPF::RoutingTableEntry::Type2External) || 02446 (routingEntry->GetArea() != AnsaOSPF::BackboneAreaID)) 02447 { 02448 break; 02449 } else { 02450 destinationEntry = routingEntry; 02451 break; 02452 } 02453 } 02454 } 02455 if (destinationEntry == NULL) { 02456 continue; 02457 } 02458 02459 AnsaOSPF::RoutingTableEntry* borderRouterEntry = NULL; 02460 unsigned short currentCost = routeCost; 02461 02462 for (j = 0; j < routeCount; j++) { // (4) BR == borderRouterEntry 02463 AnsaOSPF::RoutingTableEntry* routingEntry = newRoutingTable[j]; 02464 02465 if ((routingEntry->GetArea() == areaID) && 02466 (((routingEntry->GetDestinationType() & AnsaOSPF::RoutingTableEntry::AreaBorderRouterDestination) != 0) || 02467 ((routingEntry->GetDestinationType() & AnsaOSPF::RoutingTableEntry::ASBoundaryRouterDestination) != 0)) && 02468 (routingEntry->GetDestinationID().getInt() == originatingRouter)) 02469 { 02470 borderRouterEntry = routingEntry; 02471 currentCost += borderRouterEntry->GetCost(); 02472 break; 02473 } 02474 } 02475 if (borderRouterEntry == NULL) { 02476 continue; 02477 } else { // (5) 02478 if (currentCost <= destinationEntry->GetCost()) { 02479 if (currentCost < destinationEntry->GetCost()) { 02480 destinationEntry->ClearNextHops(); 02481 } 02482 02483 unsigned long nextHopCount = borderRouterEntry->GetNextHopCount(); 02484 02485 for (j = 0; j < nextHopCount; j++) { 02486 destinationEntry->AddNextHop(borderRouterEntry->GetNextHop(j)); 02487 } 02488 } 02489 } 02490 } 02491 }