diff --git a/doc/models/Makefile b/doc/models/Makefile index 6cdcea584..3fb25a0dc 100644 --- a/doc/models/Makefile +++ b/doc/models/Makefile @@ -90,6 +90,7 @@ SOURCES = \ $(SRC)/traffic-control/doc/codel.rst \ $(SRC)/traffic-control/doc/cobalt.rst \ $(SRC)/traffic-control/doc/fq-codel.rst \ + $(SRC)/traffic-control/doc/fq-cobalt.rst \ $(SRC)/traffic-control/doc/pie.rst \ $(SRC)/traffic-control/doc/mq.rst \ $(SRC)/spectrum/doc/spectrum.rst \ diff --git a/doc/models/source/traffic-control.rst b/doc/models/source/traffic-control.rst index 4315d2aa4..afdfaf2f0 100644 --- a/doc/models/source/traffic-control.rst +++ b/doc/models/source/traffic-control.rst @@ -13,5 +13,6 @@ Traffic Control Layer codel fq-codel cobalt + fq-cobalt pie mq diff --git a/src/test/ns3tc/fq-cobalt-queue-disc-test-suite.cc b/src/test/ns3tc/fq-cobalt-queue-disc-test-suite.cc index 627277f89..a75da72d0 100644 --- a/src/test/ns3tc/fq-cobalt-queue-disc-test-suite.cc +++ b/src/test/ns3tc/fq-cobalt-queue-disc-test-suite.cc @@ -1,6 +1,7 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2016 Universita' degli Studi di Napoli Federico II + * Copyright (c) 2020 NITK Surathkal (adapted for COBALT) * * 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 @@ -17,7 +18,8 @@ * * Authors: Pasquale Imputato * Stefano Avallone -*/ + * Modified by: Bhaskar Kataria (COBALT changes) + */ #include "ns3/test.h" #include "ns3/simulator.h" diff --git a/src/traffic-control/doc/fq-cobalt.rst b/src/traffic-control/doc/fq-cobalt.rst index ef6511b51..89e05edca 100644 --- a/src/traffic-control/doc/fq-cobalt.rst +++ b/src/traffic-control/doc/fq-cobalt.rst @@ -2,15 +2,20 @@ .. highlight:: cpp .. highlight:: bash +.. _sec-fq-cobalt: + FqCobalt queue disc ------------------- +------------------- -This chapter describes the FqCobalt ([Hoe16]_) queue disc implementation in |ns3|. +This chapter describes the FqCobalt ([Pal19]_) queue disc implementation in |ns3|. -The FlowQueue-Cobalt (FQ-Cobalt) algorithm is similar to FlowQueue-CoDel (FQ-CoDel) algorithm available in ns-3-dev/src/traffic-control/doc/fq-codel.rst. -The documentation for Cobalt is available in ns-3-dev/src/traffic-control/doc/cobalt.rst. +The FlowQueue-Cobalt (FQ-Cobalt) algorithm is similar to FlowQueue-CoDel (FQ-CoDel) algorithm available in ::ref:`sec-fq-codel`. +The documentation for Cobalt is available in +``ns-3-dev/src/traffic-control/doc/cobalt.rst``. -FqCobalt is one of the crucial piece needed to complete to CAKE module `` +FqCobalt is one of the key components of the CAKE smart queue management framework ([Hoe18]_). The COBALT AQM is preferred to the CoDel AQM for CAKE because +it adds a heuristic called BLUE to cover cases in which the CoDel control +law is too sluggish to respond to queue growth. Model Description ***************** @@ -19,38 +24,40 @@ The source code for the FqCobalt queue disc is located in the directory ``src/traffic-control/model`` and consists of 2 files `fq-cobalt-queue-disc.h` and `fq-cobalt-queue-disc.cc` defining a FqCobaltQueueDisc class and a helper FqCobaltFlow class. The code was ported to |ns3| based on Linux kernel code -implemented by Jonathan Morton. +implemented by Jonathan Morton +(https://github.com/torvalds/linux/blob/master/net/sched/sch_cake.c). The Model Description is similar to the FqCoDel documentation mentioned above. - References ========== -.. [CAK16] https://github.com/torvalds/linux/blob/master/net/sched/sch_cake.c , Implementation of CAKE in Linux +.. [Pal19] J. Palmei, S. Gupta, P. Imputato, J. Morton, M. Tahiliani, S. Avallone, and D. Taht, Design and Evaluation of COBALT Queue Discipline, 2019 IEEE International Symposium on Local and Metropolitan Area Networks (LANMAN), Paris, France, 2019. + +.. [Hoe18] T. Hoiland-Jørgensen, D. Taht and J. Morton, "Piece of CAKE: A Comprehensive Queue Management Solution for Home Gateways," 2018 IEEE International Symposium on Local and Metropolitan Area Networks (LANMAN), Washington, DC, USA, 2018. Attributes ========== -The key attributes that the FqCobaltQueue class holds include the following: +Most of the key attributes are similar to the FqCoDel implementation mentioned above. One difference is the absence of the ``MinBytes`` parameter. + +Some additional parameters implemented as attributes are: -Most of the key attributes are similar to the FqCoDel implementation mentioned above. -Some differences are: -Absence of ``MinBytes`` parameter. -Some extra parameters are * ``Pdrop:`` Value of drop probability. * ``Increment:`` Increment value of drop probability. Default value is 1./256 . * ``Decrement:`` Decrement value of drop probability. Default value is 1./4096 . -* ``BlueThreshold:`` The Threshold after which Blue is enabled. Default value is 400ms. +* ``BlueThreshold:`` The threshold after which Blue is enabled. Default value is 400ms. Note that if the user wants to disable Blue Enhancement then the user can set -it to a large value for example Time::Max(). +it to a large value; for example, to `Time::Max ()`. + Examples ======== -A typical usage pattern is to create a traffic control helper and to configure type -and attributes of queue disc and filters from the helper. For example, FqCobalt -can be configured as follows: +A typical usage pattern is to create a traffic control helper and to configure +the type +and attributes of the queue disc and filters from the helper. +For example, `FqCobalt` can be configured as follows: .. sourcecode:: cpp @@ -73,4 +80,4 @@ The test suite can be run using the following commands:: or:: - $ NS_LOG="FqCobaltQueueDisc" ./waf --run "test-runner --suite=fq-cobalt-queue-disc" \ No newline at end of file + $ NS_LOG="FqCobaltQueueDisc" ./waf --run "test-runner --suite=fq-cobalt-queue-disc" diff --git a/src/traffic-control/doc/fq-codel.rst b/src/traffic-control/doc/fq-codel.rst index 78e7015f3..dae54167b 100644 --- a/src/traffic-control/doc/fq-codel.rst +++ b/src/traffic-control/doc/fq-codel.rst @@ -2,6 +2,8 @@ .. highlight:: cpp .. highlight:: bash +.. _sec-fq-codel: + FqCoDel queue disc ------------------ diff --git a/src/traffic-control/model/cobalt-queue-disc.cc b/src/traffic-control/model/cobalt-queue-disc.cc index 06a6f14f0..536aa2112 100644 --- a/src/traffic-control/model/cobalt-queue-disc.cc +++ b/src/traffic-control/model/cobalt-queue-disc.cc @@ -72,7 +72,7 @@ TypeId CobaltQueueDisc::GetTypeId (void) .AddAttribute ("Pdrop", "Marking Probability", DoubleValue (0), - MakeDoubleAccessor (&CobaltQueueDisc::m_Pdrop), + MakeDoubleAccessor (&CobaltQueueDisc::m_pDrop), MakeDoubleChecker ()) .AddAttribute ("Increment", "Pdrop increment value", @@ -159,9 +159,9 @@ CobaltQueueDisc::CobaltQueueDisc () m_uv = CreateObject (); } -double CobaltQueueDisc::GetPdrop () +double CobaltQueueDisc::GetPdrop () const { - return m_Pdrop; + return m_pDrop; } CobaltQueueDisc::~CobaltQueueDisc () @@ -204,25 +204,25 @@ CobaltQueueDisc::CoDelTimeAfterEq (int64_t a, int64_t b) } int64_t -CobaltQueueDisc::Time2CoDel (Time t) +CobaltQueueDisc::Time2CoDel (Time t) const { return (t.GetNanoSeconds ()); } Time -CobaltQueueDisc::GetTarget (void) +CobaltQueueDisc::GetTarget (void) const { return m_target; } Time -CobaltQueueDisc::GetInterval (void) +CobaltQueueDisc::GetInterval (void) const { return m_interval; } int64_t -CobaltQueueDisc::GetDropNext (void) +CobaltQueueDisc::GetDropNext (void) const { return m_dropNext; } @@ -408,7 +408,7 @@ void CobaltQueueDisc::CobaltQueueFull (int64_t now) if (CoDelTimeAfter ((now - m_lastUpdateTimeBlue), Time2CoDel (m_target))) { NS_LOG_LOGIC ("inside IF block"); - m_Pdrop = min (m_Pdrop + m_increment, (double)1.0); + m_pDrop = min (m_pDrop + m_increment, (double)1.0); m_lastUpdateTimeBlue = now; } m_dropping = true; @@ -423,9 +423,9 @@ void CobaltQueueDisc::CobaltQueueFull (int64_t now) void CobaltQueueDisc::CobaltQueueEmpty (int64_t now) { NS_LOG_FUNCTION (this); - if (m_Pdrop && CoDelTimeAfter ((now - m_lastUpdateTimeBlue), Time2CoDel (m_target))) + if (m_pDrop && CoDelTimeAfter ((now - m_lastUpdateTimeBlue), Time2CoDel (m_target))) { - m_Pdrop = max (m_Pdrop - m_decrement, (double)0.0); + m_pDrop = max (m_pDrop - m_decrement, (double)0.0); m_lastUpdateTimeBlue = now; } m_dropping = false; @@ -526,19 +526,19 @@ bool CobaltQueueDisc::CobaltShouldDrop (Ptr item, int64_t now) { NS_LOG_LOGIC ("Marking due to CeThreshold " << m_ceThreshold.GetSeconds ()); } - + // Enable Blue Enhancement if sojourn time is greater than blueThreshold and its been m_target time until the last time blue was updated if (CoDelTimeAfter (sojournTime, Time2CoDel (m_blueThreshold)) && CoDelTimeAfter ((now - m_lastUpdateTimeBlue), Time2CoDel (m_target))) { - m_Pdrop = min (m_Pdrop + m_increment, (double)1.0); + m_pDrop = min (m_pDrop + m_increment, (double)1.0); m_lastUpdateTimeBlue = now; } /* Simple BLUE implementation. Lack of ECN is deliberate. */ - if (m_Pdrop) + if (m_pDrop) { double u = m_uv->GetValue (); - drop = drop | (u < m_Pdrop); + drop = drop | (u < m_pDrop); } /* Overload the drop_next field as an activity timeout */ diff --git a/src/traffic-control/model/cobalt-queue-disc.h b/src/traffic-control/model/cobalt-queue-disc.h index eac450e37..fbf1a663a 100644 --- a/src/traffic-control/model/cobalt-queue-disc.h +++ b/src/traffic-control/model/cobalt-queue-disc.h @@ -84,21 +84,21 @@ public: * * \returns The target queue delay */ - Time GetTarget (void); + Time GetTarget (void) const; /** * \brief Get the interval * * \returns The interval */ - Time GetInterval (void); + Time GetInterval (void) const; /** * \brief Get the time for next packet drop while in the dropping state * - * \returns The time for next packet drop + * \returns The time (in microseconds) for next packet drop */ - int64_t GetDropNext (void); + int64_t GetDropNext (void) const; static constexpr const char* TARGET_EXCEEDED_DROP = "Target exceeded drop"; //!< Sojourn time above target static constexpr const char* OVERLIMIT_DROP = "Overlimit drop"; //!< Overlimit dropped packet @@ -110,7 +110,7 @@ public: * * \returns The current value of Blue's drop probability */ - double GetPdrop (); + double GetPdrop () const; /** * Assign a fixed random variable stream number to the random variables @@ -128,7 +128,7 @@ public: * @param t the input Time Object * @return the unsigned 32-bit integer representation */ - int64_t Time2CoDel (Time t); + int64_t Time2CoDel (Time t) const; protected: /** @@ -198,17 +198,21 @@ private: /** * Called when the queue becomes full to alter the drop probabilities of Blue + * \param now time in CoDel time units (microseconds) */ void CobaltQueueFull (int64_t now); /** * Called when the queue becomes empty to alter the drop probabilities of Blue + * \param now time in CoDel time units (microseconds) */ void CobaltQueueEmpty (int64_t now); /** * Called to decide whether the current packet should be dropped based on decisions taken by Blue and Codel working parallely * Returns true if the packet should be dropped, false otherwise + * \param item current packet + * \param now time in CoDel time units (microseconds) */ bool CobaltShouldDrop (Ptr item, int64_t now); @@ -225,8 +229,8 @@ private: uint32_t m_recInvSqrtCache[REC_INV_SQRT_CACHE] = {0}; //!< Cache to maintain some initial values of InvSqrt // Supplied by user - Time m_interval; //!< 100 ms sliding minimum time window width - Time m_target; //!< 5 ms target queue delay + Time m_interval; //!< sliding minimum time window width + Time m_target; //!< target queue delay bool m_useEcn; //!< True if ECN is used (packets are marked instead of being dropped) Time m_ceThreshold; //!< Threshold above which to CE mark bool m_useL4s; //!< True if L4S is used (ECT1 packets are marked at CE threshold) @@ -240,7 +244,7 @@ private: // Supplied by user double m_increment; //!< increment value for marking probability double m_decrement; //!< decrement value for marking probability - double m_Pdrop; //!< Drop Probability + double m_pDrop; //!< Drop Probability }; diff --git a/src/traffic-control/model/fq-cobalt-queue-disc.cc b/src/traffic-control/model/fq-cobalt-queue-disc.cc index a6db5d47e..77fe5dc60 100644 --- a/src/traffic-control/model/fq-cobalt-queue-disc.cc +++ b/src/traffic-control/model/fq-cobalt-queue-disc.cc @@ -1,6 +1,7 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2016 Universita' degli Studi di Napoli Federico II + * Copyright (c) 2020 NITK Surathkal (adapted for COBALT) * * 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 @@ -17,7 +18,12 @@ * * Authors: Pasquale Imputato * Stefano Avallone -*/ + * Modified by: Bhaskar Kataria (for COBALT) + * Tom Henderson + * Mohit P. Tahiliani + * Vivek Jain + * Ankit Deepak + */ #include "ns3/log.h" #include "ns3/string.h" @@ -405,7 +411,8 @@ FqCobaltQueueDisc::DoDequeue (void) { NS_LOG_DEBUG ("Dequeued packet " << item->GetPacket ()); } - } while (item == 0); + } + while (item == 0); flow->IncreaseDeficit (item->GetSize () * -1); @@ -458,7 +465,7 @@ FqCobaltQueueDisc::CheckConfig (void) // If UseL4S attribute is enabled then CE threshold must be set. if (m_useL4s) { - NS_ABORT_MSG_IF (m_ceThreshold == Time::Max(), "CE threshold not set"); + NS_ABORT_MSG_IF (m_ceThreshold == Time::Max (), "CE threshold not set"); if (m_useEcn == false) { NS_LOG_WARN ("Enabling ECN as L4S mode is enabled"); @@ -514,7 +521,8 @@ FqCobaltQueueDisc::FqCobaltDrop (void) item = qd->GetInternalQueue (0)->Dequeue (); DropAfterDequeue (item, OVERLIMIT_DROP); len += item->GetSize (); - } while (++count < m_dropBatchSize && len < threshold); + } + while (++count < m_dropBatchSize && len < threshold); return index; } diff --git a/src/traffic-control/model/fq-cobalt-queue-disc.h b/src/traffic-control/model/fq-cobalt-queue-disc.h index 417858156..0f296d6ac 100644 --- a/src/traffic-control/model/fq-cobalt-queue-disc.h +++ b/src/traffic-control/model/fq-cobalt-queue-disc.h @@ -1,6 +1,7 @@ /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2020 NITK Surathkal + * Copyright (c) 2016 Universita' degli Studi di Napoli Federico II + * Copyright (c) 2020 NITK Surathkal (adapted for COBALT) * * 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,8 +16,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * Authors: Bhaskar Kataria - * Tom Henderson + * Authors: Pasquale Imputato + * Stefano Avallone + * Modified by: Bhaskar Kataria (for COBALT) + * Tom Henderson * Mohit P. Tahiliani * Vivek Jain * Ankit Deepak @@ -38,7 +41,8 @@ namespace ns3 { * \brief A flow queue used by the FqCobalt queue disc */ -class FqCobaltFlow : public QueueDiscClass { +class FqCobaltFlow : public QueueDiscClass +{ public: /** * \brief Get the type ID. @@ -57,11 +61,11 @@ public: * \brief Used to determine the status of this flow queue */ enum FlowStatus - { - INACTIVE, - NEW_FLOW, - OLD_FLOW - }; + { + INACTIVE, + NEW_FLOW, + OLD_FLOW + }; /** * \brief Set the deficit for this flow @@ -112,7 +116,8 @@ private: * \brief A FqCobalt packet queue disc */ -class FqCobaltQueueDisc : public QueueDisc { +class FqCobaltQueueDisc : public QueueDisc +{ public: /** * \brief Get the type ID. @@ -126,19 +131,19 @@ public: virtual ~FqCobaltQueueDisc (); - /** - * \brief Set the quantum value. - * - * \param quantum The number of bytes each queue gets to dequeue on each round of the scheduling algorithm - */ - void SetQuantum (uint32_t quantum); + /** + * \brief Set the quantum value. + * + * \param quantum The number of bytes each queue gets to dequeue on each round of the scheduling algorithm + */ + void SetQuantum (uint32_t quantum); - /** - * \brief Get the quantum value. - * - * \returns The number of bytes each queue gets to dequeue on each round of the scheduling algorithm - */ - uint32_t GetQuantum (void) const; + /** + * \brief Get the quantum value. + * + * \returns The number of bytes each queue gets to dequeue on each round of the scheduling algorithm + */ + uint32_t GetQuantum (void) const; // Reasons for dropping packets static constexpr const char* UNCLASSIFIED_DROP = "Unclassified drop"; //!< No packet filter able to classify packet