|
INET Framework for OMNeT++/OMNEST
|
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 }