17#include "OSPF_Neighbor.h"
19#include "OSPF_Interface.h"
22#define is_neighbor_DR(ospf,neigh) (!OSPFID_COMPARE(ospf->designaterRouter,neigh->neighborId))
23#define is_neighbor_backupDR(ospf, neigh) (!OSPFID_COMPARE(ospf->backupDesignaterRouter,neigh->neighborId))
25static void ospf_neighbor_attempt_adjacency(ptrOSPF_NEIGHBOR neigh)
30 print_ospf_log(OSPF_LOG,
"New DD seq no is %d", neigh->DDSeqNo);
34 print_ospf_log(OSPF_LOG,
"First time adjacency is attempted. Declaring itself as master.");
35 neigh->isMaster =
true;
36 neigh->DDSeqNo = (UINT)(pstruEventDetails->dEventTime / MILLISECOND);
37 print_ospf_log(OSPF_LOG,
"New DD seq no is %d", neigh->DDSeqNo);
38 print_ospf_log(OSPF_LOG,
"Start sending DD msg");
39 start_sending_dd_msg();
43static void ospf_neighbor_change_state(ptrOSPF_NEIGHBOR neigh,
46 OSPFNEIGHSTATE oldState = neigh->state;
47 print_ospf_log(OSPF_LOG,
"Neighbor(%s) state changed to %s from %s",
48 neigh->neighborId->str_ip,
49 strNeighborState[state],
50 strNeighborState[neigh->state]);
54 if ((oldState != state) && (state == OSPFNEIGHSTATE_ExStart))
57 ospf_neighbor_attempt_adjacency(neigh);
61 if ((oldState == OSPFNEIGHSTATE_Full &&
62 neigh->state != OSPFNEIGHSTATE_Full) ||
63 (oldState != OSPFNEIGHSTATE_Full &&
64 neigh->state == OSPFNEIGHSTATE_Full))
66 ptrOSPF_PDS ospf = OSPF_PDS_CURRENT();
67 ptrOSPF_IF thisInterface = OSPF_IF_CURRENT();
68 ptrOSPFAREA_DS area = OSPF_AREA_GET_IN(ospf, pstruEventDetails->nInterfaceId);
69 ospf_lsa_schedule_routerLSA(ospf, area,
false);
70 if (thisInterface->State == OSPFIFSTATE_DR)
72 ospf_lsa_scheduleNWLSA(ospf,
79 if ((oldState < OSPFNEIGHSTATE_2Way &&
80 state >= OSPFNEIGHSTATE_2Way) ||
81 (oldState >= OSPFNEIGHSTATE_2Way &&
82 state < OSPFNEIGHSTATE_2Way))
84 ospf_event_add(pstruEventDetails->dEventTime,
85 pstruEventDetails->nDeviceId,
86 pstruEventDetails->nInterfaceId,
93ptrOSPF_NEIGHBOR OSPF_NEIGHBOR_FIND(ptrOSPF_IF ospf, OSPFID
id)
96 for (i = 0; i < ospf->neighborRouterCount; i++)
98 ptrOSPF_NEIGHBOR neigh = ospf->neighborRouterList[i];
99 if (!OSPFID_COMPARE(neigh->neighborId,
id) ||
100 !OSPFID_COMPARE(neigh->neighborIPAddr,
id))
106ptrOSPF_NEIGHBOR OSPF_NEIGHBOR_FIND_BY_IP(ptrOSPF_IF thisInterface, NETSIM_IPAddress ip)
109 for (i = 0; i < thisInterface->neighborRouterCount; i++)
111 ptrOSPF_NEIGHBOR neigh = thisInterface->neighborRouterList[i];
112 if (!IP_COMPARE(neigh->neighborIPAddr, ip))
118ptrOSPF_NEIGHBOR ospf_neighbor_new(NETSIM_IPAddress ip,
121 ptrOSPF_NEIGHBOR neigh;
122 neigh = calloc(1,
sizeof* neigh);
123 neigh->devId = fn_NetSim_Stack_GetDeviceId_asIP(rid, &neigh->devInterface);
124 neigh->neighborId = rid;
125 neigh->neighborIPAddr = ip;
127 ospf_neighbor_change_state(neigh, OSPFNEIGHSTATE_DOWN);
129 neigh->neighLSReqList = ospf_lsreq_initList();
130 neigh->neighLSRxtList = ospf_list_init(OSPF_LSA_MSG_FREE, OSPF_LSA_MSG_COPY);
131 neigh->neighDBSummaryList = ospf_list_init(OSPF_LSA_MSG_FREE, OSPF_LSA_MSG_COPY);
132 neigh->linkStateSendList = ospf_list_init(OSPF_LSA_MSG_FREE, OSPF_LSA_MSG_COPY);
137void ospf_neighbor_add(ptrOSPF_IF ospf, ptrOSPF_NEIGHBOR neigh)
139 if (ospf->neighborRouterCount)
140 ospf->neighborRouterList = realloc(ospf->neighborRouterList,
141 (ospf->neighborRouterCount + 1) * (
sizeof* ospf->neighborRouterList));
143 ospf->neighborRouterList = calloc(1,
sizeof* ospf->neighborRouterList);
144 ospf->neighborRouterList[ospf->neighborRouterCount] = neigh;
145 ospf->neighborRouterCount++;
148void ospf_neighbor_remove(ptrOSPF_PDS ospf, ptrOSPF_IF thisInterface, ptrOSPF_NEIGHBOR neigh)
153 for (n = 0; n < thisInterface->neighborRouterCount; n++)
155 if (thisInterface->neighborRouterList[n] == neigh)
158 thisInterface->neighborRouterList[n] = thisInterface->neighborRouterList[n + 1];
161 thisInterface->neighborRouterCount--;
163 ospf_list_delete_all(neigh->linkStateSendList);
164 ospf_list_destroy(neigh->linkStateSendList);
166 ospf_list_delete_all(neigh->neighDBSummaryList);
167 ospf_list_destroy(neigh->neighDBSummaryList);
169 ospf_list_delete_all(neigh->neighLSReqList);
170 ospf_list_destroy(neigh->neighLSReqList);
172 ospf_list_delete_all(neigh->neighLSRxtList);
173 ospf_list_destroy(neigh->neighLSRxtList);
175 OSPF_HDR_FREE(neigh->lastrecvDDPacket);
176 OSPF_HDR_FREE(neigh->lastSentDDPacket);
178 fnDeleteEvent(neigh->inactivityTimerId);
179 neigh->inactivityTimerId =
false;
183void ospf_neighbor_handle_1way_event()
185 ptrOSPF_NEIGHBOR neigh = pstruEventDetails->szOtherDetails;
187 print_ospf_log(OSPF_LOG,
"Time %0.4lf, Router %d, Interface %d (%s) 1-way event is triggered for neighbor %s",
188 pstruEventDetails->dEventTime/MILLISECOND,
189 pstruEventDetails->nDeviceId,
190 pstruEventDetails->nInterfaceId,
191 DEVICE_MYIP()->str_ip,
192 neigh->neighborId->str_ip);
194 if (neigh->state == OSPFNEIGHSTATE_2Way)
195 ospf_neighbor_change_state(neigh, OSPFNEIGHSTATE_Init);
197 print_ospf_log(OSPF_LOG,
"\n");
200static bool is_adjacency_should_established(ptrOSPF_IF ospf,
201 ptrOSPF_NEIGHBOR neigh)
203 if (ospf->Type == OSPFIFTYPE_P2P ||
204 ospf->Type == OSPFIFTYPE_P2MP ||
205 ospf->Type == OSPFIFTYPE_VIRTUALLINK)
208 if (ospf->State == OSPFIFSTATE_DR)
211 if (ospf->State == OSPFIFSTATE_BACKUP)
214 if (is_neighbor_DR(ospf, neigh))
217 if (is_neighbor_backupDR(ospf, neigh))
223static void ospf_handle_2wayReceived_event_in_init_state(ptrOSPF_IF ospf,
224 ptrOSPF_NEIGHBOR neigh)
226 print_ospf_log(OSPF_LOG,
"Neighbor state is Init");
228 bool isAdjacency = is_adjacency_should_established(ospf, neigh);
231 print_ospf_log(OSPF_LOG,
"Adjacency is required");
232 ospf_neighbor_change_state(neigh, OSPFNEIGHSTATE_ExStart);
236 print_ospf_log(OSPF_LOG,
"Adjacency is not required");
237 ospf_neighbor_change_state(neigh, OSPFNEIGHSTATE_2Way);
241void ospf_neighbor_handle_2wayReceived_event()
243 ptrOSPF_IF ospf = OSPF_IF_CURRENT();
244 ptrOSPF_NEIGHBOR neigh = pstruEventDetails->szOtherDetails;
246 print_ospf_log(OSPF_LOG,
"Time %0.4lf: Router %d, interface %d (%s) 2-Way received event triggered for neighbor %s",
247 pstruEventDetails->dEventTime / MILLISECOND,
248 pstruEventDetails->nDeviceId,
249 pstruEventDetails->nInterfaceId,
250 DEVICE_MYIP()->str_ip,
251 neigh->neighborId->str_ip);
253 if (neigh->state == OSPFNEIGHSTATE_Init)
254 ospf_handle_2wayReceived_event_in_init_state(ospf, neigh);
255 print_ospf_log(OSPF_LOG,
"\n");
258void ospf_neighbor_handle_helloReceived_event()
260 ptrOSPF_NEIGHBOR neigh = pstruEventDetails->szOtherDetails;
262 print_ospf_log(OSPF_LOG,
"Time %0.4lf, Router %d, interface %d (%s) HelloReceived event triggered for neighbor %s",
263 pstruEventDetails->dEventTime/MILLISECOND,
264 pstruEventDetails->nDeviceId,
265 pstruEventDetails->nInterfaceId,
266 DEVICE_MYIP()->str_ip,
267 neigh->neighborId->str_ip);
269 if (neigh->state == OSPFNEIGHSTATE_DOWN)
270 ospf_neighbor_change_state(neigh, OSPFNEIGHSTATE_Init);
272 neigh->lastHelloRecvTime = OSPF_CURR_TIME();
273 if (!neigh->isInactivityTimerAdded)
275 ptrOSPF_IF ospf = OSPF_IF_CURRENT();
277 double time = pstruEventDetails->dEventTime +
278 ospf->routerDeadInterval*SECOND;
280 print_ospf_log(OSPF_LOG,
"Adding Inactivity timer at time %0.4lf",
283 neigh->inactivityTimerId = ospf_event_add(time,
284 pstruEventDetails->nDeviceId,
285 pstruEventDetails->nInterfaceId,
286 OSPF_InactivityTimer,
289 neigh->isInactivityTimerAdded =
true;
291 print_ospf_log(OSPF_LOG,
"\n");
294static void ospf_neighbor_addToRxtList(ptrOSPF_PDS ospf,
295 ptrOSPF_IF thisInterface,
296 ptrOSPF_NEIGHBOR neigh,
299 lsa = OSPF_LSA_HDR_COPY(lsa);
301 lsa->time = OSPF_CURR_TIME();
302 ospf_list_add_mem(neigh->neighLSRxtList, lsa);
303 ospf_lsa_printList(form_dlogId(
"RXTLIST", ospf->myId), neigh->neighLSRxtList,
"add Rxlist");
304 ospf_list_add_mem(neigh->linkStateSendList, OSPF_LSA_HDR_COPY(lsa));
306 if (!neigh->LSRxtTimer)
308 ptrLSRXTTIMERDETAILS detail = calloc(1,
sizeof* detail);
309 detail->advertisingRouter = lsa->AdvertisingRouter;
310 detail->msgType = OSPFMSG_LSUPDATE;
311 detail->neighborIP = neigh->neighborIPAddr;
312 detail->rxmtSeqNum = neigh->LSRxtSeqNum;
313 ospf_event_add(OSPF_CURR_TIME() + thisInterface->RxmtInterval*SECOND,
319 neigh->LSRxtTimer =
true;
323static void ospf_neighbor_update_DBSummaryList(ptrOSPF_PDS ospf,
324 ptrOSPF_IF thisInterface,
325 ptrOSPF_NEIGHBOR neigh,
328 ptrOSPFLSAHDR lsa = NULL;
329 void* item = ospf_list_newIterator();
330 while ((lsa = ospf_list_iterate_mem(list, item)) != NULL)
333 if (ospf_lsa_maskDoNotAge(ospf, lsa->LSAge) == ospf->LSAMaxAge)
335 ospf_neighbor_addToRxtList(ospf,
342 ptrOSPFLSAHDR cpy = OSPF_LSA_HDR_COPY(lsa);
343 ospf_list_add_mem(neigh->neighDBSummaryList, cpy);
345 ospf_list_deleteIterator(item);
348static void ospf_neighbor_create_DBSummaryList(ptrOSPF_PDS pds,
350 ptrOSPF_NEIGHBOR neigh)
352 ptrOSPFAREA_DS area = OSPF_AREA_GET_IN(pds, ospf->id);
353 ospf_neighbor_update_DBSummaryList(pds, ospf, neigh, area->routerLSAList);
354 ospf_neighbor_update_DBSummaryList(pds, ospf, neigh, area->nwLSAList);
355 ospf_neighbor_update_DBSummaryList(pds, ospf, neigh, area->routerSummaryLSAList);
356 ospf_neighbor_update_DBSummaryList(pds, ospf, neigh, area->nwSummaryLSAList);
359void ospf_neighbor_handle_negotiationDone_event()
361 ptrOSPF_NEIGHBOR neigh = pstruEventDetails->szOtherDetails;
362 print_ospf_log(OSPF_LOG,
"Time %0.4lf, Router %d, Interface %d (%s), %s event is triggered for neighbor %s",
363 pstruEventDetails->dEventTime / MILLISECOND,
364 pstruEventDetails->nDeviceId,
365 pstruEventDetails->nInterfaceId,
366 DEVICE_MYIP()->str_ip,
367 GetStringOSPF_Subevent(pstruEventDetails->nSubEventType),
368 neigh->neighborId->str_ip);
369 print_ospf_log(OSPF_LOG,
"Neighbor state is %s",
370 strNeighborState[neigh->state]);
371 if(neigh->state != OSPFNEIGHSTATE_ExStart)
374 ospf_neighbor_change_state(neigh, OSPFNEIGHSTATE_Exchange);
375 print_ospf_log(OSPF_LOG,
"Creating DB summary list");
376 ospf_neighbor_create_DBSummaryList(OSPF_PDS_CURRENT(),
379 print_ospf_log(OSPF_LOG,
"");
382void ospf_neighbor_handle_exchangeDone_event()
384 ptrOSPF_PDS ospf = OSPF_PDS_CURRENT();
385 ptrOSPF_NEIGHBOR neigh = pstruEventDetails->szOtherDetails;
386 print_ospf_log(OSPF_LOG,
"Time %0.4lf, Router %d, Interface %d (%s), %s event is triggered for neighbor %s",
387 pstruEventDetails->dEventTime / MILLISECOND,
388 pstruEventDetails->nDeviceId,
389 pstruEventDetails->nInterfaceId,
390 DEVICE_MYIP()->str_ip,
391 GetStringOSPF_Subevent(pstruEventDetails->nSubEventType),
392 neigh->neighborId->str_ip);
393 print_ospf_log(OSPF_LOG,
"Neighbor state is %s",
394 strNeighborState[neigh->state]);
396 if (neigh->state != OSPFNEIGHSTATE_Exchange)
399 if (ospf_list_is_empty(neigh->neighLSReqList))
401 print_ospf_log(OSPF_LOG,
"Neighbor LSR list is empty");
402 ospf_neighbor_change_state(neigh, OSPFNEIGHSTATE_Full);
406 print_ospf_log(OSPF_LOG,
"Neighbor LSR is not empty");
407 ospf_neighbor_change_state(neigh, OSPFNEIGHSTATE_Loading);
408 ospf_lsreq_send(ospf,
409 pstruEventDetails->nInterfaceId,
410 neigh->neighborIPAddr,
413 print_ospf_log(OSPF_LOG,
"");
416void ospf_neighbor_handle_start_event()
422static void restart_inactivity_timer(ptrOSPF_IF ospf,
423 ptrOSPF_NEIGHBOR neigh)
425 double time = neigh->lastHelloRecvTime +
426 ospf->routerDeadInterval*SECOND;
428 print_ospf_log(OSPF_LOG,
"Adding Inactivity timer at time %0.4lf",
431 neigh->inactivityTimerId = ospf_event_add(time,
432 pstruEventDetails->nDeviceId,
433 pstruEventDetails->nInterfaceId,
434 OSPF_InactivityTimer,
437 neigh->isInactivityTimerAdded =
true;
440void ospf_neighbor_handle_inactivityTimer_event()
442 ptrOSPF_IF ospf = OSPF_IF_CURRENT();
443 ptrOSPF_NEIGHBOR neigh = pstruEventDetails->szOtherDetails;
445 print_ospf_log(OSPF_LOG,
"Time %0.4lf, Router %d, Interface %d (%s), "
446 "%s event is triggered for neighbor %s.",
447 pstruEventDetails->dEventTime / MILLISECOND,
448 pstruEventDetails->nDeviceId,
449 pstruEventDetails->nInterfaceId,
450 DEVICE_MYIP()->str_ip,
451 GetStringOSPF_Subevent(pstruEventDetails->nSubEventType),
452 neigh->neighborId->str_ip);
454 double lt = neigh->lastHelloRecvTime;
455 if (lt + ospf->routerDeadInterval*SECOND <=
456 pstruEventDetails->dEventTime)
458 print_ospf_log(OSPF_LOG,
"Neighbor is inactive");
459 ospf_neighbor_change_state(neigh, OSPFNEIGHSTATE_DOWN);
461 ospf_list_delete_all(neigh->neighLSReqList);
462 ospf_list_destroy(neigh->neighLSReqList);
463 neigh->neighLSReqList = NULL;
465 ospf_list_delete_all(neigh->neighDBSummaryList);
466 ospf_list_destroy(neigh->neighDBSummaryList);
467 neigh->neighDBSummaryList = NULL;
469 ospf_list_delete_all(neigh->neighLSRxtList);
470 ospf_list_destroy(neigh->neighLSRxtList);
471 neigh->neighLSRxtList = NULL;
473 ospf_list_delete_all(neigh->linkStateSendList);
474 ospf_list_destroy(neigh->linkStateSendList);
475 neigh->linkStateSendList = NULL;
477 neigh->isInactivityTimerAdded =
false;
479 OSPF_HDR_FREE(neigh->lastrecvDDPacket);
480 neigh->lastrecvDDPacket = NULL;
482 OSPF_HDR_FREE(neigh->lastSentDDPacket);
483 neigh->lastSentDDPacket = NULL;
485 neigh->neighborDesignateBackupRouter = NULL;
486 neigh->neighborDesignateRouter = NULL;
491 print_ospf_log(OSPF_LOG,
"Neighbor is active");
492 restart_inactivity_timer(ospf, neigh);
494 print_ospf_log(OSPF_LOG,
"");
497bool ospf_is_router_fullAdjacentWithDR(ptrOSPF_IF ospf)
500 for (i = 0; i < ospf->neighborRouterCount; i++)
502 ptrOSPF_NEIGHBOR neigh = ospf->neighborRouterList[i];
503 if (!OSPFID_COMPARE(neigh->neighborId, ospf->designaterRouter) &&
504 neigh->state == OSPFNEIGHSTATE_Full)
510bool ospf_is_dr_router_fulladjacentwithAnother(ptrOSPF_IF ospf)
513 for (i = 0; i < ospf->neighborRouterCount; i++)
515 ptrOSPF_NEIGHBOR neigh = ospf->neighborRouterList[i];
516 if (neigh->state == OSPFNEIGHSTATE_Full)
522bool ospf_neighbor_isAnyNeighborInExchangeOrLoadingState(ptrOSPF_PDS ospf)
525 for (i = 0; i < ospf->ifCount; i++)
527 ptrOSPF_IF thisInterface = ospf->ospfIf[i];
528 ptrOSPF_NEIGHBOR neigh;
529 for (n = 0; n < thisInterface->neighborRouterCount; n++)
531 neigh = thisInterface->neighborRouterList[n];
532 if (neigh->state == OSPFNEIGHSTATE_Exchange ||
533 neigh->state == OSPFNEIGHSTATE_Loading)
540ptrOSPFLSAHDR ospf_neighbor_searchSendList(ptrOSPFLIST list,
544 void* pass = ospf_list_newIterator();
545 while ((l = ospf_list_iterate_mem(list, pass)) != NULL)
547 if (l->LSType == lsa->LSType &&
548 !OSPFID_COMPARE(l->AdvertisingRouter, lsa->AdvertisingRouter) &&
549 !OSPFID_COMPARE(l->LinkStateID, lsa->LinkStateID))
551 ospf_list_deleteIterator(pass);
555 ospf_list_deleteIterator(pass);
559void ospf_neighbor_insertToSendList(ptrOSPFLIST list,
563 ptrOSPFLSAHDR s = OSPF_LSA_HDR_COPY(lsa);
565 ospf_list_add_mem(list, s);
568NETSIM_ID ospf_neighbor_getInterfaceIdforThisNeighbor(ptrOSPF_PDS ospf,
569 NETSIM_IPAddress neighIPaddr)
572 for (i = 0; i < ospf->ifCount; i++)
574 ptrOSPF_IF thisInterface = ospf->ospfIf[i];
577 for(n=0;n<thisInterface->neighborRouterCount;n++)
579 ptrOSPF_NEIGHBOR neigh = thisInterface->neighborRouterList[n];
580 if (!IP_COMPARE(neigh->neighborIPAddr, neighIPaddr))
581 return thisInterface->id;
587void ospf_neighbor_handle_LoadingDoneEvent()
589 NETSIM_ID d = pstruEventDetails->nDeviceId;
590 ptrOSPF_NEIGHBOR tempNeighborInfo = pstruEventDetails->szOtherDetails;
592 if (tempNeighborInfo->state != OSPFNEIGHSTATE_Loading)
595 if (tempNeighborInfo->state != OSPFNEIGHSTATE_Full)
596 print_ospf_log(OSPF_LOG,
"Router %d, LoadingDone event is triggered"
597 "Neighbor (%s) state move up to Full", d, tempNeighborInfo->neighborId);
599 ospf_neighbor_change_state(tempNeighborInfo, OSPFNEIGHSTATE_Full);
602void ospf_neighbor_handle_KillNbrEvent()
604 ptrOSPF_PDS ospf = OSPF_PDS_CURRENT();
605 ptrOSPF_IF thisInterface = OSPF_IF_CURRENT();
606 ptrOSPF_NEIGHBOR neighbor = pstruEventDetails->szOtherDetails;
608 ospf_neighbor_change_state(neighbor, OSPFNEIGHSTATE_DOWN);
609 ospf_neighbor_remove(ospf, thisInterface, neighbor);