diff --git a/RELEASE_NOTES b/RELEASE_NOTES index a4479c9b3..162c692d7 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -29,6 +29,7 @@ Bugs fixed - Bug 2450 - LogDistancePropagationLossModel is not continuous - Bug 2463 - create trace source to trace the TXOP time that is actually used - Bug 2477 - DCF manager assert +- Bug 2485 - Check for queue full should happen before checking RED thresholds - Bug 2492 - uan: Make use of RxGain attribute in UanPhyGen class - Bug 2511 - HT Greenfield is not working - Bug 2513 - ParetoRandomVariable needs a "scale", not a "mean" attribute. diff --git a/src/traffic-control/doc/red.rst b/src/traffic-control/doc/red.rst index 41a1b70ef..53253def1 100644 --- a/src/traffic-control/doc/red.rst +++ b/src/traffic-control/doc/red.rst @@ -34,7 +34,25 @@ weight, MinTh and MaxTh and (ii) adapts maximum drop probability. The model in ns-3 contains implementation of both the features, and is a port of Sally Floyd's ns-2 ARED model. Note that the user is allowed to choose and explicitly configure the simulation by selecting feature (i) or feature (ii), or both. - + +Explicit Congestion Notification (ECN) +====================================== +This RED model supports an ECN mode of operation to notify endpoints of +congestion that may be developing in a bottleneck queue, without resorting +to packet drops. Such a mode is enabled by setting the UseEcn attribute to +true (it is false by default) and only affects incoming packets with the +ECT bit set in their header. When the average queue length is between the +minimum and maximum thresholds, an incoming packet is marked instead of being +dropped. When the average queue length is above the maximum threshold, an +incoming packet is marked (instead of being dropped) only if the UseHardDrop +attribute is set to false (it is true by default). + +The implementation of support for ECN marking is done in such a way as +to not impose an internet module dependency on the traffic control module. +The RED model does not directly set ECN bits on the header, but delegates +that job to the QueueDiscItem class. As a result, it is possible to +use RED queues for other non-IP QueueDiscItems that may or may not support +the ``Mark ()`` method. References ========== @@ -45,6 +63,9 @@ S.Floyd, K.Fall http://icir.org/floyd/papers/redsims.ps ARED queue implementation is based on the algorithm provided in: S. Floyd et al, http://www.icir.org/floyd/papers/adaptiveRed.pdf +The addition of explicit congestion notification (ECN) to IP: +K. K. Ramakrishnan et al, https://tools.ietf.org/html/rfc3168 + Attributes ========== @@ -62,6 +83,8 @@ policies: * LInterm * LinkBandwidth * LinkDelay +* UseEcn +* UseHardDrop In addition to RED attributes, ARED queue requires following attributes: diff --git a/src/traffic-control/model/red-queue-disc.cc b/src/traffic-control/model/red-queue-disc.cc index 0269ab664..65c4217e8 100644 --- a/src/traffic-control/model/red-queue-disc.cc +++ b/src/traffic-control/model/red-queue-disc.cc @@ -193,6 +193,16 @@ TypeId RedQueueDisc::GetTypeId (void) TimeValue (MilliSeconds (20)), MakeTimeAccessor (&RedQueueDisc::m_linkDelay), MakeTimeChecker ()) + .AddAttribute ("UseEcn", + "True to use ECN (packets are marked instead of being dropped)", + BooleanValue (false), + MakeBooleanAccessor (&RedQueueDisc::m_useEcn), + MakeBooleanChecker ()) + .AddAttribute ("UseHardDrop", + "True to always drop packets above max threshold", + BooleanValue (true), + MakeBooleanAccessor (&RedQueueDisc::m_useHardDrop), + MakeBooleanChecker ()) ; return tid; @@ -382,36 +392,43 @@ RedQueueDisc::DoEnqueue (Ptr item) m_old = 0; } - if ((GetMode () == Queue::QUEUE_MODE_PACKETS && nQueued >= m_queueLimit) || - (GetMode () == Queue::QUEUE_MODE_BYTES && nQueued + item->GetPacketSize() > m_queueLimit)) - { - NS_LOG_DEBUG ("\t Dropping due to Queue Full " << nQueued); - dropType = DTYPE_FORCED; - m_stats.qLimDrop++; - } - if (dropType == DTYPE_UNFORCED) { - NS_LOG_DEBUG ("\t Dropping due to Prob Mark " << m_qAvg); - m_stats.unforcedDrop++; - Drop (item); - return false; + if (!m_useEcn || !item->Mark ()) + { + NS_LOG_DEBUG ("\t Dropping due to Prob Mark " << m_qAvg); + m_stats.unforcedDrop++; + Drop (item); + return false; + } + NS_LOG_DEBUG ("\t Marking due to Prob Mark " << m_qAvg); + m_stats.unforcedMark++; } else if (dropType == DTYPE_FORCED) { - NS_LOG_DEBUG ("\t Dropping due to Hard Mark " << m_qAvg); - m_stats.forcedDrop++; - Drop (item); - if (m_isNs1Compat) + if (m_useHardDrop || !m_useEcn || !item->Mark ()) { - m_count = 0; - m_countBytes = 0; + NS_LOG_DEBUG ("\t Dropping due to Hard Mark " << m_qAvg); + m_stats.forcedDrop++; + Drop (item); + if (m_isNs1Compat) + { + m_count = 0; + m_countBytes = 0; + } + return false; } - return false; + NS_LOG_DEBUG ("\t Marking due to Hard Mark " << m_qAvg); + m_stats.forcedMark++; } bool retval = GetInternalQueue (0)->Enqueue (item); + if (!retval) + { + m_stats.qLimDrop++; + } + // If Queue::Enqueue fails, QueueDisc::Drop is called by the internal queue // because QueueDisc::AddInternalQueue sets the drop callback @@ -471,6 +488,8 @@ RedQueueDisc::InitializeParams (void) m_stats.forcedDrop = 0; m_stats.unforcedDrop = 0; m_stats.qLimDrop = 0; + m_stats.forcedMark = 0; + m_stats.unforcedMark = 0; m_qAvg = 0.0; m_count = 0; diff --git a/src/traffic-control/model/red-queue-disc.h b/src/traffic-control/model/red-queue-disc.h index 235363ccc..216c1b31f 100644 --- a/src/traffic-control/model/red-queue-disc.h +++ b/src/traffic-control/model/red-queue-disc.h @@ -108,6 +108,8 @@ public: uint32_t unforcedDrop; //!< Early probability drops uint32_t forcedDrop; //!< Forced drops, qavg > max threshold uint32_t qLimDrop; //!< Drops due to queue limits + uint32_t unforcedMark; //!< Early probability marks + uint32_t forcedMark; //!< Forced marks, qavg > max threshold } Stats; /** @@ -298,6 +300,8 @@ private: bool m_isNs1Compat; //!< Ns-1 compatibility DataRate m_linkBandwidth; //!< Link bandwidth Time m_linkDelay; //!< Link delay + bool m_useEcn; //!< True if ECN is used (packets are marked instead of being dropped) + bool m_useHardDrop; //!< True if packets are always dropped above max threshold // ** Variables maintained by RED double m_vProb1; //!< Prob. of packet drop before "count"