A Discrete-Event Network Simulator
API
fq-pie-queue-disc.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Universita' degli Studi di Napoli Federico II
3  * Copyright (c) 2018 NITK Surathkal (modified for FQ-PIE)
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: Pasquale Imputato <p.imputato@gmail.com>
19  * Stefano Avallone <stefano.avallone@unina.it>
20  * Modified for FQ-PIE by: Sumukha PK <sumukhapk46@gmail.com>
21  * Prajval M <26prajval98@gmail.com>
22  * Ishaan R D <ishaanrd6@gmail.com>
23  * Mohit P. Tahiliani <tahiliani@nitk.edu.in>
24  */
25 
26 #include "fq-pie-queue-disc.h"
27 
28 #include "pie-queue-disc.h"
29 
30 #include "ns3/log.h"
31 #include "ns3/net-device-queue-interface.h"
32 #include "ns3/queue.h"
33 #include "ns3/string.h"
34 
35 namespace ns3
36 {
37 
38 NS_LOG_COMPONENT_DEFINE("FqPieQueueDisc");
39 
41 
42 TypeId
44 {
45  static TypeId tid = TypeId("ns3::FqPieFlow")
47  .SetGroupName("TrafficControl")
48  .AddConstructor<FqPieFlow>();
49  return tid;
50 }
51 
53  : m_deficit(0),
54  m_status(INACTIVE),
55  m_index(0)
56 {
57  NS_LOG_FUNCTION(this);
58 }
59 
61 {
62  NS_LOG_FUNCTION(this);
63 }
64 
65 void
66 FqPieFlow::SetDeficit(uint32_t deficit)
67 {
68  NS_LOG_FUNCTION(this << deficit);
69  m_deficit = deficit;
70 }
71 
72 int32_t
74 {
75  NS_LOG_FUNCTION(this);
76  return m_deficit;
77 }
78 
79 void
81 {
82  NS_LOG_FUNCTION(this << deficit);
83  m_deficit += deficit;
84 }
85 
86 void
88 {
89  NS_LOG_FUNCTION(this);
90  m_status = status;
91 }
92 
95 {
96  NS_LOG_FUNCTION(this);
97  return m_status;
98 }
99 
100 void
101 FqPieFlow::SetIndex(uint32_t index)
102 {
103  NS_LOG_FUNCTION(this);
104  m_index = index;
105 }
106 
107 uint32_t
109 {
110  return m_index;
111 }
112 
114 
115 TypeId
117 {
118  static TypeId tid =
119  TypeId("ns3::FqPieQueueDisc")
120  .SetParent<QueueDisc>()
121  .SetGroupName("TrafficControl")
122  .AddConstructor<FqPieQueueDisc>()
123  .AddAttribute("UseEcn",
124  "True to use ECN (packets are marked instead of being dropped)",
125  BooleanValue(true),
128  .AddAttribute("MarkEcnThreshold",
129  "ECN marking threshold (RFC 8033 suggests 0.1 (i.e., 10%) default)",
130  DoubleValue(0.1),
132  MakeDoubleChecker<double>(0, 1))
133  .AddAttribute("CeThreshold",
134  "The FqPie CE threshold for marking packets",
135  TimeValue(Time::Max()),
137  MakeTimeChecker())
138  .AddAttribute("UseL4s",
139  "True to use L4S (only ECT1 packets are marked at CE threshold)",
140  BooleanValue(false),
143  .AddAttribute("MeanPktSize",
144  "Average of packet size",
145  UintegerValue(1000),
147  MakeUintegerChecker<uint32_t>())
148  .AddAttribute("A",
149  "Value of alpha",
150  DoubleValue(0.125),
152  MakeDoubleChecker<double>())
153  .AddAttribute("B",
154  "Value of beta",
155  DoubleValue(1.25),
157  MakeDoubleChecker<double>())
158  .AddAttribute("Tupdate",
159  "Time period to calculate drop probability",
160  TimeValue(Seconds(0.015)),
162  MakeTimeChecker())
163  .AddAttribute("Supdate",
164  "Start time of the update timer",
165  TimeValue(Seconds(0)),
167  MakeTimeChecker())
168  .AddAttribute("MaxSize",
169  "The maximum number of packets accepted by this queue disc",
170  QueueSizeValue(QueueSize("10240p")),
171  MakeQueueSizeAccessor(&QueueDisc::SetMaxSize, &QueueDisc::GetMaxSize),
172  MakeQueueSizeChecker())
173  .AddAttribute("DequeueThreshold",
174  "Minimum queue size in bytes before dequeue rate is measured",
175  UintegerValue(16384),
177  MakeUintegerChecker<uint32_t>())
178  .AddAttribute("QueueDelayReference",
179  "Desired queue delay",
180  TimeValue(Seconds(0.015)),
182  MakeTimeChecker())
183  .AddAttribute("MaxBurstAllowance",
184  "Current max burst allowance before random drop",
185  TimeValue(Seconds(0.15)),
187  MakeTimeChecker())
188  .AddAttribute("UseDequeueRateEstimator",
189  "Enable/Disable usage of Dequeue Rate Estimator",
190  BooleanValue(false),
193  .AddAttribute("UseCapDropAdjustment",
194  "Enable/Disable Cap Drop Adjustment feature mentioned in RFC 8033",
195  BooleanValue(true),
198  .AddAttribute("UseDerandomization",
199  "Enable/Disable Derandomization feature mentioned in RFC 8033",
200  BooleanValue(false),
203  .AddAttribute("Flows",
204  "The number of queues into which the incoming packets are classified",
205  UintegerValue(1024),
207  MakeUintegerChecker<uint32_t>())
208  .AddAttribute("DropBatchSize",
209  "The maximum number of packets dropped from the fat flow",
210  UintegerValue(64),
212  MakeUintegerChecker<uint32_t>())
213  .AddAttribute("Perturbation",
214  "The salt used as an additional input to the hash function used to "
215  "classify packets",
216  UintegerValue(0),
218  MakeUintegerChecker<uint32_t>())
219  .AddAttribute("EnableSetAssociativeHash",
220  "Enable/Disable Set Associative Hash",
221  BooleanValue(false),
224  .AddAttribute("SetWays",
225  "The size of a set of queues (used by set associative hash)",
226  UintegerValue(8),
228  MakeUintegerChecker<uint32_t>());
229  return tid;
230 }
231 
234  m_quantum(0)
235 {
236  NS_LOG_FUNCTION(this);
237 }
238 
240 {
241  NS_LOG_FUNCTION(this);
242 }
243 
244 void
245 FqPieQueueDisc::SetQuantum(uint32_t quantum)
246 {
247  NS_LOG_FUNCTION(this << quantum);
248  m_quantum = quantum;
249 }
250 
251 uint32_t
253 {
254  return m_quantum;
255 }
256 
257 uint32_t
259 {
260  NS_LOG_FUNCTION(this << flowHash);
261 
262  uint32_t h = (flowHash % m_flows);
263  uint32_t innerHash = h % m_setWays;
264  uint32_t outerHash = h - innerHash;
265 
266  for (uint32_t i = outerHash; i < outerHash + m_setWays; i++)
267  {
268  auto it = m_flowsIndices.find(i);
269 
270  if (it == m_flowsIndices.end() ||
271  (m_tags.find(i) != m_tags.end() && m_tags[i] == flowHash) ||
272  StaticCast<FqPieFlow>(GetQueueDiscClass(it->second))->GetStatus() ==
274  {
275  // this queue has not been created yet or is associated with this flow
276  // or is inactive, hence we can use it
277  m_tags[i] = flowHash;
278  return i;
279  }
280  }
281 
282  // all the queues of the set are used. Use the first queue of the set
283  m_tags[outerHash] = flowHash;
284  return outerHash;
285 }
286 
287 bool
289 {
290  NS_LOG_FUNCTION(this << item);
291 
292  uint32_t flowHash;
293  uint32_t h;
294 
295  if (GetNPacketFilters() == 0)
296  {
297  flowHash = item->Hash(m_perturbation);
298  }
299  else
300  {
301  int32_t ret = Classify(item);
302 
303  if (ret != PacketFilter::PF_NO_MATCH)
304  {
305  flowHash = static_cast<uint32_t>(ret);
306  }
307  else
308  {
309  NS_LOG_ERROR("No filter has been able to classify this packet, drop it.");
311  return false;
312  }
313  }
314 
316  {
317  h = SetAssociativeHash(flowHash);
318  }
319  else
320  {
321  h = flowHash % m_flows;
322  }
323 
324  Ptr<FqPieFlow> flow;
325  if (m_flowsIndices.find(h) == m_flowsIndices.end())
326  {
327  NS_LOG_DEBUG("Creating a new flow queue with index " << h);
328  flow = m_flowFactory.Create<FqPieFlow>();
330  // If Pie, Set values of PieQueueDisc to match this QueueDisc
331  Ptr<PieQueueDisc> pie = qd->GetObject<PieQueueDisc>();
332  if (pie)
333  {
334  pie->SetAttribute("UseEcn", BooleanValue(m_useEcn));
335  pie->SetAttribute("CeThreshold", TimeValue(m_ceThreshold));
336  pie->SetAttribute("UseL4s", BooleanValue(m_useL4s));
337  }
338  qd->Initialize();
339  flow->SetQueueDisc(qd);
340  flow->SetIndex(h);
341  AddQueueDiscClass(flow);
342 
344  }
345  else
346  {
347  flow = StaticCast<FqPieFlow>(GetQueueDiscClass(m_flowsIndices[h]));
348  }
349 
350  if (flow->GetStatus() == FqPieFlow::INACTIVE)
351  {
352  flow->SetStatus(FqPieFlow::NEW_FLOW);
353  flow->SetDeficit(m_quantum);
354  m_newFlows.push_back(flow);
355  }
356 
357  flow->GetQueueDisc()->Enqueue(item);
358 
359  NS_LOG_DEBUG("Packet enqueued into flow " << h << "; flow index " << m_flowsIndices[h]);
360 
361  if (GetCurrentSize() > GetMaxSize())
362  {
363  NS_LOG_DEBUG("Overload; enter FqPieDrop ()");
364  FqPieDrop();
365  }
366 
367  return true;
368 }
369 
372 {
373  NS_LOG_FUNCTION(this);
374 
375  Ptr<FqPieFlow> flow;
376  Ptr<QueueDiscItem> item;
377 
378  do
379  {
380  bool found = false;
381 
382  while (!found && !m_newFlows.empty())
383  {
384  flow = m_newFlows.front();
385 
386  if (flow->GetDeficit() <= 0)
387  {
388  NS_LOG_DEBUG("Increase deficit for new flow index " << flow->GetIndex());
389  flow->IncreaseDeficit(m_quantum);
390  flow->SetStatus(FqPieFlow::OLD_FLOW);
391  m_oldFlows.push_back(flow);
392  m_newFlows.pop_front();
393  }
394  else
395  {
396  NS_LOG_DEBUG("Found a new flow " << flow->GetIndex() << " with positive deficit");
397  found = true;
398  }
399  }
400 
401  while (!found && !m_oldFlows.empty())
402  {
403  flow = m_oldFlows.front();
404 
405  if (flow->GetDeficit() <= 0)
406  {
407  NS_LOG_DEBUG("Increase deficit for old flow index " << flow->GetIndex());
408  flow->IncreaseDeficit(m_quantum);
409  m_oldFlows.push_back(flow);
410  m_oldFlows.pop_front();
411  }
412  else
413  {
414  NS_LOG_DEBUG("Found an old flow " << flow->GetIndex() << " with positive deficit");
415  found = true;
416  }
417  }
418 
419  if (!found)
420  {
421  NS_LOG_DEBUG("No flow found to dequeue a packet");
422  return nullptr;
423  }
424 
425  item = flow->GetQueueDisc()->Dequeue();
426 
427  if (!item)
428  {
429  NS_LOG_DEBUG("Could not get a packet from the selected flow queue");
430  if (!m_newFlows.empty())
431  {
432  flow->SetStatus(FqPieFlow::OLD_FLOW);
433  m_oldFlows.push_back(flow);
434  m_newFlows.pop_front();
435  }
436  else
437  {
438  flow->SetStatus(FqPieFlow::INACTIVE);
439  m_oldFlows.pop_front();
440  }
441  }
442  else
443  {
444  NS_LOG_DEBUG("Dequeued packet " << item->GetPacket());
445  }
446  } while (!item);
447 
448  flow->IncreaseDeficit(item->GetSize() * -1);
449 
450  return item;
451 }
452 
453 bool
455 {
456  NS_LOG_FUNCTION(this);
457  if (GetNQueueDiscClasses() > 0)
458  {
459  NS_LOG_ERROR("FqPieQueueDisc cannot have classes");
460  return false;
461  }
462 
463  if (GetNInternalQueues() > 0)
464  {
465  NS_LOG_ERROR("FqPieQueueDisc cannot have internal queues");
466  return false;
467  }
468  // we are at initialization time. If the user has not set a quantum value,
469  // set the quantum to the MTU of the device (if any)
470  if (!m_quantum)
471  {
473  Ptr<NetDevice> dev;
474  // if the NetDeviceQueueInterface object is aggregated to a
475  // NetDevice, get the MTU of such NetDevice
476  if (ndqi && (dev = ndqi->GetObject<NetDevice>()))
477  {
478  m_quantum = dev->GetMtu();
479  NS_LOG_DEBUG("Setting the quantum to the MTU of the device: " << m_quantum);
480  }
481 
482  if (!m_quantum)
483  {
484  NS_LOG_ERROR("The quantum parameter cannot be null");
485  return false;
486  }
487  }
488 
490  {
491  NS_LOG_ERROR("The number of queues must be an integer multiple of the size "
492  "of the set of queues used by set associative hash");
493  return false;
494  }
495 
496  // If UseL4S attribute is enabled then CE threshold must be set.
497  if (m_useL4s)
498  {
499  NS_ABORT_MSG_IF(m_ceThreshold == Time::Max(), "CE threshold not set");
500  if (!m_useEcn)
501  {
502  NS_LOG_WARN("Enabling ECN as L4S mode is enabled");
503  }
504  }
505  return true;
506 }
507 
508 void
510 {
511  NS_LOG_FUNCTION(this);
512 
513  m_flowFactory.SetTypeId("ns3::FqPieFlow");
514 
515  m_queueDiscFactory.SetTypeId("ns3::PieQueueDisc");
516  m_queueDiscFactory.Set("MaxSize", QueueSizeValue(GetMaxSize()));
522  m_queueDiscFactory.Set("DequeueThreshold", UintegerValue(m_dqThreshold));
523  m_queueDiscFactory.Set("QueueDelayReference", TimeValue(m_qDelayRef));
524  m_queueDiscFactory.Set("MaxBurstAllowance", TimeValue(m_maxBurst));
525  m_queueDiscFactory.Set("UseDequeueRateEstimator", BooleanValue(m_useDqRateEstimator));
526  m_queueDiscFactory.Set("UseCapDropAdjustment", BooleanValue(m_isCapDropAdjustment));
528 }
529 
530 uint32_t
532 {
533  NS_LOG_FUNCTION(this);
534 
535  uint32_t maxBacklog = 0;
536  uint32_t index = 0;
537  Ptr<QueueDisc> qd;
538 
539  /* Queue is full! Find the fat flow and drop packet(s) from it */
540  for (uint32_t i = 0; i < GetNQueueDiscClasses(); i++)
541  {
542  qd = GetQueueDiscClass(i)->GetQueueDisc();
543  uint32_t bytes = qd->GetNBytes();
544  if (bytes > maxBacklog)
545  {
546  maxBacklog = bytes;
547  index = i;
548  }
549  }
550 
551  /* Our goal is to drop half of this fat flow backlog */
552  uint32_t len = 0;
553  uint32_t count = 0;
554  uint32_t threshold = maxBacklog >> 1;
555  qd = GetQueueDiscClass(index)->GetQueueDisc();
556  Ptr<QueueDiscItem> item;
557 
558  do
559  {
560  NS_LOG_DEBUG("Drop packet (overflow); count: " << count << " len: " << len
561  << " threshold: " << threshold);
562  item = qd->GetInternalQueue(0)->Dequeue();
564  len += item->GetSize();
565  } while (++count < m_dropBatchSize && len < threshold);
566 
567  return index;
568 }
569 
570 } // namespace ns3
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
A flow queue used by the FqPie queue disc.
void SetIndex(uint32_t index)
Set the index for this flow.
FlowStatus
Used to determine the status of this flow queue.
int32_t m_deficit
the deficit for this flow
void SetStatus(FlowStatus status)
Set the status for this flow.
static TypeId GetTypeId()
Get the type ID.
~FqPieFlow() override
FlowStatus GetStatus() const
Get the status of this flow.
FlowStatus m_status
the status of this flow
uint32_t m_index
the index for this flow
void SetDeficit(uint32_t deficit)
Set the deficit for this flow.
uint32_t GetIndex() const
Get the index of this flow.
FqPieFlow()
FqPieFlow constructor.
void IncreaseDeficit(int32_t deficit)
Increase the deficit for this flow.
int32_t GetDeficit() const
Get the deficit for this flow.
A FqPie packet queue disc.
Time m_qDelayRef
Desired queue delay.
std::map< uint32_t, uint32_t > m_tags
Tags used by set associative hash.
bool m_useEcn
True if ECN is used (packets are marked instead of being dropped)
bool m_enableSetAssociativeHash
whether to enable set associative hash
uint32_t m_meanPktSize
Average packet size in bytes.
static constexpr const char * UNCLASSIFIED_DROP
No packet filter able to classify packet.
uint32_t GetQuantum() const
Get the quantum value.
uint32_t m_perturbation
hash perturbation value
FqPieQueueDisc()
FqPieQueueDisc constructor.
ObjectFactory m_queueDiscFactory
Factory to create a new queue.
bool DoEnqueue(Ptr< QueueDiscItem > item) override
This function actually enqueues a packet into the queue disc.
double m_a
Parameter to pie controller.
Time m_sUpdate
Start time of the update timer.
bool m_useDqRateEstimator
Enable/Disable usage of dequeue rate estimator for queue delay calculation.
Time m_ceThreshold
Threshold above which to CE mark.
uint32_t m_dqThreshold
Minimum queue size in bytes before dequeue rate is measured.
Ptr< QueueDiscItem > DoDequeue() override
This function actually extracts a packet from the queue disc.
bool CheckConfig() override
Check whether the current configuration is correct.
uint32_t m_dropBatchSize
Max number of packets dropped from the fat flow.
uint32_t m_quantum
Deficit assigned to flows at each round.
Time m_tUpdate
Time period after which CalculateP () is called.
uint32_t FqPieDrop()
Drop a packet from the head of the queue with the largest current byte count.
bool m_isCapDropAdjustment
Enable/Disable Cap Drop Adjustment feature mentioned in RFC 8033.
std::list< Ptr< FqPieFlow > > m_newFlows
The list of new flows.
Time m_maxBurst
Maximum burst allowed before random early dropping kicks in.
bool m_useDerandomization
Enable Derandomization feature mentioned in RFC 8033.
uint32_t m_setWays
size of a set of queues (used by set associative hash)
uint32_t m_flows
Number of flow queues.
static TypeId GetTypeId()
Get the type ID.
double m_markEcnTh
ECN marking threshold (default 10% as suggested in RFC 8033)
void InitializeParams() override
Initialize parameters (if any) before the first packet is enqueued.
std::map< uint32_t, uint32_t > m_flowsIndices
Map with the index of class for each flow.
uint32_t SetAssociativeHash(uint32_t flowHash)
Compute the index of the queue for the flow having the given flowHash, according to the set associati...
static constexpr const char * OVERLIMIT_DROP
Overlimit dropped packets.
bool m_useL4s
True if L4S is used (ECT1 packets are marked at CE threshold)
void SetQuantum(uint32_t quantum)
Set the quantum value.
double m_b
Parameter to pie controller.
ObjectFactory m_flowFactory
Factory to create a new flow.
std::list< Ptr< FqPieFlow > > m_oldFlows
The list of old flows.
Network layer to device interface.
Definition: net-device.h:98
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:204
Ptr< Object > Create() const
Create an Object instance of the configured TypeId.
void Set(const std::string &name, const AttributeValue &value, Args &&... args)
Set an attribute to be set during construction.
void SetTypeId(TypeId tid)
Set the TypeId of the Objects to be created by this factory.
static const int PF_NO_MATCH
Standard value used by packet filters to indicate that no match was possible.
Definition: packet-filter.h:49
Implements PIE Active Queue Management discipline.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
QueueDiscClass is the base class for classes that are included in a queue disc.
Definition: queue-disc.h:52
QueueDisc is an abstract base class providing the interface and implementing the operations common to...
Definition: queue-disc.h:184
void AddQueueDiscClass(Ptr< QueueDiscClass > qdClass)
Add a queue disc class to the tail of the list of classes.
Definition: queue-disc.cc:624
uint32_t GetNBytes() const
Get the amount of bytes stored by the queue disc.
Definition: queue-disc.cc:439
Ptr< InternalQueue > GetInternalQueue(std::size_t i) const
Get the i-th internal queue.
Definition: queue-disc.cc:591
QueueSize GetCurrentSize() const
Get the current size of the queue disc in bytes, if operating in bytes mode, or packets,...
Definition: queue-disc.cc:515
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:667
Ptr< NetDeviceQueueInterface > GetNetDeviceQueueInterface() const
Definition: queue-disc.cc:538
void DropAfterDequeue(Ptr< const QueueDiscItem > item, const char *reason)
Perform the actions required when the queue disc is notified of a packet dropped after dequeue.
Definition: queue-disc.cc:759
std::size_t GetNQueueDiscClasses() const
Get the number of queue disc classes.
Definition: queue-disc.cc:661
QueueSize GetMaxSize() const
Get the maximum size of the queue disc.
Definition: queue-disc.cc:446
Ptr< QueueDiscClass > GetQueueDiscClass(std::size_t i) const
Get the i-th queue disc class.
Definition: queue-disc.cc:654
std::size_t GetNPacketFilters() const
Get the number of packet filters.
Definition: queue-disc.cc:618
bool SetMaxSize(QueueSize size)
Set the maximum size of the queue disc.
Definition: queue-disc.cc:474
std::size_t GetNInternalQueues() const
Get the number of internal queues.
Definition: queue-disc.cc:598
void DropBeforeEnqueue(Ptr< const QueueDiscItem > item, const char *reason)
Perform the actions required when the queue disc is notified of a packet dropped before enqueue.
Definition: queue-disc.cc:720
Class for representing queue sizes.
Definition: queue-size.h:96
static Time Max()
Maximum representable Time Not to be confused with Max(Time,Time).
Definition: nstime.h:297
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
Hold an unsigned integer type.
Definition: uinteger.h:45
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:261
@ INACTIVE
Inactive Period or unslotted CSMA-CA.
Definition: lr-wpan-mac.h:104
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
QueueSizeUnit
Enumeration of the operating modes of queues.
Definition: queue-size.h:44
@ PACKETS
Use number of packets for queue size.
Definition: queue-size.h:45
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
QueueDiscSizePolicy
Enumeration of the available policies to handle the queue disc size.
Definition: queue-disc.h:107
@ MULTIPLE_QUEUES
Used by queue discs with multiple internal queues/child queue discs.
Definition: queue-disc.h:110
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Definition: nstime.h:1414
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:533
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:86
Ptr< const AttributeAccessor > MakeDoubleAccessor(T1 a1)
Definition: double.h:43
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46