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 "ns3/abort.h"
20#include "ns3/data-rate.h"
21#include "ns3/ipv4-address-helper.h"
22#include "ns3/log.h"
23#include "ns3/net-device-container.h"
24#include "ns3/net-device.h"
25#include "ns3/point-to-point-helper.h"
26#include "ns3/random-variable-stream.h"
27#include "ns3/rng-seed-manager.h"
28
29#include <fstream>
30#include <iostream>
31
32namespace ns3
33{
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(nullptr),
45 m_numNodes(0),
46 m_numEdges(0)
47{
48 NS_LOG_FUNCTION(this);
49
50 m_uv = CreateObject<UniformRandomVariable>();
51}
52
54 : m_confFile(confFile),
55 m_numAs(0),
56 m_topology(nullptr),
57 m_numNodes(0),
58 m_numEdges(0)
59{
60 NS_LOG_FUNCTION(this);
61
62 m_uv = CreateObject<UniformRandomVariable>();
63}
64
66{
67 NS_LOG_FUNCTION(this);
68 delete m_topology;
69
70 while (!m_netDevices.empty())
71 {
72 delete m_netDevices.back();
73 m_netDevices.pop_back();
74 }
75
76 while (!m_asLeafNodes.empty())
77 {
78 delete m_asLeafNodes.back();
79 m_asLeafNodes.pop_back();
80 }
81
82 while (!m_nodesByAs.empty())
83 {
84 delete m_nodesByAs.back();
85 m_nodesByAs.pop_back();
86 }
87}
88
89void
91{
92 m_uv->SetStream(streamNumber);
93}
94
95void
97{
98 NS_LOG_FUNCTION(this);
99 brite::Graph* g = m_topology->GetGraph();
100 for (int i = 0; i < g->GetNumNodes(); ++i)
101 {
102 BriteNodeInfo nodeInfo;
103 nodeInfo.nodeId = g->GetNodePtr(i)->GetId();
104 nodeInfo.xCoordinate = g->GetNodePtr(i)->GetNodeInfo()->GetCoordX();
105 nodeInfo.yCoordinate = g->GetNodePtr(i)->GetNodeInfo()->GetCoordY();
106 nodeInfo.inDegree = g->GetNodePtr(i)->GetInDegree();
107 nodeInfo.outDegree = g->GetNodePtr(i)->GetOutDegree();
108
109 switch (g->GetNodePtr(i)->GetNodeInfo()->GetNodeType())
110 {
111 case brite::NodeConf::RT_NODE:
112
113 if (((brite::RouterNodeConf*)(g->GetNodePtr(i)->GetNodeInfo()))->GetASId() == -1)
114 {
115 m_numAs = nodeInfo.asId = 0;
116 }
117 else
118 {
119 m_numAs = nodeInfo.asId =
120 ((brite::RouterNodeConf*)(g->GetNodePtr(i)->GetNodeInfo()))->GetASId();
121 }
122
123 switch (((brite::RouterNodeConf*)(g->GetNodePtr(i)->GetNodeInfo()))->GetRouterType())
124 {
125 case brite::RouterNodeConf::RT_NONE:
126 nodeInfo.type = "RT_NONE ";
127 break;
128 case brite::RouterNodeConf::RT_LEAF:
129 nodeInfo.type = "RT_LEAF ";
130 break;
131 case brite::RouterNodeConf::RT_BORDER:
132 nodeInfo.type = "RT_BORDER";
133 break;
134 case brite::RouterNodeConf::RT_STUB:
135 nodeInfo.type = "RT_STUB ";
136 break;
137 case brite::RouterNodeConf::RT_BACKBONE:
138 nodeInfo.type = "RT_BACKBONE ";
139 break;
140 default:
142 "Topology::Output(): Improperly classified 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 classified 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 =
205 (((brite::RouterNodeConf*)((*el)->GetSrc()->GetNodeInfo()))->GetASId() == -1)
206 ? 0
207 : ((brite::RouterNodeConf*)((*el)->GetSrc()->GetNodeInfo()))->GetASId();
208 edgeInfo.asTo =
209 (((brite::RouterNodeConf*)((*el)->GetDst()->GetNodeInfo()))->GetASId() == -1)
210 ? 0
211 : ((brite::RouterNodeConf*)((*el)->GetDst()->GetNodeInfo()))->GetASId();
212 break;
213
214 case brite::EdgeConf::AS_EDGE:
215 edgeInfo.delay = -1; /* No delay for AS Edges */
216 edgeInfo.bandwidth = (*el)->GetConf()->GetBW();
217 edgeInfo.asFrom = ((brite::ASNodeConf*)((*el)->GetSrc()->GetNodeInfo()))->GetASId();
218 edgeInfo.asTo = ((brite::ASNodeConf*)((*el)->GetDst()->GetNodeInfo()))->GetASId();
219 break;
220
221 default:
222 NS_FATAL_ERROR("Topology::Output(): Invalid Edge type encountered...");
223 }
224
225 switch ((*el)->GetConf()->GetEdgeType())
226 {
227 case brite::EdgeConf::RT_EDGE:
228 switch (((brite::RouterEdgeConf*)(*el)->GetConf())->GetRouterEdgeType())
229 {
230 case brite::RouterEdgeConf::RT_NONE:
231 edgeInfo.type = "E_RT_NONE ";
232 break;
233 case brite::RouterEdgeConf::RT_STUB:
234 edgeInfo.type = "E_RT_STUB ";
235 break;
236 case brite::RouterEdgeConf::RT_BORDER:
237 edgeInfo.type = "E_RT_BORDER ";
238 break;
239 case brite::RouterEdgeConf::RT_BACKBONE:
240 edgeInfo.type = "E_RT_BACKBONE ";
241 break;
242 default:
243 NS_FATAL_ERROR("Output(): Invalid router edge type...");
244 }
245 break;
246
247 case brite::EdgeConf::AS_EDGE:
248 switch (((brite::ASEdgeConf*)((*el)->GetConf()))->GetASEdgeType())
249 {
250 case brite::ASEdgeConf::AS_NONE:
251 edgeInfo.type = "E_AS_NONE ";
252 break;
253 case brite::ASEdgeConf::AS_STUB:
254 edgeInfo.type = "E_AS_STUB ";
255 break;
256 case brite::ASEdgeConf::AS_BORDER:
257 edgeInfo.type = "E_AS_BORDER ";
258 break;
259 case brite::ASEdgeConf::AS_BACKBONE:
260 edgeInfo.type = "E_AS_BACKBONE ";
261 break;
262 default:
263 NS_FATAL_ERROR("BriteOutput(): Invalid AS edge type...");
264 }
265 break;
266
267 default:
268 NS_FATAL_ERROR("BriteOutput(): Invalid edge type...");
269 }
270
271 m_briteEdgeInfoList.push_back(edgeInfo);
272 }
273}
274
277{
278 return m_asLeafNodes[asNum]->Get(leafNum);
279}
280
283{
284 return m_nodesByAs[asNum]->Get(nodeNum);
285}
286
289{
290 return m_nodesByAs[asNum]->GetN();
291}
292
295{
296 return m_asLeafNodes[asNum]->GetN();
297}
298
301{
302 return m_numNodes;
303}
304
307{
308 return m_numEdges;
309}
310
313{
314 return m_numAs;
315}
316
319{
320 return m_systemForAs[asNum];
321}
322
323void
325{
326 NS_ASSERT_MSG(!m_topology, "Brite Topology Already Created");
327
328 // check to see if need to generate seed file
329 bool generateSeedFile = m_seedFile.empty();
330
331 if (generateSeedFile)
332 {
333 NS_LOG_LOGIC("Generating BRITE Seed file");
334
335 std::ofstream seedFile;
336
337 // overwrite file if already there
338 seedFile.open("briteSeedFile.txt", std::ios_base::out | std::ios_base::trunc);
339
340 // verify open
341 NS_ASSERT(!seedFile.fail());
342
343 // Generate seed file expected by BRITE
344 // need unsigned shorts 0-65535
345 seedFile << "PLACES " << m_uv->GetInteger(0, 65535) << " " << m_uv->GetInteger(0, 65535)
346 << " " << m_uv->GetInteger(0, 65535) << std::endl;
347 seedFile << "CONNECT " << m_uv->GetInteger(0, 65535) << " " << m_uv->GetInteger(0, 65535)
348 << " " << m_uv->GetInteger(0, 65535) << std::endl;
349 seedFile << "EDGE_CONN " << m_uv->GetInteger(0, 65535) << " " << m_uv->GetInteger(0, 65535)
350 << " " << m_uv->GetInteger(0, 65535) << std::endl;
351 seedFile << "GROUPING " << m_uv->GetInteger(0, 65535) << " " << m_uv->GetInteger(0, 65535)
352 << " " << m_uv->GetInteger(0, 65535) << std::endl;
353 seedFile << "ASSIGNMENT " << m_uv->GetInteger(0, 65535) << " " << m_uv->GetInteger(0, 65535)
354 << " " << m_uv->GetInteger(0, 65535) << std::endl;
355 seedFile << "BANDWIDTH " << m_uv->GetInteger(0, 65535) << " " << m_uv->GetInteger(0, 65535)
356 << " " << m_uv->GetInteger(0, 65535) << std::endl;
357 seedFile.close();
358
359 // if we're using NS3 generated seed files don't want brite to create a new seed file.
360 m_seedFile = m_newSeedFile = "briteSeedFile.txt";
361 }
362
363 brite::Brite br(m_confFile, m_seedFile, m_newSeedFile);
364 m_topology = br.GetTopology();
367
368 // brite automatically spits out the seed values used to a separate file so no need to keep this
369 // anymore
370 if (generateSeedFile)
371 {
372 remove("briteSeedFile.txt");
373 remove("last_seed_file");
374 }
375}
376
377void
379{
380 NS_LOG_FUNCTION(this);
381
383
384 // not using MPI so each AS is on system number 0
385 for (uint32_t i = 0; i < m_numAs; ++i)
386 {
387 m_systemForAs.push_back(0);
388 }
389
390 // create all nodes with system number 0
392
394
395 NS_LOG_DEBUG(m_numNodes << " nodes created in BRITE topology");
396
397 stack.Install(m_nodes);
398
400}
401
402void
404{
405 NS_LOG_FUNCTION(this);
406
408
409 // determine as system number for each AS
410 NS_LOG_LOGIC("Assigning << " << m_numAs << " AS to " << systemCount << " MPI instances");
411 for (uint32_t i = 0; i < m_numAs; ++i)
412 {
413 int val = i % systemCount;
414 m_systemForAs.push_back(val);
415 NS_LOG_INFO("AS: " << i << " System: " << val);
416 }
417
418 // create nodes
419 for (BriteTopologyHelper::BriteNodeInfoList::iterator it = m_briteNodeInfoList.begin();
420 it != m_briteNodeInfoList.end();
421 ++it)
422 {
423 m_nodes.Add(CreateObject<Node>(GetSystemNumberForAs((*it).asId)));
424 m_numNodes++;
425 }
426
427 NS_LOG_INFO(m_numNodes << " nodes created in BRITE topology");
428
429 stack.Install(m_nodes);
430
432}
433
434void
436{
437 NS_LOG_FUNCTION(this);
438 // assign IPs
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
451 for (std::size_t i = 0; i < m_netDevices.size(); ++i)
452 {
453 address.Assign(*m_netDevices[i]);
454 address.NewNetwork();
455 }
456}
457
458void
460{
461 NS_LOG_FUNCTION(this);
462 // create one node container to hold leaf nodes for attaching
463 for (uint32_t i = 0; i < m_numAs; ++i)
464 {
465 m_asLeafNodes.push_back(new NodeContainer());
466 m_nodesByAs.push_back(new NodeContainer());
467 }
468
469 for (BriteTopologyHelper::BriteEdgeInfoList::iterator it = m_briteEdgeInfoList.begin();
470 it != m_briteEdgeInfoList.end();
471 ++it)
472 {
473 // Set the link delay
474 // The brite value for delay is given in milliseconds
476 TimeValue(Seconds((*it).delay / 1000.0)));
477
478 // The brite value for data rate is given in Mbps
480 "DataRate",
481 DataRateValue(DataRate((*it).bandwidth * mbpsToBps)));
482
483 m_netDevices.push_back(
485 m_nodes.Get((*it).destId))));
486
487 m_numEdges++;
488 }
489
490 NS_LOG_INFO("Created " << m_numEdges << " edges in BRITE topology");
491
492 // iterate through all nodes and add leaf nodes for each AS
493 for (BriteTopologyHelper::BriteNodeInfoList::iterator it = m_briteNodeInfoList.begin();
494 it != m_briteNodeInfoList.end();
495 ++it)
496 {
497 m_nodesByAs[(*it).asId]->Add(m_nodes.Get((*it).nodeId));
498
499 if ((*it).type == "RT_LEAF ")
500 {
501 m_asLeafNodes[(*it).asId]->Add(m_nodes.Get((*it).nodeId));
502 }
503 }
504}
505
506} // 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:1425
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: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:160
#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:1338
address
Definition: first.py:40
stack
Definition: first.py:37
Every class exported by the ns3 library is enclosed in the ns3 namespace.