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
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
34namespace ns3
35{
36
37NS_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
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 =
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
184void
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
279{
280 return m_asLeafNodes[asNum]->Get(leafNum);
281}
282
285{
286 return m_nodesByAs[asNum]->Get(nodeNum);
287}
288
291{
292 return m_nodesByAs[asNum]->GetN();
293}
294
297{
298 return m_asLeafNodes[asNum]->GetN();
299}
300
303{
304 return m_numNodes;
305}
306
309{
310 return m_numEdges;
311}
312
315{
316 return m_numAs;
317}
318
321{
322 return m_systemForAs[asNum];
323}
324
325void
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
379void
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
404void
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
436void
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
448void
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
460void
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:327
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.