traffic-control: (fixes #2485) Add ECN support to RED

This commit is contained in:
Stefano Avallone
2016-12-13 19:56:41 +01:00
parent 7681d190c2
commit 3ae9d85c2f
4 changed files with 67 additions and 20 deletions

View File

@@ -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.

View File

@@ -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:

View File

@@ -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<QueueDiscItem> 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;

View File

@@ -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"