traffic-control: (fixes #2389) Internal queues need to notify their queue disc of packet drops

This commit is contained in:
Stefano Avallone
2016-05-11 12:10:02 +02:00
parent 93bf31ac56
commit 500ef9f4a6
6 changed files with 65 additions and 21 deletions

View File

@@ -97,19 +97,18 @@ bool
Queue::Enqueue (Ptr<QueueItem> item)
{
NS_LOG_FUNCTION (this << item);
Ptr<Packet> p = item->GetPacket ();
if (m_mode == QUEUE_MODE_PACKETS && (m_nPackets.Get () >= m_maxPackets))
{
NS_LOG_LOGIC ("Queue full (at max packets) -- dropping pkt");
Drop (p);
Drop (item);
return false;
}
if (m_mode == QUEUE_MODE_BYTES && (m_nBytes.Get () + item->GetPacketSize () > m_maxBytes))
{
NS_LOG_LOGIC ("Queue full (packet would exceed max bytes) -- dropping pkt");
Drop (p);
Drop (item);
return false;
}
@@ -319,15 +318,33 @@ Queue::GetMaxBytes (void) const
}
void
Queue::Drop (Ptr<Packet> p)
Queue::SetDropCallback (DropCallback cb)
{
NS_LOG_FUNCTION (this << p);
m_dropCallback = cb;
}
void
Queue::NotifyDrop (Ptr<QueueItem> item)
{
NS_LOG_FUNCTION (this << item);
if (!m_dropCallback.IsNull ())
{
m_dropCallback (item);
}
}
void
Queue::Drop (Ptr<QueueItem> item)
{
NS_LOG_FUNCTION (this << item);
m_nTotalDroppedPackets++;
m_nTotalDroppedBytes += p->GetSize ();
m_nTotalDroppedBytes += item->GetPacketSize ();
NS_LOG_LOGIC ("m_traceDrop (p)");
m_traceDrop (p);
m_traceDrop (item->GetPacket ());
NotifyDrop (item);
}
} // namespace ns3

View File

@@ -190,16 +190,28 @@ public:
double GetDroppedPacketsPerSecondVariance (void);
#endif
/// Callback set by the object (e.g., a queue disc) that wants to be notified of a packet drop
typedef Callback<void, Ptr<QueueItem> > DropCallback;
/**
* \brief Set the drop callback
* \param cb the callback to set
*
* Called when a queue is added to a queue disc in order to set a
* callback to the Drop method of the queue disc.
*/
virtual void SetDropCallback (DropCallback cb);
protected:
/**
* \brief Drop a packet
* \param p packet that was dropped
* \param item item that was dropped
*
* This method is called by the base class when a packet is dropped because
* the queue is full and by the subclasses to notify parent (this class) that
* a packet has been dropped for other reasons.
*/
void Drop (Ptr<Packet> p);
void Drop (Ptr<QueueItem> item);
private:
/**
@@ -219,6 +231,12 @@ private:
*/
virtual Ptr<const QueueItem> DoPeek (void) const = 0;
/**
* \brief Notification of a packet drop
* \param item item that was dropped
*/
void NotifyDrop (Ptr<QueueItem> item);
/// Traced callback: fired when a packet is enqueued
TracedCallback<Ptr<const Packet> > m_traceEnqueue;
/// Traced callback: fired when a packet is dequeued
@@ -236,6 +254,7 @@ private:
uint32_t m_maxPackets; //!< max packets in the queue
uint32_t m_maxBytes; //!< max bytes in the queue
QueueMode m_mode; //!< queue mode (packets or bytes limited)
DropCallback m_dropCallback; //!< drop callback
};
} // namespace ns3

View File

@@ -296,13 +296,16 @@ CoDelQueueDisc::DoEnqueue (Ptr<QueueDiscItem> item)
// Tag packet with current time for DoDequeue() to compute sojourn time
CoDelTimestampTag tag;
p->AddPacketTag (tag);
GetInternalQueue (0)->Enqueue (item);
bool retval = GetInternalQueue (0)->Enqueue (item);
// If Queue::Enqueue fails, QueueDisc::Drop is called by the internal queue
// because QueueDisc::AddInternalQueue sets the drop callback
NS_LOG_LOGIC ("Number packets " << GetInternalQueue (0)->GetNPackets ());
NS_LOG_LOGIC ("Number bytes " << GetInternalQueue (0)->GetNBytes ());
return true;
return retval;
}
bool

View File

@@ -87,15 +87,14 @@ PfifoFastQueueDisc::DoEnqueue (Ptr<QueueDiscItem> item)
band = ret;
}
if (!GetInternalQueue(band)->Enqueue (item))
{
NS_LOG_LOGIC ("Enqueue failed -- dropping pkt");
Drop (item);
return false;
}
bool retval = GetInternalQueue(band)->Enqueue (item);
// If Queue::Enqueue fails, QueueDisc::Drop is called by the internal queue
// because QueueDisc::AddInternalQueue sets the drop callback
NS_LOG_LOGIC ("Number packets band " << band << ": " << GetInternalQueue(band)->GetNPackets ());
return true;
return retval;
}
Ptr<QueueDiscItem>

View File

@@ -313,6 +313,9 @@ void
QueueDisc::AddInternalQueue (Ptr<Queue> queue)
{
NS_LOG_FUNCTION (this);
// set the drop callback on the internal queue, so that the queue disc is
// notified of packets dropped by the internal queue
queue->SetDropCallback (MakeCallback (&QueueDisc::Drop, this));
m_queues.push_back (queue);
}

View File

@@ -410,12 +410,15 @@ RedQueueDisc::DoEnqueue (Ptr<QueueDiscItem> item)
return false;
}
GetInternalQueue (0)->Enqueue (item);
bool retval = GetInternalQueue (0)->Enqueue (item);
// If Queue::Enqueue fails, QueueDisc::Drop is called by the internal queue
// because QueueDisc::AddInternalQueue sets the drop callback
NS_LOG_LOGIC ("Number packets " << GetInternalQueue (0)->GetNPackets ());
NS_LOG_LOGIC ("Number bytes " << GetInternalQueue (0)->GetNBytes ());
return true;
return retval;
}
/*