FlatNetworkConfigurator6.cc

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2005 Eric Wu
00003 // Copyright (C) 2004 Andras Varga
00004 //
00005 // This program is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 //
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU Lesser General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU Lesser General Public License
00016 // along with this program; if not, see <http://www.gnu.org/licenses/>.
00017 //
00018 
00019 #include <algorithm>
00020 #include "FlatNetworkConfigurator6.h"
00021 #include "IInterfaceTable.h"
00022 #include "IPAddressResolver.h"
00023 #ifndef WITHOUT_IPv6
00024 #include "IPv6InterfaceData.h"
00025 #include "RoutingTable6.h"
00026 #endif
00027 
00028 // FIXME UPDATE DOCU!!!!!!!
00029 
00030 Define_Module(FlatNetworkConfigurator6);
00031 
00032 void FlatNetworkConfigurator6::initialize(int stage)
00033 {
00034 #ifndef WITHOUT_IPv6
00035     // FIXME refactor: make routers[] array? (std::vector<cTopology::Node*>)
00036     // FIXME: spare common beginning for all stages?
00037 
00038     cTopology topo("topo");
00039 
00040     // extract topology
00041     topo.extractByProperty("node");
00042     EV << "cTopology found " << topo.getNumNodes() << " nodes\n";
00043 
00044     if (stage==2)
00045     {
00046         configureAdvPrefixes(topo);
00047     }
00048     else if (stage==3)
00049     {
00050         addOwnAdvPrefixRoutes(topo);
00051         addStaticRoutes(topo);
00052     }
00053 #else
00054     error("FlatNetworkConfigurator6 not supported: WITHOUT_IPv6 option was defined during compilation");
00055 #endif
00056 }
00057 
00058 void FlatNetworkConfigurator6::handleMessage(cMessage *)
00059 {
00060     error("this module doesn't handle messages, it runs only in initialize()");
00061 }
00062 
00063 void FlatNetworkConfigurator6::setDisplayString(int numIPNodes, int numNonIPNodes)
00064 {
00065     // update display string
00066     char buf[80];
00067     sprintf(buf, "%d IPv6 nodes\n%d non-IP nodes", numIPNodes, numNonIPNodes);
00068     getDisplayString().setTagArg("t", 0, buf);
00069 }
00070 
00071 bool FlatNetworkConfigurator6::isIPNode(cTopology::Node *node)
00072 {
00073     return IPAddressResolver().findInterfaceTableOf(node->getModule()) != NULL;
00074 }
00075 
00076 #ifndef WITHOUT_IPv6
00077 void FlatNetworkConfigurator6::configureAdvPrefixes(cTopology& topo)
00078 {
00079     // assign advertised prefixes to all router interfaces
00080     for (int i = 0; i < topo.getNumNodes(); i++)
00081     {
00082         // skip bus types
00083         if (!isIPNode(topo.getNode(i)))
00084             continue;
00085 
00086         int nodeIndex = i;
00087 
00088         // find interface table and assign address to all (non-loopback) interfaces
00089         cModule *mod = topo.getNode(i)->getModule();
00090         IInterfaceTable *ift = IPAddressResolver().interfaceTableOf(mod);
00091         RoutingTable6 *rt = IPAddressResolver().routingTable6Of(mod);
00092 
00093         // skip hosts
00094         if (!rt->par("isRouter").boolValue())
00095             continue;
00096 
00097         // assign prefix to interfaces
00098         for (int k = 0; k < ift->getNumInterfaces(); k++)
00099         {
00100             InterfaceEntry *ie = ift->getInterface(k);
00101             if (!ie->ipv6Data() || ie->isLoopback())
00102                 continue;
00103             if (ie->ipv6Data()->getNumAdvPrefixes()>0)
00104                 continue;  // already has one
00105 
00106             // add a prefix
00107             IPv6Address prefix(0xaaaa0000+nodeIndex, ie->getNetworkLayerGateIndex()<<16, 0, 0);
00108             ASSERT(prefix.isGlobal());
00109 
00110             IPv6InterfaceData::AdvPrefix p;
00111             p.prefix = prefix;
00112             p.prefixLength = 64;
00113             // RFC 2461:6.2.1. Only default values are used in FlatNetworkConfigurator6
00114             // Default: 2592000 seconds (30 days), fixed (i.e., stays the same in
00115             // consecutive advertisements).
00116             p.advValidLifetime = 2592000;
00117             // Default: TRUE
00118             p.advOnLinkFlag = true;
00119             // Default: 604800 seconds (7 days), fixed (i.e., stays the same in consecutive
00120             // advertisements).
00121             p.advPreferredLifetime = 604800;
00122             // Default: TRUE
00123             p.advAutonomousFlag = true;
00124             ie->ipv6Data()->addAdvPrefix(p);
00125 
00126             // add a link-local address (tentative) if it doesn't have one
00127             if (ie->ipv6Data()->getLinkLocalAddress().isUnspecified())
00128                 ie->ipv6Data()->assignAddress(IPv6Address::formLinkLocalAddress(ie->getInterfaceToken()), true, 0, 0);
00129         }
00130     }
00131 }
00132 
00133 void FlatNetworkConfigurator6::addOwnAdvPrefixRoutes(cTopology& topo)
00134 {
00135     // add globally routable prefixes to routing table
00136     for (int i = 0; i < topo.getNumNodes(); i++)
00137     {
00138         cTopology::Node *node = topo.getNode(i);
00139 
00140         // skip bus types
00141         if (!isIPNode(node))
00142             continue;
00143 
00144         RoutingTable6 *rt = IPAddressResolver().routingTable6Of(node->getModule());
00145         IInterfaceTable *ift = IPAddressResolver().interfaceTableOf(node->getModule());
00146 
00147         // skip hosts
00148         if (!rt->par("isRouter").boolValue())
00149             continue;
00150 
00151         // add globally routable prefixes to routing table
00152         for (int x = 0; x < ift->getNumInterfaces(); x++)
00153         {
00154             InterfaceEntry *ie = ift->getInterface(x);
00155 
00156             if (ie->isLoopback())
00157                 continue;
00158 
00159             for (int y = 0; y < ie->ipv6Data()->getNumAdvPrefixes(); y++)
00160                 if (ie->ipv6Data()->getAdvPrefix(y).prefix.isGlobal())
00161                     rt->addOrUpdateOwnAdvPrefix(ie->ipv6Data()->getAdvPrefix(y).prefix,
00162                                                 ie->ipv6Data()->getAdvPrefix(y).prefixLength,
00163                                                 ie->getInterfaceId(), 0);
00164         }
00165     }
00166 }
00167 
00168 void FlatNetworkConfigurator6::addStaticRoutes(cTopology& topo)
00169 {
00170     int numIPNodes = 0;
00171 
00172     // fill in routing tables
00173     for (int i = 0; i < topo.getNumNodes(); i++)
00174     {
00175         cTopology::Node *destNode = topo.getNode(i);
00176 
00177         // skip bus types
00178         if (!isIPNode(destNode))
00179             continue;
00180 /*
00181     void addOrUpdateOwnAdvPrefix(const IPv6Address& destPrefix, int prefixLength,
00182                                  int interfaceId, simtime_t expiryTime);
00183 */
00184 
00185         numIPNodes++; // FIXME split into num hosts, num routers
00186         RoutingTable6 *destRt = IPAddressResolver().routingTable6Of(destNode->getModule());
00187         IInterfaceTable *destIft = IPAddressResolver().interfaceTableOf(destNode->getModule());
00188 
00189         // don't add routes towards hosts
00190         if (!destRt->par("isRouter").boolValue())
00191             continue;
00192 
00193         // get a list of globally routable prefixes from the dest node
00194         std::vector<const IPv6InterfaceData::AdvPrefix*> destPrefixes;
00195         for (int x = 0; x < destIft->getNumInterfaces(); x++)
00196         {
00197             InterfaceEntry *destIf = destIft->getInterface(x);
00198 
00199             if (destIf->isLoopback())
00200                 continue;
00201 
00202             for (int y = 0; y < destIf->ipv6Data()->getNumAdvPrefixes(); y++)
00203                 if (destIf->ipv6Data()->getAdvPrefix(y).prefix.isGlobal())
00204                     destPrefixes.push_back(&destIf->ipv6Data()->getAdvPrefix(y));
00205         }
00206 
00207         std::string destModName = destNode->getModule()->getFullName();
00208 
00209         // calculate shortest paths from everywhere towards destNode
00210         topo.calculateUnweightedSingleShortestPathsTo(destNode);
00211 
00212         // add route (with dest=destPrefixes) to every router routing table in the network
00213         for (int j = 0; j < topo.getNumNodes(); j++)
00214         {
00215             if (i == j)
00216                 continue;
00217             if (!isIPNode(topo.getNode(j)))
00218                 continue;
00219 
00220             cTopology::Node *atNode = topo.getNode(j);
00221             if (atNode->getNumPaths() == 0)
00222                 continue;       // not connected
00223 
00224             RoutingTable6 *rt = IPAddressResolver().routingTable6Of(atNode->getModule());
00225             IInterfaceTable *ift = IPAddressResolver().interfaceTableOf(atNode->getModule());
00226 
00227             // skip hosts' routing tables
00228             if (!rt->par("isRouter").boolValue())
00229                 continue;
00230 
00231             // determine the local interface id
00232             cGate *localGate = atNode->getPath(0)->getLocalGate();
00233             InterfaceEntry *localIf = ift->getInterfaceByNodeOutputGateId(localGate->getId());
00234 
00235             // determine next hop link address. That's a bit tricky because
00236             // the directly adjacent cTopo node might be a non-IP getNode(ethernet switch etc)
00237             // so we have to "seek through" them.
00238             cTopology::Node *prevNode = atNode;
00239             // if there's no ethernet switch between atNode and it's next hop
00240             // neighbour, we don't go into the following while() loop
00241             while (!isIPNode(prevNode->getPath(0)->getRemoteNode()))
00242                 prevNode = prevNode->getPath(0)->getRemoteNode();
00243 
00244             // ok, the next hop is now just one step away from prevNode
00245             cGate *remoteGate = prevNode->getPath(0)->getRemoteGate();
00246             cModule *nextHop = remoteGate->getOwnerModule();
00247             IInterfaceTable *nextHopIft = IPAddressResolver().interfaceTableOf(nextHop);
00248             InterfaceEntry *nextHopOnlinkIf = nextHopIft->getInterfaceByNodeInputGateId(remoteGate->getId());
00249 
00250             // find link-local address for next hop
00251             IPv6Address nextHopLinkLocalAddr = nextHopOnlinkIf->ipv6Data()->getLinkLocalAddress();
00252 
00253             // traverse through address of each node
00254             // add to route table
00255             for (unsigned int k = 0; k < destPrefixes.size(); k++)
00256             {
00257                 rt->addStaticRoute(destPrefixes[k]->prefix, destPrefixes[k]->prefixLength,
00258                                    localIf->getInterfaceId(), nextHopLinkLocalAddr);
00259             }
00260         }
00261     }
00262 
00263     // update display string
00264     setDisplayString(numIPNodes, topo.getNumNodes()-numIPNodes);
00265 }
00266 #endif
00267 
00268