00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "LinkStateUpdateHandler.h"
00019 #include "OSPFcommon.h"
00020 #include "OSPFRouter.h"
00021 #include "OSPFArea.h"
00022 #include "OSPFNeighbor.h"
00023
00024 class LSAProcessingMarker
00025 {
00026 private:
00027 unsigned int index;
00028
00029 public:
00030 LSAProcessingMarker(unsigned int counter) : index(counter) { EV << " --> Processing LSA(" << index << ")\n"; }
00031 ~LSAProcessingMarker() { EV << " <-- LSA(" << index << ") processed.\n"; }
00032 };
00033
00034
00035 OSPF::LinkStateUpdateHandler::LinkStateUpdateHandler(OSPF::Router* containingRouter) :
00036 OSPF::IMessageHandler(containingRouter)
00037 {
00038 }
00039
00043 void OSPF::LinkStateUpdateHandler::ProcessPacket(OSPFPacket* packet, OSPF::Interface* intf, OSPF::Neighbor* neighbor)
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
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 }
00259
00260 void OSPF::LinkStateUpdateHandler::AcknowledgeLSA(OSPFLSAHeader& lsaHeader,
00261 OSPF::Interface* intf,
00262 OSPF::LinkStateUpdateHandler::AcknowledgementFlags acknowledgementFlags,
00263 OSPF::RouterID lsaSource)
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);
00313 ackPacket->setChecksum(0);
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 }