#include <NetworkConfigurator.h>
Protected Types | |
typedef std::vector< NodeInfo > | NodeInfoVector |
typedef std::vector< std::string > | StringVector |
Protected Member Functions | |
virtual int | numInitStages () const |
virtual void | initialize (int stage) |
virtual void | handleMessage (cMessage *msg) |
void | extractTopology (cTopology &topo, NodeInfoVector &nodeInfo) |
void | assignAddresses (cTopology &topo, NodeInfoVector &nodeInfo) |
void | addPointToPointPeerRoutes (cTopology &topo, NodeInfoVector &nodeInfo) |
void | addDefaultRoutes (cTopology &topo, NodeInfoVector &nodeInfo) |
void | setPeersParameter (const char *submodName, cTopology &topo, NodeInfoVector &nodeInfo) |
void | fillRoutingTables (cTopology &topo, NodeInfoVector &nodeInfo) |
void | setDisplayString (cTopology &topo, NodeInfoVector &nodeInfo) |
Classes | |
struct | NodeInfo |
|
|
|
|
|
00189 { 00190 // add default route to nodes with exactly one (non-loopback) interface 00191 for (int i=0; i<topo.nodes(); i++) 00192 { 00193 // skip bus types 00194 if (!nodeInfo[i].isIPNode) 00195 continue; 00196 00197 cTopology::Node *node = topo.node(i); 00198 InterfaceTable *ift = nodeInfo[i].ift; 00199 RoutingTable *rt = nodeInfo[i].rt; 00200 00201 // count non-loopback interfaces 00202 int numIntf = 0; 00203 InterfaceEntry *ie = NULL; 00204 for (int k=0; k<ift->numInterfaces(); k++) 00205 if (!ift->interfaceAt(k)->isLoopback()) 00206 {ie = ift->interfaceAt(k); numIntf++;} 00207 00208 nodeInfo[i].usesDefaultRoute = (numIntf==1); 00209 if (numIntf!=1) 00210 continue; // only deal with nodes with one interface plus loopback 00211 00212 EV << " " << node->module()->fullName() << " has only one (non-loopback) " 00213 "interface, adding default route\n"; 00214 00215 // add route 00216 RoutingEntry *e = new RoutingEntry(); 00217 e->host = IPAddress(); 00218 e->netmask = IPAddress(); 00219 e->interfaceName = ie->name(); 00220 e->interfacePtr = ie; 00221 e->type = RoutingEntry::REMOTE; 00222 e->source = RoutingEntry::MANUAL; 00223 //e->metric() = 1; 00224 rt->addRoutingEntry(e); 00225 } 00226 }
|
|
00121 { 00122 bool useRouterIdForRoutes = true; // TODO make it parameter 00123 00124 // add routes towards point-to-point routers (in real life these routes are 00125 // created automatically after PPP handshake when neighbour's address is learned) 00126 for (int i=0; i<topo.nodes(); i++) 00127 { 00128 // skip bus types 00129 if (!nodeInfo[i].isIPNode) 00130 continue; 00131 00132 cTopology::Node *node = topo.node(i); 00133 //InterfaceTable *ift = nodeInfo[i].ift; 00134 RoutingTable *rt = nodeInfo[i].rt; 00135 00136 // loop through neighbors 00137 for (int j=0; j<node->outLinks(); j++) 00138 { 00139 cTopology::Node *neighbor = node->out(j)->remoteNode(); 00140 00141 // find neighbour's index in cTopology ==> k 00142 int k; 00143 for (k=0; k<topo.nodes(); k++) 00144 if (topo.node(k)==neighbor) 00145 break; 00146 ASSERT(k<=topo.nodes()); 00147 00148 // if it's not an IP node (e.g. an Ethernet switch), then we're not interested 00149 if (!nodeInfo[k].isIPNode) 00150 continue; 00151 00152 // find out neighbor's routerId 00153 IPAddress neighborRouterId = nodeInfo[k].rt->routerId(); 00154 00155 // find out neighbor's interface IP address 00156 int neighborGateId = node->out(j)->remoteGate()->id(); 00157 InterfaceEntry *neighborIe = nodeInfo[k].ift->interfaceByNodeInputGateId(neighborGateId); 00158 ASSERT(neighborIe); 00159 IPAddress neighborAddr = neighborIe->ipv4()->inetAddress(); 00160 00161 // find our own interface towards neighbor 00162 int gateId = node->out(j)->localGate()->id(); 00163 InterfaceEntry *ie = nodeInfo[i].ift->interfaceByNodeOutputGateId(gateId); 00164 ASSERT(ie); 00165 00166 // add route 00167 RoutingEntry *e = new RoutingEntry(); 00168 if (useRouterIdForRoutes) 00169 { 00170 e->host = neighborRouterId; 00171 e->gateway = neighborAddr; 00172 } 00173 else 00174 { 00175 e->host = neighborAddr; // and no gateway 00176 } 00177 e->netmask = IPAddress(255,255,255,255); // full match needed 00178 e->interfaceName = ie->name(); 00179 e->interfacePtr = ie; 00180 e->type = RoutingEntry::DIRECT; 00181 e->source = RoutingEntry::MANUAL; 00182 //e->metric() = 1; 00183 rt->addRoutingEntry(e); 00184 } 00185 } 00186 }
|
|
00087 { 00088 uint32 base = 10 << 24; // 10.x.x.x addresses 00089 int nodeCtr = 1; // middle 16 bits 00090 00091 for (int i=0; i<topo.nodes(); i++) 00092 { 00093 // skip bus types 00094 if (!nodeInfo[i].isIPNode) 00095 continue; 00096 00097 uint32 addr = base + (nodeCtr++ << 8); // --> 10.nn.nn.0 00098 00099 // assign address to all (non-loopback) interfaces 00100 InterfaceTable *ift = nodeInfo[i].ift; 00101 for (int k=0; k<ift->numInterfaces(); k++) 00102 { 00103 InterfaceEntry *ie = ift->interfaceAt(k); 00104 if (!ie->isLoopback()) 00105 { 00106 ie->ipv4()->setInetAddress(IPAddress(addr | (uint32)k)); 00107 ie->ipv4()->setNetmask(IPAddress::ALLONES_ADDRESS); // full address must match for local delivery 00108 } 00109 } 00110 00111 // set routerId as well (if not yet configured) 00112 RoutingTable *rt = nodeInfo[i].rt; 00113 if (rt->routerId().isUnspecified()) 00114 { 00115 rt->setRouterId(IPAddress(addr | 1U)); // 10.nn.nn.1 00116 } 00117 } 00118 }
|
|
00068 { 00069 StringVector types = cStringTokenizer(par("moduleTypes"), " ").asVector(); 00070 00071 // extract topology 00072 topo.extractByModuleType(types); 00073 EV << "cTopology found " << topo.nodes() << " nodes\n"; 00074 00075 // fill in isIPNode, ift and rt members in nodeInfo[] 00076 nodeInfo.resize(topo.nodes()); 00077 for (int i=0; i<topo.nodes(); i++) 00078 { 00079 cModule *mod = topo.node(i)->module(); 00080 nodeInfo[i].ift = IPAddressResolver().findInterfaceTableOf(mod); 00081 nodeInfo[i].rt = IPAddressResolver().findRoutingTableOf(mod); 00082 nodeInfo[i].isIPNode = nodeInfo[i].rt!=NULL; 00083 } 00084 }
|
|
00267 { 00268 /* FIXME TBD 00269 // fill in routing tables with static routes 00270 for (int i=0; i<topo.nodes(); i++) 00271 { 00272 cTopology::Node *destNode = topo.node(i); 00273 00274 // skip bus types 00275 if (!nodeInfo[i].isIPNode) 00276 continue; 00277 00278 IPAddress destAddr = nodeInfo[i].address; 00279 std::string destModName = destNode->module()->fullName(); 00280 00281 // calculate shortest paths from everywhere towards destNode 00282 topo.unweightedSingleShortestPathsTo(destNode); 00283 00284 // add route (with host=destNode) to every routing table in the network 00285 // (excepting nodes with only one interface -- there we'll set up a default route) 00286 for (int j=0; j<topo.nodes(); j++) 00287 { 00288 if (i==j) continue; 00289 if (!nodeInfo[j].isIPNode) 00290 continue; 00291 00292 cTopology::Node *atNode = topo.node(j); 00293 if (atNode->paths()==0) 00294 continue; // not connected 00295 if (nodeInfo[j].usesDefaultRoute) 00296 continue; // already added default route here 00297 00298 IPAddress atAddr = nodeInfo[j].address; 00299 00300 InterfaceTable *ift = nodeInfo[j].ift; 00301 00302 int outputGateId = atNode->path(0)->localGate()->id(); 00303 InterfaceEntry *ie = ift->interfaceByNodeOutputGateId(outputGateId); 00304 if (!ie) 00305 error("%s has no interface for output gate id %d", ift->fullPath().c_str(), outputGateId); 00306 00307 EV << " from " << atNode->module()->fullName() << "=" << IPAddress(atAddr); 00308 EV << " towards " << destModName << "=" << IPAddress(destAddr) << " interface " << ie->name() << endl; 00309 00310 // add route 00311 RoutingTable *rt = nodeInfo[j].rt; 00312 RoutingEntry *e = new RoutingEntry(); 00313 e->host = destAddr; 00314 e->gateway = ??? 00315 e->netmask = IPAddress(255,255,255,255); // full match needed 00316 e->interfaceName = ie->name(); 00317 e->interfacePtr = ie; 00318 e->type = RoutingEntry::REMOTE; 00319 e->source = RoutingEntry::MANUAL; 00320 //e->metric() = 1; 00321 rt->addRoutingEntry(e); 00322 } 00323 } 00324 */ 00325 }
|
|
00328 {
00329 error("this module doesn't handle messages, it runs only in initialize()");
00330 }
|
|
00035 { 00036 if (stage==2) 00037 { 00038 cTopology topo("topo"); 00039 NodeInfoVector nodeInfo; // will be of size topo.nodes[] 00040 00041 // extract topology into the cTopology object, then fill in 00042 // isIPNode, rt and ift members of nodeInfo[] 00043 extractTopology(topo, nodeInfo); 00044 00045 // assign addresses to IP nodes, and also store result in nodeInfo[].address 00046 assignAddresses(topo, nodeInfo); 00047 00048 // add routes for point-to-point peers 00049 addPointToPointPeerRoutes(topo, nodeInfo); 00050 00051 // add default routes to hosts (nodes with a single attachment); 00052 // also remember result in nodeInfo[].usesDefaultRoute 00053 addDefaultRoutes(topo, nodeInfo); 00054 00055 // help configure RSVP and LinkStateRouting modules by setting their "peers" parameters 00056 setPeersParameter("rsvp", topo, nodeInfo); 00057 setPeersParameter("linkStateRouting", topo, nodeInfo); 00058 00059 // calculate shortest paths, and add corresponding static routes 00060 fillRoutingTables(topo, nodeInfo); 00061 00062 // update display string 00063 setDisplayString(topo, nodeInfo); 00064 } 00065 }
|
|
00048 {return 3;}
|
|
00333 { 00334 int numIPNodes = 0; 00335 for (int i=0; i<topo.nodes(); i++) 00336 if (nodeInfo[i].isIPNode) 00337 numIPNodes++; 00338 00339 // update display string 00340 char buf[80]; 00341 sprintf(buf, "%d IP nodes\n%d non-IP nodes", numIPNodes, topo.nodes()-numIPNodes); 00342 displayString().setTagArg("t",0,buf); 00343 }
|
|
00229 { 00230 // the RSVP module expects a "peers" module parameter to contain the interfaces 00231 // towards directly connected other RSVP routers. Since it's cumbersome to configure 00232 // manually in a large network, do it here (submodName = "rsvp"). 00233 // The LinkStateRouting module is similar, so this function is also called with submodName = "LinkStateRouting". 00234 00235 // for each RSVP router, collect neighbors which are also RSVP routers 00236 for (int i=0; i<topo.nodes(); i++) 00237 { 00238 // if it doesn't have an RSVP submodule, we're not interested 00239 cModule *submod = topo.node(i)->module()->submodule(submodName); 00240 if (submod==NULL) 00241 continue; 00242 00243 std::string peers; 00244 cTopology::Node *node = topo.node(i); 00245 for (int j=0; j<node->outLinks(); j++) 00246 { 00247 // if neighbor is not an RSVP router, then we're not interested 00248 cModule *neighborSubmod = node->out(j)->remoteNode()->module()->submodule(submodName); 00249 if (neighborSubmod==NULL) 00250 continue; 00251 00252 // find our own interface towards neighbor 00253 int gateId = node->out(j)->localGate()->id(); 00254 InterfaceEntry *ie = nodeInfo[i].ift->interfaceByNodeOutputGateId(gateId); 00255 ASSERT(ie); 00256 00257 // interface name to peers list 00258 peers += std::string(" ") + ie->name(); 00259 } 00260 00261 // set "peers" parameter 00262 submod->par("peers") = peers.c_str(); 00263 } 00264 }
|