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