traffic-control: PfifoFastQueueDisc uses priority to map packets to bands
This commit is contained in:
@@ -306,8 +306,7 @@ int main (int argc, char *argv[])
|
||||
stack.InstallAll ();
|
||||
|
||||
TrafficControlHelper tchPfifo;
|
||||
uint32_t handle = tchPfifo.SetRootQueueDisc ("ns3::PfifoFastQueueDisc");
|
||||
tchPfifo.AddPacketFilter (handle, "ns3::PfifoFastIpv4PacketFilter");
|
||||
tchPfifo.SetRootQueueDisc ("ns3::PfifoFastQueueDisc");
|
||||
|
||||
TrafficControlHelper tchCoDel;
|
||||
tchCoDel.SetRootQueueDisc ("ns3::CoDelQueueDisc");
|
||||
|
||||
@@ -58,136 +58,4 @@ Ipv4PacketFilter::CheckProtocol (Ptr<QueueDiscItem> item) const
|
||||
return (DynamicCast<Ipv4QueueDiscItem> (item) != 0);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------- //
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (PfifoFastIpv4PacketFilter);
|
||||
|
||||
TypeId
|
||||
PfifoFastIpv4PacketFilter::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::PfifoFastIpv4PacketFilter")
|
||||
.SetParent<Ipv4PacketFilter> ()
|
||||
.SetGroupName ("Internet")
|
||||
.AddConstructor<PfifoFastIpv4PacketFilter> ()
|
||||
.AddAttribute ("Mode",
|
||||
"Whether to interpret the TOS byte as legacy TOS or DSCP",
|
||||
EnumValue (PF_MODE_DSCP),
|
||||
MakeEnumAccessor (&PfifoFastIpv4PacketFilter::m_trafficClassMode),
|
||||
MakeEnumChecker (PF_MODE_TOS, "TOS semantics",
|
||||
PF_MODE_DSCP, "DSCP semantics"))
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
PfifoFastIpv4PacketFilter::PfifoFastIpv4PacketFilter ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
PfifoFastIpv4PacketFilter::~PfifoFastIpv4PacketFilter()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
int32_t
|
||||
PfifoFastIpv4PacketFilter::DoClassify (Ptr<QueueDiscItem> item) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << item);
|
||||
uint32_t band;
|
||||
Ptr<Ipv4QueueDiscItem> ipv4Item = DynamicCast<Ipv4QueueDiscItem> (item);
|
||||
|
||||
NS_ASSERT (ipv4Item != 0);
|
||||
|
||||
if (m_trafficClassMode == PF_MODE_TOS)
|
||||
{
|
||||
uint8_t tos = ipv4Item->GetHeader ().GetTos ();
|
||||
band = TosToBand (tos);
|
||||
NS_LOG_DEBUG ("Found Ipv4 packet; TOS " << (uint8_t) tos << " band " << band);
|
||||
}
|
||||
else
|
||||
{
|
||||
Ipv4Header::DscpType dscp = ipv4Item->GetHeader ().GetDscp ();
|
||||
band = DscpToBand (dscp);
|
||||
NS_LOG_DEBUG ("Found Ipv4 packet; DSCP " << ipv4Item->GetHeader ().DscpTypeToString (dscp) << " band " << band);
|
||||
}
|
||||
|
||||
return band;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
PfifoFastIpv4PacketFilter::TosToBand (uint8_t tos) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << (uint16_t) tos);
|
||||
|
||||
uint32_t band = 1;
|
||||
switch (tos) {
|
||||
case 0x10 :
|
||||
case 0x12 :
|
||||
case 0x14 :
|
||||
case 0x16 :
|
||||
band = 0;
|
||||
break;
|
||||
case 0x0 :
|
||||
case 0x4 :
|
||||
case 0x6 :
|
||||
case 0x18 :
|
||||
case 0x1a :
|
||||
case 0x1c :
|
||||
case 0x1e :
|
||||
band = 1;
|
||||
break;
|
||||
case 0x2 :
|
||||
case 0x8 :
|
||||
case 0xa :
|
||||
case 0xc :
|
||||
case 0xe :
|
||||
band = 2;
|
||||
break;
|
||||
default :
|
||||
NS_LOG_ERROR ("Invalid TOS " << (uint16_t) tos);
|
||||
}
|
||||
return band;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
PfifoFastIpv4PacketFilter::DscpToBand (Ipv4Header::DscpType dscpType) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
uint32_t band = 1;
|
||||
switch (dscpType) {
|
||||
case Ipv4Header::DSCP_EF :
|
||||
case Ipv4Header::DSCP_AF13 :
|
||||
case Ipv4Header::DSCP_AF23 :
|
||||
case Ipv4Header::DSCP_AF33 :
|
||||
case Ipv4Header::DSCP_AF43 :
|
||||
case Ipv4Header::DscpDefault :
|
||||
case Ipv4Header::DSCP_CS2 :
|
||||
case Ipv4Header::DSCP_CS3 :
|
||||
band = 1;
|
||||
break;
|
||||
case Ipv4Header::DSCP_AF11 :
|
||||
case Ipv4Header::DSCP_AF21 :
|
||||
case Ipv4Header::DSCP_AF31 :
|
||||
case Ipv4Header::DSCP_AF41 :
|
||||
case Ipv4Header::DSCP_CS1 :
|
||||
band = 2;
|
||||
break;
|
||||
case Ipv4Header::DSCP_AF12 :
|
||||
case Ipv4Header::DSCP_AF22 :
|
||||
case Ipv4Header::DSCP_AF32 :
|
||||
case Ipv4Header::DSCP_AF42 :
|
||||
case Ipv4Header::DSCP_CS4 :
|
||||
case Ipv4Header::DSCP_CS5 :
|
||||
case Ipv4Header::DSCP_CS6 :
|
||||
case Ipv4Header::DSCP_CS7 :
|
||||
band = 0;
|
||||
break;
|
||||
default :
|
||||
band = 1;
|
||||
}
|
||||
NS_LOG_DEBUG ("Band returned: " << band);
|
||||
return band;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -50,124 +50,6 @@ private:
|
||||
virtual int32_t DoClassify (Ptr<QueueDiscItem> item) const = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup ipv4
|
||||
* \ingroup traffic-control
|
||||
*
|
||||
* PfifoFastIpv4PacketFilter is the filter to be added to the PfifoFast
|
||||
* queue disc to simulate the behavior of the pfifo_fast Linux queue disc.
|
||||
*
|
||||
* Two modes of operation are provided. In PF_MODE_TOS mode, packets are
|
||||
* classified based on the TOS byte (originally defined by RFC 1349:
|
||||
* http://www.ietf.org/rfc/rfc1349.txt)
|
||||
*
|
||||
* 0 1 2 3 4 5 6 7
|
||||
* +-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
* | PRECEDENCE | TOS | MBZ |
|
||||
* +-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
*
|
||||
* where MBZ stands for 'must be zero'.
|
||||
*
|
||||
* In the eight-bit legacy TOS byte, there were five lower bits for TOS
|
||||
* and three upper bits for Precedence. Bit 7 was never used. Bits 6-7
|
||||
* are now repurposed for ECN. The below TOS values correspond to
|
||||
* bits 3-7 in the TOS byte (i.e. including MBZ), omitting the precedence
|
||||
* bits 0-2.
|
||||
*
|
||||
* TOS | Bits | Means | Linux Priority | Band
|
||||
* -----|------|-------------------------|----------------|-----
|
||||
* 0x0 | 0 | Normal Service | 0 Best Effort | 1
|
||||
* 0x2 | 1 | Minimize Monetary Cost | 1 Filler | 2
|
||||
* 0x4 | 2 | Maximize Reliability | 0 Best Effort | 1
|
||||
* 0x6 | 3 | mmc+mr | 0 Best Effort | 1
|
||||
* 0x8 | 4 | Maximize Throughput | 2 Bulk | 2
|
||||
* 0xa | 5 | mmc+mt | 2 Bulk | 2
|
||||
* 0xc | 6 | mr+mt | 2 Bulk | 2
|
||||
* 0xe | 7 | mmc+mr+mt | 2 Bulk | 2
|
||||
* 0x10 | 8 | Minimize Delay | 6 Interactive | 0
|
||||
* 0x12 | 9 | mmc+md | 6 Interactive | 0
|
||||
* 0x14 | 10 | mr+md | 6 Interactive | 0
|
||||
* 0x16 | 11 | mmc+mr+md | 6 Interactive | 0
|
||||
* 0x18 | 12 | mt+md | 4 Int. Bulk | 1
|
||||
* 0x1a | 13 | mmc+mt+md | 4 Int. Bulk | 1
|
||||
* 0x1c | 14 | mr+mt+md | 4 Int. Bulk | 1
|
||||
* 0x1e | 15 | mmc+mr+mt+md | 4 Int. Bulk | 1
|
||||
*
|
||||
* In PF_MODE_TOS, the above values are used to map packets into bands, and
|
||||
* IP precedence bits are disregarded.
|
||||
*
|
||||
* In PF_MODE_DSCP (the default), the following mappings are used.
|
||||
*
|
||||
* For DSCP, the following values are recommended for Linux in a patch
|
||||
* to the netdev mailing list from Jesper Dangaard Brouer <brouer@redhat.com>
|
||||
* on 15 Sept 2014. CS* values I made up myself.
|
||||
*
|
||||
* DSCP | Hex | Means | Linux Priority | Band
|
||||
* -----|------|----------------------------|----------------|-----
|
||||
* EF | 0x2E | TC_PRIO_INTERACTIVE_BULK=4 | 4 Int. Bulk | 1
|
||||
* AF11 | 0x0A | TC_PRIO_BULK=2 | 2 Bulk | 2
|
||||
* AF21 | 0x12 | TC_PRIO_BULK=2 | 2 Bulk | 2
|
||||
* AF31 | 0x1A | TC_PRIO_BULK=2 | 2 Bulk | 2
|
||||
* AF41 | 0x22 | TC_PRIO_BULK=2 | 2 Bulk | 2
|
||||
* AF12 | 0x0C | TC_PRIO_INTERACTIVE=6 | 6 Interactive | 0
|
||||
* AF22 | 0x14 | TC_PRIO_INTERACTIVE=6 | 6 Interactive | 0
|
||||
* AF32 | 0x1C | TC_PRIO_INTERACTIVE=6 | 6 Interactive | 0
|
||||
* AF42 | 0x34 | TC_PRIO_INTERACTIVE=6 | 6 Interactive | 0
|
||||
* AF13 | 0x0E | TC_PRIO_INTERACTIVE_BULK=4 | 4 Int. Bulk | 1
|
||||
* AF23 | 0x16 | TC_PRIO_INTERACTIVE_BULK=4 | 4 Int. Bulk | 1
|
||||
* AF33 | 0x1E | TC_PRIO_INTERACTIVE_BULK=4 | 4 Int. Bulk | 1
|
||||
* AF43 | 0x26 | TC_PRIO_INTERACTIVE_BULK=4 | 4 Int. Bulk | 1
|
||||
* CS0 | 0x00 | TC_PRIO_BESTEFFORT | 0 Best Effort | 1
|
||||
* CS1 | 0x20 | TC_PRIO_FILLER | 1 Filler | 2
|
||||
* CS2 | 0x40 | TC_PRIO_BULK | 2 Bulk | 1
|
||||
* CS3 | 0x60 | TC_PRIO_INTERACTIVE_BULK | 4 Int. Bulk | 1
|
||||
* CS4 | 0x80 | TC_PRIO_INTERACTIVE | 6 Interactive | 0
|
||||
* CS5 | 0xA0 | TC_PRIO_INTERACTIVE | 6 Interactive | 0
|
||||
* CS6 | 0xC0 | TC_PRIO_INTERACTIVE | 6 Interactive | 0
|
||||
* CS7 | 0xE0 | TC_PRIO_CONTROL | 8 Control | 0
|
||||
*
|
||||
*/
|
||||
class PfifoFastIpv4PacketFilter: public Ipv4PacketFilter {
|
||||
public:
|
||||
/**
|
||||
* \brief Get the type ID.
|
||||
* \return the object TypeId
|
||||
*/
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
PfifoFastIpv4PacketFilter ();
|
||||
virtual ~PfifoFastIpv4PacketFilter ();
|
||||
|
||||
/**
|
||||
* \brief Enumeration of modes of Ipv4 header traffic class semantics
|
||||
*/
|
||||
enum Ipv4TrafficClassMode
|
||||
{
|
||||
PF_MODE_TOS, //!< use legacy TOS semantics to interpret TOS byte
|
||||
PF_MODE_DSCP, //!< use DSCP semantics to interpret TOS byte
|
||||
};
|
||||
|
||||
private:
|
||||
virtual int32_t DoClassify (Ptr<QueueDiscItem> item) const;
|
||||
|
||||
/**
|
||||
* \brief Converts a TOS field value into a priority band.
|
||||
* \param tos The tos to convert.
|
||||
* \returns The converted band value.
|
||||
*/
|
||||
uint32_t TosToBand (uint8_t tos) const;
|
||||
|
||||
/**
|
||||
* \brief Converts a DSCP field value into a priority band.
|
||||
* \param dscpType The DSCP to convert.
|
||||
* \returns The converted band value.
|
||||
*/
|
||||
uint32_t DscpToBand (Ipv4Header::DscpType dscpType) const;
|
||||
|
||||
Ipv4TrafficClassMode m_trafficClassMode; //!< traffic class mode
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* IPV4_PACKET_FILTER */
|
||||
|
||||
@@ -58,86 +58,4 @@ Ipv6PacketFilter::CheckProtocol (Ptr<QueueDiscItem> item) const
|
||||
return (DynamicCast<Ipv6QueueDiscItem> (item) != 0);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------- //
|
||||
|
||||
NS_OBJECT_ENSURE_REGISTERED (PfifoFastIpv6PacketFilter);
|
||||
|
||||
TypeId
|
||||
PfifoFastIpv6PacketFilter::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::PfifoFastIpv6PacketFilter")
|
||||
.SetParent<Ipv6PacketFilter> ()
|
||||
.SetGroupName ("Internet")
|
||||
.AddConstructor<PfifoFastIpv6PacketFilter> ()
|
||||
;
|
||||
return tid;
|
||||
}
|
||||
|
||||
PfifoFastIpv6PacketFilter::PfifoFastIpv6PacketFilter ()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
PfifoFastIpv6PacketFilter::~PfifoFastIpv6PacketFilter()
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
int32_t
|
||||
PfifoFastIpv6PacketFilter::DoClassify (Ptr<QueueDiscItem> item) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this << item);
|
||||
uint32_t band;
|
||||
Ptr<Ipv6QueueDiscItem> ipv6Item = DynamicCast<Ipv6QueueDiscItem> (item);
|
||||
|
||||
NS_ASSERT (ipv6Item != 0);
|
||||
|
||||
Ipv6Header::DscpType dscp = ipv6Item->GetHeader ().GetDscp ();
|
||||
band = DscpToBand (dscp);
|
||||
NS_LOG_DEBUG ("Found Ipv6 packet; DSCP " << ipv6Item->GetHeader ().DscpTypeToString (dscp) << " band " << band);
|
||||
|
||||
return band;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
PfifoFastIpv6PacketFilter::DscpToBand (Ipv6Header::DscpType dscpType) const
|
||||
{
|
||||
NS_LOG_FUNCTION (this);
|
||||
|
||||
uint32_t band = 1;
|
||||
switch (dscpType) {
|
||||
case Ipv6Header::DSCP_EF :
|
||||
case Ipv6Header::DSCP_AF13 :
|
||||
case Ipv6Header::DSCP_AF23 :
|
||||
case Ipv6Header::DSCP_AF33 :
|
||||
case Ipv6Header::DSCP_AF43 :
|
||||
case Ipv6Header::DscpDefault :
|
||||
case Ipv6Header::DSCP_CS2 :
|
||||
case Ipv6Header::DSCP_CS3 :
|
||||
band = 1;
|
||||
break;
|
||||
case Ipv6Header::DSCP_AF11 :
|
||||
case Ipv6Header::DSCP_AF21 :
|
||||
case Ipv6Header::DSCP_AF31 :
|
||||
case Ipv6Header::DSCP_AF41 :
|
||||
case Ipv6Header::DSCP_CS1 :
|
||||
band = 2;
|
||||
break;
|
||||
case Ipv6Header::DSCP_AF12 :
|
||||
case Ipv6Header::DSCP_AF22 :
|
||||
case Ipv6Header::DSCP_AF32 :
|
||||
case Ipv6Header::DSCP_AF42 :
|
||||
case Ipv6Header::DSCP_CS4 :
|
||||
case Ipv6Header::DSCP_CS5 :
|
||||
case Ipv6Header::DSCP_CS6 :
|
||||
case Ipv6Header::DSCP_CS7 :
|
||||
band = 0;
|
||||
break;
|
||||
default :
|
||||
band = 1;
|
||||
}
|
||||
NS_LOG_DEBUG ("Band returned: " << band);
|
||||
return band;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -50,66 +50,6 @@ private:
|
||||
virtual int32_t DoClassify (Ptr<QueueDiscItem> item) const = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup ipv6
|
||||
* \ingroup traffic-control
|
||||
*
|
||||
* PfifoFastIpv6PacketFilter is the filter to be added to the PfifoFast
|
||||
* queue disc to simulate the behavior of the pfifo_fast Linux queue disc.
|
||||
*
|
||||
* Packets are classified based on the DSCP. The following values are
|
||||
* recommended for Linux in a patch to the netdev mailing list from
|
||||
* Jesper Dangaard Brouer <brouer@redhat.com> on 15 Sept 2014.
|
||||
* CS* values I made up myself.
|
||||
*
|
||||
* DSCP | Hex | Means | Linux Priority | Band
|
||||
* -----|------|----------------------------|----------------|-----
|
||||
* EF | 0x2E | TC_PRIO_INTERACTIVE_BULK=4 | 4 Int. Bulk | 1
|
||||
* AF11 | 0x0A | TC_PRIO_BULK=2 | 2 Bulk | 2
|
||||
* AF21 | 0x12 | TC_PRIO_BULK=2 | 2 Bulk | 2
|
||||
* AF31 | 0x1A | TC_PRIO_BULK=2 | 2 Bulk | 2
|
||||
* AF41 | 0x22 | TC_PRIO_BULK=2 | 2 Bulk | 2
|
||||
* AF12 | 0x0C | TC_PRIO_INTERACTIVE=6 | 6 Interactive | 0
|
||||
* AF22 | 0x14 | TC_PRIO_INTERACTIVE=6 | 6 Interactive | 0
|
||||
* AF32 | 0x1C | TC_PRIO_INTERACTIVE=6 | 6 Interactive | 0
|
||||
* AF42 | 0x34 | TC_PRIO_INTERACTIVE=6 | 6 Interactive | 0
|
||||
* AF13 | 0x0E | TC_PRIO_INTERACTIVE_BULK=4 | 4 Int. Bulk | 1
|
||||
* AF23 | 0x16 | TC_PRIO_INTERACTIVE_BULK=4 | 4 Int. Bulk | 1
|
||||
* AF33 | 0x1E | TC_PRIO_INTERACTIVE_BULK=4 | 4 Int. Bulk | 1
|
||||
* AF43 | 0x26 | TC_PRIO_INTERACTIVE_BULK=4 | 4 Int. Bulk | 1
|
||||
* CS0 | 0x00 | TC_PRIO_BESTEFFORT | 0 Best Effort | 1
|
||||
* CS1 | 0x20 | TC_PRIO_FILLER | 1 Filler | 2
|
||||
* CS2 | 0x40 | TC_PRIO_BULK | 2 Bulk | 1
|
||||
* CS3 | 0x60 | TC_PRIO_INTERACTIVE_BULK | 4 Int. Bulk | 1
|
||||
* CS4 | 0x80 | TC_PRIO_INTERACTIVE | 6 Interactive | 0
|
||||
* CS5 | 0xA0 | TC_PRIO_INTERACTIVE | 6 Interactive | 0
|
||||
* CS6 | 0xC0 | TC_PRIO_INTERACTIVE | 6 Interactive | 0
|
||||
* CS7 | 0xE0 | TC_PRIO_CONTROL | 8 Control | 0
|
||||
*
|
||||
*/
|
||||
class PfifoFastIpv6PacketFilter: public Ipv6PacketFilter {
|
||||
public:
|
||||
/**
|
||||
* \brief Get the type ID.
|
||||
* \return the object TypeId
|
||||
*/
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
PfifoFastIpv6PacketFilter ();
|
||||
virtual ~PfifoFastIpv6PacketFilter ();
|
||||
|
||||
private:
|
||||
virtual int32_t DoClassify (Ptr<QueueDiscItem> item) const;
|
||||
|
||||
/**
|
||||
* \brief Converts a DSCP field value into a priority band.
|
||||
* \param dscpType The DSCP to convert.
|
||||
* \returns The converted band value.
|
||||
*/
|
||||
uint32_t DscpToBand (Ipv6Header::DscpType dscpType) const;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
#endif /* IPV6_PACKET_FILTER */
|
||||
|
||||
@@ -22,11 +22,11 @@
|
||||
#include "ns3/drop-tail-queue.h"
|
||||
#include "ns3/ipv4-queue-disc-item.h"
|
||||
#include "ns3/ipv6-queue-disc-item.h"
|
||||
#include "ns3/ipv4-packet-filter.h"
|
||||
#include "ns3/enum.h"
|
||||
#include "ns3/uinteger.h"
|
||||
#include "ns3/pointer.h"
|
||||
#include "ns3/object-factory.h"
|
||||
#include "ns3/socket.h"
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
@@ -41,7 +41,6 @@ public:
|
||||
|
||||
private:
|
||||
virtual void DoRun (void);
|
||||
Ptr<Packet> CreatePacketWithTos (uint8_t tos);
|
||||
void TestTosValue (Ptr<PfifoFastQueueDisc> queue, uint8_t tos, uint32_t band);
|
||||
};
|
||||
|
||||
@@ -54,24 +53,17 @@ PfifoFastQueueDiscTosPrioritization::~PfifoFastQueueDiscTosPrioritization ()
|
||||
{
|
||||
}
|
||||
|
||||
Ptr<Packet>
|
||||
PfifoFastQueueDiscTosPrioritization::CreatePacketWithTos (uint8_t tos)
|
||||
void
|
||||
PfifoFastQueueDiscTosPrioritization::TestTosValue (Ptr<PfifoFastQueueDisc> queue, uint8_t tos, uint32_t band)
|
||||
{
|
||||
Ptr<Packet> p = Create<Packet> (100);
|
||||
Ipv4Header ipHeader;
|
||||
ipHeader.SetPayloadSize (100);
|
||||
ipHeader.SetTos (tos);
|
||||
ipHeader.SetProtocol (6);
|
||||
p->AddHeader (ipHeader);
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
PfifoFastQueueDiscTosPrioritization::TestTosValue (Ptr<PfifoFastQueueDisc> queue, uint8_t tos, uint32_t band)
|
||||
{
|
||||
Ptr<Packet> p = CreatePacketWithTos (tos);
|
||||
Ipv4Header ipHeader;
|
||||
p->RemoveHeader (ipHeader);
|
||||
SocketPriorityTag priorityTag;
|
||||
priorityTag.SetPriority (Socket::IpTos2Priority (tos));
|
||||
p->AddPacketTag (priorityTag);
|
||||
Address dest;
|
||||
Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, ipHeader);
|
||||
queue->Enqueue (item);
|
||||
@@ -84,10 +76,6 @@ void
|
||||
PfifoFastQueueDiscTosPrioritization::DoRun (void)
|
||||
{
|
||||
Ptr<PfifoFastQueueDisc> queueDisc = CreateObject<PfifoFastQueueDisc> ();
|
||||
Ptr<PfifoFastIpv4PacketFilter> filter = CreateObject<PfifoFastIpv4PacketFilter> ();
|
||||
bool ok = filter->SetAttributeFailSafe ("Mode", EnumValue (PfifoFastIpv4PacketFilter::PF_MODE_TOS));
|
||||
NS_TEST_ASSERT_MSG_EQ (ok, true, "unable to set attribute");
|
||||
queueDisc->AddPacketFilter (filter);
|
||||
for (uint16_t i = 0; i < 3; i++)
|
||||
{
|
||||
Ptr<DropTailQueue> queue = CreateObject<DropTailQueue> ();
|
||||
@@ -99,22 +87,23 @@ PfifoFastQueueDiscTosPrioritization::DoRun (void)
|
||||
NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 0, "initialized non-zero");
|
||||
NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (2)->GetNPackets (), 0, "initialized non-zero");
|
||||
|
||||
TestTosValue (queueDisc, 0x0, 1);
|
||||
TestTosValue (queueDisc, 0x2, 2);
|
||||
TestTosValue (queueDisc, 0x4, 1);
|
||||
TestTosValue (queueDisc, 0x6, 1);
|
||||
TestTosValue (queueDisc, 0x8, 2);
|
||||
TestTosValue (queueDisc, 0xa, 2);
|
||||
TestTosValue (queueDisc, 0xc, 2);
|
||||
TestTosValue (queueDisc, 0xe, 2);
|
||||
TestTosValue (queueDisc, 0x10, 0);
|
||||
TestTosValue (queueDisc, 0x12, 0);
|
||||
TestTosValue (queueDisc, 0x14, 0);
|
||||
TestTosValue (queueDisc, 0x16, 0);
|
||||
TestTosValue (queueDisc, 0x18, 1);
|
||||
TestTosValue (queueDisc, 0x1a, 1);
|
||||
TestTosValue (queueDisc, 0x1c, 1);
|
||||
TestTosValue (queueDisc, 0x1e, 1);
|
||||
// Service name priority band
|
||||
TestTosValue (queueDisc, 0x00, 1); // Normal service -> Best Effort (0) -> 1
|
||||
TestTosValue (queueDisc, 0x02, 1); // MMC -> Best Effort (0) -> 1
|
||||
TestTosValue (queueDisc, 0x04, 1); // MR -> Best Effort (0) -> 1
|
||||
TestTosValue (queueDisc, 0x06, 1); // MMC+MR -> Best Effort (0) -> 1
|
||||
TestTosValue (queueDisc, 0x08, 2); // Max. Throughput -> Bulk (2) -> 2
|
||||
TestTosValue (queueDisc, 0x0a, 2); // MMC+MT -> Bulk (2) -> 2
|
||||
TestTosValue (queueDisc, 0x0c, 2); // MR+MT -> Bulk (2) -> 2
|
||||
TestTosValue (queueDisc, 0x0e, 2); // MMC+MR+MT -> Bulk (2) -> 2
|
||||
TestTosValue (queueDisc, 0x10, 0); // Minimize Delay -> Interactive (6) -> 0
|
||||
TestTosValue (queueDisc, 0x12, 0); // MMC+MD -> Interactive (6) -> 0
|
||||
TestTosValue (queueDisc, 0x14, 0); // MR+MD -> Interactive (6) -> 0
|
||||
TestTosValue (queueDisc, 0x16, 0); // MMC+MR+MD -> Interactive (6) -> 0
|
||||
TestTosValue (queueDisc, 0x18, 1); // MT+MD -> Int. Bulk (4) -> 1
|
||||
TestTosValue (queueDisc, 0x1a, 1); // MMC+MT+MD -> Int. Bulk (4) -> 1
|
||||
TestTosValue (queueDisc, 0x1c, 1); // MR+MT+MD -> Int. Bulk (4) -> 1
|
||||
TestTosValue (queueDisc, 0x1e, 1); // MMC+MR+MT+MD -> Int. Bulk (4) -> 1
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,7 +117,6 @@ public:
|
||||
|
||||
private:
|
||||
virtual void DoRun (void);
|
||||
Ptr<Packet> CreatePacketWithDscp (Ipv4Header::DscpType dscp);
|
||||
void TestDscpValue (Ptr<PfifoFastQueueDisc> queue, Ipv4Header::DscpType dscp, uint32_t band);
|
||||
};
|
||||
|
||||
@@ -141,24 +129,17 @@ PfifoFastQueueDiscDscpPrioritization::~PfifoFastQueueDiscDscpPrioritization ()
|
||||
{
|
||||
}
|
||||
|
||||
Ptr<Packet>
|
||||
PfifoFastQueueDiscDscpPrioritization::CreatePacketWithDscp (Ipv4Header::DscpType dscp)
|
||||
void
|
||||
PfifoFastQueueDiscDscpPrioritization::TestDscpValue (Ptr<PfifoFastQueueDisc> queue, Ipv4Header::DscpType dscp, uint32_t band)
|
||||
{
|
||||
Ptr<Packet> p = Create<Packet> (100);
|
||||
Ipv4Header ipHeader;
|
||||
ipHeader.SetPayloadSize (100);
|
||||
ipHeader.SetProtocol (6);
|
||||
ipHeader.SetDscp (dscp);
|
||||
p->AddHeader (ipHeader);
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
PfifoFastQueueDiscDscpPrioritization::TestDscpValue (Ptr<PfifoFastQueueDisc> queue, Ipv4Header::DscpType dscp, uint32_t band)
|
||||
{
|
||||
Ptr<Packet> p = CreatePacketWithDscp (dscp);
|
||||
Ipv4Header ipHeader;
|
||||
p->RemoveHeader (ipHeader);
|
||||
SocketPriorityTag priorityTag;
|
||||
priorityTag.SetPriority (Socket::IpTos2Priority (ipHeader.GetTos ()));
|
||||
p->AddPacketTag (priorityTag);
|
||||
Address dest;
|
||||
Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, ipHeader);
|
||||
queue->Enqueue (item);
|
||||
@@ -171,10 +152,6 @@ void
|
||||
PfifoFastQueueDiscDscpPrioritization::DoRun (void)
|
||||
{
|
||||
Ptr<PfifoFastQueueDisc> queueDisc = CreateObject<PfifoFastQueueDisc> ();
|
||||
Ptr<PfifoFastIpv4PacketFilter> filter = CreateObject<PfifoFastIpv4PacketFilter> ();
|
||||
bool ok = filter->SetAttributeFailSafe ("Mode", EnumValue (PfifoFastIpv4PacketFilter::PF_MODE_DSCP));
|
||||
NS_TEST_ASSERT_MSG_EQ (ok, true, "unable to set attribute");
|
||||
queueDisc->AddPacketFilter (filter);
|
||||
for (uint16_t i = 0; i < 3; i++)
|
||||
{
|
||||
Ptr<DropTailQueue> queue = CreateObject<DropTailQueue> ();
|
||||
@@ -186,27 +163,28 @@ PfifoFastQueueDiscDscpPrioritization::DoRun (void)
|
||||
NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (1)->GetNPackets (), 0, "initialized non-zero");
|
||||
NS_TEST_ASSERT_MSG_EQ (queueDisc->GetInternalQueue (2)->GetNPackets (), 0, "initialized non-zero");
|
||||
|
||||
TestDscpValue (queueDisc, Ipv4Header::DscpDefault, 1);
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_EF, 1);
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_AF11, 2);
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_AF21, 2);
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_AF31, 2);
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_AF41, 2);
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_AF12, 0);
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_AF22, 0);
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_AF32, 0);
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_AF42, 0);
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_AF13, 1);
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_AF23, 1);
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_AF33, 1);
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_AF43, 1);
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_CS1, 2);
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_CS2, 1);
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_CS3, 1);
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_CS4, 0);
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_CS5, 0);
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_CS6, 0);
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_CS7, 0);
|
||||
// priority band
|
||||
TestDscpValue (queueDisc, Ipv4Header::DscpDefault, 1); // Best Effort (0) -> 1
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_EF, 1); // Int. Bulk (4) -> 1
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_AF11, 2); // Bulk (2) -> 2
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_AF21, 2); // Bulk (2) -> 2
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_AF31, 2); // Bulk (2) -> 2
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_AF41, 2); // Bulk (2) -> 2
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_AF12, 0); // Interactive (6) -> 0
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_AF22, 0); // Interactive (6) -> 0
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_AF32, 0); // Interactive (6) -> 0
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_AF42, 0); // Interactive (6) -> 0
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_AF13, 1); // Int. Bulk (4) -> 1
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_AF23, 1); // Int. Bulk (4) -> 1
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_AF33, 1); // Int. Bulk (4) -> 1
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_AF43, 1); // Int. Bulk (4) -> 1
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_CS1, 1); // Best Effort (0) -> 1
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_CS2, 1); // Best Effort (0) -> 1
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_CS3, 1); // Best Effort (0) -> 1
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_CS4, 1); // Best Effort (0) -> 1
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_CS5, 1); // Best Effort (0) -> 1
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_CS6, 1); // Best Effort (0) -> 1
|
||||
TestDscpValue (queueDisc, Ipv4Header::DSCP_CS7, 1); // Best Effort (0) -> 1
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -240,6 +218,9 @@ PfifoFastQueueDiscOverflow::AddPacket (Ptr<PfifoFastQueueDisc> queue, Ipv4Header
|
||||
ipHeader.SetPayloadSize (100);
|
||||
ipHeader.SetProtocol (6);
|
||||
ipHeader.SetDscp (dscp);
|
||||
SocketPriorityTag priorityTag;
|
||||
priorityTag.SetPriority (Socket::IpTos2Priority (ipHeader.GetTos ()));
|
||||
p->AddPacketTag (priorityTag);
|
||||
Address dest;
|
||||
Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, ipHeader);
|
||||
queue->Enqueue (item);
|
||||
@@ -255,10 +236,6 @@ PfifoFastQueueDiscOverflow::DoRun (void)
|
||||
queueDisc->AddInternalQueue (band0);
|
||||
queueDisc->AddInternalQueue (band1);
|
||||
queueDisc->AddInternalQueue (band2);
|
||||
Ptr<PfifoFastIpv4PacketFilter> filter = CreateObject<PfifoFastIpv4PacketFilter> ();
|
||||
bool ok = filter->SetAttributeFailSafe ("Mode", EnumValue (PfifoFastIpv4PacketFilter::PF_MODE_DSCP));
|
||||
NS_TEST_ASSERT_MSG_EQ (ok, true, "unable to set attribute");
|
||||
queueDisc->AddPacketFilter (filter);
|
||||
|
||||
// Add two packets per each band
|
||||
AddPacket (queueDisc, Ipv4Header::DSCP_AF42); // 0
|
||||
@@ -283,35 +260,33 @@ PfifoFastQueueDiscOverflow::DoRun (void)
|
||||
}
|
||||
|
||||
/**
|
||||
* This class tests that non-IP packets are handled by placing them into
|
||||
* band 1
|
||||
* This class tests that packets without a priority tag are handled by placing
|
||||
* them into band 1
|
||||
*/
|
||||
class PfifoFastQueueDiscNonIpHeader : public TestCase
|
||||
class PfifoFastQueueDiscNoPriority : public TestCase
|
||||
{
|
||||
public:
|
||||
PfifoFastQueueDiscNonIpHeader ();
|
||||
virtual ~PfifoFastQueueDiscNonIpHeader ();
|
||||
PfifoFastQueueDiscNoPriority ();
|
||||
virtual ~PfifoFastQueueDiscNoPriority ();
|
||||
|
||||
private:
|
||||
virtual void DoRun (void);
|
||||
};
|
||||
|
||||
PfifoFastQueueDiscNonIpHeader::PfifoFastQueueDiscNonIpHeader ()
|
||||
: TestCase ("Test queue with non IP header")
|
||||
PfifoFastQueueDiscNoPriority::PfifoFastQueueDiscNoPriority ()
|
||||
: TestCase ("Test queue with no priority tag")
|
||||
{
|
||||
}
|
||||
|
||||
PfifoFastQueueDiscNonIpHeader::~PfifoFastQueueDiscNonIpHeader ()
|
||||
PfifoFastQueueDiscNoPriority::~PfifoFastQueueDiscNoPriority ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
PfifoFastQueueDiscNonIpHeader::DoRun (void)
|
||||
PfifoFastQueueDiscNoPriority::DoRun (void)
|
||||
{
|
||||
// all packets with non-IP headers should enqueue in band 1
|
||||
Ptr<PfifoFastQueueDisc> queueDisc = CreateObject<PfifoFastQueueDisc> ();
|
||||
Ptr<PfifoFastIpv4PacketFilter> filter = CreateObject<PfifoFastIpv4PacketFilter> ();
|
||||
queueDisc->AddPacketFilter (filter);
|
||||
for (uint16_t i = 0; i < 3; i++)
|
||||
{
|
||||
Ptr<DropTailQueue> queue = CreateObject<DropTailQueue> ();
|
||||
@@ -358,7 +333,7 @@ PfifoFastQueueDiscTestSuite::PfifoFastQueueDiscTestSuite ()
|
||||
AddTestCase (new PfifoFastQueueDiscTosPrioritization, TestCase::QUICK);
|
||||
AddTestCase (new PfifoFastQueueDiscDscpPrioritization, TestCase::QUICK);
|
||||
AddTestCase (new PfifoFastQueueDiscOverflow, TestCase::QUICK);
|
||||
AddTestCase (new PfifoFastQueueDiscNonIpHeader, TestCase::QUICK);
|
||||
AddTestCase (new PfifoFastQueueDiscNoPriority, TestCase::QUICK);
|
||||
}
|
||||
|
||||
static PfifoFastQueueDiscTestSuite pfifoFastQueueTestSuite;
|
||||
|
||||
@@ -189,6 +189,8 @@ variants has the same effect. Note that, if some subsequent code tries
|
||||
to read the Packet data buffer, the fake buffer will be converted to
|
||||
a real (zeroed) buffer on the spot, and the efficiency will be lost there.
|
||||
|
||||
.. _Socket-options:
|
||||
|
||||
Socket options
|
||||
**************
|
||||
|
||||
|
||||
@@ -338,7 +338,6 @@ AdaptiveRedQueueDiscTestCase::RunAdaptiveRedDiscTest (StringValue mode)
|
||||
TrafficControlHelper tchPfifo;
|
||||
uint16_t handle = tchPfifo.SetRootQueueDisc ("ns3::PfifoFastQueueDisc");
|
||||
tchPfifo.AddInternalQueues (handle, 3, "ns3::DropTailQueue", "MaxPackets", UintegerValue (1000));
|
||||
tchPfifo.AddPacketFilter (handle, "ns3::PfifoFastIpv4PacketFilter");
|
||||
|
||||
TrafficControlHelper tchRed;
|
||||
tchRed.SetRootQueueDisc ("ns3::RedQueueDisc", "LinkBandwidth", StringValue (aredLinkDataRate),
|
||||
|
||||
@@ -8,9 +8,32 @@ Model Description
|
||||
*****************
|
||||
|
||||
Linux pfifo_fast is the default priority queue enabled on Linux
|
||||
systems. Packets are enqueued in three FIFO droptail queues according
|
||||
to three priority bands based on the classification returned by
|
||||
the configured packet filters.
|
||||
systems. Packets are enqueued in three priority bands (implemented
|
||||
as FIFO droptail queues) based on their priority (users can read
|
||||
:ref:`Socket-options` for details on how to set packet priority).
|
||||
The four least significant bits of the priority are used to determine
|
||||
the selected band according to the following table:
|
||||
|
||||
============== ======
|
||||
Priority & 0xf Band
|
||||
============== ======
|
||||
0 1
|
||||
1 2
|
||||
2 2
|
||||
3 2
|
||||
4 1
|
||||
5 2
|
||||
6 0
|
||||
7 0
|
||||
8 1
|
||||
9 1
|
||||
10 1
|
||||
11 1
|
||||
12 1
|
||||
13 1
|
||||
14 1
|
||||
15 1
|
||||
============== ======
|
||||
|
||||
The system behaves similar to three ns3::DropTail queues operating
|
||||
together, in which packets from higher priority bands are always
|
||||
@@ -22,15 +45,7 @@ plays the same role as txqueuelen in Linux. If no internal queue is
|
||||
provided, three DropTail queues having each a capacity equal to limit are
|
||||
created by default. User is allowed to provide queues, but they must be
|
||||
three, operate in packet mode and each have a capacity not less
|
||||
than limit.
|
||||
|
||||
It is necessary to provide at least one packet filter. To simulate the
|
||||
Linux behavior, the PfifoFastIpv4PacketFilter and/or the PfifoFastIpv6PacketFilter
|
||||
shall be provided. These filters classify packets based on their Type of
|
||||
Service bits or DSCP bits. If the filters are unable to classify a packet,
|
||||
i.e., they return -1 (PF_NO_MATCH), that packet is enqueued into band 1
|
||||
(normal service).
|
||||
|
||||
than limit. No packet filter can be added to a PfifoFastQueueDisc.
|
||||
|
||||
|
||||
Attributes
|
||||
|
||||
@@ -311,7 +311,6 @@ main (int argc, char *argv[])
|
||||
TrafficControlHelper tchPfifo;
|
||||
uint16_t handle = tchPfifo.SetRootQueueDisc ("ns3::PfifoFastQueueDisc");
|
||||
tchPfifo.AddInternalQueues (handle, 3, "ns3::DropTailQueue", "MaxPackets", UintegerValue (1000));
|
||||
tchPfifo.AddPacketFilter (handle, "ns3::PfifoFastIpv4PacketFilter");
|
||||
|
||||
TrafficControlHelper tchRed;
|
||||
tchRed.SetRootQueueDisc ("ns3::RedQueueDisc", "LinkBandwidth", StringValue (aredLinkDataRate),
|
||||
|
||||
@@ -343,8 +343,7 @@ int main (int argc, char *argv[])
|
||||
stack.InstallAll ();
|
||||
|
||||
TrafficControlHelper tchPfifo;
|
||||
uint32_t handle = tchPfifo.SetRootQueueDisc ("ns3::PfifoFastQueueDisc");
|
||||
tchPfifo.AddPacketFilter (handle, "ns3::PfifoFastIpv4PacketFilter");
|
||||
tchPfifo.SetRootQueueDisc ("ns3::PfifoFastQueueDisc");
|
||||
|
||||
TrafficControlHelper tchCoDel;
|
||||
tchCoDel.SetRootQueueDisc ("ns3::CoDelQueueDisc");
|
||||
|
||||
@@ -150,8 +150,7 @@ int main (int argc, char *argv[])
|
||||
stack.InstallAll ();
|
||||
|
||||
TrafficControlHelper tchPfifo;
|
||||
uint32_t handle = tchPfifo.SetRootQueueDisc ("ns3::PfifoFastQueueDisc");
|
||||
tchPfifo.AddPacketFilter (handle, "ns3::PfifoFastIpv4PacketFilter");
|
||||
tchPfifo.SetRootQueueDisc ("ns3::PfifoFastQueueDisc");
|
||||
|
||||
TrafficControlHelper tchCoDel;
|
||||
tchCoDel.SetRootQueueDisc ("ns3::CoDelQueueDisc");
|
||||
|
||||
@@ -347,7 +347,6 @@ main (int argc, char *argv[])
|
||||
TrafficControlHelper tchPfifo;
|
||||
uint16_t handle = tchPfifo.SetRootQueueDisc ("ns3::PfifoFastQueueDisc");
|
||||
tchPfifo.AddInternalQueues (handle, 3, "ns3::DropTailQueue", "MaxPackets", UintegerValue (1000));
|
||||
tchPfifo.AddPacketFilter (handle, "ns3::PfifoFastIpv4PacketFilter");
|
||||
|
||||
TrafficControlHelper tchRed;
|
||||
tchRed.SetRootQueueDisc ("ns3::RedQueueDisc", "LinkBandwidth", StringValue (redLinkDataRate),
|
||||
|
||||
@@ -111,8 +111,6 @@ TrafficControlHelper::Default (void)
|
||||
TrafficControlHelper helper;
|
||||
uint16_t handle = helper.SetRootQueueDisc ("ns3::PfifoFastQueueDisc");
|
||||
helper.AddInternalQueues (handle, 3, "ns3::DropTailQueue", "MaxPackets", UintegerValue (1000));
|
||||
helper.AddPacketFilter (handle, "ns3::PfifoFastIpv4PacketFilter");
|
||||
helper.AddPacketFilter (handle, "ns3::PfifoFastIpv6PacketFilter");
|
||||
return helper;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "ns3/pointer.h"
|
||||
#include "ns3/object-factory.h"
|
||||
#include "ns3/drop-tail-queue.h"
|
||||
#include "ns3/socket.h"
|
||||
#include "pfifo-fast-queue-disc.h"
|
||||
|
||||
namespace ns3 {
|
||||
@@ -57,6 +58,8 @@ PfifoFastQueueDisc::~PfifoFastQueueDisc ()
|
||||
NS_LOG_FUNCTION (this);
|
||||
}
|
||||
|
||||
constexpr int PfifoFastQueueDisc::prio2band[];
|
||||
|
||||
bool
|
||||
PfifoFastQueueDisc::DoEnqueue (Ptr<QueueDiscItem> item)
|
||||
{
|
||||
@@ -69,23 +72,14 @@ PfifoFastQueueDisc::DoEnqueue (Ptr<QueueDiscItem> item)
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t band;
|
||||
int32_t ret = Classify (item);
|
||||
uint8_t priority = 0;
|
||||
SocketPriorityTag priorityTag;
|
||||
if (item->GetPacket ()->PeekPacketTag (priorityTag))
|
||||
{
|
||||
priority = priorityTag.GetPriority ();
|
||||
}
|
||||
|
||||
if (ret == PacketFilter::PF_NO_MATCH)
|
||||
{
|
||||
band = 1;
|
||||
NS_LOG_DEBUG ("The filter was unable to classify; using default band of " << band);
|
||||
}
|
||||
else if (ret < 0 || ret > 2)
|
||||
{
|
||||
band = 1;
|
||||
NS_LOG_DEBUG ("The filter returned an invalid value; using default band of " << band);
|
||||
}
|
||||
else
|
||||
{
|
||||
band = ret;
|
||||
}
|
||||
uint32_t band = prio2band[priority & 0x0f];
|
||||
|
||||
bool retval = GetInternalQueue(band)->Enqueue (item);
|
||||
|
||||
@@ -147,9 +141,9 @@ PfifoFastQueueDisc::CheckConfig (void)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GetNPacketFilters () == 0)
|
||||
if (GetNPacketFilters () != 0)
|
||||
{
|
||||
NS_LOG_ERROR ("PfifoFastQueueDisc needs at least a packet filter");
|
||||
NS_LOG_ERROR ("PfifoFastQueueDisc needs no packet filter");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,8 +32,7 @@ namespace ns3 {
|
||||
*
|
||||
* Linux pfifo_fast is the default priority queue enabled on Linux
|
||||
* systems. Packets are enqueued in three FIFO droptail queues according
|
||||
* to three priority bands based on the classification returned by
|
||||
* the configured packet filters.
|
||||
* to three priority bands based on the packet priority.
|
||||
*
|
||||
* The system behaves similar to three ns3::DropTail queues operating
|
||||
* together, in which packets from higher priority bands are always
|
||||
@@ -45,14 +44,7 @@ namespace ns3 {
|
||||
* provided, three DropTail queues having each a capacity equal to limit are
|
||||
* created by default. User is allowed to provide queues, but they must be
|
||||
* three, operate in packet mode and each have a capacity not less
|
||||
* than limit.
|
||||
*
|
||||
* It is necessary to provide at least one packet filter. To simulate the
|
||||
* Linux behavior, the PfifoFastIpv4PacketFilter and/or the PfifoFastIpv6PacketFilter
|
||||
* shall be provided. These filters classify packets based on their Type of
|
||||
* Service bits or DSCP bits. If the filters are unable to classify a packet,
|
||||
* i.e., they return -1 (PF_NO_MATCH), that packet is enqueued into band 1
|
||||
* (normal service).
|
||||
* than limit. No packet filter can be provided.
|
||||
*/
|
||||
class PfifoFastQueueDisc : public QueueDisc {
|
||||
public:
|
||||
@@ -70,6 +62,11 @@ public:
|
||||
|
||||
virtual ~PfifoFastQueueDisc();
|
||||
|
||||
/*
|
||||
* Priority to band map
|
||||
*/
|
||||
static constexpr int prio2band[] = {1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1};
|
||||
|
||||
private:
|
||||
virtual bool DoEnqueue (Ptr<QueueDiscItem> item);
|
||||
virtual Ptr<QueueDiscItem> DoDequeue (void);
|
||||
|
||||
Reference in New Issue
Block a user