INET Framework for OMNeT++/OMNEST
inet::Ipv4RoutingTable Class Reference

Represents the routing table. More...

#include <Ipv4RoutingTable.h>

Inheritance diagram for inet::Ipv4RoutingTable:
inet::IIpv4RoutingTable inet::ILifecycle inet::IRoutingTable

Classes

class  RouteLessThan
 

Public Member Functions

 Ipv4RoutingTable ()
 
virtual ~Ipv4RoutingTable ()
 
virtual void printRoutingTable () const override
 For debugging. More...
 
virtual void printMulticastRoutingTable () const override
 For debugging. More...
 
virtual cModule * getHostModule () override
 Returns the host or router this routing table lives in. More...
 
Interfaces
virtual NetworkInterfacegetInterfaceByAddress (const Ipv4Address &address) const override
 Returns an interface given by its address. More...
 
virtual bool isAdminDistEnabled () const override
 AdminDist on/off. More...
 
virtual bool isForwardingEnabled () const override
 Ipv4 forwarding on/off. More...
 
virtual bool isMulticastForwardingEnabled () const override
 Ipv4 multicast forwarding on/off. More...
 
virtual Ipv4Address getRouterId () const override
 Returns routerId. More...
 
virtual void setRouterId (Ipv4Address a) override
 Sets routerId. More...
 
Routing functions (query the route table)
virtual bool isLocalAddress (const Ipv4Address &dest) const override
 Checks if the address is a local one, i.e. More...
 
virtual bool isLocalBroadcastAddress (const Ipv4Address &dest) const override
 Checks if the address is a local network broadcast address, i.e. More...
 
virtual NetworkInterfacefindInterfaceByLocalBroadcastAddress (const Ipv4Address &dest) const override
 Returns the interface entry having the specified address as its local broadcast address. More...
 
virtual Ipv4RoutefindBestMatchingRoute (const Ipv4Address &dest) const override
 The routing function. More...
 
virtual NetworkInterfacegetInterfaceForDestAddr (const Ipv4Address &dest) const override
 Convenience function based on findBestMatchingRoute(). More...
 
virtual Ipv4Address getGatewayForDestAddr (const Ipv4Address &dest) const override
 Convenience function based on findBestMatchingRoute(). More...
 
Multicast routing functions
virtual bool isLocalMulticastAddress (const Ipv4Address &dest) const override
 Checks if the address is in one of the local multicast group address list. More...
 
virtual const Ipv4MulticastRoutefindBestMatchingMulticastRoute (const Ipv4Address &origin, const Ipv4Address &group) const override
 Returns route for a multicast source and multicast group. More...
 
- Public Member Functions inherited from inet::IIpv4RoutingTable
virtual ~IIpv4RoutingTable ()
 
virtual NetworkInterfacegetInterfaceByAddress (const L3Address &address) const=0
 Returns an interface given by its address. More...
 
virtual bool isLocalAddress (const L3Address &dest) const=0
 Checks if the address is a local one, i.e. More...
 
virtual IRoutefindBestMatchingRoute (const L3Address &dest) const=0
 The routing function. More...
 
virtual bool isLocalMulticastAddress (const L3Address &dest) const=0
 Checks if the address is in one of the local multicast group address list. More...
 
virtual IMulticastRoutefindBestMatchingMulticastRoute (const L3Address &origin, const L3Address &group) const=0
 Returns route for a multicast origin and group. More...
 
virtual void addRoute (IRoute *entry)=0
 Adds a route to the routing table. More...
 
virtual IRouteremoveRoute (IRoute *entry)=0
 Removes the given route from the routing table, and returns it. More...
 
virtual bool deleteRoute (IRoute *entry)=0
 Deletes the given route from the routing table. More...
 
virtual void addMulticastRoute (IMulticastRoute *entry)=0
 Adds a multicast route to the routing table. More...
 
virtual IMulticastRouteremoveMulticastRoute (IMulticastRoute *entry)=0
 Removes the given route from the routing table, and returns it. More...
 
virtual bool deleteMulticastRoute (IMulticastRoute *entry)=0
 Deletes the given multicast route from the routing table. More...
 
- Public Member Functions inherited from inet::IRoutingTable
virtual ~IRoutingTable ()
 
- Public Member Functions inherited from inet::ILifecycle
virtual ~ILifecycle ()
 

Protected Types

typedef Ipv4MulticastRoute::OutInterface OutInterface
 
typedef Ipv4MulticastRoute::OutInterfaceVector OutInterfaceVector
 
typedef std::map< Ipv4Address, Ipv4Route * > RoutingCache
 
typedef std::set< Ipv4AddressAddressSet
 

Protected Member Functions

virtual void configureRouterId ()
 
virtual void updateNetmaskRoutes ()
 
virtual Ipv4RoutecreateNewRoute ()
 
virtual void refreshDisplay () const override
 
virtual void deleteInterfaceRoutes (const NetworkInterface *entry)
 
virtual void invalidateCache ()
 
bool routeLessThan (const Ipv4Route *a, const Ipv4Route *b) const
 
void internalAddRoute (Ipv4Route *entry)
 
Ipv4RouteinternalRemoveRoute (Ipv4Route *entry)
 
void internalAddMulticastRoute (Ipv4MulticastRoute *entry)
 
Ipv4MulticastRouteinternalRemoveMulticastRoute (Ipv4MulticastRoute *entry)
 
virtual int numInitStages () const override
 
virtual void initialize (int stage) override
 
virtual void handleMessage (cMessage *) override
 Raises an error. More...
 
virtual void receiveSignal (cComponent *source, simsignal_t signalID, cObject *obj, cObject *details) override
 Called by the signal handler whenever a change of a category occurs to which this client has subscribed. More...
 

Static Protected Member Functions

static bool multicastRouteLessThan (const Ipv4MulticastRoute *a, const Ipv4MulticastRoute *b)
 

Protected Attributes

ModuleRefByPar< IInterfaceTableift
 
Ipv4Address routerId
 
const char * netmaskRoutes = nullptr
 
bool forwarding = false
 
bool multicastForward = false
 
bool isNodeUp = false
 
bool useAdminDist = false
 
RoutingCache routingCache
 
AddressSet localBroadcastAddresses
 

Private Types

typedef std::vector< Ipv4Route * > RouteVector
 
typedef std::vector< Ipv4MulticastRoute * > MulticastRouteVector
 

Private Attributes

RouteVector routes
 
MulticastRouteVector multicastRoutes
 

Route table manipulation

virtual int getNumRoutes () const override
 Returns the total number of routes (unicast, multicast, plus the default route). More...
 
virtual Ipv4RoutegetRoute (int k) const override
 Returns the kth route. More...
 
virtual Ipv4RoutegetDefaultRoute () const override
 Finds and returns the default route, or nullptr if it doesn't exist. More...
 
virtual void addRoute (Ipv4Route *entry) override
 Adds a route to the routing table. More...
 
virtual Ipv4RouteremoveRoute (Ipv4Route *entry) override
 Removes the given route from the routing table, and returns it. More...
 
virtual bool deleteRoute (Ipv4Route *entry) override
 Removes the given route from the routing table, and delete it. More...
 
virtual int getNumMulticastRoutes () const override
 Returns the total number of multicast routes. More...
 
virtual Ipv4MulticastRoutegetMulticastRoute (int k) const override
 Returns the kth multicast route. More...
 
virtual void addMulticastRoute (Ipv4MulticastRoute *entry) override
 Adds a multicast route to the routing table. More...
 
virtual Ipv4MulticastRouteremoveMulticastRoute (Ipv4MulticastRoute *entry) override
 Removes the given route from the routing table, and returns it. More...
 
virtual bool deleteMulticastRoute (Ipv4MulticastRoute *entry) override
 Deletes the given multicast route from the routing table. More...
 
virtual void purge () override
 Deletes invalid routes from the routing table. More...
 
virtual std::vector< Ipv4AddressgatherAddresses () const override
 Utility function: Returns a vector of all addresses of the node. More...
 
virtual void routeChanged (Ipv4Route *entry, int fieldCode) override
 To be called from route objects whenever a field changes. More...
 
virtual void multicastRouteChanged (Ipv4MulticastRoute *entry, int fieldCode) override
 To be called from multicast route objects whenever a field changes. More...
 
virtual bool handleOperationStage (LifecycleOperation *operation, IDoneCallback *doneCallback) override
 ILifecycle method. More...
 
virtual L3Address getRouterIdAsGeneric () const override
 Returns routerId. More...
 
virtual bool isLocalAddress (const L3Address &dest) const override
 Checks if the address is a local one, i.e. More...
 
virtual NetworkInterfacegetInterfaceByAddress (const L3Address &address) const override
 Returns an interface given by its address. More...
 
virtual IRoutefindBestMatchingRoute (const L3Address &dest) const override
 The routing function. More...
 
virtual NetworkInterfacegetOutputInterfaceForDestination (const L3Address &dest) const override
 Convenience function based on findBestMatchingRoute(). More...
 
virtual L3Address getNextHopForDestination (const L3Address &dest) const override
 Convenience function based on findBestMatchingRoute(). More...
 
virtual bool isLocalMulticastAddress (const L3Address &dest) const override
 Checks if the address is in one of the local multicast group address list. More...
 
virtual IMulticastRoutefindBestMatchingMulticastRoute (const L3Address &origin, const L3Address &group) const override
 Returns route for a multicast origin and group. More...
 
virtual IRoutecreateRoute () override
 
virtual void addRoute (IRoute *entry) override
 Adds a route to the routing table. More...
 
virtual IRouteremoveRoute (IRoute *entry) override
 Removes the given route from the routing table, and returns it. More...
 
virtual bool deleteRoute (IRoute *entry) override
 Deletes the given route from the routing table. More...
 
virtual void addMulticastRoute (IMulticastRoute *entry) override
 Adds a multicast route to the routing table. More...
 
virtual IMulticastRouteremoveMulticastRoute (IMulticastRoute *entry) override
 Removes the given route from the routing table, and returns it. More...
 
virtual bool deleteMulticastRoute (IMulticastRoute *entry) override
 Deletes the given multicast route from the routing table. More...
 

Detailed Description

Represents the routing table.

This object has one instance per host or router. It has methods to manage the route table and the interface table, so one can achieve functionality similar to the "route" and "ifconfig" commands.

See the NED documentation for general overview.

This is a simple module without gates, it requires function calls to it (message handling does nothing). Methods are provided for reading and updating the interface table and the route table, as well as for unicast and multicast routing.

Interfaces are dynamically registered: at the start of the simulation, every L2 module adds its own interface entry to the table.

The route table is read from a file (RoutingTableParser); the file can also fill in or overwrite interface settings. The route table can also be read and modified during simulation, typically by routing protocol implementations (e.g. OSPF).

Entries in the route table are represented by Ipv4Route objects. Ipv4Route objects can be polymorphic: if a routing protocol needs to store additional data, it can simply subclass from Ipv4Route, and add the derived object to the table.

Uses RoutingTableParser to read routing files (.irt, .mrt).

See also
NetworkInterface, Ipv4InterfaceData, Ipv4Route

Member Typedef Documentation

◆ AddressSet

typedef std::set<Ipv4Address> inet::Ipv4RoutingTable::AddressSet
protected

◆ MulticastRouteVector

◆ OutInterface

◆ OutInterfaceVector

◆ RouteVector

typedef std::vector<Ipv4Route *> inet::Ipv4RoutingTable::RouteVector
private

◆ RoutingCache

Constructor & Destructor Documentation

◆ Ipv4RoutingTable()

inet::Ipv4RoutingTable::Ipv4RoutingTable ( )
inline
138 {}

◆ ~Ipv4RoutingTable()

inet::Ipv4RoutingTable::~Ipv4RoutingTable ( )
virtual
46 {
47  for (auto& elem : routes)
48  delete elem;
49  for (auto& elem : multicastRoutes)
50  delete elem;
51 }

Member Function Documentation

◆ addMulticastRoute() [1/2]

virtual void inet::Ipv4RoutingTable::addMulticastRoute ( IMulticastRoute entry)
inlineoverrideprivatevirtual

Adds a multicast route to the routing table.

Routes are allowed to be modified while in the routing table. (There is a notification mechanism that allows routing table internals to be updated on a routing entry change.)

Implements inet::IRoutingTable.

381 { addMulticastRoute(check_and_cast<Ipv4MulticastRoute *>(entry)); }

Referenced by addMulticastRoute().

◆ addMulticastRoute() [2/2]

void inet::Ipv4RoutingTable::addMulticastRoute ( Ipv4MulticastRoute entry)
overridevirtual

Adds a multicast route to the routing table.

Routes are allowed to be modified while in the routing table. (There is a notification mechanism that allows routing table internals to be updated on a routing entry change.)

Implements inet::IIpv4RoutingTable.

638 {
639  Enter_Method("addMulticastRoute(...)");
641  emit(mrouteAddedSignal, entry);
642 }

◆ addRoute() [1/2]

void inet::Ipv4RoutingTable::addRoute ( Ipv4Route entry)
overridevirtual

Adds a route to the routing table.

Routes are allowed to be modified while in the routing table. (There is a notification mechanism that allows routing table internals to be updated on a routing entry change.)

Implements inet::IIpv4RoutingTable.

533 {
534  Enter_Method("addRoute(...)");
535  // This method should be called before calling entry->str()
536  internalAddRoute(entry);
537  EV_INFO << "add route " << entry->str() << "\n";
538  emit(routeAddedSignal, entry);
539 }

◆ addRoute() [2/2]

virtual void inet::Ipv4RoutingTable::addRoute ( IRoute entry)
inlineoverrideprivatevirtual

Adds a route to the routing table.

Routes are allowed to be modified while in the routing table. (There is a notification mechanism that allows routing table internals to be updated on a routing entry change.)

Implements inet::IRoutingTable.

377 { addRoute(check_and_cast<Ipv4Route *>(entry)); }

Referenced by addRoute().

◆ configureRouterId()

void inet::Ipv4RoutingTable::configureRouterId ( )
protectedvirtual
106 {
107  if (routerId.isUnspecified()) { // not yet configured
108  const char *routerIdStr = par("routerId");
109  if (!strcmp(routerIdStr, "auto")) { // non-"auto" cases already handled earlier
110  // choose highest interface address as routerId
111  for (int i = 0; i < ift->getNumInterfaces(); ++i) {
112  NetworkInterface *ie = ift->getInterface(i);
113  if (!ie->isLoopback()) {
114  auto ipv4Data = ie->findProtocolData<Ipv4InterfaceData>();
115  if (ipv4Data && ipv4Data->getIPAddress().getInt() > routerId.getInt()) {
116  routerId = ipv4Data->getIPAddress();
117  }
118  }
119  }
120  }
121  }
122  else { // already configured
123  // if there is no interface with routerId yet, assign it to the loopback address;
124  // TODO find out if this is a good practice, in which situations it is useful etc.
125  if (getInterfaceByAddress(routerId) == nullptr) {
126  NetworkInterface *lo0 = CHK(ift->findFirstLoopbackInterface());
127  auto ipv4Data = lo0->getProtocolDataForUpdate<Ipv4InterfaceData>();
128  ipv4Data->setIPAddress(routerId);
129  ipv4Data->setNetmask(Ipv4Address::ALLONES_ADDRESS);
130  }
131  }
132 }

◆ createNewRoute()

Ipv4Route * inet::Ipv4RoutingTable::createNewRoute ( )
protectedvirtual
782 {
783  return new Ipv4Route();
784 }

◆ createRoute()

virtual IRoute* inet::Ipv4RoutingTable::createRoute ( )
inlineoverridevirtual

Implements inet::IRoutingTable.

374 { return new Ipv4Route(); }

◆ deleteInterfaceRoutes()

void inet::Ipv4RoutingTable::deleteInterfaceRoutes ( const NetworkInterface entry)
protectedvirtual
198 {
199  // delete unicast routes using this interface
200  for (auto it = routes.begin(); it != routes.end();) {
201  Ipv4Route *route = *it;
202  if (route->getInterface() == entry) {
203  it = routes.erase(it);
204  invalidateCache();
205  ASSERT(route->getRoutingTable() == this); // still filled in, for the listeners' benefit
206  emit(routeDeletedSignal, route);
207  delete route;
208  }
209  else
210  ++it;
211  }
212 
213  // delete or update multicast routes:
214  // 1. delete routes has entry as input interface
215  // 2. remove entry from output interface list
216  for (auto it = multicastRoutes.begin(); it != multicastRoutes.end();) {
217  Ipv4MulticastRoute *route = *it;
218  if (route->getInInterface() && route->getInInterface()->getInterface() == entry) {
219  it = multicastRoutes.erase(it);
220  invalidateCache();
221  ASSERT(route->getRoutingTable() == this); // still filled in, for the listeners' benefit
222  emit(mrouteDeletedSignal, route);
223  delete route;
224  }
225  else {
226  if (route->removeOutInterface(entry)) {
227  invalidateCache();
228  emit(mrouteChangedSignal, route);
229  }
230  ++it;
231  }
232  }
233 }

◆ deleteMulticastRoute() [1/2]

virtual bool inet::Ipv4RoutingTable::deleteMulticastRoute ( IMulticastRoute entry)
inlineoverrideprivatevirtual

Deletes the given multicast route from the routing table.

Returns true if the route was deleted, and false if it was not in the routing table.

Implements inet::IRoutingTable.

383 { return deleteMulticastRoute(check_and_cast<Ipv4MulticastRoute *>(entry)); }

Referenced by deleteMulticastRoute().

◆ deleteMulticastRoute() [2/2]

bool inet::Ipv4RoutingTable::deleteMulticastRoute ( Ipv4MulticastRoute entry)
overridevirtual

Deletes the given multicast route from the routing table.

Returns true if the route was deleted, and false if it was not in the routing table.

Implements inet::IIpv4RoutingTable.

670 {
671  Enter_Method("deleteMulticastRoute(...)");
672  entry = internalRemoveMulticastRoute(entry);
673  if (entry != nullptr) {
674  ASSERT(entry->getRoutingTable() == this); // still filled in, for the listeners' benefit
675  emit(mrouteDeletedSignal, entry);
676  delete entry;
677  }
678  return entry != nullptr;
679 }

◆ deleteRoute() [1/2]

bool inet::Ipv4RoutingTable::deleteRoute ( Ipv4Route entry)
overridevirtual

Removes the given route from the routing table, and delete it.

Returns true if the route was deleted, and false if it was not in the routing table.

Implements inet::IIpv4RoutingTable.

568 {
569  Enter_Method("deleteRoute(...)");
570 
571  entry = internalRemoveRoute(entry);
572 
573  if (entry != nullptr) {
574  EV_INFO << "delete route " << entry->str() << "\n";
575  ASSERT(entry->getRoutingTable() == this); // still filled in, for the listeners' benefit
576  emit(routeDeletedSignal, entry);
577  delete entry;
578  }
579  return entry != nullptr;
580 }

◆ deleteRoute() [2/2]

virtual bool inet::Ipv4RoutingTable::deleteRoute ( IRoute entry)
inlineoverrideprivatevirtual

Deletes the given route from the routing table.

Returns true if the route was deleted, and false if it was not in the routing table.

Implements inet::IRoutingTable.

379 { return deleteRoute(check_and_cast<Ipv4Route *>(entry)); }

Referenced by deleteRoute().

◆ findBestMatchingMulticastRoute() [1/2]

const Ipv4MulticastRoute * inet::Ipv4RoutingTable::findBestMatchingMulticastRoute ( const Ipv4Address origin,
const Ipv4Address group 
) const
overridevirtual

Returns route for a multicast source and multicast group.

Implements inet::IIpv4RoutingTable.

434 {
435  Enter_Method("getMulticastRoutesFor(%u.%u.%u.%u, %u.%u.%u.%u)",
436  origin.getDByte(0), origin.getDByte(1), origin.getDByte(2), origin.getDByte(3),
437  group.getDByte(0), group.getDByte(1), group.getDByte(2), group.getDByte(3)); // note: str().c_str() too slow here here
438 
439  // TODO caching?
440 
441  for (auto e : multicastRoutes) {
442  if (e->isValid() && e->matches(origin, group))
443  return e;
444  }
445 
446  return nullptr;
447 }

◆ findBestMatchingMulticastRoute() [2/2]

virtual IMulticastRoute* inet::Ipv4RoutingTable::findBestMatchingMulticastRoute ( const L3Address origin,
const L3Address group 
) const
inlineoverridevirtual

Returns route for a multicast origin and group.

Implements inet::IRoutingTable.

373 { return const_cast<Ipv4MulticastRoute *>(findBestMatchingMulticastRoute(origin.toIpv4(), group.toIpv4())); } // TODO remove 'const' from Ipv4 method?

Referenced by findBestMatchingMulticastRoute().

◆ findBestMatchingRoute() [1/2]

Ipv4Route * inet::Ipv4RoutingTable::findBestMatchingRoute ( const Ipv4Address dest) const
overridevirtual

The routing function.

Performs longest prefix match for the given destination address, and returns the resulting route. Returns nullptr if there is no matching route.

Implements inet::IIpv4RoutingTable.

392 {
393  Enter_Method("findBestMatchingRoute(%u.%u.%u.%u)", dest.getDByte(0), dest.getDByte(1), dest.getDByte(2), dest.getDByte(3)); // note: str().c_str() too slow here
394 
395  auto it = routingCache.find(dest);
396  if (it != routingCache.end()) {
397  if (it->second == nullptr || it->second->isValid())
398  return it->second;
399  }
400 
401  // find best match (one with longest prefix)
402  // default route has zero prefix length, so (if exists) it'll be selected as last resort
403  Ipv4Route *bestRoute = nullptr;
404  for (auto e : routes) {
405  if (e->isValid()) {
406  if (Ipv4Address::maskedAddrAreEqual(dest, e->getDestination(), e->getNetmask())) { // match
407  bestRoute = const_cast<Ipv4Route *>(e);
408  break;
409  }
410  }
411  }
412 
413  routingCache[dest] = bestRoute;
414  return bestRoute;
415 }

◆ findBestMatchingRoute() [2/2]

virtual IRoute* inet::Ipv4RoutingTable::findBestMatchingRoute ( const L3Address dest) const
inlineoverridevirtual

The routing function.

Performs longest prefix match for the given destination address, and returns the resulting route. Returns nullptr if there is no matching route.

Implements inet::IRoutingTable.

369 { return findBestMatchingRoute(dest.toIpv4()); }

Referenced by findBestMatchingRoute().

◆ findInterfaceByLocalBroadcastAddress()

NetworkInterface * inet::Ipv4RoutingTable::findInterfaceByLocalBroadcastAddress ( const Ipv4Address dest) const
overridevirtual

Returns the interface entry having the specified address as its local broadcast address.

Implements inet::IIpv4RoutingTable.

333 {
334  Enter_Method("findInterfaceByLocalBroadcastAddress(%u.%u.%u.%u)", dest.getDByte(0), dest.getDByte(1), dest.getDByte(2), dest.getDByte(3)); // note: str().c_str() too slow here
335 
336  for (int i = 0; i < ift->getNumInterfaces(); i++) {
337  NetworkInterface *ie = ift->getInterface(i);
338  if (!ie->isBroadcast())
339  continue;
340  Ipv4Address interfaceAddr = ie->getProtocolData<Ipv4InterfaceData>()->getIPAddress();
341  Ipv4Address broadcastAddr = interfaceAddr.makeBroadcastAddress(ie->getProtocolData<Ipv4InterfaceData>()->getNetmask());
342  if (broadcastAddr == dest)
343  return ie;
344  }
345  return nullptr;
346 }

◆ gatherAddresses()

std::vector< Ipv4Address > inet::Ipv4RoutingTable::gatherAddresses ( ) const
overridevirtual

Utility function: Returns a vector of all addresses of the node.

Implements inet::IIpv4RoutingTable.

286 {
287  std::vector<Ipv4Address> addressvector;
288 
289  for (int i = 0; i < ift->getNumInterfaces(); ++i)
290  addressvector.push_back(ift->getInterface(i)->getProtocolData<Ipv4InterfaceData>()->getIPAddress());
291  return addressvector;
292 }

◆ getDefaultRoute()

Ipv4Route * inet::Ipv4RoutingTable::getDefaultRoute ( ) const
overridevirtual

Finds and returns the default route, or nullptr if it doesn't exist.

Implements inet::IIpv4RoutingTable.

457 {
458  // if exists default route entry, it is the last valid entry
459  for (RouteVector::const_reverse_iterator i = routes.rbegin(); i != routes.rend() && (*i)->getNetmask().isUnspecified(); ++i) {
460  if ((*i)->isValid())
461  return *i;
462  }
463  return nullptr;
464 }

◆ getGatewayForDestAddr()

Ipv4Address inet::Ipv4RoutingTable::getGatewayForDestAddr ( const Ipv4Address dest) const
overridevirtual

Convenience function based on findBestMatchingRoute().

Returns the gateway for the destination address. Returns the unspecified address if the destination is not in routing table or the gateway field is not filled in in the route.

Implements inet::IIpv4RoutingTable.

426 {
427  Enter_Method("getGatewayForDestAddr(%u.%u.%u.%u)", dest.getDByte(0), dest.getDByte(1), dest.getDByte(2), dest.getDByte(3)); // note: str().c_str() too slow here
428 
429  const Ipv4Route *e = findBestMatchingRoute(dest);
430  return e ? e->getGateway() : Ipv4Address();
431 }

◆ getHostModule()

cModule * inet::Ipv4RoutingTable::getHostModule ( )
overridevirtual

Returns the host or router this routing table lives in.

Implements inet::IIpv4RoutingTable.

193 {
194  return findContainingNode(this);
195 }

◆ getInterfaceByAddress() [1/2]

NetworkInterface * inet::Ipv4RoutingTable::getInterfaceByAddress ( const Ipv4Address address) const
overridevirtual

Returns an interface given by its address.

Returns nullptr if not found.

Implements inet::IIpv4RoutingTable.

297 {
298  Enter_Method("getInterfaceByAddress(%u.%u.%u.%u)", addr.getDByte(0), addr.getDByte(1), addr.getDByte(2), addr.getDByte(3)); // note: str().c_str() too slow here
299  return ift->findInterfaceByAddress(addr);
300 }

◆ getInterfaceByAddress() [2/2]

virtual NetworkInterface* inet::Ipv4RoutingTable::getInterfaceByAddress ( const L3Address address) const
inlineoverridevirtual

Returns an interface given by its address.

Returns nullptr if not found.

Implements inet::IRoutingTable.

368 { return getInterfaceByAddress(address.toIpv4()); }

Referenced by getInterfaceByAddress().

◆ getInterfaceForDestAddr()

NetworkInterface * inet::Ipv4RoutingTable::getInterfaceForDestAddr ( const Ipv4Address dest) const
overridevirtual

Convenience function based on findBestMatchingRoute().

Returns the output interface for the packets with dest as destination address, or nullptr if the destination is not in routing table.

Implements inet::IIpv4RoutingTable.

418 {
419  Enter_Method("getInterfaceForDestAddr(%u.%u.%u.%u)", dest.getDByte(0), dest.getDByte(1), dest.getDByte(2), dest.getDByte(3)); // note: str().c_str() too slow here
420 
421  const Ipv4Route *e = findBestMatchingRoute(dest);
422  return e ? e->getInterface() : nullptr;
423 }

◆ getMulticastRoute()

virtual Ipv4MulticastRoute* inet::Ipv4RoutingTable::getMulticastRoute ( int  k) const
inlineoverridevirtual

Returns the kth multicast route.

Implements inet::IIpv4RoutingTable.

313 { return k >= 0 && static_cast<size_t>(k) < multicastRoutes.size() ? multicastRoutes[k] : nullptr; }

◆ getNextHopForDestination()

virtual L3Address inet::Ipv4RoutingTable::getNextHopForDestination ( const L3Address dest) const
inlineoverridevirtual

Convenience function based on findBestMatchingRoute().

Returns the gateway for the destination address. Returns the unspecified address if the destination is not in routing table or the gateway field is not filled in in the route.

Implements inet::IRoutingTable.

371 { return getGatewayForDestAddr(dest.toIpv4()); } // TODO inconsistent names

◆ getNumMulticastRoutes()

virtual int inet::Ipv4RoutingTable::getNumMulticastRoutes ( ) const
inlineoverridevirtual

Returns the total number of multicast routes.

Implements inet::IRoutingTable.

308 { return multicastRoutes.size(); }

◆ getNumRoutes()

virtual int inet::Ipv4RoutingTable::getNumRoutes ( ) const
inlineoverridevirtual

Returns the total number of routes (unicast, multicast, plus the default route).

Implements inet::IRoutingTable.

273 { return routes.size(); }

◆ getOutputInterfaceForDestination()

virtual NetworkInterface* inet::Ipv4RoutingTable::getOutputInterfaceForDestination ( const L3Address dest) const
inlineoverridevirtual

Convenience function based on findBestMatchingRoute().

Returns the output interface for the packets with dest as destination address, or nullptr if the destination is not in routing table.

Implements inet::IRoutingTable.

370 { return getInterfaceForDestAddr(dest.toIpv4()); } // TODO inconsistent names

◆ getRoute()

Ipv4Route * inet::Ipv4RoutingTable::getRoute ( int  k) const
overridevirtual

Returns the kth route.

Implements inet::IIpv4RoutingTable.

450 {
451  if (k < (int)routes.size())
452  return routes[k];
453  return nullptr;
454 }

◆ getRouterId()

virtual Ipv4Address inet::Ipv4RoutingTable::getRouterId ( ) const
inlineoverridevirtual

Returns routerId.

Implements inet::IIpv4RoutingTable.

198 { return routerId; }

◆ getRouterIdAsGeneric()

virtual L3Address inet::Ipv4RoutingTable::getRouterIdAsGeneric ( ) const
inlineoverridevirtual

Returns routerId.

Implements inet::IRoutingTable.

366 { return getRouterId(); }

◆ handleMessage()

void inet::Ipv4RoutingTable::handleMessage ( cMessage *  msg)
overrideprotectedvirtual

Raises an error.

145 {
146  throw cRuntimeError("This module doesn't process messages");
147 }

◆ handleOperationStage()

bool inet::Ipv4RoutingTable::handleOperationStage ( LifecycleOperation operation,
IDoneCallback doneCallback 
)
overridevirtual

ILifecycle method.

Implements inet::ILifecycle.

747 {
748  Enter_Method("handleOperationStage");
749  int stage = operation->getCurrentStage();
750  if (dynamic_cast<ModuleStartOperation *>(operation)) {
752  // read routing table file (and interface configuration)
753  const char *filename = par("routingFile");
754  RoutingTableParser parser(ift, this);
755  if (*filename && parser.readRoutingTableFromFile(filename) == -1)
756  throw cRuntimeError("Error reading routing table file %s", filename);
757  }
761  isNodeUp = true;
762  }
763  }
764  else if (dynamic_cast<ModuleStopOperation *>(operation)) {
766  while (!routes.empty())
767  delete removeRoute(routes[0]);
768  isNodeUp = false;
769  }
770  }
771  else if (dynamic_cast<ModuleCrashOperation *>(operation)) {
773  while (!routes.empty())
774  delete removeRoute(routes[0]);
775  isNodeUp = false;
776  }
777  }
778  return true;
779 }

◆ initialize()

void inet::Ipv4RoutingTable::initialize ( int  stage)
overrideprotectedvirtual
54 {
55  cSimpleModule::initialize(stage);
56 
57  if (stage == INITSTAGE_LOCAL) {
58  // get a pointer to the host module and IInterfaceTable
59  cModule *host = getContainingNode(this);
60  host->subscribe(interfaceCreatedSignal, this);
61  host->subscribe(interfaceDeletedSignal, this);
62  host->subscribe(interfaceStateChangedSignal, this);
63  host->subscribe(interfaceConfigChangedSignal, this);
64  host->subscribe(interfaceIpv4ConfigChangedSignal, this);
65 
66  ift.reference(this, "interfaceTableModule", true);
67 
68  netmaskRoutes = par("netmaskRoutes");
69  forwarding = par("forwarding");
70  multicastForward = par("multicastForwarding");
71  useAdminDist = par("useAdminDist");
72 
73  WATCH_PTRVECTOR(routes);
74  WATCH_PTRVECTOR(multicastRoutes);
75  WATCH(netmaskRoutes);
76  WATCH(forwarding);
77  WATCH(multicastForward);
78  WATCH(routerId);
79  }
80  else if (stage == INITSTAGE_ROUTER_ID_ASSIGNMENT) {
81  cModule *node = findContainingNode(this);
82  NodeStatus *nodeStatus = node ? check_and_cast_nullable<NodeStatus *>(node->getSubmodule("status")) : nullptr;
83  isNodeUp = !nodeStatus || nodeStatus->getState() == NodeStatus::UP;
84  if (isNodeUp) {
85  // set routerId if param is not "" (==no routerId) or "auto" (in which case we'll
86  // do it later in a later stage, after network configurators configured the interfaces)
87  const char *routerIdStr = par("routerId");
88  if (strcmp(routerIdStr, "") && strcmp(routerIdStr, "auto"))
89  routerId = Ipv4Address(routerIdStr);
90  // read routing table file (and interface configuration)
91  const char *filename = par("routingFile");
92  RoutingTableParser parser(ift, this);
93  if (*filename && parser.readRoutingTableFromFile(filename) == -1)
94  throw cRuntimeError("Error reading routing table file %s", filename);
95  // routerID selection must be after network autoconfiguration assigned interface addresses
97  }
98  }
99  else if (stage == INITSTAGE_NETWORK_LAYER) {
100  // we don't use notifications during initialize(), so we do it manually.
102  }
103 }

◆ internalAddMulticastRoute()

void inet::Ipv4RoutingTable::internalAddMulticastRoute ( Ipv4MulticastRoute entry)
protected
601 {
602  if (!entry->getOriginNetmask().isValidNetmask())
603  throw cRuntimeError("addMulticastRoute(): wrong netmask %s in multicast route", entry->getOriginNetmask().str().c_str());
604 
605  if ((entry->getOrigin().getInt() & ~entry->getOriginNetmask().getInt()) != 0)
606  throw cRuntimeError("addMulticastRoute(): suspicious route: origin IP address %s has bits set outside netmask %s",
607  entry->getOrigin().str().c_str(), entry->getOriginNetmask().str().c_str());
608 
609  if (!entry->getMulticastGroup().isUnspecified() && !entry->getMulticastGroup().isMulticast())
610  throw cRuntimeError("addMulticastRoute(): group address (%s) is not a multicast address",
611  entry->getMulticastGroup().str().c_str());
612 
613  // check that the interface exists
614  if (entry->getInInterface() && !entry->getInInterface()->getInterface()->isMulticast())
615  throw cRuntimeError("addMulticastRoute(): input interface must be multicast capable");
616 
617  for (unsigned int i = 0; i < entry->getNumOutInterfaces(); i++) {
618  Ipv4MulticastRoute::OutInterface *outInterface = entry->getOutInterface(i);
619  if (!outInterface)
620  throw cRuntimeError("addMulticastRoute(): output interface cannot be nullptr");
621  else if (!outInterface->getInterface()->isMulticast())
622  throw cRuntimeError("addMulticastRoute(): output interface must be multicast capable");
623  else if (entry->getInInterface() && outInterface->getInterface() == entry->getInInterface()->getInterface())
624  throw cRuntimeError("addMulticastRoute(): output interface cannot be the same as the input interface");
625  }
626 
627  // add to tables
628  // we keep entries sorted by netmask desc, metric asc in routeList, so that we can
629  // stop at the first match when doing the longest netmask matching
630  auto pos =
631  upper_bound(multicastRoutes.begin(), multicastRoutes.end(), entry, multicastRouteLessThan);
632  multicastRoutes.insert(pos, entry);
633  invalidateCache();
634  entry->setRoutingTable(this);
635 }

◆ internalAddRoute()

void inet::Ipv4RoutingTable::internalAddRoute ( Ipv4Route entry)
protected
494 {
495  if (!entry->getNetmask().isValidNetmask())
496  throw cRuntimeError("addRoute(): wrong netmask %s in route", entry->getNetmask().str().c_str());
497 
498  if (entry->getNetmask().getInt() != 0 && (entry->getDestination().getInt() & entry->getNetmask().getInt()) == 0)
499  throw cRuntimeError("addRoute(): all bits of destination address %s is 0 inside non zero netmask %s",
500  entry->getDestination().str().c_str(), entry->getNetmask().str().c_str());
501 
502  if ((entry->getDestination().getInt() & ~entry->getNetmask().getInt()) != 0)
503  throw cRuntimeError("addRoute(): suspicious route: destination IP address %s has bits set outside netmask %s",
504  entry->getDestination().str().c_str(), entry->getNetmask().str().c_str());
505 
506  // check that the interface exists
507  if (!entry->getInterface())
508  throw cRuntimeError("addRoute(): interface cannot be nullptr");
509 
510  // if this is a default route, remove old default route (we're replacing it)
511  if (entry->getNetmask().isUnspecified()) {
512  Ipv4Route *oldDefaultRoute = getDefaultRoute();
513  if (oldDefaultRoute != nullptr)
514  deleteRoute(oldDefaultRoute);
515  }
516 
517  // The 'routes' vector may contain multiple routes with the same destination/netmask.
518  // Routes are stored in descending netmask length and ascending administrative_distance/metric order,
519  // so the first matching is the best one.
520  // TODO Should only the route with the best metic be stored? Then the worse route should be deleted and
521  // internalAddRoute() should return a bool indicating if it was successful.
522 
523  // add to tables
524  // we keep entries sorted by netmask desc, metric asc in routeList, so that we can
525  // stop at the first match when doing the longest netmask matching
526  auto pos = upper_bound(routes.begin(), routes.end(), entry, RouteLessThan(*this));
527  routes.insert(pos, entry);
528  invalidateCache();
529  entry->setRoutingTable(this);
530 }

◆ internalRemoveMulticastRoute()

Ipv4MulticastRoute * inet::Ipv4RoutingTable::internalRemoveMulticastRoute ( Ipv4MulticastRoute entry)
protected
645 {
646  auto i = find(multicastRoutes, entry);
647  if (i != multicastRoutes.end()) {
648  multicastRoutes.erase(i);
649  invalidateCache();
650  return entry;
651  }
652  return nullptr;
653 }

◆ internalRemoveRoute()

Ipv4Route * inet::Ipv4RoutingTable::internalRemoveRoute ( Ipv4Route entry)
protected
542 {
543  auto i = find(routes, entry);
544  if (i != routes.end()) {
545  routes.erase(i);
546  invalidateCache();
547  return entry;
548  }
549  return nullptr;
550 }

◆ invalidateCache()

void inet::Ipv4RoutingTable::invalidateCache ( )
protectedvirtual
236 {
237  routingCache.clear();
238  localBroadcastAddresses.clear();
239 }

◆ isAdminDistEnabled()

virtual bool inet::Ipv4RoutingTable::isAdminDistEnabled ( ) const
inlineoverridevirtual

AdminDist on/off.

Implements inet::IRoutingTable.

183 { return useAdminDist; }

◆ isForwardingEnabled()

virtual bool inet::Ipv4RoutingTable::isForwardingEnabled ( ) const
inlineoverridevirtual

Ipv4 forwarding on/off.

Implements inet::IRoutingTable.

188 { return forwarding; }

◆ isLocalAddress() [1/2]

bool inet::Ipv4RoutingTable::isLocalAddress ( const Ipv4Address dest) const
overridevirtual

Checks if the address is a local one, i.e.

one of the host's.

Implements inet::IIpv4RoutingTable.

305 {
306  Enter_Method("isLocalAddress(%u.%u.%u.%u)", dest.getDByte(0), dest.getDByte(1), dest.getDByte(2), dest.getDByte(3)); // note: str().c_str() too slow here
307  return ift->isLocalAddress(dest);
308 }

◆ isLocalAddress() [2/2]

virtual bool inet::Ipv4RoutingTable::isLocalAddress ( const L3Address dest) const
inlineoverridevirtual

Checks if the address is a local one, i.e.

one of the host's.

Implements inet::IRoutingTable.

367 { return isLocalAddress(dest.toIpv4()); }

Referenced by isLocalAddress().

◆ isLocalBroadcastAddress()

bool inet::Ipv4RoutingTable::isLocalBroadcastAddress ( const Ipv4Address dest) const
overridevirtual

Checks if the address is a local network broadcast address, i.e.

one of the broadcast addresses derived from the interface addresses and netmasks.

Implements inet::IIpv4RoutingTable.

312 {
313  Enter_Method("isLocalBroadcastAddress(%u.%u.%u.%u)", dest.getDByte(0), dest.getDByte(1), dest.getDByte(2), dest.getDByte(3)); // note: str().c_str() too slow here
314 
315  if (localBroadcastAddresses.empty()) {
316  // collect interface addresses if not yet done
317  for (int i = 0; i < ift->getNumInterfaces(); i++) {
318  NetworkInterface *ie = ift->getInterface(i);
319  if (!ie->isBroadcast())
320  continue;
321  Ipv4Address interfaceAddr = ie->getProtocolData<Ipv4InterfaceData>()->getIPAddress();
322  Ipv4Address broadcastAddr = interfaceAddr.makeBroadcastAddress(ie->getProtocolData<Ipv4InterfaceData>()->getNetmask());
323  if (!broadcastAddr.isUnspecified()) {
324  localBroadcastAddresses.insert(broadcastAddr);
325  }
326  }
327  }
328 
329  return contains(localBroadcastAddresses, dest);
330 }

◆ isLocalMulticastAddress() [1/2]

bool inet::Ipv4RoutingTable::isLocalMulticastAddress ( const Ipv4Address dest) const
overridevirtual

Checks if the address is in one of the local multicast group address list.

Implements inet::IIpv4RoutingTable.

349 {
350  Enter_Method("isLocalMulticastAddress(%u.%u.%u.%u)", dest.getDByte(0), dest.getDByte(1), dest.getDByte(2), dest.getDByte(3)); // note: str().c_str() too slow here
351 
352  for (int i = 0; i < ift->getNumInterfaces(); i++) {
353  NetworkInterface *ie = ift->getInterface(i);
354  if (ie->getProtocolData<Ipv4InterfaceData>()->isMemberOfMulticastGroup(dest))
355  return true;
356  }
357  return false;
358 }

◆ isLocalMulticastAddress() [2/2]

virtual bool inet::Ipv4RoutingTable::isLocalMulticastAddress ( const L3Address dest) const
inlineoverridevirtual

Checks if the address is in one of the local multicast group address list.

Implements inet::IRoutingTable.

372 { return isLocalMulticastAddress(dest.toIpv4()); }

Referenced by isLocalMulticastAddress().

◆ isMulticastForwardingEnabled()

virtual bool inet::Ipv4RoutingTable::isMulticastForwardingEnabled ( ) const
inlineoverridevirtual

Ipv4 multicast forwarding on/off.

Implements inet::IRoutingTable.

193 { return multicastForward; }

◆ multicastRouteChanged()

void inet::Ipv4RoutingTable::multicastRouteChanged ( Ipv4MulticastRoute entry,
int  fieldCode 
)
overridevirtual

To be called from multicast route objects whenever a field changes.

Used for maintaining internal data structures and firing "routing table changed" notifications.

Implements inet::IIpv4RoutingTable.

692 {
693  if (fieldCode == Ipv4MulticastRoute::F_ORIGIN || fieldCode == Ipv4MulticastRoute::F_ORIGINMASK ||
694  fieldCode == Ipv4MulticastRoute::F_MULTICASTGROUP || fieldCode == Ipv4MulticastRoute::F_METRIC) // our data structures depend on these fields
695  {
696  entry = internalRemoveMulticastRoute(entry);
697  ASSERT(entry != nullptr); // failure means inconsistency: route was not found in this routing table
699  }
700  emit(mrouteChangedSignal, entry); // TODO include fieldCode in the notification
701 }

◆ multicastRouteLessThan()

bool inet::Ipv4RoutingTable::multicastRouteLessThan ( const Ipv4MulticastRoute a,
const Ipv4MulticastRoute b 
)
staticprotected
583 {
584  // We want routes with longer
585  // prefixes to be at front, so we compare them as "less".
586  if (a->getOriginNetmask() != b->getOriginNetmask())
587  return a->getOriginNetmask() > b->getOriginNetmask();
588 
589  // For metric, a smaller value is better (we report that as "less").
590  if (a->getOrigin() != b->getOrigin())
591  return a->getOrigin() < b->getOrigin();
592 
593  // put the unspecified group after the specified ones
594  if (a->getMulticastGroup() != b->getMulticastGroup())
595  return a->getMulticastGroup() > b->getMulticastGroup();
596 
597  return a->getMetric() < b->getMetric();
598 }

◆ numInitStages()

virtual int inet::Ipv4RoutingTable::numInitStages ( ) const
inlineoverrideprotectedvirtual
142 { return NUM_INIT_STAGES; }

◆ printMulticastRoutingTable()

void inet::Ipv4RoutingTable::printMulticastRoutingTable ( ) const
overridevirtual

For debugging.

Implements inet::IIpv4RoutingTable.

262 {
263  EV << "-- Multicast routing table --\n";
264  EV << stringf("%-16s %-16s %-16s %-6s %-6s %s\n",
265  "Source", "Netmask", "Group", "Metric", "In", "Outs");
266 
267  for (int i = 0; i < getNumMulticastRoutes(); i++) {
268  Ipv4MulticastRoute *route = getMulticastRoute(i);
269  EV << stringf("%-16s %-16s %-16s %-6d %-6s ",
270  route->getOrigin().isUnspecified() ? "*" : route->getOrigin().str().c_str(),
271  route->getOriginNetmask().isUnspecified() ? "*" : route->getOriginNetmask().str().c_str(),
272  route->getMulticastGroup().isUnspecified() ? "*" : route->getMulticastGroup().str().c_str(),
273  route->getMetric(),
274  !route->getInInterface() ? "*" : route->getInInterface()->getInterface()->getInterfaceName());
275  for (unsigned int i = 0; i < route->getNumOutInterfaces(); i++) {
276  if (i != 0)
277  EV << ",";
278  EV << route->getOutInterface(i)->getInterface()->getInterfaceName();
279  }
280  EV << "\n";
281  }
282  EV << "\n";
283 }

◆ printRoutingTable()

void inet::Ipv4RoutingTable::printRoutingTable ( ) const
overridevirtual

For debugging.

Implements inet::IRoutingTable.

242 {
243  EV << "-- Routing table --\n";
244  EV << stringf("%-16s %-16s %-16s %-4s %-16s %s\n",
245  "Destination", "Netmask", "Gateway", "Iface", "", "Metric");
246 
247  for (int i = 0; i < getNumRoutes(); i++) {
248  Ipv4Route *route = getRoute(i);
249  NetworkInterface *interfacePtr = route->getInterface();
250  EV << stringf("%-16s %-16s %-16s %-4s %-16s %6d\n",
251  route->getDestination().isUnspecified() ? "*" : route->getDestination().str().c_str(),
252  route->getNetmask().isUnspecified() ? "*" : route->getNetmask().str().c_str(),
253  route->getGateway().isUnspecified() ? "*" : route->getGateway().str().c_str(),
254  !interfacePtr ? "*" : interfacePtr->getInterfaceName(),
255  !interfacePtr ? "(*)" : (std::string("(") + interfacePtr->getProtocolData<Ipv4InterfaceData>()->getIPAddress().str() + ")").c_str(),
256  route->getMetric());
257  }
258  EV << "\n";
259 }

◆ purge()

void inet::Ipv4RoutingTable::purge ( )
overridevirtual

Deletes invalid routes from the routing table.

Invalid routes are those where the isValid() method returns false.

Implements inet::IIpv4RoutingTable.

361 {
362  // purge unicast routes
363  for (auto it = routes.begin(); it != routes.end();) {
364  Ipv4Route *route = *it;
365  if (route->isValid())
366  ++it;
367  else {
368  it = routes.erase(it);
369  invalidateCache();
370  ASSERT(route->getRoutingTable() == this); // still filled in, for the listeners' benefit
371  emit(routeDeletedSignal, route);
372  delete route;
373  }
374  }
375 
376  // purge multicast routes
377  for (auto it = multicastRoutes.begin(); it != multicastRoutes.end();) {
378  Ipv4MulticastRoute *route = *it;
379  if (route->isValid())
380  ++it;
381  else {
382  it = multicastRoutes.erase(it);
383  invalidateCache();
384  ASSERT(route->getRoutingTable() == this); // still filled in, for the listeners' benefit
385  emit(mrouteDeletedSignal, route);
386  delete route;
387  }
388  }
389 }

◆ receiveSignal()

void inet::Ipv4RoutingTable::receiveSignal ( cComponent *  source,
simsignal_t  signalID,
cObject *  obj,
cObject *  details 
)
overrideprotectedvirtual

Called by the signal handler whenever a change of a category occurs to which this client has subscribed.

150 {
151  if (getSimulation()->getContextType() == CTX_INITIALIZE)
152  return; // ignore notifications during initialize
153 
154  Enter_Method("%s", cComponent::getSignalName(signalID));
155 
156  printSignalBanner(signalID, obj, details);
157 
158  if (signalID == interfaceCreatedSignal) {
159  // add netmask route for the new interface
161  invalidateCache();
162  }
163  else if (signalID == interfaceDeletedSignal) {
164  // remove all routes that point to that interface
165  const NetworkInterface *entry = check_and_cast<const NetworkInterface *>(obj);
166  deleteInterfaceRoutes(entry);
167  invalidateCache();
168  }
169  else if (signalID == interfaceStateChangedSignal) {
170  invalidateCache();
171  const auto *ieChangeDetails = check_and_cast<const NetworkInterfaceChangeDetails *>(obj);
172  auto fieldId = ieChangeDetails->getFieldId();
173  if (fieldId == NetworkInterface::F_STATE || fieldId == NetworkInterface::F_CARRIER) {
174  const auto *entry = ieChangeDetails->getNetworkInterface();
176  if (!entry->isUp())
177  deleteInterfaceRoutes(entry);
178  invalidateCache();
179  }
180  }
181  else if (signalID == interfaceConfigChangedSignal) {
182  invalidateCache();
183  }
184  else if (signalID == interfaceIpv4ConfigChangedSignal) {
185  // if anything Ipv4-related changes in the interfaces, interface netmask
186  // based routes have to be re-built.
188  invalidateCache();
189  }
190 }

◆ refreshDisplay()

void inet::Ipv4RoutingTable::refreshDisplay ( ) const
overrideprotectedvirtual
135 {
136  char buf[80];
137  if (routerId.isUnspecified())
138  sprintf(buf, "%d+%d routes", (int)routes.size(), (int)multicastRoutes.size());
139  else
140  sprintf(buf, "routerId: %s\n%d+%d routes", routerId.str().c_str(), (int)routes.size(), (int)multicastRoutes.size());
141  getDisplayString().setTagArg("t", 0, buf);
142 }

◆ removeMulticastRoute() [1/2]

virtual IMulticastRoute* inet::Ipv4RoutingTable::removeMulticastRoute ( IMulticastRoute entry)
inlineoverrideprivatevirtual

Removes the given route from the routing table, and returns it.

nullptr is returned of the route was not in the routing table.

Implements inet::IRoutingTable.

382 { return removeMulticastRoute(check_and_cast<Ipv4MulticastRoute *>(entry)); }

Referenced by removeMulticastRoute().

◆ removeMulticastRoute() [2/2]

Ipv4MulticastRoute * inet::Ipv4RoutingTable::removeMulticastRoute ( Ipv4MulticastRoute entry)
overridevirtual

Removes the given route from the routing table, and returns it.

nullptr is returned of the route was not in the routing table.

Implements inet::IIpv4RoutingTable.

656 {
657  Enter_Method("removeMulticastRoute(...)");
658 
659  entry = internalRemoveMulticastRoute(entry);
660 
661  if (entry != nullptr) {
662  ASSERT(entry->getRoutingTable() == this); // still filled in, for the listeners' benefit
663  emit(mrouteDeletedSignal, entry);
664  entry->setRoutingTable(nullptr);
665  }
666  return entry;
667 }

◆ removeRoute() [1/2]

Ipv4Route * inet::Ipv4RoutingTable::removeRoute ( Ipv4Route entry)
overridevirtual

Removes the given route from the routing table, and returns it.

nullptr is returned of the route was not in the routing table.

Implements inet::IIpv4RoutingTable.

553 {
554  Enter_Method("removeRoute(...)");
555 
556  entry = internalRemoveRoute(entry);
557 
558  if (entry != nullptr) {
559  EV_INFO << "remove route " << entry->str() << "\n";
560  ASSERT(entry->getRoutingTable() == this); // still filled in, for the listeners' benefit
561  emit(routeDeletedSignal, entry);
562  entry->setRoutingTable(nullptr);
563  }
564  return entry;
565 }

◆ removeRoute() [2/2]

virtual IRoute* inet::Ipv4RoutingTable::removeRoute ( IRoute entry)
inlineoverrideprivatevirtual

Removes the given route from the routing table, and returns it.

nullptr is returned if the route was not in the routing table.

Implements inet::IRoutingTable.

378 { return removeRoute(check_and_cast<Ipv4Route *>(entry)); }

Referenced by removeRoute().

◆ routeChanged()

void inet::Ipv4RoutingTable::routeChanged ( Ipv4Route entry,
int  fieldCode 
)
overridevirtual

To be called from route objects whenever a field changes.

Used for maintaining internal data structures and firing "routing table changed" notifications.

Implements inet::IIpv4RoutingTable.

682 {
683  if (fieldCode == Ipv4Route::F_DESTINATION || fieldCode == Ipv4Route::F_PREFIX_LENGTH || fieldCode == Ipv4Route::F_METRIC) { // our data structures depend on these fields
684  entry = internalRemoveRoute(entry);
685  ASSERT(entry != nullptr); // failure means inconsistency: route was not found in this routing table
686  internalAddRoute(entry);
687  }
688  emit(routeChangedSignal, entry); // TODO include fieldCode in the notification
689 }

◆ routeLessThan()

bool inet::Ipv4RoutingTable::routeLessThan ( const Ipv4Route a,
const Ipv4Route b 
) const
protected
470 {
471  // longer prefixes are better, because they are more specific
472  if (a->getNetmask() != b->getNetmask())
473  return a->getNetmask() > b->getNetmask();
474 
475  if (a->getDestination() != b->getDestination())
476  return a->getDestination() < b->getDestination();
477 
478  // for the same destination/netmask:
479 
480  // smaller administration distance is better (if useAdminDist)
481  if (useAdminDist && (a->getAdminDist() != b->getAdminDist()))
482  return a->getAdminDist() < b->getAdminDist();
483 
484  // smaller metric is better
485  return a->getMetric() < b->getMetric();
486 }

◆ setRouterId()

void inet::Ipv4RoutingTable::setRouterId ( Ipv4Address  a)
overridevirtual

Sets routerId.

Implements inet::IIpv4RoutingTable.

489 {
490  routerId = a;
491 }

◆ updateNetmaskRoutes()

void inet::Ipv4RoutingTable::updateNetmaskRoutes ( )
protectedvirtual
704 {
705  // first, delete all routes with src=IFACENETMASK
706  for (unsigned int k = 0; k < routes.size(); k++) {
707  if (routes[k]->getSourceType() == IRoute::IFACENETMASK) {
708  auto it = routes.begin() + (k--); // '--' is necessary because indices shift down
709  Ipv4Route *route = *it;
710  routes.erase(it);
711  invalidateCache();
712  ASSERT(route->getRoutingTable() == this); // still filled in, for the listeners' benefit
713  emit(routeDeletedSignal, route);
714  delete route;
715  }
716  }
717 
718  // then re-add them, according to actual interface configuration
719  // TODO say there's a node somewhere in the network that belongs to the interface's subnet
720  // TODO and it is not on the same link, and the gateway does not use proxy ARP, how will packets reach that node?
721  PatternMatcher interfaceNameMatcher(netmaskRoutes, false, true, true);
722  for (int i = 0; i < ift->getNumInterfaces(); i++) {
723  NetworkInterface *ie = ift->getInterface(i);
724  if (ie->isUp() && interfaceNameMatcher.matches(ie->getFullName())) {
725  auto ipv4Data = ie->findProtocolData<Ipv4InterfaceData>();
726  if (ipv4Data && ipv4Data->getNetmask() != Ipv4Address::ALLONES_ADDRESS) {
727  Ipv4Route *route = createNewRoute();
728  route->setSourceType(IRoute::IFACENETMASK);
729  route->setSource(ie);
730  route->setDestination(ipv4Data->getIPAddress().doAnd(ipv4Data->getNetmask()));
731  route->setNetmask(ipv4Data->getNetmask());
732  route->setGateway(Ipv4Address());
733  route->setAdminDist(Ipv4Route::dDirectlyConnected);
734  route->setMetric(ipv4Data->getMetric());
735  route->setInterface(ie);
736  route->setRoutingTable(this);
737  auto pos = upper_bound(routes.begin(), routes.end(), route, RouteLessThan(*this));
738  routes.insert(pos, route);
739  invalidateCache();
740  emit(routeAddedSignal, route);
741  }
742  }
743  }
744 }

Member Data Documentation

◆ forwarding

bool inet::Ipv4RoutingTable::forwarding = false
protected

◆ ift

ModuleRefByPar<IInterfaceTable> inet::Ipv4RoutingTable::ift
protected

◆ isNodeUp

bool inet::Ipv4RoutingTable::isNodeUp = false
protected

◆ localBroadcastAddresses

AddressSet inet::Ipv4RoutingTable::localBroadcastAddresses
mutableprotected

◆ multicastForward

bool inet::Ipv4RoutingTable::multicastForward = false
protected

◆ multicastRoutes

MulticastRouteVector inet::Ipv4RoutingTable::multicastRoutes
private

◆ netmaskRoutes

const char* inet::Ipv4RoutingTable::netmaskRoutes = nullptr
protected

◆ routerId

Ipv4Address inet::Ipv4RoutingTable::routerId
protected

◆ routes

RouteVector inet::Ipv4RoutingTable::routes
private

◆ routingCache

RoutingCache inet::Ipv4RoutingTable::routingCache
mutableprotected

◆ useAdminDist

bool inet::Ipv4RoutingTable::useAdminDist = false
protected

The documentation for this class was generated from the following files:
inet::findContainingNode
cModule * findContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:31
CHK
#define CHK(x)
Definition: INETDefs.h:87
inet::ModuleCrashOperation::Stage
Stage
Definition: ModuleOperations.h:75
inet::Ipv4MulticastRoute::F_MULTICASTGROUP
@ F_MULTICASTGROUP
Definition: Ipv4Route.h:150
inet::NetworkInterface::F_STATE
@ F_STATE
Definition: NetworkInterface.h:146
inet::Ipv4Address::getInt
uint32_t getInt() const
Returns the address as an uint32_t in host byte order (e.g.
Definition: Ipv4Address.h:186
inet::Ipv4RoutingTable::deleteMulticastRoute
virtual bool deleteMulticastRoute(Ipv4MulticastRoute *entry) override
Deletes the given multicast route from the routing table.
Definition: Ipv4RoutingTable.cc:669
inet::IRoute::F_DESTINATION
@ F_DESTINATION
Definition: IRoute.h:47
inet::Ipv4RoutingTable::createNewRoute
virtual Ipv4Route * createNewRoute()
Definition: Ipv4RoutingTable.cc:781
inet::ModuleStopOperation::STAGE_NETWORK_LAYER
@ STAGE_NETWORK_LAYER
Definition: ModuleOperations.h:53
inet::Ipv4RoutingTable::multicastRouteLessThan
static bool multicastRouteLessThan(const Ipv4MulticastRoute *a, const Ipv4MulticastRoute *b)
Definition: Ipv4RoutingTable.cc:582
inet::Ipv4RoutingTable::multicastForward
bool multicastForward
Definition: Ipv4RoutingTable.h:71
inet::Ipv4RoutingTable::getInterfaceForDestAddr
virtual NetworkInterface * getInterfaceForDestAddr(const Ipv4Address &dest) const override
Convenience function based on findBestMatchingRoute().
Definition: Ipv4RoutingTable.cc:417
inet::IRoute::dDirectlyConnected
@ dDirectlyConnected
Definition: IRoute.h:61
inet::getContainingNode
cModule * getContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:40
inet::Ipv4RoutingTable::routes
RouteVector routes
Definition: Ipv4RoutingTable.h:94
inet::ModuleStartOperation::STAGE_NETWORK_LAYER
@ STAGE_NETWORK_LAYER
Definition: ModuleOperations.h:29
inet::routeChangedSignal
simsignal_t routeChangedSignal
Definition: Simsignals.cc:43
inet::units::constants::e
const value< double, units::C > e(1.602176487e-19)
inet::INITSTAGE_NETWORK_LAYER
INET_API InitStage INITSTAGE_NETWORK_LAYER
Initialization of network layer protocols.
inet::printSignalBanner
void printSignalBanner(simsignal_t signalID, const cObject *obj, const cObject *details)
Utility function.
Definition: Simsignals.cc:126
inet::ModuleStartOperation::Stage
Stage
Definition: ModuleOperations.h:25
inet::find
std::vector< T >::iterator find(std::vector< T > &v, const Tk &a)
Definition: stlutils.h:44
inet::Ipv4RoutingTable::deleteRoute
virtual bool deleteRoute(Ipv4Route *entry) override
Removes the given route from the routing table, and delete it.
Definition: Ipv4RoutingTable.cc:567
inet::Ipv4RoutingTable::updateNetmaskRoutes
virtual void updateNetmaskRoutes()
Definition: Ipv4RoutingTable.cc:703
inet::Ipv4RoutingTable::getRoute
virtual Ipv4Route * getRoute(int k) const override
Returns the kth route.
Definition: Ipv4RoutingTable.cc:449
inet::Ipv4RoutingTable::addRoute
virtual void addRoute(Ipv4Route *entry) override
Adds a route to the routing table.
Definition: Ipv4RoutingTable.cc:532
inet::Ipv4Address::ALLONES_ADDRESS
static const Ipv4Address ALLONES_ADDRESS
255.255.255.255
Definition: Ipv4Address.h:94
inet::mrouteDeletedSignal
simsignal_t mrouteDeletedSignal
Definition: Simsignals.cc:45
inet::interfaceDeletedSignal
simsignal_t interfaceDeletedSignal
Definition: Simsignals.cc:31
inet::NetworkInterface::F_CARRIER
@ F_CARRIER
Definition: NetworkInterface.h:146
inet::Ipv4RoutingTable::internalAddRoute
void internalAddRoute(Ipv4Route *entry)
Definition: Ipv4RoutingTable.cc:493
inet::Ipv4RoutingTable::addMulticastRoute
virtual void addMulticastRoute(Ipv4MulticastRoute *entry) override
Adds a multicast route to the routing table.
Definition: Ipv4RoutingTable.cc:637
inet::Ipv4RoutingTable::getMulticastRoute
virtual Ipv4MulticastRoute * getMulticastRoute(int k) const override
Returns the kth multicast route.
Definition: Ipv4RoutingTable.h:313
inet::Ipv4MulticastRoute::F_ORIGINMASK
@ F_ORIGINMASK
Definition: Ipv4Route.h:150
inet::Ipv4RoutingTable::routerId
Ipv4Address routerId
Definition: Ipv4RoutingTable.h:68
inet::contains
bool contains(const std::vector< T > &v, const Tk &a)
Definition: stlutils.h:65
inet::Ipv4Address::maskedAddrAreEqual
static bool maskedAddrAreEqual(const Ipv4Address &addr1, const Ipv4Address &addr2, const Ipv4Address &netmask)
Test if the masked addresses (ie the mask is applied to addr1 and addr2) are equal.
Definition: Ipv4Address.cc:249
inet::Ipv4MulticastRoute::F_ORIGIN
@ F_ORIGIN
Definition: Ipv4Route.h:150
inet::mrouteAddedSignal
simsignal_t mrouteAddedSignal
Definition: Simsignals.cc:44
inet::ModuleStopOperation::Stage
Stage
Definition: ModuleOperations.h:48
inet::Ipv4RoutingTable::internalRemoveMulticastRoute
Ipv4MulticastRoute * internalRemoveMulticastRoute(Ipv4MulticastRoute *entry)
Definition: Ipv4RoutingTable.cc:644
inet::Ipv4RoutingTable::invalidateCache
virtual void invalidateCache()
Definition: Ipv4RoutingTable.cc:235
inet::interfaceStateChangedSignal
simsignal_t interfaceStateChangedSignal
Definition: Simsignals.cc:32
inet::INITSTAGE_LOCAL
INET_API InitStage INITSTAGE_LOCAL
Initialization of local state that don't use or affect other modules includes:
inet::Ipv4RoutingTable::getNumMulticastRoutes
virtual int getNumMulticastRoutes() const override
Returns the total number of multicast routes.
Definition: Ipv4RoutingTable.h:308
inet::Ipv4RoutingTable::getNumRoutes
virtual int getNumRoutes() const override
Returns the total number of routes (unicast, multicast, plus the default route).
Definition: Ipv4RoutingTable.h:273
inet::Ipv4Address::str
std::string str(bool printUnspec=true) const
Returns the string representation of the address (e.g.
Definition: Ipv4Address.cc:98
inet::Ipv4RoutingTable::isNodeUp
bool isNodeUp
Definition: Ipv4RoutingTable.h:72
inet::units::values::b
value< int64_t, units::b > b
Definition: Units.h:1241
inet::routeAddedSignal
simsignal_t routeAddedSignal
Definition: Simsignals.cc:41
inet::utils::stringf
std::string stringf(const char *fmt,...)
Accepts a printf-like argument list, and returns the result in a string.
Definition: INETUtils.cc:110
inet::Ipv4RoutingTable::ift
ModuleRefByPar< IInterfaceTable > ift
Definition: Ipv4RoutingTable.h:66
NUM_INIT_STAGES
#define NUM_INIT_STAGES
Definition: InitStageRegistry.h:73
inet::Ipv4RoutingTable::getDefaultRoute
virtual Ipv4Route * getDefaultRoute() const override
Finds and returns the default route, or nullptr if it doesn't exist.
Definition: Ipv4RoutingTable.cc:456
inet::Ipv4RoutingTable::removeMulticastRoute
virtual Ipv4MulticastRoute * removeMulticastRoute(Ipv4MulticastRoute *entry) override
Removes the given route from the routing table, and returns it.
Definition: Ipv4RoutingTable.cc:655
inet::physicallayer::k
const double k
Definition: Qam1024Modulation.cc:14
inet::ModuleCrashOperation::STAGE_CRASH
@ STAGE_CRASH
Definition: ModuleOperations.h:76
inet::Ipv4RoutingTable::isLocalAddress
virtual bool isLocalAddress(const Ipv4Address &dest) const override
Checks if the address is a local one, i.e.
Definition: Ipv4RoutingTable.cc:304
inet::Ipv4RoutingTable::findBestMatchingMulticastRoute
virtual const Ipv4MulticastRoute * findBestMatchingMulticastRoute(const Ipv4Address &origin, const Ipv4Address &group) const override
Returns route for a multicast source and multicast group.
Definition: Ipv4RoutingTable.cc:433
inet::Ipv4RoutingTable::forwarding
bool forwarding
Definition: Ipv4RoutingTable.h:70
inet::Ipv4RoutingTable::removeRoute
virtual Ipv4Route * removeRoute(Ipv4Route *entry) override
Removes the given route from the routing table, and returns it.
Definition: Ipv4RoutingTable.cc:552
inet::NodeStatus::UP
@ UP
Definition: NodeStatus.h:28
Enter_Method
#define Enter_Method(...)
Definition: SelfDoc.h:71
inet::Ipv4RoutingTable::internalAddMulticastRoute
void internalAddMulticastRoute(Ipv4MulticastRoute *entry)
Definition: Ipv4RoutingTable.cc:600
inet::routeDeletedSignal
simsignal_t routeDeletedSignal
Definition: Simsignals.cc:42
inet::Ipv4RoutingTable::configureRouterId
virtual void configureRouterId()
Definition: Ipv4RoutingTable.cc:105
inet::Ipv4RoutingTable::multicastRoutes
MulticastRouteVector multicastRoutes
Definition: Ipv4RoutingTable.h:97
inet::interfaceIpv4ConfigChangedSignal
simsignal_t interfaceIpv4ConfigChangedSignal
Definition: Simsignals.cc:35
inet::Ipv4RoutingTable::useAdminDist
bool useAdminDist
Definition: Ipv4RoutingTable.h:73
inet::Ipv4RoutingTable::routingCache
RoutingCache routingCache
Definition: Ipv4RoutingTable.h:81
inet::Ipv4RoutingTable::getInterfaceByAddress
virtual NetworkInterface * getInterfaceByAddress(const Ipv4Address &address) const override
Returns an interface given by its address.
Definition: Ipv4RoutingTable.cc:296
inet::Ipv4RoutingTable::internalRemoveRoute
Ipv4Route * internalRemoveRoute(Ipv4Route *entry)
Definition: Ipv4RoutingTable.cc:541
inet::mrouteChangedSignal
simsignal_t mrouteChangedSignal
Definition: Simsignals.cc:46
inet::Ipv4RoutingTable::getGatewayForDestAddr
virtual Ipv4Address getGatewayForDestAddr(const Ipv4Address &dest) const override
Convenience function based on findBestMatchingRoute().
Definition: Ipv4RoutingTable.cc:425
inet::INITSTAGE_ROUTER_ID_ASSIGNMENT
INET_API InitStage INITSTAGE_ROUTER_ID_ASSIGNMENT
Initialization of network addresses.
inet::Ipv4RoutingTable::deleteInterfaceRoutes
virtual void deleteInterfaceRoutes(const NetworkInterface *entry)
Definition: Ipv4RoutingTable.cc:197
inet::IRoute::F_PREFIX_LENGTH
@ F_PREFIX_LENGTH
Definition: IRoute.h:48
inet::Ipv4RoutingTable::netmaskRoutes
const char * netmaskRoutes
Definition: Ipv4RoutingTable.h:69
inet::Ipv4RoutingTable::localBroadcastAddresses
AddressSet localBroadcastAddresses
Definition: Ipv4RoutingTable.h:86
inet::interfaceCreatedSignal
simsignal_t interfaceCreatedSignal
Definition: Simsignals.cc:30
inet::IRoute::F_METRIC
@ F_METRIC
Definition: IRoute.h:54
inet::ModuleStartOperation::STAGE_TRANSPORT_LAYER
@ STAGE_TRANSPORT_LAYER
Definition: ModuleOperations.h:30
inet::interfaceConfigChangedSignal
simsignal_t interfaceConfigChangedSignal
Definition: Simsignals.cc:33
inet::Ipv4Address::isUnspecified
bool isUnspecified() const
True if all four address bytes are zero.
Definition: Ipv4Address.h:165
inet::Ipv4MulticastRoute::F_METRIC
@ F_METRIC
Definition: Ipv4Route.h:150
inet::Ipv4RoutingTable::getRouterId
virtual Ipv4Address getRouterId() const override
Returns routerId.
Definition: Ipv4RoutingTable.h:198
inet::IRoute::IFACENETMASK
@ IFACENETMASK
comes from an interface's netmask
Definition: IRoute.h:30
inet::Ipv4RoutingTable::isLocalMulticastAddress
virtual bool isLocalMulticastAddress(const Ipv4Address &dest) const override
Checks if the address is in one of the local multicast group address list.
Definition: Ipv4RoutingTable.cc:348
inet::Ipv4RoutingTable::findBestMatchingRoute
virtual Ipv4Route * findBestMatchingRoute(const Ipv4Address &dest) const override
The routing function.
Definition: Ipv4RoutingTable.cc:391