A Discrete-Event Network Simulator
API
fq-codel-queue-disc-test-suite.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2016 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: Pasquale Imputato <p.imputato@gmail.com>
19  * Stefano Avallone <stefano.avallone@unina.it>
20 */
21 
22 #include "ns3/test.h"
23 #include "ns3/simulator.h"
24 #include "ns3/fq-codel-queue-disc.h"
25 #include "ns3/codel-queue-disc.h"
26 #include "ns3/ipv4-header.h"
27 #include "ns3/ipv4-packet-filter.h"
28 #include "ns3/ipv4-queue-disc-item.h"
29 #include "ns3/ipv4-address.h"
30 #include "ns3/ipv6-header.h"
31 #include "ns3/ipv6-packet-filter.h"
32 #include "ns3/ipv6-queue-disc-item.h"
33 #include "ns3/tcp-header.h"
34 #include "ns3/udp-header.h"
35 #include "ns3/string.h"
36 #include "ns3/pointer.h"
37 
38 using namespace ns3;
39 
40 // Variable to assign hash to a new packet's flow
41 int32_t hash;
42 
48 public:
53  static TypeId GetTypeId (void);
54 
56  virtual ~Ipv4TestPacketFilter ();
57 
58 private:
59  virtual int32_t DoClassify (Ptr<QueueDiscItem> item) const;
60  virtual bool CheckProtocol (Ptr<QueueDiscItem> item) const;
61 };
62 
63 TypeId
65 {
66  static TypeId tid = TypeId ("ns3::Ipv4TestPacketFilter")
68  .SetGroupName ("Internet")
69  .AddConstructor<Ipv4TestPacketFilter> ()
70  ;
71  return tid;
72 }
73 
75 {
76 }
77 
79 {
80 }
81 
82 int32_t
84 {
85  return hash;
86 }
87 
88 bool
90 {
91  return true;
92 }
93 
98 {
99 public:
102 
103 private:
104  virtual void DoRun (void);
105 };
106 
108  : TestCase ("Test packets that are not classified by any filter")
109 {
110 }
111 
113 {
114 }
115 
116 void
118 {
119  // Packets that cannot be classified by the available filters should be dropped
120  Ptr<FqCoDelQueueDisc> queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc> ("MaxSize", StringValue ("4p"));
121  Ptr<Ipv4TestPacketFilter> filter = CreateObject<Ipv4TestPacketFilter> ();
122  queueDisc->AddPacketFilter (filter);
123 
124  hash = -1;
125  queueDisc->SetQuantum (1500);
126  queueDisc->Initialize ();
127 
128  Ptr<Packet> p;
129  p = Create<Packet> ();
131  Ipv6Header ipv6Header;
132  Address dest;
133  item = Create<Ipv6QueueDiscItem> (p, dest, 0, ipv6Header);
134  queueDisc->Enqueue (item);
135  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetNQueueDiscClasses (), 0, "no flow queue should have been created");
136 
137  p = Create<Packet> (reinterpret_cast<const uint8_t*> ("hello, world"), 12);
138  item = Create<Ipv6QueueDiscItem> (p, dest, 0, ipv6Header);
139  queueDisc->Enqueue (item);
140  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetNQueueDiscClasses (), 0, "no flow queue should have been created");
141 
142  Simulator::Destroy ();
143 }
144 
149 {
150 public:
153 
154 private:
155  virtual void DoRun (void);
156  void AddPacket (Ptr<FqCoDelQueueDisc> queue, Ipv4Header hdr);
157 };
158 
160  : TestCase ("Test IP flows separation and packet limit")
161 {
162 }
163 
165 {
166 }
167 
168 void
170 {
171  Ptr<Packet> p = Create<Packet> (100);
172  Address dest;
173  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, hdr);
174  queue->Enqueue (item);
175 }
176 
177 void
179 {
180  Ptr<FqCoDelQueueDisc> queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc> ("MaxSize", StringValue ("4p"));
181 
182  queueDisc->SetQuantum (1500);
183  queueDisc->Initialize ();
184 
185  Ipv4Header hdr;
186  hdr.SetPayloadSize (100);
187  hdr.SetSource (Ipv4Address ("10.10.1.1"));
188  hdr.SetDestination (Ipv4Address ("10.10.1.2"));
189  hdr.SetProtocol (7);
190 
191  // Add three packets from the first flow
192  AddPacket (queueDisc, hdr);
193  AddPacket (queueDisc, hdr);
194  AddPacket (queueDisc, hdr);
195  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 3, "unexpected number of packets in the queue disc");
196  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the flow queue");
197 
198  // Add two packets from the second flow
199  hdr.SetDestination (Ipv4Address ("10.10.1.7"));
200  // Add the first packet
201  AddPacket (queueDisc, hdr);
202  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 4, "unexpected number of packets in the queue disc");
203  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the flow queue");
204  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the flow queue");
205  // Add the second packet that causes two packets to be dropped from the fat flow (max backlog = 300, threshold = 150)
206  AddPacket (queueDisc, hdr);
207  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 3, "unexpected number of packets in the queue disc");
208  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the flow queue");
209  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the flow queue");
210 
211  Simulator::Destroy ();
212 }
213 
218 {
219 public:
221  virtual ~FqCoDelQueueDiscDeficit ();
222 
223 private:
224  virtual void DoRun (void);
225  void AddPacket (Ptr<FqCoDelQueueDisc> queue, Ipv4Header hdr);
226 };
227 
229  : TestCase ("Test credits and flows status")
230 {
231 }
232 
234 {
235 }
236 
237 void
239 {
240  Ptr<Packet> p = Create<Packet> (100);
241  Address dest;
242  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, hdr);
243  queue->Enqueue (item);
244 }
245 
246 void
248 {
249  Ptr<FqCoDelQueueDisc> queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc> ();
250 
251  queueDisc->SetQuantum (90);
252  queueDisc->Initialize ();
253 
254  Ipv4Header hdr;
255  hdr.SetPayloadSize (100);
256  hdr.SetSource (Ipv4Address ("10.10.1.1"));
257  hdr.SetDestination (Ipv4Address ("10.10.1.2"));
258  hdr.SetProtocol (7);
259 
260  // Add a packet from the first flow
261  AddPacket (queueDisc, hdr);
262  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 1, "unexpected number of packets in the queue disc");
263  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the first flow queue");
264  Ptr<FqCoDelFlow> flow1 = StaticCast<FqCoDelFlow> (queueDisc->GetQueueDiscClass (0));
265  NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), static_cast<int32_t> (queueDisc->GetQuantum ()), "the deficit of the first flow must equal the quantum");
266  NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqCoDelFlow::NEW_FLOW, "the first flow must be in the list of new queues");
267  // Dequeue a packet
268  queueDisc->Dequeue ();
269  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 0, "unexpected number of packets in the queue disc");
270  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 0, "unexpected number of packets in the first flow queue");
271  // the deficit for the first flow becomes 90 - (100+20) = -30
272  NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), -30, "unexpected deficit for the first flow");
273 
274  // Add two packets from the first flow
275  AddPacket (queueDisc, hdr);
276  AddPacket (queueDisc, hdr);
277  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 2, "unexpected number of packets in the queue disc");
278  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the first flow queue");
279  NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqCoDelFlow::NEW_FLOW, "the first flow must still be in the list of new queues");
280 
281  // Add two packets from the second flow
282  hdr.SetDestination (Ipv4Address ("10.10.1.10"));
283  AddPacket (queueDisc, hdr);
284  AddPacket (queueDisc, hdr);
285  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 4, "unexpected number of packets in the queue disc");
286  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the first flow queue");
287  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the second flow queue");
288  Ptr<FqCoDelFlow> flow2 = StaticCast<FqCoDelFlow> (queueDisc->GetQueueDiscClass (1));
289  NS_TEST_ASSERT_MSG_EQ (flow2->GetDeficit (), static_cast<int32_t> (queueDisc->GetQuantum ()), "the deficit of the second flow must equal the quantum");
290  NS_TEST_ASSERT_MSG_EQ (flow2->GetStatus (), FqCoDelFlow::NEW_FLOW, "the second flow must be in the list of new queues");
291 
292  // Dequeue a packet (from the second flow, as the first flow has a negative deficit)
293  queueDisc->Dequeue ();
294  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 3, "unexpected number of packets in the queue disc");
295  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the first flow queue");
296  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
297  // the first flow got a quantum of deficit (-30+90=60) and has been moved to the end of the list of old queues
298  NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), 60, "unexpected deficit for the first flow");
299  NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqCoDelFlow::OLD_FLOW, "the first flow must be in the list of old queues");
300  // the second flow has a negative deficit (-30) and is still in the list of new queues
301  NS_TEST_ASSERT_MSG_EQ (flow2->GetDeficit (), -30, "unexpected deficit for the second flow");
302  NS_TEST_ASSERT_MSG_EQ (flow2->GetStatus (), FqCoDelFlow::NEW_FLOW, "the second flow must be in the list of new queues");
303 
304  // Dequeue a packet (from the first flow, as the second flow has a negative deficit)
305  queueDisc->Dequeue ();
306  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 2, "unexpected number of packets in the queue disc");
307  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the first flow queue");
308  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
309  // the first flow has a negative deficit (60-(100+20)= -60) and stays in the list of old queues
310  NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), -60, "unexpected deficit for the first flow");
311  NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqCoDelFlow::OLD_FLOW, "the first flow must be in the list of old queues");
312  // the second flow got a quantum of deficit (-30+90=60) and has been moved to the end of the list of old queues
313  NS_TEST_ASSERT_MSG_EQ (flow2->GetDeficit (), 60, "unexpected deficit for the second flow");
314  NS_TEST_ASSERT_MSG_EQ (flow2->GetStatus (), FqCoDelFlow::OLD_FLOW, "the second flow must be in the list of new queues");
315 
316  // Dequeue a packet (from the second flow, as the first flow has a negative deficit)
317  queueDisc->Dequeue ();
318  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 1, "unexpected number of packets in the queue disc");
319  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the first flow queue");
320  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 0, "unexpected number of packets in the second flow queue");
321  // the first flow got a quantum of deficit (-60+90=30) and has been moved to the end of the list of old queues
322  NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), 30, "unexpected deficit for the first flow");
323  NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqCoDelFlow::OLD_FLOW, "the first flow must be in the list of old queues");
324  // the second flow has a negative deficit (60-(100+20)= -60)
325  NS_TEST_ASSERT_MSG_EQ (flow2->GetDeficit (), -60, "unexpected deficit for the second flow");
326  NS_TEST_ASSERT_MSG_EQ (flow2->GetStatus (), FqCoDelFlow::OLD_FLOW, "the second flow must be in the list of new queues");
327 
328  // Dequeue a packet (from the first flow, as the second flow has a negative deficit)
329  queueDisc->Dequeue ();
330  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 0, "unexpected number of packets in the queue disc");
331  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 0, "unexpected number of packets in the first flow queue");
332  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 0, "unexpected number of packets in the second flow queue");
333  // the first flow has a negative deficit (30-(100+20)= -90)
334  NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), -90, "unexpected deficit for the first flow");
335  NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqCoDelFlow::OLD_FLOW, "the first flow must be in the list of old queues");
336  // the second flow got a quantum of deficit (-60+90=30) and has been moved to the end of the list of old queues
337  NS_TEST_ASSERT_MSG_EQ (flow2->GetDeficit (), 30, "unexpected deficit for the second flow");
338  NS_TEST_ASSERT_MSG_EQ (flow2->GetStatus (), FqCoDelFlow::OLD_FLOW, "the second flow must be in the list of new queues");
339 
340  // Dequeue a packet
341  queueDisc->Dequeue ();
342  // the first flow is at the head of the list of old queues but has a negative deficit, thus it gets a quantun
343  // of deficit (-90+90=0) and is moved to the end of the list of old queues. Then, the second flow (which has a
344  // positive deficit) is selected, but the second flow is empty and thus it is set to inactive. The first flow is
345  // reconsidered, but it has a null deficit, hence it gets another quantum of deficit (0+90=90). Then, the first
346  // flow is reconsidered again, now it has a positive deficit and hence it is selected. But, it is empty and
347  // therefore is set to inactive, too.
348  NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), 90, "unexpected deficit for the first flow");
349  NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqCoDelFlow::INACTIVE, "the first flow must be inactive");
350  NS_TEST_ASSERT_MSG_EQ (flow2->GetDeficit (), 30, "unexpected deficit for the second flow");
351  NS_TEST_ASSERT_MSG_EQ (flow2->GetStatus (), FqCoDelFlow::INACTIVE, "the second flow must be inactive");
352 
353  Simulator::Destroy ();
354 }
355 
360 {
361 public:
364 
365 private:
366  virtual void DoRun (void);
367  void AddPacket (Ptr<FqCoDelQueueDisc> queue, Ipv4Header ipHdr, TcpHeader tcpHdr);
368 };
369 
371  : TestCase ("Test TCP flows separation")
372 {
373 }
374 
376 {
377 }
378 
379 void
381 {
382  Ptr<Packet> p = Create<Packet> (100);
383  p->AddHeader (tcpHdr);
384  Address dest;
385  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, ipHdr);
386  queue->Enqueue (item);
387 }
388 
389 void
391 {
392  Ptr<FqCoDelQueueDisc> queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc> ("MaxSize", StringValue ("10p"));
393 
394  queueDisc->SetQuantum (1500);
395  queueDisc->Initialize ();
396 
397  Ipv4Header hdr;
398  hdr.SetPayloadSize (100);
399  hdr.SetSource (Ipv4Address ("10.10.1.1"));
400  hdr.SetDestination (Ipv4Address ("10.10.1.2"));
401  hdr.SetProtocol (6);
402 
403  TcpHeader tcpHdr;
404  tcpHdr.SetSourcePort (7);
405  tcpHdr.SetDestinationPort (27);
406 
407  // Add three packets from the first flow
408  AddPacket (queueDisc, hdr, tcpHdr);
409  AddPacket (queueDisc, hdr, tcpHdr);
410  AddPacket (queueDisc, hdr, tcpHdr);
411  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 3, "unexpected number of packets in the queue disc");
412  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
413 
414  // Add a packet from the second flow
415  tcpHdr.SetSourcePort (8);
416  AddPacket (queueDisc, hdr, tcpHdr);
417  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 4, "unexpected number of packets in the queue disc");
418  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
419  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
420 
421  // Add a packet from the third flow
422  tcpHdr.SetDestinationPort (28);
423  AddPacket (queueDisc, hdr, tcpHdr);
424  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 5, "unexpected number of packets in the queue disc");
425  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
426  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
427  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the third flow queue");
428 
429  // Add two packets from the fourth flow
430  tcpHdr.SetSourcePort (7);
431  AddPacket (queueDisc, hdr, tcpHdr);
432  AddPacket (queueDisc, hdr, tcpHdr);
433  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 7, "unexpected number of packets in the queue disc");
434  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
435  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
436  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the third flow queue");
437  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (3)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the third flow queue");
438 
439  Simulator::Destroy ();
440 }
441 
446 {
447 public:
450 
451 private:
452  virtual void DoRun (void);
453  void AddPacket (Ptr<FqCoDelQueueDisc> queue, Ipv4Header ipHdr, UdpHeader udpHdr);
454 };
455 
457  : TestCase ("Test UDP flows separation")
458 {
459 }
460 
462 {
463 }
464 
465 void
467 {
468  Ptr<Packet> p = Create<Packet> (100);
469  p->AddHeader (udpHdr);
470  Address dest;
471  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, ipHdr);
472  queue->Enqueue (item);
473 }
474 
475 void
477 {
478  Ptr<FqCoDelQueueDisc> queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc> ("MaxSize", StringValue ("10p"));
479 
480  queueDisc->SetQuantum (1500);
481  queueDisc->Initialize ();
482 
483  Ipv4Header hdr;
484  hdr.SetPayloadSize (100);
485  hdr.SetSource (Ipv4Address ("10.10.1.1"));
486  hdr.SetDestination (Ipv4Address ("10.10.1.2"));
487  hdr.SetProtocol (17);
488 
489  UdpHeader udpHdr;
490  udpHdr.SetSourcePort (7);
491  udpHdr.SetDestinationPort (27);
492 
493  // Add three packets from the first flow
494  AddPacket (queueDisc, hdr, udpHdr);
495  AddPacket (queueDisc, hdr, udpHdr);
496  AddPacket (queueDisc, hdr, udpHdr);
497  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 3, "unexpected number of packets in the queue disc");
498  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
499 
500  // Add a packet from the second flow
501  udpHdr.SetSourcePort (8);
502  AddPacket (queueDisc, hdr, udpHdr);
503  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 4, "unexpected number of packets in the queue disc");
504  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
505  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
506 
507  // Add a packet from the third flow
508  udpHdr.SetDestinationPort (28);
509  AddPacket (queueDisc, hdr, udpHdr);
510  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 5, "unexpected number of packets in the queue disc");
511  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
512  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
513  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the third flow queue");
514 
515  // Add two packets from the fourth flow
516  udpHdr.SetSourcePort (7);
517  AddPacket (queueDisc, hdr, udpHdr);
518  AddPacket (queueDisc, hdr, udpHdr);
519  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 7, "unexpected number of packets in the queue disc");
520  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
521  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
522  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the third flow queue");
523  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (3)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the third flow queue");
524 
525  Simulator::Destroy ();
526 }
527 
533 {
534 public:
536  virtual ~FqCoDelQueueDiscECNMarking ();
537 
538 private:
539  virtual void DoRun (void);
540  void AddPacket (Ptr<FqCoDelQueueDisc> queue, Ipv4Header hdr, u_int32_t nPkt, u_int32_t nPktEnqueued, u_int32_t nQueueFlows);
541  void Dequeue (Ptr<FqCoDelQueueDisc> queue, uint32_t nPkt);
542  void DequeueWithDelay (Ptr<FqCoDelQueueDisc> queue, double delay, uint32_t nPkt);
543 };
544 
546  : TestCase ("Test ECN marking")
547 {
548 }
549 
551 {
552 }
553 
554 void
555 FqCoDelQueueDiscECNMarking::AddPacket (Ptr<FqCoDelQueueDisc> queue, Ipv4Header hdr, u_int32_t nPkt, u_int32_t nPktEnqueued, u_int32_t nQueueFlows)
556 {
557  Address dest;
558  Ptr<Packet> p = Create<Packet> (100);
559  for (uint32_t i = 0; i < nPkt; i++)
560  {
561  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, hdr);
562  queue->Enqueue (item);
563  }
564  NS_TEST_EXPECT_MSG_EQ (queue->GetNQueueDiscClasses (), nQueueFlows, "unexpected number of flow queues");
565  NS_TEST_EXPECT_MSG_EQ (queue->GetNPackets (), nPktEnqueued, "unexpected number of enqueued packets");
566 }
567 
568 void
570 {
571  for (uint32_t i = 0; i < nPkt; i++)
572  {
573  Ptr<QueueDiscItem> item = queue->Dequeue ();
574  }
575 }
576 
577 void
579 {
580  for (uint32_t i = 0; i < nPkt; i++)
581  {
582  Simulator::Schedule (Time (Seconds ((i + 1) * delay)), &FqCoDelQueueDiscECNMarking::Dequeue, this, queue, 1);
583  }
584 }
585 
586 void
588 {
589  // Test is divided into 3 sub test cases:
590  // 1) CeThreshold disabled
591  // 2) CeThreshold enabled
592  // 3) Same as 2 but with higher queue delay, leading to both mark types, and checks that the same packet is not marked twice
593 
594  // Test case 1, CeThreshold disabled
595  Ptr<FqCoDelQueueDisc> queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc> ("MaxSize", StringValue ("10240p"), "UseEcn", BooleanValue (true),
596  "Perturbation", UintegerValue (0));
597 
598  queueDisc->SetQuantum (1514);
599  queueDisc->Initialize ();
600  Ipv4Header hdr;
601  hdr.SetPayloadSize (100);
602  hdr.SetSource (Ipv4Address ("10.10.1.1"));
603  hdr.SetDestination (Ipv4Address ("10.10.1.2"));
604  hdr.SetProtocol (7);
605  hdr.SetEcn (Ipv4Header::ECN_ECT0);
606 
607  // Add 20 ECT0 (ECN capable) packets from the first flow
608  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 20, 1);
609 
610  // Add 20 ECT0 (ECN capable) packets from second flow
611  hdr.SetDestination (Ipv4Address ("10.10.1.10"));
612  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 40, 2);
613 
614  // Add 20 ECT0 (ECN capable) packets from third flow
615  hdr.SetDestination (Ipv4Address ("10.10.1.20"));
616  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 60, 3);
617 
618  // Add 20 NotECT packets from fourth flow
619  hdr.SetDestination (Ipv4Address ("10.10.1.30"));
620  hdr.SetEcn (Ipv4Header::ECN_NotECT);
621  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 80, 4);
622 
623  // Add 20 NotECT packets from fifth flow
624  hdr.SetDestination (Ipv4Address ("10.10.1.40"));
625  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 100, 5);
626 
627  //Dequeue 60 packets with delay 110ms to induce packet drops and keep some remaining packets in each queue
628  DequeueWithDelay (queueDisc, 0.11, 60);
629  Simulator::Run ();
630  Simulator::Stop (Seconds (8.0));
631  Ptr<CoDelQueueDisc> q0 = queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
632  Ptr<CoDelQueueDisc> q1 = queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
633  Ptr<CoDelQueueDisc> q2 = queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
634  Ptr<CoDelQueueDisc> q3 = queueDisc->GetQueueDiscClass (3)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
635  Ptr<CoDelQueueDisc> q4 = queueDisc->GetQueueDiscClass (4)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
636 
637 
638  //Ensure there are some remaining packets in the flow queues to check for flow queues with ECN capable packets
639  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
640  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
641  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
642  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (3)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
643  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (4)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
644 
645  // As packets in flow queues are ECN capable
646  NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK), 6, "There should be 6 marked packets"
647  "with 20 packets, total bytes in the queue = 120 * 20 = 2400. First packet dequeues at 110ms which is greater than"
648  "test's default target value 5ms. Sojourn time has just gone above target from below, need to stay above for at"
649  "least q->interval before packet can be dropped. Second packet dequeues at 220ms which is greater than last dequeue"
650  "time plus q->interval(test default 100ms) so the packet is marked. Third packet dequeues at 330ms and the sojourn"
651  "time stayed above the target and dropnext value is less than 320 hence the packet is marked. 4 subsequent packets"
652  "are marked as the sojourn time stays above the target. With 8th dequeue number of bytes in queue = 120 * 12 = 1440"
653  "which is less m_minBytes(test's default value 1500 bytes) hence the packets stop getting marked");
654  NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
655  NS_TEST_EXPECT_MSG_EQ (q1->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK), 6, "There should be 6 marked packets");
656  NS_TEST_EXPECT_MSG_EQ (q1->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
657  NS_TEST_EXPECT_MSG_EQ (q2->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK), 6, "There should be 6 marked packets");
658  NS_TEST_EXPECT_MSG_EQ (q2->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
659 
660  // As packets in flow queues are not ECN capable
661  NS_TEST_EXPECT_MSG_EQ (q3->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 4, "There should be 4 dropped packets"
662  "with 20 packets, total bytes in the queue = 120 * 20 = 2400. First packet dequeues at 110ms which is greater than"
663  "test's default target value 5ms. Sojourn time has just gone above target from below, need to stay above for at"
664  "least q->interval before packet can be dropped. Second packet dequeues at 220ms which is greater than last dequeue"
665  "time plus q->interval(test default 100ms) so packet is dropped and next is dequeued. 4th packet dequeues at 330ms"
666  "and the sojourn time stayed above the target and dropnext value is less than 320 hence the packet is dropped and next"
667  "packet is dequeued. 6th packet dequeues at 440ms and 2 more packets are dropped as dropnext value is increased twice."
668  "12 Packets remaining in the queue, total number of bytes int the queue = 120 * 12 = 1440 which is less"
669  "m_minBytes(test's default value 1500 bytes) hence the packets stop getting dropped");
670  NS_TEST_EXPECT_MSG_EQ (q3->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK), 0, "There should not be any marked packets");
671  NS_TEST_EXPECT_MSG_EQ (q4->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 4, "There should be 4 dropped packets");
672  NS_TEST_EXPECT_MSG_EQ (q4->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK), 0, "There should not be any marked packets");
673  // Ensure flow queue 0,1 and 2 have ECN capable packets
674  // Peek () changes the stats of the queue and that is reason to be keep this test at last
675  Ptr<const Ipv4QueueDiscItem> pktQ0 = DynamicCast<const Ipv4QueueDiscItem> (q0->Peek ());
676  NS_TEST_EXPECT_MSG_NE (pktQ0->GetHeader ().GetEcn (), Ipv4Header::ECN_NotECT,"flow queue should have ECT0 packets");
677  Ptr<const Ipv4QueueDiscItem> pktQ1 = DynamicCast<const Ipv4QueueDiscItem> (q1->Peek ());
678  NS_TEST_EXPECT_MSG_NE (pktQ1->GetHeader ().GetEcn (), Ipv4Header::ECN_NotECT,"flow queue should have ECT0 packets");
679  Ptr<const Ipv4QueueDiscItem> pktQ2 = DynamicCast<const Ipv4QueueDiscItem> (q2->Peek ());
680  NS_TEST_EXPECT_MSG_NE (pktQ2->GetHeader ().GetEcn (), Ipv4Header::ECN_NotECT,"flow queue should have ECT0 packets");
681 
682  Simulator::Destroy ();
683 
684  // Test case 2, CeThreshold set to 2ms
685  queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc> ("MaxSize", StringValue ("10240p"), "UseEcn", BooleanValue (true),
686  "CeThreshold", TimeValue (MilliSeconds (2)));
687  queueDisc->SetQuantum (1514);
688  queueDisc->Initialize ();
689 
690  // Add 20 ECT0 (ECN capable) packets from first flow
691  hdr.SetDestination (Ipv4Address ("10.10.1.2"));
692  hdr.SetEcn (Ipv4Header::ECN_ECT0);
693  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 20, 1);
694 
695  // Add 20 ECT0 (ECN capable) packets from second flow
696  hdr.SetDestination (Ipv4Address ("10.10.1.10"));
697  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 40, 2);
698 
699  // Add 20 ECT0 (ECN capable) packets from third flow
700  hdr.SetDestination (Ipv4Address ("10.10.1.20"));
701  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 60, 3);
702 
703  // Add 20 NotECT packets from fourth flow
704  hdr.SetDestination (Ipv4Address ("10.10.1.30"));
705  hdr.SetEcn (Ipv4Header::ECN_NotECT);
706  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 80, 4);
707 
708  // Add 20 NotECT packets from fifth flow
709  hdr.SetDestination (Ipv4Address ("10.10.1.40"));
710  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 100, 5);
711 
712  //Dequeue 60 packets with delay 0.1ms to induce packet drops and keep some remaining packets in each queue
713  DequeueWithDelay (queueDisc, 0.0001, 60);
714  Simulator::Run ();
715  Simulator::Stop (Seconds (8.0));
716  q0 = queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
717  q1 = queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
718  q2 = queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
719  q3 = queueDisc->GetQueueDiscClass (3)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
720  q4 = queueDisc->GetQueueDiscClass (4)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
721 
722  //Ensure there are some remaining packets in the flow queues to check for flow queues with ECN capable packets
723  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
724  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
725  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
726  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (3)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
727  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (4)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
728 
729  // As packets in flow queues are ECN capable
730  NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
731  NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK), 0, "There should not be any marked packets"
732  "with quantum of 1514, 13 packets of size 120 bytes can be dequeued. sojourn time of 13th packet is 1.3ms which is"
733  "less than CE threshold");
734  NS_TEST_EXPECT_MSG_EQ (q1->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
735  NS_TEST_EXPECT_MSG_EQ (q1->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK), 6, "There should be 6 marked packets"
736  "with quantum of 1514, 13 packets of size 120 bytes can be dequeued. sojourn time of 8th packet is 2.1ms which is greater"
737  "than CE threshold and subsequent packet also have sojourn time more 8th packet hence remaining packet are marked.");
738  NS_TEST_EXPECT_MSG_EQ (q2->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
739  NS_TEST_EXPECT_MSG_EQ (q2->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK), 13, "There should be 13 marked packets"
740  "with quantum of 1514, 13 packets of size 120 bytes can be dequeued and all of them have sojourn time more than CE threshold");
741 
742  // As packets in flow queues are not ECN capable
743  NS_TEST_EXPECT_MSG_EQ (q3->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK), 0, "There should not be any marked packets");
744  NS_TEST_EXPECT_MSG_EQ (q3->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
745  NS_TEST_EXPECT_MSG_EQ (q4->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK), 0, "There should not be any marked packets");
746  NS_TEST_EXPECT_MSG_EQ (q4->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
747 
748  // Ensure flow queue 0,1 and 2 have ECN capable packets
749  // Peek () changes the stats of the queue and that is reason to be keep this test at last
750  pktQ0 = DynamicCast<const Ipv4QueueDiscItem> (q0->Peek ());
751  NS_TEST_EXPECT_MSG_NE (pktQ0->GetHeader ().GetEcn (), Ipv4Header::ECN_NotECT,"flow queue should have ECT0 packets");
752  pktQ1 = DynamicCast<const Ipv4QueueDiscItem> (q1->Peek ());
753  NS_TEST_EXPECT_MSG_NE (pktQ1->GetHeader ().GetEcn (), Ipv4Header::ECN_NotECT,"flow queue should have ECT0 packets");
754  pktQ2 = DynamicCast<const Ipv4QueueDiscItem> (q2->Peek ());
755  NS_TEST_EXPECT_MSG_NE (pktQ2->GetHeader ().GetEcn (), Ipv4Header::ECN_NotECT,"flow queue should have ECT0 packets");
756 
757  Simulator::Destroy ();
758 
759  // Test case 3, CeThreshold set to 2ms with higher queue delay
760  queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc> ("MaxSize", StringValue ("10240p"), "UseEcn", BooleanValue (true),
761  "CeThreshold", TimeValue (MilliSeconds (2)));
762  queueDisc->SetQuantum (1514);
763  queueDisc->Initialize ();
764 
765  // Add 20 ECT0 (ECN capable) packets from first flow
766  hdr.SetDestination (Ipv4Address ("10.10.1.2"));
767  hdr.SetEcn (Ipv4Header::ECN_ECT0);
768  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 20, 1);
769 
770  // Add 20 ECT0 (ECN capable) packets from second flow
771  hdr.SetDestination (Ipv4Address ("10.10.1.10"));
772  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 40, 2);
773 
774  // Add 20 ECT0 (ECN capable) packets from third flow
775  hdr.SetDestination (Ipv4Address ("10.10.1.20"));
776  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 60, 3);
777 
778  // Add 20 NotECT packets from fourth flow
779  hdr.SetDestination (Ipv4Address ("10.10.1.30"));
780  hdr.SetEcn (Ipv4Header::ECN_NotECT);
781  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 80, 4);
782 
783  // Add 20 NotECT packets from fifth flow
784  hdr.SetDestination (Ipv4Address ("10.10.1.40"));
785  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 100, 5);
786 
787  //Dequeue 60 packets with delay 110ms to induce packet drops and keep some remaining packets in each queue
788  DequeueWithDelay (queueDisc, 0.110, 60);
789  Simulator::Run ();
790  Simulator::Stop (Seconds (8.0));
791  q0 = queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
792  q1 = queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
793  q2 = queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
794  q3 = queueDisc->GetQueueDiscClass (3)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
795  q4 = queueDisc->GetQueueDiscClass (4)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
796 
797  //Ensure there are some remaining packets in the flow queues to check for flow queues with ECN capable packets
798  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
799  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
800  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
801  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (3)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
802  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (4)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
803 
804  // As packets in flow queues are ECN capable
805  NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
806  NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK) +
807  q0->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK), 20 - q0->GetNPackets (), "Number of CE threshold"
808  " exceeded marks plus Number of Target exceeded marks should be equal to total number of packets dequeued");
809  NS_TEST_EXPECT_MSG_EQ (q1->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
810  NS_TEST_EXPECT_MSG_EQ (q1->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK) +
811  q1->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK), 20 - q1->GetNPackets (), "Number of CE threshold"
812  " exceeded marks plus Number of Target exceeded marks should be equal to total number of packets dequeued");
813  NS_TEST_EXPECT_MSG_EQ (q2->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
814  NS_TEST_EXPECT_MSG_EQ (q2->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK) +
815  q2->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK), 20 - q2->GetNPackets (), "Number of CE threshold"
816  " exceeded marks plus Number of Target exceeded marks should be equal to total number of packets dequeued");
817 
818  // As packets in flow queues are not ECN capable
819  NS_TEST_EXPECT_MSG_EQ (q3->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK), 0, "There should not be any marked packets");
820  NS_TEST_EXPECT_MSG_EQ (q3->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 4, "There should be 4 dropped packets"
821  " As queue delay is same as in test case 1, number of dropped packets should also be same");
822  NS_TEST_EXPECT_MSG_EQ (q4->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK), 0, "There should not be any marked packets");
823  NS_TEST_EXPECT_MSG_EQ (q4->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 4, "There should be 4 dropped packets");
824 
825  // Ensure flow queue 0,1 and 2 have ECN capable packets
826  // Peek () changes the stats of the queue and that is reason to be keep this test at last
827  pktQ0 = DynamicCast<const Ipv4QueueDiscItem> (q0->Peek ());
828  NS_TEST_EXPECT_MSG_NE (pktQ0->GetHeader ().GetEcn (), Ipv4Header::ECN_NotECT,"flow queue should have ECT0 packets");
829  pktQ1 = DynamicCast<const Ipv4QueueDiscItem> (q1->Peek ());
830  NS_TEST_EXPECT_MSG_NE (pktQ1->GetHeader ().GetEcn (), Ipv4Header::ECN_NotECT,"flow queue should have ECT0 packets");
831  pktQ2 = DynamicCast<const Ipv4QueueDiscItem> (q2->Peek ());
832  NS_TEST_EXPECT_MSG_NE (pktQ2->GetHeader ().GetEcn (), Ipv4Header::ECN_NotECT,"flow queue should have ECT0 packets");
833 
834  Simulator::Destroy ();
835 }
836 
837 /*
838  * This class tests linear probing, collision response, and set
839  * creation capability of set associative hashing in FqCodel.
840  * We modified DoClassify () and CheckProtocol () so that we could control
841  * the hash returned for each packet. In the beginning, we use flow hashes
842  * ranging from 0 to 7. These must go into different queues in the same set.
843  * The set number for these is obtained using outerHash, which is 0.
844  * When a new packet arrives with flow hash 1024, outerHash = 0 is obtained
845  * and the first set is iteratively searched.
846  * The packet is eventually added to queue 0 since the tags of queues
847  * in the set do not match with the hash of the flow. The tag of queue 0 is
848  * updated as 1024. When a packet with hash 1025 arrives, outerHash = 0
849  * is obtained and the first set is iteratively searched.
850  * Since there is no match, it is added to queue 0 and the tag of queue 0 is
851  * updated to 1025.
852  *
853  * The variable outerHash stores the nearest multiple of 8 that is lesser than
854  * the hash. When a flow hash of 20 arrives, the value of outerHash
855  * is 16. Since m_flowIndices[16] wasn’t previously allotted, a new flow
856  * is created, and the tag corresponding to this queue is set to 20.
857 */
858 
860 {
861 public:
864 private:
865  virtual void DoRun (void);
866  void AddPacket (Ptr<FqCoDelQueueDisc> queue, Ipv4Header hdr);
867 };
868 
870  : TestCase ("Test credits and flows status")
871 {
872 }
873 
875 {
876 }
877 
878 void
880 {
881  Ptr<Packet> p = Create<Packet> (100);
882  Address dest;
883  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, hdr);
884  queue->Enqueue (item);
885 }
886 
887 void
889 {
890  Ptr<FqCoDelQueueDisc> queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc> ("EnableSetAssociativeHash", BooleanValue (true));
891  queueDisc->SetQuantum (90);
892  queueDisc->Initialize ();
893 
894  Ptr<Ipv4TestPacketFilter> filter = CreateObject<Ipv4TestPacketFilter> ();
895  queueDisc->AddPacketFilter (filter);
896 
897  Ipv4Header hdr;
898  hdr.SetPayloadSize (100);
899  hdr.SetSource (Ipv4Address ("10.10.1.1"));
900  hdr.SetDestination (Ipv4Address ("10.10.1.2"));
901  hdr.SetProtocol (7);
902 
903  hash = 0;
904  AddPacket (queueDisc, hdr);
905  hash = 1;
906  AddPacket (queueDisc, hdr);
907  AddPacket (queueDisc, hdr);
908  hash = 2;
909  AddPacket (queueDisc, hdr);
910  hash = 3;
911  AddPacket (queueDisc, hdr);
912  hash = 4;
913  AddPacket (queueDisc, hdr);
914  AddPacket (queueDisc, hdr);
915  hash = 5;
916  AddPacket (queueDisc, hdr);
917  hash = 6;
918  AddPacket (queueDisc, hdr);
919  hash = 7;
920  AddPacket (queueDisc, hdr);
921  hash = 1024;
922  AddPacket (queueDisc, hdr);
923 
924  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 11,
925  "unexpected number of packets in the queue disc");
926  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 2,
927  "unexpected number of packets in the first flow queue of set one");
928  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 2,
929  "unexpected number of packets in the second flow queue of set one");
930  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetNPackets (), 1,
931  "unexpected number of packets in the third flow queue of set one");
932  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (3)->GetQueueDisc ()->GetNPackets (), 1,
933  "unexpected number of packets in the fourth flow queue of set one");
934  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (4)->GetQueueDisc ()->GetNPackets (), 2,
935  "unexpected number of packets in the fifth flow queue of set one");
936  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (5)->GetQueueDisc ()->GetNPackets (), 1,
937  "unexpected number of packets in the sixth flow queue of set one");
938  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (6)->GetQueueDisc ()->GetNPackets (), 1,
939  "unexpected number of packets in the seventh flow queue of set one");
940  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (7)->GetQueueDisc ()->GetNPackets (), 1,
941  "unexpected number of packets in the eighth flow queue of set one");
942  hash = 1025;
943  AddPacket (queueDisc, hdr);
944  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3,
945  "unexpected number of packets in the first flow of set one");
946  hash = 10;
947  AddPacket (queueDisc, hdr);
948  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (8)->GetQueueDisc ()->GetNPackets (), 1,
949  "unexpected number of packets in the first flow of set two");
950  Simulator::Destroy ();
951 }
952 
953 
959 {
960 public:
962  virtual ~FqCoDelQueueDiscL4sMode ();
963 
964 private:
965  virtual void DoRun (void);
966  void AddPacket (Ptr<FqCoDelQueueDisc> queue, Ipv4Header hdr, u_int32_t nPkt);
967  void AddPacketWithDelay (Ptr<FqCoDelQueueDisc> queue,Ipv4Header hdr, double delay, uint32_t nPkt);
968  void Dequeue (Ptr<FqCoDelQueueDisc> queue, uint32_t nPkt);
969  void DequeueWithDelay (Ptr<FqCoDelQueueDisc> queue, double delay, uint32_t nPkt);
970 };
971 
973  : TestCase ("Test L4S mode")
974 {
975 }
976 
978 {
979 }
980 
981 void
983 {
984  Address dest;
985  Ptr<Packet> p = Create<Packet> (100);
986  for (uint32_t i = 0; i < nPkt; i++)
987  {
988  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, hdr);
989  queue->Enqueue (item);
990  }
991 }
992 
993 void
995 {
996  for (uint32_t i = 0; i < nPkt; i++)
997  {
998  Simulator::Schedule (Time (Seconds ((i + 1) * delay)), &FqCoDelQueueDiscL4sMode::AddPacket, this, queue, hdr, 1);
999  }
1000 }
1001 
1002 void
1004 {
1005  for (uint32_t i = 0; i < nPkt; i++)
1006  {
1007  Ptr<QueueDiscItem> item = queue->Dequeue ();
1008  }
1009 }
1010 
1011 void
1013 {
1014  for (uint32_t i = 0; i < nPkt; i++)
1015  {
1016  Simulator::Schedule (Time (Seconds ((i + 1) * delay)), &FqCoDelQueueDiscL4sMode::Dequeue, this, queue, 1);
1017  }
1018 }
1019 
1020 void
1022 {
1023  // Test is divided into 2 sub test cases:
1024  // 1) Without hash collisions
1025  // 2) With hash collisions
1026 
1027  // Test case 1, Without hash collisions
1028  Ptr<FqCoDelQueueDisc> queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc> ("MaxSize", StringValue ("10240p"), "UseEcn", BooleanValue (true),
1029  "Perturbation", UintegerValue (0), "UseL4s", BooleanValue (true),
1030  "CeThreshold", TimeValue (MilliSeconds (2)));
1031 
1032  queueDisc->SetQuantum (1514);
1033  queueDisc->Initialize ();
1034  Ipv4Header hdr;
1035  hdr.SetPayloadSize (100);
1036  hdr.SetSource (Ipv4Address ("10.10.1.1"));
1037  hdr.SetDestination (Ipv4Address ("10.10.1.2"));
1038  hdr.SetProtocol (7);
1039  hdr.SetEcn (Ipv4Header::ECN_ECT1);
1040 
1041  // Add 70 ECT1 (ECN capable) packets from the first flow
1042  // Set delay = 0.5ms
1043  double delay = 0.0005;
1044  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscL4sMode::AddPacketWithDelay, this, queueDisc, hdr, delay, 70);
1045 
1046  // Add 70 ECT0 (ECN capable) packets from second flow
1047  hdr.SetEcn (Ipv4Header::ECN_ECT0);
1048  hdr.SetDestination (Ipv4Address ("10.10.1.10"));
1049  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscL4sMode::AddPacketWithDelay, this, queueDisc, hdr, delay, 70);
1050 
1051  //Dequeue 140 packets with delay 1ms
1052  delay = 0.001;
1053  DequeueWithDelay (queueDisc, delay, 140);
1054  Simulator::Run ();
1055  Simulator::Stop (Seconds (8.0));
1056  Ptr<CoDelQueueDisc> q0 = queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
1057  Ptr<CoDelQueueDisc> q1 = queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
1058 
1059  NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK), 66, "There should be 66 marked packets"
1060  "4th packet is enqueued at 2ms and dequeued at 4ms hence the delay of 2ms which not greater than CE threshold"
1061  "5th packet is enqueued at 2.5ms and dequeued at 5ms hence the delay of 2.5ms and subsequent packet also do have delay"
1062  "greater than CE threshold so all the packets after 4th packet are marked");
1063  NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
1064  NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK), 0, "There should not be any marked packets");
1065  NS_TEST_EXPECT_MSG_EQ (q1->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK), 1, "There should be 1 marked packets");
1066  NS_TEST_EXPECT_MSG_EQ (q1->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
1067 
1068  Simulator::Destroy ();
1069 
1070  // Test case 2, With hash collisions
1071  queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc> ("MaxSize", StringValue ("10240p"), "UseEcn", BooleanValue (true),
1072  "Perturbation", UintegerValue (0), "UseL4s", BooleanValue (true),
1073  "CeThreshold", TimeValue (MilliSeconds (2)));
1074 
1075  queueDisc->SetQuantum (1514);
1076  queueDisc->Initialize ();
1077  hdr.SetPayloadSize (100);
1078  hdr.SetSource (Ipv4Address ("10.10.1.1"));
1079  hdr.SetDestination (Ipv4Address ("10.10.1.2"));
1080  hdr.SetProtocol (7);
1081  hdr.SetEcn (Ipv4Header::ECN_ECT1);
1082 
1083  // Add 70 ECT1 (ECN capable) packets from the first flow
1084  // Set delay = 1ms
1085  delay = 0.001;
1086  Simulator::Schedule (Time (Seconds (0.0005)), &FqCoDelQueueDiscL4sMode::AddPacket, this, queueDisc, hdr, 1);
1087  Simulator::Schedule (Time (Seconds (0.0005)), &FqCoDelQueueDiscL4sMode::AddPacketWithDelay, this, queueDisc, hdr, delay, 69);
1088 
1089  // Add 70 ECT0 (ECN capable) packets from first flow
1090  hdr.SetEcn (Ipv4Header::ECN_ECT0);
1091  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscL4sMode::AddPacketWithDelay, this, queueDisc, hdr, delay, 70);
1092 
1093  //Dequeue 140 packets with delay 1ms
1094  DequeueWithDelay (queueDisc, delay, 140);
1095  Simulator::Run ();
1096  Simulator::Stop (Seconds (8.0));
1097  q0 = queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
1098 
1099  NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK), 68, "There should be 68 marked packets"
1100  "2nd ECT1 packet is enqueued at 1.5ms and dequeued at 3ms hence the delay of 1.5ms which not greater than CE threshold"
1101  "3rd packet is enqueued at 2.5ms and dequeued at 5ms hence the delay of 2.5ms and subsequent packet also do have delay"
1102  "greater than CE threshold so all the packets after 2nd packet are marked");
1103  NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
1104  NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK), 1, "There should be 1 marked packets");
1105 
1106  Simulator::Destroy ();
1107 
1108 }
1110 {
1111 public:
1113 };
1114 
1116  : TestSuite ("fq-codel-queue-disc", UNIT)
1117 {
1118  AddTestCase (new FqCoDelQueueDiscNoSuitableFilter, TestCase::QUICK);
1120  AddTestCase (new FqCoDelQueueDiscDeficit, TestCase::QUICK);
1121  AddTestCase (new FqCoDelQueueDiscTCPFlowsSeparation, TestCase::QUICK);
1122  AddTestCase (new FqCoDelQueueDiscUDPFlowsSeparation, TestCase::QUICK);
1123  AddTestCase (new FqCoDelQueueDiscECNMarking, TestCase::QUICK);
1124  AddTestCase (new FqCoDelQueueDiscSetLinearProbing, TestCase::QUICK);
1125  AddTestCase (new FqCoDelQueueDiscL4sMode, TestCase::QUICK);
1126 }
1127 
void SetSource(Ipv4Address source)
Definition: ipv4-header.cc:285
void AddPacketWithDelay(Ptr< FqCoDelQueueDisc > queue, Ipv4Header hdr, double delay, uint32_t nPkt)
Ptr< const QueueDiscItem > Peek(void)
Get a copy of the next packet the queue discipline will extract.
Definition: queue-disc.cc:930
void SetPayloadSize(uint16_t size)
Definition: ipv4-header.cc:56
virtual int32_t DoClassify(Ptr< QueueDiscItem > item) const
Classify a packet.
void DequeueWithDelay(Ptr< FqCoDelQueueDisc > queue, double delay, uint32_t nPkt)
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header hdr, u_int32_t nPkt, u_int32_t nPktEnqueued, u_int32_t nQueueFlows)
virtual void DoRun(void)
Implementation to actually run this TestCase.
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
uint32_t GetNPackets(void) const
Get the number of packets stored by the queue disc.
Definition: queue-disc.cc:440
Packet header for IPv6.
Definition: ipv6-header.h:34
void SetDestination(Ipv4Address destination)
Definition: ipv4-header.cc:298
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
AttributeValue implementation for Boolean.
Definition: boolean.h:36
bool Enqueue(Ptr< QueueDiscItem > item)
Pass a packet to store to the queue discipline.
Definition: queue-disc.cc:861
void DequeueWithDelay(Ptr< FqCoDelQueueDisc > queue, double delay, uint32_t nPkt)
Hold variables of type string.
Definition: string.h:41
virtual void DoRun(void)
Implementation to actually run this TestCase.
A suite of tests to run.
Definition: test.h:1343
void SetDestinationPort(uint16_t port)
Definition: udp-header.cc:55
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1286
void Dequeue(Ptr< FqCoDelQueueDisc > queue, uint32_t nPkt)
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:283
void SetSourcePort(uint16_t port)
Definition: udp-header.cc:60
void SetProtocol(uint8_t num)
Definition: ipv4-header.cc:278
encapsulates test code
Definition: test.h:1153
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header hdr)
virtual void DoRun(void)
Implementation to actually run this TestCase.
a polymophic address class
Definition: address.h:90
This class tests the TCP flows separation.
Packet header for IPv4.
Definition: ipv4-header.h:33
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header hdr, u_int32_t nPkt)
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header hdr)
AttributeValue implementation for Time.
Definition: nstime.h:1342
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
Hold an unsigned integer type.
Definition: uinteger.h:44
uint32_t GetNDroppedPackets(std::string reason) const
Get the number of packets dropped for the given reason.
Definition: queue-disc.cc:110
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:166
This class tests packets for which there is no suitable filter.
uint32_t GetQuantum(void) const
Get the quantum value.
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header ipHdr, TcpHeader tcpHdr)
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header ipHdr, UdpHeader udpHdr)
virtual void DoRun(void)
Implementation to actually run this TestCase.
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header hdr)
const Stats & GetStats(void)
Retrieve all the collected statistics.
Definition: queue-disc.cc:421
virtual void DoRun(void)
Implementation to actually run this TestCase.
Ptr< QueueDiscClass > GetQueueDiscClass(std::size_t i) const
Get the i-th queue disc class.
Definition: queue-disc.cc:662
void SetDestinationPort(uint16_t port)
Set the destination port.
Definition: tcp-header.cc:95
This class tests L4S mode Any future classifier options (e.g.
Ptr< QueueDiscItem > Dequeue(void)
Extract from the queue disc the packet that has been dequeued by calling Peek, if any...
Definition: queue-disc.cc:896
virtual void DoRun(void)
Implementation to actually run this TestCase.
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:669
void SetQuantum(uint32_t quantum)
Set the quantum value.
Header for the Transmission Control Protocol.
Definition: tcp-header.h:44
This class tests the UDP flows separation.
virtual bool CheckProtocol(Ptr< QueueDiscItem > item) const
Checks if the filter is able to classify a kind of items.
void SetSourcePort(uint16_t port)
Set the source port.
Definition: tcp-header.cc:89
This class tests ECN marking Any future classifier options (e.g.
uint32_t GetNMarkedPackets(std::string reason) const
Get the number of packets marked for the given reason.
Definition: queue-disc.cc:152
Packet header for UDP packets.
Definition: udp-header.h:39
#define NS_TEST_EXPECT_MSG_NE(actual, limit, msg)
Test that an actual and expected (limit) value are not equal and report if not.
Definition: test.h:737
static FqCoDelQueueDiscTestSuite fqCoDelQueueDiscTestSuite
A CoDel packet queue disc.
This class tests the IP flows separation and the packet limit.
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
static TypeId GetTypeId(void)
Get the type ID.
void SetEcn(EcnType ecn)
Set ECN Field.
Definition: ipv4-header.cc:97
Ipv4PacketFilter is the abstract base class for filters defined for IPv4 packets. ...
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1278
This class tests the deficit per flow.
void AddPacketFilter(Ptr< PacketFilter > filter)
Add a packet filter to the tail of the list of filters used to classify packets.
Definition: queue-disc.cc:614
Simple test packet filter able to classify IPv4 packets.
void Dequeue(Ptr< FqCoDelQueueDisc > queue, uint32_t nPkt)
a unique identifier for an interface.
Definition: type-id.h:58
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
Inactive Period or unslotted CSMA-CA.
Definition: lr-wpan-mac.h:93
void Initialize(void)
Invoke DoInitialize on all Objects aggregated to this one.
Definition: object.cc:183
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256