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

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

#include <OSPFRouter.h>

Public Member Functions

 Router (RouterID id, 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
 
MessageHandlergetMessageHandler ()
 
unsigned long getASExternalLSACount () const
 
ASExternalLSAgetASExternalLSA (unsigned long i)
 
const ASExternalLSAgetASExternalLSA (unsigned long i) const
 
bool getASBoundaryRouter () const
 
unsigned long getRoutingTableEntryCount () const
 
RoutingTableEntrygetRoutingTableEntry (unsigned long i)
 
const RoutingTableEntrygetRoutingTableEntry (unsigned long i) const
 
void addRoutingTableEntry (RoutingTableEntry *entry)
 
void addWatches ()
 Adds OMNeT++ watches for the routerID, the list of Areas and the list of AS External LSAs. More...
 
void addArea (Area *area)
 Adds a new Area to the Area list. More...
 
AreagetAreaByID (AreaID areaID)
 Returns the pointer to the Area identified by the input areaID, if it's on the Area list, nullptr otherwise. More...
 
AreagetAreaByAddr (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...
 
InterfacegetNonVirtualInterface (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 (OSPFLSA *lsa, AreaID areaID=BACKBONE_AREAID)
 Installs a new LSA into the Router database. More...
 
OSPFLSAfindLSA (LSAType 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 (OSPFLSA *lsa, AreaID areaID=BACKBONE_AREAID, Interface *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 (OSPFLSA *lsa) const
 Returns true if the destination described by the input lsa is in the routing table, false otherwise. More...
 
RoutingTableEntrylookup (IPv4Address destination, std::vector< RoutingTableEntry * > *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...
 
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...
 
void updateExternalRoute (IPv4Address networkAddress, const OSPFASExternalLSAContents &externalRouteContents, int ifIndex)
 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 OSPFASExternalLSAContents &externalRouteContents, int ifIndex)
 Add an AS External Route in IPRoutingTable. More...
 
void removeExternalRoute (IPv4Address networkAddress)
 Removes an AS External Route from the database. More...
 
RoutingTableEntrygetPreferredEntry (const OSPFLSA &lsa, bool skipSelfOriginated, std::vector< RoutingTableEntry * > *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 (OSPFASExternalLSA *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< RoutingTableEntry * > &newRoutingTable)
 Calculate the AS External Routes from the ASExternalLSAs in the database. More...
 
void notifyAboutRoutingTableChanges (std::vector< RoutingTableEntry * > &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< RoutingTableEntry * > &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< RoutingTableEntry * > getRoutesToASBoundaryRouter (const std::vector< RoutingTableEntry * > &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< RoutingTableEntry * > &asbrEntries) const
 Prunes the input std::vector of RoutingTableEntries according to the RFC2328 Section 16.4.1. More...
 
RoutingTableEntryselectLeastCostRoutingEntry (std::vector< RoutingTableEntry * > &entries) const
 Selects the least cost RoutingTableEntry from the input std::vector of RoutingTableEntries. More...
 

Private Attributes

IInterfaceTableift
 
IIPv4RoutingTablert
 
RouterID routerID
 The router ID assigned by the IP layer. More...
 
std::map< AreaID, Area * > areasByID
 A map of the contained areas with the AreaID as key. More...
 
std::vector< Area * > 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, OSPFASExternalLSAContentsexternalRoutes
 A map of the external route advertised by this router. More...
 
cMessage * ageTimer
 Database age timer - fires every second. More...
 
std::vector< RoutingTableEntry * > routingTable
 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

inet::ospf::Router::Router ( RouterID  id,
cSimpleModule *  containingModule,
IInterfaceTable ift,
IIPv4RoutingTable rt 
)

Constructor.

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

24  :
25  ift(ift),
26  rt(rt),
27  routerID(id),
29 {
30  messageHandler = new MessageHandler(this, containingModule);
31  ageTimer = new cMessage();
32  ageTimer->setKind(DATABASE_AGE_TIMER);
33  ageTimer->setContextPointer(this);
34  ageTimer->setName("Router::DatabaseAgeTimer");
36 }
bool rfc1583Compatibility
Decides whether to handle the preferred routing table entry to an AS boundary router as defined in RF...
Definition: OSPFRouter.h:56
IIPv4RoutingTable * rt
Definition: OSPFRouter.h:46
void startTimer(cMessage *timer, simtime_t delay)
Definition: MessageHandler.cc:372
cMessage * ageTimer
Database age timer - fires every second.
Definition: OSPFRouter.h:53
IInterfaceTable * ift
Definition: OSPFRouter.h:45
RouterID routerID
The router ID assigned by the IP layer.
Definition: OSPFRouter.h:47
Definition: OSPFTimer.h:36
MessageHandler * messageHandler
The message dispatcher class.
Definition: OSPFRouter.h:55
inet::ospf::Router::~Router ( )
virtual

Destructor.

Clears all LSA lists and kills the Database Age timer.

39 {
40  long areaCount = areas.size();
41  for (long i = 0; i < areaCount; i++) {
42  delete areas[i];
43  }
44  long lsaCount = asExternalLSAs.size();
45  for (long j = 0; j < lsaCount; j++) {
46  delete asExternalLSAs[j];
47  }
48  long routeCount = routingTable.size();
49  for (long k = 0; k < routeCount; k++) {
50  delete routingTable[k];
51  }
53  delete ageTimer;
54  delete messageHandler;
55 }
std::vector< ASExternalLSA * > asExternalLSAs
A list of the ASExternalLSAs advertised by this router.
Definition: OSPFRouter.h:51
std::vector< RoutingTableEntry * > routingTable
The OSPF routing table - contains more information than the one in the IP layer.
Definition: OSPFRouter.h:54
cMessage * ageTimer
Database age timer - fires every second.
Definition: OSPFRouter.h:53
MessageHandler * messageHandler
The message dispatcher class.
Definition: OSPFRouter.h:55
void clearTimer(cMessage *timer)
Definition: MessageHandler.cc:367
const double k
Definition: QAM16Modulation.cc:24
std::vector< Area * > areas
A list of the contained areas.
Definition: OSPFRouter.h:49

Member Function Documentation

void inet::ospf::Router::addArea ( Area area)

Adds a new Area to the Area list.

Parameters
area[in] The Area to add.

Referenced by inet::ospf::OSPFConfigReader::loadAreaFromXML().

66 {
67  area->setRouter(this);
68  areasByID[area->getAreaID()] = area;
69  areas.push_back(area);
70 }
std::map< AreaID, Area * > areasByID
A map of the contained areas with the AreaID as key.
Definition: OSPFRouter.h:48
std::vector< Area * > areas
A list of the contained areas.
Definition: OSPFRouter.h:49
void inet::ospf::Router::addExternalRouteInIPTable ( IPv4Address  networkAddress,
const OSPFASExternalLSAContents 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]

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

1376 {
1377  int routingEntryNumber = rt->getNumRoutes();
1378  bool inRoutingTable = false;
1379 
1380  // add the external route to the IPv4 routing table if it was not added by another module
1381  for (int i = 1; i < routingEntryNumber; i++) {
1382  const IPv4Route *entry = rt->getRoute(i);
1383  if ((entry->getDestination() == networkAddress)
1384  && (entry->getNetmask() == externalRouteContents.getNetworkMask())) //TODO is it enough?
1385  {
1386  inRoutingTable = true;
1387  break;
1388  }
1389  }
1390 
1391  if (!inRoutingTable) {
1392  IPv4Route *entry = new IPv4Route();
1393  entry->setDestination(networkAddress);
1394  entry->setNetmask(externalRouteContents.getNetworkMask());
1395  entry->setInterface(ift->getInterfaceById(ifIndex));
1396  entry->setSourceType(IRoute::OSPF);
1397  entry->setMetric(OSPF_BGP_DEFAULT_COST);
1398  rt->addRoute(entry);
1399  }
1400 }
virtual InterfaceEntry * getInterfaceById(int id) const =0
Returns an interface by its Id.
managed by the given routing protocol
Definition: IRoute.h:46
virtual IPv4Route * getRoute(int k) const override=0
Returns the kth route.
virtual int getNumRoutes() const =0
Returns the total number of unicast routes.
#define OSPF_BGP_DEFAULT_COST
Definition: OSPFcommon.h:62
IIPv4RoutingTable * rt
Definition: OSPFRouter.h:46
IInterfaceTable * ift
Definition: OSPFRouter.h:45
virtual void addRoute(IPv4Route *entry)=0
Adds a route to the routing table.
void inet::ospf::Router::addRoutingTableEntry ( RoutingTableEntry entry)
inline
87 { routingTable.push_back(entry); }
std::vector< RoutingTableEntry * > routingTable
The OSPF routing table - contains more information than the one in the IP layer.
Definition: OSPFRouter.h:54
void inet::ospf::Router::addWatches ( )

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

Referenced by inet::ospf::OSPFRouting::createOspfRouter().

58 {
59  WATCH(routerID);
60  WATCH_PTRVECTOR(areas);
61  WATCH_PTRVECTOR(asExternalLSAs);
62  WATCH_PTRVECTOR(routingTable);
63 }
std::vector< ASExternalLSA * > asExternalLSAs
A list of the ASExternalLSAs advertised by this router.
Definition: OSPFRouter.h:51
std::vector< RoutingTableEntry * > routingTable
The OSPF routing table - contains more information than the one in the IP layer.
Definition: OSPFRouter.h:54
RouterID routerID
The router ID assigned by the IP layer.
Definition: OSPFRouter.h:47
std::vector< Area * > areas
A list of the contained areas.
Definition: OSPFRouter.h:49
void inet::ospf::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.

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

293 {
294  long lsaCount = asExternalLSAs.size();
295  bool shouldRebuildRoutingTable = false;
296 
297  for (long i = 0; i < lsaCount; i++) {
298  unsigned short lsAge = asExternalLSAs[i]->getHeader().getLsAge();
299  bool selfOriginated = (asExternalLSAs[i]->getHeader().getAdvertisingRouter() == routerID);
300  bool unreachable = isDestinationUnreachable(asExternalLSAs[i]);
301  ASExternalLSA *lsa = asExternalLSAs[i];
302 
303  if ((selfOriginated && (lsAge < (LS_REFRESH_TIME - 1))) || (!selfOriginated && (lsAge < (MAX_AGE - 1)))) {
304  lsa->getHeader().setLsAge(lsAge + 1);
305  if ((lsAge + 1) % CHECK_AGE == 0) {
306  if (!lsa->validateLSChecksum()) {
307  EV_ERROR << "Invalid LS checksum. Memory error detected!\n";
308  }
309  }
310  lsa->incrementInstallTime();
311  }
312  if (selfOriginated && (lsAge == (LS_REFRESH_TIME - 1))) {
313  if (unreachable) {
314  lsa->getHeader().setLsAge(MAX_AGE);
316  lsa->incrementInstallTime();
317  }
318  else {
319  long sequenceNumber = lsa->getHeader().getLsSequenceNumber();
320  if (sequenceNumber == MAX_SEQUENCE_NUMBER) {
321  lsa->getHeader().setLsAge(MAX_AGE);
323  lsa->incrementInstallTime();
324  }
325  else {
326  ASExternalLSA *newLSA = originateASExternalLSA(lsa);
327 
328  newLSA->getHeader().setLsSequenceNumber(sequenceNumber + 1);
329  shouldRebuildRoutingTable |= lsa->update(newLSA);
330  delete newLSA;
331 
333  }
334  }
335  }
336  if (!selfOriginated && (lsAge == MAX_AGE - 1)) {
337  lsa->getHeader().setLsAge(MAX_AGE);
339  lsa->incrementInstallTime();
340  }
341  if (lsAge == MAX_AGE) {
342  LSAKeyType lsaKey;
343 
344  lsaKey.linkStateID = lsa->getHeader().getLinkStateID();
345  lsaKey.advertisingRouter = lsa->getHeader().getAdvertisingRouter();
346 
347  if (!isOnAnyRetransmissionList(lsaKey) &&
349  {
350  if (!selfOriginated || unreachable) {
351  asExternalLSAsByID.erase(lsaKey);
352  delete lsa;
353  asExternalLSAs[i] = nullptr;
354  shouldRebuildRoutingTable = true;
355  }
356  else {
357  if (lsa->getPurgeable()) {
358  asExternalLSAsByID.erase(lsaKey);
359  delete lsa;
360  asExternalLSAs[i] = nullptr;
361  shouldRebuildRoutingTable = true;
362  }
363  else {
364  ASExternalLSA *newLSA = originateASExternalLSA(lsa);
365  long sequenceNumber = lsa->getHeader().getLsSequenceNumber();
366 
367  newLSA->getHeader().setLsSequenceNumber((sequenceNumber == MAX_SEQUENCE_NUMBER) ? INITIAL_SEQUENCE_NUMBER : sequenceNumber + 1);
368  shouldRebuildRoutingTable |= lsa->update(newLSA);
369  delete newLSA;
370 
372  }
373  }
374  }
375  }
376  }
377 
378  auto it = asExternalLSAs.begin();
379  while (it != asExternalLSAs.end()) {
380  if ((*it) == nullptr) {
381  it = asExternalLSAs.erase(it);
382  }
383  else {
384  it++;
385  }
386  }
387 
388  long areaCount = areas.size();
389  for (long j = 0; j < areaCount; j++) {
390  areas[j]->ageDatabase();
391  }
393 
394  if (shouldRebuildRoutingTable) {
396  }
397 }
ASExternalLSA * originateASExternalLSA(ASExternalLSA *lsa)
Originates a new AS External LSA based on the input lsa.
Definition: OSPFRouter.cc:477
std::vector< ASExternalLSA * > asExternalLSAs
A list of the ASExternalLSAs advertised by this router.
Definition: OSPFRouter.h:51
std::map< LSAKeyType, ASExternalLSA *, LSAKeyType_Less > asExternalLSAsByID
A map of the ASExternalLSAs advertised by this router.
Definition: OSPFRouter.h:50
#define INITIAL_SEQUENCE_NUMBER
Definition: OSPFcommon.h:42
bool isDestinationUnreachable(OSPFLSA *lsa) const
Returns true if the destination described by the input lsa is in the routing table, false otherwise.
Definition: OSPFRouter.cc:493
void startTimer(cMessage *timer, simtime_t delay)
Definition: MessageHandler.cc:372
const AreaID BACKBONE_AREAID(0, 0, 0, 0)
#define CHECK_AGE
Definition: OSPFcommon.h:37
cMessage * ageTimer
Database age timer - fires every second.
Definition: OSPFRouter.h:53
bool hasAnyNeighborInStates(int states) const
Returns true if any Neighbor on any Interface in any of the Router&#39;s Areas is in any of the input sta...
Definition: OSPFRouter.cc:399
Definition: OSPFNeighbor.h:68
#define MAX_SEQUENCE_NUMBER
Definition: OSPFcommon.h:43
RouterID routerID
The router ID assigned by the IP layer.
Definition: OSPFRouter.h:47
bool floodLSA(OSPFLSA *lsa, AreaID areaID=BACKBONE_AREAID, Interface *intf=nullptr, Neighbor *neighbor=nullptr)
Floods out the input lsa on a set of Interfaces.
Definition: OSPFRouter.cc:429
#define MAX_AGE
Definition: OSPFcommon.h:36
#define LS_REFRESH_TIME
Definition: OSPFcommon.h:33
MessageHandler * messageHandler
The message dispatcher class.
Definition: OSPFRouter.h:55
std::vector< Area * > areas
A list of the contained areas.
Definition: OSPFRouter.h:49
Definition: OSPFNeighbor.h:67
bool isOnAnyRetransmissionList(LSAKeyType lsaKey) const
Returns true if there&#39;s at least one LSA on any Neighbor&#39;s retransmission list identified by the inpu...
Definition: OSPFRouter.cc:418
void rebuildRoutingTable()
Rebuilds the routing table from scratch(based on the LSA database).
Definition: OSPFRouter.cc:704
void inet::ospf::Router::calculateASExternalRoutes ( std::vector< RoutingTableEntry * > &  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.

Referenced by rebuildRoutingTable().

922 {
923  // see RFC 2328 16.4.
924  unsigned long lsaCount = asExternalLSAs.size();
925  unsigned long i;
926 
927  for (i = 0; i < lsaCount; i++) {
928  ASExternalLSA *currentLSA = asExternalLSAs[i];
929  OSPFLSAHeader& currentHeader = currentLSA->getHeader();
930  unsigned short externalCost = currentLSA->getContents().getRouteCost();
931  RouterID originatingRouter = currentHeader.getAdvertisingRouter();
932 
933  RoutingTableEntry *preferredEntry = getPreferredEntry(*currentLSA, true, &newRoutingTable);
934  if (preferredEntry == nullptr) {
935  continue;
936  }
937 
938  IPv4Address destination = currentHeader.getLinkStateID() & currentLSA->getContents().getNetworkMask();
939 
940  Metric preferredCost = preferredEntry->getCost();
941  RoutingTableEntry *destinationEntry = lookup(destination, &newRoutingTable); // (5)
942  if (destinationEntry == nullptr) {
943  bool type2ExternalMetric = currentLSA->getContents().getE_ExternalMetricType();
944  unsigned int nextHopCount = preferredEntry->getNextHopCount();
945  RoutingTableEntry *newEntry = new RoutingTableEntry(ift);
946 
947  newEntry->setDestination(destination);
948  newEntry->setNetmask(currentLSA->getContents().getNetworkMask());
949  newEntry->setArea(preferredEntry->getArea());
950  newEntry->setPathType(type2ExternalMetric ? RoutingTableEntry::TYPE2_EXTERNAL : RoutingTableEntry::TYPE1_EXTERNAL);
951  if (type2ExternalMetric) {
952  newEntry->setCost(preferredCost);
953  newEntry->setType2Cost(externalCost);
954  }
955  else {
956  newEntry->setCost(preferredCost + externalCost);
957  }
958  newEntry->setDestinationType(RoutingTableEntry::NETWORK_DESTINATION);
959  newEntry->setOptionalCapabilities(currentHeader.getLsOptions());
960  newEntry->setLinkStateOrigin(currentLSA);
961 
962  for (unsigned int j = 0; j < nextHopCount; j++) {
963  NextHop nextHop = preferredEntry->getNextHop(j);
964 
965  nextHop.advertisingRouter = originatingRouter;
966  newEntry->addNextHop(nextHop);
967  }
968 
969  newRoutingTable.push_back(newEntry);
970  }
971  else {
972  RoutingTableEntry::RoutingPathType destinationPathType = destinationEntry->getPathType();
973  bool type2ExternalMetric = currentLSA->getContents().getE_ExternalMetricType();
974  unsigned int nextHopCount = preferredEntry->getNextHopCount();
975 
976  if ((destinationPathType == RoutingTableEntry::INTRAAREA) ||
977  (destinationPathType == RoutingTableEntry::INTERAREA)) // (6) (a)
978  {
979  continue;
980  }
981 
982  if (((destinationPathType == RoutingTableEntry::TYPE1_EXTERNAL) &&
983  (type2ExternalMetric)) ||
984  ((destinationPathType == RoutingTableEntry::TYPE2_EXTERNAL) &&
985  (type2ExternalMetric) &&
986  (destinationEntry->getType2Cost() < externalCost))) // (6) (b)
987  {
988  continue;
989  }
990 
991  RoutingTableEntry *destinationPreferredEntry = getPreferredEntry(*(destinationEntry->getLinkStateOrigin()), false, &newRoutingTable);
992  if ((!rfc1583Compatibility) &&
993  (destinationPreferredEntry->getPathType() == RoutingTableEntry::INTRAAREA) &&
994  (destinationPreferredEntry->getArea() != BACKBONE_AREAID) &&
995  ((preferredEntry->getPathType() != RoutingTableEntry::INTRAAREA) ||
996  (preferredEntry->getArea() == BACKBONE_AREAID)))
997  {
998  continue;
999  }
1000 
1001  if ((((destinationPathType == RoutingTableEntry::TYPE1_EXTERNAL) &&
1002  (!type2ExternalMetric) &&
1003  (destinationEntry->getCost() < preferredCost + externalCost))) ||
1004  ((destinationPathType == RoutingTableEntry::TYPE2_EXTERNAL) &&
1005  (type2ExternalMetric) &&
1006  (destinationEntry->getType2Cost() == externalCost) &&
1007  (destinationPreferredEntry->getCost() < preferredCost)))
1008  {
1009  continue;
1010  }
1011 
1012  if (((destinationPathType == RoutingTableEntry::TYPE1_EXTERNAL) &&
1013  (!type2ExternalMetric) &&
1014  (destinationEntry->getCost() == (preferredCost + externalCost))) ||
1015  ((destinationPathType == RoutingTableEntry::TYPE2_EXTERNAL) &&
1016  (type2ExternalMetric) &&
1017  (destinationEntry->getType2Cost() == externalCost) &&
1018  (destinationPreferredEntry->getCost() == preferredCost))) // equal cost
1019  {
1020  for (unsigned int j = 0; j < nextHopCount; j++) {
1021  // TODO: merge next hops, not add
1022  NextHop nextHop = preferredEntry->getNextHop(j);
1023 
1024  nextHop.advertisingRouter = originatingRouter;
1025  destinationEntry->addNextHop(nextHop);
1026  }
1027  continue;
1028  }
1029 
1030  // LSA is better
1031  destinationEntry->setArea(preferredEntry->getArea());
1032  destinationEntry->setPathType(type2ExternalMetric ? RoutingTableEntry::TYPE2_EXTERNAL : RoutingTableEntry::TYPE1_EXTERNAL);
1033  if (type2ExternalMetric) {
1034  destinationEntry->setCost(preferredCost);
1035  destinationEntry->setType2Cost(externalCost);
1036  }
1037  else {
1038  destinationEntry->setCost(preferredCost + externalCost);
1039  }
1040  destinationEntry->setDestinationType(RoutingTableEntry::NETWORK_DESTINATION);
1041  destinationEntry->setOptionalCapabilities(currentHeader.getLsOptions());
1042  destinationEntry->clearNextHops();
1043 
1044  for (unsigned int j = 0; j < nextHopCount; j++) {
1045  NextHop nextHop = preferredEntry->getNextHop(j);
1046 
1047  nextHop.advertisingRouter = originatingRouter;
1048  destinationEntry->addNextHop(nextHop);
1049  }
1050  }
1051  }
1052 }
std::vector< ASExternalLSA * > asExternalLSAs
A list of the ASExternalLSAs advertised by this router.
Definition: OSPFRouter.h:51
unsigned long Metric
Definition: OSPFcommon.h:64
Definition: OSPFRoutingTableEntry.h:42
Definition: OSPFRoutingTableEntry.h:39
bool rfc1583Compatibility
Decides whether to handle the preferred routing table entry to an AS boundary router as defined in RF...
Definition: OSPFRouter.h:56
RoutingTableEntry * getPreferredEntry(const OSPFLSA &lsa, bool skipSelfOriginated, std::vector< RoutingTableEntry * > *fromRoutingTable=nullptr)
Selects the preferred routing table entry for the input LSA(which is either an ASExternalLSA or a Sum...
Definition: OSPFRouter.cc:868
RoutingTableEntry * lookup(IPv4Address destination, std::vector< RoutingTableEntry * > *table=nullptr) const
Do a lookup in either the input OSPF routing table, or if it&#39;s nullptr then in the Router&#39;s own routi...
Definition: OSPFRouter.cc:615
const AreaID BACKBONE_AREAID(0, 0, 0, 0)
Definition: OSPFRoutingTableEntry.h:40
static const unsigned char NETWORK_DESTINATION
Definition: OSPFRoutingTableEntry.h:48
IInterfaceTable * ift
Definition: OSPFRouter.h:45
IPv4Address NextHop
Definition: BGPCommon.h:51
RoutingPathType
Definition: OSPFRoutingTableEntry.h:38
IPv4Address RouterID
Definition: OSPFcommon.h:137
Definition: OSPFRoutingTableEntry.h:41
ASExternalLSA * inet::ospf::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.

Referenced by findLSA(), and getUniqueLinkStateID().

271 {
272  auto lsaIt = asExternalLSAsByID.find(lsaKey);
273  if (lsaIt != asExternalLSAsByID.end()) {
274  return lsaIt->second;
275  }
276  else {
277  return nullptr;
278  }
279 }
std::map< LSAKeyType, ASExternalLSA *, LSAKeyType_Less > asExternalLSAsByID
A map of the ASExternalLSAs advertised by this router.
Definition: OSPFRouter.h:50
const ASExternalLSA * inet::ospf::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.
282 {
283  std::map<LSAKeyType, ASExternalLSA *, LSAKeyType_Less>::const_iterator lsaIt = asExternalLSAsByID.find(lsaKey);
284  if (lsaIt != asExternalLSAsByID.end()) {
285  return lsaIt->second;
286  }
287  else {
288  return nullptr;
289  }
290 }
std::map< LSAKeyType, ASExternalLSA *, LSAKeyType_Less > asExternalLSAsByID
A map of the ASExternalLSAs advertised by this router.
Definition: OSPFRouter.h:50
OSPFLSA * inet::ospf::Router::findLSA ( LSAType  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.

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

231 {
232  switch (lsaType) {
233  case ROUTERLSA_TYPE: {
234  auto areaIt = areasByID.find(areaID);
235  if (areaIt != areasByID.end()) {
236  return areaIt->second->findRouterLSA(lsaKey.linkStateID);
237  }
238  }
239  break;
240 
241  case NETWORKLSA_TYPE: {
242  auto areaIt = areasByID.find(areaID);
243  if (areaIt != areasByID.end()) {
244  return areaIt->second->findNetworkLSA(lsaKey.linkStateID);
245  }
246  }
247  break;
248 
251  auto areaIt = areasByID.find(areaID);
252  if (areaIt != areasByID.end()) {
253  return areaIt->second->findSummaryLSA(lsaKey);
254  }
255  }
256  break;
257 
258  case AS_EXTERNAL_LSA_TYPE: {
259  return findASExternalLSA(lsaKey);
260  }
261  break;
262 
263  default:
264  ASSERT(false);
265  break;
266  }
267  return nullptr;
268 }
std::map< AreaID, Area * > areasByID
A map of the contained areas with the AreaID as key.
Definition: OSPFRouter.h:48
Definition: OSPFPacket_m.h:246
Definition: OSPFPacket_m.h:245
Definition: OSPFPacket_m.h:249
ASExternalLSA * findASExternalLSA(LSAKeyType lsaKey)
Find the AS External LSA identified by the input lsaKey in the database.
Definition: OSPFRouter.cc:270
Definition: OSPFPacket_m.h:247
Definition: OSPFPacket_m.h:248
bool inet::ospf::Router::floodLSA ( OSPFLSA lsa,
AreaID  areaID = BACKBONE_AREAID,
Interface 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.

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

430 {
431  bool floodedBackOut = false;
432 
433  if (lsa != nullptr) {
434  if (lsa->getHeader().getLsType() == AS_EXTERNAL_LSA_TYPE) {
435  long areaCount = areas.size();
436  for (long i = 0; i < areaCount; i++) {
437  if (areas[i]->getExternalRoutingCapability()) {
438  if (areas[i]->floodLSA(lsa, intf, neighbor)) {
439  floodedBackOut = true;
440  }
441  }
442  }
443  }
444  else {
445  auto areaIt = areasByID.find(areaID);
446  if (areaIt != areasByID.end()) {
447  floodedBackOut = areaIt->second->floodLSA(lsa, intf, neighbor);
448  }
449  }
450  }
451 
452  return floodedBackOut;
453 }
std::map< AreaID, Area * > areasByID
A map of the contained areas with the AreaID as key.
Definition: OSPFRouter.h:48
bool floodLSA(OSPFLSA *lsa, AreaID areaID=BACKBONE_AREAID, Interface *intf=nullptr, Neighbor *neighbor=nullptr)
Floods out the input lsa on a set of Interfaces.
Definition: OSPFRouter.cc:429
Definition: OSPFPacket_m.h:249
std::vector< Area * > areas
A list of the contained areas.
Definition: OSPFRouter.h:49
Area * inet::ospf::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.
84 {
85  long areaCount = areas.size();
86 
87  for (long i = 0; i < areaCount; i++) {
88  if (areas[i]->containsAddress(address))
89  return areas[i];
90  }
91 
92  return nullptr;
93 }
std::vector< Area * > areas
A list of the contained areas.
Definition: OSPFRouter.h:49
Area * inet::ospf::Router::getAreaByID ( AreaID  areaID)

Returns the pointer to the Area identified by the input areaID, if it's on the Area list, nullptr otherwise.

Parameters
areaID[in] The Area identifier.

Referenced by inet::ospf::Area::calculateShortestPathTree(), inet::ospf::OSPFConfigReader::loadHostRoute(), inet::ospf::OSPFConfigReader::loadInterfaceParameters(), inet::ospf::OSPFConfigReader::loadVirtualLink(), inet::ospf::Area::originateRouterLSA(), inet::ospf::LinkStateUpdateHandler::processPacket(), inet::ospf::MessageHandler::processPacket(), and rebuildRoutingTable().

73 {
74  auto areaIt = areasByID.find(areaID);
75  if (areaIt != areasByID.end()) {
76  return areaIt->second;
77  }
78  else {
79  return nullptr;
80  }
81 }
std::map< AreaID, Area * > areasByID
A map of the contained areas with the AreaID as key.
Definition: OSPFRouter.h:48
unsigned long inet::ospf::Router::getAreaCount ( ) const
inline

Referenced by inet::ospf::Area::originateRouterLSA(), and inet::ospf::MessageHandler::processPacket().

75 { return areas.size(); }
std::vector< Area * > areas
A list of the contained areas.
Definition: OSPFRouter.h:49
bool inet::ospf::Router::getASBoundaryRouter ( ) const
inline

Referenced by inet::ospf::Area::originateRouterLSA().

82 { return externalRoutes.size() > 0; }
std::map< IPv4Address, OSPFASExternalLSAContents > externalRoutes
A map of the external route advertised by this router.
Definition: OSPFRouter.h:52
ASExternalLSA* inet::ospf::Router::getASExternalLSA ( unsigned long  i)
inline

Referenced by inet::ospf::OSPFRouting::checkExternalRoute(), and inet::ospf::Neighbor::createDatabaseSummary().

80 { return asExternalLSAs[i]; }
std::vector< ASExternalLSA * > asExternalLSAs
A list of the ASExternalLSAs advertised by this router.
Definition: OSPFRouter.h:51
const ASExternalLSA* inet::ospf::Router::getASExternalLSA ( unsigned long  i) const
inline
81 { return asExternalLSAs[i]; }
std::vector< ASExternalLSA * > asExternalLSAs
A list of the ASExternalLSAs advertised by this router.
Definition: OSPFRouter.h:51
unsigned long inet::ospf::Router::getASExternalLSACount ( ) const
inline

Referenced by inet::ospf::OSPFRouting::checkExternalRoute(), and inet::ospf::Neighbor::createDatabaseSummary().

79 { return asExternalLSAs.size(); }
std::vector< ASExternalLSA * > asExternalLSAs
A list of the ASExternalLSAs advertised by this router.
Definition: OSPFRouter.h:51
IPv4AddressRange inet::ospf::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.

Referenced by notifyAboutRoutingTableChanges(), and inet::ospf::Area::originateSummaryLSA().

1055 {
1056  unsigned long areaCount = areas.size();
1057  for (unsigned long i = 0; i < areaCount; i++) {
1058  IPv4AddressRange containingAddressRange = areas[i]->getContainingAddressRange(addressRange, advertise);
1059  if (containingAddressRange != NULL_IPV4ADDRESSRANGE) {
1060  return containingAddressRange;
1061  }
1062  }
1063  if (advertise != nullptr) {
1064  *advertise = false;
1065  }
1066  return NULL_IPV4ADDRESSRANGE;
1067 }
std::vector< Area * > areas
A list of the contained areas.
Definition: OSPFRouter.h:49
const IPv4AddressRange NULL_IPV4ADDRESSRANGE(IPv4Address(0, 0, 0, 0), IPv4Address(0, 0, 0, 0))
MessageHandler* inet::ospf::Router::getMessageHandler ( )
inline

Referenced by inet::ospf::LinkStateUpdateHandler::acknowledgeLSA(), inet::ospf::Neighbor::clearRequestRetransmissionTimer(), inet::ospf::Neighbor::clearUpdateRetransmissionTimer(), inet::ospf::Interface::floodLSA(), inet::ospf::OSPFRouting::handleMessage(), inet::ospf::NeighborStateLoading::processEvent(), inet::ospf::InterfaceStatePointToPoint::processEvent(), inet::ospf::NeighborStateExchange::processEvent(), inet::ospf::NeighborStateDown::processEvent(), inet::ospf::NeighborStateExchangeStart::processEvent(), inet::ospf::NeighborStateFull::processEvent(), inet::ospf::NeighborStateInit::processEvent(), inet::ospf::InterfaceStateNotDesignatedRouter::processEvent(), inet::ospf::InterfaceStateWaiting::processEvent(), inet::ospf::NeighborStateTwoWay::processEvent(), inet::ospf::InterfaceStateBackup::processEvent(), inet::ospf::InterfaceStateDesignatedRouter::processEvent(), inet::ospf::NeighborStateAttempt::processEvent(), inet::ospf::InterfaceStateDown::processEvent(), inet::ospf::LinkStateRequestHandler::processPacket(), inet::ospf::HelloHandler::processPacket(), inet::ospf::LinkStateAcknowledgementHandler::processPacket(), inet::ospf::DatabaseDescriptionHandler::processPacket(), inet::ospf::LinkStateUpdateHandler::processPacket(), inet::ospf::Interface::reset(), inet::ospf::Neighbor::reset(), inet::ospf::Neighbor::retransmitDatabaseDescriptionPacket(), inet::ospf::Neighbor::retransmitUpdatePacket(), inet::ospf::Neighbor::sendDatabaseDescriptionPacket(), inet::ospf::Interface::sendDelayedAcknowledgements(), inet::ospf::Interface::sendHelloPacket(), inet::ospf::Neighbor::sendLinkStateRequestPacket(), inet::ospf::Interface::sendLSAcknowledgement(), inet::ospf::Neighbor::startRequestRetransmissionTimer(), inet::ospf::Neighbor::startUpdateRetransmissionTimer(), inet::ospf::Interface::~Interface(), and inet::ospf::Neighbor::~Neighbor().

77 { return messageHandler; }
MessageHandler * messageHandler
The message dispatcher class.
Definition: OSPFRouter.h:55
Interface * inet::ospf::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.

Referenced by inet::ospf::Area::originateSummaryLSA().

96 {
97  long areaCount = areas.size();
98 
99  for (long i = 0; i < areaCount; i++) {
100  Interface *intf = areas[i]->getInterface(ifIndex);
101  if (intf != nullptr) {
102  return intf;
103  }
104  }
105  return nullptr;
106 }
std::vector< Area * > areas
A list of the contained areas.
Definition: OSPFRouter.h:49
RoutingTableEntry * inet::ospf::Router::getPreferredEntry ( const OSPFLSA lsa,
bool  skipSelfOriginated,
std::vector< RoutingTableEntry * > *  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

Referenced by calculateASExternalRoutes(), and inet::ospf::Area::originateSummaryLSA().

869 {
870  // see RFC 2328 16.3. and 16.4.
871  if (fromRoutingTable == nullptr) {
872  fromRoutingTable = &routingTable;
873  }
874 
875  const OSPFLSAHeader& lsaHeader = lsa.getHeader();
876  const OSPFASExternalLSA *asExternalLSA = dynamic_cast<const OSPFASExternalLSA *>(&lsa);
877  unsigned long externalCost = (asExternalLSA != nullptr) ? asExternalLSA->getContents().getRouteCost() : 0;
878  unsigned short lsAge = lsaHeader.getLsAge();
879  RouterID originatingRouter = lsaHeader.getAdvertisingRouter();
880  bool selfOriginated = (originatingRouter == routerID);
881  IPv4Address forwardingAddress; // 0.0.0.0
882 
883  if (asExternalLSA != nullptr) {
884  forwardingAddress = asExternalLSA->getContents().getForwardingAddress();
885  }
886 
887  if ((externalCost == LS_INFINITY) || (lsAge == MAX_AGE) || (skipSelfOriginated && selfOriginated)) { // (1) and(2)
888  return nullptr;
889  }
890 
891  if (!hasRouteToASBoundaryRouter(*fromRoutingTable, originatingRouter)) { // (3)
892  return nullptr;
893  }
894 
895  if (forwardingAddress.isUnspecified()) { // (3)
896  std::vector<RoutingTableEntry *> asbrEntries = getRoutesToASBoundaryRouter(*fromRoutingTable, originatingRouter);
897  if (!rfc1583Compatibility) {
898  pruneASBoundaryRouterEntries(asbrEntries);
899  }
900  return selectLeastCostRoutingEntry(asbrEntries);
901  }
902  else {
903  RoutingTableEntry *forwardEntry = lookup(forwardingAddress, fromRoutingTable);
904 
905  if (forwardEntry == nullptr) {
906  return nullptr;
907  }
908 
909  if ((forwardEntry->getPathType() != RoutingTableEntry::INTRAAREA) &&
910  (forwardEntry->getPathType() != RoutingTableEntry::INTERAREA))
911  {
912  return nullptr;
913  }
914 
915  return forwardEntry;
916  }
917 
918  return nullptr;
919 }
Definition: OSPFRoutingTableEntry.h:39
bool rfc1583Compatibility
Decides whether to handle the preferred routing table entry to an AS boundary router as defined in RF...
Definition: OSPFRouter.h:56
std::vector< RoutingTableEntry * > routingTable
The OSPF routing table - contains more information than the one in the IP layer.
Definition: OSPFRouter.h:54
RoutingTableEntry * lookup(IPv4Address destination, std::vector< RoutingTableEntry * > *table=nullptr) const
Do a lookup in either the input OSPF routing table, or if it&#39;s nullptr then in the Router&#39;s own routi...
Definition: OSPFRouter.cc:615
Definition: OSPFRoutingTableEntry.h:40
RouterID routerID
The router ID assigned by the IP layer.
Definition: OSPFRouter.h:47
#define LS_INFINITY
Definition: TED.cc:32
#define MAX_AGE
Definition: OSPFcommon.h:36
RoutingTableEntry * selectLeastCostRoutingEntry(std::vector< RoutingTableEntry * > &entries) const
Selects the least cost RoutingTableEntry from the input std::vector of RoutingTableEntries.
Definition: OSPFRouter.cc:845
void pruneASBoundaryRouterEntries(std::vector< RoutingTableEntry * > &asbrEntries) const
Prunes the input std::vector of RoutingTableEntries according to the RFC2328 Section 16...
Definition: OSPFRouter.cc:818
IPv4Address RouterID
Definition: OSPFcommon.h:137
bool hasRouteToASBoundaryRouter(const std::vector< RoutingTableEntry * > &inRoutingTable, RouterID routerID) const
Returns true if there is a route to the AS Boundary Router identified by asbrRouterID in the input in...
Definition: OSPFRouter.cc:788
std::vector< RoutingTableEntry * > getRoutesToASBoundaryRouter(const std::vector< RoutingTableEntry * > &fromRoutingTable, RouterID routerID) const
Returns an std::vector of routes leading to the AS Boundary Router identified by asbrRouterID from th...
Definition: OSPFRouter.cc:802
bool inet::ospf::Router::getRFC1583Compatibility ( ) const
inline
74 { return rfc1583Compatibility; }
bool rfc1583Compatibility
Decides whether to handle the preferred routing table entry to an AS boundary router as defined in RF...
Definition: OSPFRouter.h:56
std::vector< RoutingTableEntry * > inet::ospf::Router::getRoutesToASBoundaryRouter ( const std::vector< RoutingTableEntry * > &  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.

Referenced by getPreferredEntry().

803 {
804  std::vector<RoutingTableEntry *> results;
805  long routeCount = fromRoutingTable.size();
806 
807  for (long i = 0; i < routeCount; i++) {
808  RoutingTableEntry *routingEntry = fromRoutingTable[i];
809  if (((routingEntry->getDestinationType() & RoutingTableEntry::AS_BOUNDARY_ROUTER_DESTINATION) != 0) &&
810  (routingEntry->getDestination() == asbrRouterID))
811  {
812  results.push_back(routingEntry);
813  }
814  }
815  return results;
816 }
static const unsigned char AS_BOUNDARY_ROUTER_DESTINATION
Definition: OSPFRoutingTableEntry.h:50
RoutingTableEntry* inet::ospf::Router::getRoutingTableEntry ( unsigned long  i)
inline

Referenced by inet::ospf::Area::originateSummaryLSA().

85 { return routingTable[i]; }
std::vector< RoutingTableEntry * > routingTable
The OSPF routing table - contains more information than the one in the IP layer.
Definition: OSPFRouter.h:54
const RoutingTableEntry* inet::ospf::Router::getRoutingTableEntry ( unsigned long  i) const
inline
86 { return routingTable[i]; }
std::vector< RoutingTableEntry * > routingTable
The OSPF routing table - contains more information than the one in the IP layer.
Definition: OSPFRouter.h:54
unsigned long inet::ospf::Router::getRoutingTableEntryCount ( ) const
inline

Referenced by inet::ospf::Area::originateSummaryLSA().

84 { return routingTable.size(); }
std::vector< RoutingTableEntry * > routingTable
The OSPF routing table - contains more information than the one in the IP layer.
Definition: OSPFRouter.h:54
LinkStateID inet::ospf::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
1073 {
1074  if (lsaToReoriginate != nullptr) {
1075  delete lsaToReoriginate;
1076  lsaToReoriginate = nullptr;
1077  }
1078 
1079  LSAKeyType lsaKey;
1080 
1081  lsaKey.linkStateID = destination.address;
1082  lsaKey.advertisingRouter = routerID;
1083 
1084  const ASExternalLSA *foundLSA = findASExternalLSA(lsaKey);
1085 
1086  if (foundLSA == nullptr) {
1087  return lsaKey.linkStateID;
1088  }
1089  else {
1090  IPv4Address existingMask = foundLSA->getContents().getNetworkMask();
1091 
1092  if (destination.mask >= existingMask) {
1093  return lsaKey.linkStateID.makeBroadcastAddress(destination.mask);
1094  }
1095  else {
1096  ASExternalLSA *asExternalLSA = new ASExternalLSA(*foundLSA);
1097 
1098  long sequenceNumber = asExternalLSA->getHeader().getLsSequenceNumber();
1099 
1100  asExternalLSA->getHeader().setLsAge(0);
1101  asExternalLSA->getHeader().setLsSequenceNumber((sequenceNumber == MAX_SEQUENCE_NUMBER) ? INITIAL_SEQUENCE_NUMBER : sequenceNumber + 1);
1102  asExternalLSA->getContents().setNetworkMask(destination.mask);
1103  asExternalLSA->getContents().setE_ExternalMetricType(externalMetricIsType2);
1104  asExternalLSA->getContents().setRouteCost(destinationCost);
1105 
1106  lsaToReoriginate = asExternalLSA;
1107 
1108  return lsaKey.linkStateID.makeBroadcastAddress(existingMask);
1109  }
1110  }
1111 }
#define INITIAL_SEQUENCE_NUMBER
Definition: OSPFcommon.h:42
#define MAX_SEQUENCE_NUMBER
Definition: OSPFcommon.h:43
RouterID routerID
The router ID assigned by the IP layer.
Definition: OSPFRouter.h:47
ASExternalLSA * findASExternalLSA(LSAKeyType lsaKey)
Find the AS External LSA identified by the input lsaKey in the database.
Definition: OSPFRouter.cc:270
bool inet::ospf::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.

Referenced by inet::ospf::Area::calculateInterAreaRoutes().

467 {
468  long areaCount = areas.size();
469  for (long i = 0; i < areaCount; i++) {
470  if (areas[i]->hasAddressRange(addressRange)) {
471  return true;
472  }
473  }
474  return false;
475 }
bool hasAddressRange(const IPv4AddressRange &addressRange) const
Returns true if one of the Router&#39;s Areas the same IPv4 address range configured as the input IPv4 ad...
Definition: OSPFRouter.cc:466
std::vector< Area * > areas
A list of the contained areas.
Definition: OSPFRouter.h:49
bool inet::ospf::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.

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

400 {
401  long areaCount = areas.size();
402  for (long i = 0; i < areaCount; i++) {
403  if (areas[i]->hasAnyNeighborInStates(states)) {
404  return true;
405  }
406  }
407  return false;
408 }
bool hasAnyNeighborInStates(int states) const
Returns true if any Neighbor on any Interface in any of the Router&#39;s Areas is in any of the input sta...
Definition: OSPFRouter.cc:399
std::vector< Area * > areas
A list of the contained areas.
Definition: OSPFRouter.h:49
bool inet::ospf::Router::hasRouteToASBoundaryRouter ( const std::vector< RoutingTableEntry * > &  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.

Referenced by getPreferredEntry().

789 {
790  long routeCount = inRoutingTable.size();
791  for (long i = 0; i < routeCount; i++) {
792  RoutingTableEntry *routingEntry = inRoutingTable[i];
793  if (((routingEntry->getDestinationType() & RoutingTableEntry::AS_BOUNDARY_ROUTER_DESTINATION) != 0) &&
794  (routingEntry->getDestination() == asbrRouterID))
795  {
796  return true;
797  }
798  }
799  return false;
800 }
static const unsigned char AS_BOUNDARY_ROUTER_DESTINATION
Definition: OSPFRoutingTableEntry.h:50
bool inet::ospf::Router::installASExternalLSA ( OSPFASExternalLSA 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...

Referenced by installLSA(), and updateExternalRoute().

153 {
171  // TODO: how to solve this problem?
172 
173  RouterID advertisingRouter = lsa->getHeader().getAdvertisingRouter();
174  bool reachable = false;
175  unsigned int routeCount = routingTable.size();
176 
177  for (unsigned int i = 0; i < routeCount; i++) {
178  if ((((routingTable[i]->getDestinationType() & RoutingTableEntry::AREA_BORDER_ROUTER_DESTINATION) != 0) ||
179  ((routingTable[i]->getDestinationType() & RoutingTableEntry::AS_BOUNDARY_ROUTER_DESTINATION) != 0)) &&
180  (routingTable[i]->getDestination() == advertisingRouter))
181  {
182  reachable = true;
183  break;
184  }
185  }
186 
187  bool ownLSAFloodedOut = false;
188  LSAKeyType lsaKey;
189 
190  lsaKey.linkStateID = lsa->getHeader().getLinkStateID();
191  lsaKey.advertisingRouter = routerID;
192 
193  auto lsaIt = asExternalLSAsByID.find(lsaKey);
194  if ((lsaIt != asExternalLSAsByID.end()) &&
195  reachable &&
196  (lsaIt->second->getContents().getE_ExternalMetricType() == lsa->getContents().getE_ExternalMetricType()) &&
197  (lsaIt->second->getContents().getRouteCost() == lsa->getContents().getRouteCost()) &&
198  (lsa->getContents().getForwardingAddress().getInt() != 0) && // forwarding address != 0.0.0.0
199  (lsaIt->second->getContents().getForwardingAddress() == lsa->getContents().getForwardingAddress()))
200  {
201  if (routerID > advertisingRouter) {
202  return false;
203  }
204  else {
205  lsaIt->second->getHeader().setLsAge(MAX_AGE);
206  floodLSA(lsaIt->second, BACKBONE_AREAID);
207  lsaIt->second->incrementInstallTime();
208  ownLSAFloodedOut = true;
209  }
210  }
211 
212  lsaKey.advertisingRouter = advertisingRouter;
213 
214  lsaIt = asExternalLSAsByID.find(lsaKey);
215  if (lsaIt != asExternalLSAsByID.end()) {
216  unsigned long areaCount = areas.size();
217  for (unsigned long i = 0; i < areaCount; i++) {
218  areas[i]->removeFromAllRetransmissionLists(lsaKey);
219  }
220  return (lsaIt->second->update(lsa)) | ownLSAFloodedOut;
221  }
222  else {
223  ASExternalLSA *lsaCopy = new ASExternalLSA(*lsa);
224  asExternalLSAsByID[lsaKey] = lsaCopy;
225  asExternalLSAs.push_back(lsaCopy);
226  return true;
227  }
228 }
std::vector< ASExternalLSA * > asExternalLSAs
A list of the ASExternalLSAs advertised by this router.
Definition: OSPFRouter.h:51
std::map< LSAKeyType, ASExternalLSA *, LSAKeyType_Less > asExternalLSAsByID
A map of the ASExternalLSAs advertised by this router.
Definition: OSPFRouter.h:50
std::vector< RoutingTableEntry * > routingTable
The OSPF routing table - contains more information than the one in the IP layer.
Definition: OSPFRouter.h:54
const AreaID BACKBONE_AREAID(0, 0, 0, 0)
static const unsigned char AS_BOUNDARY_ROUTER_DESTINATION
Definition: OSPFRoutingTableEntry.h:50
static const unsigned char AREA_BORDER_ROUTER_DESTINATION
Definition: OSPFRoutingTableEntry.h:49
RouterID routerID
The router ID assigned by the IP layer.
Definition: OSPFRouter.h:47
bool floodLSA(OSPFLSA *lsa, AreaID areaID=BACKBONE_AREAID, Interface *intf=nullptr, Neighbor *neighbor=nullptr)
Floods out the input lsa on a set of Interfaces.
Definition: OSPFRouter.cc:429
#define MAX_AGE
Definition: OSPFcommon.h:36
std::vector< Area * > areas
A list of the contained areas.
Definition: OSPFRouter.h:49
IPv4Address RouterID
Definition: OSPFcommon.h:137
bool inet::ospf::Router::installLSA ( OSPFLSA 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.

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

109 {
110  switch (lsa->getHeader().getLsType()) {
111  case ROUTERLSA_TYPE: {
112  auto areaIt = areasByID.find(areaID);
113  if (areaIt != areasByID.end()) {
114  OSPFRouterLSA *ospfRouterLSA = check_and_cast<OSPFRouterLSA *>(lsa);
115  return areaIt->second->installRouterLSA(ospfRouterLSA);
116  }
117  }
118  break;
119 
120  case NETWORKLSA_TYPE: {
121  auto areaIt = areasByID.find(areaID);
122  if (areaIt != areasByID.end()) {
123  OSPFNetworkLSA *ospfNetworkLSA = check_and_cast<OSPFNetworkLSA *>(lsa);
124  return areaIt->second->installNetworkLSA(ospfNetworkLSA);
125  }
126  }
127  break;
128 
131  auto areaIt = areasByID.find(areaID);
132  if (areaIt != areasByID.end()) {
133  OSPFSummaryLSA *ospfSummaryLSA = check_and_cast<OSPFSummaryLSA *>(lsa);
134  return areaIt->second->installSummaryLSA(ospfSummaryLSA);
135  }
136  }
137  break;
138 
139  case AS_EXTERNAL_LSA_TYPE: {
140  OSPFASExternalLSA *ospfASExternalLSA = check_and_cast<OSPFASExternalLSA *>(lsa);
141  return installASExternalLSA(ospfASExternalLSA);
142  }
143  break;
144 
145  default:
146  ASSERT(false);
147  break;
148  }
149  return false;
150 }
bool installASExternalLSA(OSPFASExternalLSA *lsa)
Installs a new AS External LSA into the Router&#39;s database.
Definition: OSPFRouter.cc:152
std::map< AreaID, Area * > areasByID
A map of the contained areas with the AreaID as key.
Definition: OSPFRouter.h:48
Definition: OSPFPacket_m.h:246
Definition: OSPFPacket_m.h:245
Definition: OSPFPacket_m.h:249
Definition: OSPFPacket_m.h:247
Definition: OSPFPacket_m.h:248
bool inet::ospf::Router::isDestinationUnreachable ( OSPFLSA 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.

Referenced by inet::ospf::Area::ageDatabase(), and ageDatabase().

494 {
495  IPv4Address destination = IPv4Address(lsa->getHeader().getLinkStateID());
496 
497  OSPFRouterLSA *routerLSA = dynamic_cast<OSPFRouterLSA *>(lsa);
498  OSPFNetworkLSA *networkLSA = dynamic_cast<OSPFNetworkLSA *>(lsa);
499  OSPFSummaryLSA *summaryLSA = dynamic_cast<OSPFSummaryLSA *>(lsa);
500  OSPFASExternalLSA *asExternalLSA = dynamic_cast<OSPFASExternalLSA *>(lsa);
501  // TODO: verify
502  if (routerLSA != nullptr) {
503  RoutingInfo *routingInfo = check_and_cast<RoutingInfo *>(routerLSA);
504  if (routerLSA->getHeader().getLinkStateID() == routerID) { // this is spfTreeRoot
505  return false;
506  }
507 
508  // get the interface address pointing backwards on the shortest path tree
509  unsigned int linkCount = routerLSA->getLinksArraySize();
510  RouterLSA *toRouterLSA = dynamic_cast<RouterLSA *>(routingInfo->getParent());
511  if (toRouterLSA != nullptr) {
512  bool destinationFound = false;
513  bool unnumberedPointToPointLink = false;
514  IPv4Address firstNumberedIfAddress;
515 
516  for (unsigned int i = 0; i < linkCount; i++) {
517  Link& link = routerLSA->getLinks(i);
518 
519  if (link.getType() == POINTTOPOINT_LINK) {
520  if (link.getLinkID() == IPv4Address(toRouterLSA->getHeader().getLinkStateID())) {
521  if ((link.getLinkData() & 0xFF000000) == 0) {
522  unnumberedPointToPointLink = true;
523  if (!firstNumberedIfAddress.isUnspecified()) {
524  break;
525  }
526  }
527  else {
528  destination = IPv4Address(link.getLinkData());
529  destinationFound = true;
530  break;
531  }
532  }
533  else {
534  if (((link.getLinkData() & 0xFF000000) != 0) &&
535  firstNumberedIfAddress.isUnspecified())
536  {
537  firstNumberedIfAddress = IPv4Address(link.getLinkData());
538  }
539  }
540  }
541  else if (link.getType() == TRANSIT_LINK) {
542  if (firstNumberedIfAddress.isUnspecified()) {
543  firstNumberedIfAddress = IPv4Address(link.getLinkData());
544  }
545  }
546  else if (link.getType() == VIRTUAL_LINK) {
547  if (link.getLinkID() == toRouterLSA->getHeader().getLinkStateID()) {
548  destination = IPv4Address(link.getLinkData());
549  destinationFound = true;
550  break;
551  }
552  else {
553  if (firstNumberedIfAddress.isUnspecified()) {
554  firstNumberedIfAddress = IPv4Address(link.getLinkData());
555  }
556  }
557  }
558  // There's no way to get an interface address for the router from a STUB_LINK
559  }
560  if (unnumberedPointToPointLink) {
561  if (!firstNumberedIfAddress.isUnspecified()) {
562  destination = firstNumberedIfAddress;
563  }
564  else {
565  return true;
566  }
567  }
568  if (!destinationFound) {
569  return true;
570  }
571  }
572  else {
573  NetworkLSA *toNetworkLSA = dynamic_cast<NetworkLSA *>(routingInfo->getParent());
574  if (toNetworkLSA != nullptr) {
575  // get the interface address pointing backwards on the shortest path tree
576  bool destinationFound = false;
577  for (unsigned int i = 0; i < linkCount; i++) {
578  Link& link = routerLSA->getLinks(i);
579 
580  if ((link.getType() == TRANSIT_LINK) &&
581  (link.getLinkID() == IPv4Address(toNetworkLSA->getHeader().getLinkStateID())))
582  {
583  destination = IPv4Address(link.getLinkData());
584  destinationFound = true;
585  break;
586  }
587  }
588  if (!destinationFound) {
589  return true;
590  }
591  }
592  else {
593  return true;
594  }
595  }
596  }
597  if (networkLSA != nullptr) {
598  destination = networkLSA->getHeader().getLinkStateID() & networkLSA->getNetworkMask();
599  }
600  if ((summaryLSA != nullptr) && (summaryLSA->getHeader().getLsType() == SUMMARYLSA_NETWORKS_TYPE)) {
601  destination = summaryLSA->getHeader().getLinkStateID() & summaryLSA->getNetworkMask();
602  }
603  if (asExternalLSA != nullptr) {
604  destination = asExternalLSA->getHeader().getLinkStateID() & asExternalLSA->getContents().getNetworkMask();
605  }
606 
607  if (lookup(destination) == nullptr) {
608  return true;
609  }
610  else {
611  return false;
612  }
613 }
Definition: OSPFPacket_m.h:379
RoutingTableEntry * lookup(IPv4Address destination, std::vector< RoutingTableEntry * > *table=nullptr) const
Do a lookup in either the input OSPF routing table, or if it&#39;s nullptr then in the Router&#39;s own routi...
Definition: OSPFRouter.cc:615
Definition: OSPFPacket_m.h:377
RouterID routerID
The router ID assigned by the IP layer.
Definition: OSPFRouter.h:47
Definition: OSPFPacket_m.h:376
Definition: OSPFPacket_m.h:247
bool inet::ospf::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.

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

456 {
457  long areaCount = areas.size();
458  for (long i = 0; i < areaCount; i++) {
459  if (areas[i]->isLocalAddress(address)) {
460  return true;
461  }
462  }
463  return false;
464 }
bool isLocalAddress(IPv4Address address) const
Returns true if the input IPv4 address falls into any of the Router&#39;s Areas&#39; configured IPv4 address ...
Definition: OSPFRouter.cc:455
std::vector< Area * > areas
A list of the contained areas.
Definition: OSPFRouter.h:49
bool inet::ospf::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.

Referenced by ageDatabase().

419 {
420  long areaCount = areas.size();
421  for (long i = 0; i < areaCount; i++) {
422  if (areas[i]->isOnAnyRetransmissionList(lsaKey)) {
423  return true;
424  }
425  }
426  return false;
427 }
std::vector< Area * > areas
A list of the contained areas.
Definition: OSPFRouter.h:49
bool isOnAnyRetransmissionList(LSAKeyType lsaKey) const
Returns true if there&#39;s at least one LSA on any Neighbor&#39;s retransmission list identified by the inpu...
Definition: OSPFRouter.cc:418
RoutingTableEntry * inet::ospf::Router::lookup ( IPv4Address  destination,
std::vector< RoutingTableEntry * > *  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.

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

616 {
617  const std::vector<RoutingTableEntry *>& rTable = (table == nullptr) ? routingTable : (*table);
618  unsigned long dest = destination.getInt();
619  unsigned long routingTableSize = rTable.size();
620  bool unreachable = false;
621  std::vector<RoutingTableEntry *> discard;
622  unsigned long i;
623 
624  unsigned long areaCount = areas.size();
625  for (i = 0; i < areaCount; i++) {
626  unsigned int addressRangeCount = areas[i]->getAddressRangeCount();
627  for (unsigned int j = 0; j < addressRangeCount; j++) {
628  IPv4AddressRange range = areas[i]->getAddressRange(j);
629 
630  for (unsigned int k = 0; k < routingTableSize; k++) {
631  RoutingTableEntry *entry = rTable[k];
632 
633  if (entry->getDestinationType() != RoutingTableEntry::NETWORK_DESTINATION) {
634  continue;
635  }
636 // if (((entry->getDestination().getInt() & entry->getNetmask().getInt() & range.mask.getInt()) == (range.address & range.mask).getInt()) &&
637 // (entry->getPathType() == RoutingTableEntry::INTRAAREA))
638  if (range.containsRange(entry->getDestination(), entry->getNetmask()) &&
639  (entry->getPathType() == RoutingTableEntry::INTRAAREA))
640  {
641  // active area address range
642  RoutingTableEntry *discardEntry = new RoutingTableEntry(ift);
643  discardEntry->setDestination(range.address);
644  discardEntry->setNetmask(range.mask);
645  discardEntry->setDestinationType(RoutingTableEntry::NETWORK_DESTINATION);
646  discardEntry->setPathType(RoutingTableEntry::INTERAREA);
647  discardEntry->setArea(areas[i]->getAreaID());
648  discard.push_back(discardEntry);
649  break;
650  }
651  }
652  }
653  }
654 
655  RoutingTableEntry *bestMatch = nullptr;
656  unsigned long longestMatch = 0;
657 
658  for (i = 0; i < routingTableSize; i++) {
659  if (rTable[i]->getDestinationType() == RoutingTableEntry::NETWORK_DESTINATION) {
660  RoutingTableEntry *entry = rTable[i];
661  unsigned long entryAddress = entry->getDestination().getInt();
662  unsigned long entryMask = entry->getNetmask().getInt();
663 
664  if ((entryAddress & entryMask) == (dest & entryMask)) {
665  if ((dest & entryMask) > longestMatch) {
666  longestMatch = (dest & entryMask);
667  bestMatch = entry;
668  }
669  }
670  }
671  }
672 
673  unsigned int discardCount = discard.size();
674  if (bestMatch == nullptr) {
675  unreachable = true;
676  }
677  else {
678  for (i = 0; i < discardCount; i++) {
679  RoutingTableEntry *entry = discard[i];
680  unsigned long entryAddress = entry->getDestination().getInt();
681  unsigned long entryMask = entry->getNetmask().getInt();
682 
683  if ((entryAddress & entryMask) == (dest & entryMask)) {
684  if ((dest & entryMask) > longestMatch) {
685  unreachable = true;
686  break;
687  }
688  }
689  }
690  }
691 
692  for (i = 0; i < discardCount; i++) {
693  delete discard[i];
694  }
695 
696  if (unreachable) {
697  return nullptr;
698  }
699  else {
700  return bestMatch;
701  }
702 }
Definition: OSPFRoutingTableEntry.h:39
std::vector< RoutingTableEntry * > routingTable
The OSPF routing table - contains more information than the one in the IP layer.
Definition: OSPFRouter.h:54
Definition: OSPFRoutingTableEntry.h:40
static const unsigned char NETWORK_DESTINATION
Definition: OSPFRoutingTableEntry.h:48
IInterfaceTable * ift
Definition: OSPFRouter.h:45
const double k
Definition: QAM16Modulation.cc:24
std::vector< Area * > areas
A list of the contained areas.
Definition: OSPFRouter.h:49
void inet::ospf::Router::notifyAboutRoutingTableChanges ( std::vector< RoutingTableEntry * > &  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).

Referenced by rebuildRoutingTable().

1115 {
1116  if (areas.size() <= 1) {
1117  return;
1118  }
1119 
1120  typedef std::map<IPv4AddressRange, RoutingTableEntry *> RoutingTableEntryMap;
1121  unsigned long routeCount = oldRoutingTable.size();
1122  RoutingTableEntryMap oldTableMap;
1123  RoutingTableEntryMap newTableMap;
1124  unsigned long i, j, k;
1125 
1126  for (i = 0; i < routeCount; i++) {
1127  IPv4AddressRange destination(oldRoutingTable[i]->getDestination() & oldRoutingTable[i]->getNetmask(), oldRoutingTable[i]->getNetmask());
1128  oldTableMap[destination] = oldRoutingTable[i];
1129  }
1130 
1131  routeCount = routingTable.size();
1132  for (i = 0; i < routeCount; i++) {
1133  IPv4AddressRange destination(routingTable[i]->getDestination() & routingTable[i]->getNetmask(), routingTable[i]->getNetmask());
1134  newTableMap[destination] = routingTable[i];
1135  }
1136 
1137  unsigned long areaCount = areas.size();
1138  for (i = 0; i < areaCount; i++) {
1139  std::map<LSAKeyType, bool, LSAKeyType_Less> originatedLSAMap;
1140  std::map<LSAKeyType, bool, LSAKeyType_Less> deletedLSAMap;
1141  LSAKeyType lsaKey;
1142 
1143  routeCount = routingTable.size();
1144  for (j = 0; j < routeCount; j++) {
1145  IPv4AddressRange destination(routingTable[j]->getDestination() & routingTable[j]->getNetmask(), routingTable[j]->getNetmask());
1146  auto destIt = oldTableMap.find(destination);
1147  if (destIt == oldTableMap.end()) { // new routing entry
1148  SummaryLSA *lsaToReoriginate = nullptr;
1149  SummaryLSA *newLSA = areas[i]->originateSummaryLSA(routingTable[j], originatedLSAMap, lsaToReoriginate);
1150 
1151  if (newLSA != nullptr) {
1152  if (lsaToReoriginate != nullptr) {
1153  areas[i]->installSummaryLSA(lsaToReoriginate);
1154 // floodLSA(lsaToReoriginate, BACKBONE_AREAID);
1155  floodLSA(lsaToReoriginate, areas[i]->getAreaID());
1156 
1157  lsaKey.linkStateID = lsaToReoriginate->getHeader().getLinkStateID();
1158  lsaKey.advertisingRouter = routerID;
1159  originatedLSAMap[lsaKey] = true;
1160 
1161  delete lsaToReoriginate;
1162  }
1163 
1164  areas[i]->installSummaryLSA(newLSA);
1165 // floodLSA(newLSA, BACKBONE_AREAID);
1166  floodLSA(newLSA, areas[i]->getAreaID());
1167 
1168  lsaKey.linkStateID = newLSA->getHeader().getLinkStateID();
1169  lsaKey.advertisingRouter = routerID;
1170  originatedLSAMap[lsaKey] = true;
1171 
1172  delete newLSA;
1173  }
1174  }
1175  else {
1176  if (*(routingTable[j]) != *(destIt->second)) { // modified routing entry
1177  SummaryLSA *lsaToReoriginate = nullptr;
1178  SummaryLSA *newLSA = areas[i]->originateSummaryLSA(routingTable[j], originatedLSAMap, lsaToReoriginate);
1179 
1180  if (newLSA != nullptr) {
1181  if (lsaToReoriginate != nullptr) {
1182  areas[i]->installSummaryLSA(lsaToReoriginate);
1183 // floodLSA(lsaToReoriginate, BACKBONE_AREAID);
1184  floodLSA(lsaToReoriginate, areas[i]->getAreaID());
1185 
1186  lsaKey.linkStateID = lsaToReoriginate->getHeader().getLinkStateID();
1187  lsaKey.advertisingRouter = routerID;
1188  originatedLSAMap[lsaKey] = true;
1189 
1190  delete lsaToReoriginate;
1191  }
1192 
1193  areas[i]->installSummaryLSA(newLSA);
1194 // floodLSA(newLSA, BACKBONE_AREAID);
1195  floodLSA(newLSA, areas[i]->getAreaID());
1196 
1197  lsaKey.linkStateID = newLSA->getHeader().getLinkStateID();
1198  lsaKey.advertisingRouter = routerID;
1199  originatedLSAMap[lsaKey] = true;
1200 
1201  delete newLSA;
1202  }
1203  else {
1204  IPv4AddressRange destinationAddressRange(routingTable[j]->getDestination(), routingTable[j]->getNetmask());
1205 
1206  if ((routingTable[j]->getDestinationType() == RoutingTableEntry::NETWORK_DESTINATION) &&
1207  ((routingTable[j]->getPathType() == RoutingTableEntry::INTRAAREA) ||
1208  (routingTable[j]->getPathType() == RoutingTableEntry::INTERAREA)))
1209  {
1210  IPv4AddressRange containingAddressRange = getContainingAddressRange(destinationAddressRange);
1211  if (containingAddressRange != NULL_IPV4ADDRESSRANGE) {
1212  destinationAddressRange = containingAddressRange;
1213  }
1214  }
1215 
1216  Metric maxRangeCost = 0;
1217  Metric oneLessCost = 0;
1218 
1219  for (k = 0; k < routeCount; k++) {
1220  if ((routingTable[k]->getDestinationType() == RoutingTableEntry::NETWORK_DESTINATION) &&
1221  (routingTable[k]->getPathType() == RoutingTableEntry::INTRAAREA) &&
1222  ((routingTable[k]->getDestination().getInt() & routingTable[k]->getNetmask().getInt() & destinationAddressRange.mask.getInt()) ==
1223  (destinationAddressRange.address & destinationAddressRange.mask).getInt()) &&
1224  (routingTable[k]->getCost() > maxRangeCost))
1225  {
1226  oneLessCost = maxRangeCost;
1227  maxRangeCost = routingTable[k]->getCost();
1228  }
1229  }
1230 
1231  if (maxRangeCost == routingTable[j]->getCost()) { // this entry gives the range's cost
1232  lsaKey.linkStateID = destinationAddressRange.address;
1233  lsaKey.advertisingRouter = routerID;
1234 
1235  SummaryLSA *summaryLSA = areas[i]->findSummaryLSA(lsaKey);
1236 
1237  if (summaryLSA != nullptr) {
1238  if (oneLessCost != 0) { // there's an other entry in this range
1239  summaryLSA->setRouteCost(oneLessCost);
1240 // floodLSA(summaryLSA, BACKBONE_AREAID);
1241  floodLSA(summaryLSA, areas[i]->getAreaID());
1242 
1243  originatedLSAMap[lsaKey] = true;
1244  }
1245  else { // no more entries in this range -> delete it
1246  std::map<LSAKeyType, bool, LSAKeyType_Less>::const_iterator deletedIt = deletedLSAMap.find(lsaKey);
1247  if (deletedIt == deletedLSAMap.end()) {
1248  summaryLSA->getHeader().setLsAge(MAX_AGE);
1249 // floodLSA(summaryLSA, BACKBONE_AREAID);
1250  floodLSA(summaryLSA, areas[i]->getAreaID());
1251 
1252  deletedLSAMap[lsaKey] = true;
1253  }
1254  }
1255  }
1256  }
1257  }
1258  }
1259  }
1260  }
1261 
1262  routeCount = oldRoutingTable.size();
1263  for (j = 0; j < routeCount; j++) {
1264  IPv4AddressRange destination(oldRoutingTable[j]->getDestination() & oldRoutingTable[j]->getNetmask(), oldRoutingTable[j]->getNetmask());
1265  auto destIt = newTableMap.find(destination);
1266  if (destIt == newTableMap.end()) { // deleted routing entry
1267  IPv4AddressRange destinationAddressRange(oldRoutingTable[j]->getDestination(), oldRoutingTable[j]->getNetmask());
1268 
1269  if ((oldRoutingTable[j]->getDestinationType() == RoutingTableEntry::NETWORK_DESTINATION) &&
1270  ((oldRoutingTable[j]->getPathType() == RoutingTableEntry::INTRAAREA) ||
1271  (oldRoutingTable[j]->getPathType() == RoutingTableEntry::INTERAREA)))
1272  {
1273  IPv4AddressRange containingAddressRange = getContainingAddressRange(destinationAddressRange);
1274  if (containingAddressRange != NULL_IPV4ADDRESSRANGE) {
1275  destinationAddressRange = containingAddressRange;
1276  }
1277  }
1278 
1279  Metric maxRangeCost = 0;
1280 
1281  unsigned long newRouteCount = routingTable.size();
1282  for (k = 0; k < newRouteCount; k++) {
1283  if ((routingTable[k]->getDestinationType() == RoutingTableEntry::NETWORK_DESTINATION) &&
1284  (routingTable[k]->getPathType() == RoutingTableEntry::INTRAAREA) &&
1285  ((routingTable[k]->getDestination().getInt() & routingTable[k]->getNetmask().getInt() & destinationAddressRange.mask.getInt()) ==
1286  (destinationAddressRange.address & destinationAddressRange.mask).getInt()) && //FIXME correcting network comparison
1287  (routingTable[k]->getCost() > maxRangeCost))
1288  {
1289  maxRangeCost = routingTable[k]->getCost();
1290  }
1291  }
1292 
1293  if (maxRangeCost < oldRoutingTable[j]->getCost()) { // the range's cost will change
1294  lsaKey.linkStateID = destinationAddressRange.address;
1295  lsaKey.advertisingRouter = routerID;
1296 
1297  SummaryLSA *summaryLSA = areas[i]->findSummaryLSA(lsaKey);
1298 
1299  if (summaryLSA != nullptr) {
1300  if (maxRangeCost > 0) { // there's an other entry in this range
1301  summaryLSA->setRouteCost(maxRangeCost);
1302  floodLSA(summaryLSA, BACKBONE_AREAID);
1303 
1304  originatedLSAMap[lsaKey] = true;
1305  }
1306  else { // no more entries in this range -> delete it
1307  std::map<LSAKeyType, bool, LSAKeyType_Less>::const_iterator deletedIt = deletedLSAMap.find(lsaKey);
1308  if (deletedIt == deletedLSAMap.end()) {
1309  summaryLSA->getHeader().setLsAge(MAX_AGE);
1310  floodLSA(summaryLSA, BACKBONE_AREAID);
1311 
1312  deletedLSAMap[lsaKey] = true;
1313  }
1314  }
1315  }
1316  }
1317  }
1318  }
1319  }
1320 }
unsigned long Metric
Definition: OSPFcommon.h:64
Definition: OSPFRoutingTableEntry.h:39
std::vector< RoutingTableEntry * > routingTable
The OSPF routing table - contains more information than the one in the IP layer.
Definition: OSPFRouter.h:54
IPv4AddressRange getContainingAddressRange(const IPv4AddressRange &addressRange, bool *advertise=nullptr) const
Scans through the router&#39;s areas&#39; preconfigured address ranges and returns the one containing the inp...
Definition: OSPFRouter.cc:1054
const AreaID BACKBONE_AREAID(0, 0, 0, 0)
Definition: OSPFRoutingTableEntry.h:40
static const unsigned char NETWORK_DESTINATION
Definition: OSPFRoutingTableEntry.h:48
RouterID routerID
The router ID assigned by the IP layer.
Definition: OSPFRouter.h:47
bool floodLSA(OSPFLSA *lsa, AreaID areaID=BACKBONE_AREAID, Interface *intf=nullptr, Neighbor *neighbor=nullptr)
Floods out the input lsa on a set of Interfaces.
Definition: OSPFRouter.cc:429
#define MAX_AGE
Definition: OSPFcommon.h:36
const double k
Definition: QAM16Modulation.cc:24
std::vector< Area * > areas
A list of the contained areas.
Definition: OSPFRouter.h:49
const IPv4AddressRange NULL_IPV4ADDRESSRANGE(IPv4Address(0, 0, 0, 0), IPv4Address(0, 0, 0, 0))
ASExternalLSA * inet::ospf::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.

Referenced by ageDatabase().

478 {
479  ASExternalLSA *asExternalLSA = new ASExternalLSA(*lsa);
480  OSPFLSAHeader& lsaHeader = asExternalLSA->getHeader();
481  OSPFOptions lsaOptions;
482 
483  lsaHeader.setLsAge(0);
484  memset(&lsaOptions, 0, sizeof(OSPFOptions));
485  lsaOptions.E_ExternalRoutingCapability = true;
486  lsaHeader.setLsOptions(lsaOptions);
487  lsaHeader.setLsSequenceNumber(INITIAL_SEQUENCE_NUMBER);
488  asExternalLSA->setSource(LSATrackingInfo::ORIGINATED);
489 
490  return asExternalLSA;
491 }
#define INITIAL_SEQUENCE_NUMBER
Definition: OSPFcommon.h:42
void inet::ospf::Router::pruneASBoundaryRouterEntries ( std::vector< RoutingTableEntry * > &  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.

Referenced by getPreferredEntry().

819 {
820  bool hasNonBackboneIntraAreaPath = false;
821  for (auto routingEntry : asbrEntries) {
822  if ((routingEntry->getPathType() == RoutingTableEntry::INTRAAREA) &&
823  (routingEntry->getArea() != BACKBONE_AREAID))
824  {
825  hasNonBackboneIntraAreaPath = true;
826  break;
827  }
828  }
829 
830  if (hasNonBackboneIntraAreaPath) {
831  auto it = asbrEntries.begin();
832  while (it != asbrEntries.end()) {
833  if (((*it)->getPathType() != RoutingTableEntry::INTRAAREA) ||
834  ((*it)->getArea() == BACKBONE_AREAID))
835  {
836  it = asbrEntries.erase(it);
837  }
838  else {
839  it++;
840  }
841  }
842  }
843 }
Definition: OSPFRoutingTableEntry.h:39
const AreaID BACKBONE_AREAID(0, 0, 0, 0)
void inet::ospf::Router::rebuildRoutingTable ( )

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

See also
RFC2328 Section 16.

Referenced by inet::ospf::Area::ageDatabase(), ageDatabase(), inet::ospf::InterfaceState::changeState(), inet::ospf::NeighborState::changeState(), inet::ospf::HelloHandler::processPacket(), inet::ospf::LinkStateUpdateHandler::processPacket(), and updateExternalRoute().

705 {
706  unsigned long areaCount = areas.size();
707  bool hasTransitAreas = false;
708  std::vector<RoutingTableEntry *> newTable;
709  unsigned long i;
710 
711  EV_INFO << "Rebuilding routing table:\n";
712 
713  for (i = 0; i < areaCount; i++) {
714  areas[i]->calculateShortestPathTree(newTable);
715  if (areas[i]->getTransitCapability()) {
716  hasTransitAreas = true;
717  }
718  }
719  if (areaCount > 1) {
720  Area *backbone = getAreaByID(BACKBONE_AREAID);
721  if (backbone != nullptr) {
722  backbone->calculateInterAreaRoutes(newTable);
723  }
724  }
725  else {
726  if (areaCount == 1) {
727  areas[0]->calculateInterAreaRoutes(newTable);
728  }
729  }
730  if (hasTransitAreas) {
731  for (i = 0; i < areaCount; i++) {
732  if (areas[i]->getTransitCapability()) {
733  areas[i]->recheckSummaryLSAs(newTable);
734  }
735  }
736  }
737  calculateASExternalRoutes(newTable);
738 
739  // backup the routing table
740  unsigned long routeCount = routingTable.size();
741  std::vector<RoutingTableEntry *> oldTable;
742 
743  oldTable.assign(routingTable.begin(), routingTable.end());
744  routingTable.clear();
745  routingTable.assign(newTable.begin(), newTable.end());
746 
747  std::vector<IPv4Route *> eraseEntries;
748  unsigned long routingEntryNumber = rt->getNumRoutes();
749  // remove entries from the IPv4 routing table inserted by the OSPF module
750  for (i = 0; i < routingEntryNumber; i++) {
751  IPv4Route *entry = rt->getRoute(i);
752  RoutingTableEntry *ospfEntry = dynamic_cast<RoutingTableEntry *>(entry);
753  if (ospfEntry != nullptr) {
754  eraseEntries.push_back(entry);
755  }
756  }
757 
758  unsigned int eraseCount = eraseEntries.size();
759  for (i = 0; i < eraseCount; i++) {
760  rt->deleteRoute(eraseEntries[i]);
761  }
762 
763  // add the new routing entries
764  routeCount = routingTable.size();
765  for (i = 0; i < routeCount; i++) {
766  if (routingTable[i]->getDestinationType() == RoutingTableEntry::NETWORK_DESTINATION) {
767  rt->addRoute(new RoutingTableEntry(*(routingTable[i])));
768  }
769  }
770 
772 
773  routeCount = oldTable.size();
774  for (i = 0; i < routeCount; i++) {
775  delete (oldTable[i]);
776  }
777 
778  EV_INFO << "Routing table was rebuilt.\n"
779  << "Results:\n";
780 
781  routeCount = routingTable.size();
782  for (i = 0; i < routeCount; i++) {
783  EV_INFO << *routingTable[i]
784  << "\n";
785  }
786 }
virtual IPv4Route * getRoute(int k) const override=0
Returns the kth route.
virtual int getNumRoutes() const =0
Returns the total number of unicast routes.
IIPv4RoutingTable * rt
Definition: OSPFRouter.h:46
std::vector< RoutingTableEntry * > routingTable
The OSPF routing table - contains more information than the one in the IP layer.
Definition: OSPFRouter.h:54
virtual bool deleteRoute(IPv4Route *entry)=0
Deletes the given route from the routing table.
const AreaID BACKBONE_AREAID(0, 0, 0, 0)
static const unsigned char NETWORK_DESTINATION
Definition: OSPFRoutingTableEntry.h:48
void calculateASExternalRoutes(std::vector< RoutingTableEntry * > &newRoutingTable)
Calculate the AS External Routes from the ASExternalLSAs in the database.
Definition: OSPFRouter.cc:921
virtual void addRoute(IPv4Route *entry)=0
Adds a route to the routing table.
void notifyAboutRoutingTableChanges(std::vector< RoutingTableEntry * > &oldRoutingTable)
After a routing table rebuild the changes in the routing table are identified and new SummaryLSAs are...
Definition: OSPFRouter.cc:1114
Area * getAreaByID(AreaID areaID)
Returns the pointer to the Area identified by the input areaID, if it&#39;s on the Area list...
Definition: OSPFRouter.cc:72
std::vector< Area * > areas
A list of the contained areas.
Definition: OSPFRouter.h:49
void inet::ospf::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.
1403 {
1404  LSAKeyType lsaKey;
1405 
1406  lsaKey.linkStateID = networkAddress;
1407  lsaKey.advertisingRouter = routerID;
1408 
1409  auto lsaIt = asExternalLSAsByID.find(lsaKey);
1410  if (lsaIt != asExternalLSAsByID.end()) {
1411  lsaIt->second->getHeader().setLsAge(MAX_AGE);
1412  lsaIt->second->setPurgeable();
1413  floodLSA(lsaIt->second, BACKBONE_AREAID);
1414  }
1415 
1416  auto externalIt = externalRoutes.find(networkAddress);
1417  if (externalIt != externalRoutes.end()) {
1418  externalRoutes.erase(externalIt);
1419  }
1420 }
std::map< LSAKeyType, ASExternalLSA *, LSAKeyType_Less > asExternalLSAsByID
A map of the ASExternalLSAs advertised by this router.
Definition: OSPFRouter.h:50
const AreaID BACKBONE_AREAID(0, 0, 0, 0)
std::map< IPv4Address, OSPFASExternalLSAContents > externalRoutes
A map of the external route advertised by this router.
Definition: OSPFRouter.h:52
RouterID routerID
The router ID assigned by the IP layer.
Definition: OSPFRouter.h:47
bool floodLSA(OSPFLSA *lsa, AreaID areaID=BACKBONE_AREAID, Interface *intf=nullptr, Neighbor *neighbor=nullptr)
Floods out the input lsa on a set of Interfaces.
Definition: OSPFRouter.cc:429
#define MAX_AGE
Definition: OSPFcommon.h:36
void inet::ospf::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.

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

411 {
412  long areaCount = areas.size();
413  for (long i = 0; i < areaCount; i++) {
414  areas[i]->removeFromAllRetransmissionLists(lsaKey);
415  }
416 }
std::vector< Area * > areas
A list of the contained areas.
Definition: OSPFRouter.h:49
RoutingTableEntry * inet::ospf::Router::selectLeastCostRoutingEntry ( std::vector< RoutingTableEntry * > &  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.

Referenced by getPreferredEntry().

846 {
847  if (entries.empty()) {
848  return nullptr;
849  }
850 
851  RoutingTableEntry *leastCostEntry = entries[0];
852  Metric leastCost = leastCostEntry->getCost();
853  long routeCount = entries.size();
854 
855  for (long i = 1; i < routeCount; i++) {
856  Metric currentCost = entries[i]->getCost();
857  if ((currentCost < leastCost) ||
858  ((currentCost == leastCost) && (entries[i]->getArea() > leastCostEntry->getArea())))
859  {
860  leastCostEntry = entries[i];
861  leastCost = currentCost;
862  }
863  }
864 
865  return leastCostEntry;
866 }
unsigned long Metric
Definition: OSPFcommon.h:64
void inet::ospf::Router::setRFC1583Compatibility ( bool  compatibility)
inline

Referenced by inet::ospf::OSPFConfigReader::loadConfigFromXML().

73 { rfc1583Compatibility = compatibility; }
bool rfc1583Compatibility
Decides whether to handle the preferred routing table entry to an AS boundary router as defined in RF...
Definition: OSPFRouter.h:56
void inet::ospf::Router::setRouterID ( RouterID  id)
inline
71 { routerID = id; }
RouterID routerID
The router ID assigned by the IP layer.
Definition: OSPFRouter.h:47
uint16_t id
Definition: TCP_NSC.cc:85
void inet::ospf::Router::updateExternalRoute ( IPv4Address  networkAddress,
const OSPFASExternalLSAContents externalRouteContents,
int  ifIndex 
)

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]

Referenced by inet::ospf::OSPFRouting::insertExternalRoute(), and inet::ospf::OSPFConfigReader::loadExternalRoute().

1323 {
1324  ASExternalLSA *asExternalLSA = new ASExternalLSA;
1325  OSPFLSAHeader& lsaHeader = asExternalLSA->getHeader();
1326  OSPFOptions lsaOptions;
1327  //LSAKeyType lsaKey;
1328 
1329  unsigned long routingEntryNumber = rt->getNumRoutes();
1330  bool inRoutingTable = false;
1331  // add the external route to the routing table if it was not added by another module
1332  for (unsigned long i = 0; i < routingEntryNumber; i++) {
1333  const IPv4Route *entry = rt->getRoute(i);
1334  if ((entry->getDestination() == networkAddress)
1335  && (entry->getNetmask() == externalRouteContents.getNetworkMask())) //TODO is it enough?
1336  {
1337  inRoutingTable = true;
1338  }
1339  }
1340 
1341  if (!inRoutingTable) {
1342  IPv4Route *entry = new IPv4Route;
1343  entry->setDestination(networkAddress);
1344  entry->setNetmask(externalRouteContents.getNetworkMask());
1345  entry->setInterface(ift->getInterfaceById(ifIndex));
1346  entry->setSourceType(IRoute::MANUAL);
1347  entry->setMetric(externalRouteContents.getRouteCost());
1348  rt->addRoute(entry); // IIPv4RoutingTable deletes entry pointer
1349  }
1350 
1351  lsaHeader.setLsAge(0);
1352  memset(&lsaOptions, 0, sizeof(OSPFOptions));
1353  lsaOptions.E_ExternalRoutingCapability = true;
1354  lsaHeader.setLsOptions(lsaOptions);
1355  lsaHeader.setLsType(AS_EXTERNAL_LSA_TYPE);
1356  lsaHeader.setLinkStateID(networkAddress); // TODO: get unique LinkStateID
1357  lsaHeader.setAdvertisingRouter(IPv4Address(routerID));
1358  lsaHeader.setLsSequenceNumber(INITIAL_SEQUENCE_NUMBER);
1359 
1360  asExternalLSA->setContents(externalRouteContents);
1361 
1362  asExternalLSA->setSource(LSATrackingInfo::ORIGINATED);
1363 
1364  externalRoutes[networkAddress] = externalRouteContents;
1365 
1366  bool rebuild = installASExternalLSA(asExternalLSA);
1367  floodLSA(asExternalLSA, BACKBONE_AREAID);
1368  delete asExternalLSA;
1369 
1370  if (rebuild) {
1372  }
1373 }
virtual InterfaceEntry * getInterfaceById(int id) const =0
Returns an interface by its Id.
virtual IPv4Route * getRoute(int k) const override=0
Returns the kth route.
#define INITIAL_SEQUENCE_NUMBER
Definition: OSPFcommon.h:42
virtual int getNumRoutes() const =0
Returns the total number of unicast routes.
IIPv4RoutingTable * rt
Definition: OSPFRouter.h:46
bool installASExternalLSA(OSPFASExternalLSA *lsa)
Installs a new AS External LSA into the Router&#39;s database.
Definition: OSPFRouter.cc:152
const AreaID BACKBONE_AREAID(0, 0, 0, 0)
std::map< IPv4Address, OSPFASExternalLSAContents > externalRoutes
A map of the external route advertised by this router.
Definition: OSPFRouter.h:52
IInterfaceTable * ift
Definition: OSPFRouter.h:45
RouterID routerID
The router ID assigned by the IP layer.
Definition: OSPFRouter.h:47
bool floodLSA(OSPFLSA *lsa, AreaID areaID=BACKBONE_AREAID, Interface *intf=nullptr, Neighbor *neighbor=nullptr)
Floods out the input lsa on a set of Interfaces.
Definition: OSPFRouter.cc:429
virtual void addRoute(IPv4Route *entry)=0
Adds a route to the routing table.
virtual void setDestination(IPv4Address _dest)
Definition: IPv4Route.h:96
Definition: OSPFPacket_m.h:249
manually added static route
Definition: IRoute.h:40
void rebuildRoutingTable()
Rebuilds the routing table from scratch(based on the LSA database).
Definition: OSPFRouter.cc:704

Member Data Documentation

cMessage* inet::ospf::Router::ageTimer
private

Database age timer - fires every second.

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

std::map<AreaID, Area *> inet::ospf::Router::areasByID
private

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

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

std::vector<ASExternalLSA *> inet::ospf::Router::asExternalLSAs
private

A list of the ASExternalLSAs advertised by this router.

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

std::map<LSAKeyType, ASExternalLSA *, LSAKeyType_Less> inet::ospf::Router::asExternalLSAsByID
private

A map of the ASExternalLSAs advertised by this router.

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

std::map<IPv4Address, OSPFASExternalLSAContents> inet::ospf::Router::externalRoutes
private

A map of the external route advertised by this router.

Referenced by removeExternalRoute(), and updateExternalRoute().

MessageHandler* inet::ospf::Router::messageHandler
private

The message dispatcher class.

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

bool inet::ospf::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().

std::vector<RoutingTableEntry *> inet::ospf::Router::routingTable
private

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

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

IIPv4RoutingTable* inet::ospf::Router::rt
private

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