diff --git a/src/brite/doc/brite.rst b/src/brite/doc/brite.rst new file mode 100644 index 000000000..f058cef44 --- /dev/null +++ b/src/brite/doc/brite.rst @@ -0,0 +1,144 @@ +.. include:: replace.txt + +BRITE Integration +------------------ + +This model implements an interface to BRITE, the Boston university +Representative Internet Topology gEnerator [1]_. BRITE is a standard tool for +generating realistic internet topologies. The ns-3 model, described herein, +provides a helper class to facilitate generating ns-3 specific topologies +using BRITE configuration files. BRITE builds the original graph which is +stored as nodes and edges in the ns-3 BriteTopolgyHelper class. In the ns-3 +integration of BRITE, the generator generates a topology and then provides +access to leaf nodes for each AS generated. ns-3 users can than attach +custom topologies to these leaf nodes either by creating them manually or +using topology generators provided in ns-3. + +There are three major types of topologies available in BRITE: Router, +AS, and Hierarchical which is a combination of AS and Router. For the +purposes of ns-3 simulation, the most useful are likely to be Router and +Hierarchical. Router level topologies be generated using either the Waxman +model or the Barabasi-Albert model. Each model has different parameters that +effect topology creation. For flat router topologies, all nodes are considered +to be in the same AS. + +BRITE Hierarchical topologies contain two levels. The first is the AS level. +This level can be also be created by using either the Waxman model or the +Barabasi-Albert model. Then for each node in the AS topology, a router level +topology is constructed. These router level topologies can again either use +the Waxman model or the Barbasi-Albert model. BRITE interconnects these separate +router topologies as specified by the AS level topology. Once the hierarchical +topology is constructed, it is flattened into a large router level topology. + +Further information can be found in the BRITE user manual::: + + http://www.cs.bu.edu/brite/publications/usermanual.pdf + +Model Description +***************** + +The model relies on building an external BRITE library, +and then building some ns-3 helpers that call out to the library. +The source code for the ns-3 helpers lives in the directory +``src/brite/helper``. + +Design +====== + +To generate the BRITE topology, ns-3 helpers call out to the external BRITE library, +and using a standard BRITE configuration file, the BRITE code builds a graph with nodes +and edges according to this configuration file. Please see the BRITE documenation +or the example configuration files in src/brite/examples/conf_files to get a better +grasp of BRITE configuration options. The graph built by BRITE is returned to ns-3, +and a ns-3 implementation of the graph is built. Leaf nodes for each AS are available +for the user to either attach custom topologies or install ns-3 applications directly. + + +References +========== + +.. [1] Alberto Medina, Anukool Lakhina, Ibrahim Matta, and John Byers. BRITE: An Approach to Universal Topology Generation. In Proceedings of the International Workshop on Modeling, Analysis and Simulation of Computer and Telecommunications Systems- MASCOTS '01, Cincinnati, Ohio, August 2001. + +Usage +***** + +The brite-generic-example can be referenced to see basic usage of the BRITE +interface. In summary, the BriteTopologyHelper is used as the interface point +by passing in a BRITE configuration file. Along with the configuration file a +BRITE formatted random seed file can also be passed in. If a seed file is not +passed in, the helper will create a seed file using ns-3's UniformRandomVariable. +Once the topology has been generated by BRITE, BuildBriteTopology() is called to +create the ns-3 representation. Next IP Address can be assigned to the topology +using either AssignIpv4Addresses() or AssignIpv6Addresses(). It should be noted +that each point-to-point link in the topology will be treated as a new network +therefore for IPV4 a /30 subnet should be used to avoid wasting a large amount of +the available address space. + +Example BRITE configuration files can be found in /src/brite/examples/conf_files/. +ASBarbasi and ASWaxman are examples of AS only topologies. The RTBarabasi and +RTWaxman files are examples of router only topologies. Finally the +TD_ASBarabasi_RTWaxman configuration file is an example of a Hierarchical topology +that uses the Barabasi-Albert model for the AS level and the Waxman model for each +of the router level topologies. Information on the BRITE parameters used in these files +can be found in the BRITE user manual. + + +Building BRITE Integration +========================== + +The first step is to download and build the ns-3 specific BRITE repository::: + + $ hg clone http://code.nsnam.org/BRITE + $ cd BRITE + $ make + +This will build BRITE and create a library, libbrite.so, within the BRITE +directory. + +Once BRITE has been built successfully, we proceed to configure ns-3 with +BRITE support. Change to your ns-3 directory::: + + $ ./waf configure --with-brite=/your/path/to/brite/source --enable-examples + +Make sure it says 'enabled' beside 'BRITE Integration'. If it does not, then +something has gone wrong. Either you have forgotten to build BRITE first +following the steps above, or ns-3 could not find your BRITE directory. + +Next, build ns-3::: + + $ ./waf + +Examples +======== +For an example demonstrating BRITE integration +run::: + + $ ./waf --run 'brite-generic-example' + +By enabling the verbose parameter, the example will print out the node and +edge information in a similar format to standard BRITE output. There are +many other command-line parameters including confFile, tracing, and nix, described below: + + confFile: A BRITE configuration file. Many different BRITE configuration + file examples exist in the src/brite/examples/conf_files directory, for + example, RTBarabasi20.conf and RTWaxman.conf. Please refer to + the conf_files directory for more examples. + + tracing: Enables ascii tracing. + + nix: Enables nix-vector routing. Global routing is used by default. + +The generic BRITE example also support visualization using pyviz, assuming +python bindings in ns-3 are enabled::: + + $ ./waf --run brite-generic-example --vis + +Simulations involving BRITE can also be used with MPI. The total number of MPI instances is +passed to the BRITE topology helper where a modulo divide is used to assign the nodes for each +AS to a MPI instance. An example can be found in src/brite/examples::: + + $ mpirun -np 2 ./waf --run brite-MPI-example + +Please see the ns-3 MPI documentation for information on setting up MPI with ns-3. + + diff --git a/src/brite/examples/brite-MPI-example.cc b/src/brite/examples/brite-MPI-example.cc new file mode 100644 index 000000000..9b13e7926 --- /dev/null +++ b/src/brite/examples/brite-MPI-example.cc @@ -0,0 +1,217 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include "ns3/core-module.h" +#include "ns3/mpi-interface.h" +#include "ns3/network-module.h" +#include "ns3/internet-module.h" +#include "ns3/point-to-point-module.h" +#include "ns3/mobility-module.h" +#include "ns3/applications-module.h" +#include "ns3/brite-module.h" +#include "ns3/ipv4-nix-vector-helper.h" + + + +#include +#include + +#ifdef NS3_MPI +#include +#endif + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("BriteMPITest"); + +int +main (int argc, char *argv[]) +{ +#ifdef NS3_MPI + // Distributed simulation setup + MpiInterface::Enable (&argc, &argv); + GlobalValue::Bind ("SimulatorImplementationType", + StringValue ("ns3::DistributedSimulatorImpl")); + + LogComponentEnable ("BriteMPITest", LOG_LEVEL_ALL); + LogComponentEnable ("TcpSocketBase", LOG_LEVEL_INFO); + + uint32_t systemId = MpiInterface::GetSystemId (); + uint32_t systemCount = MpiInterface::GetSize (); + + // Check for valid distributed parameters. + // For just this particular example, must have 2 and only 2 Logical Processors (LPs) + NS_ASSERT_MSG (systemCount == 2, "This demonstration requires 2 and only 2 logical processors."); + + // BRITE needs a configuration file to build its graph. By default, this + // example will use the TD_ASBarabasi_RTWaxman.conf file. There are many others + // which can be found in the BRITE/conf_files directory + std::string confFile = "src/brite/examples/conf_files/TD_ASBarabasi_RTWaxman.conf"; + bool tracing = false; + bool nix = false; + + CommandLine cmd; + cmd.AddValue ("confFile", "BRITE conf file", confFile); + cmd.AddValue ("tracing", "Enable or disable ascii tracing", tracing); + cmd.AddValue ("nix", "Enable or disable nix-vector routing", nix); + + cmd.Parse (argc,argv); + + // Invoke the BriteTopologyHelper and pass in a BRITE + // configuration file and a seed file. This will use + // BRITE to build a graph from which we can build the ns-3 topology + BriteTopologyHelper bth (confFile); + + PointToPointHelper p2p; + + Ipv4StaticRoutingHelper staticRouting; + Ipv4GlobalRoutingHelper globalRouting; + Ipv4ListRoutingHelper listRouting; + Ipv4NixVectorHelper nixRouting; + + InternetStackHelper stack; + + if (nix) + { + listRouting.Add (staticRouting, 0); + listRouting.Add (nixRouting, 10); + } + else + { + listRouting.Add (staticRouting, 0); + listRouting.Add (globalRouting, 10); + } + + stack.SetRoutingHelper (listRouting); + + Ipv4AddressHelper address; + address.SetBase ("10.0.0.0", "255.255.255.252"); + + //build topology as normal but also pass systemCount + bth.BuildBriteTopology (stack, systemCount); + bth.AssignIpv4Addresses (address); + + NS_LOG_LOGIC ("Number of AS created " << bth.GetNAs ()); + + uint16_t port = 5001; + + NodeContainer client; + NodeContainer server; + + //For this example will use AS 0 and AS 1 which will be on seperate systems + //due to the mod divide used to assign AS to system. + + //GetSystemNumberForAs (uint32_t) can be used to determine which system an + //AS is assigned to + NS_LOG_LOGIC ("AS 0 has been assigned to system " << bth.GetSystemNumberForAs (0)); + NS_LOG_LOGIC ("As 1 has been assigned to system " << bth.GetSystemNumberForAs (1)); + + //install client node on last leaf node of AS 0 + client.Add (CreateObject (0)); + stack.Install (client); + int numLeafNodesInAsZero = bth.GetNLeafNodesForAs (0); + client.Add (bth.GetLeafNodeForAs (0, numLeafNodesInAsZero - 1)); + + //install server node on last leaf node on AS 1 + server.Add (CreateObject (1)); + stack.Install (server); + int numLeafNodesInAsOne = bth.GetNLeafNodesForAs (1); + server.Add (bth.GetLeafNodeForAs (1, numLeafNodesInAsOne - 1)); + + p2p.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); + p2p.SetChannelAttribute ("Delay", StringValue ("2ms")); + + NetDeviceContainer p2pClientDevices; + NetDeviceContainer p2pServerDevices; + + p2pClientDevices = p2p.Install (client); + p2pServerDevices = p2p.Install (server); + + address.SetBase ("10.1.0.0", "255.255.0.0"); + Ipv4InterfaceContainer clientInterfaces; + clientInterfaces = address.Assign (p2pClientDevices); + + address.SetBase ("10.2.0.0", "255.255.0.0"); + Ipv4InterfaceContainer serverInterfaces; + serverInterfaces = address.Assign (p2pServerDevices); + + if (!nix) + { + Ipv4GlobalRoutingHelper::PopulateRoutingTables (); + } + + //only has two systems in this example. Install applications only on nodes in my system + + + //Moved here to get totalRX at end + ApplicationContainer sinkApps; + + if (systemId == 1) + { + + Address sinkLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port)); + PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", sinkLocalAddress); + sinkApps.Add (packetSinkHelper.Install (server.Get (0))); + sinkApps.Start (Seconds (0.0)); + sinkApps.Stop (Seconds (10.0)); + } + + if (systemId == 0) + { + OnOffHelper clientHelper ("ns3::TcpSocketFactory", Address ()); + clientHelper.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]")); + clientHelper.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]")); + + ApplicationContainer clientApps; + AddressValue remoteAddress (InetSocketAddress (serverInterfaces.GetAddress (0), port)); + clientHelper.SetAttribute ("Remote", remoteAddress); + clientApps.Add (clientHelper.Install (client.Get (0))); + clientApps.Start (Seconds (1.0)); // Start 1 second after sink + clientApps.Stop (Seconds (9.0)); // Stop before the sink + } + + if (!nix) + { + Ipv4GlobalRoutingHelper::PopulateRoutingTables (); + } + + if (tracing) + { + AsciiTraceHelper ascii; + p2p.EnableAsciiAll (ascii.CreateFileStream ("briteLeaves.tr")); + } + + // Run the simulator + Simulator::Stop (Seconds (200.0)); + Simulator::Run (); + Simulator::Destroy (); + + if (systemId == 1) + { + Ptr sink1 = DynamicCast (sinkApps.Get (0)); + NS_LOG_DEBUG ("Total Bytes Received: " << sink1->GetTotalRx ()); + } + + MpiInterface::Disable (); + + return 0; + +#else + NS_FATAL_ERROR ("Can't use distributed simulator without MPI compiled in"); +#endif +} diff --git a/src/brite/examples/brite-generic-example.cc b/src/brite/examples/brite-generic-example.cc new file mode 100644 index 000000000..d6d60b1b2 --- /dev/null +++ b/src/brite/examples/brite-generic-example.cc @@ -0,0 +1,163 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include "ns3/core-module.h" +#include "ns3/network-module.h" +#include "ns3/internet-module.h" +#include "ns3/point-to-point-module.h" +#include "ns3/mobility-module.h" +#include "ns3/applications-module.h" +#include "ns3/brite-module.h" +#include "ns3/ipv4-nix-vector-helper.h" +#include +#include + +using namespace ns3; + +NS_LOG_COMPONENT_DEFINE ("BriteExample"); + +int +main (int argc, char *argv[]) +{ + LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_ALL); + LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_ALL); + + LogComponentEnable ("BriteExample", LOG_LEVEL_ALL); + + // BRITE needs a configuration file to build its graph. By default, this + // example will use the TD_ASBarabasi_RTWaxman.conf file. There are many others + // which can be found in the BRITE/conf_files directory + std::string confFile = "src/brite/examples/conf_files/TD_ASBarabasi_RTWaxman.conf"; + bool tracing = false; + bool nix = false; + + CommandLine cmd; + cmd.AddValue ("confFile", "BRITE conf file", confFile); + cmd.AddValue ("tracing", "Enable or disable ascii tracing", tracing); + cmd.AddValue ("nix", "Enable or disable nix-vector routing", nix); + + cmd.Parse (argc,argv); + + nix = false; + + // Invoke the BriteTopologyHelper and pass in a BRITE + // configuration file and a seed file. This will use + // BRITE to build a graph from which we can build the ns-3 topology + BriteTopologyHelper bth (confFile); + bth.AssignStreams (3); + + PointToPointHelper p2p; + + Ipv4StaticRoutingHelper staticRouting; + Ipv4GlobalRoutingHelper globalRouting; + Ipv4ListRoutingHelper listRouting; + Ipv4NixVectorHelper nixRouting; + + InternetStackHelper stack; + + if (nix) + { + listRouting.Add (staticRouting, 0); + listRouting.Add (nixRouting, 10); + } + else + { + listRouting.Add (staticRouting, 0); + listRouting.Add (globalRouting, 10); + } + + stack.SetRoutingHelper (listRouting); + + Ipv4AddressHelper address; + address.SetBase ("10.0.0.0", "255.255.255.252"); + + bth.BuildBriteTopology (stack); + bth.AssignIpv4Addresses (address); + + NS_LOG_INFO ("Number of AS created " << bth.GetNAs ()); + + //The BRITE topology generator generates a topology of routers. Here we create + //two subnetworks which we attach to router leaf nodes generated by BRITE + //Any NS3 topology may be used to attach to the BRITE leaf nodes but here we + //use just one node + + NodeContainer client; + NodeContainer server; + + client.Create (1); + stack.Install (client); + + //install client node on last leaf node of AS 0 + int numLeafNodesInAsZero = bth.GetNLeafNodesForAs (0); + client.Add (bth.GetLeafNodeForAs (0, numLeafNodesInAsZero - 1)); + + server.Create (1); + stack.Install (server); + + //install server node on last leaf node on AS 1 + int numLeafNodesInAsOne = bth.GetNLeafNodesForAs (1); + server.Add (bth.GetLeafNodeForAs (1, numLeafNodesInAsOne - 1)); + + p2p.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); + p2p.SetChannelAttribute ("Delay", StringValue ("2ms")); + + NetDeviceContainer p2pClientDevices; + NetDeviceContainer p2pServerDevices; + + p2pClientDevices = p2p.Install (client); + p2pServerDevices = p2p.Install (server); + + address.SetBase ("10.1.0.0", "255.255.0.0"); + Ipv4InterfaceContainer clientInterfaces; + clientInterfaces = address.Assign (p2pClientDevices); + + address.SetBase ("10.2.0.0", "255.255.0.0"); + Ipv4InterfaceContainer serverInterfaces; + serverInterfaces = address.Assign (p2pServerDevices); + + UdpEchoServerHelper echoServer (9); + ApplicationContainer serverApps = echoServer.Install (server.Get (0)); + serverApps.Start (Seconds (1.0)); + serverApps.Stop (Seconds (5.0)); + + UdpEchoClientHelper echoClient (serverInterfaces.GetAddress (0), 9); + echoClient.SetAttribute ("MaxPackets", UintegerValue (1)); + echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.))); + echoClient.SetAttribute ("PacketSize", UintegerValue (1024)); + + ApplicationContainer clientApps = echoClient.Install (client.Get (0)); + clientApps.Start (Seconds (2.0)); + clientApps.Stop (Seconds (5.0)); + + if (!nix) + { + Ipv4GlobalRoutingHelper::PopulateRoutingTables (); + } + + if (tracing) + { + AsciiTraceHelper ascii; + p2p.EnableAsciiAll (ascii.CreateFileStream ("briteLeaves.tr")); + } + // Run the simulator + Simulator::Stop (Seconds (6.0)); + Simulator::Run (); + Simulator::Destroy (); + + return 0; +} diff --git a/src/brite/examples/conf_files/ASBarabasi.conf b/src/brite/examples/conf_files/ASBarabasi.conf new file mode 100644 index 000000000..b75cb6de3 --- /dev/null +++ b/src/brite/examples/conf_files/ASBarabasi.conf @@ -0,0 +1,21 @@ +#This config file was generated by the GUI. + +BriteConfig + +BeginModel + Name = 4 #Router Barabasi=2, AS Barabasi =4 + N = 1000 #Number of nodes in graph + HS = 1000 #Size of main plane (number of squares) + LS = 100 #Size of inner planes (number of squares) + NodePlacement = 1 #Random = 1, Heavy Tailed = 2 + m = 2 #Number of neighboring node each new node connects to. + BWDist = 1 #Constant = 1, Uniform =2, HeavyTailed = 3, Exponential =4 + BWMin = 10.0 + BWMax = 1024.0 +EndModel + + +BeginOutput #**Atleast one of these options should have value 1** + BRITE = 1 #0 = Do not save as BRITE, 1 = save as BRITE. + OTTER = 0 #0 = Do not visualize with Otter, 1 = Visualize +EndOutput diff --git a/src/brite/examples/conf_files/ASWaxman.conf b/src/brite/examples/conf_files/ASWaxman.conf new file mode 100644 index 000000000..ffed2b3f6 --- /dev/null +++ b/src/brite/examples/conf_files/ASWaxman.conf @@ -0,0 +1,23 @@ +#This config file was generated by the GUI. + +BriteConfig + +BeginModel + Name = 3 #Router Waxman = 1, AS Waxman = 3 + N = 1000 #Number of nodes in graph + HS = 1000 #Size of main plane (number of squares) + LS = 100 #Size of inner planes (number of squares) + NodePlacement = 1 #Random = 1, Heavy Tailed = 2 + GrowthType = 1 #Incremental = 1, All = 2 + m = 2 #Number of neighboring node each new node connects to. + alpha = 0.15 #Waxman Parameter + beta = 0.2 #Waxman Parameter + BWDist = 1 #Constant = 1, Uniform =2, HeavyTailed = 3, Exponential =4 + BWMin = 10.0 + BWMax = 1024.0 +EndModel + +BeginOutput #**Atleast one of these options should have value 1** + BRITE = 1 #0 = Do not save as BRITE, 1 = save as BRITE. + OTTER = 0 #0 = Do not visualize with Otter, 1 = Visualize +EndOutput diff --git a/src/brite/examples/conf_files/RTBarabasi.conf b/src/brite/examples/conf_files/RTBarabasi.conf new file mode 100644 index 000000000..3b8a57e21 --- /dev/null +++ b/src/brite/examples/conf_files/RTBarabasi.conf @@ -0,0 +1,22 @@ +#This config file was generated by the GUI. + +BriteConfig + +BeginModel + Name = 2 #Router Barabasi=2, AS Barabasi =4 + N = 100 #Number of nodes in graph + HS = 1000 #Size of main plane (number of squares) + LS = 100 #Size of inner planes (number of squares) + NodePlacement = 1 #Random = 1, Heavy Tailed = 2 + m = 2 #Number of neighboring node each new node connects to. + BWDist = 1 #Constant = 1, Uniform =2, HeavyTailed = 3, Exponential =4 + BWMin = 10.0 + BWMax = 1024.0 +EndModel + + + +BeginOutput #**Atleast one of these options should have value 1** + BRITE = 1 #0 = Do not save as BRITE, 1 = save as BRITE. + OTTER = 0 #0 = Do not visualize with Otter, 1 = Visualize +EndOutput diff --git a/src/brite/examples/conf_files/RTBarabasi10.conf b/src/brite/examples/conf_files/RTBarabasi10.conf new file mode 100644 index 000000000..52b0c3d54 --- /dev/null +++ b/src/brite/examples/conf_files/RTBarabasi10.conf @@ -0,0 +1,22 @@ +#This config file was generated by the GUI. + +BriteConfig + +BeginModel + Name = 2 #Router Barabasi=2, AS Barabasi =4 + N = 10 #Number of nodes in graph + HS = 1000 #Size of main plane (number of squares) + LS = 100 #Size of inner planes (number of squares) + NodePlacement = 1 #Random = 1, Heavy Tailed = 2 + m = 2 #Number of neighboring node each new node connects to. + BWDist = 1 #Constant = 1, Uniform =2, HeavyTailed = 3, Exponential =4 + BWMin = 10.0 + BWMax = 1024.0 +EndModel + + + +BeginOutput #**Atleast one of these options should have value 1** + BRITE = 1 #0 = Do not save as BRITE, 1 = save as BRITE. + OTTER = 0 #0 = Do not visualize with Otter, 1 = Visualize +EndOutput diff --git a/src/brite/examples/conf_files/RTBarabasi20.conf b/src/brite/examples/conf_files/RTBarabasi20.conf new file mode 100644 index 000000000..0c3aef97e --- /dev/null +++ b/src/brite/examples/conf_files/RTBarabasi20.conf @@ -0,0 +1,22 @@ +#This config file was generated by the GUI. + +BriteConfig + +BeginModel + Name = 2 #Router Barabasi=2, AS Barabasi =4 + N = 20 #Number of nodes in graph + HS = 1000 #Size of main plane (number of squares) + LS = 100 #Size of inner planes (number of squares) + NodePlacement = 1 #Random = 1, Heavy Tailed = 2 + m = 2 #Number of neighboring node each new node connects to. + BWDist = 1 #Constant = 1, Uniform =2, HeavyTailed = 3, Exponential =4 + BWMin = 10.0 + BWMax = 1024.0 +EndModel + + + +BeginOutput #**Atleast one of these options should have value 1** + BRITE = 1 #0 = Do not save as BRITE, 1 = save as BRITE. + OTTER = 1 #0 = Do not visualize with Otter, 1 = Visualize +EndOutput diff --git a/src/brite/examples/conf_files/RTBarabasi5.conf b/src/brite/examples/conf_files/RTBarabasi5.conf new file mode 100644 index 000000000..1d47d9ae2 --- /dev/null +++ b/src/brite/examples/conf_files/RTBarabasi5.conf @@ -0,0 +1,22 @@ +#This config file was generated by the GUI. + +BriteConfig + +BeginModel + Name = 2 #Router Barabasi=2, AS Barabasi =4 + N = 5 #Number of nodes in graph + HS = 1000 #Size of main plane (number of squares) + LS = 100 #Size of inner planes (number of squares) + NodePlacement = 1 #Random = 1, Heavy Tailed = 2 + m = 2 #Number of neighboring node each new node connects to. + BWDist = 1 #Constant = 1, Uniform =2, HeavyTailed = 3, Exponential =4 + BWMin = 10.0 + BWMax = 1024.0 +EndModel + + + +BeginOutput #**Atleast one of these options should have value 1** + BRITE = 1 #0 = Do not save as BRITE, 1 = save as BRITE. + OTTER = 0 #0 = Do not visualize with Otter, 1 = Visualize +EndOutput diff --git a/src/brite/examples/conf_files/RTWaxman.conf b/src/brite/examples/conf_files/RTWaxman.conf new file mode 100644 index 000000000..bcaa85ae6 --- /dev/null +++ b/src/brite/examples/conf_files/RTWaxman.conf @@ -0,0 +1,25 @@ +#This config file was generated by the GUI. + +BriteConfig + +BeginModel + Name = 1 #Router Waxman = 1, AS Waxman = 3 + N = 1000 #Number of nodes in graph + HS = 1000 #Size of main plane (number of squares) + LS = 100 #Size of inner planes (number of squares) + NodePlacement = 1 #Random = 1, Heavy Tailed = 2 + GrowthType = 1 #Incremental = 1, All = 2 + m = 2 #Number of neighboring node each new node connects to. + alpha = 0.15 #Waxman Parameter + beta = 0.2 #Waxman Parameter + BWDist = 1 #Constant = 1, Uniform =2, HeavyTailed = 3, Exponential =4 + BWMin = 10.0 + BWMax = 1024.0 +EndModel + + + +BeginOutput #**Atleast one of these options should have value 1** + BRITE = 1 #0 = Do not save as BRITE, 1 = save as BRITE. + OTTER = 1 #0 = Do not visualize with Otter, 1 = Visualize +EndOutput diff --git a/src/brite/examples/conf_files/RTWaxman10.conf b/src/brite/examples/conf_files/RTWaxman10.conf new file mode 100644 index 000000000..a2064be8d --- /dev/null +++ b/src/brite/examples/conf_files/RTWaxman10.conf @@ -0,0 +1,25 @@ +#This config file was generated by the GUI. + +BriteConfig + +BeginModel + Name = 1 #Router Waxman = 1, AS Waxman = 3 + N = 10 #Number of nodes in graph + HS = 1000 #Size of main plane (number of squares) + LS = 100 #Size of inner planes (number of squares) + NodePlacement = 1 #Random = 1, Heavy Tailed = 2 + GrowthType = 1 #Incremental = 1, All = 2 + m = 2 #Number of neighboring node each new node connects to. + alpha = 0.15 #Waxman Parameter + beta = 0.2 #Waxman Parameter + BWDist = 1 #Constant = 1, Uniform =2, HeavyTailed = 3, Exponential =4 + BWMin = 10.0 + BWMax = 1024.0 +EndModel + + + +BeginOutput #**Atleast one of these options should have value 1** + BRITE = 1 #0 = Do not save as BRITE, 1 = save as BRITE. + OTTER = 0 #0 = Do not visualize with Otter, 1 = Visualize +EndOutput diff --git a/src/brite/examples/conf_files/RTWaxman20.conf b/src/brite/examples/conf_files/RTWaxman20.conf new file mode 100644 index 000000000..7e601bc17 --- /dev/null +++ b/src/brite/examples/conf_files/RTWaxman20.conf @@ -0,0 +1,25 @@ +#This config file was generated by the GUI. + +BriteConfig + +BeginModel + Name = 1 #Router Waxman = 1, AS Waxman = 3 + N = 20 #Number of nodes in graph + HS = 1000 #Size of main plane (number of squares) + LS = 100 #Size of inner planes (number of squares) + NodePlacement = 1 #Random = 1, Heavy Tailed = 2 + GrowthType = 1 #Incremental = 1, All = 2 + m = 2 #Number of neighboring node each new node connects to. + alpha = 0.15 #Waxman Parameter + beta = 0.2 #Waxman Parameter + BWDist = 1 #Constant = 1, Uniform =2, HeavyTailed = 3, Exponential =4 + BWMin = 10.0 + BWMax = 1024.0 +EndModel + + + +BeginOutput #**Atleast one of these options should have value 1** + BRITE = 1 #0 = Do not save as BRITE, 1 = save as BRITE. + OTTER = 0 #0 = Do not visualize with Otter, 1 = Visualize +EndOutput diff --git a/src/brite/examples/conf_files/RTWaxman5.conf b/src/brite/examples/conf_files/RTWaxman5.conf new file mode 100644 index 000000000..ce46dd5d6 --- /dev/null +++ b/src/brite/examples/conf_files/RTWaxman5.conf @@ -0,0 +1,25 @@ +#This config file was generated by the GUI. + +BriteConfig + +BeginModel + Name = 1 #Router Waxman = 1, AS Waxman = 3 + N = 5 #Number of nodes in graph + HS = 1000 #Size of main plane (number of squares) + LS = 100 #Size of inner planes (number of squares) + NodePlacement = 1 #Random = 1, Heavy Tailed = 2 + GrowthType = 1 #Incremental = 1, All = 2 + m = 2 #Number of neighboring node each new node connects to. + alpha = 0.15 #Waxman Parameter + beta = 0.2 #Waxman Parameter + BWDist = 1 #Constant = 1, Uniform =2, HeavyTailed = 3, Exponential =4 + BWMin = 10.0 + BWMax = 1024.0 +EndModel + + + +BeginOutput #**Atleast one of these options should have value 1** + BRITE = 1 #0 = Do not save as BRITE, 1 = save as BRITE. + OTTER = 0 #0 = Do not visualize with Otter, 1 = Visualize +EndOutput diff --git a/src/brite/examples/conf_files/TD_ASBarabasi_RTWaxman.conf b/src/brite/examples/conf_files/TD_ASBarabasi_RTWaxman.conf new file mode 100644 index 000000000..65d8069f8 --- /dev/null +++ b/src/brite/examples/conf_files/TD_ASBarabasi_RTWaxman.conf @@ -0,0 +1,50 @@ +#This config file was generated by the GUI. + +BriteConfig + + + +BeginModel + Name = 5 #Top Down = 5 + edgeConn = 2 #Random=1, Smallest Nonleaf = 2, Smallest Deg = 3, k-Degree=4 + k = -1 #Only needed if edgeConn is set to K-Degree, otherwise use -1 + BWInter = 1 #Constant = 1, Uniform =2, HeavyTailed = 3, Exponential =4 + BWInterMin = 10.0 + BWInterMax = 1024.0 + BWIntra = 3 #Constant = 1, Uniform =2, HeavyTailed = 3, Exponential =4 + BWIntraMin = 10.0 + BWIntraMax = 1024.0 +EndModel + +BeginModel + Name = 4 #Router Barabasi=2, AS Barabasi =4 + N = 2 #Number of nodes in graph + HS = 1000 #Size of main plane (number of squares) + LS = 100 #Size of inner planes (number of squares) + NodePlacement = 1 #Random = 1, Heavy Tailed = 2 + m = 1 #Number of neighboring node each new node connects to. + BWDist = 1 #Constant = 1, Uniform =2, HeavyTailed = 3, Exponential =4 + BWMin = -1.0 + BWMax = -1.0 +EndModel + +BeginModel + Name = 1 #Router Waxman=2, AS Waxman =3 + N = 20 #Number of nodes in graph + HS = 1000 #Size of main plane (number of squares) + LS = 100 #Size of inner planes (number of squares) + NodePlacement = 2 #Random = 1, Heavy Tailed = 2 + GrowthType = 1 #Incremental = 1, All = 2 + m = 1 #Number of neighboring node each new node connects to. + alpha = 0.5 #Waxman Parameter + beta = 0.8 #Waxman Parameter + BWDist = 1 #Constant = 1, Uniform =2, HeavyTailed = 3, Exponential =4 + BWMin = -1.0 + BWMax = -1.0 +EndModel + +BeginOutput #**Atleast one of these options should have value 1** + BRITE = 1 #0 = Do not save as BRITE, 1 = save as BRITE. + OTTER = 0 #0 = Do not visualize with Otter, 1 = Visualize +EndOutput + diff --git a/src/brite/examples/wscript b/src/brite/examples/wscript new file mode 100644 index 000000000..24fe6f367 --- /dev/null +++ b/src/brite/examples/wscript @@ -0,0 +1,7 @@ +## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- + +def build(bld): + obj = bld.create_ns3_program('brite-generic-example', ['brite', 'internet', 'point-to-point', 'nix-vector-routing', 'applications']) + obj.source = 'brite-generic-example.cc' + obj = bld.create_ns3_program('brite-MPI-example', ['brite', 'internet', 'point-to-point', 'nix-vector-routing', 'applications', 'mpi']) + obj.source = 'brite-MPI-example.cc' diff --git a/src/brite/helper/brite-topology-helper.cc b/src/brite/helper/brite-topology-helper.cc new file mode 100644 index 000000000..93ea94e5c --- /dev/null +++ b/src/brite/helper/brite-topology-helper.cc @@ -0,0 +1,483 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "ns3/log.h" +#include "ns3/abort.h" +#include "ns3/net-device.h" +#include "ns3/net-device-container.h" +#include "ns3/point-to-point-helper.h" +#include "ns3/ipv4-address-helper.h" +#include "ns3/random-variable-stream.h" +#include "ns3/data-rate.h" +#include "ns3/rng-seed-manager.h" + +#include "brite-topology-helper.h" + +#include +#include + +NS_LOG_COMPONENT_DEFINE ("BriteTopologyHelper"); + +namespace ns3 { + +BriteTopologyHelper::BriteTopologyHelper (std::string confFile, + std::string seedFile, + std::string newseedFile) : m_confFile (confFile), + m_seedFile (seedFile), + m_newSeedFile (newseedFile), + m_numAs (0), + m_topology (NULL), + m_numNodes (0), + m_numEdges (0) +{ + NS_LOG_FUNCTION (this); + + m_uv = CreateObject (); + +} + +BriteTopologyHelper::BriteTopologyHelper (std::string confFile) : m_confFile (confFile), + m_numAs (0), + m_topology (NULL), + m_numNodes (0), + m_numEdges (0) +{ + NS_LOG_FUNCTION (this); + + m_uv = CreateObject (); + +} + +BriteTopologyHelper::~BriteTopologyHelper () +{ + NS_LOG_FUNCTION (this); + delete m_topology; + + while (!m_netDevices.empty ()) + { + delete m_netDevices.back (); + m_netDevices.pop_back (); + } + + while (!m_asLeafNodes.empty ()) + { + delete m_asLeafNodes.back (); + m_asLeafNodes.pop_back (); + } + + while (!m_nodesByAs.empty ()) + { + delete m_nodesByAs.back (); + m_nodesByAs.pop_back (); + } +} + +void +BriteTopologyHelper::AssignStreams (int64_t streamNumber) +{ + m_uv->SetStream (streamNumber); +} + +void +BriteTopologyHelper::BuildBriteNodeInfoList (void) +{ + NS_LOG_FUNCTION (this); + brite::Graph *g = m_topology->GetGraph (); + for (int i = 0; i < g->GetNumNodes (); ++i) + { + BriteNodeInfo nodeInfo; + nodeInfo.nodeId = g->GetNodePtr (i)->GetId (); + nodeInfo.xCoordinate = g->GetNodePtr (i)->GetNodeInfo ()->GetCoordX (); + nodeInfo.yCoordinate = g->GetNodePtr (i)->GetNodeInfo ()->GetCoordY (); + nodeInfo.inDegree = g->GetNodePtr (i)->GetInDegree (); + nodeInfo.outDegree = g->GetNodePtr (i)->GetOutDegree (); + + switch (g->GetNodePtr (i)->GetNodeInfo ()->GetNodeType ()) + { + case brite::NodeConf::RT_NODE: + + if (((brite::RouterNodeConf*)(g->GetNodePtr (i)->GetNodeInfo ()))->GetASId () == -1) + { + m_numAs = nodeInfo.asId = 0; + } + else + { + m_numAs = nodeInfo.asId = ((brite::RouterNodeConf*)(g->GetNodePtr (i)->GetNodeInfo ()))->GetASId (); + } + + switch (((brite::RouterNodeConf*)(g->GetNodePtr (i)->GetNodeInfo ()))->GetRouterType ()) + { + case brite::RouterNodeConf::RT_NONE: + nodeInfo.type = "RT_NONE "; + break; + case brite::RouterNodeConf::RT_LEAF: + nodeInfo.type = "RT_LEAF "; + break; + case brite::RouterNodeConf::RT_BORDER: + nodeInfo.type = "RT_BORDER"; + break; + case brite::RouterNodeConf::RT_STUB: + nodeInfo.type = "RT_STUB "; + break; + case brite::RouterNodeConf::RT_BACKBONE: + nodeInfo.type = "RT_BACKBONE "; + break; + default: + NS_FATAL_ERROR ("Topology::Output(): Improperly classfied Router node encountered..."); + } + break; + + case brite::NodeConf::AS_NODE: + m_numAs = nodeInfo.asId = + ((brite::ASNodeConf*)(g->GetNodePtr (i)->GetNodeInfo ()))->GetASId (); + + switch (((brite::ASNodeConf*)(g->GetNodePtr (i)->GetNodeInfo ()))->GetASType ()) + { + case brite::ASNodeConf::AS_NONE: + nodeInfo.type = "AS_NONE "; + break; + case brite::ASNodeConf::AS_LEAF: + nodeInfo.type = "AS_LEAF "; + break; + case brite::ASNodeConf::AS_STUB: + nodeInfo.type = "AS_STUB "; + break; + case brite::ASNodeConf::AS_BORDER: + nodeInfo.type = "AS_BORDER "; + break; + case brite::ASNodeConf::AS_BACKBONE: + nodeInfo.type = "AS_BACKBONE "; + break; + default: + NS_FATAL_ERROR ("Topology::Output(): Improperly classfied AS node encountered..."); + } + break; + } + + m_briteNodeInfoList.push_back (nodeInfo); + } + + //Currently m_numAs stores the highest AS number. We want m_numAs to store the number + //of AS created in the topology. Since AS numbering starts at 0 we add one to get + //the correct count + m_numAs++; +} + +void +BriteTopologyHelper::BuildBriteEdgeInfoList (void) +{ + NS_LOG_FUNCTION (this); + brite::Graph *g = m_topology->GetGraph (); + std::list::iterator el; + std::list edgeList = g->GetEdges (); + + for (el = edgeList.begin (); el != edgeList.end (); el++) + { + BriteEdgeInfo edgeInfo; + edgeInfo.edgeId = (*el)->GetId (); + edgeInfo.srcId = (*el)->GetSrc ()->GetId (); + edgeInfo.destId = (*el)->GetDst ()->GetId (); + edgeInfo.length = (*el)->Length (); + + switch ((*el)->GetConf ()->GetEdgeType ()) + { + case brite::EdgeConf::RT_EDGE: + edgeInfo.delay = ((brite::RouterEdgeConf*)((*el)->GetConf ()))->GetDelay (); + edgeInfo.bandwidth = (*el)->GetConf ()->GetBW (); + //If there is only one AS, BRITE will use -1 as AS Number. We want it to be 0 instead. + edgeInfo.asFrom = (((brite::RouterNodeConf*)((*el)->GetSrc ()->GetNodeInfo ()))->GetASId () == -1) ? 0 : ((brite::RouterNodeConf*)((*el)->GetSrc ()->GetNodeInfo ()))->GetASId (); + edgeInfo.asTo = (((brite::RouterNodeConf*)((*el)->GetDst ()->GetNodeInfo ()))->GetASId () == -1) ? 0 : ((brite::RouterNodeConf*)((*el)->GetDst ()->GetNodeInfo ()))->GetASId (); + break; + + case brite::EdgeConf::AS_EDGE: + edgeInfo.delay = -1; /* No delay for AS Edges */ + edgeInfo.bandwidth = (*el)->GetConf ()->GetBW (); + edgeInfo.asFrom = ((brite::ASNodeConf*)((*el)->GetSrc ()->GetNodeInfo ()))->GetASId (); + edgeInfo.asTo = ((brite::ASNodeConf*)((*el)->GetDst ()->GetNodeInfo ()))->GetASId (); + break; + + default: + NS_FATAL_ERROR ("Topology::Output(): Invalid Edge type encountered..."); + } + + switch ((*el)->GetConf ()->GetEdgeType ()) + { + case brite::EdgeConf::RT_EDGE: + switch (((brite::RouterEdgeConf*)(*el)->GetConf ())->GetRouterEdgeType ()) + { + case brite::RouterEdgeConf::RT_NONE: + edgeInfo.type = "E_RT_NONE "; + break; + case brite::RouterEdgeConf::RT_STUB: + edgeInfo.type = "E_RT_STUB "; + break; + case brite::RouterEdgeConf::RT_BORDER: + edgeInfo.type = "E_RT_BORDER "; + break; + case brite::RouterEdgeConf::RT_BACKBONE: + edgeInfo.type = "E_RT_BACKBONE "; + break; + default: + NS_FATAL_ERROR ("Output(): Invalid router edge type..."); + } + break; + + case brite::EdgeConf::AS_EDGE: + switch (((brite::ASEdgeConf*)((*el)->GetConf ()))->GetASEdgeType ()) + { + case brite::ASEdgeConf::AS_NONE: + edgeInfo.type = "E_AS_NONE "; + break; + case brite::ASEdgeConf::AS_STUB: + edgeInfo.type = "E_AS_STUB "; + break; + case brite::ASEdgeConf::AS_BORDER: + edgeInfo.type = "E_AS_BORDER "; + break; + case brite::ASEdgeConf::AS_BACKBONE: + edgeInfo.type = "E_AS_BACKBONE "; + break; + default: + NS_FATAL_ERROR ("BriteOutput(): Invalid AS edge type..."); + } + break; + + default: + NS_FATAL_ERROR ("BriteOutput(): Invalid edge type..."); + + } + + m_briteEdgeInfoList.push_back (edgeInfo); + } +} + +Ptr +BriteTopologyHelper::GetLeafNodeForAs (uint32_t asNum, uint32_t leafNum) +{ + return m_asLeafNodes[asNum]->Get (leafNum); +} + +Ptr +BriteTopologyHelper::GetNodeForAs (uint32_t asNum, uint32_t nodeNum) +{ + return m_nodesByAs[asNum]->Get (nodeNum); +} + +uint32_t +BriteTopologyHelper::GetNNodesForAs (uint32_t asNum) +{ + return m_nodesByAs[asNum]->GetN (); +} + +uint32_t +BriteTopologyHelper::GetNLeafNodesForAs (uint32_t asNum) +{ + return m_asLeafNodes[asNum]->GetN (); +} + +uint32_t +BriteTopologyHelper::GetNNodesTopology () const +{ + return m_numNodes; +} + +uint32_t +BriteTopologyHelper::GetNEdgesTopology () const +{ + return m_numEdges; +} + +uint32_t +BriteTopologyHelper::GetNAs (void) const +{ + return m_numAs; +} + +uint32_t +BriteTopologyHelper::GetSystemNumberForAs (uint32_t asNum) const +{ + return m_systemForAs[asNum]; +} + +void BriteTopologyHelper::GenerateBriteTopology (void) +{ + NS_ASSERT_MSG (m_topology == NULL, "Brite Topology Already Created"); + + //check to see if need to generate seed file + bool generateSeedFile = m_seedFile.empty (); + + if (generateSeedFile) + { + NS_LOG_LOGIC ("Generating BRITE Seed file"); + + std::ofstream seedFile; + + //overwrite file if already there + seedFile.open ("briteSeedFile.txt", std::ios_base::out | std::ios_base::trunc); + + //verify open + NS_ASSERT (!seedFile.fail ()); + + //Generate seed file expected by BRITE + //need unsigned shorts 0-65535 + seedFile << "PLACES " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << std::endl; + seedFile << "CONNECT " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << std::endl; + seedFile << "EDGE_CONN " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << std::endl; + seedFile << "GROUPING " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << std::endl; + seedFile << "ASSIGNMENT " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << std::endl; + seedFile << "BANDWIDTH " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << " " << m_uv->GetInteger (0, 65535) << std::endl; + seedFile.close (); + + //if we're using NS3 generated seed files don't want brite to create a new seed file. + m_seedFile = m_newSeedFile = "briteSeedFile.txt"; + } + + brite::Brite br (m_confFile, m_seedFile, m_newSeedFile); + m_topology = br.GetTopology (); + BuildBriteNodeInfoList (); + BuildBriteEdgeInfoList (); + + //brite automatically spits out the seed values used to a seperate file so no need to keep this anymore + if (generateSeedFile) + { + remove ("briteSeedFile.txt"); + } + +} + +void +BriteTopologyHelper::BuildBriteTopology (InternetStackHelper& stack) +{ + NS_LOG_FUNCTION (this); + + GenerateBriteTopology (); + + //not using MPI so each AS is on system number 0 + for (uint32_t i = 0; i < m_numAs; ++i) + { + m_systemForAs.push_back (0); + } + + //create all nodes with system number 0 + m_nodes.Create (m_briteNodeInfoList.size ()); + + m_numNodes = m_briteNodeInfoList.size (); + + NS_LOG_DEBUG (m_numNodes << " nodes created in BRITE topology"); + + stack.Install (m_nodes); + + ConstructTopology (); +} + +void +BriteTopologyHelper::BuildBriteTopology (InternetStackHelper& stack, const uint32_t systemCount) +{ + NS_LOG_FUNCTION (this); + + GenerateBriteTopology (); + + //determine as system number for each AS + NS_LOG_LOGIC ("Assigning << " << m_numAs << " AS to " << systemCount << " MPI instances"); + for (uint32_t i = 0; i < m_numAs; ++i) + { + int val = i % systemCount; + m_systemForAs.push_back (val); + NS_LOG_INFO ("AS: " << i << " System: " << val); + } + + //create nodes + for (BriteTopologyHelper::BriteNodeInfoList::iterator it = m_briteNodeInfoList.begin (); it != m_briteNodeInfoList.end (); ++it) + { + m_nodes.Add (CreateObject (GetSystemNumberForAs ((*it).asId))); + m_numNodes++; + } + + NS_LOG_INFO (m_numNodes << " nodes created in BRITE topology"); + + stack.Install (m_nodes); + + ConstructTopology (); +} + +void +BriteTopologyHelper::AssignIpv4Addresses (Ipv4AddressHelper& address) +{ + NS_LOG_FUNCTION (this); + //assign IPs + for (unsigned int i = 0; i < m_netDevices.size (); ++i) + { + address.Assign (*m_netDevices[i]); + address.NewNetwork (); + } +} + +void +BriteTopologyHelper::AssignIpv6Addresses (Ipv6AddressHelper& address) +{ + NS_LOG_FUNCTION (this); + + for (unsigned int i = 0; i < m_netDevices.size (); ++i) + { + address.Assign (*m_netDevices[i]); + address.NewNetwork (); + } +} + +void +BriteTopologyHelper::ConstructTopology () +{ + NS_LOG_FUNCTION (this); + //create one node container to hold leaf nodes for attaching + for (uint32_t i = 0; i < m_numAs; ++i) + { + m_asLeafNodes.push_back (new NodeContainer ()); + m_nodesByAs.push_back (new NodeContainer ()); + } + + for (BriteTopologyHelper::BriteEdgeInfoList::iterator it = m_briteEdgeInfoList.begin (); it != m_briteEdgeInfoList.end (); ++it) + { + // Set the link delay + // The brite value for delay is given in milliseconds + m_britePointToPointHelper.SetChannelAttribute ("Delay", + TimeValue (MilliSeconds ((*it).delay))); + + // The brite value for data rate is given in Mbps + m_britePointToPointHelper.SetDeviceAttribute ("DataRate", + DataRateValue (DataRate ((*it).bandwidth * mbpsToBps))); + + m_netDevices.push_back ( new NetDeviceContainer ( m_britePointToPointHelper.Install (m_nodes.Get ((*it).srcId), m_nodes.Get ((*it).destId)))); + + m_numEdges++; + + } + + NS_LOG_INFO ("Created " << m_numEdges << " edges in BRITE topology"); + + //iterate through all nodes and add leaf nodes for each AS + for (BriteTopologyHelper::BriteNodeInfoList::iterator it = m_briteNodeInfoList.begin (); it != m_briteNodeInfoList.end (); ++it) + { + m_nodesByAs[(*it).asId]->Add (m_nodes.Get ((*it).nodeId)); + + if ((*it).type == "RT_LEAF ") + { + m_asLeafNodes[(*it).asId]->Add (m_nodes.Get ((*it).nodeId)); + } + } +} + +} // namespace ns3 diff --git a/src/brite/helper/brite-topology-helper.h b/src/brite/helper/brite-topology-helper.h new file mode 100644 index 000000000..41e998c42 --- /dev/null +++ b/src/brite/helper/brite-topology-helper.h @@ -0,0 +1,298 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef BRITE_TOPOLOGY_HELPER_H +#define BRITE_TOPOLOGY_HELPER_H + +#include +#include + +#include "ns3/channel.h" +#include "ns3/node-container.h" +#include "ns3/node-list.h" +#include "ns3/point-to-point-helper.h" +#include "ns3/internet-stack-helper.h" +#include "ns3/ipv6-address-helper.h" +#include "ns3/random-variable-stream.h" + +//located in BRITE source directory +#include "Brite.h" + +namespace ns3 { + +/** + * \brief Interface with BRITE, the Boston university Representative Internet + * Topology gEnerator + * + * This helper class creates an interface with BRITE and allows the user to + * easily create ns-3 topologies from BRITE generated graphs. This class + * accepts a BRITE configuration and seed file, much like the stand-alone + * BRITE software. Using these files, BRITE generates a graph which is + * stored herein. ns-3 examples can then grab the BRITE generated nodes and + * edges from this helper and create ns-3 specific topologies. + * + */ + +class PointToPointHelper; + +class BriteTopologyHelper +{ +public: + /* + * Construct a BriteTopologyHelper + * + * \param confFile a BRITE configuration file + * \param seedFile a BRITE seed file + * \param newseedFile a BRITE seed file with newly generated values + */ + BriteTopologyHelper (std::string confFile, + std::string seedFile, + std::string newseedFile); + + /* + * Construct a BriteTopologyHelper using NS3 to generate seed values + * need by BRITE + * + */ + BriteTopologyHelper (std::string confFile); + + ~BriteTopologyHelper (); + + /* + * Assigns stream number to UniformRandomVariable used to + * generate brite seed file + * + * \param streamNumber the stream number to assign + * + */ + void AssignStreams (int64_t streamNumber); + + /* + * Create NS3 topology using information generated from BRITE. + * + * \param stack Internet stack to assign to nodes in topology + */ + void BuildBriteTopology (InternetStackHelper& stack); + + /* + * Create NS3 topology using information generated from BRITE and configure topology for MPI use. + * + * \param stack Internet stack to assign to nodes in topology. + * \param systemCount The number of MPI instances to be used in the simulation. + * + */ + void BuildBriteTopology (InternetStackHelper& stack, const uint32_t systemCount); + + /* + * Returns the number of router leaf nodes for a given AS + * + * \param asNum the AS number + * \returns the number of leaf nodes in the specified AS + * + */ + uint32_t GetNLeafNodesForAs (uint32_t asNum); + + /* + * Returns a given router leaf node from a given AS + * + * \param asNum the AS number + * \param leafNum the leaf number + * \returns the specified node + */ + Ptr GetLeafNodeForAs (uint32_t asNum, uint32_t leafNum); + + /* + * Returns the total number of nodes for a given AS + * + * \param asNum the AS number + * \returns the total number of nodes in the given AS + */ + uint32_t GetNNodesForAs (uint32_t asNum); + + /* + * Returns a given router node for a given AS + * + * \param asNum the AS number + * \return the specified node + * + */ + Ptr GetNodeForAs (uint32_t asNum, uint32_t nodeNum); + + /** + * Returns the number of AS created in the topology + * + * \returns the number of AS created in the topology + */ + uint32_t GetNAs (void) const; + + /** + * Returns the system number for the MPI instance that this AS is assigned to. Will always return 0 if MPI not used + * + * \returns The system number that the specified AS number belongs to + * + * param asNum The AS Number + */ + uint32_t GetSystemNumberForAs (uint32_t asNum) const; + + /** + * \param address an Ipv4AddressHelper which is used to install + * Ipv4 addresses on all the node interfaces in + * the topology + */ + void AssignIpv4Addresses (Ipv4AddressHelper& address); + + /** + * \param network an IPv6 address representing the network portion + * of the IPv6 Address + * \param prefix the prefix length + */ + void AssignIpv6Addresses (Ipv6AddressHelper& address); + + /** + * Returns the number of nodes created within + * the topology + * + * \returns the total number of nodes within the brite topology + */ + uint32_t GetNNodesTopology () const; + + /** + * Returns the number of edges created within + * the topology + * + * \returns the total number of edges within the brite topology + */ + uint32_t GetNEdgesTopology () const; + +private: + //brite values are unitless however all examples provided use mbps to specify rate + //this constant value is used to convert the mbps provided by brite to bps. + static const int mbpsToBps = 1000000; + + /** + * \brief Node information from BRITE + * + * The BRITE code generates a graph and returns + * information on the nodes generated. This is + * stored here in a struct. + */ + struct BriteNodeInfo + { + int nodeId; + double xCoordinate; + double yCoordinate; + int inDegree; + int outDegree; + int asId; + std::string type; + }; + + /** + * \brief Edge information from BRITE + * + * The BRITE code generates a graph and returns + * information on the edges generated. This is + * stored here in a struct. + */ + struct BriteEdgeInfo + { + int edgeId; + int srcId; + int destId; + double length; + double delay; + double bandwidth; + int asFrom; + int asTo; + std::string type; + }; + + //stores all of the nodes used in the BRITE generated topology + NodeContainer m_nodes; + + /** + * \internal + */ + void BuildBriteNodeInfoList (void); + + /** + * \internal + */ + void BuildBriteEdgeInfoList (void); + + /** + * \internal + */ + void ConstructTopology (void); + + /** + * \internal + */ + void GenerateBriteTopology (void); + + //brite configuration file to use + std::string m_confFile; + + //brite seed file to use + std::string m_seedFile; + + //brite seed file to generate for next run + std::string m_newSeedFile; + + //stores the number of AS in the BRITE generated topology + uint32_t m_numAs; + + //stores the netdevices created for each AS + std::vector m_netDevices; + + //stores the leaf router nodes for each AS + std::vector m_asLeafNodes; + + //stores all of the nodes in the brite topology by AS number + std::vector m_nodesByAs; + + //stores the MPI system number each AS assigned to. All assigned to 0 if MPI not used. + std::vector m_systemForAs; + + brite::Topology* m_topology; + + //stores the number of nodes created in the BRITE topology + uint32_t m_numNodes; + + //stores the number of edges created in the BRITE topology + uint32_t m_numEdges; + + /** + * The BRITE code generates multiple nodes and edges. Each + * node and edge is stored in a BriteNodeInfo or BriteEdgeInfo + * struct, and each instance is stored in a vector. + */ + typedef std::vector BriteNodeInfoList; + typedef std::vector BriteEdgeInfoList; + + BriteNodeInfoList m_briteNodeInfoList; + BriteEdgeInfoList m_briteEdgeInfoList; + + //used to create the links within the topology + PointToPointHelper m_britePointToPointHelper; + + Ptr m_uv; +}; + +} // namespace ns3 + +#endif /* BRITE_TOPOLOGY_HELPER_H */ diff --git a/src/brite/test/brite-test-topology.cc b/src/brite/test/brite-test-topology.cc new file mode 100644 index 000000000..969c961d3 --- /dev/null +++ b/src/brite/test/brite-test-topology.cc @@ -0,0 +1,200 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include "ns3/core-module.h" +#include "ns3/network-module.h" +#include "ns3/internet-module.h" +#include "ns3/point-to-point-module.h" +#include "ns3/packet-sink-helper.h" +#include "ns3/packet-sink.h" +#include "ns3/random-variable-stream.h" +#include "ns3/on-off-helper.h" +#include "ns3/brite-module.h" +#include "ns3/test.h" +#include +#include + +namespace ns3 { + +class BriteTopologyStructureTestCase : public TestCase +{ +public: + BriteTopologyStructureTestCase (); + virtual ~BriteTopologyStructureTestCase (); + +private: + virtual void DoRun (void); + +}; + +BriteTopologyStructureTestCase::BriteTopologyStructureTestCase () + : TestCase ("Test that two brite topologies created with same seed value produce same graph (not an exact test)") +{ +} + +BriteTopologyStructureTestCase::~BriteTopologyStructureTestCase () +{ +} + +void BriteTopologyStructureTestCase::DoRun (void) +{ + + std::string confFile = "src/brite/test/test.conf"; + + SeedManager::SetRun (1); + SeedManager::SetSeed (1); + BriteTopologyHelper bthA (confFile); + bthA.AssignStreams (1); + + SeedManager::SetRun (1); + SeedManager::SetSeed (1); + BriteTopologyHelper bthB (confFile); + bthB.AssignStreams (1); + + InternetStackHelper stack; + + bthA.BuildBriteTopology (stack); + bthB.BuildBriteTopology (stack); + + int numAsA = bthA.GetNAs (); + int numAsB = bthB.GetNAs (); + + //numAs should be 2 for the conf file in /src/brite/test/test.conf + NS_TEST_ASSERT_MSG_EQ (numAsA, 2, "Number of AS for this topology must be 2"); + NS_TEST_ASSERT_MSG_EQ (numAsA, numAsB, "Number of AS should be same for both test topologies"); + NS_TEST_ASSERT_MSG_EQ (bthA.GetNNodesTopology (), bthB.GetNNodesTopology (), "Total number of nodes for each topology should be equal"); + NS_TEST_ASSERT_MSG_EQ (bthA.GetNEdgesTopology (), bthB.GetNEdgesTopology (), "Total number of edges for each topology should be equal"); + + for (unsigned int i = 0; i < bthA.GetNAs (); ++i) + { + NS_TEST_ASSERT_MSG_EQ (bthA.GetNLeafNodesForAs (i), bthB.GetNLeafNodesForAs (i), "Total number of leaf nodes different for AS " << i); + } +} + +class BriteTopologyFunctionTestCase : public TestCase +{ +public: + BriteTopologyFunctionTestCase (); + virtual ~BriteTopologyFunctionTestCase (); + +private: + virtual void DoRun (void); + +}; + +BriteTopologyFunctionTestCase::BriteTopologyFunctionTestCase () + : TestCase ("Test that packets can be send across a BRITE topology using UDP") +{ +} + +BriteTopologyFunctionTestCase::~BriteTopologyFunctionTestCase () +{ +} + +void BriteTopologyFunctionTestCase::DoRun (void) +{ + + std::string confFile = "src/brite/test/test.conf"; + BriteTopologyHelper bth (confFile); + + PointToPointHelper p2p; + InternetStackHelper stack; + Ipv4AddressHelper address; + + address.SetBase ("10.0.0.0", "255.255.255.0"); + + bth.BuildBriteTopology (stack); + bth.AssignIpv4Addresses (address); + + NodeContainer source; + NodeContainer sink; + + source.Create (1); + stack.Install (source); + + //install source node on last leaf node of AS 0 + int numNodesInAsZero = bth.GetNNodesForAs (0); + source.Add (bth.GetNodeForAs (0, numNodesInAsZero - 1)); + + sink.Create (1); + stack.Install (sink); + + //install sink node on last leaf node on AS 1 + int numNodesInAsOne = bth.GetNNodesForAs (1); + sink.Add (bth.GetNodeForAs (1, numNodesInAsOne - 1)); + + p2p.SetDeviceAttribute ("DataRate", StringValue ("5Mbps")); + p2p.SetChannelAttribute ("Delay", StringValue ("2ms")); + + NetDeviceContainer p2pSourceDevices; + NetDeviceContainer p2pSinkDevices; + + p2pSourceDevices = p2p.Install (source); + p2pSinkDevices = p2p.Install (sink); + + address.SetBase ("10.1.0.0", "255.255.0.0"); + Ipv4InterfaceContainer sourceInterfaces; + sourceInterfaces = address.Assign (p2pSourceDevices); + + address.SetBase ("10.2.0.0", "255.255.0.0"); + Ipv4InterfaceContainer sinkInterfaces; + sinkInterfaces = address.Assign (p2pSinkDevices); + + uint16_t port = 9; + + OnOffHelper onOff ("ns3::UdpSocketFactory", + Address (InetSocketAddress (sinkInterfaces.GetAddress (0), port))); + onOff.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]")); + onOff.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]")); + onOff.SetAttribute ("DataRate", DataRateValue (DataRate (6000))); + + ApplicationContainer apps = onOff.Install (source.Get (0)); + + apps.Start (Seconds (1.0)); + apps.Stop (Seconds (10.0)); + + PacketSinkHelper sinkHelper ("ns3::UdpSocketFactory", + Address (InetSocketAddress (Ipv4Address::GetAny (), port))); + apps = sinkHelper.Install (sink.Get (0)); + + apps.Start (Seconds (1.0)); + apps.Stop (Seconds (10.0)); + + Ipv4GlobalRoutingHelper::PopulateRoutingTables (); + + Simulator::Stop (Seconds (10.0)); + Simulator::Run (); + + Ptr sink1 = DynamicCast (apps.Get (0)); + //NS_TEST_ASSERT_MSG_EQ (sink1->GetTotalRx (), 6656, "Not all packets received from source"); + + Simulator::Destroy (); + +} + +class BriteTestSuite : public TestSuite +{ +public: + BriteTestSuite () : TestSuite ("brite-testing", UNIT) + { + AddTestCase (new BriteTopologyStructureTestCase); + AddTestCase (new BriteTopologyFunctionTestCase); + } +} g_briteTestSuite; + +} // namespace ns3 diff --git a/src/brite/test/examples-to-run.py b/src/brite/test/examples-to-run.py new file mode 100644 index 000000000..7dee389cf --- /dev/null +++ b/src/brite/test/examples-to-run.py @@ -0,0 +1,20 @@ +#! /usr/bin/env python +## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- + +# A list of C++ examples to run in order to ensure that they remain +# buildable and runnable over time. Each tuple in the list contains +# +# (example_name, do_run, do_valgrind_run). +# +# See test.py for more information. +cpp_examples = [ + ("brite-generic-example", "ENABLE_BRITE == True", "False"), +] + +# A list of Python examples to run in order to ensure that they remain +# runnable over time. Each tuple in the list contains +# +# (example_name, do_run). +# +# See test.py for more information. +python_examples = [] diff --git a/src/brite/test/test.conf b/src/brite/test/test.conf new file mode 100644 index 000000000..4ea8d3266 --- /dev/null +++ b/src/brite/test/test.conf @@ -0,0 +1,50 @@ +#This config file was generated by the GUI. + +BriteConfig + + + +BeginModel + Name = 5 #Top Down = 5 + edgeConn = 2 #Random=1, Smallest Nonleaf = 2, Smallest Deg = 3, k-Degree=4 + k = -1 #Only needed if edgeConn is set to K-Degree, otherwise use -1 + BWInter = 1 #Constant = 1, Uniform =2, HeavyTailed = 3, Exponential =4 + BWInterMin = 10.0 + BWInterMax = 1024.0 + BWIntra = 3 #Constant = 1, Uniform =2, HeavyTailed = 3, Exponential =4 + BWIntraMin = 10.0 + BWIntraMax = 1024.0 +EndModel + +BeginModel + Name = 4 #Router Barabasi=2, AS Barabasi =4 + N = 2 #Number of nodes in graph + HS = 1000 #Size of main plane (number of squares) + LS = 100 #Size of inner planes (number of squares) + NodePlacement = 1 #Random = 1, Heavy Tailed = 2 + m = 1 #Number of neighboring node each new node connects to. + BWDist = 1 #Constant = 1, Uniform =2, HeavyTailed = 3, Exponential =4 + BWMin = -1.0 + BWMax = -1.0 +EndModel + +BeginModel + Name = 1 #Router Waxman=2, AS Waxman =3 + N = 5 #Number of nodes in graph + HS = 1000 #Size of main plane (number of squares) + LS = 100 #Size of inner planes (number of squares) + NodePlacement = 2 #Random = 1, Heavy Tailed = 2 + GrowthType = 1 #Incremental = 1, All = 2 + m = 1 #Number of neighboring node each new node connects to. + alpha = 0.5 #Waxman Parameter + beta = 0.8 #Waxman Parameter + BWDist = 1 #Constant = 1, Uniform =2, HeavyTailed = 3, Exponential =4 + BWMin = -1.0 + BWMax = -1.0 +EndModel + +BeginOutput #**Atleast one of these options should have value 1** + BRITE = 1 #0 = Do not save as BRITE, 1 = save as BRITE. + OTTER = 0 #0 = Do not visualize with Otter, 1 = Visualize +EndOutput + diff --git a/src/brite/wscript b/src/brite/wscript new file mode 100644 index 000000000..ab50ac853 --- /dev/null +++ b/src/brite/wscript @@ -0,0 +1,91 @@ +## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- +import os +import Options + + +def options(opt): + opt.add_option('--with-brite', + help=('Use BRITE integration support, given by the indicated path,' + ' to allow the use of the BRITE topology generator'), + default=False, dest='with_brite') + +def configure(conf): + conf.env['ENABLE_BRITE'] = False + + if Options.options.with_brite: + if os.path.isdir(Options.options.with_brite): + conf.msg("Checking BRITE location", ("%s (given)" % Options.options.with_brite)) + conf.env['WITH_BRITE'] = os.path.abspath(Options.options.with_brite) + else: + brite_dir = os.path.join('..','BRITE') + if os.path.isdir(brite_dir): + conf.msg("Checking for BRITE location", ("%s (guessed)" % brite_dir)) + conf.env['WITH_BRITE'] = os.path.abspath(brite_dir) + del brite_dir + if not conf.env['WITH_BRITE']: + conf.msg("Checking for BRITE location", False) + conf.report_optional_feature("brite", "BRITE Integration", False, + "BRITE not found (see option --with-brite)") + return + else: + conf.report_optional_feature("brite", "BRITE Integration", False, 'BRITE not enabled (see option --with-brite)') + return + + test_code = ''' +#include "Brite.h" + +int main() +{ + return 0; +} +''' + + conf.env['DL'] = conf.check(mandatory=True, lib='dl', define_name='DL', uselib='DL') + + conf.env.append_value('NS3_MODULE_PATH',os.path.abspath(os.path.join(conf.env['WITH_BRITE'], '.'))) + + conf.env['INCLUDES_BRITE'] = os.path.abspath(os.path.join(conf.env['WITH_BRITE'],'.')) + + conf.env['CPPPATH_BRITE'] = [ + os.path.abspath(os.path.join(conf.env['WITH_BRITE'],'.')), + os.path.abspath(os.path.join(conf.env['WITH_BRITE'],'Models')) + ] + conf.env['LIBPATH_BRITE'] = [os.path.abspath(os.path.join(conf.env['WITH_BRITE'], '.'))] + + conf.env.append_value('CXXDEFINES', 'NS3_BRITE') + conf.env.append_value('CPPPATH', conf.env['CPPPATH_BRITE']) + + conf.env['BRITE'] = conf.check(fragment=test_code, lib='brite', libpath=conf.env['LIBPATH_BRITE'], use='BRITE DL') + conf.report_optional_feature("brite", "BRITE Integration", + conf.env['BRITE'], "BRITE library not found") + + if conf.env['BRITE']: + conf.env['ENABLE_BRITE'] = True + conf.env.append_value('CXXDEFINES', 'NS3_BRITE') + conf.env.append_value('CPPPATH', conf.env['CPPPATH_BRITE']) + +def build(bld): + + module = bld.create_ns3_module('brite', ['network', 'core', 'internet', 'point-to-point']) + module.source = [ + ] + + module_test = bld.create_ns3_module_test_library('brite') + module_test.source = [ + ] + + if bld.env['BRITE'] and bld.env['DL']: + module.uselib = 'BRITE DL' + + headers = bld.new_task_gen(features=['ns3header']) + headers.module = 'brite' + headers.source = [ + ] + + if bld.env['ENABLE_BRITE']: + module.source.append ('helper/brite-topology-helper.cc') + headers.source.append ('helper/brite-topology-helper.h') + module_test.source.append('test/brite-test-topology.cc') + + if bld.env['ENABLE_EXAMPLES'] and bld.env['ENABLE_BRITE']: + bld.add_subdirs('examples') diff --git a/test.py b/test.py index 51209c234..55dbfd89e 100755 --- a/test.py +++ b/test.py @@ -52,6 +52,7 @@ interesting_config_items = [ "EXAMPLE_DIRECTORIES", "ENABLE_PYTHON_BINDINGS", "ENABLE_CLICK", + "ENABLE_BRITE", "ENABLE_OPENFLOW", "APPNAME", "BUILD_PROFILE", @@ -65,6 +66,7 @@ ENABLE_THREADING = False ENABLE_EXAMPLES = True ENABLE_TESTS = True ENABLE_CLICK = False +ENABLE_BRITE = False ENABLE_OPENFLOW = False EXAMPLE_DIRECTORIES = [] APPNAME = ""