INET Framework for OMNeT++/OMNEST
inet::ospfv2::Router Class Reference

All OSPF classes are in this namespace. More...

#include <Ospfv2Router.h>

Public Member Functions

 Router (cSimpleModule *containingModule, IInterfaceTable *ift, IIpv4RoutingTable *rt)
 Constructor. More...
 
virtual ~Router ()
 Destructor. More...
 
void setRouterID (RouterId id)
 
RouterId getRouterID () const
 
void setRFC1583Compatibility (bool compatibility)
 
bool getRFC1583Compatibility () const
 
unsigned long getAreaCount () const
 
std::vector< AreaIdgetAreaIds ()
 
MessageHandlergetMessageHandler ()
 
unsigned long getASExternalLSACount () const
 
AsExternalLsagetASExternalLSA (unsigned long i)
 
const AsExternalLsagetASExternalLSA (unsigned long i) const
 
bool getASBoundaryRouter () const
 
unsigned long getRoutingTableEntryCount () const
 
Ospfv2RoutingTableEntrygetRoutingTableEntry (unsigned long i)
 
const Ospfv2RoutingTableEntrygetRoutingTableEntry (unsigned long i) const
 
void addRoutingTableEntry (Ospfv2RoutingTableEntry *entry)
 
void addWatches ()
 Adds OMNeT++ watches for the routerID, the list of Areas and the list of AS External LSAs. More...
 
void addArea (Ospfv2Area *area)
 Adds a new Area to the Area list. More...
 
Ospfv2AreagetAreaByID (AreaId areaID)
 Returns the pointer to the Area identified by the input areaID, if it's on the Area list, nullptr otherwise. More...
 
Ospfv2AreagetAreaByAddr (Ipv4Address address)
 Returns the Area pointer from the Area list which contains the input Ipv4 address, nullptr if there's no such area connected to the Router. More...
 
Ospfv2InterfacegetNonVirtualInterface (unsigned char ifIndex)
 Returns the pointer of the physical Interface identified by the input interface index, nullptr if the Router doesn't have such an interface. More...
 
bool installLSA (const Ospfv2Lsa *lsa, AreaId areaID=BACKBONE_AREAID)
 Installs a new LSA into the Router database. More...
 
Ospfv2LsafindLSA (Ospfv2LsaType lsaType, LsaKeyType lsaKey, AreaId areaID)
 Find the LSA identified by the input lsaKey in the database. More...
 
void ageDatabase ()
 Ages the LSAs in the Router's database. More...
 
bool hasAnyNeighborInStates (int states) const
 Returns true if any Neighbor on any Interface in any of the Router's Areas is in any of the input states, false otherwise. More...
 
void removeFromAllRetransmissionLists (LsaKeyType lsaKey)
 Removes all LSAs from all Neighbor's retransmission lists which are identified by the input lsaKey. More...
 
bool isOnAnyRetransmissionList (LsaKeyType lsaKey) const
 Returns true if there's at least one LSA on any Neighbor's retransmission list identified by the input lsaKey, false otherwise. More...
 
bool floodLSA (const Ospfv2Lsa *lsa, AreaId areaID=BACKBONE_AREAID, Ospfv2Interface *intf=nullptr, Neighbor *neighbor=nullptr)
 Floods out the input lsa on a set of Interfaces. More...
 
bool isLocalAddress (Ipv4Address address) const
 Returns true if the input Ipv4 address falls into any of the Router's Areas' configured Ipv4 address ranges, false otherwise. More...
 
bool hasAddressRange (const Ipv4AddressRange &addressRange) const
 Returns true if one of the Router's Areas the same Ipv4 address range configured as the input Ipv4 address range, false otherwise. More...
 
bool isDestinationUnreachable (Ospfv2Lsa *lsa) const
 Returns true if the destination described by the input lsa is in the routing table, false otherwise. More...
 
Ospfv2RoutingTableEntrylookup (Ipv4Address destination, std::vector< Ospfv2RoutingTableEntry * > *table=nullptr) const
 Do a lookup in either the input OSPF routing table, or if it's nullptr then in the Router's own routing table. More...
 
void rebuildRoutingTable ()
 Rebuilds the routing table from scratch(based on the LSA database). More...
 
bool deleteRoute (Ospfv2RoutingTableEntry *entry)
 
Ipv4AddressRange getContainingAddressRange (const Ipv4AddressRange &addressRange, bool *advertise=nullptr) const
 Scans through the router's areas' preconfigured address ranges and returns the one containing the input addressRange. More...
 
Ipv4RoutegetDefaultRoute ()
 get the default route in the routing table. More...
 
void updateExternalRoute (Ipv4Address networkAddress, const Ospfv2AsExternalLsaContents &externalRouteContents, int ifIndex=-1)
 Stores information on an AS External Route in externalRoutes and intalls(or updates) a new AsExternalLsa into the database. More...
 
void addExternalRouteInIPTable (Ipv4Address networkAddress, const Ospfv2AsExternalLsaContents &externalRouteContents, int ifIndex)
 Add an AS External Route in IPRoutingTable. More...
 
void removeExternalRoute (Ipv4Address networkAddress)
 Removes an AS External Route from the database. More...
 
Ospfv2RoutingTableEntrygetPreferredEntry (const Ospfv2Lsa &lsa, bool skipSelfOriginated, std::vector< Ospfv2RoutingTableEntry * > *fromRoutingTable=nullptr)
 Selects the preferred routing table entry for the input LSA(which is either an AsExternalLsa or a SummaryLsa) according to the algorithm defined in RFC2328 Section 16.4. More...
 

Private Member Functions

bool installASExternalLSA (const Ospfv2AsExternalLsa *lsa)
 Installs a new AS External LSA into the Router's database. More...
 
AsExternalLsafindASExternalLSA (LsaKeyType lsaKey)
 Find the AS External LSA identified by the input lsaKey in the database. More...
 
const AsExternalLsafindASExternalLSA (LsaKeyType lsaKey) const
 Find the AS External LSA identified by the input lsaKey in the database. More...
 
AsExternalLsaoriginateASExternalLSA (AsExternalLsa *lsa)
 Originates a new AS External LSA based on the input lsa. More...
 
LinkStateId getUniqueLinkStateID (const Ipv4AddressRange &destination, Metric destinationCost, AsExternalLsa *&lsaToReoriginate, bool externalMetricIsType2=false) const
 Generates a unique LinkStateId for a given destination. More...
 
void calculateASExternalRoutes (std::vector< Ospfv2RoutingTableEntry * > &newRoutingTable)
 Calculate the AS External Routes from the ASExternalLSAs in the database. More...
 
void notifyAboutRoutingTableChanges (std::vector< Ospfv2RoutingTableEntry * > &oldRoutingTable)
 After a routing table rebuild the changes in the routing table are identified and new SummaryLSAs are originated or old ones are flooded out in each area as necessary. More...
 
bool hasRouteToASBoundaryRouter (const std::vector< Ospfv2RoutingTableEntry * > &inRoutingTable, RouterId routerID) const
 Returns true if there is a route to the AS Boundary Router identified by asbrRouterID in the input inRoutingTable, false otherwise. More...
 
std::vector< Ospfv2RoutingTableEntry * > getRoutesToASBoundaryRouter (const std::vector< Ospfv2RoutingTableEntry * > &fromRoutingTable, RouterId routerID) const
 Returns an std::vector of routes leading to the AS Boundary Router identified by asbrRouterID from the input fromRoutingTable. More...
 
void pruneASBoundaryRouterEntries (std::vector< Ospfv2RoutingTableEntry * > &asbrEntries) const
 Prunes the input std::vector of RoutingTableEntries according to the RFC2328 Section 16.4.1. More...
 
Ospfv2RoutingTableEntryselectLeastCostRoutingEntry (std::vector< Ospfv2RoutingTableEntry * > &entries) const
 Selects the least cost RoutingTableEntry from the input std::vector of RoutingTableEntries. More...
 
void printAsExternalLsa ()
 
bool isDirectRoute (Ospfv2RoutingTableEntry &entry)
 

Private Attributes

IInterfaceTableift = nullptr
 
IIpv4RoutingTablert = nullptr
 
RouterId routerID
 The router ID assigned by the IP layer. More...
 
std::map< AreaId, Ospfv2Area * > areasByID
 A map of the contained areas with the AreaId as key. More...
 
std::vector< Ospfv2Area * > areas
 A list of the contained areas. More...
 
std::map< LsaKeyType, AsExternalLsa *, LsaKeyType_LessasExternalLSAsByID
 A map of the ASExternalLSAs advertised by this router. More...
 
std::vector< AsExternalLsa * > asExternalLSAs
 A list of the ASExternalLSAs advertised by this router. More...
 
std::map< Ipv4Address, Ospfv2AsExternalLsaContentsexternalRoutes
 A map of the external route advertised by this router. More...
 
cMessage * ageTimer
 Database age timer - fires every second. More...
 
std::vector< Ospfv2RoutingTableEntry * > ospfRoutingTable
 The OSPF routing table - contains more information than the one in the IP layer. More...
 
MessageHandlermessageHandler
 The message dispatcher class. More...
 
bool rfc1583Compatibility
 Decides whether to handle the preferred routing table entry to an AS boundary router as defined in RFC1583 or not. More...
 

Detailed Description

All OSPF classes are in this namespace.

Represents the full OSPF data structure as laid out in RFC2328.

Constructor & Destructor Documentation

◆ Router()

inet::ospfv2::Router::Router ( cSimpleModule *  containingModule,
IInterfaceTable ift,
IIpv4RoutingTable rt 
)

Constructor.

Initializes internal variables, adds a MessageHandler and starts the Database Age timer.

17  :
18  ift(ift),
19  rt(rt),
22 {
23  messageHandler = new MessageHandler(this, containingModule);
24  ageTimer = new cMessage("Router::DatabaseAgeTimer", DATABASE_AGE_TIMER);
25  ageTimer->setContextPointer(this);
27 }

◆ ~Router()

inet::ospfv2::Router::~Router ( )
virtual

Destructor.

Clears all LSA lists and kills the Database Age timer.

30 {
31  long areaCount = areas.size();
32  for (long i = 0; i < areaCount; i++) {
33  delete areas[i];
34  }
35  long lsaCount = asExternalLSAs.size();
36  for (long j = 0; j < lsaCount; j++) {
37  delete asExternalLSAs[j];
38  }
39  long routeCount = ospfRoutingTable.size();
40  for (long k = 0; k < routeCount; k++) {
41  delete ospfRoutingTable[k];
42  }
44  delete ageTimer;
45  delete messageHandler;
46 }

Member Function Documentation

◆ addArea()

void inet::ospfv2::Router::addArea ( Ospfv2Area area)

Adds a new Area to the Area list.

Parameters
area[in] The Area to add.
57 {
58  area->setRouter(this);
59  areasByID[area->getAreaID()] = area;
60  areas.push_back(area);
61 }

Referenced by inet::ospfv2::Ospfv2ConfigReader::loadAreaFromXML().

◆ addExternalRouteInIPTable()

void inet::ospfv2::Router::addExternalRouteInIPTable ( Ipv4Address  networkAddress,
const Ospfv2AsExternalLsaContents externalRouteContents,
int  ifIndex 
)

Add an AS External Route in IPRoutingTable.

Parameters
networkAddress[in] The external route's network address.
externalRouteContents[in] Route configuration data for the external route.
ifIndex[in]
1416 {
1417  // add the external route to the Ipv4 routing table if it was not added by another module
1418  bool inRoutingTable = false;
1419  for (int32_t i = 1; i < rt->getNumRoutes(); i++) {
1420  const Ipv4Route *entry = rt->getRoute(i);
1421  if ((entry->getDestination() == networkAddress)
1422  && (entry->getNetmask() == externalRouteContents.getNetworkMask())) // TODO is it enough?
1423  {
1424  inRoutingTable = true;
1425  break;
1426  }
1427  }
1428 
1429  if (!inRoutingTable) {
1430  Ipv4Route *entry = new Ipv4Route();
1431  entry->setDestination(networkAddress);
1432  entry->setNetmask(externalRouteContents.getNetworkMask());
1433  entry->setInterface(ift->getInterfaceById(ifIndex));
1434  entry->setSourceType(IRoute::OSPF);
1435  entry->setMetric(OSPFv2_BGP_DEFAULT_COST);
1436  rt->addRoute(entry);
1437  }
1438 }

◆ addRoutingTableEntry()

void inet::ospfv2::Router::addRoutingTableEntry ( Ospfv2RoutingTableEntry entry)
inline
76 { ospfRoutingTable.push_back(entry); }

◆ addWatches()

void inet::ospfv2::Router::addWatches ( )

Adds OMNeT++ watches for the routerID, the list of Areas and the list of AS External LSAs.

49 {
50  WATCH(routerID);
51  WATCH_PTRVECTOR(areas);
52  WATCH_PTRVECTOR(asExternalLSAs);
53  WATCH_PTRVECTOR(ospfRoutingTable);
54 }

Referenced by inet::ospfv2::Ospfv2::createOspfRouter().

◆ ageDatabase()

void inet::ospfv2::Router::ageDatabase ( )

Ages the LSAs in the Router's database.

This method is called on every firing of the DATABASE_AGE_TIMER(every second).

See also
RFC2328 Section 14.
279 {
280  long lsaCount = asExternalLSAs.size();
281  bool shouldRebuildRoutingTable = false;
282 
283  for (long i = 0; i < lsaCount; i++) {
284  unsigned short lsAge = asExternalLSAs[i]->getHeader().getLsAge();
285  bool selfOriginated = (asExternalLSAs[i]->getHeader().getAdvertisingRouter() == routerID);
286  bool unreachable = isDestinationUnreachable(asExternalLSAs[i]);
287  AsExternalLsa *lsa = asExternalLSAs[i];
288 
289  if ((selfOriginated && (lsAge < (LS_REFRESH_TIME - 1))) || (!selfOriginated && (lsAge < (MAX_AGE - 1)))) {
290  lsa->getHeaderForUpdate().setLsAge(lsAge + 1);
291  if ((lsAge + 1) % CHECK_AGE == 0) {
292  if (!lsa->validateLSChecksum()) {
293  EV_ERROR << "Invalid LS checksum. Memory error detected!\n";
294  }
295  }
296  lsa->incrementInstallTime();
297  }
298  if (selfOriginated && (lsAge == (LS_REFRESH_TIME - 1))) {
299  if (unreachable) {
300  lsa->getHeaderForUpdate().setLsAge(MAX_AGE);
302  lsa->incrementInstallTime();
303  }
304  else {
305  long sequenceNumber = lsa->getHeader().getLsSequenceNumber();
306  if (sequenceNumber == MAX_SEQUENCE_NUMBER) {
307  lsa->getHeaderForUpdate().setLsAge(MAX_AGE);
309  lsa->incrementInstallTime();
310  }
311  else {
312  AsExternalLsa *newLSA = originateASExternalLSA(lsa);
313 
314  newLSA->getHeaderForUpdate().setLsSequenceNumber(sequenceNumber + 1);
315  shouldRebuildRoutingTable |= lsa->update(newLSA);
316  delete newLSA;
317 
319  }
320  }
321  }
322  if (!selfOriginated && (lsAge == MAX_AGE - 1)) {
323  lsa->getHeaderForUpdate().setLsAge(MAX_AGE);
325  lsa->incrementInstallTime();
326  }
327  if (lsAge == MAX_AGE) {
328  LsaKeyType lsaKey;
329 
330  lsaKey.linkStateID = lsa->getHeader().getLinkStateID();
331  lsaKey.advertisingRouter = lsa->getHeader().getAdvertisingRouter();
332 
333  if (!isOnAnyRetransmissionList(lsaKey) &&
335  {
336  if (!selfOriginated || unreachable) {
337  asExternalLSAsByID.erase(lsaKey);
338  delete lsa;
339  asExternalLSAs[i] = nullptr;
340  shouldRebuildRoutingTable = true;
341  }
342  else {
343  if (lsa->getPurgeable()) {
344  asExternalLSAsByID.erase(lsaKey);
345  delete lsa;
346  asExternalLSAs[i] = nullptr;
347  shouldRebuildRoutingTable = true;
348  }
349  else {
350  AsExternalLsa *newLSA = originateASExternalLSA(lsa);
351  long sequenceNumber = lsa->getHeader().getLsSequenceNumber();
352 
353  newLSA->getHeaderForUpdate().setLsSequenceNumber((sequenceNumber == MAX_SEQUENCE_NUMBER) ? INITIAL_SEQUENCE_NUMBER : sequenceNumber + 1);
354  shouldRebuildRoutingTable |= lsa->update(newLSA);
355  delete newLSA;
356 
358  }
359  }
360  }
361  }
362  }
363 
364  auto it = asExternalLSAs.begin();
365  while (it != asExternalLSAs.end()) {
366  if ((*it) == nullptr) {
367  it = asExternalLSAs.erase(it);
368  }
369  else {
370  it++;
371  }
372  }
373 
374  for (uint32_t j = 0; j < areas.size(); j++)
375  areas[j]->ageDatabase();
376 
378 
379  if (shouldRebuildRoutingTable) {
381  }
382 }

Referenced by inet::ospfv2::MessageHandler::handleTimer().

◆ calculateASExternalRoutes()

void inet::ospfv2::Router::calculateASExternalRoutes ( std::vector< Ospfv2RoutingTableEntry * > &  newRoutingTable)
private

Calculate the AS External Routes from the ASExternalLSAs in the database.

Parameters
newRoutingTable[in/out] Push the new RoutingTableEntries into this routing table, and also use this for path calculations.
See also
RFC2328 Section 16.4.
944 {
945  // see RFC 2328 16.4.
946 
948 
949  for (uint32_t i = 0; i < asExternalLSAs.size(); i++) {
950  AsExternalLsa *currentLSA = asExternalLSAs[i];
951  const Ospfv2LsaHeader& currentHeader = currentLSA->getHeader();
952  unsigned short externalCost = currentLSA->getContents().getExternalTOSInfo(0).routeCost;
953  RouterId originatingRouter = currentHeader.getAdvertisingRouter();
954 
955  Ospfv2RoutingTableEntry *preferredEntry = getPreferredEntry(*currentLSA, true, &newRoutingTable);
956  if (!preferredEntry)
957  continue;
958 
959  Ipv4Address destination = currentHeader.getLinkStateID() & currentLSA->getContents().getNetworkMask();
960 
961  Metric preferredCost = preferredEntry->getCost();
962  Ospfv2RoutingTableEntry *destinationEntry = lookup(destination, &newRoutingTable); // (5)
963  if (destinationEntry == nullptr) {
964  bool type2ExternalMetric = currentLSA->getContents().getExternalTOSInfo(0).E_ExternalMetricType;
965  Ospfv2RoutingTableEntry *newEntry = new Ospfv2RoutingTableEntry(ift);
966 
967  newEntry->setDestination(destination);
968  newEntry->setNetmask(currentLSA->getContents().getNetworkMask());
969  newEntry->setArea(preferredEntry->getArea());
970  newEntry->setPathType(type2ExternalMetric ? Ospfv2RoutingTableEntry::TYPE2_EXTERNAL : Ospfv2RoutingTableEntry::TYPE1_EXTERNAL);
971  if (type2ExternalMetric) {
972  newEntry->setCost(preferredCost);
973  newEntry->setType2Cost(externalCost);
974  }
975  else {
976  newEntry->setCost(preferredCost + externalCost);
977  }
978  newEntry->setDestinationType(Ospfv2RoutingTableEntry::NETWORK_DESTINATION);
979  newEntry->setOptionalCapabilities(currentHeader.getLsOptions());
980  newEntry->setLinkStateOrigin(currentLSA);
981 
982  for (unsigned int j = 0; j < preferredEntry->getNextHopCount(); j++) {
983  NextHop nextHop = preferredEntry->getNextHop(j);
984  if (!nextHop.hopAddress.isUnspecified()) {
985  nextHop.advertisingRouter = originatingRouter;
986  newEntry->addNextHop(nextHop);
987  }
988  }
989 
990  newRoutingTable.push_back(newEntry);
991  }
992  else {
993  Ospfv2RoutingTableEntry::RoutingPathType destinationPathType = destinationEntry->getPathType();
994  bool type2ExternalMetric = currentLSA->getContents().getExternalTOSInfo(0).E_ExternalMetricType;
995  unsigned int nextHopCount = preferredEntry->getNextHopCount();
996 
997  if ((destinationPathType == Ospfv2RoutingTableEntry::INTRAAREA) ||
998  (destinationPathType == Ospfv2RoutingTableEntry::INTERAREA)) // (6) (a)
999  {
1000  continue;
1001  }
1002 
1003  if (((destinationPathType == Ospfv2RoutingTableEntry::TYPE1_EXTERNAL) &&
1004  (type2ExternalMetric)) ||
1005  ((destinationPathType == Ospfv2RoutingTableEntry::TYPE2_EXTERNAL) &&
1006  (type2ExternalMetric) &&
1007  (destinationEntry->getType2Cost() < externalCost))) // (6) (b)
1008  {
1009  continue;
1010  }
1011 
1012  Ospfv2RoutingTableEntry *destinationPreferredEntry = getPreferredEntry(*(destinationEntry->getLinkStateOrigin()), false, &newRoutingTable);
1013  if ((!rfc1583Compatibility) &&
1014  (destinationPreferredEntry->getPathType() == Ospfv2RoutingTableEntry::INTRAAREA) &&
1015  (destinationPreferredEntry->getArea() != BACKBONE_AREAID) &&
1016  ((preferredEntry->getPathType() != Ospfv2RoutingTableEntry::INTRAAREA) ||
1017  (preferredEntry->getArea() == BACKBONE_AREAID)))
1018  {
1019  continue;
1020  }
1021 
1022  if ((((destinationPathType == Ospfv2RoutingTableEntry::TYPE1_EXTERNAL) &&
1023  (!type2ExternalMetric) &&
1024  (destinationEntry->getCost() < preferredCost + externalCost))) ||
1025  ((destinationPathType == Ospfv2RoutingTableEntry::TYPE2_EXTERNAL) &&
1026  (type2ExternalMetric) &&
1027  (destinationEntry->getType2Cost() == externalCost) &&
1028  (destinationPreferredEntry->getCost() < preferredCost)))
1029  {
1030  continue;
1031  }
1032 
1033  if (((destinationPathType == Ospfv2RoutingTableEntry::TYPE1_EXTERNAL) &&
1034  (!type2ExternalMetric) &&
1035  (destinationEntry->getCost() == (preferredCost + externalCost))) ||
1036  ((destinationPathType == Ospfv2RoutingTableEntry::TYPE2_EXTERNAL) &&
1037  (type2ExternalMetric) &&
1038  (destinationEntry->getType2Cost() == externalCost) &&
1039  (destinationPreferredEntry->getCost() == preferredCost))) // equal cost
1040  {
1041  for (unsigned int j = 0; j < nextHopCount; j++) {
1042  // TODO merge next hops, not add
1043  NextHop nextHop = preferredEntry->getNextHop(j);
1044  if (!nextHop.hopAddress.isUnspecified()) {
1045  nextHop.advertisingRouter = originatingRouter;
1046  destinationEntry->addNextHop(nextHop);
1047  }
1048  }
1049  continue;
1050  }
1051 
1052  // LSA is better
1053  destinationEntry->setArea(preferredEntry->getArea());
1054  destinationEntry->setPathType(type2ExternalMetric ? Ospfv2RoutingTableEntry::TYPE2_EXTERNAL : Ospfv2RoutingTableEntry::TYPE1_EXTERNAL);
1055  if (type2ExternalMetric) {
1056  destinationEntry->setCost(preferredCost);
1057  destinationEntry->setType2Cost(externalCost);
1058  }
1059  else {
1060  destinationEntry->setCost(preferredCost + externalCost);
1061  }
1062  destinationEntry->setDestinationType(Ospfv2RoutingTableEntry::NETWORK_DESTINATION);
1063  destinationEntry->setOptionalCapabilities(currentHeader.getLsOptions());
1064  destinationEntry->clearNextHops();
1065 
1066  for (unsigned int j = 0; j < nextHopCount; j++) {
1067  NextHop nextHop = preferredEntry->getNextHop(j);
1068  if (!nextHop.hopAddress.isUnspecified()) {
1069  nextHop.advertisingRouter = originatingRouter;
1070  destinationEntry->addNextHop(nextHop);
1071  }
1072  }
1073  }
1074  }
1075 }

Referenced by rebuildRoutingTable().

◆ deleteRoute()

bool inet::ospfv2::Router::deleteRoute ( Ospfv2RoutingTableEntry entry)
777 {
778  auto i = find(ospfRoutingTable, entry);
779  if (i != ospfRoutingTable.end()) {
780  delete *i;
781  ospfRoutingTable.erase(i);
782  return true;
783  }
784  return false;
785 }

Referenced by inet::ospfv2::Ospfv2::handleInterfaceDown().

◆ findASExternalLSA() [1/2]

AsExternalLsa * inet::ospfv2::Router::findASExternalLSA ( LsaKeyType  lsaKey)
private

Find the AS External LSA identified by the input lsaKey in the database.

Parameters
lsaKey[in] Look for the AS External LSA which is identified by this key.
Returns
The pointer to the AS External LSA if it was found, nullptr otherwise.
267 {
268  auto lsaIt = asExternalLSAsByID.find(lsaKey);
269  return (lsaIt != asExternalLSAsByID.end()) ? lsaIt->second : nullptr;
270 }

Referenced by findLSA(), and getUniqueLinkStateID().

◆ findASExternalLSA() [2/2]

const AsExternalLsa * inet::ospfv2::Router::findASExternalLSA ( LsaKeyType  lsaKey) const
private

Find the AS External LSA identified by the input lsaKey in the database.

Parameters
lsaKey[in] Look for the AS External LSA which is identified by this key.
Returns
The const pointer to the AS External LSA if it was found, nullptr otherwise.
273 {
274  auto lsaIt = asExternalLSAsByID.find(lsaKey);
275  return (lsaIt != asExternalLSAsByID.end()) ? lsaIt->second : nullptr;
276 }

◆ findLSA()

Ospfv2Lsa * inet::ospfv2::Router::findLSA ( Ospfv2LsaType  lsaType,
LsaKeyType  lsaKey,
AreaId  areaID 
)

Find the LSA identified by the input lsaKey in the database.

Parameters
lsaType[in] Look for an LSA of this type.
lsaKey[in] Look for the LSA which is identified by this key.
areaID[in] In case of Router, Network and Summary LSAs, look in the Area's database identified by this parameter.
Returns
The pointer to the LSA if it was found, nullptr otherwise.
227 {
228  switch (lsaType) {
229  case ROUTERLSA_TYPE: {
230  auto areaIt = areasByID.find(areaID);
231  if (areaIt != areasByID.end()) {
232  return areaIt->second->findRouterLSA(lsaKey.linkStateID);
233  }
234  }
235  break;
236 
237  case NETWORKLSA_TYPE: {
238  auto areaIt = areasByID.find(areaID);
239  if (areaIt != areasByID.end()) {
240  return areaIt->second->findNetworkLSA(lsaKey.linkStateID);
241  }
242  }
243  break;
244 
247  auto areaIt = areasByID.find(areaID);
248  if (areaIt != areasByID.end()) {
249  return areaIt->second->findSummaryLSA(lsaKey);
250  }
251  }
252  break;
253 
254  case AS_EXTERNAL_LSA_TYPE: {
255  return findASExternalLSA(lsaKey);
256  }
257  break;
258 
259  default:
260  ASSERT(false);
261  break;
262  }
263  return nullptr;
264 }

Referenced by inet::ospfv2::DatabaseDescriptionHandler::processDDPacket(), inet::ospfv2::LinkStateRequestHandler::processPacket(), and inet::ospfv2::LinkStateUpdateHandler::processPacket().

◆ floodLSA()

bool inet::ospfv2::Router::floodLSA ( const Ospfv2Lsa lsa,
AreaId  areaID = BACKBONE_AREAID,
Ospfv2Interface intf = nullptr,
Neighbor neighbor = nullptr 
)

Floods out the input lsa on a set of Interfaces.

See also
RFC2328 Section 13.3.
Parameters
lsa[in] The LSA to be flooded out.
areaID[in] If the lsa is a Router, Network or Summary LSA, then flood it only in this Area.
intf[in] The Interface this LSA arrived on.
neighbor[in] The Nieghbor this LSA arrived from.
Returns
True if the LSA was floooded back out on the receiving Interface, false otherwise.
409 {
410  bool floodedBackOut = false;
411 
412  if (lsa != nullptr) {
413  if (lsa->getHeader().getLsType() == AS_EXTERNAL_LSA_TYPE) {
414  for (uint32_t i = 0; i < areas.size(); i++) {
415  if (areas[i]->getExternalRoutingCapability()) {
416  if (areas[i]->floodLSA(lsa, intf, neighbor)) {
417  floodedBackOut = true;
418  }
419  }
420  /* RFC 2328, Section 3.6: In order to take advantage of the OSPF stub area support,
421  default routing must be used in the stub area. This is
422  accomplished as follows. One or more of the stub area's area
423  border routers must advertise a default route into the stub area
424  via summary-LSAs. These summary defaults are flooded throughout
425  the stub area, but no further.
426  */
427  else {
428  SummaryLsa *summaryLsa = areas[i]->originateSummaryLSA_Stub();
429  if (areas[i]->floodLSA(summaryLsa, intf, neighbor)) {
430  floodedBackOut = true;
431  }
432  }
433  }
434  }
435  else {
436  auto areaIt = areasByID.find(areaID);
437  if (areaIt != areasByID.end()) {
438  floodedBackOut = areaIt->second->floodLSA(lsa, intf, neighbor);
439  }
440  }
441  }
442 
443  return floodedBackOut;
444 }

Referenced by ageDatabase(), installASExternalLSA(), notifyAboutRoutingTableChanges(), inet::ospfv2::LinkStateUpdateHandler::processPacket(), removeExternalRoute(), and updateExternalRoute().

◆ getAreaByAddr()

Ospfv2Area * inet::ospfv2::Router::getAreaByAddr ( Ipv4Address  address)

Returns the Area pointer from the Area list which contains the input Ipv4 address, nullptr if there's no such area connected to the Router.

Parameters
address[in] The Ipv4 address whose containing Area we're looking for.
70 {
71  long areaCount = areas.size();
72 
73  for (long i = 0; i < areaCount; i++) {
74  if (areas[i]->containsAddress(address))
75  return areas[i];
76  }
77 
78  return nullptr;
79 }

◆ getAreaByID()

Ospfv2Area * inet::ospfv2::Router::getAreaByID ( AreaId  areaID)

◆ getAreaCount()

unsigned long inet::ospfv2::Router::getAreaCount ( ) const
inline

◆ getAreaIds()

std::vector< AreaId > inet::ospfv2::Router::getAreaIds ( )
82 {
83  std::vector<AreaId> areaIds;
84  for (auto& entry : areas)
85  areaIds.push_back(entry->getAreaID());
86  return areaIds;
87 }

Referenced by inet::ospfv2::Ospfv2::handleInterfaceDown().

◆ getASBoundaryRouter()

bool inet::ospfv2::Router::getASBoundaryRouter ( ) const
inline
71 { return externalRoutes.size() > 0; }

Referenced by inet::ospfv2::Ospfv2Area::originateRouterLSA().

◆ getASExternalLSA() [1/2]

AsExternalLsa* inet::ospfv2::Router::getASExternalLSA ( unsigned long  i)
inline

◆ getASExternalLSA() [2/2]

const AsExternalLsa* inet::ospfv2::Router::getASExternalLSA ( unsigned long  i) const
inline
70 { return asExternalLSAs[i]; }

◆ getASExternalLSACount()

unsigned long inet::ospfv2::Router::getASExternalLSACount ( ) const
inline

◆ getContainingAddressRange()

Ipv4AddressRange inet::ospfv2::Router::getContainingAddressRange ( const Ipv4AddressRange addressRange,
bool *  advertise = nullptr 
) const

Scans through the router's areas' preconfigured address ranges and returns the one containing the input addressRange.

Parameters
addressRange[in] The address range to look for.
advertise[out] Whether the advertise flag is set in the returned preconfigured address range.
Returns
The containing preconfigured address range if found, NULL_IPV4ADDRESSRANGE otherwise.
1078 {
1079  unsigned long areaCount = areas.size();
1080  for (unsigned long i = 0; i < areaCount; i++) {
1081  Ipv4AddressRange containingAddressRange = areas[i]->getContainingAddressRange(addressRange, advertise);
1082  if (containingAddressRange != NULL_IPV4ADDRESSRANGE) {
1083  return containingAddressRange;
1084  }
1085  }
1086  if (advertise != nullptr) {
1087  *advertise = false;
1088  }
1089  return NULL_IPV4ADDRESSRANGE;
1090 }

Referenced by notifyAboutRoutingTableChanges(), and inet::ospfv2::Ospfv2Area::originateSummaryLSA().

◆ getDefaultRoute()

Ipv4Route * inet::ospfv2::Router::getDefaultRoute ( )

get the default route in the routing table.

1347 {
1348  for (int32_t i = 0; i < rt->getNumRoutes(); i++) {
1349  Ipv4Route *entry = rt->getRoute(i);
1350  if (entry->getDestination().isUnspecified() && entry->getNetmask().isUnspecified())
1351  return entry;
1352  }
1353  return nullptr;
1354 }

Referenced by inet::ospfv2::Ospfv2ConfigReader::initiateDefaultRouteDistribution().

◆ getMessageHandler()

MessageHandler* inet::ospfv2::Router::getMessageHandler ( )
inline
66 { return messageHandler; }

Referenced by inet::ospfv2::LinkStateUpdateHandler::acknowledgeLSA(), inet::ospfv2::Neighbor::clearRequestRetransmissionTimer(), inet::ospfv2::Neighbor::clearUpdateRetransmissionTimer(), inet::ospfv2::Ospfv2Interface::floodLsa(), inet::ospfv2::Ospfv2::handleMessageWhenUp(), inet::ospfv2::InterfaceStateDown::processEvent(), inet::ospfv2::InterfaceStateNotDesignatedRouter::processEvent(), inet::ospfv2::NeighborStateDown::processEvent(), inet::ospfv2::NeighborStateAttempt::processEvent(), inet::ospfv2::NeighborStateExchange::processEvent(), inet::ospfv2::NeighborStateExchangeStart::processEvent(), inet::ospfv2::NeighborStateFull::processEvent(), inet::ospfv2::InterfaceStatePointToPoint::processEvent(), inet::ospfv2::NeighborStateLoading::processEvent(), inet::ospfv2::InterfaceStateWaiting::processEvent(), inet::ospfv2::NeighborStateInit::processEvent(), inet::ospfv2::NeighborStateTwoWay::processEvent(), inet::ospfv2::InterfaceStateBackup::processEvent(), inet::ospfv2::InterfaceStateDesignatedRouter::processEvent(), inet::ospfv2::LinkStateRequestHandler::processPacket(), inet::ospfv2::HelloHandler::processPacket(), inet::ospfv2::LinkStateAcknowledgementHandler::processPacket(), inet::ospfv2::DatabaseDescriptionHandler::processPacket(), inet::ospfv2::LinkStateUpdateHandler::processPacket(), inet::ospfv2::Ospfv2Interface::reset(), inet::ospfv2::Neighbor::reset(), inet::ospfv2::Neighbor::retransmitDatabaseDescriptionPacket(), inet::ospfv2::Neighbor::retransmitUpdatePacket(), inet::ospfv2::Neighbor::sendDatabaseDescriptionPacket(), inet::ospfv2::Ospfv2Interface::sendDelayedAcknowledgements(), inet::ospfv2::Ospfv2Interface::sendHelloPacket(), inet::ospfv2::Neighbor::sendLinkStateRequestPacket(), inet::ospfv2::Ospfv2Interface::sendLsAcknowledgement(), inet::ospfv2::Neighbor::startRequestRetransmissionTimer(), inet::ospfv2::Neighbor::startUpdateRetransmissionTimer(), inet::ospfv2::Neighbor::~Neighbor(), and inet::ospfv2::Ospfv2Interface::~Ospfv2Interface().

◆ getNonVirtualInterface()

Ospfv2Interface * inet::ospfv2::Router::getNonVirtualInterface ( unsigned char  ifIndex)

Returns the pointer of the physical Interface identified by the input interface index, nullptr if the Router doesn't have such an interface.

Parameters
ifIndex[in] The interface index to look for.
90 {
91  long areaCount = areas.size();
92 
93  for (long i = 0; i < areaCount; i++) {
94  Ospfv2Interface *intf = areas[i]->getInterface(ifIndex);
95  if (intf != nullptr) {
96  return intf;
97  }
98  }
99  return nullptr;
100 }

Referenced by inet::ospfv2::Ospfv2Area::originateSummaryLSA().

◆ getPreferredEntry()

Ospfv2RoutingTableEntry * inet::ospfv2::Router::getPreferredEntry ( const Ospfv2Lsa lsa,
bool  skipSelfOriginated,
std::vector< Ospfv2RoutingTableEntry * > *  fromRoutingTable = nullptr 
)

Selects the preferred routing table entry for the input LSA(which is either an AsExternalLsa or a SummaryLsa) according to the algorithm defined in RFC2328 Section 16.4.

points(1) through(3). This method is used when calculating the AS external routes and also when originating an SummaryLsa for an AS Boundary Router.

Parameters
lsa[in] The LSA describing the destination for which the preferred Routing Entry is sought for.
skipSelfOriginated[in] Whether to disregard this LSA if it was self-originated.
fromRoutingTable[in] The Routing Table from which to select the preferred RoutingTableEntry. If it is nullptr then the router's current routing table is used instead.
Returns
The preferred RoutingTableEntry, or nullptr if no such entry exists.
See also
RFC2328 Section 16.4. points(1) through(3)
Area::originateSummaryLSA
890 {
891  // see RFC 2328 16.3. and 16.4.
892  if (fromRoutingTable == nullptr)
893  fromRoutingTable = &ospfRoutingTable;
894 
895  const Ospfv2LsaHeader& lsaHeader = lsa.getHeader();
896  const Ospfv2AsExternalLsa *asExternalLSA = dynamic_cast<const Ospfv2AsExternalLsa *>(&lsa);
897  unsigned long externalCost = (asExternalLSA != nullptr) ? asExternalLSA->getContents().getExternalTOSInfo(0).routeCost : 0;
898  unsigned short lsAge = lsaHeader.getLsAge();
899  RouterId originatingRouter = lsaHeader.getAdvertisingRouter();
900  bool selfOriginated = (originatingRouter == routerID);
901  Ipv4Address forwardingAddress; // 0.0.0.0
902 
903  if (asExternalLSA != nullptr)
904  forwardingAddress = asExternalLSA->getContents().getExternalTOSInfo(0).forwardingAddress;
905 
906  if ((externalCost == LS_INFINITY) || (lsAge == MAX_AGE) || (skipSelfOriginated && selfOriginated)) // (1) and(2)
907  return nullptr;
908 
909  if (!hasRouteToASBoundaryRouter(*fromRoutingTable, originatingRouter)) // (3)
910  return nullptr;
911 
912  if (forwardingAddress.isUnspecified()) { // (3)
913  auto asbrEntries = getRoutesToASBoundaryRouter(*fromRoutingTable, originatingRouter);
915  pruneASBoundaryRouterEntries(asbrEntries);
916  return selectLeastCostRoutingEntry(asbrEntries);
917  }
918  else {
919  Ospfv2RoutingTableEntry *forwardEntry = lookup(forwardingAddress, fromRoutingTable);
920 
921  if (forwardEntry == nullptr)
922  return nullptr;
923 
924  if ((forwardEntry->getPathType() != Ospfv2RoutingTableEntry::INTRAAREA) &&
925  (forwardEntry->getPathType() != Ospfv2RoutingTableEntry::INTERAREA))
926  {
927  return nullptr;
928  }
929 
930  // if a direct delivery, update hop address to point to the forward address
931  if (isDirectRoute(*forwardEntry)) {
932  forwardEntry->clearNextHops();
933  NextHop hop = { forwardEntry->getInterface()->getInterfaceId(), forwardingAddress, routerID };
934  forwardEntry->addNextHop(hop);
935  }
936 
937  return forwardEntry;
938  }
939 
940  return nullptr;
941 }

Referenced by calculateASExternalRoutes(), and inet::ospfv2::Ospfv2Area::originateSummaryLSA().

◆ getRFC1583Compatibility()

bool inet::ospfv2::Router::getRFC1583Compatibility ( ) const
inline
62 { return rfc1583Compatibility; }

◆ getRouterID()

◆ getRoutesToASBoundaryRouter()

std::vector< Ospfv2RoutingTableEntry * > inet::ospfv2::Router::getRoutesToASBoundaryRouter ( const std::vector< Ospfv2RoutingTableEntry * > &  fromRoutingTable,
RouterId  routerID 
) const
private

Returns an std::vector of routes leading to the AS Boundary Router identified by asbrRouterID from the input fromRoutingTable.

If there are no routes leading to the AS Boundary Router, the returned std::vector is empty.

Parameters
fromRoutingTable[in] The routing table to look in.
asbrRouterID[in] The ID of the AS Boundary Router to look for.
815 {
816  std::vector<Ospfv2RoutingTableEntry *> results;
817  for (uint32_t i = 0; i < fromRoutingTable.size(); i++) {
818  Ospfv2RoutingTableEntry *routingEntry = fromRoutingTable[i];
819  if (routingEntry->getDestination() == (asbrRouterID & routingEntry->getNetmask())) {
820  if (!routingEntry->getGateway().isUnspecified())
821  results.push_back(routingEntry);
822  else {
823  // ASBR is a directly-connected router
824  for (uint32_t i = 0; i < areas.size(); i++) {
825  Ospfv2Interface *ospfIfEntry = areas[i]->getInterface(routingEntry->getInterface()->getInterfaceId());
826  if (ospfIfEntry) {
827  Neighbor *neighbor = ospfIfEntry->getNeighborById(asbrRouterID);
828  if (neighbor) {
829  results.push_back(routingEntry);
830  break;
831  }
832  }
833  }
834  }
835  }
836  }
837  return results;
838 }

Referenced by getPreferredEntry().

◆ getRoutingTableEntry() [1/2]

Ospfv2RoutingTableEntry* inet::ospfv2::Router::getRoutingTableEntry ( unsigned long  i)
inline

◆ getRoutingTableEntry() [2/2]

const Ospfv2RoutingTableEntry* inet::ospfv2::Router::getRoutingTableEntry ( unsigned long  i) const
inline
75 { return ospfRoutingTable[i]; }

◆ getRoutingTableEntryCount()

unsigned long inet::ospfv2::Router::getRoutingTableEntryCount ( ) const
inline

◆ getUniqueLinkStateID()

LinkStateId inet::ospfv2::Router::getUniqueLinkStateID ( const Ipv4AddressRange destination,
Metric  destinationCost,
AsExternalLsa *&  lsaToReoriginate,
bool  externalMetricIsType2 = false 
) const
private

Generates a unique LinkStateId for a given destination.

This may require the reorigination of an LSA already in the database(with a different LinkStateId).

Parameters
destination[in] The destination for which a unique LinkStateId is required.
destinationCost[in] The path cost to the destination.
lsaToReoriginate[out] The LSA to reoriginate(which was already in the database, and had to be changed).
externalMetricIsType2[in] True if the destinationCost is given as a Type2 external metric.
Returns
the LinkStateId for the destination.
See also
RFC2328 Appendix E.
Area::getUniqueLinkStateID
1096 {
1097  if (lsaToReoriginate != nullptr) {
1098  delete lsaToReoriginate;
1099  lsaToReoriginate = nullptr;
1100  }
1101 
1102  LsaKeyType lsaKey;
1103 
1104  lsaKey.linkStateID = destination.address;
1105  lsaKey.advertisingRouter = routerID;
1106 
1107  const AsExternalLsa *foundLSA = findASExternalLSA(lsaKey);
1108 
1109  if (foundLSA == nullptr) {
1110  return lsaKey.linkStateID;
1111  }
1112  else {
1113  Ipv4Address existingMask = foundLSA->getContents().getNetworkMask();
1114 
1115  if (destination.mask >= existingMask) {
1116  return lsaKey.linkStateID.makeBroadcastAddress(destination.mask);
1117  }
1118  else {
1119  AsExternalLsa *asExternalLSA = new AsExternalLsa(*foundLSA);
1120 
1121  long sequenceNumber = asExternalLSA->getHeader().getLsSequenceNumber();
1122 
1123  asExternalLSA->getHeaderForUpdate().setLsAge(0);
1124  asExternalLSA->getHeaderForUpdate().setLsSequenceNumber((sequenceNumber == MAX_SEQUENCE_NUMBER) ? INITIAL_SEQUENCE_NUMBER : sequenceNumber + 1);
1125  asExternalLSA->getContentsForUpdate().setNetworkMask(destination.mask);
1126  asExternalLSA->getContentsForUpdate().getExternalTOSInfoForUpdate(0).E_ExternalMetricType = externalMetricIsType2;
1127  asExternalLSA->getContentsForUpdate().getExternalTOSInfoForUpdate(0).routeCost = destinationCost;
1128 
1129  lsaToReoriginate = asExternalLSA;
1130 
1131  return lsaKey.linkStateID.makeBroadcastAddress(existingMask);
1132  }
1133  }
1134 }

◆ hasAddressRange()

bool inet::ospfv2::Router::hasAddressRange ( const Ipv4AddressRange addressRange) const

Returns true if one of the Router's Areas the same Ipv4 address range configured as the input Ipv4 address range, false otherwise.

Parameters
addressRange[in] The Ipv4 address range to look for.
458 {
459  long areaCount = areas.size();
460  for (long i = 0; i < areaCount; i++) {
461  if (areas[i]->hasAddressRange(addressRange)) {
462  return true;
463  }
464  }
465  return false;
466 }

Referenced by inet::ospfv2::Ospfv2Area::calculateInterAreaRoutes().

◆ hasAnyNeighborInStates()

bool inet::ospfv2::Router::hasAnyNeighborInStates ( int  states) const

Returns true if any Neighbor on any Interface in any of the Router's Areas is in any of the input states, false otherwise.

Parameters
states[in] A bitfield combination of NeighborStateType values.
385 {
386  for (uint32_t i = 0; i < areas.size(); i++) {
387  if (areas[i]->hasAnyNeighborInStates(states))
388  return true;
389  }
390  return false;
391 }

Referenced by ageDatabase(), and inet::ospfv2::LinkStateUpdateHandler::processPacket().

◆ hasRouteToASBoundaryRouter()

bool inet::ospfv2::Router::hasRouteToASBoundaryRouter ( const std::vector< Ospfv2RoutingTableEntry * > &  inRoutingTable,
RouterId  routerID 
) const
private

Returns true if there is a route to the AS Boundary Router identified by asbrRouterID in the input inRoutingTable, false otherwise.

Parameters
inRoutingTable[in] The routing table to look in.
asbrRouterID[in] The ID of the AS Boundary Router to look for.
788 {
789  for (uint32_t i = 0; i < inRoutingTable.size(); i++) {
790  Ospfv2RoutingTableEntry *routingEntry = inRoutingTable[i];
791  if (routingEntry->getDestination() == (asbrRouterID & routingEntry->getNetmask())) {
792  if (!routingEntry->getGateway().isUnspecified())
793  return true;
794  else {
795  // ASBR is a directly-connected router
796  bool nextHopFound = false;
797  for (uint32_t i = 0; i < areas.size(); i++) {
798  Ospfv2Interface *ospfIfEntry = areas[i]->getInterface(routingEntry->getInterface()->getInterfaceId());
799  if (ospfIfEntry) {
800  Neighbor *neighbor = ospfIfEntry->getNeighborById(asbrRouterID);
801  if (neighbor) {
802  nextHopFound = true;
803  break;
804  }
805  }
806  }
807  return nextHopFound;
808  }
809  }
810  }
811  return false;
812 }

Referenced by getPreferredEntry().

◆ installASExternalLSA()

bool inet::ospfv2::Router::installASExternalLSA ( const Ospfv2AsExternalLsa lsa)
private

Installs a new AS External LSA into the Router's database.

It tries to install keep one of multiple functionally equivalent AS External LSAs in the database. (See the comment in the method implementation.)

Parameters
lsa[in] The LSA to install. It will be copied into the database.
Returns
True if the routing table needs to be updated, false otherwise.

From RFC2328 Section 12.4.4.1.: "If two routers, both reachable from one another, originate functionally equivalent AS-External-LSAs(i.e., same destination, cost and non-zero forwarding address), then the LSA originated by the router having the highest OSPF Router ID is used. The router having the lower OSPF Router ID can then flush its LSA." The problem is: how do we tell whether two routers are reachable from one another based on a Link State Update packet? 0. We can assume that if this LSA reached this router, then this router is reachable from the other router. But what about the other direction?

  1. The update packet is most likely not sent by the router originating the functionally equivalent AS-External-LSA, so we cannot use the IPv4 packet source address.
  2. The AS-External-LSA contains only the Router ID of the advertising router, so we can only look up "router" type routing entries in the routing table(these contain the Router ID as their Destination ID). However these entries are only inserted into the routing table for intra-area routers...
148 {
166  // TODO how to solve this problem?
167 
168  RouterId advertisingRouter = lsa->getHeader().getAdvertisingRouter();
169 
170  bool reachable = false;
171  for (uint32_t i = 0; i < ospfRoutingTable.size(); i++) {
172  if ((((ospfRoutingTable[i]->getDestinationType() & Ospfv2RoutingTableEntry::AREA_BORDER_ROUTER_DESTINATION) != 0) ||
173  ((ospfRoutingTable[i]->getDestinationType() & Ospfv2RoutingTableEntry::AS_BOUNDARY_ROUTER_DESTINATION) != 0)) &&
174  (ospfRoutingTable[i]->getDestination() == advertisingRouter))
175  {
176  reachable = true;
177  break;
178  }
179  }
180 
181  bool ownLSAFloodedOut = false;
182  LsaKeyType lsaKey;
183 
184  lsaKey.linkStateID = lsa->getHeader().getLinkStateID();
185  lsaKey.advertisingRouter = routerID;
186 
187  auto lsaIt = asExternalLSAsByID.find(lsaKey);
188  if ((lsaIt != asExternalLSAsByID.end()) &&
189  reachable &&
190  (lsaIt->second->getContents().getExternalTOSInfo(0).E_ExternalMetricType == lsa->getContents().getExternalTOSInfo(0).E_ExternalMetricType) &&
191  (lsaIt->second->getContents().getExternalTOSInfo(0).tos == lsa->getContents().getExternalTOSInfo(0).tos) &&
192  (lsaIt->second->getContents().getExternalTOSInfo(0).routeCost == lsa->getContents().getExternalTOSInfo(0).routeCost) &&
193  (lsa->getContents().getExternalTOSInfo(0).forwardingAddress.getInt() != 0) && // forwarding address != 0.0.0.0
194  (lsaIt->second->getContents().getExternalTOSInfo(0).forwardingAddress == lsa->getContents().getExternalTOSInfo(0).forwardingAddress))
195  {
196  if (routerID > advertisingRouter) {
197  return false;
198  }
199  else {
200  lsaIt->second->getHeaderForUpdate().setLsAge(MAX_AGE);
201  floodLSA(lsaIt->second, BACKBONE_AREAID);
202  lsaIt->second->incrementInstallTime();
203  ownLSAFloodedOut = true;
204  }
205  }
206 
207  lsaKey.advertisingRouter = advertisingRouter;
208 
209  lsaIt = asExternalLSAsByID.find(lsaKey);
210  if (lsaIt != asExternalLSAsByID.end()) {
211  unsigned long areaCount = areas.size();
212  for (unsigned long i = 0; i < areaCount; i++) {
213  areas[i]->removeFromAllRetransmissionLists(lsaKey);
214  }
215  return (lsaIt->second->update(lsa)) | ownLSAFloodedOut;
216  }
217  else {
218  AsExternalLsa *lsaCopy = new AsExternalLsa(*lsa);
219  asExternalLSAsByID[lsaKey] = lsaCopy;
220  ASSERT(lsaCopy->getHeader().getLsaLength() != 0);
221  asExternalLSAs.push_back(lsaCopy);
222  return true;
223  }
224 }

Referenced by installLSA(), and updateExternalRoute().

◆ installLSA()

bool inet::ospfv2::Router::installLSA ( const Ospfv2Lsa lsa,
AreaId  areaID = BACKBONE_AREAID 
)

Installs a new LSA into the Router database.

Checks the input LSA's type and installs it into either the selected Area's database, or if it's an AS External LSA then into the Router's common asExternalLSAs list.

Parameters
lsa[in] The LSA to install. It will be copied into the database.
areaID[in] Identifies the input Router, Network and Summary LSA's Area.
Returns
True if the routing table needs to be updated, false otherwise.
103 {
104  switch (lsa->getHeader().getLsType()) {
105  case ROUTERLSA_TYPE: {
106  auto areaIt = areasByID.find(areaID);
107  if (areaIt != areasByID.end()) {
108  const Ospfv2RouterLsa *ospfRouterLSA = check_and_cast<const Ospfv2RouterLsa *>(lsa);
109  return areaIt->second->installRouterLSA(ospfRouterLSA);
110  }
111  }
112  break;
113 
114  case NETWORKLSA_TYPE: {
115  auto areaIt = areasByID.find(areaID);
116  if (areaIt != areasByID.end()) {
117  const Ospfv2NetworkLsa *ospfNetworkLSA = check_and_cast<const Ospfv2NetworkLsa *>(lsa);
118  return areaIt->second->installNetworkLSA(ospfNetworkLSA);
119  }
120  }
121  break;
122 
125  auto areaIt = areasByID.find(areaID);
126  if (areaIt != areasByID.end()) {
127  const Ospfv2SummaryLsa *ospfSummaryLSA = check_and_cast<const Ospfv2SummaryLsa *>(lsa);
128  return areaIt->second->installSummaryLSA(ospfSummaryLSA);
129  }
130  }
131  break;
132 
133  case AS_EXTERNAL_LSA_TYPE: {
134  const Ospfv2AsExternalLsa *ospfASExternalLSA = check_and_cast<const Ospfv2AsExternalLsa *>(lsa);
135  ASSERT(ospfASExternalLSA->getHeader().getLsaLength() != 0);
136  return installASExternalLSA(ospfASExternalLSA);
137  }
138  break;
139 
140  default:
141  ASSERT(false);
142  break;
143  }
144  return false;
145 }

Referenced by inet::ospfv2::LinkStateUpdateHandler::processPacket().

◆ isDestinationUnreachable()

bool inet::ospfv2::Router::isDestinationUnreachable ( Ospfv2Lsa lsa) const

Returns true if the destination described by the input lsa is in the routing table, false otherwise.

Parameters
lsa[in] The LSA which describes the destination to look for.
484 {
485  Ipv4Address destination = Ipv4Address(lsa->getHeader().getLinkStateID());
486 
487  Ospfv2RouterLsa *routerLSA = dynamic_cast<Ospfv2RouterLsa *>(lsa);
488  // TODO verify
489  if (routerLSA) {
490  RoutingInfo *routingInfo = check_and_cast<RoutingInfo *>(routerLSA);
491  if (routerLSA->getHeader().getLinkStateID() == routerID) // this is spfTreeRoot
492  return false;
493 
494  // get the interface address pointing backwards on the shortest path tree
495  unsigned int linkCount = routerLSA->getLinksArraySize();
496  RouterLsa *toRouterLSA = dynamic_cast<RouterLsa *>(routingInfo->getParent());
497  if (toRouterLSA) {
498  bool destinationFound = false;
499  bool unnumberedPointToPointLink = false;
500  Ipv4Address firstNumberedIfAddress;
501 
502  for (unsigned int i = 0; i < linkCount; i++) {
503  const auto& link = routerLSA->getLinks(i);
504 
505  if (link.getType() == POINTTOPOINT_LINK) {
506  if (link.getLinkID() == Ipv4Address(toRouterLSA->getHeader().getLinkStateID())) {
507  if ((link.getLinkData() & 0xFF000000) == 0) {
508  unnumberedPointToPointLink = true;
509  if (!firstNumberedIfAddress.isUnspecified())
510  break;
511  }
512  else {
513  destination = Ipv4Address(link.getLinkData());
514  destinationFound = true;
515  break;
516  }
517  }
518  else {
519  if (((link.getLinkData() & 0xFF000000) != 0) &&
520  firstNumberedIfAddress.isUnspecified())
521  {
522  firstNumberedIfAddress = Ipv4Address(link.getLinkData());
523  }
524  }
525  }
526  else if (link.getType() == TRANSIT_LINK) {
527  if (firstNumberedIfAddress.isUnspecified())
528  firstNumberedIfAddress = Ipv4Address(link.getLinkData());
529  }
530  else if (link.getType() == VIRTUAL_LINK) {
531  if (link.getLinkID() == toRouterLSA->getHeader().getLinkStateID()) {
532  destination = Ipv4Address(link.getLinkData());
533  destinationFound = true;
534  break;
535  }
536  else {
537  if (firstNumberedIfAddress.isUnspecified())
538  firstNumberedIfAddress = Ipv4Address(link.getLinkData());
539  }
540  }
541  // There's no way to get an interface address for the router from a STUB_LINK
542  }
543 
544  if (unnumberedPointToPointLink) {
545  if (!firstNumberedIfAddress.isUnspecified())
546  destination = firstNumberedIfAddress;
547  else
548  return true;
549  }
550 
551  if (!destinationFound)
552  return true;
553  }
554  else {
555  NetworkLsa *toNetworkLSA = dynamic_cast<NetworkLsa *>(routingInfo->getParent());
556  if (toNetworkLSA) {
557  // get the interface address pointing backwards on the shortest path tree
558  bool destinationFound = false;
559  for (unsigned int i = 0; i < linkCount; i++) {
560  const auto& link = routerLSA->getLinks(i);
561 
562  if ((link.getType() == TRANSIT_LINK) &&
563  (link.getLinkID() == Ipv4Address(toNetworkLSA->getHeader().getLinkStateID())))
564  {
565  destination = Ipv4Address(link.getLinkData());
566  destinationFound = true;
567  break;
568  }
569  }
570  if (!destinationFound)
571  return true;
572  }
573  else
574  return true;
575  }
576  }
577 
578  Ospfv2NetworkLsa *networkLSA = dynamic_cast<Ospfv2NetworkLsa *>(lsa);
579  if (networkLSA)
580  destination = networkLSA->getHeader().getLinkStateID() & networkLSA->getNetworkMask();
581 
582  Ospfv2SummaryLsa *summaryLSA = dynamic_cast<Ospfv2SummaryLsa *>(lsa);
583  if ((summaryLSA) && (summaryLSA->getHeader().getLsType() == SUMMARYLSA_NETWORKS_TYPE))
584  destination = summaryLSA->getHeader().getLinkStateID() & summaryLSA->getNetworkMask();
585 
586  Ospfv2AsExternalLsa *asExternalLSA = dynamic_cast<Ospfv2AsExternalLsa *>(lsa);
587  if (asExternalLSA)
588  destination = asExternalLSA->getHeader().getLinkStateID() & asExternalLSA->getContents().getNetworkMask();
589 
590  return lookup(destination) == nullptr;
591 }

Referenced by inet::ospfv2::Ospfv2Area::ageDatabase(), and ageDatabase().

◆ isDirectRoute()

bool inet::ospfv2::Router::isDirectRoute ( Ospfv2RoutingTableEntry entry)
private
1488 {
1489  if (entry.getGateway().isUnspecified())
1490  return true;
1491 
1492  for (int i = 0; i < ift->getNumInterfaces(); i++) {
1493  NetworkInterface *intf = ift->getInterface(i);
1494  if (intf && !intf->isLoopback()) {
1495  const auto& ipv4data = intf->findProtocolData<Ipv4InterfaceData>();
1496  if (ipv4data) {
1497  if ((entry.getDestination() & ipv4data->getNetmask()) == (ipv4data->getIPAddress() & ipv4data->getNetmask()))
1498  return true;
1499  }
1500  }
1501  }
1502 
1503  return false;
1504 }

Referenced by getPreferredEntry(), and rebuildRoutingTable().

◆ isLocalAddress()

bool inet::ospfv2::Router::isLocalAddress ( Ipv4Address  address) const

Returns true if the input Ipv4 address falls into any of the Router's Areas' configured Ipv4 address ranges, false otherwise.

Parameters
address[in] The Ipv4 address to look for.
447 {
448  long areaCount = areas.size();
449  for (long i = 0; i < areaCount; i++) {
450  if (areas[i]->isLocalAddress(address)) {
451  return true;
452  }
453  }
454  return false;
455 }

Referenced by inet::ospfv2::LinkStateUpdateHandler::processPacket().

◆ isOnAnyRetransmissionList()

bool inet::ospfv2::Router::isOnAnyRetransmissionList ( LsaKeyType  lsaKey) const

Returns true if there's at least one LSA on any Neighbor's retransmission list identified by the input lsaKey, false otherwise.

Parameters
lsaKey[in] Identifies the LSAs to look for on the retransmission lists.
400 {
401  for (uint32_t i = 0; i < areas.size(); i++) {
402  if (areas[i]->isOnAnyRetransmissionList(lsaKey))
403  return true;
404  }
405  return false;
406 }

Referenced by ageDatabase().

◆ lookup()

Ospfv2RoutingTableEntry * inet::ospfv2::Router::lookup ( Ipv4Address  destination,
std::vector< Ospfv2RoutingTableEntry * > *  table = nullptr 
) const

Do a lookup in either the input OSPF routing table, or if it's nullptr then in the Router's own routing table.

See also
RFC2328 Section 11.1.
Parameters
destination[in] The destination to look up in the routing table.
table[in] The routing table to do the lookup in.
Returns
The RoutingTableEntry describing the input destination if there's one, false otherwise.
594 {
595  const std::vector<Ospfv2RoutingTableEntry *>& rTable = (table == nullptr) ? ospfRoutingTable : (*table);
596  bool unreachable = false;
597  std::vector<Ospfv2RoutingTableEntry *> discard;
598 
599  for (uint32_t i = 0; i < areas.size(); i++) {
600  for (uint32_t j = 0; j < areas[i]->getAddressRangeCount(); j++) {
601  Ipv4AddressRange range = areas[i]->getAddressRange(j);
602  for (auto entry : rTable) {
603  if (entry->getDestinationType() != Ospfv2RoutingTableEntry::NETWORK_DESTINATION)
604  continue;
605  if (range.containsRange(entry->getDestination(), entry->getNetmask()) &&
606  (entry->getPathType() == Ospfv2RoutingTableEntry::INTRAAREA))
607  {
608  // active area address range
609  Ospfv2RoutingTableEntry *discardEntry = new Ospfv2RoutingTableEntry(ift);
610  discardEntry->setDestination(range.address);
611  discardEntry->setNetmask(range.mask);
612  discardEntry->setDestinationType(Ospfv2RoutingTableEntry::NETWORK_DESTINATION);
613  discardEntry->setPathType(Ospfv2RoutingTableEntry::INTERAREA);
614  discardEntry->setArea(areas[i]->getAreaID());
615  discard.push_back(discardEntry);
616  break;
617  }
618  }
619  }
620  }
621 
622  Ospfv2RoutingTableEntry *bestMatch = nullptr;
623  unsigned long longestMatch = 0;
624  unsigned long dest = destination.getInt();
625 
626  for (auto entry : rTable) {
627  if (entry->getDestinationType() != Ospfv2RoutingTableEntry::NETWORK_DESTINATION)
628  continue;
629  unsigned long entryAddress = entry->getDestination().getInt();
630  unsigned long entryMask = entry->getNetmask().getInt();
631  if ((entryAddress & entryMask) == (dest & entryMask)) {
632  if ((dest & entryMask) > longestMatch) {
633  longestMatch = (dest & entryMask);
634  bestMatch = entry;
635  }
636  }
637  }
638 
639  if (bestMatch == nullptr)
640  unreachable = true;
641  else {
642  for (auto entry : discard) {
643  unsigned long entryAddress = entry->getDestination().getInt();
644  unsigned long entryMask = entry->getNetmask().getInt();
645  if ((entryAddress & entryMask) == (dest & entryMask)) {
646  if ((dest & entryMask) > longestMatch) {
647  unreachable = true;
648  break;
649  }
650  }
651  }
652  }
653 
654  for (uint32_t i = 0; i < discard.size(); i++)
655  delete discard[i];
656 
657  if (unreachable)
658  return nullptr;
659  else
660  return bestMatch;
661 }

Referenced by calculateASExternalRoutes(), getPreferredEntry(), and isDestinationUnreachable().

◆ notifyAboutRoutingTableChanges()

void inet::ospfv2::Router::notifyAboutRoutingTableChanges ( std::vector< Ospfv2RoutingTableEntry * > &  oldRoutingTable)
private

After a routing table rebuild the changes in the routing table are identified and new SummaryLSAs are originated or old ones are flooded out in each area as necessary.

Parameters
oldRoutingTable[in] The previous version of the routing table(which is then compared with the one in routingTable).
See also
RFC2328 Section 12.4. points(5) through(6).
1138 {
1139  // return if this router is not an ABR
1140  if (areas.size() <= 1)
1141  return;
1142  auto position = std::find_if(areas.begin(), areas.end(),
1143  [&] (const Ospfv2Area *m) -> bool { return m->getAreaID() == BACKBONE_AREAID; });
1144  if (position == areas.end())
1145  return;
1146 
1147  typedef std::map<Ipv4AddressRange, Ospfv2RoutingTableEntry *> RoutingTableEntryMap;
1148  RoutingTableEntryMap oldTableMap;
1149  RoutingTableEntryMap newTableMap;
1150 
1151  for (uint32_t i = 0; i < oldRoutingTable.size(); i++) {
1152  Ipv4AddressRange destination(oldRoutingTable[i]->getDestination() & oldRoutingTable[i]->getNetmask(), oldRoutingTable[i]->getNetmask());
1153  oldTableMap[destination] = oldRoutingTable[i];
1154  }
1155 
1156  for (uint32_t i = 0; i < ospfRoutingTable.size(); i++) {
1157  Ipv4AddressRange destination(ospfRoutingTable[i]->getDestination() & ospfRoutingTable[i]->getNetmask(), ospfRoutingTable[i]->getNetmask());
1158  newTableMap[destination] = ospfRoutingTable[i];
1159  }
1160 
1161  for (uint32_t i = 0; i < areas.size(); i++) {
1162  std::map<LsaKeyType, bool, LsaKeyType_Less> originatedLSAMap;
1163  std::map<LsaKeyType, bool, LsaKeyType_Less> deletedLSAMap;
1164  LsaKeyType lsaKey;
1165 
1166  // iterate over the new routing table and look for new or modified entries
1167  for (uint32_t j = 0; j < ospfRoutingTable.size(); j++) {
1168  Ipv4AddressRange destination(ospfRoutingTable[j]->getDestination() & ospfRoutingTable[j]->getNetmask(), ospfRoutingTable[j]->getNetmask());
1169  auto destIt = oldTableMap.find(destination);
1170  if (destIt == oldTableMap.end()) { // new routing entry
1171  SummaryLsa *lsaToReoriginate = nullptr;
1172  SummaryLsa *newLSA = areas[i]->originateSummaryLSA(ospfRoutingTable[j], originatedLSAMap, lsaToReoriginate);
1173 
1174  if (newLSA != nullptr) {
1175  if (lsaToReoriginate != nullptr) {
1176  areas[i]->installSummaryLSA(lsaToReoriginate);
1177  floodLSA(lsaToReoriginate, areas[i]->getAreaID());
1178 
1179  lsaKey.linkStateID = lsaToReoriginate->getHeader().getLinkStateID();
1180  lsaKey.advertisingRouter = routerID;
1181  originatedLSAMap[lsaKey] = true;
1182 
1183  delete lsaToReoriginate;
1184  }
1185 
1186  areas[i]->installSummaryLSA(newLSA);
1187  floodLSA(newLSA, areas[i]->getAreaID());
1188 
1189  lsaKey.linkStateID = newLSA->getHeader().getLinkStateID();
1190  lsaKey.advertisingRouter = routerID;
1191  originatedLSAMap[lsaKey] = true;
1192 
1193  delete newLSA;
1194  }
1195  }
1196  else {
1197  if (*(ospfRoutingTable[j]) != *(destIt->second)) { // modified routing entry
1198  SummaryLsa *lsaToReoriginate = nullptr;
1199  SummaryLsa *newLSA = areas[i]->originateSummaryLSA(ospfRoutingTable[j], originatedLSAMap, lsaToReoriginate);
1200 
1201  if (newLSA != nullptr) {
1202  if (lsaToReoriginate != nullptr) {
1203  areas[i]->installSummaryLSA(lsaToReoriginate);
1204  floodLSA(lsaToReoriginate, areas[i]->getAreaID());
1205 
1206  lsaKey.linkStateID = lsaToReoriginate->getHeader().getLinkStateID();
1207  lsaKey.advertisingRouter = routerID;
1208  originatedLSAMap[lsaKey] = true;
1209 
1210  delete lsaToReoriginate;
1211  }
1212 
1213  /*
1214  * A router uses initial sequence number the first time it originates any LSA.
1215  * Afterwards, the LSA's sequence number is incremented each time the router
1216  * originates a new instance of the LSA.
1217  */
1218  int32_t sequenceNumber = newLSA->getHeader().getLsSequenceNumber();
1219  if (sequenceNumber != MAX_SEQUENCE_NUMBER)
1220  newLSA->getHeaderForUpdate().setLsSequenceNumber(sequenceNumber + 1);
1221 
1222  areas[i]->installSummaryLSA(newLSA);
1223  floodLSA(newLSA, areas[i]->getAreaID());
1224 
1225  lsaKey.linkStateID = newLSA->getHeader().getLinkStateID();
1226  lsaKey.advertisingRouter = routerID;
1227  originatedLSAMap[lsaKey] = true;
1228 
1229  delete newLSA;
1230  }
1231  else {
1232  Ipv4AddressRange destinationAddressRange(ospfRoutingTable[j]->getDestination(), ospfRoutingTable[j]->getNetmask());
1233 
1234  if ((ospfRoutingTable[j]->getDestinationType() == Ospfv2RoutingTableEntry::NETWORK_DESTINATION) &&
1235  ((ospfRoutingTable[j]->getPathType() == Ospfv2RoutingTableEntry::INTRAAREA) ||
1236  (ospfRoutingTable[j]->getPathType() == Ospfv2RoutingTableEntry::INTERAREA)))
1237  {
1238  Ipv4AddressRange containingAddressRange = getContainingAddressRange(destinationAddressRange);
1239  if (containingAddressRange != NULL_IPV4ADDRESSRANGE) {
1240  destinationAddressRange = containingAddressRange;
1241  }
1242  }
1243 
1244  Metric maxRangeCost = 0;
1245  Metric oneLessCost = 0;
1246 
1247  for (uint32_t k = 0; k < ospfRoutingTable.size(); k++) {
1248  if ((ospfRoutingTable[k]->getDestinationType() == Ospfv2RoutingTableEntry::NETWORK_DESTINATION) &&
1249  (ospfRoutingTable[k]->getPathType() == Ospfv2RoutingTableEntry::INTRAAREA) &&
1250  ((ospfRoutingTable[k]->getDestination().getInt() & ospfRoutingTable[k]->getNetmask().getInt() & destinationAddressRange.mask.getInt()) ==
1251  (destinationAddressRange.address & destinationAddressRange.mask).getInt()) &&
1252  (ospfRoutingTable[k]->getCost() > maxRangeCost))
1253  {
1254  oneLessCost = maxRangeCost;
1255  maxRangeCost = ospfRoutingTable[k]->getCost();
1256  }
1257  }
1258 
1259  if (maxRangeCost == ospfRoutingTable[j]->getCost()) { // this entry gives the range's cost
1260  lsaKey.linkStateID = destinationAddressRange.address;
1261  lsaKey.advertisingRouter = routerID;
1262 
1263  SummaryLsa *summaryLSA = areas[i]->findSummaryLSA(lsaKey);
1264 
1265  if (summaryLSA != nullptr) {
1266  if (oneLessCost != 0) { // there's an other entry in this range
1267  summaryLSA->setRouteCost(oneLessCost);
1268  floodLSA(summaryLSA, areas[i]->getAreaID());
1269 
1270  originatedLSAMap[lsaKey] = true;
1271  }
1272  else { // no more entries in this range -> delete it
1273  if (!containsKey(deletedLSAMap, lsaKey)) {
1274  summaryLSA->getHeaderForUpdate().setLsAge(MAX_AGE);
1275  floodLSA(summaryLSA, areas[i]->getAreaID());
1276 
1277  deletedLSAMap[lsaKey] = true;
1278  }
1279  }
1280  }
1281  }
1282  }
1283  }
1284  }
1285  }
1286 
1287  // iterate over the old routing table and look for deleted entries
1288  for (uint32_t j = 0; j < oldRoutingTable.size(); j++) {
1289  Ipv4AddressRange destination(oldRoutingTable[j]->getDestination() & oldRoutingTable[j]->getNetmask(), oldRoutingTable[j]->getNetmask());
1290  if (!containsKey(newTableMap, destination)) { // deleted routing entry
1291  Ipv4AddressRange destinationAddressRange(oldRoutingTable[j]->getDestination(), oldRoutingTable[j]->getNetmask());
1292 
1293  if ((oldRoutingTable[j]->getDestinationType() == Ospfv2RoutingTableEntry::NETWORK_DESTINATION) &&
1294  ((oldRoutingTable[j]->getPathType() == Ospfv2RoutingTableEntry::INTRAAREA) ||
1295  (oldRoutingTable[j]->getPathType() == Ospfv2RoutingTableEntry::INTERAREA)))
1296  {
1297  Ipv4AddressRange containingAddressRange = getContainingAddressRange(destinationAddressRange);
1298  if (containingAddressRange != NULL_IPV4ADDRESSRANGE) {
1299  destinationAddressRange = containingAddressRange;
1300  }
1301  }
1302 
1303  Metric maxRangeCost = 0;
1304 
1305  unsigned long newRouteCount = ospfRoutingTable.size();
1306  for (uint32_t k = 0; k < newRouteCount; k++) {
1307  if ((ospfRoutingTable[k]->getDestinationType() == Ospfv2RoutingTableEntry::NETWORK_DESTINATION) &&
1308  (ospfRoutingTable[k]->getPathType() == Ospfv2RoutingTableEntry::INTRAAREA) &&
1309  ((ospfRoutingTable[k]->getDestination().getInt() & ospfRoutingTable[k]->getNetmask().getInt() & destinationAddressRange.mask.getInt()) ==
1310  (destinationAddressRange.address & destinationAddressRange.mask).getInt()) && // FIXME correcting network comparison
1311  (ospfRoutingTable[k]->getCost() > maxRangeCost))
1312  {
1313  maxRangeCost = ospfRoutingTable[k]->getCost();
1314  }
1315  }
1316 
1317  if (maxRangeCost < oldRoutingTable[j]->getCost()) { // the range's cost will change
1318  lsaKey.linkStateID = destinationAddressRange.address;
1319  lsaKey.advertisingRouter = routerID;
1320 
1321  SummaryLsa *summaryLSA = areas[i]->findSummaryLSA(lsaKey);
1322 
1323  if (summaryLSA != nullptr) {
1324  if (maxRangeCost > 0) { // there's an other entry in this range
1325  summaryLSA->setRouteCost(maxRangeCost);
1326  floodLSA(summaryLSA, areas[i]->getAreaID());
1327 
1328  originatedLSAMap[lsaKey] = true;
1329  }
1330  else { // no more entries in this range -> delete it
1331  auto deletedIt = deletedLSAMap.find(lsaKey);
1332  if (deletedIt == deletedLSAMap.end()) {
1333  summaryLSA->getHeaderForUpdate().setLsAge(MAX_AGE);
1334  floodLSA(summaryLSA, areas[i]->getAreaID());
1335 
1336  deletedLSAMap[lsaKey] = true;
1337  }
1338  }
1339  }
1340  }
1341  }
1342  }
1343  }
1344 }

Referenced by rebuildRoutingTable().

◆ originateASExternalLSA()

AsExternalLsa * inet::ospfv2::Router::originateASExternalLSA ( AsExternalLsa lsa)
private

Originates a new AS External LSA based on the input lsa.

Parameters
lsa[in] The LSA whose contents should be copied into the newly originated LSA.
Returns
The newly originated LSA.
469 {
470  AsExternalLsa *asExternalLSA = new AsExternalLsa(*lsa);
471  Ospfv2LsaHeader& lsaHeader = asExternalLSA->getHeaderForUpdate();
472  Ospfv2Options lsaOptions;
473 
474  lsaHeader.setLsAge(0);
475  lsaOptions.E_ExternalRoutingCapability = true;
476  lsaHeader.setLsOptions(lsaOptions);
477  lsaHeader.setLsSequenceNumber(INITIAL_SEQUENCE_NUMBER);
478  asExternalLSA->setSource(LsaTrackingInfo::ORIGINATED);
479 
480  return asExternalLSA;
481 }

Referenced by ageDatabase().

◆ printAsExternalLsa()

void inet::ospfv2::Router::printAsExternalLsa ( )
private
1461 {
1462  for (uint32_t i = 0; i < asExternalLSAs.size(); i++) {
1463  Ospfv2AsExternalLsa *entry = check_and_cast<Ospfv2AsExternalLsa *>(asExternalLSAs[i]);
1464 
1465  const Ospfv2LsaHeader& head = entry->getHeader();
1466  std::string routerId = head.getAdvertisingRouter().str(false);
1467  EV_DETAIL << "AS External LSA in OSPF router with ID " << routerId << std::endl;
1468 
1469  // print header info
1470  EV_DETAIL << " LS age: " << head.getLsAge() << std::endl;
1471  EV_DETAIL << " LS type: " << head.getLsType() << std::endl;
1472  EV_DETAIL << " Link state ID (IP network): " << head.getLinkStateID() << std::endl;
1473  EV_DETAIL << " Advertising router: " << head.getAdvertisingRouter() << std::endl;
1474  EV_DETAIL << " Seq number: " << head.getLsSequenceNumber() << std::endl;
1475  EV_DETAIL << " Length: " << head.getLsaLength() << std::endl;
1476 
1477  EV_DETAIL << " Network Mask: " << entry->getContents().getNetworkMask().str(false) << std::endl;
1478  EV_DETAIL << " Metric: " << entry->getContents().getExternalTOSInfo(0).routeCost << std::endl;
1479  EV_DETAIL << " E flag: " << ((entry->getContents().getExternalTOSInfo(0).E_ExternalMetricType == true) ? "set" : "unset") << std::endl;
1480  EV_DETAIL << " Forwarding Address: " << entry->getContents().getExternalTOSInfo(0).forwardingAddress.str(false) << std::endl;
1481  EV_DETAIL << " External Route Tag: " << entry->getContents().getExternalTOSInfo(0).externalRouteTag << std::endl;
1482  // todo: add ExternalTosInfo externalTOSInfo[];
1483  EV_DETAIL << std::endl;
1484  }
1485 }

Referenced by calculateASExternalRoutes().

◆ pruneASBoundaryRouterEntries()

void inet::ospfv2::Router::pruneASBoundaryRouterEntries ( std::vector< Ospfv2RoutingTableEntry * > &  asbrEntries) const
private

Prunes the input std::vector of RoutingTableEntries according to the RFC2328 Section 16.4.1.

Parameters
asbrEntries[in/out] The list of RoutingTableEntries to prune.
See also
RFC2328 Section 16.4.1.
841 {
842  bool hasNonBackboneIntraAreaPath = false;
843  for (auto routingEntry : asbrEntries) {
844  if ((routingEntry->getPathType() == Ospfv2RoutingTableEntry::INTRAAREA) &&
845  (routingEntry->getArea() != BACKBONE_AREAID))
846  {
847  hasNonBackboneIntraAreaPath = true;
848  break;
849  }
850  }
851 
852  if (hasNonBackboneIntraAreaPath) {
853  auto it = asbrEntries.begin();
854  while (it != asbrEntries.end()) {
855  if (((*it)->getPathType() != Ospfv2RoutingTableEntry::INTRAAREA) ||
856  ((*it)->getArea() == BACKBONE_AREAID))
857  {
858  delete *it;
859  it = asbrEntries.erase(it);
860  }
861  else {
862  it++;
863  }
864  }
865  }
866 }

Referenced by getPreferredEntry().

◆ rebuildRoutingTable()

void inet::ospfv2::Router::rebuildRoutingTable ( )

Rebuilds the routing table from scratch(based on the LSA database).

See also
RFC2328 Section 16.
664 {
665  unsigned long areaCount = areas.size();
666  bool hasTransitAreas = false;
667  std::vector<Ospfv2RoutingTableEntry *> newTable;
668 
669  EV_INFO << "--> Rebuilding routing table:\n";
670 
671  for (uint32_t i = 0; i < areaCount; i++) {
672  areas[i]->calculateShortestPathTree(newTable);
673  if (areas[i]->getTransitCapability())
674  hasTransitAreas = true;
675  }
676 
677  if (areaCount > 1) {
678  Ospfv2Area *backbone = getAreaByID(BACKBONE_AREAID);
679  // if this is an ABR and at least one adjacency in FULL state is built over the backbone
680  if (backbone && backbone->hasAnyNeighborInStates(Neighbor::FULL_STATE))
681  backbone->calculateInterAreaRoutes(newTable);
682  else {
683  for (auto& area : areas)
684  area->calculateInterAreaRoutes(newTable);
685  }
686  }
687  else if (areaCount == 1)
688  areas[0]->calculateInterAreaRoutes(newTable);
689 
690  if (hasTransitAreas) {
691  for (uint32_t i = 0; i < areaCount; i++) {
692  if (areas[i]->getTransitCapability())
693  areas[i]->recheckSummaryLSAs(newTable);
694  }
695  }
696 
697  calculateASExternalRoutes(newTable);
698 
699  // backup the routing table
700  std::vector<Ospfv2RoutingTableEntry *> oldTable;
701  oldTable.assign(ospfRoutingTable.begin(), ospfRoutingTable.end());
702  ospfRoutingTable.clear();
703  ospfRoutingTable.assign(newTable.begin(), newTable.end());
704 
705  // remove entries from the Ipv4 routing table inserted by the OSPF module
706  std::vector<Ipv4Route *> eraseEntries;
707  for (int32_t i = 0; i < rt->getNumRoutes(); i++) {
708  Ipv4Route *entry = rt->getRoute(i);
709  Ospfv2RoutingTableEntry *ospfEntry = dynamic_cast<Ospfv2RoutingTableEntry *>(entry);
710  if (ospfEntry != nullptr)
711  eraseEntries.push_back(entry);
712  }
713 
714  // add the new routing entries
715  std::vector<Ipv4Route *> addEntries;
716  for (auto& tableEntry : ospfRoutingTable) {
717  if (tableEntry->getDestinationType() == Ospfv2RoutingTableEntry::NETWORK_DESTINATION) {
718  // OSPF never adds direct routes into the IP routing table
719  if (!isDirectRoute(*tableEntry)) {
720  // ignore advertised loopback addresses with dest=gateway
721  if (tableEntry->getDestination() != tableEntry->getGateway()) {
722  Ipv4Route *entry = new Ospfv2RoutingTableEntry(*tableEntry);
723  addEntries.push_back(entry);
724  }
725  }
726  }
727  }
728 
729  // find the difference between two tables
730  std::vector<Ipv4Route *> diffAddEntries;
731  std::vector<Ipv4Route *> diffEraseEntries;
732  diffEraseEntries.assign(eraseEntries.begin(), eraseEntries.end());
733  for (auto& entry : addEntries) {
734  auto position = std::find_if(diffEraseEntries.begin(), diffEraseEntries.end(), [&] (const Ipv4Route *m) -> bool {
735  return (m->getDestination() == entry->getDestination()) &&
736  (m->getNetmask() == entry->getNetmask()) &&
737  (m->getInterface()->getInterfaceId() == entry->getInterface()->getInterfaceId()) &&
738  (m->getGateway() == entry->getGateway()) &&
739  (m->getMetric() == entry->getMetric());
740  });
741  if (position != diffEraseEntries.end())
742  diffEraseEntries.erase(position);
743  else
744  diffAddEntries.push_back(entry);
745  }
746 
747  if (!diffEraseEntries.empty() || !diffAddEntries.empty()) {
748  EV_INFO << "OSPF routing table has changed: \n";
749  for (auto& entry : diffEraseEntries)
750  EV_INFO << "deleted: " << entry << "\n";
751  for (auto& entry : diffAddEntries)
752  EV_INFO << "added: " << entry << "\n";
753  }
754  else {
755  EV_INFO << "No changes to the OSPF routing table. \n";
756  }
757 
758  for (auto& entry : eraseEntries)
759  rt->deleteRoute(entry);
760 
761  for (auto& entry : addEntries)
762  rt->addRoute(entry);
763 
764  EV_INFO << "<-- Routing table was rebuilt.\n"
765  << "Results:\n";
766 
767  for (auto& entry : ospfRoutingTable)
768  EV_INFO << entry << "\n";
769 
771 
772  for (auto& entry : oldTable)
773  delete entry;
774 }

Referenced by inet::ospfv2::Ospfv2Area::ageDatabase(), ageDatabase(), inet::ospfv2::Ospfv2InterfaceState::changeState(), inet::ospfv2::NeighborState::changeState(), inet::ospfv2::HelloHandler::processPacket(), inet::ospfv2::LinkStateUpdateHandler::processPacket(), and updateExternalRoute().

◆ removeExternalRoute()

void inet::ospfv2::Router::removeExternalRoute ( Ipv4Address  networkAddress)

Removes an AS External Route from the database.

Parameters
networkAddress[in] The network address of the external route which needs to be removed.
1441 {
1442  LsaKeyType lsaKey;
1443 
1444  lsaKey.linkStateID = networkAddress;
1445  lsaKey.advertisingRouter = routerID;
1446 
1447  auto lsaIt = asExternalLSAsByID.find(lsaKey);
1448  if (lsaIt != asExternalLSAsByID.end()) {
1449  lsaIt->second->getHeaderForUpdate().setLsAge(MAX_AGE);
1450  lsaIt->second->setPurgeable();
1451  floodLSA(lsaIt->second, BACKBONE_AREAID);
1452  }
1453 
1454  auto externalIt = externalRoutes.find(networkAddress);
1455  if (externalIt != externalRoutes.end()) {
1456  externalRoutes.erase(externalIt);
1457  }
1458 }

◆ removeFromAllRetransmissionLists()

void inet::ospfv2::Router::removeFromAllRetransmissionLists ( LsaKeyType  lsaKey)

Removes all LSAs from all Neighbor's retransmission lists which are identified by the input lsaKey.

Parameters
lsaKey[in] Identifies the LSAs to remove from the retransmission lists.
394 {
395  for (uint32_t i = 0; i < areas.size(); i++)
397 }

Referenced by inet::ospfv2::LinkStateUpdateHandler::processPacket().

◆ selectLeastCostRoutingEntry()

Ospfv2RoutingTableEntry * inet::ospfv2::Router::selectLeastCostRoutingEntry ( std::vector< Ospfv2RoutingTableEntry * > &  entries) const
private

Selects the least cost RoutingTableEntry from the input std::vector of RoutingTableEntries.

Parameters
entries[in] The RoutingTableEntries to choose the least cost one from.
Returns
The least cost entry or nullptr if entries is empty.
869 {
870  if (entries.empty())
871  return nullptr;
872 
873  Ospfv2RoutingTableEntry *leastCostEntry = entries[0];
874  Metric leastCost = leastCostEntry->getCost();
875 
876  for (uint32_t i = 1; i < entries.size(); i++) {
877  Metric currentCost = entries[i]->getCost();
878  if ((currentCost < leastCost) ||
879  ((currentCost == leastCost) && (entries[i]->getArea() > leastCostEntry->getArea())))
880  {
881  leastCostEntry = entries[i];
882  leastCost = currentCost;
883  }
884  }
885 
886  return leastCostEntry;
887 }

Referenced by getPreferredEntry().

◆ setRFC1583Compatibility()

void inet::ospfv2::Router::setRFC1583Compatibility ( bool  compatibility)
inline

◆ setRouterID()

void inet::ospfv2::Router::setRouterID ( RouterId  id)
inline
59 { routerID = id; }

◆ updateExternalRoute()

void inet::ospfv2::Router::updateExternalRoute ( Ipv4Address  networkAddress,
const Ospfv2AsExternalLsaContents externalRouteContents,
int  ifIndex = -1 
)

Stores information on an AS External Route in externalRoutes and intalls(or updates) a new AsExternalLsa into the database.

Parameters
networkAddress[in] The external route's network address.
externalRouteContents[in] Route configuration data for the external route.
ifIndex[in]
1357 {
1358  if (ifIndex != -1) {
1359  bool inRoutingTable = false;
1360  Ipv4Route *entry = nullptr;
1361  // add the external route to the routing table if it was not added by another module
1362  for (int32_t i = 0; i < rt->getNumRoutes(); i++) {
1363  entry = rt->getRoute(i);
1364  if ((entry->getDestination() == networkAddress)
1365  && (entry->getNetmask() == externalRouteContents.getNetworkMask())) // TODO is it enough?
1366  {
1367  inRoutingTable = true;
1368  break;
1369  }
1370  }
1371 
1372  if (!inRoutingTable) {
1373  Ipv4Route *entry = new Ipv4Route;
1374  entry->setDestination(networkAddress);
1375  entry->setNetmask(externalRouteContents.getNetworkMask());
1376  entry->setInterface(ift->getInterfaceById(ifIndex));
1377  entry->setSourceType(IRoute::MANUAL);
1378  entry->setMetric(externalRouteContents.getExternalTOSInfo(0).routeCost);
1379  rt->addRoute(entry); // IIpv4RoutingTable deletes entry pointer
1380  }
1381  else {
1382  ASSERT(entry);
1383  entry->setMetric(externalRouteContents.getExternalTOSInfo(0).routeCost);
1384  }
1385  }
1386 
1387  AsExternalLsa *asExternalLSA = new AsExternalLsa;
1388  Ospfv2LsaHeader& lsaHeader = asExternalLSA->getHeaderForUpdate();
1389  Ospfv2Options lsaOptions;
1390 
1391  lsaHeader.setLsAge(0);
1392  lsaOptions.E_ExternalRoutingCapability = true;
1393  lsaHeader.setLsOptions(lsaOptions);
1394  lsaHeader.setLsType(AS_EXTERNAL_LSA_TYPE);
1395  lsaHeader.setLinkStateID(networkAddress); // TODO get unique LinkStateId
1396  lsaHeader.setAdvertisingRouter(Ipv4Address(routerID));
1397  lsaHeader.setLsSequenceNumber(INITIAL_SEQUENCE_NUMBER);
1398 
1399  asExternalLSA->setContents(externalRouteContents);
1400 
1401  asExternalLSA->setSource(LsaTrackingInfo::ORIGINATED);
1402 
1403  externalRoutes[networkAddress] = externalRouteContents;
1404 
1405  lsaHeader.setLsaLength(B(calculateLsaSize(*asExternalLSA)).get());
1406 
1407  bool rebuild = installASExternalLSA(asExternalLSA);
1408  floodLSA(asExternalLSA, BACKBONE_AREAID);
1409  delete asExternalLSA;
1410 
1411  if (rebuild)
1413 }

Referenced by inet::ospfv2::Ospfv2ConfigReader::initiateDefaultRouteDistribution(), inet::ospfv2::Ospfv2::insertExternalRoute(), and inet::ospfv2::Ospfv2ConfigReader::loadExternalRoute().

Member Data Documentation

◆ ageTimer

cMessage* inet::ospfv2::Router::ageTimer
private

Database age timer - fires every second.

Referenced by ageDatabase(), Router(), and ~Router().

◆ areas

◆ areasByID

std::map<AreaId, Ospfv2Area *> inet::ospfv2::Router::areasByID
private

A map of the contained areas with the AreaId as key.

Referenced by addArea(), findLSA(), floodLSA(), getAreaByID(), and installLSA().

◆ asExternalLSAs

std::vector<AsExternalLsa *> inet::ospfv2::Router::asExternalLSAs
private

A list of the ASExternalLSAs advertised by this router.

Referenced by addWatches(), ageDatabase(), calculateASExternalRoutes(), installASExternalLSA(), printAsExternalLsa(), and ~Router().

◆ asExternalLSAsByID

std::map<LsaKeyType, AsExternalLsa *, LsaKeyType_Less> inet::ospfv2::Router::asExternalLSAsByID
private

A map of the ASExternalLSAs advertised by this router.

Referenced by ageDatabase(), findASExternalLSA(), installASExternalLSA(), and removeExternalRoute().

◆ externalRoutes

std::map<Ipv4Address, Ospfv2AsExternalLsaContents> inet::ospfv2::Router::externalRoutes
private

A map of the external route advertised by this router.

Referenced by removeExternalRoute(), and updateExternalRoute().

◆ ift

◆ messageHandler

MessageHandler* inet::ospfv2::Router::messageHandler
private

The message dispatcher class.

Referenced by ageDatabase(), Router(), and ~Router().

◆ ospfRoutingTable

std::vector<Ospfv2RoutingTableEntry *> inet::ospfv2::Router::ospfRoutingTable
private

The OSPF routing table - contains more information than the one in the IP layer.

Referenced by addWatches(), deleteRoute(), getPreferredEntry(), installASExternalLSA(), lookup(), notifyAboutRoutingTableChanges(), rebuildRoutingTable(), and ~Router().

◆ rfc1583Compatibility

bool inet::ospfv2::Router::rfc1583Compatibility
private

Decides whether to handle the preferred routing table entry to an AS boundary router as defined in RFC1583 or not.

Referenced by calculateASExternalRoutes(), and getPreferredEntry().

◆ routerID

◆ rt

IIpv4RoutingTable* inet::ospfv2::Router::rt = nullptr
private

The documentation for this class was generated from the following files:
inet::ospfv2::Router::notifyAboutRoutingTableChanges
void notifyAboutRoutingTableChanges(std::vector< Ospfv2RoutingTableEntry * > &oldRoutingTable)
After a routing table rebuild the changes in the routing table are identified and new SummaryLSAs are...
Definition: Ospfv2Router.cc:1137
inet::ospfv2::RouterId
Ipv4Address RouterId
Definition: Ospfv2Common.h:129
OSPFv2_BGP_DEFAULT_COST
#define OSPFv2_BGP_DEFAULT_COST
Definition: Ospfv2Common.h:54
inet::ospfv2::Neighbor::FULL_STATE
@ FULL_STATE
Definition: Ospfv2Neighbor.h:57
inet::ospfv2::Router::lookup
Ospfv2RoutingTableEntry * lookup(Ipv4Address destination, std::vector< Ospfv2RoutingTableEntry * > *table=nullptr) const
Do a lookup in either the input OSPF routing table, or if it's nullptr then in the Router's own routi...
Definition: Ospfv2Router.cc:593
inet::units::value::str
std::string str() const
Definition: Units.h:101
inet::ospfv2::Router::ospfRoutingTable
std::vector< Ospfv2RoutingTableEntry * > ospfRoutingTable
The OSPF routing table - contains more information than the one in the IP layer.
Definition: Ospfv2Router.h:42
inet::ospfv2::Router::rt
IIpv4RoutingTable * rt
Definition: Ospfv2Router.h:34
inet::IIpv4RoutingTable::getRouterId
virtual Ipv4Address getRouterId() const =0
Returns routerId.
inet::ospfv2::Router::removeFromAllRetransmissionLists
void removeFromAllRetransmissionLists(LsaKeyType lsaKey)
Removes all LSAs from all Neighbor's retransmission lists which are identified by the input lsaKey.
Definition: Ospfv2Router.cc:393
MAX_SEQUENCE_NUMBER
#define MAX_SEQUENCE_NUMBER
Definition: Ospfv2Common.h:34
inet::ospfv2::SUMMARYLSA_NETWORKS_TYPE
@ SUMMARYLSA_NETWORKS_TYPE
Definition: Ospfv2Packet_m.h:285
inet::ospfv2::Metric
unsigned long Metric
Definition: Ospfv2Common.h:56
inet::ospfv2::Router::externalRoutes
std::map< Ipv4Address, Ospfv2AsExternalLsaContents > externalRoutes
A map of the external route advertised by this router.
Definition: Ospfv2Router.h:40
inet::IRoute::MANUAL
@ MANUAL
manually added static route
Definition: IRoute.h:29
inet::bgp::NextHop
Ipv4Address NextHop
Definition: BgpCommon.h:50
inet::ospfv2::Ospfv2RoutingTableEntry::TYPE1_EXTERNAL
@ TYPE1_EXTERNAL
Definition: Ospfv2RoutingTableEntry.h:28
inet::ospfv2::Router::asExternalLSAs
std::vector< AsExternalLsa * > asExternalLSAs
A list of the ASExternalLSAs advertised by this router.
Definition: Ospfv2Router.h:39
inet::ospfv2::Router::ageTimer
cMessage * ageTimer
Database age timer - fires every second.
Definition: Ospfv2Router.h:41
inet::ospfv2::Router::asExternalLSAsByID
std::map< LsaKeyType, AsExternalLsa *, LsaKeyType_Less > asExternalLSAsByID
A map of the ASExternalLSAs advertised by this router.
Definition: Ospfv2Router.h:38
inet::ospfv2::Router::pruneASBoundaryRouterEntries
void pruneASBoundaryRouterEntries(std::vector< Ospfv2RoutingTableEntry * > &asbrEntries) const
Prunes the input std::vector of RoutingTableEntries according to the RFC2328 Section 16....
Definition: Ospfv2Router.cc:840
inet::ospfv2::Router::areas
std::vector< Ospfv2Area * > areas
A list of the contained areas.
Definition: Ospfv2Router.h:37
inet::ospfv2::Router::printAsExternalLsa
void printAsExternalLsa()
Definition: Ospfv2Router.cc:1460
inet::ospfv2::NULL_IPV4ADDRESSRANGE
const Ipv4AddressRange NULL_IPV4ADDRESSRANGE(Ipv4Address(0, 0, 0, 0), Ipv4Address(0, 0, 0, 0))
inet::find
std::vector< T >::iterator find(std::vector< T > &v, const Tk &a)
Definition: stlutils.h:44
inet::ospfv2::ROUTERLSA_TYPE
@ ROUTERLSA_TYPE
Definition: Ospfv2Packet_m.h:283
MAX_AGE
#define MAX_AGE
Definition: Ospfv2Common.h:27
inet::ospfv2::Ospfv2RoutingTableEntry::AREA_BORDER_ROUTER_DESTINATION
static const unsigned char AREA_BORDER_ROUTER_DESTINATION
Definition: Ospfv2RoutingTableEntry.h:36
inet::ospfv2::Router::areasByID
std::map< AreaId, Ospfv2Area * > areasByID
A map of the contained areas with the AreaId as key.
Definition: Ospfv2Router.h:36
inet::math::head
T head(const Point< T, TS ... > &p)
Returns the first coordinate of p.
Definition: Point.h:222
inet::NetworkInterface::findProtocolData
const T * findProtocolData() const
Returns the protocol data for the provided type or returns nullptr if no such protocol data is found.
Definition: NetworkInterface.h:299
inet::ospfv2::calculateLsaSize
B calculateLsaSize(const Ospfv2RouterLsa &lsa)
Definition: Lsa.cc:92
inet::IInterfaceTable::getInterfaceById
virtual NetworkInterface * getInterfaceById(int id) const =0
Returns an interface by its Id.
inet::ospfv2::Router::isLocalAddress
bool isLocalAddress(Ipv4Address address) const
Returns true if the input Ipv4 address falls into any of the Router's Areas' configured Ipv4 address ...
Definition: Ospfv2Router.cc:446
inet::ospfv2::Ospfv2RoutingTableEntry::NETWORK_DESTINATION
static const unsigned char NETWORK_DESTINATION
Definition: Ospfv2RoutingTableEntry.h:35
inet::ospfv2::Router::rebuildRoutingTable
void rebuildRoutingTable()
Rebuilds the routing table from scratch(based on the LSA database).
Definition: Ospfv2Router.cc:663
inet::ospfv2::SUMMARYLSA_ASBOUNDARYROUTERS_TYPE
@ SUMMARYLSA_ASBOUNDARYROUTERS_TYPE
Definition: Ospfv2Packet_m.h:286
INITIAL_SEQUENCE_NUMBER
#define INITIAL_SEQUENCE_NUMBER
Definition: Ospfv2Common.h:33
inet::ospfv2::Router::messageHandler
MessageHandler * messageHandler
The message dispatcher class.
Definition: Ospfv2Router.h:43
inet::ospfv2::Router::getRoutesToASBoundaryRouter
std::vector< Ospfv2RoutingTableEntry * > getRoutesToASBoundaryRouter(const std::vector< Ospfv2RoutingTableEntry * > &fromRoutingTable, RouterId routerID) const
Returns an std::vector of routes leading to the AS Boundary Router identified by asbrRouterID from th...
Definition: Ospfv2Router.cc:814
inet::ospfv2::BACKBONE_AREAID
const AreaId BACKBONE_AREAID(0, 0, 0, 0)
inet::ospfv2::Router::getAreaByID
Ospfv2Area * getAreaByID(AreaId areaID)
Returns the pointer to the Area identified by the input areaID, if it's on the Area list,...
Definition: Ospfv2Router.cc:63
inet::ospfv2::Router::hasRouteToASBoundaryRouter
bool hasRouteToASBoundaryRouter(const std::vector< Ospfv2RoutingTableEntry * > &inRoutingTable, RouterId routerID) const
Returns true if there is a route to the AS Boundary Router identified by asbrRouterID in the input in...
Definition: Ospfv2Router.cc:787
inet::units::units::B
intscale< b, 1, 8 > B
Definition: Units.h:1168
inet::ospfv2::Router::floodLSA
bool floodLSA(const Ospfv2Lsa *lsa, AreaId areaID=BACKBONE_AREAID, Ospfv2Interface *intf=nullptr, Neighbor *neighbor=nullptr)
Floods out the input lsa on a set of Interfaces.
Definition: Ospfv2Router.cc:408
inet::IIpv4RoutingTable::getRoute
virtual Ipv4Route * getRoute(int k) const override=0
Returns the kth route.
inet::ospfv2::Router::routerID
RouterId routerID
The router ID assigned by the IP layer.
Definition: Ospfv2Router.h:35
inet::IRoute::OSPF
@ OSPF
managed by the given routing protocol
Definition: IRoute.h:35
inet::ospfv2::AS_EXTERNAL_LSA_TYPE
@ AS_EXTERNAL_LSA_TYPE
Definition: Ospfv2Packet_m.h:287
inet::ospfv2::MessageHandler::startTimer
void startTimer(cMessage *timer, simtime_t delay)
Definition: MessageHandler.cc:375
inet::ospfv2::Ospfv2RoutingTableEntry::INTERAREA
@ INTERAREA
Definition: Ospfv2RoutingTableEntry.h:27
inet::ospfv2::VIRTUAL_LINK
@ VIRTUAL_LINK
Definition: Ospfv2Packet_m.h:433
inet::ospfv2::Router::rfc1583Compatibility
bool rfc1583Compatibility
Decides whether to handle the preferred routing table entry to an AS boundary router as defined in RF...
Definition: Ospfv2Router.h:44
inet::IIpv4RoutingTable::deleteRoute
virtual bool deleteRoute(Ipv4Route *entry)=0
Deletes the given route from the routing table.
inet::ospfv2::Neighbor::EXCHANGE_STATE
@ EXCHANGE_STATE
Definition: Ospfv2Neighbor.h:55
inet::ospfv2::Router::findASExternalLSA
AsExternalLsa * findASExternalLSA(LsaKeyType lsaKey)
Find the AS External LSA identified by the input lsaKey in the database.
Definition: Ospfv2Router.cc:266
inet::IRoutingTable::getNumRoutes
virtual int getNumRoutes() const =0
Returns the total number of unicast routes.
inet::ospfv2::Router::isDirectRoute
bool isDirectRoute(Ospfv2RoutingTableEntry &entry)
Definition: Ospfv2Router.cc:1487
inet::ospfv2::Ospfv2RoutingTableEntry::AS_BOUNDARY_ROUTER_DESTINATION
static const unsigned char AS_BOUNDARY_ROUTER_DESTINATION
Definition: Ospfv2RoutingTableEntry.h:37
inet::ospfv2::Router::isDestinationUnreachable
bool isDestinationUnreachable(Ospfv2Lsa *lsa) const
Returns true if the destination described by the input lsa is in the routing table,...
Definition: Ospfv2Router.cc:483
inet::ospfv2::POINTTOPOINT_LINK
@ POINTTOPOINT_LINK
Definition: Ospfv2Packet_m.h:430
CHECK_AGE
#define CHECK_AGE
Definition: Ospfv2Common.h:28
inet::ospfv2::Router::ageDatabase
void ageDatabase()
Ages the LSAs in the Router's database.
Definition: Ospfv2Router.cc:278
inet::IIpv4RoutingTable::addRoute
virtual void addRoute(Ipv4Route *entry)=0
Adds a route to the routing table.
inet::physicallayer::k
const double k
Definition: Qam1024Modulation.cc:14
inet::ospfv2::DATABASE_AGE_TIMER
@ DATABASE_AGE_TIMER
Definition: Ospfv2Packet_m.h:101
inet::ospfv2::Router::ift
IInterfaceTable * ift
Definition: Ospfv2Router.h:33
inet::ospfv2::Router::installASExternalLSA
bool installASExternalLSA(const Ospfv2AsExternalLsa *lsa)
Installs a new AS External LSA into the Router's database.
Definition: Ospfv2Router.cc:147
inet::ospfv2::Router::getPreferredEntry
Ospfv2RoutingTableEntry * getPreferredEntry(const Ospfv2Lsa &lsa, bool skipSelfOriginated, std::vector< Ospfv2RoutingTableEntry * > *fromRoutingTable=nullptr)
Selects the preferred routing table entry for the input LSA(which is either an AsExternalLsa or a Sum...
Definition: Ospfv2Router.cc:889
inet::ospfv2::LsaTrackingInfo::ORIGINATED
@ ORIGINATED
Definition: Lsa.h:54
inet::ospfv2::Router::calculateASExternalRoutes
void calculateASExternalRoutes(std::vector< Ospfv2RoutingTableEntry * > &newRoutingTable)
Calculate the AS External Routes from the ASExternalLSAs in the database.
Definition: Ospfv2Router.cc:943
LS_INFINITY
#define LS_INFINITY
Definition: Ted.cc:23
inet::IInterfaceTable::getNumInterfaces
virtual int getNumInterfaces() const =0
Returns the number of interfaces.
inet::ospfv2::Router::hasAnyNeighborInStates
bool hasAnyNeighborInStates(int states) const
Returns true if any Neighbor on any Interface in any of the Router's Areas is in any of the input sta...
Definition: Ospfv2Router.cc:384
inet::ospfv2::Router::originateASExternalLSA
AsExternalLsa * originateASExternalLSA(AsExternalLsa *lsa)
Originates a new AS External LSA based on the input lsa.
Definition: Ospfv2Router.cc:468
inet::Ipv4Route::setDestination
virtual void setDestination(Ipv4Address _dest)
Definition: Ipv4Route.h:64
inet::ospfv2::NETWORKLSA_TYPE
@ NETWORKLSA_TYPE
Definition: Ospfv2Packet_m.h:284
inet::ospfv2::Neighbor::LOADING_STATE
@ LOADING_STATE
Definition: Ospfv2Neighbor.h:56
inet::IInterfaceTable::getInterface
virtual NetworkInterface * getInterface(int pos) const =0
Returns the NetworkInterface specified by an index 0..numInterfaces-1.
inet::ospfv2::TRANSIT_LINK
@ TRANSIT_LINK
Definition: Ospfv2Packet_m.h:431
inet::ospfv2::Router::isOnAnyRetransmissionList
bool isOnAnyRetransmissionList(LsaKeyType lsaKey) const
Returns true if there's at least one LSA on any Neighbor's retransmission list identified by the inpu...
Definition: Ospfv2Router.cc:399
inet::ospfv2::Router::selectLeastCostRoutingEntry
Ospfv2RoutingTableEntry * selectLeastCostRoutingEntry(std::vector< Ospfv2RoutingTableEntry * > &entries) const
Selects the least cost RoutingTableEntry from the input std::vector of RoutingTableEntries.
Definition: Ospfv2Router.cc:868
inet::units::values::m
value< double, units::m > m
Definition: Units.h:1233
inet::ospfv2::Router::getContainingAddressRange
Ipv4AddressRange getContainingAddressRange(const Ipv4AddressRange &addressRange, bool *advertise=nullptr) const
Scans through the router's areas' preconfigured address ranges and returns the one containing the inp...
Definition: Ospfv2Router.cc:1077
inet::ospfv2::Ospfv2RoutingTableEntry::INTRAAREA
@ INTRAAREA
Definition: Ospfv2RoutingTableEntry.h:26
inet::ospfv2::Router::hasAddressRange
bool hasAddressRange(const Ipv4AddressRange &addressRange) const
Returns true if one of the Router's Areas the same Ipv4 address range configured as the input Ipv4 ad...
Definition: Ospfv2Router.cc:457
inet::ospfv2::Ospfv2RoutingTableEntry::TYPE2_EXTERNAL
@ TYPE2_EXTERNAL
Definition: Ospfv2RoutingTableEntry.h:29
LS_REFRESH_TIME
#define LS_REFRESH_TIME
Definition: Ospfv2Common.h:24
inet::ospfv2::Ospfv2RoutingTableEntry::RoutingPathType
RoutingPathType
Definition: Ospfv2RoutingTableEntry.h:25
inet::ospfv2::MessageHandler::clearTimer
void clearTimer(cMessage *timer)
Definition: MessageHandler.cc:370
inet::containsKey
bool containsKey(const std::map< K, V, _C > &m, const Tk &a)
Definition: stlutils.h:80