|
INET Framework for OMNeT++/OMNEST
|
00001 #include "AnsaLinkStateUpdateHandler.h" 00002 #include "AnsaOSPFcommon.h" 00003 #include "AnsaOSPFRouter.h" 00004 #include "AnsaOSPFArea.h" 00005 #include "AnsaOSPFNeighbor.h" 00006 00007 class LSAProcessingMarker 00008 { 00009 private: 00010 unsigned int index; 00011 00012 public: 00013 LSAProcessingMarker(unsigned int counter) : index(counter) { EV << " --> Processing LSA(" << index << ")\n"; } 00014 ~LSAProcessingMarker() { EV << " <-- LSA(" << index << ") processed.\n"; } 00015 }; 00016 00017 00018 AnsaOSPF::LinkStateUpdateHandler::LinkStateUpdateHandler(AnsaOSPF::Router* containingRouter) : 00019 AnsaOSPF::IMessageHandler(containingRouter) 00020 { 00021 } 00022 00026 void AnsaOSPF::LinkStateUpdateHandler::ProcessPacket(OSPFPacket* packet, AnsaOSPF::Interface* intf, AnsaOSPF::Neighbor* neighbor) 00027 { 00028 router->GetMessageHandler()->PrintEvent("Link State Update packet received", intf, neighbor); 00029 00030 OSPFLinkStateUpdatePacket* lsUpdatePacket = check_and_cast<OSPFLinkStateUpdatePacket*> (packet); 00031 bool rebuildRoutingTable = false; 00032 00033 if (neighbor->GetState() >= AnsaOSPF::Neighbor::ExchangeState) { 00034 AnsaOSPF::AreaID areaID = lsUpdatePacket->getAreaID().getInt(); 00035 AnsaOSPF::Area* area = router->GetArea(areaID); 00036 LSAType currentType = RouterLSAType; 00037 unsigned int currentLSAIndex = 0; 00038 00039 EV << " Processing packet contents:\n"; 00040 00041 while (currentType <= ASExternalLSAType) { 00042 unsigned int lsaCount = 0; 00043 00044 switch (currentType) { 00045 case RouterLSAType: 00046 lsaCount = lsUpdatePacket->getRouterLSAsArraySize(); 00047 break; 00048 case NetworkLSAType: 00049 lsaCount = lsUpdatePacket->getNetworkLSAsArraySize(); 00050 break; 00051 case SummaryLSA_NetworksType: 00052 case SummaryLSA_ASBoundaryRoutersType: 00053 lsaCount = lsUpdatePacket->getSummaryLSAsArraySize(); 00054 break; 00055 case ASExternalLSAType: 00056 lsaCount = lsUpdatePacket->getAsExternalLSAsArraySize(); 00057 break; 00058 default: break; 00059 } 00060 00061 for (unsigned int i = 0; i < lsaCount; i++) { 00062 OSPFLSA* currentLSA; 00063 00064 switch (currentType) { 00065 case RouterLSAType: 00066 currentLSA = (&(lsUpdatePacket->getRouterLSAs(i))); 00067 break; 00068 case NetworkLSAType: 00069 currentLSA = (&(lsUpdatePacket->getNetworkLSAs(i))); 00070 break; 00071 case SummaryLSA_NetworksType: 00072 case SummaryLSA_ASBoundaryRoutersType: 00073 currentLSA = (&(lsUpdatePacket->getSummaryLSAs(i))); 00074 break; 00075 case ASExternalLSAType: 00076 currentLSA = (&(lsUpdatePacket->getAsExternalLSAs(i))); 00077 break; 00078 default: break; 00079 } 00080 00081 if (!ValidateLSChecksum(currentLSA)) { 00082 continue; 00083 } 00084 00085 LSAType lsaType = static_cast<LSAType> (currentLSA->getHeader().getLsType()); 00086 if ((lsaType != RouterLSAType) && 00087 (lsaType != NetworkLSAType) && 00088 (lsaType != SummaryLSA_NetworksType) && 00089 (lsaType != SummaryLSA_ASBoundaryRoutersType) && 00090 (lsaType != ASExternalLSAType)) 00091 { 00092 continue; 00093 } 00094 00095 LSAProcessingMarker marker(currentLSAIndex++); 00096 EV << " "; 00097 PrintLSAHeader(currentLSA->getHeader(), ev.getOStream()); 00098 EV << "\n"; 00099 00100 if ((lsaType == ASExternalLSAType) && (!area->GetExternalRoutingCapability())) { 00101 continue; 00102 } 00103 AnsaOSPF::LSAKeyType lsaKey; 00104 00105 lsaKey.linkStateID = currentLSA->getHeader().getLinkStateID(); 00106 lsaKey.advertisingRouter = currentLSA->getHeader().getAdvertisingRouter().getInt(); 00107 00108 OSPFLSA* lsaInDatabase = router->FindLSA(lsaType, lsaKey, areaID); 00109 unsigned short lsAge = currentLSA->getHeader().getLsAge(); 00110 AcknowledgementFlags ackFlags; 00111 00112 ackFlags.floodedBackOut = false; 00113 ackFlags.lsaIsNewer = false; 00114 ackFlags.lsaIsDuplicate = false; 00115 ackFlags.impliedAcknowledgement = false; 00116 ackFlags.lsaReachedMaxAge = (lsAge == MAX_AGE); 00117 ackFlags.noLSAInstanceInDatabase = (lsaInDatabase == NULL); 00118 ackFlags.anyNeighborInExchangeOrLoadingState = router->HasAnyNeighborInStates(AnsaOSPF::Neighbor::ExchangeState | AnsaOSPF::Neighbor::LoadingState); 00119 00120 00121 if ((ackFlags.lsaReachedMaxAge) && (ackFlags.noLSAInstanceInDatabase) && (!ackFlags.anyNeighborInExchangeOrLoadingState)) { 00122 if (intf->GetType() == AnsaOSPF::Interface::Broadcast) { 00123 if ((intf->GetState() == AnsaOSPF::Interface::DesignatedRouterState) || 00124 (intf->GetState() == AnsaOSPF::Interface::BackupState) || 00125 (intf->GetDesignatedRouter() == AnsaOSPF::NullDesignatedRouterID)) 00126 { 00127 intf->SendLSAcknowledgement(&(currentLSA->getHeader()), AnsaOSPF::AllSPFRouters); 00128 } else { 00129 intf->SendLSAcknowledgement(&(currentLSA->getHeader()), AnsaOSPF::AllDRouters); 00130 } 00131 } else { 00132 if (intf->GetType() == AnsaOSPF::Interface::PointToPoint) { 00133 intf->SendLSAcknowledgement(&(currentLSA->getHeader()), AnsaOSPF::AllSPFRouters); 00134 } else { 00135 intf->SendLSAcknowledgement(&(currentLSA->getHeader()), neighbor->GetAddress()); 00136 } 00137 } 00138 continue; 00139 } 00140 00141 if (!ackFlags.noLSAInstanceInDatabase) { 00142 // operator< and operator== on OSPFLSAHeaders determines which one is newer(less means older) 00143 ackFlags.lsaIsNewer = (lsaInDatabase->getHeader() < currentLSA->getHeader()); 00144 ackFlags.lsaIsDuplicate = (operator== (lsaInDatabase->getHeader(), currentLSA->getHeader())); 00145 } 00146 if ((ackFlags.noLSAInstanceInDatabase) || (ackFlags.lsaIsNewer)) { 00147 LSATrackingInfo* info = (!ackFlags.noLSAInstanceInDatabase) ? dynamic_cast<LSATrackingInfo*> (lsaInDatabase) : NULL; 00148 if ((!ackFlags.noLSAInstanceInDatabase) && 00149 (info != NULL) && 00150 (info->GetSource() == LSATrackingInfo::Flooded) && 00151 (info->GetInstallTime() < MIN_LS_ARRIVAL)) 00152 { 00153 //continue; 00154 } 00155 ackFlags.floodedBackOut = router->FloodLSA(currentLSA, areaID, intf, neighbor); 00156 if (!ackFlags.noLSAInstanceInDatabase) { 00157 AnsaOSPF::LSAKeyType lsaKey; 00158 00159 lsaKey.linkStateID = lsaInDatabase->getHeader().getLinkStateID(); 00160 lsaKey.advertisingRouter = lsaInDatabase->getHeader().getAdvertisingRouter().getInt(); 00161 00162 router->RemoveFromAllRetransmissionLists(lsaKey); 00163 } 00164 rebuildRoutingTable |= router->InstallLSA(currentLSA, areaID); 00165 00166 EV << " (update installed)\n"; 00167 00168 AcknowledgeLSA(currentLSA->getHeader(), intf, ackFlags, lsUpdatePacket->getRouterID().getInt()); 00169 if ((currentLSA->getHeader().getAdvertisingRouter().getInt() == router->GetRouterID()) || 00170 ((lsaType == NetworkLSAType) && 00171 (router->IsLocalAddress(IPv4AddressFromULong(currentLSA->getHeader().getLinkStateID()))))) 00172 { 00173 if (ackFlags.noLSAInstanceInDatabase) { 00174 currentLSA->getHeader().setLsAge(MAX_AGE); 00175 router->FloodLSA(currentLSA, areaID); 00176 } else { 00177 if (ackFlags.lsaIsNewer) { 00178 long sequenceNumber = currentLSA->getHeader().getLsSequenceNumber(); 00179 if (sequenceNumber == MAX_SEQUENCE_NUMBER) { 00180 lsaInDatabase->getHeader().setLsAge(MAX_AGE); 00181 router->FloodLSA(lsaInDatabase, areaID); 00182 } else { 00183 lsaInDatabase->getHeader().setLsSequenceNumber(sequenceNumber + 1); 00184 router->FloodLSA(lsaInDatabase, areaID); 00185 } 00186 } 00187 } 00188 } 00189 continue; 00190 } 00191 if (neighbor->IsLSAOnRequestList(lsaKey)) { 00192 neighbor->ProcessEvent(AnsaOSPF::Neighbor::BadLinkStateRequest); 00193 break; 00194 } 00195 if (ackFlags.lsaIsDuplicate) { 00196 if (neighbor->IsLSAOnRetransmissionList(lsaKey)) { 00197 neighbor->RemoveFromRetransmissionList(lsaKey); 00198 ackFlags.impliedAcknowledgement = true; 00199 } 00200 AcknowledgeLSA(currentLSA->getHeader(), intf, ackFlags, lsUpdatePacket->getRouterID().getInt()); 00201 continue; 00202 } 00203 if ((lsaInDatabase->getHeader().getLsAge() == MAX_AGE) && 00204 (lsaInDatabase->getHeader().getLsSequenceNumber() == MAX_SEQUENCE_NUMBER)) 00205 { 00206 continue; 00207 } 00208 if (!neighbor->IsOnTransmittedLSAList(lsaKey)) { 00209 OSPFLinkStateUpdatePacket* updatePacket = intf->CreateUpdatePacket(lsaInDatabase); 00210 if (updatePacket != NULL) { 00211 int ttl = (intf->GetType() == AnsaOSPF::Interface::Virtual) ? VIRTUAL_LINK_TTL : 1; 00212 00213 if (intf->GetType() == AnsaOSPF::Interface::Broadcast) { 00214 if ((intf->GetState() == AnsaOSPF::Interface::DesignatedRouterState) || 00215 (intf->GetState() == AnsaOSPF::Interface::BackupState) || 00216 (intf->GetDesignatedRouter() == AnsaOSPF::NullDesignatedRouterID)) 00217 { 00218 router->GetMessageHandler()->SendPacket(updatePacket, AnsaOSPF::AllSPFRouters, intf->GetIfIndex(), ttl); 00219 } else { 00220 router->GetMessageHandler()->SendPacket(updatePacket, AnsaOSPF::AllDRouters, intf->GetIfIndex(), ttl); 00221 } 00222 } else { 00223 if (intf->GetType() == AnsaOSPF::Interface::PointToPoint) { 00224 router->GetMessageHandler()->SendPacket(updatePacket, AnsaOSPF::AllSPFRouters, intf->GetIfIndex(), ttl); 00225 } else { 00226 router->GetMessageHandler()->SendPacket(updatePacket, neighbor->GetAddress(), intf->GetIfIndex(), ttl); 00227 } 00228 } 00229 } 00230 } 00231 } 00232 currentType = static_cast<LSAType> (currentType + 1); 00233 if (currentType == SummaryLSA_NetworksType) { 00234 currentType = static_cast<LSAType> (currentType + 1); 00235 } 00236 } 00237 } 00238 00239 if (rebuildRoutingTable) { 00240 router->RebuildRoutingTable(); 00241 } 00242 } 00243 00244 void AnsaOSPF::LinkStateUpdateHandler::AcknowledgeLSA(OSPFLSAHeader& lsaHeader, 00245 AnsaOSPF::Interface* intf, 00246 AnsaOSPF::LinkStateUpdateHandler::AcknowledgementFlags acknowledgementFlags, 00247 AnsaOSPF::RouterID lsaSource) 00248 { 00249 bool sendDirectAcknowledgment = false; 00250 00251 if (!acknowledgementFlags.floodedBackOut) { 00252 if (intf->GetState() == AnsaOSPF::Interface::BackupState) { 00253 if ((acknowledgementFlags.lsaIsNewer && (lsaSource == intf->GetDesignatedRouter().routerID)) || 00254 (acknowledgementFlags.lsaIsDuplicate && acknowledgementFlags.impliedAcknowledgement)) 00255 { 00256 intf->AddDelayedAcknowledgement(lsaHeader); 00257 } else { 00258 if ((acknowledgementFlags.lsaIsDuplicate && !acknowledgementFlags.impliedAcknowledgement) || 00259 (acknowledgementFlags.lsaReachedMaxAge && 00260 acknowledgementFlags.noLSAInstanceInDatabase && 00261 acknowledgementFlags.anyNeighborInExchangeOrLoadingState)) 00262 { 00263 sendDirectAcknowledgment = true; 00264 } 00265 } 00266 } else { 00267 if (acknowledgementFlags.lsaIsNewer) { 00268 intf->AddDelayedAcknowledgement(lsaHeader); 00269 } else { 00270 if ((acknowledgementFlags.lsaIsDuplicate && !acknowledgementFlags.impliedAcknowledgement) || 00271 (acknowledgementFlags.lsaReachedMaxAge && 00272 acknowledgementFlags.noLSAInstanceInDatabase && 00273 acknowledgementFlags.anyNeighborInExchangeOrLoadingState)) 00274 { 00275 sendDirectAcknowledgment = true; 00276 } 00277 } 00278 } 00279 } 00280 00281 if (sendDirectAcknowledgment) { 00282 OSPFLinkStateAcknowledgementPacket* ackPacket = new OSPFLinkStateAcknowledgementPacket; 00283 00284 ackPacket->setType(LinkStateAcknowledgementPacket); 00285 ackPacket->setRouterID(router->GetRouterID()); 00286 ackPacket->setAreaID(intf->GetArea()->GetAreaID()); 00287 ackPacket->setAuthenticationType(intf->GetAuthenticationType()); 00288 AnsaOSPF::AuthenticationKeyType authKey = intf->GetAuthenticationKey(); 00289 for (int i = 0; i < 8; i++) { 00290 ackPacket->setAuthentication(i, authKey.bytes[i]); 00291 } 00292 00293 ackPacket->setLsaHeadersArraySize(1); 00294 ackPacket->setLsaHeaders(0, lsaHeader); 00295 00296 ackPacket->setPacketLength(0); // TODO: Calculate correct length 00297 ackPacket->setChecksum(0); // TODO: Calculate correct cheksum(16-bit one's complement of the entire packet) 00298 00299 int ttl = (intf->GetType() == AnsaOSPF::Interface::Virtual) ? VIRTUAL_LINK_TTL : 1; 00300 00301 if (intf->GetType() == AnsaOSPF::Interface::Broadcast) { 00302 if ((intf->GetState() == AnsaOSPF::Interface::DesignatedRouterState) || 00303 (intf->GetState() == AnsaOSPF::Interface::BackupState) || 00304 (intf->GetDesignatedRouter() == AnsaOSPF::NullDesignatedRouterID)) 00305 { 00306 router->GetMessageHandler()->SendPacket(ackPacket, AnsaOSPF::AllSPFRouters, intf->GetIfIndex(), ttl); 00307 } else { 00308 router->GetMessageHandler()->SendPacket(ackPacket, AnsaOSPF::AllDRouters, intf->GetIfIndex(), ttl); 00309 } 00310 } else { 00311 if (intf->GetType() == AnsaOSPF::Interface::PointToPoint) { 00312 router->GetMessageHandler()->SendPacket(ackPacket, AnsaOSPF::AllSPFRouters, intf->GetIfIndex(), ttl); 00313 } else { 00314 router->GetMessageHandler()->SendPacket(ackPacket, intf->GetNeighborByID(lsaSource)->GetAddress(), intf->GetIfIndex(), ttl); 00315 } 00316 } 00317 } 00318 }