A Discrete-Event Network Simulator
API
brite-topology-helper.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License version 2 as
4  * published by the Free Software Foundation;
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9  * GNU General Public License for more details.
10  *
11  * You should have received a copy of the GNU General Public License
12  * along with this program; if not, write to the Free Software
13  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14  *
15  */
16 
17 #include "brite-topology-helper.h"
18 
19 #include "Brite.h"
20 
21 #include "ns3/abort.h"
22 #include "ns3/data-rate.h"
23 #include "ns3/ipv4-address-helper.h"
24 #include "ns3/log.h"
25 #include "ns3/net-device-container.h"
26 #include "ns3/net-device.h"
27 #include "ns3/point-to-point-helper.h"
28 #include "ns3/random-variable-stream.h"
29 #include "ns3/rng-seed-manager.h"
30 
31 #include <fstream>
32 #include <iostream>
33 
34 namespace ns3
35 {
36 
37 NS_LOG_COMPONENT_DEFINE("BriteTopologyHelper");
38 
40  std::string seedFile,
41  std::string newseedFile)
42  : m_confFile(confFile),
43  m_seedFile(seedFile),
44  m_newSeedFile(newseedFile),
45  m_numAs(0),
46  m_topology(nullptr),
47  m_numNodes(0),
48  m_numEdges(0)
49 {
50  NS_LOG_FUNCTION(this);
51 
52  m_uv = CreateObject<UniformRandomVariable>();
53 }
54 
56  : m_confFile(confFile),
57  m_numAs(0),
58  m_topology(nullptr),
59  m_numNodes(0),
60  m_numEdges(0)
61 {
62  NS_LOG_FUNCTION(this);
63 
64  m_uv = CreateObject<UniformRandomVariable>();
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
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 =
122  ((brite::RouterNodeConf*)(g->GetNodePtr(i)->GetNodeInfo()))->GetASId();
123  }
124 
125  switch (((brite::RouterNodeConf*)(g->GetNodePtr(i)->GetNodeInfo()))->GetRouterType())
126  {
127  case brite::RouterNodeConf::RT_NONE:
128  nodeInfo.type = "RT_NONE ";
129  break;
130  case brite::RouterNodeConf::RT_LEAF:
131  nodeInfo.type = "RT_LEAF ";
132  break;
133  case brite::RouterNodeConf::RT_BORDER:
134  nodeInfo.type = "RT_BORDER";
135  break;
136  case brite::RouterNodeConf::RT_STUB:
137  nodeInfo.type = "RT_STUB ";
138  break;
139  case brite::RouterNodeConf::RT_BACKBONE:
140  nodeInfo.type = "RT_BACKBONE ";
141  break;
142  default:
144  "Topology::Output(): Improperly classified Router node encountered...");
145  }
146  break;
147 
148  case brite::NodeConf::AS_NODE:
149  m_numAs = nodeInfo.asId =
150  ((brite::ASNodeConf*)(g->GetNodePtr(i)->GetNodeInfo()))->GetASId();
151 
152  switch (((brite::ASNodeConf*)(g->GetNodePtr(i)->GetNodeInfo()))->GetASType())
153  {
154  case brite::ASNodeConf::AS_NONE:
155  nodeInfo.type = "AS_NONE ";
156  break;
157  case brite::ASNodeConf::AS_LEAF:
158  nodeInfo.type = "AS_LEAF ";
159  break;
160  case brite::ASNodeConf::AS_STUB:
161  nodeInfo.type = "AS_STUB ";
162  break;
163  case brite::ASNodeConf::AS_BORDER:
164  nodeInfo.type = "AS_BORDER ";
165  break;
166  case brite::ASNodeConf::AS_BACKBONE:
167  nodeInfo.type = "AS_BACKBONE ";
168  break;
169  default:
170  NS_FATAL_ERROR("Topology::Output(): Improperly classified AS node encountered...");
171  }
172  break;
173  }
174 
175  m_briteNodeInfoList.push_back(nodeInfo);
176  }
177 
178  // Currently m_numAs stores the highest AS number. We want m_numAs to store the number
179  // of AS created in the topology. Since AS numbering starts at 0 we add one to get
180  // the correct count
181  m_numAs++;
182 }
183 
184 void
186 {
187  NS_LOG_FUNCTION(this);
188  brite::Graph* g = m_topology->GetGraph();
189  std::list<brite::Edge*>::iterator el;
190  std::list<brite::Edge*> edgeList = g->GetEdges();
191 
192  for (el = edgeList.begin(); el != edgeList.end(); el++)
193  {
194  BriteEdgeInfo edgeInfo;
195  edgeInfo.edgeId = (*el)->GetId();
196  edgeInfo.srcId = (*el)->GetSrc()->GetId();
197  edgeInfo.destId = (*el)->GetDst()->GetId();
198  edgeInfo.length = (*el)->Length();
199 
200  switch ((*el)->GetConf()->GetEdgeType())
201  {
202  case brite::EdgeConf::RT_EDGE:
203  edgeInfo.delay = ((brite::RouterEdgeConf*)((*el)->GetConf()))->GetDelay();
204  edgeInfo.bandwidth = (*el)->GetConf()->GetBW();
205  // If there is only one AS, BRITE will use -1 as AS Number. We want it to be 0 instead.
206  edgeInfo.asFrom =
207  (((brite::RouterNodeConf*)((*el)->GetSrc()->GetNodeInfo()))->GetASId() == -1)
208  ? 0
209  : ((brite::RouterNodeConf*)((*el)->GetSrc()->GetNodeInfo()))->GetASId();
210  edgeInfo.asTo =
211  (((brite::RouterNodeConf*)((*el)->GetDst()->GetNodeInfo()))->GetASId() == -1)
212  ? 0
213  : ((brite::RouterNodeConf*)((*el)->GetDst()->GetNodeInfo()))->GetASId();
214  break;
215 
216  case brite::EdgeConf::AS_EDGE:
217  edgeInfo.delay = -1; /* No delay for AS Edges */
218  edgeInfo.bandwidth = (*el)->GetConf()->GetBW();
219  edgeInfo.asFrom = ((brite::ASNodeConf*)((*el)->GetSrc()->GetNodeInfo()))->GetASId();
220  edgeInfo.asTo = ((brite::ASNodeConf*)((*el)->GetDst()->GetNodeInfo()))->GetASId();
221  break;
222 
223  default:
224  NS_FATAL_ERROR("Topology::Output(): Invalid Edge type encountered...");
225  }
226 
227  switch ((*el)->GetConf()->GetEdgeType())
228  {
229  case brite::EdgeConf::RT_EDGE:
230  switch (((brite::RouterEdgeConf*)(*el)->GetConf())->GetRouterEdgeType())
231  {
232  case brite::RouterEdgeConf::RT_NONE:
233  edgeInfo.type = "E_RT_NONE ";
234  break;
235  case brite::RouterEdgeConf::RT_STUB:
236  edgeInfo.type = "E_RT_STUB ";
237  break;
238  case brite::RouterEdgeConf::RT_BORDER:
239  edgeInfo.type = "E_RT_BORDER ";
240  break;
241  case brite::RouterEdgeConf::RT_BACKBONE:
242  edgeInfo.type = "E_RT_BACKBONE ";
243  break;
244  default:
245  NS_FATAL_ERROR("Output(): Invalid router edge type...");
246  }
247  break;
248 
249  case brite::EdgeConf::AS_EDGE:
250  switch (((brite::ASEdgeConf*)((*el)->GetConf()))->GetASEdgeType())
251  {
252  case brite::ASEdgeConf::AS_NONE:
253  edgeInfo.type = "E_AS_NONE ";
254  break;
255  case brite::ASEdgeConf::AS_STUB:
256  edgeInfo.type = "E_AS_STUB ";
257  break;
258  case brite::ASEdgeConf::AS_BORDER:
259  edgeInfo.type = "E_AS_BORDER ";
260  break;
261  case brite::ASEdgeConf::AS_BACKBONE:
262  edgeInfo.type = "E_AS_BACKBONE ";
263  break;
264  default:
265  NS_FATAL_ERROR("BriteOutput(): Invalid AS edge type...");
266  }
267  break;
268 
269  default:
270  NS_FATAL_ERROR("BriteOutput(): Invalid edge type...");
271  }
272 
273  m_briteEdgeInfoList.push_back(edgeInfo);
274  }
275 }
276 
277 Ptr<Node>
278 BriteTopologyHelper::GetLeafNodeForAs(uint32_t asNum, uint32_t leafNum)
279 {
280  return m_asLeafNodes[asNum]->Get(leafNum);
281 }
282 
283 Ptr<Node>
284 BriteTopologyHelper::GetNodeForAs(uint32_t asNum, uint32_t nodeNum)
285 {
286  return m_nodesByAs[asNum]->Get(nodeNum);
287 }
288 
289 uint32_t
291 {
292  return m_nodesByAs[asNum]->GetN();
293 }
294 
295 uint32_t
297 {
298  return m_asLeafNodes[asNum]->GetN();
299 }
300 
301 uint32_t
303 {
304  return m_numNodes;
305 }
306 
307 uint32_t
309 {
310  return m_numEdges;
311 }
312 
313 uint32_t
315 {
316  return m_numAs;
317 }
318 
319 uint32_t
321 {
322  return m_systemForAs[asNum];
323 }
324 
325 void
327 {
328  NS_ASSERT_MSG(!m_topology, "Brite Topology Already Created");
329 
330  // check to see if need to generate seed file
331  bool generateSeedFile = m_seedFile.empty();
332 
333  if (generateSeedFile)
334  {
335  NS_LOG_LOGIC("Generating BRITE Seed file");
336 
337  std::ofstream seedFile;
338 
339  // overwrite file if already there
340  seedFile.open("briteSeedFile.txt", std::ios_base::out | std::ios_base::trunc);
341 
342  // verify open
343  NS_ASSERT(!seedFile.fail());
344 
345  // Generate seed file expected by BRITE
346  // need unsigned shorts 0-65535
347  seedFile << "PLACES " << m_uv->GetInteger(0, 65535) << " " << m_uv->GetInteger(0, 65535)
348  << " " << m_uv->GetInteger(0, 65535) << std::endl;
349  seedFile << "CONNECT " << m_uv->GetInteger(0, 65535) << " " << m_uv->GetInteger(0, 65535)
350  << " " << m_uv->GetInteger(0, 65535) << std::endl;
351  seedFile << "EDGE_CONN " << m_uv->GetInteger(0, 65535) << " " << m_uv->GetInteger(0, 65535)
352  << " " << m_uv->GetInteger(0, 65535) << std::endl;
353  seedFile << "GROUPING " << m_uv->GetInteger(0, 65535) << " " << m_uv->GetInteger(0, 65535)
354  << " " << m_uv->GetInteger(0, 65535) << std::endl;
355  seedFile << "ASSIGNMENT " << m_uv->GetInteger(0, 65535) << " " << m_uv->GetInteger(0, 65535)
356  << " " << m_uv->GetInteger(0, 65535) << std::endl;
357  seedFile << "BANDWIDTH " << m_uv->GetInteger(0, 65535) << " " << m_uv->GetInteger(0, 65535)
358  << " " << m_uv->GetInteger(0, 65535) << std::endl;
359  seedFile.close();
360 
361  // if we're using NS3 generated seed files don't want brite to create a new seed file.
362  m_seedFile = m_newSeedFile = "briteSeedFile.txt";
363  }
364 
365  brite::Brite br(m_confFile, m_seedFile, m_newSeedFile);
366  m_topology = br.GetTopology();
369 
370  // brite automatically spits out the seed values used to a separate file so no need to keep this
371  // anymore
372  if (generateSeedFile)
373  {
374  remove("briteSeedFile.txt");
375  remove("last_seed_file");
376  }
377 }
378 
379 void
381 {
382  NS_LOG_FUNCTION(this);
383 
385 
386  // not using MPI so each AS is on system number 0
387  for (uint32_t i = 0; i < m_numAs; ++i)
388  {
389  m_systemForAs.push_back(0);
390  }
391 
392  // create all nodes with system number 0
394 
396 
397  NS_LOG_DEBUG(m_numNodes << " nodes created in BRITE topology");
398 
399  stack.Install(m_nodes);
400 
402 }
403 
404 void
406 {
407  NS_LOG_FUNCTION(this);
408 
410 
411  // determine as system number for each AS
412  NS_LOG_LOGIC("Assigning << " << m_numAs << " AS to " << systemCount << " MPI instances");
413  for (uint32_t i = 0; i < m_numAs; ++i)
414  {
415  int val = i % systemCount;
416  m_systemForAs.push_back(val);
417  NS_LOG_INFO("AS: " << i << " System: " << val);
418  }
419 
420  // create nodes
421  for (BriteTopologyHelper::BriteNodeInfoList::iterator it = m_briteNodeInfoList.begin();
422  it != m_briteNodeInfoList.end();
423  ++it)
424  {
425  m_nodes.Add(CreateObject<Node>(GetSystemNumberForAs((*it).asId)));
426  m_numNodes++;
427  }
428 
429  NS_LOG_INFO(m_numNodes << " nodes created in BRITE topology");
430 
431  stack.Install(m_nodes);
432 
434 }
435 
436 void
438 {
439  NS_LOG_FUNCTION(this);
440  // assign IPs
441  for (std::size_t i = 0; i < m_netDevices.size(); ++i)
442  {
443  address.Assign(*m_netDevices[i]);
444  address.NewNetwork();
445  }
446 }
447 
448 void
450 {
451  NS_LOG_FUNCTION(this);
452 
453  for (std::size_t i = 0; i < m_netDevices.size(); ++i)
454  {
455  address.Assign(*m_netDevices[i]);
456  address.NewNetwork();
457  }
458 }
459 
460 void
462 {
463  NS_LOG_FUNCTION(this);
464  // create one node container to hold leaf nodes for attaching
465  for (uint32_t i = 0; i < m_numAs; ++i)
466  {
467  m_asLeafNodes.push_back(new NodeContainer());
468  m_nodesByAs.push_back(new NodeContainer());
469  }
470 
471  for (BriteTopologyHelper::BriteEdgeInfoList::iterator it = m_briteEdgeInfoList.begin();
472  it != m_briteEdgeInfoList.end();
473  ++it)
474  {
475  // Set the link delay
476  // The brite value for delay is given in milliseconds
478  TimeValue(Seconds((*it).delay / 1000.0)));
479 
480  // The brite value for data rate is given in Mbps
482  "DataRate",
483  DataRateValue(DataRate((*it).bandwidth * mbpsToBps)));
484 
485  m_netDevices.push_back(
487  m_nodes.Get((*it).destId))));
488 
489  m_numEdges++;
490  }
491 
492  NS_LOG_INFO("Created " << m_numEdges << " edges in BRITE topology");
493 
494  // iterate through all nodes and add leaf nodes for each AS
495  for (BriteTopologyHelper::BriteNodeInfoList::iterator it = m_briteNodeInfoList.begin();
496  it != m_briteNodeInfoList.end();
497  ++it)
498  {
499  m_nodesByAs[(*it).asId]->Add(m_nodes.Get((*it).nodeId));
500 
501  if ((*it).type == "RT_LEAF ")
502  {
503  m_asLeafNodes[(*it).asId]->Add(m_nodes.Get((*it).nodeId));
504  }
505  }
506 }
507 
508 } // namespace ns3
BriteNodeInfoList m_briteNodeInfoList
The BRITE code generates multiple nodes and edges.
void AssignIpv6Addresses(Ipv6AddressHelper &address)
Assign IPv6 addresses.
void AssignStreams(int64_t streamNumber)
Assigns stream number to UniformRandomVariable used to generate brite seed file.
BriteEdgeInfoList m_briteEdgeInfoList
The BRITE code generates multiple nodes and edges.
PointToPointHelper m_britePointToPointHelper
used to create the links within the topology
Ptr< UniformRandomVariable > m_uv
random variable stream for brite seed file
brite::Topology * m_topology
the Brite topology
uint32_t m_numNodes
stores the number of nodes created in the BRITE topology
uint32_t GetNAs() const
Returns the number of AS created in the topology.
std::vector< NetDeviceContainer * > m_netDevices
stores the netdevices created for each AS
uint32_t m_numEdges
stores the number of edges created in the BRITE topology
uint32_t GetNNodesTopology() const
Returns the number of nodes created within the topology.
void BuildBriteTopology(InternetStackHelper &stack)
Create NS3 topology using information generated from BRITE.
std::vector< NodeContainer * > m_asLeafNodes
stores the leaf router nodes for each AS
std::vector< NodeContainer * > m_nodesByAs
stores all of the nodes in the brite topology by AS number
uint32_t m_numAs
stores the number of AS in the BRITE generated topology
void BuildBriteNodeInfoList()
Build the Node Info list.
void GenerateBriteTopology()
Generate the BRITE topology.
static const int mbpsToBps
brite values are unitless however all examples provided use mbps to specify rate this constant value ...
Ptr< Node > GetNodeForAs(uint32_t asNum, uint32_t nodeNum)
Returns a given router node for a given AS.
void ConstructTopology()
Construct the topology.
void BuildBriteEdgeInfoList()
Build the Edge Info list.
void AssignIpv4Addresses(Ipv4AddressHelper &address)
Assign IPv4 addresses.
uint32_t GetNNodesForAs(uint32_t asNum)
Returns the total number of nodes for a given AS.
uint32_t GetNLeafNodesForAs(uint32_t asNum)
Returns the number of router leaf nodes for a given AS.
std::string m_newSeedFile
brite seed file to generate for next run
std::string m_seedFile
brite seed file to use
std::vector< int > m_systemForAs
stores the MPI system number each AS assigned to. All assigned to 0 if MPI not used.
NodeContainer m_nodes
stores all of the nodes used in the BRITE generated topology
uint32_t GetNEdgesTopology() const
Returns the number of edges created within the topology.
BriteTopologyHelper(std::string confFile, std::string seedFile, std::string newseedFile)
Construct a BriteTopologyHelper.
Ptr< Node > GetLeafNodeForAs(uint32_t asNum, uint32_t leafNum)
Returns a given router leaf node from a given AS.
uint32_t GetSystemNumberForAs(uint32_t asNum) const
Returns the system number for the MPI instance that this AS is assigned to.
std::string m_confFile
brite configuration file to use
AttributeValue implementation for DataRate.
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
Helper class to auto-assign global IPv6 unicast addresses.
holds a vector of ns3::NetDevice pointers
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
void Add(const NodeContainer &nc)
Append the contents of another NodeContainer to the end of this container.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
void SetDeviceAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each NetDevice created by the helper.
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
NetDeviceContainer Install(NodeContainer c)
void SetStream(int64_t stream)
Specifies the stream number for the RngStream.
AttributeValue implementation for Time.
Definition: nstime.h:1423
uint32_t GetInteger(uint32_t min, uint32_t max)
Get the next random value drawn from the distribution.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:86
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
void(* DataRate)(DataRate oldValue, DataRate newValue)
TracedValue callback signature for DataRate.
Definition: data-rate.h:328
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
address
Definition: first.py:40
stack
Definition: first.py:37
Every class exported by the ns3 library is enclosed in the ns3 namespace.