OSPFInterfaceState.cc

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