diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..75a9a52 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,7 @@ +# EditorConfig is awesome: https://EditorConfig.org + +# top-most EditorConfig file +root = false + +[*.md] +trim_trailing_whitespace = false diff --git a/CMakeLists.txt b/CMakeLists.txt index 0592252..d1fff1c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -163,7 +163,7 @@ build_lib( TEST_SOURCES ${test_sources} ) -# Add BOFUSS dependecy to OFSwitch13 module +# Add BOFUSS dependency to OFSwitch13 module if(NOT bofuss_FOUND AND NOT ${bofuss_FOUND}) add_dependencies(${libofswitch13} bofuss_dep) if(NOT ${XCODE}) diff --git a/README.md b/README.md index b5ed08d..6cc5a2c 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,34 @@ -# OpenFlow 1.3 module for ns-3 # -This is the OFSwitch13 module, which enhances the [ns-3 Network Simulator][ns-3] with [OpenFlow 1.3][ofp13] capabilities, allowing ns-3 users to simulate Software-Defined Networks (SDN). In fact, this module implements the interface for interconnecting the ns-3 simulator to the [BOFUSS library][ofs13]. This library provides the switch implementation, the support for converting to/from OpenFlow 1.3 wire format, and the dpctl tool for configuring the switch from the console. - -Please, visit the [OFSwitch13 project homepage][project] for detailed information on the module design, documentation, and *how to get started* tutorials. -The code API documentation for the latest release of this project is available [here][apidoc]. - -# Contribute # -Please, contribute to this project submitting your bug reports to the [issue tracker][issues]. For fixes and improvements, consider creating a pull request. - -# License # -The OFSwitch13 module is free software, licensed under the [GNU GPLv2 license][gpl], and is publicly available for research, development, and use. - -# Acknowledgments # -Thanks to the main contributors: - -* Luciano Jerez Chaves -* Vítor Marge Eichemberger -* Islene Calciolari Garcia -* Arthur Boeacht Mazzi -* *"Your name here"* - -# Contact # -Feel free to subscribe to [our mailing list at Google groups][group] and provide some feedback, give us suggestions, interact with other users, or to just say hello! - -[ns-3]: https://www.nsnam.org -[ofp13]: https://www.opennetworking.org/sdn-resources/technical-library -[ofs13]: https://github.com/ljerezchaves/ofsoftswitch13 -[project]: http://www.lrc.ic.unicamp.br/ofswitch13/ -[apidoc]: http://www.lrc.ic.unicamp.br/ofswitch13/latest/doc/html/index.html -[issues]: https://github.com/ljerezchaves/ofswitch13-module/issues -[gpl]: http://www.gnu.org/copyleft/gpl.html -[group]: https://groups.google.com/forum/#!forum/ofswitch13-users +# OpenFlow 1.3 module for ns-3 + +The OFSwitch13 module enhances the [ns-3 Network Simulator][ns-3] with Software-Defined Networking (SDN) capabilities. +OFSwitch13 supports [OpenFlow protocol version 1.3][ofp13], bringing a switch device and a controller application interface to the ns-3 simulator. +With OFSwitch13, it is possible to interconnect ns-3 nodes to send and receive traffic using the existing CSMA and virtual network devices. +Extending the controller application interface allows users to implement any desired control logic to orchestrate the network. +The communication between the controller and the switches happens over standard ns-3 protocol stack, devices, and channels. +The OFSwitch13 module relies on the external [BOFUSS library][bofuss] that provides the switch datapath implementation and the support for OpenFlow messages in wire format. + +Please visit the [OFSwitch13 project homepage][project] and refer to the documentation for details about the module design, installation, and usage. + +## License + +The OFSwitch13 module is a free software licensed under the [GNU GPLv2 license][gpl]. + +## Contribute + +The OFSwitch13 module is currently maintained by Luciano Jerez Chaves. +It also received contributions from Vítor Marge Eichemberger, Islene Calciolari Garcia, Arthur Boechat Mazzi, and Pasquale Imputato. +We thank Eder Leão Fernandes for helping with the BOFUSS library integration. + +Please contribute to this project by submitting your bug reports to the [issue tracker][issues]. For fixes and improvements, consider creating a pull request. + +## Contact + +Feel free to subscribe to the [mailing list at Google Groups][group] and provide feedback, give suggestions, interact with other users, or say hello! + +[ns-3]: https://www.nsnam.org +[ofp13]: https://www.opennetworking.org/sdn-resources/technical-library +[bofuss]: https://github.com/ljerezchaves/ofsoftswitch13 +[project]: http://www.lrc.ic.unicamp.br/ofswitch13/ +[issues]: https://github.com/ljerezchaves/ofswitch13-module/issues +[gpl]: http://www.gnu.org/copyleft/gpl.html +[group]: https://groups.google.com/forum/#!forum/ofswitch13-users diff --git a/RELEASE_NOTES b/RELEASE_NOTES deleted file mode 100644 index ecc814f..0000000 --- a/RELEASE_NOTES +++ /dev/null @@ -1,470 +0,0 @@ -++++++++++++++++++++++++ -OFSwitch13 release notes -++++++++++++++++++++++++ - -This file contains OFSwitch13 release notes (most recent releases first). - -Release 5.2.2 (Sep 01, 2023) -============================ - -- Removing examples/ofswitch13-qos-controller dependency from netanim module. - -- Updating buffer timeout operation with millisecond resolution. - -- Updating the maximum size of the parent OFSwitch13Queue class with the sum of - maximum size of internal queues. The operation mode (packets or bytes) of all - internal queues must be the same. - -- This version is compatible with ns-3 versions 3.38 and 3.39 (including - patches). There is no backward compatibility with older ns-3 versions. - -- Compilation was tested in Ubuntu 22.04.1 LTS. - - -Release 5.2.1 (Mar 31, 2023) -============================ - -- Replacing V4PingHelper by PingHelper in examples for ns-3.38 compatibility. - -- This version is compatible with ns-3 version 3.38 (including patches). There - is no backward compatibility with older ns-3 versions. - -- Compilation was tested in Ubuntu 22.04.1 LTS. - - -Release 5.2.0 (Mar 31, 2023) -============================ - -- Updating CMakeLists.txt to automatically download and build the BOFUSS - library. - -- Updating the module documentation to reflect the changes in library building. - -- Replacing the outdated ofsoftswitch13 library name by BOFUSS in the project - (source code and documentation). - -- Refactoring the BOFUSS ns3lib branch to simplify library compilation. - -- This version is compatible with ns-3 versions 3.36 and 3.37 (including - patches). There is no backward compatibility with older ns-3 versions. - -- Compilation was tested in Ubuntu 22.04.1 LTS. - - -Release 5.1.0 (Dec 10, 2022) -============================ - -- Updating the build system to work with CMake to match ns-3.36. - -- Updating the source code formatting to match ns-3.37. - -- Updating the module documentation, removing outdated figures. - -- New CSMA full-duplex patch for improved channel operation. - -- Fixing errors when compiling the project with gcc 11.3.0 in Ubuntu 22.04.1. - -- This version is compatible with ofsoftswitch13 library release v5.1.x and - ns-3 versions 3.36 and 3.37 (including patches). There is no backward - compatibility with older ns-3 versions. - -- Compilation was tested in Ubuntu 22.04.1 LTS. - - -Release 5.0.1 (Dec 20, 2021) -============================ - -- Updating OFSwitch13Queue for compatibility with the ns-3 queue API. - -- Removing DL library dependency to prevent issues with boost library. - -- This version is compatible with ofsoftswitch13 library release v5.0.x and - ns-3 version 3.31 to 3.35 (including patches). There is no backward - compatibility with older ns-3 versions. - -- Compilation was tested in Ubuntu 20.04.3 LTS. - - -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) -============================ - -- BE AWARE THAT this release brings incompatible API changes in respect to - prior OFSwitch13 versions. - -- Refactoring the OpenFlow queue: - * The OFSwitch13Queue base class implements the queue interface, extending - the ns3::Queue class to allow compatibility with the CsmaNetDevice - used by OFSwitch13Port. Internally, it holds a collection of N (possibly - different) queues, identified by IDs ranging from 0 to N-1. The Enqueue - method uses the ns3::QueueTag to identify which internal queue will hold - the packet. - * Specialized subclasses can perform different output scheduling algorithms - by implementing the Peek, Dequeue, and Remove methods. The last two methods - must call the NotifyDequeue and NotifyRemoved methods respectively, which - are used to update statistics and keep consistency with the base class. - * The OFSwitch13PriorityQueue implements the specialized priority queuing - discipline for a collection of N priority queues, identified by IDs ranging - from 0 to N-1 with decreasing priority (queue ID 0 has the highest - priority). The output scheduling algorithm ensures that higher-priority - queues are "always" served first. The OFSwitch13PriorityQueue::QueueFactory - and OFSwitch13PriorityQueue::NumQueues attributes can be used to configure - the type and the number of internal priority queues, respectively. - * The OpenFlow port queue can be configured by the - OFSwitch13Port::QueueFactory attribute at construction time. - -- Overriding the OFSwitch13Helper::InstallSwitch method. When the first - parameter is a node container, the method returns an OpenFlow device - container. When the first parameter is a node pointer, the method returns the - OpenFlow device pointer. For the latter, there's the optional second - parameter of a device container that will be configured as switch ports. - -- The OFSwitch13Device::FlowTableSize, GroupTableSize, and MeterTableSize - attributes can now be adjusted at any time. - -- New OFSwitch13Port::GetPortDevice, GetPortQueue and GetSwitchDevice methods. - -- New OFSwitch13Device::GetDpId method as an alias for the GetDatapathId - method. - -- New OFSwitch13Device::GetDatapathStruct and OFSwitch13Port::GetPortStruct - methods returning a pointer to the ofsoftswitch13 library structures. - -- Renaming OFSwitch13Device::GetOFSwitch13Port method to GetSwitchPort. - -- Renaming OFSwitch13Device attributes and trace sources to better reflect what - they really represent: PipelineCapacity attribute was renamed to CpuCapacity, - PipelineLoad traced value was renamed to CpuLoad, and LoadDrop trace source - was renamed to OverloadDrop. The methods GetPipelineLoad and - GetPipelineCapacity were also renamed to GetCpuLoad and GetCpuCapacity. These - changes also reflects on the OFSwitch13StatsCalculator: GetEwmaPipelineLoad - and GetAvgPipelineUsage were renamed to GetEwmaCpuLoad and GetAvgCpuUsage. - -- Updating OFSwitch13Device::Get* methods for improved datapath stats. The - GetFlowEntries, GetGroupEntries, and GetMeterEntries methods were replaced by - GetFlowTableEntries, GetGroupTableEntries, and GetMeterTableEntries. The - following new methods were included: GetDatapathTimeout, GetFlowTableUsage, - GetGroupTableUsage, GetMeterTableUsage, GetNControllers, GetBufferEntries, - GetBufferSize. The BufferUsage traced value was removed, but the method with - the same can be used to get this value on demand. - -- Improving OFSwitch13StatsCalculator with more statistics. It can now dump - individual flow table stats. This is an optional feature (disabled by - default), that can be enabled by the FlowTableDetails attribute. - -- Renaming OFSwitch13StatsCalculator column names in first row, removing any - special character from them. - -- Increasing the maximum number of OpenFlow switch ports to 4096 - (see DP_MAX_PORTS at lib/ofsoftswitch13/udatapath/dp_ports.h) - -- Increasing the maximum number of output queues on ports to 32 - (see NETDEV_MAX_QUEUES at lib/ofsoftswitch13/lib/netdev.h) - -- Removing the NetBee library dependence when compiling the ofsoftswitch13 - library. The packet inspection is now performed by the packet_parse method - at lib/ofsoftswitch13/udatapath/packet_handle_std.c. - -- Improving ofsoftswitch13 library performance and fixing memory leak errors. - -- 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 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) -============================ - -- Fix incorrect bitwise comparison when checking port configuration. - -- Fix incorrect ns-3 version comparison that was preventing module - configuration in ns-3.28.1 - -- Introducing a new OFSwitch13Device PipelineTables attribute, allowing a - custom number of pipeline flow tables in the switch. - -- The OFSwitch13Device PipelineTables, FlowTableSize, GroupTableSize, and - MeterTableSize attributes must now be adjusted at construction time. You can - use the OFSwitch13Helper::SetDeviceAttribute to accomplish this task. - -- Renaming OFSwitch13Device::GetFlowEntries (void) to GetSumFlowEntries (void) - and the OFSwitch13StatsCalculator::GetEwmaFlowEntries (void) to - GetEwmaSumFlowEntries (void) to better describe that these methods return the - sum of entries in all pipeline tables. - -- Merging new commits from the CPqD ofsoftswitch13 library. - -- Preparing patches for ns-3.29. - -- This version is compatible with ofsoftswitch13 library release v3.3.x and - ns-3 versions 3.28 and 3.29 (including patches). There is no backward - compatibility with older ns-3 versions. - - -Release 3.2.2 (Jul 05, 2018) -============================ - -- Fixing errors when compiling the project with gcc 7.3.0 in Ubuntu 18.04. - -- Moving the project from the mercurial repository in the BitBucket to a new - git repository in the GitHub, and updating the documentation to reflect these - changes. - -- Configuring the ofsoftswitch13 project as a submodule within the OFSwitch13 - project, which will automatically handle source code compatibility. - -- Updating the waf configuration script to automatically detect the library - source code at lib/ofsoftswitch13 folder. - -- This version is compatible with ofsoftswitch13 library release v3.2.x and - ns-3 version 3.28 (including patches). There is no backward compatibility - with older ns-3 versions. - - -Release 3.2.1 (May 22, 2018) -============================ - -- Updating OFSwitch13Queue and OFSwitch13InternalHelper to avoid using - deprecated ns-3 queue API when setting queue size and mode. - -- This version is compatible with ofsoftswitch13 library release v3.2.x and - ns-3 version 3.28 (including patches). There is no backward compatibility - with older ns-3 versions. - - -Release 3.2.0 (May 22, 2018) -============================ - -- Updating OFSwitch13Queue to make it work with ns-3.27 release. Special thanks - to Stefano Avallone for improving ns-3 queue environment and providing the - patch to update OFSwitch13. - -- Fixing the NetBee library repository link on module documentation. - -- This version is compatible with ofsoftswitch13 library release v3.2.x and - ns-3 version 3.27 (including patches). There is no backward compatibility - with older ns-3 versions. - - -Release 3.1.1 (May 12, 2018) -============================ - -- Including a new counter on the OFSwitch13StatsCalculator to measure the - pipeline load regarding the number of packets. - -- New OFSwitch13Queue::QueueFactory attribute for the object factory used to - create internal OpenFlow queues on output ports. - -- Fixing small bugs when handling packet tags and refilling meter tokens. - -- This version is compatible with ofsoftswitch13 library release v3.1.x and - ns-3 version 3.26 (including patches). There is no backward compatibility - with older ns-3 versions. - - -Release 3.1.0 (May 29, 2017) -============================ - -- Improving the OFSwitch13Device with the PipelineCapacity attribute that can - be used to limit the traffic throughput within the pipeline to a specific - data rate. - -- Improving the OFSwitch13Device with the FlowTableSize, GroupTableSize, and - MeterTableSize attributes, that can be used to define the maximum number of - entries in pipeline tables. - -- Improving the OFSwitch13Queue with the NumQueues attribute that can be used - to define the number of output queues available for use. - -- Updating some ofsoftswitch13 library defines to allow more entries on each - datapath table (flow, meter, and group). - -- Including the meter ID parameter on OFSwitch13Device::MeterDrop trace source. - -- Including new trace sources and private member accessors on OFSwitch13Device - that can be used for monitoring datapath performance. - -- Renaming some OFSwitch13Device private member accessors. - -- Refactoring the OFSwitch13StatsCalculator to dump statistics in a better way. - -- Improving the logical port example with a stateless tunnel application. - -- Adjust the size of queue interface to avoid dropping packets when we still - have space on internal queues. - -- Improving the way switches and controllers deals with TCP sockets from - OpenFlow channels using the new OFSwitch13SocketHandler class. - -- Updating the default TCAM delay attribute on switch device to better reflect - real hardware operation. - -- This version is compatible with ofsoftswitch13 library release v3.1.x and - ns-3 version 3.26 (including patches). There is no backward compatibility - with older ns-3 versions. - - -Release 3.0.0 (Feb 10, 2017) -============================ - -- Starting using the Semantic Versioning (http://semver.org) on this project. - So, BE AWARE THAT this release brings incompatible API changes in respect to - prior OFSwitch13 versions. - -- The OFSwitch13Queue was updated to match the changes introduced in the Queue - API by ns-3.26. No more backward compatibility is available for ns-3.25 or - prior versions. - -- Including support for multiple controllers on the same OpenFlow network - domain. - -- Including support to build switch ports over VirtualNetDevices to work as - logical ports. - -- Renaming examples files to ofswitch13-*.cc and including the new - ofswitch13-logical-port example. - -- Removing the need of registering the switch at the controller before the - connection start. - -- Removing the controller address attribute from the OpenFlow device. It now - must be indicated by the helper as a parameter to the - StartControllerConnection() device method. - -- Creating the OFSwitch13StatsCalculator for switch performance monitoring. - -- Implementing a simplified OpenFlow version-negotiation in OpenFlow device. - -- Create the SocketReader class to read OpenFlow messages from TCP sockets - safely and independently. - -- Creating the RemoteController and RemoteSwitch classes, which can be used to - independently store information of several remote connections, allowing the - implementation of multiple controller functionalities. - -- Refactoring the OFSwitch13Controller class: - * Splitting the DpctlCommand into 'execute' and 'schedule' versions; - * Removing dependence from OFSwitch13Device class; - * Renaming ConnectionStarted() method to HandshakeSuccessful() to reflect - the method semantic; - * Implementing the handshake procedure; - * Implementing barrier reply, hello and features reply handlers; - * Using constant pointers to RemoteSwitch objects to avoid mistakes. - -- Refactoring the OFSwitch13Helper class: - * Using the OFSwitch13Helper as a base class and implementing extended - helpers for configuring an OpenFlow network domain with internal controller - applications (OFSwitch13InternalHelper) or a real external controller - (OFSwitch13ExternalHelper); - * Supporting the configuration of OpenFlow networks domains with multiple - controllers; - * Removing the dependence of installing the controller before the switches; - * Introducing the CreateOpenFlowChannels() member function to effectively - connect switches to controllers after installing switches and controllers - into respective nodes (the use of this function is mandatory). - -- This version is compatible with ofsoftswitch13 library release v3.0.x and - ns-3 version 3.26 (including patches). There is no backward compatibility - with older ns-3 versions. - - -Release 2.0.3 (Sep 12, 2016) -============================ - -- Bugfix: wrong variable type on priority output queue selection. - - -Release 2.0.2 (Apr 11, 2016) -============================ - -- Including the QosController example. - -- The OpenFlow device is not a NetDevice child anymore. It avoids misleading - interpretation and configuration problems with further ns-3 versions. The - OFSwitch13NetDevice class was renamed to OFSwitch13Deviceto reflect this - change better. - -- Replacing the CsmaNetDevice OpenFlow trace source, used by prior versions to - get packets from the CsmaNetDevice port, by a new CsmaNetDevice OpenFlow - receive callback. This new callback avoids problems with internal receive - semantics in the way that CsmaNetDevices configure as OpenFlow ports never - invoke the default receive callback. - -- Creating the OFSwitch13DeviceContainer for handling CsmaNetDevices. Note the - change on InstallSwitch* methods on the OFSwitch13Helper. - -- By default, 8 priority queues are created for each OFSwitch13Queue and are - available for use. - -- Updating the documentation with a better module design description (including - new figures) and the QosController description. - -- This version is compatible with ofsoftswitch13 library release v2.0.x and - ns-3 versions 3.22, 3.23 and 3.24.1, and 3.25 (including patches for - ns-3.25). - - -Release 2.0.1 (Feb 16, 2016) -============================ - -- Updating the documentation with more details on the differences between this - module and the existing ns-3 one. - -- Including patches for already tested ns-3 versions (3.22, 3.23 and 3.24.1). - -- Including this release notes file. - -- This version is compatible with ofsoftswitch13 library release v2.0.x and - ns-3 versions 3.22, 3.23 and 3.24.1. - - -Release 2.0.0 (Feb 15, 2016) -============================ - -- First public release of the OFSwitch13 module, including source code and - documentation. - -- This version is compatible with ofsoftswitch13 library release v2.0.x and - ns-3 versions 3.22, 3.23 and 3.24.1. - diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md new file mode 100644 index 0000000..0d7417d --- /dev/null +++ b/RELEASE_NOTES.md @@ -0,0 +1,257 @@ +# Release notes + +This file contains OFSwitch13 release notes (most recent releases first). + +## [Release 5.2.3](https://github.com/ljerezchaves/ofswitch13/releases/tag/5.2.3) + +**Release date:** Mar 02, 2024. +**Works with:** ns-3.38, ns-3.39, and ns-3.40. + +- Configuring `OFSwitch13PriorityQueue::QueueFactory` with `DropTailQueue` queues by default. +- Renaming `OFSwitch13Helper::ChannelType` enumeration values to match coding style. +- Enabling checksum computations in `OFSwitch13Helper::CreateOpenFlowChannel()` methods. +- This release automatically handles the integration between OFSwitch13 module and BOFUSS library v5.2.x. + +## [Release 5.2.2](https://github.com/ljerezchaves/ofswitch13/releases/tag/5.2.2) + +**Release date:** Sep 01, 2023. +**Works with:** ns-3.38 and ns-3.39. + +- Removing `examples/ofswitch13-qos-controller` dependency from the NetAnim module. +- Updating buffer timeout operation with millisecond resolution support. +- Updating the maximum size of the parent `OFSwitch13Queue` class with the sum of the maximum size of all internal queues (the operation mode of all internal queues must be the same). +- This release automatically handles the integration between OFSwitch13 module and BOFUSS library v5.2.x. + +## [Release 5.2.1](https://github.com/ljerezchaves/ofswitch13/releases/tag/5.2.1) + +**Release date:** Mar 31, 2023. +**Works with:** ns-3.38. + +- Replacing `V4PingHelper` by `PingHelper` in examples. +- This release automatically handles the integration between OFSwitch13 module and BOFUSS library v5.2.x. + +## [Release 5.2.0](https://github.com/ljerezchaves/ofswitch13/releases/tag/5.2.0) + +**Release date:** Mar 31, 2023. +**Works with:** ns-3.36 and ns-3.37. + +- Replacing the outdated ofsoftswitch13 name by BOFUSS in the project (source code and documentation). +- Refactoring the BOFUSS ns3lib branch to simplify library compilation. +- Updating `CMakeLists.txt` to automatically download, configure and build the BOFUSS library. +- Updating the module documentation to reflect the changes in building process. +- This release automatically handles the integration between OFSwitch13 module and BOFUSS library v5.2.x. + +## [Release 5.1.0](https://github.com/ljerezchaves/ofswitch13/releases/tag/5.1.0) + +**Release date:** Dec 10, 2022. +**Works with:** ns-3.36 and ns-3.37. + +- Updating the build system to work with CMake introduced by ns-3.36. +- Updating the source code formatting to match ns-3.37 coding style. +- Updating the module documentation, removing outdated figures. +- New CSMA full-duplex patch for improved channel operation. +- Fixing errors when compiling the project with gcc 11.3.0 in Ubuntu 22.04.1. +- This release requires manual integration between OFSwitch13 module and BOFUSS library v5.1.x. + +## [Release 5.0.1](https://github.com/ljerezchaves/ofswitch13/releases/tag/5.0.1) + +**Release date:** Dec 20, 2021. +**Works with:** ns-3.31, ns-3.32, ns-3.33, ns-3.34, and ns-3.35. + +- Updating the `OFSwitch13Queue` class to match the changes introduced in the Queue API by ns-3.31. +- Removing DL library dependency to prevent issues with boost library. +- This release requires manual integration between OFSwitch13 module and BOFUSS library v5.0.x. + +## [Release 5.0.0](https://github.com/ljerezchaves/ofswitch13/releases/tag/5.0.0) + +**Release date:** Dec 19, 2021. +**Works with:** ns-3.30. + +**BE AWARE THAT** this release brings incompatible API changes. + +- Refactoring the `OFSwitch13Controller::Dpctl*()` methods: + - The `OFSwitch13Controller::DpctlExecute()` method has no more overloaded definitions. The target switch (first parameter) must be the switch's datapath IP. Previous signature using the `Ptr` pointer was removed. Users can fix compilation errors by just using `RemoteSwitch::GetDpId()` method when invoking `OFSwitch13Controller::DpctlExecute()`. + - The `OFSwitch13Controller::DpctlSchedule()` method was deprecated in favor of `OFSwitch13Controller::DpctlExecute()`. When the switch is not connected to the controller, the `OFSwitch13Controller::DpctlExecute()` method will automatically schedule the command for execution just after the handshake procedure. This is particularly useful for executing commands when creating the topology, before invoking `Simulator::Run()`. +- New `OFSwitch13Device::TableDrop` trace source to notify unmatched packets dropped by flow tables without table-miss entries. +- New `TabDrps` column in the `OFSwitch13StatsCalculator` output file. +- Updating the `OFSwitch13Queue` class to match the changes introduced in the Queue API by ns-3.30. +- 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 release requires manual integration between OFSwitch13 module and BOFUSS library v5.0.x. + +## [Release 4.0.0](https://github.com/ljerezchaves/ofswitch13/releases/tag/4.0.0) + +**Release date:** Apr 02, 2019. +**Works with:** ns-3.28 and ns-3.29. + +**BE AWARE THAT** this release brings incompatible API changes. + +- Refactoring the OFSwitch13 queue API: + - The `OFSwitch13Queue` class implements the queue interface, extending the `Queue` class to allow compatibility with the `CsmaNetDevice` used by `OFSwitch13Port`. Internally, it holds a collection of N (possibly different) queues, identified by IDs ranging from 0 to N-1. The `OFSwitch13Queue::Enqueue()` method uses the `QueueTag` to identify which internal queue will hold the packet. + - Specialized `OFSwitch13Queue` subclasses can perform different output scheduling algorithms by implementing the virtual `OFSwitch13Queue::Peek()`, `OFSwitch13Queue::Dequeue()`, and `OFSwitch13Queue::Remove()` methods. The last two methods must call the `OFSwitch13Queue::NotifyDequeue()` and `OFSwitch13Queue::NotifyRemoved()`, respectively, to update statistics and keep consistency with the base class. + - The `OFSwitch13Port::QueueFactory` attribute can be used to configure OpenFlow port queue at construction time. + - The new `OFSwitch13PriorityQueue` class implements the specialized priority queuing discipline for a collection of N priority queues, identified by IDs ranging from 0 to N-1 with decreasing priority (queue ID 0 has the highest priority). The output scheduling algorithm ensures that higher-priority queues are always served first. The `OFSwitch13PriorityQueue::QueueFactory` and `OFSwitch13PriorityQueue::NumQueues` attributes can be used to configure the type and the number of internal priority queues. +- Refactoring the `OFSwitch13Device` class: + - Adjusting `OFSwitch13Device::PipelineTables`, `OFSwitch13Device::FlowTableSize`, `OFSwitch13Device::GroupTableSize`, and `OFSwitch13Device::MeterTableSize` attributes at any time. + - New `OFSwitch13Device::GetDpId()` method as an alias for the `OFSwitch13Device::GetDatapathId()` method. + - New `OFSwitch13Device::GetDatapathStruct()` and `OFSwitch13Port::GetPortStruct()` methods returning pointers to the BOFUSS library internal structures. + - New `OFSwitch13Device::GetDatapathTimeout()`, `OFSwitch13Device::GetFlowTableUsage()`, `OFSwitch13Device::GetGroupTableUsage()`, `OFSwitch13Device::GetMeterTableUsage()`, `OFSwitch13Device::GetNControllers()`, `OFSwitch13Device::GetBufferEntries()`, `OFSwitch13Device::GetBufferUsage()`, and `OFSwitch13Device::GetBufferSize()` methods for datapath statistics. + - Renaming `OFSwitch13Device::PipelineCapacity` attribute to `OFSwitch13Device::CpuCapacity`, + - Renaming `OFSwitch13Device::PipelineLoad` traced value to `OFSwitch13Device::CpuLoad`, + - Renaming `OFSwitch13Device::LoadDrop` trace source to `OFSwitch13Device::OverloadDrop`. + - Renaming `OFSwitch13Device::GetOFSwitch13Port()` method to `OFSwitch13Device::GetSwitchPort()`. + - Renaming `OFSwitch13Device::GetPipelineLoad()` method to `OFSwitch13Device::GetCpuLoad()`. + - Renaming `OFSwitch13Device::GetPipelineCapacity()` method to `OFSwitch13Device::GetCpuCapacity()`. + - Renaming `OFSwitch13Device::GetFlowEntries()` method to `OFSwitch13Device::GetFlowTableEntries()` + - Renaming `OFSwitch13Device::GetGroupEntries()` method to `OFSwitch13Device::GetGroupTableEntries()`. + - Renaming `OFSwitch13Device::GetMeterEntries()` method to `OFSwitch13Device::GetMeterTableEntries()`. +- Refactoring the `OFSwitch13StatsCalculator` class: + - New `OFSwitch13StatsCalculator::FlowTableDetails` attribute to dump individual flow table statistics. + - Renaming `OFSwitch13StatsCalculator::GetEwmaPipelineLoad()` method to `OFSwitch13StatsCalculator::GetEwmaCpuLoad()`. + - Renaming `OFSwitch13StatsCalculator::GetAvgPipelineUsage()` method to `OFSwitch13StatsCalculator::GetAvgCpuUsage()`. + - Renaming column names in first row, removing any special character from them. +- Overriding the `OFSwitch13Helper::InstallSwitch()` method: + - When the first parameter is a node container, the method returns an OpenFlow device container. + - When the first parameter is a node pointer, the method returns the OpenFlow device pointer (there's the optional second parameter of a device container that will be configured as switch ports). +- New `OFSwitch13Port::GetPortDevice()`, `OFSwitch13Port::GetPortQueue()` and `OFSwitch13Port::GetSwitchDevice()` methods. +- Increasing the maximum number of OpenFlow switch ports to 4096 (see DP_MAX_PORTS at BOFUSS library) +- Increasing the maximum number of output queues on ports to 32 (see NETDEV_MAX_QUEUES at BOFUSS library) +- Removing the BOFUSS library dependency on the NetBee library. +- Improving the BOFUSS library performance and fixing memory leak errors. +- This release requires manual integration between OFSwitch13 module and BOFUSS library v4.0.x. + +## [Release 3.3.0](https://github.com/ljerezchaves/ofswitch13/releases/tag/3.3.0) + +**Release date:** Sep 29, 2018. +**Works with:** ns-3.28 and ns-3.29. + +- Fixing incorrect bitwise comparison in port configuration. +- Fixing incorrect ns-3 version comparison that was preventing module configuration in ns-3.28.1 +- New `OFSwitch13Device::PipelineTables` attribute to define the number of flow tables in the pipeline. +- Adjusting `OFSwitch13Device::PipelineTables`, `OFSwitch13Device::FlowTableSize`, `OFSwitch13Device::GroupTableSize`, and `OFSwitch13Device::MeterTableSize` attributes at construction time only. +- Renaming the `OFSwitch13Device::GetFlowEntries()` method to `OFSwitch13Device::GetSumFlowEntries()`. +- Renaming the `OFSwitch13StatsCalculator::GetEwmaFlowEntries()` method to `OFSwitch13StatsCalculator::GetEwmaSumFlowEntries()`. +- This release requires manual integration between OFSwitch13 module and BOFUSS library v3.3.x. + +## [Release 3.2.2](https://github.com/ljerezchaves/ofswitch13/releases/tag/3.2.2) + +**Release date:** Jul 05, 2018. +**Works with:** ns-3.28. + +- Fixing errors when compiling the project with gcc 7.3.0 in Ubuntu 18.04. +- Replacing Mercurial by Git as version control system. +- Configuring the BOFUSS library as a git submodule that automatically handle version compatibility. +- This release requires manual integration between OFSwitch13 module and BOFUSS library v3.2.x. + +## [Release 3.2.1](https://github.com/ljerezchaves/ofswitch13/releases/tag/3.2.1) + +**Release date:** May 22, 2018. +**Works with:** ns-3.28. + +- Updating `OFSwitch13Queue` and `OFSwitch13InternalHelper` classes to avoid using deprecated ns-3 queue API when setting queue size and queue mode. +- This release requires manual integration between OFSwitch13 module and BOFUSS library v3.2.x. + +## [Release 3.2.0](https://github.com/ljerezchaves/ofswitch13/releases/tag/3.2.0) + +**Release date:** May 22, 2018. +**Works with:** ns-3.27. + +- Updating `OFSwitch13Queue` class to match the changes introduced in the Queue API by ns-3.27 (special thanks to Stefano Avallone for providing the necessary patches). +- This release requires manual integration between OFSwitch13 module and BOFUSS library v3.2.x. + +## [Release 3.1.1](https://github.com/ljerezchaves/ofswitch13/releases/tag/3.1.1) + +**Release date:** May 12, 2018. +**Works with:** ns-3.26. + +- New packet counter in `OFSwitch13StatsCalculator` class to measure the pipeline load. +- New `OFSwitch13Queue::QueueFactory` attribute for the object factory used to create internal OpenFlow queues on device ports. +- Fixing errors when handling packet tags and refilling meter tokens. +- This release requires manual integration between OFSwitch13 module and BOFUSS library v3.1.x. + +## [Release 3.1.0](https://github.com/ljerezchaves/ofswitch13/releases/tag/3.1.0) + +**Release date:** May 29, 2017. +**Works with:** ns-3.26. + +- New `OFSwitch13Device::PipelineCapacity` attribute to limit the traffic throughput to a specific data rate. +- New `OFSwitch13Device::FlowTableSize`, `OFSwitch13Device::GroupTableSize`, and `OFSwitch13Device::MeterTableSize` attributes to define the maximum number of entries in pipeline tables. +- New `OFSwitch13Queue::NumQueues` attribute to define the number of output queues available for use. +- New `OFSwitch13SocketHandler` class to assist switches and controllers dealing with TCP sockets used by the OpenFlow channels. +- Including the meter ID parameter on the `OFSwitch13Device::MeterDrop` trace source. +- Including new trace sources in `OFSwitch13Device` for monitoring datapath performance. +- Refactoring the `OFSwitch13StatsCalculator` to dump statistics in a clear way. +- Improving the `ofswitch13-logical-port` example with a stateless tunnel application. +- Updating the default `OFSwitch13Device::TcamDelay` attribute value to better reflect real hardware operation. +- This release requires manual integration between OFSwitch13 module and BOFUSS library v3.1.x. + +## [Release 3.0.0](https://github.com/ljerezchaves/ofswitch13/releases/tag/3.0.0) + +**Release date:** Feb 10, 2017. +**Works with:** ns-3.26. + +**BE AWARE THAT** this release brings incompatible API changes. + +- Start using the [semantic versioning](http://semver.org) on this project. +- Updating the `OFSwitch13Queue` class to match the changes introduced in the Queue API by ns-3.26. +- Supporting multiple controllers in the same OpenFlow network domain. +- Supporting `VirtualNetDevice` as logical OpenFlow port. +- Renaming examples files with prefix `ofswitch13-`. +- New `ofswitch13-logical-port` example. +- Removing the need of registering the switch at the controller before starting the connection. +- Removing the `OFSwitch13Device::ControllerAddr` attribute (the controller address must be indicated by the helper as a parameter to the `OFSwitch13Device::StartControllerConnection()` method). +- New `OFSwitch13StatsCalculator` class for switch performance monitoring. +- Implementing a simplified OpenFlow version-negotiation in OpenFlow device. +- New `SocketReader` class for safely reading OpenFlow messages from TCP sockets. +- New `RemoteController` and `RemoteSwitch` classes to handle several remote connections. +- Refactoring the `OFSwitch13Controller` class: + - Splitting the `DpctlCommand()` method into `DpctlExecute()` and `DpctlSchedule()`. + - Removing the dependence from the `OFSwitch13Device` class. + - Renaming the `ConnectionStarted()` method to `HandshakeSuccessful()`. + - Implementing the handshake procedure. + - Implementing the barrier reply, hello and features reply handlers. + - Using constant pointers to `RemoteSwitch` objects. +- Refactoring the `OFSwitch13Helper` class: + - Using the `OFSwitch13Helper` as a base class and implementing extended helpers for configuring an OpenFlow network domain with internal controller applications (`OFSwitch13InternalHelper`) or an external controller (`OFSwitch13ExternalHelper`). + - Removing the need of installing the controller before configuring the switches. + - Introducing the `CreateOpenFlowChannels()` method to effectively connect switches to controllers after installing switches and controllers into respective nodes (the use of this function is mandatory). +- This release requires manual integration between OFSwitch13 module and BOFUSS library v3.0.x. + +## [Release 2.0.3](https://github.com/ljerezchaves/ofswitch13/releases/tag/2.0.3) + +**Release date:** Sep 12, 2016. +**Works with:** ns-3.22, ns-3.23, ns-3.24.1, and ns-3.25. + +- Fixing a wrong variable type on priority output queue selection. +- This release requires manual integration between OFSwitch13 module and BOFUSS library v2.0.x. + +## [Release 2.0.2](https://github.com/ljerezchaves/ofswitch13/releases/tag/2.0.2) + +**Release date:** Apr 11, 2016. +**Works with:** ns-3.22, ns-3.23, ns-3.24.1, and ns-3.25. + +- Renaming `OFSwitch13NetDevice` to `OFSwitch13Device`, as the OpenFlow device is not a network device anymore. +- New `OFSwitch13DeviceContainer` for handling OpenFlow devices. +- New `CsmaNetDevice` OpenFlow receive callback that forwards packets with all headers from the underlying CSMA port to the OpenFlow device. +- New `qos-controller` example. +- Creating 8 priority queues for each `OFSwitch13Queue`. +- Updating the documentation with detailed module design and `qos-controller` example description. +- This release requires manual integration between OFSwitch13 module and BOFUSS library v2.0.x. + +## [Release 2.0.1](https://github.com/ljerezchaves/ofswitch13/releases/tag/2.0.1) + +**Release date:** Feb 16, 2016. +**Works with:** ns-3.22, ns-3.23 and ns-3.24.1. + +- Improving documentation with highlights for the differences between the OFSwitch13 module and the existing ns-3 OpenFlow module. +- Patches for integrating OFSwitch13 with ns-3 versions 3.22, 3.23 and 3.24.1. +- This release requires manual integration between OFSwitch13 module and BOFUSS library v2.0.x. + +## [Release 2.0.0](https://github.com/ljerezchaves/ofswitch13/releases/tag/2.0.0) + +**Release date:** Feb 15, 2016. +**Works with:** ns-3.22, ns-3.23, and ns-3.24.1. + +- The first public release of the OFSwitch13 module, including source code and documentation. +- This release requires manual integration between OFSwitch13 module and BOFUSS library v2.0.x. diff --git a/doc/source/conf.py b/doc/source/conf.py index 1b5a32b..a566199 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -26,15 +26,15 @@ # Tip from https://stackoverflow.com/questions/9899283/how-do-you-change-the-code-example-font-size-in-latex-pdf-output-with-sphinx/9955928 # Note: sizes are \footnotesize (8pt), \small (9pt), and \normalsize (10pt). -#from sphinx.highlighting import PygmentsBridge -#from pygments.formatters.latex import LatexFormatter +# from sphinx.highlighting import PygmentsBridge +# from pygments.formatters.latex import LatexFormatter # -#class CustomLatexFormatter(LatexFormatter): +# class CustomLatexFormatter(LatexFormatter): # def __init__(self, **options): # super(CustomLatexFormatter, self).__init__(**options) # self.verboptions = r"formatcom=\footnotesize" # -#PygmentsBridge.latex_formatter = CustomLatexFormatter +# PygmentsBridge.latex_formatter = CustomLatexFormatter # -- General configuration ------------------------------------------------ @@ -45,37 +45,37 @@ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = ['sphinx.ext.imgmath'] +extensions = ["sphinx.ext.imgmath"] # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # # source_suffix = ['.rst', '.md'] -source_suffix = '.rst' +source_suffix = ".rst" # The encoding of source files. # # source_encoding = 'utf-8-sig' # The master toctree document. -master_doc = 'ofswitch13' +master_doc = "ofswitch13" # General information about the project. -project = u'OFSwitch13' -author = u'Luciano Jerez Chaves' -copyright = u'2023 Computer Networks Laboratory' +project = "OFSwitch13" +author = "Luciano Jerez Chaves" +copyright = "2023 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 = u'5.2.2' +version = "5.2.3" # The full version, including alpha/beta/rc tags. -release = u'5.2.2' +release = "5.2.3" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -96,7 +96,7 @@ # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # These patterns also affect html_static_path and html_extra_path -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] # The reST default role (used for this markup: `text`) to use for all # documents. @@ -118,7 +118,7 @@ # show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. # modindex_common_prefix = [] @@ -135,7 +135,7 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'ns3_html_theme' +html_theme = "ns3_html_theme" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the @@ -144,13 +144,13 @@ # html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. -html_theme_path = ['../../../../doc/'] +html_theme_path = ["../../../../doc/"] # The name for this set of Sphinx documents. # " v documentation" by default. # # html_title = 'est vtest' -html_title = 'Manual' +html_title = "Manual" # A shorter title for the navigation bar. Default is the same as html_title. # @@ -182,7 +182,7 @@ # bottom, using the given strftime format. # The empty string is equivalent to '%b %d, %Y'. # -html_last_updated_fmt = '%b %d, %Y %H:%M' +html_last_updated_fmt = "%b %d, %Y %H:%M" # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. @@ -250,7 +250,7 @@ # html_search_scorer = 'scorer.js' # Output file base name for HTML help builder. -htmlhelp_basename = 'ns-3doc' +htmlhelp_basename = "ns-3doc" # -- Options for LaTeX output -------------------------------------------------- @@ -258,11 +258,9 @@ # The paper size ('letterpaper' or 'a4paper'). # # 'papersize': 'letterpaper', - # The font size ('10pt', '11pt' or '12pt'). # # 'pointsize': '10pt', - # Additional stuff for the LaTeX preamble. # # VerbatimBorderColor: make the box around code samples blend into the background @@ -275,10 +273,10 @@ # See above to change the font size of verbatim code blocks # # 'preamble': '', - 'preamble': u'''\\usepackage{amssymb} + "preamble": """\\usepackage{amssymb} \\definecolor{VerbatimBorderColor}{rgb}{1,1,1} \\renewcommand{\\sphinxcode}[1]{\\texttt{\\small{#1}}} -''' +""" # Latex figure (float) alignment # # 'figure_align': 'htbp', @@ -288,14 +286,19 @@ # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - ('ofswitch13', 'ofswitch13.tex', u'OFSwitch13 Module Documentation', - u'Computer Networks Laboratory at Unicamp, Brazil', 'manual'), + ( + "ofswitch13", + "ofswitch13.tex", + "OFSwitch13 Module Documentation", + "Computer Networks Laboratory at Unicamp, Brazil", + "manual", + ), ] # The name of an image file (relative to this directory) to place at the top of # the title page. # -#latex_logo = None +# latex_logo = None # If true, show page references after internal links. # @@ -323,10 +326,7 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'ns-3-manual', u'ns-3 Manual', - [u'ns-3 project'], 1) -] +man_pages = [("index", "ns-3-manual", "ns-3 Manual", ["ns-3 project"], 1)] # If true, show URL addresses after external links. # @@ -334,11 +334,11 @@ # -- Options for texinfo output --------------------------------------- -#texinfo_documents = [ +# texinfo_documents = [ # (master_doc, 'test', u'test Documentation', # author, 'test', 'One line description of project.', # 'Miscellaneous'), -#] +# ] # Documents to append as an appendix to all manuals. # diff --git a/doc/source/ofswitch13-description.rst b/doc/source/ofswitch13-description.rst index 1c6bfe9..bc92a90 100644 --- a/doc/source/ofswitch13-description.rst +++ b/doc/source/ofswitch13-description.rst @@ -1,7 +1,6 @@ Module Description ****************** -.. include:: replace.txt .. highlight:: cpp .. heading hierarchy: @@ -13,13 +12,13 @@ Module Description Overview ======== -The |ofs13| module enhances the `ns-3 Network Simulator `_ with Software-Defined Networking (SDN) support. -Despite the fact that the |ns3| already has a module for simulating OpenFlow switches, it provides a very outdated protocol implementation (OpenFlow 0.8.9, from 2008). -Alternatively, |ofs13| supports OpenFlow protocol version 1.3, bringing both a switch device and a controller application interface to the |ns3| simulator, as depicted in :ref:`fig-ofswitch13-module`, from [Chaves2016a]_. -With |ofs13|, it is possible to interconnect |ns3| nodes to send and receive traffic using ``CsmaNetDevice`` or ``VirtualNetDevice``. +The *OFSwitch13* module enhances the `ns-3 Network Simulator `_ with Software-Defined Networking (SDN) support. +Despite the fact that the *ns-3* already has a module for simulating OpenFlow switches, it provides a very outdated protocol implementation (OpenFlow 0.8.9, from 2008). +Alternatively, *OFSwitch13* supports OpenFlow protocol version 1.3, bringing both a switch device and a controller application interface to the *ns-3* simulator, as depicted in :ref:`fig-ofswitch13-module`, from [Chaves2016a]_. +With *OFSwitch13*, it is possible to interconnect *ns-3* nodes to send and receive traffic using ``CsmaNetDevice`` or ``VirtualNetDevice``. The controller application interface can be extended to implement any desired control logic to orchestrate the network. -The communication between the controller and the switch is realized over standard |ns3| protocol stack, devices, and channels. -The |ofs13| module relies on the external `BOFUSS library for OFSwitch13 `_. +The communication between the controller and the switch is realized over standard *ns-3* protocol stack, devices, and channels. +The *OFSwitch13* module relies on the external `BOFUSS library for OFSwitch13 `_. This library provides the switch datapath implementation, the support for converting OpenFlow messages to/from wire format, and the ``dpctl`` utility tool for configuring the switch from the command line. .. _fig-ofswitch13-module: @@ -27,7 +26,7 @@ This library provides the switch datapath implementation, the support for conver .. figure:: figures/ofswitch13-module.* :align: center - The |ofs13| module overview + The *OFSwitch13* module overview Design ====== @@ -37,12 +36,12 @@ Design OpenFlow 1.3 Switch Device ########################## -The OpenFlow 1.3 switch device, namely ``OFSwitch13Device``, can be used to interconnect |ns3| nodes using the existing network devices and channels. -:ref:`fig-ofswitch13-netdevice` figure shows the internal switch device structure. It takes a collection of ``OFSwitch13Port`` acting as input/output ports, each one associated with an |ns3| underlying ``NetDevice``. +The OpenFlow 1.3 switch device, namely ``OFSwitch13Device``, can be used to interconnect *ns-3* nodes using the existing network devices and channels. +:ref:`fig-ofswitch13-netdevice` figure shows the internal switch device structure. It takes a collection of ``OFSwitch13Port`` acting as input/output ports, each one associated with an *ns-3* underlying ``NetDevice``. In most cases, the ``CsmaNetDevice`` is used to build the ports, which will act as physical ports. However, it is possible to use the ``VirtualNetDevice`` to implement logical ports. The switch device acts as the intermediary between the ports, receiving a packet from one port and forwarding it to another. -The |bofuss| library provides the OpenFlow switch datapath implementation (flow tables, group table, and meter table). +The *BOFUSS* library provides the OpenFlow switch datapath implementation (flow tables, group table, and meter table). Thus, packets entering the switch are sent to the library for OpenFlow pipeline processing before being forwarded to the correct output port(s). OpenFlow messages received from the controller are also sent to the library for datapath configuration. @@ -55,10 +54,10 @@ OpenFlow messages received from the controller are also sent to the library for A packet enters the switch device through the OpenFlow receive callback in the underlying ``NetDevice``, which is invoked for successfully received packets. This callback is a promiscuous one, but in contrast to a promiscuous protocol handler, the packet sent to this callback includes all the headers required for OpenFlow pipeline processing. -Including this new callback in the ``NetDevice`` is the only required modification to the |ns3| source code for |ofs13| usage. +Including this new callback in the ``NetDevice`` is the only required modification to the *ns-3* source code for *OFSwitch13* usage. The incoming packet is checked for conformance to the CPU processing capacity (throughput) defined by the ``OFSwitch13Device::CpuCapacity`` attribute. -Packets exceeding CPU processing capacity are dropped, while conformant packets are sent to the pipeline at the |bofuss| library. +Packets exceeding CPU processing capacity are dropped, while conformant packets are sent to the pipeline at the *BOFUSS* library. The module considers the concept of *virtual TCAM* (Ternary Content-Addressable Memory) to estimate the average flow table search time to model OpenFlow hardware operations. It considers that real OpenFlow implementations use sophisticated search algorithms for packet matching such as hierarchical hash tables or binary search trees. Because of that, the equation *K \* log_2 (n)* is used to estimate the delay, where *K* is the ``OFSwitch13Device::TcamDelay`` attribute set to the time for a single TCAM operation, and *n* is the current number of entries on pipeline flow tables. @@ -67,10 +66,10 @@ Packets coming back from the library for output action are sent to the OpenFlow 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 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 (``VirtualNetDevice`` does not use queues). +The ``OFSwitch13Queue`` abstract base class implements the queue interface, extending the *ns-3* ``Queue`` class to allow compatibility with the ``CsmaNetDevice`` used within ``OFSwitch13Port`` objects (``VirtualNetDevice`` does not use queues). In this way, it is possible to replace the standard ``CsmaNetDevice::TxQueue`` attribute by this modified ``OFSwitch13Queue`` object. Internally, it can hold a collection of N (possibly different) queues, each one identified by a unique ID ranging from 0 to N-1. Packets sent to the OpenFlow queue for transmission by the ``CsmaNetDevice`` are expected to carry the ``QueueTag``, which is used by the ``OFSwitch13Queue::Enqueue`` method to identify the internal queue that will hold the packet. -Specialized ``OFSwitch13Queue`` subclasses can perform different output scheduling algorithms by implementing the ``Peek``, ``Dequeue``, and ``Remove`` pure virtual methods from |ns3| ``Queue``. +Specialized ``OFSwitch13Queue`` subclasses can perform different output scheduling algorithms by implementing the ``Peek``, ``Dequeue``, and ``Remove`` pure virtual methods from *ns-3* ``Queue``. The last two methods must call the ``NotifyDequeue`` and ``NotifyRemoved`` methods respectively, which are used by the ``OFSwitch13Queue`` to keep consistent statistics. The OpenFlow port type queue can be configured by the ``OFSwitch13Port::QueueFactory`` attribute at construction time. @@ -85,7 +84,7 @@ OpenFlow 1.3 Controller Application Interface The OpenFlow 1.3 controller application interface, namely ``OFSwitch13Controller``, provides the necessary functionalities for controller implementation. It can handle a collection of OpenFlow switches, as illustrated in :ref:`fig-ofswitch13-controller` figure. -For constructing OpenFlow configuration messages and sending them to the switches, the controller interface relies on the ``dpctl`` utility provided by the |bofuss| library. +For constructing OpenFlow configuration messages and sending them to the switches, the controller interface relies on the ``dpctl`` utility provided by the *BOFUSS* library. With a simple command-line syntax, this utility can be used to add flows to the pipeline, query for switch features and status, and change other configurations. .. _fig-ofswitch13-controller: @@ -98,7 +97,7 @@ With a simple command-line syntax, this utility can be used to add flows to the For OpenFlow messages coming from the switches, the controller interface provides a collection of internal handlers to deal with the different types of messages. Some handlers cannot be modified by derived class, as they must behave as already implemented. Other handlers can be overridden to implement the desired control logic. -The |ofs13| module brings the ``OFSwitch13LearningController`` class that implements the controller interface to work as a "learning bridge controller" (see 802.1D). +The *OFSwitch13* module brings the ``OFSwitch13LearningController`` class that implements the controller interface to work as a "learning bridge controller" (see 802.1D). This learning controller instructs the OpenFlow switches to forward incoming unicast frames from one port to the single correct output port whenever possible (similar to the ``ns3::BridgeNetDevice``). OpenFlow channel @@ -106,35 +105,35 @@ OpenFlow channel The OpenFlow channel is the interface that connects switches to OpenFlow controllers. Through this interface, the controller configures and manages the switch. -In the |ofs13| module, the controller interface can manage the switch devices remotely over a separate dedicated network (out-of-band controller connection). -It is possible to use standard |ns3| protocol stack, channels and devices to create the OpenFlow channel connections using a single shared channel or individual links between the controller interface and each switch device. +In the *OFSwitch13* module, the controller interface can manage the switch devices remotely over a separate dedicated network (out-of-band controller connection). +It is possible to use standard *ns-3* protocol stack, channels and devices to create the OpenFlow channel connections using a single shared channel or individual links between the controller interface and each switch device. This model provides realistic control plane connections, including communication delay and, optionally, error models. -It also simplifies the OpenFlow protocol analysis, as the |ns3| tracing subsystem can be used for outputting PCAP files. +It also simplifies the OpenFlow protocol analysis, as the *ns-3* tracing subsystem can be used for outputting PCAP files. -Considering that the OpenFlow messages traversing the OpenFlow channel follow the standard wire format, it is also possible to use the |ns3| ``TapBridge`` module to integrate an external OpenFlow controller, running on the local machine, to the simulated environment. +Considering that the OpenFlow messages traversing the OpenFlow channel follow the standard wire format, it is also possible to use the *ns-3* ``TapBridge`` module to integrate an external OpenFlow controller, running on the local machine, to the simulated environment. BOFUSS library integration ########################## This module was designed to work together with a OpenFlow user-space software switch implementation. -The original `Basic OpenFlow User Space Software Switch (BOFUSS) project `_ (previously known as *ofsoftswitch13*) [Fernandes2020]_ was forked and modified for proper integration with |ns3|, resulting in the `BOFUSS library for OFSwitch13 `_ library. +The original `Basic OpenFlow User Space Software Switch (BOFUSS) project `_ (previously known as *ofsoftswitch13*) [Fernandes2020]_ was forked and modified for proper integration with *ns-3*, resulting in the `BOFUSS library for OFSwitch13 `_ library. The ``master`` branch does not modify the original switch datapath implementation, which is currently maintained in the original repository and regularly synced to this one. -The modified ``ns3lib`` branch includes only the necessary files for building the |bofuss| library and integrating it with the |ofs13| module. +The modified ``ns3lib`` branch includes only the necessary files for building the *BOFUSS* library and integrating it with the *OFSwitch13* module. -The |bofuss| library provides the complete OpenFlow switch datapath implementation, including input and output ports, the flow-table pipeline for packet matching, the group table, and the meter table. +The *BOFUSS* library provides the complete OpenFlow switch datapath implementation, including input and output ports, the flow-table pipeline for packet matching, the group table, and the meter table. It also provides support for converting internal messages to and from OpenFlow 1.3 wire format and delivers the ``dpctl`` utility for converting text commands into internal messages. -For proper |ofs13| integration, the library was modified to receive and send packets directly to the |ns3| environment. -To this, all library functions related to sending and receiving packets over ports were annotated as *weak symbols*, allowing the |ofs13| module to override them at link time. +For proper *OFSwitch13* integration, the library was modified to receive and send packets directly to the *ns-3* environment. +To this, all library functions related to sending and receiving packets over ports were annotated as *weak symbols*, allowing the *OFSwitch13* module to override them at link time. This same strategy was used for overriding time-related functions, ensuring time consistency between the library and the simulator. -The integration also relies on *callbacks*, which are used by |bofuss| to notify the |ofs13| module about internal packet events, like packets dropped by meter bands, packet content modifications by pipeline instructions, packets cloned by group actions, and buffered packets sent to the controller. +The integration also relies on *callbacks*, which are used by *BOFUSS* to notify the *OFSwitch13* module about internal packet events, like packets dropped by meter bands, packet content modifications by pipeline instructions, packets cloned by group actions, and buffered packets sent to the controller. As this integration involves callbacks and overridden functions, the module uses a global map to save pointers to all ``OFSwitch13Devices`` objects in the simulation, allowing faster object retrieve by datapath IP. -One potential performance drawback is the conversion between the |ns3| packet representation and the serialized packet buffer used by the library. -This problem is even more critical for empty packets, as |ns3| provides optimized internal representation for them. -To improve the performance, when a packet is sent to the library for pipeline processing, the module keeps track of its original |ns3| packet using the ``PipelinePacket`` structure. -For packets processed by the pipeline without content changes, the switch device forwards the original |ns3| packet to the specified output port. -In the face of content changes, the switch device creates a new |ns3| packet with the modified content (discarding the original packet, eventually copying all packet and byte tags [#f1]_ to the new one). +One potential performance drawback is the conversion between the *ns-3* packet representation and the serialized packet buffer used by the library. +This problem is even more critical for empty packets, as *ns-3* provides optimized internal representation for them. +To improve the performance, when a packet is sent to the library for pipeline processing, the module keeps track of its original *ns-3* packet using the ``PipelinePacket`` structure. +For packets processed by the pipeline without content changes, the switch device forwards the original *ns-3* packet to the specified output port. +In the face of content changes, the switch device creates a new *ns-3* packet with the modified content (discarding the original packet, eventually copying all packet and byte tags [#f1]_ to the new one). This approach is more expensive than the previous one but is far more simple than identifying which changes were made to the packet by the library. .. [#f1] Note that the byte tags in the new packet will cover the entire packet, regardless of the byte range in the original packet. @@ -151,28 +150,28 @@ However, some features are not yet supported: According to the OpenFlow specifications, auxiliary connections could be created by the switch to improve the switch processing performance and exploit the parallelism of most switch implementations. * **OpenFlow channel encryption**: The switch and controller may communicate through a TLS connection to provide authentication and encryption of the connection. - However, as there is no straightforward TLS support on |ns3|, the OpenFlow channel is implemented over a plain TCP connection, without encryption. + However, as there is no straightforward TLS support on *ns-3*, the OpenFlow channel is implemented over a plain TCP connection, without encryption. * **In-band control**: The OpenFlow controller manages the switches remotely over a separate dedicated network (out-of-band controller connection), as the switch port representing the switch's local networking stack and its management stack is not implemented. * **Platform support**: This module is currently supported only for GNU/Linux platforms, as the code relies on an external library linked to the simulator that *must* be compiled with GCC. -|ns3| OpenFlow comparison +*ns-3* OpenFlow comparison ========================= -Note that the |ofs13| is not an extension of the available |ns3| OpenFlow module. +Note that the *OFSwitch13* is not an extension of the available *ns-3* OpenFlow module. They share some design principles, like the use of an external software library linked to the simulator, the virtual TCAM, and the collection of ``CsmaNetDevices`` to work as OpenFlow ports. However, this is an entirely new code and can be used to simulate a broad number of scenarios in comparison to the available implementation. -One difference between the |ns3| OpenFlow model and the |ofs13| is the introduction of the OpenFlow channel, using |ns3| devices and channels to provide the control connection between the controller and the switches. +One difference between the *ns-3* OpenFlow model and the *OFSwitch13* is the introduction of the OpenFlow channel, using *ns-3* devices and channels to provide the control connection between the controller and the switches. It allows the user to collect PCAP traces for this control channel, simplifying the analysis of OpenFlow messages. -It is also possible the use of the |ns3| ``TapBridge`` module to integrate a local external OpenFlow 1.3 controller to the simulated environment. +It is also possible the use of the *ns-3* ``TapBridge`` module to integrate a local external OpenFlow 1.3 controller to the simulated environment. In respect to the controller, this module provides a more flexible interface. Instead of dealing with the internal library structures, the user can use simplified ``dpctl`` commands to build OpenFlow messages and send them to the switches. However, for processing OpenFlow messages received by the controller, the user still need to understand internal library structures and functions to extract the desired information. -In respect to the OpenFlow protocol implementation, the |ofs13| module brings many improved features from version 1.3 in comparison to the available |ns3| model (version 0.8.9). +In respect to the OpenFlow protocol implementation, the *OFSwitch13* module brings many improved features from version 1.3 in comparison to the available *ns-3* model (version 0.8.9). Some of the most important features are: * **Multiple tables**: Prior versions of the OpenFlow specification did expose to the controller the abstraction of a single table. @@ -186,7 +185,7 @@ Some of the most important features are: * **Logical ports**: Prior versions of the OpenFlow specification assumed that all the ports of the OpenFlow switch were physical ports. This version of the specification adds support for logical ports, which can represent complex forwarding abstractions such as tunnels. - In the |ofs13| module, logical ports are implemented with the help of ``VirtualNetDevice``, where the user can configure callbacks to handle packets properly. + In the *OFSwitch13* module, logical ports are implemented with the help of ``VirtualNetDevice``, where the user can configure callbacks to handle packets properly. * **Extensible match support**: Prior versions of the OpenFlow specification used a static fixed length structure to specify ``ofp_match``, which prevents flexible expression of matches and prevents inclusion of new match fields. The ``ofp_match`` has been changed to a TLV structure, called OpenFlow Extensible Match (OXM), which dramatically increases flexibility. @@ -196,28 +195,28 @@ Some of the most important features are: * **Per-flow meters**: Per-flow meters can be attached to flow entries and can measure and control the rate of packets. One of the primary applications of per-flow meters is to rate limit packets sent to the controller. -For |ns3| OpenFlow users who want to port existing code to this new module, please, check the :ref:`port-coding` section for detailed instructions. +For *ns-3* OpenFlow users who want to port existing code to this new module, please, check the :ref:`port-coding` section for detailed instructions. -|ns3| code compatibility +*ns-3* code compatibility ======================== -The only required modification to the |ns3| source code for |ofs13| integration is the inclusion of the new OpenFlow receive callback in the ``CsmaNetDevice`` and ``VirtualNetDevice``. -The module brings the patch for including this receive callback into |ns3| source code, available under ``utils/`` directory. +The only required modification to the *ns-3* source code for *OFSwitch13* integration is the inclusion of the new OpenFlow receive callback in the ``CsmaNetDevice`` and ``VirtualNetDevice``. +The module brings the patch for including this receive callback into *ns-3* source code, available under ``utils/`` directory. -The current |ofs13| stable version is 5.2.2. -This version is compatible with |ns3| versions 3.38 and 3.39, and will not compile with older |ns3| versions. -If you need to use another |ns3| release, you can check the 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. +The current *OFSwitch13* stable version is 5.2.3. +This version is compatible with *ns-3* versions 3.38, 3.39, adn 3.40, and will not compile with older *ns-3* versions. +If you need to use another *ns-3* release, you can check the RELEASE_NOTES file for previous *OFSwitch13* releases and their *ns-3* 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. References ========== -#. The reference [Chaves2016a]_ presents the |ofs13| module, including details about module design and implementation. +#. The reference [Chaves2016a]_ presents the *OFSwitch13* module, including details about module design and implementation. A case study scenario is also used to illustrate some of the available OpenFlow 1.3 module features. -#. The reference [Fernandes2020]_ describes the design, implementation, evolution and the current state of the |bofuss| project. +#. The reference [Fernandes2020]_ describes the design, implementation, evolution and the current state of the *BOFUSS* project. #. The references [Chaves2015]_, [Chaves2016b]_, and [Chaves2017]_ are related to the integration between OpenFlow and LTE technologies. - The |ns3| simulator, enhanced with the |ofs13| module, was used as the performance evaluation tool for these works. + The *ns-3* simulator, enhanced with the *OFSwitch13* module, was used as the performance evaluation tool for these works. .. [Chaves2015] Luciano J. Chaves, Vítor M. Eichemberger, Islene C. Garcia, and Edmundo R. M. Madeira. `"Integrating OpenFlow to LTE: some issues toward Software-Defined Mobile Networks" `_. diff --git a/doc/source/ofswitch13-usage.rst b/doc/source/ofswitch13-usage.rst index a88b21b..0e86f4e 100644 --- a/doc/source/ofswitch13-usage.rst +++ b/doc/source/ofswitch13-usage.rst @@ -1,7 +1,6 @@ Usage ***** -.. include:: replace.txt .. highlight:: cpp .. heading hierarchy: @@ -13,8 +12,8 @@ Usage Building the Module =================== -The |ofs13| module interconnects the |ns3| simulator and the |bofuss| software switch compiled as a library. -Follow the instructions below to compile the |ofs13| module. +The *OFSwitch13* module interconnects the *ns-3* simulator and the *BOFUSS* software switch compiled as a library. +Follow the instructions below to compile the *OFSwitch13* module. *Instructions were tested on Ubuntu 22.04.1 LTS.* [#f1]_ .. [#f1] Other distributions or versions may require different steps, especially regarding library compilation. @@ -32,57 +31,57 @@ Before starting, ensure you have the following minimal requirements installed on Compiling the code ################## -Clone the |ns3| source code repository into your machine and checkout a stable version (we are using the ns-3.39): +Clone the *ns-3* source code repository into your machine and checkout a stable version (we are using the ns-3.40): .. code-block:: bash $ git clone https://gitlab.com/nsnam/ns-3-dev.git $ cd ns-3-dev - $ git checkout -b ns-3.39 ns-3.39 + $ git checkout -b ns-3.40 ns-3.40 -Download the |ofs13| code into the ``contrib/`` folder. +Download the *OFSwitch13* code into the ``contrib/`` folder. .. code-block:: bash $ cd contrib/ $ git clone https://github.com/ljerezchaves/ofswitch13.git -Update the |ofs13| code to a stable version (we are using release 5.2.2, which is compatible with ns-3.39) [#f2]_: +Update the *OFSwitch13* code to a stable version (we are using release 5.2.3, which is compatible with ns-3.40) [#f2]_: -.. [#f2] Starting at |ofs13| release 5.2.0, the ``cmake`` build system will automatically download and compile the correct version of |bofuss| library (Internet connection is required). - For older |ofs13| releases, we suggest you check the documentation and follow the proper build steps. +.. [#f2] Starting at *OFSwitch13* release 5.2.0, the ``cmake`` build system will automatically download and compile the correct version of *BOFUSS* library (Internet connection is required). + For older *OFSwitch13* releases, we suggest you check the documentation and follow the proper build steps. .. code-block:: bash $ cd ofswitch13 - $ git checkout 5.2.2 + $ git checkout 5.2.3 -Go back to the |ns3| root directory and patch the |ns3| code with the appropriated ``ofswitch13`` patch available under the ``ofswitch13/utils/`` directory (check for the correct |ns3| version): +Go back to the *ns-3* root directory and patch the *ns-3* code with the appropriated ``ofswitch13`` patch available under the ``ofswitch13/utils/`` directory (check for the correct *ns-3* version): .. code-block:: bash $ cd ../../ - $ patch -p1 < contrib/ofswitch13/utils/ofswitch13-3_39.patch + $ patch -p1 < contrib/ofswitch13/utils/ofswitch13-3_40.patch This patch creates the new OpenFlow receive callback at ``CsmaNetDevice`` and ``VirtualNetDevice``, allowing OpenFlow switch to get raw packets from these devices. The module also brings a ``csma-full-duplex`` patch for improving CSMA connections with full-duplex support. -This is an optional patch that can be applyed *after* the ``ofswitch13`` patch. +This is an optional patch that can be applied *after* the ``ofswitch13`` patch. -Now, configure the |ns3|. By default, the ``cmake`` build system will handle |bofuss| library download and compilation. -Anyway, if your want to use a custom |bofuss| library, use the ``-DNS3_OFSWITCH13_BOFUSS_PATH`` configuration option to specify its location: +Now, configure the *ns-3*. By default, the ``cmake`` build system will handle *BOFUSS* library download and compilation. +Anyway, if your want to use a custom *BOFUSS* library, use the ``-DNS3_OFSWITCH13_BOFUSS_PATH`` configuration option to specify its location: .. code-block:: bash $ ./ns3 configure -Check for the enabled |ns3| |ofs13| *integration* feature after configuration. +Check for the enabled *ns-3* *OFSwitch13* *integration* feature after configuration. Finally, compile the simulator: .. code-block:: bash $ ./ns3 build -That's it! Enjoy your |ns3| fresh compilation with OpenFlow 1.3 capabilities. +That's it! Enjoy your *ns-3* fresh compilation with OpenFlow 1.3 capabilities. Basic usage =========== @@ -104,9 +103,6 @@ This script connects two hosts to a single OpenFlow switch using CSMA links, and int main(int argc, char* argv[]) { - // Enable checksum computations (required by OFSwitch13 module) - GlobalValue::Bind("ChecksumEnabled", BooleanValue(true)); - // Create two host nodes NodeContainer hosts; hosts.Create(2); @@ -157,21 +153,19 @@ This script connects two hosts to a single OpenFlow switch using CSMA links, and Simulator::Destroy(); } -At first, don't forget to enable checksum computations, which are required by the |ofs13| module. -After creating host and switch nodes, the user is responsible for connect the hosts and switches to create the desired network topology. +After creating host and switch nodes, the user is responsible for connecting the hosts and switches to create the desired network topology. Using CSMA links for these connections is mandatory. Note that ``CsmaNetDevices`` created and installed into switch node will be later configured as switch ports. After connecting hosts and switches, it's time to create a controller node and configure the OpenFlow network. -The -``OFSwitch13InternalHelper`` can be used to configure an OpenFlow network domain with internal controller application. +The ``OFSwitch13InternalHelper`` can be used to configure an OpenFlow network domain with internal controller application. The ``InstallController()`` method configures the controller node with a default OpenFlow learning controller application. The ``InstallSwitch()`` method installs the OpenFlow datapath into switch node and configures the switch ports. In the end, it's mandatory to call the ``CreateOpenFlowChannels()`` method to create the connections and start the communication between switches and controllers. -The rest of this example follows the standard |ns3| usage: installing TCP/IP stack into host nodes, configuring IP addresses, installing applications and running the simulation. +The rest of this example follows the standard *ns-3* usage: installing TCP/IP stack into host nodes, configuring IP addresses, installing applications and running the simulation. Don't install the TCP/IP stack into switches and controllers nodes (the helper does that for you). Also, don't assign an IP address to devices configured as switch ports. -For instructions on how to compile and run simulation programs, please refer to the |ns3| tutorial. +For instructions on how to compile and run simulation programs, please refer to the *ns-3* tutorial. Helpers ======= @@ -183,7 +177,7 @@ This module follows the pattern usage of standard helpers. The ``OFSwitch13Helper`` is a base class that must be extended to create and configure an OpenFlow 1.3 network domain, composed of one or more OpenFlow switches connected to single or multiple OpenFlow controllers. By default, the connections between switches and controllers are created using a single shared out-of-band CSMA channel, with IP addresses assigned to the 10.100.0.0/24 network. Users can modify this configuration by changing the ``OFSwitch13Helper::ChannelType`` attribute (dedicated out-of-band connections over CSMA or point-to-point channels are also available), or setting a different IP network address with the ``OFSwitch13Helper::SetAddressBase()`` static method. -The use of standard |ns3| channels and devices provides realistic connections with delay and error models. +The use of standard *ns-3* channels and devices provides realistic connections with delay and error models. This base class brings the methods for configuring the switches (derived classes configure the controllers). The ``InstallSwitch()`` method can be used to create and aggregate an ``OFSwitch13Device`` object to each switch node. @@ -217,7 +211,7 @@ OFSwitch13ExternalHelper This helper extends the base class and can be instantiated to create and configure an OpenFlow 1.3 network domain composed of one or more OpenFlow switches connected to a single external real OpenFlow controller. It brings methods for installing the controller node for TapBridge usage and creating the OpenFlow channels. The current implementation only supports the single shared CSMA channel type. -To configure the external controller, the ``InstallExternalController()`` method can be used to prepare the controller node so it can be used to connect internal simulated switches to an external OpenFlow controller running on the local machine over a TapBridge device. +To configure the external controller, the ``InstallExternalController()`` method can be used to prepare the controller node, so it can be used to connect internal simulated switches to an external OpenFlow controller running on the local machine over a TapBridge device. It installs the TCP/IP stack into controller node, attach it to the common CSMA channel, configure IP address for it and returns the ``NetDevice`` that the user will be responsible to bind to the TabBridge. Note that this helper is prepared to configure a single controller node. See the :ref:`external-controller` section for details. @@ -305,7 +299,7 @@ OFSwitch13StatsCalculator Output ====== -This module relies on the |ns3| tracing subsystem for output. +This module relies on the *ns-3* tracing subsystem for output. The ``OFSwitch13Helper`` base class allows users to monitor control-plane traffic by enabling PCAP and ASCII trace files for the ``NetDevices`` used to create the OpenFlow Channel(s). This approach can be useful to analyze the OpenFlow messages exchanged between switches and controllers on this network domain. To enable these traces, use the ``EnableOpenFlowPcap()`` and ``EnableOpenFlowAscii()`` helper member functions *after* configuring the switches and creating the OpenFlow channels. @@ -341,7 +335,7 @@ To enable performance monitoring, use the ``EnableDatapathStats()`` helper membe By default, statistics are dumped every second, but users can adjust this interval with the ``OFSwitch13StatsCalculator::DumpTimeout`` attribute. Besides, an Exponentially Weighted Moving Average (EWMA) is used to update the average values, and the attribute ``OFSwitch13StatsCalculator::EwmaAlpha`` can be adjusted to reflect the desired weight given to most recent measured values. -When necessary, it is also possible to enable the |bofuss| library logging mechanism using two different approaches: +When necessary, it is also possible to enable the *BOFUSS* library logging mechanism using two different approaches: #. The simplified ``OFSwitch13Helper::EnableDatapathLogs()`` static method dumps messages at debug level for all library internal modules into the output file (users can set the filename prefix); @@ -349,11 +343,11 @@ When necessary, it is also possible to enable the |bofuss| library logging mecha .. _port-coding: -Porting |ns3| OpenFlow code +Porting *ns-3* OpenFlow code =========================== -For |ns3| OpenFlow users that want to port existing code to the new |ofs13| module, keep in mind that this is not an extension of the available implementation. -For simulation scenarios using the existing |ns3| OpenFlow module configured with the ``ns3::OpenFlowSwitchHelper`` helper and using the ``ns3::ofi::LearningController``, it is possible to port the code to the |ofs13| module with little effort. +For *ns-3* OpenFlow users that want to port existing code to the new *OFSwitch13* module, keep in mind that this is not an extension of the available implementation. +For simulation scenarios using the existing *ns-3* OpenFlow module configured with the ``ns3::OpenFlowSwitchHelper`` helper and using the ``ns3::ofi::LearningController``, it is possible to port the code to the *OFSwitch13* module with little effort. The following code, based on the ``openflow-switch.cc`` example, is used for demonstration: .. code-block:: cpp @@ -385,7 +379,7 @@ This code creates an ``ns3::ofi::LearningController`` object instance as the con It also sets the internal attribute ``ExpirationTime`` for cache timeout. Then, the helper installs the OpenFlow switch device into the ``switchNode`` node. The CSMA devices from ``switchDevices`` container are installed as OpenFlow ports, and the ``controller`` object is set as the OpenFlow controller for the network. -The following code implements the same logic in the |ofs13| module: +The following code implements the same logic in the *OFSwitch13* module: .. code-block:: cpp @@ -414,14 +408,14 @@ The following code implements the same logic in the |ofs13| module: // Arbitrary simulation duration (can be changed for any value) Simulator::Stop(Seconds(10)); -Note that the |ofs13| module requires a new node to install the controller application into it. +Note that the *OFSwitch13* module requires a new node to install the controller application into it. The ``InstallController()`` function creates the learning application object instance and installs it in the ``controllerNode``. Then, the ``InstallSwitch()`` function installs the OpenFlow device into ``switchNode`` and configures the CSMA devices from ``switchDevices`` container as OpenFlow ports. Finally, the ``CreateOpenFlowChannels()`` function configures the connection between the switch and the controller. Note that the ``OFSwitch13LearningController`` does not provide the ``ExpirationTime`` attribute. Don't forget to include the ``Simulator::Stop()`` command to schedule the time delay until the Simulator should stop; otherwise, the simulation will never end. -For users who have implemented new controllers in the |ns3| OpenFlow module, extending the ``ns3::ofi::Controller`` class, are encouraged to explore the examples and the Doxygen documentation for the ``OFSwitch13Controller`` base class. +For users who have implemented new controllers in the *ns-3* OpenFlow module, extending the ``ns3::ofi::Controller`` class, are encouraged to explore the examples and the Doxygen documentation for the ``OFSwitch13Controller`` base class. In a nutshell, the ``ReceiveFromSwitch()`` function is replaced by the internal handlers, used to process each type of OpenFlow message received from the switch. See the :ref:`extending-controller` section for more details. @@ -464,7 +458,7 @@ It looks for L2 switching information and removes associated entry. The ``QosController`` example includes a non-trivial controller implementation that is used to configure the network described in :ref:`qos-controller` section. Several ``dpctl`` commands are used to configure the switches based on network topology and desired control logic, while the ``HandlePacketIn()`` is used to filter packets sent to the controller by the switch. -Note that the |bofuss| function ``oxm_match_lookup()`` is used across the code to extract match information from the message received by the controller. +Note that the *BOFUSS* function ``oxm_match_lookup()`` is used across the code to extract match information from the message received by the controller. For ARP messages, ``HandleArpPacketIn()`` exemplifies how to create a new packet at the controller and send to the network over a packet-out message. Developers are encouraged to study the library internal structures to understand better how the handlers are implemented and also how to build an OpenFlow message manually. @@ -473,7 +467,7 @@ Developers are encouraged to study the library internal structures to understand External controller ################### -Considering that the OpenFlow messages traversing the OpenFlow channel follow the standard wire format, it is possible to use the |ns3| ``TapBridge`` module to integrate an external OpenFlow 1.3 controller, running on the local system, to the simulated environment. +Considering that the OpenFlow messages traversing the OpenFlow channel follow the standard wire format, it is possible to use the *ns-3* ``TapBridge`` module to integrate an external OpenFlow 1.3 controller, running on the local system, to the simulated environment. The experimental ``external-controller.cc`` example uses the ``OFSwitch13ExternalHelper`` to this end, as follows: .. code-block:: cpp @@ -542,14 +536,14 @@ Examples summary The QoS controller example ########################## -A case study scenario was used by [Chaves2016a]_ to demonstrate how some of the available OpenFlow 1.3 module features can be employed to improve network management. +A case study scenario was used by [Chaves2016a]_ to demonstrate how some available OpenFlow 1.3 module features can be employed to improve network management. Figure :ref:`fig-network-topo` shows the network topology used in this example. It represents the internal network of an organization, where servers and client nodes are located far from each other (e.g., in separated buildings). The "long-distance" connection between the sites is via two links of 10 Mbps each, while all the other local connections are 100 Mbps. On the server side, the *OpenFlow border switch* acts as a border router element: it is responsible for handling connection requests coming from the clients and redirecting them to the appropriate internal server. On the client side, the *OpenFlow client switch* is used to interconnect all clients in a star topology. Between these two switches, there is the *OpenFlow aggregation switch*, located at the border of the client side and used to provide improved long-distance communication. -The default |ofs13| learning controller is used to manage the client switch, whereas the new *OpenFlow QoS controller* is used to manage the other two switches. +The default *OFSwitch13* learning controller is used to manage the client switch, whereas the new *OpenFlow QoS controller* is used to manage the other two switches. The latter controller implements some QoS functionalities exploiting OpenFlow 1.3 features, as described below. Each client opens a single TCP connection with one of the 2 available servers, and sends packets in uplink direction as much as possible, trying to fill the available bandwidth. @@ -569,7 +563,7 @@ Each group receives packets as input and performs any OpenFlow actions on these The power of a group is that it contains separate lists of actions, and each action list is referred to as an OpenFlow bucket. There are different types of groups, and the *select* group type can be used to perform link aggregation. Each bucket in a select group has an assigned weight, and each packet that enters the group is sent to a single bucket. -The bucket selection algorithm is undefined and is dependent on the switch's implementation (the |bofuss| library implements the weighted round robin algorithm). +The bucket selection algorithm is undefined and is dependent on the switch's implementation (the *BOFUSS* library implements the weighted round-robin algorithm). In the proposed network topology, the QoS controller configures both the border and the aggregation switches to perform link aggregation over the two narrowband long-distance connections, providing a 20 Mbps connection between servers and clients (use the ``QosController::LinkAggregation`` attribute to enable/disable this feature). Each OpenFlow bucket has the same weight in the select group, so the load is evenly distributed among the links. @@ -582,7 +576,7 @@ The most commonly used applications of load balancing is to provide single Inter In the proposed network topology, the OpenFlow QoS controller configures the border switch to listen for new requests on the IP and port where external clients connect to access the servers. The switch forwards the new request to the controller, which decides which of the internal servers must take care of this connection. Then, it installs the match rules into border switch to forward the subsequent packets from the same connection directly to the chosen server. -All this happen without the client ever knowing about the internal separation of functions. +All this happens without the client ever knowing about the internal separation of functions. To implement this load balancing mechanism, the QoS controller depends on the extensible match support introduced in OpenFlow 1.2. Prior versions of the OpenFlow specification used a static fixed length structure to specify matches, which prevents flexible expression of matches and prevents the inclusion of new match fields. diff --git a/doc/source/ofswitch13.rst b/doc/source/ofswitch13.rst index ca301d7..f273eaa 100644 --- a/doc/source/ofswitch13.rst +++ b/doc/source/ofswitch13.rst @@ -2,7 +2,6 @@ OpenFlow 1.3 Module (OFSwitch13) -------------------------------- -.. include:: replace.txt .. highlight:: cpp .. heading hierarchy: diff --git a/doc/source/replace.txt b/doc/source/replace.txt deleted file mode 100644 index 730f152..0000000 --- a/doc/source/replace.txt +++ /dev/null @@ -1,8 +0,0 @@ -.. |ns3| replace:: *ns-3* - -.. |ns2| replace:: *ns-2* - -.. |ofs13| replace:: *OFSwitch13* - -.. |bofuss| replace:: *BOFUSS* - diff --git a/examples/ofswitch13-custom-switch.cc b/examples/ofswitch13-custom-switch.cc index e4bdada..42c5491 100644 --- a/examples/ofswitch13-custom-switch.cc +++ b/examples/ofswitch13-custom-switch.cc @@ -78,8 +78,6 @@ main(int argc, char* argv[]) LogComponentEnable("OFSwitch13InternalHelper", LOG_LEVEL_ALL); } - // Enable checksum computations (required by OFSwitch13 module) - GlobalValue::Bind("ChecksumEnabled", BooleanValue(true)); // Create two host nodes NodeContainer hosts; diff --git a/examples/ofswitch13-external-controller.cc b/examples/ofswitch13-external-controller.cc index 2bb6c66..65a69fa 100644 --- a/examples/ofswitch13-external-controller.cc +++ b/examples/ofswitch13-external-controller.cc @@ -82,8 +82,6 @@ main(int argc, char* argv[]) LogComponentEnable("OFSwitch13InternalHelper", LOG_LEVEL_ALL); } - // Enable checksum computations (required by OFSwitch13 module) - GlobalValue::Bind("ChecksumEnabled", BooleanValue(true)); // Set simulator to real time mode GlobalValue::Bind("SimulatorImplementationType", StringValue("ns3::RealtimeSimulatorImpl")); diff --git a/examples/ofswitch13-first.cc b/examples/ofswitch13-first.cc index b0a2297..ef79ee8 100644 --- a/examples/ofswitch13-first.cc +++ b/examples/ofswitch13-first.cc @@ -66,9 +66,6 @@ main(int argc, char* argv[]) LogComponentEnable("OFSwitch13InternalHelper", LOG_LEVEL_ALL); } - // Enable checksum computations (required by OFSwitch13 module) - GlobalValue::Bind("ChecksumEnabled", BooleanValue(true)); - // Create two host nodes NodeContainer hosts; hosts.Create(2); diff --git a/examples/ofswitch13-logical-port/main.cc b/examples/ofswitch13-logical-port/main.cc index 95c1684..3a03c11 100644 --- a/examples/ofswitch13-logical-port/main.cc +++ b/examples/ofswitch13-logical-port/main.cc @@ -75,9 +75,6 @@ main(int argc, char* argv[]) LogComponentEnable("GtpTunnelApp", LOG_LEVEL_ALL); } - // Enable checksum computations (required by OFSwitch13 module) - GlobalValue::Bind("ChecksumEnabled", BooleanValue(true)); - // Create two host nodes NodeContainer hosts; hosts.Create(2); diff --git a/examples/ofswitch13-multiple-controllers.cc b/examples/ofswitch13-multiple-controllers.cc index aeff24b..47c4786 100644 --- a/examples/ofswitch13-multiple-controllers.cc +++ b/examples/ofswitch13-multiple-controllers.cc @@ -70,9 +70,6 @@ main(int argc, char* argv[]) LogComponentEnable("OFSwitch13InternalHelper", LOG_LEVEL_ALL); } - // Enable checksum computations (required by OFSwitch13 module) - GlobalValue::Bind("ChecksumEnabled", BooleanValue(true)); - // Create two host nodes NodeContainer hosts; hosts.Create(2); diff --git a/examples/ofswitch13-multiple-domains.cc b/examples/ofswitch13-multiple-domains.cc index 6a09bed..da23afa 100644 --- a/examples/ofswitch13-multiple-domains.cc +++ b/examples/ofswitch13-multiple-domains.cc @@ -66,9 +66,6 @@ main(int argc, char* argv[]) LogComponentEnable("OFSwitch13InternalHelper", LOG_LEVEL_ALL); } - // Enable checksum computations (required by OFSwitch13 module) - GlobalValue::Bind("ChecksumEnabled", BooleanValue(true)); - // Create two host nodes NodeContainer hosts; hosts.Create(2); diff --git a/examples/ofswitch13-qos-controller/main.cc b/examples/ofswitch13-qos-controller/main.cc index 6f816d1..e8ba576 100644 --- a/examples/ofswitch13-qos-controller/main.cc +++ b/examples/ofswitch13-qos-controller/main.cc @@ -82,14 +82,11 @@ main(int argc, char* argv[]) // Configure dedicated connections between controller and switches Config::SetDefault("ns3::OFSwitch13Helper::ChannelType", - EnumValue(OFSwitch13Helper::DEDICATEDCSMA)); + EnumValue(OFSwitch13Helper::DEDICATED_CSMA)); // Increase TCP MSS for larger packets Config::SetDefault("ns3::TcpSocket::SegmentSize", UintegerValue(1400)); - // Enable checksum computations (required by OFSwitch13 module) - GlobalValue::Bind("ChecksumEnabled", BooleanValue(true)); - // Discard the first MAC address ("00:00:00:00:00:01") which will be used by // the border switch in association with the first IP address ("10.1.1.1") // for the Internet service. diff --git a/examples/ofswitch13-single-domain.cc b/examples/ofswitch13-single-domain.cc index 63d70ce..abb3ebe 100644 --- a/examples/ofswitch13-single-domain.cc +++ b/examples/ofswitch13-single-domain.cc @@ -68,9 +68,6 @@ main(int argc, char* argv[]) LogComponentEnable("OFSwitch13InternalHelper", LOG_LEVEL_ALL); } - // Enable checksum computations (required by OFSwitch13 module) - GlobalValue::Bind("ChecksumEnabled", BooleanValue(true)); - // Create two host nodes NodeContainer hosts; hosts.Create(2); diff --git a/helper/ofswitch13-external-helper.cc b/helper/ofswitch13-external-helper.cc index ce7e1db..2ded4a1 100644 --- a/helper/ofswitch13-external-helper.cc +++ b/helper/ofswitch13-external-helper.cc @@ -21,6 +21,8 @@ #include "ofswitch13-external-helper.h" +#include + namespace ns3 { @@ -64,7 +66,7 @@ OFSwitch13ExternalHelper::SetChannelType(ChannelType type) NS_LOG_FUNCTION(this << type); // Check for valid channel type for this helper. - NS_ABORT_MSG_IF(type != OFSwitch13Helper::SINGLECSMA, + NS_ABORT_MSG_IF(type != OFSwitch13Helper::SINGLE_CSMA, "Invalid channel type for OFSwitch13ExternalHelper (use SingleCsma)."); OFSwitch13Helper::SetChannelType(type); } @@ -89,10 +91,13 @@ OFSwitch13ExternalHelper::CreateOpenFlowChannels() // Block this helper to avoid further calls to install methods. m_blocked = true; + // Enable checksum computations (mandatory for this module) + GlobalValue::Bind("ChecksumEnabled", BooleanValue(true)); + // Create and start the connections between switches and controllers. switch (m_channelType) { - case OFSwitch13ExternalHelper::SINGLECSMA: { + case OFSwitch13ExternalHelper::SINGLE_CSMA: { NS_LOG_INFO("Attach all switches and controllers to the same CSMA network."); // Connecting all switches to the common channel. @@ -112,8 +117,8 @@ OFSwitch13ExternalHelper::CreateOpenFlowChannels() m_ipv4helper.NewNetwork(); break; } - case OFSwitch13ExternalHelper::DEDICATEDCSMA: - case OFSwitch13ExternalHelper::DEDICATEDP2P: + case OFSwitch13ExternalHelper::DEDICATED_CSMA: + case OFSwitch13ExternalHelper::DEDICATED_P2P: default: { NS_ABORT_MSG("Invalid OpenflowChannelType."); } diff --git a/helper/ofswitch13-helper.cc b/helper/ofswitch13-helper.cc index ecc0e14..a2f340f 100644 --- a/helper/ofswitch13-helper.cc +++ b/helper/ofswitch13-helper.cc @@ -64,13 +64,13 @@ OFSwitch13Helper::GetTypeId() .AddAttribute("ChannelType", "The configuration used to create the OpenFlow channel", TypeId::ATTR_GET | TypeId::ATTR_CONSTRUCT, - EnumValue(OFSwitch13Helper::SINGLECSMA), + EnumValue(OFSwitch13Helper::SINGLE_CSMA), MakeEnumAccessor(&OFSwitch13Helper::SetChannelType), - MakeEnumChecker(OFSwitch13Helper::SINGLECSMA, + MakeEnumChecker(OFSwitch13Helper::SINGLE_CSMA, "SingleCsma", - OFSwitch13Helper::DEDICATEDCSMA, + OFSwitch13Helper::DEDICATED_CSMA, "DedicatedCsma", - OFSwitch13Helper::DEDICATEDP2P, + OFSwitch13Helper::DEDICATED_P2P, "DedicatedP2p")); return tid; } @@ -108,12 +108,12 @@ OFSwitch13Helper::EnableOpenFlowPcap(std::string prefix, bool promiscuous) NS_ABORT_MSG_IF(!m_blocked, "OpenFlow channels not configured yet."); switch (m_channelType) { - case OFSwitch13Helper::SINGLECSMA: - case OFSwitch13Helper::DEDICATEDCSMA: { + case OFSwitch13Helper::SINGLE_CSMA: + case OFSwitch13Helper::DEDICATED_CSMA: { m_csmaHelper.EnablePcap(prefix, m_controlDevs, promiscuous); break; } - case OFSwitch13Helper::DEDICATEDP2P: { + case OFSwitch13Helper::DEDICATED_P2P: { m_p2pHelper.EnablePcap(prefix, m_controlDevs, promiscuous); break; } @@ -132,12 +132,12 @@ OFSwitch13Helper::EnableOpenFlowAscii(std::string prefix) AsciiTraceHelper ascii; switch (m_channelType) { - case OFSwitch13Helper::SINGLECSMA: - case OFSwitch13Helper::DEDICATEDCSMA: { + case OFSwitch13Helper::SINGLE_CSMA: + case OFSwitch13Helper::DEDICATED_CSMA: { m_csmaHelper.EnableAsciiAll(ascii.CreateFileStream(prefix + ".txt")); break; } - case OFSwitch13Helper::DEDICATEDP2P: { + case OFSwitch13Helper::DEDICATED_P2P: { m_p2pHelper.EnableAsciiAll(ascii.CreateFileStream(prefix + ".txt")); break; } diff --git a/helper/ofswitch13-helper.h b/helper/ofswitch13-helper.h index 48480eb..c222bab 100644 --- a/helper/ofswitch13-helper.h +++ b/helper/ofswitch13-helper.h @@ -78,9 +78,9 @@ class OFSwitch13Helper : public Object */ enum ChannelType { - SINGLECSMA = 0, //!< Uses a single shared CSMA channel. - DEDICATEDCSMA = 1, //!< Uses individual CSMA channels. - DEDICATEDP2P = 2 //!< Uses individual P2P channels. + SINGLE_CSMA = 0, //!< Uses a single shared CSMA channel. + DEDICATED_CSMA = 1, //!< Uses individual CSMA channels. + DEDICATED_P2P = 2 //!< Uses individual P2P channels. }; OFSwitch13Helper(); //!< Default constructor. diff --git a/helper/ofswitch13-internal-helper.cc b/helper/ofswitch13-internal-helper.cc index 6c08c1a..1de7c8c 100644 --- a/helper/ofswitch13-internal-helper.cc +++ b/helper/ofswitch13-internal-helper.cc @@ -21,6 +21,7 @@ #include "ofswitch13-internal-helper.h" +#include #include namespace ns3 @@ -62,10 +63,13 @@ OFSwitch13InternalHelper::CreateOpenFlowChannels() // Block this helper to avoid further calls to install methods. m_blocked = true; + // Enable checksum computations (mandatory for this module) + GlobalValue::Bind("ChecksumEnabled", BooleanValue(true)); + // Create and start the connections between switches and controllers. switch (m_channelType) { - case OFSwitch13InternalHelper::SINGLECSMA: { + case OFSwitch13InternalHelper::SINGLE_CSMA: { NS_LOG_INFO("Attach all switches and controllers to the same CSMA network."); // Create the common channel for all switches and controllers. @@ -98,8 +102,8 @@ OFSwitch13InternalHelper::CreateOpenFlowChannels() m_ipv4helper.NewNetwork(); break; } - case OFSwitch13InternalHelper::DEDICATEDCSMA: - case OFSwitch13InternalHelper::DEDICATEDP2P: { + case OFSwitch13InternalHelper::DEDICATED_CSMA: + case OFSwitch13InternalHelper::DEDICATED_P2P: { // Setting channel/device data rates. m_p2pHelper.SetDeviceAttribute("DataRate", DataRateValue(m_channelDataRate)); m_csmaHelper.SetChannelAttribute("DataRate", DataRateValue(m_channelDataRate)); @@ -188,13 +192,13 @@ OFSwitch13InternalHelper::Connect(Ptr ctrl, Ptr swtch) NodeContainer pairNodes(ctrl, swtch); switch (m_channelType) { - case OFSwitch13InternalHelper::DEDICATEDCSMA: { + case OFSwitch13InternalHelper::DEDICATED_CSMA: { return m_csmaHelper.Install(pairNodes); } - case OFSwitch13InternalHelper::DEDICATEDP2P: { + case OFSwitch13InternalHelper::DEDICATED_P2P: { return m_p2pHelper.Install(pairNodes); } - case OFSwitch13InternalHelper::SINGLECSMA: + case OFSwitch13InternalHelper::SINGLE_CSMA: default: { NS_ABORT_MSG("Invalid OpenflowChannelType."); } diff --git a/helper/ofswitch13-stats-calculator.h b/helper/ofswitch13-stats-calculator.h index 6c16b08..5cd52d7 100644 --- a/helper/ofswitch13-stats-calculator.h +++ b/helper/ofswitch13-stats-calculator.h @@ -32,7 +32,7 @@ namespace ns3 * calculator connects to a collection of trace sources in the OpenFlow switch * device to monitor the following metrics: * - * -# [LoaKbps] CPU porocessing load in the last interval (Kbps); + * -# [LoaKbps] CPU processing load in the last interval (Kbps); * -# [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); diff --git a/model/ofswitch13-device.cc b/model/ofswitch13-device.cc index fcd5c41..aa91427 100644 --- a/model/ofswitch13-device.cc +++ b/model/ofswitch13-device.cc @@ -701,7 +701,7 @@ OFSwitch13Device::DatapathNew() { NS_LOG_FUNCTION(this); - struct datapath* dp = (struct datapath*)xmalloc(sizeof(struct datapath)); + auto dp = (struct datapath*)xmalloc(sizeof(struct datapath)); dp->mfr_desc = (char*)xmalloc(DESC_STR_LEN); dp->hw_desc = (char*)xmalloc(DESC_STR_LEN); @@ -1014,7 +1014,7 @@ OFSwitch13Device::ReceiveFromController(Ptr packet, Address from) // was sent and the one that was received in the version fields. So, for // the OFPT_HELLO message, we will check for advertised version to see // if it is higher than ours, in which case we can continue. - struct ofp_header* header = (struct ofp_header*)buffer->data; + auto header = (struct ofp_header*)buffer->data; if (header->type != OFPT_HELLO || header->version <= OFP_VERSION) { // This is not a hello message or the advertised version is lower diff --git a/model/ofswitch13-device.h b/model/ofswitch13-device.h index 0ea40d8..d9c33e6 100644 --- a/model/ofswitch13-device.h +++ b/model/ofswitch13-device.h @@ -394,7 +394,7 @@ class OFSwitch13Device : public Object /** * Check if any flow in any table is timed out and update port status. This - * method schedules itself at every m_timout interval, to periodically check + * method schedules itself at every m_timeout interval, to periodically check * the pipeline for timed out flow entries and update port status. * \see BOFUSS function pipeline_timeout() at udatapath/pipeline.c * \param dp The datapath. diff --git a/model/ofswitch13-interface.cc b/model/ofswitch13-interface.cc index 49ed5de..81300bc 100644 --- a/model/ofswitch13-interface.cc +++ b/model/ofswitch13-interface.cc @@ -41,7 +41,7 @@ EnableBofussLog(bool printToFile, std::string filename = prefix; if (!explicitFilename) { - if (filename.size() && filename.back() != '-') + if (!filename.empty() && filename.back() != '-') { filename += "-"; } @@ -55,7 +55,7 @@ EnableBofussLog(bool printToFile, vlog_set_levels(VLM_ANY_MODULE, VLF_CONSOLE, VLL_DBG); } - if (customLevels.size()) + if (!customLevels.empty()) { vlog_set_levels_from_string(customLevels.c_str()); } diff --git a/model/ofswitch13-learning-controller.cc b/model/ofswitch13-learning-controller.cc index 6e176de..37a6990 100644 --- a/model/ofswitch13-learning-controller.cc +++ b/model/ofswitch13-learning-controller.cc @@ -169,8 +169,7 @@ OFSwitch13LearningController::HandlePacketIn(struct ofl_msg_packet_in* msg, } // Create output action - struct ofl_action_output* a = - (struct ofl_action_output*)xmalloc(sizeof(struct ofl_action_output)); + auto a = (struct ofl_action_output*)xmalloc(sizeof(struct ofl_action_output)); a->header.type = OFPAT_OUTPUT; a->port = outPort; a->max_len = 0; diff --git a/model/ofswitch13-priority-queue.cc b/model/ofswitch13-priority-queue.cc index 961cd5c..2e58578 100644 --- a/model/ofswitch13-priority-queue.cc +++ b/model/ofswitch13-priority-queue.cc @@ -37,7 +37,6 @@ GetDefaultQueueFactory() // Setting default internal queue configuration. ObjectFactory queueFactory; queueFactory.SetTypeId("ns3::DropTailQueue"); - queueFactory.Set("MaxSize", StringValue("100p")); return queueFactory; } diff --git a/utils/csma-full-duplex-3_40.patch b/utils/csma-full-duplex-3_40.patch new file mode 100644 index 0000000..706ee5f --- /dev/null +++ b/utils/csma-full-duplex-3_40.patch @@ -0,0 +1,908 @@ +From 776bf612d60d1656940786c6bca6ee3def99a7c4 Mon Sep 17 00:00:00 2001 +From: Luciano J Chaves +Date: Wed, 11 Oct 2023 10:15:37 -0300 +Subject: [PATCH] CSMA full-duplex patch + +--- + src/csma/doc/csma.rst | 62 +++++++++----- + src/csma/examples/CMakeLists.txt | 1 + + src/csma/examples/csma-duplex.cc | 105 +++++++++++++++++++++++ + src/csma/model/csma-channel.cc | 133 +++++++++++++++++++++++------- + src/csma/model/csma-channel.h | 112 ++++++++++++++++++++++--- + src/csma/model/csma-net-device.cc | 80 +++++++++++------- + src/csma/test/examples-to-run.py | 1 + + 7 files changed, 401 insertions(+), 93 deletions(-) + create mode 100644 src/csma/examples/csma-duplex.cc + +diff --git a/src/csma/doc/csma.rst b/src/csma/doc/csma.rst +index 13cc3c876..c4f59ce47 100644 +--- a/src/csma/doc/csma.rst ++++ b/src/csma/doc/csma.rst +@@ -14,6 +14,12 @@ The |ns3| CSMA device models a simple bus network in the spirit of Ethernet. + Although it does not model any real physical network you could ever build or + buy, it does provide some very useful functionality. + ++When Ethernet was standardised, all communication was half-duplex. Half-duplex ++communication restricts a node to either transmit or receive at a time but not ++perform both actions concurrently. By default, the |ns3| CSMA device models a ++half-duplex bus network, with no fixed limit on the number of devices connected ++to the shared transmission medium. ++ + Typically when one thinks of a bus network Ethernet or IEEE 802.3 comes to mind. + Ethernet uses CSMA/CD (Carrier Sense Multiple Access with Collision Detection + with exponentially increasing backoff to contend for the shared transmission +@@ -23,6 +29,12 @@ light) carrier sense and priority-based collision "avoidance." Collisions in the + sense of Ethernet never happen and so the |ns3| CSMA device does not model + collision detection, nor will any transmission in progress be "jammed." + ++This model also offers support for full-duplex communication, where the ++transmission medium can operate in both directions simultaneously but is ++restricted to a maximum of two devices connected on the single full-duplex ++link. When in full-duplex operation, the original CSMA/CD protocol is shut off ++and the two devices on the link can send data independently. ++ + CSMA Layer Model + ++++++++++++++++ + +@@ -83,8 +95,7 @@ the protocol stack. + CSMA Channel Model + ****************** + +-The class CsmaChannel models the actual transmission medium. There is no fixed +-limit for the number of devices connected to the channel. The CsmaChannel models ++The class CsmaChannel models the actual transmission medium. The CsmaChannel models + a data rate and a speed-of-light delay which can be accessed via the attributes + "DataRate" and "Delay" respectively. The data rate provided to the channel is + used to set the data rates used by the transmitter sections of the CSMA devices +@@ -94,6 +105,18 @@ limitation (other than by the data type holding the value) on the speed at which + CSMA channels and devices can operate; and no restriction based on any kind of + PHY characteristics. + ++The CsmaChannel can operate in half-duplex or in full-duplex mode, which can be ++defined via the attribute "FullDuplex". The CsmaChannel holds two internal ++subchannels. When operating in half-duplex mode, only the first subchannel is ++used by all devices for both transmission and reception procedures. In this ++case, the CsmaChannel models a broadcast medium so the packet is delivered to ++all of the devices on the channel (except the source) at the end of the ++propagation time. It is the responsibility of the sending device to determine ++whether or not it receives a packet broadcast over the channel. When the ++CsmaChannel is operating in full-duplex mode (with a maximum of two devices ++attached to the channel), each device uses its exclusive subchannel for ++unidirectional packet transmission, getting rid of the CSMA/CD mechanism. ++ + The CsmaChannel has three states, ``IDLE``, ``TRANSMITTING`` and + ``PROPAGATING``. These three states are "seen" instantaneously by all devices on + the channel. By this we mean that if one device begins or ends a simulated +@@ -133,15 +156,11 @@ through its cable to the hub; plus 2) the time it takes for the hub to forward + the packet out a port; plus 3) the time it takes for the signal in question to + propagate to the destination net device. + +-The CsmaChannel models a broadcast medium so the packet is delivered to all of +-the devices on the channel (including the source) at the end of the propagation +-time. It is the responsibility of the sending device to determine whether or not +-it receives a packet broadcast over the channel. +- + The CsmaChannel provides following Attributes: + + * DataRate: The bitrate for packet transmission on connected devices; +-* Delay: The speed of light transmission delay for the channel. ++* Delay: The speed of light transmission delay for the channel; ++* FullDuplex: Whether the channel is operating in full-duplex mode or not. + + CSMA Net Device Model + ********************* +@@ -195,7 +214,9 @@ The CsmaNetDevice implements a random exponential backoff algorithm that is + executed if the channel is determined to be busy (``TRANSMITTING`` or + ``PPROPAGATING``) when the device wants to start propagating. This results in a + random delay of up to pow (2, retries) - 1 microseconds before a retry is +-attempted. The default maximum number of retries is 1000. ++attempted. The default maximum number of retries is 1000. Note that the random ++exponential backoff algorithm is not used when the device is attached to a ++channel in full-duplex operation. + + Using the CsmaNetDevice + *********************** +@@ -349,16 +370,19 @@ net device. + Summary + ******* + +-The ns3 CSMA model is a simplistic model of an Ethernet-like network. It +-supports a Carrier-Sense function and allows for Multiple Access to a +-shared medium. It is not physical in the sense that the state of the +-medium is instantaneously shared among all devices. This means that there +-is no collision detection required in this model and none is implemented. +-There will never be a "jam" of a packet already on the medium. Access to +-the shared channel is on a first-come first-served basis as determined by +-the simulator scheduler. If the channel is determined to be busy by looking +-at the global state, a random exponential backoff is performed and a retry +-is attempted. ++The ns3 CSMA model is a simplistic model of an Ethernet-like network that can ++operate in half-duplex or in full-duplex modes. In half-duplex mode, it ++supports a Carrier-Sense function and allows for Multiple Access to a shared ++medium. It is not physical in the sense that the state of the medium is ++instantaneously shared among all devices. This means that there is no collision ++detection required in this model and none is implemented. There will never be a ++"jam" of a packet already on the medium. Access to the shared channel is on a ++first-come first-served basis as determined by the simulator scheduler. If the ++channel is determined to be busy by looking at the global state, a random ++exponential backoff is performed and a retry is attempted. When operating in ++full-duplex mode, restricted to a maximum of two devices on the channel, the ++transmission medium can operate in both directions simultaneously and there is ++no need of the original CSMA/CD protocol. + + Ns-3 Attributes provide a mechanism for setting various parameters in the + device and channel such as addresses, encapsulation modes and error model +diff --git a/src/csma/examples/CMakeLists.txt b/src/csma/examples/CMakeLists.txt +index 6bf85da2a..201fa9d3d 100644 +--- a/src/csma/examples/CMakeLists.txt ++++ b/src/csma/examples/CMakeLists.txt +@@ -3,6 +3,7 @@ set(base_examples + csma-broadcast + csma-packet-socket + csma-multicast ++ csma-duplex + ) + foreach( + example +diff --git a/src/csma/examples/csma-duplex.cc b/src/csma/examples/csma-duplex.cc +new file mode 100644 +index 000000000..c9a3a3f2b +--- /dev/null ++++ b/src/csma/examples/csma-duplex.cc +@@ -0,0 +1,105 @@ ++/* ++ * Copyright (c) 2017 Luciano Jerez Chaves ++ * ++ * 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 ++ * published by the Free Software Foundation; ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ * ++ * Author: Luciano Jerez Chaves ++ */ ++ ++#include "ns3/applications-module.h" ++#include "ns3/core-module.h" ++#include "ns3/csma-module.h" ++#include "ns3/internet-module.h" ++#include "ns3/network-module.h" ++ ++using namespace ns3; ++ ++int ++main(int argc, char* argv[]) ++{ ++ bool verbose = false; ++ bool trace = false; ++ ++ CommandLine cmd; ++ cmd.AddValue("verbose", "Tell application to log if true", verbose); ++ cmd.AddValue("trace", "Tracing traffic to files", trace); ++ cmd.AddValue("duplex", "ns3::CsmaChannel::FullDuplex"); ++ cmd.Parse(argc, argv); ++ ++ if (verbose) ++ { ++ LogComponentEnable("CsmaNetDevice", LOG_LEVEL_ALL); ++ LogComponentEnable("CsmaChannel", LOG_LEVEL_ALL); ++ LogComponentEnable("Backoff", LOG_LEVEL_ALL); ++ } ++ ++ // Create the host nodes ++ NodeContainer hosts; ++ hosts.Create(2); ++ ++ // Connecting the hosts ++ CsmaHelper csmaHelper; ++ csmaHelper.SetChannelAttribute("DataRate", DataRateValue(DataRate("100Mbps"))); ++ csmaHelper.SetChannelAttribute("Delay", TimeValue(MilliSeconds(1))); ++ NetDeviceContainer hostDevices = csmaHelper.Install(hosts); ++ ++ // Enable pcap traces ++ if (trace) ++ { ++ csmaHelper.EnablePcap("csma-duplex", hostDevices); ++ } ++ ++ // Installing the tcp/ip stack into hosts ++ InternetStackHelper internet; ++ internet.Install(hosts); ++ ++ // Set IPv4 host address ++ Ipv4AddressHelper ipv4switches; ++ Ipv4InterfaceContainer internetIpIfaces; ++ ipv4switches.SetBase("10.1.1.0", "255.255.255.0"); ++ internetIpIfaces = ipv4switches.Assign(hostDevices); ++ Ipv4Address h0Addr = internetIpIfaces.GetAddress(0); ++ Ipv4Address h1Addr = internetIpIfaces.GetAddress(1); ++ ++ ApplicationContainer senderApps; ++ ApplicationContainer sinkApps; ++ ++ // TCP traffic from host 0 to 1 ++ BulkSendHelper sender0("ns3::TcpSocketFactory", InetSocketAddress(h1Addr, 10000)); ++ PacketSinkHelper sink1("ns3::TcpSocketFactory", ++ InetSocketAddress(Ipv4Address::GetAny(), 10000)); ++ senderApps.Add(sender0.Install(hosts.Get(0))); ++ sinkApps.Add(sink1.Install(hosts.Get(1))); ++ ++ // TCP traffic from host 1 to 0 ++ BulkSendHelper sender1("ns3::TcpSocketFactory", InetSocketAddress(h0Addr, 10001)); ++ PacketSinkHelper sink0("ns3::TcpSocketFactory", ++ InetSocketAddress(Ipv4Address::GetAny(), 10001)); ++ senderApps.Add(sender1.Install(hosts.Get(1))); ++ sinkApps.Add(sink0.Install(hosts.Get(0))); ++ ++ sinkApps.Start(Seconds(0)); ++ senderApps.Start(Seconds(0.01)); ++ senderApps.Stop(Seconds(5)); ++ ++ // Run the simulation ++ Simulator::Run(); ++ Simulator::Destroy(); ++ ++ // Transmitted bytes ++ Ptr pktSink0 = DynamicCast(sinkApps.Get(1)); ++ Ptr pktSink1 = DynamicCast(sinkApps.Get(0)); ++ std::cout << "Total bytes sent from H0 to H1: " << pktSink1->GetTotalRx() << std::endl; ++ std::cout << "Total bytes sent from H1 to H0: " << pktSink0->GetTotalRx() << std::endl; ++} +diff --git a/src/csma/model/csma-channel.cc b/src/csma/model/csma-channel.cc +index 2a0defc8c..7881aa96a 100644 +--- a/src/csma/model/csma-channel.cc ++++ b/src/csma/model/csma-channel.cc +@@ -1,5 +1,8 @@ + /* + * Copyright (c) 2007 Emmanuelle Laprise ++ * Copyright (c) 2012 Jeff Young ++ * Copyright (c) 2014 Murphy McCauley ++ * Copyright (c) 2017 Luciano Jerez Chaves + * + * 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 +@@ -15,6 +18,9 @@ + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Emmanuelle Laprise ++ * Author: Jeff Young ++ * Author: Murphy McCauley ++ * Author: Luciano Jerez Chaves + */ + + #include "csma-channel.h" +@@ -50,7 +56,13 @@ CsmaChannel::GetTypeId() + "Transmission delay through the channel", + TimeValue(Seconds(0)), + MakeTimeAccessor(&CsmaChannel::m_delay), +- MakeTimeChecker()); ++ MakeTimeChecker()) ++ .AddAttribute("FullDuplex", ++ "Whether the channel is full-duplex mode.", ++ TypeId::ATTR_CONSTRUCT, ++ BooleanValue(false), ++ MakeBooleanAccessor(&CsmaChannel::m_fullDuplex), ++ MakeBooleanChecker()); + return tid; + } + +@@ -58,7 +70,6 @@ CsmaChannel::CsmaChannel() + : Channel() + { + NS_LOG_FUNCTION_NOARGS(); +- m_state = IDLE; + m_deviceList.clear(); + } + +@@ -74,9 +85,21 @@ CsmaChannel::Attach(Ptr device) + NS_LOG_FUNCTION(this << device); + NS_ASSERT(device); + ++ // ++ // For full-duplex links we can only attach two devices to the same channel ++ // since there is no backoff mechanism for concurrent transmissions. ++ // ++ if (m_fullDuplex && m_deviceList.size() >= 2) ++ { ++ NS_LOG_DEBUG("Falling back to half-duplex"); ++ m_fullDuplex = false; ++ } ++ + CsmaDeviceRec rec(device); + + m_deviceList.push_back(rec); ++ SetState(m_deviceList.size() - 1, IDLE); ++ SetCurrentSrc(m_deviceList.size() - 1, m_deviceList.size() - 1); + return (m_deviceList.size() - 1); + } + +@@ -109,7 +132,7 @@ CsmaChannel::Reattach(uint32_t deviceId) + { + NS_LOG_FUNCTION(this << deviceId); + +- if (deviceId < m_deviceList.size()) ++ if (deviceId >= m_deviceList.size()) + { + return false; + } +@@ -140,7 +163,7 @@ CsmaChannel::Detach(uint32_t deviceId) + + m_deviceList[deviceId].active = false; + +- if ((m_state == TRANSMITTING) && (m_currentSrc == deviceId)) ++ if ((GetState(deviceId) == TRANSMITTING) && (GetCurrentSrc(deviceId) == deviceId)) + { + NS_LOG_WARN("CsmaChannel::Detach(): Device is currently" + << "transmitting (" << deviceId << ")"); +@@ -177,7 +200,7 @@ CsmaChannel::TransmitStart(Ptr p, uint32_t srcId) + NS_LOG_FUNCTION(this << p << srcId); + NS_LOG_INFO("UID is " << p->GetUid() << ")"); + +- if (m_state != IDLE) ++ if (GetState(srcId) != IDLE) + { + NS_LOG_WARN("CsmaChannel::TransmitStart(): State is not IDLE"); + return false; +@@ -186,14 +209,14 @@ CsmaChannel::TransmitStart(Ptr p, uint32_t srcId) + if (!IsActive(srcId)) + { + NS_LOG_ERROR( +- "CsmaChannel::TransmitStart(): Seclected source is not currently attached to network"); ++ "CsmaChannel::TransmitStart(): Selected source is not currently attached to network"); + return false; + } + + NS_LOG_LOGIC("switch to TRANSMITTING"); +- m_currentPkt = p->Copy(); +- m_currentSrc = srcId; +- m_state = TRANSMITTING; ++ SetCurrentPkt(srcId, p->Copy()); ++ SetCurrentSrc(srcId, srcId); ++ SetState(srcId, TRANSMITTING); + return true; + } + +@@ -204,17 +227,23 @@ CsmaChannel::IsActive(uint32_t deviceId) + } + + bool +-CsmaChannel::TransmitEnd() ++CsmaChannel::IsFullDuplex() const ++{ ++ return m_fullDuplex; ++} ++ ++bool ++CsmaChannel::TransmitEnd(uint32_t srcId) + { +- NS_LOG_FUNCTION(this << m_currentPkt << m_currentSrc); +- NS_LOG_INFO("UID is " << m_currentPkt->GetUid() << ")"); ++ NS_LOG_FUNCTION(this << GetCurrentPkt(srcId) << GetCurrentSrc(srcId)); ++ NS_LOG_INFO("UID is " << GetCurrentPkt(srcId)->GetUid() << ")"); + +- NS_ASSERT(m_state == TRANSMITTING); +- m_state = PROPAGATING; ++ NS_ASSERT(GetState(srcId) == TRANSMITTING); ++ SetState(srcId, PROPAGATING); + + bool retVal = true; + +- if (!IsActive(m_currentSrc)) ++ if (!IsActive(GetCurrentSrc(srcId))) + { + NS_LOG_ERROR("CsmaChannel::TransmitEnd(): Seclected source was detached before the end of " + "the transmission"); +@@ -227,31 +256,47 @@ CsmaChannel::TransmitEnd() + + for (auto it = m_deviceList.begin(); it < m_deviceList.end(); it++) + { +- if (it->IsActive() && it->devicePtr != m_deviceList[m_currentSrc].devicePtr) ++ if (it->IsActive() && it->devicePtr != m_deviceList[GetCurrentSrc(srcId)].devicePtr) + { + // schedule reception events + Simulator::ScheduleWithContext(it->devicePtr->GetNode()->GetId(), + m_delay, + &CsmaNetDevice::Receive, + it->devicePtr, +- m_currentPkt->Copy(), +- m_deviceList[m_currentSrc].devicePtr); ++ GetCurrentPkt(srcId)->Copy(), ++ m_deviceList[GetCurrentSrc(srcId)].devicePtr); + } + } + +- // also schedule for the tx side to go back to IDLE +- Simulator::Schedule(m_delay, &CsmaChannel::PropagationCompleteEvent, this); ++ // Schedule for the TX side to go back to IDLE. ++ if (IsFullDuplex()) ++ { ++ // ++ // In full-duplex mode, the channel should be IDLE during propagation ++ // since it's ok to start transmitting again. In this case, we don't need ++ // to wait for the channel delay. ++ // ++ PropagationCompleteEvent(srcId); ++ } ++ else ++ { ++ // ++ // In half-duplex mode, the channel can only go back to IDLE after ++ // propagation delay. ++ // ++ Simulator::Schedule(m_delay, &CsmaChannel::PropagationCompleteEvent, this, srcId); ++ } + return retVal; + } + + void +-CsmaChannel::PropagationCompleteEvent() ++CsmaChannel::PropagationCompleteEvent(uint32_t deviceId) + { +- NS_LOG_FUNCTION(this << m_currentPkt); +- NS_LOG_INFO("UID is " << m_currentPkt->GetUid() << ")"); ++ NS_LOG_FUNCTION(this << GetCurrentPkt(deviceId)); ++ NS_LOG_INFO("UID is " << GetCurrentPkt(deviceId)->GetUid() << ")"); + +- NS_ASSERT(m_state == PROPAGATING); +- m_state = IDLE; ++ NS_ASSERT(GetState(deviceId) == PROPAGATING); ++ SetState(deviceId, IDLE); + } + + uint32_t +@@ -303,9 +348,9 @@ CsmaChannel::GetDeviceNum(Ptr device) + } + + bool +-CsmaChannel::IsBusy() ++CsmaChannel::IsBusy(uint32_t deviceId) + { +- return m_state != IDLE; ++ return GetState(deviceId) != IDLE; + } + + DataRate +@@ -321,9 +366,9 @@ CsmaChannel::GetDelay() + } + + WireState +-CsmaChannel::GetState() ++CsmaChannel::GetState(uint32_t deviceId) + { +- return m_state; ++ return m_state[m_fullDuplex ? deviceId : 0]; + } + + Ptr +@@ -332,6 +377,36 @@ CsmaChannel::GetDevice(std::size_t i) const + return GetCsmaDevice(i); + } + ++Ptr ++CsmaChannel::GetCurrentPkt(uint32_t deviceId) ++{ ++ return m_currentPkt[m_fullDuplex ? deviceId : 0]; ++} ++ ++void ++CsmaChannel::SetCurrentPkt(uint32_t deviceId, Ptr pkt) ++{ ++ m_currentPkt[m_fullDuplex ? deviceId : 0] = pkt; ++} ++ ++uint32_t ++CsmaChannel::GetCurrentSrc(uint32_t deviceId) ++{ ++ return m_currentSrc[m_fullDuplex ? deviceId : 0]; ++} ++ ++void ++CsmaChannel::SetCurrentSrc(uint32_t deviceId, uint32_t transmitterId) ++{ ++ m_currentSrc[m_fullDuplex ? deviceId : 0] = transmitterId; ++} ++ ++void ++CsmaChannel::SetState(uint32_t deviceId, WireState state) ++{ ++ m_state[m_fullDuplex ? deviceId : 0] = state; ++} ++ + CsmaDeviceRec::CsmaDeviceRec() + { + active = false; +diff --git a/src/csma/model/csma-channel.h b/src/csma/model/csma-channel.h +index da4e948da..5d824f073 100644 +--- a/src/csma/model/csma-channel.h ++++ b/src/csma/model/csma-channel.h +@@ -1,5 +1,8 @@ + /* + * Copyright (c) 2007 Emmanuelle Laprise ++ * Copyright (c) 2012 Jeffrey Young ++ * Copyright (c) 2014 Murphy McCauley ++ * Copyright (c) 2017 Luciano Jerez Chaves + * + * 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 +@@ -15,11 +18,15 @@ + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Emmanuelle Laprise ++ * Author: Jeff Young ++ * Author: Murphy McCauley ++ * Author: Luciano Jerez Chaves + */ + + #ifndef CSMA_CHANNEL_H + #define CSMA_CHANNEL_H + ++#include "ns3/boolean.h" + #include "ns3/channel.h" + #include "ns3/data-rate.h" + #include "ns3/nstime.h" +@@ -86,7 +93,11 @@ enum WireState + * when many nodes are connected to one wire. It uses a single busy + * flag to indicate if the channel is currently in use. It does not + * take into account the distances between stations or the speed of +- * light to determine collisions. ++ * light to determine collisions. Optionally, it allows for full- ++ * duplex operation when there are only two attached nodes. To ++ * implement full-duplex, we internally keep two TX "subchannels" ++ * (one for each attached node). When in half-duplex mode, only ++ * the first subchannel is used. + */ + class CsmaChannel : public Channel + { +@@ -201,19 +212,23 @@ class CsmaChannel : public Channel + * packet p as the m_currentPkt, the packet being currently + * transmitting. + * ++ * \param deviceId The ID that was assigned to the net device when ++ * it was attached to the channel. + * \return Returns true unless the source was detached before it + * completed its transmission. + */ +- bool TransmitEnd(); ++ bool TransmitEnd(uint32_t deviceId); + + /** + * \brief Indicates that the channel has finished propagating the + * current packet. The channel is released and becomes free. + * +- * Calls the receive function of every active net device that is ++ * \param deviceId The ID that was assigned to the net device when ++ * it was attached to the channel. ++ * Calls the receive function of the other net device that is + * attached to the channel. + */ +- void PropagationCompleteEvent(); ++ void PropagationCompleteEvent(uint32_t deviceId); + + /** + * \return Returns the device number assigned to a net device by the +@@ -225,19 +240,25 @@ class CsmaChannel : public Channel + int32_t GetDeviceNum(Ptr device); + + /** ++ * \brief Checks the state of the channel. ++ * ++ * \param deviceId The ID that was assigned to the net device when ++ * it was attached to the channel. + * \return Returns the state of the channel (IDLE -- free, + * TRANSMITTING -- busy, PROPAGATING - busy ) + */ +- WireState GetState(); ++ WireState GetState(uint32_t deviceId); + + /** + * \brief Indicates if the channel is busy. The channel will only + * accept new packets for transmission if it is not busy. + * ++ * \param deviceId The ID that was assigned to the net device when ++ * it was attached to the channel. + * \return Returns true if the channel is busy and false if it is + * free. + */ +- bool IsBusy(); ++ bool IsBusy(uint32_t deviceId); + + /** + * \brief Indicates if a net device is currently attached or +@@ -250,6 +271,14 @@ class CsmaChannel : public Channel + */ + bool IsActive(uint32_t deviceId); + ++ /** ++ * \brief Indicates if channel is operating in full-duplex mode. ++ * ++ * \return Returns true if channel is in full-duplex mode, false if in ++ * half-duplex mode. ++ */ ++ bool IsFullDuplex() const; ++ + /** + * \return Returns the number of net devices that are currently + * attached to the channel. +@@ -307,6 +336,11 @@ class CsmaChannel : public Channel + */ + Time m_delay; + ++ /** ++ * Whether the channel is in full-duplex mode. ++ */ ++ bool m_fullDuplex; ++ + /** + * List of the net devices that have been or are currently connected + * to the channel. +@@ -321,23 +355,75 @@ class CsmaChannel : public Channel + std::vector m_deviceList; + + /** +- * The Packet that is currently being transmitted on the channel (or last +- * packet to have been transmitted on the channel if the channel is +- * free.) ++ * The Packet that is currently being transmitted on the subchannel (or the ++ * last packet to have been transmitted if the subchannel is free). ++ * In half-duplex mode, only the first subchannel is used. + */ +- Ptr m_currentPkt; ++ Ptr m_currentPkt[2]; + + /** + * Device Id of the source that is currently transmitting on the ++ * subchannel, or the last source to have transmitted a packet on the ++ * subchannel, if it is not currently busy. ++ * In half-duplex mode, only the first subchannel is used. ++ */ ++ uint32_t m_currentSrc[2]; ++ ++ /** ++ * Current state of each subchannel. ++ * In half-duplex mode, only the first subchannel is used. ++ */ ++ WireState m_state[2]; ++ ++ /** ++ * \brief Gets current packet ++ * ++ * \param deviceId The ID that was assigned to the net device when ++ * it was attached to the channel. ++ * \return Device Id of the source that is currently transmitting on the ++ * subchannel or the last source to have transmitted a packet on the ++ * subchannel, if it is not currently busy. ++ */ ++ Ptr GetCurrentPkt(uint32_t deviceId); ++ ++ /** ++ * \brief Sets the current packet ++ * ++ * \param deviceId The ID that was assigned to the net device when ++ * it was attached to the channel. ++ * \param The Packet that is current being transmitted by deviceId (or last ++ * packet to have been transmitted on the channel if the channel is free.) ++ */ ++ void SetCurrentPkt(uint32_t deviceId, Ptr pkt); ++ ++ /** ++ * \brief Gets current transmitter ++ * ++ * \param deviceId The ID that was assigned to the net device when ++ * it was attached to the channel. ++ * \return Device Id of the source that is currently transmitting on the + * channel. Or last source to have transmitted a packet on the + * channel, if the channel is currently not busy. + */ +- uint32_t m_currentSrc; ++ uint32_t GetCurrentSrc(uint32_t deviceId); + + /** +- * Current state of the channel ++ * \brief Sets the current transmitter ++ * ++ * \param deviceId The ID that was assigned to the net device when ++ * it was attached to the channel. ++ * \param transmitterId The ID of the transmitting device. ++ */ ++ void SetCurrentSrc(uint32_t deviceId, uint32_t transmitterId); ++ ++ /** ++ * \brief Sets the state of the channel ++ * ++ * \param deviceId The ID that was assigned to the net device when ++ * it was attached to the channel. ++ * \param state The new channel state. + */ +- WireState m_state; ++ void SetState(uint32_t deviceId, WireState state); + }; + + } // namespace ns3 +diff --git a/src/csma/model/csma-net-device.cc b/src/csma/model/csma-net-device.cc +index f6d3ff4ae..e2998cd19 100644 +--- a/src/csma/model/csma-net-device.cc ++++ b/src/csma/model/csma-net-device.cc +@@ -1,5 +1,8 @@ + /* + * Copyright (c) 2007 Emmanuelle Laprise ++ * Copyright (c) 2012 Jeffrey Young ++ * Copyright (c) 2014 Murphy McCauley ++ * Copyright (c) 2017 Luciano Jerez Chaves + * + * 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 +@@ -15,6 +18,9 @@ + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Emmanuelle Laprise ++ * Author: Jeff Young ++ * Author: Murphy McCauley ++ * Author: Luciano Jerez Chaves + */ + + #include "csma-net-device.h" +@@ -455,6 +461,7 @@ CsmaNetDevice::TransmitStart() + + NS_LOG_LOGIC("m_currentPkt = " << m_currentPkt); + NS_LOG_LOGIC("UID = " << m_currentPkt->GetUid()); ++ NS_LOG_LOGIC("Device ID = " << m_deviceId); + + // + // Only transmit if the send side of net device is enabled +@@ -476,34 +483,38 @@ CsmaNetDevice::TransmitStart() + "Must be READY to transmit. Tx state is: " << m_txMachineState); + + // +- // Now we have to sense the state of the medium and either start transmitting +- // if it is idle, or backoff our transmission if someone else is on the wire. ++ // Now we sense the state of the medium. If idle, we start transmitting. ++ // Otherwise, we have to wait. + // +- if (m_channel->GetState() != IDLE) ++ if (m_channel->GetState(m_deviceId) != IDLE) + { + // +- // The channel is busy -- backoff and rechedule TransmitStart() unless +- // we have exhausted all of our retries. ++ // The (sub)channel is busy. If in half-duplex mode, backoff and ++ // reschedule TransmitStart() unless we have exhausted all of our ++ // retries. This is not supposed to happen in full-duplex mode. + // +- m_txMachineState = BACKOFF; +- +- if (m_backoff.MaxRetriesReached()) +- { +- // +- // Too many retries, abort transmission of packet +- // +- TransmitAbort(); +- } +- else ++ if (m_channel->IsFullDuplex() == false) + { +- m_macTxBackoffTrace(m_currentPkt); +- +- m_backoff.IncrNumRetries(); +- Time backoffTime = m_backoff.GetBackoffTime(); +- +- NS_LOG_LOGIC("Channel busy, backing off for " << backoffTime.As(Time::S)); +- +- Simulator::Schedule(backoffTime, &CsmaNetDevice::TransmitStart, this); ++ m_txMachineState = BACKOFF; ++ ++ if (m_backoff.MaxRetriesReached()) ++ { ++ // ++ // Too many retries, abort transmission of packet ++ // ++ TransmitAbort(); ++ } ++ else ++ { ++ m_macTxBackoffTrace(m_currentPkt); ++ ++ m_backoff.IncrNumRetries(); ++ Time backoffTime = m_backoff.GetBackoffTime(); ++ ++ NS_LOG_LOGIC("Channel busy, backing off for " << backoffTime.As(Time::S)); ++ ++ Simulator::Schedule(backoffTime, &CsmaNetDevice::TransmitStart, this); ++ } + } + } + else +@@ -595,7 +606,7 @@ CsmaNetDevice::TransmitCompleteEvent() + // + NS_ASSERT_MSG(m_txMachineState == BUSY, + "CsmaNetDevice::transmitCompleteEvent(): Must be BUSY if transmitting"); +- NS_ASSERT(m_channel->GetState() == TRANSMITTING); ++ NS_ASSERT(m_channel->GetState(m_deviceId) == TRANSMITTING); + m_txMachineState = GAP; + + // +@@ -605,8 +616,9 @@ CsmaNetDevice::TransmitCompleteEvent() + NS_ASSERT_MSG(m_currentPkt, "CsmaNetDevice::TransmitCompleteEvent(): m_currentPkt zero"); + NS_LOG_LOGIC("m_currentPkt=" << m_currentPkt); + NS_LOG_LOGIC("Pkt UID is " << m_currentPkt->GetUid() << ")"); ++ NS_LOG_LOGIC("Device ID is " << m_deviceId); + +- m_channel->TransmitEnd(); ++ m_channel->TransmitEnd(m_deviceId); + m_phyTxEndTrace(m_currentPkt); + m_currentPkt = nullptr; + +@@ -663,6 +675,8 @@ CsmaNetDevice::Attach(Ptr ch) + + m_deviceId = m_channel->Attach(this); + ++ NS_LOG_FUNCTION("Device ID is " << m_deviceId); ++ + // + // The channel provides us with the transmitter data rate. + // +@@ -699,6 +713,7 @@ CsmaNetDevice::Receive(Ptr packet, Ptr senderDevice) + { + NS_LOG_FUNCTION(packet << senderDevice); + NS_LOG_LOGIC("UID is " << packet->GetUid()); ++ NS_LOG_LOGIC("Device ID is " << m_deviceId); + + // + // We never forward up packets that we sent. Real devices don't do this since +@@ -996,6 +1011,7 @@ CsmaNetDevice::SendFrom(Ptr packet, + NS_LOG_FUNCTION(packet << src << dest << protocolNumber); + NS_LOG_LOGIC("packet =" << packet); + NS_LOG_LOGIC("UID is " << packet->GetUid() << ")"); ++ NS_LOG_LOGIC("Device ID is " << m_deviceId); + + NS_ASSERT(IsLinkUp()); + +@@ -1052,13 +1068,6 @@ CsmaNetDevice::GetNode() const + return m_node; + } + +-void +-CsmaNetDevice::SetOpenFlowReceiveCallback(NetDevice::PromiscReceiveCallback cb) +-{ +- NS_LOG_FUNCTION(&cb); +- m_openFlowRxCallback = cb; +-} +- + void + CsmaNetDevice::SetNode(Ptr node) + { +@@ -1074,6 +1083,13 @@ CsmaNetDevice::NeedsArp() const + return true; + } + ++void ++CsmaNetDevice::SetOpenFlowReceiveCallback(NetDevice::PromiscReceiveCallback cb) ++{ ++ NS_LOG_FUNCTION(&cb); ++ m_openFlowRxCallback = cb; ++} ++ + void + CsmaNetDevice::SetReceiveCallback(NetDevice::ReceiveCallback cb) + { +diff --git a/src/csma/test/examples-to-run.py b/src/csma/test/examples-to-run.py +index 3e49f1972..c671e5427 100644 +--- a/src/csma/test/examples-to-run.py ++++ b/src/csma/test/examples-to-run.py +@@ -8,6 +8,7 @@ + # See test.py for more information. + cpp_examples = [ + ("csma-broadcast", "True", "True"), ++ ("csma-duplex", "True", "True"), + ("csma-multicast", "True", "True"), + ("csma-one-subnet", "True", "True"), + ("csma-packet-socket", "True", "True"), +-- +2.34.1 + diff --git a/utils/ofswitch13-3_40.patch b/utils/ofswitch13-3_40.patch new file mode 100644 index 0000000..a6950cc --- /dev/null +++ b/utils/ofswitch13-3_40.patch @@ -0,0 +1,189 @@ +From 2ddd4f2187ac73c4024d7252ae3b9816116f811a Mon Sep 17 00:00:00 2001 +From: Luciano J Chaves +Date: Wed, 11 Oct 2023 09:49:03 -0300 +Subject: [PATCH] OFSwitch13 patch + +--- + .../custom-modules/ns3-configtable.cmake | 3 ++ + src/csma/model/csma-net-device.cc | 35 +++++++++++++++++++ + src/csma/model/csma-net-device.h | 13 +++++++ + .../model/virtual-net-device.cc | 30 ++++++++++++++++ + .../model/virtual-net-device.h | 11 ++++++ + 5 files changed, 92 insertions(+) + +diff --git a/build-support/custom-modules/ns3-configtable.cmake b/build-support/custom-modules/ns3-configtable.cmake +index 6de18dd2d..bdcf266cf 100644 +--- a/build-support/custom-modules/ns3-configtable.cmake ++++ b/build-support/custom-modules/ns3-configtable.cmake +@@ -169,6 +169,9 @@ macro(write_configtable) + string(APPEND out "ns-3 Click Integration : ") + check_on_or_off("ON" "NS3_CLICK") + ++ string(APPEND out "ns-3 OFSwitch13 Integration : ") ++ check_on_or_off("ON" "NS3_OFSWITCH13") ++ + string(APPEND out "ns-3 OpenFlow Integration : ") + check_on_or_off("ON" "NS3_OPENFLOW") + +diff --git a/src/csma/model/csma-net-device.cc b/src/csma/model/csma-net-device.cc +index bb0b93894..f6d3ff4ae 100644 +--- a/src/csma/model/csma-net-device.cc ++++ b/src/csma/model/csma-net-device.cc +@@ -806,6 +806,34 @@ CsmaNetDevice::Receive(Ptr packet, Ptr senderDevice) + 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 packet 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 +@@ -1024,6 +1052,13 @@ CsmaNetDevice::GetNode() const + return m_node; + } + ++void ++CsmaNetDevice::SetOpenFlowReceiveCallback(NetDevice::PromiscReceiveCallback cb) ++{ ++ NS_LOG_FUNCTION(&cb); ++ m_openFlowRxCallback = cb; ++} ++ + void + CsmaNetDevice::SetNode(Ptr node) + { +diff --git a/src/csma/model/csma-net-device.h b/src/csma/model/csma-net-device.h +index ff72aad2a..c65304e02 100644 +--- a/src/csma/model/csma-net-device.h ++++ b/src/csma/model/csma-net-device.h +@@ -313,6 +313,14 @@ class CsmaNetDevice : public NetDevice + */ + bool NeedsArp() const override; + ++ /** ++ * Set the callback used to notify the OpenFlow when a packet has been ++ * received by this device. ++ * ++ * \param cb The callback. ++ */ ++ void SetOpenFlowReceiveCallback(NetDevice::PromiscReceiveCallback cb); ++ + /** + * Set the callback to be used to notify higher layers when a packet has been + * received. +@@ -693,6 +701,11 @@ class CsmaNetDevice : public NetDevice + */ + Mac48Address m_address; + ++ /** ++ * The OpenFlow receive callback. ++ */ ++ NetDevice::PromiscReceiveCallback m_openFlowRxCallback; ++ + /** + * The callback used to notify higher layers that a packet has been received. + */ +diff --git a/src/virtual-net-device/model/virtual-net-device.cc b/src/virtual-net-device/model/virtual-net-device.cc +index 31518b7dc..e7613508f 100644 +--- a/src/virtual-net-device/model/virtual-net-device.cc ++++ b/src/virtual-net-device/model/virtual-net-device.cc +@@ -142,6 +142,29 @@ VirtualNetDevice::Receive(Ptr packet, + 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 packet 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 +@@ -311,4 +334,11 @@ VirtualNetDevice::IsBridge() const + 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 +index 66718596a..c0eb0c468 100644 +--- a/src/virtual-net-device/model/virtual-net-device.h ++++ b/src/virtual-net-device/model/virtual-net-device.h +@@ -153,6 +153,14 @@ class VirtualNetDevice : public NetDevice + bool SupportsSendFrom() const override; + bool IsBridge() const override; + ++ /** ++ * Set the callback used to notify the OpenFlow when a packet has been ++ * received by this device. ++ * ++ * \param cb The OpenFlow receive callback. ++ */ ++ void SetOpenFlowReceiveCallback(NetDevice::PromiscReceiveCallback cb); ++ + protected: + void DoDispose() override; + +@@ -173,6 +181,9 @@ class VirtualNetDevice : public NetDevice + bool m_needsArp; //!< True if the device needs ARP + bool m_supportsSendFrom; //!< True if the device supports SendFrm + bool m_isPointToPoint; //!< True if the device is a PointToPoint type device ++ ++ /** The OpenFlow receive callback. */ ++ NetDevice::PromiscReceiveCallback m_openFlowRxCallback; + }; + + } // namespace ns3 +-- +2.34.1 +