#include <RoutingTable6.h>
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 InterfaceEntry * | getInterfaceByAddress (const IPv6Address &address) |
Routing functions | |
virtual bool | isLocalAddress (const IPv6Address &dest) const |
const IPv6Address & | lookupDestCache (const IPv6Address &dest, int &outInterfaceId) const |
const IPv6Route * | doLongestPrefixMatch (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 IPv6Route * | getRoute (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 | |
IInterfaceTable * | ift |
NotificationBoard * | nb |
bool | isrouter |
DestCache | destCache |
RouteList | routeList |
Friends | |
std::ostream & | operator<< (std::ostream &os, const DestCacheEntry &e) |
Classes | |
struct | DestCacheEntry |
typedef std::map<IPv6Address,DestCacheEntry> RoutingTable6::DestCache [protected] |
typedef std::vector<IPv6Route*> RoutingTable6::RouteList [protected] |
RoutingTable6::~RoutingTable6 | ( | ) | [virtual] |
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 }
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 }
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] |
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] |
IP forwarding on/off
Referenced by IPv6NeighbourDiscovery::initialize(), isLocalAddress(), IPv6::routeMulticastPacket(), IPv6::routePacket(), and IPv6NeighbourDiscovery::sendSolicitedNA().
00179 {return isrouter;}
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] |
std::ostream& operator<< | ( | std::ostream & | os, | |
const DestCacheEntry & | e | |||
) | [friend] |
IInterfaceTable* RoutingTable6::ift [protected] |
Referenced by getInterfaceByAddress(), initialize(), isLocalAddress(), and parseXMLConfigFile().
NotificationBoard* RoutingTable6::nb [protected] |
Referenced by addOrUpdateOnLinkPrefix(), addOrUpdateOwnAdvPrefix(), addRoute(), initialize(), and removeRoute().
bool RoutingTable6::isrouter [protected] |
Referenced by configureInterfaceForIPv6(), and initialize().
DestCache RoutingTable6::destCache [protected] |
RouteList RoutingTable6::routeList [protected] |