A Discrete-Event Network Simulator
API
prio-queue-disc.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2017 Universita' degli Studi di Napoli Federico II
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Authors: Stefano Avallone <stavallo@unina.it>
19  */
20 
21 #include "ns3/log.h"
22 #include "ns3/pointer.h"
23 #include "ns3/object-factory.h"
24 #include "ns3/socket.h"
25 #include "prio-queue-disc.h"
26 #include <algorithm>
27 #include <iterator>
28 
29 namespace ns3 {
30 
31 NS_LOG_COMPONENT_DEFINE ("PrioQueueDisc");
32 
33 NS_OBJECT_ENSURE_REGISTERED (PrioQueueDisc);
34 
36 
37 std::ostream &
38 operator << (std::ostream &os, const Priomap &priomap)
39 {
40  std::copy (priomap.begin (), priomap.end ()-1, std::ostream_iterator<uint16_t>(os, " "));
41  os << priomap.back ();
42  return os;
43 }
44 
45 std::istream &operator >> (std::istream &is, Priomap &priomap)
46 {
47  for (int i = 0; i < 16; i++)
48  {
49  if (!(is >> priomap[i]))
50  {
51  NS_FATAL_ERROR ("Incomplete priomap specification (" << i << " values provided, 16 required)");
52  }
53  }
54  return is;
55 }
56 
58 {
59  static TypeId tid = TypeId ("ns3::PrioQueueDisc")
60  .SetParent<QueueDisc> ()
61  .SetGroupName ("TrafficControl")
62  .AddConstructor<PrioQueueDisc> ()
63  .AddAttribute ("Priomap", "The priority to band mapping.",
64  PriomapValue (Priomap{{1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}}),
67  ;
68  return tid;
69 }
70 
73 {
74  NS_LOG_FUNCTION (this);
75 }
76 
78 {
79  NS_LOG_FUNCTION (this);
80 }
81 
82 void
83 PrioQueueDisc::SetBandForPriority (uint8_t prio, uint16_t band)
84 {
85  NS_LOG_FUNCTION (this << prio << band);
86 
87  NS_ASSERT_MSG (prio < 16, "Priority must be a value between 0 and 15");
88 
89  m_prio2band[prio] = band;
90 }
91 
92 uint16_t
94 {
95  NS_LOG_FUNCTION (this << prio);
96 
97  NS_ASSERT_MSG (prio < 16, "Priority must be a value between 0 and 15");
98 
99  return m_prio2band[prio];
100 }
101 
102 bool
104 {
105  NS_LOG_FUNCTION (this << item);
106 
107  uint32_t band = m_prio2band[0];
108 
109  int32_t ret = Classify (item);
110 
111  if (ret == PacketFilter::PF_NO_MATCH)
112  {
113  NS_LOG_DEBUG ("No filter has been able to classify this packet, using priomap.");
114 
115  SocketPriorityTag priorityTag;
116  if (item->GetPacket ()->PeekPacketTag (priorityTag))
117  {
118  band = m_prio2band[priorityTag.GetPriority () & 0x0f];
119  }
120  }
121  else
122  {
123  NS_LOG_DEBUG ("Packet filters returned " << ret);
124 
125  if (ret >= 0 && static_cast<uint32_t>(ret) < GetNQueueDiscClasses ())
126  {
127  band = ret;
128  }
129  }
130 
131  NS_ASSERT_MSG (band < GetNQueueDiscClasses (), "Selected band out of range");
132  bool retval = GetQueueDiscClass (band)->GetQueueDisc ()->Enqueue (item);
133 
134  // If Queue::Enqueue fails, QueueDisc::Drop is called by the child queue disc
135  // because QueueDisc::AddQueueDiscClass sets the drop callback
136 
137  NS_LOG_LOGIC ("Number packets band " << band << ": " << GetQueueDiscClass (band)->GetQueueDisc ()->GetNPackets ());
138 
139  return retval;
140 }
141 
144 {
145  NS_LOG_FUNCTION (this);
146 
147  Ptr<QueueDiscItem> item;
148 
149  for (uint32_t i = 0; i < GetNQueueDiscClasses (); i++)
150  {
151  if ((item = GetQueueDiscClass (i)->GetQueueDisc ()->Dequeue ()) != 0)
152  {
153  NS_LOG_LOGIC ("Popped from band " << i << ": " << item);
154  NS_LOG_LOGIC ("Number packets band " << i << ": " << GetQueueDiscClass (i)->GetQueueDisc ()->GetNPackets ());
155  return item;
156  }
157  }
158 
159  NS_LOG_LOGIC ("Queue empty");
160  return item;
161 }
162 
165 {
166  NS_LOG_FUNCTION (this);
167 
169 
170  for (uint32_t i = 0; i < GetNQueueDiscClasses (); i++)
171  {
172  if ((item = GetQueueDiscClass (i)->GetQueueDisc ()->Peek ()) != 0)
173  {
174  NS_LOG_LOGIC ("Peeked from band " << i << ": " << item);
175  NS_LOG_LOGIC ("Number packets band " << i << ": " << GetQueueDiscClass (i)->GetQueueDisc ()->GetNPackets ());
176  return item;
177  }
178  }
179 
180  NS_LOG_LOGIC ("Queue empty");
181  return item;
182 }
183 
184 bool
186 {
187  NS_LOG_FUNCTION (this);
188  if (GetNInternalQueues () > 0)
189  {
190  NS_LOG_ERROR ("PrioQueueDisc cannot have internal queues");
191  return false;
192  }
193 
194  if (GetNQueueDiscClasses () == 0)
195  {
196  // create 3 fifo queue discs
197  ObjectFactory factory;
198  factory.SetTypeId ("ns3::FifoQueueDisc");
199  for (uint8_t i = 0; i < 2; i++)
200  {
201  Ptr<QueueDisc> qd = factory.Create<QueueDisc> ();
202  qd->Initialize ();
203  Ptr<QueueDiscClass> c = CreateObject<QueueDiscClass> ();
204  c->SetQueueDisc (qd);
205  AddQueueDiscClass (c);
206  }
207  }
208 
209  if (GetNQueueDiscClasses () < 2)
210  {
211  NS_LOG_ERROR ("PrioQueueDisc needs at least 2 classes");
212  return false;
213  }
214 
215  return true;
216 }
217 
218 void
220 {
221  NS_LOG_FUNCTION (this);
222 }
223 
224 } // namespace ns3
Ptr< const QueueDiscItem > Peek(void)
Get a copy of the next packet the queue discipline will extract.
Definition: queue-disc.cc:913
std::istream & operator>>(std::istream &is, Angles &a)
initialize a struct Angles from input
Definition: angles.cc:48
static TypeId GetTypeId(void)
Get the type ID.
virtual bool DoEnqueue(Ptr< QueueDiscItem > item)
This function actually enqueues a packet into the queue disc.
uint32_t GetNPackets(void) const
Get the number of packets stored by the queue disc.
Definition: queue-disc.cc:440
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void AddQueueDiscClass(Ptr< QueueDiscClass > qdClass)
Add a queue disc class to the tail of the list of classes.
Definition: queue-disc.cc:620
std::array< uint16_t, 16 > Priomap
static const int PF_NO_MATCH
Standard value used by packet filters to indicate that no match was possible.
Definition: packet-filter.h:48
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
NS_ASSERT_MSG(false, "Ipv4AddressGenerator::MaskToIndex(): Impossible")
#define ATTRIBUTE_HELPER_CPP(type)
Define the attribute value, accessor and checkers for class type.
uint8_t GetPriority(void) const
Get the tag&#39;s priority.
Definition: socket.cc:848
Used by queue discs with unlimited size.
Definition: queue-disc.h:109
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
QueueDisc is an abstract base class providing the interface and implementing the operations common to...
Definition: queue-disc.h:182
virtual Ptr< const QueueDiscItem > DoPeek(void)
Return a copy of the next packet the queue disc will extract.
Ptr< const AttributeChecker > MakePriomapChecker(void)
PrioQueueDisc()
PrioQueueDisc constructor.
void SetBandForPriority(uint8_t prio, uint16_t band)
Set the band (class) assigned to packets with specified priority.
Ptr< Object > Create(void) const
Create an Object instance of the configured TypeId.
indicates whether the socket has a priority set.
Definition: socket.h:1307
int32_t Classify(Ptr< QueueDiscItem > item)
Classify a packet by calling the packet filters, one at a time, until either a filter able to classif...
Definition: queue-disc.cc:658
Ptr< QueueDiscClass > GetQueueDiscClass(std::size_t i) const
Get the i-th queue disc class.
Definition: queue-disc.cc:645
Ptr< QueueDiscItem > Dequeue(void)
Extract from the queue disc the packet that has been dequeued by calling Peek, if any...
Definition: queue-disc.cc:879
std::ostream & operator<<(std::ostream &os, const Angles &a)
print a struct Angles to output
Definition: angles.cc:42
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::size_t GetNQueueDiscClasses(void) const
Get the number of queue disc classes.
Definition: queue-disc.cc:652
virtual bool CheckConfig(void)
Check whether the current configuration is correct.
NS_LOG_LOGIC("Net device "<< nd<< " is not bridged")
virtual void InitializeParams(void)
Initialize parameters (if any) before the first packet is enqueued.
QueueDiscSizePolicy
Enumeration of the available policies to handle the queue disc size.
Definition: queue-disc.h:104
Instantiate subclasses of ns3::Object.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:270
uint16_t GetBandForPriority(uint8_t prio) const
Get the band (class) assigned to packets with specified priority.
Priomap m_prio2band
Priority to band mapping.
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
Ptr< const AttributeAccessor > MakePriomapAccessor(T1 a1)
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:915
void Initialize(void)
Invoke DoInitialize on all Objects aggregated to this one.
Definition: object.cc:183
The Prio qdisc is a simple classful queueing discipline that contains an arbitrary number of classes ...
virtual Ptr< QueueDiscItem > DoDequeue(void)
This function actually extracts a packet from the queue disc.
std::size_t GetNInternalQueues(void) const
Get the number of internal queues.
Definition: queue-disc.cc:594