Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

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 Router containingRouter  ) 
 

00018                                                                                 :
00019     OSPF::IMessageHandler (containingRouter)
00020 {
00021 }


Member Function Documentation

void OSPF::LinkStateUpdateHandler::AcknowledgeLSA OSPFLSAHeader &  lsaHeader,
Interface intf,
AcknowledgementFlags  acknowledgementFlags,
RouterID  lsaSource
[private]
 

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 }

void OSPF::LinkStateUpdateHandler::ProcessPacket OSPFPacket *  packet,
OSPF::Interface intf,
OSPF::Neighbor neighbor
 

See also:
RFC2328 Section 13.
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 }

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

00023 { return true; }   // not implemented


The documentation for this class was generated from the following files:
Generated on Sat Apr 1 20:52:25 2006 for INET Framework for OMNeT++/OMNEST by  doxygen 1.4.1