15#include "NetSim_utility.h"
19#include "OSPF_Neighbor.h"
20#include "OSPF_Interface.h"
21#include "OSPF_RoutingTable.h"
24static void ospf_lsa_printHdr(
char* logid,
25 ptrOSPFLSAHDR LSHeader)
27 print_ospf_Dlog(logid,
"Age = %d\tType = %s",
29 strLSTYPE[LSHeader->LSType]);
30 print_ospf_Dlog(logid,
"Link state id = %s",
31 LSHeader->LinkStateID->str_ip);
32 print_ospf_Dlog(logid,
"Advertising router = %s",
33 LSHeader->AdvertisingRouter->str_ip);
34 print_ospf_Dlog(logid,
"seq number = %d",
35 LSHeader->LSSequenceNumber);
38void ospf_lsa_print(
char* logid,
39 ptrOSPFLSAHDR LSHeader,
42 if (!ospf_dlog_isEnable(logid))
45 print_ospf_Dlog(logid,
"\n.....Time %lf.........\n",
47 print_ospf_Dlog(logid, msg);
48 ospf_lsa_printHdr(logid, LSHeader);
49 switch (LSHeader->LSType)
51 case LSTYPE_ROUTERLSA:
52 ospf_lsa_printRLSA(logid, LSHeader->lsaInfo);
55 fnNetSimError(
"Unknown LS Type %s in %s",
56 strLSTYPE[LSHeader->LSType], __FUNCTION__);
61void ospf_lsa_printList(
char* logid,
65 if (!ospf_dlog_isEnable(logid))
68 print_ospf_Dlog(logid,
"\n.......Time = %lf, %s..........",
71 print_ospf_Dlog(logid,
"Item Count = %d", ospf_list_get_size(list));
72 ptrOSPFLSAHDR lsa = NULL;
73 void* pass = ospf_list_newIterator();
74 while ((lsa=ospf_list_iterate_mem(list,pass))!=NULL)
76 ospf_lsa_print(logid, lsa, name);
78 ospf_list_deleteIterator(pass);
81void ospf_lsa_schedule_routerLSA(ptrOSPF_PDS ospf,
87 if (area->isRouterLSTimer)
90 area->isRouterLSTimer =
true;
93 if (!area->lastLSAOriginateTime)
94 delay = NETSIM_RAND_01() * OSPF_BROADCAST_JITTER + 1;
95 else if (OSPF_CURR_TIME() - area->lastLSAOriginateTime >=
97 delay = NETSIM_RAND_01() * OSPF_BROADCAST_JITTER;
99 delay = ospf->minLSInterval -
100 (OSPF_CURR_TIME() - area->lastLSAOriginateTime);
102 ptrEVENTLSDB lsdb = calloc(1,
sizeof* lsdb);
103 lsdb->lsType = LSTYPE_ROUTERLSA;
105 lsdb->isFlush = isFlush;
106 ospf_event_add(pstruEventDetails->dEventTime + delay,
107 pstruEventDetails->nDeviceId,
108 pstruEventDetails->nInterfaceId,
114void ospf_lsa_scheduleNWLSA(ptrOSPF_PDS ospf,
115 ptrOSPF_IF thisInterface,
120 ptrOSPFLSAHDR oldLSA = ospf_lsdb_lookup_lsaList(area->nwLSAList,
122 thisInterface->IPIfAddr);
124 bool isHaveAdjNeigh =
false;
125 isHaveAdjNeigh = ospf_is_dr_router_fulladjacentwithAnother(thisInterface);
127 if (isHaveAdjNeigh && !isFlush)
130 else if (oldLSA && (!isHaveAdjNeigh || isFlush))
135 if (thisInterface->networkLSTimer && !isFlush)
138 thisInterface->networkLSTimerSeqNumber++;
140 if (thisInterface->networkLSAOriginateTime == 0 ||
141 OSPF_CURR_TIME() - thisInterface->networkLSAOriginateTime >=
144 delay = NETSIM_RAND_01()*OSPF_BROADCAST_JITTER;
148 delay = ospf->minLSInterval -
149 (OSPF_CURR_TIME() - thisInterface->networkLSAOriginateTime);
152 thisInterface->networkLSTimer =
true;
153 ptrEVENTLSDB l = calloc(1,
sizeof* l);
155 l->isFlush = isFlush;
156 l->lsType = LSTYPE_NETWORKLSA;
157 l->nwLSASeqNum = thisInterface->networkLSTimerSeqNumber;
159 ospf_event_add(OSPF_CURR_TIME() + delay,
167void ospf_lsa_scheduleSummaryLSA(ptrOSPF_PDS ospf,
168 ptrOSPF_IF thisInterface,
170 NETSIM_IPAddress destAddr,
171 NETSIM_IPAddress destMask,
172 OSPFDESTTYPE destType,
175 ptrEVENTLSDB l = calloc(1,
sizeof* l);
177 l->destAddr = destAddr;
178 l->destMask = destMask;
179 l->isFlush = isFlush;
180 l->destType = destType;
181 if (destType == OSPFDESTTYPE_NETWORK)
182 l->lsType = LSTYPE_SUMMARYLSA_NETWORK;
183 else if (destType == OSPFDESTTYPE_ROUTER)
184 l->lsType = LSTYPE_SUMMARYLSA_ROUTER;
186 ospf_event_add(OSPF_CURR_TIME() + ospf->minLSInterval,
194void OSPFLSAINFO_FREE(ptrOSPFLSAHDR lsa)
198 case LSTYPE_ROUTERLSA:
199 OSPFLSAINFO_FREE_RLSA(lsa->lsaInfo);
201 case LSTYPE_NETWORKLSA:
202 case LSTYPE_SUMMARYLSA_NETWORK:
203 case LSTYPE_SUMMARYLSA_ROUTER:
205 fnNetSimError(
"Unknown LSTYPE %d in %s",
212void* OSPFLSAINFO_COPY(ptrOSPFLSAHDR lsa)
216 case LSTYPE_ROUTERLSA:
217 return OSPFLSAINFO_COPY_RLSA(lsa->lsaInfo);
219 case LSTYPE_NETWORKLSA:
220 case LSTYPE_SUMMARYLSA_NETWORK:
221 case LSTYPE_SUMMARYLSA_ROUTER:
223 fnNetSimError(
"Unknown LSTYPE %d in %s",
231void OSPF_LSA_MSG_FREE(ptrOSPFLSAHDR hdr)
233 OSPFLSAINFO_FREE(hdr);
237ptrOSPFLSAHDR OSPF_LSA_MSG_COPY(ptrOSPFLSAHDR hdr)
239 ptrOSPFLSAHDR lsa = calloc(1,
sizeof* lsa);
240 memcpy(lsa, hdr,
sizeof* lsa);
241 lsa->lsaInfo = OSPFLSAINFO_COPY(hdr);
245ptrOSPFLSAHDR OSPF_LSA_HDR_COPY(ptrOSPFLSAHDR lsa)
247 ptrOSPFLSAHDR l = calloc(1,
sizeof* l);
248 memcpy(l, lsa,
sizeof* l);
253void OSPF_LSA_HDR_FREE(ptrOSPFLSAHDR lsa)
258ptrOSPFLSAHDR ospf_lsa_find_old_lsa(ptrOSPFLIST list,
262 void* pass = ospf_list_newIterator();
263 ptrOSPFLSAHDR hdr = NULL;
264 while ((hdr = ospf_list_iterate_mem(list, pass)) != NULL)
266 if (!OSPFID_COMPARE(hdr->AdvertisingRouter, rid) &&
267 !OSPFID_COMPARE(hdr->LinkStateID, lid))
269 ospf_list_deleteIterator(pass);
273 ospf_list_deleteIterator(pass);
277bool ospf_lsa_update_lsahdr(ptrOSPF_PDS ospf,
283 lsa->LSType = lstype;
284 lsa->length = OSPFLSAHDR_LEN;
287 if (old->LSSequenceNumber == OSPF_MAX_SEQUENCE_NUMBER &&
288 ospf_lsa_maskDoNotAge(ospf,old->LSAge) < ospf->LSAMaxAge)
290 ospf_lsa_flush(ospf, area, old);
293 else if (ospf_lsa_maskDoNotAge(ospf,old->LSAge) == ospf->LSAMaxAge)
299 lsa->LSSequenceNumber = old->LSSequenceNumber + 1;
303 lsa->LSSequenceNumber = OSPF_INITIAL_SEQUENCE_NUMBER;
308void ospf_lsahdr_add_lsa(ptrOSPFLSAHDR lhdr,
316static void ospf_lsa_removeFromRxtList(ptrOSPF_PDS ospf,
321 for (i = 0; i < ospf->ifCount; i++)
323 ptrOSPF_IF ospfIf = ospf->ospfIf[i];
324 if (OSPFID_COMPARE(area, ospfIf->areaId))
327 for (n = 0; n < ospfIf->neighborRouterCount; n++)
329 ptrOSPF_NEIGHBOR neigh = ospfIf->neighborRouterList[n];
331 ospf_lsa_printList(form_dlogId(
"RXTLIST", ospf->myId), neigh->neighLSRxtList,
"before Rxlist remove");
332 void* pass = ospf_list_newIterator();
333 while ((hdr = ospf_list_iterate_mem(neigh->neighLSRxtList, pass)) != NULL)
335 if (!OSPFID_COMPARE(lsa->LinkStateID, hdr->LinkStateID) &&
336 lsa->LSType == hdr->LSType &&
337 !OSPFID_COMPARE(lsa->AdvertisingRouter, hdr->AdvertisingRouter))
339 ospf_list_delete_mem(neigh->neighLSRxtList, hdr, pass);
342 ospf_list_deleteIterator(pass);
343 ospf_lsa_printList(form_dlogId(
"RXTLIST", ospf->myId), neigh->neighLSRxtList,
"after Rxlist remove");
344 if (ospf_list_is_empty(neigh->neighLSRxtList) &&
347 neigh->LSRxtTimer =
false;
348 neigh->LSRxtSeqNum++;
354bool ospf_lsa_checkForDoNotAge(ptrOSPF_PDS ospf,
359 if (routerLSAAge & OSPF_DO_NOT_AGE)
370UINT16 ospf_lsa_maskDoNotAge(ptrOSPF_PDS ospf,
373 if (ospf_lsa_checkForDoNotAge(ospf, routerLSAAge))
374 return routerLSAAge & ~OSPF_DO_NOT_AGE;
379void ospf_lsa_assignNewLSAge(ptrOSPF_PDS ospf,
380 UINT16* routerLSAAge,
383 if (ospf_lsa_checkForDoNotAge(ospf, *routerLSAAge))
385 *routerLSAAge = OSPF_DO_NOT_AGE | newLSAAge;
389 *routerLSAAge = newLSAAge;
393static INT16 ospf_lsa_DiffOfAge(ptrOSPF_PDS ospf,
397 a1 = ospf_lsa_maskDoNotAge(ospf, a1);
398 a2 = ospf_lsa_maskDoNotAge(ospf, a2);
403int ospf_lsa_compare(ptrOSPF_PDS ospf,
408 if (newLS->LSSequenceNumber > oldLS->LSSequenceNumber)
411 if (oldLS->LSSequenceNumber > newLS->LSSequenceNumber)
414 if (ospf_lsa_maskDoNotAge(ospf, newLS->LSAge) >= ospf->LSAMaxAge &&
415 ospf_lsa_maskDoNotAge(ospf, oldLS->LSAge) < ospf->LSAMaxAge)
418 if (ospf_lsa_maskDoNotAge(ospf, oldLS->LSAge) >= ospf->LSAMaxAge &&
419 ospf_lsa_maskDoNotAge(ospf, newLS->LSAge) < ospf->LSAMaxAge)
422 if ((abs(ospf_lsa_DiffOfAge(ospf, newLS->LSAge, oldLS->LSAge)) >
423 OSPF_LSA_MAX_AGE_DIFF / SECOND) &&
424 (ospf_lsa_maskDoNotAge(ospf, newLS->LSAge) <
425 ospf_lsa_maskDoNotAge(ospf, oldLS->LSAge)))
428 if ((abs(ospf_lsa_DiffOfAge(ospf, newLS->LSAge, oldLS->LSAge)) >
429 OSPF_LSA_MAX_AGE_DIFF / SECOND) &&
430 (ospf_lsa_maskDoNotAge(ospf, newLS->LSAge) >
431 ospf_lsa_maskDoNotAge(ospf, oldLS->LSAge)))
437bool ospf_lsa_compareToListMem(ptrOSPF_PDS ospf,
441 if (oldLS->LSType == newLS->LSType &&
442 !OSPFID_COMPARE(oldLS->AdvertisingRouter, newLS->AdvertisingRouter) &&
443 !OSPFID_COMPARE(oldLS->LinkStateID, newLS->LinkStateID) &&
444 !ospf_lsa_compare(ospf, oldLS, newLS))
449void ospf_lsa_queueToFlood(ptrOSPF_PDS ospf,
450 ptrOSPF_IF thisInterface,
453 void* item = ospf_list_newIterator();
454 ptrOSPFLSAHDR hdr = NULL;
455 ptrOSPFLSAHDR updateLSA = OSPF_LSA_MSG_COPY(lsa);
456 while ((hdr = ospf_list_iterate_mem(thisInterface->updateLSAList, item)) != NULL)
458 if (hdr->LSAge == lsa->LSAge &&
459 !OSPFID_COMPARE(hdr->LinkStateID, lsa->LinkStateID) &&
460 !OSPFID_COMPARE(hdr->AdvertisingRouter, lsa->AdvertisingRouter))
462 if (ospf_lsa_compare(ospf, hdr, lsa) > 0)
464 ospf_list_delete_mem(thisInterface->updateLSAList, hdr, item);
465 ospf_list_add_mem(thisInterface->updateLSAList, updateLSA);
470 ospf_list_deleteIterator(item);
471 ospf_list_add_mem(thisInterface->updateLSAList, updateLSA);
474bool ospf_lsa_flood(ptrOSPF_PDS pds,
477 NETSIM_IPAddress srcAddr,
480 bool floodBack =
false;
481 ptrOSPFLIST list = ospf_list_init(NULL, NULL);
483 ospf_lsa_removeFromRxtList(pds, area, lsa);
485 for (i = 0; i < pds->ifCount; i++)
487 bool isAddedToRxtList =
false;
488 ptrOSPF_IF ospf = pds->ospfIf[i];
490 if (ospf->State == OSPFIFSTATE_DOWN)
493 if (OSPFID_COMPARE(ospf->areaId, area))
497 for (n = 0; n < ospf->neighborRouterCount; n++)
499 ptrOSPF_NEIGHBOR neigh = ospf->neighborRouterList[n];
500 if(neigh->state <OSPFNEIGHSTATE_Exchange)
503 if (neigh->state != OSPFNEIGHSTATE_Full)
505 ptrOSPFLSAHDR lsHdr = ospf_lsReq_searchFromList(neigh, lsa);
509 int isRecent = ospf_lsa_compare(pds, lsHdr, lsa);
514 ospf_lsreq_removeFromReqList(neigh->neighLSReqList, lsHdr);
516 if (ospf_list_is_empty(neigh->neighLSReqList) &&
517 neigh->state == OSPFNEIGHSTATE_Loading)
520 neigh->LSRxtSeqNum += 1;
521 ospf_event_set_and_call(OSPF_LoadingDone,
528 ospf_lsreq_removeFromReqList(neigh->neighLSReqList, lsHdr);
530 if (ospf_list_is_empty(neigh->neighLSReqList) &&
531 neigh->state == OSPFNEIGHSTATE_Loading)
534 neigh->LSRxtSeqNum += 1;
535 ospf_list_add_mem(list, neigh);
541 if (!srcAddr || !IP_COMPARE(srcAddr, neigh->neighborIPAddr))
544 ptrOSPFLSAHDR rxtlsa = OSPF_LSA_MSG_COPY(lsa);
545 ospf_list_add_mem(neigh->neighLSRxtList, rxtlsa);
546 ospf_lsa_printList(form_dlogId(
"RXTLIST", pds->myId), neigh->neighLSRxtList,
"add Rxlist");
547 isAddedToRxtList =
true;
549 if (!isAddedToRxtList)
552 if (ospf->Type == OSPFIFTYPE_BROADCAST &&
553 IP_COMPARE(srcAddr, ANY_DEST) &&
556 if (!IP_COMPARE(srcAddr, ospf->designaterRouter) ||
557 !IP_COMPARE(srcAddr, ospf->backupDesignaterRouter))
560 if (ospf->State == OSPFIFSTATE_BACKUP)
564 if (IP_COMPARE(srcAddr, ANY_DEST) &&
568 ospf_lsa_queueToFlood(pds, ospf, lsa);
570 if (!ospf->isFloodTimerSet)
572 double t = pstruEventDetails->dEventTime;
573 t = max(t, ospf->lastFloodTimer + pds->minLSInterval);
574 t += pds->dFloodTimer*NETSIM_RAND_01();
576 pstruEventDetails->nDeviceId,
581 ospf->lastFloodTimer = t;
582 ospf->isFloodTimerSet =
true;
586 void* pass = ospf_list_newIterator();
587 ptrOSPF_NEIGHBOR neigh;
588 while ((neigh = ospf_list_iterate_mem(list, pass)) != NULL)
589 ospf_event_set_and_call(OSPF_LoadingDone, neigh);
590 ospf_list_deleteIterator(pass);
591 ospf_list_destroy(list);
595static bool ospf_lsa_isBodyChanged(ptrOSPFLSAHDR newLSA,
596 ptrOSPFLSAHDR oldLSA)
598 switch (newLSA->LSType)
600 case LSTYPE_ROUTERLSA:
601 return ospf_rlsa_isBodyChanged(newLSA, oldLSA);
602 case LSTYPE_NETWORKLSA:
603 case LSTYPE_SUMMARYLSA_ROUTER:
604 case LSTYPE_SUMMARYLSA_NETWORK:
605 case LSTYPE_ASEXTERNALLSA:
606 fnNetSimError(
"Implement lsa_isbodychange function");
607#pragma message(__LOC__"Implement lsa_isbodychange function")
610 fnNetSimError(
"Unknown LS Type %d in %s\n",
611 newLSA->LSType, __FUNCTION__);
617bool ospf_lsa_is_content_changed(ptrOSPF_PDS ospf,
618 ptrOSPFLSAHDR newLSA,
619 ptrOSPFLSAHDR oldLSA)
621 if (newLSA->Options != oldLSA->Options)
624 if ((ospf_lsa_maskDoNotAge(ospf, newLSA->LSAge) == ospf->LSAMaxAge &&
625 ospf_lsa_maskDoNotAge(ospf, oldLSA->LSAge) != ospf->LSAMaxAge) ||
626 (ospf_lsa_maskDoNotAge(ospf, newLSA->LSAge) != ospf->LSAMaxAge &&
627 ospf_lsa_maskDoNotAge(ospf, oldLSA->LSAge) == ospf->LSAMaxAge))
630 if (newLSA->length != oldLSA->length)
633 if (ospf_lsa_isBodyChanged(newLSA, oldLSA))
639void ospf_lsa_assignNewLSAIntoLSOrigin(ptrOSPF_PDS ospf,
641 ptrOSPFLSAHDR newLSA)
644 ptrOSPFROUTINGTABLE rtTable = ospf->routingTable;
646 for (i = 0; i < rtTable->numRow; i++)
648 ptrOSPFROUTINGTABLEROW row = rtTable->rows[i];
649 if (row->LSOrigin == LSA)
650 row->LSOrigin = newLSA;
654bool ospf_lsa_hasMaxAge(ptrOSPF_PDS ospf,
657 return ospf_lsa_maskDoNotAge(ospf, lsa->LSAge) == ospf->LSAMaxAge;
660static bool ospf_lsa_isPresentInMaxAgeList(ptrOSPF_PDS ospf,
665 void* pass = ospf_list_newIterator();
666 while ((hdr = ospf_list_iterate_mem(list, pass)) != NULL)
668 if (hdr->LSType == lsa->LSType &&
669 !OSPFID_COMPARE(hdr->LinkStateID, lsa->LinkStateID) &&
670 !OSPFID_COMPARE(hdr->AdvertisingRouter, lsa->AdvertisingRouter) &&
671 !ospf_lsa_compare(ospf, lsa, hdr))
673 ospf_list_deleteIterator(pass);
677 ospf_list_deleteIterator(pass);
681void ospf_lsa_addToMaxAgeLSAList(ptrOSPF_PDS ospf,
685 ptrOSPFAREA_DS area = OSPF_AREA_GET_ID(ospf, areaId);
687 if (!ospf_lsa_isPresentInMaxAgeList(ospf, area->maxAgeList, lsa))
689 ptrOSPFLSAHDR newLSA = OSPF_LSA_MSG_COPY(lsa);
690 ospf_list_add_mem(area->maxAgeList, newLSA);
692 if (!ospf->isMaxAgeRemovalTimerSet)
694 ospf_lsdb_scheduleMaxAgeRemovalTimer(ospf);
699void ospf_lsa_ScheduleLSDB()
701 ptrEVENTLSDB lsdb = pstruEventDetails->szOtherDetails;
702 LSTYPE lsType = lsdb->lsType;
704 if (lsType == LSTYPE_ROUTERLSA)
706 ospf_rlsa_originateRouterLSA(lsdb->area, lsdb->isFlush);
710 fnNetSimError(
"write other condition for different LSA type");
711#pragma message(__LOC__"write other condition for different LSA type")
716void ospf_lsa_handle_floodTimer_event()
718 ptrOSPF_IF ospf = OSPF_IF_CURRENT();
719 if (!ospf->isFloodTimerSet)
721 ospf_lsupdate_send();
722 ospf->isFloodTimerSet =
false;
725int ospf_lsa_isMoreRecent(ptrOSPF_PDS ospf, ptrOSPFLSAHDR newLSA, ptrOSPFLSAHDR oldLSA)
731 return ospf_lsa_compare(ospf, oldLSA, newLSA);
734bool ospf_lsa_isSelfOriginated(ptrOSPF_PDS ospf,
737 if (!OSPFID_COMPARE(lsa->AdvertisingRouter, ospf->routerId) ||
738 (ospf_isMyAddr(ospf->myId, lsa->LinkStateID) &&
739 lsa->LSType == LSTYPE_NETWORKLSA))
745void ospf_lsa_flush(ptrOSPF_PDS ospf,
749 if (lsa->LSAge == ospf->LSAMaxAge)
752 lsa->LSAge = ospf->LSAMaxAge;
754 ospf_lsa_flood(ospf, area->areaId, lsa, ANY_DEST, 0);
755 ospf_lsa_addToMaxAgeLSAList(ospf, area->areaId, lsa);
756 ospf_spf_scheduleCalculation(ospf);
759void ospf_lsa_schedule(ptrOSPF_PDS ospf,
760 ptrOSPF_IF thisInterface,
766 case LSTYPE_ROUTERLSA:
767 ospf_lsa_schedule_routerLSA(ospf,
771 case LSTYPE_NETWORKLSA:
772 ospf_lsa_scheduleNWLSA(ospf,
777 case LSTYPE_SUMMARYLSA_NETWORK:
778 ospf_lsa_scheduleSummaryLSA(ospf,
783 OSPFDESTTYPE_NETWORK,
786 case LSTYPE_SUMMARYLSA_ROUTER:
787 ospf_lsa_scheduleSummaryLSA(ospf,
796 fnNetSimError(
"Unknown LS type %s in %s",
797 strLSTYPE[lsa->LSType],
802static bool ospf_nwlsa_hasLink(ptrOSPF_PDS ospf,
809#pragma message(__LOC__"Implement after NW LSA implementation")
810 fnNetSimError(
"Implement after NW LSA implementation");
814bool ospf_lsa_hasLink(ptrOSPF_PDS ospf,
818 if (wlsa->LSType == LSTYPE_ROUTERLSA)
819 return ospf_rlsa_hasLink(ospf, wlsa, vlsa);
820 else if (wlsa->LSType == LSTYPE_NETWORKLSA)
821 return ospf_nwlsa_hasLink(ospf, wlsa, vlsa);