OverSim
RUNetworkConfigurator.cc
Go to the documentation of this file.
1 //
2 // Copyright (C) 2010 Institut fuer Telematik, Karlsruher Institut fuer Technologie (KIT)
3 //
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 //
18 
25 #include "RUNetworkConfigurator.h"
26 #include <sstream>
27 
28 
30 
31 using namespace std;
32 using namespace RUNetConf;
33 
35 {
36 }
37 
39 {
40 }
41 
43 {
44  if (stage != 2)
45  return;
46 
47 
48  //TODO: read number of AS
49  cTopology tempTopology("tempTopo");
50  tempTopology.extractByProperty("AS");
51 
52  noAS = tempTopology.getNumNodes();
53  cout << noAS <<endl;
54  nextPow = 1;
55  while ((1 << nextPow) < noAS + 1) {
56  nextPow++;
57  }
58  IP_NET_SHIFT = 32 - nextPow;
59  NET_MASK = 0xffffffff << IP_NET_SHIFT;
60 
61  // extract topology nodes and assign IP addresses
62  extractTopology();
63 
64  // assign an IPAddress to all nodes in the network
65  //FIXME: does asNodeVec.size() work as intended? may need to use noAS instead
66  for (unsigned int i = 0; i < asNodeVec.size(); i++) {
67  if ((unsigned int) rlTopology[i]->getNumNodes() > (0xffffffff - NET_MASK))
68  opp_error("to many nodes in current topology");
69  cerr << asNodeVec[i].module->getFullPath() << endl;
70  //
71  // insert each router-level node into a node map
72  //
73  for (int j = 0; j < rlTopology[i]->getNumNodes(); j++) {
74  nodeInfoRL curRLNode(rlTopology[i]->getNode(j));
75  asNodeVec[i].nodeMap.insert(NODE_MAP_PAIR(curRLNode.moduleId, curRLNode));
76  }
77 
78  // assign IP address and add default route
79  assignAddressAndSetDefaultRoutes(asNodeVec[i]);
80  }
81 
82  // add all further routes in router-level topology
83  // (unequal to default route)
84  for (unsigned int i = 0; i < asNodeVec.size(); i++)
85  setIntraASRoutes(*rlTopology[i], asNodeVec[i]);
86 
87  // Having configured all router topologies, add Inter-AS routing paths
88  if (noAS > 0)
89  createInterASPaths();
90 
91  // free Memory
92  for (int i = 0; i < noAS; i++) {
93  rlTopology[i]->clear();
94  delete rlTopology[i];
95  asNodeVec[i].nodeMap.clear();
96  }
97  asTopology.clear();
98  asNodeVec.clear();
99  tempTopology.clear();
100 }
101 
103 {
104  IPAddress netmask(NET_MASK);
105  int asIdHistory = 0;
106  unsigned int tmpAddr = 0;
107  for (int i = 0; i < asTopology.getNumNodes(); i++) {
108  // calculate prefix of current core node
109  nodeInfoRL destCore(asTopology.getNode(i));
110  tmpAddr = destCore.addr.getInt() >> IP_NET_SHIFT;
111  tmpAddr = tmpAddr << IP_NET_SHIFT;
112  destCore.addr = IPAddress(tmpAddr);
113  asIdHistory = -1;
114  for (int j = 0; j < asTopology.getNumNodes(); j++) {
115  if (i == j)
116  continue;
117  nodeInfoRL srcCore(asTopology.getNode(j));
118  tmpAddr = srcCore.addr.getInt() >> IP_NET_SHIFT;
119  tmpAddr = tmpAddr << IP_NET_SHIFT;
120  srcCore.addr = IPAddress(tmpAddr);
121 
122  // do not calculate paths between nodes of the same AS
123  if (destCore.asId == srcCore.asId)
124  continue;
125 
126  // cross only transit AS in order to reach destination core node
127  // therefore, temporarily disable all stub links
128  if (asIdHistory != srcCore.asId) {
129  disableStubLinks(destCore, srcCore);
130  asTopology.calculateUnweightedSingleShortestPathsTo(destCore.node);
131  }
132  // add routing entry from srcCore to destCore into routing table of srcCore
133  InterfaceEntry *ie = srcCore.ift->getInterfaceByNodeOutputGateId(srcCore.node->getPath(0)->getLocalGate()->getId());
134  IPRoute *e = new IPRoute();
135  e->setHost(destCore.addr);
136  e->setNetmask(netmask);
137  e->setInterface(ie);
138  e->setType(IPRoute::DIRECT);
139  e->setSource(IPRoute::MANUAL);
140  srcCore.rt->addRoute(e);
141 
142  // re-enable all stub links
143  if (asIdHistory != srcCore.asId) {
144  enableStubLinks();
145  }
146  asIdHistory = srcCore.asId;
147  }
148  }
149 }
150 
152 {
153  for (unsigned int i = 0; i < asNodeVec.size(); i++) {
154  if ((asNodeVec[i].id == dst.asId) || (asNodeVec[i].id == src.asId))
155  continue;
156  if (asNodeVec[i].asType == TRANSIT_AS)
157  continue;
158 
159  for (unsigned int j = 0; j < asNodeVec[i].coreNode.size(); j++) {
160  for (int k = 0; k < asNodeVec[i].coreNode[j].node->getNumInLinks(); k++)
161  asNodeVec[i].coreNode[j].node->getLinkIn(k)->disable();
162  }
163  }
164 }
165 
167 {
168  for (unsigned int i = 0; i < asNodeVec.size(); i++) {
169  if (asNodeVec[i].asType == TRANSIT_AS)
170  continue;
171  for (unsigned int j = 0; j < asNodeVec[i].coreNode.size(); j++) {
172  for (int k = 0; k < asNodeVec[i].coreNode[j].node->getNumInLinks(); k++)
173  asNodeVec[i].coreNode[j].node->getLinkIn(k)->enable();
174  }
175  }
176 }
177 
179 {
180  cTopology currentAS;
181 
182  // get the AS-level topology
183  if (noAS > 0) {
184  currentAS.extractByProperty("AS"); //TODO: check if this is acceptable
185  if (currentAS.getNumNodes() != noAS)
186  opp_error("Error: AS-Topology contains %u elements - expected %u\n", currentAS.getNumNodes(), noAS);
187  }
188  else if (noAS == 0) {
189  // Network is router-level only
190  currentAS.extractByProperty("Internet"); //TODO: check if this is acceptable
191  if (currentAS.getNumNodes() != 1)
192  opp_error("Error: tried to extract router-level only topology, but found more than 1 Inet module\n");
193  }
194 
195  // get each router-level topology
196  unsigned int netIP = 1 << IP_NET_SHIFT;
197  for (int i = 0; i < currentAS.getNumNodes(); i++) {
198  cTopology *tmpTopo = new cTopology();
199  // extract router-level nodes from NED file
200  tmpTopo->extractFromNetwork(getRouterLevelNodes, (void *) currentAS.getNode(i)->getModule()->getName());
201  rlTopology.push_back(tmpTopo);
202  // assign unique /16 IP address prefix to each AS
203  asNodeVec.push_back(nodeInfoAS(currentAS.getNode(i), IPAddress(netIP), IPAddress(NET_MASK)));
204  netIP += 1 << IP_NET_SHIFT;
205  }
206 
207  asTopology.extractFromNetwork(getCoreNodes); //TODO: the extra function may be superfuous. extraction could be probably be done via asTopology.extractByProperty("CoreRouter"); -Claus
208 
209  //free memory
210  currentAS.clear();
211 }
212 
213 bool RUNetConf::getRouterLevelNodes(cModule *curMod, void *name)
214 {
215  char *curName = (char*) name;
216  if (curName == NULL)
217  opp_error("Error while casting void* name to char*\n");
218 
219  string sCurName = curName;
220  sCurName += ".";
221  string curModPath = curMod->getFullPath();
222  if (curModPath.find(sCurName) == string::npos)
223  return 0;
224  //TODO: took some code from ctopology.cc to implement this, check if functionality is correct -Claus
225  const char* property = "RL";
226  cProperty *prop = curMod->getProperties()->get(property);
227  if (!prop)
228  return 0;
229  const char *value = prop->getValue(cProperty::DEFAULTKEY, 0);
230  return opp_strcmp(value, "false")!=0;
231 }
232 
233 bool RUNetConf::getCoreNodes(cModule *curMod, void *nullPointer)
234 {
235  //TODO: took some code from ctopology.cc to implement this, check if functionality is correct -Claus
236  const char* property = "CoreRouter";
237  cProperty *prop = curMod->getProperties()->get(property);
238  if (!prop)
239  return 0;
240  const char *value = prop->getValue(cProperty::DEFAULTKEY, 0);
241  return opp_strcmp(value, "false")!=0;
242 }
243 
245 {
246  unsigned int currentIP = asInfo.addr.getInt() + 1;
247  int countEdgeRouter = 2; // avoids IP address 127.0.0.1
248  int countRouter = 1;
249  int edgeShift = 0;
250 
251  NODE_MAP::iterator mapIt = asInfo.nodeMap.begin();
252  while (mapIt != asInfo.nodeMap.end()) {
253  if (mapIt->second.routerType == EDGE) {
254  countEdgeRouter++;
255  }
256  mapIt++;
257  }
258 
259  nextPow = 0;
260  while ((1 << nextPow) < countEdgeRouter) {
261  nextPow++;
262  }
263 
264  edgeShift = IP_NET_SHIFT - nextPow;
265  asInfo.subnetmask = IPAddress(0xffffffff << edgeShift);
266  countEdgeRouter = 1;
267 
268  mapIt = asInfo.nodeMap.begin();
269  while (mapIt != asInfo.nodeMap.end()) {
270  if (mapIt->second.routerType == ENDSYS) {
271  mapIt++;
272  continue;
273  }
274 
275  if (mapIt->second.routerType == EDGE) {
276  currentIP = asInfo.addr.getInt() + 1 + (countEdgeRouter++ << edgeShift);
277  edgeRouter temp;
278  temp.edgeIP = currentIP;
279  temp.usedIPs = 1;
280  temp.module = mapIt->second.module;
281  asInfo.edgeRouter.push_back(temp);
282  }
283  else {
284  currentIP = asInfo.addr.getInt() + countRouter++;
285  }
286 
287  for (int j = 0; j < mapIt->second.ift->getNumInterfaces(); j++) {
288  //
289  // all interfaces except loopback get the same IP address
290  //
291  InterfaceEntry *ie = mapIt->second.ift->getInterface(j);
292  if (!ie->isLoopback()) {
293  ie->ipv4Data()->setIPAddress(IPAddress(currentIP));
294  ie->ipv4Data()->setNetmask(IPAddress::ALLONES_ADDRESS);
295  }
296  }
297  if (mapIt->second.rt->getRouterId().isUnspecified())
298  mapIt->second.rt->setRouterId(IPAddress(currentIP));
299  mapIt->second.addr.set(currentIP);
300 
301  // remember core nodes of each AS in additional list for assignment
302  // of Inter-AS routing paths
303  if (mapIt->second.routerType == CORE)
304  asInfo.coreNode.push_back(mapIt->second);
305  else {
306  //
307  // add default route in case of gw, edge, or host
308  //
309  IPRoute *e = new IPRoute();
310  e->setHost(IPAddress());
311  e->setNetmask(IPAddress());
312  e->setInterface(mapIt->second.defaultRouteIE);
313  e->setType(IPRoute::REMOTE);
314  e->setSource(IPRoute::MANUAL);
315  //e->setMetric(1);
316  mapIt->second.rt->addRoute(e);
317  }
318 
319  currentIP++;
320  mapIt++;
321  }
322 }
323 
324 void RUNetworkConfigurator::setIntraASRoutes(cTopology &topology, nodeInfoAS &asInfo)
325 {
326  // calculate static routes from each of the AS's router-level nodes to all
327  // other nodes of the AS
328 
329  for (int i = 0; i < topology.getNumNodes(); i++) {
330  nodeInfoRL destNode = asInfo.nodeMap[topology.getNode(i)->getModule()->getId()];
331  //
332  // calculate shortest path form everywhere toward destNode
333  //
334  topology.calculateUnweightedSingleShortestPathsTo(destNode.node);
335  for (int j = 0; j < topology.getNumNodes(); j++) {
336  if (j == i)
337  continue;
338  nodeInfoRL srcNode = asInfo.nodeMap[topology.getNode(j)->getModule()->getId()];
339  // no route exists at all
340  if (srcNode.node->getNumPaths() == 0)
341  continue;
342  // end systems only know a default route to the edge router
343  else if (srcNode.routerType == ENDSYS)
344  continue;
345  else if (destNode.routerType == ENDSYS) {
346  if (srcNode.routerType != EDGE)
347  continue;
348  InterfaceEntry *ie = srcNode.ift->getInterfaceByNodeOutputGateId(srcNode.node->getPath(0)->getLocalGate()->getId());
349  if (ie == srcNode.defaultRouteIE)
350  continue;
351 
352  for (uint32 i = 0; i < asInfo.edgeRouter.size(); i++) {
353 
354  if (srcNode.module == asInfo.edgeRouter[i].module) {
355 
356  destNode.addr = IPAddress(asInfo.edgeRouter[i].edgeIP + asInfo.edgeRouter[i].usedIPs);
357  asInfo.edgeRouter[i].usedIPs++;
358  }
359  }
360 
361  for (int j = 0; j < destNode.ift->getNumInterfaces(); j++) {
362  //
363  // all interfaces except loopback get the same IP address
364  //
365  InterfaceEntry *ie = destNode.ift->getInterface(j);
366  if (!ie->isLoopback()) {
367  ie->ipv4Data()->setIPAddress(destNode.addr);
368  ie->ipv4Data()->setNetmask(IPAddress::ALLONES_ADDRESS);
369  }
370  }
371  IPRoute *e = new IPRoute();
372  e->setHost(IPAddress());
373  e->setNetmask(IPAddress());
374  e->setInterface(destNode.defaultRouteIE);
375  e->setType(IPRoute::REMOTE);
376  e->setSource(IPRoute::MANUAL);
377  destNode.rt->addRoute(e);
378 
379  ie = srcNode.ift->getInterfaceByNodeOutputGateId(srcNode.node->getPath(0)->getLocalGate()->getId());
380  e = new IPRoute();
381  e->setHost(destNode.addr);
382  e->setNetmask(IPAddress(255, 255, 255, 255));
383  e->setInterface(ie);
384  e->setType(IPRoute::DIRECT);
385  e->setSource(IPRoute::MANUAL);
386  srcNode.rt->addRoute(e);
387  }
388  else {
389  //
390  // if destination is reachable through default route, no routing entry is necessary
391  //
392  InterfaceEntry *ie = srcNode.ift->getInterfaceByNodeOutputGateId(srcNode.node->getPath(0)->getLocalGate()->getId());
393  if (ie == srcNode.defaultRouteIE)
394  continue;
395  else {
396  // add specific routing entry into routing table
397  IPRoute *e = new IPRoute();
398  e->setHost(destNode.addr);
399  if (destNode.routerType == EDGE)
400  e->setNetmask(asInfo.subnetmask);
401  else
402  e->setNetmask(IPAddress(255, 255, 255, 255));
403  e->setInterface(ie);
404  e->setType(IPRoute::DIRECT);
405  e->setSource(IPRoute::MANUAL);
406  srcNode.rt->addRoute(e);
407  }
408  }
409  }
410  }
411 }
412 
413