RoutingTable6 Class Reference

#include <RoutingTable6.h>

Inheritance diagram for RoutingTable6:

INotifiable

List of all members.


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.

Public Member Functions

 RoutingTable6 ()
virtual ~RoutingTable6 ()
virtual bool isRouter () const
Interfaces


virtual InterfaceEntrygetInterfaceByAddress (const IPv6Address &address)
Routing functions


virtual bool isLocalAddress (const IPv6Address &dest) const
const IPv6AddresslookupDestCache (const IPv6Address &dest, int &outInterfaceId) const
const IPv6RoutedoLongestPrefixMatch (const IPv6Address &dest)
virtual bool isPrefixPresent (const IPv6Address &prefix) const
Managing the destination cache


virtual void updateDestCache (const IPv6Address &dest, const IPv6Address &nextHopAddr, int interfaceId)
virtual void purgeDestCache ()
virtual void purgeDestCacheEntriesToNeighbour (const IPv6Address &nextHopAddr, int interfaceId)
Managing prefixes and the route table


virtual void addOrUpdateOnLinkPrefix (const IPv6Address &destPrefix, int prefixLength, int interfaceId, simtime_t expiryTime)
virtual void removeOnLinkPrefix (const IPv6Address &destPrefix, int prefixLength)
virtual void addOrUpdateOwnAdvPrefix (const IPv6Address &destPrefix, int prefixLength, int interfaceId, simtime_t expiryTime)
virtual void addStaticRoute (const IPv6Address &destPrefix, int prefixLength, unsigned int interfaceId, const IPv6Address &nextHop, int metric=0)
virtual void addDefaultRoute (const IPv6Address &raSrcAddr, unsigned int ifID, simtime_t routerLifetime)
virtual void addRoutingProtocolRoute (IPv6Route *route)
virtual void removeRoute (IPv6Route *route)
virtual int getNumRoutes () const
virtual IPv6RoutegetRoute (int i)

Protected Types

typedef std::map< IPv6Address,
DestCacheEntry
DestCache
typedef std::vector< IPv6Route * > RouteList

Protected Member Functions

virtual void addRoute (IPv6Route *route)
virtual void configureInterfaceForIPv6 (InterfaceEntry *ie)
virtual void assignRequiredNodeAddresses (InterfaceEntry *ie)
virtual void configureInterfaceFromXML (InterfaceEntry *ie, cXMLElement *cfg)
virtual void updateDisplayString ()
virtual int numInitStages () const
virtual void initialize (int stage)
virtual void parseXMLConfigFile ()
virtual void handleMessage (cMessage *)
virtual void receiveChangeNotification (int category, const cPolymorphic *details)

Static Protected Member Functions

static bool routeLessThan (const IPv6Route *a, const IPv6Route *b)

Protected Attributes

IInterfaceTableift
NotificationBoardnb
bool isrouter
DestCache destCache
RouteList routeList

Friends

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

Classes

struct  DestCacheEntry


Member Typedef Documentation

typedef std::map<IPv6Address,DestCacheEntry> RoutingTable6::DestCache [protected]

typedef std::vector<IPv6Route*> RoutingTable6::RouteList [protected]


Constructor & Destructor Documentation

RoutingTable6::RoutingTable6 (  ) 

00074 {
00075 }

RoutingTable6::~RoutingTable6 (  )  [virtual]

00078 {
00079     for (unsigned int i=0; i<routeList.size(); i++)
00080         delete routeList[i];
00081 }


Member Function Documentation

void RoutingTable6::addRoute ( IPv6Route route  )  [protected, virtual]

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

00620 {
00621     routeList.push_back(route);
00622 
00623     // we keep entries sorted by prefix length in routeList, so that we can
00624     // stop at the first match when doing the longest prefix matching
00625     std::sort(routeList.begin(), routeList.end(), routeLessThan);
00626 
00627     updateDisplayString();
00628 
00629     nb->fireChangeNotification(NF_IPv6_ROUTE_ADDED, route);
00630 }

bool RoutingTable6::routeLessThan ( const IPv6Route a,
const IPv6Route b 
) [static, protected]

Referenced by addRoute().

00610 {
00611     // helper for sort() in addRoute(). We want routes with longer
00612     // prefixes to be at front, so we compare them as "less".
00613     // For metric, a smaller value is better (we report that as "less").
00614     if (a->getPrefixLength()!=b->getPrefixLength())
00615         return a->getPrefixLength() > b->getPrefixLength();
00616     return a->getMetric() < b->getMetric();
00617 }

void RoutingTable6::configureInterfaceForIPv6 ( InterfaceEntry ie  )  [protected, virtual]

Referenced by initialize().

00217 {
00218     IPv6InterfaceData *ipv6IfData = new IPv6InterfaceData();
00219     ie->setIPv6Data(ipv6IfData);
00220 
00221     // for routers, turn on advertisements by default
00222     //FIXME: we will use this isRouter flag for now. what if future implementations
00223     //have 2 interfaces where one interface is configured as a router and the other
00224     //as a host?
00225     ipv6IfData->setAdvSendAdvertisements(isrouter);//Added by WEI
00226 
00227     // metric: some hints: OSPF cost (2e9/bps value), MS KB article Q299540, ...
00228     //d->setMetric((int)ceil(2e9/ie->getDatarate())); // use OSPF cost as default
00229     //FIXME TBD fill in the rest
00230 
00231     assignRequiredNodeAddresses(ie);
00232 }

void RoutingTable6::assignRequiredNodeAddresses ( InterfaceEntry ie  )  [protected, virtual]

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.

Referenced by configureInterfaceForIPv6().

00235 {
00236     //RFC 3513 Section 2.8:A Node's Required Addresses
00237     /*A host is required to recognize the following addresses as
00238     identifying itself:*/
00239 
00240     //o  The loopback address.
00241     if (ie->isLoopback())
00242     {
00243         ie->ipv6Data()->assignAddress(IPv6Address("::1"), false, 0, 0);
00244         return;
00245     }
00246     //o  Its required Link-Local Address for each interface.
00247     //IPv6Address linkLocalAddr = IPv6Address().formLinkLocalAddress(ie->getInterfaceToken());
00248     //ie->ipv6Data()->assignAddress(linkLocalAddr, true, 0, 0);
00249 
00250     /*o  Any additional Unicast and Anycast Addresses that have been configured
00251     for the node's interfaces (manually or automatically).*/
00252 
00253     // FIXME FIXME Andras: commented out the following lines, because these addresses
00254     // are implicitly checked for in isLocalAddress()  (we don't want redundancy,
00255     // and manually adding solicited-node mcast address for each and every address
00256     // is very error-prone!)
00257     //
00258     //o  The All-Nodes Multicast Addresses defined in section 2.7.1.
00259 
00260     /*o  The Solicited-Node Multicast Address for each of its unicast and anycast
00261     addresses.*/
00262 
00263     //o  Multicast Addresses of all other groups to which the node belongs.
00264 
00265     /*A router is required to recognize all addresses that a host is
00266     required to recognize, plus the following addresses as identifying
00267     itself:*/
00268     /*o  The Subnet-Router Anycast Addresses for all interfaces for
00269     which it is configured to act as a router.*/
00270 
00271     //o  All other Anycast Addresses with which the router has been configured.
00272     //o  The All-Routers Multicast Addresses defined in section 2.7.1.
00273 }

void RoutingTable6::configureInterfaceFromXML ( InterfaceEntry ie,
cXMLElement *  cfg 
) [protected, virtual]

Referenced by parseXMLConfigFile().

00291 {
00292     /*XML parsing capabilities tweaked by WEI. For now, we can configure a specific
00293     node's interface. We can set advertising prefixes and other variables to be used
00294     in RAs. The IPv6 interface data gets overwritten if lines 249 to 262 is uncommented.
00295     The fix is to create an XML file with all the default values. Customised XML files
00296     can be used for future protocols that requires different values. (MIPv6)*/
00297     IPv6InterfaceData *d = ie->ipv6Data();
00298 
00299     // parse basic config (attributes)
00300     d->setAdvSendAdvertisements(toBool(getRequiredAttr(cfg, "AdvSendAdvertisements")));
00301     //TODO: leave this off first!! They overwrite stuff!
00302 /* TODO: Wei commented out the stuff below. To be checked why (Andras).
00303     d->setMaxRtrAdvInterval(OPP_Global::atod(getRequiredAttr(cfg, "MaxRtrAdvInterval")));
00304     d->setMinRtrAdvInterval(OPP_Global::atod(getRequiredAttr(cfg, "MinRtrAdvInterval")));
00305     d->setAdvManagedFlag(toBool(getRequiredAttr(cfg, "AdvManagedFlag")));
00306     d->setAdvOtherConfigFlag(toBool(getRequiredAttr(cfg, "AdvOtherConfigFlag")));
00307     d->setAdvLinkMTU(OPP_Global::atoul(getRequiredAttr(cfg, "AdvLinkMTU")));
00308     d->setAdvReachableTime(OPP_Global::atoul(getRequiredAttr(cfg, "AdvReachableTime")));
00309     d->setAdvRetransTimer(OPP_Global::atoul(getRequiredAttr(cfg, "AdvRetransTimer")));
00310     d->setAdvCurHopLimit(OPP_Global::atoul(getRequiredAttr(cfg, "AdvCurHopLimit")));
00311     d->setAdvDefaultLifetime(OPP_Global::atoul(getRequiredAttr(cfg, "AdvDefaultLifetime")));
00312     ie->setMtu(OPP_Global::atoul(getRequiredAttr(cfg, "HostLinkMTU")));
00313     d->setCurHopLimit(OPP_Global::atoul(getRequiredAttr(cfg, "HostCurHopLimit")));
00314     d->setBaseReachableTime(OPP_Global::atoul(getRequiredAttr(cfg, "HostBaseReachableTime")));
00315     d->setRetransTimer(OPP_Global::atoul(getRequiredAttr(cfg, "HostRetransTimer")));
00316     d->setDupAddrDetectTransmits(OPP_Global::atoul(getRequiredAttr(cfg, "HostDupAddrDetectTransmits")));
00317 */
00318 
00319     // parse prefixes (AdvPrefix elements; they should be inside an AdvPrefixList
00320     // element, but we don't check that)
00321     cXMLElementList prefixList = cfg->getElementsByTagName("AdvPrefix");
00322     for (unsigned int i=0; i<prefixList.size(); i++)
00323     {
00324         cXMLElement *node = prefixList[i];
00325         IPv6InterfaceData::AdvPrefix prefix;
00326 
00327         // FIXME todo implement: advValidLifetime, advPreferredLifetime can
00328         // store (absolute) expiry time (if >0) or lifetime (delta) (if <0);
00329         // 0 should be treated as infinity
00330         int pfxLen;
00331         if (!prefix.prefix.tryParseAddrWithPrefix(node->getNodeValue(),pfxLen))
00332             opp_error("element <%s> at %s: wrong IPv6Address/prefix syntax %s",
00333                       node->getTagName(), node->getSourceLocation(), node->getNodeValue());
00334         prefix.prefixLength = pfxLen;
00335         prefix.advValidLifetime = OPP_Global::atoul(getRequiredAttr(node, "AdvValidLifetime"));
00336         prefix.advOnLinkFlag = toBool(getRequiredAttr(node, "AdvOnLinkFlag"));
00337         prefix.advPreferredLifetime = OPP_Global::atoul(getRequiredAttr(node, "AdvPreferredLifetime"));
00338         prefix.advAutonomousFlag = toBool(getRequiredAttr(node, "AdvAutonomousFlag"));
00339         d->addAdvPrefix(prefix);
00340     }
00341 
00342     // parse addresses
00343     cXMLElementList addrList = cfg->getChildrenByTagName("inetAddr");
00344     for (unsigned int k=0; k<addrList.size(); k++)
00345     {
00346         cXMLElement *node = addrList[k];
00347         IPv6Address address = node->getNodeValue();
00348         //We can now decide if the address is tentative or not.
00349         d->assignAddress(address, toBool(getRequiredAttr(node, "tentative")), 0, 0);  // set up with infinite lifetimes
00350     }
00351 }

void RoutingTable6::updateDisplayString (  )  [protected, virtual]

Referenced by addOrUpdateOnLinkPrefix(), addOrUpdateOwnAdvPrefix(), addRoute(), initialize(), purgeDestCache(), purgeDestCacheEntriesToNeighbour(), removeOnLinkPrefix(), removeRoute(), and updateDestCache().

00170 {
00171     if (!ev.isGUI())
00172         return;
00173 
00174     char buf[80];
00175     sprintf(buf, "%d routes\n%d destcache entries", getNumRoutes(), destCache.size());
00176     getDisplayString().setTagArg("t",0,buf);
00177 }

virtual int RoutingTable6::numInitStages (  )  const [inline, protected, virtual]

00152 {return 5;}

void RoutingTable6::initialize ( int  stage  )  [protected, virtual]

00084 {
00085     if (stage==1)
00086     {
00087         ift = InterfaceTableAccess().get();
00088         nb = NotificationBoardAccess().get();
00089 
00090         nb->subscribe(this, NF_INTERFACE_CREATED);
00091         nb->subscribe(this, NF_INTERFACE_DELETED);
00092         nb->subscribe(this, NF_INTERFACE_STATE_CHANGED);
00093         nb->subscribe(this, NF_INTERFACE_CONFIG_CHANGED);
00094         nb->subscribe(this, NF_INTERFACE_IPv6CONFIG_CHANGED);
00095 
00096         WATCH_PTRVECTOR(routeList);
00097         WATCH_MAP(destCache); // FIXME commented out for now
00098         isrouter = par("isRouter");
00099         WATCH(isrouter);
00100 
00101         // add IPv6InterfaceData to interfaces
00102         for (int i=0; i<ift->getNumInterfaces(); i++)
00103         {
00104             InterfaceEntry *ie = ift->getInterface(i);
00105             configureInterfaceForIPv6(ie);
00106         }
00107 
00108         parseXMLConfigFile();
00109 
00110         // skip hosts
00111         if (isrouter)
00112         {
00113             // add globally routable prefixes to routing table
00114             for (int x = 0; x < ift->getNumInterfaces(); x++)
00115             {
00116                 InterfaceEntry *ie = ift->getInterface(x);
00117 
00118                 if (ie->isLoopback())
00119                     continue;
00120 
00121                 for (int y = 0; y < ie->ipv6Data()->getNumAdvPrefixes(); y++)
00122                     if (ie->ipv6Data()->getAdvPrefix(y).prefix.isGlobal())
00123                         addOrUpdateOwnAdvPrefix(ie->ipv6Data()->getAdvPrefix(y).prefix,
00124                                                 ie->ipv6Data()->getAdvPrefix(y).prefixLength,
00125                                                 ie->getInterfaceId(), 0);
00126             }
00127         }
00128     }
00129     else if (stage==4)
00130     {
00131         // configurator adds routes only in stage==3
00132         updateDisplayString();
00133     }
00134 }

void RoutingTable6::parseXMLConfigFile (  )  [protected, virtual]

Referenced by initialize().

00137 {
00138     // TODO to be revised by Andras
00139     // configure interfaces from XML config file
00140     cXMLElement *config = par("routingTableFile");
00141     for (cXMLElement *child=config->getFirstChild(); child; child = child->getNextSibling())
00142     {
00143         //std::cout << "configuring interfaces from XML file." << endl;
00144         //std::cout << "selected element is: " << child->getTagName() << endl;
00145         // we ensure that the selected element is local.
00146         if (opp_strcmp(child->getTagName(),"local")!=0) continue;
00147         //ensure that this is the right parent module we are configuring.
00148         if (opp_strcmp(child->getAttribute("node"),getParentModule()->getFullName())!=0)
00149             continue;
00150         //Go one level deeper.
00151         //child = child->getFirstChild();
00152         for (cXMLElement *ifTag=child->getFirstChild(); ifTag; ifTag = ifTag->getNextSibling())
00153         {
00154             //The next tag should be "interface".
00155             if (opp_strcmp(ifTag->getTagName(),"interface")!=0)
00156                 continue;
00157             //std::cout << "Getting attribute: name" << endl;
00158             const char *ifname = ifTag->getAttribute("name");
00159             if (!ifname)
00160                 error("<interface> without name attribute at %s", child->getSourceLocation());
00161             InterfaceEntry *ie = ift->getInterfaceByName(ifname);
00162             if (!ie)
00163                 error("no interface named %s was registered, %s", ifname, child->getSourceLocation());
00164             configureInterfaceFromXML(ie, ifTag);
00165         }
00166     }
00167 }

void RoutingTable6::handleMessage ( cMessage *  msg  )  [protected, virtual]

Raises an error.

00180 {
00181     opp_error("This module doesn't process messages");
00182 }

void RoutingTable6::receiveChangeNotification ( int  category,
const cPolymorphic *  details 
) [protected, virtual]

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

Implements INotifiable.

00185 {
00186     if (simulation.getContextType()==CTX_INITIALIZE)
00187         return;  // ignore notifications during initialize
00188 
00189     Enter_Method_Silent();
00190     printNotificationBanner(category, details);
00191 
00192     if (category==NF_INTERFACE_CREATED)
00193     {
00194         //TODO something like this:
00195         //InterfaceEntry *ie = check_and_cast<InterfaceEntry*>(details);
00196         //configureInterfaceForIPv6(ie);
00197     }
00198     else if (category==NF_INTERFACE_DELETED)
00199     {
00200         //TODO remove all routes that point to that interface (?)
00201     }
00202     else if (category==NF_INTERFACE_STATE_CHANGED)
00203     {
00204         //TODO invalidate routing cache (?)
00205     }
00206     else if (category==NF_INTERFACE_CONFIG_CHANGED)
00207     {
00208         //TODO invalidate routing cache (?)
00209     }
00210     else if (category==NF_INTERFACE_IPv6CONFIG_CHANGED)
00211     {
00212         //TODO
00213     }
00214 }

InterfaceEntry * RoutingTable6::getInterfaceByAddress ( const IPv6Address address  )  [virtual]

Returns an interface given by its address. Returns NULL if not found.

Referenced by IPv6::encapsulate().

00354 {
00355     Enter_Method("getInterfaceByAddress(%s)=?", addr.str().c_str());
00356 
00357     if (addr.isUnspecified())
00358         return NULL;
00359     for (int i=0; i<ift->getNumInterfaces(); ++i)
00360     {
00361         InterfaceEntry *ie = ift->getInterface(i);
00362         if (ie->ipv6Data()->hasAddress(addr))
00363             return ie;
00364     }
00365     return NULL;
00366 }

virtual bool RoutingTable6::isRouter (  )  const [inline, virtual]

bool RoutingTable6::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).

Referenced by IPv6NeighbourDiscovery::processNSForTentativeAddress(), IPv6::routeMulticastPacket(), and IPv6::routePacket().

00369 {
00370     Enter_Method("isLocalAddress(%s) y/n", dest.str().c_str());
00371 
00372     // first, check if we have an interface with this address
00373     for (int i=0; i<ift->getNumInterfaces(); i++)
00374     {
00375         InterfaceEntry *ie = ift->getInterface(i);
00376         if (ie->ipv6Data()->hasAddress(dest))
00377             return true;
00378     }
00379 
00380     // then check for special, preassigned multicast addresses
00381     // (these addresses occur more rarely than specific interface addresses,
00382     // that's why we check for them last)
00383 
00384     if (dest==IPv6Address::ALL_NODES_1 || dest==IPv6Address::ALL_NODES_2)
00385         return true;
00386     if (isRouter() && (dest==IPv6Address::ALL_ROUTERS_1 || dest==IPv6Address::ALL_ROUTERS_2 || dest==IPv6Address::ALL_ROUTERS_5))
00387         return true;
00388 
00389     // check for solicited-node multicast address
00390     if (dest.matches(IPv6Address::SOLICITED_NODE_PREFIX, 104))
00391     {
00392         for (int i=0; i<ift->getNumInterfaces(); i++)
00393         {
00394             InterfaceEntry *ie = ift->getInterface(i);
00395             if (ie->ipv6Data()->matchesSolicitedNodeMulticastAddress(dest))
00396                 return true;
00397         }
00398     }
00399     return false;
00400 }

const IPv6Address & RoutingTable6::lookupDestCache ( const IPv6Address dest,
int &  outInterfaceId 
) const

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.

Referenced by IPv6::routePacket().

00403 {
00404     Enter_Method("lookupDestCache(%s)", dest.str().c_str());
00405 
00406     DestCache::const_iterator it = destCache.find(dest);
00407     if (it == destCache.end())
00408     {
00409         outInterfaceId = -1;
00410         return IPv6Address::UNSPECIFIED_ADDRESS;
00411     }
00412     outInterfaceId = it->second.interfaceId;
00413     return it->second.nextHopAddr;
00414 }

const IPv6Route * RoutingTable6::doLongestPrefixMatch ( const IPv6Address dest  ) 

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

Referenced by IPv6NeighbourDiscovery::determineNextHop(), and IPv6::routePacket().

00417 {
00418     Enter_Method("doLongestPrefixMatch(%s)", dest.str().c_str());
00419 
00420     // we'll just stop at the first match, because the table is sorted
00421     // by prefix lengths and metric (see addRoute())
00422     for (RouteList::const_iterator it=routeList.begin(); it!=routeList.end(); it++)
00423     {
00424         if (dest.matches((*it)->getDestPrefix(),(*it)->getPrefixLength()))
00425         {
00426             // FIXME proofread this code, iterator invalidation-wise, etc
00427             bool entryExpired = false;
00428             if (simTime() > (*it)->getExpiryTime() && (*it)->getExpiryTime() != 0)//since 0 represents infinity.
00429             {
00430                 EV << "Expired prefix detected!!" << endl;
00431                 removeOnLinkPrefix((*it)->getDestPrefix(), (*it)->getPrefixLength());
00432                 entryExpired = true;
00433             }
00434             if (entryExpired == false) return *it;
00435         }
00436     }
00437     // FIXME todo: if we selected an expired route, throw it out and select again!
00438     return NULL;
00439 }

bool RoutingTable6::isPrefixPresent ( const IPv6Address prefix  )  const [virtual]

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

Referenced by IPv6NeighbourDiscovery::processRAPrefixInfo().

00442 {
00443     for (RouteList::const_iterator it=routeList.begin(); it!=routeList.end(); it++)
00444         if (prefix.matches((*it)->getDestPrefix(),128))
00445             return true;
00446     return false;
00447 }

void RoutingTable6::updateDestCache ( const IPv6Address dest,
const IPv6Address nextHopAddr,
int  interfaceId 
) [virtual]

Add or update a destination cache entry.

Referenced by IPv6NeighbourDiscovery::determineNextHop(), and IPv6::routePacket().

00450 {
00451     // FIXME this performs 2 lookups -- optimize to do only one
00452     destCache[dest].nextHopAddr = nextHopAddr;
00453     destCache[dest].interfaceId = interfaceId;
00454 
00455     updateDisplayString();
00456 }

void RoutingTable6::purgeDestCache (  )  [virtual]

Discard all entries in destination cache

00459 {
00460     destCache.clear();
00461     updateDisplayString();
00462 }

void RoutingTable6::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.

Referenced by IPv6NeighbourDiscovery::timeoutDefaultRouter().

00465 {
00466     for (DestCache::iterator it=destCache.begin(); it!=destCache.end(); )
00467     {
00468         if (it->second.interfaceId==interfaceId && it->second.nextHopAddr==nextHopAddr)
00469         {
00470             // move the iterator past this element before removing it
00471             DestCache::iterator oldIt = it++;
00472             destCache.erase(oldIt);
00473         }
00474         else
00475         {
00476             it++;
00477         }
00478     }
00479 
00480     updateDisplayString();
00481 }

void RoutingTable6::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.

Referenced by IPv6NeighbourDiscovery::processRAPrefixInfo().

00485 {
00486     // see if prefix exists in table
00487     IPv6Route *route = NULL;
00488     for (RouteList::iterator it=routeList.begin(); it!=routeList.end(); it++)
00489     {
00490         if ((*it)->getSrc()==IPv6Route::FROM_RA && (*it)->getDestPrefix()==destPrefix && (*it)->getPrefixLength()==prefixLength)
00491         {
00492             route = *it;
00493             break;
00494         }
00495     }
00496 
00497     if (route==NULL)
00498     {
00499         // create new route object
00500         IPv6Route *route = new IPv6Route(destPrefix, prefixLength, IPv6Route::FROM_RA);
00501         route->setInterfaceId(interfaceId);
00502         route->setExpiryTime(expiryTime);
00503         route->setMetric(0);
00504 
00505         // then add it
00506         addRoute(route);
00507     }
00508     else
00509     {
00510         // update existing one; notification-wise, we pretend the route got removed then re-added
00511         nb->fireChangeNotification(NF_IPv6_ROUTE_DELETED, route);
00512         route->setInterfaceId(interfaceId);
00513         route->setExpiryTime(expiryTime);
00514         nb->fireChangeNotification(NF_IPv6_ROUTE_ADDED, route);
00515     }
00516 
00517     updateDisplayString();
00518 }

void RoutingTable6::removeOnLinkPrefix ( 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.

Referenced by doLongestPrefixMatch(), IPv6NeighbourDiscovery::processRAPrefixInfo(), and IPv6NeighbourDiscovery::timeoutPrefixEntry().

00560 {
00561     // scan the routing table for this prefix and remove it
00562     for (RouteList::iterator it=routeList.begin(); it!=routeList.end(); it++)
00563     {
00564         if ((*it)->getSrc()==IPv6Route::FROM_RA && (*it)->getDestPrefix()==destPrefix && (*it)->getPrefixLength()==prefixLength)
00565         {
00566             routeList.erase(it);
00567             return; // there can be only one such route, addOrUpdateOnLinkPrefix() guarantees that
00568         }
00569     }
00570 
00571     updateDisplayString();
00572 }

void RoutingTable6::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.

Referenced by FlatNetworkConfigurator6::addOwnAdvPrefixRoutes(), and initialize().

00522 {
00523     // FIXME this is very similar to the one above -- refactor!!
00524 
00525     // see if prefix exists in table
00526     IPv6Route *route = NULL;
00527     for (RouteList::iterator it=routeList.begin(); it!=routeList.end(); it++)
00528     {
00529         if ((*it)->getSrc()==IPv6Route::OWN_ADV_PREFIX && (*it)->getDestPrefix()==destPrefix && (*it)->getPrefixLength()==prefixLength)
00530         {
00531             route = *it;
00532             break;
00533         }
00534     }
00535 
00536     if (route==NULL)
00537     {
00538         // create new route object
00539         IPv6Route *route = new IPv6Route(destPrefix, prefixLength, IPv6Route::OWN_ADV_PREFIX);
00540         route->setInterfaceId(interfaceId);
00541         route->setExpiryTime(expiryTime);
00542         route->setMetric(0);
00543 
00544         // then add it
00545         addRoute(route);
00546     }
00547     else
00548     {
00549         // update existing one; notification-wise, we pretend the route got removed then re-added
00550         nb->fireChangeNotification(NF_IPv6_ROUTE_DELETED, route);
00551         route->setInterfaceId(interfaceId);
00552         route->setExpiryTime(expiryTime);
00553         nb->fireChangeNotification(NF_IPv6_ROUTE_ADDED, route);
00554     }
00555 
00556     updateDisplayString();
00557 }

void RoutingTable6::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.

Referenced by FlatNetworkConfigurator6::addStaticRoutes().

00577 {
00578     // create route object
00579     IPv6Route *route = new IPv6Route(destPrefix, prefixLength, IPv6Route::STATIC);
00580     route->setInterfaceId(interfaceId);
00581     route->setNextHop(nextHop);
00582     if (metric==0)
00583         metric = 10; // TBD should be filled from interface metric
00584     route->setMetric(metric);
00585 
00586     // then add it
00587     addRoute(route);
00588 }

void RoutingTable6::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().

Referenced by IPv6NeighbourDiscovery::processRAForRouterUpdates().

00592 {
00593     // create route object
00594     IPv6Route *route = new IPv6Route(IPv6Address(), 0, IPv6Route::FROM_RA);
00595     route->setInterfaceId(ifID);
00596     route->setNextHop(nextHop);
00597     route->setMetric(10);//FIXME:should be filled from interface metric
00598 
00599     // then add it
00600     addRoute(route);
00601 }

void RoutingTable6::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.

00604 {
00605     ASSERT(route->getSrc()==IPv6Route::ROUTING_PROT);
00606     addRoute(route);
00607 }

void RoutingTable6::removeRoute ( IPv6Route route  )  [virtual]

Deletes the given route from the route table.

00633 {
00634     RouteList::iterator it = std::find(routeList.begin(), routeList.end(), route);
00635     ASSERT(it!=routeList.end());
00636 
00637     nb->fireChangeNotification(NF_IPv6_ROUTE_DELETED, route); // rather: going to be deleted
00638 
00639     routeList.erase(it);
00640     delete route;
00641 
00642     updateDisplayString();
00643 }

int RoutingTable6::getNumRoutes (  )  const [virtual]

Return the number of routes.

Referenced by updateDisplayString().

00646 {
00647     return routeList.size();
00648 }

IPv6Route * RoutingTable6::getRoute ( int  i  )  [virtual]

Return the ith route.

00651 {
00652     ASSERT(i>=0 && i<(int)routeList.size());
00653     return routeList[i];
00654 }


Friends And Related Function Documentation

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

00068 {
00069     os << "if=" << e.interfaceId << " " << e.nextHopAddr;  //FIXME try printing interface name
00070     return os;
00071 };


Member Data Documentation

bool RoutingTable6::isrouter [protected]


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

Generated on Fri Mar 20 18:51:20 2009 for INET Framework for OMNeT++/OMNEST by  doxygen 1.5.5