A Discrete-Event Network Simulator
API
ofswitch13-external-controller.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 University of Campinas (Unicamp)
3  * 2020 Federal University of Juiz de Fora (UFJF)
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Luciano Jerez Chaves <ljerezchaves@gmail.com>
19  * Arthur Boechat Mazzi <arthurmazzi@ice.ufjf.br>
20  */
21 
22 /*
23  * There are N switches connected in line and managed by an external controller.
24  * There are M hosts equally distributed among the switches.
25  * Random pings among hosts.
26  *
27  * External controller
28  * |
29  * +----------------+-------- ... --------+
30  * | | |
31  * +----------+ +----------+ +----------+
32  * | Switch 1 | === | Switch 2 | == ... == | Switch N |
33  * +----------+ +----------+ +----------+
34  * || || ||
35  * Hosts Hosts Hosts
36  * 1, N+1, ... 2, N+2, ... N, 2N, ...
37  */
38 
39 #include <ns3/core-module.h>
40 #include <ns3/csma-module.h>
41 #include <ns3/internet-apps-module.h>
42 #include <ns3/internet-module.h>
43 #include <ns3/network-module.h>
44 #include <ns3/ofswitch13-module.h>
45 #include <ns3/tap-bridge-module.h>
46 
47 using namespace ns3;
48 
49 int
50 main(int argc, char* argv[])
51 {
52  uint16_t simTime = 100;
53  bool verbose = false;
54  bool trace = false;
55  uint16_t numHosts = 20;
56  uint16_t numSwitches = 3;
57  uint16_t numPings = 20;
58  uint16_t pingTime = 10;
59 
60  // Configure command line parameters
62  cmd.AddValue("simTime", "Simulation time (seconds)", simTime);
63  cmd.AddValue("verbose", "Enable verbose output", verbose);
64  cmd.AddValue("trace", "Enable datapath stats and pcap traces", trace);
65  cmd.AddValue("numHosts", "Number of hosts in the simulation", numHosts);
66  cmd.AddValue("numSwitches", "Number of switches in the simulation", numSwitches);
67  cmd.AddValue("numPings", "Number of ping apps int the simulation", numPings);
68  cmd.AddValue("pingTime", "Ping time (seconds)", pingTime);
69  cmd.Parse(argc, argv);
70 
71  if (verbose)
72  {
74  LogComponentEnable("OFSwitch13Interface", LOG_LEVEL_ALL);
75  LogComponentEnable("OFSwitch13Device", LOG_LEVEL_ALL);
76  LogComponentEnable("OFSwitch13Port", LOG_LEVEL_ALL);
77  LogComponentEnable("OFSwitch13Queue", LOG_LEVEL_ALL);
78  LogComponentEnable("OFSwitch13SocketHandler", LOG_LEVEL_ALL);
79  LogComponentEnable("OFSwitch13Controller", LOG_LEVEL_ALL);
80  LogComponentEnable("OFSwitch13LearningController", LOG_LEVEL_ALL);
81  LogComponentEnable("OFSwitch13Helper", LOG_LEVEL_ALL);
82  LogComponentEnable("OFSwitch13InternalHelper", LOG_LEVEL_ALL);
83  }
84 
85  // Enable checksum computations (required by OFSwitch13 module)
86  GlobalValue::Bind("ChecksumEnabled", BooleanValue(true));
87 
88  // Set simulator to real time mode
89  GlobalValue::Bind("SimulatorImplementationType", StringValue("ns3::RealtimeSimulatorImpl"));
90 
91  // Create host nodes
92  NodeContainer hosts;
93  hosts.Create(numHosts);
94 
95  // Create switch nodes
96  NodeContainer switches;
97  switches.Create(numSwitches);
98 
99  // Use the CsmaHelper to connect host and switch
100  CsmaHelper csmaHelper;
101  csmaHelper.SetChannelAttribute("DataRate", DataRateValue(DataRate("100Mbps")));
102  csmaHelper.SetChannelAttribute("Delay", TimeValue(MilliSeconds(2)));
103 
104  NodeContainer pair;
105  NetDeviceContainer pairDevs;
106  NetDeviceContainer hostDevices;
107  NetDeviceContainer switchPorts[numSwitches];
108  for (int i = 0; i < numSwitches; i++)
109  {
110  switchPorts[i] = NetDeviceContainer();
111  }
112 
113  // Connect hosts to switches in round robin
114  for (size_t i = 0; i < numHosts; i++)
115  {
116  int j = i % numSwitches;
117  pair = NodeContainer(hosts.Get(i), switches.Get(j));
118  pairDevs = csmaHelper.Install(pair);
119  hostDevices.Add(pairDevs.Get(0));
120  switchPorts[j].Add(pairDevs.Get(1));
121  }
122 
123  // Connect the switches in chain
124  for (int i = 0; i < numSwitches - 1; i++)
125  {
126  pair = NodeContainer(switches.Get(i), switches.Get(i + 1));
127  pairDevs = csmaHelper.Install(pair);
128  switchPorts[i].Add(pairDevs.Get(0));
129  switchPorts[i + 1].Add(pairDevs.Get(1));
130  }
131 
132  // Create the controller node
133  Ptr<Node> controllerNode = CreateObject<Node>();
134 
135  // Configure the OpenFlow network domain using an external controller
136  Ptr<OFSwitch13ExternalHelper> of13Helper = CreateObject<OFSwitch13ExternalHelper>();
137  Ptr<NetDevice> ctrlDev = of13Helper->InstallExternalController(controllerNode);
138  for (int i = 0; i < numSwitches; i++)
139  {
140  of13Helper->InstallSwitch(switches.Get(i), switchPorts[i]);
141  }
142  of13Helper->CreateOpenFlowChannels();
143 
144  // TapBridge the controller device to local machine
145  // The default configuration expects a controller on local port 6653
146  TapBridgeHelper tapBridge;
147  tapBridge.SetAttribute("Mode", StringValue("ConfigureLocal"));
148  tapBridge.SetAttribute("DeviceName", StringValue("ctrl"));
149  tapBridge.Install(controllerNode, ctrlDev);
150 
151  // Install the TCP/IP stack into hosts nodes
152  InternetStackHelper internet;
153  internet.Install(hosts);
154 
155  // Set IPv4 host addresses
156  Ipv4AddressHelper ipv4helpr;
157  Ipv4InterfaceContainer hostIpIfaces;
158  ipv4helpr.SetBase("10.1.1.0", "255.255.255.0");
159  hostIpIfaces = ipv4helpr.Assign(hostDevices);
160 
161  // Random number generators for ping applications
162  Ptr<UniformRandomVariable> randomHostRng = CreateObject<UniformRandomVariable>();
163  randomHostRng->SetAttribute("Min", DoubleValue(0));
164  randomHostRng->SetAttribute("Max", DoubleValue(numHosts - 1));
165 
166  Ptr<ExponentialRandomVariable> randomStartRng = CreateObject<ExponentialRandomVariable>();
167  randomStartRng->SetAttribute("Mean", DoubleValue(20));
168 
169  // Configure ping application between random hosts
170  Time startTime = Seconds(1);
171  for (int i = 0; i < numPings; i++)
172  {
173  int srcHost = randomHostRng->GetInteger();
174  int dstHost = randomHostRng->GetInteger();
175 
176  PingHelper pingHelper(Ipv4Address(hostIpIfaces.GetAddress(dstHost)));
177  pingHelper.SetAttribute("VerboseMode", EnumValue(Ping::VerboseMode::VERBOSE));
178  Ptr<Application> pingApp = pingHelper.Install(hosts.Get(srcHost)).Get(0);
179 
180  startTime += Seconds(std::abs(randomStartRng->GetValue()));
181  pingApp->SetStartTime(startTime);
182  pingApp->SetStopTime(startTime + Seconds(pingTime));
183  }
184 
185  // Enable datapath stats and pcap traces at hosts, switch(es), and controller(s)
186  if (trace)
187  {
188  of13Helper->EnableOpenFlowPcap("openflow");
189  of13Helper->EnableDatapathStats("switch-stats");
190  csmaHelper.EnablePcap("host", hostDevices);
191  for (int i = 0; i < numSwitches; i++)
192  {
193  csmaHelper.EnablePcap("switch", switchPorts[i], true);
194  }
195  }
196 
197  // Run the simulation
198  Simulator::Stop(Seconds(simTime));
199  Simulator::Run();
201 }
void SetStopTime(Time stop)
Specify application stop time.
Definition: application.cc:78
void SetStartTime(Time start)
Specify application start time.
Definition: application.cc:71
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Parse command-line arguments.
Definition: command-line.h:232
build a set of CsmaNetDevice objects
Definition: csma-helper.h:48
void SetChannelAttribute(std::string n1, const AttributeValue &v1)
Definition: csma-helper.cc:56
NetDeviceContainer Install(Ptr< Node > node) const
This method creates an ns3::CsmaChannel with the attributes configured by CsmaHelper::SetChannelAttri...
Definition: csma-helper.cc:226
AttributeValue implementation for DataRate.
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
Hold variables of type enum.
Definition: enum.h:56
double GetValue(double mean, double bound)
Get the next random value drawn from the distribution.
static void Bind(std::string name, const AttributeValue &value)
Iterate over the set of GlobalValues until a matching name is found and then set its value with Globa...
aggregate IP/TCP/UDP functionality to existing Nodes.
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:43
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
holds a vector of ns3::NetDevice pointers
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
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.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
static void EnableDatapathLogs(std::string prefix="", bool explicitFilename=false)
Enable OpenFlow datapath logs at all OpenFlow switch devices on the simulation.
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:200
void EnablePcap(std::string prefix, Ptr< NetDevice > nd, bool promiscuous=false, bool explicitFilename=false)
Enable pcap output the indicated net device.
Create a ping application and associate it to a node.
Definition: ping-helper.h:48
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:140
static void Run()
Run the simulation.
Definition: simulator.cc:176
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:184
Hold variables of type string.
Definition: string.h:56
build TapBridge to allow ns-3 simulations to interact with Linux tap devices and processes on the Lin...
Ptr< NetDevice > Install(Ptr< Node > node, Ptr< NetDevice > nd)
This method installs a TapBridge on the specified Node and forms the bridge with the NetDevice specif...
void SetAttribute(std::string n1, const AttributeValue &v1)
Set an attribute in the underlying TapBridge net device when these devices are automatically created.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
AttributeValue implementation for Time.
Definition: nstime.h:1423
uint32_t GetInteger(uint32_t min, uint32_t max)
Get the next random value drawn from the distribution.
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:1336
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1348
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void LogComponentEnable(const std::string &name, LogLevel level)
Enable the logging output associated with that log component.
Definition: log.cc:305
@ LOG_LEVEL_ALL
Print everything.
Definition: log.h:116
cmd
Definition: second.py:33
bool verbose