A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
brite-topology-helper.cc
Go to the documentation of this file.
1/*
2 * SPDX-License-Identifier: GPL-2.0-only
3 *
4 */
5
7
8#include "Brite.h"
9
10#include "ns3/abort.h"
11#include "ns3/data-rate.h"
12#include "ns3/ipv4-address-helper.h"
13#include "ns3/log.h"
14#include "ns3/net-device-container.h"
15#include "ns3/net-device.h"
16#include "ns3/point-to-point-helper.h"
17#include "ns3/random-variable-stream.h"
18#include "ns3/rng-seed-manager.h"
19
20#include <fstream>
21#include <iostream>
22
23namespace ns3
24{
25
26NS_LOG_COMPONENT_DEFINE("BriteTopologyHelper");
27
29 std::string seedFile,
30 std::string newseedFile)
31 : m_confFile(confFile),
32 m_seedFile(seedFile),
33 m_newSeedFile(newseedFile),
34 m_numAs(0),
35 m_topology(nullptr),
36 m_numNodes(0),
37 m_numEdges(0)
38{
39 NS_LOG_FUNCTION(this);
40
42}
43
45 : m_confFile(confFile),
46 m_numAs(0),
47 m_topology(nullptr),
48 m_numNodes(0),
49 m_numEdges(0)
50{
51 NS_LOG_FUNCTION(this);
52
54}
55
57{
58 NS_LOG_FUNCTION(this);
59 delete m_topology;
60
61 while (!m_netDevices.empty())
62 {
63 delete m_netDevices.back();
64 m_netDevices.pop_back();
65 }
66
67 while (!m_asLeafNodes.empty())
68 {
69 delete m_asLeafNodes.back();
70 m_asLeafNodes.pop_back();
71 }
72
73 while (!m_nodesByAs.empty())
74 {
75 delete m_nodesByAs.back();
76 m_nodesByAs.pop_back();
77 }
78}
79
80void
82{
83 m_uv->SetStream(streamNumber);
84}
85
86void
88{
89 NS_LOG_FUNCTION(this);
90 brite::Graph* g = m_topology->GetGraph();
91 for (int i = 0; i < g->GetNumNodes(); ++i)
92 {
93 BriteNodeInfo nodeInfo;
94 nodeInfo.nodeId = g->GetNodePtr(i)->GetId();
95 nodeInfo.xCoordinate = g->GetNodePtr(i)->GetNodeInfo()->GetCoordX();
96 nodeInfo.yCoordinate = g->GetNodePtr(i)->GetNodeInfo()->GetCoordY();
97 nodeInfo.inDegree = g->GetNodePtr(i)->GetInDegree();
98 nodeInfo.outDegree = g->GetNodePtr(i)->GetOutDegree();
99
100 switch (g->GetNodePtr(i)->GetNodeInfo()->GetNodeType())
101 {
102 case brite::NodeConf::RT_NODE:
103
104 if (((brite::RouterNodeConf*)(g->GetNodePtr(i)->GetNodeInfo()))->GetASId() == -1)
105 {
106 m_numAs = nodeInfo.asId = 0;
107 }
108 else
109 {
110 m_numAs = nodeInfo.asId =
111 ((brite::RouterNodeConf*)(g->GetNodePtr(i)->GetNodeInfo()))->GetASId();
112 }
113
114 switch (((brite::RouterNodeConf*)(g->GetNodePtr(i)->GetNodeInfo()))->GetRouterType())
115 {
116 case brite::RouterNodeConf::RT_NONE:
117 nodeInfo.type = "RT_NONE ";
118 break;
119 case brite::RouterNodeConf::RT_LEAF:
120 nodeInfo.type = "RT_LEAF ";
121 break;
122 case brite::RouterNodeConf::RT_BORDER:
123 nodeInfo.type = "RT_BORDER";
124 break;
125 case brite::RouterNodeConf::RT_STUB:
126 nodeInfo.type = "RT_STUB ";
127 break;
128 case brite::RouterNodeConf::RT_BACKBONE:
129 nodeInfo.type = "RT_BACKBONE ";
130 break;
131 default:
133 "Topology::Output(): Improperly classified Router node encountered...");
134 }
135 break;
136
137 case brite::NodeConf::AS_NODE:
138 m_numAs = nodeInfo.asId =
139 ((brite::ASNodeConf*)(g->GetNodePtr(i)->GetNodeInfo()))->GetASId();
140
141 switch (((brite::ASNodeConf*)(g->GetNodePtr(i)->GetNodeInfo()))->GetASType())
142 {
143 case brite::ASNodeConf::AS_NONE:
144 nodeInfo.type = "AS_NONE ";
145 break;
146 case brite::ASNodeConf::AS_LEAF:
147 nodeInfo.type = "AS_LEAF ";
148 break;
149 case brite::ASNodeConf::AS_STUB:
150 nodeInfo.type = "AS_STUB ";
151 break;
152 case brite::ASNodeConf::AS_BORDER:
153 nodeInfo.type = "AS_BORDER ";
154 break;
155 case brite::ASNodeConf::AS_BACKBONE:
156 nodeInfo.type = "AS_BACKBONE ";
157 break;
158 default:
159 NS_FATAL_ERROR("Topology::Output(): Improperly classified AS node encountered...");
160 }
161 break;
162 }
163
164 m_briteNodeInfoList.push_back(nodeInfo);
165 }
166
167 // Currently m_numAs stores the highest AS number. We want m_numAs to store the number
168 // of AS created in the topology. Since AS numbering starts at 0 we add one to get
169 // the correct count
170 m_numAs++;
171}
172
173void
175{
176 NS_LOG_FUNCTION(this);
177 brite::Graph* g = m_topology->GetGraph();
178 std::list<brite::Edge*> edgeList = g->GetEdges();
179
180 for (auto el = edgeList.begin(); el != edgeList.end(); el++)
181 {
182 BriteEdgeInfo edgeInfo;
183 edgeInfo.edgeId = (*el)->GetId();
184 edgeInfo.srcId = (*el)->GetSrc()->GetId();
185 edgeInfo.destId = (*el)->GetDst()->GetId();
186 edgeInfo.length = (*el)->Length();
187
188 switch ((*el)->GetConf()->GetEdgeType())
189 {
190 case brite::EdgeConf::RT_EDGE:
191 edgeInfo.delay = ((brite::RouterEdgeConf*)((*el)->GetConf()))->GetDelay();
192 edgeInfo.bandwidth = (*el)->GetConf()->GetBW();
193 // If there is only one AS, BRITE will use -1 as AS Number. We want it to be 0 instead.
194 edgeInfo.asFrom =
195 (((brite::RouterNodeConf*)((*el)->GetSrc()->GetNodeInfo()))->GetASId() == -1)
196 ? 0
197 : ((brite::RouterNodeConf*)((*el)->GetSrc()->GetNodeInfo()))->GetASId();
198 edgeInfo.asTo =
199 (((brite::RouterNodeConf*)((*el)->GetDst()->GetNodeInfo()))->GetASId() == -1)
200 ? 0
201 : ((brite::RouterNodeConf*)((*el)->GetDst()->GetNodeInfo()))->GetASId();
202 break;
203
204 case brite::EdgeConf::AS_EDGE:
205 edgeInfo.delay = -1; /* No delay for AS Edges */
206 edgeInfo.bandwidth = (*el)->GetConf()->GetBW();
207 edgeInfo.asFrom = ((brite::ASNodeConf*)((*el)->GetSrc()->GetNodeInfo()))->GetASId();
208 edgeInfo.asTo = ((brite::ASNodeConf*)((*el)->GetDst()->GetNodeInfo()))->GetASId();
209 break;
210
211 default:
212 NS_FATAL_ERROR("Topology::Output(): Invalid Edge type encountered...");
213 }
214
215 switch ((*el)->GetConf()->GetEdgeType())
216 {
217 case brite::EdgeConf::RT_EDGE:
218 switch (((brite::RouterEdgeConf*)(*el)->GetConf())->GetRouterEdgeType())
219 {
220 case brite::RouterEdgeConf::RT_NONE:
221 edgeInfo.type = "E_RT_NONE ";
222 break;
223 case brite::RouterEdgeConf::RT_STUB:
224 edgeInfo.type = "E_RT_STUB ";
225 break;
226 case brite::RouterEdgeConf::RT_BORDER:
227 edgeInfo.type = "E_RT_BORDER ";
228 break;
229 case brite::RouterEdgeConf::RT_BACKBONE:
230 edgeInfo.type = "E_RT_BACKBONE ";
231 break;
232 default:
233 NS_FATAL_ERROR("Output(): Invalid router edge type...");
234 }
235 break;
236
237 case brite::EdgeConf::AS_EDGE:
238 switch (((brite::ASEdgeConf*)((*el)->GetConf()))->GetASEdgeType())
239 {
240 case brite::ASEdgeConf::AS_NONE:
241 edgeInfo.type = "E_AS_NONE ";
242 break;
243 case brite::ASEdgeConf::AS_STUB:
244 edgeInfo.type = "E_AS_STUB ";
245 break;
246 case brite::ASEdgeConf::AS_BORDER:
247 edgeInfo.type = "E_AS_BORDER ";
248 break;
249 case brite::ASEdgeConf::AS_BACKBONE:
250 edgeInfo.type = "E_AS_BACKBONE ";
251 break;
252 default:
253 NS_FATAL_ERROR("BriteOutput(): Invalid AS edge type...");
254 }
255 break;
256
257 default:
258 NS_FATAL_ERROR("BriteOutput(): Invalid edge type...");
259 }
260
261 m_briteEdgeInfoList.push_back(edgeInfo);
262 }
263}
264
267{
268 return m_asLeafNodes[asNum]->Get(leafNum);
269}
270
273{
274 return m_nodesByAs[asNum]->Get(nodeNum);
275}
276
279{
280 return m_nodesByAs[asNum]->GetN();
281}
282
285{
286 return m_asLeafNodes[asNum]->GetN();
287}
288
294
300
303{
304 return m_numAs;
305}
306
309{
310 return m_systemForAs[asNum];
311}
312
313void
315{
316 NS_ASSERT_MSG(!m_topology, "Brite Topology Already Created");
317
318 // check to see if need to generate seed file
319 bool generateSeedFile = m_seedFile.empty();
320
321 if (generateSeedFile)
322 {
323 NS_LOG_LOGIC("Generating BRITE Seed file");
324
325 std::ofstream seedFile;
326
327 // overwrite file if already there
328 seedFile.open("briteSeedFile.txt", std::ios_base::out | std::ios_base::trunc);
329
330 // verify open
331 NS_ASSERT(!seedFile.fail());
332
333 // Generate seed file expected by BRITE
334 // need unsigned shorts 0-65535
335 seedFile << "PLACES " << m_uv->GetInteger(0, 65535) << " " << m_uv->GetInteger(0, 65535)
336 << " " << m_uv->GetInteger(0, 65535) << std::endl;
337 seedFile << "CONNECT " << m_uv->GetInteger(0, 65535) << " " << m_uv->GetInteger(0, 65535)
338 << " " << m_uv->GetInteger(0, 65535) << std::endl;
339 seedFile << "EDGE_CONN " << m_uv->GetInteger(0, 65535) << " " << m_uv->GetInteger(0, 65535)
340 << " " << m_uv->GetInteger(0, 65535) << std::endl;
341 seedFile << "GROUPING " << m_uv->GetInteger(0, 65535) << " " << m_uv->GetInteger(0, 65535)
342 << " " << m_uv->GetInteger(0, 65535) << std::endl;
343 seedFile << "ASSIGNMENT " << m_uv->GetInteger(0, 65535) << " " << m_uv->GetInteger(0, 65535)
344 << " " << m_uv->GetInteger(0, 65535) << std::endl;
345 seedFile << "BANDWIDTH " << m_uv->GetInteger(0, 65535) << " " << m_uv->GetInteger(0, 65535)
346 << " " << m_uv->GetInteger(0, 65535) << std::endl;
347 seedFile.close();
348
349 // if we're using NS3 generated seed files don't want brite to create a new seed file.
350 m_seedFile = m_newSeedFile = "briteSeedFile.txt";
351 }
352
353 brite::Brite br(m_confFile, m_seedFile, m_newSeedFile);
354 m_topology = br.GetTopology();
357
358 // brite automatically spits out the seed values used to a separate file so no need to keep this
359 // anymore
360 if (generateSeedFile)
361 {
362 remove("briteSeedFile.txt");
363 remove("last_seed_file");
364 }
365}
366
367void
369{
370 NS_LOG_FUNCTION(this);
371
373
374 // not using MPI so each AS is on system number 0
375 for (uint32_t i = 0; i < m_numAs; ++i)
376 {
377 m_systemForAs.push_back(0);
378 }
379
380 // create all nodes with system number 0
382
384
385 NS_LOG_DEBUG(m_numNodes << " nodes created in BRITE topology");
386
387 stack.Install(m_nodes);
388
390}
391
392void
394{
395 NS_LOG_FUNCTION(this);
396
398
399 // determine as system number for each AS
400 NS_LOG_LOGIC("Assigning << " << m_numAs << " AS to " << systemCount << " MPI instances");
401 for (uint32_t i = 0; i < m_numAs; ++i)
402 {
403 uint32_t val = i % systemCount;
404 m_systemForAs.push_back(static_cast<int>(val));
405 NS_LOG_INFO("AS: " << i << " System: " << val);
406 }
407
408 // create nodes
409 for (auto it = m_briteNodeInfoList.begin(); it != m_briteNodeInfoList.end(); ++it)
410 {
412 m_numNodes++;
413 }
414
415 NS_LOG_INFO(m_numNodes << " nodes created in BRITE topology");
416
417 stack.Install(m_nodes);
418
420}
421
422void
424{
425 NS_LOG_FUNCTION(this);
426 // assign IPs
427 for (std::size_t i = 0; i < m_netDevices.size(); ++i)
428 {
429 address.Assign(*m_netDevices[i]);
430 address.NewNetwork();
431 }
432}
433
434void
436{
437 NS_LOG_FUNCTION(this);
438
439 for (std::size_t i = 0; i < m_netDevices.size(); ++i)
440 {
441 address.Assign(*m_netDevices[i]);
442 address.NewNetwork();
443 }
444}
445
446void
448{
449 NS_LOG_FUNCTION(this);
450 // create one node container to hold leaf nodes for attaching
451 for (uint32_t i = 0; i < m_numAs; ++i)
452 {
453 m_asLeafNodes.push_back(new NodeContainer());
454 m_nodesByAs.push_back(new NodeContainer());
455 }
456
457 for (auto it = m_briteEdgeInfoList.begin(); it != m_briteEdgeInfoList.end(); ++it)
458 {
459 // Set the link delay
460 // The brite value for delay is given in milliseconds
462 TimeValue(Seconds((*it).delay / 1000.0)));
463
464 // The brite value for data rate is given in Mbps
466 "DataRate",
467 DataRateValue(DataRate((*it).bandwidth * mbpsToBps)));
468
469 m_netDevices.push_back(
471 m_nodes.Get((*it).destId))));
472
473 m_numEdges++;
474 }
475
476 NS_LOG_INFO("Created " << m_numEdges << " edges in BRITE topology");
477
478 // iterate through all nodes and add leaf nodes for each AS
479 for (auto it = m_briteNodeInfoList.begin(); it != m_briteNodeInfoList.end(); ++it)
480 {
481 m_nodesByAs[(*it).asId]->Add(m_nodes.Get((*it).nodeId));
482
483 if ((*it).type == "RT_LEAF ")
484 {
485 m_asLeafNodes[(*it).asId]->Add(m_nodes.Get((*it).nodeId));
486 }
487 }
488}
489
490} // 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
Class for representing data rates.
Definition data-rate.h:78
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)
Smart pointer class similar to boost::intrusive_ptr.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#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:75
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#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:264
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
Every class exported by the ns3 library is enclosed in the ns3 namespace.