00035 {
00036 error("The TunOut underlay doesn't work in this version (work in progress)!");
00037
00038 if (stage!=2)
00039 return;
00040
00041 cTopology topo("topo");
00042
00043 cTopology::Node* outNode = 0;
00044 uint32 outAddr = 0;
00045
00046 StringVector OutTypes = cStringTokenizer(par("outModule"), " ").asVector();
00047 const char* outDevName = par("outDevName").stringValue();
00048 topo.extractByModuleType(OutTypes);
00049 if( topo.nodes() != 1)
00050 error ("Wrong number of OutNodes!");
00051
00052 StringVector types = cStringTokenizer(par("moduleTypes"), " ").asVector();
00053 StringVector nonIPTypes = cStringTokenizer(par("nonIPModuleTypes"), " ").asVector();
00054 int i;
00055 for (i=0; i<(int) nonIPTypes.size(); i++)
00056 types.push_back(nonIPTypes[i]);
00057
00058
00059 topo.extractByModuleType(types);
00060 ev << "cTopology found " << topo.nodes() << " nodes\n";
00061
00062
00063
00064 uint32 networkAddress = IPAddress(par("networkAddress").stringValue()).getInt();
00065 uint32 netmask = IPAddress(par("netmask").stringValue()).getInt();
00066 int maxNodes = (~netmask)-1;
00067 if (topo.nodes()>maxNodes)
00068 error("netmask too large, not enough addresses for all %d nodes", topo.nodes());
00069
00070
00071 std::vector<uint32> nodeAddresses;
00072 nodeAddresses.resize(topo.nodes());
00073
00074 int numIPNodes = 0;
00075 for (i=0; i<topo.nodes(); i++) {
00076
00077 if (isNonIPType(topo.node(i), nonIPTypes))
00078 continue;
00079
00080 uint32 addr = networkAddress | uint32(++numIPNodes);
00081 nodeAddresses[i] = addr;
00082 if ( isOutModuleType(topo.node(i), OutTypes) ) {
00083 outAddr = addr;
00084 outNode = topo.node(i);
00085 }
00086
00087
00088
00089 cModule *mod = topo.node(i)->module();
00090 InterfaceTable *ift = IPAddressResolver().interfaceTableOf(mod);
00091
00092
00093 for (int k=0; k<ift->numInterfaces(); k++) {
00094 InterfaceEntry *ie = ift->interfaceAt(k);
00095 if ( !strcmp(ie->name(), outDevName) ) {
00096 RoutingTable *rt = IPAddressResolver().routingTableOf(mod);
00097 RoutingEntry *e = new RoutingEntry();
00098 e->host = IPAddress();
00099 e->netmask = IPAddress();
00100 e->interfaceName = ie->name();
00101 e->interfacePtr = ie;
00102 e->type = RoutingEntry::REMOTE;
00103 e->source = RoutingEntry::MANUAL;
00104
00105 rt->addRoutingEntry(e);
00106 }
00107
00108 if (!ie->isLoopback()) {
00109 ie->ipv4()->setInetAddress(IPAddress(addr));
00110 ie->ipv4()->setNetmask(IPAddress::ALLONES_ADDRESS);
00111 }
00112 }
00113 }
00114
00115
00116
00117 std::vector<bool> usesDefaultRoute;
00118 usesDefaultRoute.resize(topo.nodes());
00119 for (i=0; i<topo.nodes(); i++) {
00120 cTopology::Node *node = topo.node(i);
00121
00122
00123 if (isNonIPType(topo.node(i), nonIPTypes))
00124 continue;
00125
00126 InterfaceTable *ift = IPAddressResolver().interfaceTableOf(node->module());
00127 RoutingTable *rt = IPAddressResolver().routingTableOf(node->module());
00128
00129
00130 int numIntf = 0;
00131 InterfaceEntry *ie = NULL;
00132 for (int k=0; k<ift->numInterfaces(); k++)
00133 if (!ift->interfaceAt(k)->isLoopback()) {
00134 ie = ift->interfaceAt(k);
00135 numIntf++;
00136 }
00137
00138 usesDefaultRoute[i] = (numIntf==1);
00139 if ( numIntf!=1 )
00140 continue;
00141
00142 ev << " " << node->module()->fullName() << "=" << IPAddress(nodeAddresses[i])
00143 << " has only one (non-loopback) interface, adding default route\n";
00144
00145
00146 RoutingEntry *e = new RoutingEntry();
00147 e->host = IPAddress();
00148 e->netmask = IPAddress();
00149 e->interfaceName = ie->name();
00150 e->interfacePtr = ie;
00151 e->type = RoutingEntry::REMOTE;
00152 e->source = RoutingEntry::MANUAL;
00153
00154 rt->addRoutingEntry(e);
00155 }
00156
00157
00158 for (i=0; i<topo.nodes(); i++) {
00159 cTopology::Node *destNode = topo.node(i);
00160
00161
00162 if (isNonIPType(destNode, nonIPTypes))
00163 continue;
00164
00165 uint32 destAddr = nodeAddresses[i];
00166 std::string destModName = destNode->module()->fullName();
00167
00168
00169 topo.unweightedSingleShortestPathsTo(destNode);
00170
00171
00172
00173 for (int j=0; j<topo.nodes(); j++) {
00174 if (i==j)
00175 continue;
00176 if (isNonIPType(topo.node(j), nonIPTypes))
00177 continue;
00178
00179 cTopology::Node *atNode = topo.node(j);
00180 if (atNode->paths()==0)
00181 continue;
00182 if (usesDefaultRoute[j])
00183 continue;
00184
00185 uint32 atAddr = nodeAddresses[j];
00186
00187 int outputPort = atNode->path(0)->localGate()->index();
00188 ev << " from " << atNode->module()->fullName() << "=" << IPAddress(atAddr);
00189 ev << " towards " << destModName << "=" << IPAddress(destAddr) << " outputPort=" << outputPort << endl;
00190
00191
00192 InterfaceTable *ift = IPAddressResolver().interfaceTableOf(atNode->module());
00193 RoutingTable *rt = IPAddressResolver().routingTableOf(atNode->module());
00194 InterfaceEntry *ie = ift->interfaceByNodeOutputGateId(outputPort);
00195 if (!ie)
00196 error("%s has no entry for interface %d", ift->fullPath().c_str(), outputPort);
00197
00198 RoutingEntry *e = new RoutingEntry();
00199 e->host = IPAddress(destAddr);
00200 e->netmask = IPAddress(255,255,255,255);
00201 e->interfaceName = ie->name();
00202 e->interfacePtr = ie;
00203 e->type = RoutingEntry::DIRECT;
00204 e->source = RoutingEntry::MANUAL;
00205
00206 rt->addRoutingEntry(e);
00207 }
00208 }
00209
00210 std::string outModName = outNode->module()->fullName();
00211
00212
00213 topo.unweightedSingleShortestPathsTo(outNode);
00214
00215 for (int j=0; j<topo.nodes(); j++) {
00216 if (isNonIPType(topo.node(j), nonIPTypes))
00217 continue;
00218
00219 cTopology::Node *atNode = topo.node(j);
00220 if (atNode == outNode)
00221 continue;
00222 if (atNode->paths()==0)
00223 continue;
00224 if (usesDefaultRoute[j])
00225 continue;
00226
00227 uint32 atAddr = nodeAddresses[j];
00228
00229 int outputPort = atNode->path(0)->localGate()->index();
00230 ev << " from " << atNode->module()->fullName() << "=" << IPAddress(atAddr);
00231 ev << " towards outNode" << "=" << IPAddress(outAddr) << " outputPort=" << outputPort << endl;
00232
00233
00234 InterfaceTable *ift = IPAddressResolver().interfaceTableOf(atNode->module());
00235 RoutingTable *rt = IPAddressResolver().routingTableOf(atNode->module());
00236 InterfaceEntry *ie = ift->interfaceByNodeOutputGateId(outputPort);
00237 if (!ie)
00238 error("%s has no entry for interface %d", ift->fullPath().c_str(), outputPort);
00239
00240 RoutingEntry *e = new RoutingEntry();
00241 e->host = IPAddress();
00242 e->netmask = IPAddress();
00243 e->interfaceName = ie->name();
00244 e->interfacePtr = ie;
00245 e->type = RoutingEntry::REMOTE;
00246 e->source = RoutingEntry::MANUAL;
00247
00248 rt->addRoutingEntry(e);
00249 }
00250
00251
00252 setDisplayString(numIPNodes, topo.nodes()-numIPNodes);
00253 }