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 seperate 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 this RNG stream.
uint32_t m_numEdges
stores the number of edges created in the BRITE topology
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:201
uint32_t GetNAs(void) const
Returns the number of AS created in the topology.
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:277
#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.
brite::Topology * m_topology
the Brite topology
std::vector< NodeContainer * > m_nodesByAs
stores all of the nodes in the brite topology by AS number
Ipv6InterfaceContainer Assign(const NetDeviceContainer &c)
Allocate an Ipv6InterfaceContainer with auto-assigned addresses.
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:1055
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.
void AssignIpv4Addresses(Ipv4AddressHelper &address)
uint32_t GetNNodesTopology() const
Returns the number of nodes created within the topology.
holds a vector of ns3::NetDevice pointers
std::vector< int > m_systemForAs
stores the MPI system number each AS assigned to. All assigned to 0 if MPI not used.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:285
Every class exported by the ns3 library is enclosed in the ns3 namespace.
keep track of a set of node pointers.
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
BriteNodeInfoList m_briteNodeInfoList
The BRITE code generates multiple nodes and edges.
std::string m_confFile
brite configuration file to use
tuple stack
Definition: first.py:34
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.
#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:90
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
Returns the system number for the MPI instance that this AS is assigned to.
AttributeValue implementation for DataRate.
Definition: data-rate.h:242
Ptr< Node > Get(uint32_t i) const
Get the Ptr stored in this container at a given index.
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:269
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:993
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
PointToPointHelper m_britePointToPointHelper
used to create the links within the topology
Ipv4Address NewNetwork(void)
Increment the network number and reset the IP address counter to the base value provided in the SetBa...
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
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.
void NewNetwork(void)
Allocate a new network.