A Discrete-Event Network Simulator
API
tbf-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 Kungliga Tekniska Högskolan
4  * 2017 Universita' degli Studi di Napoli Federico II
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * TBF, The Token Bucket Filter Queueing discipline
20  *
21  * This implementation is based on linux kernel code by
22  * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
23  * Dmitry Torokhov <dtor@mail.ru> - allow attaching inner qdiscs -
24  * original idea by Martin Devera
25  *
26  * Implemented in ns-3 by: Surya Seetharaman <suryaseetharaman.9@gmail.com>
27  * Stefano Avallone <stavallo@unina.it>
28  */
29 
30 #include "ns3/log.h"
31 #include "ns3/enum.h"
32 #include "ns3/simulator.h"
33 #include "ns3/uinteger.h"
34 #include "ns3/attribute.h"
35 #include "ns3/object-factory.h"
36 #include "ns3/drop-tail-queue.h"
37 #include "ns3/net-device-queue-interface.h"
38 #include "tbf-queue-disc.h"
39 
40 namespace ns3 {
41 
42 NS_LOG_COMPONENT_DEFINE ("TbfQueueDisc");
43 
44 NS_OBJECT_ENSURE_REGISTERED (TbfQueueDisc);
45 
47 {
48  static TypeId tid = TypeId ("ns3::TbfQueueDisc")
49  .SetParent<QueueDisc> ()
50  .SetGroupName ("TrafficControl")
51  .AddConstructor<TbfQueueDisc> ()
52  .AddAttribute ("MaxSize",
53  "The max queue size",
54  QueueSizeValue (QueueSize ("1000p")),
58  .AddAttribute ("Burst",
59  "Size of the first bucket in bytes",
60  UintegerValue (125000),
62  MakeUintegerChecker<uint32_t> ())
63  .AddAttribute ("Mtu",
64  "Size of the second bucket in bytes. If null, it is initialized"
65  " to the MTU of the receiving NetDevice (if any)",
66  UintegerValue (0),
68  MakeUintegerChecker<uint32_t> ())
69  .AddAttribute ("Rate",
70  "Rate at which tokens enter the first bucket in bps or Bps.",
71  DataRateValue (DataRate ("125KB/s")),
74  .AddAttribute ("PeakRate",
75  "Rate at which tokens enter the second bucket in bps or Bps."
76  "If null, there is no second bucket",
77  DataRateValue (DataRate ("0KB/s")),
80  .AddTraceSource ("TokensInFirstBucket",
81  "Number of First Bucket Tokens in bytes",
83  "ns3::TracedValueCallback::Uint32")
84  .AddTraceSource ("TokensInSecondBucket",
85  "Number of Second Bucket Tokens in bytes",
87  "ns3::TracedValueCallback::Uint32")
88  ;
89 
90  return tid;
91 }
92 
95 {
96  NS_LOG_FUNCTION (this);
97 }
98 
100 {
101  NS_LOG_FUNCTION (this);
102 }
103 
104 void
106 {
107  NS_LOG_FUNCTION (this);
109 }
110 
111 void
112 TbfQueueDisc::SetBurst (uint32_t burst)
113 {
114  NS_LOG_FUNCTION (this << burst);
115  m_burst = burst;
116 }
117 
118 uint32_t
120 {
121  NS_LOG_FUNCTION (this);
122  return m_burst;
123 }
124 
125 void
126 TbfQueueDisc::SetMtu (uint32_t mtu)
127 {
128  NS_LOG_FUNCTION (this << mtu);
129  m_mtu = mtu;
130 }
131 
132 uint32_t
134 {
135  NS_LOG_FUNCTION (this);
136  return m_mtu;
137 }
138 
139 void
141 {
142  NS_LOG_FUNCTION (this << rate);
143  m_rate = rate;
144 }
145 
146 DataRate
148 {
149  NS_LOG_FUNCTION (this);
150  return m_rate;
151 }
152 
153 void
155 {
156  NS_LOG_FUNCTION (this << peakRate);
157  m_peakRate = peakRate;
158 }
159 
160 DataRate
162 {
163  NS_LOG_FUNCTION (this);
164  return m_peakRate;
165 }
166 
167 uint32_t
169 {
170  NS_LOG_FUNCTION (this);
171  return m_btokens;
172 }
173 
174 uint32_t
176 {
177  NS_LOG_FUNCTION (this);
178  return m_ptokens;
179 }
180 
181 bool
183 {
184  NS_LOG_FUNCTION (this << item);
185 
186  bool retval = GetQueueDiscClass (0)->GetQueueDisc ()->Enqueue (item);
187 
188  // If Queue::Enqueue fails, QueueDisc::Drop is called by the child queue
189  // disc because QueueDisc::AddQueueDiscClass sets the drop callback
190 
191  NS_LOG_LOGIC ("Current queue size: " << GetNPackets () << " packets, " << GetNBytes () << " bytes");
192 
193  return retval;
194 }
195 
198 {
199  NS_LOG_FUNCTION (this);
200  Ptr<const QueueDiscItem> itemPeek = GetQueueDiscClass (0)->GetQueueDisc ()->Peek ();
201 
202  if (itemPeek)
203  {
204  uint32_t pktSize = itemPeek->GetSize ();
205  NS_LOG_LOGIC ("Next packet size " << pktSize);
206 
207  int64_t btoks = 0;
208  int64_t ptoks = 0;
209  Time now = Simulator::Now ();
210 
211  double delta = (now - m_timeCheckPoint).GetSeconds ();
212  NS_LOG_LOGIC ("Time Difference delta " << delta);
213 
214  if (m_peakRate > DataRate ("0bps"))
215  {
216  ptoks = m_ptokens + round (delta * (m_peakRate.GetBitRate () / 8));
217  if (ptoks > m_mtu)
218  {
219  ptoks = m_mtu;
220  }
221  NS_LOG_LOGIC ("Number of ptokens we can consume " << ptoks);
222  NS_LOG_LOGIC ("Required to dequeue next packet " << pktSize);
223  ptoks -= pktSize;
224  }
225 
226  btoks = m_btokens + round (delta * (m_rate.GetBitRate () / 8));
227 
228  if (btoks > m_burst)
229  {
230  btoks = m_burst;
231  }
232 
233  NS_LOG_LOGIC ("Number of btokens we can consume " << btoks);
234  NS_LOG_LOGIC ("Required to dequeue next packet " << pktSize);
235  btoks -= pktSize;
236 
237  if ((btoks|ptoks) >= 0) // else packet blocked
238  {
239  Ptr<QueueDiscItem> item = GetQueueDiscClass (0)->GetQueueDisc ()->Dequeue ();
240  if (!item)
241  {
242  NS_LOG_DEBUG ("That's odd! Expecting the peeked packet, we got no packet.");
243  return item;
244  }
245 
246  m_timeCheckPoint = now;
247  m_btokens = btoks;
248  m_ptokens = ptoks;
249 
250  NS_LOG_LOGIC (m_btokens << " btokens and " << m_ptokens << " ptokens after packet dequeue");
251  NS_LOG_LOGIC ("Current queue size: " << GetNPackets () << " packets, " << GetNBytes () << " bytes");
252 
253  return item;
254  }
255 
256  // the watchdog timer setup.
257  /* A packet gets blocked if the above if condition is not satisfied, i.e.
258  both the ptoks and btoks are less than zero. In that case we have to
259  schedule the waking of queue when enough tokens are available. */
260  if (m_id.IsExpired () == true)
261  {
262  Time requiredDelayTime = std::max (m_rate.CalculateBytesTxTime (-btoks),
264 
265  m_id = Simulator::Schedule (requiredDelayTime, &QueueDisc::Run, this);
266  NS_LOG_LOGIC("Waking Event Scheduled in " << requiredDelayTime);
267  }
268  }
269  return 0;
270 }
271 
272 bool
274 {
275  NS_LOG_FUNCTION (this);
276  if (GetNInternalQueues () > 0)
277  {
278  NS_LOG_ERROR ("TbfQueueDisc cannot have internal queues");
279  return false;
280  }
281 
282  if (GetNPacketFilters () > 0)
283  {
284  NS_LOG_ERROR ("TbfQueueDisc cannot have packet filters");
285  return false;
286  }
287 
288  if (GetNQueueDiscClasses () == 0)
289  {
290  // create a FIFO queue disc
291  ObjectFactory factory;
292  factory.SetTypeId ("ns3::FifoQueueDisc");
293  Ptr<QueueDisc> qd = factory.Create<QueueDisc> ();
294 
295  if (!qd->SetMaxSize (GetMaxSize ()))
296  {
297  NS_LOG_ERROR ("Cannot set the max size of the child queue disc to that of TbfQueueDisc");
298  return false;
299  }
300  qd->Initialize ();
301 
302  Ptr<QueueDiscClass> c = CreateObject<QueueDiscClass> ();
303  c->SetQueueDisc (qd);
304  AddQueueDiscClass (c);
305  }
306 
307  if (GetNQueueDiscClasses () != 1)
308  {
309  NS_LOG_ERROR ("TbfQueueDisc needs 1 child queue disc");
310  return false;
311  }
312 
313  // This type of variable initialization would normally be done in
314  // InitializeParams (), but we want to use the value to subsequently
315  // check configuration of peak rate, so we move it forward here.
316  if (m_mtu == 0)
317  {
319  Ptr<NetDevice> dev;
320  // if the NetDeviceQueueInterface object is aggregated to a
321  // NetDevice, get the MTU of such NetDevice
322  if (ndqi && (dev = ndqi->GetObject<NetDevice> ()))
323  {
324  m_mtu = dev->GetMtu ();
325  }
326  }
327 
328  if (m_mtu == 0 && m_peakRate > DataRate ("0bps"))
329  {
330  NS_LOG_ERROR ("A non-null peak rate has been set, but the mtu is null. No packet will be dequeued");
331  return false;
332  }
333 
334  if (m_burst <= m_mtu)
335  {
336  NS_LOG_WARN ("The size of the first bucket (" << m_burst << ") should be "
337  << "greater than the size of the second bucket (" << m_mtu << ").");
338  }
339 
340  if (m_peakRate > DataRate ("0bps") && m_peakRate <= m_rate)
341  {
342  NS_LOG_WARN ("The rate for the second bucket (" << m_peakRate << ") should be "
343  << "greater than the rate for the first bucket (" << m_rate << ").");
344  }
345 
346  return true;
347 }
348 
349 void
351 {
352  NS_LOG_FUNCTION (this);
353  // Token Buckets are full at the beginning.
354  m_btokens = m_burst;
355  m_ptokens = m_mtu;
356  // Initialising other variables to 0.
358  m_id = EventId ();
359 }
360 
361 } // namespace ns3
ns3::TbfQueueDisc::TbfQueueDisc
TbfQueueDisc()
TbfQueueDisc Constructor.
Definition: tbf-queue-disc.cc:93
ns3::TypeId
a unique identifier for an interface.
Definition: type-id.h:59
NS_LOG_COMPONENT_DEFINE
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
ns3::DataRateValue
AttributeValue implementation for DataRate.
Definition: data-rate.h:298
ns3::QueueDiscSizePolicy
QueueDiscSizePolicy
Enumeration of the available policies to handle the queue disc size.
Definition: queue-disc.h:104
ns3::TbfQueueDisc::DoEnqueue
virtual bool DoEnqueue(Ptr< QueueDiscItem > item)
This function actually enqueues a packet into the queue disc.
Definition: tbf-queue-disc.cc:182
NS_OBJECT_ENSURE_REGISTERED
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
ns3::TbfQueueDisc::GetTypeId
static TypeId GetTypeId(void)
Get the type ID.
Definition: tbf-queue-disc.cc:46
ns3::QueueDisc::Run
void Run(void)
Modelled after the Linux function __qdisc_run (net/sched/sch_generic.c) Dequeues multiple packets,...
Definition: queue-disc.cc:955
ns3::DataRate::CalculateBytesTxTime
Time CalculateBytesTxTime(uint32_t bytes) const
Calculate transmission time.
Definition: data-rate.cc:275
ns3::TbfQueueDisc::CheckConfig
virtual bool CheckConfig(void)
Check whether the current configuration is correct.
Definition: tbf-queue-disc.cc:273
ns3::EventId
An identifier for simulation events.
Definition: event-id.h:54
ns3::Simulator::Now
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
ns3::QueueDisc::SetMaxSize
bool SetMaxSize(QueueSize size)
Set the maximum size of the queue disc.
Definition: queue-disc.cc:482
ns3
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ns3::MakeDataRateAccessor
Ptr< const AttributeAccessor > MakeDataRateAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: data-rate.h:298
ns3::QueueDisc
QueueDisc is an abstract base class providing the interface and implementing the operations common to...
Definition: queue-disc.h:181
ns3::QueueDisc::GetMaxSize
QueueSize GetMaxSize(void) const
Get the maximum size of the queue disc.
Definition: queue-disc.cc:454
ns3::TbfQueueDisc::m_burst
uint32_t m_burst
Size of first bucket in bytes.
Definition: tbf-queue-disc.h:156
ns3::TbfQueueDisc::GetMtu
uint32_t GetMtu(void) const
Get the size of the second bucket in bytes.
Definition: tbf-queue-disc.cc:133
ns3::QueueDisc::GetQueueDiscClass
Ptr< QueueDiscClass > GetQueueDiscClass(std::size_t i) const
Get the i-th queue disc class.
Definition: queue-disc.cc:662
ns3::MakeQueueSizeChecker
Ptr< const AttributeChecker > MakeQueueSizeChecker(void)
Definition: queue-size.cc:29
NS_LOG_WARN
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:265
ns3::TbfQueueDisc::SetMtu
void SetMtu(uint32_t mtu)
Set the size of the second bucket in bytes.
Definition: tbf-queue-disc.cc:126
ns3::TbfQueueDisc::SetBurst
void SetBurst(uint32_t burst)
Set the size of the first bucket in bytes.
Definition: tbf-queue-disc.cc:112
ns3::QueueDisc::GetNBytes
uint32_t GetNBytes(void) const
Get the amount of bytes stored by the queue disc.
Definition: queue-disc.cc:447
ns3::QueueDisc::AddQueueDiscClass
void AddQueueDiscClass(Ptr< QueueDiscClass > qdClass)
Add a queue disc class to the tail of the list of classes.
Definition: queue-disc.cc:634
ns3::Simulator::Schedule
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
ns3::QueueDisc::GetNPacketFilters
std::size_t GetNPacketFilters(void) const
Get the number of packet filters.
Definition: queue-disc.cc:628
ns3::TypeId::SetParent
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
ns3::TbfQueueDisc::DoDequeue
virtual Ptr< QueueDiscItem > DoDequeue(void)
This function actually extracts a packet from the queue disc.
Definition: tbf-queue-disc.cc:197
ns3::MakeTraceSourceAccessor
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Definition: trace-source-accessor.h:202
ns3::QueueSizeValue
Definition: queue-size.h:221
ns3::QueueDisc::GetNetDeviceQueueInterface
Ptr< NetDeviceQueueInterface > GetNetDeviceQueueInterface(void) const
Definition: queue-disc.cc:546
ns3::Ptr
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
ns3::DataRate
Class for representing data rates.
Definition: data-rate.h:89
ns3::QueueDisc::DoDispose
virtual void DoDispose(void)
Dispose of the object.
Definition: queue-disc.cc:383
max
#define max(a, b)
Definition: 80211b.c:43
ns3::TbfQueueDisc::m_peakRate
DataRate m_peakRate
Rate at which tokens enter the second bucket.
Definition: tbf-queue-disc.h:159
tbf-queue-disc.h
ns3::ObjectFactory
Instantiate subclasses of ns3::Object.
Definition: object-factory.h:48
ns3::TbfQueueDisc::m_ptokens
TracedValue< uint32_t > m_ptokens
Current number of tokens in second bucket.
Definition: tbf-queue-disc.h:163
ns3::Time
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:104
ns3::QueueDisc::GetNInternalQueues
std::size_t GetNInternalQueues(void) const
Get the number of internal queues.
Definition: queue-disc.cc:608
ns3::TbfQueueDisc::DoDispose
virtual void DoDispose(void)
Dispose of the object.
Definition: tbf-queue-disc.cc:105
ns3::TbfQueueDisc::~TbfQueueDisc
virtual ~TbfQueueDisc()
Destructor.
Definition: tbf-queue-disc.cc:99
ns3::TbfQueueDisc::GetSecondBucketTokens
uint32_t GetSecondBucketTokens(void) const
Get the current number of tokens inside the second bucket in bytes.
Definition: tbf-queue-disc.cc:175
ns3::TbfQueueDisc::SetRate
void SetRate(DataRate rate)
Set the rate of the tokens entering the first bucket.
Definition: tbf-queue-disc.cc:140
ns3::DataRate::GetBitRate
uint64_t GetBitRate() const
Get the underlying bitrate.
Definition: data-rate.cc:287
ns3::TbfQueueDisc::GetFirstBucketTokens
uint32_t GetFirstBucketTokens(void) const
Get the current number of tokens inside the first bucket in bytes.
Definition: tbf-queue-disc.cc:168
ns3::TbfQueueDisc::m_rate
DataRate m_rate
Rate at which tokens enter the first bucket.
Definition: tbf-queue-disc.h:158
ns3::SINGLE_CHILD_QUEUE_DISC
@ SINGLE_CHILD_QUEUE_DISC
Used by queue discs with single child queue disc.
Definition: queue-disc.h:106
NS_LOG_LOGIC
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
NS_LOG_ERROR
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:257
ns3::QueueDisc::GetNPackets
uint32_t GetNPackets(void) const
Get the number of packets stored by the queue disc.
Definition: queue-disc.cc:440
ns3::TbfQueueDisc::m_btokens
TracedValue< uint32_t > m_btokens
Current number of tokens in first bucket.
Definition: tbf-queue-disc.h:162
NS_LOG_DEBUG
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
ns3::Seconds
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
ns3::TbfQueueDisc::m_mtu
uint32_t m_mtu
Size of second bucket in bytes.
Definition: tbf-queue-disc.h:157
pktSize
uint32_t pktSize
packet size used for the simulation (in bytes)
Definition: wifi-bianchi.cc:86
NS_LOG_FUNCTION
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Definition: log-macros-enabled.h:244
ns3::TbfQueueDisc::GetPeakRate
DataRate GetPeakRate(void) const
Get the rate of the tokens entering the second bucket.
Definition: tbf-queue-disc.cc:161
ns3::MakeQueueSizeAccessor
Ptr< const AttributeAccessor > MakeQueueSizeAccessor(T1 a1)
Definition: queue-size.h:221
ns3::TbfQueueDisc::m_id
EventId m_id
EventId of the scheduled queue waking event when enough tokens are available.
Definition: tbf-queue-disc.h:165
ns3::ObjectFactory::SetTypeId
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
Definition: object-factory.cc:40
ns3::UintegerValue
Hold an unsigned integer type.
Definition: uinteger.h:44
ns3::ObjectFactory::Create
Ptr< Object > Create(void) const
Create an Object instance of the configured TypeId.
Definition: object-factory.cc:98
ns3::TbfQueueDisc::SetPeakRate
void SetPeakRate(DataRate peakRate)
Set the rate of the tokens entering the second bucket.
Definition: tbf-queue-disc.cc:154
ns3::MakeUintegerAccessor
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: uinteger.h:45
ns3::QueueDisc::GetNQueueDiscClasses
std::size_t GetNQueueDiscClasses(void) const
Get the number of queue disc classes.
Definition: queue-disc.cc:669
ns3::Object::Initialize
void Initialize(void)
Invoke DoInitialize on all Objects aggregated to this one.
Definition: object.cc:183
ns3::QueueSize
Class for representing queue sizes.
Definition: queue-size.h:95
ns3::TbfQueueDisc::GetRate
DataRate GetRate(void) const
Get the rate of the tokens entering the first bucket.
Definition: tbf-queue-disc.cc:147
ns3::TbfQueueDisc::m_timeCheckPoint
Time m_timeCheckPoint
Time check-point.
Definition: tbf-queue-disc.h:164
ns3::TbfQueueDisc::GetBurst
uint32_t GetBurst(void) const
Get the size of the first bucket in bytes.
Definition: tbf-queue-disc.cc:119
ns3::TbfQueueDisc::InitializeParams
virtual void InitializeParams(void)
Initialize parameters (if any) before the first packet is enqueued.
Definition: tbf-queue-disc.cc:350
ns3::MakeDataRateChecker
Ptr< const AttributeChecker > MakeDataRateChecker(void)
Definition: data-rate.cc:30
ns3::TbfQueueDisc
A TBF packet queue disc.
Definition: tbf-queue-disc.h:49
ns3::EventId::IsExpired
bool IsExpired(void) const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:65
ns3::NetDevice
Network layer to device interface.
Definition: net-device.h:96