diff --git a/README.md b/README.md index f02787b..a42bc05 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ Thanks to the main contributors: * Luciano Jerez Chaves * Vítor Marge Eichemberger * Islene Calciolari Garcia +* Arthur Boeacht Mazzi * *"Your name here"* # Contact # diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 9a3d2a9..d82e2d4 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -5,6 +5,44 @@ OFSwitch13 release notes This file contains OFSwitch13 release notes (most recent releases first). +Release 5.0.0 (Dec 19, 2021) +============================ + +- BE AWARE THAT this release brings incompatible API changes in respect to + prior OFSwitch13 versions. + +- Refactoring OFSwitch13Controller::Dpctl* () methods: + * The DpctlExecute () method has no more overloaded definitions. The target + switch (first parameter) must be the switch's datapath IP. Previous + signature using the Ptr swtch pointer was removed. + Users can fix compilation errors by just using swtch->GetDpId () when + invoking DpctlExecute (); + * The DpctlSchedule () method was deprecated in favor of DpctlExecute (). + When the switch is not connected to the controller, the DpctlExecute () + will automatically schedule the command for execution just after the + handshake procedure. This is particularly useful for executing dpctl + commands when creating the topology, before invoking Simulator::Run (). + +- Creating a new OFSwitch13Device::TableDrop trace source to notify unmatched + packets dropped by flow tables without table-miss entries. A new TabDrps + column was also inserted in the OFSwitch13StatsCalculator output file. + +- Updating OFSwitch13Queue for compatibility with the ns-3 queue API. + +- Updating the ofswitch13-external-controller example with a custom topology + configuration. This example was tested with the Ryu controller. + +- Fixing incorrect Ethernet 802.3 packet header parsing. + +- Fixing errors when compiling the project with gcc 9.3.0 in Ubuntu 20.04. + +- This version is compatible with ofsoftswitch13 library release v5.0.x and + ns-3 version 3.30 (including patch). There is no backward compatibility with + older ns-3 versions. + +- Compilation was tested in Debian 8, Ubuntu 18.04 LTS, and Ubuntu 20.04 LTS. + + Release 4.0.0 (Apr 02, 2019) ============================ @@ -89,9 +127,11 @@ Release 4.0.0 (Apr 02, 2019) - Merging new commits from the CPqD ofsoftswitch13 library. - This version is compatible with ofsoftswitch13 library release v4.0.x and - ns-3 versions 3.28 or later (including patches). There is no backward + ns-3 versions 3.28 and 3.29 (including patches). There is no backward compatibility with older ns-3 versions. +- Compilation was tested in Ubuntu 18.04 LTS. + Release 3.3.0 (Sep 29, 2018) ============================ diff --git a/doc/source/conf.py b/doc/source/conf.py index d53b22d..3612110 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -41,16 +41,16 @@ # General information about the project. project = u'OFSwitch13' -copyright = u'2019 Computer Networks Laboratory' +copyright = u'2021 Computer Networks Laboratory' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. -version = '4.0.0' +version = '5.0.0' # The full version, including alpha/beta/rc tags. -release = '4.0.0' +release = '5.0.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/doc/source/ofswitch13-description.rst b/doc/source/ofswitch13-description.rst index 12b1216..8923265 100644 --- a/doc/source/ofswitch13-description.rst +++ b/doc/source/ofswitch13-description.rst @@ -107,7 +107,7 @@ Packets coming back from the library for output action are sent to the OpenFlow queue provided by the module. An OpenFlow switch provides limited QoS support employing a simple queuing mechanism, where each port can have one or more queues attached to it. Packets sent to a specific queue are treated according -to that queue’s configuration. Queue configuration takes place outside the +to that queue's configuration. Queue configuration takes place outside the OpenFlow protocol. The ``OFSwitch13Queue`` abstract base class implements the queue interface, extending the |ns3| ``Queue`` class to allow compatibility with the ``CsmaNetDevice`` used within ``OFSwitch13Port`` objects @@ -359,13 +359,12 @@ receive callback into |ns3| source code, available under the receive callbacks inclusion, and an optional *doc* patch that can be used for including the |ofs13| when compiling Doxygen and Sphinx documentation. -The current |ofs13| stable version is 4.0.0. This version is compatible with -|ns3| version 3.28 or later, and will not compile with older |ns3| -versions. If you need to use another |ns3| release, you can check the |ofs13| -RELEASE_NOTES file for previous |ofs13| releases and their |ns3| version -compatibility, but keep in mind that old releases may have known bugs and an -old API. It is strongly recommended to use the latest module version for better -results. +The current |ofs13| stable version is 5.0.0. This version is compatible with +|ns3| version 3.30, and will not compile with older |ns3| versions. If you need +to use another |ns3| release, you can check the |ofs13| RELEASE_NOTES file for +previous |ofs13| releases and their |ns3| version compatibility, but keep in +mind that old releases may have known bugs and an old API. It is strongly +recommended to use the latest module version for better results. References ========== @@ -394,7 +393,7 @@ References .. [Risso2006] Fulvio Risso and Mario Baldi. `"Netpdl: An extensible xml-based language for packet header description" `_. - Computer Networks, 50(5):688–706, 2006. + Computer Networks, 50(5):688-706, 2006. .. [Chaves2016] Luciano J. Chaves, Islene C. Garcia, and Edmundo R. M. Madeira. `"OFSwitch13: Enhancing ns-3 with OpenFlow 1.3 support" diff --git a/doc/source/ofswitch13-usage.rst b/doc/source/ofswitch13-usage.rst index 4a3e8c4..e2540e7 100644 --- a/doc/source/ofswitch13-usage.rst +++ b/doc/source/ofswitch13-usage.rst @@ -16,33 +16,32 @@ Building the Module The |ofs13| module was designed as an interface for interconnecting the |ns3| simulator to the |ofslib| software switch compiled as a library. Follow the instructions below to compile and link the |ns3| simulator to the |ofslib| -library. *These instructions were tested on Debian 8, Ubuntu 16.04 LTS, and -Ubuntu 18.04 LTS. Other distributions or versions may require different steps, +library. *These instructions were tested on Debian 8, Ubuntu 18.04.6 LTS, and +Ubuntu 20.04.3 LTS. Other distributions or versions may require different steps, especially regarding library compilation.* Before starting ############### Before starting, ensure you have the following packages installed on your -system [#f1]_: +system: .. code-block:: bash $ sudo apt-get install build-essential gcc g++ python git mercurial unzip cmake - $ sudo apt-get install pkg-config autoconf libtool libboost-dev - -.. [#f1] The *NetBee* library dependence was removed in |ofs13| - release version 4.0.0. + $ sudo apt-get install pkg-config autoconf automake libtool libboost-dev Compiling the code ################## -Download a recent stable |ns3| code into your machine (we are using the -mercurial repository for ns-3.29): +Clone the |ns3| source code repository into your machine and checkout a stable +version (we are using the ns-3.30): .. code-block:: bash - $ hg clone http://code.nsnam.org/ns-3.29 + $ git clone https://gitlab.com/nsnam/ns-3-dev.git + $ cd ns-3-dev + $ git checkout -b ns-3.30 ns-3.30 Download the |ofs13| code into the ``src/`` folder (starting with ns-3.28, you can also download the code into the new ``contrib/`` folder). This procedure @@ -51,13 +50,13 @@ will recursively download the |ofslib| code into the .. code-block:: bash - $ cd ns-3.29/src + $ cd src/ $ git clone --recurse-submodules https://github.com/ljerezchaves/ofswitch13.git -Update the code to the desired release version (we are using release 4.0.0, -which is compatible with ns-3.28 or later) [#f2]_: +Update the code to the desired release version (we are using the latest release +5.0.0, which is compatible with ns-3.30) [#f1]_: -.. [#f2] For |ofs13| release versions prior to 3.2.2 (when no submodule +.. [#f1] For |ofs13| release versions prior to 3.2.2 (when no submodule dependence was configured in the git repository), the |ofslib| code will not automatically update to the correct version. In this case, you must manually updated the |ofslib| code to the proper version @@ -67,7 +66,7 @@ which is compatible with ns-3.28 or later) [#f2]_: .. code-block:: bash $ cd ofswitch13 - $ git checkout 4.0.0 && git submodule update --recursive + $ git checkout 5.0.0 && git submodule update --recursive Now it is time to compile the |ofslib| as a static library. Configure and build the library (don't forget to add the ``--enable-ns3-lib`` during @@ -89,8 +88,8 @@ correct |ns3| version): .. code-block:: bash $ cd ../../../../ - $ patch -p1 < src/ofswitch13/utils/ofswitch13-src-3_29.patch - $ patch -p1 < src/ofswitch13/utils/ofswitch13-doc-3_29.patch + $ patch -p1 < src/ofswitch13/utils/ofswitch13-src-3_30.patch + $ patch -p1 < src/ofswitch13/utils/ofswitch13-doc-3_30.patch The ``src`` patch creates the new OpenFlow receive callback at ``CsmaNetDevice`` and ``VirtualNetDevice``, allowing OpenFlow switch to get raw @@ -413,8 +412,9 @@ the following datapath metrics on the output file: #. [``LoaUsag``] Average CPU processing capacity usage (percent); #. [``Packets``] Packets processed by the pipeline in the last interval; #. [``DlyUsec``] EWMA pipeline lookup delay for packet processing (usecs); -#. [``LoaDrop``] Packets dropped by capacity overloaded in the last interval; +#. [``LoaDrps``] Packets dropped by capacity overloaded in the last interval; #. [``MetDrps``] Packets dropped by meter bands in the last interval; +#. [``TabDrps``] Unmatched packets dropped by flow tables in the last interval; #. [``FloMods``] Flow-mod operations executed in the last interval; #. [``MetMods``] Meter-mod operations executed in the last interval; #. [``GroMods``] Group-mod operations executed in the last interval; @@ -560,10 +560,11 @@ switch. With this tool, it is possible to add flows to the flow table, query for switch features and status, and change other configurations. The ``DpctlExecute()`` function can be used by derived controllers to convert a variety of ``dpctl`` commands into OpenFlow messages and send it to the target -switch. There's also the ``DpctlSchedule()`` variant, which can be used to -schedule commands to be executed just after the handshake procedure between the -controller and the switch (this can be useful for scheduling commands during -the topology creation, before the simulation start). +switch. If the switch is not connected to the controller yet, this method will +automatically schedule the commands for execution just after the handshake +procedure between the controller and the switch. This is particularly useful +for executing dpctl commands when creating the topology, before invoking +``Simulator::Run ()``. Check the `utility documentation `_ for details @@ -651,10 +652,8 @@ controller is running on the local machine at port 6653 (the helper automatically sets the IP address). Users can modify the local port number setting the ``OFSwitch13ExternalHelper::Port`` attribute. -This example was tested with the Floodlight 1.2 controller -(http://www.projectfloodlight.org) running on the local machine. Consistent -behavior was observed once sufficient time elapses (say 3 to 5 minutes) between -any two executions. +This example was tested with the Ryu controller (https://ryu-sdn.org) running +on the local machine. Examples ======== diff --git a/examples/ofswitch13-external-controller.cc b/examples/ofswitch13-external-controller.cc index f8fc8f0..bdc4ca7 100644 --- a/examples/ofswitch13-external-controller.cc +++ b/examples/ofswitch13-external-controller.cc @@ -1,6 +1,7 @@ /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2017 University of Campinas (Unicamp) + * 2020 Federal University of Juiz de Fora (UFJF) * * 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 @@ -16,17 +17,22 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Author: Luciano Chaves + * Arthur Boechat Mazzi * - * Two hosts connected to different OpenFlow switches. - * Both switches are managed by the same external controller application. + * There are N switches connected in line and managed by an external controller. + * There are M hosts equally distributed among the switches. + * Random pings among hosts. * - * External Controller - * | - * +-------------+ - * | | - * +----------+ +----------+ - * Host 0 === | Switch 0 | === | Switch 1 | === Host 1 - * +----------+ +----------+ + * External controller + * | + * +----------------+-------- ... --------+ + * | | | + * +----------+ +----------+ +----------+ + * | Switch 1 | === | Switch 2 | == ... == | Switch N | + * +----------+ +----------+ +----------+ + * || || || + * Hosts Hosts Hosts + * 1, N+1, ... 2, N+2, ... N, 2N, ... */ #include @@ -42,15 +48,23 @@ using namespace ns3; int main (int argc, char *argv[]) { - uint16_t simTime = 10; + uint16_t simTime = 100; bool verbose = false; bool trace = false; + uint16_t numHosts = 20; + uint16_t numSwitches = 3; + uint16_t numPings = 20; + uint16_t pingTime = 10; // Configure command line parameters CommandLine cmd; cmd.AddValue ("simTime", "Simulation time (seconds)", simTime); cmd.AddValue ("verbose", "Enable verbose output", verbose); cmd.AddValue ("trace", "Enable datapath stats and pcap traces", trace); + cmd.AddValue ("numHosts", "Number of hosts in the simulation", numHosts); + cmd.AddValue ("numSwitches", "Number of switches in the simulation", numSwitches); + cmd.AddValue ("numPings", "Number of ping apps int the simulation", numPings); + cmd.AddValue ("pingTime", "Ping time (seconds)", pingTime); cmd.Parse (argc, argv); if (verbose) @@ -64,7 +78,7 @@ main (int argc, char *argv[]) LogComponentEnable ("OFSwitch13Controller", LOG_LEVEL_ALL); LogComponentEnable ("OFSwitch13LearningController", LOG_LEVEL_ALL); LogComponentEnable ("OFSwitch13Helper", LOG_LEVEL_ALL); - LogComponentEnable ("OFSwitch13ExternalHelper", LOG_LEVEL_ALL); + LogComponentEnable ("OFSwitch13InternalHelper", LOG_LEVEL_ALL); } // Enable checksum computations (required by OFSwitch13 module) @@ -73,15 +87,15 @@ main (int argc, char *argv[]) // Set simulator to real time mode GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::RealtimeSimulatorImpl")); - // Create two host nodes + // Create host nodes NodeContainer hosts; - hosts.Create (2); + hosts.Create (numHosts); - // Create two switch nodes + // Create switch nodes NodeContainer switches; - switches.Create (2); + switches.Create (numSwitches); - // Use the CsmaHelper to connect hosts and switches + // Use the CsmaHelper to connect host and switch CsmaHelper csmaHelper; csmaHelper.SetChannelAttribute ("DataRate", DataRateValue (DataRate ("100Mbps"))); csmaHelper.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2))); @@ -89,27 +103,30 @@ main (int argc, char *argv[]) NodeContainer pair; NetDeviceContainer pairDevs; NetDeviceContainer hostDevices; - NetDeviceContainer switchPorts [2]; - switchPorts [0] = NetDeviceContainer (); - switchPorts [1] = NetDeviceContainer (); - - // Connect host 0 to first switch - pair = NodeContainer (hosts.Get (0), switches.Get (0)); - pairDevs = csmaHelper.Install (pair); - hostDevices.Add (pairDevs.Get (0)); - switchPorts [0].Add (pairDevs.Get (1)); - - // Connect host 1 to second switch - pair = NodeContainer (hosts.Get (1), switches.Get (1)); - pairDevs = csmaHelper.Install (pair); - hostDevices.Add (pairDevs.Get (0)); - switchPorts [1].Add (pairDevs.Get (1)); - - // Connect the switches - pair = NodeContainer (switches.Get (0), switches.Get (1)); - pairDevs = csmaHelper.Install (pair); - switchPorts [0].Add (pairDevs.Get (0)); - switchPorts [1].Add (pairDevs.Get (1)); + NetDeviceContainer switchPorts [numSwitches]; + for (int i = 0; i < numSwitches; i++) + { + switchPorts [i] = NetDeviceContainer (); + } + + // Connect hosts to switches in round robin + for (size_t i = 0; i < numHosts; i++) + { + int j = i % numSwitches; + pair = NodeContainer (hosts.Get (i), switches.Get (j)); + pairDevs = csmaHelper.Install (pair); + hostDevices.Add (pairDevs.Get (0)); + switchPorts [j].Add (pairDevs.Get (1)); + } + + // Connect the switches in chain + for (int i = 0; i < numSwitches - 1; i++) + { + pair = NodeContainer (switches.Get (i), switches.Get (i + 1)); + pairDevs = csmaHelper.Install (pair); + switchPorts [i].Add (pairDevs.Get (0)); + switchPorts [i + 1].Add (pairDevs.Get (1)); + } // Create the controller node Ptr controllerNode = CreateObject (); @@ -117,8 +134,10 @@ main (int argc, char *argv[]) // Configure the OpenFlow network domain using an external controller Ptr of13Helper = CreateObject (); Ptr ctrlDev = of13Helper->InstallExternalController (controllerNode); - of13Helper->InstallSwitch (switches.Get (0), switchPorts [0]); - of13Helper->InstallSwitch (switches.Get (1), switchPorts [1]); + for (int i = 0; i < numSwitches; i++) + { + of13Helper->InstallSwitch (switches.Get (i), switchPorts [i]); + } of13Helper->CreateOpenFlowChannels (); // TapBridge the controller device to local machine @@ -138,20 +157,40 @@ main (int argc, char *argv[]) ipv4helpr.SetBase ("10.1.1.0", "255.255.255.0"); hostIpIfaces = ipv4helpr.Assign (hostDevices); - // Configure ping application between hosts - V4PingHelper pingHelper = V4PingHelper (hostIpIfaces.GetAddress (1)); - pingHelper.SetAttribute ("Verbose", BooleanValue (true)); - ApplicationContainer pingApps = pingHelper.Install (hosts.Get (0)); - pingApps.Start (Seconds (1)); + // Random number generators for ping applications + Ptr randomHostRng = CreateObject (); + randomHostRng->SetAttribute ("Min", DoubleValue (0)); + randomHostRng->SetAttribute ("Max", DoubleValue (numHosts - 1)); + + Ptr randomStartRng = CreateObject (); + randomStartRng->SetAttribute ("Mean", DoubleValue (20)); + + // Configure ping application between random hosts + Time startTime = Seconds (1); + for (int i = 0; i < numPings; i++) + { + int srcHost = randomHostRng->GetInteger (); + int dstHost = randomHostRng->GetInteger (); + + V4PingHelper pingHelper = V4PingHelper (hostIpIfaces.GetAddress (dstHost)); + pingHelper.SetAttribute ("Verbose", BooleanValue (true)); + Ptr pingApp = pingHelper.Install (hosts.Get (srcHost)).Get (0); + + startTime += Seconds (std::abs (randomStartRng->GetValue ())); + pingApp->SetStartTime (startTime); + pingApp->SetStopTime (startTime + Seconds (pingTime)); + } // Enable datapath stats and pcap traces at hosts, switch(es), and controller(s) if (trace) { of13Helper->EnableOpenFlowPcap ("openflow"); of13Helper->EnableDatapathStats ("switch-stats"); - csmaHelper.EnablePcap ("switch", switchPorts [0], true); - csmaHelper.EnablePcap ("switch", switchPorts [1], true); csmaHelper.EnablePcap ("host", hostDevices); + for (int i = 0; i < numSwitches; i++) + { + csmaHelper.EnablePcap ("switch", switchPorts [i], true); + } } // Run the simulation diff --git a/examples/ofswitch13-logical-port/tunnel-controller.cc b/examples/ofswitch13-logical-port/tunnel-controller.cc index b914d51..712cb2a 100644 --- a/examples/ofswitch13-logical-port/tunnel-controller.cc +++ b/examples/ofswitch13-logical-port/tunnel-controller.cc @@ -97,12 +97,15 @@ TunnelController::HandshakeSuccessful (Ptr swtch) { NS_LOG_FUNCTION (this << swtch); + // Get the switch datapath ID + uint64_t swDpId = swtch->GetDpId (); + // Send ARP requests to controller. - DpctlExecute (swtch, "flow-mod cmd=add,table=0,prio=16 eth_type=0x0806 " + DpctlExecute (swDpId, "flow-mod cmd=add,table=0,prio=16 eth_type=0x0806 " "apply:output=ctrl"); // Table miss entry. - DpctlExecute (swtch, "flow-mod cmd=add,table=0,prio=0 apply:output=ctrl"); + DpctlExecute (swDpId, "flow-mod cmd=add,table=0,prio=0 apply:output=ctrl"); } ofl_err @@ -112,6 +115,9 @@ TunnelController::HandlePacketIn ( { NS_LOG_FUNCTION (this << swtch << xid); + // Get the switch datapath ID + uint64_t swDpId = swtch->GetDpId (); + struct ofl_match_tlv *tlv; enum ofp_packet_in_reason reason = msg->reason; if (reason == OFPR_NO_MATCH) @@ -131,7 +137,7 @@ TunnelController::HandlePacketIn ( // from the host node. In this case, identify and set TEID and tunnel // endpoint IPv4 address into tunnel metadata, and output the packet // on the logical port 2. - Ipv4Address dstAddr = GetTunnelEndpoint (swtch->GetDpId (), 2); + Ipv4Address dstAddr = GetTunnelEndpoint (swDpId, 2); uint64_t tunnelId = (uint64_t)dstAddr.Get () << 32; tunnelId |= 0xFFFF; char tunnelIdStr [20]; @@ -142,7 +148,7 @@ TunnelController::HandlePacketIn ( << " in_port=1,eth_type=0x0800 " << "write:set_field=tunn_id:" << tunnelIdStr << ",output=2"; - DpctlExecute (swtch, cmd.str ()); + DpctlExecute (swDpId, cmd.str ()); // All handlers must free the message when everything is ok ofl_msg_free ((struct ofl_msg_header*)msg, 0); @@ -167,7 +173,7 @@ TunnelController::HandlePacketIn ( << " in_port=2,eth_type=0x0800,tunn_id=0xFFFF " << "write:set_field=eth_dst:" << dstMac << ",output=1"; - DpctlExecute (swtch, cmd.str ()); + DpctlExecute (swDpId, cmd.str ()); // All handlers must free the message when everything is ok ofl_msg_free ((struct ofl_msg_header*)msg, 0); diff --git a/examples/ofswitch13-multiple-controllers.cc b/examples/ofswitch13-multiple-controllers.cc index 14ea340..27ca36f 100644 --- a/examples/ofswitch13-multiple-controllers.cc +++ b/examples/ofswitch13-multiple-controllers.cc @@ -149,7 +149,7 @@ class Controller0 : public OFSwitch13Controller void Controller0::HandshakeSuccessful (Ptr swtch) { - DpctlExecute (swtch, "flow-mod cmd=add,table=0,prio=1 in_port=1 write:output=2"); + DpctlExecute (swtch->GetDpId (), "flow-mod cmd=add,table=0,prio=1 in_port=1 write:output=2"); } /** Controller 1 installs the rule to forward packets from host 1 to 0 (port 2 to 1). */ @@ -163,5 +163,5 @@ class Controller1 : public OFSwitch13Controller void Controller1::HandshakeSuccessful (Ptr swtch) { - DpctlExecute (swtch, "flow-mod cmd=add,table=0,prio=1 in_port=2 write:output=1"); + DpctlExecute (swtch->GetDpId (), "flow-mod cmd=add,table=0,prio=1 in_port=2 write:output=1"); } diff --git a/examples/ofswitch13-qos-controller/main.cc b/examples/ofswitch13-qos-controller/main.cc index d306b22..46ae2a1 100644 --- a/examples/ofswitch13-qos-controller/main.cc +++ b/examples/ofswitch13-qos-controller/main.cc @@ -260,7 +260,7 @@ main (int argc, char *argv[]) if (getcwd (cwd, sizeof (cwd)) != NULL) { std::string path = std::string (cwd) + - "/src/ofswitch13/examples/qos-controller/images/"; + "/src/ofswitch13/examples/ofswitch13-qos-controller/images/"; uint32_t serverImg = anim.AddResource (path + "server.png"); uint32_t switchImg = anim.AddResource (path + "switch.png"); uint32_t controllerImg = anim.AddResource (path + "controller.png"); diff --git a/examples/ofswitch13-qos-controller/qos-controller.cc b/examples/ofswitch13-qos-controller/qos-controller.cc index a34a069..f3b05e7 100644 --- a/examples/ofswitch13-qos-controller/qos-controller.cc +++ b/examples/ofswitch13-qos-controller/qos-controller.cc @@ -144,18 +144,21 @@ QosController::ConfigureBorderSwitch (Ptr swtch) { NS_LOG_FUNCTION (this << swtch); + // Get the switch datapath ID + uint64_t swDpId = swtch->GetDpId (); + // For packet-in messages, send only the first 128 bytes to the controller - DpctlExecute (swtch, "set-config miss=128"); + DpctlExecute (swDpId, "set-config miss=128"); // Redirect ARP requests to the controller - DpctlExecute (swtch, "flow-mod cmd=add,table=0,prio=20 " + DpctlExecute (swDpId, "flow-mod cmd=add,table=0,prio=20 " "eth_type=0x0806,arp_op=1 apply:output=ctrl"); // Using group #3 for rewriting headers and forwarding packets to clients if (m_linkAggregation) { // Configure Group #3 for aggregating links 1 and 2 - DpctlExecute (swtch, "group-mod cmd=add,type=sel,group=3 " + DpctlExecute (swDpId, "group-mod cmd=add,type=sel,group=3 " "weight=1,port=any,group=any set_field=ip_src:10.1.1.1" ",set_field=eth_src:00:00:00:00:00:01,output=1 " "weight=1,port=any,group=any set_field=ip_src:10.1.1.1" @@ -164,31 +167,31 @@ QosController::ConfigureBorderSwitch (Ptr swtch) else { // Configure Group #3 for sending packets only over link 1 - DpctlExecute (swtch, "group-mod cmd=add,type=ind,group=3 " + DpctlExecute (swDpId, "group-mod cmd=add,type=ind,group=3 " "weight=0,port=any,group=any set_field=ip_src:10.1.1.1" ",set_field=eth_src:00:00:00:00:00:01,output=1"); } // Groups #1 and #2 send traffic to internal servers (ports 3 and 4) - DpctlExecute (swtch, "group-mod cmd=add,type=ind,group=1 " + DpctlExecute (swDpId, "group-mod cmd=add,type=ind,group=1 " "weight=0,port=any,group=any set_field=ip_dst:10.1.1.2," "set_field=eth_dst:00:00:00:00:00:08,output=3"); - DpctlExecute (swtch, "group-mod cmd=add,type=ind,group=2 " + DpctlExecute (swDpId, "group-mod cmd=add,type=ind,group=2 " "weight=0,port=any,group=any set_field=ip_dst:10.1.1.3," "set_field=eth_dst:00:00:00:00:00:0a,output=4"); // Incoming TCP connections (ports 1 and 2) are sent to the controller - DpctlExecute (swtch, "flow-mod cmd=add,table=0,prio=500 " + DpctlExecute (swDpId, "flow-mod cmd=add,table=0,prio=500 " "in_port=1,eth_type=0x0800,ip_proto=6,ip_dst=10.1.1.1," "eth_dst=00:00:00:00:00:01 apply:output=ctrl"); - DpctlExecute (swtch, "flow-mod cmd=add,table=0,prio=500 " + DpctlExecute (swDpId, "flow-mod cmd=add,table=0,prio=500 " "in_port=2,eth_type=0x0800,ip_proto=6,ip_dst=10.1.1.1," "eth_dst=00:00:00:00:00:01 apply:output=ctrl"); // TCP packets from servers are sent to the external network through group 3 - DpctlExecute (swtch, "flow-mod cmd=add,table=0,prio=700 " + DpctlExecute (swDpId, "flow-mod cmd=add,table=0,prio=700 " "in_port=3,eth_type=0x0800,ip_proto=6 apply:group=3"); - DpctlExecute (swtch, "flow-mod cmd=add,table=0,prio=700 " + DpctlExecute (swDpId, "flow-mod cmd=add,table=0,prio=700 " "in_port=4,eth_type=0x0800,ip_proto=6 apply:group=3"); } @@ -197,28 +200,31 @@ QosController::ConfigureAggregationSwitch (Ptr swtch) { NS_LOG_FUNCTION (this << swtch); + // Get the switch datapath ID + uint64_t swDpId = swtch->GetDpId (); + if (m_linkAggregation) { // Configure Group #1 for aggregating links 1 and 2 - DpctlExecute (swtch, "group-mod cmd=add,type=sel,group=1 " + DpctlExecute (swDpId, "group-mod cmd=add,type=sel,group=1 " "weight=1,port=any,group=any output=1 " "weight=1,port=any,group=any output=2"); } else { // Configure Group #1 for sending packets only over link 1 - DpctlExecute (swtch, "group-mod cmd=add,type=ind,group=1 " + DpctlExecute (swDpId, "group-mod cmd=add,type=ind,group=1 " "weight=0,port=any,group=any output=1"); } // Packets from input ports 1 and 2 are redirecte to port 3 - DpctlExecute (swtch, "flow-mod cmd=add,table=0,prio=500 " + DpctlExecute (swDpId, "flow-mod cmd=add,table=0,prio=500 " "in_port=1 write:output=3"); - DpctlExecute (swtch, "flow-mod cmd=add,table=0,prio=500 " + DpctlExecute (swDpId, "flow-mod cmd=add,table=0,prio=500 " "in_port=2 write:output=3"); // Packets from input port 3 are redirected to group 1 - DpctlExecute (swtch, "flow-mod cmd=add,table=0,prio=500 " + DpctlExecute (swDpId, "flow-mod cmd=add,table=0,prio=500 " "in_port=3 write:group=1"); } @@ -261,7 +267,7 @@ QosController::HandleArpPacketIn ( uint8_t replyData[64]; // Check for destination IP - if (dstIp.IsEqual (serverIp)) + if (dstIp == serverIp) { // Reply with virtual service IP/MAC addresses Ptr pkt = CreateArpReply (serverMac, dstIp, srcMac, srcIp); @@ -366,7 +372,7 @@ QosController::HandleConnectionRequest ( free (arpAction); // Check for valid service connection request - NS_ASSERT_MSG (dstIp.IsEqual (serverIp) && dstPort == m_serverTcpPort, + NS_ASSERT_MSG ((dstIp == serverIp) && (dstPort == m_serverTcpPort), "Invalid IP address / TCP port."); // Select an internal server to handle this connection @@ -374,13 +380,16 @@ QosController::HandleConnectionRequest ( NS_LOG_INFO ("Connection " << connectionCounter << " redirected to server " << serverNumber); + // Get the switch datapath ID + uint64_t swDpId = swtch->GetDpId (); + // If enable, install the metter entry for this connection if (m_meterEnable) { std::ostringstream meterCmd; meterCmd << "meter-mod cmd=add,flags=1,meter=" << connectionCounter << " drop:rate=" << m_meterRate.GetBitRate () / 1000; - DpctlExecute (swtch, meterCmd.str ()); + DpctlExecute (swDpId, meterCmd.str ()); } // Install the flow entry for this TCP connection @@ -395,7 +404,7 @@ QosController::HandleConnectionRequest ( flowCmd << " meter:" << connectionCounter; } flowCmd << " write:group=" << serverNumber; - DpctlExecute (swtch, flowCmd.str ()); + DpctlExecute (swDpId, flowCmd.str ()); // Create group action with server number struct ofl_action_group *action = diff --git a/helper/ofswitch13-external-helper.cc b/helper/ofswitch13-external-helper.cc index 83a64d4..e4451b5 100644 --- a/helper/ofswitch13-external-helper.cc +++ b/helper/ofswitch13-external-helper.cc @@ -136,14 +136,17 @@ OFSwitch13ExternalHelper::InstallExternalController (Ptr cNode) NS_ABORT_MSG_IF (m_blocked || m_controlDevs.GetN () != 0, "OpenFlow controller/channels already configured."); - // Install the TCP/IP stack and the controller application into node. - m_internet.Install (cNode); - m_controlNode = cNode; + // Install the TCP/IP stack into controller node. + if (cNode->GetObject () == 0) + { + m_internet.Install (cNode); + } // Connect the controller node to the common channel and configure IP addrs. m_controlDevs = m_csmaHelper.Install (cNode, m_csmaChannel); Ipv4InterfaceContainer ctrlIface = m_ipv4helper.Assign (m_controlDevs); m_controlAddr = ctrlIface.GetAddress (0); + m_controlNode = cNode; return m_controlDevs.Get (0); } diff --git a/helper/ofswitch13-helper.cc b/helper/ofswitch13-helper.cc index 3f6c985..669caf7 100644 --- a/helper/ofswitch13-helper.cc +++ b/helper/ofswitch13-helper.cc @@ -222,10 +222,13 @@ OFSwitch13Helper::InstallSwitch (Ptr swNode) NS_LOG_FUNCTION (this << swNode); NS_LOG_INFO ("Installing OpenFlow device on node " << swNode->GetId ()); - NS_ASSERT_MSG (!m_blocked, "OpenFlow channels already configured."); + NS_ABORT_MSG_IF (m_blocked, "OpenFlow channels already configured."); // Install the TCP/IP stack into switch node. - m_internet.Install (swNode); + if (swNode->GetObject () == 0) + { + m_internet.Install (swNode); + } // Create and aggregate the OpenFlow device to the switch node. Ptr openFlowDev = m_devFactory.Create (); diff --git a/helper/ofswitch13-internal-helper.cc b/helper/ofswitch13-internal-helper.cc index 3f01dae..b00b86e 100644 --- a/helper/ofswitch13-internal-helper.cc +++ b/helper/ofswitch13-internal-helper.cc @@ -175,8 +175,13 @@ OFSwitch13InternalHelper::InstallController ( NS_LOG_INFO ("Installing OpenFlow controller on node " << cNode->GetId ()); NS_ABORT_MSG_IF (m_blocked, "OpenFlow channels already configured."); - // Install the TCP/IP stack and the controller application into node. - m_internet.Install (cNode); + // Install the TCP/IP stack into controller node. + if (cNode->GetObject () == 0) + { + m_internet.Install (cNode); + } + + // Configure and save controller application and node. controller->SetStartTime (Seconds (0)); cNode->AddApplication (controller); m_controlApps.Add (controller); diff --git a/helper/ofswitch13-internal-helper.h b/helper/ofswitch13-internal-helper.h index 6c9192f..cd01ba3 100644 --- a/helper/ofswitch13-internal-helper.h +++ b/helper/ofswitch13-internal-helper.h @@ -71,7 +71,6 @@ class OFSwitch13InternalHelper : public OFSwitch13Helper /** Destructor implementation. */ virtual void DoDispose (); -private: /** * Create an individual connection between the switch and the controller * node, using the already configured channel type. diff --git a/helper/ofswitch13-stats-calculator.cc b/helper/ofswitch13-stats-calculator.cc index 73688b5..45a61cc 100644 --- a/helper/ofswitch13-stats-calculator.cc +++ b/helper/ofswitch13-stats-calculator.cc @@ -51,6 +51,7 @@ OFSwitch13StatsCalculator::OFSwitch13StatsCalculator () m_lastPacketsOut (0), m_loadDrops (0), m_meterDrops (0), + m_tableDrops (0), m_packets (0) { NS_LOG_FUNCTION (this); @@ -109,8 +110,9 @@ OFSwitch13StatsCalculator::HookSinks (Ptr device) << " " << setw (7) << "LoaUsag" << " " << setw (7) << "Packets" << " " << setw (7) << "DlyUsec" - << " " << setw (7) << "LoaDrop" + << " " << setw (7) << "LoaDrps" << " " << setw (7) << "MetDrps" + << " " << setw (7) << "TabDrps" << " " << setw (7) << "FloMods" << " " << setw (7) << "MetMods" << " " << setw (7) << "GroMods" @@ -152,6 +154,10 @@ OFSwitch13StatsCalculator::HookSinks (Ptr device) "MeterDrop", MakeCallback ( &OFSwitch13StatsCalculator::NotifyMeterDrop, Ptr (this))); + device->TraceConnectWithoutContext ( + "TableDrop", MakeCallback ( + &OFSwitch13StatsCalculator::NotifyTableDrop, + Ptr (this))); device->TraceConnectWithoutContext ( "PipelinePacket", MakeCallback ( &OFSwitch13StatsCalculator::NotifyPipelinePacket, @@ -348,6 +354,15 @@ OFSwitch13StatsCalculator::NotifyMeterDrop (Ptr packet, m_meterDrops++; } +void +OFSwitch13StatsCalculator::NotifyTableDrop (Ptr packet, + uint8_t tableId) +{ + NS_LOG_FUNCTION (this << packet << static_cast (tableId)); + + m_tableDrops++; +} + void OFSwitch13StatsCalculator::NotifyPipelinePacket (Ptr packet) { @@ -391,6 +406,7 @@ OFSwitch13StatsCalculator::DumpStatistics (void) << " " << setw (7) << GetEwmaPipelineDelay ().GetMicroSeconds () << " " << setw (7) << m_loadDrops << " " << setw (7) << m_meterDrops + << " " << setw (7) << m_tableDrops << " " << setw (7) << flowMods - m_lastFlowMods << " " << setw (7) << meterMods - m_lastMeterMods << " " << setw (7) << groupMods - m_lastGroupMods @@ -426,6 +442,7 @@ OFSwitch13StatsCalculator::DumpStatistics (void) m_lastPacketsOut = packetsOut; m_loadDrops = 0; m_meterDrops = 0; + m_tableDrops = 0; m_packets = 0; // Scheduling next update. diff --git a/helper/ofswitch13-stats-calculator.h b/helper/ofswitch13-stats-calculator.h index 7ee84ad..41dcd0d 100644 --- a/helper/ofswitch13-stats-calculator.h +++ b/helper/ofswitch13-stats-calculator.h @@ -36,8 +36,9 @@ namespace ns3 { * -# [LoaUsag] Average CPU processing capacity usage (percent); * -# [Packets] Packets processed by the pipeline in the last interval; * -# [DlyUsec] EWMA pipeline lookup delay for packet processing (usecs); - * -# [LoaDrop] Packets dropped by capacity overloaded in the last interval; + * -# [LoaDrps] Packets dropped by capacity overloaded in the last interval; * -# [MetDrps] Packets dropped by meter bands in the last interval; + * -# [TabDrps] Unmatched packets dropped by flow tables in the last interval; * -# [FloMods] Flow-mod operations executed in the last interval; * -# [MetMods] Meter-mod operations executed in the last interval; * -# [GroMods] Group-mod operations executed in the last interval; @@ -138,6 +139,14 @@ class OFSwitch13StatsCalculator : public Object */ void NotifyMeterDrop (Ptr packet, uint32_t meterId); + /** + * Notify when an unmatched packet is dropped by a flow table without a + * table-miss entry. + * \param packet The packet. + * \param tableId The flow table ID. + */ + void NotifyTableDrop (Ptr packet, uint8_t tableId); + /** * Notify when a packet is sent to pipeline. * \param packet The packet. @@ -177,6 +186,7 @@ class OFSwitch13StatsCalculator : public Object uint64_t m_lastPacketsOut; uint64_t m_loadDrops; uint64_t m_meterDrops; + uint64_t m_tableDrops; uint64_t m_packets; //\} }; diff --git a/lib/ofsoftswitch13 b/lib/ofsoftswitch13 index 23b81ff..430dbd3 160000 --- a/lib/ofsoftswitch13 +++ b/lib/ofsoftswitch13 @@ -1 +1 @@ -Subproject commit 23b81fff3b31f92ef365627f7bbf61167f2cf647 +Subproject commit 430dbd3e37a8a5df7eac0d856cc403ee9132ee51 diff --git a/model/ofswitch13-controller.cc b/model/ofswitch13-controller.cc index 96f6d46..2bd86a0 100644 --- a/model/ofswitch13-controller.cc +++ b/model/ofswitch13-controller.cc @@ -63,25 +63,51 @@ OFSwitch13Controller::DoDispose () NS_LOG_FUNCTION (this); m_serverSocket = 0; - m_switchesMap.clear (); - m_echoMap.clear (); + m_addrSwMap.clear (); m_barrierMap.clear (); - m_schedCommands.clear (); + m_commandsMap.clear (); + m_dpIdSwMap.clear (); + m_echoMap.clear (); Application::DoDispose (); } int -OFSwitch13Controller::DpctlExecute (Ptr swtch, - const std::string textCmd) +OFSwitch13Controller::DpctlExecute (uint64_t dpId, const std::string textCmd) { - NS_LOG_FUNCTION (this << swtch << textCmd); + NS_LOG_FUNCTION (this << dpId << textCmd); + + Ptr swtch = GetRemoteSwitch (dpId); + if (!swtch) + { + // Save this command for further execution after handshake procedure. + NS_LOG_DEBUG ("Schedulling command for an unregistered switch."); + auto it = m_commandsMap.find (dpId); + if (it == m_commandsMap.end ()) + { + // Create a new pending commands object for this datapath id. + Ptr pendCmds = Create (); + std::pair > entry (dpId, pendCmds); + auto ret = m_commandsMap.insert (entry); + if (ret.second == false) + { + NS_LOG_ERROR ("Error when creating pending commands object."); + } + it = ret.first; + } + + // Save the dpctl command in the pending queue and return. + it->second->m_queue.push (textCmd); + return 0; + } + // Parse the textCmd. wordexp_t cmd; wordexp (textCmd.c_str (), &cmd, 0); char **argv = cmd.we_wordv; size_t argc = cmd.we_wordc; + // Check for unsupported commands. if ((strcmp (argv[0], "ping") == 0) || (strcmp (argv[0], "monitor") == 0) || (strcmp (argv[0], "set-desc") == 0) @@ -93,34 +119,12 @@ OFSwitch13Controller::DpctlExecute (Ptr swtch, return EXIT_FAILURE; } + // Execute the command. int ret = dpctl_exec_ns3_command ((void*)PeekPointer (swtch), argc, argv); wordfree (&cmd); return ret; } -int -OFSwitch13Controller::DpctlExecute (uint64_t dpId, const std::string textCmd) -{ - NS_LOG_FUNCTION (this << dpId << textCmd); - - Ptr swtch = GetRemoteSwitch (dpId); - NS_ASSERT_MSG (swtch, "Can't execute command for an unregistered switch."); - return DpctlExecute (swtch, textCmd); -} - -int -OFSwitch13Controller::DpctlSchedule (uint64_t dpId, const std::string textCmd) -{ - NS_LOG_FUNCTION (this << textCmd); - - Ptr swtch = GetRemoteSwitch (dpId); - NS_ASSERT_MSG (!swtch, "Can't schedule command for a registered switch."); - - std::pair entry (dpId, textCmd); - m_schedCommands.insert (entry); - return 0; -} - void OFSwitch13Controller::DpctlSendAndPrint (struct vconn *vconn, struct ofl_msg_header *msg) @@ -158,12 +162,11 @@ OFSwitch13Controller::StopApplication () { NS_LOG_FUNCTION (this << m_port); - for (auto const &it : m_switchesMap) + for (auto const &it : m_dpIdSwMap) { Ptr swtch = it.second; swtch->m_handler = 0; } - m_switchesMap.clear (); if (m_serverSocket) { @@ -171,6 +174,12 @@ OFSwitch13Controller::StopApplication () m_serverSocket->SetRecvCallback ( MakeNullCallback > ()); } + + m_addrSwMap.clear (); + m_barrierMap.clear (); + m_commandsMap.clear (); + m_dpIdSwMap.clear (); + m_echoMap.clear (); } uint32_t @@ -190,13 +199,10 @@ OFSwitch13Controller::GetRemoteSwitch (uint64_t dpId) const { NS_LOG_FUNCTION (this << dpId); - for (auto const &it : m_switchesMap) + auto it = m_dpIdSwMap.find (dpId); + if (it != m_dpIdSwMap.end ()) { - Ptr swtch = it.second; - if (swtch->m_dpId == dpId) - { - return swtch; - } + return it->second; } return 0; } @@ -382,13 +388,25 @@ OFSwitch13Controller::HandleFeaturesReply ( swtch->m_capabilities = msg->capabilities; ofl_msg_free ((struct ofl_msg_header*)msg, 0); - // Executing any scheduled commands for this OpenFlow datapath ID - auto ret = m_schedCommands.equal_range (swtch->m_dpId); - for (auto it = ret.first; it != ret.second; it++) + std::pair > entry (swtch->m_dpId, swtch); + auto ret = m_dpIdSwMap.insert (entry); + if (ret.second == false) + { + NS_LOG_ERROR ("This switch is already registered with this controller."); + } + + // Execute any pending command for this OpenFlow datapath ID. + auto it = m_commandsMap.find (swtch->m_dpId); + if (it != m_commandsMap.end ()) { - DpctlExecute (swtch, it->second); + Ptr pendCommands = it->second; + while (!pendCommands->m_queue.empty ()) + { + DpctlExecute (swtch->m_dpId, pendCommands->m_queue.front ()); + pendCommands->m_queue.pop (); + } + m_commandsMap.erase (swtch->m_dpId); } - m_schedCommands.erase (ret.first, ret.second); // Notify listeners that the handshake procedure is concluded. HandshakeSuccessful (swtch); @@ -612,8 +630,8 @@ OFSwitch13Controller::GetRemoteSwitch (Address address) { NS_LOG_FUNCTION (this << address); - auto it = m_switchesMap.find (address); - if (it != m_switchesMap.end ()) + auto it = m_addrSwMap.find (address); + if (it != m_addrSwMap.end ()) { return it->second; } @@ -658,7 +676,7 @@ OFSwitch13Controller::SocketAccept (Ptr socket, const Address& from) MakeCallback (&OFSwitch13Controller::ReceiveFromSwitch, this)); std::pair > entry (swtch->m_address, swtch); - auto ret = m_switchesMap.insert (entry); + auto ret = m_addrSwMap.insert (entry); if (ret.second == false) { NS_LOG_ERROR ("This switch is already registered with this controller."); @@ -744,4 +762,8 @@ OFSwitch13Controller::BarrierInfo::BarrierInfo (Ptr swtch) { } +OFSwitch13Controller::PendingCommands::PendingCommands () +{ +} + } // namespace ns3 diff --git a/model/ofswitch13-controller.h b/model/ofswitch13-controller.h index ca8f7ba..e1a86bb 100644 --- a/model/ofswitch13-controller.h +++ b/model/ofswitch13-controller.h @@ -140,6 +140,23 @@ class OFSwitch13Controller : public Application Ptr m_swtch; //!< Remote switch. }; +private: + /** + * \ingroup ofswitch13 + * Inner class to save pending commands waiting for handshake procedure. + */ + class PendingCommands : public SimpleRefCount + { + friend class OFSwitch13Controller; + +public: + /** Default (empty) constructor. */ + PendingCommands (); + +private: + std::queue m_queue; //!< Queue of pending dpctl commands. + }; + public: OFSwitch13Controller (); //!< Default constructor virtual ~OFSwitch13Controller (); //!< Dummy destructor, see DoDispose. @@ -155,14 +172,6 @@ class OFSwitch13Controller : public Application */ virtual void DoDispose (); - /** - * Execute a dpctl command to interact with the remote switch. - * \param swtch The target remote switch. - * \param textCmd The dpctl command to execute. - * \return 0 if everything's ok, otherwise an error number. - */ - int DpctlExecute (Ptr swtch, const std::string textCmd); - /** * Execute a dpctl command to interact with the remote switch. * \param dpId The OpenFlow datapath ID. @@ -171,15 +180,6 @@ class OFSwitch13Controller : public Application */ int DpctlExecute (uint64_t dpId, const std::string textCmd); - /** - * Schedule a dpctl command to be executed after a successfull handshake with - * the remote switch. - * \param dpId The OpenFlow datapath ID. - * \param textCmd The dpctl command to be executed. - * \return 0 if everything's ok, otherwise an error number. - */ - int DpctlSchedule (uint64_t dpId, const std::string textCmd); - /** * Overriding ofsoftswitch13 dpctl_send_and_print and * dpctl_transact_and_print weak functions from utilities/dpctl.c. Send a @@ -373,11 +373,14 @@ class OFSwitch13Controller : public Application /** Map to store barrier information by transaction id */ typedef std::map BarrierMsgMap_t; - /** Multimap saving pair */ - typedef std::multimap DpIdCmdMap_t; + /** Map saving pair */ + typedef std::map > DpIdCmdMap_t; + + /** Map to store switch info by ip address */ + typedef std::map > AddrSwMap_t; - /** Map to store switch info by Address */ - typedef std::map > SwitchsMap_t; + /** Map to store switch info by datapath id */ + typedef std::map > DpIdSwMap_t; uint32_t m_xid; //!< Global transaction idx. uint16_t m_port; //!< Local controller tcp port. @@ -385,8 +388,9 @@ class OFSwitch13Controller : public Application EchoMsgMap_t m_echoMap; //!< Metadata for echo requests. BarrierMsgMap_t m_barrierMap; //!< Metadata for barrier requests. - DpIdCmdMap_t m_schedCommands; //!< Scheduled commands for execution. - SwitchsMap_t m_switchesMap; //!< Registered switches metadata's. + DpIdCmdMap_t m_commandsMap; //!< Commands scheduled for execution. + AddrSwMap_t m_addrSwMap; //!< Registered switches by address. + DpIdSwMap_t m_dpIdSwMap; //!< Registered switches by datapath id. }; } // namespace ns3 diff --git a/model/ofswitch13-device.cc b/model/ofswitch13-device.cc index 6f6da4c..b9b475f 100644 --- a/model/ofswitch13-device.cc +++ b/model/ofswitch13-device.cc @@ -148,6 +148,12 @@ OFSwitch13Device::GetTypeId (void) MakeTraceSourceAccessor ( &OFSwitch13Device::m_loadDropTrace), "ns3::Packet::TracedCallback") + .AddTraceSource ("TableDrop", + "Trace source indicating an unmatched packet dropped by " + "a flow table without a table-miss entry.", + MakeTraceSourceAccessor ( + &OFSwitch13Device::m_tableDropTrace), + "ns3::OFSwitch13Device::TableDropTracedCallback") .AddTraceSource ("PipelinePacket", "Trace source indicating a packet sent to pipeline.", MakeTraceSourceAccessor ( @@ -604,6 +610,14 @@ OFSwitch13Device::MeterDropCallback (struct packet *pkt, dev->NotifyPacketDroppedByMeter (pkt, entry); } +void +OFSwitch13Device::TableDropCallback (struct packet *pkt, + struct flow_table *table) +{ + Ptr dev = OFSwitch13Device::GetDevice (pkt->dp->id); + dev->NotifyPacketDroppedByTable (pkt, table); +} + void OFSwitch13Device::PacketCloneCallback (struct packet *pkt, struct packet *clone) @@ -760,6 +774,7 @@ OFSwitch13Device::DatapathNew () dp->buff_save_cb = &OFSwitch13Device::BufferSaveCallback; dp->buff_retrieve_cb = &OFSwitch13Device::BufferRetrieveCallback; dp->meter_drop_cb = &OFSwitch13Device::MeterDropCallback; + dp->miss_drop_cb = &OFSwitch13Device::TableDropCallback; dp->meter_created_cb = &OFSwitch13Device::MeterCreatedCallback; return dp; @@ -1247,10 +1262,25 @@ OFSwitch13Device::NotifyPacketDroppedByMeter (struct packet *pkt, NS_LOG_DEBUG ("OpenFlow meter id " << meterId << " dropped packet " << pkt->ns3_uid); - // Increase counter and fire drop trace source. + // Fire drop trace source. m_meterDropTrace (m_pipePkt.GetPacket (), meterId); } +void +OFSwitch13Device::NotifyPacketDroppedByTable (struct packet *pkt, + struct flow_table *table) +{ + NS_LOG_FUNCTION (this << pkt->ns3_uid << table->stats->table_id); + + uint8_t tableId = table->stats->table_id; + NS_ASSERT_MSG (m_pipePkt.HasId (pkt->ns3_uid), "Invalid packet ID."); + NS_LOG_DEBUG ("OpenFlow table id " << static_cast (tableId) << + " dropped unmatched packet " << pkt->ns3_uid); + + // Fire drop trace source. + m_tableDropTrace (m_pipePkt.GetPacket (), tableId); +} + void OFSwitch13Device::BufferPacketSave (uint64_t packetId, time_t timeout) { diff --git a/model/ofswitch13-device.h b/model/ofswitch13-device.h index 616a032..5a55285 100644 --- a/model/ofswitch13-device.h +++ b/model/ofswitch13-device.h @@ -303,6 +303,15 @@ class OFSwitch13Device : public Object static void MeterDropCallback (struct packet *pkt, struct meter_entry *entry); + /** + * Callback fired when an unmatched packet is dropped by a flow table without + * a table-miss entry. + * \param pkt The original internal packet. + * \param table The flow table that dropped the packet. + */ + static void + TableDropCallback (struct packet *pkt, struct flow_table *table); + /** * Callback fired when a packet is cloned. * \param pkt The internal original packet. @@ -348,6 +357,15 @@ class OFSwitch13Device : public Object typedef void (*MeterDropTracedCallback)( Ptr packet, uint32_t meterId); + /** + * TracedCallback signature for unmatched packets dropped by flow tables + * without table-miss entries. + * \param packet The dropped packet. + * \param tableId The flow table ID that dropped the packet. + */ + typedef void (*TableDropTracedCallback)( + Ptr packet, uint8_t tableId); + /** * TracedCallback signature for OpenFlow switch device. * \param deve The OpenFlow switch device pointer. @@ -500,6 +518,15 @@ class OFSwitch13Device : public Object void NotifyPacketDroppedByMeter (struct packet *pkt, struct meter_entry *entry); + /** + * Notify this device of an unmatched packet dropped by OpenFlow flow table + * without a table-miss entry. + * \param pkt The ofsoftswitch13 packet. + * \param table The flow table that dropped the packet. + */ + void NotifyPacketDroppedByTable (struct packet *pkt, + struct flow_table *table); + /** * Notify this device of a packet saved into buffer. This method will get the * ns-3 packet in pipeline and save into buffer map. @@ -607,6 +634,9 @@ class OFSwitch13Device : public Object /** Trace source fired when a packet is dropped by a meter band. */ TracedCallback, uint32_t> m_meterDropTrace; + /** Trace source fired when an unmatched packet is dropped by flow table. */ + TracedCallback, uint8_t> m_tableDropTrace; + /** Trace source fired when a packet is sent to pipeline. */ TracedCallback > m_pipePacketTrace; diff --git a/model/ofswitch13-learning-controller.cc b/model/ofswitch13-learning-controller.cc index a9e3f0a..47ec8d6 100644 --- a/model/ofswitch13-learning-controller.cc +++ b/model/ofswitch13-learning-controller.cc @@ -66,9 +66,11 @@ OFSwitch13LearningController::HandlePacketIn ( static int prio = 100; uint32_t outPort = OFPP_FLOOD; - uint64_t dpId = swtch->GetDpId (); enum ofp_packet_in_reason reason = msg->reason; + // Get the switch datapath ID + uint64_t swDpId = swtch->GetDpId (); + char *msgStr = ofl_structs_match_to_string ((struct ofl_match_header*)msg->match, 0); NS_LOG_DEBUG ("Packet in match: " << msgStr); @@ -94,7 +96,7 @@ OFSwitch13LearningController::HandlePacketIn ( dst48.CopyFrom (ethDst->value); // Get L2Table for this datapath - auto it = m_learnedInfo.find (dpId); + auto it = m_learnedInfo.find (swDpId); if (it != m_learnedInfo.end ()) { L2Table_t *l2Table = &it->second; @@ -136,7 +138,7 @@ OFSwitch13LearningController::HandlePacketIn ( cmd << "flow-mod cmd=add,table=0,idle=10,flags=0x0001" << ",prio=" << ++prio << " eth_dst=" << src48 << " apply:output=" << inPort; - DpctlExecute (swtch, cmd.str ()); + DpctlExecute (swDpId, cmd.str ()); } } else @@ -147,7 +149,7 @@ OFSwitch13LearningController::HandlePacketIn ( } else { - NS_LOG_ERROR ("No L2 table for this datapath id " << dpId); + NS_LOG_ERROR ("No L2 table for this datapath id " << swDpId); } // Lets send the packet out to switch. @@ -195,9 +197,11 @@ OFSwitch13LearningController::HandleFlowRemoved ( { NS_LOG_FUNCTION (this << swtch << xid); + // Get the switch datapath ID + uint64_t swDpId = swtch->GetDpId (); + NS_LOG_DEBUG ( "Flow entry expired. Removing from L2 switch table."); - uint64_t dpId = swtch->GetDpId (); - auto it = m_learnedInfo.find (dpId); + auto it = m_learnedInfo.find (swDpId); if (it != m_learnedInfo.end ()) { Mac48Address mac48; @@ -225,22 +229,23 @@ OFSwitch13LearningController::HandshakeSuccessful ( { NS_LOG_FUNCTION (this << swtch); + // Get the switch datapath ID + uint64_t swDpId = swtch->GetDpId (); + // After a successfull handshake, let's install the table-miss entry, setting // to 128 bytes the maximum amount of data from a packet that should be sent // to the controller. - DpctlExecute (swtch, "flow-mod cmd=add,table=0,prio=0 " + DpctlExecute (swDpId, "flow-mod cmd=add,table=0,prio=0 " "apply:output=ctrl:128"); // Configure te switch to buffer packets and send only the first 128 bytes of // each packet sent to the controller when not using an output action to the // OFPP_CONTROLLER logical port. - DpctlExecute (swtch, "set-config miss=128"); + DpctlExecute (swDpId, "set-config miss=128"); // Create an empty L2SwitchingTable and insert it into m_learnedInfo L2Table_t l2Table; - uint64_t dpId = swtch->GetDpId (); - - std::pair entry (dpId, l2Table); + std::pair entry (swDpId, l2Table); auto ret = m_learnedInfo.insert (entry); if (ret.second == false) { diff --git a/model/ofswitch13-queue.cc b/model/ofswitch13-queue.cc index ba64221..20d9de3 100644 --- a/model/ofswitch13-queue.cc +++ b/model/ofswitch13-queue.cc @@ -87,7 +87,7 @@ OFSwitch13Queue::Enqueue (Ptr packet) // Enqueue the packet in this queue too. // This is necessary to ensure consistent statistics. Otherwise, when the // NetDevice calls the IsEmpty () method, it will return true. - DoEnqueue (Tail (), packet); + DoEnqueue (end (), packet); } else { @@ -210,7 +210,7 @@ OFSwitch13Queue::NotifyDequeue (Ptr packet) // Dequeue the packet from this queue too. As we don't know the // exactly packet location on this queue, we have to look for it. - for (auto it = Head (); it != Tail (); it++) + for (auto it = begin (); it != end (); it++) { if ((*it) == packet) { @@ -228,7 +228,7 @@ OFSwitch13Queue::NotifyRemove (Ptr packet) // Remove the packet from this queue too. As we don't know the // exactly packet location on this queue, we have to look for it. - for (auto it = Head (); it != Tail (); it++) + for (auto it = begin (); it != end (); it++) { if ((*it) == packet) { diff --git a/utils/ofswitch13-doc-3_29.patch b/utils/ofswitch13-doc-3_29.patch deleted file mode 100644 index b1038b7..0000000 --- a/utils/ofswitch13-doc-3_29.patch +++ /dev/null @@ -1,87 +0,0 @@ -diff --git a/doc/main.h b/doc/main.h ---- a/doc/main.h -+++ b/doc/main.h -@@ -51,6 +51,7 @@ - * - nix-vector-routing - * - ns3tcp - * - ns3wifi -+ * - ofswitch13 - * - olsr - * - openflow - * - point-to-point -diff --git a/doc/models/Makefile b/doc/models/Makefile ---- a/doc/models/Makefile -+++ b/doc/models/Makefile -@@ -67,6 +67,10 @@ - $(SRC)/internet/doc/udp.rst \ - $(SRC)/internet-apps/doc/internet-apps.rst \ - $(SRC)/mobility/doc/mobility.rst \ -+ $(SRC)/ofswitch13/doc/source/ofswitch13.rst \ -+ $(SRC)/ofswitch13/doc/source/ofswitch13-description.rst \ -+ $(SRC)/ofswitch13/doc/source/ofswitch13-usage.rst \ -+ $(SRC)/ofswitch13/doc/source/ofswitch13-validation.rst \ - $(SRC)/olsr/doc/olsr.rst \ - $(SRC)/openflow/doc/openflow-switch.rst \ - $(SRC)/point-to-point/doc/point-to-point.rst \ -@@ -285,6 +289,12 @@ - $(SRC)/netanim/doc/figures/RoutingTables.pdf \ - $(SRC)/netanim/doc/figures/PacketTimeline.png \ - $(SRC)/netanim/doc/figures/PacketTimeline.pdf \ -+ $(SRC)/ofswitch13/doc/source/figures/ofswitch13-controller.eps \ -+ $(SRC)/ofswitch13/doc/source/figures/ofswitch13-library.eps \ -+ $(SRC)/ofswitch13/doc/source/figures/ofswitch13-module.eps \ -+ $(SRC)/ofswitch13/doc/source/figures/ofswitch13-qos-topology.eps \ -+ $(SRC)/ofswitch13/doc/source/figures/ofswitch13-queue.eps \ -+ $(SRC)/ofswitch13/doc/source/figures/ofswitch13-switch.eps \ - $(SRC)/spectrum/doc/spectrum-channel-phy-interface.png \ - $(SRC)/spectrum/doc/spectrum-channel-phy-interface.pdf \ - $(SRC)/spectrum/doc/spectrum-analyzer-example.eps \ -@@ -382,6 +392,12 @@ - $(FIGURES)/lr-wpan-primitives.eps \ - $(FIGURES)/lr-wpan-data-example.eps \ - $(FIGURES)/lr-wpan-arch.eps \ -+ $(FIGURES)/ofswitch13-controller.eps \ -+ $(FIGURES)/ofswitch13-library.eps \ -+ $(FIGURES)/ofswitch13-module.eps \ -+ $(FIGURES)/ofswitch13-qos-topology.eps \ -+ $(FIGURES)/ofswitch13-queue.eps \ -+ $(FIGURES)/ofswitch13-switch.eps \ - $(FIGURES)/802-15-4-ber.eps \ - $(FIGURES)/802-15-4-per-sens.eps \ - $(FIGURES)/802-15-4-psr-distance.eps \ -@@ -449,6 +465,12 @@ - $(FIGURES)/spectrum-tv-rand-geo-points.pdf_width = 8cm - $(FIGURES)/lr-wpan-primitives.pdf_width = 3in - $(FIGURES)/lr-wpan-arch.pdf_width = 2in -+$(FIGURES)/ofswitch13-controller.pdf_width = 10cm -+$(FIGURES)/ofswitch13-library.pdf_width = 14cm -+$(FIGURES)/ofswitch13-module.pdf_width = 14cm -+$(FIGURES)/ofswitch13-qos-topology.pdf_width = 12cm -+$(FIGURES)/ofswitch13-queue.pdf_width = 10cm -+$(FIGURES)/ofswitch13-switch.pdf_width = 10cm - $(FIGURES)/clear-channel.pdf_width = 12cm - $(FIGURES)/nist-frame-success-rate.pdf_width = 12cm - $(FIGURES)/nist-frame-success-rate-n.pdf_width = 12cm -diff --git a/doc/models/source/index.rst b/doc/models/source/index.rst ---- a/doc/models/source/index.rst -+++ b/doc/models/source/index.rst -@@ -40,6 +40,7 @@ - mobility - network - nix-vector-routing -+ ofswitch13 - olsr - openflow-switch - point-to-point -diff --git a/doc/ns3_html_theme/get_version.sh b/doc/ns3_html_theme/get_version.sh ---- a/doc/ns3_html_theme/get_version.sh -+++ b/doc/ns3_html_theme/get_version.sh -@@ -191,7 +191,7 @@ - echo "// ns3_version.js: automatically generated" > $outf - echo "// private urls" >> $outf - echo "var ns3_host = \"file://$PWD/\";" > $outf -- echo "var ns3_version = \"$repo @ $version$dirty\";" >> $outf -+ echo "var ns3_version = \"ns-3.29 + OFSwitch13 4.0.0\";" >> $outf - echo "var ns3_release = \"doc/\";" >> $outf - echo "var ns3_local = \"build/\";" >> $outf - echo "var ns3_doxy = \"html/\";" >> $outf diff --git a/utils/ofswitch13-doc-3_28.patch b/utils/ofswitch13-doc-3_30.patch similarity index 90% rename from utils/ofswitch13-doc-3_28.patch rename to utils/ofswitch13-doc-3_30.patch index 16ca283..396abbb 100644 --- a/utils/ofswitch13-doc-3_28.patch +++ b/utils/ofswitch13-doc-3_30.patch @@ -12,7 +12,7 @@ diff --git a/doc/main.h b/doc/main.h diff --git a/doc/models/Makefile b/doc/models/Makefile --- a/doc/models/Makefile +++ b/doc/models/Makefile -@@ -67,6 +67,10 @@ +@@ -67,6 +67,10 @@ SOURCES = \ $(SRC)/internet/doc/udp.rst \ $(SRC)/internet-apps/doc/internet-apps.rst \ $(SRC)/mobility/doc/mobility.rst \ @@ -23,7 +23,7 @@ diff --git a/doc/models/Makefile b/doc/models/Makefile $(SRC)/olsr/doc/olsr.rst \ $(SRC)/openflow/doc/openflow-switch.rst \ $(SRC)/point-to-point/doc/point-to-point.rst \ -@@ -279,6 +283,12 @@ +@@ -302,6 +306,12 @@ SOURCEFIGS = \ $(SRC)/netanim/doc/figures/RoutingTables.pdf \ $(SRC)/netanim/doc/figures/PacketTimeline.png \ $(SRC)/netanim/doc/figures/PacketTimeline.pdf \ @@ -36,7 +36,7 @@ diff --git a/doc/models/Makefile b/doc/models/Makefile $(SRC)/spectrum/doc/spectrum-channel-phy-interface.png \ $(SRC)/spectrum/doc/spectrum-channel-phy-interface.pdf \ $(SRC)/spectrum/doc/spectrum-analyzer-example.eps \ -@@ -376,6 +386,12 @@ +@@ -404,6 +414,12 @@ IMAGES_EPS = \ $(FIGURES)/lr-wpan-primitives.eps \ $(FIGURES)/lr-wpan-data-example.eps \ $(FIGURES)/lr-wpan-arch.eps \ @@ -49,7 +49,7 @@ diff --git a/doc/models/Makefile b/doc/models/Makefile $(FIGURES)/802-15-4-ber.eps \ $(FIGURES)/802-15-4-per-sens.eps \ $(FIGURES)/802-15-4-psr-distance.eps \ -@@ -443,6 +459,12 @@ +@@ -476,6 +492,12 @@ $(FIGURES)/spectrum-analyzer-example.pdf_width = 15cm $(FIGURES)/spectrum-tv-rand-geo-points.pdf_width = 8cm $(FIGURES)/lr-wpan-primitives.pdf_width = 3in $(FIGURES)/lr-wpan-arch.pdf_width = 2in @@ -65,7 +65,7 @@ diff --git a/doc/models/Makefile b/doc/models/Makefile diff --git a/doc/models/source/index.rst b/doc/models/source/index.rst --- a/doc/models/source/index.rst +++ b/doc/models/source/index.rst -@@ -40,6 +40,7 @@ +@@ -40,6 +40,7 @@ This document is written in `reStructuredText $outf echo "// private urls" >> $outf echo "var ns3_host = \"file://$PWD/\";" > $outf - echo "var ns3_version = \"$repo @ $version$dirty\";" >> $outf -+ echo "var ns3_version = \"ns-3.28 + OFSwitch13 4.0.0\";" >> $outf ++ echo "var ns3_version = \"ns-3.30 + OFSwitch13 5.0.0\";" >> $outf echo "var ns3_release = \"doc/\";" >> $outf echo "var ns3_local = \"build/\";" >> $outf echo "var ns3_doxy = \"html/\";" >> $outf diff --git a/utils/ofswitch13-src-3_29.patch b/utils/ofswitch13-src-3_29.patch deleted file mode 100644 index 7e95993..0000000 --- a/utils/ofswitch13-src-3_29.patch +++ /dev/null @@ -1,151 +0,0 @@ -diff --git a/src/csma/model/csma-net-device.cc b/src/csma/model/csma-net-device.cc ---- a/src/csma/model/csma-net-device.cc -+++ b/src/csma/model/csma-net-device.cc -@@ -831,6 +831,30 @@ - packetType = PACKET_OTHERHOST; - } - -+ // -+ // Check if this device is configure as an OpenFlow switch port. -+ // -+ if (!m_openFlowRxCallback.IsNull ()) -+ { -+ // For all kinds of packet we receive, we hit the promiscuous sniffer -+ // hook. If the packet is addressed to this device (which is not supposed -+ // to happen in normal situations), we also hit the non-promiscuous -+ // sniffer hook, but in both cases we don't forward the packt up the -+ // stack. -+ m_promiscSnifferTrace (originalPacket); -+ if (packetType != PACKET_OTHERHOST) -+ { -+ m_snifferTrace (originalPacket); -+ } -+ -+ // We forward the original packet (which includes the EthernetHeader) to -+ // the OpenFlow receive callback for all kinds of packetType we receive -+ // (broadcast, multicast, host or other host). -+ m_openFlowRxCallback (this, originalPacket, protocol, -+ header.GetSource (), header.GetDestination (), packetType); -+ return; -+ } -+ - // - // For all kinds of packetType we receive, we hit the promiscuous sniffer - // hook and pass a copy up to the promiscuous callback. Pass a copy to -@@ -1056,6 +1080,13 @@ - } - - void -+CsmaNetDevice::SetOpenFlowReceiveCallback (NetDevice::PromiscReceiveCallback cb) -+{ -+ NS_LOG_FUNCTION (&cb); -+ m_openFlowRxCallback = cb; -+} -+ -+void - CsmaNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) - { - NS_LOG_FUNCTION (&cb); -diff --git a/src/csma/model/csma-net-device.h b/src/csma/model/csma-net-device.h ---- a/src/csma/model/csma-net-device.h -+++ b/src/csma/model/csma-net-device.h -@@ -308,6 +308,14 @@ - virtual bool NeedsArp (void) const; - - /** -+ * Set the callback used to notify the OpenFlow when a packet has been -+ * received by this device. -+ * -+ * \param cb The callback. -+ */ -+ virtual void SetOpenFlowReceiveCallback (NetDevice::PromiscReceiveCallback cb); -+ -+ /** - * Set the callback to be used to notify higher layers when a packet has been - * received. - * -@@ -698,6 +706,11 @@ - Mac48Address m_address; - - /** -+ * The OpenFlow receive callback. -+ */ -+ NetDevice::PromiscReceiveCallback m_openFlowRxCallback; -+ -+ /** - * The callback used to notify higher layers that a packet has been received. - */ - NetDevice::ReceiveCallback m_rxCallback; -diff --git a/src/virtual-net-device/model/virtual-net-device.cc b/src/virtual-net-device/model/virtual-net-device.cc ---- a/src/virtual-net-device/model/virtual-net-device.cc -+++ b/src/virtual-net-device/model/virtual-net-device.cc -@@ -141,6 +141,29 @@ - const Address &source, const Address &destination, - PacketType packetType) - { -+ // -+ // Check if this device is configure as an OpenFlow switch port. -+ // -+ if (!m_openFlowRxCallback.IsNull ()) -+ { -+ // For all kinds of packetType we receive, we hit the promiscuous sniffer -+ // hook. If the packet is addressed to this device (which is not supposed -+ // to happen in normal situations), we also hit the non-promiscuous -+ // sniffer hook, but in both cases we don't forward the packt up the -+ // stack. -+ m_promiscSnifferTrace (packet); -+ if (packetType != PACKET_OTHERHOST) -+ { -+ m_snifferTrace (packet); -+ } -+ -+ // We then forward the original packet to the OpenFlow receive callback -+ // for all kinds of packetType we receive (broadcast, multicast, host or -+ // other host). -+ m_openFlowRxCallback (this, packet, protocol, source, destination, packetType); -+ return true; -+ } -+ - // - // For all kinds of packetType we receive, we hit the promiscuous sniffer - // hook and pass a copy up to the promiscuous callback. Pass a copy to -@@ -314,5 +337,11 @@ - return false; - } - -+void -+VirtualNetDevice::SetOpenFlowReceiveCallback (NetDevice::PromiscReceiveCallback cb) -+{ -+ NS_LOG_FUNCTION (&cb); -+ m_openFlowRxCallback = cb; -+} - - } // namespace ns3 -diff --git a/src/virtual-net-device/model/virtual-net-device.h b/src/virtual-net-device/model/virtual-net-device.h ---- a/src/virtual-net-device/model/virtual-net-device.h -+++ b/src/virtual-net-device/model/virtual-net-device.h -@@ -146,6 +146,14 @@ - virtual bool SupportsSendFrom () const; - virtual bool IsBridge (void) const; - -+ /** -+ * Set the callback used to notify the OpenFlow when a packet has been -+ * received by this device. -+ * -+ * \param cb The OpenFlow receive callback. -+ */ -+ virtual void SetOpenFlowReceiveCallback (NetDevice::PromiscReceiveCallback cb); -+ - protected: - - virtual void DoDispose (void); -@@ -168,6 +176,9 @@ - bool m_needsArp; - bool m_supportsSendFrom; - bool m_isPointToPoint; -+ -+ /** The OpenFlow receive callback. */ -+ NetDevice::PromiscReceiveCallback m_openFlowRxCallback; - }; - - } // namespace ns3 diff --git a/utils/ofswitch13-src-3_28.patch b/utils/ofswitch13-src-3_30.patch similarity index 91% rename from utils/ofswitch13-src-3_28.patch rename to utils/ofswitch13-src-3_30.patch index 7e95993..dcca9f9 100644 --- a/utils/ofswitch13-src-3_28.patch +++ b/utils/ofswitch13-src-3_30.patch @@ -1,7 +1,7 @@ diff --git a/src/csma/model/csma-net-device.cc b/src/csma/model/csma-net-device.cc --- a/src/csma/model/csma-net-device.cc +++ b/src/csma/model/csma-net-device.cc -@@ -831,6 +831,30 @@ +@@ -795,6 +795,30 @@ CsmaNetDevice::Receive (Ptr packet, Ptr senderDevice) packetType = PACKET_OTHERHOST; } @@ -32,54 +32,54 @@ diff --git a/src/csma/model/csma-net-device.cc b/src/csma/model/csma-net-device. // // For all kinds of packetType we receive, we hit the promiscuous sniffer // hook and pass a copy up to the promiscuous callback. Pass a copy to -@@ -1056,6 +1080,13 @@ +@@ -1019,6 +1043,13 @@ CsmaNetDevice::NeedsArp (void) const + return true; } - void ++void +CsmaNetDevice::SetOpenFlowReceiveCallback (NetDevice::PromiscReceiveCallback cb) +{ + NS_LOG_FUNCTION (&cb); + m_openFlowRxCallback = cb; +} + -+void + void CsmaNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb) { - NS_LOG_FUNCTION (&cb); diff --git a/src/csma/model/csma-net-device.h b/src/csma/model/csma-net-device.h --- a/src/csma/model/csma-net-device.h +++ b/src/csma/model/csma-net-device.h -@@ -308,6 +308,14 @@ +@@ -306,6 +306,14 @@ public: + */ virtual bool NeedsArp (void) const; - /** ++ /** + * Set the callback used to notify the OpenFlow when a packet has been + * received by this device. + * + * \param cb The callback. + */ + virtual void SetOpenFlowReceiveCallback (NetDevice::PromiscReceiveCallback cb); -+ -+ /** ++ + /** * Set the callback to be used to notify higher layers when a packet has been * received. - * -@@ -698,6 +706,11 @@ +@@ -688,6 +696,11 @@ private: + */ Mac48Address m_address; - /** ++ /** + * The OpenFlow receive callback. + */ + NetDevice::PromiscReceiveCallback m_openFlowRxCallback; -+ -+ /** ++ + /** * The callback used to notify higher layers that a packet has been received. */ - NetDevice::ReceiveCallback m_rxCallback; diff --git a/src/virtual-net-device/model/virtual-net-device.cc b/src/virtual-net-device/model/virtual-net-device.cc --- a/src/virtual-net-device/model/virtual-net-device.cc +++ b/src/virtual-net-device/model/virtual-net-device.cc -@@ -141,6 +141,29 @@ +@@ -141,6 +141,29 @@ VirtualNetDevice::Receive (Ptr packet, uint16_t protocol, const Address &source, const Address &destination, PacketType packetType) { @@ -109,7 +109,7 @@ diff --git a/src/virtual-net-device/model/virtual-net-device.cc b/src/virtual-ne // // For all kinds of packetType we receive, we hit the promiscuous sniffer // hook and pass a copy up to the promiscuous callback. Pass a copy to -@@ -314,5 +337,11 @@ +@@ -314,5 +337,11 @@ bool VirtualNetDevice::IsBridge (void) const return false; } @@ -124,7 +124,7 @@ diff --git a/src/virtual-net-device/model/virtual-net-device.cc b/src/virtual-ne diff --git a/src/virtual-net-device/model/virtual-net-device.h b/src/virtual-net-device/model/virtual-net-device.h --- a/src/virtual-net-device/model/virtual-net-device.h +++ b/src/virtual-net-device/model/virtual-net-device.h -@@ -146,6 +146,14 @@ +@@ -146,6 +146,14 @@ public: virtual bool SupportsSendFrom () const; virtual bool IsBridge (void) const; @@ -139,7 +139,7 @@ diff --git a/src/virtual-net-device/model/virtual-net-device.h b/src/virtual-net protected: virtual void DoDispose (void); -@@ -168,6 +176,9 @@ +@@ -168,6 +176,9 @@ private: bool m_needsArp; bool m_supportsSendFrom; bool m_isPointToPoint;