Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

RoutingTable6 Class Reference

#include <RoutingTable6.h>

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 ()
bool isRouter () const
Interfaces
InterfaceEntryinterfaceByAddress (const IPv6Address &address)
Routing functions
bool localDeliver (const IPv6Address &dest)
const IPv6AddresslookupDestCache (const IPv6Address &dest, int &outInterfaceId)
const IPv6RoutedoLongestPrefixMatch (const IPv6Address &dest)
bool isPrefixPresent (const IPv6Address &prefix)
Managing the destination cache
void updateDestCache (const IPv6Address &dest, const IPv6Address &nextHopAddr, int interfaceId)
void purgeDestCache ()
void purgeDestCacheEntriesToNeighbour (const IPv6Address &nextHopAddr, int interfaceId)
Managing prefixes and the route table
void addOrUpdateOnLinkPrefix (const IPv6Address &destPrefix, int prefixLength, int interfaceId, simtime_t expiryTime)
void removeOnLinkPrefix (const IPv6Address &destPrefix, int prefixLength)
void addOrUpdateOwnAdvPrefix (const IPv6Address &destPrefix, int prefixLength, int interfaceId, simtime_t expiryTime)
void addStaticRoute (const IPv6Address &destPrefix, int prefixLength, unsigned int interfaceId, const IPv6Address &nextHop, int metric=0)
void addDefaultRoute (const IPv6Address &raSrcAddr, unsigned int ifID, simtime_t routerLifetime)
void addRoutingProtocolRoute (IPv6Route *route)
void removeRoute (IPv6Route *route)
int numRoutes () const
IPv6Routeroute (int i)

Protected Member Functions

void updateDisplayString ()
int numInitStages () const
void initialize (int stage)
void parseXMLConfigFile ()
void handleMessage (cMessage *)

Private Types

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

Private Member Functions

void addRoute (IPv6Route *route)
void configureInterfaceForIPv6 (InterfaceEntry *ie)
void assignRequiredNodeAddresses (InterfaceEntry *ie)
void configureInterfaceFromXML (InterfaceEntry *ie, cXMLElement *cfg)

Static Private Member Functions

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

Private Attributes

InterfaceTableift
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 [private]
 

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


Constructor & Destructor Documentation

RoutingTable6::RoutingTable6  ) 
 

00075 {
00076 }

RoutingTable6::~RoutingTable6  )  [virtual]
 

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


Member Function Documentation

void RoutingTable6::addDefaultRoute const IPv6Address raSrcAddr,
unsigned int  ifID,
simtime_t  routerLifetime
 

Adds a default route for a host. This method requires the RA's source address and the router expiry time plus the simTime().

00552 {
00553     // create route object
00554     IPv6Route *route = new IPv6Route(IPv6Address(), 0, IPv6Route::FROM_RA);
00555     route->setInterfaceID(ifID);
00556     route->setNextHop(nextHop);
00557     route->setMetric(10);//FIXME:should be filled from interface metric
00558 
00559     // then add it
00560     addRoute(route);
00561 }

void RoutingTable6::addOrUpdateOnLinkPrefix const IPv6Address destPrefix,
int  prefixLength,
int  interfaceId,
simtime_t  expiryTime
 

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 InterfaceTable (see IPv6InterfaceData); that has to be done separately.

00447 {
00448     // see if prefix exists in table
00449     IPv6Route *route = NULL;
00450     for (RouteList::iterator it=routeList.begin(); it!=routeList.end(); it++)
00451     {
00452         if ((*it)->src()==IPv6Route::FROM_RA && (*it)->destPrefix()==destPrefix && (*it)->prefixLength()==prefixLength)
00453         {
00454             route = *it;
00455             break;
00456         }
00457     }
00458 
00459     if (route==NULL)
00460     {
00461         // create new route object
00462         IPv6Route *route = new IPv6Route(destPrefix, prefixLength, IPv6Route::FROM_RA);
00463         route->setInterfaceID(interfaceId);
00464         route->setExpiryTime(expiryTime);
00465         route->setMetric(0);
00466 
00467         // then add it
00468         addRoute(route);
00469     }
00470     else
00471     {
00472         // update existing one
00473         route->setInterfaceID(interfaceId);
00474         route->setExpiryTime(expiryTime);
00475     }
00476 
00477     updateDisplayString();
00478 }

void RoutingTable6::addOrUpdateOwnAdvPrefix const IPv6Address destPrefix,
int  prefixLength,
int  interfaceId,
simtime_t  expiryTime
 

Add route of type OWN_ADV_PREFIX. This is a prefix that *this* router advertises on this interface.

00482 {
00483     // FIXME this is very similar to the one above -- refactor!!
00484 
00485     // see if prefix exists in table
00486     IPv6Route *route = NULL;
00487     for (RouteList::iterator it=routeList.begin(); it!=routeList.end(); it++)
00488     {
00489         if ((*it)->src()==IPv6Route::OWN_ADV_PREFIX && (*it)->destPrefix()==destPrefix && (*it)->prefixLength()==prefixLength)
00490         {
00491             route = *it;
00492             break;
00493         }
00494     }
00495 
00496     if (route==NULL)
00497     {
00498         // create new route object
00499         IPv6Route *route = new IPv6Route(destPrefix, prefixLength, IPv6Route::OWN_ADV_PREFIX);
00500         route->setInterfaceID(interfaceId);
00501         route->setExpiryTime(expiryTime);
00502         route->setMetric(0);
00503 
00504         // then add it
00505         addRoute(route);
00506     }
00507     else
00508     {
00509         // update existing one
00510         route->setInterfaceID(interfaceId);
00511         route->setExpiryTime(expiryTime);
00512     }
00513 
00514     updateDisplayString();
00515 }

void RoutingTable6::addRoute IPv6Route route  )  [private]
 

00580 {
00581     routeList.push_back(route);
00582 
00583     // we keep entries sorted by prefix length in routeList, so that we can
00584     // stop at the first match when doing the longest prefix matching
00585     std::sort(routeList.begin(), routeList.end(), routeLessThan);
00586 
00587     updateDisplayString();
00588 }

void RoutingTable6::addRoutingProtocolRoute IPv6Route route  ) 
 

Adds the given route (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.

00564 {
00565     ASSERT(route->src()==IPv6Route::ROUTING_PROT);
00566     addRoute(route);
00567 }

void RoutingTable6::addStaticRoute const IPv6Address destPrefix,
int  prefixLength,
unsigned int  interfaceId,
const IPv6Address nextHop,
int  metric = 0
 

Creates a static route. If metric is omitted, it gets initialized to the interface's metric value.

00535 {
00536     // create route object
00537     IPv6Route *route = new IPv6Route(destPrefix, prefixLength, IPv6Route::STATIC);
00538     route->setInterfaceID(interfaceId);
00539     route->setNextHop(nextHop);
00540     if (metric==0)
00541     {
00542         metric = 10; // TBD should be filled from interface metric
00543     }
00544     route->setMetric(metric);
00545 
00546     // then add it
00547     addRoute(route);
00548 }

void RoutingTable6::assignRequiredNodeAddresses InterfaceEntry ie  )  [private]
 

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.

00197 {
00198     //RFC 3513 Section 2.8:A Node's Required Addresses
00199     /*A host is required to recognize the following addresses as
00200     identifying itself:*/
00201 
00202     //o  The loopback address.
00203     if (ie->isLoopback())
00204     {
00205         ie->ipv6()->assignAddress(IPv6Address("::1"), false, 0, 0);
00206         return;
00207     }
00208     //o  Its required Link-Local Address for each interface.
00209     //IPv6Address linkLocalAddr = IPv6Address().formLinkLocalAddress(ie->interfaceToken());
00210     //ie->ipv6()->assignAddress(linkLocalAddr, true, 0, 0);
00211 
00212     /*o  Any additional Unicast and Anycast Addresses that have been configured
00213     for the node's interfaces (manually or automatically).*/
00214 
00215     // FIXME FIXME Andras: commented out the following lines, because these addresses
00216     // are implicitly checked for in localDeliver()  (we don't want redundancy,
00217     // and manually adding solicited-node mcast address for each and every address
00218     // is very error-prone!)
00219     //
00220     //o  The All-Nodes Multicast Addresses defined in section 2.7.1.
00221 
00222     /*o  The Solicited-Node Multicast Address for each of its unicast and anycast
00223     addresses.*/
00224 
00225     //o  Multicast Addresses of all other groups to which the node belongs.
00226 
00227     /*A router is required to recognize all addresses that a host is
00228     required to recognize, plus the following addresses as identifying
00229     itself:*/
00230     /*o  The Subnet-Router Anycast Addresses for all interfaces for
00231     which it is configured to act as a router.*/
00232 
00233     //o  All other Anycast Addresses with which the router has been configured.
00234     //o  The All-Routers Multicast Addresses defined in section 2.7.1.
00235 }

void RoutingTable6::configureInterfaceForIPv6 InterfaceEntry ie  )  [private]
 

00179 {
00180     IPv6InterfaceData *ipv6IfData = new IPv6InterfaceData();
00181     ie->setIPv6Data(ipv6IfData);
00182 
00183     // for routers, turn on advertisements by default
00184     //FIXME: we will use this isRouter flag for now. what if future implementations
00185     //have 2 interfaces where one interface is configured as a router and the other
00186     //as a host?
00187     ipv6IfData->setAdvSendAdvertisements(isrouter);//Added by WEI
00188 
00189     // metric: some hints: OSPF cost (2e9/bps value), MS KB article Q299540, ...
00190     //d->setMetric((int)ceil(2e9/ie->datarate())); // use OSPF cost as default
00191     //FIXME TBD fill in the rest
00192 
00193     assignRequiredNodeAddresses(ie);
00194 }

void RoutingTable6::configureInterfaceFromXML InterfaceEntry ie,
cXMLElement *  cfg
[private]
 

00253 {
00254     /*XML parsing capabilities tweaked by WEI. For now, we can configure a specific
00255     node's interface. We can set advertising prefixes and other variables to be used
00256     in RAs. The IPv6 interface data gets overwritten if lines 249 to 262 is uncommented.
00257     The fix is to create an XML file with all the default values. Customised XML files
00258     can be used for future protocols that requires different values. (MIPv6)*/
00259     IPv6InterfaceData *d = ie->ipv6();
00260 
00261     // parse basic config (attributes)
00262     d->setAdvSendAdvertisements(toBool(getRequiredAttr(cfg, "AdvSendAdvertisements")));
00263     //TODO: leave this off first!! They overwrite stuff!
00264 /* TODO: Wei commented out the stuff below. To be checked why (Andras).
00265     d->setMaxRtrAdvInterval(OPP_Global::atod(getRequiredAttr(cfg, "MaxRtrAdvInterval")));
00266     d->setMinRtrAdvInterval(OPP_Global::atod(getRequiredAttr(cfg, "MinRtrAdvInterval")));
00267     d->setAdvManagedFlag(toBool(getRequiredAttr(cfg, "AdvManagedFlag")));
00268     d->setAdvOtherConfigFlag(toBool(getRequiredAttr(cfg, "AdvOtherConfigFlag")));
00269     d->setAdvLinkMTU(OPP_Global::atoul(getRequiredAttr(cfg, "AdvLinkMTU")));
00270     d->setAdvReachableTime(OPP_Global::atoul(getRequiredAttr(cfg, "AdvReachableTime")));
00271     d->setAdvRetransTimer(OPP_Global::atoul(getRequiredAttr(cfg, "AdvRetransTimer")));
00272     d->setAdvCurHopLimit(OPP_Global::atoul(getRequiredAttr(cfg, "AdvCurHopLimit")));
00273     d->setAdvDefaultLifetime(OPP_Global::atoul(getRequiredAttr(cfg, "AdvDefaultLifetime")));
00274     ie->setMtu(OPP_Global::atoul(getRequiredAttr(cfg, "HostLinkMTU")));
00275     d->setCurHopLimit(OPP_Global::atoul(getRequiredAttr(cfg, "HostCurHopLimit")));
00276     d->setBaseReachableTime(OPP_Global::atoul(getRequiredAttr(cfg, "HostBaseReachableTime")));
00277     d->setRetransTimer(OPP_Global::atoul(getRequiredAttr(cfg, "HostRetransTimer")));
00278     d->setDupAddrDetectTransmits(OPP_Global::atoul(getRequiredAttr(cfg, "HostDupAddrDetectTransmits")));
00279 */
00280 
00281     // parse prefixes (AdvPrefix elements; they should be inside an AdvPrefixList
00282     // element, but we don't check that)
00283     cXMLElementList prefixList = cfg->getElementsByTagName("AdvPrefix");
00284     for (unsigned int i=0; i<prefixList.size(); i++)
00285     {
00286         cXMLElement *node = prefixList[i];
00287         IPv6InterfaceData::AdvPrefix prefix;
00288 
00289         // FIXME todo implement: advValidLifetime, advPreferredLifetime can
00290         // store (absolute) expiry time (if >0) or lifetime (delta) (if <0);
00291         // 0 should be treated as infinity
00292         int pfxLen;
00293         if (!prefix.prefix.tryParseAddrWithPrefix(node->getNodeValue(),pfxLen))
00294             opp_error("element <%s> at %s: wrong IPv6Address/prefix syntax %s",
00295                       node->getTagName(), node->getSourceLocation(), node->getNodeValue());
00296         prefix.prefixLength = pfxLen;
00297         prefix.advValidLifetime = OPP_Global::atoul(getRequiredAttr(node, "AdvValidLifetime"));
00298         prefix.advOnLinkFlag = toBool(getRequiredAttr(node, "AdvOnLinkFlag"));
00299         prefix.advPreferredLifetime = OPP_Global::atoul(getRequiredAttr(node, "AdvPreferredLifetime"));
00300         prefix.advAutonomousFlag = toBool(getRequiredAttr(node, "AdvAutonomousFlag"));
00301         d->addAdvPrefix(prefix);
00302     }
00303 
00304     // parse addresses
00305     cXMLElementList addrList = cfg->getChildrenByTagName("inetAddr");
00306     for (unsigned int k=0; k<addrList.size(); k++)
00307     {
00308         cXMLElement *node = addrList[k];
00309         IPv6Address address(node->getNodeValue());
00310         //We can now decide if the address is tentative or not.
00311         d->assignAddress(address, toBool(getRequiredAttr(node, "tentative")), 0, 0);  // set up with infinite lifetimes
00312     }
00313 }

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.

00379 {
00380     Enter_Method("doLongestPrefixMatch(%s)", dest.str().c_str());
00381 
00382     // we'll just stop at the first match, because the table is sorted
00383     // by prefix lengths and metric (see addRoute())
00384     for (RouteList::iterator it=routeList.begin(); it!=routeList.end(); it++)
00385     {
00386         if (dest.matches((*it)->destPrefix(),(*it)->prefixLength()))
00387         {
00388             // FIXME proofread this code, iterator invalidation-wise, etc
00389             bool entryExpired = false;
00390             if (simTime() > (*it)->expiryTime() && (*it)->expiryTime() != 0)//since 0 represents infinity.
00391             {
00392                 EV << "Expired prefix detected!!" << endl;
00393                 removeOnLinkPrefix((*it)->destPrefix(), (*it)->prefixLength());
00394                 entryExpired = true;
00395             }
00396             if (entryExpired == false) return *it;
00397         }
00398     }
00399     // FIXME todo: if we selected an expired route, throw it out and select again!
00400     return NULL;
00401 }

void RoutingTable6::handleMessage cMessage *   )  [protected]
 

Raises an error.

00174 {
00175     opp_error("This module doesn't process messages");
00176 }

void RoutingTable6::initialize int  stage  )  [protected]
 

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

InterfaceEntry * RoutingTable6::interfaceByAddress const IPv6Address address  ) 
 

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

00316 {
00317     Enter_Method("interfaceByAddress(%s)=?", addr.str().c_str());
00318 
00319     if (addr.isUnspecified())
00320         return NULL;
00321     for (int i=0; i<ift->numInterfaces(); ++i)
00322     {
00323         InterfaceEntry *ie = ift->interfaceAt(i);
00324         if (ie->ipv6()->hasAddress(addr))
00325             return ie;
00326     }
00327     return NULL;
00328 }

bool RoutingTable6::isPrefixPresent const IPv6Address prefix  ) 
 

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

00404 {
00405     for (RouteList::iterator it=routeList.begin(); it!=routeList.end(); it++)
00406         if (prefix.matches((*it)->destPrefix(),128))
00407             return true;
00408     return false;
00409 }

bool RoutingTable6::isRouter  )  const [inline]
 

IP forwarding on/off

00171 {return isrouter;}

bool RoutingTable6::localDeliver const IPv6Address dest  ) 
 

Checks if the address is one of the host's addresses, i.e. assigned to one of its interfaces (tentatively or not).

00331 {
00332     Enter_Method("localDeliver(%s) y/n", dest.str().c_str());
00333 
00334     // first, check if we have an interface with this address
00335     for (int i=0; i<ift->numInterfaces(); i++)
00336     {
00337         InterfaceEntry *ie = ift->interfaceAt(i);
00338         if (ie->ipv6()->hasAddress(dest))
00339             return true;
00340     }
00341 
00342     // then check for special, preassigned multicast addresses
00343     // (these addresses occur more rarely than specific interface addresses,
00344     // that's why we check for them last)
00345 
00346     if (dest==IPv6Address::ALL_NODES_1 || dest==IPv6Address::ALL_NODES_2)
00347         return true;
00348     if (isRouter() && (dest==IPv6Address::ALL_ROUTERS_1 || dest==IPv6Address::ALL_ROUTERS_2 || dest==IPv6Address::ALL_ROUTERS_5))
00349         return true;
00350 
00351     // check for solicited-node multicast address
00352     if (dest.matches(IPv6Address::SOLICITED_NODE_PREFIX, 104))
00353     {
00354         for (int i=0; i<ift->numInterfaces(); i++)
00355         {
00356             InterfaceEntry *ie = ift->interfaceAt(i);
00357             if (ie->ipv6()->matchesSolicitedNodeMulticastAddress(dest))
00358                 return true;
00359         }
00360     }
00361     return false;
00362 }

const IPv6Address & RoutingTable6::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.

00365 {
00366     Enter_Method("lookupDestCache(%s)", dest.str().c_str());
00367 
00368     DestCache::iterator it = destCache.find(dest);
00369     if (it == destCache.end())
00370     {
00371         outInterfaceId = -1;
00372         return IPv6Address::UNSPECIFIED_ADDRESS;
00373     }
00374     outInterfaceId = it->second.interfaceId;
00375     return it->second.nextHopAddr;
00376 }

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

00150 {return 5;}

int RoutingTable6::numRoutes  )  const
 

Return the number of routes.

00600 {
00601     return routeList.size();
00602 }

void RoutingTable6::parseXMLConfigFile  )  [protected]
 

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

void RoutingTable6::purgeDestCache  ) 
 

Discard all entries in destination cache

00421 {
00422     destCache.clear();
00423     updateDisplayString();
00424 }

void RoutingTable6::purgeDestCacheEntriesToNeighbour const IPv6Address nextHopAddr,
int  interfaceId
 

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.

00427 {
00428     for (DestCache::iterator it=destCache.begin(); it!=destCache.end(); )
00429     {
00430         if (it->second.interfaceId==interfaceId && it->second.nextHopAddr==nextHopAddr)
00431         {
00432             // move the iterator past this element before removing it
00433             DestCache::iterator oldIt = it++;
00434             destCache.erase(oldIt);
00435         }
00436         else
00437         {
00438             it++;
00439         }
00440     }
00441 
00442     updateDisplayString();
00443 }

void RoutingTable6::removeOnLinkPrefix const IPv6Address destPrefix,
int  prefixLength
 

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 InterfaceTable (see IPv6InterfaceData); that has to be done separately.

00518 {
00519     // scan the routing table for this prefix and remove it
00520     for (RouteList::iterator it=routeList.begin(); it!=routeList.end(); it++)
00521     {
00522         if ((*it)->src()==IPv6Route::FROM_RA && (*it)->destPrefix()==destPrefix && (*it)->prefixLength()==prefixLength)
00523         {
00524             routeList.erase(it);
00525             return; // there can be only one such route, addOrUpdateOnLinkPrefix() guarantees that
00526         }
00527     }
00528 
00529     updateDisplayString();
00530 }

void RoutingTable6::removeRoute IPv6Route route  ) 
 

Deletes the given route from the route table.

00591 {
00592     RouteList::iterator it = std::find(routeList.begin(), routeList.end(), route);
00593     ASSERT(it!=routeList.end());
00594     routeList.erase(it);
00595 
00596     updateDisplayString();
00597 }

IPv6Route * RoutingTable6::route int  i  ) 
 

Return the ith route.

00605 {
00606     ASSERT(i>=0 && i<routeList.size());
00607     return routeList[i];
00608 }

bool RoutingTable6::routeLessThan const IPv6Route a,
const IPv6Route b
[static, private]
 

00570 {
00571     // helper for sort() in addRoute(). We want routes with longer
00572     // prefixes to be at front, so we compare them as "less".
00573     // For metric, a smaller value is better (we report that as "less").
00574     if (a->prefixLength()!=b->prefixLength())
00575         return a->prefixLength() > b->prefixLength();
00576     return a->metric() < b->metric();
00577 }

void RoutingTable6::updateDestCache const IPv6Address dest,
const IPv6Address nextHopAddr,
int  interfaceId
 

Add or update a destination cache entry.

00412 {
00413     // FIXME this performs 2 lookups -- optimize to do only one
00414     destCache[dest].nextHopAddr = nextHopAddr;
00415     destCache[dest].interfaceId = interfaceId;
00416 
00417     updateDisplayString();
00418 }

void RoutingTable6::updateDisplayString  )  [protected]
 

00164 {
00165     if (!ev.isGUI())
00166         return;
00167 
00168     char buf[80];
00169     sprintf(buf, "%d routes\n%d destcache entries", numRoutes(), destCache.size());
00170     displayString().setTagArg("t",0,buf);
00171 }


Friends And Related Function Documentation

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

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


Member Data Documentation

DestCache RoutingTable6::destCache [private]
 

InterfaceTable* RoutingTable6::ift [private]
 

bool RoutingTable6::isrouter [private]
 

RouteList RoutingTable6::routeList [private]
 


The documentation for this class was generated from the following files:
Generated on Thu Oct 19 18:22:28 2006 for INET Framework for OMNeT++/OMNEST by  doxygen 1.4.0