#include <LinkStateUpdateHandler.h>
Inheritance diagram for OSPF::LinkStateUpdateHandler:
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 |
|
00018 : 00019 OSPF::IMessageHandler (containingRouter) 00020 { 00021 }
|
|
00247 { 00248 bool sendDirectAcknowledgment = false; 00249 00250 if (!acknowledgementFlags.floodedBackOut) { 00251 if (intf->GetState () == OSPF::Interface::BackupState) { 00252 if ((acknowledgementFlags.lsaIsNewer && (lsaSource == intf->GetDesignatedRouter ().routerID)) || 00253 (acknowledgementFlags.lsaIsDuplicate && acknowledgementFlags.impliedAcknowledgement)) 00254 { 00255 intf->AddDelayedAcknowledgement (lsaHeader); 00256 } else { 00257 if ((acknowledgementFlags.lsaIsDuplicate && !acknowledgementFlags.impliedAcknowledgement) || 00258 (acknowledgementFlags.lsaReachedMaxAge && 00259 acknowledgementFlags.noLSAInstanceInDatabase && 00260 acknowledgementFlags.anyNeighborInExchangeOrLoadingState)) 00261 { 00262 sendDirectAcknowledgment = true; 00263 } 00264 } 00265 } else { 00266 if (acknowledgementFlags.lsaIsNewer) { 00267 intf->AddDelayedAcknowledgement (lsaHeader); 00268 } else { 00269 if ((acknowledgementFlags.lsaIsDuplicate && !acknowledgementFlags.impliedAcknowledgement) || 00270 (acknowledgementFlags.lsaReachedMaxAge && 00271 acknowledgementFlags.noLSAInstanceInDatabase && 00272 acknowledgementFlags.anyNeighborInExchangeOrLoadingState)) 00273 { 00274 sendDirectAcknowledgment = true; 00275 } 00276 } 00277 } 00278 } 00279 00280 if (sendDirectAcknowledgment) { 00281 OSPFLinkStateAcknowledgementPacket* ackPacket = new OSPFLinkStateAcknowledgementPacket; 00282 00283 ackPacket->setType (LinkStateAcknowledgementPacket); 00284 ackPacket->setRouterID (router->GetRouterID ()); 00285 ackPacket->setAreaID (intf->GetArea ()->GetAreaID ()); 00286 ackPacket->setAuthenticationType (intf->GetAuthenticationType ()); 00287 OSPF::AuthenticationKeyType authKey = intf->GetAuthenticationKey (); 00288 for (int i = 0; i < 8; i++) { 00289 ackPacket->setAuthentication (i, authKey.bytes[i]); 00290 } 00291 00292 ackPacket->setLsaHeadersArraySize (1); 00293 ackPacket->setLsaHeaders (0, lsaHeader); 00294 00295 ackPacket->setPacketLength (0); // TODO: Calculate correct length 00296 ackPacket->setChecksum (0); // TODO: Calculate correct cheksum (16-bit one's complement of the entire packet) 00297 00298 int ttl = (intf->GetType () == OSPF::Interface::Virtual) ? VIRTUAL_LINK_TTL : 1; 00299 00300 if (intf->GetType () == OSPF::Interface::Broadcast) { 00301 if ((intf->GetState () == OSPF::Interface::DesignatedRouterState) || 00302 (intf->GetState () == OSPF::Interface::BackupState) || 00303 (intf->GetDesignatedRouter () == OSPF::NullDesignatedRouterID)) 00304 { 00305 router->GetMessageHandler ()->SendPacket (ackPacket, OSPF::AllSPFRouters, intf->GetIfIndex (), ttl); 00306 } else { 00307 router->GetMessageHandler ()->SendPacket (ackPacket, OSPF::AllDRouters, intf->GetIfIndex (), ttl); 00308 } 00309 } else { 00310 if (intf->GetType () == OSPF::Interface::PointToPoint) { 00311 router->GetMessageHandler ()->SendPacket (ackPacket, OSPF::AllSPFRouters, intf->GetIfIndex (), ttl); 00312 } else { 00313 router->GetMessageHandler ()->SendPacket (ackPacket, intf->GetNeighborByID (lsaSource)->GetAddress (), intf->GetIfIndex (), ttl); 00314 } 00315 } 00316 } 00317 }
|
|
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 () >= OSPF::Neighbor::ExchangeState) { 00034 OSPF::AreaID areaID = lsUpdatePacket->getAreaID ().getInt (); 00035 OSPF::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 ()); 00098 EV << "\n"; 00099 00100 if ((lsaType == ASExternalLSAType) && (!area->GetExternalRoutingCapability ())) { 00101 continue; 00102 } 00103 OSPF::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->AnyNeighborInStates (OSPF::Neighbor::ExchangeState | OSPF::Neighbor::LoadingState); 00119 00120 if ((ackFlags.lsaReachedMaxAge) && (ackFlags.noLSAInstanceInDatabase) && (!ackFlags.anyNeighborInExchangeOrLoadingState)) { 00121 if (intf->GetType () == OSPF::Interface::Broadcast) { 00122 if ((intf->GetState () == OSPF::Interface::DesignatedRouterState) || 00123 (intf->GetState () == OSPF::Interface::BackupState) || 00124 (intf->GetDesignatedRouter () == OSPF::NullDesignatedRouterID)) 00125 { 00126 intf->SendLSAcknowledgement (&(currentLSA->getHeader ()), OSPF::AllSPFRouters); 00127 } else { 00128 intf->SendLSAcknowledgement (&(currentLSA->getHeader ()), OSPF::AllDRouters); 00129 } 00130 } else { 00131 if (intf->GetType () == OSPF::Interface::PointToPoint) { 00132 intf->SendLSAcknowledgement (&(currentLSA->getHeader ()), OSPF::AllSPFRouters); 00133 } else { 00134 intf->SendLSAcknowledgement (&(currentLSA->getHeader ()), neighbor->GetAddress ()); 00135 } 00136 } 00137 continue; 00138 } 00139 00140 if (!ackFlags.noLSAInstanceInDatabase) { 00141 // operator< and operator== on OSPFLSAHeaders determines which one is newer (less means older) 00142 ackFlags.lsaIsNewer = (lsaInDatabase->getHeader () < currentLSA->getHeader ()); 00143 ackFlags.lsaIsDuplicate = (operator== (lsaInDatabase->getHeader (), currentLSA->getHeader ())); 00144 } 00145 if ((ackFlags.noLSAInstanceInDatabase) || (ackFlags.lsaIsNewer)) { 00146 LSATrackingInfo* info = (!ackFlags.noLSAInstanceInDatabase) ? dynamic_cast<LSATrackingInfo*> (lsaInDatabase) : NULL; 00147 if ((!ackFlags.noLSAInstanceInDatabase) && 00148 (info != NULL) && 00149 (info->GetSource () == LSATrackingInfo::Flooded) && 00150 (info->GetInstallTime () < MIN_LS_ARRIVAL)) 00151 { 00152 continue; 00153 } 00154 ackFlags.floodedBackOut = router->FloodLSA (currentLSA, areaID, intf, neighbor); 00155 if (!ackFlags.noLSAInstanceInDatabase) { 00156 OSPF::LSAKeyType lsaKey; 00157 00158 lsaKey.linkStateID = lsaInDatabase->getHeader ().getLinkStateID (); 00159 lsaKey.advertisingRouter = lsaInDatabase->getHeader ().getAdvertisingRouter ().getInt (); 00160 00161 router->RemoveFromAllRetransmissionLists (lsaKey); 00162 } 00163 rebuildRoutingTable |= router->InstallLSA (currentLSA, areaID); 00164 00165 EV << " (update installed)\n"; 00166 00167 AcknowledgeLSA (currentLSA->getHeader (), intf, ackFlags, lsUpdatePacket->getRouterID ().getInt ()); 00168 if ((currentLSA->getHeader ().getAdvertisingRouter ().getInt () == router->GetRouterID ()) || 00169 ((lsaType == NetworkLSAType) && 00170 (router->IsLocalAddress (IPv4AddressFromULong (currentLSA->getHeader ().getLinkStateID ()))))) 00171 { 00172 if (ackFlags.noLSAInstanceInDatabase) { 00173 currentLSA->getHeader ().setLsAge (MAX_AGE); 00174 router->FloodLSA (currentLSA, areaID); 00175 } else { 00176 if (ackFlags.lsaIsNewer) { 00177 long sequenceNumber = currentLSA->getHeader ().getLsSequenceNumber (); 00178 if (sequenceNumber == MAX_SEQUENCE_NUMBER) { 00179 lsaInDatabase->getHeader ().setLsAge (MAX_AGE); 00180 router->FloodLSA (lsaInDatabase, areaID); 00181 } else { 00182 lsaInDatabase->getHeader ().setLsSequenceNumber (sequenceNumber + 1); 00183 router->FloodLSA (lsaInDatabase, areaID); 00184 } 00185 } 00186 } 00187 } 00188 continue; 00189 } 00190 if (neighbor->IsLSAOnRequestList (lsaKey)) { 00191 neighbor->ProcessEvent (OSPF::Neighbor::BadLinkStateRequest); 00192 break; 00193 } 00194 if (ackFlags.lsaIsDuplicate) { 00195 if (neighbor->IsLSAOnRetransmissionList (lsaKey)) { 00196 neighbor->RemoveFromRetransmissionList (lsaKey); 00197 ackFlags.impliedAcknowledgement = true; 00198 } 00199 AcknowledgeLSA (currentLSA->getHeader (), intf, ackFlags, lsUpdatePacket->getRouterID ().getInt ()); 00200 continue; 00201 } 00202 if ((lsaInDatabase->getHeader ().getLsAge () == MAX_AGE) && 00203 (lsaInDatabase->getHeader ().getLsSequenceNumber () == MAX_SEQUENCE_NUMBER)) 00204 { 00205 continue; 00206 } 00207 if (!neighbor->IsOnTransmittedLSAList (lsaKey)) { 00208 OSPFLinkStateUpdatePacket* updatePacket = intf->CreateUpdatePacket (lsaInDatabase); 00209 if (updatePacket != NULL) { 00210 int ttl = (intf->GetType () == OSPF::Interface::Virtual) ? VIRTUAL_LINK_TTL : 1; 00211 00212 if (intf->GetType () == OSPF::Interface::Broadcast) { 00213 if ((intf->GetState () == OSPF::Interface::DesignatedRouterState) || 00214 (intf->GetState () == OSPF::Interface::BackupState) || 00215 (intf->GetDesignatedRouter () == OSPF::NullDesignatedRouterID)) 00216 { 00217 router->GetMessageHandler ()->SendPacket (updatePacket, OSPF::AllSPFRouters, intf->GetIfIndex (), ttl); 00218 } else { 00219 router->GetMessageHandler ()->SendPacket (updatePacket, OSPF::AllDRouters, intf->GetIfIndex (), ttl); 00220 } 00221 } else { 00222 if (intf->GetType () == OSPF::Interface::PointToPoint) { 00223 router->GetMessageHandler ()->SendPacket (updatePacket, OSPF::AllSPFRouters, intf->GetIfIndex (), ttl); 00224 } else { 00225 router->GetMessageHandler ()->SendPacket (updatePacket, neighbor->GetAddress (), intf->GetIfIndex (), ttl); 00226 } 00227 } 00228 } 00229 } 00230 } 00231 currentType = static_cast<LSAType> (currentType + 1); 00232 if (currentType == SummaryLSA_NetworksType) { 00233 currentType = static_cast<LSAType> (currentType + 1); 00234 } 00235 } 00236 } 00237 00238 if (rebuildRoutingTable) { 00239 router->RebuildRoutingTable (); 00240 } 00241 }
|
|
00023 { return true; } // not implemented
|