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