Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

OSPF::Area Class Reference

#include <OSPFArea.h>

List of all members.

Public Member Functions

 Area (AreaID id=BackboneAreaID)
virtual ~Area (void)
void SetAreaID (AreaID areaId)
AreaID GetAreaID (void) const
void AddAddressRange (IPv4AddressRange addressRange, bool advertise)
unsigned int GetAddressRangeCount (void) const
IPv4AddressRange GetAddressRange (unsigned int index) const
void AddHostRoute (HostRouteParameters &hostRouteParameters)
void SetTransitCapability (bool transit)
bool GetTransitCapability (void) const
void SetExternalRoutingCapability (bool flooded)
bool GetExternalRoutingCapability (void) const
void SetStubDefaultCost (Metric cost)
Metric GetStubDefaultCost (void) const
void SetSPFTreeRoot (RouterLSA *root)
RouterLSAGetSPFTreeRoot (void)
const RouterLSAGetSPFTreeRoot (void) const
void SetRouter (Router *router)
RouterGetRouter (void)
const RouterGetRouter (void) const
unsigned long GetRouterLSACount (void) const
RouterLSAGetRouterLSA (unsigned long i)
const RouterLSAGetRouterLSA (unsigned long i) const
unsigned long GetNetworkLSACount (void) const
NetworkLSAGetNetworkLSA (unsigned long i)
const NetworkLSAGetNetworkLSA (unsigned long i) const
unsigned long GetSummaryLSACount (void) const
SummaryLSAGetSummaryLSA (unsigned long i)
const SummaryLSAGetSummaryLSA (unsigned long i) const
bool ContainsAddress (IPv4Address address) const
bool HasAddressRange (IPv4AddressRange addressRange) const
IPv4AddressRange GetContainingAddressRange (IPv4AddressRange addressRange, bool *advertise=NULL) const
void AddInterface (Interface *intf)
InterfaceGetInterface (unsigned char ifIndex)
InterfaceGetInterface (IPv4Address address)
bool HasVirtualLink (AreaID withTransitArea) const
InterfaceFindVirtualLink (RouterID routerID)
bool InstallRouterLSA (OSPFRouterLSA *lsa)
bool InstallNetworkLSA (OSPFNetworkLSA *lsa)
bool InstallSummaryLSA (OSPFSummaryLSA *lsa)
RouterLSAFindRouterLSA (LinkStateID linkStateID)
const RouterLSAFindRouterLSA (LinkStateID linkStateID) const
NetworkLSAFindNetworkLSA (LinkStateID linkStateID)
const NetworkLSAFindNetworkLSA (LinkStateID linkStateID) const
SummaryLSAFindSummaryLSA (LSAKeyType lsaKey)
const SummaryLSAFindSummaryLSA (LSAKeyType lsaKey) const
void AgeDatabase (void)
bool AnyNeighborInStates (int states) const
void RemoveFromAllRetransmissionLists (LSAKeyType lsaKey)
bool IsOnAnyRetransmissionList (LSAKeyType lsaKey) const
bool FloodLSA (OSPFLSA *lsa, Interface *intf=NULL, Neighbor *neighbor=NULL)
bool IsLocalAddress (IPv4Address address) const
RouterLSAOriginateRouterLSA (void)
NetworkLSAOriginateNetworkLSA (const Interface *intf)
SummaryLSAOriginateSummaryLSA (const RoutingTableEntry *entry, const std::map< LSAKeyType, bool, LSAKeyType_Less > &originatedLSAs, SummaryLSA *&lsaToReoriginate)
void CalculateShortestPathTree (std::vector< RoutingTableEntry * > &newRoutingTable)
void CalculateInterAreaRoutes (std::vector< RoutingTableEntry * > &newRoutingTable)
void ReCheckSummaryLSAs (std::vector< RoutingTableEntry * > &newRoutingTable)
void info (char *buffer)
std::string detailedInfo (void) const

Private Member Functions

SummaryLSAOriginateSummaryLSA (const OSPF::SummaryLSA *summaryLSA)
bool HasLink (OSPFLSA *fromLSA, OSPFLSA *toLSA) const
std::vector< NextHop > * CalculateNextHops (OSPFLSA *destination, OSPFLSA *parent) const
std::vector< NextHop > * CalculateNextHops (Link &destination, OSPFLSA *parent) const
LinkStateID GetUniqueLinkStateID (IPv4AddressRange destination, Metric destinationCost, SummaryLSA *&lsaToReoriginate) const
bool FindSameOrWorseCostRoute (const std::vector< OSPF::RoutingTableEntry * > &newRoutingTable, const OSPF::SummaryLSA &currentLSA, unsigned short currentCost, bool &destinationInRoutingTable, std::list< OSPF::RoutingTableEntry * > &sameOrWorseCost) const
RoutingTableEntryCreateRoutingTableEntryFromSummaryLSA (const OSPF::SummaryLSA &summaryLSA, unsigned short entryCost, const OSPF::RoutingTableEntry &borderRouterEntry) const

Private Attributes

AreaID areaID
std::map< IPv4AddressRange,
bool, IPv4AddressRange_Less
advertiseAddressRanges
std::vector< IPv4AddressRangeareaAddressRanges
std::vector< Interface * > associatedInterfaces
std::vector< HostRouteParametershostRoutes
std::map< LinkStateID, RouterLSA * > routerLSAsByID
std::vector< RouterLSA * > routerLSAs
std::map< LinkStateID, NetworkLSA * > networkLSAsByID
std::vector< NetworkLSA * > networkLSAs
std::map< LSAKeyType, SummaryLSA *,
LSAKeyType_Less
summaryLSAsByID
std::vector< SummaryLSA * > summaryLSAs
bool transitCapability
bool externalRoutingCapability
Metric stubDefaultCost
RouterLSAspfTreeRoot
RouterparentRouter


Constructor & Destructor Documentation

OSPF::Area::Area AreaID  id = BackboneAreaID  ) 
 

00008                              :
00009     areaID (id),
00010     transitCapability (false),
00011     externalRoutingCapability (true),
00012     stubDefaultCost (1),
00013     spfTreeRoot (NULL),
00014     parentRouter (NULL)
00015 {
00016 }

OSPF::Area::~Area void   )  [virtual]
 

00019 {
00020     int interfaceNum = associatedInterfaces.size ();
00021     for (int i = 0; i < interfaceNum; i++) {
00022         delete (associatedInterfaces[i]);
00023     }
00024     long lsaCount = routerLSAs.size ();
00025     for (long j = 0; j < lsaCount; j++) {
00026         delete routerLSAs[j];
00027     }
00028     routerLSAs.clear ();
00029     lsaCount = networkLSAs.size ();
00030     for (long k = 0; k < lsaCount; k++) {
00031         delete networkLSAs[k];
00032     }
00033     networkLSAs.clear ();
00034     lsaCount = summaryLSAs.size ();
00035     for (long m = 0; m < lsaCount; m++) {
00036         delete summaryLSAs[m];
00037     }
00038     summaryLSAs.clear ();
00039 }


Member Function Documentation

void OSPF::Area::AddAddressRange IPv4AddressRange  addressRange,
bool  advertise
[inline]
 

00040 { areaAddressRanges.push_back (addressRange); advertiseAddressRanges[addressRange] = advertise; }

void OSPF::Area::AddHostRoute HostRouteParameters hostRouteParameters  )  [inline]
 

00043 { hostRoutes.push_back (hostRouteParameters); }

void OSPF::Area::AddInterface Interface intf  ) 
 

00042 {
00043     intf->SetArea (this);
00044     associatedInterfaces.push_back (intf);
00045 }

void OSPF::Area::AgeDatabase void   ) 
 

00328 {
00329     long            lsaCount            = routerLSAs.size ();
00330     bool            rebuildRoutingTable = false;
00331     long            i;
00332 
00333     for (i = 0; i < lsaCount; i++) {
00334         unsigned short   lsAge          = routerLSAs[i]->getHeader ().getLsAge ();
00335         bool             selfOriginated = (routerLSAs[i]->getHeader ().getAdvertisingRouter ().getInt () == parentRouter->GetRouterID ());
00336         bool             unreachable    = parentRouter->DestinationIsUnreachable (routerLSAs[i]);
00337         OSPF::RouterLSA* lsa            = routerLSAs[i];
00338 
00339         if ((selfOriginated && (lsAge < (LS_REFRESH_TIME - 1))) || (!selfOriginated && (lsAge < (MAX_AGE - 1)))) {
00340             lsa->getHeader ().setLsAge (lsAge + 1);
00341             if ((lsAge + 1) % CHECK_AGE == 0) {
00342                 if (!lsa->ValidateLSChecksum ()) {
00343                     EV << "Invalid LS checksum. Memory error detected!\n";
00344                 }
00345             }
00346             lsa->IncrementInstallTime ();
00347         }
00348         if (selfOriginated && (lsAge == (LS_REFRESH_TIME - 1))) {
00349             if (unreachable) {
00350                 lsa->getHeader ().setLsAge (MAX_AGE);
00351                 FloodLSA (lsa);
00352                 lsa->IncrementInstallTime ();
00353             } else {
00354                 long sequenceNumber = lsa->getHeader ().getLsSequenceNumber ();
00355                 if (sequenceNumber == MAX_SEQUENCE_NUMBER) {
00356                     lsa->getHeader ().setLsAge (MAX_AGE);
00357                     FloodLSA (lsa);
00358                     lsa->IncrementInstallTime ();
00359                 } else {
00360                     OSPF::RouterLSA* newLSA = OriginateRouterLSA ();
00361 
00362                     newLSA->getHeader ().setLsSequenceNumber (sequenceNumber + 1);
00363                     newLSA->getHeader ().setLsChecksum (0);    // TODO: calculate correct LS checksum
00364                     rebuildRoutingTable |= lsa->Update (newLSA);
00365                     delete newLSA;
00366 
00367                     FloodLSA (lsa);
00368                 }
00369             }
00370         }
00371         if (!selfOriginated && (lsAge == MAX_AGE - 1)) {
00372             lsa->getHeader ().setLsAge (MAX_AGE);
00373             FloodLSA (lsa);
00374             lsa->IncrementInstallTime ();
00375         }
00376         if (lsAge == MAX_AGE) {
00377             OSPF::LSAKeyType lsaKey;
00378 
00379             lsaKey.linkStateID = lsa->getHeader ().getLinkStateID ();
00380             lsaKey.advertisingRouter = lsa->getHeader ().getAdvertisingRouter ().getInt ();
00381 
00382             if (!IsOnAnyRetransmissionList (lsaKey) &&
00383                 !AnyNeighborInStates (OSPF::Neighbor::ExchangeState | OSPF::Neighbor::LoadingState))
00384             {
00385                 if (!selfOriginated || unreachable) {
00386                     routerLSAsByID.erase (lsa->getHeader ().getLinkStateID ());
00387                     delete lsa;
00388                     routerLSAs[i] = NULL;
00389                     rebuildRoutingTable = true;
00390                 } else {
00391                     OSPF::RouterLSA* newLSA              = OriginateRouterLSA ();
00392                     long             sequenceNumber      = lsa->getHeader ().getLsSequenceNumber ();
00393 
00394                     newLSA->getHeader ().setLsSequenceNumber ((sequenceNumber == MAX_SEQUENCE_NUMBER) ? INITIAL_SEQUENCE_NUMBER : sequenceNumber + 1);
00395                     newLSA->getHeader ().setLsChecksum (0);    // TODO: calculate correct LS checksum
00396                     rebuildRoutingTable |= lsa->Update (newLSA);
00397                     delete newLSA;
00398 
00399                     FloodLSA (lsa);
00400                 }
00401             }
00402         }
00403     }
00404 
00405     std::vector<RouterLSA*>::iterator routerIt = routerLSAs.begin ();
00406     while (routerIt != routerLSAs.end ()) {
00407         if ((*routerIt) == NULL) {
00408             routerIt = routerLSAs.erase (routerIt);
00409         } else {
00410             routerIt++;
00411         }
00412     }
00413 
00414     lsaCount = networkLSAs.size ();
00415     for (i = 0; i < lsaCount; i++) {
00416         unsigned short    lsAge          = networkLSAs[i]->getHeader ().getLsAge ();
00417         bool              unreachable    = parentRouter->DestinationIsUnreachable (networkLSAs[i]);
00418         OSPF::NetworkLSA* lsa            = networkLSAs[i];
00419         OSPF::Interface*  localIntf      = GetInterface (IPv4AddressFromULong (lsa->getHeader ().getLinkStateID ()));
00420         bool              selfOriginated = false;
00421 
00422         if ((localIntf != NULL) &&
00423             (localIntf->GetState () == OSPF::Interface::DesignatedRouterState) &&
00424             (localIntf->GetNeighborCount () > 0) &&
00425             (localIntf->AnyNeighborInStates (OSPF::Neighbor::FullState)))
00426         {
00427             selfOriginated = true;
00428         }
00429 
00430         if ((selfOriginated && (lsAge < (LS_REFRESH_TIME - 1))) || (!selfOriginated && (lsAge < (MAX_AGE - 1)))) {
00431             lsa->getHeader ().setLsAge (lsAge + 1);
00432             if ((lsAge + 1) % CHECK_AGE == 0) {
00433                 if (!lsa->ValidateLSChecksum ()) {
00434                     EV << "Invalid LS checksum. Memory error detected!\n";
00435                 }
00436             }
00437             lsa->IncrementInstallTime ();
00438         }
00439         if (selfOriginated && (lsAge == (LS_REFRESH_TIME - 1))) {
00440             if (unreachable) {
00441                 lsa->getHeader ().setLsAge (MAX_AGE);
00442                 FloodLSA (lsa);
00443                 lsa->IncrementInstallTime ();
00444             } else {
00445                 long sequenceNumber = lsa->getHeader ().getLsSequenceNumber ();
00446                 if (sequenceNumber == MAX_SEQUENCE_NUMBER) {
00447                     lsa->getHeader ().setLsAge (MAX_AGE);
00448                     FloodLSA (lsa);
00449                     lsa->IncrementInstallTime ();
00450                 } else {
00451                     OSPF::NetworkLSA* newLSA = OriginateNetworkLSA (localIntf);
00452 
00453                     if (newLSA != NULL) {
00454                         newLSA->getHeader ().setLsSequenceNumber (sequenceNumber + 1);
00455                         newLSA->getHeader ().setLsChecksum (0);    // TODO: calculate correct LS checksum
00456                         rebuildRoutingTable |= lsa->Update (newLSA);
00457                         delete newLSA;
00458                     } else {    // no neighbors on the network -> old NetworkLSA must be flushed
00459                         lsa->getHeader ().setLsAge (MAX_AGE);
00460                         lsa->IncrementInstallTime ();
00461                     }
00462 
00463                     FloodLSA (lsa);
00464                 }
00465             }
00466         }
00467         if (!selfOriginated && (lsAge == MAX_AGE - 1)) {
00468             lsa->getHeader ().setLsAge (MAX_AGE);
00469             FloodLSA (lsa);
00470             lsa->IncrementInstallTime ();
00471         }
00472         if (lsAge == MAX_AGE) {
00473             OSPF::LSAKeyType lsaKey;
00474 
00475             lsaKey.linkStateID = lsa->getHeader ().getLinkStateID ();
00476             lsaKey.advertisingRouter = lsa->getHeader ().getAdvertisingRouter ().getInt ();
00477 
00478             if (!IsOnAnyRetransmissionList (lsaKey) &&
00479                 !AnyNeighborInStates (OSPF::Neighbor::ExchangeState | OSPF::Neighbor::LoadingState))
00480             {
00481                 if (!selfOriginated || unreachable) {
00482                     networkLSAsByID.erase (lsa->getHeader ().getLinkStateID ());
00483                     delete lsa;
00484                     networkLSAs[i] = NULL;
00485                     rebuildRoutingTable = true;
00486                 } else {
00487                     OSPF::NetworkLSA* newLSA              = OriginateNetworkLSA (localIntf);
00488                     long              sequenceNumber      = lsa->getHeader ().getLsSequenceNumber ();
00489 
00490                     if (newLSA != NULL) {
00491                         newLSA->getHeader ().setLsSequenceNumber ((sequenceNumber == MAX_SEQUENCE_NUMBER) ? INITIAL_SEQUENCE_NUMBER : sequenceNumber + 1);
00492                         newLSA->getHeader ().setLsChecksum (0);    // TODO: calculate correct LS checksum
00493                         rebuildRoutingTable |= lsa->Update (newLSA);
00494                         delete newLSA;
00495 
00496                         FloodLSA (lsa);
00497                     } else {    // no neighbors on the network -> old NetworkLSA must be deleted
00498                         delete networkLSAs[i];
00499                     }
00500                 }
00501             }
00502         }
00503     }
00504 
00505     std::vector<NetworkLSA*>::iterator networkIt = networkLSAs.begin ();
00506     while (networkIt != networkLSAs.end ()) {
00507         if ((*networkIt) == NULL) {
00508             networkIt = networkLSAs.erase (networkIt);
00509         } else {
00510             networkIt++;
00511         }
00512     }
00513 
00514     lsaCount = summaryLSAs.size ();
00515     for (i = 0; i < lsaCount; i++) {
00516         unsigned short    lsAge          = summaryLSAs[i]->getHeader ().getLsAge ();
00517         bool              selfOriginated = (summaryLSAs[i]->getHeader ().getAdvertisingRouter ().getInt () == parentRouter->GetRouterID ());
00518         bool              unreachable    = parentRouter->DestinationIsUnreachable (summaryLSAs[i]);
00519         OSPF::SummaryLSA* lsa            = summaryLSAs[i];
00520 
00521         if ((selfOriginated && (lsAge < (LS_REFRESH_TIME - 1))) || (!selfOriginated && (lsAge < (MAX_AGE - 1)))) {
00522             lsa->getHeader ().setLsAge (lsAge + 1);
00523             if ((lsAge + 1) % CHECK_AGE == 0) {
00524                 if (!lsa->ValidateLSChecksum ()) {
00525                     EV << "Invalid LS checksum. Memory error detected!\n";
00526                 }
00527             }
00528             lsa->IncrementInstallTime ();
00529         }
00530         if (selfOriginated && (lsAge == (LS_REFRESH_TIME - 1))) {
00531             if (unreachable) {
00532                 lsa->getHeader ().setLsAge (MAX_AGE);
00533                 FloodLSA (lsa);
00534                 lsa->IncrementInstallTime ();
00535             } else {
00536                 long sequenceNumber = lsa->getHeader ().getLsSequenceNumber ();
00537                 if (sequenceNumber == MAX_SEQUENCE_NUMBER) {
00538                     lsa->getHeader ().setLsAge (MAX_AGE);
00539                     FloodLSA (lsa);
00540                     lsa->IncrementInstallTime ();
00541                 } else {
00542                     OSPF::SummaryLSA* newLSA = OriginateSummaryLSA (lsa);
00543 
00544                     if (newLSA != NULL) {
00545                         newLSA->getHeader ().setLsSequenceNumber (sequenceNumber + 1);
00546                         newLSA->getHeader ().setLsChecksum (0);    // TODO: calculate correct LS checksum
00547                         rebuildRoutingTable |= lsa->Update (newLSA);
00548                         delete newLSA;
00549 
00550                         FloodLSA (lsa);
00551                     } else {
00552                         lsa->getHeader ().setLsAge (MAX_AGE);
00553                         FloodLSA (lsa);
00554                         lsa->IncrementInstallTime ();
00555                     }
00556                 }
00557             }
00558         }
00559         if (!selfOriginated && (lsAge == MAX_AGE - 1)) {
00560             lsa->getHeader ().setLsAge (MAX_AGE);
00561             FloodLSA (lsa);
00562             lsa->IncrementInstallTime ();
00563         }
00564         if (lsAge == MAX_AGE) {
00565             OSPF::LSAKeyType lsaKey;
00566 
00567             lsaKey.linkStateID = lsa->getHeader ().getLinkStateID ();
00568             lsaKey.advertisingRouter = lsa->getHeader ().getAdvertisingRouter ().getInt ();
00569 
00570             if (!IsOnAnyRetransmissionList (lsaKey) &&
00571                 !AnyNeighborInStates (OSPF::Neighbor::ExchangeState | OSPF::Neighbor::LoadingState))
00572             {
00573                 if (!selfOriginated || unreachable) {
00574                     summaryLSAsByID.erase (lsaKey);
00575                     delete lsa;
00576                     summaryLSAs[i] = NULL;
00577                     rebuildRoutingTable = true;
00578                 } else {
00579                     OSPF::SummaryLSA* newLSA = OriginateSummaryLSA (lsa);
00580                     if (newLSA != NULL) {
00581                         long sequenceNumber = lsa->getHeader ().getLsSequenceNumber ();
00582 
00583                         newLSA->getHeader ().setLsSequenceNumber ((sequenceNumber == MAX_SEQUENCE_NUMBER) ? INITIAL_SEQUENCE_NUMBER : sequenceNumber + 1);
00584                         newLSA->getHeader ().setLsChecksum (0);    // TODO: calculate correct LS checksum
00585                         rebuildRoutingTable |= lsa->Update (newLSA);
00586                         delete newLSA;
00587 
00588                         FloodLSA (lsa);
00589                     } else {
00590                         summaryLSAsByID.erase (lsaKey);
00591                         delete lsa;
00592                         summaryLSAs[i] = NULL;
00593                         rebuildRoutingTable = true;
00594                     }
00595                 }
00596             }
00597         }
00598     }
00599 
00600     std::vector<SummaryLSA*>::iterator summaryIt = summaryLSAs.begin ();
00601     while (summaryIt != summaryLSAs.end ()) {
00602         if ((*summaryIt) == NULL) {
00603             summaryIt = summaryLSAs.erase (summaryIt);
00604         } else {
00605             summaryIt++;
00606         }
00607     }
00608 
00609     long interfaceCount = associatedInterfaces.size ();
00610     for (long m = 0; m < interfaceCount; m++) {
00611         associatedInterfaces[m]->AgeTransmittedLSALists ();
00612     }
00613 
00614     if (rebuildRoutingTable) {
00615         parentRouter->RebuildRoutingTable ();
00616     }
00617 }

bool OSPF::Area::AnyNeighborInStates int  states  )  const
 

00620 {
00621     long interfaceCount = associatedInterfaces.size ();
00622     for (long i = 0; i < interfaceCount; i++) {
00623         if (associatedInterfaces[i]->AnyNeighborInStates (states)) {
00624             return true;
00625         }
00626     }
00627     return false;
00628 }

void OSPF::Area::CalculateInterAreaRoutes std::vector< RoutingTableEntry * > &  newRoutingTable  ) 
 

See also:
RFC 2328 Section 16.2.

Todo:
This function does a lot of lookup in the input newRoutingTable. Restructuring the input vector into some kind of hash would quite probably speed up execution.
02185 {
02186     unsigned long i = 0;
02187     unsigned long j = 0;
02188     unsigned long lsaCount = summaryLSAs.size ();
02189 
02190     for (i = 0; i < lsaCount; i++) {
02191         OSPF::SummaryLSA* currentLSA        = summaryLSAs[i];
02192         OSPFLSAHeader&    currentHeader     = currentLSA->getHeader ();
02193 
02194         unsigned long     routeCost         = currentLSA->getRouteCost ();
02195         unsigned short    lsAge             = currentHeader.getLsAge ();
02196         RouterID          originatingRouter = currentHeader.getAdvertisingRouter ().getInt ();
02197         bool              selfOriginated    = (originatingRouter == parentRouter->GetRouterID ());
02198 
02199         if ((routeCost == LS_INFINITY) || (lsAge == MAX_AGE) || (selfOriginated)) { // (1) and (2)
02200             continue;
02201         }
02202 
02203         char                   lsType     = currentHeader.getLsType ();
02204         unsigned long          routeCount = newRoutingTable.size ();
02205         OSPF::IPv4AddressRange destination;
02206 
02207         destination.address = IPv4AddressFromULong (currentHeader.getLinkStateID ());
02208         destination.mask    = IPv4AddressFromULong (currentLSA->getNetworkMask ().getInt ());
02209 
02210         if ((lsType == SummaryLSA_NetworksType) && (parentRouter->HasAddressRange (destination))) { // (3)
02211             bool foundIntraAreaRoute = false;
02212 
02213             // look for an "Active" IntraArea route
02214             for (j = 0; j < routeCount; j++) {
02215                 OSPF::RoutingTableEntry* routingEntry = newRoutingTable[j];
02216 
02217                 if ((routingEntry->GetDestinationType () == OSPF::RoutingTableEntry::NetworkDestination) &&
02218                     (routingEntry->GetPathType () == OSPF::RoutingTableEntry::IntraArea) &&
02219                     ((routingEntry->GetDestinationID ().getInt () &
02220                       routingEntry->GetAddressMask ().getInt ()   &
02221                       ULongFromIPv4Address (destination.mask)       ) == ULongFromIPv4Address (destination.address &
02222                                                                                                destination.mask)))
02223                 {
02224                     foundIntraAreaRoute = true;
02225                     break;
02226                 }
02227             }
02228             if (foundIntraAreaRoute) {
02229                 continue;
02230             }
02231         }
02232 
02233         OSPF::RoutingTableEntry* borderRouterEntry = NULL;
02234 
02235         // The routingEntry describes a route to an other area -> look for the border router originating it
02236         for (j = 0; j < routeCount; j++) {     // (4) N == destination, BR == borderRouterEntry
02237             OSPF::RoutingTableEntry* routingEntry = newRoutingTable[j];
02238 
02239             if ((routingEntry->GetArea () == areaID) &&
02240                 (((routingEntry->GetDestinationType () & OSPF::RoutingTableEntry::AreaBorderRouterDestination) != 0) ||
02241                  ((routingEntry->GetDestinationType () & OSPF::RoutingTableEntry::ASBoundaryRouterDestination) != 0)) &&
02242                 (routingEntry->GetDestinationID ().getInt () == originatingRouter))
02243             {
02244                 borderRouterEntry = routingEntry;
02245                 break;
02246             }
02247         }
02248         if (borderRouterEntry == NULL) {
02249             continue;
02250         } else {    // (5)
02251             /* "Else, this LSA describes an inter-area path to destination N,
02252              * whose cost is the distance to BR plus the cost specified in the LSA.
02253              * Call the cost of this inter-area path IAC."
02254              */
02255             bool                                destinationInRoutingTable = true;
02256             unsigned short                      currentCost               = routeCost + borderRouterEntry->GetCost ();
02257             std::list<OSPF::RoutingTableEntry*> sameOrWorseCost;
02258 
02259             if (FindSameOrWorseCostRoute (newRoutingTable,
02260                                           *currentLSA,
02261                                           currentCost,
02262                                           destinationInRoutingTable,
02263                                           sameOrWorseCost))
02264             {
02265                 continue;
02266             }
02267 
02268             if (destinationInRoutingTable && (sameOrWorseCost.size () > 0)) {
02269                 OSPF::RoutingTableEntry* equalEntry = NULL;
02270 
02271                 /* Look for an equal cost entry in the sameOrWorseCost list, and
02272                  * also clear the more expensive entries from the newRoutingTable.
02273                  */
02274                 for (std::list<OSPF::RoutingTableEntry*>::iterator it = sameOrWorseCost.begin (); it != sameOrWorseCost.end (); it++) {
02275                     OSPF::RoutingTableEntry* checkedEntry = (*it);
02276 
02277                     if (checkedEntry->GetCost () > currentCost) {
02278                         for (std::vector<OSPF::RoutingTableEntry*>::iterator entryIt = newRoutingTable.begin (); entryIt != newRoutingTable.end (); entryIt++) {
02279                             if (checkedEntry == (*entryIt)) {
02280                                 newRoutingTable.erase (entryIt);
02281                                 break;
02282                             }
02283                         }
02284                     } else {    // EntryCost == currentCost
02285                         equalEntry = checkedEntry;  // should be only one - if there are more they are ignored
02286                     }
02287                 }
02288 
02289                 unsigned long nextHopCount = borderRouterEntry->GetNextHopCount ();
02290 
02291                 if (equalEntry != NULL) {
02292                     /* Add the next hops of the border router advertising this destination
02293                      * to the equal entry.
02294                      */
02295                     for (unsigned long j = 0; j < nextHopCount; j++) {
02296                         equalEntry->AddNextHop (borderRouterEntry->GetNextHop (j));
02297                     }
02298                 } else {
02299                     OSPF::RoutingTableEntry* newEntry = CreateRoutingTableEntryFromSummaryLSA (*currentLSA, currentCost, *borderRouterEntry);
02300                     ASSERT (newEntry != NULL);
02301                     newRoutingTable.push_back (newEntry);
02302                 }
02303             } else {
02304                 OSPF::RoutingTableEntry* newEntry = CreateRoutingTableEntryFromSummaryLSA (*currentLSA, currentCost, *borderRouterEntry);
02305                 ASSERT (newEntry != NULL);
02306                 newRoutingTable.push_back (newEntry);
02307             }
02308         }
02309     }
02310 }

std::vector< OSPF::NextHop > * OSPF::Area::CalculateNextHops Link &  destination,
OSPFLSA *  parent
const [private]
 

01920 {
01921     std::vector<OSPF::NextHop>* hops = new std::vector<OSPF::NextHop>;
01922     unsigned long                i;
01923 
01924     OSPF::RouterLSA* routerLSA = check_and_cast<OSPF::RouterLSA*> (parent);
01925     if (routerLSA != spfTreeRoot) {
01926         unsigned int nextHopCount = routerLSA->GetNextHopCount ();
01927         for (i = 0; i < nextHopCount; i++) {
01928             hops->push_back (routerLSA->GetNextHop (i));
01929         }
01930         return hops;
01931     } else {
01932         unsigned long interfaceNum = associatedInterfaces.size ();
01933         for (i = 0; i < interfaceNum; i++) {
01934             OSPF::Interface::OSPFInterfaceType intfType = associatedInterfaces[i]->GetType ();
01935 
01936             if (intfType == OSPF::Interface::PointToPoint) {
01937                 OSPF::Neighbor* neighbor = (associatedInterfaces[i]->GetNeighborCount () > 0) ? associatedInterfaces[i]->GetNeighbor (0) : NULL;
01938                 if (neighbor != NULL) {
01939                     OSPF::IPv4Address neighborAddress = neighbor->GetAddress ();
01940                     if (((neighborAddress != OSPF::NullIPv4Address) &&
01941                          (ULongFromIPv4Address (neighborAddress) == destination.getLinkID ().getInt ())) ||
01942                         ((neighborAddress == OSPF::NullIPv4Address) &&
01943                          (ULongFromIPv4Address (associatedInterfaces[i]->GetAddressRange ().address) == destination.getLinkID ().getInt ()) &&
01944                          (ULongFromIPv4Address (associatedInterfaces[i]->GetAddressRange ().mask) == destination.getLinkData ())))
01945                     {
01946                         NextHop nextHop;
01947                         nextHop.ifIndex           = associatedInterfaces[i]->GetIfIndex ();
01948                         nextHop.hopAddress        = neighborAddress;
01949                         nextHop.advertisingRouter = parentRouter->GetRouterID ();
01950                         hops->push_back (nextHop);
01951                         break;
01952                     }
01953                 }
01954             }
01955             if ((intfType == OSPF::Interface::Broadcast) ||
01956                 (intfType == OSPF::Interface::NBMA))
01957             {
01958                 if ((destination.getLinkID ().getInt () == ULongFromIPv4Address (associatedInterfaces[i]->GetAddressRange ().address & associatedInterfaces[i]->GetAddressRange ().mask)) &&
01959                     (destination.getLinkData () == ULongFromIPv4Address (associatedInterfaces[i]->GetAddressRange ().mask)))
01960                 {
01961                     NextHop nextHop;
01962                     nextHop.ifIndex           = associatedInterfaces[i]->GetIfIndex ();
01963                     nextHop.hopAddress        = IPv4AddressFromULong (destination.getLinkID ().getInt ());
01964                     nextHop.advertisingRouter = parentRouter->GetRouterID ();
01965                     hops->push_back (nextHop);
01966                     break;
01967                 }
01968             }
01969             if (intfType == OSPF::Interface::PointToMultiPoint) {
01970                 if (destination.getType () == StubLink) {
01971                     if (destination.getLinkID ().getInt () == ULongFromIPv4Address (associatedInterfaces[i]->GetAddressRange ().address)) {
01972                         // The link contains the router's own interface address and a full mask,
01973                         // so we insert a next hop pointing to the interface itself. Kind of pointless, but
01974                         // not much else we could do...
01975                         // TODO: check what other OSPF implementations do in this situation
01976                         NextHop nextHop;
01977                         nextHop.ifIndex           = associatedInterfaces[i]->GetIfIndex ();
01978                         nextHop.hopAddress        = associatedInterfaces[i]->GetAddressRange ().address;
01979                         nextHop.advertisingRouter = parentRouter->GetRouterID ();
01980                         hops->push_back (nextHop);
01981                         break;
01982                     }
01983                 }
01984                 if (destination.getType () == PointToPointLink) {
01985                     OSPF::Neighbor* neighbor = associatedInterfaces[i]->GetNeighborByID (destination.getLinkID ().getInt ());
01986                     if (neighbor != NULL) {
01987                         NextHop nextHop;
01988                         nextHop.ifIndex           = associatedInterfaces[i]->GetIfIndex ();
01989                         nextHop.hopAddress        = neighbor->GetAddress ();
01990                         nextHop.advertisingRouter = parentRouter->GetRouterID ();
01991                         hops->push_back (nextHop);
01992                         break;
01993                     }
01994                 }
01995             }
01996             // next hops for virtual links are generated later, after examining transit areas' SummaryLSAs
01997         }
01998 
01999         if (hops->size () == 0) {
02000             unsigned long hostRouteCount = hostRoutes.size ();
02001             for (i = 0; i < hostRouteCount; i++) {
02002                 if ((destination.getLinkID ().getInt () == ULongFromIPv4Address (hostRoutes[i].address)) &&
02003                     (destination.getLinkData () == 0xFFFFFFFF))
02004                 {
02005                     NextHop nextHop;
02006                     nextHop.ifIndex           = hostRoutes[i].ifIndex;
02007                     nextHop.hopAddress        = hostRoutes[i].address;
02008                     nextHop.advertisingRouter = parentRouter->GetRouterID ();
02009                     hops->push_back (nextHop);
02010                     break;
02011                 }
02012             }
02013         }
02014     }
02015 
02016     return hops;
02017 }

std::vector< OSPF::NextHop > * OSPF::Area::CalculateNextHops OSPFLSA *  destination,
OSPFLSA *  parent
const [private]
 

01795 {
01796     std::vector<OSPF::NextHop>* hops = new std::vector<OSPF::NextHop>;
01797     unsigned long               i, j;
01798 
01799     OSPF::RouterLSA* routerLSA = dynamic_cast<OSPF::RouterLSA*> (parent);
01800     if (routerLSA != NULL) {
01801         if (routerLSA != spfTreeRoot) {
01802             unsigned int nextHopCount = routerLSA->GetNextHopCount ();
01803             for (i = 0; i < nextHopCount; i++) {
01804                 hops->push_back (routerLSA->GetNextHop (i));
01805             }
01806             return hops;
01807         } else {
01808             OSPF::RouterLSA* destinationRouterLSA = dynamic_cast<OSPF::RouterLSA*> (destination);
01809             if (destinationRouterLSA != NULL) {
01810                 unsigned long interfaceNum   = associatedInterfaces.size ();
01811                 for (i = 0; i < interfaceNum; i++) {
01812                     OSPF::Interface::OSPFInterfaceType intfType = associatedInterfaces[i]->GetType ();
01813                     if (intfType == OSPF::Interface::PointToPoint) {
01814                         OSPF::Neighbor* ptpNeighbor = associatedInterfaces[i]->GetNeighbor (0);
01815                         if (ptpNeighbor != NULL) {
01816                             if (ptpNeighbor->GetNeighborID () == destinationRouterLSA->getHeader ().getLinkStateID ()) {
01817                                 NextHop nextHop;
01818                                 nextHop.ifIndex           = associatedInterfaces[i]->GetIfIndex ();
01819                                 nextHop.hopAddress        = ptpNeighbor->GetAddress ();
01820                                 nextHop.advertisingRouter = destinationRouterLSA->getHeader ().getAdvertisingRouter ().getInt ();
01821                                 hops->push_back (nextHop);
01822                                 break;
01823                             }
01824                         }
01825                     }
01826                     if (intfType == OSPF::Interface::PointToMultiPoint) {
01827                         OSPF::Neighbor* ptmpNeighbor = associatedInterfaces[i]->GetNeighborByID (destinationRouterLSA->getHeader ().getLinkStateID ());
01828                         if (ptmpNeighbor != NULL) {
01829                             unsigned int   linkCount = destinationRouterLSA->getLinksArraySize ();
01830                             OSPF::RouterID rootID    = parentRouter->GetRouterID ();
01831                             for (j = 0; j < linkCount; j++) {
01832                                 Link& link = destinationRouterLSA->getLinks (j);
01833                                 if (link.getLinkID () == rootID) {
01834                                     NextHop nextHop;
01835                                     nextHop.ifIndex           = associatedInterfaces[i]->GetIfIndex ();
01836                                     nextHop.hopAddress        = IPv4AddressFromULong (link.getLinkData ());
01837                                     nextHop.advertisingRouter = destinationRouterLSA->getHeader ().getAdvertisingRouter ().getInt ();
01838                                     hops->push_back (nextHop);
01839                                 }
01840                             }
01841                             break;
01842                         }
01843                     }
01844                 }
01845             } else {
01846                 OSPF::NetworkLSA* destinationNetworkLSA = dynamic_cast<OSPF::NetworkLSA*> (destination);
01847                 if (destinationNetworkLSA != NULL) {
01848                     OSPF::IPv4Address networkDesignatedRouter = IPv4AddressFromULong (destinationNetworkLSA->getHeader ().getLinkStateID ());
01849                     unsigned long     interfaceNum            = associatedInterfaces.size ();
01850                     for (i = 0; i < interfaceNum; i++) {
01851                         OSPF::Interface::OSPFInterfaceType intfType = associatedInterfaces[i]->GetType ();
01852                         if (((intfType == OSPF::Interface::Broadcast) ||
01853                              (intfType == OSPF::Interface::NBMA)) &&
01854                             (associatedInterfaces[i]->GetDesignatedRouter ().ipInterfaceAddress == networkDesignatedRouter))
01855                         {
01856                             OSPF::IPv4AddressRange range = associatedInterfaces[i]->GetAddressRange ();
01857                             NextHop                nextHop;
01858 
01859                             nextHop.ifIndex           = associatedInterfaces[i]->GetIfIndex ();
01860                             nextHop.hopAddress        = (range.address & range.mask);
01861                             nextHop.advertisingRouter = destinationNetworkLSA->getHeader ().getAdvertisingRouter ().getInt ();
01862                             hops->push_back (nextHop);
01863                         }
01864                     }
01865                 }
01866             }
01867         }
01868     } else {
01869         OSPF::NetworkLSA* networkLSA = dynamic_cast<OSPF::NetworkLSA*> (parent);
01870         if (networkLSA != NULL) {
01871             if (networkLSA->GetParent () != spfTreeRoot) {
01872                 unsigned int nextHopCount = networkLSA->GetNextHopCount ();
01873                 for (i = 0; i < nextHopCount; i++) {
01874                     hops->push_back (networkLSA->GetNextHop (i));
01875                 }
01876                 return hops;
01877             } else {
01878                 unsigned long parentLinkStateID = parent->getHeader ().getLinkStateID ();
01879 
01880                 OSPF::RouterLSA* destinationRouterLSA = dynamic_cast<OSPF::RouterLSA*> (destination);
01881                 if (destinationRouterLSA != NULL) {
01882                     OSPF::RouterID destinationRouterID = destinationRouterLSA->getHeader ().getLinkStateID ();
01883                     unsigned int   linkCount           = destinationRouterLSA->getLinksArraySize ();
01884                     for (i = 0; i < linkCount; i++) {
01885                         Link&   link = destinationRouterLSA->getLinks (i);
01886                         NextHop nextHop;
01887 
01888                         if (((link.getType () == TransitLink) &&
01889                              (link.getLinkID ().getInt () == parentLinkStateID)) ||
01890                             ((link.getType () == StubLink) &&
01891                              ((link.getLinkID ().getInt () & link.getLinkData ()) == (parentLinkStateID & networkLSA->getNetworkMask ().getInt ()))))
01892                         {
01893                             unsigned long interfaceNum   = associatedInterfaces.size ();
01894                             for (j = 0; j < interfaceNum; j++) {
01895                                 OSPF::Interface::OSPFInterfaceType intfType = associatedInterfaces[j]->GetType ();
01896                                 if (((intfType == OSPF::Interface::Broadcast) ||
01897                                      (intfType == OSPF::Interface::NBMA)) &&
01898                                     (associatedInterfaces[j]->GetDesignatedRouter ().ipInterfaceAddress == IPv4AddressFromULong (parentLinkStateID)))
01899                                 {
01900                                     OSPF::Neighbor* nextHopNeighbor = associatedInterfaces[j]->GetNeighborByID (destinationRouterID);
01901                                     if (nextHopNeighbor != NULL) {
01902                                         nextHop.ifIndex           = associatedInterfaces[j]->GetIfIndex ();
01903                                         nextHop.hopAddress        = nextHopNeighbor->GetAddress ();
01904                                         nextHop.advertisingRouter = destinationRouterLSA->getHeader ().getAdvertisingRouter ().getInt ();
01905                                         hops->push_back (nextHop);
01906                                     }
01907                                 }
01908                             }
01909                         }
01910                     }
01911                 }
01912             }
01913         }
01914     }
01915 
01916     return hops;
01917 }

void OSPF::Area::CalculateShortestPathTree std::vector< RoutingTableEntry * > &  newRoutingTable  ) 
 

01321 {
01322     OSPF::RouterID          routerID = parentRouter->GetRouterID ();
01323     bool                    finished = false;
01324     std::vector<OSPFLSA*>   treeVertices;
01325     OSPFLSA*                justAddedVertex;
01326     std::vector<OSPFLSA*>   candidateVertices;
01327     unsigned long            i, j, k;
01328     unsigned long            lsaCount;
01329 
01330     if (spfTreeRoot == NULL) {
01331         OSPF::RouterLSA* newLSA = OriginateRouterLSA ();
01332 
01333         InstallRouterLSA (newLSA);
01334 
01335         OSPF::RouterLSA* routerLSA = FindRouterLSA (routerID);
01336 
01337         spfTreeRoot = routerLSA;
01338         FloodLSA (newLSA);
01339         delete newLSA;
01340     }
01341     if (spfTreeRoot == NULL) {
01342         return;
01343     }
01344 
01345     lsaCount = routerLSAs.size ();
01346     for (i = 0; i < lsaCount; i++) {
01347         routerLSAs[i]->ClearNextHops ();
01348     }
01349     lsaCount = networkLSAs.size ();
01350     for (i = 0; i < lsaCount; i++) {
01351         networkLSAs[i]->ClearNextHops ();
01352     }
01353     spfTreeRoot->SetDistance (0);
01354     treeVertices.push_back (spfTreeRoot);
01355     justAddedVertex = spfTreeRoot;          // (1)
01356 
01357     do {
01358         LSAType vertexType = static_cast<LSAType> (justAddedVertex->getHeader ().getLsType ());
01359 
01360         if ((vertexType == RouterLSAType)) {
01361             OSPF::RouterLSA* routerVertex = check_and_cast<OSPF::RouterLSA*> (justAddedVertex);
01362             if (routerVertex->getV_VirtualLinkEndpoint ()) {    // (2)
01363                 transitCapability = true;
01364             }
01365 
01366             unsigned int linkCount = routerVertex->getLinksArraySize ();
01367             for (i = 0; i < linkCount; i++) {
01368                 Link&    link     = routerVertex->getLinks (i);
01369                 LinkType linkType = static_cast<LinkType> (link.getType ());
01370                 OSPFLSA* joiningVertex;
01371                 LSAType  joiningVertexType;
01372 
01373                 if (linkType == StubLink) {     // (2) (a)
01374                     continue;
01375                 }
01376 
01377                 if (linkType == TransitLink) {
01378                     joiningVertex     = FindNetworkLSA (link.getLinkID ().getInt ());
01379                     joiningVertexType = NetworkLSAType;
01380                 } else {
01381                     joiningVertex     = FindRouterLSA (link.getLinkID ().getInt ());
01382                     joiningVertexType = RouterLSAType;
01383                 }
01384 
01385                 if ((joiningVertex == NULL) ||
01386                     (joiningVertex->getHeader ().getLsAge () == MAX_AGE) ||
01387                     (!HasLink (joiningVertex, justAddedVertex)))  // (from, to)     (2) (b)
01388                 {
01389                     continue;
01390                 }
01391 
01392                 unsigned int treeSize      = treeVertices.size ();
01393                 bool         alreadyOnTree = false;
01394 
01395                 for (j = 0; j < treeSize; j++) {
01396                     if (treeVertices[j] == joiningVertex) {
01397                         alreadyOnTree = true;
01398                         break;
01399                     }
01400                 }
01401                 if (alreadyOnTree) {    // (2) (c)
01402                     continue;
01403                 }
01404 
01405                 unsigned long linkStateCost  = routerVertex->GetDistance () + link.getLinkCost ();
01406                 unsigned int  candidateCount = candidateVertices.size ();
01407                 OSPFLSA*      candidate      = NULL;
01408 
01409                 for (j = 0; j < candidateCount; j++) {
01410                     if (candidateVertices[j] == joiningVertex) {
01411                         candidate = candidateVertices[j];
01412                     }
01413                 }
01414                 if (candidate != NULL) {    // (2) (d)
01415                     OSPF::RoutingInfo* routingInfo       = check_and_cast<OSPF::RoutingInfo*> (candidate);
01416                     unsigned long      candidateDistance = routingInfo->GetDistance ();
01417 
01418                     if (linkStateCost > candidateDistance) {
01419                         continue;
01420                     }
01421                     if (linkStateCost < candidateDistance) {
01422                         routingInfo->SetDistance (linkStateCost);
01423                         routingInfo->ClearNextHops ();
01424                     }
01425                     std::vector<OSPF::NextHop>* newNextHops = CalculateNextHops (joiningVertex, justAddedVertex); // (destination, parent)
01426                     unsigned int nextHopCount = newNextHops->size ();
01427                     for (k = 0; k < nextHopCount; k++) {
01428                         routingInfo->AddNextHop ((*newNextHops)[k]);
01429                     }
01430                     delete newNextHops;
01431                 } else {
01432                     if (joiningVertexType == RouterLSAType) {
01433                         OSPF::RouterLSA* joiningRouterVertex = check_and_cast<OSPF::RouterLSA*> (joiningVertex);
01434                         joiningRouterVertex->SetDistance (linkStateCost);
01435                         std::vector<OSPF::NextHop>* newNextHops = CalculateNextHops (joiningVertex, justAddedVertex); // (destination, parent)
01436                         unsigned int nextHopCount = newNextHops->size ();
01437                         for (k = 0; k < nextHopCount; k++) {
01438                             joiningRouterVertex->AddNextHop ((*newNextHops)[k]);
01439                         }
01440                         delete newNextHops;
01441                         OSPF::RoutingInfo* vertexRoutingInfo = check_and_cast<OSPF::RoutingInfo*> (joiningRouterVertex);
01442                         vertexRoutingInfo->SetParent (justAddedVertex);
01443 
01444                         candidateVertices.push_back (joiningRouterVertex);
01445                     } else {
01446                         OSPF::NetworkLSA* joiningNetworkVertex = check_and_cast<OSPF::NetworkLSA*> (joiningVertex);
01447                         joiningNetworkVertex->SetDistance (linkStateCost);
01448                         std::vector<OSPF::NextHop>* newNextHops = CalculateNextHops (joiningVertex, justAddedVertex); // (destination, parent)
01449                         unsigned int nextHopCount = newNextHops->size ();
01450                         for (k = 0; k < nextHopCount; k++) {
01451                             joiningNetworkVertex->AddNextHop ((*newNextHops)[k]);
01452                         }
01453                         delete newNextHops;
01454                         OSPF::RoutingInfo* vertexRoutingInfo = check_and_cast<OSPF::RoutingInfo*> (joiningNetworkVertex);
01455                         vertexRoutingInfo->SetParent (justAddedVertex);
01456 
01457                         candidateVertices.push_back (joiningNetworkVertex);
01458                     }
01459                 }
01460             }
01461         }
01462 
01463         if ((vertexType == NetworkLSAType)) {
01464             OSPF::NetworkLSA* networkVertex = check_and_cast<OSPF::NetworkLSA*> (justAddedVertex);
01465             unsigned int      routerCount   = networkVertex->getAttachedRoutersArraySize ();
01466 
01467             for (i = 0; i < routerCount; i++) {     // (2)
01468                 OSPF::RouterLSA* joiningVertex = FindRouterLSA (networkVertex->getAttachedRouters (i).getInt ());
01469                 if ((joiningVertex == NULL) ||
01470                     (joiningVertex->getHeader ().getLsAge () == MAX_AGE) ||
01471                     (!HasLink (joiningVertex, justAddedVertex)))  // (from, to)     (2) (b)
01472                 {
01473                     continue;
01474                 }
01475 
01476                 unsigned int treeSize      = treeVertices.size ();
01477                 bool         alreadyOnTree = false;
01478 
01479                 for (j = 0; j < treeSize; j++) {
01480                     if (treeVertices[j] == joiningVertex) {
01481                         alreadyOnTree = true;
01482                         break;
01483                     }
01484                 }
01485                 if (alreadyOnTree) {    // (2) (c)
01486                     continue;
01487                 }
01488 
01489                 unsigned long linkStateCost  = networkVertex->GetDistance ();   // link cost from network to router is always 0
01490                 unsigned int  candidateCount = candidateVertices.size ();
01491                 OSPFLSA*      candidate      = NULL;
01492 
01493                 for (j = 0; j < candidateCount; j++) {
01494                     if (candidateVertices[j] == joiningVertex) {
01495                         candidate = candidateVertices[j];
01496                     }
01497                 }
01498                 if (candidate != NULL) {    // (2) (d)
01499                     OSPF::RoutingInfo* routingInfo       = check_and_cast<OSPF::RoutingInfo*> (candidate);
01500                     unsigned long      candidateDistance = routingInfo->GetDistance ();
01501 
01502                     if (linkStateCost > candidateDistance) {
01503                         continue;
01504                     }
01505                     if (linkStateCost < candidateDistance) {
01506                         routingInfo->SetDistance (linkStateCost);
01507                         routingInfo->ClearNextHops ();
01508                     }
01509                     std::vector<OSPF::NextHop>* newNextHops = CalculateNextHops (joiningVertex, justAddedVertex); // (destination, parent)
01510                     unsigned int nextHopCount = newNextHops->size ();
01511                     for (k = 0; k < nextHopCount; k++) {
01512                         routingInfo->AddNextHop ((*newNextHops)[k]);
01513                     }
01514                     delete newNextHops;
01515                 } else {
01516                     joiningVertex->SetDistance (linkStateCost);
01517                     std::vector<OSPF::NextHop>* newNextHops = CalculateNextHops (joiningVertex, justAddedVertex); // (destination, parent)
01518                     unsigned int nextHopCount = newNextHops->size ();
01519                     for (k = 0; k < nextHopCount; k++) {
01520                         joiningVertex->AddNextHop ((*newNextHops)[k]);
01521                     }
01522                     delete newNextHops;
01523                     OSPF::RoutingInfo* vertexRoutingInfo = check_and_cast<OSPF::RoutingInfo*> (joiningVertex);
01524                     vertexRoutingInfo->SetParent (justAddedVertex);
01525 
01526                     candidateVertices.push_back (joiningVertex);
01527                 }
01528             }
01529         }
01530 
01531         if (candidateVertices.empty ()) {  // (3)
01532             finished = true;
01533         } else {
01534             unsigned int  candidateCount = candidateVertices.size ();
01535             unsigned long minDistance = LS_INFINITY;
01536             OSPFLSA*      closestVertex = candidateVertices[0];
01537 
01538             for (i = 0; i < candidateCount; i++) {
01539                 OSPF::RoutingInfo* routingInfo     = check_and_cast<OSPF::RoutingInfo*> (candidateVertices[i]);
01540                 unsigned long      currentDistance = routingInfo->GetDistance ();
01541 
01542                 if (currentDistance < minDistance) {
01543                     closestVertex = candidateVertices[i];
01544                     minDistance = currentDistance;
01545                 } else {
01546                     if (currentDistance == minDistance) {
01547                         if ((closestVertex->getHeader ().getLsType () == RouterLSAType) &&
01548                             (candidateVertices[i]->getHeader ().getLsType () == NetworkLSAType))
01549                         {
01550                             closestVertex = candidateVertices[i];
01551                         }
01552                     }
01553                 }
01554             }
01555 
01556             treeVertices.push_back (closestVertex);
01557 
01558             for (std::vector<OSPFLSA*>::iterator it = candidateVertices.begin (); it != candidateVertices.end (); it++) {
01559                 if ((*it) == closestVertex) {
01560                     candidateVertices.erase (it);
01561                     break;
01562                 }
01563             }
01564 
01565             if (closestVertex->getHeader ().getLsType () == RouterLSAType) {
01566                 OSPF::RouterLSA* routerLSA = check_and_cast<OSPF::RouterLSA*> (closestVertex);
01567                 if (routerLSA->getB_AreaBorderRouter () || routerLSA->getE_ASBoundaryRouter ()) {
01568                     OSPF::RoutingTableEntry*                        entry           = new OSPF::RoutingTableEntry;
01569                     OSPF::RouterID                                  destinationID   = routerLSA->getHeader ().getLinkStateID ();
01570                     unsigned int                                    nextHopCount    = routerLSA->GetNextHopCount ();
01571                     OSPF::RoutingTableEntry::RoutingDestinationType destinationType = OSPF::RoutingTableEntry::NetworkDestination;
01572 
01573                     entry->SetDestinationID (destinationID);
01574                     entry->SetLinkStateOrigin (routerLSA);
01575                     entry->SetArea (areaID);
01576                     entry->SetPathType (OSPF::RoutingTableEntry::IntraArea);
01577                     entry->SetCost (routerLSA->GetDistance ());
01578                     if (routerLSA->getB_AreaBorderRouter ()) {
01579                         destinationType |= OSPF::RoutingTableEntry::AreaBorderRouterDestination;
01580                     }
01581                     if (routerLSA->getE_ASBoundaryRouter ()) {
01582                         destinationType |= OSPF::RoutingTableEntry::ASBoundaryRouterDestination;
01583                     }
01584                     entry->SetDestinationType (destinationType);
01585                     entry->SetOptionalCapabilities (routerLSA->getHeader ().getLsOptions ());
01586                     for (i = 0; i < nextHopCount; i++) {
01587                         entry->AddNextHop (routerLSA->GetNextHop (i));
01588                     }
01589 
01590                     newRoutingTable.push_back (entry);
01591 
01592                     OSPF::Area* backbone;
01593                     if (areaID != OSPF::BackboneAreaID) {
01594                         backbone = parentRouter->GetArea (OSPF::BackboneAreaID);
01595                     } else {
01596                         backbone = this;
01597                     }
01598                     if (backbone != NULL) {
01599                         OSPF::Interface* virtualIntf = backbone->FindVirtualLink (destinationID);
01600                         if ((virtualIntf != NULL) && (virtualIntf->GetAreaID () == areaID)) {
01601                             OSPF::IPv4AddressRange range;
01602                             range.address = GetInterface (routerLSA->GetNextHop (0).ifIndex)->GetAddressRange ().address;
01603                             range.mask    = IPv4AddressFromULong (0xFFFFFFFF);
01604                             virtualIntf->SetAddressRange (range);
01605                             virtualIntf->SetIfIndex (routerLSA->GetNextHop (0).ifIndex);
01606                             OSPF::Neighbor* virtualNeighbor = virtualIntf->GetNeighbor (0);
01607                             if (virtualNeighbor != NULL) {
01608                                 unsigned int     linkCount   = routerLSA->getLinksArraySize ();
01609                                 OSPF::RouterLSA* toRouterLSA = dynamic_cast<OSPF::RouterLSA*> (justAddedVertex);
01610                                 if (toRouterLSA != NULL) {
01611                                     for (i = 0; i < linkCount; i++) {
01612                                         Link& link = routerLSA->getLinks (i);
01613 
01614                                         if ((link.getType () == PointToPointLink) &&
01615                                             (link.getLinkID () == toRouterLSA->getHeader ().getLinkStateID ()))
01616                                         {
01617                                             virtualNeighbor->SetAddress (IPv4AddressFromULong (link.getLinkData ()));
01618                                             virtualIntf->ProcessEvent (OSPF::Interface::InterfaceUp);
01619                                             break;
01620                                         }
01621                                     }
01622                                 } else {
01623                                     OSPF::NetworkLSA* toNetworkLSA = dynamic_cast<OSPF::NetworkLSA*> (justAddedVertex);
01624                                     if (toNetworkLSA != NULL) {
01625                                         for (i = 0; i < linkCount; i++) {
01626                                             Link& link = routerLSA->getLinks (i);
01627 
01628                                             if ((link.getType () == TransitLink) &&
01629                                                 (link.getLinkID () == toNetworkLSA->getHeader ().getLinkStateID ()))
01630                                             {
01631                                                 virtualNeighbor->SetAddress (IPv4AddressFromULong (link.getLinkData ()));
01632                                                 virtualIntf->ProcessEvent (OSPF::Interface::InterfaceUp);
01633                                                 break;
01634                                             }
01635                                         }
01636                                     }
01637                                 }
01638                             }
01639                         }
01640                     }
01641                 }
01642             }
01643 
01644             if (closestVertex->getHeader ().getLsType () == NetworkLSAType) {
01645                 OSPF::NetworkLSA*        networkLSA    = check_and_cast<OSPF::NetworkLSA*> (closestVertex);
01646                 unsigned long            destinationID = (networkLSA->getHeader().getLinkStateID () & networkLSA->getNetworkMask ().getInt ());
01647                 unsigned int             nextHopCount  = networkLSA->GetNextHopCount ();
01648                 bool                     overWrite     = false;
01649                 OSPF::RoutingTableEntry* entry         = NULL;
01650                 unsigned long            routeCount    = newRoutingTable.size ();
01651                 unsigned long            longestMatch  = 0;
01652 
01653                 for (i = 0; i < routeCount; i++) {
01654                     if (newRoutingTable[i]->GetDestinationType () == OSPF::RoutingTableEntry::NetworkDestination) {
01655                         OSPF::RoutingTableEntry* routingEntry = newRoutingTable[i];
01656                         unsigned long            entryAddress = routingEntry->GetDestinationID ().getInt ();
01657                         unsigned long            entryMask    = routingEntry->GetAddressMask ().getInt ();
01658 
01659                         if ((entryAddress & entryMask) == (destinationID & entryMask)) {
01660                             if ((destinationID & entryMask) > longestMatch) {
01661                                 longestMatch = (destinationID & entryMask);
01662                                 entry        = routingEntry;
01663                             }
01664                         }
01665                     }
01666                 }
01667                 if (entry != NULL) {
01668                     const OSPFLSA* entryOrigin = entry->GetLinkStateOrigin ();
01669                     if ((entry->GetCost () != networkLSA->GetDistance ()) ||
01670                         (entryOrigin->getHeader ().getLinkStateID () >= networkLSA->getHeader().getLinkStateID ()))
01671                     {
01672                         overWrite = true;
01673                     }
01674                 }
01675 
01676                 if ((entry == NULL) || (overWrite)) {
01677                     if (entry == NULL) {
01678                         entry = new OSPF::RoutingTableEntry;
01679                     }
01680 
01681                     entry->SetDestinationID (destinationID);
01682                     entry->SetAddressMask (networkLSA->getNetworkMask ());
01683                     entry->SetLinkStateOrigin (networkLSA);
01684                     entry->SetArea (areaID);
01685                     entry->SetPathType (OSPF::RoutingTableEntry::IntraArea);
01686                     entry->SetCost (networkLSA->GetDistance ());
01687                     entry->SetDestinationType (OSPF::RoutingTableEntry::NetworkDestination);
01688                     entry->SetOptionalCapabilities (networkLSA->getHeader ().getLsOptions ());
01689                     for (i = 0; i < nextHopCount; i++) {
01690                         entry->AddNextHop (networkLSA->GetNextHop (i));
01691                     }
01692 
01693                     if (!overWrite) {
01694                         newRoutingTable.push_back (entry);
01695                     }
01696                 }
01697             }
01698 
01699             justAddedVertex = closestVertex;
01700         }
01701     } while (!finished);
01702 
01703     unsigned int treeSize      = treeVertices.size ();
01704     for (i = 0; i < treeSize; i++) {
01705         OSPF::RouterLSA* routerVertex = dynamic_cast<OSPF::RouterLSA*> (treeVertices[i]);
01706         if (routerVertex == NULL) {
01707             continue;
01708         }
01709 
01710         unsigned int linkCount = routerVertex->getLinksArraySize ();
01711         for (j = 0; j < linkCount; j++) {
01712             Link&    link     = routerVertex->getLinks (j);
01713             if (link.getType () != StubLink) {
01714                 continue;
01715             }
01716 
01717             unsigned long            distance      = routerVertex->GetDistance () + link.getLinkCost ();
01718             unsigned long            destinationID = (link.getLinkID ().getInt () & link.getLinkData ());
01719             OSPF::RoutingTableEntry* entry         = NULL;
01720             unsigned long            routeCount    = newRoutingTable.size ();
01721             unsigned long            longestMatch  = 0;
01722 
01723             for (k = 0; k < routeCount; k++) {
01724                 if (newRoutingTable[k]->GetDestinationType () == OSPF::RoutingTableEntry::NetworkDestination) {
01725                     OSPF::RoutingTableEntry* routingEntry = newRoutingTable[k];
01726                     unsigned long            entryAddress = routingEntry->GetDestinationID ().getInt ();
01727                     unsigned long            entryMask    = routingEntry->GetAddressMask ().getInt ();
01728 
01729                     if ((entryAddress & entryMask) == (destinationID & entryMask)) {
01730                         if ((destinationID & entryMask) > longestMatch) {
01731                             longestMatch = (destinationID & entryMask);
01732                             entry        = routingEntry;
01733                         }
01734                     }
01735                 }
01736             }
01737 
01738             if (entry != NULL) {
01739                 Metric entryCost = entry->GetCost ();
01740 
01741                 if (distance > entryCost) {
01742                     continue;
01743                 }
01744                 if (distance < entryCost) {
01745                     //FIXME remove
01746                     //if (parentRouter->GetRouterID () == 0xC0A80302) {
01747                     //    EV << "CHEAPER STUB LINK FOUND TO " << IPAddress (destinationID).str () << "\n";
01748                     //}
01749                     entry->SetCost (distance);
01750                     entry->ClearNextHops ();
01751                     entry->SetLinkStateOrigin (routerVertex);
01752                 }
01753                 if (distance == entryCost) {
01754                     // no const version from check_and_cast
01755                     OSPF::RouterLSA* routerOrigin = check_and_cast<OSPF::RouterLSA*> (const_cast<OSPFLSA*> (entry->GetLinkStateOrigin ()));
01756                     if (routerOrigin->getHeader ().getLinkStateID () < routerVertex->getHeader ().getLinkStateID ()) {
01757                         entry->SetLinkStateOrigin (routerVertex);
01758                     }
01759                 }
01760                 std::vector<OSPF::NextHop>* newNextHops = CalculateNextHops (link, routerVertex); // (destination, parent)
01761                 unsigned int nextHopCount = newNextHops->size ();
01762                 for (k = 0; k < nextHopCount; k++) {
01763                     entry->AddNextHop ((*newNextHops)[k]);
01764                 }
01765                 delete newNextHops;
01766             } else {
01767                 //FIXME remove
01768                 //if (parentRouter->GetRouterID () == 0xC0A80302) {
01769                 //    EV << "STUB LINK FOUND TO " << IPAddress (destinationID).str () << "\n";
01770                 //}
01771                 entry = new OSPF::RoutingTableEntry;
01772 
01773                 entry->SetDestinationID (destinationID);
01774                 entry->SetAddressMask (link.getLinkData ());
01775                 entry->SetLinkStateOrigin (routerVertex);
01776                 entry->SetArea (areaID);
01777                 entry->SetPathType (OSPF::RoutingTableEntry::IntraArea);
01778                 entry->SetCost (distance);
01779                 entry->SetDestinationType (OSPF::RoutingTableEntry::NetworkDestination);
01780                 entry->SetOptionalCapabilities (routerVertex->getHeader ().getLsOptions ());
01781                 std::vector<OSPF::NextHop>* newNextHops = CalculateNextHops (link, routerVertex); // (destination, parent)
01782                 unsigned int nextHopCount = newNextHops->size ();
01783                 for (k = 0; k < nextHopCount; k++) {
01784                     entry->AddNextHop ((*newNextHops)[k]);
01785                 }
01786                 delete newNextHops;
01787 
01788                 newRoutingTable.push_back (entry);
01789             }
01790         }
01791     }
01792 }

bool OSPF::Area::ContainsAddress IPv4Address  address  )  const
 

00101 {
00102     int addressRangeNum = areaAddressRanges.size ();
00103     for (int i = 0; i < addressRangeNum; i++) {
00104         if ((areaAddressRanges[i].address & areaAddressRanges[i].mask) == (address & areaAddressRanges[i].mask)) {
00105             return true;
00106         }
00107     }
00108     return false;
00109 }

OSPF::RoutingTableEntry * OSPF::Area::CreateRoutingTableEntryFromSummaryLSA const OSPF::SummaryLSA summaryLSA,
unsigned short  entryCost,
const OSPF::RoutingTableEntry borderRouterEntry
const [private]
 

Returns a new RoutingTableEntry based on the input SummaryLSA, with the input cost and the borderRouterEntry's next hops.

02147 {
02148     OSPF::IPv4AddressRange destination;
02149 
02150     destination.address = IPv4AddressFromULong (summaryLSA.getHeader ().getLinkStateID ());
02151     destination.mask    = IPv4AddressFromULong (summaryLSA.getNetworkMask ().getInt ());
02152 
02153     OSPF::RoutingTableEntry* newEntry = new OSPF::RoutingTableEntry;
02154 
02155     if (summaryLSA.getHeader ().getLsType () == SummaryLSA_NetworksType) {
02156         newEntry->SetDestinationID (ULongFromIPv4Address (destination.address & destination.mask));
02157         newEntry->SetAddressMask (ULongFromIPv4Address (destination.mask));
02158         newEntry->SetDestinationType (OSPF::RoutingTableEntry::NetworkDestination);
02159     } else {
02160         newEntry->SetDestinationID (ULongFromIPv4Address (destination.address));
02161         newEntry->SetAddressMask (0xFFFFFFFF);
02162         newEntry->SetDestinationType (OSPF::RoutingTableEntry::ASBoundaryRouterDestination);
02163     }
02164     newEntry->SetArea (areaID);
02165     newEntry->SetPathType (OSPF::RoutingTableEntry::InterArea);
02166     newEntry->SetCost (entryCost);
02167     newEntry->SetOptionalCapabilities (summaryLSA.getHeader ().getLsOptions ());
02168     newEntry->SetLinkStateOrigin (&summaryLSA);
02169 
02170     unsigned int nextHopCount = borderRouterEntry.GetNextHopCount ();
02171     for (unsigned int j = 0; j < nextHopCount; j++) {
02172         newEntry->AddNextHop (borderRouterEntry.GetNextHop (j));
02173     }
02174 
02175     return newEntry;
02176 }

std::string OSPF::Area::detailedInfo void   )  const
 

00056 {
00057     std::stringstream out;
00058     char addressString[16];
00059     int i;
00060     out << "\n    areaID: " << AddressStringFromULong (addressString, 16, areaID) << ", ";
00061     out << "transitCapability: " << (transitCapability ? "true" : "false") << ", ";
00062     out << "externalRoutingCapability: " << (externalRoutingCapability ? "true" : "false") << ", ";
00063     out << "stubDefaultCost: " << stubDefaultCost << "\n";
00064     int addressRangeNum = areaAddressRanges.size ();
00065     for (i = 0; i < addressRangeNum; i++) {
00066         out << "    addressRanges[" << i << "]: ";
00067         out << AddressStringFromIPv4Address (addressString, 16, areaAddressRanges[i].address);
00068         out << "/" << AddressStringFromIPv4Address (addressString, 16, areaAddressRanges[i].mask) << "\n";
00069     }
00070     int interfaceNum = associatedInterfaces.size ();
00071     for (i = 0; i < interfaceNum; i++) {
00072         out << "    interface[" << i << "]: addressRange: ";
00073         out << AddressStringFromIPv4Address (addressString, 16, associatedInterfaces[i]->GetAddressRange ().address);
00074         out << "/" << AddressStringFromIPv4Address (addressString, 16, associatedInterfaces[i]->GetAddressRange ().mask) << "\n";
00075     }
00076 
00077     out << "\n";
00078     out << "    Database:\n";
00079     out << "      RouterLSAs:\n";
00080     long lsaCount = routerLSAs.size ();
00081     for (i = 0; i < lsaCount; i++) {
00082         out << "        " << *routerLSAs[i] << "\n";
00083     }
00084     out << "      NetworkLSAs:\n";
00085     lsaCount = networkLSAs.size ();
00086     for (i = 0; i < lsaCount; i++) {
00087         out << "        " << *networkLSAs[i] << "\n";
00088     }
00089     out << "      SummaryLSAs:\n";
00090     lsaCount = summaryLSAs.size ();
00091     for (i = 0; i < lsaCount; i++) {
00092         out << "        " << *summaryLSAs[i] << "\n";
00093     }
00094 
00095     out << "--------------------------------------------------------------------------------";
00096 
00097     return out.str();
00098 }

const OSPF::NetworkLSA * OSPF::Area::FindNetworkLSA LinkStateID  linkStateID  )  const
 

00298 {
00299     std::map<OSPF::LinkStateID, OSPF::NetworkLSA*>::const_iterator lsaIt = networkLSAsByID.find (linkStateID);
00300     if (lsaIt != networkLSAsByID.end ()) {
00301         return lsaIt->second;
00302     } else {
00303         return NULL;
00304     }
00305 }

OSPF::NetworkLSA * OSPF::Area::FindNetworkLSA LinkStateID  linkStateID  ) 
 

00288 {
00289     std::map<OSPF::LinkStateID, OSPF::NetworkLSA*>::iterator lsaIt = networkLSAsByID.find (linkStateID);
00290     if (lsaIt != networkLSAsByID.end ()) {
00291         return lsaIt->second;
00292     } else {
00293         return NULL;
00294     }
00295 }

const OSPF::RouterLSA * OSPF::Area::FindRouterLSA LinkStateID  linkStateID  )  const
 

00278 {
00279     std::map<OSPF::LinkStateID, OSPF::RouterLSA*>::const_iterator lsaIt = routerLSAsByID.find (linkStateID);
00280     if (lsaIt != routerLSAsByID.end ()) {
00281         return lsaIt->second;
00282     } else {
00283         return NULL;
00284     }
00285 }

OSPF::RouterLSA * OSPF::Area::FindRouterLSA LinkStateID  linkStateID  ) 
 

00268 {
00269     std::map<OSPF::LinkStateID, OSPF::RouterLSA*>::iterator lsaIt = routerLSAsByID.find (linkStateID);
00270     if (lsaIt != routerLSAsByID.end ()) {
00271         return lsaIt->second;
00272     } else {
00273         return NULL;
00274     }
00275 }

bool OSPF::Area::FindSameOrWorseCostRoute const std::vector< OSPF::RoutingTableEntry * > &  newRoutingTable,
const OSPF::SummaryLSA summaryLSA,
unsigned short  currentCost,
bool &  destinationInRoutingTable,
std::list< OSPF::RoutingTableEntry * > &  sameOrWorseCost
const [private]
 

Browse through the newRoutingTable looking for entries describing the same destination as the currentLSA. If a cheaper route is found then skip this LSA (return true), else note those which are of equal or worse cost than the currentCost.

02086 {
02087     destinationInRoutingTable = false;
02088     sameOrWorseCost.clear ();
02089 
02090     long                   routeCount = newRoutingTable.size ();
02091     OSPF::IPv4AddressRange destination;
02092 
02093     destination.address = IPv4AddressFromULong (summaryLSA.getHeader ().getLinkStateID ());
02094     destination.mask    = IPv4AddressFromULong (summaryLSA.getNetworkMask ().getInt ());
02095 
02096     for (long j = 0; j < routeCount; j++) {
02097         OSPF::RoutingTableEntry* routingEntry  = newRoutingTable[j];
02098         bool                     foundMatching = false;
02099 
02100         if (summaryLSA.getHeader ().getLsType () == SummaryLSA_NetworksType) {
02101             if ((routingEntry->GetDestinationType () == OSPF::RoutingTableEntry::NetworkDestination) &&
02102                 (ULongFromIPv4Address (destination.address & destination.mask) == routingEntry->GetDestinationID ().getInt ()))
02103             {
02104                 foundMatching = true;
02105             }
02106         } else {
02107             if ((((routingEntry->GetDestinationType () & OSPF::RoutingTableEntry::AreaBorderRouterDestination) != 0) ||
02108                  ((routingEntry->GetDestinationType () & OSPF::RoutingTableEntry::ASBoundaryRouterDestination) != 0)) &&
02109                 (ULongFromIPv4Address (destination.address) == routingEntry->GetDestinationID ().getInt ()))
02110             {
02111                 foundMatching = true;
02112             }
02113         }
02114 
02115         if (foundMatching) {
02116             destinationInRoutingTable = true;
02117 
02118             /* If the matching entry is an IntraArea route (intra-area paths are
02119                 * always preferred to other paths of any cost), or it's a cheaper InterArea
02120                 * route, then skip this LSA.
02121                 */
02122             if ((routingEntry->GetPathType () == OSPF::RoutingTableEntry::IntraArea) ||
02123                 ((routingEntry->GetPathType () == OSPF::RoutingTableEntry::InterArea) &&
02124                  (routingEntry->GetCost () < currentCost)))
02125             {
02126                 return true;
02127             } else {
02128                 // if it's an other InterArea path
02129                 if ((routingEntry->GetPathType () == OSPF::RoutingTableEntry::InterArea) &&
02130                     (routingEntry->GetCost () >= currentCost))
02131                 {
02132                     sameOrWorseCost.push_back (routingEntry);
02133                 }   // else it's external -> same as if not in the table
02134             }
02135         }
02136     }
02137     return false;
02138 }

const OSPF::SummaryLSA * OSPF::Area::FindSummaryLSA LSAKeyType  lsaKey  )  const
 

00318 {
00319     std::map<OSPF::LSAKeyType, OSPF::SummaryLSA*, OSPF::LSAKeyType_Less>::const_iterator lsaIt = summaryLSAsByID.find (lsaKey);
00320     if (lsaIt != summaryLSAsByID.end ()) {
00321         return lsaIt->second;
00322     } else {
00323         return NULL;
00324     }
00325 }

OSPF::SummaryLSA * OSPF::Area::FindSummaryLSA LSAKeyType  lsaKey  ) 
 

00308 {
00309     std::map<OSPF::LSAKeyType, OSPF::SummaryLSA*, OSPF::LSAKeyType_Less>::iterator lsaIt = summaryLSAsByID.find (lsaKey);
00310     if (lsaIt != summaryLSAsByID.end ()) {
00311         return lsaIt->second;
00312     } else {
00313         return NULL;
00314     }
00315 }

OSPF::Interface * OSPF::Area::FindVirtualLink RouterID  routerID  ) 
 

00191 {
00192     int interfaceNum = associatedInterfaces.size ();
00193     for (int i = 0; i < interfaceNum; i++) {
00194         if ((associatedInterfaces[i]->GetType () == OSPF::Interface::Virtual) &&
00195             (associatedInterfaces[i]->GetNeighborByID (routerID) != NULL))
00196         {
00197             return associatedInterfaces[i];
00198         }
00199     }
00200     return NULL;
00201 }

bool OSPF::Area::FloodLSA OSPFLSA *  lsa,
Interface intf = NULL,
Neighbor neighbor = NULL
 

00650 {
00651     bool floodedBackOut  = false;
00652     long interfaceCount = associatedInterfaces.size ();
00653 
00654     for (long i = 0; i < interfaceCount; i++) {
00655         if (associatedInterfaces[i]->FloodLSA (lsa, intf, neighbor)) {
00656             floodedBackOut = true;
00657         }
00658     }
00659 
00660     return floodedBackOut;
00661 }

IPv4AddressRange OSPF::Area::GetAddressRange unsigned int  index  )  const [inline]
 

00042 { return areaAddressRanges[index]; }

unsigned int OSPF::Area::GetAddressRangeCount void   )  const [inline]
 

00041 { return areaAddressRanges.size (); }

AreaID OSPF::Area::GetAreaID void   )  const [inline]
 

00039 { return areaID; }

OSPF::IPv4AddressRange OSPF::Area::GetContainingAddressRange IPv4AddressRange  addressRange,
bool *  advertise = NULL
const
 

00125 {
00126     int addressRangeNum = areaAddressRanges.size ();
00127     for (int i = 0; i < addressRangeNum; i++) {
00128         if ((areaAddressRanges[i].address & areaAddressRanges[i].mask) == (addressRange.address & areaAddressRanges[i].mask)) {
00129             if (advertise != NULL) {
00130                 std::map<OSPF::IPv4AddressRange, bool, OSPF::IPv4AddressRange_Less>::const_iterator rangeIt = advertiseAddressRanges.find (areaAddressRanges[i]);
00131                 if (rangeIt != advertiseAddressRanges.end ()) {
00132                     *advertise = rangeIt->second;
00133                 } else {
00134                     *advertise = true;
00135                 }
00136             }
00137             return areaAddressRanges[i];
00138         }
00139     }
00140     if (advertise != NULL) {
00141         *advertise =  false;
00142     }
00143     return NullIPv4AddressRange;
00144 }

bool OSPF::Area::GetExternalRoutingCapability void   )  const [inline]
 

00047 { return externalRoutingCapability; }

OSPF::Interface * OSPF::Area::GetInterface IPv4Address  address  ) 
 

00160 {
00161     int interfaceNum = associatedInterfaces.size ();
00162     for (int i = 0; i < interfaceNum; i++) {
00163         if ((associatedInterfaces[i]->GetType () != OSPF::Interface::Virtual) &&
00164             (associatedInterfaces[i]->GetAddressRange ().address == address))
00165         {
00166             return associatedInterfaces[i];
00167         }
00168     }
00169     return NULL;
00170 }

OSPF::Interface * OSPF::Area::GetInterface unsigned char  ifIndex  ) 
 

00147 {
00148     int interfaceNum = associatedInterfaces.size ();
00149     for (int i = 0; i < interfaceNum; i++) {
00150         if ((associatedInterfaces[i]->GetType () != OSPF::Interface::Virtual) &&
00151             (associatedInterfaces[i]->GetIfIndex () == ifIndex))
00152         {
00153             return associatedInterfaces[i];
00154         }
00155     }
00156     return NULL;
00157 }

const NetworkLSA* OSPF::Area::GetNetworkLSA unsigned long  i  )  const [inline]
 

00063 { return networkLSAs[i]; }

NetworkLSA* OSPF::Area::GetNetworkLSA unsigned long  i  )  [inline]
 

00062 { return networkLSAs[i]; }

unsigned long OSPF::Area::GetNetworkLSACount void   )  const [inline]
 

00061 { return networkLSAs.size (); }

const Router* OSPF::Area::GetRouter void   )  const [inline]
 

00056 { return parentRouter; }

Router* OSPF::Area::GetRouter void   )  [inline]
 

00055 { return parentRouter; }

const RouterLSA* OSPF::Area::GetRouterLSA unsigned long  i  )  const [inline]
 

00060 { return routerLSAs[i]; }

RouterLSA* OSPF::Area::GetRouterLSA unsigned long  i  )  [inline]
 

00059 { return routerLSAs[i]; }

unsigned long OSPF::Area::GetRouterLSACount void   )  const [inline]
 

00058 { return routerLSAs.size (); }

const RouterLSA* OSPF::Area::GetSPFTreeRoot void   )  const [inline]
 

00052 { return spfTreeRoot; }

RouterLSA* OSPF::Area::GetSPFTreeRoot void   )  [inline]
 

00051 { return spfTreeRoot; }

Metric OSPF::Area::GetStubDefaultCost void   )  const [inline]
 

00049 { return stubDefaultCost; }

const SummaryLSA* OSPF::Area::GetSummaryLSA unsigned long  i  )  const [inline]
 

00066 { return summaryLSAs[i]; }

SummaryLSA* OSPF::Area::GetSummaryLSA unsigned long  i  )  [inline]
 

00065 { return summaryLSAs[i]; }

unsigned long OSPF::Area::GetSummaryLSACount void   )  const [inline]
 

00064 { return summaryLSAs.size (); }

bool OSPF::Area::GetTransitCapability void   )  const [inline]
 

00045 { return transitCapability; }

OSPF::LinkStateID OSPF::Area::GetUniqueLinkStateID OSPF::IPv4AddressRange  destination,
OSPF::Metric  destinationCost,
OSPF::SummaryLSA *&  lsaToReoriginate
const [private]
 

Returns a link state ID for the input destination. If this router hasn't originated a Summary LSA for the input destination then the function returs the destination address as link state ID. If it has originated a Summary LSA for the input destination then the function checks which LSA would contain the longer netmask. If the two masks are equal then this means thet we're updating an LSA already in the database, so the function returns the destination address as link state ID. If the input destination netmask is longer then the one already in the database, then the returned link state ID is the input destination address ORed together with the inverse of the input destination mask. If the input destination netmask is shorter, then the Summary LSA already in the database has to be replaced by the current destination. In this case the lsaToReoriginate parameter is filled with a copy of the Summary LSA in the database with it's mask replaced by the destination mask and the cost replaced by the input destination cost; the returned link state ID is the input destination address ORed together with the inverse of the mask stored in the Summary LSA in the database. This means that if the lsaToReoriginate parameter is not NULL on return then another lookup in the database is needed with the same LSAKey as used here (input destination address and the router's own routerID) and the resulting Summary LSA's link state ID should be changed to the one returned by this function.

00978 {
00979     if (lsaToReoriginate != NULL) {
00980         delete lsaToReoriginate;
00981         lsaToReoriginate = NULL;
00982     }
00983 
00984     OSPF::LSAKeyType lsaKey;
00985 
00986     lsaKey.linkStateID = ULongFromIPv4Address (destination.address);
00987     lsaKey.advertisingRouter = parentRouter->GetRouterID ();
00988 
00989     const OSPF::SummaryLSA* foundLSA = FindSummaryLSA (lsaKey);
00990 
00991     if (foundLSA == NULL) {
00992         return lsaKey.linkStateID;
00993     } else {
00994         OSPF::IPv4Address existingMask = IPv4AddressFromULong (foundLSA->getNetworkMask ().getInt ());
00995 
00996         if (destination.mask == existingMask) {
00997             return lsaKey.linkStateID;
00998         } else {
00999             if (destination.mask >= existingMask) {
01000                 return (lsaKey.linkStateID | (~(ULongFromIPv4Address (destination.mask))));
01001             } else {
01002                 OSPF::SummaryLSA* summaryLSA = new OSPF::SummaryLSA (*foundLSA);
01003 
01004                 long sequenceNumber = summaryLSA->getHeader ().getLsSequenceNumber ();
01005 
01006                 summaryLSA->getHeader ().setLsAge (0);
01007                 summaryLSA->getHeader ().setLsSequenceNumber ((sequenceNumber == MAX_SEQUENCE_NUMBER) ? INITIAL_SEQUENCE_NUMBER : sequenceNumber + 1);
01008                 summaryLSA->setNetworkMask (ULongFromIPv4Address (destination.mask));
01009                 summaryLSA->setRouteCost (destinationCost);
01010                 summaryLSA->getHeader ().setLsChecksum (0);    // TODO: calculate correct LS checksum
01011 
01012                 lsaToReoriginate = summaryLSA;
01013 
01014                 return (lsaKey.linkStateID | (~(ULongFromIPv4Address (existingMask))));
01015             }
01016         }
01017     }
01018 }

bool OSPF::Area::HasAddressRange IPv4AddressRange  addressRange  )  const
 

00112 {
00113     int addressRangeNum = areaAddressRanges.size ();
00114     for (int i = 0; i < addressRangeNum; i++) {
00115         if ((areaAddressRanges[i].address == addressRange.address) &&
00116             (areaAddressRanges[i].mask == addressRange.mask))
00117         {
00118             return true;
00119         }
00120     }
00121     return false;
00122 }

bool OSPF::Area::HasLink OSPFLSA *  fromLSA,
OSPFLSA *  toLSA
const [private]
 

02020 {
02021     unsigned int i;
02022 
02023     OSPF::RouterLSA* fromRouterLSA = dynamic_cast<OSPF::RouterLSA*> (fromLSA);
02024     if (fromRouterLSA != NULL) {
02025         unsigned int     linkCount   = fromRouterLSA->getLinksArraySize ();
02026         OSPF::RouterLSA* toRouterLSA = dynamic_cast<OSPF::RouterLSA*> (toLSA);
02027         if (toRouterLSA != NULL) {
02028             for (i = 0; i < linkCount; i++) {
02029                 Link&    link     = fromRouterLSA->getLinks (i);
02030                 LinkType linkType = static_cast<LinkType> (link.getType ());
02031 
02032                 if (((linkType == PointToPointLink) ||
02033                      (linkType == VirtualLink)) &&
02034                     (link.getLinkID ().getInt () == toRouterLSA->getHeader ().getLinkStateID ()))
02035                 {
02036                     return true;
02037                 }
02038             }
02039         } else {
02040             OSPF::NetworkLSA* toNetworkLSA = dynamic_cast<OSPF::NetworkLSA*> (toLSA);
02041             if (toNetworkLSA != NULL) {
02042                 for (i = 0; i < linkCount; i++) {
02043                     Link&    link     = fromRouterLSA->getLinks (i);
02044 
02045                     if ((link.getType () == TransitLink) &&
02046                         (link.getLinkID ().getInt () == toNetworkLSA->getHeader ().getLinkStateID ()))
02047                     {
02048                         return true;
02049                     }
02050                     if ((link.getType () == StubLink) &&
02051                         ((link.getLinkID ().getInt () & link.getLinkData ()) == (toNetworkLSA->getHeader ().getLinkStateID () & toNetworkLSA->getNetworkMask ().getInt ())))
02052                     {
02053                         return true;
02054                     }
02055                 }
02056             }
02057         }
02058     } else {
02059         OSPF::NetworkLSA* fromNetworkLSA = dynamic_cast<OSPF::NetworkLSA*> (fromLSA);
02060         if (fromNetworkLSA != NULL) {
02061             unsigned int     routerCount   = fromNetworkLSA->getAttachedRoutersArraySize ();
02062             OSPF::RouterLSA* toRouterLSA = dynamic_cast<OSPF::RouterLSA*> (toLSA);
02063             if (toRouterLSA != NULL) {
02064                 for (i = 0; i < routerCount; i++) {
02065                     if (fromNetworkLSA->getAttachedRouters (i).getInt () == toRouterLSA->getHeader ().getLinkStateID ()) {
02066                         return true;
02067                     }
02068                 }
02069             }
02070         }
02071     }
02072 
02073     return false;
02074 }

bool OSPF::Area::HasVirtualLink AreaID  withTransitArea  )  const
 

00173 {
00174     if ((areaID != OSPF::BackboneAreaID) || (withTransitArea == OSPF::BackboneAreaID)) {
00175         return false;
00176     }
00177 
00178     int interfaceNum = associatedInterfaces.size ();
00179     for (int i = 0; i < interfaceNum; i++) {
00180         if ((associatedInterfaces[i]->GetType () == OSPF::Interface::Virtual) &&
00181             (associatedInterfaces[i]->GetAreaID () == withTransitArea))
00182         {
00183             return true;
00184         }
00185     }
00186     return false;
00187 }

void OSPF::Area::info char *  buffer  ) 
 

00048 {
00049     std::stringstream out;
00050     char areaString[16];
00051     out << "areaID: " << AddressStringFromULong (areaString, 16, areaID);
00052     strcpy(buffer, out.str().c_str());
00053 }

bool OSPF::Area::InstallNetworkLSA OSPFNetworkLSA *  lsa  ) 
 

00224 {
00225     OSPF::LinkStateID linkStateID = lsa->getHeader ().getLinkStateID ();
00226     std::map<OSPF::LinkStateID, OSPF::NetworkLSA*>::iterator lsaIt = networkLSAsByID.find (linkStateID);
00227     if (lsaIt != networkLSAsByID.end ()) {
00228         OSPF::LSAKeyType lsaKey;
00229 
00230         lsaKey.linkStateID = lsa->getHeader ().getLinkStateID ();
00231         lsaKey.advertisingRouter = lsa->getHeader ().getAdvertisingRouter ().getInt ();
00232 
00233         RemoveFromAllRetransmissionLists (lsaKey);
00234         return lsaIt->second->Update (lsa);
00235     } else {
00236         OSPF::NetworkLSA* lsaCopy = new OSPF::NetworkLSA (*lsa);
00237         networkLSAsByID[linkStateID] = lsaCopy;
00238         networkLSAs.push_back (lsaCopy);
00239         return true;
00240     }
00241 }

bool OSPF::Area::InstallRouterLSA OSPFRouterLSA *  lsa  ) 
 

00204 {
00205     OSPF::LinkStateID linkStateID = lsa->getHeader ().getLinkStateID ();
00206     std::map<OSPF::LinkStateID, OSPF::RouterLSA*>::iterator lsaIt = routerLSAsByID.find (linkStateID);
00207     if (lsaIt != routerLSAsByID.end ()) {
00208         OSPF::LSAKeyType lsaKey;
00209 
00210         lsaKey.linkStateID = lsa->getHeader ().getLinkStateID ();
00211         lsaKey.advertisingRouter = lsa->getHeader ().getAdvertisingRouter ().getInt ();
00212 
00213         RemoveFromAllRetransmissionLists (lsaKey);
00214         return lsaIt->second->Update (lsa);
00215     } else {
00216         OSPF::RouterLSA* lsaCopy = new OSPF::RouterLSA (*lsa);
00217         routerLSAsByID[linkStateID] = lsaCopy;
00218         routerLSAs.push_back (lsaCopy);
00219         return true;
00220     }
00221 }

bool OSPF::Area::InstallSummaryLSA OSPFSummaryLSA *  lsa  ) 
 

00244 {
00245     OSPF::LSAKeyType lsaKey;
00246 
00247     lsaKey.linkStateID = lsa->getHeader ().getLinkStateID ();
00248     lsaKey.advertisingRouter = lsa->getHeader ().getAdvertisingRouter ().getInt ();
00249 
00250     std::map<OSPF::LSAKeyType, OSPF::SummaryLSA*, OSPF::LSAKeyType_Less>::iterator lsaIt = summaryLSAsByID.find (lsaKey);
00251     if (lsaIt != summaryLSAsByID.end ()) {
00252         OSPF::LSAKeyType lsaKey;
00253 
00254         lsaKey.linkStateID = lsa->getHeader ().getLinkStateID ();
00255         lsaKey.advertisingRouter = lsa->getHeader ().getAdvertisingRouter ().getInt ();
00256 
00257         RemoveFromAllRetransmissionLists (lsaKey);
00258         return lsaIt->second->Update (lsa);
00259     } else {
00260         OSPF::SummaryLSA* lsaCopy = new OSPF::SummaryLSA (*lsa);
00261         summaryLSAsByID[lsaKey] = lsaCopy;
00262         summaryLSAs.push_back (lsaCopy);
00263         return true;
00264     }
00265 }

bool OSPF::Area::IsLocalAddress IPv4Address  address  )  const
 

00664 {
00665     long interfaceCount = associatedInterfaces.size ();
00666     for (long i = 0; i < interfaceCount; i++) {
00667         if (associatedInterfaces[i]->GetAddressRange ().address == address) {
00668             return true;
00669         }
00670     }
00671     return false;
00672 }

bool OSPF::Area::IsOnAnyRetransmissionList LSAKeyType  lsaKey  )  const
 

00639 {
00640     long interfaceCount = associatedInterfaces.size ();
00641     for (long i = 0; i < interfaceCount; i++) {
00642         if (associatedInterfaces[i]->IsOnAnyRetransmissionList (lsaKey)) {
00643             return true;
00644         }
00645     }
00646     return false;
00647 }

OSPF::NetworkLSA * OSPF::Area::OriginateNetworkLSA const Interface intf  ) 
 

00916 {
00917     if (intf->AnyNeighborInStates (OSPF::Neighbor::FullState)) {
00918         OSPF::NetworkLSA* networkLSA      = new OSPF::NetworkLSA;
00919         OSPFLSAHeader&   lsaHeader        = networkLSA->getHeader ();
00920         long             neighborCount    = intf->GetNeighborCount ();
00921         OSPFOptions      lsOptions;
00922 
00923         lsaHeader.setLsAge (0);
00924         memset (&lsOptions, 0, sizeof (OSPFOptions));
00925         lsOptions.E_ExternalRoutingCapability = externalRoutingCapability;
00926         lsaHeader.setLsOptions (lsOptions);
00927         lsaHeader.setLsType (NetworkLSAType);
00928         lsaHeader.setLinkStateID (ULongFromIPv4Address (intf->GetAddressRange ().address));
00929         lsaHeader.setAdvertisingRouter (parentRouter->GetRouterID ());
00930         lsaHeader.setLsSequenceNumber (INITIAL_SEQUENCE_NUMBER);
00931 
00932         networkLSA->setNetworkMask (ULongFromIPv4Address (intf->GetAddressRange ().mask));
00933 
00934         for (long j = 0; j < neighborCount; j++) {
00935             const OSPF::Neighbor* neighbor = intf->GetNeighbor (j);
00936             if (neighbor->GetState () == OSPF::Neighbor::FullState) {
00937                 unsigned short netIndex = networkLSA->getAttachedRoutersArraySize ();
00938                 networkLSA->setAttachedRoutersArraySize (netIndex + 1);
00939                 networkLSA->setAttachedRouters (netIndex, neighbor->GetNeighborID ());
00940             }
00941         }
00942         unsigned short netIndex = networkLSA->getAttachedRoutersArraySize ();
00943         networkLSA->setAttachedRoutersArraySize (netIndex + 1);
00944         networkLSA->setAttachedRouters (netIndex, parentRouter->GetRouterID ());
00945 
00946         lsaHeader.setLsChecksum (0);    // TODO: calculate correct LS checksum
00947 
00948         return networkLSA;
00949     } else {
00950         return NULL;
00951     }
00952 }

OSPF::RouterLSA * OSPF::Area::OriginateRouterLSA void   ) 
 

00675 {
00676     OSPF::RouterLSA* routerLSA      = new OSPF::RouterLSA;
00677     OSPFLSAHeader&   lsaHeader      = routerLSA->getHeader ();
00678     long             interfaceCount = associatedInterfaces.size ();
00679     OSPFOptions      lsOptions;
00680     long             i;
00681 
00682     lsaHeader.setLsAge (0);
00683     memset (&lsOptions, 0, sizeof (OSPFOptions));
00684     lsOptions.E_ExternalRoutingCapability = externalRoutingCapability;
00685     lsaHeader.setLsOptions (lsOptions);
00686     lsaHeader.setLsType (RouterLSAType);
00687     lsaHeader.setLinkStateID (parentRouter->GetRouterID ());
00688     lsaHeader.setAdvertisingRouter (parentRouter->GetRouterID ());
00689     lsaHeader.setLsSequenceNumber (INITIAL_SEQUENCE_NUMBER);
00690 
00691     routerLSA->setB_AreaBorderRouter (parentRouter->GetAreaCount () > 1);
00692     routerLSA->setE_ASBoundaryRouter ((externalRoutingCapability && parentRouter->GetASBoundaryRouter ()) ? true : false);
00693     OSPF::Area* backbone = parentRouter->GetArea (OSPF::BackboneAreaID);
00694     routerLSA->setV_VirtualLinkEndpoint ((backbone == NULL) ? false : backbone->HasVirtualLink (areaID));
00695 
00696     routerLSA->setNumberOfLinks (0);
00697     routerLSA->setLinksArraySize (0);
00698     for (i = 0; i < interfaceCount; i++) {
00699         OSPF::Interface* intf = associatedInterfaces[i];
00700 
00701         if (intf->GetState () == OSPF::Interface::DownState) {
00702             continue;
00703         }
00704         if ((intf->GetState () == OSPF::Interface::LoopbackState) &&
00705             ((intf->GetType () != OSPF::Interface::PointToPoint) ||
00706              (intf->GetAddressRange ().address != OSPF::NullIPv4Address)))
00707         {
00708             Link stubLink;
00709             stubLink.setType (StubLink);
00710             stubLink.setLinkID (ULongFromIPv4Address (intf->GetAddressRange ().address));
00711             stubLink.setLinkData (0xFFFFFFFF);
00712             stubLink.setLinkCost (0);
00713             stubLink.setNumberOfTOS (0);
00714             stubLink.setTosDataArraySize (0);
00715 
00716             unsigned short linkIndex = routerLSA->getLinksArraySize ();
00717             routerLSA->setLinksArraySize (linkIndex + 1);
00718             routerLSA->setNumberOfLinks (linkIndex + 1);
00719             routerLSA->setLinks (linkIndex, stubLink);
00720         }
00721         if (intf->GetState () > OSPF::Interface::LoopbackState) {
00722             switch (intf->GetType ()) {
00723                 case OSPF::Interface::PointToPoint:
00724                     {
00725                         OSPF::Neighbor* neighbor = (intf->GetNeighborCount () > 0) ? intf->GetNeighbor (0) : NULL;
00726                         if (neighbor != NULL) {
00727                             if (neighbor->GetState () == OSPF::Neighbor::FullState) {
00728                                 Link link;
00729                                 link.setType (PointToPointLink);
00730                                 link.setLinkID (neighbor->GetNeighborID ());
00731                                 if (intf->GetAddressRange ().address != OSPF::NullIPv4Address) {
00732                                     link.setLinkData (ULongFromIPv4Address (intf->GetAddressRange ().address));
00733                                 } else {
00734                                     link.setLinkData (intf->GetIfIndex ());
00735                                 }
00736                                 link.setLinkCost (intf->GetOutputCost ());
00737                                 link.setNumberOfTOS (0);
00738                                 link.setTosDataArraySize (0);
00739 
00740                                 unsigned short linkIndex = routerLSA->getLinksArraySize ();
00741                                 routerLSA->setLinksArraySize (linkIndex + 1);
00742                                 routerLSA->setNumberOfLinks (linkIndex + 1);
00743                                 routerLSA->setLinks (linkIndex, link);
00744                             }
00745                             if (intf->GetState () == OSPF::Interface::PointToPointState) {
00746                                 if (neighbor->GetAddress () != OSPF::NullIPv4Address) {
00747                                     Link stubLink;
00748                                     stubLink.setType (StubLink);
00749                                     stubLink.setLinkID (ULongFromIPv4Address (neighbor->GetAddress ()));
00750                                     stubLink.setLinkData (0xFFFFFFFF);
00751                                     stubLink.setLinkCost (intf->GetOutputCost ());
00752                                     stubLink.setNumberOfTOS (0);
00753                                     stubLink.setTosDataArraySize (0);
00754 
00755                                     unsigned short linkIndex = routerLSA->getLinksArraySize ();
00756                                     routerLSA->setLinksArraySize (linkIndex + 1);
00757                                     routerLSA->setNumberOfLinks (linkIndex + 1);
00758                                     routerLSA->setLinks (linkIndex, stubLink);
00759                                 } else {
00760                                     if (ULongFromIPv4Address (intf->GetAddressRange ().mask) != 0xFFFFFFFF) {
00761                                         Link stubLink;
00762                                         stubLink.setType (StubLink);
00763                                         stubLink.setLinkID (ULongFromIPv4Address (intf->GetAddressRange ().address &
00764                                                                                   intf->GetAddressRange ().mask));
00765                                         stubLink.setLinkData (ULongFromIPv4Address (intf->GetAddressRange ().mask));
00766                                         stubLink.setLinkCost (intf->GetOutputCost ());
00767                                         stubLink.setNumberOfTOS (0);
00768                                         stubLink.setTosDataArraySize (0);
00769 
00770                                         unsigned short linkIndex = routerLSA->getLinksArraySize ();
00771                                         routerLSA->setLinksArraySize (linkIndex + 1);
00772                                         routerLSA->setNumberOfLinks (linkIndex + 1);
00773                                         routerLSA->setLinks (linkIndex, stubLink);
00774                                     }
00775                                 }
00776                             }
00777                         }
00778                     }
00779                     break;
00780                 case OSPF::Interface::Broadcast:
00781                 case OSPF::Interface::NBMA:
00782                     {
00783                         if (intf->GetState () == OSPF::Interface::WaitingState) {
00784                             Link stubLink;
00785                             stubLink.setType (StubLink);
00786                             stubLink.setLinkID (ULongFromIPv4Address (intf->GetAddressRange ().address &
00787                                                                       intf->GetAddressRange ().mask));
00788                             stubLink.setLinkData (ULongFromIPv4Address (intf->GetAddressRange ().mask));
00789                             stubLink.setLinkCost (intf->GetOutputCost ());
00790                             stubLink.setNumberOfTOS (0);
00791                             stubLink.setTosDataArraySize (0);
00792 
00793                             unsigned short linkIndex = routerLSA->getLinksArraySize ();
00794                             routerLSA->setLinksArraySize (linkIndex + 1);
00795                             routerLSA->setNumberOfLinks (linkIndex + 1);
00796                             routerLSA->setLinks (linkIndex, stubLink);
00797                         } else {
00798                             OSPF::Neighbor* dRouter = intf->GetNeighborByAddress (intf->GetDesignatedRouter ().ipInterfaceAddress);
00799                             if (((dRouter != NULL) && (dRouter->GetState () == OSPF::Neighbor::FullState)) ||
00800                                 ((intf->GetDesignatedRouter ().routerID == parentRouter->GetRouterID ()) &&
00801                                  (intf->AnyNeighborInStates (OSPF::Neighbor::FullState))))
00802                             {
00803                                 Link link;
00804                                 link.setType (TransitLink);
00805                                 link.setLinkID (ULongFromIPv4Address (intf->GetDesignatedRouter ().ipInterfaceAddress));
00806                                 link.setLinkData (ULongFromIPv4Address (intf->GetAddressRange ().address));
00807                                 link.setLinkCost (intf->GetOutputCost ());
00808                                 link.setNumberOfTOS (0);
00809                                 link.setTosDataArraySize (0);
00810 
00811                                 unsigned short linkIndex = routerLSA->getLinksArraySize ();
00812                                 routerLSA->setLinksArraySize (linkIndex + 1);
00813                                 routerLSA->setNumberOfLinks (linkIndex + 1);
00814                                 routerLSA->setLinks (linkIndex, link);
00815                             } else {
00816                                 Link stubLink;
00817                                 stubLink.setType (StubLink);
00818                                 stubLink.setLinkID (ULongFromIPv4Address (intf->GetAddressRange ().address &
00819                                                                           intf->GetAddressRange ().mask));
00820                                 stubLink.setLinkData (ULongFromIPv4Address (intf->GetAddressRange ().mask));
00821                                 stubLink.setLinkCost (intf->GetOutputCost ());
00822                                 stubLink.setNumberOfTOS (0);
00823                                 stubLink.setTosDataArraySize (0);
00824 
00825                                 unsigned short linkIndex = routerLSA->getLinksArraySize ();
00826                                 routerLSA->setLinksArraySize (linkIndex + 1);
00827                                 routerLSA->setNumberOfLinks (linkIndex + 1);
00828                                 routerLSA->setLinks (linkIndex, stubLink);
00829                             }
00830                         }
00831                     }
00832                     break;
00833                 case OSPF::Interface::Virtual:
00834                     {
00835                         OSPF::Neighbor* neighbor = (intf->GetNeighborCount () > 0) ? intf->GetNeighbor (0) : NULL;
00836                         if ((neighbor != NULL) && (neighbor->GetState () == OSPF::Neighbor::FullState)) {
00837                             Link link;
00838                             link.setType (VirtualLink);
00839                             link.setLinkID (neighbor->GetNeighborID ());
00840                             link.setLinkData (ULongFromIPv4Address (intf->GetAddressRange ().address));
00841                             link.setLinkCost (intf->GetOutputCost ());
00842                             link.setNumberOfTOS (0);
00843                             link.setTosDataArraySize (0);
00844 
00845                             unsigned short linkIndex = routerLSA->getLinksArraySize ();
00846                             routerLSA->setLinksArraySize (linkIndex + 1);
00847                             routerLSA->setNumberOfLinks (linkIndex + 1);
00848                             routerLSA->setLinks (linkIndex, link);
00849                         }
00850                     }
00851                     break;
00852                 case OSPF::Interface::PointToMultiPoint:
00853                     {
00854                         Link stubLink;
00855                         stubLink.setType (StubLink);
00856                         stubLink.setLinkID (ULongFromIPv4Address (intf->GetAddressRange ().address));
00857                         stubLink.setLinkData (0xFFFFFFFF);
00858                         stubLink.setLinkCost (0);
00859                         stubLink.setNumberOfTOS (0);
00860                         stubLink.setTosDataArraySize (0);
00861 
00862                         unsigned short linkIndex = routerLSA->getLinksArraySize ();
00863                         routerLSA->setLinksArraySize (linkIndex + 1);
00864                         routerLSA->setNumberOfLinks (linkIndex + 1);
00865                         routerLSA->setLinks (linkIndex, stubLink);
00866 
00867                         long neighborCount = intf->GetNeighborCount ();
00868                         for (long i = 0; i < neighborCount; i++) {
00869                             OSPF::Neighbor* neighbor = intf->GetNeighbor (i);
00870                             if (neighbor->GetState () == OSPF::Neighbor::FullState) {
00871                                 Link link;
00872                                 link.setType (PointToPointLink);
00873                                 link.setLinkID (neighbor->GetNeighborID ());
00874                                 link.setLinkData (ULongFromIPv4Address (intf->GetAddressRange ().address));
00875                                 link.setLinkCost (intf->GetOutputCost ());
00876                                 link.setNumberOfTOS (0);
00877                                 link.setTosDataArraySize (0);
00878 
00879                                 unsigned short linkIndex = routerLSA->getLinksArraySize ();
00880                                 routerLSA->setLinksArraySize (linkIndex + 1);
00881                                 routerLSA->setNumberOfLinks (linkIndex + 1);
00882                                 routerLSA->setLinks (linkIndex, stubLink);
00883                             }
00884                         }
00885                     }
00886                     break;
00887                 default: break;
00888             }
00889         }
00890     }
00891 
00892     long hostRouteCount = hostRoutes.size ();
00893     for (i = 0; i < hostRouteCount; i++) {
00894         Link stubLink;
00895         stubLink.setType (StubLink);
00896         stubLink.setLinkID (ULongFromIPv4Address (hostRoutes[i].address));
00897         stubLink.setLinkData (0xFFFFFFFF);
00898         stubLink.setLinkCost (hostRoutes[i].linkCost);
00899         stubLink.setNumberOfTOS (0);
00900         stubLink.setTosDataArraySize (0);
00901 
00902         unsigned short linkIndex = routerLSA->getLinksArraySize ();
00903         routerLSA->setLinksArraySize (linkIndex + 1);
00904         routerLSA->setNumberOfLinks (linkIndex + 1);
00905         routerLSA->setLinks (linkIndex, stubLink);
00906     }
00907 
00908     lsaHeader.setLsChecksum (0);    // TODO: calculate correct LS checksum
00909 
00910     routerLSA->SetSource (OSPF::LSATrackingInfo::Originated);
00911 
00912     return routerLSA;
00913 }

OSPF::SummaryLSA * OSPF::Area::OriginateSummaryLSA const OSPF::SummaryLSA summaryLSA  )  [private]
 

01279 {
01280     const std::map<OSPF::LSAKeyType, bool, OSPF::LSAKeyType_Less> emptyMap;
01281     OSPF::SummaryLSA*                                             dontReoriginate = NULL;
01282 
01283     const OSPFLSAHeader& lsaHeader   = summaryLSA->getHeader ();
01284     unsigned long   entryCount = parentRouter->GetRoutingTableEntryCount ();
01285 
01286     for (unsigned long i = 0; i < entryCount; i++) {
01287         const OSPF::RoutingTableEntry* entry = parentRouter->GetRoutingTableEntry (i);
01288 
01289         if ((lsaHeader.getLsType () == SummaryLSA_ASBoundaryRoutersType) &&
01290             ((((entry->GetDestinationType () & OSPF::RoutingTableEntry::AreaBorderRouterDestination) != 0) ||
01291               ((entry->GetDestinationType () & OSPF::RoutingTableEntry::ASBoundaryRouterDestination) != 0)) &&
01292              ((entry->GetDestinationID ().getInt () == lsaHeader.getLinkStateID ()) &&
01293               (entry->GetAddressMask () == summaryLSA->getNetworkMask ()))))
01294         {
01295             OSPF::SummaryLSA* returnLSA = OriginateSummaryLSA (entry, emptyMap, dontReoriginate);
01296             if (dontReoriginate != NULL) {
01297                 delete dontReoriginate;
01298             }
01299             return returnLSA;
01300         }
01301 
01302         unsigned long lsaMask = summaryLSA->getNetworkMask ().getInt ();
01303 
01304         if ((lsaHeader.getLsType () == SummaryLSA_NetworksType) &&
01305             (entry->GetDestinationType () == OSPF::RoutingTableEntry::NetworkDestination) &&
01306             (entry->GetAddressMask ().getInt () == lsaMask) &&
01307             (entry->GetDestinationID ().getInt () & lsaMask == lsaHeader.getLinkStateID () & lsaMask))
01308         {
01309             OSPF::SummaryLSA* returnLSA = OriginateSummaryLSA (entry, emptyMap, dontReoriginate);
01310             if (dontReoriginate != NULL) {
01311                 delete dontReoriginate;
01312             }
01313             return returnLSA;
01314         }
01315     }
01316 
01317     return NULL;
01318 }

OSPF::SummaryLSA * OSPF::Area::OriginateSummaryLSA const RoutingTableEntry entry,
const std::map< LSAKeyType, bool, LSAKeyType_Less > &  originatedLSAs,
SummaryLSA *&  lsaToReoriginate
 

01023 {
01024     if (((entry->GetDestinationType () & OSPF::RoutingTableEntry::AreaBorderRouterDestination) != 0) ||
01025         (entry->GetPathType () == OSPF::RoutingTableEntry::Type1External) ||
01026         (entry->GetPathType () == OSPF::RoutingTableEntry::Type2External) ||
01027         (entry->GetArea () == areaID))
01028     {
01029         return NULL;
01030     }
01031 
01032     bool         allNextHopsInThisArea = true;
01033     unsigned int nextHopCount          = entry->GetNextHopCount ();
01034 
01035     for (unsigned int i = 0; i < nextHopCount; i++) {
01036         OSPF::Interface* nextHopInterface = parentRouter->GetNonVirtualInterface (entry->GetNextHop (i).ifIndex);
01037         if ((nextHopInterface != NULL) && (nextHopInterface->GetAreaID () != areaID)) {
01038             allNextHopsInThisArea = false;
01039             break;
01040         }
01041     }
01042     if ((allNextHopsInThisArea) || (entry->GetCost () >= LS_INFINITY)){
01043         return NULL;
01044     }
01045 
01046     if ((entry->GetDestinationType () & OSPF::RoutingTableEntry::ASBoundaryRouterDestination) != 0) {
01047         OSPF::RoutingTableEntry* preferredEntry = parentRouter->GetPreferredEntry (*(entry->GetLinkStateOrigin ()), false);
01048         if ((preferredEntry != NULL) && (*preferredEntry == *entry) && (externalRoutingCapability)) {
01049             OSPF::SummaryLSA* summaryLSA    = new OSPF::SummaryLSA;
01050             OSPFLSAHeader&    lsaHeader     = summaryLSA->getHeader ();
01051             OSPFOptions       lsOptions;
01052 
01053             lsaHeader.setLsAge (0);
01054             memset (&lsOptions, 0, sizeof (OSPFOptions));
01055             lsOptions.E_ExternalRoutingCapability = externalRoutingCapability;
01056             lsaHeader.setLsOptions (lsOptions);
01057             lsaHeader.setLsType (SummaryLSA_ASBoundaryRoutersType);
01058             lsaHeader.setLinkStateID (entry->GetDestinationID ().getInt ());
01059             lsaHeader.setAdvertisingRouter (parentRouter->GetRouterID ());
01060             lsaHeader.setLsSequenceNumber (INITIAL_SEQUENCE_NUMBER);
01061 
01062             summaryLSA->setNetworkMask (entry->GetAddressMask ());
01063             summaryLSA->setRouteCost (entry->GetCost ());
01064             summaryLSA->setTosDataArraySize (0);
01065 
01066             lsaHeader.setLsChecksum (0);    // TODO: calculate correct LS checksum
01067 
01068             summaryLSA->SetSource (OSPF::LSATrackingInfo::Originated);
01069 
01070             return summaryLSA;
01071         }
01072     } else {    // entry->GetDestinationType () == OSPF::RoutingTableEntry::NetworkDestination
01073         if (entry->GetPathType () == OSPF::RoutingTableEntry::InterArea) {
01074             OSPF::IPv4AddressRange destinationRange;
01075 
01076             destinationRange.address = IPv4AddressFromULong (entry->GetDestinationID ().getInt ());
01077             destinationRange.mask = IPv4AddressFromULong (entry->GetAddressMask ().getInt ());
01078 
01079             OSPF::LinkStateID newLinkStateID = GetUniqueLinkStateID (destinationRange, entry->GetCost (), lsaToReoriginate);
01080 
01081             if (lsaToReoriginate != NULL) {
01082                 OSPF::LSAKeyType lsaKey;
01083 
01084                 lsaKey.linkStateID = entry->GetDestinationID ().getInt ();
01085                 lsaKey.advertisingRouter = parentRouter->GetRouterID ();
01086 
01087                 std::map<OSPF::LSAKeyType, OSPF::SummaryLSA*, OSPF::LSAKeyType_Less>::iterator lsaIt = summaryLSAsByID.find (lsaKey);
01088                 if (lsaIt == summaryLSAsByID.end ()) {
01089                     delete (lsaToReoriginate);
01090                     lsaToReoriginate = NULL;
01091                     return NULL;
01092                 } else {
01093                     OSPF::SummaryLSA* summaryLSA = new OSPF::SummaryLSA (*(lsaIt->second));
01094                     OSPFLSAHeader&    lsaHeader  = summaryLSA->getHeader ();
01095 
01096                     lsaHeader.setLsAge (0);
01097                     lsaHeader.setLsSequenceNumber (INITIAL_SEQUENCE_NUMBER);
01098                     lsaHeader.setLinkStateID (newLinkStateID);
01099                     lsaHeader.setLsChecksum (0);    // TODO: calculate correct LS checksum
01100 
01101                     return summaryLSA;
01102                 }
01103             } else {
01104                 OSPF::SummaryLSA* summaryLSA    = new OSPF::SummaryLSA;
01105                 OSPFLSAHeader&    lsaHeader     = summaryLSA->getHeader ();
01106                 OSPFOptions       lsOptions;
01107 
01108                 lsaHeader.setLsAge (0);
01109                 memset (&lsOptions, 0, sizeof (OSPFOptions));
01110                 lsOptions.E_ExternalRoutingCapability = externalRoutingCapability;
01111                 lsaHeader.setLsOptions (lsOptions);
01112                 lsaHeader.setLsType (SummaryLSA_NetworksType);
01113                 lsaHeader.setLinkStateID (newLinkStateID);
01114                 lsaHeader.setAdvertisingRouter (parentRouter->GetRouterID ());
01115                 lsaHeader.setLsSequenceNumber (INITIAL_SEQUENCE_NUMBER);
01116 
01117                 summaryLSA->setNetworkMask (entry->GetAddressMask ());
01118                 summaryLSA->setRouteCost (entry->GetCost ());
01119                 summaryLSA->setTosDataArraySize (0);
01120 
01121                 lsaHeader.setLsChecksum (0);    // TODO: calculate correct LS checksum
01122 
01123                 summaryLSA->SetSource (OSPF::LSATrackingInfo::Originated);
01124 
01125                 return summaryLSA;
01126             }
01127         } else {    // entry->GetPathType () == OSPF::RoutingTableEntry::IntraArea
01128             OSPF::IPv4AddressRange destinationAddressRange;
01129 
01130             destinationAddressRange.address = IPv4AddressFromULong (entry->GetDestinationID ().getInt ());
01131             destinationAddressRange.mask = IPv4AddressFromULong (entry->GetAddressMask ().getInt ());
01132 
01133             bool doAdvertise = false;
01134             OSPF::IPv4AddressRange containingAddressRange = parentRouter->GetContainingAddressRange (destinationAddressRange, &doAdvertise);
01135             if (((entry->GetArea () == OSPF::BackboneAreaID) &&         // the backbone's configured ranges should be ignored
01136                  (transitCapability)) ||                                // when originating Summary LSAs into transit areas
01137                 (containingAddressRange == OSPF::NullIPv4AddressRange))
01138             {
01139                 OSPF::LinkStateID newLinkStateID = GetUniqueLinkStateID (destinationAddressRange, entry->GetCost (), lsaToReoriginate);
01140 
01141                 if (lsaToReoriginate != NULL) {
01142                     OSPF::LSAKeyType lsaKey;
01143 
01144                     lsaKey.linkStateID = entry->GetDestinationID ().getInt ();
01145                     lsaKey.advertisingRouter = parentRouter->GetRouterID ();
01146 
01147                     std::map<OSPF::LSAKeyType, OSPF::SummaryLSA*, OSPF::LSAKeyType_Less>::iterator lsaIt = summaryLSAsByID.find (lsaKey);
01148                     if (lsaIt == summaryLSAsByID.end ()) {
01149                         delete (lsaToReoriginate);
01150                         lsaToReoriginate = NULL;
01151                         return NULL;
01152                     } else {
01153                         OSPF::SummaryLSA* summaryLSA = new OSPF::SummaryLSA (*(lsaIt->second));
01154                         OSPFLSAHeader&    lsaHeader  = summaryLSA->getHeader ();
01155 
01156                         lsaHeader.setLsAge (0);
01157                         lsaHeader.setLsSequenceNumber (INITIAL_SEQUENCE_NUMBER);
01158                         lsaHeader.setLinkStateID (newLinkStateID);
01159                         lsaHeader.setLsChecksum (0);    // TODO: calculate correct LS checksum
01160 
01161                         return summaryLSA;
01162                     }
01163                 } else {
01164                     OSPF::SummaryLSA* summaryLSA    = new OSPF::SummaryLSA;
01165                     OSPFLSAHeader&    lsaHeader     = summaryLSA->getHeader ();
01166                     OSPFOptions       lsOptions;
01167 
01168                     lsaHeader.setLsAge (0);
01169                     memset (&lsOptions, 0, sizeof (OSPFOptions));
01170                     lsOptions.E_ExternalRoutingCapability = externalRoutingCapability;
01171                     lsaHeader.setLsOptions (lsOptions);
01172                     lsaHeader.setLsType (SummaryLSA_NetworksType);
01173                     lsaHeader.setLinkStateID (newLinkStateID);
01174                     lsaHeader.setAdvertisingRouter (parentRouter->GetRouterID ());
01175                     lsaHeader.setLsSequenceNumber (INITIAL_SEQUENCE_NUMBER);
01176 
01177                     summaryLSA->setNetworkMask (entry->GetAddressMask ());
01178                     summaryLSA->setRouteCost (entry->GetCost ());
01179                     summaryLSA->setTosDataArraySize (0);
01180 
01181                     lsaHeader.setLsChecksum (0);    // TODO: calculate correct LS checksum
01182 
01183                     summaryLSA->SetSource (OSPF::LSATrackingInfo::Originated);
01184 
01185                     return summaryLSA;
01186                 }
01187             } else {
01188                 if (doAdvertise) {
01189                     Metric        maxRangeCost = 0;
01190                     unsigned long entryCount   = parentRouter->GetRoutingTableEntryCount ();
01191 
01192                     for (unsigned long i = 0; i < entryCount; i++) {
01193                         const OSPF::RoutingTableEntry* routingEntry = parentRouter->GetRoutingTableEntry (i);
01194 
01195                         if ((routingEntry->GetDestinationType () == OSPF::RoutingTableEntry::NetworkDestination) &&
01196                             (routingEntry->GetPathType () == OSPF::RoutingTableEntry::IntraArea) &&
01197                             ((routingEntry->GetDestinationID ().getInt () & routingEntry->GetAddressMask ().getInt () & ULongFromIPv4Address (containingAddressRange.mask)) ==
01198                              ULongFromIPv4Address (containingAddressRange.address & containingAddressRange.mask)) &&
01199                             (routingEntry->GetCost () > maxRangeCost))
01200                         {
01201                             maxRangeCost = routingEntry->GetCost ();
01202                         }
01203                     }
01204 
01205                     OSPF::LinkStateID newLinkStateID = GetUniqueLinkStateID (containingAddressRange, maxRangeCost, lsaToReoriginate);
01206                     OSPF::LSAKeyType  lsaKey;
01207 
01208                     if (lsaToReoriginate != NULL) {
01209                         lsaKey.linkStateID = lsaToReoriginate->getHeader ().getLinkStateID ();
01210                         lsaKey.advertisingRouter = parentRouter->GetRouterID ();
01211 
01212                         std::map<OSPF::LSAKeyType, bool, OSPF::LSAKeyType_Less>::const_iterator originatedIt = originatedLSAs.find (lsaKey);
01213                         if (originatedIt != originatedLSAs.end ()) {
01214                             delete (lsaToReoriginate);
01215                             lsaToReoriginate = NULL;
01216                             return NULL;
01217                         }
01218 
01219                         lsaKey.linkStateID = entry->GetDestinationID ().getInt ();
01220                         lsaKey.advertisingRouter = parentRouter->GetRouterID ();
01221 
01222                         std::map<OSPF::LSAKeyType, OSPF::SummaryLSA*, OSPF::LSAKeyType_Less>::iterator lsaIt = summaryLSAsByID.find (lsaKey);
01223                         if (lsaIt == summaryLSAsByID.end ()) {
01224                             delete (lsaToReoriginate);
01225                             lsaToReoriginate = NULL;
01226                             return NULL;
01227                         }
01228 
01229                         OSPF::SummaryLSA* summaryLSA = new OSPF::SummaryLSA (*(lsaIt->second));
01230                         OSPFLSAHeader&    lsaHeader  = summaryLSA->getHeader ();
01231 
01232                         lsaHeader.setLsAge (0);
01233                         lsaHeader.setLsSequenceNumber (INITIAL_SEQUENCE_NUMBER);
01234                         lsaHeader.setLinkStateID (newLinkStateID);
01235                         lsaHeader.setLsChecksum (0);    // TODO: calculate correct LS checksum
01236 
01237                         return summaryLSA;
01238                     } else {
01239                         lsaKey.linkStateID = newLinkStateID;
01240                         lsaKey.advertisingRouter = parentRouter->GetRouterID ();
01241 
01242                         std::map<OSPF::LSAKeyType, bool, OSPF::LSAKeyType_Less>::const_iterator originatedIt = originatedLSAs.find (lsaKey);
01243                         if (originatedIt != originatedLSAs.end ()) {
01244                             return NULL;
01245                         }
01246 
01247                         OSPF::SummaryLSA* summaryLSA    = new OSPF::SummaryLSA;
01248                         OSPFLSAHeader&    lsaHeader     = summaryLSA->getHeader ();
01249                         OSPFOptions       lsOptions;
01250 
01251                         lsaHeader.setLsAge (0);
01252                         memset (&lsOptions, 0, sizeof (OSPFOptions));
01253                         lsOptions.E_ExternalRoutingCapability = externalRoutingCapability;
01254                         lsaHeader.setLsOptions (lsOptions);
01255                         lsaHeader.setLsType (SummaryLSA_NetworksType);
01256                         lsaHeader.setLinkStateID (newLinkStateID);
01257                         lsaHeader.setAdvertisingRouter (parentRouter->GetRouterID ());
01258                         lsaHeader.setLsSequenceNumber (INITIAL_SEQUENCE_NUMBER);
01259 
01260                         summaryLSA->setNetworkMask (entry->GetAddressMask ());
01261                         summaryLSA->setRouteCost (entry->GetCost ());
01262                         summaryLSA->setTosDataArraySize (0);
01263 
01264                         lsaHeader.setLsChecksum (0);    // TODO: calculate correct LS checksum
01265 
01266                         summaryLSA->SetSource (OSPF::LSATrackingInfo::Originated);
01267 
01268                         return summaryLSA;
01269                     }
01270                 }
01271             }
01272         }
01273     }
01274 
01275     return NULL;
01276 }

void OSPF::Area::ReCheckSummaryLSAs std::vector< RoutingTableEntry * > &  newRoutingTable  ) 
 

02313 {
02314     unsigned long i = 0;
02315     unsigned long j = 0;
02316     unsigned long lsaCount = summaryLSAs.size ();
02317 
02318     for (i = 0; i < lsaCount; i++) {
02319         OSPF::SummaryLSA* currentLSA        = summaryLSAs[i];
02320         OSPFLSAHeader&    currentHeader     = currentLSA->getHeader ();
02321 
02322         unsigned long     routeCost         = currentLSA->getRouteCost ();
02323         unsigned short    lsAge             = currentHeader.getLsAge ();
02324         RouterID          originatingRouter = currentHeader.getAdvertisingRouter ().getInt ();
02325         bool              selfOriginated    = (originatingRouter == parentRouter->GetRouterID ());
02326 
02327         if ((routeCost == LS_INFINITY) || (lsAge == MAX_AGE) || (selfOriginated)) { // (1) and (2)
02328             continue;
02329         }
02330 
02331         unsigned long            routeCount       = newRoutingTable.size ();
02332         char                     lsType           = currentHeader.getLsType ();
02333         OSPF::RoutingTableEntry* destinationEntry = NULL;
02334         OSPF::IPv4AddressRange   destination;
02335 
02336         destination.address = IPv4AddressFromULong (currentHeader.getLinkStateID ());
02337         destination.mask    = IPv4AddressFromULong (currentLSA->getNetworkMask ().getInt ());
02338 
02339         for (j = 0; j < routeCount; j++) {  // (3)
02340             OSPF::RoutingTableEntry* routingEntry  = newRoutingTable[j];
02341             bool                     foundMatching = false;
02342 
02343             if (lsType == SummaryLSA_NetworksType) {
02344                 if ((routingEntry->GetDestinationType () == OSPF::RoutingTableEntry::NetworkDestination) &&
02345                     (ULongFromIPv4Address (destination.address & destination.mask) == routingEntry->GetDestinationID ().getInt ()))
02346                 {
02347                     foundMatching = true;
02348                 }
02349             } else {
02350                 if ((((routingEntry->GetDestinationType () & OSPF::RoutingTableEntry::AreaBorderRouterDestination) != 0) ||
02351                      ((routingEntry->GetDestinationType () & OSPF::RoutingTableEntry::ASBoundaryRouterDestination) != 0)) &&
02352                     (ULongFromIPv4Address (destination.address) == routingEntry->GetDestinationID ().getInt ()))
02353                 {
02354                     foundMatching = true;
02355                 }
02356             }
02357 
02358             if (foundMatching) {
02359                 OSPF::RoutingTableEntry::RoutingPathType pathType = routingEntry->GetPathType ();
02360 
02361                 if ((pathType == OSPF::RoutingTableEntry::Type1External) ||
02362                     (pathType == OSPF::RoutingTableEntry::Type2External) ||
02363                     (routingEntry->GetArea () != OSPF::BackboneAreaID))
02364                 {
02365                     break;
02366                 } else {
02367                     destinationEntry = routingEntry;
02368                 }
02369             }
02370         }
02371         if (destinationEntry == NULL) {
02372             continue;
02373         }
02374 
02375         OSPF::RoutingTableEntry* borderRouterEntry = NULL;
02376         unsigned short           currentCost       = routeCost;
02377 
02378         for (j = 0; j < routeCount; j++) {     // (4) BR == borderRouterEntry
02379             OSPF::RoutingTableEntry* routingEntry = newRoutingTable[j];
02380 
02381             if ((routingEntry->GetArea () == areaID) &&
02382                 (((routingEntry->GetDestinationType () & OSPF::RoutingTableEntry::AreaBorderRouterDestination) != 0) ||
02383                  ((routingEntry->GetDestinationType () & OSPF::RoutingTableEntry::ASBoundaryRouterDestination) != 0)) &&
02384                 (routingEntry->GetDestinationID ().getInt () == originatingRouter))
02385             {
02386                 borderRouterEntry = routingEntry;
02387                 currentCost += borderRouterEntry->GetCost ();
02388                 break;
02389             }
02390         }
02391         if (borderRouterEntry == NULL) {
02392             continue;
02393         } else {    // (5)
02394             if (currentCost <= destinationEntry->GetCost ()) {
02395                 if (currentCost < destinationEntry->GetCost ()) {
02396                     destinationEntry->ClearNextHops ();
02397                 }
02398 
02399                 unsigned long nextHopCount = borderRouterEntry->GetNextHopCount ();
02400 
02401                 for (j = 0; j < nextHopCount; j++) {
02402                     destinationEntry->AddNextHop (borderRouterEntry->GetNextHop (j));
02403                 }
02404             }
02405         }
02406     }
02407 }

void OSPF::Area::RemoveFromAllRetransmissionLists LSAKeyType  lsaKey  ) 
 

00631 {
00632     long interfaceCount = associatedInterfaces.size ();
00633     for (long i = 0; i < interfaceCount; i++) {
00634         associatedInterfaces[i]->RemoveFromAllRetransmissionLists (lsaKey);
00635     }
00636 }

void OSPF::Area::SetAreaID AreaID  areaId  )  [inline]
 

00038 { areaID = areaId; }

void OSPF::Area::SetExternalRoutingCapability bool  flooded  )  [inline]
 

00046 { externalRoutingCapability = flooded; }

void OSPF::Area::SetRouter Router router  )  [inline]
 

00054 { parentRouter = router; }

void OSPF::Area::SetSPFTreeRoot RouterLSA root  )  [inline]
 

00050 { spfTreeRoot = root; }

void OSPF::Area::SetStubDefaultCost Metric  cost  )  [inline]
 

00048 { stubDefaultCost = cost; }

void OSPF::Area::SetTransitCapability bool  transit  )  [inline]
 

00044 { transitCapability = transit; }


Member Data Documentation

std::map<IPv4AddressRange, bool, IPv4AddressRange_Less> OSPF::Area::advertiseAddressRanges [private]
 

std::vector<IPv4AddressRange> OSPF::Area::areaAddressRanges [private]
 

AreaID OSPF::Area::areaID [private]
 

std::vector<Interface*> OSPF::Area::associatedInterfaces [private]
 

bool OSPF::Area::externalRoutingCapability [private]
 

std::vector<HostRouteParameters> OSPF::Area::hostRoutes [private]
 

std::vector<NetworkLSA*> OSPF::Area::networkLSAs [private]
 

std::map<LinkStateID, NetworkLSA*> OSPF::Area::networkLSAsByID [private]
 

Router* OSPF::Area::parentRouter [private]
 

std::vector<RouterLSA*> OSPF::Area::routerLSAs [private]
 

std::map<LinkStateID, RouterLSA*> OSPF::Area::routerLSAsByID [private]
 

RouterLSA* OSPF::Area::spfTreeRoot [private]
 

Metric OSPF::Area::stubDefaultCost [private]
 

std::vector<SummaryLSA*> OSPF::Area::summaryLSAs [private]
 

std::map<LSAKeyType, SummaryLSA*, LSAKeyType_Less> OSPF::Area::summaryLSAsByID [private]
 

bool OSPF::Area::transitCapability [private]
 


The documentation for this class was generated from the following files:
Generated on Sat Apr 1 20:52:26 2006 for INET Framework for OMNeT++/OMNEST by  doxygen 1.4.1