OLD | NEW |
(Empty) | |
| 1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
| 2 /* |
| 3 * This program is free software; you can redistribute it and/or modify |
| 4 * it under the terms of the GNU General Public License version 2 as |
| 5 * published by the Free Software Foundation; |
| 6 * |
| 7 * This program is distributed in the hope that it will be useful, |
| 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 10 * GNU General Public License for more details. |
| 11 * |
| 12 * You should have received a copy of the GNU General Public License |
| 13 * along with this program; if not, write to the Free Software |
| 14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 15 */ |
| 16 |
| 17 // Network topology |
| 18 // |
| 19 // n0 n1 |
| 20 // | | |
| 21 // ---------- |
| 22 // | Switch | |
| 23 // ---------- |
| 24 // | | |
| 25 // n2 n3 |
| 26 // |
| 27 // |
| 28 // - CBR/UDP flows from n0 to n1 and from n3 to n0 |
| 29 // - DropTail queues |
| 30 // - Tracing of queues and packet receptions to file "openflow-switch.tr" |
| 31 // - If order of adding nodes and netdevices is kept: |
| 32 // n0 = 00:00:00;00:00:01, n1 = 00:00:00:00:00:03, n3 = 00:00:00:00:00:07 |
| 33 // and port number corresponds to node number, so port 0 is connected to n0
, for example. |
| 34 |
| 35 #include <iostream> |
| 36 #include <fstream> |
| 37 |
| 38 #include "ns3/core-module.h" |
| 39 #include "ns3/network-module.h" |
| 40 #include "ns3/csma-module.h" |
| 41 #include "ns3/internet-module.h" |
| 42 #include "ns3/applications-module.h" |
| 43 #include "ns3/openflow-module.h" |
| 44 #include "ns3/log.h" |
| 45 |
| 46 using namespace ns3; |
| 47 |
| 48 NS_LOG_COMPONENT_DEFINE ("OpenFlowCsmaSwitchExample"); |
| 49 |
| 50 bool verbose = false; |
| 51 bool use_drop = false; |
| 52 ns3::Time timeout = ns3::Seconds (0); |
| 53 |
| 54 bool |
| 55 SetVerbose (std::string value) |
| 56 { |
| 57 verbose = true; |
| 58 return true; |
| 59 } |
| 60 |
| 61 bool |
| 62 SetDrop (std::string value) |
| 63 { |
| 64 use_drop = true; |
| 65 return true; |
| 66 } |
| 67 |
| 68 bool |
| 69 SetTimeout (std::string value) |
| 70 { |
| 71 try { |
| 72 timeout = ns3::Seconds (atof (value.c_str ())); |
| 73 return true; |
| 74 } |
| 75 catch (...) { return false; } |
| 76 return false; |
| 77 } |
| 78 |
| 79 int |
| 80 main (int argc, char *argv[]) |
| 81 { |
| 82 #ifdef NS3_OPENFLOW |
| 83 // |
| 84 // Allow the user to override any of the defaults and the above Bind() at |
| 85 // run-time, via command-line arguments |
| 86 // |
| 87 CommandLine cmd; |
| 88 cmd.AddValue ("v", "Verbose (turns on logging).", MakeCallback (&SetVerbose)); |
| 89 cmd.AddValue ("verbose", "Verbose (turns on logging).", MakeCallback (&SetVerb
ose)); |
| 90 cmd.AddValue ("d", "Use Drop Controller (Learning if not specified).", MakeCal
lback (&SetDrop)); |
| 91 cmd.AddValue ("drop", "Use Drop Controller (Learning if not specified).", Make
Callback (&SetDrop)); |
| 92 cmd.AddValue ("t", "Learning Controller Timeout (has no effect if drop control
ler is specified).", MakeCallback( &SetTimeout)); |
| 93 cmd.AddValue ("timeout", "Learning Controller Timeout (has no effect if drop c
ontroller is specified).", MakeCallback( &SetTimeout)); |
| 94 ·· |
| 95 cmd.Parse (argc, argv); |
| 96 |
| 97 if (verbose) |
| 98 { |
| 99 LogComponentEnable ("OpenFlowCsmaSwitchExample", LOG_LEVEL_INFO); |
| 100 LogComponentEnable ("OpenFlowInterface", LOG_LEVEL_INFO); |
| 101 LogComponentEnable ("OpenFlowSwitchNetDevice", LOG_LEVEL_INFO); |
| 102 } |
| 103 |
| 104 // |
| 105 // Explicitly create the nodes required by the topology (shown above). |
| 106 // |
| 107 NS_LOG_INFO ("Create nodes."); |
| 108 NodeContainer terminals; |
| 109 terminals.Create (4); |
| 110 |
| 111 NodeContainer csmaSwitch; |
| 112 csmaSwitch.Create (1); |
| 113 |
| 114 NS_LOG_INFO ("Build Topology"); |
| 115 CsmaHelper csma; |
| 116 csma.SetChannelAttribute ("DataRate", DataRateValue (5000000)); |
| 117 csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2))); |
| 118 |
| 119 // Create the csma links, from each terminal to the switch |
| 120 NetDeviceContainer terminalDevices; |
| 121 NetDeviceContainer switchDevices; |
| 122 for (int i = 0; i < 4; i++) |
| 123 { |
| 124 NetDeviceContainer link = csma.Install (NodeContainer (terminals.Get (i),
csmaSwitch)); |
| 125 terminalDevices.Add (link.Get (0)); |
| 126 switchDevices.Add (link.Get (1)); |
| 127 } |
| 128 |
| 129 // Create the switch netdevice, which will do the packet switching |
| 130 Ptr<Node> switchNode = csmaSwitch.Get (0); |
| 131 OpenFlowSwitchHelper swtch; |
| 132 ·· |
| 133 if (use_drop) |
| 134 { |
| 135 Ptr<ns3::ofi::DropController> controller = CreateObject<ns3::ofi::DropContro
ller> (); |
| 136 swtch.Install (switchNode, switchDevices, controller); |
| 137 } |
| 138 else |
| 139 { |
| 140 Ptr<ns3::ofi::LearningController> controller = CreateObject<ns3::ofi::Learni
ngController> (); |
| 141 if (!timeout.IsZero ()) controller->SetAttribute ("ExpirationTime", TimeValu
e (timeout)); |
| 142 swtch.Install (switchNode, switchDevices, controller); |
| 143 } |
| 144 |
| 145 // Add internet stack to the terminals |
| 146 InternetStackHelper internet; |
| 147 internet.Install (terminals); |
| 148 |
| 149 // We've got the "hardware" in place. Now we need to add IP addresses. |
| 150 NS_LOG_INFO ("Assign IP Addresses."); |
| 151 Ipv4AddressHelper ipv4; |
| 152 ipv4.SetBase ("10.1.1.0", "255.255.255.0"); |
| 153 ipv4.Assign (terminalDevices); |
| 154 |
| 155 // Create an OnOff application to send UDP datagrams from n0 to n1. |
| 156 NS_LOG_INFO ("Create Applications."); |
| 157 uint16_t port = 9; // Discard port (RFC 863) |
| 158 |
| 159 OnOffHelper onoff ("ns3::UdpSocketFactory", |
| 160 Address (InetSocketAddress (Ipv4Address ("10.1.1.2"), port)
)); |
| 161 onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable (1))); |
| 162 onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable (0))); |
| 163 |
| 164 ApplicationContainer app = onoff.Install (terminals.Get (0)); |
| 165 // Start the application |
| 166 app.Start (Seconds (1.0)); |
| 167 app.Stop (Seconds (10.0)); |
| 168 |
| 169 // Create an optional packet sink to receive these packets |
| 170 PacketSinkHelper sink ("ns3::UdpSocketFactory", |
| 171 Address (InetSocketAddress (Ipv4Address::GetAny (), por
t))); |
| 172 app = sink.Install (terminals.Get (1)); |
| 173 app.Start (Seconds (0.0)); |
| 174 |
| 175 // |
| 176 // Create a similar flow from n3 to n0, starting at time 1.1 seconds |
| 177 // |
| 178 onoff.SetAttribute ("Remote", |
| 179 AddressValue (InetSocketAddress (Ipv4Address ("10.1.1.1"),
port))); |
| 180 app = onoff.Install (terminals.Get (3)); |
| 181 app.Start (Seconds (1.1)); |
| 182 app.Stop (Seconds (10.0)); |
| 183 |
| 184 app = sink.Install (terminals.Get (0)); |
| 185 app.Start (Seconds (0.0)); |
| 186 |
| 187 NS_LOG_INFO ("Configure Tracing."); |
| 188 |
| 189 // |
| 190 // Configure tracing of all enqueue, dequeue, and NetDevice receive events. |
| 191 // Trace output will be sent to the file "openflow-switch.tr" |
| 192 // |
| 193 AsciiTraceHelper ascii; |
| 194 csma.EnableAsciiAll (ascii.CreateFileStream ("openflow-switch.tr")); |
| 195 |
| 196 // |
| 197 // Also configure some tcpdump traces; each interface will be traced. |
| 198 // The output files will be named: |
| 199 // openflow-switch-<nodeId>-<interfaceId>.pcap |
| 200 // and can be read by the "tcpdump -r" command (use "-tt" option to |
| 201 // display timestamps correctly) |
| 202 // |
| 203 csma.EnablePcapAll ("openflow-switch", false); |
| 204 |
| 205 // |
| 206 // Now, do the actual simulation. |
| 207 // |
| 208 NS_LOG_INFO ("Run Simulation."); |
| 209 Simulator::Run (); |
| 210 Simulator::Destroy (); |
| 211 NS_LOG_INFO ("Done."); |
| 212 #else |
| 213 NS_LOG_INFO ("NS-3 OpenFlow is not enabled. Cannot run simulation."); |
| 214 #endif // NS3_OPENFLOW |
| 215 } |
OLD | NEW |