Just as a reference posting my code which is a modification of the
given openflow example.. it works fine with two controllers but fails
with single controller
#include <iostream>
#include <fstream>
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"
#include "ns3/applications-module.h"
#include "ns3/openflow-module.h"
#include "ns3/log.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("OpenFlowCsmaSwitchExample");
bool verbose = false;
bool use_drop = false;
ns3::Time timeout = ns3::Seconds (0);
bool
SetVerbose (std::string value)
{
verbose = true;
return true;
}
bool
SetDrop (std::string value)
{
use_drop = true;
return true;
}
bool
SetTimeout (std::string value)
{
try {
timeout = ns3::Seconds (atof (value.c_str ()));
return true;
}
catch (...) { return false; }
return false;
}
int
main (int argc, char *argv[])
{
#ifdef NS3_OPENFLOW
//
// Allow the user to override any of the defaults and the above
Bind() at
// run-time, via command-line arguments
//
CommandLine cmd;
cmd.AddValue ("v", "Verbose (turns on logging).", MakeCallback
(&SetVerbose));
cmd.AddValue ("verbose", "Verbose (turns on logging).", MakeCallback
(&SetVerbose));
cmd.AddValue ("d", "Use Drop Controller (Learning if not
specified).", MakeCallback (&SetDrop));
cmd.AddValue ("drop", "Use Drop Controller (Learning if not
specified).", MakeCallback (&SetDrop));
cmd.AddValue ("t", "Learning Controller Timeout (has no effect if
drop controller is specified).", MakeCallback ( &SetTimeout));
cmd.AddValue ("timeout", "Learning Controller Timeout (has no effect
if drop controller is specified).", MakeCallback ( &SetTimeout));
cmd.Parse (argc, argv);
if (verbose)
{
LogComponentEnable ("OpenFlowCsmaSwitchExample",
LOG_LEVEL_INFO);
LogComponentEnable ("OpenFlowInterface", LOG_LEVEL_INFO);
LogComponentEnable ("OpenFlowSwitchNetDevice", LOG_LEVEL_INFO);
}
//
// Explicitly create the nodes required by the topology (shown
above).
//
NS_LOG_INFO ("Create nodes.");
NodeContainer terminals;
terminals.Create (2);
NodeContainer csmaSwitch;
csmaSwitch.Create (2);
NS_LOG_INFO ("Build Topology");
CsmaHelper csma;
csma.SetChannelAttribute ("DataRate", DataRateValue (5000000));
csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
// Create the csma links, from each terminal to the switch
NetDeviceContainer terminalDevicesTp,terminalDevicesBt;
NetDeviceContainer switchDevicesTp,switchDevicesBt;
NetDeviceContainer link = csma.Install (NodeContainer (terminals.Get
(0), csmaSwitch.Get (0)));
terminalDevicesTp.Add (link.Get (0));
switchDevicesTp.Add (link.Get (1));
NetDeviceContainer link1 = csma.Install (NodeContainer
(terminals.Get (1), csmaSwitch.Get (1)));
terminalDevicesBt.Add (link1.Get (0));
switchDevicesBt.Add (link1.Get (1));
NetDeviceContainer link2 = csma.Install (NodeContainer
(csmaSwitch.Get (0), csmaSwitch.Get (1)));
switchDevicesTp.Add (link2.Get (0));
switchDevicesBt.Add (link2.Get (1));
// Create the switch netdevice, which will do the packet switching
Ptr<Node> switchNode1 = csmaSwitch.Get (0);
Ptr<Node> switchNode2 = csmaSwitch.Get (1);
OpenFlowSwitchHelper swtch;
Ptr<ns3::ofi::LearningController> controller1 =
CreateObject<ns3::ofi::LearningController> ();
if (!timeout.IsZero ()) controller1->SetAttribute ("ExpirationTime",
TimeValue (timeout));
swtch.Install (switchNode1, switchDevicesTp, controller1);
swtch.Install (switchNode2, switchDevicesBt, controller1);
//Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
// Add internet stack to the terminals
InternetStackHelper internet;
internet.Install (terminals);
// We've got the "hardware" in place. Now we need to add IP
addresses.
NS_LOG_INFO ("Assign IP Addresses.");
Ipv4AddressHelper ipv4;
ipv4.SetBase ("10.1.1.0", "255.255.255.0");
ipv4.Assign (terminalDevicesTp);
ipv4.Assign (terminalDevicesBt);
// Create an OnOff application to send UDP datagrams from n0 to n1.
NS_LOG_INFO ("Create Applications.");
uint16_t port = 9; // Discard port (RFC 863)
OnOffHelper onoff ("ns3::UdpSocketFactory",
Address (InetSocketAddress (Ipv4Address
("10.1.1.2"), port)));
onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable
(1)));
onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable
(0)));
ApplicationContainer app = onoff.Install (terminals.Get (0));
// Start the application
app.Start (Seconds (1.0));
app.Stop (Seconds (1.1));
// Create an optional packet sink to receive these packets
PacketSinkHelper sink ("ns3::UdpSocketFactory",
Address (InetSocketAddress
(Ipv4Address::GetAny (), port)));
app = sink.Install (terminals.Get (1));
app.Start (Seconds (0.0));
//
// Configure tracing of all enqueue, dequeue, and NetDevice receive
events.
// Trace output will be sent to the file "
openflow-switch.tr"
//
AsciiTraceHelper ascii;
csma.EnableAsciiAll (ascii.CreateFileStream ("
openflow-switch.tr"));
//
// Also configure some tcpdump traces; each interface will be
traced.
// The output files will be named:
// openflow-switch-<nodeId>-<interfaceId>.pcap
// and can be read by the "tcpdump -r" command (use "-tt" option to
// display timestamps correctly)
//
csma.EnablePcapAll ("openflow-switch", false);
//
// Now, do the actual simulation.
//
NS_LOG_INFO ("Run Simulation.");
Simulator::Run ();
Simulator::Destroy ();
NS_LOG_INFO ("Done.");
#else
NS_LOG_INFO ("NS-3 OpenFlow is not enabled. Cannot run
simulation.");
#endif // NS3_OPENFLOW