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
29
30#include <iostream>
31#include <fstream>
32
33namespace ns3 {
34
35NS_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
91void
93{
94 m_uv->SetStream (streamNumber);
95}
96
97void
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
182void
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
272{
273 return m_asLeafNodes[asNum]->Get (leafNum);
274}
275
278{
279 return m_nodesByAs[asNum]->Get (nodeNum);
280}
281
284{
285 return m_nodesByAs[asNum]->GetN ();
286}
287
290{
291 return m_asLeafNodes[asNum]->GetN ();
292}
293
296{
297 return m_numNodes;
298}
299
302{
303 return m_numEdges;
304}
305
308{
309 return m_numAs;
310}
311
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 remove ("last_seed_file");
361 }
362
363}
364
365void
367{
368 NS_LOG_FUNCTION (this);
369
371
372 //not using MPI so each AS is on system number 0
373 for (uint32_t i = 0; i < m_numAs; ++i)
374 {
375 m_systemForAs.push_back (0);
376 }
377
378 //create all nodes with system number 0
380
382
383 NS_LOG_DEBUG (m_numNodes << " nodes created in BRITE topology");
384
385 stack.Install (m_nodes);
386
388}
389
390void
392{
393 NS_LOG_FUNCTION (this);
394
396
397 //determine as system number for each AS
398 NS_LOG_LOGIC ("Assigning << " << m_numAs << " AS to " << systemCount << " MPI instances");
399 for (uint32_t i = 0; i < m_numAs; ++i)
400 {
401 int val = i % systemCount;
402 m_systemForAs.push_back (val);
403 NS_LOG_INFO ("AS: " << i << " System: " << val);
404 }
405
406 //create nodes
407 for (BriteTopologyHelper::BriteNodeInfoList::iterator it = m_briteNodeInfoList.begin (); it != m_briteNodeInfoList.end (); ++it)
408 {
409 m_nodes.Add (CreateObject<Node> (GetSystemNumberForAs ((*it).asId)));
410 m_numNodes++;
411 }
412
413 NS_LOG_INFO (m_numNodes << " nodes created in BRITE topology");
414
415 stack.Install (m_nodes);
416
418}
419
420void
422{
423 NS_LOG_FUNCTION (this);
424 //assign IPs
425 for (unsigned int i = 0; i < m_netDevices.size (); ++i)
426 {
427 address.Assign (*m_netDevices[i]);
428 address.NewNetwork ();
429 }
430}
431
432void
434{
435 NS_LOG_FUNCTION (this);
436
437 for (unsigned int i = 0; i < m_netDevices.size (); ++i)
438 {
439 address.Assign (*m_netDevices[i]);
440 address.NewNetwork ();
441 }
442}
443
444void
446{
447 NS_LOG_FUNCTION (this);
448 //create one node container to hold leaf nodes for attaching
449 for (uint32_t i = 0; i < m_numAs; ++i)
450 {
451 m_asLeafNodes.push_back (new NodeContainer ());
452 m_nodesByAs.push_back (new NodeContainer ());
453 }
454
455 for (BriteTopologyHelper::BriteEdgeInfoList::iterator it = m_briteEdgeInfoList.begin (); it != m_briteEdgeInfoList.end (); ++it)
456 {
457 // Set the link delay
458 // The brite value for delay is given in milliseconds
460 TimeValue (Seconds ((*it).delay/1000.0)));
461
462 // The brite value for data rate is given in Mbps
464 DataRateValue (DataRate ((*it).bandwidth * mbpsToBps)));
465
466 m_netDevices.push_back ( new NetDeviceContainer ( m_britePointToPointHelper.Install (m_nodes.Get ((*it).srcId), m_nodes.Get ((*it).destId))));
467
468 m_numEdges++;
469
470 }
471
472 NS_LOG_INFO ("Created " << m_numEdges << " edges in BRITE topology");
473
474 //iterate through all nodes and add leaf nodes for each AS
475 for (BriteTopologyHelper::BriteNodeInfoList::iterator it = m_briteNodeInfoList.begin (); it != m_briteNodeInfoList.end (); ++it)
476 {
477 m_nodesByAs[(*it).asId]->Add (m_nodes.Get ((*it).nodeId));
478
479 if ((*it).type == "RT_LEAF ")
480 {
481 m_asLeafNodes[(*it).asId]->Add (m_nodes.Get ((*it).nodeId));
482 }
483 }
484}
485
486} // namespace ns3
uint32_t GetNAs(void) const
Returns the number of AS created in the topology.
BriteNodeInfoList m_briteNodeInfoList
The BRITE code generates multiple nodes and edges.
void AssignIpv6Addresses(Ipv6AddressHelper &address)
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
void GenerateBriteTopology(void)
Generate the BRITE topology.
brite::Topology * m_topology
the Brite topology
uint32_t m_numNodes
stores the number of nodes created in the BRITE topology
std::vector< NetDeviceContainer * > m_netDevices
stores the netdevices created for each AS
void ConstructTopology(void)
Construct the topology.
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(void)
Build the Node Info list.
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 AssignIpv4Addresses(Ipv4AddressHelper &address)
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.
void BuildBriteEdgeInfoList(void)
Build the Edge Info list.
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
Class for representing data rates.
Definition: data-rate.h:89
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(NodeContainer other)
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:1308
uint32_t GetInteger(uint32_t min, uint32_t max)
Get the next random value, as an unsigned integer in the specified range .
#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_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:88
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
#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:281
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
address
Definition: first.py:44
stack
Definition: first.py:41
Every class exported by the ns3 library is enclosed in the ns3 namespace.