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

Represents the Ipv6 routing table and neighbour discovery data structures. More...

#include <Ipv6RoutingTable.h>

Inheritance diagram for inet::Ipv6RoutingTable:
inet::IRoutingTable inet::ILifecycle

Classes

struct  DestCacheEntry
 
class  RouteLessThan
 

Public Member Functions

virtual void addRoute (Ipv6Route *route)
 
 Ipv6RoutingTable ()
 
virtual ~Ipv6RoutingTable ()
 
Interfaces
virtual NetworkInterfacegetInterfaceByAddress (const Ipv6Address &address) const
 Returns an interface given by its address. More...
 
virtual bool isRouter () const
 IP forwarding on/off. More...
 
virtual bool isMulticastForwardingEnabled ()
 
virtual void routeChanged (Ipv6Route *entry, int fieldCode)
 To be called from route objects whenever a field changes. More...
 
Routing functions
virtual bool isLocalAddress (const Ipv6Address &dest) const
 Checks if the address is one of the host's addresses, i.e. More...
 
const Ipv6AddresslookupDestCache (const Ipv6Address &dest, int &outInterfaceId)
 Looks up the given destination address in the Destination Cache, then returns the next-hop address and the interface in the outInterfaceId variable. More...
 
const Ipv6RoutedoLongestPrefixMatch (const Ipv6Address &dest)
 Performs longest prefix match in the routing table and returns the resulting route, or nullptr if there was no match. More...
 
virtual bool isPrefixPresent (const Ipv6Address &prefix) const
 Checks if the given prefix already exists in the routing table (prefix list) More...
 
Managing the destination cache
virtual void updateDestCache (const Ipv6Address &dest, const Ipv6Address &nextHopAddr, int interfaceId, simtime_t expiryTime)
 Add or update a destination cache entry. More...
 
virtual void purgeDestCache ()
 Discard all entries in destination cache. More...
 
virtual void purgeDestCacheEntriesToNeighbour (const Ipv6Address &nextHopAddr, int interfaceId)
 Discard all entries in destination cache where next hop is the given address on the given interface. More...
 
void purgeDestCacheForInterfaceId (int interfaceId)
 Removes all destination cache entries for the specified interface. More...
 
Managing prefixes and the route table
virtual void addOrUpdateOnLinkPrefix (const Ipv6Address &destPrefix, int prefixLength, int interfaceId, simtime_t expiryTime)
 Add on-link prefix (route of type FROM_RA), or update existing one. More...
 
virtual void deleteOnLinkPrefix (const Ipv6Address &destPrefix, int prefixLength)
 Remove an on-link prefix. More...
 
virtual void addOrUpdateOwnAdvPrefix (const Ipv6Address &destPrefix, int prefixLength, int interfaceId, simtime_t expiryTime)
 Add route of type OWN_ADV_PREFIX. More...
 
virtual void addStaticRoute (const Ipv6Address &destPrefix, int prefixLength, unsigned int interfaceId, const Ipv6Address &nextHop, int metric=0)
 Creates a static route. More...
 
virtual void addDefaultRoute (const Ipv6Address &raSrcAddr, unsigned int ifID, simtime_t routerLifetime)
 Adds a default route for a host. More...
 
virtual void addRoutingProtocolRoute (Ipv6Route *route)
 Adds the given getRoute(which can be OSPF, BGP, RIP or any other route) with src==ROUTING_PROT. More...
 
virtual Ipv6RouteremoveRoute (Ipv6Route *route)
 Removes the given route from the routing table, and returns it. More...
 
virtual bool deleteRoute (Ipv6Route *route)
 Deletes the given route from the route table. More...
 
virtual void deleteInterfaceRoutes (const NetworkInterface *entry)
 Deletes the routes that are using the specified interface. More...
 
virtual int getNumRoutes () const override
 Return the number of routes. More...
 
virtual Ipv6RoutegetRoute (int i) const override
 Return the ith route. More...
 
virtual bool handleOperationStage (LifecycleOperation *operation, IDoneCallback *doneCallback) override
 ILifecycle method. More...
 
virtual bool isAdminDistEnabled () const override
 Administrative distance on/off. More...
 
virtual bool isForwardingEnabled () const override
 Forwarding on/off. More...
 
virtual bool isMulticastForwardingEnabled () const override
 Multicast forwarding on/off. 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 bool isLocalBroadcastAddress (const L3Address &dest) const
 
virtual NetworkInterfacegetInterfaceByAddress (const L3Address &address) const override
 Returns an interface given by its address. More...
 
virtual NetworkInterfacefindInterfaceByLocalBroadcastAddress (const L3Address &dest) const
 
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 IRoutegetDefaultRoute () const override
 Finds and returns the default route, or nullptr if it doesn't exist. More...
 
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 IMulticastRoutegetMulticastRoute (int i) const override
 Returns the kth multicast route. More...
 
virtual int getNumMulticastRoutes () const override
 Returns the total number of multicast routes. 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...
 
virtual IRoutecreateRoute () override
 
virtual void printRoutingTable () const override
 Prints 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 std::map< Ipv6Address, DestCacheEntryDestCache
 
typedef std::vector< Ipv6Route * > RouteList
 

Protected Member Functions

virtual Ipv6RoutecreateNewRoute (Ipv6Address destPrefix, int prefixLength, IRoute::SourceType src)
 
bool routeLessThan (const Ipv6Route *a, const Ipv6Route *b) const
 
virtual void configureInterfaceForIpv6 (NetworkInterface *ie)
 
virtual void assignRequiredNodeAddresses (NetworkInterface *ie)
 RFC 3513: Section 2.8 A Node's Required Address Assign the various addresses to the node's respective interface. More...
 
virtual void configureInterfaceFromXml (NetworkInterface *ie, cXMLElement *cfg)
 
virtual void configureTunnelFromXml (cXMLElement *cfg)
 
void internalAddRoute (Ipv6Route *route)
 
Ipv6RouteinternalRemoveRoute (Ipv6Route *route)
 
RouteList::iterator internalDeleteRoute (RouteList::iterator it)
 
virtual void refreshDisplay () const override
 
virtual int numInitStages () const override
 
virtual void initialize (int stage) override
 
virtual void parseXmlConfigFile ()
 
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...
 

Protected Attributes

ModuleRefByPar< IInterfaceTableift
 
bool isrouter = false
 
bool multicastForward = false
 
bool useAdminDist = false
 
DestCache destCache
 
RouteList routeList
 

Friends

std::ostream & operator<< (std::ostream &os, const DestCacheEntry &e)
 

Detailed Description

Represents the Ipv6 routing table and neighbour discovery data structures.

This object has one instance per host or router.

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.

The route table is read from a file. The route table can also be read and modified during simulation, typically by routing protocol implementations.

Member Typedef Documentation

◆ DestCache

◆ RouteList

typedef std::vector<Ipv6Route *> inet::Ipv6RoutingTable::RouteList
protected

Constructor & Destructor Documentation

◆ Ipv6RoutingTable()

inet::Ipv6RoutingTable::Ipv6RoutingTable ( )
37 {
38 }

◆ ~Ipv6RoutingTable()

inet::Ipv6RoutingTable::~Ipv6RoutingTable ( )
virtual
41 {
42  for (auto& elem : routeList)
43  delete elem;
44 }

Member Function Documentation

◆ addDefaultRoute()

void inet::Ipv6RoutingTable::addDefaultRoute ( const Ipv6Address raSrcAddr,
unsigned int  ifID,
simtime_t  routerLifetime 
)
virtual

Adds a default route for a host.

This method requires the RA's source address and the router expiry time plus the simTime().

628 {
629  // create route object
630  Ipv6Route *route = createNewRoute(Ipv6Address(), 0, IRoute::ROUTER_ADVERTISEMENT);
631  route->setInterface(ift->getInterfaceById(ifID));
632  route->setNextHop(nextHop);
633  route->setMetric(10); // FIXMEshould be filled from interface metric
634  route->setAdminDist(Ipv6Route::dStatic);
635 
636 #ifdef INET_WITH_xMIPv6
637  route->setExpiryTime(routerLifetime); // lifetime useful after transitioning to new AR // 27.07.08 - CB
638 #endif /* INET_WITH_xMIPv6 */
639 
640  // then add it
641  addRoute(route);
642 }

◆ addMulticastRoute()

virtual void inet::Ipv6RoutingTable::addMulticastRoute ( IMulticastRoute entry)
inlineoverridevirtual

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.

395 { /*TODO addMulticastRoute(entry);*/ }

◆ addOrUpdateOnLinkPrefix()

void inet::Ipv6RoutingTable::addOrUpdateOnLinkPrefix ( const Ipv6Address destPrefix,
int  prefixLength,
int  interfaceId,
simtime_t  expiryTime 
)
virtual

Add on-link prefix (route of type FROM_RA), or update existing one.

To be called from code processing on-link prefixes in Router Advertisements. Expiry time can be derived from the Valid Lifetime field in the Router Advertisements.

NOTE: This method does NOT update the lifetime of matching addresses in the IInterfaceTable (see Ipv6InterfaceData); that has to be done separately.

534 {
535  // see if prefix exists in table
536  Ipv6Route *route = nullptr;
537  for (auto& elem : routeList) {
538  if ((elem)->getSourceType() == IRoute::ROUTER_ADVERTISEMENT && (elem)->getDestPrefix() == destPrefix && (elem)->getPrefixLength() == prefixLength) {
539  route = elem;
540  break;
541  }
542  }
543 
544  if (route == nullptr) {
545  // create new route object
546  Ipv6Route *route = createNewRoute(destPrefix, prefixLength, IRoute::ROUTER_ADVERTISEMENT);
547  route->setInterface(ift->getInterfaceById(interfaceId));
548  route->setExpiryTime(expiryTime);
549  route->setMetric(0);
550  route->setAdminDist(Ipv6Route::dDirectlyConnected);
551 
552  // then add it
553  addRoute(route);
554  }
555  else {
556  // update existing one; notification-wise, we pretend the route got removed then re-added
557  emit(routeDeletedSignal, route);
558  route->setInterface(ift->getInterfaceById(interfaceId));
559  route->setExpiryTime(expiryTime);
560  emit(routeAddedSignal, route);
561  }
562 }

◆ addOrUpdateOwnAdvPrefix()

void inet::Ipv6RoutingTable::addOrUpdateOwnAdvPrefix ( const Ipv6Address destPrefix,
int  prefixLength,
int  interfaceId,
simtime_t  expiryTime 
)
virtual

Add route of type OWN_ADV_PREFIX.

This is a prefix that this router advertises on this interface.

566 {
567  // FIXME this is very similar to the one above -- refactor!!
568 
569  // see if prefix exists in table
570  Ipv6Route *route = nullptr;
571  for (auto& elem : routeList) {
572  if ((elem)->getSourceType() == IRoute::OWN_ADV_PREFIX && (elem)->getDestPrefix() == destPrefix && (elem)->getPrefixLength() == prefixLength) {
573  route = elem;
574  break;
575  }
576  }
577 
578  if (route == nullptr) {
579  // create new route object
580  Ipv6Route *route = createNewRoute(destPrefix, prefixLength, IRoute::OWN_ADV_PREFIX);
581  route->setInterface(ift->getInterfaceById(interfaceId));
582  route->setExpiryTime(expiryTime);
583  route->setMetric(0);
584  route->setAdminDist(Ipv6Route::dDirectlyConnected);
585 
586  // then add it
587  addRoute(route);
588  }
589  else {
590  // update existing one; notification-wise, we pretend the route got removed then re-added
591  emit(routeDeletedSignal, route);
592  route->setInterface(ift->getInterfaceById(interfaceId));
593  route->setExpiryTime(expiryTime);
594  emit(routeAddedSignal, route);
595  }
596 }

Referenced by inet::Ipv6FlatNetworkConfigurator::addOwnAdvPrefixRoutes(), and initialize().

◆ addRoute() [1/2]

void inet::Ipv6RoutingTable::addRoute ( Ipv6Route route)
virtual
667 {
668  internalAddRoute(route);
669 
670  /*TODO this deletes some cache entries we want to keep, but the node MUST update
671  the Destination Cache in such a way that the latest route information are used.*/
672  purgeDestCache();
673 
674  emit(routeAddedSignal, route);
675 }

Referenced by addDefaultRoute(), addOrUpdateOnLinkPrefix(), addOrUpdateOwnAdvPrefix(), addRoutingProtocolRoute(), and addStaticRoute().

◆ addRoute() [2/2]

virtual void inet::Ipv6RoutingTable::addRoute ( IRoute entry)
inlineoverridevirtual

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.

390 { addRoutingProtocolRoute(check_and_cast<Ipv6Route *>(entry)); } // TODO contrast that with addStaticRoute()!

◆ addRoutingProtocolRoute()

void inet::Ipv6RoutingTable::addRoutingProtocolRoute ( Ipv6Route route)
virtual

Adds the given getRoute(which can be OSPF, BGP, RIP or any other route) with src==ROUTING_PROT.

To store additional information with the route, one can subclass from Ipv6Route and add more fields.

645 {
646  // TODO ASSERT(route->getSrc()==Ipv6Route::ROUTING_PROT);
647  addRoute(route);
648 }

◆ addStaticRoute()

void inet::Ipv6RoutingTable::addStaticRoute ( const Ipv6Address destPrefix,
int  prefixLength,
unsigned int  interfaceId,
const Ipv6Address nextHop,
int  metric = 0 
)
virtual

Creates a static route.

If metric is omitted, it gets initialized to the interface's metric value.

612 {
613  // create route object
614  Ipv6Route *route = createNewRoute(destPrefix, prefixLength, IRoute::MANUAL);
615  route->setInterface(ift->getInterfaceById(interfaceId));
616  route->setNextHop(nextHop);
617  if (metric == 0)
618  metric = 10; // TODO should be filled from interface metric
619  route->setMetric(metric);
620  route->setAdminDist(Ipv6Route::dStatic);
621 
622  // then add it
623  addRoute(route);
624 }

Referenced by inet::Ipv6FlatNetworkConfigurator::addStaticRoutes(), and configureInterfaceForIpv6().

◆ assignRequiredNodeAddresses()

void inet::Ipv6RoutingTable::assignRequiredNodeAddresses ( NetworkInterface ie)
protectedvirtual

RFC 3513: Section 2.8 A Node's Required Address Assign the various addresses to the node's respective interface.

This should be done when the Ipv6 Protocol stack is created.

244 {
245  // RFC 3513 Section 2.8:A Node's Required Addresses
246  /*A host is required to recognize the following addresses as
247  identifying itself:*/
248 
249  // o The loopback address.
250  if (ie->isLoopback()) {
251  ie->getProtocolDataForUpdate<Ipv6InterfaceData>()->assignAddress(Ipv6Address("::1"), false, SIMTIME_ZERO, SIMTIME_ZERO);
252  return;
253  }
254  // o Its required Link-Local Address for each interface.
255 
256 #ifndef INET_WITH_xMIPv6
257 // Ipv6Address linkLocalAddr = Ipv6Address().formLinkLocalAddress(ie->getInterfaceToken());
258 // ie->getProtocolData<Ipv6InterfaceData>()->assignAddress(linkLocalAddr, true, 0, 0);
259 #else /* INET_WITH_xMIPv6 */
260  Ipv6Address linkLocalAddr = Ipv6Address().formLinkLocalAddress(ie->getInterfaceToken());
261  ie->getProtocolDataForUpdate<Ipv6InterfaceData>()->assignAddress(linkLocalAddr, true, SIMTIME_ZERO, SIMTIME_ZERO);
262 #endif /* INET_WITH_xMIPv6 */
263 
264  /*o Any additional Unicast and Anycast Addresses that have been configured
265  for the node's interfaces (manually or automatically).*/
266 
267  // FIXME FIXME Andras: commented out the following lines, because these addresses
268  // are implicitly checked for in isLocalAddress() (we don't want redundancy,
269  // and manually adding solicited-node mcast address for each and every address
270  // is very error-prone!)
271  //
272  // o The All-Nodes Multicast Addresses defined in section 2.7.1.
273 
274  /*o The Solicited-Node Multicast Address for each of its unicast and anycast
275  addresses.*/
276 
277  // o Multicast Addresses of all other groups to which the node belongs.
278 
279  /*A router is required to recognize all addresses that a host is
280  required to recognize, plus the following addresses as identifying
281  itself:*/
282  /*o The Subnet-Router Anycast Addresses for all interfaces for
283  which it is configured to act as a router.*/
284 
285  // o All other Anycast Addresses with which the router has been configured.
286  // o The All-Routers Multicast Addresses defined in section 2.7.1.
287 }

Referenced by configureInterfaceForIpv6().

◆ configureInterfaceForIpv6()

void inet::Ipv6RoutingTable::configureInterfaceForIpv6 ( NetworkInterface ie)
protectedvirtual
216 {
217  auto ipv6IfData = ie->addProtocolData<Ipv6InterfaceData>();
218 
219  // for routers, turn on advertisements by default
220  // FIXME we will use this isRouter flag for now. what if future implementations
221  // have 2 interfaces where one interface is configured as a router and the other
222  // as a host?
223  ipv6IfData->setAdvSendAdvertisements(isrouter); // Added by WEI
224 
225  // metric: some hints: OSPF cost (2e9/bps value), MS KB article Q299540, ...
226  //d->setMetric((int)ceil(2e9/ie->getDatarate())); // use OSPF cost as default
227  // FIXME TODO fill in the rest
228 
230 
231  // add link-local prefix to each interface according to RFC 4861 5.1
232  if (!ie->isLoopback())
234 
235  if (ie->isMulticast()) {
236  // TODO join other ALL_NODES_x and ALL_ROUTERS_x addresses too?
237  ipv6IfData->joinMulticastGroup(Ipv6Address::ALL_NODES_2);
238  if (isrouter)
239  ipv6IfData->joinMulticastGroup(Ipv6Address::ALL_ROUTERS_2);
240  }
241 }

Referenced by initialize().

◆ configureInterfaceFromXml()

void inet::Ipv6RoutingTable::configureInterfaceFromXml ( NetworkInterface ie,
cXMLElement *  cfg 
)
protectedvirtual
307 {
308  /*XML parsing capabilities tweaked by WEI. For now, we can configure a specific
309  node's interface. We can set advertising prefixes and other variables to be used
310  in RAs. The Ipv6 interface data gets overwritten if lines 249 to 262 is uncommented.
311  The fix is to create an XML file with all the default values. Customised XML files
312  can be used for future protocols that requires different values. (MIPv6)*/
313  auto d = ie->getProtocolDataForUpdate<Ipv6InterfaceData>();
314 
315  // parse basic config (attributes)
316  d->setAdvSendAdvertisements(toBool(getRequiredAttr(cfg, "AdvSendAdvertisements")));
317  // TODO leave this off first!! They overwrite stuff!
318 
319  /* TODO Wei commented out the stuff below. To be checked why (Andras).
320  d->setMaxRtrAdvInterval(utils::atod(getRequiredAttr(cfg, "MaxRtrAdvInterval")));
321  d->setMinRtrAdvInterval(utils::atod(getRequiredAttr(cfg, "MinRtrAdvInterval")));
322  d->setAdvManagedFlag(toBool(getRequiredAttr(cfg, "AdvManagedFlag")));
323  d->setAdvOtherConfigFlag(toBool(getRequiredAttr(cfg, "AdvOtherConfigFlag")));
324  d->setAdvLinkMTU(utils::atoul(getRequiredAttr(cfg, "AdvLinkMTU")));
325  d->setAdvReachableTime(utils::atoul(getRequiredAttr(cfg, "AdvReachableTime")));
326  d->setAdvRetransTimer(utils::atoul(getRequiredAttr(cfg, "AdvRetransTimer")));
327  d->setAdvCurHopLimit(utils::atoul(getRequiredAttr(cfg, "AdvCurHopLimit")));
328  d->setAdvDefaultLifetime(utils::atoul(getRequiredAttr(cfg, "AdvDefaultLifetime")));
329  ie->setMtu(utils::atoul(getRequiredAttr(cfg, "HostLinkMTU")));
330  d->setCurHopLimit(utils::atoul(getRequiredAttr(cfg, "HostCurHopLimit")));
331  d->setBaseReachableTime(utils::atoul(getRequiredAttr(cfg, "HostBaseReachableTime")));
332  d->setRetransTimer(utils::atoul(getRequiredAttr(cfg, "HostRetransTimer")));
333  d->setDupAddrDetectTransmits(utils::atoul(getRequiredAttr(cfg, "HostDupAddrDetectTransmits")));
334  */
335 
336  // parse prefixes (AdvPrefix elements; they should be inside an AdvPrefixList
337  // element, but we don't check that)
338  cXMLElementList prefixList = cfg->getElementsByTagName("AdvPrefix");
339  for (auto& elem : prefixList) {
340  cXMLElement *node = elem;
341  Ipv6InterfaceData::AdvPrefix prefix;
342 
343  // FIXME todo implement: advValidLifetime, advPreferredLifetime can
344  // store (absolute) expiry time (if >0) or lifetime (delta) (if <0);
345  // 0 should be treated as infinity
346  int pfxLen;
347  if (!prefix.prefix.tryParseAddrWithPrefix(node->getNodeValue(), pfxLen))
348  throw cRuntimeError("Element <%s> at %s: wrong Ipv6Address/prefix syntax %s",
349  node->getTagName(), node->getSourceLocation(), node->getNodeValue());
350 
351  prefix.prefixLength = pfxLen;
352  prefix.advValidLifetime = utils::atoul(getRequiredAttr(node, "AdvValidLifetime"));
353  prefix.advOnLinkFlag = toBool(getRequiredAttr(node, "AdvOnLinkFlag"));
354  prefix.advPreferredLifetime = utils::atoul(getRequiredAttr(node, "AdvPreferredLifetime"));
355  prefix.advAutonomousFlag = toBool(getRequiredAttr(node, "AdvAutonomousFlag"));
356  d->addAdvPrefix(prefix);
357  }
358 
359  // parse addresses
360  cXMLElementList addrList = cfg->getChildrenByTagName("inetAddr");
361  for (auto& elem : addrList) {
362  cXMLElement *node = elem;
363  Ipv6Address address = Ipv6Address(node->getNodeValue());
364  // We can now decide if the address is tentative or not.
365  d->assignAddress(address, toBool(getRequiredAttr(node, "tentative")), SIMTIME_ZERO, SIMTIME_ZERO); // set up with infinite lifetimes
366  }
367 }

Referenced by parseXmlConfigFile().

◆ configureTunnelFromXml()

void inet::Ipv6RoutingTable::configureTunnelFromXml ( cXMLElement *  cfg)
protectedvirtual
370 {
371  Ipv6Tunneling *tunneling = getModuleFromPar<Ipv6Tunneling>(par("ipv6TunnelingModule"), this);
372 
373  // parse basic config (attributes)
374  cXMLElementList tunnelList = cfg->getElementsByTagName("tunnelEntry");
375  for (auto& elem : tunnelList) {
376  cXMLElement *node = elem;
377 
378  Ipv6Address entry, exit, trigger;
379  entry.set(getRequiredAttr(node, "entryPoint"));
380  exit.set(getRequiredAttr(node, "exitPoint"));
381 
382  cXMLElementList triggerList = node->getElementsByTagName("triggers");
383 
384  if (triggerList.size() != 1)
385  throw cRuntimeError("element <%s> at %s: Only exactly one trigger allowed",
386  node->getTagName(), node->getSourceLocation());
387 
388  cXMLElement *triggerNode = triggerList[0];
389  trigger.set(getRequiredAttr(triggerNode, "destination"));
390 
391  EV_INFO << "New tunnel: " << "entry=" << entry << ",exit=" << exit << ",trigger=" << trigger << endl;
392  tunneling->createTunnel(Ipv6Tunneling::NORMAL, entry, exit, trigger);
393  }
394 }

Referenced by parseXmlConfigFile().

◆ createNewRoute()

Ipv6Route * inet::Ipv6RoutingTable::createNewRoute ( Ipv6Address  destPrefix,
int  prefixLength,
IRoute::SourceType  src 
)
protectedvirtual
47 {
48  return new Ipv6Route(destPrefix, prefixLength, src);
49 }

Referenced by addDefaultRoute(), addOrUpdateOnLinkPrefix(), addOrUpdateOwnAdvPrefix(), and addStaticRoute().

◆ createRoute()

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

Implements inet::IRoutingTable.

398 { return new Ipv6Route(Ipv6Address(), 0, IRoute::MANUAL); }

◆ deleteInterfaceRoutes()

void inet::Ipv6RoutingTable::deleteInterfaceRoutes ( const NetworkInterface entry)
virtual

Deletes the routes that are using the specified interface.

835 {
836  bool changed = false;
837 
838  // delete unicast routes using this interface
839  for (auto it = routeList.begin(); it != routeList.end();) {
840  Ipv6Route *route = *it;
841  if (route->getInterface() == entry) {
842  it = internalDeleteRoute(it);
843  changed = true;
844  }
845  else
846  ++it;
847  }
848 
849  // TODO delete or update multicast routes:
850  // 1. delete routes has entry as parent
851  // 2. remove entry from children list
852 
853  if (changed) {
854 // invalidateCache();
855  }
856 }

Referenced by receiveSignal().

◆ deleteMulticastRoute()

virtual bool inet::Ipv6RoutingTable::deleteMulticastRoute ( IMulticastRoute entry)
inlineoverridevirtual

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.

397 { return false; /*TODO deleteMulticastRoute(entry);*/ }

◆ deleteOnLinkPrefix()

void inet::Ipv6RoutingTable::deleteOnLinkPrefix ( const Ipv6Address destPrefix,
int  prefixLength 
)
virtual

Remove an on-link prefix.

To be called when the prefix gets advertised with zero lifetime, or to purge an expired prefix.

NOTE: This method does NOT remove the matching addresses from the IInterfaceTable (see Ipv6InterfaceData); that has to be done separately.

599 {
600  // scan the routing table for this prefix and remove it
601  for (auto it = routeList.begin(); it != routeList.end(); it++) {
602  if ((*it)->getSourceType() == IRoute::ROUTER_ADVERTISEMENT && (*it)->getDestPrefix() == destPrefix && (*it)->getPrefixLength() == prefixLength) {
604  return; // there can be only one such route, addOrUpdateOnLinkPrefix() guarantees that
605  }
606  }
607 }

◆ deleteRoute() [1/2]

bool inet::Ipv6RoutingTable::deleteRoute ( Ipv6Route route)
virtual

Deletes the given route from the route table.

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

724 {
725  auto it = find(routeList, route);
726  if (it == routeList.end())
727  return false;
728 
730  return true;
731 }

◆ deleteRoute() [2/2]

virtual bool inet::Ipv6RoutingTable::deleteRoute ( IRoute entry)
inlineoverridevirtual

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.

392 { return deleteRoute(check_and_cast<Ipv6Route *>(entry)); }

Referenced by deleteRoute().

◆ doLongestPrefixMatch()

const Ipv6Route * inet::Ipv6RoutingTable::doLongestPrefixMatch ( const Ipv6Address dest)

Performs longest prefix match in the routing table and returns the resulting route, or nullptr if there was no match.

459 {
460  Enter_Method("doLongestPrefixMatch(%s)", dest.str().c_str());
461 
462  // we'll just stop at the first match, because the table is sorted
463  // by prefix lengths and metric (see addRoute())
464 
465  auto it = routeList.begin();
466  while (it != routeList.end()) {
467  if (dest.matches((*it)->getDestPrefix(), (*it)->getPrefixLength())) {
468  if (simTime() > (*it)->getExpiryTime() && (*it)->getExpiryTime() != 0) { // since 0 represents infinity.
469  if ((*it)->getSourceType() == IRoute::ROUTER_ADVERTISEMENT) {
470  EV_INFO << "Expired prefix detected!!" << endl;
471  it = internalDeleteRoute(it); // TODO update display string
472  }
473  }
474  else
475  return *it;
476  }
477  else
478  ++it;
479  }
480  // FIXME todo: if we selected an expired route, throw it out and select again!
481  return nullptr;
482 }

◆ findBestMatchingMulticastRoute()

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

Returns route for a multicast origin and group.

Implements inet::IRoutingTable.

388 { return nullptr; /*TODO findBestMatchingMulticastRoute(origin.toIPv6(), group.toIPv6());*/ }

◆ findBestMatchingRoute()

virtual IRoute* inet::Ipv6RoutingTable::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.

384 { return const_cast<Ipv6Route *>((const_cast<Ipv6RoutingTable *>(this))->doLongestPrefixMatch(dest.toIpv6())); } // FIXME what a name??!! also: remove const; ALSO: THIS DOES NOT UPDATE DESTCACHE LIKE METHODS BUILT ON IT!

◆ findInterfaceByLocalBroadcastAddress()

virtual NetworkInterface* inet::Ipv6RoutingTable::findInterfaceByLocalBroadcastAddress ( const L3Address dest) const
inlinevirtual
383 { return nullptr; /*TODO findInterfaceByLocalBroadcastAddress(dest.toIPv6());*/ }

◆ getDefaultRoute()

virtual IRoute* inet::Ipv6RoutingTable::getDefaultRoute ( ) const
inlineoverridevirtual

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

Implements inet::IRoutingTable.

389 { return nullptr; /*TODO getDefaultRoute();*/ }

◆ getInterfaceByAddress() [1/2]

NetworkInterface * inet::Ipv6RoutingTable::getInterfaceByAddress ( const Ipv6Address address) const
virtual

Returns an interface given by its address.

Returns nullptr if not found.

397 {
398  Enter_Method("getInterfaceByAddress(%s)=?", addr.str().c_str());
399 
400  return ift->findInterfaceByAddress(addr);
401 }

Referenced by getInterfaceByAddress().

◆ getInterfaceByAddress() [2/2]

NetworkInterface * inet::Ipv6RoutingTable::getInterfaceByAddress ( const L3Address address) const
overridevirtual

Returns an interface given by its address.

Returns nullptr if not found.

Implements inet::IRoutingTable.

404 {
405  return getInterfaceByAddress(address.toIpv6());
406 }

◆ getMulticastRoute()

virtual IMulticastRoute* inet::Ipv6RoutingTable::getMulticastRoute ( int  k) const
inlineoverridevirtual

Returns the kth multicast route.

Implements inet::IRoutingTable.

393 { return nullptr; /*TODO*/ }

◆ getNextHopForDestination()

virtual L3Address inet::Ipv6RoutingTable::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.

386 { const Ipv6Route *e = (const_cast<Ipv6RoutingTable *>(this))->doLongestPrefixMatch(dest.toIpv6()); return e ? e->getNextHopAsGeneric() : L3Address(); }

◆ getNumMulticastRoutes()

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

Returns the total number of multicast routes.

Implements inet::IRoutingTable.

394 { return 0; /*TODO getNumMulticastRoutes();*/ }

◆ getNumRoutes()

int inet::Ipv6RoutingTable::getNumRoutes ( ) const
overridevirtual

Return the number of routes.

Implements inet::IRoutingTable.

734 {
735  return routeList.size();
736 }

Referenced by inet::ospfv3::Ospfv3Process::isInRoutingTable6(), and refreshDisplay().

◆ getOutputInterfaceForDestination()

virtual NetworkInterface* inet::Ipv6RoutingTable::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.

385 { const Ipv6Route *e = (const_cast<Ipv6RoutingTable *>(this))->doLongestPrefixMatch(dest.toIpv6()); return e ? e->getInterface() : nullptr; }

◆ getRoute()

Ipv6Route * inet::Ipv6RoutingTable::getRoute ( int  i) const
overridevirtual

Return the ith route.

Implements inet::IRoutingTable.

739 {
740  ASSERT(i >= 0 && i < (int)routeList.size());
741  return routeList[i];
742 }

Referenced by inet::ospfv3::Ospfv3Process::isInRoutingTable6().

◆ getRouterIdAsGeneric()

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

Returns routerId.

Implements inet::IRoutingTable.

379 { return L3Address(Ipv6Address()); /*TODO getRouterId();*/ }

◆ handleMessage()

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

Raises an error.

162 {
163  throw cRuntimeError("This module doesn't process messages");
164 }

◆ handleOperationStage()

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

ILifecycle method.

Implements inet::ILifecycle.

859 {
860  Enter_Method("handleOperationStage");
861  int stage = operation->getCurrentStage();
862  if (dynamic_cast<ModuleStartOperation *>(operation)) {
864  ; // TODO
865  }
866  else if (dynamic_cast<ModuleStopOperation *>(operation)) {
868  while (!routeList.empty())
869  delete removeRoute(routeList[0]);
870 
871  }
872  else if (dynamic_cast<ModuleCrashOperation *>(operation)) {
874  while (!routeList.empty())
875  delete removeRoute(routeList[0]);
876 
877  }
878  return true;
879 }

◆ initialize()

void inet::Ipv6RoutingTable::initialize ( int  stage)
overrideprotectedvirtual
52 {
53  cSimpleModule::initialize(stage);
54 
55  if (stage == INITSTAGE_LOCAL) {
56  WATCH_PTRVECTOR(routeList);
57  WATCH_MAP(destCache); // FIXME commented out for now
58  isrouter = par("isRouter");
59  multicastForward = par("multicastForwarding");
60  useAdminDist = par("useAdminDist");
61  WATCH(isrouter);
62 
63  ift.reference(this, "interfaceTableModule", true);
64 
65 #ifdef INET_WITH_xMIPv6
66  // the following MIPv6 related flags will be overridden by the MIPv6 module (if existing)
67  ishome_agent = false;
68  WATCH(ishome_agent);
69 
70  ismobile_node = false;
71  WATCH(ismobile_node);
72 
73  mipv6Support = false; // 4.9.07 - CB
74 #endif /* INET_WITH_xMIPv6 */
75 
76  cModule *host = getContainingNode(this);
77 
78  host->subscribe(interfaceCreatedSignal, this);
79  host->subscribe(interfaceDeletedSignal, this);
80  host->subscribe(interfaceStateChangedSignal, this);
81  host->subscribe(interfaceConfigChangedSignal, this);
82  host->subscribe(interfaceIpv6ConfigChangedSignal, this);
83  }
84  // TODO INITSTAGE
85  else if (stage == INITSTAGE_LINK_LAYER) {
86  // add Ipv6InterfaceData to interfaces
87  for (int i = 0; i < ift->getNumInterfaces(); i++) {
88  NetworkInterface *ie = ift->getInterface(i);
90  }
91  }
92  // TODO INITSTAGE
93  else if (stage == INITSTAGE_NETWORK_CONFIGURATION) {
95 
96  // skip hosts
97  if (isrouter) {
98  // add globally routable prefixes to routing table
99  for (int x = 0; x < ift->getNumInterfaces(); x++) {
100  NetworkInterface *ie = ift->getInterface(x);
101 
102  if (ie->isLoopback())
103  continue;
104 
105  for (int y = 0; y < ie->getProtocolData<Ipv6InterfaceData>()->getNumAdvPrefixes(); y++)
106  if (ie->getProtocolData<Ipv6InterfaceData>()->getAdvPrefix(y).prefix.isGlobal())
107  addOrUpdateOwnAdvPrefix(ie->getProtocolData<Ipv6InterfaceData>()->getAdvPrefix(y).prefix,
108  ie->getProtocolData<Ipv6InterfaceData>()->getAdvPrefix(y).prefixLength,
109  ie->getInterfaceId(), SIMTIME_ZERO);
110 
111  }
112  }
113  }
114 }

◆ internalAddRoute()

void inet::Ipv6RoutingTable::internalAddRoute ( Ipv6Route route)
protected
689 {
690  ASSERT(route->getRoutingTable() == nullptr);
691 
692  routeList.push_back(route);
693  route->setRoutingTable(this);
694 
695  // we keep entries sorted by prefix length in routeList, so that we can
696  // stop at the first match when doing the longest prefix matching
697  std::stable_sort(routeList.begin(), routeList.end(), RouteLessThan(*this));
698 }

Referenced by addRoute(), and routeChanged().

◆ internalDeleteRoute()

Ipv6RoutingTable::RouteList::iterator inet::Ipv6RoutingTable::internalDeleteRoute ( RouteList::iterator  it)
protected
713 {
714  ASSERT(it != routeList.end());
715  Ipv6Route *route = *it;
716  it = routeList.erase(it);
717  emit(routeDeletedSignal, route);
718  // TODO purge cache?
719  delete route;
720  return it;
721 }

Referenced by deleteInterfaceRoutes(), deleteOnLinkPrefix(), deleteRoute(), and doLongestPrefixMatch().

◆ internalRemoveRoute()

Ipv6Route * inet::Ipv6RoutingTable::internalRemoveRoute ( Ipv6Route route)
protected
701 {
702  auto i = find(routeList, route);
703  if (i != routeList.end()) {
704  ASSERT(route->getRoutingTable() == this);
705  routeList.erase(i);
706  route->setRoutingTable(nullptr);
707  return route;
708  }
709  return nullptr;
710 }

Referenced by removeRoute(), and routeChanged().

◆ isAdminDistEnabled()

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

Administrative distance on/off.

Implements inet::IRoutingTable.

376 { return useAdminDist; }

◆ isForwardingEnabled()

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

Forwarding on/off.

Implements inet::IRoutingTable.

377 { return isRouter(); } // TODO inconsistent names

◆ isLocalAddress() [1/2]

bool inet::Ipv6RoutingTable::isLocalAddress ( const Ipv6Address dest) const
virtual

Checks if the address is one of the host's addresses, i.e.

assigned to one of its interfaces (tentatively or not).

409 {
410  Enter_Method("isLocalAddress(%s) y/n", dest.str().c_str());
411 
412  // first, check if we have an interface with this address
413  if (ift->isLocalAddress(dest))
414  return true;
415 
416  // then check for special, preassigned multicast addresses
417  // (these addresses occur more rarely than specific interface addresses,
418  // that's why we check for them last)
419 
420  if (dest == Ipv6Address::ALL_NODES_1 || dest == Ipv6Address::ALL_NODES_2)
421  return true;
422 
425  return true;
426 
427  // check for solicited-node multicast address
428  if (dest.matches(Ipv6Address::SOLICITED_NODE_PREFIX, 104)) {
429  for (int i = 0; i < ift->getNumInterfaces(); i++) {
430  NetworkInterface *ie = ift->getInterface(i);
431  if (ie->getProtocolData<Ipv6InterfaceData>()->matchesSolicitedNodeMulticastAddress(dest))
432  return true;
433  }
434  }
435  return false;
436 }

◆ isLocalAddress() [2/2]

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

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

one of the host's.

Implements inet::IRoutingTable.

380 { return isLocalAddress(dest.toIpv6()); }

Referenced by isLocalAddress().

◆ isLocalBroadcastAddress()

virtual bool inet::Ipv6RoutingTable::isLocalBroadcastAddress ( const L3Address dest) const
inlinevirtual
381 { return false; /*TODO isLocalBroadcastAddress(dest.toIPv6());*/ }

◆ isLocalMulticastAddress()

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

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

Implements inet::IRoutingTable.

387 { return false; /*TODO isLocalMulticastAddress(dest.toIPv6());*/ }

◆ isMulticastForwardingEnabled() [1/2]

virtual bool inet::Ipv6RoutingTable::isMulticastForwardingEnabled ( )
inlinevirtual
147 { return multicastForward; }

◆ isMulticastForwardingEnabled() [2/2]

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

Multicast forwarding on/off.

Implements inet::IRoutingTable.

378 { return true; /*TODO isMulticastForwardingEnabled();*/ }

◆ isPrefixPresent()

bool inet::Ipv6RoutingTable::isPrefixPresent ( const Ipv6Address prefix) const
virtual

Checks if the given prefix already exists in the routing table (prefix list)

485 {
486  for (const auto& elem : routeList)
487  if (prefix.matches((elem)->getDestPrefix(), 128))
488  return true;
489 
490  return false;
491 }

◆ isRouter()

virtual bool inet::Ipv6RoutingTable::isRouter ( ) const
inlinevirtual

IP forwarding on/off.

145 { return isrouter; }

Referenced by isLocalAddress().

◆ lookupDestCache()

const Ipv6Address & inet::Ipv6RoutingTable::lookupDestCache ( const Ipv6Address dest,
int &  outInterfaceId 
)

Looks up the given destination address in the Destination Cache, then returns the next-hop address and the interface in the outInterfaceId variable.

If the destination is not in the cache, outInterfaceId is set to -1 and the unspecified address is returned. The caller should check for interfaceId==-1, because unspecified address is also returned if the link layer doesn't use addresses at all (e.g. PPP).

NOTE: outInterfaceId is an OUTPUT parameter – its initial value is ignored, and the lookupDestCache() sets it to the correct value instead.

439 {
440  Enter_Method("lookupDestCache(%s)", dest.str().c_str());
441 
442  auto it = destCache.find(dest);
443  if (it == destCache.end()) {
444  outInterfaceId = -1;
446  }
447  DestCacheEntry& entry = it->second;
448  if (entry.expiryTime > 0 && simTime() > entry.expiryTime) {
449  destCache.erase(it);
450  outInterfaceId = -1;
452  }
453 
454  outInterfaceId = entry.interfaceId;
455  return entry.nextHopAddr;
456 }

◆ numInitStages()

virtual int inet::Ipv6RoutingTable::numInitStages ( ) const
inlineoverrideprotectedvirtual
118 { return NUM_INIT_STAGES; }

◆ parseXmlConfigFile()

void inet::Ipv6RoutingTable::parseXmlConfigFile ( )
protectedvirtual
117 {
118  cModule *host = getContainingNode(this);
119 
120  // configure interfaces from XML config file
121  cXMLElement *config = par("routes");
122  for (cXMLElement *child = config->getFirstChild(); child; child = child->getNextSibling()) {
123 // std::cout << "configuring interfaces from XML file." << endl;
124 // std::cout << "selected element is: " << child->getTagName() << endl;
125  // we ensure that the selected element is local.
126  if (opp_strcmp(child->getTagName(), "local") != 0)
127  continue;
128  // ensure that this is the right parent module we are configuring.
129  if (opp_strcmp(child->getAttribute("node"), host->getFullName()) != 0)
130  continue;
131  // Go one level deeper.
132 // child = child->getFirstChild();
133  for (cXMLElement *ifTag = child->getFirstChild(); ifTag; ifTag = ifTag->getNextSibling()) {
134  // The next tag should be "interface".
135  if (opp_strcmp(ifTag->getTagName(), "interface") == 0) {
136 // std::cout << "Getting attribute: name" << endl;
137  const char *ifname = ifTag->getAttribute("name");
138  if (!ifname)
139  throw cRuntimeError("<interface> without name attribute at %s", child->getSourceLocation());
140 
141  NetworkInterface *ie = ift->findInterfaceByName(ifname);
142  if (!ie)
143  throw cRuntimeError("no interface named %s was registered, %s", ifname, child->getSourceLocation());
144 
145  configureInterfaceFromXml(ie, ifTag);
146  }
147  else if (opp_strcmp(ifTag->getTagName(), "tunnel") == 0)
148  configureTunnelFromXml(ifTag);
149  }
150  }
151 }

Referenced by initialize().

◆ printRoutingTable()

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

Prints the routing table.

Implements inet::IRoutingTable.

882 {
883  for (const auto& elem : routeList)
884  EV_INFO << (elem)->getInterface()->getInterfaceFullPath() << " -> " << (elem)->getDestinationAsGeneric().str() << " as " << (elem)->str() << endl;
885 }

◆ purgeDestCache()

void inet::Ipv6RoutingTable::purgeDestCache ( )
virtual

Discard all entries in destination cache.

502 {
503  destCache.clear();
504 }

Referenced by addRoute().

◆ purgeDestCacheEntriesToNeighbour()

void inet::Ipv6RoutingTable::purgeDestCacheEntriesToNeighbour ( const Ipv6Address nextHopAddr,
int  interfaceId 
)
virtual

Discard all entries in destination cache where next hop is the given address on the given interface.

This is typically called when a router becomes unreachable, and all destinations going via that router have to go though router selection again.

507 {
508  for (auto it = destCache.begin(); it != destCache.end();) {
509  if (it->second.interfaceId == interfaceId && it->second.nextHopAddr == nextHopAddr) {
510  // move the iterator past this element before removing it
511  destCache.erase(it++);
512  }
513  else {
514  it++;
515  }
516  }
517 }

◆ purgeDestCacheForInterfaceId()

void inet::Ipv6RoutingTable::purgeDestCacheForInterfaceId ( int  interfaceId)

Removes all destination cache entries for the specified interface.

520 {
521  for (auto it = destCache.begin(); it != destCache.end();) {
522  if (it->second.interfaceId == interfaceId) {
523  // move the iterator past this element before removing it
524  destCache.erase(it++);
525  }
526  else {
527  ++it;
528  }
529  }
530 }

Referenced by receiveSignal().

◆ receiveSignal()

void inet::Ipv6RoutingTable::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.

167 {
168  if (getSimulation()->getContextType() == CTX_INITIALIZE)
169  return; // ignore notifications during initialize
170 
171  Enter_Method("%s", cComponent::getSignalName(signalID));
172 
173  printSignalBanner(signalID, obj, details);
174 
175  if (signalID == interfaceCreatedSignal) {
176  // TODO something like this:
177 // NetworkInterface *ie = check_and_cast<NetworkInterface*>(details);
178 // configureInterfaceForIPv6(ie);
179  }
180  else if (signalID == interfaceDeletedSignal) {
181  // remove all routes that point to that interface
182  const NetworkInterface *entry = check_and_cast<const NetworkInterface *>(obj);
183  deleteInterfaceRoutes(entry);
184  }
185  else if (signalID == interfaceStateChangedSignal) {
186  const NetworkInterface *networkInterface = check_and_cast<const NetworkInterfaceChangeDetails *>(obj)->getNetworkInterface();
187  int networkInterfaceId = networkInterface->getInterfaceId();
188 
189  // an interface went down
190  if (!networkInterface->isUp()) {
191  deleteInterfaceRoutes(networkInterface);
192  purgeDestCacheForInterfaceId(networkInterfaceId);
193  }
194  }
195  else if (signalID == interfaceConfigChangedSignal) {
196  // TODO invalidate routing cache (?)
197  }
198  else if (signalID == interfaceIpv6ConfigChangedSignal) {
199  // TODO
200  }
201 }

◆ refreshDisplay()

void inet::Ipv6RoutingTable::refreshDisplay ( ) const
overrideprotectedvirtual
154 {
155  std::stringstream os;
156 
157  os << getNumRoutes() << " routes\n" << destCache.size() << " destcache entries";
158  getDisplayString().setTagArg("t", 0, os.str().c_str());
159 }

◆ removeMulticastRoute()

virtual IMulticastRoute* inet::Ipv6RoutingTable::removeMulticastRoute ( IMulticastRoute entry)
inlineoverridevirtual

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.

396 { /*TODO removeMulticastRoute(entry);*/ return entry; }

◆ removeRoute() [1/2]

Ipv6Route * inet::Ipv6RoutingTable::removeRoute ( Ipv6Route route)
virtual

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

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

678 {
679  route = internalRemoveRoute(route);
680  if (route) {
681  // TODO purge cache?
682 
683  emit(routeDeletedSignal, route); // rather: going to be deleted
684  }
685  return route;
686 }

Referenced by handleOperationStage().

◆ removeRoute() [2/2]

virtual IRoute* inet::Ipv6RoutingTable::removeRoute ( IRoute entry)
inlineoverridevirtual

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.

391 { return removeRoute(check_and_cast<Ipv6Route *>(entry)); }

Referenced by removeRoute().

◆ routeChanged()

void inet::Ipv6RoutingTable::routeChanged ( Ipv6Route entry,
int  fieldCode 
)
virtual

To be called from route objects whenever a field changes.

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

204 {
205  if (fieldCode == Ipv6Route::F_DESTINATION || fieldCode == Ipv6Route::F_PREFIX_LENGTH || fieldCode == Ipv6Route::F_METRIC) { // our data structures depend on these fields
206  entry = internalRemoveRoute(entry);
207  ASSERT(entry != nullptr); // failure means inconsistency: route was not found in this routing table
208  internalAddRoute(entry);
209 
210 // invalidateCache();
211  }
212  emit(routeChangedSignal, entry); // TODO include fieldCode in the notification
213 }

Referenced by inet::Ipv6Route::changed().

◆ routeLessThan()

bool inet::Ipv6RoutingTable::routeLessThan ( const Ipv6Route a,
const Ipv6Route b 
) const
protected
651 {
652  // helper for sort() in addRoute(). We want routes with longer
653  // prefixes to be at front, so we compare them as "less".
654  // For metric, a smaller value is better (we report that as "less").
655  if (a->getPrefixLength() != b->getPrefixLength())
656  return a->getPrefixLength() > b->getPrefixLength();
657 
658  // smaller administrative distance is better
659  if (useAdminDist && (a->getAdminDist() != b->getAdminDist()))
660  return a->getAdminDist() < b->getAdminDist();
661 
662  // smaller metric is better
663  return a->getMetric() < b->getMetric();
664 }

◆ updateDestCache()

void inet::Ipv6RoutingTable::updateDestCache ( const Ipv6Address dest,
const Ipv6Address nextHopAddr,
int  interfaceId,
simtime_t  expiryTime 
)
virtual

Add or update a destination cache entry.

494 {
495  DestCacheEntry& entry = destCache[dest];
496  entry.nextHopAddr = nextHopAddr;
497  entry.interfaceId = interfaceId;
498  entry.expiryTime = expiryTime;
499 }

Friends And Related Function Documentation

◆ operator<<

std::ostream& operator<< ( std::ostream &  os,
const DestCacheEntry e 
)
friend
31 {
32  os << "if=" << e.interfaceId << " " << e.nextHopAddr; // FIXME try printing interface name
33  return os;
34 };

Member Data Documentation

◆ destCache

◆ ift

◆ isrouter

bool inet::Ipv6RoutingTable::isrouter = false
protected

◆ multicastForward

bool inet::Ipv6RoutingTable::multicastForward = false
protected

Referenced by initialize().

◆ routeList

◆ useAdminDist

bool inet::Ipv6RoutingTable::useAdminDist = false
protected

Referenced by initialize(), and routeLessThan().


The documentation for this class was generated from the following files:
inet::INITSTAGE_NETWORK_CONFIGURATION
INET_API InitStage INITSTAGE_NETWORK_CONFIGURATION
Initialization of network configuration (e.g.
inet::ModuleCrashOperation::Stage
Stage
Definition: ModuleOperations.h:75
inet::Ipv6RoutingTable::addRoutingProtocolRoute
virtual void addRoutingProtocolRoute(Ipv6Route *route)
Adds the given getRoute(which can be OSPF, BGP, RIP or any other route) with src==ROUTING_PROT.
Definition: Ipv6RoutingTable.cc:644
inet::Ipv6Address::ALL_ROUTERS_2
static const Ipv6Address ALL_ROUTERS_2
All-routers multicast address, scope 2 (link-local)
Definition: Ipv6Address.h:69
inet::Ipv6RoutingTable::deleteInterfaceRoutes
virtual void deleteInterfaceRoutes(const NetworkInterface *entry)
Deletes the routes that are using the specified interface.
Definition: Ipv6RoutingTable.cc:834
inet::Ipv6RoutingTable::createNewRoute
virtual Ipv6Route * createNewRoute(Ipv6Address destPrefix, int prefixLength, IRoute::SourceType src)
Definition: Ipv6RoutingTable.cc:46
inet::Ipv6Route::dStatic
@ dStatic
Definition: Ipv6Route.h:31
inet::IRoute::F_DESTINATION
@ F_DESTINATION
Definition: IRoute.h:47
inet::Ipv6RoutingTable::Ipv6RoutingTable
Ipv6RoutingTable()
Definition: Ipv6RoutingTable.cc:36
inet::Ipv6RoutingTable::purgeDestCacheForInterfaceId
void purgeDestCacheForInterfaceId(int interfaceId)
Removes all destination cache entries for the specified interface.
Definition: Ipv6RoutingTable.cc:519
inet::Ipv6RoutingTable::internalAddRoute
void internalAddRoute(Ipv6Route *route)
Definition: Ipv6RoutingTable.cc:688
inet::ModuleStopOperation::STAGE_NETWORK_LAYER
@ STAGE_NETWORK_LAYER
Definition: ModuleOperations.h:53
inet::IRoute::MANUAL
@ MANUAL
manually added static route
Definition: IRoute.h:29
inet::Ipv6Route::dDirectlyConnected
@ dDirectlyConnected
Definition: Ipv6Route.h:30
inet::Ipv6RoutingTable::deleteRoute
virtual bool deleteRoute(Ipv6Route *route)
Deletes the given route from the route table.
Definition: Ipv6RoutingTable.cc:723
inet::IRoute::ROUTER_ADVERTISEMENT
@ ROUTER_ADVERTISEMENT
on-link prefix, from Router Advertisement
Definition: IRoute.h:31
inet::Ipv6RoutingTable::isrouter
bool isrouter
Definition: Ipv6RoutingTable.h:45
inet::Ipv6Address::ALL_NODES_2
static const Ipv6Address ALL_NODES_2
All-nodes multicast address, scope 2 (link-local)
Definition: Ipv6Address.h:63
inet::getContainingNode
cModule * getContainingNode(const cModule *from)
Find the node containing the given module.
Definition: ModuleAccess.cc:40
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::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::Ipv6RoutingTable::configureInterfaceForIpv6
virtual void configureInterfaceForIpv6(NetworkInterface *ie)
Definition: Ipv6RoutingTable.cc:215
inet::Ipv6Address::ALL_ROUTERS_1
static const Ipv6Address ALL_ROUTERS_1
All-routers multicast address, scope 1 (interface-local)
Definition: Ipv6Address.h:66
inet::Ipv6Address::ALL_ROUTERS_5
static const Ipv6Address ALL_ROUTERS_5
All-routers multicast address, scope 5 (site-local)
Definition: Ipv6Address.h:72
inet::Ipv6Address::ALL_NODES_1
static const Ipv6Address ALL_NODES_1
All-nodes multicast address, scope 1 (interface-local)
Definition: Ipv6Address.h:60
inet::Ipv6RoutingTable::ift
ModuleRefByPar< IInterfaceTable > ift
Definition: Ipv6RoutingTable.h:43
inet::IRoute::OWN_ADV_PREFIX
@ OWN_ADV_PREFIX
on routers: on-link prefix that the router itself advertises on the link
Definition: IRoute.h:32
inet::Ipv6RoutingTable::assignRequiredNodeAddresses
virtual void assignRequiredNodeAddresses(NetworkInterface *ie)
RFC 3513: Section 2.8 A Node's Required Address Assign the various addresses to the node's respective...
Definition: Ipv6RoutingTable.cc:243
inet::interfaceDeletedSignal
simsignal_t interfaceDeletedSignal
Definition: Simsignals.cc:31
inet::Ipv6Address::LINKLOCAL_PREFIX
static const Ipv6Address LINKLOCAL_PREFIX
The link-local prefix (fe80::)
Definition: Ipv6Address.h:78
inet::Ipv6Address::UNSPECIFIED_ADDRESS
static const Ipv6Address UNSPECIFIED_ADDRESS
The unspecified address.
Definition: Ipv6Address.h:54
inet::Ipv6RoutingTable::addOrUpdateOwnAdvPrefix
virtual void addOrUpdateOwnAdvPrefix(const Ipv6Address &destPrefix, int prefixLength, int interfaceId, simtime_t expiryTime)
Add route of type OWN_ADV_PREFIX.
Definition: Ipv6RoutingTable.cc:564
inet::Ipv6RoutingTable::routeList
RouteList routeList
Definition: Ipv6RoutingTable.h:70
inet::ModuleStopOperation::Stage
Stage
Definition: ModuleOperations.h:48
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::Ipv6RoutingTable::destCache
DestCache destCache
Definition: Ipv6RoutingTable.h:65
inet::utils::atoul
unsigned long atoul(const char *s)
Converts string to unsigned long.
Definition: INETUtils.cc:89
inet::units::values::b
value< int64_t, units::b > b
Definition: Units.h:1241
inet::routeAddedSignal
simsignal_t routeAddedSignal
Definition: Simsignals.cc:41
NUM_INIT_STAGES
#define NUM_INIT_STAGES
Definition: InitStageRegistry.h:73
inet::Ipv6RoutingTable::getInterfaceByAddress
virtual NetworkInterface * getInterfaceByAddress(const Ipv6Address &address) const
Returns an interface given by its address.
Definition: Ipv6RoutingTable.cc:396
inet::Ipv6RoutingTable::parseXmlConfigFile
virtual void parseXmlConfigFile()
Definition: Ipv6RoutingTable.cc:116
inet::Ipv6RoutingTable::getNumRoutes
virtual int getNumRoutes() const override
Return the number of routes.
Definition: Ipv6RoutingTable.cc:733
inet::Ipv6RoutingTable::removeRoute
virtual Ipv6Route * removeRoute(Ipv6Route *route)
Removes the given route from the routing table, and returns it.
Definition: Ipv6RoutingTable.cc:677
inet::ModuleCrashOperation::STAGE_CRASH
@ STAGE_CRASH
Definition: ModuleOperations.h:76
inet::Ipv6RoutingTable::configureTunnelFromXml
virtual void configureTunnelFromXml(cXMLElement *cfg)
Definition: Ipv6RoutingTable.cc:369
inet::Ipv6RoutingTable::isLocalAddress
virtual bool isLocalAddress(const Ipv6Address &dest) const
Checks if the address is one of the host's addresses, i.e.
Definition: Ipv6RoutingTable.cc:408
inet::Ipv6RoutingTable::isRouter
virtual bool isRouter() const
IP forwarding on/off.
Definition: Ipv6RoutingTable.h:145
inet::Ipv6RoutingTable::internalDeleteRoute
RouteList::iterator internalDeleteRoute(RouteList::iterator it)
Definition: Ipv6RoutingTable.cc:712
Enter_Method
#define Enter_Method(...)
Definition: SelfDoc.h:71
inet::routeDeletedSignal
simsignal_t routeDeletedSignal
Definition: Simsignals.cc:42
inet::Ipv6Tunneling::NORMAL
@ NORMAL
Definition: Ipv6Tunneling.h:44
inet::Ipv6RoutingTable::addRoute
virtual void addRoute(Ipv6Route *route)
Definition: Ipv6RoutingTable.cc:666
inet::Ipv6RoutingTable::internalRemoveRoute
Ipv6Route * internalRemoveRoute(Ipv6Route *route)
Definition: Ipv6RoutingTable.cc:700
inet::Ipv6RoutingTable::useAdminDist
bool useAdminDist
Definition: Ipv6RoutingTable.h:47
inet::IRoute::F_PREFIX_LENGTH
@ F_PREFIX_LENGTH
Definition: IRoute.h:48
inet::Ipv6RoutingTable::configureInterfaceFromXml
virtual void configureInterfaceFromXml(NetworkInterface *ie, cXMLElement *cfg)
Definition: Ipv6RoutingTable.cc:306
inet::Ipv6Address::ALL_OSPF_ROUTERS_MCAST
static const Ipv6Address ALL_OSPF_ROUTERS_MCAST
OSPF multicast address for listening.
Definition: Ipv6Address.h:84
inet::interfaceCreatedSignal
simsignal_t interfaceCreatedSignal
Definition: Simsignals.cc:30
inet::Ipv6RoutingTable::addStaticRoute
virtual void addStaticRoute(const Ipv6Address &destPrefix, int prefixLength, unsigned int interfaceId, const Ipv6Address &nextHop, int metric=0)
Creates a static route.
Definition: Ipv6RoutingTable.cc:609
inet::IRoute::F_METRIC
@ F_METRIC
Definition: IRoute.h:54
inet::interfaceConfigChangedSignal
simsignal_t interfaceConfigChangedSignal
Definition: Simsignals.cc:33
inet::Ipv6Address::SOLICITED_NODE_PREFIX
static const Ipv6Address SOLICITED_NODE_PREFIX
The solicited-node multicast address prefix (prefix length = 104)
Definition: Ipv6Address.h:75
inet::Ipv6RoutingTable::purgeDestCache
virtual void purgeDestCache()
Discard all entries in destination cache.
Definition: Ipv6RoutingTable.cc:501
inet::Ipv6RoutingTable::multicastForward
bool multicastForward
Definition: Ipv6RoutingTable.h:46
inet::INITSTAGE_LINK_LAYER
INET_API InitStage INITSTAGE_LINK_LAYER
Initialization of link-layer protocols.
inet::Ipv6Address::ALL_OSPF_DESIGNATED_ROUTERS_MCAST
static const Ipv6Address ALL_OSPF_DESIGNATED_ROUTERS_MCAST
OSPF designated routers.
Definition: Ipv6Address.h:87
inet::interfaceIpv6ConfigChangedSignal
simsignal_t interfaceIpv6ConfigChangedSignal
Definition: Simsignals.cc:36