INET Framework for OMNeT++/OMNEST
inet::ospf::LinkStateUpdateHandler Class Reference

#include <LinkStateUpdateHandler.h>

Inheritance diagram for inet::ospf::LinkStateUpdateHandler:
inet::ospf::IMessageHandler

Classes

struct  AcknowledgementFlags
 

Public Member Functions

 LinkStateUpdateHandler (Router *containingRouter)
 
void processPacket (OSPFPacket *packet, Interface *intf, Neighbor *neighbor) override
 
- Public Member Functions inherited from inet::ospf::IMessageHandler
 IMessageHandler (Router *containingRouter)
 
virtual ~IMessageHandler ()
 

Private Member Functions

bool validateLSChecksum (OSPFLSA *lsa)
 
void acknowledgeLSA (OSPFLSAHeader &lsaHeader, Interface *intf, AcknowledgementFlags acknowledgementFlags, RouterID lsaSource)
 

Additional Inherited Members

- Protected Attributes inherited from inet::ospf::IMessageHandler
Routerrouter
 

Constructor & Destructor Documentation

inet::ospf::LinkStateUpdateHandler::LinkStateUpdateHandler ( Router containingRouter)
39  :
40  IMessageHandler(containingRouter)
41 {
42 }
IMessageHandler(Router *containingRouter)
Definition: IMessageHandler.h:38

Member Function Documentation

void inet::ospf::LinkStateUpdateHandler::acknowledgeLSA ( OSPFLSAHeader lsaHeader,
Interface intf,
LinkStateUpdateHandler::AcknowledgementFlags  acknowledgementFlags,
RouterID  lsaSource 
)
private

Referenced by processPacket().

295 {
296  bool sendDirectAcknowledgment = false;
297 
298  if (!acknowledgementFlags.floodedBackOut) {
299  if (intf->getState() == Interface::BACKUP_STATE) {
300  if ((acknowledgementFlags.lsaIsNewer && (lsaSource == intf->getDesignatedRouter().routerID)) ||
301  (acknowledgementFlags.lsaIsDuplicate && acknowledgementFlags.impliedAcknowledgement))
302  {
303  intf->addDelayedAcknowledgement(lsaHeader);
304  }
305  else {
306  if ((acknowledgementFlags.lsaIsDuplicate && !acknowledgementFlags.impliedAcknowledgement) ||
307  (acknowledgementFlags.lsaReachedMaxAge &&
308  acknowledgementFlags.noLSAInstanceInDatabase &&
309  acknowledgementFlags.anyNeighborInExchangeOrLoadingState))
310  {
311  sendDirectAcknowledgment = true;
312  }
313  }
314  }
315  else {
316  if (acknowledgementFlags.lsaIsNewer) {
317  intf->addDelayedAcknowledgement(lsaHeader);
318  }
319  else {
320  if ((acknowledgementFlags.lsaIsDuplicate && !acknowledgementFlags.impliedAcknowledgement) ||
321  (acknowledgementFlags.lsaReachedMaxAge &&
322  acknowledgementFlags.noLSAInstanceInDatabase &&
323  acknowledgementFlags.anyNeighborInExchangeOrLoadingState))
324  {
325  sendDirectAcknowledgment = true;
326  }
327  }
328  }
329  }
330 
331  if (sendDirectAcknowledgment) {
332  OSPFLinkStateAcknowledgementPacket *ackPacket = new OSPFLinkStateAcknowledgementPacket();
333 
334  ackPacket->setType(LINKSTATE_ACKNOWLEDGEMENT_PACKET);
335  ackPacket->setRouterID(IPv4Address(router->getRouterID()));
336  ackPacket->setAreaID(IPv4Address(intf->getArea()->getAreaID()));
337  ackPacket->setAuthenticationType(intf->getAuthenticationType());
338  AuthenticationKeyType authKey = intf->getAuthenticationKey();
339  for (int i = 0; i < 8; i++) {
340  ackPacket->setAuthentication(i, authKey.bytes[i]);
341  }
342 
343  ackPacket->setLsaHeadersArraySize(1);
344  ackPacket->setLsaHeaders(0, lsaHeader);
345 
346  ackPacket->setByteLength(OSPF_HEADER_LENGTH + OSPF_LSA_HEADER_LENGTH);
347 
348  int ttl = (intf->getType() == Interface::VIRTUAL) ? VIRTUAL_LINK_TTL : 1;
349 
350  if (intf->getType() == Interface::BROADCAST) {
351  if ((intf->getState() == Interface::DESIGNATED_ROUTER_STATE) ||
352  (intf->getState() == Interface::BACKUP_STATE) ||
353  (intf->getDesignatedRouter() == NULL_DESIGNATEDROUTERID))
354  {
355  router->getMessageHandler()->sendPacket(ackPacket, IPv4Address::ALL_OSPF_ROUTERS_MCAST, intf->getIfIndex(), ttl);
356  }
357  else {
359  }
360  }
361  else {
362  if (intf->getType() == Interface::POINTTOPOINT) {
363  router->getMessageHandler()->sendPacket(ackPacket, IPv4Address::ALL_OSPF_ROUTERS_MCAST, intf->getIfIndex(), ttl);
364  }
365  else {
366  Neighbor *neighbor = intf->getNeighborByID(lsaSource);
367  ASSERT(neighbor);
368  router->getMessageHandler()->sendPacket(ackPacket, neighbor->getAddress(), intf->getIfIndex(), ttl);
369  }
370  }
371  }
372 }
#define VIRTUAL_LINK_TTL
Definition: OSPFcommon.h:45
Definition: OSPFInterface.h:60
Router * router
Definition: IMessageHandler.h:35
Definition: OSPFInterface.h:56
RouterID getRouterID() const
Definition: OSPFRouter.h:72
const DesignatedRouterID NULL_DESIGNATEDROUTERID
Definition: OSPFcommon.h:164
Definition: OSPFInterface.h:57
#define OSPF_LSA_HEADER_LENGTH
Definition: OSPFcommon.h:49
Definition: OSPFInterface.h:69
void sendPacket(OSPFPacket *packet, IPv4Address destination, int outputIfIndex, short ttl=1)
Definition: MessageHandler.cc:305
#define OSPF_HEADER_LENGTH
Definition: OSPFcommon.h:48
MessageHandler * getMessageHandler()
Definition: OSPFRouter.h:77
static const IPv4Address ALL_OSPF_DESIGNATED_ROUTERS_MCAST
224.0.0.6 All OSPF Designated Routers
Definition: IPv4Address.h:111
uint8_t ttl
Definition: TCP_NSC.cc:87
static const IPv4Address ALL_OSPF_ROUTERS_MCAST
224.0.0.5 All OSPF routers (DR Others)
Definition: IPv4Address.h:110
void inet::ospf::LinkStateUpdateHandler::processPacket ( OSPFPacket packet,
Interface intf,
Neighbor neighbor 
)
overridevirtual
See also
RFC2328 Section 13.

Implements inet::ospf::IMessageHandler.

Referenced by inet::ospf::MessageHandler::processPacket().

48 {
49  router->getMessageHandler()->printEvent("Link State update packet received", intf, neighbor);
50 
51  OSPFLinkStateUpdatePacket *lsUpdatePacket = check_and_cast<OSPFLinkStateUpdatePacket *>(packet);
52  bool shouldRebuildRoutingTable = false;
53 
54  if (neighbor->getState() >= Neighbor::EXCHANGE_STATE) {
55  AreaID areaID = lsUpdatePacket->getAreaID();
56  Area *area = router->getAreaByID(areaID);
57  LSAType currentType = ROUTERLSA_TYPE;
58  unsigned int currentLSAIndex = 0;
59 
60  EV_INFO << " Processing packet contents:\n";
61 
62  while (currentType <= AS_EXTERNAL_LSA_TYPE) {
63  unsigned int lsaCount = 0;
64 
65  switch (currentType) {
66  case ROUTERLSA_TYPE:
67  lsaCount = lsUpdatePacket->getRouterLSAsArraySize();
68  break;
69 
70  case NETWORKLSA_TYPE:
71  lsaCount = lsUpdatePacket->getNetworkLSAsArraySize();
72  break;
73 
76  lsaCount = lsUpdatePacket->getSummaryLSAsArraySize();
77  break;
78 
80  lsaCount = lsUpdatePacket->getAsExternalLSAsArraySize();
81  break;
82 
83  default:
84  throw cRuntimeError("Invalid currentType:%d", currentType);
85  }
86 
87  for (unsigned int i = 0; i < lsaCount; i++) {
88  OSPFLSA *currentLSA;
89 
90  switch (currentType) {
91  case ROUTERLSA_TYPE:
92  currentLSA = (&(lsUpdatePacket->getRouterLSAs(i)));
93  break;
94 
95  case NETWORKLSA_TYPE:
96  currentLSA = (&(lsUpdatePacket->getNetworkLSAs(i)));
97  break;
98 
101  currentLSA = (&(lsUpdatePacket->getSummaryLSAs(i)));
102  break;
103 
105  currentLSA = (&(lsUpdatePacket->getAsExternalLSAs(i)));
106  break;
107 
108  default:
109  throw cRuntimeError("Invalid currentType:%d", currentType);
110  }
111 
112  if (!validateLSChecksum(currentLSA)) {
113  continue;
114  }
115 
116  LSAType lsaType = static_cast<LSAType>(currentLSA->getHeader().getLsType());
117  if ((lsaType != ROUTERLSA_TYPE) &&
118  (lsaType != NETWORKLSA_TYPE) &&
119  (lsaType != SUMMARYLSA_NETWORKS_TYPE) &&
120  (lsaType != SUMMARYLSA_ASBOUNDARYROUTERS_TYPE) &&
121  (lsaType != AS_EXTERNAL_LSA_TYPE))
122  {
123  continue;
124  }
125 
126  LSAProcessingMarker marker(currentLSAIndex++);
127  EV_DETAIL << " " << currentLSA->getHeader() << "\n";
128 
129  //FIXME area maybe nullptr
130  if ((lsaType == AS_EXTERNAL_LSA_TYPE) && !(area != nullptr && area->getExternalRoutingCapability())) {
131  continue;
132  }
133  LSAKeyType lsaKey;
134 
135  lsaKey.linkStateID = currentLSA->getHeader().getLinkStateID();
136  lsaKey.advertisingRouter = currentLSA->getHeader().getAdvertisingRouter();
137 
138  OSPFLSA *lsaInDatabase = router->findLSA(lsaType, lsaKey, areaID);
139  unsigned short lsAge = currentLSA->getHeader().getLsAge();
140  AcknowledgementFlags ackFlags;
141 
142  ackFlags.floodedBackOut = false;
143  ackFlags.lsaIsNewer = false;
144  ackFlags.lsaIsDuplicate = false;
145  ackFlags.impliedAcknowledgement = false;
146  ackFlags.lsaReachedMaxAge = (lsAge == MAX_AGE);
147  ackFlags.noLSAInstanceInDatabase = (lsaInDatabase == nullptr);
148  ackFlags.anyNeighborInExchangeOrLoadingState = router->hasAnyNeighborInStates(Neighbor::EXCHANGE_STATE | Neighbor::LOADING_STATE);
149 
150  if ((ackFlags.lsaReachedMaxAge) && (ackFlags.noLSAInstanceInDatabase) && (!ackFlags.anyNeighborInExchangeOrLoadingState)) {
151  if (intf->getType() == Interface::BROADCAST) {
152  if ((intf->getState() == Interface::DESIGNATED_ROUTER_STATE) ||
153  (intf->getState() == Interface::BACKUP_STATE) ||
154  (intf->getDesignatedRouter() == NULL_DESIGNATEDROUTERID))
155  {
156  intf->sendLSAcknowledgement(&(currentLSA->getHeader()), IPv4Address::ALL_OSPF_ROUTERS_MCAST);
157  }
158  else {
159  intf->sendLSAcknowledgement(&(currentLSA->getHeader()), IPv4Address::ALL_OSPF_DESIGNATED_ROUTERS_MCAST);
160  }
161  }
162  else {
163  if (intf->getType() == Interface::POINTTOPOINT) {
164  intf->sendLSAcknowledgement(&(currentLSA->getHeader()), IPv4Address::ALL_OSPF_ROUTERS_MCAST);
165  }
166  else {
167  intf->sendLSAcknowledgement(&(currentLSA->getHeader()), neighbor->getAddress());
168  }
169  }
170  continue;
171  }
172 
173  if (!ackFlags.noLSAInstanceInDatabase) {
174  // operator< and operator== on OSPFLSAHeaders determines which one is newer(less means older)
175  ackFlags.lsaIsNewer = (lsaInDatabase->getHeader() < currentLSA->getHeader());
176  ackFlags.lsaIsDuplicate = (operator==(lsaInDatabase->getHeader(), currentLSA->getHeader()));
177  }
178  if ((ackFlags.noLSAInstanceInDatabase) || (ackFlags.lsaIsNewer)) {
179  LSATrackingInfo *info = (!ackFlags.noLSAInstanceInDatabase) ? dynamic_cast<LSATrackingInfo *>(lsaInDatabase) : nullptr;
180  if ((!ackFlags.noLSAInstanceInDatabase) &&
181  (info != nullptr) &&
182  (info->getSource() == LSATrackingInfo::FLOODED) &&
183  (info->getInstallTime() < MIN_LS_ARRIVAL))
184  {
185  continue;
186  }
187  ackFlags.floodedBackOut = router->floodLSA(currentLSA, areaID, intf, neighbor);
188  if (!ackFlags.noLSAInstanceInDatabase) {
189  LSAKeyType lsaKey;
190 
191  lsaKey.linkStateID = lsaInDatabase->getHeader().getLinkStateID();
192  lsaKey.advertisingRouter = lsaInDatabase->getHeader().getAdvertisingRouter();
193 
195  }
196  shouldRebuildRoutingTable |= router->installLSA(currentLSA, areaID);
197 
198  // Add externalIPRoute in IPRoutingTable if this route is learned by BGP
199  if (currentType == AS_EXTERNAL_LSA_TYPE) {
200  OSPFASExternalLSA *externalLSA = &(lsUpdatePacket->getAsExternalLSAs(0));
201  if (externalLSA->getContents().getExternalRouteTag() == OSPF_EXTERNAL_ROUTES_LEARNED_BY_BGP) {
202  IPv4Address externalAddr = currentLSA->getHeader().getLinkStateID();
203  int ifName = intf->getIfIndex();
204  router->addExternalRouteInIPTable(externalAddr, externalLSA->getContents(), ifName);
205  }
206  }
207 
208  EV_INFO << " (update installed)\n";
209 
210  acknowledgeLSA(currentLSA->getHeader(), intf, ackFlags, lsUpdatePacket->getRouterID());
211  if ((currentLSA->getHeader().getAdvertisingRouter() == router->getRouterID()) ||
212  ((lsaType == NETWORKLSA_TYPE) &&
213  (router->isLocalAddress(currentLSA->getHeader().getLinkStateID()))))
214  {
215  if (ackFlags.noLSAInstanceInDatabase) {
216  currentLSA->getHeader().setLsAge(MAX_AGE);
217  router->floodLSA(currentLSA, areaID);
218  }
219  else {
220  if (ackFlags.lsaIsNewer) {
221  long sequenceNumber = currentLSA->getHeader().getLsSequenceNumber();
222  if (sequenceNumber == MAX_SEQUENCE_NUMBER) {
223  lsaInDatabase->getHeader().setLsAge(MAX_AGE);
224  router->floodLSA(lsaInDatabase, areaID);
225  }
226  else {
227  lsaInDatabase->getHeader().setLsSequenceNumber(sequenceNumber + 1);
228  router->floodLSA(lsaInDatabase, areaID);
229  }
230  }
231  }
232  }
233  continue;
234  }
235  if (neighbor->isLSAOnRequestList(lsaKey)) {
236  neighbor->processEvent(Neighbor::BAD_LINK_STATE_REQUEST);
237  break;
238  }
239  if (ackFlags.lsaIsDuplicate) {
240  if (neighbor->isLinkStateRequestListEmpty(lsaKey)) {
241  neighbor->removeFromRetransmissionList(lsaKey);
242  ackFlags.impliedAcknowledgement = true;
243  }
244  acknowledgeLSA(currentLSA->getHeader(), intf, ackFlags, lsUpdatePacket->getRouterID());
245  continue;
246  }
247  if ((lsaInDatabase->getHeader().getLsAge() == MAX_AGE) &&
248  (lsaInDatabase->getHeader().getLsSequenceNumber() == MAX_SEQUENCE_NUMBER))
249  {
250  continue;
251  }
252  if (!neighbor->isOnTransmittedLSAList(lsaKey)) {
253  OSPFLinkStateUpdatePacket *updatePacket = intf->createUpdatePacket(lsaInDatabase);
254  if (updatePacket != nullptr) {
255  int ttl = (intf->getType() == Interface::VIRTUAL) ? VIRTUAL_LINK_TTL : 1;
256 
257  if (intf->getType() == Interface::BROADCAST) {
258  if ((intf->getState() == Interface::DESIGNATED_ROUTER_STATE) ||
259  (intf->getState() == Interface::BACKUP_STATE) ||
260  (intf->getDesignatedRouter() == NULL_DESIGNATEDROUTERID))
261  {
262  router->getMessageHandler()->sendPacket(updatePacket, IPv4Address::ALL_OSPF_ROUTERS_MCAST, intf->getIfIndex(), ttl);
263  }
264  else {
266  }
267  }
268  else {
269  if (intf->getType() == Interface::POINTTOPOINT) {
270  router->getMessageHandler()->sendPacket(updatePacket, IPv4Address::ALL_OSPF_ROUTERS_MCAST, intf->getIfIndex(), ttl);
271  }
272  else {
273  router->getMessageHandler()->sendPacket(updatePacket, neighbor->getAddress(), intf->getIfIndex(), ttl);
274  }
275  }
276  }
277  }
278  }
279  currentType = static_cast<LSAType>(currentType + 1);
280  if (currentType == SUMMARYLSA_NETWORKS_TYPE) {
281  currentType = static_cast<LSAType>(currentType + 1);
282  }
283  }
284  }
285 
286  if (shouldRebuildRoutingTable) {
288  }
289 }
#define VIRTUAL_LINK_TTL
Definition: OSPFcommon.h:45
void printEvent(const char *eventString, const Interface *onInterface=nullptr, const Neighbor *forNeighbor=nullptr) const
Definition: MessageHandler.cc:377
void removeFromAllRetransmissionLists(LSAKeyType lsaKey)
Removes all LSAs from all Neighbor&#39;s retransmission lists which are identified by the input lsaKey...
Definition: OSPFRouter.cc:410
Definition: OSPFInterface.h:60
Router * router
Definition: IMessageHandler.h:35
IPv4Address AreaID
Definition: OSPFcommon.h:138
#define MIN_LS_ARRIVAL
Definition: OSPFcommon.h:35
bool operator==(Neighbor::DDPacketID leftID, Neighbor::DDPacketID rightID)
Definition: OSPFNeighbor.h:203
#define OSPF_EXTERNAL_ROUTES_LEARNED_BY_BGP
Definition: OSPFcommon.h:61
Definition: OSPFInterface.h:56
RouterID getRouterID() const
Definition: OSPFRouter.h:72
Definition: OSPFPacket_m.h:246
bool hasAnyNeighborInStates(int states) const
Returns true if any Neighbor on any Interface in any of the Router&#39;s Areas is in any of the input sta...
Definition: OSPFRouter.cc:399
bool installLSA(OSPFLSA *lsa, AreaID areaID=BACKBONE_AREAID)
Installs a new LSA into the Router database.
Definition: OSPFRouter.cc:108
Definition: OSPFNeighbor.h:68
#define MAX_SEQUENCE_NUMBER
Definition: OSPFcommon.h:43
virtual unsigned short getLsAge() const
const DesignatedRouterID NULL_DESIGNATEDROUTERID
Definition: OSPFcommon.h:164
bool floodLSA(OSPFLSA *lsa, AreaID areaID=BACKBONE_AREAID, Interface *intf=nullptr, Neighbor *neighbor=nullptr)
Floods out the input lsa on a set of Interfaces.
Definition: OSPFRouter.cc:429
void addExternalRouteInIPTable(IPv4Address networkAddress, const OSPFASExternalLSAContents &externalRouteContents, int ifIndex)
Add an AS External Route in IPRoutingTable.
Definition: OSPFRouter.cc:1375
Definition: OSPFInterface.h:57
OSPFLSA * findLSA(LSAType lsaType, LSAKeyType lsaKey, AreaID areaID)
Find the LSA identified by the input lsaKey in the database.
Definition: OSPFRouter.cc:230
bool isLocalAddress(IPv4Address address) const
Returns true if the input IPv4 address falls into any of the Router&#39;s Areas&#39; configured IPv4 address ...
Definition: OSPFRouter.cc:455
Area * getAreaByID(AreaID areaID)
Returns the pointer to the Area identified by the input areaID, if it&#39;s on the Area list...
Definition: OSPFRouter.cc:72
#define MAX_AGE
Definition: OSPFcommon.h:36
Definition: OSPFInterface.h:69
Definition: OSPFPacket_m.h:245
LSAType
Enum generated from inet/routing/ospfv2/OSPFPacket.msg:84 by nedtool.
Definition: OSPFPacket_m.h:244
void sendPacket(OSPFPacket *packet, IPv4Address destination, int outputIfIndex, short ttl=1)
Definition: MessageHandler.cc:305
Definition: OSPFPacket_m.h:249
MessageHandler * getMessageHandler()
Definition: OSPFRouter.h:77
virtual OSPFLSAHeader & getHeader()
Definition: OSPFNeighbor.h:67
static const IPv4Address ALL_OSPF_DESIGNATED_ROUTERS_MCAST
224.0.0.6 All OSPF Designated Routers
Definition: IPv4Address.h:111
Definition: OSPFPacket_m.h:247
uint8_t ttl
Definition: TCP_NSC.cc:87
static const IPv4Address ALL_OSPF_ROUTERS_MCAST
224.0.0.5 All OSPF routers (DR Others)
Definition: IPv4Address.h:110
void rebuildRoutingTable()
Rebuilds the routing table from scratch(based on the LSA database).
Definition: OSPFRouter.cc:704
Definition: OSPFPacket_m.h:248
bool inet::ospf::LinkStateUpdateHandler::validateLSChecksum ( OSPFLSA lsa)
inlineprivate

Referenced by processPacket().

44 { return true; } // not implemented

The documentation for this class was generated from the following files: