15#include "NetSim_utility.h"
19#include "OSPF_Neighbor.h"
20#include "OSPF_Interface.h"
23ptrOSPFLSAHDR ospf_lsdb_lookup_lsaList(ptrOSPFLIST list,
28 void* pass = ospf_list_newIterator();
29 while ((lsa = ospf_list_iterate_mem(list, pass)) != NULL)
31 if (!OSPFID_COMPARE(lsa->AdvertisingRouter, adverRouter) &&
32 !OSPFID_COMPARE(lsa->LinkStateID, linkStateId))
34 ospf_list_deleteIterator(pass);
38 ospf_list_deleteIterator(pass);
42ptrOSPFLSAHDR ospf_lsdb_lookup_lsaListByID(ptrOSPFLIST list,
46 void* pass = ospf_list_newIterator();
47 while ((lsa = ospf_list_iterate_mem(list, &pass)) != NULL)
49 if (!OSPFID_COMPARE(lsa->LinkStateID, linkStateId))
51 ospf_list_deleteIterator(pass);
55 ospf_list_deleteIterator(pass);
59ptrOSPFLSAHDR ospf_lsdb_lookup(ptrOSPF_PDS ospf,
68 case LSTYPE_ROUTERLSA:
69 return ospf_lsdb_lookup_lsaList(area->routerLSAList,
73 case LSTYPE_NETWORKLSA:
74 return ospf_lsdb_lookup_lsaList(area->nwLSAList,
78 case LSTYPE_SUMMARYLSA_ROUTER:
79 return ospf_lsdb_lookup_lsaList(area->routerSummaryLSAList,
83 case LSTYPE_SUMMARYLSA_NETWORK:
84 return ospf_lsdb_lookup_lsaList(area->nwSummaryLSAList,
89 fnNetSimError(
"Unknown LSType %d in %s\n",
97bool ospf_lsdb_install(ptrOSPF_PDS ospf,
104 void* pass = ospf_list_newIterator();
105 ptrOSPFLSAHDR hdr = NULL;
106 ptrOSPFLSAHDR newLSA;
107 while ((hdr = ospf_list_iterate_mem(list, pass)) != NULL)
109 if (!OSPFID_COMPARE(lsa->AdvertisingRouter, hdr->AdvertisingRouter) &&
110 !OSPFID_COMPARE(lsa->LinkStateID, hdr->LinkStateID))
113 ospf_list_deleteIterator(pass);
118 ret = ospf_lsa_is_content_changed(ospf, lsa, hdr);
122 newLSA = OSPF_LSA_MSG_COPY(lsa);
123 newLSA->time = OSPF_CURR_TIME();
124 ospf_list_replace_mem(list, hdr, newLSA);
126 if (lsa->LSType == LSTYPE_ROUTERLSA ||
127 lsa->LSType == LSTYPE_NETWORKLSA)
128 ospf_lsa_assignNewLSAIntoLSOrigin(ospf, lsa, newLSA);
130 OSPF_LSA_MSG_FREE(hdr);
135 newLSA = OSPF_LSA_MSG_COPY(lsa);
136 newLSA->time = OSPF_CURR_TIME();
137 ospf_list_add_mem(list, newLSA);
141 ospf_lsa_printList(form_dlogId(
"LSDB", ospf->myId), list,
"LSDB install");
143 if (ospf_lsa_hasMaxAge(ospf, lsa))
144 ospf_lsa_addToMaxAgeLSAList(ospf, areaId, lsa);
148static int ospf_lsdb_updateLSAList(ptrOSPF_PDS ospf,
149 ptrOSPF_IF thisInterface,
153 NETSIM_IPAddress srcAddr)
156 ptrOSPFLSAHDR hdr = NULL;
157 void* pass = ospf_list_newIterator();
158 while ((hdr = ospf_list_iterate_mem(list, pass)) != NULL)
160 if (!OSPFID_COMPARE(lsa->AdvertisingRouter, hdr->AdvertisingRouter) &&
161 !OSPFID_COMPARE(lsa->LinkStateID, hdr->LinkStateID))
164 print_ospf_Dlog(form_dlogId(
"LSDB", ospf->myId),
"\tLSA found in LSDB\n"
165 " advertisingRouter %s linkStateID %s",
166 lsa->AdvertisingRouter->str_ip,
167 lsa->LinkStateID->str_ip);
170 if(!ospf_lsa_isSelfOriginated(ospf,lsa) &&
171 OSPF_CURR_TIME()-hdr->time < ospf->minLSInterval)
174 print_ospf_Dlog(form_dlogId(
"LSDB", ospf->myId),
"Received LSA is more recent, but arrives "
175 "before minLSInterval. So don't update LSDB");
176 ospf_list_deleteIterator(pass);
182 ospf_list_deleteIterator(pass);
184 isFloodBack = ospf_lsa_flood(ospf,
192 if (thisInterface->State == OSPFIFSTATE_BACKUP)
194 if (!IP_COMPARE(thisInterface->designaterRouter, srcAddr))
195 ospf_lsaAck_sendDelayedAck(ospf,
201 ospf_lsaAck_sendDelayedAck(ospf,
207 return (
int)ospf_lsdb_install(ospf, area->areaId, lsa, list);
210bool ospf_lsdb_update(ptrOSPF_PDS ospf,
211 ptrOSPF_IF thisInterface,
213 ptrOSPFAREA_DS thisArea,
214 NETSIM_IPAddress srcAddr)
220 case LSTYPE_ROUTERLSA:
221 ret = ospf_lsdb_updateLSAList(ospf,
224 thisArea->routerLSAList,
228 case LSTYPE_NETWORKLSA:
229 ret = ospf_lsdb_updateLSAList(ospf,
236 case LSTYPE_SUMMARYLSA_NETWORK:
237 ret = ospf_lsdb_updateLSAList(ospf,
240 thisArea->nwSummaryLSAList,
244 case LSTYPE_SUMMARYLSA_ROUTER:
245 ret = ospf_lsdb_updateLSAList(ospf,
248 thisArea->routerSummaryLSAList,
253 fnNetSimError(
"Unknown LS hdr of type %s in %s",
254 strLSTYPE[lsa->LSType],
262 if (ospf_lsa_isSelfOriginated(ospf, lsa))
264 bool isFlush =
false;
267 case LSTYPE_NETWORKLSA:
269 NETSIM_ID in = fn_NetSim_Stack_GetInterfaceIdFromIP(ospf->myId,
272 ptrOSPF_IF myInterface;
275 myInterface = OSPF_IF_GET(ospf, in);
276 if (myInterface->State != OSPFIFSTATE_DR &&
277 OSPFID_COMPARE(lsa->AdvertisingRouter, ospf->routerId))
282 case LSTYPE_SUMMARYLSA_NETWORK:
284#pragma message(__LOC__"Implement after routing table implementation")
287 case LSTYPE_SUMMARYLSA_ROUTER:
289#pragma message(__LOC__"Implement after routing table implementation")
295 ospf_lsa_flush(ospf, thisArea, lsa);
299 ptrOSPFLSAHDR oldLSA = ospf_lsdb_lookup(ospf,
302 lsa->AdvertisingRouter,
305 oldLSA->LSSequenceNumber = lsa->LSSequenceNumber + 1;
313 ospf_lsa_schedule(ospf,
323void ospf_lsdb_scheduleMaxAgeRemovalTimer(ptrOSPF_PDS ospf)
325 ospf_event_add(OSPF_CURR_TIME() + ospf->maxAgeRemovalTime,
328 OSPF_MAXAGEREMOVALTIMER,
331 ospf->isMaxAgeRemovalTimerSet =
true;
334static bool ospf_lsdb_isLSAInNeighborRxtList(ptrOSPF_PDS ospf,
339 for (i = 0; i < ospf->ifCount; i++)
341 ptrOSPF_IF thisInterface = ospf->ospfIf[i];
342 if (OSPFID_COMPARE(areaId,invalidAreaId) &&
343 OSPFID_COMPARE(areaId,thisInterface->areaId))
347 for (n = 0; n < thisInterface->neighborRouterCount; n++)
349 ptrOSPF_NEIGHBOR neigh = thisInterface->neighborRouterList[n];
352 void* pass = ospf_list_newIterator();
354 while ((l=ospf_list_iterate_mem(neigh->neighLSRxtList,pass))!=NULL)
357 if (ospf_lsa_compareToListMem(ospf, l, lsa))
359 ospf_list_deleteIterator(pass);
363 ospf_list_deleteIterator(pass);
369static void ospf_lsdb_removeLSAFromList(ptrOSPFLIST list,
372 if (ospf_list_is_empty(list))
376 void* pass = ospf_list_newIterator();
377 while ((l = ospf_list_iterate_mem(list, pass)) != NULL)
379 if (!OSPFID_COMPARE(l->AdvertisingRouter, lsa->AdvertisingRouter) &&
380 !OSPFID_COMPARE(l->LinkStateID, lsa->LinkStateID))
381 ospf_list_delete_mem(list, l, pass);
383 ospf_list_deleteIterator(pass);
386static void ospf_lsdb_removeFromSendList(ptrOSPF_PDS ospf,
391 for (i = 0; i < ospf->ifCount; i++)
393 ptrOSPF_IF thisInterface = ospf->ospfIf[i];
396 if (OSPFID_COMPARE(thisInterface->areaId, areaId) &&
397 OSPFID_COMPARE(areaId, invalidAreaId))
401 for (n = 0; n < thisInterface->neighborRouterCount; n++)
403 ptrOSPF_NEIGHBOR neigh = thisInterface->neighborRouterList[n];
406 void* pass = ospf_list_newIterator();
407 while ((s = ospf_list_iterate_mem(neigh->linkStateSendList, pass)) != NULL)
409 if (s->LSType == lsa->LSType &&
410 !OSPFID_COMPARE(s->AdvertisingRouter, lsa->AdvertisingRouter) &&
411 !OSPFID_COMPARE(s->LinkStateID, lsa->LinkStateID))
413 ospf_list_delete_mem(neigh->linkStateSendList, s, pass);
416 ospf_list_deleteIterator(pass);
421void ospf_lsdb_removeLSA(ptrOSPF_PDS ospf,
425 bool removeFromSend =
true;
428 case LSTYPE_ROUTERLSA:
429 ospf_lsdb_removeLSAFromList(area->routerLSAList, lsa);
431 case LSTYPE_NETWORKLSA:
432 ospf_lsdb_removeLSAFromList(area->nwLSAList, lsa);
434 case LSTYPE_SUMMARYLSA_NETWORK:
435 ospf_lsdb_removeLSAFromList(area->nwSummaryLSAList, lsa);
437 case LSTYPE_SUMMARYLSA_ROUTER:
438 ospf_lsdb_removeLSAFromList(area->routerSummaryLSAList, lsa);
441 removeFromSend =
false;
442 fnNetSimError(
"Unknown LSTYPE %d in %s.",
443 lsa->LSType, __FUNCTION__);
449 ospf_lsdb_removeFromSendList(ospf,
455void ospf_lsdb_handleMaxAgeRemovalTimer()
457 ptrOSPF_PDS ospf = OSPF_PDS_CURRENT();
458 bool scheduledTimer =
false;
460 if (ospf_neighbor_isAnyNeighborInExchangeOrLoadingState(ospf))
462 ospf_lsdb_scheduleMaxAgeRemovalTimer(ospf);
467 ospf->isMaxAgeRemovalTimerSet =
false;
469 for (UINT i = 0; i < ospf->ifCount; i++)
471 ptrOSPF_IF thisInterface = ospf->ospfIf[i];
472 ptrOSPFAREA_DS area = OSPF_AREA_GET_ID(ospf, thisInterface->areaId);
478 void* pass = ospf_list_newIterator();
479 while ((lsa = ospf_list_iterate_mem(area->maxAgeList, pass)) != NULL)
482 areaId = thisInterface->areaId;
483 if (ospf_lsdb_isLSAInNeighborRxtList(ospf, areaId, lsa))
487 ospf_lsdb_scheduleMaxAgeRemovalTimer(ospf);
488 scheduledTimer =
true;
493 ospf_lsdb_removeLSA(ospf, area, lsa);
494 ospf_list_delete_mem(area->maxAgeList, lsa, pass);
496 ospf_list_deleteIterator(pass);
498 if (!ospf_list_is_empty(area->maxAgeList) &&
499 !ospf->isMaxAgeRemovalTimerSet &&
502 ospf_lsdb_scheduleMaxAgeRemovalTimer(ospf);
503 scheduledTimer =
true;
509static void ospf_lsdb_refreshLSA(ptrOSPF_PDS ospf,
510 ptrOSPFLSAHDR LSHeader,
513 ptrOSPFAREA_DS thisArea = OSPF_AREA_GET_ID(ospf, areaId);
514 if (LSHeader->LSSequenceNumber == OSPF_MAX_SEQUENCE_NUMBER)
518 ospf_lsa_flush(ospf, thisArea, LSHeader);
519 ospf_lsa_schedule(ospf, 0, thisArea, LSHeader);
523 LSHeader->LSSequenceNumber += 1;
525 LSHeader->time = OSPF_CURR_TIME();
527 ospf_lsa_flood(ospf, areaId, LSHeader, NULL, 0);
531static void ospf_LSDB_IncrementLSAgeInLSAList(ptrOSPF_PDS ospf,
535 ptrOSPFLSAHDR LSHeader = NULL;
536 void* pass = ospf_list_newIterator();
538 while ((LSHeader = ospf_list_iterate_mem(list, pass)) != NULL)
541 if (ospf_lsa_checkForDoNotAge(ospf, LSHeader->LSAge))
542 tempAge = ospf_lsa_maskDoNotAge(ospf, LSHeader->LSAge);
544 tempAge = ospf_lsa_maskDoNotAge(ospf, LSHeader->LSAge) +
545 ((UINT16)(ospf->incrementTime / SECOND));
547 if (tempAge > ospf->LSAMaxAge)
548 tempAge = ospf->LSAMaxAge;
550 if (ospf_lsa_maskDoNotAge(ospf, LSHeader->LSAge) ==
555 ospf_lsa_assignNewLSAge(ospf,
560 if (!OSPFID_COMPARE(LSHeader->AdvertisingRouter, ospf->routerId) &&
561 ospf_lsa_maskDoNotAge(ospf, tempAge) == ospf->LSRefreshTime / SECOND)
563 ospf_lsdb_refreshLSA(ospf, LSHeader, areaId);
566 else if (ospf_lsa_maskDoNotAge(ospf, tempAge) == ospf->LSAMaxAge)
573 ospf_lsa_addToMaxAgeLSAList(ospf, areaId, LSHeader);
574 ospf_spf_scheduleCalculation(ospf);
577 ospf_list_deleteIterator(pass);
580static void ospf_LSDB_removeStaleDoNotAgeLSA(ptrOSPF_PDS ospf)
582 ptrOSPFAREA_DS thisArea = NULL;
583 ptrOSPFLSAHDR LSHeader = NULL;
587 for (i = 0; i < ospf->areaCount; i++)
589 thisArea = ospf->areaDS[i];
590 pass = ospf_list_newIterator();
591 while ((LSHeader = ospf_list_iterate_mem(thisArea->nwLSAList, pass)) != NULL)
594 if (ospf_lsa_checkForDoNotAge(ospf, LSHeader->LSAge))
597 if ((OSPF_CURR_TIME() - LSHeader->time) >= ospf->LSAMaxAge)
600 ospf_lsa_flush(ospf, thisArea, LSHeader);
601 ospf_lsdb_removeLSA(ospf, thisArea, LSHeader);
605 ospf_list_deleteIterator(pass);
606 pass = ospf_list_newIterator();
607 while ((LSHeader = ospf_list_iterate_mem(thisArea->routerLSAList, pass)) != NULL)
610 if (ospf_lsa_checkForDoNotAge(ospf, LSHeader->LSAge))
613 if ((OSPF_CURR_TIME() - LSHeader->time) >= ospf->LSAMaxAge)
616 ospf_lsa_flush(ospf, thisArea, LSHeader);
617 ospf_lsdb_removeLSA(ospf, thisArea, LSHeader);
621 ospf_list_deleteIterator(pass);
622 pass = ospf_list_newIterator();
623 while ((LSHeader = ospf_list_iterate_mem(thisArea->nwSummaryLSAList, pass)) != NULL)
626 if (ospf_lsa_checkForDoNotAge(ospf, LSHeader->LSAge))
629 if ((OSPF_CURR_TIME() - LSHeader->time) >= ospf->LSAMaxAge)
632 ospf_lsa_flush(ospf, thisArea, LSHeader);
633 ospf_lsdb_removeLSA(ospf, thisArea, LSHeader);
637 ospf_list_deleteIterator(pass);
638 pass = ospf_list_newIterator();
639 while ((LSHeader = ospf_list_iterate_mem(thisArea->routerSummaryLSAList, pass)) != NULL)
642 if (ospf_lsa_checkForDoNotAge(ospf, LSHeader->LSAge))
645 if ((OSPF_CURR_TIME() - LSHeader->time) >= ospf->LSAMaxAge)
648 ospf_lsa_flush(ospf, thisArea, LSHeader);
649 ospf_lsdb_removeLSA(ospf, thisArea, LSHeader);
653 ospf_list_deleteIterator(pass);
657static void ospf_lsdb_incrementLSAge(ptrOSPF_PDS ospf)
660 for (i = 0; i < ospf->areaCount; i++)
662 ptrOSPFAREA_DS thisArea = ospf->areaDS[i];
663 ospf_LSDB_IncrementLSAgeInLSAList(ospf,
666 ospf_LSDB_IncrementLSAgeInLSAList(ospf,
667 thisArea->routerLSAList,
669 ospf_LSDB_IncrementLSAgeInLSAList(ospf,
670 thisArea->nwSummaryLSAList,
672 ospf_LSDB_IncrementLSAgeInLSAList(ospf,
673 thisArea->routerSummaryLSAList,
686 ospf_LSDB_removeStaleDoNotAgeLSA(ospf);
689void ospf_LSDB_handle_IncrementAge_event()
691 print_ospf_log(OSPF_LOG,
"Router %d, Increment Age event is triggered at time %0.3lf",
692 pstruEventDetails->nDeviceId,
693 pstruEventDetails->dEventTime / MILLISECOND);
695 ptrOSPF_PDS ospf = OSPF_PDS_CURRENT();
697 ospf_event_add(OSPF_CURR_TIME() + ospf->incrementTime,
699 pstruEventDetails->nInterfaceId,
700 pstruEventDetails->nSubEventType,
705 ospf_lsdb_incrementLSAge(ospf);