INET Framework for OMNeT++/OMNEST
AnsaOSPFInterfaceState.cc
Go to the documentation of this file.
00001 #include "AnsaOSPFInterfaceState.h"
00002 #include "AnsaOSPFInterface.h"
00003 #include "AnsaOSPFArea.h"
00004 #include "AnsaOSPFRouter.h"
00005 #include "AnsaOSPFInterfaceStateDesignatedRouter.h"
00006 #include "AnsaOSPFInterfaceStateNotDesignatedRouter.h"
00007 #include "AnsaOSPFInterfaceStateBackup.h"
00008 #include <map>
00009 
00010 void AnsaOSPF::InterfaceState::ChangeState(AnsaOSPF::Interface* intf, AnsaOSPF::InterfaceState* newState, AnsaOSPF::InterfaceState* currentState)
00011 {
00012     AnsaOSPF::Interface::InterfaceStateType oldState            = currentState->GetState();
00013     AnsaOSPF::Interface::InterfaceStateType nextState           = newState->GetState();
00014     AnsaOSPF::Interface::OSPFInterfaceType  intfType            = intf->GetType();
00015     bool                                rebuildRoutingTable = false;
00016 
00017     intf->ChangeState(newState, currentState);
00018 
00019     if ((oldState == AnsaOSPF::Interface::DownState) ||
00020         (nextState == AnsaOSPF::Interface::DownState) ||
00021         (oldState == AnsaOSPF::Interface::LoopbackState) ||
00022         (nextState == AnsaOSPF::Interface::LoopbackState) ||
00023         (oldState == AnsaOSPF::Interface::DesignatedRouterState) ||
00024         (nextState == AnsaOSPF::Interface::DesignatedRouterState) ||
00025         ((intfType == AnsaOSPF::Interface::PointToPoint) &&
00026          ((oldState == AnsaOSPF::Interface::PointToPointState) ||
00027           (nextState == AnsaOSPF::Interface::PointToPointState))) ||
00028         (((intfType == AnsaOSPF::Interface::Broadcast) ||
00029           (intfType == AnsaOSPF::Interface::NBMA)) &&
00030          ((oldState == AnsaOSPF::Interface::WaitingState) ||
00031           (nextState == AnsaOSPF::Interface::WaitingState))))
00032     {
00033         AnsaOSPF::RouterLSA* routerLSA = intf->GetArea()->FindRouterLSA(intf->GetArea()->GetRouter()->GetRouterID());
00034 
00035         if (routerLSA != NULL) {
00036             long sequenceNumber = routerLSA->getHeader().getLsSequenceNumber();
00037             if (sequenceNumber == MAX_SEQUENCE_NUMBER) {
00038                 routerLSA->getHeader().setLsAge(MAX_AGE);
00039                 intf->GetArea()->FloodLSA(routerLSA);
00040                 routerLSA->IncrementInstallTime();
00041             } else {
00042                 AnsaOSPF::RouterLSA* newLSA = intf->GetArea()->OriginateRouterLSA();
00043 
00044                 newLSA->getHeader().setLsSequenceNumber(sequenceNumber + 1);
00045                 newLSA->getHeader().setLsChecksum(0);    // TODO: calculate correct LS checksum
00046                 rebuildRoutingTable |= routerLSA->Update(newLSA);
00047                 delete newLSA;
00048 
00049                 intf->GetArea()->FloodLSA(routerLSA);
00050             }
00051         } else {  // (lsa == NULL) -> This must be the first time any interface is up...
00052             AnsaOSPF::RouterLSA* newLSA = intf->GetArea()->OriginateRouterLSA();
00053 
00054             rebuildRoutingTable |= intf->GetArea()->InstallRouterLSA(newLSA);
00055 
00056             routerLSA = intf->GetArea()->FindRouterLSA(intf->GetArea()->GetRouter()->GetRouterID());
00057 
00058             intf->GetArea()->SetSPFTreeRoot(routerLSA);
00059             intf->GetArea()->FloodLSA(newLSA);
00060             delete newLSA;
00061         }
00062     }
00063 
00064     if (nextState == AnsaOSPF::Interface::DesignatedRouterState) {
00065         AnsaOSPF::NetworkLSA* newLSA = intf->GetArea()->OriginateNetworkLSA(intf);
00066         if (newLSA != NULL) {
00067             rebuildRoutingTable |= intf->GetArea()->InstallNetworkLSA(newLSA);
00068 
00069             intf->GetArea()->FloodLSA(newLSA);
00070             delete newLSA;
00071         } else {    // no neighbors on the network -> old NetworkLSA must be flushed
00072             AnsaOSPF::NetworkLSA* oldLSA = intf->GetArea()->FindNetworkLSA(ULongFromIPv4Address(intf->GetAddressRange().address));
00073 
00074             if (oldLSA != NULL) {
00075                 oldLSA->getHeader().setLsAge(MAX_AGE);
00076                 intf->GetArea()->FloodLSA(oldLSA);
00077                 oldLSA->IncrementInstallTime();
00078             }
00079         }
00080     }
00081 
00082     if (oldState == AnsaOSPF::Interface::DesignatedRouterState) {
00083         AnsaOSPF::NetworkLSA* networkLSA = intf->GetArea()->FindNetworkLSA(ULongFromIPv4Address(intf->GetAddressRange().address));
00084 
00085         if (networkLSA != NULL) {
00086             networkLSA->getHeader().setLsAge(MAX_AGE);
00087             intf->GetArea()->FloodLSA(networkLSA);
00088             networkLSA->IncrementInstallTime();
00089         }
00090     }
00091 
00092     if (rebuildRoutingTable) {
00093         intf->GetArea()->GetRouter()->RebuildRoutingTable();
00094     }
00095 }
00096 
00097 void AnsaOSPF::InterfaceState::CalculateDesignatedRouter(AnsaOSPF::Interface* intf)
00098 {
00099     AnsaOSPF::RouterID           routerID                = intf->parentArea->GetRouter()->GetRouterID();
00100     AnsaOSPF::DesignatedRouterID currentDesignatedRouter = intf->designatedRouter;
00101     AnsaOSPF::DesignatedRouterID currentBackupRouter     = intf->backupDesignatedRouter;
00102 
00103     unsigned int             neighborCount           = intf->neighboringRouters.size();
00104     unsigned char            repeatCount             = 0;
00105     unsigned int             i;
00106 
00107     AnsaOSPF::DesignatedRouterID declaredBackup;
00108     unsigned char            declaredBackupPriority;
00109     AnsaOSPF::RouterID           declaredBackupID;
00110     bool                     backupDeclared;
00111 
00112     AnsaOSPF::DesignatedRouterID declaredDesignatedRouter;
00113     unsigned char            declaredDesignatedRouterPriority;
00114     AnsaOSPF::RouterID           declaredDesignatedRouterID;
00115     bool                     designatedRouterDeclared;
00116 
00117     do {
00118         // calculating backup designated router
00119         declaredBackup = AnsaOSPF::NullDesignatedRouterID;
00120         declaredBackupPriority = 0;
00121         declaredBackupID = AnsaOSPF::NullRouterID;
00122         backupDeclared = false;
00123 
00124         AnsaOSPF::DesignatedRouterID highestRouter                 = AnsaOSPF::NullDesignatedRouterID;
00125         unsigned char            highestPriority               = 0;
00126         AnsaOSPF::RouterID           highestID                     = AnsaOSPF::NullRouterID;
00127 
00128         for (i = 0; i < neighborCount; i++) {
00129             AnsaOSPF::Neighbor* neighbor         = intf->neighboringRouters[i];
00130             unsigned char   neighborPriority = neighbor->GetPriority();
00131 
00132             if (neighbor->GetState() < AnsaOSPF::Neighbor::TwoWayState) {
00133                 continue;
00134             }
00135             if (neighborPriority == 0) {
00136                 continue;
00137             }
00138 
00139             AnsaOSPF::RouterID           neighborID                      = neighbor->GetNeighborID();
00140             AnsaOSPF::DesignatedRouterID neighborsDesignatedRouter       = neighbor->GetDesignatedRouter();
00141             AnsaOSPF::DesignatedRouterID neighborsBackupDesignatedRouter = neighbor->GetBackupDesignatedRouter();
00142 
00143             if (neighborsDesignatedRouter.routerID != neighborID) {
00144                 if (neighborsBackupDesignatedRouter.routerID == neighborID) {
00145                     if ((neighborPriority > declaredBackupPriority) ||
00146                         ((neighborPriority == declaredBackupPriority) &&
00147                          (neighborID > declaredBackupID)))
00148                     {
00149                         declaredBackup = neighborsBackupDesignatedRouter;
00150                         declaredBackupPriority = neighborPriority;
00151                         declaredBackupID = neighborID;
00152                         backupDeclared = true;
00153                     }
00154                 }
00155                 if (!backupDeclared) {
00156                     if ((neighborPriority > highestPriority) ||
00157                         ((neighborPriority == highestPriority) &&
00158                          (neighborID > highestID)))
00159                     {
00160                         highestRouter.routerID = neighborID;
00161                         highestRouter.ipInterfaceAddress = neighbor->GetAddress();
00162                         highestPriority = neighborPriority;
00163                         highestID = neighborID;
00164                     }
00165                 }
00166             }
00167         }
00168         // also include the router itself in the calculations
00169         if (intf->routerPriority > 0) {
00170             if (currentDesignatedRouter.routerID != routerID) {
00171                 if (currentBackupRouter.routerID == routerID) {
00172                     if ((intf->routerPriority > declaredBackupPriority) ||
00173                         ((intf->routerPriority == declaredBackupPriority) &&
00174                          (routerID > declaredBackupID)))
00175                     {
00176                         declaredBackup.routerID = routerID;
00177                         declaredBackup.ipInterfaceAddress = intf->interfaceAddressRange.address;
00178                         declaredBackupPriority = intf->routerPriority;
00179                         declaredBackupID = routerID;
00180                         backupDeclared = true;
00181                     }
00182 
00183                 }
00184                 if (!backupDeclared) {
00185                     if ((intf->routerPriority > highestPriority) ||
00186                         ((intf->routerPriority == highestPriority) &&
00187                          (routerID > highestID)))
00188                     {
00189                         declaredBackup.routerID = routerID;
00190                         declaredBackup.ipInterfaceAddress = intf->interfaceAddressRange.address;
00191                         declaredBackupPriority = intf->routerPriority;
00192                         declaredBackupID = routerID;
00193                         backupDeclared = true;
00194                     } else {
00195                         declaredBackup = highestRouter;
00196                         declaredBackupPriority = highestPriority;
00197                         declaredBackupID = highestID;
00198                         backupDeclared = true;
00199                     }
00200                 }
00201             }
00202         }
00203 
00204         // calculating backup designated router
00205         declaredDesignatedRouter = AnsaOSPF::NullDesignatedRouterID;
00206         declaredDesignatedRouterPriority = 0;
00207         declaredDesignatedRouterID = AnsaOSPF::NullRouterID;
00208         designatedRouterDeclared = false;
00209 
00210         for (i = 0; i < neighborCount; i++) {
00211             AnsaOSPF::Neighbor* neighbor         = intf->neighboringRouters[i];
00212             unsigned char   neighborPriority = neighbor->GetPriority();
00213 
00214             if (neighbor->GetState() < AnsaOSPF::Neighbor::TwoWayState) {
00215                 continue;
00216             }
00217             if (neighborPriority == 0) {
00218                 continue;
00219             }
00220 
00221             AnsaOSPF::RouterID           neighborID                      = neighbor->GetNeighborID();
00222             AnsaOSPF::DesignatedRouterID neighborsDesignatedRouter       = neighbor->GetDesignatedRouter();
00223             AnsaOSPF::DesignatedRouterID neighborsBackupDesignatedRouter = neighbor->GetBackupDesignatedRouter();
00224 
00225             if (neighborsDesignatedRouter.routerID == neighborID) {
00226                 if ((neighborPriority > declaredDesignatedRouterPriority) ||
00227                     ((neighborPriority == declaredDesignatedRouterPriority) &&
00228                      (neighborID > declaredDesignatedRouterID)))
00229                 {
00230                     declaredDesignatedRouter = neighborsDesignatedRouter;
00231                     declaredDesignatedRouterPriority = neighborPriority;
00232                     declaredDesignatedRouterID = neighborID;
00233                     designatedRouterDeclared = true;
00234                 }
00235             }
00236         }
00237         // also include the router itself in the calculations
00238         if (intf->routerPriority > 0) {
00239             if (currentDesignatedRouter.routerID == routerID) {
00240                 if ((intf->routerPriority > declaredDesignatedRouterPriority) ||
00241                     ((intf->routerPriority == declaredDesignatedRouterPriority) &&
00242                      (routerID > declaredDesignatedRouterID)))
00243                 {
00244                     declaredDesignatedRouter.routerID = routerID;
00245                     declaredDesignatedRouter.ipInterfaceAddress = intf->interfaceAddressRange.address;
00246                     declaredDesignatedRouterPriority = intf->routerPriority;
00247                     declaredDesignatedRouterID = routerID;
00248                     designatedRouterDeclared = true;
00249                 }
00250 
00251             }
00252         }
00253         if (!designatedRouterDeclared) {
00254             declaredDesignatedRouter = declaredBackup;
00255             declaredDesignatedRouterPriority = declaredBackupPriority;
00256             declaredDesignatedRouterID = declaredBackupID;
00257             designatedRouterDeclared = true;
00258         }
00259 
00260         // if the router is any kind of DR or is no longer one of them, then repeat
00261         if (((declaredDesignatedRouter.routerID != AnsaOSPF::NullRouterID) &&
00262              ((currentDesignatedRouter.routerID == routerID) &&
00263               (declaredDesignatedRouter.routerID != routerID)) ||
00264              ((currentDesignatedRouter.routerID != routerID) &&
00265               (declaredDesignatedRouter.routerID == routerID))) ||
00266             ((declaredBackup.routerID != AnsaOSPF::NullRouterID) &&
00267              ((currentBackupRouter.routerID == routerID) &&
00268               (declaredBackup.routerID != routerID)) ||
00269              ((currentBackupRouter.routerID != routerID) &&
00270               (declaredBackup.routerID == routerID))))
00271         {
00272             currentDesignatedRouter = declaredDesignatedRouter;
00273             currentBackupRouter = declaredBackup;
00274             repeatCount++;
00275         } else {
00276             repeatCount += 2;
00277         }
00278 
00279     } while (repeatCount < 2);
00280 
00281     AnsaOSPF::RouterID routersOldDesignatedRouterID = intf->designatedRouter.routerID;
00282     AnsaOSPF::RouterID routersOldBackupID           = intf->backupDesignatedRouter.routerID;
00283 
00284     intf->designatedRouter = declaredDesignatedRouter;
00285     intf->backupDesignatedRouter = declaredBackup;
00286 
00287     bool wasBackupDesignatedRouter = (routersOldBackupID == routerID);
00288     bool wasDesignatedRouter       = (routersOldDesignatedRouterID == routerID);
00289     bool wasOther                  = (intf->GetState() == AnsaOSPF::Interface::NotDesignatedRouterState);
00290     bool wasWaiting                = (!wasBackupDesignatedRouter && !wasDesignatedRouter && !wasOther);
00291     bool isBackupDesignatedRouter  = (declaredBackup.routerID == routerID);
00292     bool isDesignatedRouter        = (declaredDesignatedRouter.routerID == routerID);
00293     bool isOther                   = (!isBackupDesignatedRouter && !isDesignatedRouter);
00294 
00295     if (wasBackupDesignatedRouter) {
00296         if (isDesignatedRouter) {
00297             ChangeState(intf, new AnsaOSPF::InterfaceStateDesignatedRouter, this);
00298         }
00299         if (isOther) {
00300             ChangeState(intf, new AnsaOSPF::InterfaceStateNotDesignatedRouter, this);
00301         }
00302     }
00303     if (wasDesignatedRouter) {
00304         if (isBackupDesignatedRouter) {
00305             ChangeState(intf, new AnsaOSPF::InterfaceStateBackup, this);
00306         }
00307         if (isOther) {
00308             ChangeState(intf, new AnsaOSPF::InterfaceStateNotDesignatedRouter, this);
00309         }
00310     }
00311     if (wasOther) {
00312         if (isDesignatedRouter) {
00313             ChangeState(intf, new AnsaOSPF::InterfaceStateDesignatedRouter, this);
00314         }
00315         if (isBackupDesignatedRouter) {
00316             ChangeState(intf, new AnsaOSPF::InterfaceStateBackup, this);
00317         }
00318     }
00319     if (wasWaiting) {
00320         if (isDesignatedRouter) {
00321             ChangeState(intf, new AnsaOSPF::InterfaceStateDesignatedRouter, this);
00322         }
00323         if (isBackupDesignatedRouter) {
00324             ChangeState(intf, new AnsaOSPF::InterfaceStateBackup, this);
00325         }
00326         if (isOther) {
00327             ChangeState(intf, new AnsaOSPF::InterfaceStateNotDesignatedRouter, this);
00328         }
00329     }
00330 
00331     for (i = 0; i < neighborCount; i++) {
00332         if ((intf->interfaceType == AnsaOSPF::Interface::NBMA) &&
00333             ((!wasBackupDesignatedRouter && isBackupDesignatedRouter) ||
00334              (!wasDesignatedRouter && isDesignatedRouter)))
00335         {
00336             if (intf->neighboringRouters[i]->GetPriority() == 0) {
00337                 intf->neighboringRouters[i]->ProcessEvent(AnsaOSPF::Neighbor::Start);
00338             }
00339         }
00340         if ((declaredDesignatedRouter.routerID != routersOldDesignatedRouterID) ||
00341             (declaredBackup.routerID != routersOldBackupID))
00342         {
00343             if (intf->neighboringRouters[i]->GetState() >= AnsaOSPF::Neighbor::TwoWayState) {
00344                 intf->neighboringRouters[i]->ProcessEvent(AnsaOSPF::Neighbor::IsAdjacencyOK);
00345             }
00346         }
00347     }
00348 }