OSPF::LinkStateUpdateHandler Class Reference

#include <LinkStateUpdateHandler.h>

Inheritance diagram for OSPF::LinkStateUpdateHandler:

OSPF::IMessageHandler

List of all members.

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


Constructor & Destructor Documentation

OSPF::LinkStateUpdateHandler::LinkStateUpdateHandler ( OSPF::Router containingRouter  ) 

00035                                                                                :
00036     OSPF::IMessageHandler(containingRouter)
00037 {
00038 }


Member Function Documentation

bool OSPF::LinkStateUpdateHandler::ValidateLSChecksum ( OSPFLSA *  lsa  )  [inline, private]

Referenced by ProcessPacket().

00040 { return true; }   // not implemented

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]

See also:
RFC2328 Section 13.

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 }


The documentation for this class was generated from the following files:

Generated on Fri Mar 20 18:51:23 2009 for INET Framework for OMNeT++/OMNEST by  doxygen 1.5.5