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