NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
OSPF_RoutingTable.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 "../IP/IP.h"
17#include "OSPF.h"
18#include "OSPF_enum.h"
19#include "OSPF_Msg.h"
20#include "OSPF_Neighbor.h"
21#include "OSPF_Interface.h"
22#include "OSPF_RoutingTable.h"
23#include "OSPF_List.h"
24
25static bool ospf_rtTable_compareDestType(OSPFDESTTYPE destType1,
26 OSPFDESTTYPE destType2)
27{
28 if (destType1 == destType2)
29 return true;
30
31 else if (destType1 == OSPFDESTTYPE_ABR_ASBR &&
32 (destType2 == OSPFDESTTYPE_ABR ||
33 destType2 == OSPFDESTTYPE_ASBR))
34 return true;
35
36 else if (destType2 == OSPFDESTTYPE_ABR_ASBR &&
37 (destType1 == OSPFDESTTYPE_ABR ||
38 destType1 == OSPFDESTTYPE_ASBR))
39 return true;
40
41 return false;
42}
43
44static ptrOSPFROUTINGTABLEROW ospf_rtTable_getIntraAreaRoute(ptrOSPF_PDS ospf,
45 NETSIM_IPAddress destAddr,
46 OSPFDESTTYPE destType,
47 OSPFID areaId)
48{
49 UINT i;
50 ptrOSPFROUTINGTABLE rtTable = ospf->routingTable;
51 ptrOSPFROUTINGTABLEROW* rowPtr = rtTable->rows;
52 ptrOSPFROUTINGTABLEROW longestMatchingEntry = NULL;
53
54 for (i = 0; i < rtTable->numRow; i++)
55 {
56 if (ospf->isAdvertSelfIntf)
57 {
58 if (!IP_COMPARE(rowPtr[i]->destAddr, destAddr) &&
59 ospf_rtTable_compareDestType(rowPtr[i]->destType, destType) &&
60 rowPtr[i]->pathType == OSPFPATHTYPE_INTRA_AREA &&
61 !OSPFID_COMPARE(rowPtr[i]->areaId, areaId))
62 {
63 if (!longestMatchingEntry ||
64 rowPtr[i]->addrMask->int_ip[0] >
65 longestMatchingEntry->addrMask->int_ip[0])
66 longestMatchingEntry = rowPtr[i];
67 }
68 }
69 else
70 {
71 if (((rowPtr[i]->destAddr->int_ip[0] & rowPtr[i]->addrMask->int_ip[0]) ==
72 (destAddr->int_ip[0] & rowPtr[i]->addrMask->int_ip[0])) &&
73 ospf_rtTable_compareDestType(rowPtr[i]->destType, destType) &&
74 rowPtr[i]->pathType == OSPFPATHTYPE_INTRA_AREA &&
75 !OSPFID_COMPARE(rowPtr[i]->areaId, areaId))
76 {
77 if (!longestMatchingEntry ||
78 rowPtr[i]->addrMask->int_ip[0] >
79 longestMatchingEntry->addrMask->int_ip[0])
80 longestMatchingEntry = rowPtr[i];
81 }
82 }
83 }
84 return longestMatchingEntry;
85}
86
87static ptrOSPFROUTINGTABLEROW ospf_rtTable_getRoute(ptrOSPF_PDS ospf,
88 NETSIM_IPAddress destAddr,
89 OSPFDESTTYPE destType)
90{
91 UINT i;
92 ptrOSPFROUTINGTABLE rtTable = ospf->routingTable;
93 ptrOSPFROUTINGTABLEROW* rowPtr = rtTable->rows;
94 ptrOSPFROUTINGTABLEROW longestMatchingEntry = NULL;
95
96 for (i = 0; i < rtTable->numRow; i++)
97 {
98 if (ospf->isAdvertSelfIntf)
99 {
100 if (rowPtr[i]->destAddr->int_ip[0] == destAddr->int_ip[0] &&
101 ospf_rtTable_compareDestType(rowPtr[i]->destType, destType))
102 return rowPtr[i];
103 }
104 else
105 {
106 if ((rowPtr[i]->destAddr->int_ip[0] & rowPtr[i]->addrMask->int_ip[0]) ==
107 (destAddr->int_ip[0] & rowPtr[i]->addrMask->int_ip[0]) &&
108 ospf_rtTable_compareDestType(rowPtr[i]->destType, destType))
109 {
110 if (!longestMatchingEntry ||
111 rowPtr[i]->addrMask->int_ip[0] > longestMatchingEntry->addrMask->int_ip[0])
112 {
113 longestMatchingEntry = rowPtr[i];
114 }
115 }
116 }
117 }
118 return longestMatchingEntry;
119}
120
121static bool ospf_rtTable_isRouteMatch(ptrOSPFROUTINGTABLEROW newRoute,
122 ptrOSPFROUTINGTABLEROW oldRoute)
123{
124 if (newRoute->metric == oldRoute->metric &&
125 !IP_COMPARE(newRoute->nextHop, oldRoute->nextHop))
126 return true;
127 else
128 return false;
129}
130
131static void ospf_rtTable_addRowToTable(ptrOSPF_PDS ospf,
132 ptrOSPFROUTINGTABLE table,
133 ptrOSPFROUTINGTABLEROW row)
134{
135 (void)ospf;
136
137 if (table->numRow)
138 table->rows = realloc(table->rows, ((size_t)table->numRow + 1)*(sizeof* table->rows));
139 else
140 table->rows = calloc(1, sizeof* table->rows);
141 table->rows[table->numRow] = calloc(1,sizeof* table->rows[0]);
142 memcpy(table->rows[table->numRow], row, sizeof* row);
143 table->numRow++;
144}
145
146void ospf_rtTable_addRoute(ptrOSPF_PDS ospf,
147 ptrOSPFROUTINGTABLEROW newRoute)
148{
149 ptrOSPFROUTINGTABLE rtTable = ospf->routingTable;
150 ptrOSPFROUTINGTABLEROW rowPtr;
151
152 // Get old route if any ..
153 if (newRoute->destType != OSPFDESTTYPE_NETWORK)
154 {
155 rowPtr = ospf_rtTable_getIntraAreaRoute(ospf,
156 newRoute->destAddr,
157 newRoute->destType,
158 newRoute->areaId);
159 }
160 else
161 {
162 rowPtr = ospf_rtTable_getRoute(ospf,
163 newRoute->destAddr,
164 newRoute->destType);
165 }
166
167 if (rowPtr)
168 {
169 if (ospf_rtTable_isRouteMatch(newRoute, rowPtr))
170 newRoute->flag = OSPFROUTEFLAG_NO_CHANGE;
171 else
172 newRoute->flag = OSPFROUTEFLAG_CHANGED;
173
174 memcpy(rowPtr, newRoute, sizeof* newRoute);
175 }
176 else
177 {
178 newRoute->flag = OSPFROUTEFLAG_NEW;
179 ospf_rtTable_addRowToTable(ospf, rtTable, newRoute);
180 }
181}
182
183ptrOSPFROUTINGTABLEROW ospf_rtTable_getValidHostRoute(ptrOSPF_PDS ospf,
184 NETSIM_IPAddress destAddr,
185 OSPFDESTTYPE destType)
186{
187
188 UINT i;
189 ptrOSPFROUTINGTABLE rtTable = ospf->routingTable;
190 ptrOSPFROUTINGTABLEROW rowPtr;
191
192 for (i = 0; i < rtTable->numRow; i++)
193 {
194 rowPtr = rtTable->rows[i];
195 if (rowPtr->destAddr->int_ip[0] == destAddr->int_ip[0] &&
196 ospf_rtTable_compareDestType(rowPtr->destType, destType) &&
197 rowPtr->flag != OSPFROUTEFLAG_INVALID)
198 return rowPtr;
199 }
200 return NULL;
201}
202
203ptrOSPFROUTINGTABLEROW ospf_rtTable_getValidRoute(ptrOSPF_PDS ospf,
204 NETSIM_IPAddress destAddr,
205 OSPFDESTTYPE destType)
206{
207
208 UINT i;
209 ptrOSPFROUTINGTABLE rtTable = ospf->routingTable;
210 ptrOSPFROUTINGTABLEROW rowPtr;
211 ptrOSPFROUTINGTABLEROW longestMatchingEntry = NULL;
212
213 for (i = 0; i < rtTable->numRow; i++)
214 {
215 rowPtr = rtTable->rows[i];
216
217 if (ospf->isAdvertSelfIntf)
218 {
219 if (rowPtr->destAddr->int_ip[0] == destAddr->int_ip[0] &&
220 ospf_rtTable_compareDestType(rowPtr->destType, destType) &&
221 rowPtr->flag != OSPFROUTEFLAG_INVALID)
222 return rowPtr;
223 }
224 else
225 {
226 if ((rowPtr->destAddr->int_ip[0] & rowPtr->addrMask->int_ip[0]) ==
227 (destAddr->int_ip[0] & rowPtr->addrMask->int_ip[0]) &&
228 ospf_rtTable_compareDestType(rowPtr->destType, destType) &&
229 rowPtr->flag != OSPFROUTEFLAG_INVALID)
230 {
231 if (!longestMatchingEntry ||
232 rowPtr->addrMask->int_ip[0] > longestMatchingEntry->addrMask->int_ip[0])
233 longestMatchingEntry = rowPtr;
234 }
235 }
236 }
237 return longestMatchingEntry;
238}
239
240void ospf_rtTable_freeRoute(ptrOSPF_PDS ospf,
241 ptrOSPFROUTINGTABLEROW row)
242{
243 ptrOSPFROUTINGTABLE rtTable = ospf->routingTable;
244 UINT i;
245 bool isFound = false;
246 for (i = 0; i < rtTable->numRow; i++)
247 {
248 if (rtTable->rows[i] == row)
249 {
250 isFound = true;
251 rtTable->rows[i] = NULL;
252 }
253
254 if (isFound)
255 {
256 if (i != rtTable->numRow - 1)
257 rtTable->rows[i] = rtTable->rows[i + 1];
258 else
259 rtTable->rows[i] = NULL;
260 }
261 }
262 rtTable->numRow--;
263}
264
265void ospf_rtTable_freeAllInvalidRoute(ptrOSPF_PDS ospf)
266{
267 UINT i;
268 for (i = 0; i < ospf->routingTable->numRow; i++)
269 {
270 ptrOSPFROUTINGTABLEROW row = ospf->routingTable->rows[i];
271 if (row->flag == OSPFROUTEFLAG_INVALID)
272 {
273 ospf_rtTable_freeRoute(ospf, row);
274 i--;
275 }
276 }
277}
278
279static void ospf_rtTable_deleteAllIPRoute(ptrOSPF_PDS ospf)
280{
281 UINT i;
282 for (i = 0; i < ospf->ipTableCount; i++)
283 {
284#pragma message(__LOC__"Uncomment after bug correction of link failure.")
285 /*iptable_delete_by_route(IP_WRAPPER_GET(ospf->myId),
286 ospf->ipTable[i]);*/
287 }
288 ospf->ipTableCount = 0;
289 free(ospf->ipTable);
290 ospf->ipTable = NULL;
291}
292
293static void ospf_rtTable_addIPRoute(ptrOSPF_PDS ospf,
294 void* iproute)
295{
296 if (ospf->ipTableCount)
297 ospf->ipTable = realloc(ospf->ipTable, ((size_t)ospf->ipTableCount + 1) * sizeof* ospf->ipTable);
298 else
299 ospf->ipTable = calloc(1, sizeof* ospf->ipTable);
300 ospf->ipTable[ospf->ipTableCount] = iproute;
301 ospf->ipTableCount++;
302}
303
304void ospf_rtTable_updateIPTable(ptrOSPF_PDS ospf)
305{
306 UINT i;
307 ospf_rtTable_deleteAllIPRoute(ospf);
308 ptrOSPFROUTINGTABLE rtTable = ospf->routingTable;
309 ptrOSPFROUTINGTABLEROW rowPtr;
310
311 print_ospf_Dlog(form_dlogId("OSPFROUTE", ospf->myId),
312 "Updating IP table for device %d at time %lf. Number of rows %d.",
313 ospf->myId,
314 OSPF_CURR_TIME(),
315 rtTable->numRow);
316
317 for (i = 0; i < rtTable->numRow; i++)
318 {
319 rowPtr = rtTable->rows[i];
320
321 // Avoid updating IP forwarding table for route to self and router
322 if (ospf_isMyAddr(ospf->myId, rowPtr->destAddr))
323 continue;
324 if (rowPtr->flag == OSPFROUTEFLAG_INVALID)
325 continue;
326
327 print_ospf_Dlog(form_dlogId("OSPFROUTE", ospf->myId),
328 "%s,%s,%s,%s,%d,%d,",
329 rowPtr->destAddr->str_ip,
330 rowPtr->addrMask->str_ip,
331 rowPtr->nextHop->str_ip,
332 rowPtr->outInterface->str_ip,
333 rowPtr->outInterfaceId,
334 rowPtr->metric);
335
336 void* iptable = iptable_add(IP_WRAPPER_GET(ospf->myId),
337 rowPtr->destAddr,
338 rowPtr->addrMask,
339 0,
340 rowPtr->nextHop,
341 1,
342 &rowPtr->outInterface,
343 &rowPtr->outInterfaceId,
344 rowPtr->metric,
345 "OSPF");
346 ospf_rtTable_addIPRoute(ospf, iptable);
347 }
348 print_ospf_Dlog(form_dlogId("OSPFROUTE", ospf->myId), "\n");
349}
350
351#pragma message(__LOC__"Remove after link failure bug")
352void ospf_Table_updateIPTable_Dijkstra(ptrOSPF_PDS ospf, ptrOSPF_COST_LIST list)
353{
354 //fisrt change list to add next node
355 while (list) {
356 for (NETSIM_ID i = 0; i < DEVICE(list->dest_id)->nNumOfInterface; i++)
357 {
358 if (DEVICE_INTERFACE(list->dest_id, i + 1)->nInterfaceType == INTERFACE_WAN_ROUTER) {
359 iptable_add(IP_WRAPPER_GET(ospf->myId),
360 DEVICE_NWADDRESS(list->dest_id, i + 1),
361 STR_TO_IP4("255.255.255.255"),
362 0,
363 DEVICE_NWADDRESS(list->path->next->d, list->path->next->in),
364 1,
365 &DEVICE_NWADDRESS(ospf->myId, list->path->in),
366 &list->path->in,
367 (UINT)list->cost,
368 "OSPF");
369 }
370 }
371 list = list->next;
372 }
373}