15#include "NetSim_utility.h"
19#include "OSPF_Neighbor.h"
20#include "OSPF_Interface.h"
21#include "OSPF_RoutingTable.h"
24void ospf_lsa_printRLSA(
char* logid,
29 print_ospf_Dlog(logid,
33 for (i = 0; i < rlsa->linksCount; i++)
35 ptrOSPFRLSALINK link = rlsa->rlsaLink[i];
36 print_ospf_Dlog(logid,
41 strOSPFLINKTYPE[link->type],
42 link->linkData->str_ip,
48void OSPFLSAINFO_FREE_RLSA(ptrOSPFRLSA rlsa)
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")
61ptrOSPFRLSA OSPFLSAINFO_COPY_RLSA(ptrOSPFRLSA rlsa)
65 ptrOSPFRLSA r = calloc(1,
sizeof* r);
66 memcpy(r, rlsa,
sizeof* r);
70 r->rlsaLink = calloc(rlsa->linksCount,
sizeof* r->rlsaLink);
71 for (i = 0; i < r->linksCount; i++)
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")
83static void ospf_rlsa_setABR(ptrOSPFLSAHDR hdr,
bool abr)
85 ptrOSPFRLSA rlsa = ospf_list_get_headptr(hdr->lsaInfo);
86 UCHAR* l = &rlsa->VEB;
88 x = x & maskChar(8, 8);
90 *l = *l & (~(maskChar(8, 8)));
92 *l = *l | LSHIFTCHAR(x, 8);
95static void ospf_rlsa_add_link(ptrOSPFRLSA rlsa,
99 rlsa->rlsaLink = realloc(rlsa->rlsaLink, (rlsa->linksCount + 1)*(
sizeof* rlsa->rlsaLink));
101 rlsa->rlsaLink = calloc(1,
sizeof* rlsa->rlsaLink);
102 rlsa->rlsaLink[rlsa->linksCount] = link;
106static ptrOSPFRLSALINK ospf_rlsa_add_type1link(NETSIM_ID d,
109 ptrOSPF_NEIGHBOR neigh)
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;
119static ptrOSPFRLSALINK ospf_rlsa_add_type2link(NETSIM_ID d,
121 ptrOSPF_IF thisInterface)
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;
131static ptrOSPFRLSALINK ospf_rlsa_add_type3link(NETSIM_ID d,
133 ptrOSPF_IF thisInterface)
135 ptrOSPFRLSALINK link = calloc(1,
sizeof* link);
136 link->type = OSPFLINKTYPE_STUB;
137 switch (thisInterface->Type)
139 case OSPFIFTYPE_NBMA:
140 case OSPFIFTYPE_BROADCAST:
142 link->linkId = DEVICE_NWADDRESS(d, in);
143 link->linkData = DEVICE_SUBNETMASK(d, in);
144 link->metric = (UINT16)thisInterface->interfaceOutputCost;
146 case OSPFIFTYPE_P2MP:
147 link->linkId = DEVICE_NWADDRESS(d, in);
148 link->linkData = GET_BROADCAST_IP(4);
152 fnNetSimError(
"Unknown if type %d\n", thisInterface->Type);
158static ptrOSPFRLSALINK ospf_rlsa_add_selflink(ptrOSPF_IF thisInterface)
160 ptrOSPFRLSALINK link = calloc(1,
sizeof* link);
161 link->type = OSPFLINKTYPE_STUB;
162 link->linkId = thisInterface->IPIfAddr;
163 link->linkData = GET_BROADCAST_IP(4);
168static ptrOSPFRLSALINK ospf_rlsa_add_hostRoute(NETSIM_ID d,
170 ptrOSPF_IF thisInterface,
171 ptrOSPF_NEIGHBOR neigh)
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;
184static UINT16 ospf_rlsa_add_foreach_interface(ptrOSPF_PDS ospf,
188 NETSIM_ID d = pstruEventDetails->nDeviceId;
189 ptrOSPFRLSALINK link;
190 ptrOSPFRLSA rlsa = calloc(1,
sizeof* rlsa);
191 UINT16 size = OSPFRLSA_LEN_FIXED;
193 for (i = 0; i < ospf->ifCount; i++)
195 ptrOSPF_IF ospfIf = ospf->ospfIf[i];
196 if (ospfIf->State == OSPFIFSTATE_DOWN)
198 if (OSPFID_COMPARE(ospfIf->areaId, area->areaId))
201 switch (ospfIf->Type)
203 case OSPFIFTYPE_BROADCAST:
205 if (ospfIf->State == OSPFIFSTATE_WAITING)
207 link = ospf_rlsa_add_type3link(d,
210 ospf_rlsa_add_link(rlsa, link);
211 size += OSPFRLSALINK_LEN_FIXED;
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)))
218 link = ospf_rlsa_add_type2link(d,
221 ospf_rlsa_add_link(rlsa, link);
222 size += OSPFRLSALINK_LEN_FIXED;
226 link = ospf_rlsa_add_type3link(d,
229 ospf_rlsa_add_link(rlsa, link);
230 size += OSPFRLSALINK_LEN_FIXED;
234 case OSPFIFTYPE_P2MP:
236 link = ospf_rlsa_add_selflink(ospfIf);
237 ospf_rlsa_add_link(rlsa, link);
238 size += OSPFRLSALINK_LEN_FIXED;
241 for (n = 0; n < ospfIf->neighborRouterCount; n++)
243 ptrOSPF_NEIGHBOR neigh = ospfIf->neighborRouterList[n];
244 if (neigh->state == OSPFNEIGHSTATE_Full)
246 link = ospf_rlsa_add_type1link(d,
250 ospf_rlsa_add_link(rlsa, link);
251 size += OSPFRLSALINK_LEN_FIXED;
258 NETSIM_ID in = ospfIf->id;
259 if (!ospfIf->neighborRouterCount &&
260 ospfIf->State == OSPFIFSTATE_P2P)
262 if (DEVICE_INTERFACE(d, in)->nInterfaceType != INTERFACE_VIRTUAL &&
263 DEVICE_MACLAYER(d, in)->nMacProtocolId == MAC_PROTOCOL_P2P)
265 link = ospf_rlsa_add_type3link(d,
268 ospf_rlsa_add_link(rlsa, link);
269 size += OSPFRLSALINK_LEN_FIXED;
273 for (n = 0; n < ospfIf->neighborRouterCount; n++)
275 ptrOSPF_NEIGHBOR neigh = ospfIf->neighborRouterList[n];
276 if (neigh->state == OSPFNEIGHSTATE_Full)
280 link = ospf_rlsa_add_type1link(d,
284 ospf_rlsa_add_link(rlsa, link);
285 size += OSPFRLSALINK_LEN_FIXED;
287 if (ospfIf->State == OSPFIFSTATE_P2P)
289 if (DEVICE_INTERFACE(d, in)->nInterfaceType != INTERFACE_VIRTUAL &&
290 DEVICE_MACLAYER(d, in)->nMacProtocolId == MAC_PROTOCOL_P2P)
292 link = ospf_rlsa_add_type3link(d,
295 ospf_rlsa_add_link(rlsa, link);
296 size += OSPFRLSALINK_LEN_FIXED;
300 link = ospf_rlsa_add_hostRoute(d,
304 ospf_rlsa_add_link(rlsa, link);
305 size += OSPFRLSALINK_LEN_FIXED;
312 fnNetSimError(
"Unknown if type %d for interface %d, router %s\n",
315 ospf->routerId->str_ip);
319 ospf_lsahdr_add_lsa(lsa, rlsa, size);
323bool ospf_rlsa_isBodyChanged(ptrOSPFLSAHDR newLSA,
324 ptrOSPFLSAHDR oldLSA)
328 bool* sameLinkInfo = NULL;
330 ptrOSPFRLSA newRLSA = newLSA->lsaInfo;
331 ptrOSPFRLSA oldRLSA = oldLSA->lsaInfo;
333 if (newRLSA->linksCount != oldRLSA->linksCount ||
334 newRLSA->VEB != oldRLSA->VEB)
337 ptrOSPFRLSALINK* newLink = newRLSA->rlsaLink;
338 ptrOSPFRLSALINK* oldLink = oldRLSA->rlsaLink;
340 UINT16 size = newRLSA->linksCount;
342 sameLinkInfo = (
bool*)calloc(size,
sizeof* sameLinkInfo);
344 for (i = 0; i < size; i++)
346 for (j = 0; j < size; j++)
348 if (!sameLinkInfo[j])
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)
355 sameLinkInfo[j] =
true;
362 for (j = 0; j < size; j++)
364 if (!sameLinkInfo[j])
375bool ospf_rlsa_hasLink(ptrOSPF_PDS ospf,
381 ptrOSPFRLSA rlsa = wlsa->lsaInfo;
384 for (i = 0; i < rlsa->linksCount; i++)
386 ptrOSPFRLSALINK link = rlsa->rlsaLink[i];
387 if (link->type == OSPFLINKTYPE_POINT_TO_POINT)
389 if (vlsa->LSType == LSTYPE_ROUTERLSA &&
390 !OSPFID_COMPARE(link->linkId, vlsa->AdvertisingRouter))
393 else if (link->type == OSPFLINKTYPE_TRANSIT)
395 if (vlsa->LSType == LSTYPE_NETWORKLSA &&
396 !OSPFID_COMPARE(link->linkId, vlsa->LinkStateID))
403bool Ospf_rlsa_getASBRouter(UINT8 VEB)
408 asbr = asbr & maskChar(7, 7);
411 asbr = RSHIFTCHAR(asbr, 7);
416bool Ospf_rlsa_getABRouter(UINT8 VEB)
421 abr = abr & maskChar(8, 8);
424 abr = RSHIFTCHAR(abr, 8);
429void ospf_rlsa_originateRouterLSA(ptrOSPFAREA_DS area,
433 ptrOSPF_PDS ospf = OSPF_PDS_CURRENT();
434 ptrOSPF_IF thisInterface = OSPF_IF_CURRENT();
437 ptrOSPFLSAHDR lsa = calloc(1,
sizeof* lsa);
438 ptrOSPFLSAHDR old = ospf_lsa_find_old_lsa(area->routerLSAList, ospf->routerId, ospf->routerId);
440 rlsaSize = ospf_rlsa_add_foreach_interface(ospf, area, lsa);
442 if (!ospf_lsa_update_lsahdr(ospf, area, lsa, old, LSTYPE_ROUTERLSA))
444 OSPF_LSA_MSG_FREE(lsa);
445 ospf_lsa_schedule_routerLSA(ospf, area,
false);
449 lsa->LSAge = ospf->LSAMaxAge;
451 lsa->LinkStateID = ospf->routerId;
452 lsa->AdvertisingRouter = ospf->routerId;
453 lsa->length = OSPFLSAHDR_LEN + rlsaSize;
455 if (ospf->routerType == OSPFRTYPE_ABR)
456 ospf_rlsa_setABR(lsa,
true);
458 area->lastLSAOriginateTime = pstruEventDetails->dEventTime;
459 area->isRouterLSTimer =
false;
461 ospf_lsa_print(form_dlogId(
"RLSALOG", ospf->myId), lsa,
"Originate RLSA");
467 pstruEventDetails->nInterfaceId);
469 if (ospf_lsdb_install(ospf, area->areaId, lsa, area->routerLSAList))
470 ospf_spf_scheduleCalculation(ospf);
472 OSPF_LSA_MSG_FREE(lsa);