From 1ec310b39e2d2b0372e43785d52efbe8d19b0b0d Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Thu, 14 Jul 2016 15:59:56 +0200 Subject: [PATCH] traffic-control: PfifoFastQueueDisc uses priority to map packets to bands --- examples/tcp/tcp-variants-comparison.cc | 3 +- src/internet/model/ipv4-packet-filter.cc | 132 --------------- src/internet/model/ipv4-packet-filter.h | 118 -------------- src/internet/model/ipv6-packet-filter.cc | 82 ---------- src/internet/model/ipv6-packet-filter.h | 60 ------- .../test/pfifo-fast-queue-disc-test-suite.cc | 151 ++++++++---------- src/network/doc/sockets-api.rst | 2 + .../adaptive-red-queue-disc-test-suite.cc | 1 - src/traffic-control/doc/pfifo-fast.rst | 39 +++-- .../examples/adaptive-red-tests.cc | 1 - .../examples/codel-vs-pfifo-asymmetric.cc | 3 +- .../examples/codel-vs-pfifo-basic-test.cc | 3 +- src/traffic-control/examples/red-tests.cc | 1 - .../helper/traffic-control-helper.cc | 2 - .../model/pfifo-fast-queue-disc.cc | 30 ++-- .../model/pfifo-fast-queue-disc.h | 17 +- 16 files changed, 114 insertions(+), 531 deletions(-) diff --git a/examples/tcp/tcp-variants-comparison.cc b/examples/tcp/tcp-variants-comparison.cc index 1b0616699..e0703f9f6 100644 --- a/examples/tcp/tcp-variants-comparison.cc +++ b/examples/tcp/tcp-variants-comparison.cc @@ -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"); diff --git a/src/internet/model/ipv4-packet-filter.cc b/src/internet/model/ipv4-packet-filter.cc index e96699247..d7db41f7d 100644 --- a/src/internet/model/ipv4-packet-filter.cc +++ b/src/internet/model/ipv4-packet-filter.cc @@ -58,136 +58,4 @@ Ipv4PacketFilter::CheckProtocol (Ptr item) const return (DynamicCast (item) != 0); } -// ------------------------------------------------------------------------- // - -NS_OBJECT_ENSURE_REGISTERED (PfifoFastIpv4PacketFilter); - -TypeId -PfifoFastIpv4PacketFilter::GetTypeId (void) -{ - static TypeId tid = TypeId ("ns3::PfifoFastIpv4PacketFilter") - .SetParent () - .SetGroupName ("Internet") - .AddConstructor () - .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 item) const -{ - NS_LOG_FUNCTION (this << item); - uint32_t band; - Ptr ipv4Item = DynamicCast (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 diff --git a/src/internet/model/ipv4-packet-filter.h b/src/internet/model/ipv4-packet-filter.h index c8eb648bc..c0308f959 100644 --- a/src/internet/model/ipv4-packet-filter.h +++ b/src/internet/model/ipv4-packet-filter.h @@ -50,124 +50,6 @@ private: virtual int32_t DoClassify (Ptr 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 - * 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 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 */ diff --git a/src/internet/model/ipv6-packet-filter.cc b/src/internet/model/ipv6-packet-filter.cc index 8b2ffc111..c7c54976f 100644 --- a/src/internet/model/ipv6-packet-filter.cc +++ b/src/internet/model/ipv6-packet-filter.cc @@ -58,86 +58,4 @@ Ipv6PacketFilter::CheckProtocol (Ptr item) const return (DynamicCast (item) != 0); } -// ------------------------------------------------------------------------- // - -NS_OBJECT_ENSURE_REGISTERED (PfifoFastIpv6PacketFilter); - -TypeId -PfifoFastIpv6PacketFilter::GetTypeId (void) -{ - static TypeId tid = TypeId ("ns3::PfifoFastIpv6PacketFilter") - .SetParent () - .SetGroupName ("Internet") - .AddConstructor () - ; - return tid; -} - -PfifoFastIpv6PacketFilter::PfifoFastIpv6PacketFilter () -{ - NS_LOG_FUNCTION (this); -} - -PfifoFastIpv6PacketFilter::~PfifoFastIpv6PacketFilter() -{ - NS_LOG_FUNCTION (this); -} - -int32_t -PfifoFastIpv6PacketFilter::DoClassify (Ptr item) const -{ - NS_LOG_FUNCTION (this << item); - uint32_t band; - Ptr ipv6Item = DynamicCast (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 diff --git a/src/internet/model/ipv6-packet-filter.h b/src/internet/model/ipv6-packet-filter.h index 99e52e39e..d79c974e2 100644 --- a/src/internet/model/ipv6-packet-filter.h +++ b/src/internet/model/ipv6-packet-filter.h @@ -50,66 +50,6 @@ private: virtual int32_t DoClassify (Ptr 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 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 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 */ diff --git a/src/internet/test/pfifo-fast-queue-disc-test-suite.cc b/src/internet/test/pfifo-fast-queue-disc-test-suite.cc index bcdc8d919..2292fcd61 100644 --- a/src/internet/test/pfifo-fast-queue-disc-test-suite.cc +++ b/src/internet/test/pfifo-fast-queue-disc-test-suite.cc @@ -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 CreatePacketWithTos (uint8_t tos); void TestTosValue (Ptr queue, uint8_t tos, uint32_t band); }; @@ -54,24 +53,17 @@ PfifoFastQueueDiscTosPrioritization::~PfifoFastQueueDiscTosPrioritization () { } -Ptr -PfifoFastQueueDiscTosPrioritization::CreatePacketWithTos (uint8_t tos) +void +PfifoFastQueueDiscTosPrioritization::TestTosValue (Ptr queue, uint8_t tos, uint32_t band) { Ptr p = Create (100); Ipv4Header ipHeader; ipHeader.SetPayloadSize (100); ipHeader.SetTos (tos); ipHeader.SetProtocol (6); - p->AddHeader (ipHeader); - return p; -} - -void -PfifoFastQueueDiscTosPrioritization::TestTosValue (Ptr queue, uint8_t tos, uint32_t band) -{ - Ptr p = CreatePacketWithTos (tos); - Ipv4Header ipHeader; - p->RemoveHeader (ipHeader); + SocketPriorityTag priorityTag; + priorityTag.SetPriority (Socket::IpTos2Priority (tos)); + p->AddPacketTag (priorityTag); Address dest; Ptr item = Create (p, dest, 0, ipHeader); queue->Enqueue (item); @@ -84,10 +76,6 @@ void PfifoFastQueueDiscTosPrioritization::DoRun (void) { Ptr queueDisc = CreateObject (); - Ptr filter = CreateObject (); - 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 queue = CreateObject (); @@ -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 CreatePacketWithDscp (Ipv4Header::DscpType dscp); void TestDscpValue (Ptr queue, Ipv4Header::DscpType dscp, uint32_t band); }; @@ -141,24 +129,17 @@ PfifoFastQueueDiscDscpPrioritization::~PfifoFastQueueDiscDscpPrioritization () { } -Ptr -PfifoFastQueueDiscDscpPrioritization::CreatePacketWithDscp (Ipv4Header::DscpType dscp) +void +PfifoFastQueueDiscDscpPrioritization::TestDscpValue (Ptr queue, Ipv4Header::DscpType dscp, uint32_t band) { Ptr p = Create (100); Ipv4Header ipHeader; ipHeader.SetPayloadSize (100); ipHeader.SetProtocol (6); ipHeader.SetDscp (dscp); - p->AddHeader (ipHeader); - return p; -} - -void -PfifoFastQueueDiscDscpPrioritization::TestDscpValue (Ptr queue, Ipv4Header::DscpType dscp, uint32_t band) -{ - Ptr p = CreatePacketWithDscp (dscp); - Ipv4Header ipHeader; - p->RemoveHeader (ipHeader); + SocketPriorityTag priorityTag; + priorityTag.SetPriority (Socket::IpTos2Priority (ipHeader.GetTos ())); + p->AddPacketTag (priorityTag); Address dest; Ptr item = Create (p, dest, 0, ipHeader); queue->Enqueue (item); @@ -171,10 +152,6 @@ void PfifoFastQueueDiscDscpPrioritization::DoRun (void) { Ptr queueDisc = CreateObject (); - Ptr filter = CreateObject (); - 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 queue = CreateObject (); @@ -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 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 item = Create (p, dest, 0, ipHeader); queue->Enqueue (item); @@ -255,10 +236,6 @@ PfifoFastQueueDiscOverflow::DoRun (void) queueDisc->AddInternalQueue (band0); queueDisc->AddInternalQueue (band1); queueDisc->AddInternalQueue (band2); - Ptr filter = CreateObject (); - 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 queueDisc = CreateObject (); - Ptr filter = CreateObject (); - queueDisc->AddPacketFilter (filter); for (uint16_t i = 0; i < 3; i++) { Ptr queue = CreateObject (); @@ -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; diff --git a/src/network/doc/sockets-api.rst b/src/network/doc/sockets-api.rst index 6abe41337..5f2b9bd98 100644 --- a/src/network/doc/sockets-api.rst +++ b/src/network/doc/sockets-api.rst @@ -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 ************** diff --git a/src/test/adaptive-red-queue-disc-test-suite.cc b/src/test/adaptive-red-queue-disc-test-suite.cc index a7034131c..8a350f286 100644 --- a/src/test/adaptive-red-queue-disc-test-suite.cc +++ b/src/test/adaptive-red-queue-disc-test-suite.cc @@ -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), diff --git a/src/traffic-control/doc/pfifo-fast.rst b/src/traffic-control/doc/pfifo-fast.rst index b8b8ffb7b..bbffdf87f 100644 --- a/src/traffic-control/doc/pfifo-fast.rst +++ b/src/traffic-control/doc/pfifo-fast.rst @@ -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 diff --git a/src/traffic-control/examples/adaptive-red-tests.cc b/src/traffic-control/examples/adaptive-red-tests.cc index 9a01e6497..bf6aadcb8 100644 --- a/src/traffic-control/examples/adaptive-red-tests.cc +++ b/src/traffic-control/examples/adaptive-red-tests.cc @@ -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), diff --git a/src/traffic-control/examples/codel-vs-pfifo-asymmetric.cc b/src/traffic-control/examples/codel-vs-pfifo-asymmetric.cc index 18d040843..717b44ad0 100644 --- a/src/traffic-control/examples/codel-vs-pfifo-asymmetric.cc +++ b/src/traffic-control/examples/codel-vs-pfifo-asymmetric.cc @@ -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"); diff --git a/src/traffic-control/examples/codel-vs-pfifo-basic-test.cc b/src/traffic-control/examples/codel-vs-pfifo-basic-test.cc index 9d0192d7f..9ab2f00a4 100644 --- a/src/traffic-control/examples/codel-vs-pfifo-basic-test.cc +++ b/src/traffic-control/examples/codel-vs-pfifo-basic-test.cc @@ -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"); diff --git a/src/traffic-control/examples/red-tests.cc b/src/traffic-control/examples/red-tests.cc index 10a457984..ecf1e15e8 100644 --- a/src/traffic-control/examples/red-tests.cc +++ b/src/traffic-control/examples/red-tests.cc @@ -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), diff --git a/src/traffic-control/helper/traffic-control-helper.cc b/src/traffic-control/helper/traffic-control-helper.cc index a1b8ce0b8..45df710dc 100644 --- a/src/traffic-control/helper/traffic-control-helper.cc +++ b/src/traffic-control/helper/traffic-control-helper.cc @@ -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; } diff --git a/src/traffic-control/model/pfifo-fast-queue-disc.cc b/src/traffic-control/model/pfifo-fast-queue-disc.cc index 12ea4eb99..67b0d8e53 100644 --- a/src/traffic-control/model/pfifo-fast-queue-disc.cc +++ b/src/traffic-control/model/pfifo-fast-queue-disc.cc @@ -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 item) { @@ -69,23 +72,14 @@ PfifoFastQueueDisc::DoEnqueue (Ptr 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; } diff --git a/src/traffic-control/model/pfifo-fast-queue-disc.h b/src/traffic-control/model/pfifo-fast-queue-disc.h index c5350ca97..4f9098475 100644 --- a/src/traffic-control/model/pfifo-fast-queue-disc.h +++ b/src/traffic-control/model/pfifo-fast-queue-disc.h @@ -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 item); virtual Ptr DoDequeue (void);