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.

00252 {
00253     // derive overlay node from ned
00254     cModuleType* moduleType = findModuleType("OverlayHost");//parentModule()->par("overlayTerminalType"));
00255     cModule* node = moduleType->create("overlayTerminal", parentModule());
00256 
00257     node->par("overlayType").setStringValue(parentModule()->par("overlayType"));
00258     node->par("tier2Type").setStringValue(parentModule()->par("tier1Type"));
00259     node->par("tier2Type").setStringValue(parentModule()->par("tier2Type"));
00260     node->par("tier3Type").setStringValue(parentModule()->par("tier3Type"));
00261 
00262 
00263     node->setGateSize("in", 1);
00264     node->setGateSize("out", 1);
00265     node->setDisplayString("i=device/wifilaptop_l;i2=block/circle_s");
00266     node->buildInside();
00267     node->scheduleStart(simulation.simTime());
00268 
00269     // add node to a randomly chosen access net
00270     AccessNet* accessNet = check_and_cast<AccessNet*>
00271                            (accessNode[intuniform(0, accessNode.size() - 1)]->submodule("accessNet"));
00272     accessNet->addOverlayNode(node);
00273 
00274     // append index to module name
00275     char buf[80];
00276     sprintf(buf, "overlayTerminal[%i]", numCreated);
00277     node->setName(buf);
00278 
00279     // if the node was not created during startup we have to
00280     // finish the initialization process manually
00281     if ( !initialize) {
00282         for (int i = MAX_STAGE_UNDERLAY + 1; i < NUM_STAGES_ALL; i++) {
00283             node->callInitialize(i);
00284         }
00285     }
00286 
00287     overlayTerminalCount++;
00288     numCreated++;
00289 
00290     return node->id();
00291 }

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

Cleans up configurator.

Implements UnderlayConfigurator.

00359 {
00360     // statistics
00361     recordScalar("Terminals added", numCreated);
00362     recordScalar("Terminals removed", numKilled);
00363 
00364     struct timeval now, diff;
00365     gettimeofday(&now, NULL);
00366     timersub(&now, &initFinishedTime, &diff);
00367     printf("Simulation time: %li.%06li\n", diff.tv_sec, diff.tv_usec);
00368 }

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             // If destNode is the outRouter, add a default route
00097             // to outside network via the TunOutDevice and a route to the
00098             // Gateway
00099             if ( strcmp(destNode->module()->name(), "outRouter" ) == 0 ) {
00100                 RoutingEntry* defRoute = new RoutingEntry();
00101                 defRoute->host = IPAddress::UNSPECIFIED_ADDRESS;
00102                 defRoute->netmask = IPAddress::UNSPECIFIED_ADDRESS;
00103                 defRoute->gateway = IPAddress(par("gatewayIP").stringValue());
00104                 defRoute->interfaceName = "tunDev";
00105                 defRoute->interfacePtr = IPAddressResolver().interfaceTableOf(destNode->module())->
00106                     interfaceByName("tunDev");
00107                 defRoute->type = RoutingEntry::REMOTE;
00108                 defRoute->source = RoutingEntry::MANUAL;
00109                 IPAddressResolver().routingTableOf(destNode->module())->addRoutingEntry(defRoute);
00110 
00111                 RoutingEntry* gwRoute = new RoutingEntry();
00112                 gwRoute->host = IPAddress(par("gatewayIP").stringValue());
00113                 gwRoute->netmask = IPAddress(255, 255, 255, 255);
00114                 gwRoute->interfaceName = "tunDev";
00115                 gwRoute->interfacePtr = IPAddressResolver().interfaceTableOf(destNode->module())->
00116                     interfaceByName("tunDev");
00117                 gwRoute->type = RoutingEntry::DIRECT;
00118                 gwRoute->source = RoutingEntry::MANUAL;
00119                 IPAddressResolver().routingTableOf(destNode->module())->addRoutingEntry(gwRoute);
00120             }
00121 
00122             // add route (with host=destNode) to every routing table in the network
00123             for ( int j = 0; j < topo.nodes(); j++ ) {
00124                 // continue if same node
00125                 if ( i == j )
00126                     continue;
00127 
00128                 // cancel simulation if node is not conencted with destination
00129                 cTopology::Node* atNode = topo.node(j);
00130                 if(atNode->paths() == 0)
00131                     error((std::string(atNode->module()->name()) +
00132                            ": Network is not entirely connected."
00133                            "Please increase your value for the "
00134                            "connectivity parameter").c_str());
00135 
00136                 //
00137                 // Add routes at the atNode.
00138                 //
00139 
00140                 // find atNode's interface and routing table
00141                 InterfaceTable* ift = IPAddressResolver().interfaceTableOf(atNode->module());
00142                 RoutingTable* rt = IPAddressResolver().routingTableOf(atNode->module());
00143 
00144                 // find atNode's interface entry for the next hop node
00145                 int outputGateId = atNode->path(0)->localGate()->id();
00146                 InterfaceEntry *ie = ift->interfaceByNodeOutputGateId(outputGateId);
00147 
00148                 // find the next hop node on the path towards destNode
00149                 cModule* next_hop = atNode->path(0)->remoteNode()->module();
00150                 IPAddress next_hop_ip = IPAddressResolver().addressOf(next_hop).get4();
00151 
00152 
00153                 // Requirement 1: Each router has exactly one routing entry
00154                 // (netmask 255.255.0.0) to each other router
00155                 RoutingEntry* re = new RoutingEntry();
00156 
00157                 re->host = IPAddress(destAddr);
00158                 re->interfaceName = ie->name();
00159                 re->interfacePtr = ie;
00160                 re->source = RoutingEntry::MANUAL;
00161                 re->netmask = IPAddress(255, 255, 0, 0);
00162                 re->gateway = IPAddress(next_hop_ip);
00163                 re->type = RoutingEntry::REMOTE;
00164 
00165                 rt->addRoutingEntry(re);
00166 
00167                 // Requirement 2: Each router has a point-to-point routing
00168                 // entry (netmask 255.255.255.255) for each immediate neighbour
00169                 if ( atNode->distanceToTarget() == 1 ) {
00170                     RoutingEntry* re2 = new RoutingEntry();
00171 
00172                     re2->host = IPAddress(destAddr);
00173                     re2->interfaceName = ie->name();
00174                     re2->interfacePtr = ie;
00175                     re2->source = RoutingEntry::MANUAL;
00176                     re2->netmask = IPAddress(255, 255, 255, 255);
00177                     re2->type = RoutingEntry::DIRECT;
00178 
00179                     rt->addRoutingEntry(re2);
00180                 }
00181 
00182                 // If destNode is the outRouter, add a default route
00183                 // to the next hop in the direction of the outRouter
00184                 if ( strcmp(destNode->module()->name(), "outRouter" ) == 0 ) {
00185                     RoutingEntry* defRoute = new RoutingEntry();
00186                     defRoute->host = IPAddress::UNSPECIFIED_ADDRESS;
00187                     defRoute->netmask = IPAddress::UNSPECIFIED_ADDRESS;
00188                     defRoute->gateway = IPAddress(next_hop_ip);
00189                     defRoute->interfaceName = ie->name();
00190                     defRoute->interfacePtr = ie;
00191                     defRoute->type = RoutingEntry::REMOTE;
00192                     defRoute->source = RoutingEntry::MANUAL;
00193                     
00194                     rt->addRoutingEntry(defRoute);
00195                 }
00196             }
00197         }
00198     }
00199     //accessnet configuration
00200     else if(stage == MAX_STAGE_UNDERLAY) {
00201         // fetch some parameters
00202         accessRouterNum = parentModule()->par("accessRouterNum");
00203         overlayAccessRouterNum = parentModule()->par("overlayAccessRouterNum");
00204 
00205         // flag indicating simulation initialization phase (true) vs. normal mode (false)
00206         init = true;
00207 
00208         // count the overlay clients
00209         overlayTerminalCount = 0;
00210         numCreated = 0;
00211         numKilled = 0;
00212 
00213         // add access node modules to access node vector
00214         // and assing the channel tpye to be used by the access node
00215         cModule* node;
00216         AccessNet* nodeAccess;
00217         for ( int i = 0; i < accessRouterNum; i++ ) {
00218             node = parentModule()->submodule("accessRouter", i);
00219             accessNode.push_back( node );
00220             nodeAccess = check_and_cast<AccessNet*>( node->submodule("accessNet") );
00221             nodeAccess->selectChannel( channelTypes[intuniform(0, channelTypes.size()-1)] );
00222         }
00223 
00224         for ( int i = 0; i < overlayAccessRouterNum; i++ ) {
00225             node = parentModule()->submodule("overlayAccessRouter", i);
00226             accessNode.push_back( node );
00227             nodeAccess = check_and_cast<AccessNet*>( node->submodule("accessNet") );
00228             nodeAccess->selectChannel( channelTypes[intuniform(0, channelTypes.size()-1)] );
00229         }
00230 
00231         // add the overlay nodes
00232         firstNodeId = createRandomNode(true);
00233         for ( int i = 1; i < initialOverlayTerminalNum; i++ ) {
00234             createRandomNode(true);
00235         }
00236 
00237         // debug stuff
00238         WATCH_PTRVECTOR(accessNode);
00239 
00240         // update display
00241         setDisplayString();
00242 
00243         // initialize simulation
00244         if ( par("simulateMobility") ) {
00245             cMessage* msg = new cMessage();
00246             scheduleAt(simulation.simTime(), msg);
00247         }
00248     }
00249 }

void IPv4UnderlayConfigurator::killRandomNode (  )  [virtual]

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

Implements UnderlayConfigurator.

00295 {
00296     // find an access net with one or more overlay nodes
00297     AccessNet* accessNetModule;
00298     do {
00299         int z = intuniform(0, accessNode.size()-1);
00300         accessNetModule = check_and_cast<AccessNet*>(accessNode[z]->submodule("accessNet"));
00301     } while ( accessNetModule->size() == 0 );
00302 
00303     // remove a random node from the access net and delete it
00304     int index = intuniform(0, accessNetModule->size() - 1);
00305     
00306     //TODO: keepFirstNode in while-loop?
00307     if(keepFirstNode && (firstNodeId == accessNetModule->getOverlayNodeId(index)))
00308       return;
00309 
00310     cModule* node = accessNetModule->removeOverlayNode(index);//intuniform(0, accessNetModule->size() - 1));
00311     node->callFinish();
00312     node->deleteModule();
00313 
00314     overlayTerminalCount--;
00315     numKilled++;
00316 }

void IPv4UnderlayConfigurator::migrateRandomNode (  )  [virtual]

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

Implements UnderlayConfigurator.

00319 {
00320     // find an access net with one or more overlay nodes
00321     AccessNet* accessNetModule;
00322     do {
00323         int z = intuniform(0, accessNode.size()-1);
00324         accessNetModule = check_and_cast<AccessNet*>(accessNode[z]->submodule("accessNet"));
00325     } while ( accessNetModule->size() == 0 );
00326 
00327     // disconnect a random overlay node
00328     int index = intuniform(0, accessNetModule->size() - 1);
00329     
00330     if(keepFirstNode && (firstNodeId == accessNetModule->getOverlayNodeId(index)))
00331       return;
00332 
00333     cModule* node = accessNetModule->removeOverlayNode(index);//intuniform(0, accessNetModule->size() - 1));
00334 
00335     node->bubble("I am migrating!");
00336 
00337     // connect the node to another access net
00338     AccessNet* newAccessNetModule;
00339     do {
00340         newAccessNetModule = check_and_cast<AccessNet*>(accessNode[intuniform(0, accessNode.size() - 1)]->submodule("accessNet"));
00341 
00342     } while((newAccessNetModule == accessNetModule) && (accessNode.size() != 1));
00343 
00344     newAccessNetModule->addOverlayNode(node, true);
00345 
00346     // inform the notofication board about the migration
00347     NotificationBoard* nb = check_and_cast<NotificationBoard*>(node->submodule("notificationBoard"));
00348     nb->fireChangeNotification(NF_HOSTPOSITION_UPDATED);
00349 }

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

Updates the statistics display string.

Implements UnderlayConfigurator.

00352 {
00353     char buf[80];
00354     sprintf(buf, "%i overlay clients\n%i access router\n%i overlay access router", overlayTerminalCount, accessRouterNum, overlayAccessRouterNum);
00355     displayString().setTagArg("t", 0, buf);
00356 }


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 Wed Apr 4 13:37:06 2007 for ITM OverSim by  doxygen 1.4.7