NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
OSPF_DR.c
1/************************************************************************************
2* Copyright (C) 2023 *
3* TETCOS, Bangalore. India *
4* *
5* Tetcos owns the intellectual property rights in the Product and its content. *
6* The copying, redistribution, reselling or publication of any or all of the *
7* Product or its content without express prior written consent of Tetcos is *
8* prohibited. Ownership and / or any other right relating to the software and all *
9* intellectual property rights therein shall remain at all times with Tetcos. *
10* *
11* Author: Shashi Kant Suman *
12* *
13* ---------------------------------------------------------------------------------*/
14#include "main.h"
15#include "NetSim_utility.h"
16#include "OSPF.h"
17#include "OSPF_enum.h"
18#include "OSPF_Msg.h"
19#include "OSPF_Neighbor.h"
20#include "OSPF_Interface.h"
21#include "OSPF_List.h"
22
23typedef struct
24{
25 OSPFID routerId;
26 UINT16 routerPriority;
27 NETSIM_IPAddress routerAddr;
28 UINT routerOption;
29 OSPFID DesignatedRouter;
30 OSPFID BackupDesignatedRouter;
31} drEligibleRouter,*ptrdrEligibleRouter;
32
33static void drEligibleRouter_free(ptrdrEligibleRouter d)
34{
35 free(d);
36}
37
38static void ospf_DR_listEligibleRouter(ptrOSPF_PDS ospf,
39 ptrOSPF_IF thisInterface,
40 ptrOSPFLIST eligibleRouterList)
41{
42 ptrdrEligibleRouter newRouter;
43
44 if (thisInterface->RouterPriority > 0)
45 {
46 newRouter = calloc(1, sizeof* newRouter);
47 newRouter->routerId = ospf->routerId;
48 newRouter->routerPriority = thisInterface->RouterPriority;
49 newRouter->routerAddr = thisInterface->IPIfAddr;
50 newRouter->DesignatedRouter = thisInterface->designaterRouterAddr;
51 newRouter->BackupDesignatedRouter = thisInterface->backupDesignaterRouterAddr;
52 ospf_list_add_mem(eligibleRouterList, newRouter);
53 }
54
55 ptrOSPF_NEIGHBOR neigh;
56 UINT i;
57 for (i = 0; i < thisInterface->neighborRouterCount; i++)
58 {
59 neigh = thisInterface->neighborRouterList[i];
60 if (neigh->state >= OSPFNEIGHSTATE_2Way &&
61 neigh->neighborPriority > 0)
62 {
63 newRouter = calloc(1, sizeof* newRouter);
64 newRouter->routerId = neigh->neighborId;
65 newRouter->routerPriority = neigh->neighborPriority;
66 newRouter->routerAddr = neigh->neighborIPAddr;
67 newRouter->DesignatedRouter = neigh->neighborDesignateRouter;
68 newRouter->BackupDesignatedRouter = neigh->neighborDesignateBackupRouter;
69 ospf_list_add_mem(eligibleRouterList, newRouter);
70 }
71 }
72}
73
74static void ospf_DR_electBDR(ptrOSPF_PDS ospf,
75 ptrOSPF_IF thisInterface,
76 ptrdrEligibleRouter eligibleRouter)
77{
78 ospf;
79 ptrdrEligibleRouter routerInfo;
80 void* pass = ospf_list_newIterator();
81 bool flag = false;
82 ptrdrEligibleRouter tempBDR = NULL;
83
84 while ((routerInfo = ospf_list_iterate_mem(eligibleRouter, pass)) != NULL)
85 {
86 // If the router declared itself to be DR
87 // it is not eligible to become BDR
88 if (!OSPFID_COMPARE(routerInfo->routerId,routerInfo->DesignatedRouter))
89 continue;
90 // If neighbor declared itself to be BDR
91 if (!OSPFID_COMPARE(routerInfo->routerId, routerInfo->BackupDesignatedRouter))
92 {
93 if (flag &&
94 tempBDR &&
95 (tempBDR->routerPriority > routerInfo->routerPriority ||
96 (tempBDR->routerPriority == routerInfo->routerPriority &&
97 tempBDR->routerId->int_ip > routerInfo->routerId->int_ip)))
98 {
99 // do nothing
100 }
101 else
102 {
103 tempBDR = routerInfo;
104 flag = TRUE;
105 }
106 }
107 else if (!flag)
108 {
109 if (tempBDR &&
110 (tempBDR->routerPriority > routerInfo->routerPriority ||
111 (tempBDR->routerPriority == routerInfo->routerPriority &&
112 tempBDR->routerId->int_ip > routerInfo->routerId->int_ip)))
113 {
114 // do nothing
115 }
116 else
117 {
118 tempBDR = routerInfo;
119 }
120 }
121 }
122 ospf_list_deleteIterator(pass);
123
124 // Set BDR to this interface
125 if (tempBDR)
126 {
127 thisInterface->backupDesignaterRouter = tempBDR->routerId;
128 thisInterface->backupDesignaterRouterAddr = tempBDR->routerAddr;
129 }
130 else
131 {
132 thisInterface->backupDesignaterRouter = NULL;
133 thisInterface->backupDesignaterRouterAddr = NULL;
134 }
135}
136
137static OSPFIFSTATE ospf_DR_electDR(ptrOSPF_PDS ospf,
138 ptrOSPF_IF thisInterface,
139 ptrdrEligibleRouter eligibleRouter)
140{
141 ptrdrEligibleRouter routerInfo;
142 void* pass = ospf_list_newIterator();
143 ptrdrEligibleRouter tempDR = NULL;
144
145 while ((routerInfo = ospf_list_iterate_mem(eligibleRouter, pass)) != NULL)
146 {
147 if (!OSPFID_COMPARE(routerInfo->routerAddr, routerInfo->DesignatedRouter))
148 {
149 if (tempDR &&
150 (tempDR->routerPriority > routerInfo->routerPriority ||
151 (tempDR->routerPriority == routerInfo->routerPriority &&
152 tempDR->routerId->int_ip > routerInfo->routerId->int_ip)))
153 {
154 // do nothing
155 }
156 else
157 {
158 tempDR = routerInfo;
159 }
160 }
161 }
162 ospf_list_deleteIterator(pass);
163
164 // Set DR to this interface
165 if (tempDR)
166 {
167 thisInterface->designaterRouter = tempDR->routerId;
168 thisInterface->designaterRouterAddr = tempDR->routerAddr;
169 }
170 else
171 {
172 thisInterface->designaterRouter = thisInterface->backupDesignaterRouter;
173 thisInterface->designaterRouterAddr = thisInterface->backupDesignaterRouterAddr;
174 }
175
176 // Return new interface state
177 if (!OSPFID_COMPARE(thisInterface->designaterRouter, ospf->routerId))
178 {
179 return OSPFIFSTATE_DR;
180 }
181 else if (!OSPFID_COMPARE(thisInterface->backupDesignaterRouter, ospf->routerId))
182 {
183 return OSPFIFSTATE_BACKUP;
184 }
185 else
186 {
187 return OSPFIFSTATE_DROther;
188 }
189}
190
191OSPFIFSTATE ospf_DR_election(ptrOSPF_PDS ospf,
192 ptrOSPF_IF thisInterface)
193{
194 ptrOSPFLIST eligibleRoutersList = ospf_list_init(drEligibleRouter_free, NULL);
195 OSPFID oldDR;
196 OSPFID oldBDR;
197 OSPFIFSTATE oldState;
198 OSPFIFSTATE newState;
199
200 ospf_DR_listEligibleRouter(ospf,
201 thisInterface,
202 eligibleRoutersList);
203
204 // RFC-2328, Section: 9.4.1
205 oldDR = thisInterface->designaterRouter;
206 oldBDR = thisInterface->backupDesignaterRouter;
207 oldState = thisInterface->State;
208
209 // RFC-2328, Section: 9.4.2 & 9.4.3
210 // First election of DR and BDR
211 ospf_DR_electBDR(ospf, thisInterface, eligibleRoutersList);
212 newState = ospf_DR_electDR(ospf, thisInterface, eligibleRoutersList);
213 ospf_list_delete_all(eligibleRoutersList);
214
215 // RFC-2328, Section: 9.4.4
216 if (newState != oldState &&
217 (newState != OSPFIFSTATE_DROther || oldState > OSPFIFSTATE_DROther))
218 {
219 eligibleRoutersList = ospf_list_init(drEligibleRouter_free, NULL);
220 ospf_DR_listEligibleRouter(ospf,
221 thisInterface,
222 eligibleRoutersList);
223
224 ospf_DR_electBDR(ospf, thisInterface, eligibleRoutersList);
225 newState = ospf_DR_electDR(ospf, thisInterface, eligibleRoutersList);
226 ospf_list_delete_all(eligibleRoutersList);
227 }
228
229 print_ospf_log(OSPF_LOG, "Router %d declare DR = %s and BDR = %s\n"
230 "on interface %d at time %0.3lf",
231 ospf->myId,
232 thisInterface->designaterRouter->str_ip,
233 thisInterface->backupDesignaterRouter->str_ip,
234 thisInterface->id,
235 OSPF_CURR_TIME() / MILLISECOND);
236
237
238 // RFC-2328, Section: 9.4.7
239 if (OSPFID_COMPARE(oldDR, thisInterface->designaterRouter) ||
240 OSPFID_COMPARE(oldBDR, thisInterface->backupDesignaterRouter))
241 {
242 UINT i;
243 for (i = 0; i < thisInterface->neighborRouterCount; i++)
244 {
245 ptrOSPF_NEIGHBOR neigh = thisInterface->neighborRouterList[i];
246 if (neigh->state == OSPFNEIGHSTATE_2Way)
247 {
248 ospf_event_add(OSPF_CURR_TIME(),
249 ospf->myId,
250 thisInterface->id,
251 OSPF_Adjok,
252 NULL,
253 neigh);
254 }
255 }
256 }
257 return newState;
258}