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