#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
|
1.4.1