|
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 "ansaOspfCommon6.h" 00018 #include "ansaOspfNeighbor6.h" 00019 #include "ansaOspfRouter6.h" 00020 00021 #include "ansaLinkStateUpdateHandler6.h" 00022 00023 class LsaProcessingMarker { 00024 private: 00025 unsigned int index; 00026 00027 public: 00028 LsaProcessingMarker(unsigned int counter) : index(counter) { EV<< " --> Processing LSA(" << index << ")\n"; } 00029 ~LsaProcessingMarker() { EV << " <-- LSA(" << index << ") processed.\n"; } 00030 }; 00031 00032 AnsaOspf6::LinkStateUpdateHandler::LinkStateUpdateHandler(AnsaOspf6::Router* containingRouter) : 00033 AnsaOspf6::IMessageHandler(containingRouter) { 00034 } 00035 00036 void AnsaOspf6::LinkStateUpdateHandler::ProcessPacket(OspfPacket6* packet, 00037 AnsaOspf6::Interface* intf, AnsaOspf6::Neighbor* neighbor) { 00038 00039 router->GetMessageHandler()->PrintEvent("Link State Update packet received", intf, neighbor); 00040 00041 OspfLinkStateUpdatePacket6* lsUpdatePacket = check_and_cast<OspfLinkStateUpdatePacket6*> (packet); 00042 bool rebuildRoutingTable = false; 00043 00044 if (neighbor->GetState() >= AnsaOspf6::Neighbor::ExchangeState){ 00045 AnsaOspf6::AreaID areaID = lsUpdatePacket->getAreaID(); 00046 AnsaOspf6::Area* area = router->GetArea(areaID); 00047 LsaType6 currentType = RouterLsaType; 00048 unsigned int currentLSAIndex = 0; 00049 00050 EV<< " Processing packet contents:\n"; 00051 00052 while (currentType <= IntraAreaPrefixLsaType){ 00053 unsigned int lsaCount = 0; 00054 00055 switch (currentType){ 00056 case RouterLsaType: 00057 lsaCount = lsUpdatePacket->getRouterLsasArraySize(); 00058 break; 00059 case NetworkLsaType: 00060 lsaCount = lsUpdatePacket->getNetworkLsasArraySize(); 00061 break; 00062 case InterAreaPrefixLsaType: 00063 lsaCount = lsUpdatePacket->getInterAreaPrefixLsasArraySize(); 00064 break; 00065 case InterAreaRouterLsaType: 00066 lsaCount = lsUpdatePacket->getInterAreaRouterLsasArraySize(); 00067 break; 00068 case AsExternalLsaType: 00069 lsaCount = lsUpdatePacket->getAsExternalLsasArraySize(); 00070 break; 00071 case LinkLsaType: 00072 lsaCount = lsUpdatePacket->getLinkLsasArraySize(); 00073 break; 00074 case IntraAreaPrefixLsaType: 00075 lsaCount = lsUpdatePacket->getIntraAreaPrefixLsasArraySize(); 00076 break; 00077 default: 00078 break; 00079 } 00080 00081 for (unsigned int i = 0; i < lsaCount; i++){ 00082 OspfLsa6* currentLSA; 00083 00084 switch (currentType){ 00085 case RouterLsaType: 00086 currentLSA = (&(lsUpdatePacket->getRouterLsas(i))); 00087 break; 00088 case NetworkLsaType: 00089 currentLSA = (&(lsUpdatePacket->getNetworkLsas(i))); 00090 break; 00091 case InterAreaPrefixLsaType: 00092 currentLSA = (&(lsUpdatePacket->getInterAreaPrefixLsas(i))); 00093 break; 00094 case InterAreaRouterLsaType: 00095 currentLSA = (&(lsUpdatePacket->getInterAreaRouterLsas(i))); 00096 break; 00097 case AsExternalLsaType: 00098 currentLSA = (&(lsUpdatePacket->getAsExternalLsas(i))); 00099 break; 00100 case LinkLsaType: 00101 currentLSA = (&(lsUpdatePacket->getLinkLsas(i))); 00102 break; 00103 case IntraAreaPrefixLsaType: 00104 currentLSA = (&(lsUpdatePacket->getIntraAreaPrefixLsas(i))); 00105 break; 00106 default: 00107 break; 00108 } 00109 00110 LsaType6 lsaType = static_cast<LsaType6> (currentLSA->getHeader().getLsType()); 00111 if ( (lsaType != RouterLsaType) && 00112 (lsaType != NetworkLsaType) && 00113 (lsaType != InterAreaPrefixLsaType) && 00114 (lsaType != InterAreaRouterLsaType) && 00115 (lsaType != AsExternalLsaType) && 00116 (lsaType != LinkLsaType) && 00117 (lsaType != IntraAreaPrefixLsaType)){ 00118 continue; 00119 } 00120 00121 LsaProcessingMarker marker(currentLSAIndex++); 00122 EV << " "; 00123 PrintLsaHeader6(currentLSA->getHeader(), ev.getOStream()); 00124 EV << "\n"; 00125 00126 if ((lsaType == AsExternalLsaType) && (!area->GetExternalRoutingCapability())){ 00127 continue; 00128 } 00129 AnsaOspf6::LsaKeyType6 lsaKey; 00130 00131 lsaKey.linkStateID = currentLSA->getHeader().getLinkStateID(); 00132 lsaKey.advertisingRouter = currentLSA->getHeader().getAdvertisingRouter(); 00133 00134 OspfLsa6* lsaInDatabase = router->FindLSA(lsaType, lsaKey, areaID); 00135 unsigned short lsAge = currentLSA->getHeader().getLsAge(); 00136 AcknowledgementFlags ackFlags; 00137 00138 ackFlags.floodedBackOut = false; 00139 ackFlags.lsaIsNewer = false; 00140 ackFlags.lsaIsDuplicate = false; 00141 ackFlags.impliedAcknowledgement = false; 00142 ackFlags.lsaReachedMaxAge = (lsAge == MAX_AGE); 00143 ackFlags.noLSAInstanceInDatabase = (lsaInDatabase == NULL); 00144 ackFlags.anyNeighborInExchangeOrLoadingState = router->HasAnyNeighborInStates(AnsaOspf6::Neighbor::ExchangeState | AnsaOspf6::Neighbor::LoadingState); 00145 00146 00147 if ((ackFlags.lsaReachedMaxAge) && (ackFlags.noLSAInstanceInDatabase) && (!ackFlags.anyNeighborInExchangeOrLoadingState)){ 00148 if (intf->GetType() == AnsaOspf6::Interface::Broadcast){ 00149 if ( (intf->GetState() == AnsaOspf6::Interface::DesignatedRouterState) || 00150 (intf->GetState() == AnsaOspf6::Interface::BackupState) || 00151 (intf->GetDesignatedRouter() == AnsaOspf6::NullDesignatedRouterID)){ 00152 intf->SendLSAcknowledgement(&(currentLSA->getHeader()), AnsaOspf6::AllSPFRouters); 00153 }else{ 00154 intf->SendLSAcknowledgement(&(currentLSA->getHeader()), AnsaOspf6::AllDRouters); 00155 } 00156 }else{ 00157 if (intf->GetType() == AnsaOspf6::Interface::PointToPoint){ 00158 intf->SendLSAcknowledgement(&(currentLSA->getHeader()), AnsaOspf6::AllSPFRouters); 00159 }else{ 00160 intf->SendLSAcknowledgement(&(currentLSA->getHeader()), neighbor->GetAddress()); 00161 } 00162 } 00163 continue; 00164 } 00165 00166 if (!ackFlags.noLSAInstanceInDatabase){ 00167 // operator< and operator== on OSPFLSAHeaders determines which one is newer(less means older) 00168 ackFlags.lsaIsNewer = (lsaInDatabase->getHeader() < currentLSA->getHeader()); 00169 ackFlags.lsaIsDuplicate = (operator== (lsaInDatabase->getHeader(), currentLSA->getHeader())); 00170 } 00171 if ((ackFlags.noLSAInstanceInDatabase) || (ackFlags.lsaIsNewer)){ 00172 LsaTrackingInfo* info = (!ackFlags.noLSAInstanceInDatabase) ? dynamic_cast<LsaTrackingInfo*> (lsaInDatabase) : NULL; 00173 if ( (!ackFlags.noLSAInstanceInDatabase) && 00174 (info != NULL) && 00175 (info->GetSource() == LsaTrackingInfo::Flooded) && 00176 (info->GetInstallTime() < MIN_LS_ARRIVAL)){ 00177 //continue; TODO 00178 } 00179 ackFlags.floodedBackOut = router->FloodLSA(currentLSA, areaID, intf, neighbor); 00180 if (!ackFlags.noLSAInstanceInDatabase){ 00181 AnsaOspf6::LsaKeyType6 lsaKey; 00182 00183 lsaKey.linkStateID = lsaInDatabase->getHeader().getLinkStateID(); 00184 lsaKey.advertisingRouter = lsaInDatabase->getHeader().getAdvertisingRouter(); 00185 00186 router->RemoveFromAllRetransmissionLists(lsaKey); 00187 } 00188 rebuildRoutingTable |= router->InstallLSA(currentLSA, areaID); 00189 00190 EV << " (update installed)\n"; 00191 00192 AcknowledgeLSA(currentLSA->getHeader(), intf, ackFlags, lsUpdatePacket->getRouterID()); 00193 00194 // TODO: verify 00195 if (currentLSA->getHeader().getAdvertisingRouter() == router->GetRouterID()){ 00196 00197 if (ackFlags.noLSAInstanceInDatabase){ 00198 currentLSA->getHeader().setLsAge(MAX_AGE); 00199 router->FloodLSA(currentLSA, areaID); 00200 }else{ 00201 if (ackFlags.lsaIsNewer){ 00202 long sequenceNumber = currentLSA->getHeader().getLsSequenceNumber(); 00203 if (sequenceNumber == MAX_SEQUENCE_NUMBER){ 00204 lsaInDatabase->getHeader().setLsAge(MAX_AGE); 00205 router->FloodLSA(lsaInDatabase, areaID); 00206 }else{ 00207 lsaInDatabase->getHeader().setLsSequenceNumber(sequenceNumber + 1); 00208 router->FloodLSA(lsaInDatabase, areaID); 00209 } 00210 } 00211 } 00212 } 00213 continue; 00214 } 00215 00216 00217 if (neighbor->IsLSAOnRequestList(lsaKey)){ 00218 neighbor->ProcessEvent(AnsaOspf6::Neighbor::BadLinkStateRequest); 00219 break; 00220 } 00221 00222 if (ackFlags.lsaIsDuplicate){ 00223 if (neighbor->IsLSAOnRetransmissionList(lsaKey)){ 00224 neighbor->RemoveFromRetransmissionList(lsaKey); 00225 ackFlags.impliedAcknowledgement = true; 00226 } 00227 AcknowledgeLSA(currentLSA->getHeader(), intf, ackFlags, lsUpdatePacket->getRouterID()); 00228 continue; 00229 } 00230 00231 if ( (lsaInDatabase->getHeader().getLsAge() == MAX_AGE) && 00232 (lsaInDatabase->getHeader().getLsSequenceNumber() == MAX_SEQUENCE_NUMBER)){ 00233 continue; 00234 } 00235 00236 if (!neighbor->IsOnTransmittedLSAList(lsaKey)){ 00237 OspfLinkStateUpdatePacket6* updatePacket = intf->CreateUpdatePacket(lsaInDatabase); 00238 if (updatePacket != NULL){ 00239 int ttl = (intf->GetType() == AnsaOspf6::Interface::Virtual) ? VIRTUAL_LINK_TTL : 1; 00240 00241 if (intf->GetType() == AnsaOspf6::Interface::Broadcast){ 00242 if ( (intf->GetState() == AnsaOspf6::Interface::DesignatedRouterState) || 00243 (intf->GetState() == AnsaOspf6::Interface::BackupState) || 00244 (intf->GetDesignatedRouter() == AnsaOspf6::NullDesignatedRouterID)){ 00245 router->GetMessageHandler()->SendPacket(updatePacket, AnsaOspf6::AllSPFRouters, intf->GetIfIndex(), ttl); 00246 }else{ 00247 router->GetMessageHandler()->SendPacket(updatePacket, AnsaOspf6::AllDRouters, intf->GetIfIndex(), ttl); 00248 } 00249 }else{ 00250 if (intf->GetType() == AnsaOspf6::Interface::PointToPoint){ 00251 router->GetMessageHandler()->SendPacket(updatePacket, AnsaOspf6::AllSPFRouters, intf->GetIfIndex(), ttl); 00252 }else{ 00253 router->GetMessageHandler()->SendPacket(updatePacket, neighbor->GetAddress(), intf->GetIfIndex(), ttl); 00254 } 00255 } 00256 } 00257 } 00258 00259 } // for each LSA of a type 00260 00261 currentType = static_cast<LsaType6> (currentType + 1); 00262 00263 } // for each LSA type 00264 } 00265 00266 if (rebuildRoutingTable){ 00267 router->RebuildRoutingTable(); 00268 } 00269 } 00270 00271 void AnsaOspf6::LinkStateUpdateHandler::AcknowledgeLSA(OspfLsaHeader6& lsaHeader, 00272 AnsaOspf6::Interface* intf, 00273 AnsaOspf6::LinkStateUpdateHandler::AcknowledgementFlags acknowledgementFlags, 00274 AnsaOspf6::RouterID lsaSource){ 00275 00276 bool sendDirectAcknowledgment = false; 00277 00278 if (!acknowledgementFlags.floodedBackOut){ 00279 if (intf->GetState() == AnsaOspf6::Interface::BackupState){ 00280 if ((acknowledgementFlags.lsaIsNewer 00281 && (lsaSource == intf->GetDesignatedRouter())) 00282 || (acknowledgementFlags.lsaIsDuplicate 00283 && acknowledgementFlags.impliedAcknowledgement)){ 00284 intf->AddDelayedAcknowledgement(lsaHeader); 00285 }else{ 00286 if ((acknowledgementFlags.lsaIsDuplicate 00287 && !acknowledgementFlags.impliedAcknowledgement) 00288 || (acknowledgementFlags.lsaReachedMaxAge 00289 && acknowledgementFlags.noLSAInstanceInDatabase 00290 && acknowledgementFlags.anyNeighborInExchangeOrLoadingState)){ 00291 sendDirectAcknowledgment = true; 00292 } 00293 } 00294 }else{ 00295 if (acknowledgementFlags.lsaIsNewer){ 00296 intf->AddDelayedAcknowledgement(lsaHeader); 00297 }else{ 00298 if ((acknowledgementFlags.lsaIsDuplicate 00299 && !acknowledgementFlags.impliedAcknowledgement) 00300 || (acknowledgementFlags.lsaReachedMaxAge 00301 && acknowledgementFlags.noLSAInstanceInDatabase 00302 && acknowledgementFlags.anyNeighborInExchangeOrLoadingState)){ 00303 sendDirectAcknowledgment = true; 00304 } 00305 } 00306 } 00307 } 00308 00309 if (sendDirectAcknowledgment){ 00310 OspfLinkStateAcknowledgementPacket6* ackPacket = new OspfLinkStateAcknowledgementPacket6; 00311 00312 ackPacket->setType(LinkStateAcknowledgementPacket); 00313 ackPacket->setRouterID(router->GetRouterID()); 00314 ackPacket->setAreaID(intf->GetArea()->GetAreaID()); 00315 00316 ackPacket->setLsaHeadersArraySize(1); 00317 ackPacket->setLsaHeaders(0, lsaHeader); 00318 00319 int ttl = (intf->GetType() == AnsaOspf6::Interface::Virtual) ? VIRTUAL_LINK_TTL : 1; 00320 00321 if (intf->GetType() == AnsaOspf6::Interface::Broadcast){ 00322 if ((intf->GetState() == AnsaOspf6::Interface::DesignatedRouterState) || (intf->GetState() 00323 == AnsaOspf6::Interface::BackupState) || (intf->GetDesignatedRouter() 00324 == AnsaOspf6::NullDesignatedRouterID)){ 00325 router->GetMessageHandler()->SendPacket(ackPacket, AnsaOspf6::AllSPFRouters, intf->GetIfIndex(), ttl); 00326 }else{ 00327 router->GetMessageHandler()->SendPacket(ackPacket, AnsaOspf6::AllDRouters, intf->GetIfIndex(), ttl); 00328 } 00329 }else{ 00330 if (intf->GetType() == AnsaOspf6::Interface::PointToPoint){ 00331 router->GetMessageHandler()->SendPacket(ackPacket, AnsaOspf6::AllSPFRouters, intf->GetIfIndex(), ttl); 00332 }else{ 00333 router->GetMessageHandler()->SendPacket(ackPacket, intf->GetNeighborByID(lsaSource)->GetAddress(), intf->GetIfIndex(), ttl); 00334 } 00335 } 00336 } 00337 }