A Discrete-Event Network Simulator
API
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 namespace ns3 {
34 
35 NS_LOG_COMPONENT_DEFINE ("BriteTopologyHelper");
36 
38  std::string seedFile,
39  std::string newseedFile)
40  : m_confFile (confFile),
41  m_seedFile (seedFile),
42  m_newSeedFile (newseedFile),
43  m_numAs (0),
44  m_topology (NULL),
45  m_numNodes (0),
46  m_numEdges (0)
47 {
48  NS_LOG_FUNCTION (this);
49 
50  m_uv = CreateObject<UniformRandomVariable> ();
51 
52 }
53 
55  : m_confFile (confFile),
56  m_numAs (0),
57  m_topology (NULL),
58  m_numNodes (0),
59  m_numEdges (0)
60 {
61  NS_LOG_FUNCTION (this);
62 
63  m_uv = CreateObject<UniformRandomVariable> ();
64 
65 }
66 
68 {
69  NS_LOG_FUNCTION (this);
70  delete m_topology;
71 
72  while (!m_netDevices.empty ())
73  {
74  delete m_netDevices.back ();
75  m_netDevices.pop_back ();
76  }
77 
78  while (!m_asLeafNodes.empty ())
79  {
80  delete m_asLeafNodes.back ();
81  m_asLeafNodes.pop_back ();
82  }
83 
84  while (!m_nodesByAs.empty ())
85  {
86  delete m_nodesByAs.back ();
87  m_nodesByAs.pop_back ();
88  }
89 }
90 
91 void
92 BriteTopologyHelper::AssignStreams (int64_t streamNumber)
93 {
94  m_uv->SetStream (streamNumber);
95 }
96 
97 void
99 {
100  NS_LOG_FUNCTION (this);
101  brite::Graph *g = m_topology->GetGraph ();
102  for (int i = 0; i < g->GetNumNodes (); ++i)
103  {
104  BriteNodeInfo nodeInfo;
105  nodeInfo.nodeId = g->GetNodePtr (i)->GetId ();
106  nodeInfo.xCoordinate = g->GetNodePtr (i)->GetNodeInfo ()->GetCoordX ();
107  nodeInfo.yCoordinate = g->GetNodePtr (i)->GetNodeInfo ()->GetCoordY ();
108  nodeInfo.inDegree = g->GetNodePtr (i)->GetInDegree ();
109  nodeInfo.outDegree = g->GetNodePtr (i)->GetOutDegree ();
110 
111  switch (g->GetNodePtr (i)->GetNodeInfo ()->GetNodeType ())
112  {
113  case brite::NodeConf::RT_NODE:
114 
115  if (((brite::RouterNodeConf*)(g->GetNodePtr (i)->GetNodeInfo ()))->GetASId () == -1)
116  {
117  m_numAs = nodeInfo.asId = 0;
118  }
119  else
120  {
121  m_numAs = nodeInfo.asId = ((brite::RouterNodeConf*)(g->GetNodePtr (i)->GetNodeInfo ()))->GetASId ();
122  }
123 
124  switch (((brite::RouterNodeConf*)(g->GetNodePtr (i)->GetNodeInfo ()))->GetRouterType ())
125  {
126  case brite::RouterNodeConf::RT_NONE:
127  nodeInfo.type = "RT_NONE ";
128  break;
129  case brite::RouterNodeConf::RT_LEAF:
130  nodeInfo.type = "RT_LEAF ";
131  break;
132  case brite::RouterNodeConf::RT_BORDER:
133  nodeInfo.type = "RT_BORDER";
134  break;
135  case brite::RouterNodeConf::RT_STUB:
136  nodeInfo.type = "RT_STUB ";
137  break;
138  case brite::RouterNodeConf::RT_BACKBONE:
139  nodeInfo.type = "RT_BACKBONE ";
140  break;
141  default:
142  NS_FATAL_ERROR ("Topology::Output(): Improperly classfied Router node encountered...");
143  }
144  break;
145 
146  case brite::NodeConf::AS_NODE:
147  m_numAs = nodeInfo.asId =
148  ((brite::ASNodeConf*)(g->GetNodePtr (i)->GetNodeInfo ()))->GetASId ();
149 
150  switch (((brite::ASNodeConf*)(g->GetNodePtr (i)->GetNodeInfo ()))->GetASType ())
151  {
152  case brite::ASNodeConf::AS_NONE:
153  nodeInfo.type = "AS_NONE ";
154  break;
155  case brite::ASNodeConf::AS_LEAF:
156  nodeInfo.type = "AS_LEAF ";
157  break;
158  case brite::ASNodeConf::AS_STUB:
159  nodeInfo.type = "AS_STUB ";
160  break;
161  case brite::ASNodeConf::AS_BORDER:
162  nodeInfo.type = "AS_BORDER ";
163  break;
164  case brite::ASNodeConf::AS_BACKBONE:
165  nodeInfo.type = "AS_BACKBONE ";
166  break;
167  default:
168  NS_FATAL_ERROR ("Topology::Output(): Improperly classfied AS node encountered...");
169  }
170  break;
171  }
172 
173  m_briteNodeInfoList.push_back (nodeInfo);
174  }
175 
176  //Currently m_numAs stores the highest AS number. We want m_numAs to store the number
177  //of AS created in the topology. Since AS numbering starts at 0 we add one to get
178  //the correct count
179  m_numAs++;
180 }
181 
182 void
184 {
185  NS_LOG_FUNCTION (this);
186  brite::Graph *g = m_topology->GetGraph ();
187  std::list<brite::Edge*>::iterator el;
188  std::list<brite::Edge*> edgeList = g->GetEdges ();
189 
190  for (el = edgeList.begin (); el != edgeList.end (); el++)
191  {
192  BriteEdgeInfo edgeInfo;
193  edgeInfo.edgeId = (*el)->GetId ();
194  edgeInfo.srcId = (*el)->GetSrc ()->GetId ();
195  edgeInfo.destId = (*el)->GetDst ()->GetId ();
196  edgeInfo.length = (*el)->Length ();
197 
198  switch ((*el)->GetConf ()->GetEdgeType ())
199  {
200  case brite::EdgeConf::RT_EDGE:
201  edgeInfo.delay = ((brite::RouterEdgeConf*)((*el)->GetConf ()))->GetDelay ();
202  edgeInfo.bandwidth = (*el)->GetConf ()->GetBW ();
203  //If there is only one AS, BRITE will use -1 as AS Number. We want it to be 0 instead.
204  edgeInfo.asFrom = (((brite::RouterNodeConf*)((*el)->GetSrc ()->GetNodeInfo ()))->GetASId () == -1) ? 0 : ((brite::RouterNodeConf*)((*el)->GetSrc ()->GetNodeInfo ()))->GetASId ();
205  edgeInfo.asTo = (((brite::RouterNodeConf*)((*el)->GetDst ()->GetNodeInfo ()))->GetASId () == -1) ? 0 : ((brite::RouterNodeConf*)((*el)->GetDst ()->GetNodeInfo ()))->GetASId ();
206  break;
207 
208  case brite::EdgeConf::AS_EDGE:
209  edgeInfo.delay = -1; /* No delay for AS Edges */
210  edgeInfo.bandwidth = (*el)->GetConf ()->GetBW ();
211  edgeInfo.asFrom = ((brite::ASNodeConf*)((*el)->GetSrc ()->GetNodeInfo ()))->GetASId ();
212  edgeInfo.asTo = ((brite::ASNodeConf*)((*el)->GetDst ()->GetNodeInfo ()))->GetASId ();
213  break;
214 
215  default:
216  NS_FATAL_ERROR ("Topology::Output(): Invalid Edge type encountered...");
217  }
218 
219  switch ((*el)->GetConf ()->GetEdgeType ())
220  {
221  case brite::EdgeConf::RT_EDGE:
222  switch (((brite::RouterEdgeConf*)(*el)->GetConf ())->GetRouterEdgeType ())
223  {
224  case brite::RouterEdgeConf::RT_NONE:
225  edgeInfo.type = "E_RT_NONE ";
226  break;
227  case brite::RouterEdgeConf::RT_STUB:
228  edgeInfo.type = "E_RT_STUB ";
229  break;
230  case brite::RouterEdgeConf::RT_BORDER:
231  edgeInfo.type = "E_RT_BORDER ";
232  break;
233  case brite::RouterEdgeConf::RT_BACKBONE:
234  edgeInfo.type = "E_RT_BACKBONE ";
235  break;
236  default:
237  NS_FATAL_ERROR ("Output(): Invalid router edge type...");
238  }
239  break;
240 
241  case brite::EdgeConf::AS_EDGE:
242  switch (((brite::ASEdgeConf*)((*el)->GetConf ()))->GetASEdgeType ())
243  {
244  case brite::ASEdgeConf::AS_NONE:
245  edgeInfo.type = "E_AS_NONE ";
246  break;
247  case brite::ASEdgeConf::AS_STUB:
248  edgeInfo.type = "E_AS_STUB ";
249  break;
250  case brite::ASEdgeConf::AS_BORDER:
251  edgeInfo.type = "E_AS_BORDER ";
252  break;
253  case brite::ASEdgeConf::AS_BACKBONE:
254  edgeInfo.type = "E_AS_BACKBONE ";
255  break;
256  default:
257  NS_FATAL_ERROR ("BriteOutput(): Invalid AS edge type...");
258  }
259  break;
260 
261  default:
262  NS_FATAL_ERROR ("BriteOutput(): Invalid edge type...");
263 
264  }
265 
266  m_briteEdgeInfoList.push_back (edgeInfo);
267  }
268 }
269 
270 Ptr<Node>
271 BriteTopologyHelper::GetLeafNodeForAs (uint32_t asNum, uint32_t leafNum)
272 {
273  return m_asLeafNodes[asNum]->Get (leafNum);
274 }
275 
276 Ptr<Node>
277 BriteTopologyHelper::GetNodeForAs (uint32_t asNum, uint32_t nodeNum)
278 {
279  return m_nodesByAs[asNum]->Get (nodeNum);
280 }
281 
282 uint32_t
284 {
285  return m_nodesByAs[asNum]->GetN ();
286 }
287 
288 uint32_t
290 {
291  return m_asLeafNodes[asNum]->GetN ();
292 }
293 
294 uint32_t
296 {
297  return m_numNodes;
298 }
299 
300 uint32_t
302 {
303  return m_numEdges;
304 }
305 
306 uint32_t
308 {
309  return m_numAs;
310 }
311 
312 uint32_t
314 {
315  return m_systemForAs[asNum];
316 }
317 
319 {
320  NS_ASSERT_MSG (m_topology == NULL, "Brite Topology Already Created");
321 
322  //check to see if need to generate seed file
323  bool generateSeedFile = m_seedFile.empty ();
324 
325  if (generateSeedFile)
326  {
327  NS_LOG_LOGIC ("Generating BRITE Seed file");
328 
329  std::ofstream seedFile;
330 
331  //overwrite file if already there
332  seedFile.open ("briteSeedFile.txt", std::ios_base::out | std::ios_base::trunc);
333 
334  //verify open
335  NS_ASSERT (!seedFile.fail ());
336 
337  //Generate seed file expected by BRITE
338  //need unsigned shorts 0-65535
339  seedFile << "PLACES " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << std::endl;
340  seedFile << "CONNECT " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << std::endl;
341  seedFile << "EDGE_CONN " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << std::endl;
342  seedFile << "GROUPING " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << std::endl;
343  seedFile << "ASSIGNMENT " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << std::endl;
344  seedFile << "BANDWIDTH " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << std::endl;
345  seedFile.close ();
346 
347  //if we're using NS3 generated seed files don't want brite to create a new seed file.
348  m_seedFile = m_newSeedFile = "briteSeedFile.txt";
349  }
350 
351  brite::Brite br (m_confFile, m_seedFile, m_newSeedFile);
352  m_topology = br.GetTopology ();
355 
356  //brite automatically spits out the seed values used to a separate file so no need to keep this anymore
357  if (generateSeedFile)
358  {
359  remove ("briteSeedFile.txt");
360  }
361 
362 }
363 
364 void
366 {
367  NS_LOG_FUNCTION (this);
368 
370 
371  //not using MPI so each AS is on system number 0
372  for (uint32_t i = 0; i < m_numAs; ++i)
373  {
374  m_systemForAs.push_back (0);
375  }
376 
377  //create all nodes with system number 0
379 
381 
382  NS_LOG_DEBUG (m_numNodes << " nodes created in BRITE topology");
383 
384  stack.Install (m_nodes);
385 
387 }
388 
389 void
391 {
392  NS_LOG_FUNCTION (this);
393 
395 
396  //determine as system number for each AS
397  NS_LOG_LOGIC ("Assigning << " << m_numAs << " AS to " << systemCount << " MPI instances");
398  for (uint32_t i = 0; i < m_numAs; ++i)
399  {
400  int val = i % systemCount;
401  m_systemForAs.push_back (val);
402  NS_LOG_INFO ("AS: " << i << " System: " << val);
403  }
404 
405  //create nodes
406  for (BriteTopologyHelper::BriteNodeInfoList::iterator it = m_briteNodeInfoList.begin (); it != m_briteNodeInfoList.end (); ++it)
407  {
408  m_nodes.Add (CreateObject<Node> (GetSystemNumberForAs ((*it).asId)));
409  m_numNodes++;
410  }
411 
412  NS_LOG_INFO (m_numNodes << " nodes created in BRITE topology");
413 
414  stack.Install (m_nodes);
415 
417 }
418 
419 void
421 {
422  NS_LOG_FUNCTION (this);
423  //assign IPs
424  for (unsigned int i = 0; i < m_netDevices.size (); ++i)
425  {
426  address.Assign (*m_netDevices[i]);
427  address.NewNetwork ();
428  }
429 }
430 
431 void
433 {
434  NS_LOG_FUNCTION (this);
435 
436  for (unsigned int i = 0; i < m_netDevices.size (); ++i)
437  {
438  address.Assign (*m_netDevices[i]);
439  address.NewNetwork ();
440  }
441 }
442 
443 void
445 {
446  NS_LOG_FUNCTION (this);
447  //create one node container to hold leaf nodes for attaching
448  for (uint32_t i = 0; i < m_numAs; ++i)
449  {
450  m_asLeafNodes.push_back (new NodeContainer ());
451  m_nodesByAs.push_back (new NodeContainer ());
452  }
453 
454  for (BriteTopologyHelper::BriteEdgeInfoList::iterator it = m_briteEdgeInfoList.begin (); it != m_briteEdgeInfoList.end (); ++it)
455  {
456  // Set the link delay
457  // The brite value for delay is given in milliseconds
459  TimeValue (Seconds ((*it).delay/1000.0)));
460 
461  // The brite value for data rate is given in Mbps
463  DataRateValue (DataRate ((*it).bandwidth * mbpsToBps)));
464 
465  m_netDevices.push_back ( new NetDeviceContainer ( m_britePointToPointHelper.Install (m_nodes.Get ((*it).srcId), m_nodes.Get ((*it).destId))));
466 
467  m_numEdges++;
468 
469  }
470 
471  NS_LOG_INFO ("Created " << m_numEdges << " edges in BRITE topology");
472 
473  //iterate through all nodes and add leaf nodes for each AS
474  for (BriteTopologyHelper::BriteNodeInfoList::iterator it = m_briteNodeInfoList.begin (); it != m_briteNodeInfoList.end (); ++it)
475  {
476  m_nodesByAs[(*it).asId]->Add (m_nodes.Get ((*it).nodeId));
477 
478  if ((*it).type == "RT_LEAF ")
479  {
480  m_asLeafNodes[(*it).asId]->Add (m_nodes.Get ((*it).nodeId));
481  }
482  }
483 }
484 
485 } // namespace ns3
uint32_t GetNNodesForAs(uint32_t asNum)
Returns the total number of nodes for a given AS.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
uint32_t GetNLeafNodesForAs(uint32_t asNum)
Returns the number of router leaf nodes for a given AS.
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
uint32_t m_numEdges
stores the number of edges created in the BRITE topology
uint32_t GetSystemNumberForAs(uint32_t asNum) const
Returns the system number for the MPI instance that this AS is assigned to.
NS_ASSERT_MSG(false, "Ipv4AddressGenerator::MaskToIndex(): Impossible")
NetDeviceContainer Install(NodeContainer c)
Ptr< Node > GetNodeForAs(uint32_t asNum, uint32_t nodeNum)
Returns a given router node for a given AS.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
aggregate IP/TCP/UDP functionality to existing Nodes.
void AssignIpv6Addresses(Ipv6AddressHelper &address)
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:278
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
void SetDeviceAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each NetDevice created by the helper.
void AssignStreams(int64_t streamNumber)
Assigns stream number to UniformRandomVariable used to generate brite seed file.
stack
Definition: first.py:34
brite::Topology * m_topology
the Brite topology
std::vector< NodeContainer * > m_nodesByAs
stores all of the nodes in the brite topology by AS number
Class for representing data rates.
Definition: data-rate.h:88
virtual uint32_t GetInteger(void)=0
Get the next random value as an integer drawn from the distribution.
std::string m_newSeedFile
brite seed file to generate for next run
AttributeValue implementation for Time.
Definition: nstime.h:1076
BriteTopologyHelper(std::string confFile, std::string seedFile, std::string newseedFile)
Construct a BriteTopologyHelper.
void AssignIpv4Addresses(Ipv4AddressHelper &address)
holds a vector of ns3::NetDevice pointers
uint32_t GetNAs(void) const
Returns the number of AS created in the topology.
std::vector< int > m_systemForAs
stores the MPI system number each AS assigned to. All assigned to 0 if MPI not used.
uint32_t GetNEdgesTopology() const
Returns the number of edges created within the topology.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
uint32_t GetNNodesTopology() const
Returns the number of nodes created within the topology.
keep track of a set of node pointers.
address
Definition: first.py:37
BriteNodeInfoList m_briteNodeInfoList
The BRITE code generates multiple nodes and edges.
std::string m_confFile
brite configuration file to use
NS_LOG_LOGIC("Net device "<< nd<< " is not bridged")
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
Helper class to auto-assign global IPv6 unicast addresses.
void Add(NodeContainer other)
Append the contents of another NodeContainer to the end of this container.
AttributeValue implementation for DataRate.
Definition: data-rate.h:242
Ptr< UniformRandomVariable > m_uv
random variable stream for brite seed file
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:270
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1014
std::vector< NetDeviceContainer * > m_netDevices
stores the netdevices created for each AS
std::vector< NodeContainer * > m_asLeafNodes
stores the leaf router nodes for each AS
uint32_t m_numAs
stores the number of AS in the BRITE generated topology
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
PointToPointHelper m_britePointToPointHelper
used to create the links within the topology
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.
Ptr< Node > GetLeafNodeForAs(uint32_t asNum, uint32_t leafNum)
Returns a given router leaf node from a given AS.
std::string m_seedFile
brite seed file to use
uint32_t m_numNodes
stores the number of nodes created in the BRITE topology
void BuildBriteTopology(InternetStackHelper &stack)
Create NS3 topology using information generated from BRITE.
BriteEdgeInfoList m_briteEdgeInfoList
The BRITE code generates multiple nodes and edges.