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