IPv4UnderlayConfigurator Class Reference

#include <IPv4UnderlayConfigurator.h>

Inheritance diagram for IPv4UnderlayConfigurator:

UnderlayConfigurator List of all members.

Detailed Description

Configurator module for the IPv4Underlay.

Author:
Markus Mauch
Todo:
possibility to disable tier1-3 in overlay(access)routers


Public Member Functions

int createRandomNode (bool initialize)
 Creates an overlay node and adds it to a randomly chosen access net.
void killRandomNode ()
 Removes randomly chosen overlay nodes from a randomly chosen access net.
void migrateRandomNode ()
 Migrates randomly chosen overlay nodes from on access net to another.

Protected Member Functions

void initializeUnderlay (int stage)
 Init method for derived underlay configurators.
void finish ()
 Cleans up configurator.
void setDisplayString ()
 Updates the statistics display string.

Protected Attributes

std::vector< cModule * > accessNode
int numCreated
int numKilled

Private Attributes

int accessRouterNum
int overlayAccessRouterNum
int overlayTerminalNum


Member Function Documentation

int IPv4UnderlayConfigurator::createRandomNode ( bool  initialize  )  [virtual]

Creates an overlay node and adds it to a randomly chosen access net.

Parameters:
initialize creation during init phase?

Implements UnderlayConfigurator.

00265 {
00266     // derive overlay node from ned
00267     cModuleType* moduleType = findModuleType("OverlayHost");//parentModule()->par("overlayTerminalType"));
00268     cModule* node = moduleType->create("overlayTerminal", parentModule());
00269 
00270     node->par("overlayType").setStringValue(parentModule()->par("overlayType"));
00271     node->par("tier2Type").setStringValue(parentModule()->par("tier1Type"));
00272     node->par("tier2Type").setStringValue(parentModule()->par("tier2Type"));
00273     node->par("tier3Type").setStringValue(parentModule()->par("tier3Type"));
00274 
00275 
00276     node->setGateSize("in", 1);
00277     node->setGateSize("out", 1);
00278     node->setDisplayString("i=device/wifilaptop_l;i2=block/circle_s");
00279     node->buildInside();
00280     node->scheduleStart(simulation.simTime());
00281 
00282     // add node to a randomly chosen access net
00283     AccessNet* accessNet = check_and_cast<AccessNet*>
00284                            (accessNode[intuniform(0, accessNode.size() - 1)]->submodule("accessNet"));
00285     accessNet->addOverlayNode(node);
00286 
00287     // append index to module name
00288     char buf[80];
00289     sprintf(buf, "overlayTerminal[%i]", numCreated);
00290     node->setName(buf);
00291 
00292     //add node to bootstrap oracle
00293     //TransportAddress* peer = new TransportAddress(IPAddressResolver().addressOf(node).get4());
00294     PeerInfo* info = new PeerInfo(node->submodule("overlay")->id());
00295     //bootstrapOracle->addPeer(peer, info);
00296     bootstrapOracle->addPeer(IPAddressResolver().addressOf(node).get4(), info);
00297 
00298     // if the node was not created during startup we have to
00299     // finish the initialization process manually
00300     if ( !initialize) {
00301         for (int i = MAX_STAGE_UNDERLAY + 1; i < NUM_STAGES_ALL; i++) {
00302             node->callInitialize(i);
00303         }
00304     }
00305 
00306     overlayTerminalCount++;
00307     numCreated++;
00308 
00309     return node->id();
00310 }

void IPv4UnderlayConfigurator::finish (  )  [protected, virtual]

Cleans up configurator.

Implements UnderlayConfigurator.

00385 {
00386     // statistics
00387     recordScalar("Terminals added", numCreated);
00388     recordScalar("Terminals removed", numKilled);
00389 
00390     struct timeval now, diff;
00391     gettimeofday(&now, NULL);
00392     timersub(&now, &initFinishedTime, &diff);
00393     printf("Simulation time: %li.%06li\n", diff.tv_sec, diff.tv_usec);
00394 }

void IPv4UnderlayConfigurator::initializeUnderlay ( int  stage  )  [protected, virtual]

Init method for derived underlay configurators.

Implements UnderlayConfigurator.

00035 {
00036     //backbone configuration
00037     if(stage == MIN_STAGE_UNDERLAY) {
00038         // Find all router module types.
00039         cTopology topo("topo");
00040         const char* typeNames[6];
00041         typeNames[0] = "Router";
00042         typeNames[1] = "OverlayRouter";
00043         typeNames[2] = "AccessRouter";
00044         typeNames[3] = "OverlayAccessRouter";
00045         typeNames[4] = "TunOutRouter";
00046         typeNames[5] = NULL;
00047         topo.extractByModuleType(typeNames);
00048 
00049         // Assign IP addresses to all router modules.
00050         std::vector<uint32> nodeAddresses;
00051         nodeAddresses.resize(topo.nodes());
00052 
00053         // IP addresses for backbone
00054         // Take start IP from config file
00055         // FIXME: Make Netmask for Routers configurable!
00056         uint32 lowIPBoundary = IPAddress(par("startIP").stringValue()).getInt();
00057 
00058         // uint32 lowIPBoundary = uint32((1 << 24) + 1);
00059         int numIPNodes = 0;
00060         for (int i = 0; i < topo.nodes(); i++) {
00061             ++numIPNodes;
00062 
00063             uint32 addr = lowIPBoundary + uint32(numIPNodes << 16);
00064             nodeAddresses[i] = addr;
00065 
00066             // update ip display string
00067             if (ev.isGUI()) {
00068                 const char* ip_disp = const_cast<char*>(IPAddress(addr).str().c_str());
00069                 topo.node(i)->module()->displayString().insertTag("t", 0);
00070                 topo.node(i)->module()->displayString().setTagArg("t", 0, ip_disp);
00071                 topo.node(i)->module()->displayString().setTagArg("t", 1, "l");
00072                 topo.node(i)->module()->displayString().setTagArg("t", 2, "red");
00073             }
00074 
00075             // find interface table and assign address to all (non-loopback) interfaces
00076             InterfaceTable* ift = IPAddressResolver().interfaceTableOf(topo.node(i)->module());
00077 
00078             for ( int k = 0; k < ift->numInterfaces(); k++ ) {
00079                 InterfaceEntry* ie = ift->interfaceAt(k);
00080                 if (!ie->isLoopback()) {
00081                     ie->ipv4()->setInetAddress(IPAddress(addr));
00082                     // full address must match for local delivery
00083                     ie->ipv4()->setNetmask(IPAddress::ALLONES_ADDRESS);
00084                 }
00085             }
00086         }
00087 
00088         // Fill in routing tables.
00089         for ( int i = 0; i < topo.nodes(); i++ ) {
00090             cTopology::Node* destNode = topo.node(i);
00091             uint32 destAddr = nodeAddresses[i];
00092 
00093             // calculate shortest paths from everywhere towards destNode
00094             topo.unweightedSingleShortestPathsTo(destNode);
00095 
00096             // add overlayAccessRouters and overlayBackboneRouters
00097             // to the BootstrapOracle
00098             if ((strcmp(destNode->module()->name(), "overlayBackboneRouter")
00099                  == 0 ) ||
00100                 (strcmp(destNode->module()->name(), "overlayAccessRouter")
00101                  == 0)) {
00102                 //add node to bootstrap oracle
00103                 PeerInfo* info = new PeerInfo(destNode->module()->
00104                                               submodule("overlay")->id());
00105                 bootstrapOracle->addPeer(IPvXAddress(nodeAddresses[i]), info);
00106             }
00107 
00108 
00109             // If destNode is the outRouter, add a default route
00110             // to outside network via the TunOutDevice and a route to the
00111             // Gateway
00112             if ( strcmp(destNode->module()->name(), "outRouter" ) == 0 ) {
00113                 RoutingEntry* defRoute = new RoutingEntry();
00114                 defRoute->host = IPAddress::UNSPECIFIED_ADDRESS;
00115                 defRoute->netmask = IPAddress::UNSPECIFIED_ADDRESS;
00116                 defRoute->gateway = IPAddress(par("gatewayIP").stringValue());
00117                 defRoute->interfaceName = "tunDev";
00118                 defRoute->interfacePtr = IPAddressResolver().interfaceTableOf(destNode->module())->
00119                     interfaceByName("tunDev");
00120                 defRoute->type = RoutingEntry::REMOTE;
00121                 defRoute->source = RoutingEntry::MANUAL;
00122                 IPAddressResolver().routingTableOf(destNode->module())->addRoutingEntry(defRoute);
00123 
00124                 RoutingEntry* gwRoute = new RoutingEntry();
00125                 gwRoute->host = IPAddress(par("gatewayIP").stringValue());
00126                 gwRoute->netmask = IPAddress(255, 255, 255, 255);
00127                 gwRoute->interfaceName = "tunDev";
00128                 gwRoute->interfacePtr = IPAddressResolver().interfaceTableOf(destNode->module())->
00129                     interfaceByName("tunDev");
00130                 gwRoute->type = RoutingEntry::DIRECT;
00131                 gwRoute->source = RoutingEntry::MANUAL;
00132                 IPAddressResolver().routingTableOf(destNode->module())->addRoutingEntry(gwRoute);
00133             }
00134 
00135             // add route (with host=destNode) to every routing table in the network
00136             for ( int j = 0; j < topo.nodes(); j++ ) {
00137                 // continue if same node
00138                 if ( i == j )
00139                     continue;
00140 
00141                 // cancel simulation if node is not conencted with destination
00142                 cTopology::Node* atNode = topo.node(j);
00143                 if(atNode->paths() == 0)
00144                     error((std::string(atNode->module()->name()) +
00145                            ": Network is not entirely connected."
00146                            "Please increase your value for the "
00147                            "connectivity parameter").c_str());
00148 
00149                 //
00150                 // Add routes at the atNode.
00151                 //
00152 
00153                 // find atNode's interface and routing table
00154                 InterfaceTable* ift = IPAddressResolver().interfaceTableOf(atNode->module());
00155                 RoutingTable* rt = IPAddressResolver().routingTableOf(atNode->module());
00156 
00157                 // find atNode's interface entry for the next hop node
00158                 int outputGateId = atNode->path(0)->localGate()->id();
00159                 InterfaceEntry *ie = ift->interfaceByNodeOutputGateId(outputGateId);
00160 
00161                 // find the next hop node on the path towards destNode
00162                 cModule* next_hop = atNode->path(0)->remoteNode()->module();
00163                 IPAddress next_hop_ip = IPAddressResolver().addressOf(next_hop).get4();
00164 
00165 
00166                 // Requirement 1: Each router has exactly one routing entry
00167                 // (netmask 255.255.0.0) to each other router
00168                 RoutingEntry* re = new RoutingEntry();
00169 
00170                 re->host = IPAddress(destAddr);
00171                 re->interfaceName = ie->name();
00172                 re->interfacePtr = ie;
00173                 re->source = RoutingEntry::MANUAL;
00174                 re->netmask = IPAddress(255, 255, 0, 0);
00175                 re->gateway = IPAddress(next_hop_ip);
00176                 re->type = RoutingEntry::REMOTE;
00177 
00178                 rt->addRoutingEntry(re);
00179 
00180                 // Requirement 2: Each router has a point-to-point routing
00181                 // entry (netmask 255.255.255.255) for each immediate neighbour
00182                 if ( atNode->distanceToTarget() == 1 ) {
00183                     RoutingEntry* re2 = new RoutingEntry();
00184 
00185                     re2->host = IPAddress(destAddr);
00186                     re2->interfaceName = ie->name();
00187                     re2->interfacePtr = ie;
00188                     re2->source = RoutingEntry::MANUAL;
00189                     re2->netmask = IPAddress(255, 255, 255, 255);
00190                     re2->type = RoutingEntry::DIRECT;
00191 
00192                     rt->addRoutingEntry(re2);
00193                 }
00194 
00195                 // If destNode is the outRouter, add a default route
00196                 // to the next hop in the direction of the outRouter
00197                 if ( strcmp(destNode->module()->name(), "outRouter" ) == 0 ) {
00198                     RoutingEntry* defRoute = new RoutingEntry();
00199                     defRoute->host = IPAddress::UNSPECIFIED_ADDRESS;
00200                     defRoute->netmask = IPAddress::UNSPECIFIED_ADDRESS;
00201                     defRoute->gateway = IPAddress(next_hop_ip);
00202                     defRoute->interfaceName = ie->name();
00203                     defRoute->interfacePtr = ie;
00204                     defRoute->type = RoutingEntry::REMOTE;
00205                     defRoute->source = RoutingEntry::MANUAL;
00206 
00207                     rt->addRoutingEntry(defRoute);
00208                 }
00209             }
00210         }
00211     }
00212     //accessnet configuration
00213     else if(stage == MAX_STAGE_UNDERLAY) {
00214         // fetch some parameters
00215         accessRouterNum = parentModule()->par("accessRouterNum");
00216         overlayAccessRouterNum = parentModule()->par("overlayAccessRouterNum");
00217 
00218         // flag indicating simulation initialization phase (true) vs. normal mode (false)
00219         init = true;
00220 
00221         // count the overlay clients
00222         overlayTerminalCount = 0;
00223         numCreated = 0;
00224         numKilled = 0;
00225 
00226         // add access node modules to access node vector
00227         // and assing the channel tpye to be used by the access node
00228         cModule* node;
00229         AccessNet* nodeAccess;
00230         for ( int i = 0; i < accessRouterNum; i++ ) {
00231             node = parentModule()->submodule("accessRouter", i);
00232             accessNode.push_back( node );
00233             nodeAccess = check_and_cast<AccessNet*>( node->submodule("accessNet") );
00234             nodeAccess->selectChannel( channelTypes[intuniform(0, channelTypes.size()-1)] );
00235         }
00236 
00237         for ( int i = 0; i < overlayAccessRouterNum; i++ ) {
00238             node = parentModule()->submodule("overlayAccessRouter", i);
00239             accessNode.push_back( node );
00240             nodeAccess = check_and_cast<AccessNet*>( node->submodule("accessNet") );
00241             nodeAccess->selectChannel( channelTypes[intuniform(0, channelTypes.size()-1)] );
00242         }
00243 
00244         // add the overlay nodes
00245         firstNodeId = createRandomNode(true);
00246         for ( int i = 1; i < initialOverlayTerminalNum; i++ ) {
00247             createRandomNode(true);
00248         }
00249 
00250         // debug stuff
00251         WATCH_PTRVECTOR(accessNode);
00252 
00253         // update display
00254         setDisplayString();
00255 
00256         // initialize simulation
00257         if ( par("simulateMobility") ) {
00258             cMessage* msg = new cMessage();
00259             scheduleAt(simulation.simTime(), msg);
00260         }
00261     }
00262 }

void IPv4UnderlayConfigurator::killRandomNode (  )  [virtual]

Removes randomly chosen overlay nodes from a randomly chosen access net.

Implements UnderlayConfigurator.

00314 {
00315     // find an access net with one or more overlay nodes
00316     AccessNet* accessNetModule;
00317     do {
00318         int z = intuniform(0, accessNode.size()-1);
00319         accessNetModule = check_and_cast<AccessNet*>(accessNode[z]->submodule("accessNet"));
00320     } while ( accessNetModule->size() == 0 );
00321 
00322     // remove a random node from the access net and delete it
00323     int index = intuniform(0, accessNetModule->size() - 1);
00324 
00325     //TODO: keepFirstNode in while-loop?
00326     if(keepFirstNode && (firstNodeId == accessNetModule->getOverlayNodeId(index)))
00327       return;
00328 
00329     cModule* node = accessNetModule->removeOverlayNode(index);//intuniform(0, accessNetModule->size() - 1));
00330 
00331     //remove node from bootstrap oracle
00332     bootstrapOracle->killPeer(IPAddressResolver().addressOf(node).get4());
00333 
00334     node->callFinish();
00335     node->deleteModule();
00336 
00337     overlayTerminalCount--;
00338     numKilled++;
00339 }

void IPv4UnderlayConfigurator::migrateRandomNode (  )  [virtual]

Migrates randomly chosen overlay nodes from on access net to another.

Implements UnderlayConfigurator.

00342 {
00343     // find an access net with one or more overlay nodes
00344     AccessNet* accessNetModule;
00345     do {
00346         int z = intuniform(0, accessNode.size()-1);
00347         accessNetModule = check_and_cast<AccessNet*>(accessNode[z]->submodule("accessNet"));
00348     } while ( accessNetModule->size() == 0 );
00349 
00350     // disconnect a random overlay node
00351     int index = intuniform(0, accessNetModule->size() - 1);
00352 
00353     if(keepFirstNode && (firstNodeId == accessNetModule->getOverlayNodeId(index)))
00354       return;
00355 
00356     cModule* node = accessNetModule->removeOverlayNode(index);//intuniform(0, accessNetModule->size() - 1));
00357 
00358     //remove node from bootstrap oracle
00359     bootstrapOracle->killPeer(IPAddressResolver().addressOf(node).get4());
00360 
00361     node->bubble("I am migrating!");
00362 
00363     // connect the node to another access net
00364     AccessNet* newAccessNetModule;
00365     do {
00366         newAccessNetModule = check_and_cast<AccessNet*>(accessNode[intuniform(0, accessNode.size() - 1)]->submodule("accessNet"));
00367 
00368     } while((newAccessNetModule == accessNetModule) && (accessNode.size() != 1));
00369 
00370     newAccessNetModule->addOverlayNode(node, true);
00371 
00372     // inform the notofication board about the migration
00373     NotificationBoard* nb = check_and_cast<NotificationBoard*>(node->submodule("notificationBoard"));
00374     nb->fireChangeNotification(NF_HOSTPOSITION_UPDATED);
00375 }

void IPv4UnderlayConfigurator::setDisplayString (  )  [protected, virtual]

Updates the statistics display string.

Implements UnderlayConfigurator.

00378 {
00379     char buf[80];
00380     sprintf(buf, "%i overlay clients\n%i access router\n%i overlay access router", overlayTerminalCount, accessRouterNum, overlayAccessRouterNum);
00381     displayString().setTagArg("t", 0, buf);
00382 }


Member Data Documentation

std::vector<cModule*> IPv4UnderlayConfigurator::accessNode [protected]

int IPv4UnderlayConfigurator::accessRouterNum [private]

int IPv4UnderlayConfigurator::numCreated [protected]

int IPv4UnderlayConfigurator::numKilled [protected]

int IPv4UnderlayConfigurator::overlayAccessRouterNum [private]

int IPv4UnderlayConfigurator::overlayTerminalNum [private]


The documentation for this class was generated from the following files:
Generated on Fri May 11 14:52:40 2007 for ITM OverSim by  doxygen 1.4.7