A Discrete-Event Network Simulator
API
ofswitch13-helper.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 University of Campinas (Unicamp)
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Luciano Jerez Chaves <ljerezchaves@gmail.com>
18  */
19 
20 #ifdef NS3_OFSWITCH13
21 
22 #include "ofswitch13-helper.h"
23 
25 
26 #include <ns3/ofswitch13-port.h>
27 
28 namespace ns3
29 {
30 
31 NS_LOG_COMPONENT_DEFINE("OFSwitch13Helper");
32 NS_OBJECT_ENSURE_REGISTERED(OFSwitch13Helper);
33 
34 Ipv4AddressHelper OFSwitch13Helper::m_ipv4helper =
35  Ipv4AddressHelper("10.100.0.0", "255.255.255.0");
36 
37 class OFSwitch13Controller;
38 
40  : m_blocked(false)
41 {
42  NS_LOG_FUNCTION(this);
43 
44  // Set OpenFlow device factory TypeId.
45  m_devFactory.SetTypeId("ns3::OFSwitch13Device");
46 }
47 
48 OFSwitch13Helper::~OFSwitch13Helper()
49 {
50  NS_LOG_FUNCTION(this);
51 }
52 
53 TypeId
54 OFSwitch13Helper::GetTypeId()
55 {
56  static TypeId tid =
57  TypeId("ns3::OFSwitch13Helper")
58  .SetParent<Object>()
59  .SetGroupName("OFSwitch13")
60  .AddAttribute(
61  "ChannelDataRate",
62  "The data rate to be used for the OpenFlow channel.",
63  DataRateValue(DataRate("10Gb/s")),
64  MakeDataRateAccessor(&OFSwitch13Helper::SetChannelDataRate),
65  MakeDataRateChecker())
66  .AddAttribute(
67  "ChannelType",
68  "The configuration used to create the OpenFlow channel",
69  TypeId::ATTR_GET | TypeId::ATTR_CONSTRUCT,
70  EnumValue(OFSwitch13Helper::SINGLECSMA),
71  MakeEnumAccessor(&OFSwitch13Helper::SetChannelType),
72  MakeEnumChecker(OFSwitch13Helper::SINGLECSMA,
73  "SingleCsma",
74  OFSwitch13Helper::DEDICATEDCSMA,
75  "DedicatedCsma",
76  OFSwitch13Helper::DEDICATEDP2P,
77  "DedicatedP2p"));
78  return tid;
79 }
80 
81 void
82 OFSwitch13Helper::SetDeviceAttribute(std::string n1, const AttributeValue& v1)
83 {
84  NS_LOG_FUNCTION(this);
85 
86  m_devFactory.Set(n1, v1);
87 }
88 
89 void
90 OFSwitch13Helper::SetChannelType(ChannelType type)
91 {
92  NS_LOG_FUNCTION(this << type);
93 
94  // Set the channel type and address, which will select proper netowrk mask.
95  m_channelType = type;
96 }
97 
98 void
99 OFSwitch13Helper::SetChannelDataRate(DataRate rate)
100 {
101  NS_LOG_FUNCTION(this << rate);
102 
103  m_channelDataRate = rate;
104 }
105 
106 void
107 OFSwitch13Helper::EnableOpenFlowPcap(std::string prefix, bool promiscuous)
108 {
109  NS_LOG_FUNCTION(this << prefix);
110 
111  NS_ABORT_MSG_IF(!m_blocked, "OpenFlow channels not configured yet.");
112  switch (m_channelType)
113  {
114  case OFSwitch13Helper::SINGLECSMA:
115  case OFSwitch13Helper::DEDICATEDCSMA: {
116  m_csmaHelper.EnablePcap(prefix, m_controlDevs, promiscuous);
117  break;
118  }
119  case OFSwitch13Helper::DEDICATEDP2P: {
120  m_p2pHelper.EnablePcap(prefix, m_controlDevs, promiscuous);
121  break;
122  }
123  default: {
124  NS_ABORT_MSG("Invalid OpenflowChannelType.");
125  }
126  }
127 }
128 
129 void
130 OFSwitch13Helper::EnableOpenFlowAscii(std::string prefix)
131 {
132  NS_LOG_FUNCTION(this << prefix);
133 
134  NS_ABORT_MSG_IF(!m_blocked, "OpenFlow channels not configured yet.");
135  AsciiTraceHelper ascii;
136  switch (m_channelType)
137  {
138  case OFSwitch13Helper::SINGLECSMA:
139  case OFSwitch13Helper::DEDICATEDCSMA: {
140  m_csmaHelper.EnableAsciiAll(ascii.CreateFileStream(prefix + ".txt"));
141  break;
142  }
143  case OFSwitch13Helper::DEDICATEDP2P: {
144  m_p2pHelper.EnableAsciiAll(ascii.CreateFileStream(prefix + ".txt"));
145  break;
146  }
147  default: {
148  NS_ABORT_MSG("Invalid OpenflowChannelType.");
149  }
150  }
151 }
152 
153 void
154 OFSwitch13Helper::EnableDatapathStats(std::string prefix, bool useNodeNames)
155 {
156  NS_LOG_FUNCTION(this << prefix);
157 
158  NS_ABORT_MSG_IF(!m_blocked, "OpenFlow channels not configured yet.");
159  NS_ASSERT_MSG(prefix.size(), "Empty prefix string.");
160  if (prefix.back() != '-')
161  {
162  prefix += "-";
163  }
164 
165  ObjectFactory statsFactory("ns3::OFSwitch13StatsCalculator");
166  Ptr<OFSwitch13StatsCalculator> statsCalculator;
167  const std::string extension = ".log";
168 
169  // Iterate over the container and for each OpenFlow devices create a stats
170  // calculator to monitor datapath statistcs.
171  OFSwitch13DeviceContainer::Iterator it;
172  for (it = m_openFlowDevs.Begin(); it != m_openFlowDevs.End(); it++)
173  {
174  Ptr<OFSwitch13Device> dev = *it;
175  std::string filename = prefix;
176  std::string nodename;
177 
178  if (useNodeNames)
179  {
180  Ptr<Node> node = dev->GetObject<Node>();
181  nodename = Names::FindName(node);
182  }
183  if (nodename.size())
184  {
185  filename += nodename;
186  }
187  else
188  {
189  filename += std::to_string(dev->GetDatapathId());
190  }
191  filename += extension;
192 
193  statsFactory.Set("OutputFilename", StringValue(filename));
194  statsCalculator = statsFactory.Create<OFSwitch13StatsCalculator>();
195  statsCalculator->AggregateObject(dev);
196  statsCalculator->HookSinks(dev);
197  }
198 }
199 
200 Ptr<OFSwitch13Device>
201 OFSwitch13Helper::InstallSwitch(Ptr<Node> swNode, NetDeviceContainer& swPorts)
202 {
203  NS_LOG_FUNCTION(this << swNode);
204 
205  // Install the OpenFlow device into switch node.
206  Ptr<OFSwitch13Device> openFlowDev = InstallSwitch(swNode);
207 
208  // Add switch ports.
209  NetDeviceContainer::Iterator it;
210  for (it = swPorts.Begin(); it != swPorts.End(); it++)
211  {
212  NS_LOG_INFO(" Adding switch port " << *it);
213  openFlowDev->AddSwitchPort(*it);
214  }
215 
216  return openFlowDev;
217 }
218 
219 Ptr<OFSwitch13Device>
220 OFSwitch13Helper::InstallSwitch(Ptr<Node> swNode)
221 {
222  NS_LOG_FUNCTION(this << swNode);
223 
224  NS_LOG_INFO("Installing OpenFlow device on node " << swNode->GetId());
225  NS_ABORT_MSG_IF(m_blocked, "OpenFlow channels already configured.");
226 
227  // Install the TCP/IP stack into switch node.
228  if (!swNode->GetObject<Ipv4>())
229  {
230  m_internet.Install(swNode);
231  }
232 
233  // Create and aggregate the OpenFlow device to the switch node.
234  Ptr<OFSwitch13Device> openFlowDev = m_devFactory.Create<OFSwitch13Device>();
235  swNode->AggregateObject(openFlowDev);
236  m_openFlowDevs.Add(openFlowDev);
237  m_switchNodes.Add(swNode);
238 
239  return openFlowDev;
240 }
241 
242 OFSwitch13DeviceContainer
243 OFSwitch13Helper::InstallSwitch(NodeContainer& swNodes)
244 {
245  NS_LOG_FUNCTION(this);
246 
247  // Iterate over the container and add OpenFlow devices to switch nodes.
248  OFSwitch13DeviceContainer openFlowDevices;
249  NodeContainer::Iterator it;
250  for (it = swNodes.Begin(); it != swNodes.End(); it++)
251  {
252  openFlowDevices.Add(InstallSwitch(*it));
253  }
254 
255  return openFlowDevices;
256 }
257 
258 void
259 OFSwitch13Helper::SetAddressBase(Ipv4Address network,
260  Ipv4Mask mask,
261  Ipv4Address base)
262 {
264 
265  m_ipv4helper.SetBase(network, mask, base);
266 }
267 
268 void
269 OFSwitch13Helper::EnableDatapathLogs(std::string prefix, bool explicitFilename)
270 {
272 
273  // Saving library logs into output file.
274  EnableBofussLog(true, prefix, explicitFilename);
275 }
276 
277 void
278 OFSwitch13Helper::DoDispose()
279 {
280  NS_LOG_FUNCTION(this);
281 }
282 
283 } // namespace ns3
284 #endif // NS3_OFSWITCH13
AttributeValue implementation for DataRate.
static Ipv4AddressHelper m_ipv4helper
Helper for IP address.
OFSwitch13Helper()
Default constructor.
#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
Ptr< const AttributeAccessor > MakeEnumAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: enum.h:205
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#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
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
void EnableBofussLog(bool printToFile, std::string prefix, bool explicitFilename, std::string customLevels)
Enable the logging system of the BOFUSS library.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeEnumChecker(int v, std::string n, Ts... args)
Make an EnumChecker pre-configured with a set of allowed values by name.
Definition: enum.h:163