|
INET Framework for OMNeT++/OMNEST
|
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