A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
brite-topology-helper.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License version 2 as
5  * published by the Free Software Foundation;
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15  *
16  */
17 
18 #include "ns3/log.h"
19 #include "ns3/abort.h"
20 #include "ns3/net-device.h"
21 #include "ns3/net-device-container.h"
22 #include "ns3/point-to-point-helper.h"
23 #include "ns3/ipv4-address-helper.h"
24 #include "ns3/random-variable-stream.h"
25 #include "ns3/data-rate.h"
26 #include "ns3/rng-seed-manager.h"
27 
28 #include "brite-topology-helper.h"
29 
30 #include <iostream>
31 #include <fstream>
32 
33 NS_LOG_COMPONENT_DEFINE ("BriteTopologyHelper");
34 
35 namespace ns3 {
36 
38  std::string seedFile,
39  std::string newseedFile) : m_confFile (confFile),
40  m_seedFile (seedFile),
41  m_newSeedFile (newseedFile),
42  m_numAs (0),
43  m_topology (NULL),
44  m_numNodes (0),
45  m_numEdges (0)
46 {
47  NS_LOG_FUNCTION (this);
48 
49  m_uv = CreateObject<UniformRandomVariable> ();
50 
51 }
52 
53 BriteTopologyHelper::BriteTopologyHelper (std::string confFile) : m_confFile (confFile),
54  m_numAs (0),
55  m_topology (NULL),
56  m_numNodes (0),
57  m_numEdges (0)
58 {
59  NS_LOG_FUNCTION (this);
60 
61  m_uv = CreateObject<UniformRandomVariable> ();
62 
63 }
64 
66 {
67  NS_LOG_FUNCTION (this);
68  delete m_topology;
69 
70  while (!m_netDevices.empty ())
71  {
72  delete m_netDevices.back ();
73  m_netDevices.pop_back ();
74  }
75 
76  while (!m_asLeafNodes.empty ())
77  {
78  delete m_asLeafNodes.back ();
79  m_asLeafNodes.pop_back ();
80  }
81 
82  while (!m_nodesByAs.empty ())
83  {
84  delete m_nodesByAs.back ();
85  m_nodesByAs.pop_back ();
86  }
87 }
88 
89 void
90 BriteTopologyHelper::AssignStreams (int64_t streamNumber)
91 {
92  m_uv->SetStream (streamNumber);
93 }
94 
95 void
97 {
98  NS_LOG_FUNCTION (this);
99  brite::Graph *g = m_topology->GetGraph ();
100  for (int i = 0; i < g->GetNumNodes (); ++i)
101  {
102  BriteNodeInfo nodeInfo;
103  nodeInfo.nodeId = g->GetNodePtr (i)->GetId ();
104  nodeInfo.xCoordinate = g->GetNodePtr (i)->GetNodeInfo ()->GetCoordX ();
105  nodeInfo.yCoordinate = g->GetNodePtr (i)->GetNodeInfo ()->GetCoordY ();
106  nodeInfo.inDegree = g->GetNodePtr (i)->GetInDegree ();
107  nodeInfo.outDegree = g->GetNodePtr (i)->GetOutDegree ();
108 
109  switch (g->GetNodePtr (i)->GetNodeInfo ()->GetNodeType ())
110  {
111  case brite::NodeConf::RT_NODE:
112 
113  if (((brite::RouterNodeConf*)(g->GetNodePtr (i)->GetNodeInfo ()))->GetASId () == -1)
114  {
115  m_numAs = nodeInfo.asId = 0;
116  }
117  else
118  {
119  m_numAs = nodeInfo.asId = ((brite::RouterNodeConf*)(g->GetNodePtr (i)->GetNodeInfo ()))->GetASId ();
120  }
121 
122  switch (((brite::RouterNodeConf*)(g->GetNodePtr (i)->GetNodeInfo ()))->GetRouterType ())
123  {
124  case brite::RouterNodeConf::RT_NONE:
125  nodeInfo.type = "RT_NONE ";
126  break;
127  case brite::RouterNodeConf::RT_LEAF:
128  nodeInfo.type = "RT_LEAF ";
129  break;
130  case brite::RouterNodeConf::RT_BORDER:
131  nodeInfo.type = "RT_BORDER";
132  break;
133  case brite::RouterNodeConf::RT_STUB:
134  nodeInfo.type = "RT_STUB ";
135  break;
136  case brite::RouterNodeConf::RT_BACKBONE:
137  nodeInfo.type = "RT_BACKBONE ";
138  break;
139  default:
140  NS_FATAL_ERROR ("Topology::Output(): Improperly classfied Router node encountered...");
141  }
142  break;
143 
144  case brite::NodeConf::AS_NODE:
145  m_numAs = nodeInfo.asId =
146  ((brite::ASNodeConf*)(g->GetNodePtr (i)->GetNodeInfo ()))->GetASId ();
147 
148  switch (((brite::ASNodeConf*)(g->GetNodePtr (i)->GetNodeInfo ()))->GetASType ())
149  {
150  case brite::ASNodeConf::AS_NONE:
151  nodeInfo.type = "AS_NONE ";
152  break;
153  case brite::ASNodeConf::AS_LEAF:
154  nodeInfo.type = "AS_LEAF ";
155  break;
156  case brite::ASNodeConf::AS_STUB:
157  nodeInfo.type = "AS_STUB ";
158  break;
159  case brite::ASNodeConf::AS_BORDER:
160  nodeInfo.type = "AS_BORDER ";
161  break;
162  case brite::ASNodeConf::AS_BACKBONE:
163  nodeInfo.type = "AS_BACKBONE ";
164  break;
165  default:
166  NS_FATAL_ERROR ("Topology::Output(): Improperly classfied AS node encountered...");
167  }
168  break;
169  }
170 
171  m_briteNodeInfoList.push_back (nodeInfo);
172  }
173 
174  //Currently m_numAs stores the highest AS number. We want m_numAs to store the number
175  //of AS created in the topology. Since AS numbering starts at 0 we add one to get
176  //the correct count
177  m_numAs++;
178 }
179 
180 void
182 {
183  NS_LOG_FUNCTION (this);
184  brite::Graph *g = m_topology->GetGraph ();
185  std::list<brite::Edge*>::iterator el;
186  std::list<brite::Edge*> edgeList = g->GetEdges ();
187 
188  for (el = edgeList.begin (); el != edgeList.end (); el++)
189  {
190  BriteEdgeInfo edgeInfo;
191  edgeInfo.edgeId = (*el)->GetId ();
192  edgeInfo.srcId = (*el)->GetSrc ()->GetId ();
193  edgeInfo.destId = (*el)->GetDst ()->GetId ();
194  edgeInfo.length = (*el)->Length ();
195 
196  switch ((*el)->GetConf ()->GetEdgeType ())
197  {
198  case brite::EdgeConf::RT_EDGE:
199  edgeInfo.delay = ((brite::RouterEdgeConf*)((*el)->GetConf ()))->GetDelay ();
200  edgeInfo.bandwidth = (*el)->GetConf ()->GetBW ();
201  //If there is only one AS, BRITE will use -1 as AS Number. We want it to be 0 instead.
202  edgeInfo.asFrom = (((brite::RouterNodeConf*)((*el)->GetSrc ()->GetNodeInfo ()))->GetASId () == -1) ? 0 : ((brite::RouterNodeConf*)((*el)->GetSrc ()->GetNodeInfo ()))->GetASId ();
203  edgeInfo.asTo = (((brite::RouterNodeConf*)((*el)->GetDst ()->GetNodeInfo ()))->GetASId () == -1) ? 0 : ((brite::RouterNodeConf*)((*el)->GetDst ()->GetNodeInfo ()))->GetASId ();
204  break;
205 
206  case brite::EdgeConf::AS_EDGE:
207  edgeInfo.delay = -1; /* No delay for AS Edges */
208  edgeInfo.bandwidth = (*el)->GetConf ()->GetBW ();
209  edgeInfo.asFrom = ((brite::ASNodeConf*)((*el)->GetSrc ()->GetNodeInfo ()))->GetASId ();
210  edgeInfo.asTo = ((brite::ASNodeConf*)((*el)->GetDst ()->GetNodeInfo ()))->GetASId ();
211  break;
212 
213  default:
214  NS_FATAL_ERROR ("Topology::Output(): Invalid Edge type encountered...");
215  }
216 
217  switch ((*el)->GetConf ()->GetEdgeType ())
218  {
219  case brite::EdgeConf::RT_EDGE:
220  switch (((brite::RouterEdgeConf*)(*el)->GetConf ())->GetRouterEdgeType ())
221  {
222  case brite::RouterEdgeConf::RT_NONE:
223  edgeInfo.type = "E_RT_NONE ";
224  break;
225  case brite::RouterEdgeConf::RT_STUB:
226  edgeInfo.type = "E_RT_STUB ";
227  break;
228  case brite::RouterEdgeConf::RT_BORDER:
229  edgeInfo.type = "E_RT_BORDER ";
230  break;
231  case brite::RouterEdgeConf::RT_BACKBONE:
232  edgeInfo.type = "E_RT_BACKBONE ";
233  break;
234  default:
235  NS_FATAL_ERROR ("Output(): Invalid router edge type...");
236  }
237  break;
238 
239  case brite::EdgeConf::AS_EDGE:
240  switch (((brite::ASEdgeConf*)((*el)->GetConf ()))->GetASEdgeType ())
241  {
242  case brite::ASEdgeConf::AS_NONE:
243  edgeInfo.type = "E_AS_NONE ";
244  break;
245  case brite::ASEdgeConf::AS_STUB:
246  edgeInfo.type = "E_AS_STUB ";
247  break;
248  case brite::ASEdgeConf::AS_BORDER:
249  edgeInfo.type = "E_AS_BORDER ";
250  break;
251  case brite::ASEdgeConf::AS_BACKBONE:
252  edgeInfo.type = "E_AS_BACKBONE ";
253  break;
254  default:
255  NS_FATAL_ERROR ("BriteOutput(): Invalid AS edge type...");
256  }
257  break;
258 
259  default:
260  NS_FATAL_ERROR ("BriteOutput(): Invalid edge type...");
261 
262  }
263 
264  m_briteEdgeInfoList.push_back (edgeInfo);
265  }
266 }
267 
268 Ptr<Node>
269 BriteTopologyHelper::GetLeafNodeForAs (uint32_t asNum, uint32_t leafNum)
270 {
271  return m_asLeafNodes[asNum]->Get (leafNum);
272 }
273 
274 Ptr<Node>
275 BriteTopologyHelper::GetNodeForAs (uint32_t asNum, uint32_t nodeNum)
276 {
277  return m_nodesByAs[asNum]->Get (nodeNum);
278 }
279 
280 uint32_t
282 {
283  return m_nodesByAs[asNum]->GetN ();
284 }
285 
286 uint32_t
288 {
289  return m_asLeafNodes[asNum]->GetN ();
290 }
291 
292 uint32_t
294 {
295  return m_numNodes;
296 }
297 
298 uint32_t
300 {
301  return m_numEdges;
302 }
303 
304 uint32_t
306 {
307  return m_numAs;
308 }
309 
310 uint32_t
312 {
313  return m_systemForAs[asNum];
314 }
315 
317 {
318  NS_ASSERT_MSG (m_topology == NULL, "Brite Topology Already Created");
319 
320  //check to see if need to generate seed file
321  bool generateSeedFile = m_seedFile.empty ();
322 
323  if (generateSeedFile)
324  {
325  NS_LOG_LOGIC ("Generating BRITE Seed file");
326 
327  std::ofstream seedFile;
328 
329  //overwrite file if already there
330  seedFile.open ("briteSeedFile.txt", std::ios_base::out | std::ios_base::trunc);
331 
332  //verify open
333  NS_ASSERT (!seedFile.fail ());
334 
335  //Generate seed file expected by BRITE
336  //need unsigned shorts 0-65535
337  seedFile << "PLACES " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << std::endl;
338  seedFile << "CONNECT " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << std::endl;
339  seedFile << "EDGE_CONN " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << std::endl;
340  seedFile << "GROUPING " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << std::endl;
341  seedFile << "ASSIGNMENT " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << std::endl;
342  seedFile << "BANDWIDTH " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << std::endl;
343  seedFile.close ();
344 
345  //if we're using NS3 generated seed files don't want brite to create a new seed file.
346  m_seedFile = m_newSeedFile = "briteSeedFile.txt";
347  }
348 
349  brite::Brite br (m_confFile, m_seedFile, m_newSeedFile);
350  m_topology = br.GetTopology ();
353 
354  //brite automatically spits out the seed values used to a seperate file so no need to keep this anymore
355  if (generateSeedFile)
356  {
357  remove ("briteSeedFile.txt");
358  }
359 
360 }
361 
362 void
364 {
365  NS_LOG_FUNCTION (this);
366 
368 
369  //not using MPI so each AS is on system number 0
370  for (uint32_t i = 0; i < m_numAs; ++i)
371  {
372  m_systemForAs.push_back (0);
373  }
374 
375  //create all nodes with system number 0
377 
379 
380  NS_LOG_DEBUG (m_numNodes << " nodes created in BRITE topology");
381 
382  stack.Install (m_nodes);
383 
385 }
386 
387 void
389 {
390  NS_LOG_FUNCTION (this);
391 
393 
394  //determine as system number for each AS
395  NS_LOG_LOGIC ("Assigning << " << m_numAs << " AS to " << systemCount << " MPI instances");
396  for (uint32_t i = 0; i < m_numAs; ++i)
397  {
398  int val = i % systemCount;
399  m_systemForAs.push_back (val);
400  NS_LOG_INFO ("AS: " << i << " System: " << val);
401  }
402 
403  //create nodes
404  for (BriteTopologyHelper::BriteNodeInfoList::iterator it = m_briteNodeInfoList.begin (); it != m_briteNodeInfoList.end (); ++it)
405  {
406  m_nodes.Add (CreateObject<Node> (GetSystemNumberForAs ((*it).asId)));
407  m_numNodes++;
408  }
409 
410  NS_LOG_INFO (m_numNodes << " nodes created in BRITE topology");
411 
412  stack.Install (m_nodes);
413 
415 }
416 
417 void
419 {
420  NS_LOG_FUNCTION (this);
421  //assign IPs
422  for (unsigned int i = 0; i < m_netDevices.size (); ++i)
423  {
424  address.Assign (*m_netDevices[i]);
425  address.NewNetwork ();
426  }
427 }
428 
429 void
431 {
432  NS_LOG_FUNCTION (this);
433 
434  for (unsigned int i = 0; i < m_netDevices.size (); ++i)
435  {
436  address.Assign (*m_netDevices[i]);
437  address.NewNetwork ();
438  }
439 }
440 
441 void
443 {
444  NS_LOG_FUNCTION (this);
445  //create one node container to hold leaf nodes for attaching
446  for (uint32_t i = 0; i < m_numAs; ++i)
447  {
448  m_asLeafNodes.push_back (new NodeContainer ());
449  m_nodesByAs.push_back (new NodeContainer ());
450  }
451 
452  for (BriteTopologyHelper::BriteEdgeInfoList::iterator it = m_briteEdgeInfoList.begin (); it != m_briteEdgeInfoList.end (); ++it)
453  {
454  // Set the link delay
455  // The brite value for delay is given in milliseconds
457  TimeValue (MilliSeconds ((*it).delay)));
458 
459  // The brite value for data rate is given in Mbps
461  DataRateValue (DataRate ((*it).bandwidth * mbpsToBps)));
462 
463  m_netDevices.push_back ( new NetDeviceContainer ( m_britePointToPointHelper.Install (m_nodes.Get ((*it).srcId), m_nodes.Get ((*it).destId))));
464 
465  m_numEdges++;
466 
467  }
468 
469  NS_LOG_INFO ("Created " << m_numEdges << " edges in BRITE topology");
470 
471  //iterate through all nodes and add leaf nodes for each AS
472  for (BriteTopologyHelper::BriteNodeInfoList::iterator it = m_briteNodeInfoList.begin (); it != m_briteNodeInfoList.end (); ++it)
473  {
474  m_nodesByAs[(*it).asId]->Add (m_nodes.Get ((*it).nodeId));
475 
476  if ((*it).type == "RT_LEAF ")
477  {
478  m_asLeafNodes[(*it).asId]->Add (m_nodes.Get ((*it).nodeId));
479  }
480  }
481 }
482 
483 } // namespace ns3
uint32_t GetNNodesForAs(uint32_t asNum)
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
uint32_t GetNLeafNodesForAs(uint32_t asNum)
void SetStream(int64_t stream)
Specifies the stream number for this RNG stream.
uint32_t GetInteger(uint32_t min, uint32_t max)
Returns a random unsigned integer from a uniform distribution over the interval [min,max] including both ends.
NetDeviceContainer Install(NodeContainer c)
Ptr< Node > GetNodeForAs(uint32_t asNum, uint32_t nodeNum)
#define NS_ASSERT(condition)
Definition: assert.h:64
uint32_t GetNAs(void) const
aggregate IP/TCP/UDP functionality to existing Nodes.
void AssignIpv6Addresses(Ipv6AddressHelper &address)
#define NS_LOG_INFO(msg)
Definition: log.h:264
void SetDeviceAttribute(std::string name, const AttributeValue &value)
void AssignStreams(int64_t streamNumber)
std::vector< NodeContainer * > m_nodesByAs
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
Ipv6InterfaceContainer Assign(const NetDeviceContainer &c)
Allocate an Ipv6InterfaceContainer with auto-assigned addresses.
Class for representing data rates.
Definition: data-rate.h:71
hold objects of type ns3::Time
Definition: nstime.h:828
BriteTopologyHelper(std::string confFile, std::string seedFile, std::string newseedFile)
void AssignIpv4Addresses(Ipv4AddressHelper &address)
holds a vector of ns3::NetDevice pointers
std::vector< int > m_systemForAs
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
keep track of a set of node pointers.
void Install(std::string nodeName) const
BriteNodeInfoList m_briteNodeInfoList
tuple stack
Definition: first.py:34
void SetChannelAttribute(std::string name, const AttributeValue &value)
Helper class to auto-assign global IPv6 unicast addresses.
#define NS_ASSERT_MSG(condition, message)
Definition: assert.h:86
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
void Add(NodeContainer other)
Append the contents of another NodeContainer to the end of this container.
uint32_t GetSystemNumberForAs(uint32_t asNum) const
hold objects of type ns3::DataRate
Ptr< Node > Get(uint32_t i) const
Get the Ptr stored in this container at a given index.
Ptr< UniformRandomVariable > m_uv
#define NS_LOG_DEBUG(msg)
Definition: log.h:255
std::vector< NetDeviceContainer * > m_netDevices
std::vector< NodeContainer * > m_asLeafNodes
PointToPointHelper m_britePointToPointHelper
Ipv4Address NewNetwork(void)
Increment the network number and reset the IP address counter to the base value provided in the SetBa...
void NewNetwork(Ipv6Address network, Ipv6Prefix prefix) NS_DEPRECATED
Allocate a new network.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
tuple address
Definition: first.py:37
NS_LOG_COMPONENT_DEFINE("BriteTopologyHelper")
Ptr< Node > GetLeafNodeForAs(uint32_t asNum, uint32_t leafNum)
void BuildBriteTopology(InternetStackHelper &stack)
BriteEdgeInfoList m_briteEdgeInfoList