traffic-control: RED is a queue disc now
This commit is contained in:
@@ -78,6 +78,7 @@ SOURCES = \
|
||||
$(SRC)/traffic-control/doc/traffic-control-layer.rst \
|
||||
$(SRC)/traffic-control/doc/queue-discs.rst \
|
||||
$(SRC)/traffic-control/doc/pfifo-fast.rst \
|
||||
$(SRC)/traffic-control/doc/red.rst \
|
||||
$(SRC)/spectrum/doc/spectrum.rst \
|
||||
$(SRC)/stats/doc/adaptor.rst \
|
||||
$(SRC)/stats/doc/aggregator.rst \
|
||||
|
||||
@@ -6,3 +6,4 @@ Traffic Control Layer
|
||||
traffic-control-layer
|
||||
queue-discs
|
||||
pfifo-fast
|
||||
red
|
||||
|
||||
67
src/traffic-control/doc/red.rst
Normal file
67
src/traffic-control/doc/red.rst
Normal file
@@ -0,0 +1,67 @@
|
||||
.. include:: replace.txt
|
||||
.. highlight:: cpp
|
||||
|
||||
RED queue disc
|
||||
---------------------
|
||||
|
||||
Model Description
|
||||
*****************
|
||||
|
||||
Random Early Detection (RED) is a queue discipline that aims to provide
|
||||
early signals to transport protocol congestion control (e.g. TCP) that
|
||||
congestion is imminent, so that they back off their rate gracefully
|
||||
rather than with a bunch of tail-drop losses (possibly incurring
|
||||
TCP timeout). The model in ns-3 is a port of Sally Floyd's ns-2
|
||||
RED model.
|
||||
|
||||
Note that, starting from ns-3.25, RED is no longer a queue variant and
|
||||
cannot be installed as a NetDevice queue. Instead, RED is a queue disc
|
||||
and must be installed in the context of the traffic control (see the
|
||||
examples mentioned below).
|
||||
|
||||
The RED queue disc does not require packet filters, does not admit
|
||||
child queue discs and uses a single internal queue. If not provided by
|
||||
the user, a DropTail queue operating in the same mode (packet or byte)
|
||||
as the queue disc and having a size equal to the RED queue limit attribute
|
||||
is created. If the user provides an internal queue, such a queue must
|
||||
operate in the same mode as the queue disc and have a size not less than
|
||||
the RED queue limit attribute.
|
||||
|
||||
The RED model just supports default RED. Adaptive RED is not supported.
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
The RED queue aims to be close to the results cited in:
|
||||
S.Floyd, K.Fall http://icir.org/floyd/papers/redsims.ps
|
||||
|
||||
Attributes
|
||||
==========
|
||||
|
||||
The RED queue contains a number of attributes that control the RED
|
||||
policies:
|
||||
|
||||
* Mode (bytes or packets)
|
||||
* MeanPktSize
|
||||
* IdlePktSize
|
||||
* Wait (time)
|
||||
* Gentle mode
|
||||
* MinTh, MaxTh
|
||||
* QueueLimit
|
||||
* Queue weight
|
||||
* LInterm
|
||||
* LinkBandwidth
|
||||
* LinkDelay
|
||||
|
||||
Consult the ns-3 documentation for explanation of these attributes.
|
||||
|
||||
Examples
|
||||
========
|
||||
|
||||
The RED queue example is found at ``src/traffic-control/examples/red-tests.cc``.
|
||||
|
||||
Validation
|
||||
**********
|
||||
|
||||
The RED model has been validated and the report is currently stored
|
||||
at: https://github.com/downloads/talau/ns-3-tcp-red/report-red-ns3.pdf
|
||||
@@ -1,4 +1,4 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
// /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright © 2011 Marcos Talau
|
||||
*
|
||||
@@ -63,129 +63,135 @@
|
||||
#include "ns3/simulator.h"
|
||||
#include "ns3/abort.h"
|
||||
#include "ns3/random-variable-stream.h"
|
||||
#include "red-queue.h"
|
||||
#include "red-queue-disc.h"
|
||||
#include "ns3/drop-tail-queue.h"
|
||||
|
||||
namespace ns3 {
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("RedQueue");
|
||||
NS_LOG_COMPONENT_DEFINE ("RedQueueDisc");
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (RedQueue);
|
||||
NS_OBJECT_ENSURE_REGISTERED (RedQueueDisc);
|
||||
|
||||
TypeId RedQueue::GetTypeId (void)
|
||||
TypeId RedQueueDisc::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::RedQueue")
|
||||
.SetParent<Queue> ()
|
||||
.SetGroupName("Network")
|
||||
.AddConstructor<RedQueue> ()
|
||||
static TypeId tid = TypeId ("ns3::RedQueueDisc")
|
||||
.SetParent<QueueDisc> ()
|
||||
.SetGroupName("TrafficControl")
|
||||
.AddConstructor<RedQueueDisc> ()
|
||||
.AddAttribute ("Mode",
|
||||
"Determines unit for QueueLimit",
|
||||
EnumValue (QUEUE_MODE_PACKETS),
|
||||
MakeEnumAccessor (&RedQueue::SetMode),
|
||||
MakeEnumChecker (QUEUE_MODE_BYTES, "QUEUE_MODE_BYTES",
|
||||
QUEUE_MODE_PACKETS, "QUEUE_MODE_PACKETS"))
|
||||
EnumValue (Queue::QUEUE_MODE_PACKETS),
|
||||
MakeEnumAccessor (&RedQueueDisc::SetMode),
|
||||
MakeEnumChecker (Queue::QUEUE_MODE_BYTES, "QUEUE_MODE_BYTES",
|
||||
Queue::QUEUE_MODE_PACKETS, "QUEUE_MODE_PACKETS"))
|
||||
.AddAttribute ("MeanPktSize",
|
||||
"Average of packet size",
|
||||
UintegerValue (500),
|
||||
MakeUintegerAccessor (&RedQueue::m_meanPktSize),
|
||||
MakeUintegerAccessor (&RedQueueDisc::m_meanPktSize),
|
||||
MakeUintegerChecker<uint32_t> ())
|
||||
.AddAttribute ("IdlePktSize",
|
||||
"Average packet size used during idle times. Used when m_cautions = 3",
|
||||
UintegerValue (0),
|
||||
MakeUintegerAccessor (&RedQueue::m_idlePktSize),
|
||||
MakeUintegerAccessor (&RedQueueDisc::m_idlePktSize),
|
||||
MakeUintegerChecker<uint32_t> ())
|
||||
.AddAttribute ("Wait",
|
||||
"True for waiting between dropped packets",
|
||||
BooleanValue (true),
|
||||
MakeBooleanAccessor (&RedQueue::m_isWait),
|
||||
MakeBooleanAccessor (&RedQueueDisc::m_isWait),
|
||||
MakeBooleanChecker ())
|
||||
.AddAttribute ("Gentle",
|
||||
"True to increases dropping probability slowly when average queue exceeds maxthresh",
|
||||
BooleanValue (true),
|
||||
MakeBooleanAccessor (&RedQueue::m_isGentle),
|
||||
MakeBooleanAccessor (&RedQueueDisc::m_isGentle),
|
||||
MakeBooleanChecker ())
|
||||
.AddAttribute ("MinTh",
|
||||
"Minimum average length threshold in packets/bytes",
|
||||
DoubleValue (5),
|
||||
MakeDoubleAccessor (&RedQueue::m_minTh),
|
||||
MakeDoubleAccessor (&RedQueueDisc::m_minTh),
|
||||
MakeDoubleChecker<double> ())
|
||||
.AddAttribute ("MaxTh",
|
||||
"Maximum average length threshold in packets/bytes",
|
||||
DoubleValue (15),
|
||||
MakeDoubleAccessor (&RedQueue::m_maxTh),
|
||||
MakeDoubleAccessor (&RedQueueDisc::m_maxTh),
|
||||
MakeDoubleChecker<double> ())
|
||||
.AddAttribute ("QueueLimit",
|
||||
"Queue limit in bytes/packets",
|
||||
UintegerValue (25),
|
||||
MakeUintegerAccessor (&RedQueue::m_queueLimit),
|
||||
MakeUintegerAccessor (&RedQueueDisc::SetQueueLimit),
|
||||
MakeUintegerChecker<uint32_t> ())
|
||||
.AddAttribute ("QW",
|
||||
"Queue weight related to the exponential weighted moving average (EWMA)",
|
||||
DoubleValue (0.002),
|
||||
MakeDoubleAccessor (&RedQueue::m_qW),
|
||||
MakeDoubleAccessor (&RedQueueDisc::m_qW),
|
||||
MakeDoubleChecker <double> ())
|
||||
.AddAttribute ("LInterm",
|
||||
"The maximum probability of dropping a packet",
|
||||
DoubleValue (50),
|
||||
MakeDoubleAccessor (&RedQueue::m_lInterm),
|
||||
MakeDoubleAccessor (&RedQueueDisc::m_lInterm),
|
||||
MakeDoubleChecker <double> ())
|
||||
.AddAttribute ("Ns1Compat",
|
||||
"NS-1 compatibility",
|
||||
BooleanValue (false),
|
||||
MakeBooleanAccessor (&RedQueue::m_isNs1Compat),
|
||||
MakeBooleanAccessor (&RedQueueDisc::m_isNs1Compat),
|
||||
MakeBooleanChecker ())
|
||||
.AddAttribute ("LinkBandwidth",
|
||||
"The RED link bandwidth",
|
||||
DataRateValue (DataRate ("1.5Mbps")),
|
||||
MakeDataRateAccessor (&RedQueue::m_linkBandwidth),
|
||||
MakeDataRateAccessor (&RedQueueDisc::m_linkBandwidth),
|
||||
MakeDataRateChecker ())
|
||||
.AddAttribute ("LinkDelay",
|
||||
"The RED link delay",
|
||||
TimeValue (MilliSeconds (20)),
|
||||
MakeTimeAccessor (&RedQueue::m_linkDelay),
|
||||
MakeTimeAccessor (&RedQueueDisc::m_linkDelay),
|
||||
MakeTimeChecker ())
|
||||
;
|
||||
|
||||
return tid;
|
||||
}
|
||||
|
||||
RedQueue::RedQueue () :
|
||||
Queue (),
|
||||
m_packets (),
|
||||
m_bytesInQueue (0),
|
||||
m_hasRedStarted (false)
|
||||
RedQueueDisc::RedQueueDisc () :
|
||||
QueueDisc ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_uv = CreateObject<UniformRandomVariable> ();
|
||||
}
|
||||
|
||||
RedQueue::~RedQueue ()
|
||||
RedQueueDisc::~RedQueueDisc ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
void
|
||||
RedQueue::SetMode (RedQueue::QueueMode mode)
|
||||
RedQueueDisc::DoDispose (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
m_uv = 0;
|
||||
QueueDisc::DoDispose ();
|
||||
}
|
||||
|
||||
void
|
||||
RedQueueDisc::SetMode (Queue::QueueMode mode)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << mode);
|
||||
m_mode = mode;
|
||||
}
|
||||
|
||||
RedQueue::QueueMode
|
||||
RedQueue::GetMode (void)
|
||||
Queue::QueueMode
|
||||
RedQueueDisc::GetMode (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
return m_mode;
|
||||
}
|
||||
|
||||
void
|
||||
RedQueue::SetQueueLimit (uint32_t lim)
|
||||
RedQueueDisc::SetQueueLimit (uint32_t lim)
|
||||
{
|
||||
NS_LOG_FUNCTION (this <<lim);
|
||||
NS_LOG_FUNCTION (this << lim);
|
||||
m_queueLimit = lim;
|
||||
}
|
||||
|
||||
void
|
||||
RedQueue::SetTh (double minTh, double maxTh)
|
||||
RedQueueDisc::SetTh (double minTh, double maxTh)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << minTh << maxTh);
|
||||
NS_ASSERT (minTh <= maxTh);
|
||||
@@ -193,15 +199,15 @@ RedQueue::SetTh (double minTh, double maxTh)
|
||||
m_maxTh = maxTh;
|
||||
}
|
||||
|
||||
RedQueue::Stats
|
||||
RedQueue::GetStats ()
|
||||
RedQueueDisc::Stats
|
||||
RedQueueDisc::GetStats ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
return m_stats;
|
||||
}
|
||||
|
||||
int64_t
|
||||
RedQueue::AssignStreams (int64_t stream)
|
||||
RedQueueDisc::AssignStreams (int64_t stream)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << stream);
|
||||
m_uv->SetStream (stream);
|
||||
@@ -209,29 +215,21 @@ RedQueue::AssignStreams (int64_t stream)
|
||||
}
|
||||
|
||||
bool
|
||||
RedQueue::DoEnqueue (Ptr<QueueItem> item)
|
||||
RedQueueDisc::DoEnqueue (Ptr<QueueDiscItem> item)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << item);
|
||||
Ptr<Packet> p = item->GetPacket ();
|
||||
|
||||
if (!m_hasRedStarted )
|
||||
{
|
||||
NS_LOG_INFO ("Initializing RED params.");
|
||||
InitializeParams ();
|
||||
m_hasRedStarted = true;
|
||||
}
|
||||
|
||||
uint32_t nQueued = 0;
|
||||
|
||||
if (GetMode () == QUEUE_MODE_BYTES)
|
||||
if (GetMode () == Queue::QUEUE_MODE_BYTES)
|
||||
{
|
||||
NS_LOG_DEBUG ("Enqueue in bytes mode");
|
||||
nQueued = m_bytesInQueue;
|
||||
nQueued = GetInternalQueue (0)->GetNBytes ();
|
||||
}
|
||||
else if (GetMode () == QUEUE_MODE_PACKETS)
|
||||
else if (GetMode () == Queue::QUEUE_MODE_PACKETS)
|
||||
{
|
||||
NS_LOG_DEBUG ("Enqueue in packets mode");
|
||||
nQueued = m_packets.size ();
|
||||
nQueued = GetInternalQueue (0)->GetNPackets ();
|
||||
}
|
||||
|
||||
// simulate number of packets arrival during idle period
|
||||
@@ -239,7 +237,7 @@ RedQueue::DoEnqueue (Ptr<QueueItem> item)
|
||||
|
||||
if (m_idle == 1)
|
||||
{
|
||||
NS_LOG_DEBUG ("RED Queue is idle.");
|
||||
NS_LOG_DEBUG ("RED Queue Disc is idle.");
|
||||
Time now = Simulator::Now ();
|
||||
|
||||
if (m_cautious == 3)
|
||||
@@ -257,8 +255,8 @@ RedQueue::DoEnqueue (Ptr<QueueItem> item)
|
||||
|
||||
m_qAvg = Estimator (nQueued, m + 1, m_qAvg, m_qW);
|
||||
|
||||
NS_LOG_DEBUG ("\t bytesInQueue " << m_bytesInQueue << "\tQavg " << m_qAvg);
|
||||
NS_LOG_DEBUG ("\t packetsInQueue " << m_packets.size () << "\tQavg " << m_qAvg);
|
||||
NS_LOG_DEBUG ("\t bytesInQueue " << GetInternalQueue (0)->GetNBytes () << "\tQavg " << m_qAvg);
|
||||
NS_LOG_DEBUG ("\t packetsInQueue " << GetInternalQueue (0)->GetNPackets () << "\tQavg " << m_qAvg);
|
||||
|
||||
m_count++;
|
||||
m_countBytes += item->GetPacketSize ();
|
||||
@@ -284,7 +282,7 @@ RedQueue::DoEnqueue (Ptr<QueueItem> item)
|
||||
m_countBytes = item->GetPacketSize ();
|
||||
m_old = 1;
|
||||
}
|
||||
else if (DropEarly (p, nQueued))
|
||||
else if (DropEarly (item, nQueued))
|
||||
{
|
||||
NS_LOG_LOGIC ("DropEarly returns 1");
|
||||
dropType = DTYPE_UNFORCED;
|
||||
@@ -308,14 +306,14 @@ RedQueue::DoEnqueue (Ptr<QueueItem> item)
|
||||
{
|
||||
NS_LOG_DEBUG ("\t Dropping due to Prob Mark " << m_qAvg);
|
||||
m_stats.unforcedDrop++;
|
||||
Drop (p);
|
||||
Drop (item);
|
||||
return false;
|
||||
}
|
||||
else if (dropType == DTYPE_FORCED)
|
||||
{
|
||||
NS_LOG_DEBUG ("\t Dropping due to Hard Mark " << m_qAvg);
|
||||
m_stats.forcedDrop++;
|
||||
Drop (p);
|
||||
Drop (item);
|
||||
if (m_isNs1Compat)
|
||||
{
|
||||
m_count = 0;
|
||||
@@ -324,11 +322,10 @@ RedQueue::DoEnqueue (Ptr<QueueItem> item)
|
||||
return false;
|
||||
}
|
||||
|
||||
m_bytesInQueue += item->GetPacketSize ();
|
||||
m_packets.push_back (item);
|
||||
GetInternalQueue (0)->Enqueue (item);
|
||||
|
||||
NS_LOG_LOGIC ("Number packets " << m_packets.size ());
|
||||
NS_LOG_LOGIC ("Number bytes " << m_bytesInQueue);
|
||||
NS_LOG_LOGIC ("Number packets " << GetInternalQueue (0)->GetNPackets ());
|
||||
NS_LOG_LOGIC ("Number bytes " << GetInternalQueue (0)->GetNBytes ());
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -340,9 +337,10 @@ RedQueue::DoEnqueue (Ptr<QueueItem> item)
|
||||
* and didn't seem worth the trouble...
|
||||
*/
|
||||
void
|
||||
RedQueue::InitializeParams (void)
|
||||
RedQueueDisc::InitializeParams (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
NS_LOG_INFO ("Initializing RED params.");
|
||||
|
||||
NS_ASSERT (m_minTh <= m_maxTh);
|
||||
m_stats.forcedDrop = 0;
|
||||
@@ -419,7 +417,7 @@ RedQueue::InitializeParams (void)
|
||||
|
||||
// Compute the average queue size
|
||||
double
|
||||
RedQueue::Estimator (uint32_t nQueued, uint32_t m, double qAvg, double qW)
|
||||
RedQueueDisc::Estimator (uint32_t nQueued, uint32_t m, double qAvg, double qW)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << nQueued << m << qAvg << qW);
|
||||
|
||||
@@ -433,11 +431,11 @@ RedQueue::Estimator (uint32_t nQueued, uint32_t m, double qAvg, double qW)
|
||||
|
||||
// Check if packet p needs to be dropped due to probability mark
|
||||
uint32_t
|
||||
RedQueue::DropEarly (Ptr<Packet> p, uint32_t qSize)
|
||||
RedQueueDisc::DropEarly (Ptr<QueueDiscItem> item, uint32_t qSize)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << p << qSize);
|
||||
NS_LOG_FUNCTION (this << item << qSize);
|
||||
m_vProb1 = CalculatePNew (m_qAvg, m_maxTh, m_isGentle, m_vA, m_vB, m_vC, m_vD, m_curMaxP);
|
||||
m_vProb = ModifyP (m_vProb1, m_count, m_countBytes, m_meanPktSize, m_isWait, p->GetSize ());
|
||||
m_vProb = ModifyP (m_vProb1, m_count, m_countBytes, m_meanPktSize, m_isWait, item->GetPacketSize ());
|
||||
|
||||
// Drop probability is computed, pick random number and act
|
||||
if (m_cautious == 1)
|
||||
@@ -494,7 +492,7 @@ RedQueue::DropEarly (Ptr<Packet> p, uint32_t qSize)
|
||||
|
||||
// Returns a probability using these function parameters for the DropEarly funtion
|
||||
double
|
||||
RedQueue::CalculatePNew (double qAvg, double maxTh, bool isGentle, double vA,
|
||||
RedQueueDisc::CalculatePNew (double qAvg, double maxTh, bool isGentle, double vA,
|
||||
double vB, double vC, double vD, double maxP)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << qAvg << maxTh << isGentle << vA << vB << vC << vD << maxP);
|
||||
@@ -535,13 +533,13 @@ RedQueue::CalculatePNew (double qAvg, double maxTh, bool isGentle, double vA,
|
||||
|
||||
// Returns a probability using these function parameters for the DropEarly funtion
|
||||
double
|
||||
RedQueue::ModifyP (double p, uint32_t count, uint32_t countBytes,
|
||||
RedQueueDisc::ModifyP (double p, uint32_t count, uint32_t countBytes,
|
||||
uint32_t meanPktSize, bool isWait, uint32_t size)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << p << count << countBytes << meanPktSize << isWait << size);
|
||||
double count1 = (double) count;
|
||||
|
||||
if (GetMode () == QUEUE_MODE_BYTES)
|
||||
if (GetMode () == Queue::QUEUE_MODE_BYTES)
|
||||
{
|
||||
count1 = (double) (countBytes / meanPktSize);
|
||||
}
|
||||
@@ -573,7 +571,7 @@ RedQueue::ModifyP (double p, uint32_t count, uint32_t countBytes,
|
||||
}
|
||||
}
|
||||
|
||||
if ((GetMode () == QUEUE_MODE_BYTES) && (p < 1.0))
|
||||
if ((GetMode () == Queue::QUEUE_MODE_BYTES) && (p < 1.0))
|
||||
{
|
||||
p = (p * size) / meanPktSize;
|
||||
}
|
||||
@@ -587,16 +585,16 @@ RedQueue::ModifyP (double p, uint32_t count, uint32_t countBytes,
|
||||
}
|
||||
|
||||
uint32_t
|
||||
RedQueue::GetQueueSize (void)
|
||||
RedQueueDisc::GetQueueSize (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
if (GetMode () == QUEUE_MODE_BYTES)
|
||||
if (GetMode () == Queue::QUEUE_MODE_BYTES)
|
||||
{
|
||||
return m_bytesInQueue;
|
||||
return GetInternalQueue (0)->GetNBytes ();
|
||||
}
|
||||
else if (GetMode () == QUEUE_MODE_PACKETS)
|
||||
else if (GetMode () == Queue::QUEUE_MODE_PACKETS)
|
||||
{
|
||||
return m_packets.size ();
|
||||
return GetInternalQueue (0)->GetNPackets ();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -604,12 +602,12 @@ RedQueue::GetQueueSize (void)
|
||||
}
|
||||
}
|
||||
|
||||
Ptr<QueueItem>
|
||||
RedQueue::DoDequeue (void)
|
||||
Ptr<QueueDiscItem>
|
||||
RedQueueDisc::DoDequeue (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
if (m_packets.empty ())
|
||||
if (GetInternalQueue (0)->IsEmpty ())
|
||||
{
|
||||
NS_LOG_LOGIC ("Queue empty");
|
||||
m_idle = 1;
|
||||
@@ -620,35 +618,86 @@ RedQueue::DoDequeue (void)
|
||||
else
|
||||
{
|
||||
m_idle = 0;
|
||||
Ptr<QueueItem> item = m_packets.front ();
|
||||
m_packets.pop_front ();
|
||||
m_bytesInQueue -= item->GetPacketSize ();
|
||||
Ptr<QueueDiscItem> item = StaticCast<QueueDiscItem> (GetInternalQueue (0)->Dequeue ());
|
||||
|
||||
NS_LOG_LOGIC ("Popped " << item);
|
||||
|
||||
NS_LOG_LOGIC ("Number packets " << m_packets.size ());
|
||||
NS_LOG_LOGIC ("Number bytes " << m_bytesInQueue);
|
||||
NS_LOG_LOGIC ("Number packets " << GetInternalQueue (0)->GetNPackets ());
|
||||
NS_LOG_LOGIC ("Number bytes " << GetInternalQueue (0)->GetNBytes ());
|
||||
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
Ptr<const QueueItem>
|
||||
RedQueue::DoPeek (void) const
|
||||
Ptr<const QueueDiscItem>
|
||||
RedQueueDisc::DoPeek (void) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
if (m_packets.empty ())
|
||||
if (GetInternalQueue (0)->IsEmpty ())
|
||||
{
|
||||
NS_LOG_LOGIC ("Queue empty");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Ptr<QueueItem> item = m_packets.front ();
|
||||
Ptr<const QueueDiscItem> item = StaticCast<const QueueDiscItem> (GetInternalQueue (0)->Peek ());
|
||||
|
||||
NS_LOG_LOGIC ("Number packets " << m_packets.size ());
|
||||
NS_LOG_LOGIC ("Number bytes " << m_bytesInQueue);
|
||||
NS_LOG_LOGIC ("Number packets " << GetInternalQueue (0)->GetNPackets ());
|
||||
NS_LOG_LOGIC ("Number bytes " << GetInternalQueue (0)->GetNBytes ());
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
bool
|
||||
RedQueueDisc::CheckConfig (void)
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
if (GetNQueueDiscClasses () > 0)
|
||||
{
|
||||
NS_LOG_ERROR ("RedQueueDisc cannot have classes");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GetNPacketFilters () > 0)
|
||||
{
|
||||
NS_LOG_ERROR ("RedQueueDisc cannot have packet filters");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GetNInternalQueues () == 0)
|
||||
{
|
||||
// create a DropTail queue
|
||||
Ptr<Queue> queue = CreateObjectWithAttributes<DropTailQueue> ("Mode", EnumValue (m_mode));
|
||||
if (m_mode == Queue::QUEUE_MODE_PACKETS)
|
||||
{
|
||||
queue->SetMaxPackets (m_queueLimit);
|
||||
}
|
||||
else
|
||||
{
|
||||
queue->SetMaxBytes (m_queueLimit);
|
||||
}
|
||||
AddInternalQueue (queue);
|
||||
}
|
||||
|
||||
if (GetNInternalQueues () != 1)
|
||||
{
|
||||
NS_LOG_ERROR ("RedQueueDisc needs 1 internal queue");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GetInternalQueue (0)->GetMode () != m_mode)
|
||||
{
|
||||
NS_LOG_ERROR ("The mode of the provided queue does not match the mode set on the RedQueueDisc");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((m_mode == Queue::QUEUE_MODE_PACKETS && GetInternalQueue (0)->GetMaxPackets () < m_queueLimit) ||
|
||||
(m_mode == Queue::QUEUE_MODE_BYTES && GetInternalQueue (0)->GetMaxBytes () < m_queueLimit))
|
||||
{
|
||||
NS_LOG_ERROR ("The size of the internal queue is less than the queue disc limit");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -58,12 +58,11 @@
|
||||
* [0] S.Floyd, K.Fall http://icir.org/floyd/papers/redsims.ps
|
||||
*/
|
||||
|
||||
#ifndef RED_QUEUE_H
|
||||
#define RED_QUEUE_H
|
||||
#ifndef RED_QUEUE_DISC_H
|
||||
#define RED_QUEUE_DISC_H
|
||||
|
||||
#include <queue>
|
||||
#include "ns3/packet.h"
|
||||
#include "ns3/queue.h"
|
||||
#include "ns3/queue-disc.h"
|
||||
#include "ns3/nstime.h"
|
||||
#include "ns3/boolean.h"
|
||||
#include "ns3/data-rate.h"
|
||||
@@ -75,11 +74,11 @@ class TraceContainer;
|
||||
class UniformRandomVariable;
|
||||
|
||||
/**
|
||||
* \ingroup queue
|
||||
* \ingroup traffic-control
|
||||
*
|
||||
* \brief A RED packet queue
|
||||
* \brief A RED packet queue disc
|
||||
*/
|
||||
class RedQueue : public Queue
|
||||
class RedQueueDisc : public QueueDisc
|
||||
{
|
||||
public:
|
||||
/**
|
||||
@@ -88,18 +87,18 @@ public:
|
||||
*/
|
||||
static TypeId GetTypeId (void);
|
||||
/**
|
||||
* \brief RedQueue Constructor
|
||||
* \brief RedQueueDisc Constructor
|
||||
*
|
||||
* Create a RED queue
|
||||
* Create a RED queue disc
|
||||
*/
|
||||
RedQueue ();
|
||||
RedQueueDisc ();
|
||||
|
||||
/**
|
||||
* \brief Destructor
|
||||
*
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~RedQueue ();
|
||||
virtual ~RedQueueDisc ();
|
||||
|
||||
/**
|
||||
* \brief Stats
|
||||
@@ -127,7 +126,7 @@ public:
|
||||
*
|
||||
* \param mode The operating mode of this queue.
|
||||
*/
|
||||
void SetMode (RedQueue::QueueMode mode);
|
||||
void SetMode (Queue::QueueMode mode);
|
||||
|
||||
/**
|
||||
* \brief Get the encapsulation mode of this queue.
|
||||
@@ -135,7 +134,7 @@ public:
|
||||
*
|
||||
* \returns The encapsulation mode of this queue.
|
||||
*/
|
||||
RedQueue::QueueMode GetMode (void);
|
||||
Queue::QueueMode GetMode (void);
|
||||
|
||||
/**
|
||||
* \brief Get the current value of the queue in bytes or packets.
|
||||
@@ -176,10 +175,17 @@ public:
|
||||
*/
|
||||
int64_t AssignStreams (int64_t stream);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* \brief Dispose of the object
|
||||
*/
|
||||
virtual void DoDispose (void);
|
||||
|
||||
private:
|
||||
virtual bool DoEnqueue (Ptr<QueueItem> item);
|
||||
virtual Ptr<QueueItem> DoDequeue (void);
|
||||
virtual Ptr<const QueueItem> DoPeek (void) const;
|
||||
virtual bool DoEnqueue (Ptr<QueueDiscItem> item);
|
||||
virtual Ptr<QueueDiscItem> DoDequeue (void);
|
||||
virtual Ptr<const QueueDiscItem> DoPeek (void) const;
|
||||
virtual bool CheckConfig (void);
|
||||
|
||||
/**
|
||||
* \brief Initialize the queue parameters.
|
||||
@@ -189,7 +195,7 @@ private:
|
||||
* This should be fixed, but it would require some extra parameters,
|
||||
* and didn't seem worth the trouble...
|
||||
*/
|
||||
void InitializeParams (void);
|
||||
virtual void InitializeParams (void);
|
||||
/**
|
||||
* \brief Compute the average queue size
|
||||
* \param nQueued number of queued packets
|
||||
@@ -200,12 +206,12 @@ private:
|
||||
*/
|
||||
double Estimator (uint32_t nQueued, uint32_t m, double qAvg, double qW);
|
||||
/**
|
||||
* \brief Check if packet p needs to be dropped due to probability mark
|
||||
* \param p packet
|
||||
* \brief Check if a packet needs to be dropped due to probability mark
|
||||
* \param item queue item
|
||||
* \param qSize queue size
|
||||
* \returns 0 for no drop/mark, 1 for drop
|
||||
*/
|
||||
uint32_t DropEarly (Ptr<Packet> p, uint32_t qSize);
|
||||
uint32_t DropEarly (Ptr<QueueDiscItem> item, uint32_t qSize);
|
||||
/**
|
||||
* \brief Returns a probability using these function parameters for the DropEarly function
|
||||
* \param qAvg Average queue length
|
||||
@@ -233,14 +239,10 @@ private:
|
||||
double ModifyP (double p, uint32_t count, uint32_t countBytes,
|
||||
uint32_t meanPktSize, bool wait, uint32_t size);
|
||||
|
||||
std::list<Ptr<QueueItem> > m_packets; //!< packets in the queue
|
||||
|
||||
uint32_t m_bytesInQueue; //!< bytes in the queue
|
||||
bool m_hasRedStarted; //!< True if RED has started
|
||||
Stats m_stats; //!< RED statistics
|
||||
|
||||
// ** Variables supplied by user
|
||||
QueueMode m_mode; //!< Mode (Bytes or packets)
|
||||
Queue::QueueMode m_mode; //!< Mode (Bytes or packets)
|
||||
uint32_t m_meanPktSize; //!< Avg pkt size
|
||||
uint32_t m_idlePktSize; //!< Avg pkt size used during idle times
|
||||
bool m_isWait; //!< True for waiting between dropped packets
|
||||
@@ -282,4 +284,4 @@ private:
|
||||
|
||||
}; // namespace ns3
|
||||
|
||||
#endif // RED_QUEUE_H
|
||||
#endif // RED_QUEUE_DISC_H
|
||||
|
||||
@@ -13,6 +13,7 @@ def build(bld):
|
||||
'model/packet-filter.cc',
|
||||
'model/queue-disc.cc',
|
||||
'model/pfifo-fast-queue-disc.cc',
|
||||
'model/red-queue-disc.cc',
|
||||
'helper/traffic-control-helper.cc',
|
||||
'helper/queue-disc-container.cc'
|
||||
]
|
||||
@@ -29,6 +30,7 @@ def build(bld):
|
||||
'model/packet-filter.h',
|
||||
'model/queue-disc.h',
|
||||
'model/pfifo-fast-queue-disc.h',
|
||||
'model/red-queue-disc.h',
|
||||
'helper/traffic-control-helper.h',
|
||||
'helper/queue-disc-container.h'
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user