NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
OSPF_RLSA.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_RoutingTable.h"
22#include "OSPF_List.h"
23
24void ospf_lsa_printRLSA(char* logid,
25 ptrOSPFRLSA rlsa)
26{
27 if (!rlsa)
28 return;
29 print_ospf_Dlog(logid,
30 "Link count = %d",
31 rlsa->linksCount);
32 UINT i;
33 for (i = 0; i < rlsa->linksCount; i++)
34 {
35 ptrOSPFRLSALINK link = rlsa->rlsaLink[i];
36 print_ospf_Dlog(logid,
37 "\tLink Type = %s\n"
38 "\tLink data = %s\n"
39 "\tLink Id = %s\n"
40 "\tMetric = %d\n",
41 strOSPFLINKTYPE[link->type],
42 link->linkData->str_ip,
43 link->linkId->str_ip,
44 link->metric);
45 }
46}
47
48void OSPFLSAINFO_FREE_RLSA(ptrOSPFRLSA rlsa)
49{
50 UINT i;
51 if (rlsa)
52 {
53 for (i = 0; i < rlsa->linksCount; i++)
54 free(rlsa->rlsaLink[i]);
55#pragma message(__LOC__"If TOS is implemented. Add free function for TOS")
56 free(rlsa->rlsaLink);
57 free(rlsa);
58 }
59}
60
61ptrOSPFRLSA OSPFLSAINFO_COPY_RLSA(ptrOSPFRLSA rlsa)
62{
63 if (rlsa)
64 {
65 ptrOSPFRLSA r = calloc(1, sizeof* r);
66 memcpy(r, rlsa, sizeof* r);
67 UINT i;
68 if (rlsa->linksCount)
69 {
70 r->rlsaLink = calloc(rlsa->linksCount, sizeof* r->rlsaLink);
71 for (i = 0; i < r->linksCount; i++)
72 {
73 r->rlsaLink[i] = calloc(1, sizeof* r->rlsaLink[i]);
74 memcpy(r->rlsaLink[i], rlsa->rlsaLink[i], sizeof* r->rlsaLink[i]);
75#pragma message(__LOC__"If TOS is implemented. Add TOS copy")
76 }
77 }
78 return r;
79 }
80 return NULL;
81}
82
83static void ospf_rlsa_setABR(ptrOSPFLSAHDR hdr, bool abr)
84{
85 ptrOSPFRLSA rlsa = ospf_list_get_headptr(hdr->lsaInfo);
86 UCHAR* l = &rlsa->VEB;
87 UCHAR x = (UCHAR)abr;
88 x = x & maskChar(8, 8);
89
90 *l = *l & (~(maskChar(8, 8)));
91
92 *l = *l | LSHIFTCHAR(x, 8);
93}
94
95static void ospf_rlsa_add_link(ptrOSPFRLSA rlsa,
96 ptrOSPFRLSALINK link)
97{
98 if (rlsa->linksCount)
99 rlsa->rlsaLink = realloc(rlsa->rlsaLink, (rlsa->linksCount + 1)*(sizeof* rlsa->rlsaLink));
100 else
101 rlsa->rlsaLink = calloc(1, sizeof* rlsa->rlsaLink);
102 rlsa->rlsaLink[rlsa->linksCount] = link;
103 rlsa->linksCount++;
104}
105
106static ptrOSPFRLSALINK ospf_rlsa_add_type1link(NETSIM_ID d,
107 NETSIM_ID in,
108 ptrOSPF_IF ospf,
109 ptrOSPF_NEIGHBOR neigh)
110{
111 ptrOSPFRLSALINK link = calloc(1, sizeof* link);
112 link->type = OSPFLINKTYPE_POINT_TO_POINT;
113 link->linkId = neigh->neighborId;
114 link->linkData = DEVICE_NWADDRESS(d, in);
115 link->metric = (UINT16)ospf->interfaceOutputCost;
116 return link;
117}
118
119static ptrOSPFRLSALINK ospf_rlsa_add_type2link(NETSIM_ID d,
120 NETSIM_ID in,
121 ptrOSPF_IF thisInterface)
122{
123 ptrOSPFRLSALINK link = calloc(1, sizeof* link);
124 link->type = OSPFLINKTYPE_TRANSIT;
125 link->linkId = thisInterface->designaterRouter;
126 link->linkData = DEVICE_SUBNETMASK(d, in);
127 link->metric = (UINT16)thisInterface->interfaceOutputCost;
128 return link;
129}
130
131static ptrOSPFRLSALINK ospf_rlsa_add_type3link(NETSIM_ID d,
132 NETSIM_ID in,
133 ptrOSPF_IF thisInterface)
134{
135 ptrOSPFRLSALINK link = calloc(1, sizeof* link);
136 link->type = OSPFLINKTYPE_STUB;
137 switch (thisInterface->Type)
138 {
139 case OSPFIFTYPE_NBMA:
140 case OSPFIFTYPE_BROADCAST:
141 case OSPFIFTYPE_P2P:
142 link->linkId = DEVICE_NWADDRESS(d, in);
143 link->linkData = DEVICE_SUBNETMASK(d, in);
144 link->metric = (UINT16)thisInterface->interfaceOutputCost;
145 break;
146 case OSPFIFTYPE_P2MP:
147 link->linkId = DEVICE_NWADDRESS(d, in);
148 link->linkData = GET_BROADCAST_IP(4);
149 link->metric = 0;
150 break;
151 default:
152 fnNetSimError("Unknown if type %d\n", thisInterface->Type);
153 break;
154 }
155 return link;
156}
157
158static ptrOSPFRLSALINK ospf_rlsa_add_selflink(ptrOSPF_IF thisInterface)
159{
160 ptrOSPFRLSALINK link = calloc(1, sizeof* link);
161 link->type = OSPFLINKTYPE_STUB;
162 link->linkId = thisInterface->IPIfAddr;
163 link->linkData = GET_BROADCAST_IP(4);
164 link->metric = 0;
165 return link;
166}
167
168static ptrOSPFRLSALINK ospf_rlsa_add_hostRoute(NETSIM_ID d,
169 NETSIM_ID in,
170 ptrOSPF_IF thisInterface,
171 ptrOSPF_NEIGHBOR neigh)
172{
173 d;
174 in;
175
176 ptrOSPFRLSALINK link = calloc(1, sizeof* link);
177 link->type = OSPFLINKTYPE_STUB;
178 link->linkId = neigh->neighborIPAddr;
179 link->linkData = GET_BROADCAST_IP(4);
180 link->metric = (UINT16)thisInterface->interfaceOutputCost;
181 return link;
182}
183
184static UINT16 ospf_rlsa_add_foreach_interface(ptrOSPF_PDS ospf,
185 ptrOSPFAREA_DS area,
186 ptrOSPFLSAHDR lsa)
187{
188 NETSIM_ID d = pstruEventDetails->nDeviceId;
189 ptrOSPFRLSALINK link;
190 ptrOSPFRLSA rlsa = calloc(1, sizeof* rlsa);
191 UINT16 size = OSPFRLSA_LEN_FIXED;
192 UINT i;
193 for (i = 0; i < ospf->ifCount; i++)
194 {
195 ptrOSPF_IF ospfIf = ospf->ospfIf[i];
196 if (ospfIf->State == OSPFIFSTATE_DOWN)
197 continue;
198 if (OSPFID_COMPARE(ospfIf->areaId, area->areaId))
199 continue;
200
201 switch (ospfIf->Type)
202 {
203 case OSPFIFTYPE_BROADCAST:
204 {
205 if (ospfIf->State == OSPFIFSTATE_WAITING)
206 {
207 link = ospf_rlsa_add_type3link(d,
208 ospfIf->id,
209 ospfIf);
210 ospf_rlsa_add_link(rlsa, link);
211 size += OSPFRLSALINK_LEN_FIXED;
212 }
213 else if (((ospfIf->State != OSPFIFSTATE_DR) &&
214 ospf_is_router_fullAdjacentWithDR(ospfIf)) ||
215 (ospfIf->State == OSPFIFSTATE_DR &&
216 ospf_is_dr_router_fulladjacentwithAnother(ospfIf)))
217 {
218 link = ospf_rlsa_add_type2link(d,
219 ospfIf->id,
220 ospfIf);
221 ospf_rlsa_add_link(rlsa, link);
222 size += OSPFRLSALINK_LEN_FIXED;
223 }
224 else
225 {
226 link = ospf_rlsa_add_type3link(d,
227 ospfIf->id,
228 ospfIf);
229 ospf_rlsa_add_link(rlsa, link);
230 size += OSPFRLSALINK_LEN_FIXED;
231 }
232 }
233 break;
234 case OSPFIFTYPE_P2MP:
235 {
236 link = ospf_rlsa_add_selflink(ospfIf);
237 ospf_rlsa_add_link(rlsa, link);
238 size += OSPFRLSALINK_LEN_FIXED;
239
240 UINT n;
241 for (n = 0; n < ospfIf->neighborRouterCount; n++)
242 {
243 ptrOSPF_NEIGHBOR neigh = ospfIf->neighborRouterList[n];
244 if (neigh->state == OSPFNEIGHSTATE_Full)
245 {
246 link = ospf_rlsa_add_type1link(d,
247 ospfIf->id,
248 ospfIf,
249 neigh);
250 ospf_rlsa_add_link(rlsa, link);
251 size += OSPFRLSALINK_LEN_FIXED;
252 }
253 }
254 }
255 break;
256 case OSPFIFTYPE_P2P:
257 {
258 NETSIM_ID in = ospfIf->id;
259 if (!ospfIf->neighborRouterCount &&
260 ospfIf->State == OSPFIFSTATE_P2P)
261 {
262 if (DEVICE_INTERFACE(d, in)->nInterfaceType != INTERFACE_VIRTUAL &&
263 DEVICE_MACLAYER(d, in)->nMacProtocolId == MAC_PROTOCOL_P2P)
264 {
265 link = ospf_rlsa_add_type3link(d,
266 in,
267 ospfIf);
268 ospf_rlsa_add_link(rlsa, link);
269 size += OSPFRLSALINK_LEN_FIXED;
270 }
271 }
272 UINT n;
273 for (n = 0; n < ospfIf->neighborRouterCount; n++)
274 {
275 ptrOSPF_NEIGHBOR neigh = ospfIf->neighborRouterList[n];
276 if (neigh->state == OSPFNEIGHSTATE_Full)/* ||
277 neigh->state == OSPFNEIGHSTATE_Loading)
278#pragma message(__LOC__"Check above again --- 15540")*/
279 {
280 link = ospf_rlsa_add_type1link(d,
281 in,
282 ospfIf,
283 neigh);
284 ospf_rlsa_add_link(rlsa, link);
285 size += OSPFRLSALINK_LEN_FIXED;
286 }
287 if (ospfIf->State == OSPFIFSTATE_P2P)
288 {
289 if (DEVICE_INTERFACE(d, in)->nInterfaceType != INTERFACE_VIRTUAL &&
290 DEVICE_MACLAYER(d, in)->nMacProtocolId == MAC_PROTOCOL_P2P)
291 {
292 link = ospf_rlsa_add_type3link(d,
293 in,
294 ospfIf);
295 ospf_rlsa_add_link(rlsa, link);
296 size += OSPFRLSALINK_LEN_FIXED;
297 }
298 else
299 {
300 link = ospf_rlsa_add_hostRoute(d,
301 in,
302 ospfIf,
303 neigh);
304 ospf_rlsa_add_link(rlsa, link);
305 size += OSPFRLSALINK_LEN_FIXED;
306 }
307 }
308 }
309 }
310 break;
311 default:
312 fnNetSimError("Unknown if type %d for interface %d, router %s\n",
313 ospfIf->Type,
314 ospfIf->id,
315 ospf->routerId->str_ip);
316 break;
317 }
318 }
319 ospf_lsahdr_add_lsa(lsa, rlsa, size);
320 return size;
321}
322
323bool ospf_rlsa_isBodyChanged(ptrOSPFLSAHDR newLSA,
324 ptrOSPFLSAHDR oldLSA)
325{
326 UINT16 i;
327 UINT16 j;
328 bool* sameLinkInfo = NULL;
329
330 ptrOSPFRLSA newRLSA = newLSA->lsaInfo;
331 ptrOSPFRLSA oldRLSA = oldLSA->lsaInfo;
332
333 if (newRLSA->linksCount != oldRLSA->linksCount ||
334 newRLSA->VEB != oldRLSA->VEB)
335 return true;
336
337 ptrOSPFRLSALINK* newLink = newRLSA->rlsaLink;
338 ptrOSPFRLSALINK* oldLink = oldRLSA->rlsaLink;
339
340 UINT16 size = newRLSA->linksCount;
341
342 sameLinkInfo = (bool*)calloc(size, sizeof* sameLinkInfo);
343
344 for (i = 0; i < size; i++)
345 {
346 for (j = 0; j < size; j++)
347 {
348 if (!sameLinkInfo[j])
349 {
350 if (newLink[i]->linkId == oldLink[j]->linkId &&
351 newLink[i]->type == oldLink[j]->type &&
352 !OSPFID_COMPARE(newLink[i]->linkData, oldLink[j]->linkData) &&
353 newLink[i]->metric == oldLink[j]->metric)
354 {
355 sameLinkInfo[j] = true;
356 break;
357 }
358 }
359 }
360 }
361
362 for (j = 0; j < size; j++)
363 {
364 if (!sameLinkInfo[j])
365 {
366 free(sameLinkInfo);
367 return true;
368 }
369 }
370
371 free(sameLinkInfo);
372 return false;
373}
374
375bool ospf_rlsa_hasLink(ptrOSPF_PDS ospf,
376 ptrOSPFLSAHDR wlsa,
377 ptrOSPFLSAHDR vlsa)
378{
379 ospf;
380
381 ptrOSPFRLSA rlsa = wlsa->lsaInfo;
382
383 UINT i;
384 for (i = 0; i < rlsa->linksCount; i++)
385 {
386 ptrOSPFRLSALINK link = rlsa->rlsaLink[i];
387 if (link->type == OSPFLINKTYPE_POINT_TO_POINT)
388 {
389 if (vlsa->LSType == LSTYPE_ROUTERLSA &&
390 !OSPFID_COMPARE(link->linkId, vlsa->AdvertisingRouter))
391 return true;
392 }
393 else if (link->type == OSPFLINKTYPE_TRANSIT)
394 {
395 if (vlsa->LSType == LSTYPE_NETWORKLSA &&
396 !OSPFID_COMPARE(link->linkId, vlsa->LinkStateID))
397 return true;
398 }
399 }
400 return false;
401}
402
403bool Ospf_rlsa_getASBRouter(UINT8 VEB)
404{
405 UINT8 asbr = VEB;
406
407 //clears all the bits except seventh bit
408 asbr = asbr & maskChar(7, 7);
409
410 //Right shifts so that last bit represents ASBoundaryRouter
411 asbr = RSHIFTCHAR(asbr, 7);
412
413 return (bool)asbr;
414}
415
416bool Ospf_rlsa_getABRouter(UINT8 VEB)
417{
418 UINT8 abr = VEB;
419
420 //clears all the bits except eighth bit
421 abr = abr & maskChar(8, 8);
422
423 //Right shifts so that last bit represents areaBorderRouter
424 abr = RSHIFTCHAR(abr, 8);
425
426 return (bool)abr;
427}
428
429void ospf_rlsa_originateRouterLSA(ptrOSPFAREA_DS area,
430 bool isFlush)
431{
432 UINT16 rlsaSize;
433 ptrOSPF_PDS ospf = OSPF_PDS_CURRENT();
434 ptrOSPF_IF thisInterface = OSPF_IF_CURRENT();
435 thisInterface;
436
437 ptrOSPFLSAHDR lsa = calloc(1, sizeof* lsa);
438 ptrOSPFLSAHDR old = ospf_lsa_find_old_lsa(area->routerLSAList, ospf->routerId, ospf->routerId);
439
440 rlsaSize = ospf_rlsa_add_foreach_interface(ospf, area, lsa);
441
442 if (!ospf_lsa_update_lsahdr(ospf, area, lsa, old, LSTYPE_ROUTERLSA))
443 {
444 OSPF_LSA_MSG_FREE(lsa);
445 ospf_lsa_schedule_routerLSA(ospf, area, false);
446 return;
447 }
448 if (isFlush)
449 lsa->LSAge = ospf->LSAMaxAge;
450
451 lsa->LinkStateID = ospf->routerId;
452 lsa->AdvertisingRouter = ospf->routerId;
453 lsa->length = OSPFLSAHDR_LEN + rlsaSize;
454
455 if (ospf->routerType == OSPFRTYPE_ABR)
456 ospf_rlsa_setABR(lsa, true);
457
458 area->lastLSAOriginateTime = pstruEventDetails->dEventTime;
459 area->isRouterLSTimer = false;
460
461 ospf_lsa_print(form_dlogId("RLSALOG", ospf->myId), lsa, "Originate RLSA");
462
463 ospf_lsa_flood(ospf,
464 area->areaId,
465 lsa,
466 DEVICE_MYIP(),
467 pstruEventDetails->nInterfaceId);
468
469 if (ospf_lsdb_install(ospf, area->areaId, lsa, area->routerLSAList))
470 ospf_spf_scheduleCalculation(ospf);
471
472 OSPF_LSA_MSG_FREE(lsa);
473}
474