15#include "NetSim_utility.h"
20#include "OSPF_Neighbor.h"
21#include "OSPF_Interface.h"
22#include "OSPF_RoutingTable.h"
25static bool ospf_rtTable_compareDestType(OSPFDESTTYPE destType1,
26 OSPFDESTTYPE destType2)
28 if (destType1 == destType2)
31 else if (destType1 == OSPFDESTTYPE_ABR_ASBR &&
32 (destType2 == OSPFDESTTYPE_ABR ||
33 destType2 == OSPFDESTTYPE_ASBR))
36 else if (destType2 == OSPFDESTTYPE_ABR_ASBR &&
37 (destType1 == OSPFDESTTYPE_ABR ||
38 destType1 == OSPFDESTTYPE_ASBR))
44static ptrOSPFROUTINGTABLEROW ospf_rtTable_getIntraAreaRoute(ptrOSPF_PDS ospf,
45 NETSIM_IPAddress destAddr,
46 OSPFDESTTYPE destType,
50 ptrOSPFROUTINGTABLE rtTable = ospf->routingTable;
51 ptrOSPFROUTINGTABLEROW* rowPtr = rtTable->rows;
52 ptrOSPFROUTINGTABLEROW longestMatchingEntry = NULL;
54 for (i = 0; i < rtTable->numRow; i++)
56 if (ospf->isAdvertSelfIntf)
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))
63 if (!longestMatchingEntry ||
64 rowPtr[i]->addrMask->int_ip[0] >
65 longestMatchingEntry->addrMask->int_ip[0])
66 longestMatchingEntry = rowPtr[i];
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))
77 if (!longestMatchingEntry ||
78 rowPtr[i]->addrMask->int_ip[0] >
79 longestMatchingEntry->addrMask->int_ip[0])
80 longestMatchingEntry = rowPtr[i];
84 return longestMatchingEntry;
87static ptrOSPFROUTINGTABLEROW ospf_rtTable_getRoute(ptrOSPF_PDS ospf,
88 NETSIM_IPAddress destAddr,
89 OSPFDESTTYPE destType)
92 ptrOSPFROUTINGTABLE rtTable = ospf->routingTable;
93 ptrOSPFROUTINGTABLEROW* rowPtr = rtTable->rows;
94 ptrOSPFROUTINGTABLEROW longestMatchingEntry = NULL;
96 for (i = 0; i < rtTable->numRow; i++)
98 if (ospf->isAdvertSelfIntf)
100 if (rowPtr[i]->destAddr->int_ip[0] == destAddr->int_ip[0] &&
101 ospf_rtTable_compareDestType(rowPtr[i]->destType, destType))
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))
110 if (!longestMatchingEntry ||
111 rowPtr[i]->addrMask->int_ip[0] > longestMatchingEntry->addrMask->int_ip[0])
113 longestMatchingEntry = rowPtr[i];
118 return longestMatchingEntry;
121static bool ospf_rtTable_isRouteMatch(ptrOSPFROUTINGTABLEROW newRoute,
122 ptrOSPFROUTINGTABLEROW oldRoute)
124 if (newRoute->metric == oldRoute->metric &&
125 !IP_COMPARE(newRoute->nextHop, oldRoute->nextHop))
131static void ospf_rtTable_addRowToTable(ptrOSPF_PDS ospf,
132 ptrOSPFROUTINGTABLE table,
133 ptrOSPFROUTINGTABLEROW row)
138 table->rows = realloc(table->rows, ((
size_t)table->numRow + 1)*(
sizeof* table->rows));
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);
146void ospf_rtTable_addRoute(ptrOSPF_PDS ospf,
147 ptrOSPFROUTINGTABLEROW newRoute)
149 ptrOSPFROUTINGTABLE rtTable = ospf->routingTable;
150 ptrOSPFROUTINGTABLEROW rowPtr;
153 if (newRoute->destType != OSPFDESTTYPE_NETWORK)
155 rowPtr = ospf_rtTable_getIntraAreaRoute(ospf,
162 rowPtr = ospf_rtTable_getRoute(ospf,
169 if (ospf_rtTable_isRouteMatch(newRoute, rowPtr))
170 newRoute->flag = OSPFROUTEFLAG_NO_CHANGE;
172 newRoute->flag = OSPFROUTEFLAG_CHANGED;
174 memcpy(rowPtr, newRoute,
sizeof* newRoute);
178 newRoute->flag = OSPFROUTEFLAG_NEW;
179 ospf_rtTable_addRowToTable(ospf, rtTable, newRoute);
183ptrOSPFROUTINGTABLEROW ospf_rtTable_getValidHostRoute(ptrOSPF_PDS ospf,
184 NETSIM_IPAddress destAddr,
185 OSPFDESTTYPE destType)
189 ptrOSPFROUTINGTABLE rtTable = ospf->routingTable;
190 ptrOSPFROUTINGTABLEROW rowPtr;
192 for (i = 0; i < rtTable->numRow; i++)
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)
203ptrOSPFROUTINGTABLEROW ospf_rtTable_getValidRoute(ptrOSPF_PDS ospf,
204 NETSIM_IPAddress destAddr,
205 OSPFDESTTYPE destType)
209 ptrOSPFROUTINGTABLE rtTable = ospf->routingTable;
210 ptrOSPFROUTINGTABLEROW rowPtr;
211 ptrOSPFROUTINGTABLEROW longestMatchingEntry = NULL;
213 for (i = 0; i < rtTable->numRow; i++)
215 rowPtr = rtTable->rows[i];
217 if (ospf->isAdvertSelfIntf)
219 if (rowPtr->destAddr->int_ip[0] == destAddr->int_ip[0] &&
220 ospf_rtTable_compareDestType(rowPtr->destType, destType) &&
221 rowPtr->flag != OSPFROUTEFLAG_INVALID)
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)
231 if (!longestMatchingEntry ||
232 rowPtr->addrMask->int_ip[0] > longestMatchingEntry->addrMask->int_ip[0])
233 longestMatchingEntry = rowPtr;
237 return longestMatchingEntry;
240void ospf_rtTable_freeRoute(ptrOSPF_PDS ospf,
241 ptrOSPFROUTINGTABLEROW row)
243 ptrOSPFROUTINGTABLE rtTable = ospf->routingTable;
245 bool isFound =
false;
246 for (i = 0; i < rtTable->numRow; i++)
248 if (rtTable->rows[i] == row)
251 rtTable->rows[i] = NULL;
256 if (i != rtTable->numRow - 1)
257 rtTable->rows[i] = rtTable->rows[i + 1];
259 rtTable->rows[i] = NULL;
265void ospf_rtTable_freeAllInvalidRoute(ptrOSPF_PDS ospf)
268 for (i = 0; i < ospf->routingTable->numRow; i++)
270 ptrOSPFROUTINGTABLEROW row = ospf->routingTable->rows[i];
271 if (row->flag == OSPFROUTEFLAG_INVALID)
273 ospf_rtTable_freeRoute(ospf, row);
279static void ospf_rtTable_deleteAllIPRoute(ptrOSPF_PDS ospf)
282 for (i = 0; i < ospf->ipTableCount; i++)
284#pragma message(__LOC__"Uncomment after bug correction of link failure.")
288 ospf->ipTableCount = 0;
290 ospf->ipTable = NULL;
293static void ospf_rtTable_addIPRoute(ptrOSPF_PDS ospf,
296 if (ospf->ipTableCount)
297 ospf->ipTable = realloc(ospf->ipTable, ((
size_t)ospf->ipTableCount + 1) *
sizeof* ospf->ipTable);
299 ospf->ipTable = calloc(1,
sizeof* ospf->ipTable);
300 ospf->ipTable[ospf->ipTableCount] = iproute;
301 ospf->ipTableCount++;
304void ospf_rtTable_updateIPTable(ptrOSPF_PDS ospf)
307 ospf_rtTable_deleteAllIPRoute(ospf);
308 ptrOSPFROUTINGTABLE rtTable = ospf->routingTable;
309 ptrOSPFROUTINGTABLEROW rowPtr;
311 print_ospf_Dlog(form_dlogId(
"OSPFROUTE", ospf->myId),
312 "Updating IP table for device %d at time %lf. Number of rows %d.",
317 for (i = 0; i < rtTable->numRow; i++)
319 rowPtr = rtTable->rows[i];
322 if (ospf_isMyAddr(ospf->myId, rowPtr->destAddr))
324 if (rowPtr->flag == OSPFROUTEFLAG_INVALID)
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,
336 void* iptable = iptable_add(IP_WRAPPER_GET(ospf->myId),
342 &rowPtr->outInterface,
343 &rowPtr->outInterfaceId,
346 ospf_rtTable_addIPRoute(ospf, iptable);
348 print_ospf_Dlog(form_dlogId(
"OSPFROUTE", ospf->myId),
"\n");
351#pragma message(__LOC__"Remove after link failure bug")
352void ospf_Table_updateIPTable_Dijkstra(ptrOSPF_PDS ospf, ptrOSPF_COST_LIST list)
356 for (NETSIM_ID i = 0; i < DEVICE(list->dest_id)->nNumOfInterface; i++)
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"),
363 DEVICE_NWADDRESS(list->path->next->d, list->path->next->in),
365 &DEVICE_NWADDRESS(ospf->myId, list->path->in),