A Discrete-Event Network Simulator
API
fq-codel-queue-disc-test-suite.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Universita' degli Studi di Napoli Federico II
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Authors: Pasquale Imputato <p.imputato@gmail.com>
18  * Stefano Avallone <stefano.avallone@unina.it>
19  */
20 
21 #include "ns3/codel-queue-disc.h"
22 #include "ns3/fq-codel-queue-disc.h"
23 #include "ns3/ipv4-address.h"
24 #include "ns3/ipv4-header.h"
25 #include "ns3/ipv4-packet-filter.h"
26 #include "ns3/ipv4-queue-disc-item.h"
27 #include "ns3/ipv6-header.h"
28 #include "ns3/ipv6-packet-filter.h"
29 #include "ns3/ipv6-queue-disc-item.h"
30 #include "ns3/pointer.h"
31 #include "ns3/simulator.h"
32 #include "ns3/string.h"
33 #include "ns3/tcp-header.h"
34 #include "ns3/test.h"
35 #include "ns3/udp-header.h"
36 
37 using namespace ns3;
38 
40 static int32_t g_hash;
41 
48 {
49  public:
54  static TypeId GetTypeId();
55 
57  ~Ipv4TestPacketFilter() override;
58 
59  private:
65  int32_t DoClassify(Ptr<QueueDiscItem> item) const override;
66 
72  bool CheckProtocol(Ptr<QueueDiscItem> item) const override;
73 };
74 
75 TypeId
77 {
78  static TypeId tid = TypeId("ns3::Ipv4TestPacketFilter")
80  .SetGroupName("Internet")
81  .AddConstructor<Ipv4TestPacketFilter>();
82  return tid;
83 }
84 
86 {
87 }
88 
90 {
91 }
92 
93 int32_t
95 {
96  return g_hash;
97 }
98 
99 bool
101 {
102  return true;
103 }
104 
111 {
112  public:
115 
116  private:
117  void DoRun() override;
118 };
119 
121  : TestCase("Test packets that are not classified by any filter")
122 {
123 }
124 
126 {
127 }
128 
129 void
131 {
132  // Packets that cannot be classified by the available filters should be dropped
133  Ptr<FqCoDelQueueDisc> queueDisc =
134  CreateObjectWithAttributes<FqCoDelQueueDisc>("MaxSize", StringValue("4p"));
135  Ptr<Ipv4TestPacketFilter> filter = CreateObject<Ipv4TestPacketFilter>();
136  queueDisc->AddPacketFilter(filter);
137 
138  g_hash = -1;
139  queueDisc->SetQuantum(1500);
140  queueDisc->Initialize();
141 
142  Ptr<Packet> p;
143  p = Create<Packet>();
145  Ipv6Header ipv6Header;
146  Address dest;
147  item = Create<Ipv6QueueDiscItem>(p, dest, 0, ipv6Header);
148  queueDisc->Enqueue(item);
149  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetNQueueDiscClasses(),
150  0,
151  "no flow queue should have been created");
152 
153  p = Create<Packet>(reinterpret_cast<const uint8_t*>("hello, world"), 12);
154  item = Create<Ipv6QueueDiscItem>(p, dest, 0, ipv6Header);
155  queueDisc->Enqueue(item);
156  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetNQueueDiscClasses(),
157  0,
158  "no flow queue should have been created");
159 
160  Simulator::Destroy();
161 }
162 
169 {
170  public:
173 
174  private:
175  void DoRun() override;
181  void AddPacket(Ptr<FqCoDelQueueDisc> queue, Ipv4Header hdr);
182 };
183 
185  : TestCase("Test IP flows separation and packet limit")
186 {
187 }
188 
190 {
191 }
192 
193 void
195  Ipv4Header hdr)
196 {
197  Ptr<Packet> p = Create<Packet>(100);
198  Address dest;
199  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem>(p, dest, 0, hdr);
200  queue->Enqueue(item);
201 }
202 
203 void
205 {
206  Ptr<FqCoDelQueueDisc> queueDisc =
207  CreateObjectWithAttributes<FqCoDelQueueDisc>("MaxSize", StringValue("4p"));
208 
209  queueDisc->SetQuantum(1500);
210  queueDisc->Initialize();
211 
212  Ipv4Header hdr;
213  hdr.SetPayloadSize(100);
214  hdr.SetSource(Ipv4Address("10.10.1.1"));
215  hdr.SetDestination(Ipv4Address("10.10.1.2"));
216  hdr.SetProtocol(7);
217 
218  // Add three packets from the first flow
219  AddPacket(queueDisc, hdr);
220  AddPacket(queueDisc, hdr);
221  AddPacket(queueDisc, hdr);
222  NS_TEST_ASSERT_MSG_EQ(queueDisc->QueueDisc::GetNPackets(),
223  3,
224  "unexpected number of packets in the queue disc");
225  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetNPackets(),
226  3,
227  "unexpected number of packets in the flow queue");
228 
229  // Add two packets from the second flow
230  hdr.SetDestination(Ipv4Address("10.10.1.7"));
231  // Add the first packet
232  AddPacket(queueDisc, hdr);
233  NS_TEST_ASSERT_MSG_EQ(queueDisc->QueueDisc::GetNPackets(),
234  4,
235  "unexpected number of packets in the queue disc");
236  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetNPackets(),
237  3,
238  "unexpected number of packets in the flow queue");
239  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(1)->GetQueueDisc()->GetNPackets(),
240  1,
241  "unexpected number of packets in the flow queue");
242  // Add the second packet that causes two packets to be dropped from the fat flow (max backlog =
243  // 300, threshold = 150)
244  AddPacket(queueDisc, hdr);
245  NS_TEST_ASSERT_MSG_EQ(queueDisc->QueueDisc::GetNPackets(),
246  3,
247  "unexpected number of packets in the queue disc");
248  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetNPackets(),
249  1,
250  "unexpected number of packets in the flow queue");
251  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(1)->GetQueueDisc()->GetNPackets(),
252  2,
253  "unexpected number of packets in the flow queue");
254 
255  Simulator::Destroy();
256 }
257 
264 {
265  public:
267  ~FqCoDelQueueDiscDeficit() override;
268 
269  private:
270  void DoRun() override;
276  void AddPacket(Ptr<FqCoDelQueueDisc> queue, Ipv4Header hdr);
277 };
278 
280  : TestCase("Test credits and flows status")
281 {
282 }
283 
285 {
286 }
287 
288 void
290 {
291  Ptr<Packet> p = Create<Packet>(100);
292  Address dest;
293  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem>(p, dest, 0, hdr);
294  queue->Enqueue(item);
295 }
296 
297 void
299 {
300  Ptr<FqCoDelQueueDisc> queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc>();
301 
302  queueDisc->SetQuantum(90);
303  queueDisc->Initialize();
304 
305  Ipv4Header hdr;
306  hdr.SetPayloadSize(100);
307  hdr.SetSource(Ipv4Address("10.10.1.1"));
308  hdr.SetDestination(Ipv4Address("10.10.1.2"));
309  hdr.SetProtocol(7);
310 
311  // Add a packet from the first flow
312  AddPacket(queueDisc, hdr);
313  NS_TEST_ASSERT_MSG_EQ(queueDisc->QueueDisc::GetNPackets(),
314  1,
315  "unexpected number of packets in the queue disc");
316  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetNPackets(),
317  1,
318  "unexpected number of packets in the first flow queue");
319  Ptr<FqCoDelFlow> flow1 = StaticCast<FqCoDelFlow>(queueDisc->GetQueueDiscClass(0));
320  NS_TEST_ASSERT_MSG_EQ(flow1->GetDeficit(),
321  static_cast<int32_t>(queueDisc->GetQuantum()),
322  "the deficit of the first flow must equal the quantum");
323  NS_TEST_ASSERT_MSG_EQ(flow1->GetStatus(),
324  FqCoDelFlow::NEW_FLOW,
325  "the first flow must be in the list of new queues");
326  // Dequeue a packet
327  queueDisc->Dequeue();
328  NS_TEST_ASSERT_MSG_EQ(queueDisc->QueueDisc::GetNPackets(),
329  0,
330  "unexpected number of packets in the queue disc");
331  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetNPackets(),
332  0,
333  "unexpected number of packets in the first flow queue");
334  // the deficit for the first flow becomes 90 - (100+20) = -30
335  NS_TEST_ASSERT_MSG_EQ(flow1->GetDeficit(), -30, "unexpected deficit for the first flow");
336 
337  // Add two packets from the first flow
338  AddPacket(queueDisc, hdr);
339  AddPacket(queueDisc, hdr);
340  NS_TEST_ASSERT_MSG_EQ(queueDisc->QueueDisc::GetNPackets(),
341  2,
342  "unexpected number of packets in the queue disc");
343  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetNPackets(),
344  2,
345  "unexpected number of packets in the first flow queue");
346  NS_TEST_ASSERT_MSG_EQ(flow1->GetStatus(),
347  FqCoDelFlow::NEW_FLOW,
348  "the first flow must still be in the list of new queues");
349 
350  // Add two packets from the second flow
351  hdr.SetDestination(Ipv4Address("10.10.1.10"));
352  AddPacket(queueDisc, hdr);
353  AddPacket(queueDisc, hdr);
354  NS_TEST_ASSERT_MSG_EQ(queueDisc->QueueDisc::GetNPackets(),
355  4,
356  "unexpected number of packets in the queue disc");
357  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetNPackets(),
358  2,
359  "unexpected number of packets in the first flow queue");
360  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(1)->GetQueueDisc()->GetNPackets(),
361  2,
362  "unexpected number of packets in the second flow queue");
363  Ptr<FqCoDelFlow> flow2 = StaticCast<FqCoDelFlow>(queueDisc->GetQueueDiscClass(1));
364  NS_TEST_ASSERT_MSG_EQ(flow2->GetDeficit(),
365  static_cast<int32_t>(queueDisc->GetQuantum()),
366  "the deficit of the second flow must equal the quantum");
367  NS_TEST_ASSERT_MSG_EQ(flow2->GetStatus(),
368  FqCoDelFlow::NEW_FLOW,
369  "the second flow must be in the list of new queues");
370 
371  // Dequeue a packet (from the second flow, as the first flow has a negative deficit)
372  queueDisc->Dequeue();
373  NS_TEST_ASSERT_MSG_EQ(queueDisc->QueueDisc::GetNPackets(),
374  3,
375  "unexpected number of packets in the queue disc");
376  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetNPackets(),
377  2,
378  "unexpected number of packets in the first flow queue");
379  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(1)->GetQueueDisc()->GetNPackets(),
380  1,
381  "unexpected number of packets in the second flow queue");
382  // the first flow got a quantum of deficit (-30+90=60) and has been moved to the end of the list
383  // of old queues
384  NS_TEST_ASSERT_MSG_EQ(flow1->GetDeficit(), 60, "unexpected deficit for the first flow");
385  NS_TEST_ASSERT_MSG_EQ(flow1->GetStatus(),
386  FqCoDelFlow::OLD_FLOW,
387  "the first flow must be in the list of old queues");
388  // the second flow has a negative deficit (-30) and is still in the list of new queues
389  NS_TEST_ASSERT_MSG_EQ(flow2->GetDeficit(), -30, "unexpected deficit for the second flow");
390  NS_TEST_ASSERT_MSG_EQ(flow2->GetStatus(),
391  FqCoDelFlow::NEW_FLOW,
392  "the second flow must be in the list of new queues");
393 
394  // Dequeue a packet (from the first flow, as the second flow has a negative deficit)
395  queueDisc->Dequeue();
396  NS_TEST_ASSERT_MSG_EQ(queueDisc->QueueDisc::GetNPackets(),
397  2,
398  "unexpected number of packets in the queue disc");
399  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetNPackets(),
400  1,
401  "unexpected number of packets in the first flow queue");
402  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(1)->GetQueueDisc()->GetNPackets(),
403  1,
404  "unexpected number of packets in the second flow queue");
405  // the first flow has a negative deficit (60-(100+20)= -60) and stays in the list of old queues
406  NS_TEST_ASSERT_MSG_EQ(flow1->GetDeficit(), -60, "unexpected deficit for the first flow");
407  NS_TEST_ASSERT_MSG_EQ(flow1->GetStatus(),
408  FqCoDelFlow::OLD_FLOW,
409  "the first flow must be in the list of old queues");
410  // the second flow got a quantum of deficit (-30+90=60) and has been moved to the end of the
411  // list of old queues
412  NS_TEST_ASSERT_MSG_EQ(flow2->GetDeficit(), 60, "unexpected deficit for the second flow");
413  NS_TEST_ASSERT_MSG_EQ(flow2->GetStatus(),
414  FqCoDelFlow::OLD_FLOW,
415  "the second flow must be in the list of new queues");
416 
417  // Dequeue a packet (from the second flow, as the first flow has a negative deficit)
418  queueDisc->Dequeue();
419  NS_TEST_ASSERT_MSG_EQ(queueDisc->QueueDisc::GetNPackets(),
420  1,
421  "unexpected number of packets in the queue disc");
422  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetNPackets(),
423  1,
424  "unexpected number of packets in the first flow queue");
425  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(1)->GetQueueDisc()->GetNPackets(),
426  0,
427  "unexpected number of packets in the second flow queue");
428  // the first flow got a quantum of deficit (-60+90=30) and has been moved to the end of the list
429  // of old queues
430  NS_TEST_ASSERT_MSG_EQ(flow1->GetDeficit(), 30, "unexpected deficit for the first flow");
431  NS_TEST_ASSERT_MSG_EQ(flow1->GetStatus(),
432  FqCoDelFlow::OLD_FLOW,
433  "the first flow must be in the list of old queues");
434  // the second flow has a negative deficit (60-(100+20)= -60)
435  NS_TEST_ASSERT_MSG_EQ(flow2->GetDeficit(), -60, "unexpected deficit for the second flow");
436  NS_TEST_ASSERT_MSG_EQ(flow2->GetStatus(),
437  FqCoDelFlow::OLD_FLOW,
438  "the second flow must be in the list of new queues");
439 
440  // Dequeue a packet (from the first flow, as the second flow has a negative deficit)
441  queueDisc->Dequeue();
442  NS_TEST_ASSERT_MSG_EQ(queueDisc->QueueDisc::GetNPackets(),
443  0,
444  "unexpected number of packets in the queue disc");
445  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetNPackets(),
446  0,
447  "unexpected number of packets in the first flow queue");
448  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(1)->GetQueueDisc()->GetNPackets(),
449  0,
450  "unexpected number of packets in the second flow queue");
451  // the first flow has a negative deficit (30-(100+20)= -90)
452  NS_TEST_ASSERT_MSG_EQ(flow1->GetDeficit(), -90, "unexpected deficit for the first flow");
453  NS_TEST_ASSERT_MSG_EQ(flow1->GetStatus(),
454  FqCoDelFlow::OLD_FLOW,
455  "the first flow must be in the list of old queues");
456  // the second flow got a quantum of deficit (-60+90=30) and has been moved to the end of the
457  // list of old queues
458  NS_TEST_ASSERT_MSG_EQ(flow2->GetDeficit(), 30, "unexpected deficit for the second flow");
459  NS_TEST_ASSERT_MSG_EQ(flow2->GetStatus(),
460  FqCoDelFlow::OLD_FLOW,
461  "the second flow must be in the list of new queues");
462 
463  // Dequeue a packet
464  queueDisc->Dequeue();
465  // the first flow is at the head of the list of old queues but has a negative deficit, thus it
466  // gets a quantun of deficit (-90+90=0) and is moved to the end of the list of old queues. Then,
467  // the second flow (which has a positive deficit) is selected, but the second flow is empty and
468  // thus it is set to inactive. The first flow is reconsidered, but it has a null deficit, hence
469  // it gets another quantum of deficit (0+90=90). Then, the first flow is reconsidered again, now
470  // it has a positive deficit and hence it is selected. But, it is empty and therefore is set to
471  // inactive, too.
472  NS_TEST_ASSERT_MSG_EQ(flow1->GetDeficit(), 90, "unexpected deficit for the first flow");
473  NS_TEST_ASSERT_MSG_EQ(flow1->GetStatus(),
475  "the first flow must be inactive");
476  NS_TEST_ASSERT_MSG_EQ(flow2->GetDeficit(), 30, "unexpected deficit for the second flow");
477  NS_TEST_ASSERT_MSG_EQ(flow2->GetStatus(),
479  "the second flow must be inactive");
480 
481  Simulator::Destroy();
482 }
483 
490 {
491  public:
494 
495  private:
496  void DoRun() override;
503  void AddPacket(Ptr<FqCoDelQueueDisc> queue, Ipv4Header ipHdr, TcpHeader tcpHdr);
504 };
505 
507  : TestCase("Test TCP flows separation")
508 {
509 }
510 
512 {
513 }
514 
515 void
517  Ipv4Header ipHdr,
518  TcpHeader tcpHdr)
519 {
520  Ptr<Packet> p = Create<Packet>(100);
521  p->AddHeader(tcpHdr);
522  Address dest;
523  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem>(p, dest, 0, ipHdr);
524  queue->Enqueue(item);
525 }
526 
527 void
529 {
530  Ptr<FqCoDelQueueDisc> queueDisc =
531  CreateObjectWithAttributes<FqCoDelQueueDisc>("MaxSize", StringValue("10p"));
532 
533  queueDisc->SetQuantum(1500);
534  queueDisc->Initialize();
535 
536  Ipv4Header hdr;
537  hdr.SetPayloadSize(100);
538  hdr.SetSource(Ipv4Address("10.10.1.1"));
539  hdr.SetDestination(Ipv4Address("10.10.1.2"));
540  hdr.SetProtocol(6);
541 
542  TcpHeader tcpHdr;
543  tcpHdr.SetSourcePort(7);
544  tcpHdr.SetDestinationPort(27);
545 
546  // Add three packets from the first flow
547  AddPacket(queueDisc, hdr, tcpHdr);
548  AddPacket(queueDisc, hdr, tcpHdr);
549  AddPacket(queueDisc, hdr, tcpHdr);
550  NS_TEST_ASSERT_MSG_EQ(queueDisc->QueueDisc::GetNPackets(),
551  3,
552  "unexpected number of packets in the queue disc");
553  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetNPackets(),
554  3,
555  "unexpected number of packets in the first flow queue");
556 
557  // Add a packet from the second flow
558  tcpHdr.SetSourcePort(8);
559  AddPacket(queueDisc, hdr, tcpHdr);
560  NS_TEST_ASSERT_MSG_EQ(queueDisc->QueueDisc::GetNPackets(),
561  4,
562  "unexpected number of packets in the queue disc");
563  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetNPackets(),
564  3,
565  "unexpected number of packets in the first flow queue");
566  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(1)->GetQueueDisc()->GetNPackets(),
567  1,
568  "unexpected number of packets in the second flow queue");
569 
570  // Add a packet from the third flow
571  tcpHdr.SetDestinationPort(28);
572  AddPacket(queueDisc, hdr, tcpHdr);
573  NS_TEST_ASSERT_MSG_EQ(queueDisc->QueueDisc::GetNPackets(),
574  5,
575  "unexpected number of packets in the queue disc");
576  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetNPackets(),
577  3,
578  "unexpected number of packets in the first flow queue");
579  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(1)->GetQueueDisc()->GetNPackets(),
580  1,
581  "unexpected number of packets in the second flow queue");
582  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(2)->GetQueueDisc()->GetNPackets(),
583  1,
584  "unexpected number of packets in the third flow queue");
585 
586  // Add two packets from the fourth flow
587  tcpHdr.SetSourcePort(7);
588  AddPacket(queueDisc, hdr, tcpHdr);
589  AddPacket(queueDisc, hdr, tcpHdr);
590  NS_TEST_ASSERT_MSG_EQ(queueDisc->QueueDisc::GetNPackets(),
591  7,
592  "unexpected number of packets in the queue disc");
593  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetNPackets(),
594  3,
595  "unexpected number of packets in the first flow queue");
596  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(1)->GetQueueDisc()->GetNPackets(),
597  1,
598  "unexpected number of packets in the second flow queue");
599  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(2)->GetQueueDisc()->GetNPackets(),
600  1,
601  "unexpected number of packets in the third flow queue");
602  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(3)->GetQueueDisc()->GetNPackets(),
603  2,
604  "unexpected number of packets in the third flow queue");
605 
606  Simulator::Destroy();
607 }
608 
615 {
616  public:
619 
620  private:
621  void DoRun() override;
628  void AddPacket(Ptr<FqCoDelQueueDisc> queue, Ipv4Header ipHdr, UdpHeader udpHdr);
629 };
630 
632  : TestCase("Test UDP flows separation")
633 {
634 }
635 
637 {
638 }
639 
640 void
642  Ipv4Header ipHdr,
643  UdpHeader udpHdr)
644 {
645  Ptr<Packet> p = Create<Packet>(100);
646  p->AddHeader(udpHdr);
647  Address dest;
648  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem>(p, dest, 0, ipHdr);
649  queue->Enqueue(item);
650 }
651 
652 void
654 {
655  Ptr<FqCoDelQueueDisc> queueDisc =
656  CreateObjectWithAttributes<FqCoDelQueueDisc>("MaxSize", StringValue("10p"));
657 
658  queueDisc->SetQuantum(1500);
659  queueDisc->Initialize();
660 
661  Ipv4Header hdr;
662  hdr.SetPayloadSize(100);
663  hdr.SetSource(Ipv4Address("10.10.1.1"));
664  hdr.SetDestination(Ipv4Address("10.10.1.2"));
665  hdr.SetProtocol(17);
666 
667  UdpHeader udpHdr;
668  udpHdr.SetSourcePort(7);
669  udpHdr.SetDestinationPort(27);
670 
671  // Add three packets from the first flow
672  AddPacket(queueDisc, hdr, udpHdr);
673  AddPacket(queueDisc, hdr, udpHdr);
674  AddPacket(queueDisc, hdr, udpHdr);
675  NS_TEST_ASSERT_MSG_EQ(queueDisc->QueueDisc::GetNPackets(),
676  3,
677  "unexpected number of packets in the queue disc");
678  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetNPackets(),
679  3,
680  "unexpected number of packets in the first flow queue");
681 
682  // Add a packet from the second flow
683  udpHdr.SetSourcePort(8);
684  AddPacket(queueDisc, hdr, udpHdr);
685  NS_TEST_ASSERT_MSG_EQ(queueDisc->QueueDisc::GetNPackets(),
686  4,
687  "unexpected number of packets in the queue disc");
688  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetNPackets(),
689  3,
690  "unexpected number of packets in the first flow queue");
691  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(1)->GetQueueDisc()->GetNPackets(),
692  1,
693  "unexpected number of packets in the second flow queue");
694 
695  // Add a packet from the third flow
696  udpHdr.SetDestinationPort(28);
697  AddPacket(queueDisc, hdr, udpHdr);
698  NS_TEST_ASSERT_MSG_EQ(queueDisc->QueueDisc::GetNPackets(),
699  5,
700  "unexpected number of packets in the queue disc");
701  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetNPackets(),
702  3,
703  "unexpected number of packets in the first flow queue");
704  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(1)->GetQueueDisc()->GetNPackets(),
705  1,
706  "unexpected number of packets in the second flow queue");
707  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(2)->GetQueueDisc()->GetNPackets(),
708  1,
709  "unexpected number of packets in the third flow queue");
710 
711  // Add two packets from the fourth flow
712  udpHdr.SetSourcePort(7);
713  AddPacket(queueDisc, hdr, udpHdr);
714  AddPacket(queueDisc, hdr, udpHdr);
715  NS_TEST_ASSERT_MSG_EQ(queueDisc->QueueDisc::GetNPackets(),
716  7,
717  "unexpected number of packets in the queue disc");
718  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetNPackets(),
719  3,
720  "unexpected number of packets in the first flow queue");
721  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(1)->GetQueueDisc()->GetNPackets(),
722  1,
723  "unexpected number of packets in the second flow queue");
724  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(2)->GetQueueDisc()->GetNPackets(),
725  1,
726  "unexpected number of packets in the third flow queue");
727  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(3)->GetQueueDisc()->GetNPackets(),
728  2,
729  "unexpected number of packets in the third flow queue");
730 
731  Simulator::Destroy();
732 }
733 
743 {
744  public:
746  ~FqCoDelQueueDiscECNMarking() override;
747 
748  private:
749  void DoRun() override;
758  void AddPacket(Ptr<FqCoDelQueueDisc> queue,
759  Ipv4Header hdr,
760  uint32_t nPkt,
761  uint32_t nPktEnqueued,
762  uint32_t nQueueFlows);
768  void Dequeue(Ptr<FqCoDelQueueDisc> queue, uint32_t nPkt);
775  void DequeueWithDelay(Ptr<FqCoDelQueueDisc> queue, double delay, uint32_t nPkt);
776 };
777 
779  : TestCase("Test ECN marking")
780 {
781 }
782 
784 {
785 }
786 
787 void
789  Ipv4Header hdr,
790  uint32_t nPkt,
791  uint32_t nPktEnqueued,
792  uint32_t nQueueFlows)
793 {
794  Address dest;
795  Ptr<Packet> p = Create<Packet>(100);
796  for (uint32_t i = 0; i < nPkt; i++)
797  {
798  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem>(p, dest, 0, hdr);
799  queue->Enqueue(item);
800  }
801  NS_TEST_EXPECT_MSG_EQ(queue->GetNQueueDiscClasses(),
802  nQueueFlows,
803  "unexpected number of flow queues");
804  NS_TEST_EXPECT_MSG_EQ(queue->GetNPackets(),
805  nPktEnqueued,
806  "unexpected number of enqueued packets");
807 }
808 
809 void
811 {
812  for (uint32_t i = 0; i < nPkt; i++)
813  {
814  Ptr<QueueDiscItem> item = queue->Dequeue();
815  }
816 }
817 
818 void
820  double delay,
821  uint32_t nPkt)
822 {
823  for (uint32_t i = 0; i < nPkt; i++)
824  {
825  Simulator::Schedule(Time(Seconds((i + 1) * delay)),
827  this,
828  queue,
829  1);
830  }
831 }
832 
833 void
835 {
836  // Test is divided into 3 sub test cases:
837  // 1) CeThreshold disabled
838  // 2) CeThreshold enabled
839  // 3) Same as 2 but with higher queue delay, leading to both mark types, and checks that the
840  // same packet is not marked twice
841 
842  // Test case 1, CeThreshold disabled
843  Ptr<FqCoDelQueueDisc> queueDisc =
844  CreateObjectWithAttributes<FqCoDelQueueDisc>("MaxSize",
845  StringValue("10240p"),
846  "UseEcn",
847  BooleanValue(true),
848  "Perturbation",
849  UintegerValue(0));
850 
851  queueDisc->SetQuantum(1514);
852  queueDisc->Initialize();
853  Ipv4Header hdr;
854  hdr.SetPayloadSize(100);
855  hdr.SetSource(Ipv4Address("10.10.1.1"));
856  hdr.SetDestination(Ipv4Address("10.10.1.2"));
857  hdr.SetProtocol(7);
858  hdr.SetEcn(Ipv4Header::ECN_ECT0);
859 
860  // Add 20 ECT0 (ECN capable) packets from the first flow
861  Simulator::Schedule(Time(Seconds(0)),
863  this,
864  queueDisc,
865  hdr,
866  20,
867  20,
868  1);
869 
870  // Add 20 ECT0 (ECN capable) packets from second flow
871  hdr.SetDestination(Ipv4Address("10.10.1.10"));
872  Simulator::Schedule(Time(Seconds(0)),
874  this,
875  queueDisc,
876  hdr,
877  20,
878  40,
879  2);
880 
881  // Add 20 ECT0 (ECN capable) packets from third flow
882  hdr.SetDestination(Ipv4Address("10.10.1.20"));
883  Simulator::Schedule(Time(Seconds(0)),
885  this,
886  queueDisc,
887  hdr,
888  20,
889  60,
890  3);
891 
892  // Add 20 NotECT packets from fourth flow
893  hdr.SetDestination(Ipv4Address("10.10.1.30"));
894  hdr.SetEcn(Ipv4Header::ECN_NotECT);
895  Simulator::Schedule(Time(Seconds(0)),
897  this,
898  queueDisc,
899  hdr,
900  20,
901  80,
902  4);
903 
904  // Add 20 NotECT packets from fifth flow
905  hdr.SetDestination(Ipv4Address("10.10.1.40"));
906  Simulator::Schedule(Time(Seconds(0)),
908  this,
909  queueDisc,
910  hdr,
911  20,
912  100,
913  5);
914 
915  // Dequeue 60 packets with delay 110ms to induce packet drops and keep some remaining packets in
916  // each queue
917  DequeueWithDelay(queueDisc, 0.11, 60);
918  Simulator::Run();
919  Simulator::Stop(Seconds(8.0));
921  queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetObject<CoDelQueueDisc>();
923  queueDisc->GetQueueDiscClass(1)->GetQueueDisc()->GetObject<CoDelQueueDisc>();
925  queueDisc->GetQueueDiscClass(2)->GetQueueDisc()->GetObject<CoDelQueueDisc>();
927  queueDisc->GetQueueDiscClass(3)->GetQueueDisc()->GetObject<CoDelQueueDisc>();
929  queueDisc->GetQueueDiscClass(4)->GetQueueDisc()->GetObject<CoDelQueueDisc>();
930 
931  // Ensure there are some remaining packets in the flow queues to check for flow queues with ECN
932  // capable packets
933  NS_TEST_EXPECT_MSG_NE(queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetNPackets(),
934  0,
935  "There should be some remaining packets");
936  NS_TEST_EXPECT_MSG_NE(queueDisc->GetQueueDiscClass(1)->GetQueueDisc()->GetNPackets(),
937  0,
938  "There should be some remaining packets");
939  NS_TEST_EXPECT_MSG_NE(queueDisc->GetQueueDiscClass(2)->GetQueueDisc()->GetNPackets(),
940  0,
941  "There should be some remaining packets");
942  NS_TEST_EXPECT_MSG_NE(queueDisc->GetQueueDiscClass(3)->GetQueueDisc()->GetNPackets(),
943  0,
944  "There should be some remaining packets");
945  NS_TEST_EXPECT_MSG_NE(queueDisc->GetQueueDiscClass(4)->GetQueueDisc()->GetNPackets(),
946  0,
947  "There should be some remaining packets");
948 
949  // As packets in flow queues are ECN capable
950  NS_TEST_EXPECT_MSG_EQ(q0->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK),
951  6,
952  "There should be 6 marked packets"
953  "with 20 packets, total bytes in the queue = 120 * 20 = 2400. First "
954  "packet dequeues at 110ms which is greater than"
955  "test's default target value 5ms. Sojourn time has just gone above "
956  "target from below, need to stay above for at"
957  "least q->interval before packet can be dropped. Second packet dequeues "
958  "at 220ms which is greater than last dequeue"
959  "time plus q->interval(test default 100ms) so the packet is marked. "
960  "Third packet dequeues at 330ms and the sojourn"
961  "time stayed above the target and dropnext value is less than 320 hence "
962  "the packet is marked. 4 subsequent packets"
963  "are marked as the sojourn time stays above the target. With 8th dequeue "
964  "number of bytes in queue = 120 * 12 = 1440"
965  "which is less m_minBytes(test's default value 1500 bytes) hence the "
966  "packets stop getting marked");
967  NS_TEST_EXPECT_MSG_EQ(q0->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP),
968  0,
969  "There should not be any dropped packets");
970  NS_TEST_EXPECT_MSG_EQ(q1->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK),
971  6,
972  "There should be 6 marked packets");
973  NS_TEST_EXPECT_MSG_EQ(q1->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP),
974  0,
975  "There should not be any dropped packets");
976  NS_TEST_EXPECT_MSG_EQ(q2->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK),
977  6,
978  "There should be 6 marked packets");
979  NS_TEST_EXPECT_MSG_EQ(q2->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP),
980  0,
981  "There should not be any dropped packets");
982 
983  // As packets in flow queues are not ECN capable
985  q3->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP),
986  4,
987  "There should be 4 dropped packets"
988  "with 20 packets, total bytes in the queue = 120 * 20 = 2400. First packet dequeues at "
989  "110ms which is greater than"
990  "test's default target value 5ms. Sojourn time has just gone above target from below, need "
991  "to stay above for at"
992  "least q->interval before packet can be dropped. Second packet dequeues at 220ms which is "
993  "greater than last dequeue"
994  "time plus q->interval(test default 100ms) so packet is dropped and next is dequeued. 4th "
995  "packet dequeues at 330ms"
996  "and the sojourn time stayed above the target and dropnext value is less than 320 hence "
997  "the packet is dropped and next"
998  "packet is dequeued. 6th packet dequeues at 440ms and 2 more packets are dropped as "
999  "dropnext value is increased twice."
1000  "12 Packets remaining in the queue, total number of bytes int the queue = 120 * 12 = 1440 "
1001  "which is less"
1002  "m_minBytes(test's default value 1500 bytes) hence the packets stop getting dropped");
1003  NS_TEST_EXPECT_MSG_EQ(q3->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK),
1004  0,
1005  "There should not be any marked packets");
1006  NS_TEST_EXPECT_MSG_EQ(q4->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP),
1007  4,
1008  "There should be 4 dropped packets");
1009  NS_TEST_EXPECT_MSG_EQ(q4->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK),
1010  0,
1011  "There should not be any marked packets");
1012  // Ensure flow queue 0,1 and 2 have ECN capable packets
1013  // Peek () changes the stats of the queue and that is reason to be keep this test at last
1014  Ptr<const Ipv4QueueDiscItem> pktQ0 = DynamicCast<const Ipv4QueueDiscItem>(q0->Peek());
1015  NS_TEST_EXPECT_MSG_NE(pktQ0->GetHeader().GetEcn(),
1016  Ipv4Header::ECN_NotECT,
1017  "flow queue should have ECT0 packets");
1018  Ptr<const Ipv4QueueDiscItem> pktQ1 = DynamicCast<const Ipv4QueueDiscItem>(q1->Peek());
1019  NS_TEST_EXPECT_MSG_NE(pktQ1->GetHeader().GetEcn(),
1020  Ipv4Header::ECN_NotECT,
1021  "flow queue should have ECT0 packets");
1022  Ptr<const Ipv4QueueDiscItem> pktQ2 = DynamicCast<const Ipv4QueueDiscItem>(q2->Peek());
1023  NS_TEST_EXPECT_MSG_NE(pktQ2->GetHeader().GetEcn(),
1024  Ipv4Header::ECN_NotECT,
1025  "flow queue should have ECT0 packets");
1026 
1027  Simulator::Destroy();
1028 
1029  // Test case 2, CeThreshold set to 2ms
1030  queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc>("MaxSize",
1031  StringValue("10240p"),
1032  "UseEcn",
1033  BooleanValue(true),
1034  "CeThreshold",
1035  TimeValue(MilliSeconds(2)));
1036  queueDisc->SetQuantum(1514);
1037  queueDisc->Initialize();
1038 
1039  // Add 20 ECT0 (ECN capable) packets from first flow
1040  hdr.SetDestination(Ipv4Address("10.10.1.2"));
1041  hdr.SetEcn(Ipv4Header::ECN_ECT0);
1042  Simulator::Schedule(Time(Seconds(0)),
1044  this,
1045  queueDisc,
1046  hdr,
1047  20,
1048  20,
1049  1);
1050 
1051  // Add 20 ECT0 (ECN capable) packets from second flow
1052  hdr.SetDestination(Ipv4Address("10.10.1.10"));
1053  Simulator::Schedule(Time(Seconds(0)),
1055  this,
1056  queueDisc,
1057  hdr,
1058  20,
1059  40,
1060  2);
1061 
1062  // Add 20 ECT0 (ECN capable) packets from third flow
1063  hdr.SetDestination(Ipv4Address("10.10.1.20"));
1064  Simulator::Schedule(Time(Seconds(0)),
1066  this,
1067  queueDisc,
1068  hdr,
1069  20,
1070  60,
1071  3);
1072 
1073  // Add 20 NotECT packets from fourth flow
1074  hdr.SetDestination(Ipv4Address("10.10.1.30"));
1075  hdr.SetEcn(Ipv4Header::ECN_NotECT);
1076  Simulator::Schedule(Time(Seconds(0)),
1078  this,
1079  queueDisc,
1080  hdr,
1081  20,
1082  80,
1083  4);
1084 
1085  // Add 20 NotECT packets from fifth flow
1086  hdr.SetDestination(Ipv4Address("10.10.1.40"));
1087  Simulator::Schedule(Time(Seconds(0)),
1089  this,
1090  queueDisc,
1091  hdr,
1092  20,
1093  100,
1094  5);
1095 
1096  // Dequeue 60 packets with delay 0.1ms to induce packet drops and keep some remaining packets in
1097  // each queue
1098  DequeueWithDelay(queueDisc, 0.0001, 60);
1099  Simulator::Run();
1100  Simulator::Stop(Seconds(8.0));
1101  q0 = queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetObject<CoDelQueueDisc>();
1102  q1 = queueDisc->GetQueueDiscClass(1)->GetQueueDisc()->GetObject<CoDelQueueDisc>();
1103  q2 = queueDisc->GetQueueDiscClass(2)->GetQueueDisc()->GetObject<CoDelQueueDisc>();
1104  q3 = queueDisc->GetQueueDiscClass(3)->GetQueueDisc()->GetObject<CoDelQueueDisc>();
1105  q4 = queueDisc->GetQueueDiscClass(4)->GetQueueDisc()->GetObject<CoDelQueueDisc>();
1106 
1107  // Ensure there are some remaining packets in the flow queues to check for flow queues with ECN
1108  // capable packets
1109  NS_TEST_EXPECT_MSG_NE(queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetNPackets(),
1110  0,
1111  "There should be some remaining packets");
1112  NS_TEST_EXPECT_MSG_NE(queueDisc->GetQueueDiscClass(1)->GetQueueDisc()->GetNPackets(),
1113  0,
1114  "There should be some remaining packets");
1115  NS_TEST_EXPECT_MSG_NE(queueDisc->GetQueueDiscClass(2)->GetQueueDisc()->GetNPackets(),
1116  0,
1117  "There should be some remaining packets");
1118  NS_TEST_EXPECT_MSG_NE(queueDisc->GetQueueDiscClass(3)->GetQueueDisc()->GetNPackets(),
1119  0,
1120  "There should be some remaining packets");
1121  NS_TEST_EXPECT_MSG_NE(queueDisc->GetQueueDiscClass(4)->GetQueueDisc()->GetNPackets(),
1122  0,
1123  "There should be some remaining packets");
1124 
1125  // As packets in flow queues are ECN capable
1126  NS_TEST_EXPECT_MSG_EQ(q0->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP),
1127  0,
1128  "There should not be any dropped packets");
1130  q0->GetStats().GetNMarkedPackets(CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK),
1131  0,
1132  "There should not be any marked packets"
1133  "with quantum of 1514, 13 packets of size 120 bytes can be dequeued. sojourn time of 13th "
1134  "packet is 1.3ms which is"
1135  "less than CE threshold");
1136  NS_TEST_EXPECT_MSG_EQ(q1->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP),
1137  0,
1138  "There should not be any dropped packets");
1140  q1->GetStats().GetNMarkedPackets(CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK),
1141  6,
1142  "There should be 6 marked packets"
1143  "with quantum of 1514, 13 packets of size 120 bytes can be dequeued. sojourn time of 8th "
1144  "packet is 2.1ms which is greater"
1145  "than CE threshold and subsequent packet also have sojourn time more 8th packet hence "
1146  "remaining packet are marked.");
1147  NS_TEST_EXPECT_MSG_EQ(q2->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP),
1148  0,
1149  "There should not be any dropped packets");
1151  q2->GetStats().GetNMarkedPackets(CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK),
1152  13,
1153  "There should be 13 marked packets"
1154  "with quantum of 1514, 13 packets of size 120 bytes can be dequeued and all of them have "
1155  "sojourn time more than CE threshold");
1156 
1157  // As packets in flow queues are not ECN capable
1159  q3->GetStats().GetNMarkedPackets(CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK),
1160  0,
1161  "There should not be any marked packets");
1162  NS_TEST_EXPECT_MSG_EQ(q3->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP),
1163  0,
1164  "There should not be any dropped packets");
1166  q4->GetStats().GetNMarkedPackets(CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK),
1167  0,
1168  "There should not be any marked packets");
1169  NS_TEST_EXPECT_MSG_EQ(q4->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP),
1170  0,
1171  "There should not be any dropped packets");
1172 
1173  // Ensure flow queue 0,1 and 2 have ECN capable packets
1174  // Peek () changes the stats of the queue and that is reason to be keep this test at last
1175  pktQ0 = DynamicCast<const Ipv4QueueDiscItem>(q0->Peek());
1176  NS_TEST_EXPECT_MSG_NE(pktQ0->GetHeader().GetEcn(),
1177  Ipv4Header::ECN_NotECT,
1178  "flow queue should have ECT0 packets");
1179  pktQ1 = DynamicCast<const Ipv4QueueDiscItem>(q1->Peek());
1180  NS_TEST_EXPECT_MSG_NE(pktQ1->GetHeader().GetEcn(),
1181  Ipv4Header::ECN_NotECT,
1182  "flow queue should have ECT0 packets");
1183  pktQ2 = DynamicCast<const Ipv4QueueDiscItem>(q2->Peek());
1184  NS_TEST_EXPECT_MSG_NE(pktQ2->GetHeader().GetEcn(),
1185  Ipv4Header::ECN_NotECT,
1186  "flow queue should have ECT0 packets");
1187 
1188  Simulator::Destroy();
1189 
1190  // Test case 3, CeThreshold set to 2ms with higher queue delay
1191  queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc>("MaxSize",
1192  StringValue("10240p"),
1193  "UseEcn",
1194  BooleanValue(true),
1195  "CeThreshold",
1196  TimeValue(MilliSeconds(2)));
1197  queueDisc->SetQuantum(1514);
1198  queueDisc->Initialize();
1199 
1200  // Add 20 ECT0 (ECN capable) packets from first flow
1201  hdr.SetDestination(Ipv4Address("10.10.1.2"));
1202  hdr.SetEcn(Ipv4Header::ECN_ECT0);
1203  Simulator::Schedule(Time(Seconds(0)),
1205  this,
1206  queueDisc,
1207  hdr,
1208  20,
1209  20,
1210  1);
1211 
1212  // Add 20 ECT0 (ECN capable) packets from second flow
1213  hdr.SetDestination(Ipv4Address("10.10.1.10"));
1214  Simulator::Schedule(Time(Seconds(0)),
1216  this,
1217  queueDisc,
1218  hdr,
1219  20,
1220  40,
1221  2);
1222 
1223  // Add 20 ECT0 (ECN capable) packets from third flow
1224  hdr.SetDestination(Ipv4Address("10.10.1.20"));
1225  Simulator::Schedule(Time(Seconds(0)),
1227  this,
1228  queueDisc,
1229  hdr,
1230  20,
1231  60,
1232  3);
1233 
1234  // Add 20 NotECT packets from fourth flow
1235  hdr.SetDestination(Ipv4Address("10.10.1.30"));
1236  hdr.SetEcn(Ipv4Header::ECN_NotECT);
1237  Simulator::Schedule(Time(Seconds(0)),
1239  this,
1240  queueDisc,
1241  hdr,
1242  20,
1243  80,
1244  4);
1245 
1246  // Add 20 NotECT packets from fifth flow
1247  hdr.SetDestination(Ipv4Address("10.10.1.40"));
1248  Simulator::Schedule(Time(Seconds(0)),
1250  this,
1251  queueDisc,
1252  hdr,
1253  20,
1254  100,
1255  5);
1256 
1257  // Dequeue 60 packets with delay 110ms to induce packet drops and keep some remaining packets in
1258  // each queue
1259  DequeueWithDelay(queueDisc, 0.110, 60);
1260  Simulator::Run();
1261  Simulator::Stop(Seconds(8.0));
1262  q0 = queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetObject<CoDelQueueDisc>();
1263  q1 = queueDisc->GetQueueDiscClass(1)->GetQueueDisc()->GetObject<CoDelQueueDisc>();
1264  q2 = queueDisc->GetQueueDiscClass(2)->GetQueueDisc()->GetObject<CoDelQueueDisc>();
1265  q3 = queueDisc->GetQueueDiscClass(3)->GetQueueDisc()->GetObject<CoDelQueueDisc>();
1266  q4 = queueDisc->GetQueueDiscClass(4)->GetQueueDisc()->GetObject<CoDelQueueDisc>();
1267 
1268  // Ensure there are some remaining packets in the flow queues to check for flow queues with ECN
1269  // capable packets
1270  NS_TEST_EXPECT_MSG_NE(queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetNPackets(),
1271  0,
1272  "There should be some remaining packets");
1273  NS_TEST_EXPECT_MSG_NE(queueDisc->GetQueueDiscClass(1)->GetQueueDisc()->GetNPackets(),
1274  0,
1275  "There should be some remaining packets");
1276  NS_TEST_EXPECT_MSG_NE(queueDisc->GetQueueDiscClass(2)->GetQueueDisc()->GetNPackets(),
1277  0,
1278  "There should be some remaining packets");
1279  NS_TEST_EXPECT_MSG_NE(queueDisc->GetQueueDiscClass(3)->GetQueueDisc()->GetNPackets(),
1280  0,
1281  "There should be some remaining packets");
1282  NS_TEST_EXPECT_MSG_NE(queueDisc->GetQueueDiscClass(4)->GetQueueDisc()->GetNPackets(),
1283  0,
1284  "There should be some remaining packets");
1285 
1286  // As packets in flow queues are ECN capable
1287  NS_TEST_EXPECT_MSG_EQ(q0->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP),
1288  0,
1289  "There should not be any dropped packets");
1291  q0->GetStats().GetNMarkedPackets(CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK) +
1292  q0->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK),
1293  20 - q0->GetNPackets(),
1294  "Number of CE threshold"
1295  " exceeded marks plus Number of Target exceeded marks should be equal to total number of "
1296  "packets dequeued");
1297  NS_TEST_EXPECT_MSG_EQ(q1->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP),
1298  0,
1299  "There should not be any dropped packets");
1301  q1->GetStats().GetNMarkedPackets(CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK) +
1302  q1->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK),
1303  20 - q1->GetNPackets(),
1304  "Number of CE threshold"
1305  " exceeded marks plus Number of Target exceeded marks should be equal to total number of "
1306  "packets dequeued");
1307  NS_TEST_EXPECT_MSG_EQ(q2->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP),
1308  0,
1309  "There should not be any dropped packets");
1311  q2->GetStats().GetNMarkedPackets(CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK) +
1312  q2->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK),
1313  20 - q2->GetNPackets(),
1314  "Number of CE threshold"
1315  " exceeded marks plus Number of Target exceeded marks should be equal to total number of "
1316  "packets dequeued");
1317 
1318  // As packets in flow queues are not ECN capable
1320  q3->GetStats().GetNMarkedPackets(CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK),
1321  0,
1322  "There should not be any marked packets");
1324  q3->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP),
1325  4,
1326  "There should be 4 dropped packets"
1327  " As queue delay is same as in test case 1, number of dropped packets should also be same");
1329  q4->GetStats().GetNMarkedPackets(CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK),
1330  0,
1331  "There should not be any marked packets");
1332  NS_TEST_EXPECT_MSG_EQ(q4->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP),
1333  4,
1334  "There should be 4 dropped packets");
1335 
1336  // Ensure flow queue 0,1 and 2 have ECN capable packets
1337  // Peek () changes the stats of the queue and that is reason to be keep this test at last
1338  pktQ0 = DynamicCast<const Ipv4QueueDiscItem>(q0->Peek());
1339  NS_TEST_EXPECT_MSG_NE(pktQ0->GetHeader().GetEcn(),
1340  Ipv4Header::ECN_NotECT,
1341  "flow queue should have ECT0 packets");
1342  pktQ1 = DynamicCast<const Ipv4QueueDiscItem>(q1->Peek());
1343  NS_TEST_EXPECT_MSG_NE(pktQ1->GetHeader().GetEcn(),
1344  Ipv4Header::ECN_NotECT,
1345  "flow queue should have ECT0 packets");
1346  pktQ2 = DynamicCast<const Ipv4QueueDiscItem>(q2->Peek());
1347  NS_TEST_EXPECT_MSG_NE(pktQ2->GetHeader().GetEcn(),
1348  Ipv4Header::ECN_NotECT,
1349  "flow queue should have ECT0 packets");
1350 
1351  Simulator::Destroy();
1352 }
1353 
1379 {
1380  public:
1383 
1384  private:
1385  void DoRun() override;
1391  void AddPacket(Ptr<FqCoDelQueueDisc> queue, Ipv4Header hdr);
1392 };
1393 
1395  : TestCase("Test credits and flows status")
1396 {
1397 }
1398 
1400 {
1401 }
1402 
1403 void
1405 {
1406  Ptr<Packet> p = Create<Packet>(100);
1407  Address dest;
1408  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem>(p, dest, 0, hdr);
1409  queue->Enqueue(item);
1410 }
1411 
1412 void
1414 {
1415  Ptr<FqCoDelQueueDisc> queueDisc =
1416  CreateObjectWithAttributes<FqCoDelQueueDisc>("EnableSetAssociativeHash",
1417  BooleanValue(true));
1418  queueDisc->SetQuantum(90);
1419  queueDisc->Initialize();
1420 
1421  Ptr<Ipv4TestPacketFilter> filter = CreateObject<Ipv4TestPacketFilter>();
1422  queueDisc->AddPacketFilter(filter);
1423 
1424  Ipv4Header hdr;
1425  hdr.SetPayloadSize(100);
1426  hdr.SetSource(Ipv4Address("10.10.1.1"));
1427  hdr.SetDestination(Ipv4Address("10.10.1.2"));
1428  hdr.SetProtocol(7);
1429 
1430  g_hash = 0;
1431  AddPacket(queueDisc, hdr);
1432  g_hash = 1;
1433  AddPacket(queueDisc, hdr);
1434  AddPacket(queueDisc, hdr);
1435  g_hash = 2;
1436  AddPacket(queueDisc, hdr);
1437  g_hash = 3;
1438  AddPacket(queueDisc, hdr);
1439  g_hash = 4;
1440  AddPacket(queueDisc, hdr);
1441  AddPacket(queueDisc, hdr);
1442  g_hash = 5;
1443  AddPacket(queueDisc, hdr);
1444  g_hash = 6;
1445  AddPacket(queueDisc, hdr);
1446  g_hash = 7;
1447  AddPacket(queueDisc, hdr);
1448  g_hash = 1024;
1449  AddPacket(queueDisc, hdr);
1450 
1451  NS_TEST_ASSERT_MSG_EQ(queueDisc->QueueDisc::GetNPackets(),
1452  11,
1453  "unexpected number of packets in the queue disc");
1454  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetNPackets(),
1455  2,
1456  "unexpected number of packets in the first flow queue of set one");
1457  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(1)->GetQueueDisc()->GetNPackets(),
1458  2,
1459  "unexpected number of packets in the second flow queue of set one");
1460  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(2)->GetQueueDisc()->GetNPackets(),
1461  1,
1462  "unexpected number of packets in the third flow queue of set one");
1463  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(3)->GetQueueDisc()->GetNPackets(),
1464  1,
1465  "unexpected number of packets in the fourth flow queue of set one");
1466  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(4)->GetQueueDisc()->GetNPackets(),
1467  2,
1468  "unexpected number of packets in the fifth flow queue of set one");
1469  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(5)->GetQueueDisc()->GetNPackets(),
1470  1,
1471  "unexpected number of packets in the sixth flow queue of set one");
1472  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(6)->GetQueueDisc()->GetNPackets(),
1473  1,
1474  "unexpected number of packets in the seventh flow queue of set one");
1475  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(7)->GetQueueDisc()->GetNPackets(),
1476  1,
1477  "unexpected number of packets in the eighth flow queue of set one");
1478  g_hash = 1025;
1479  AddPacket(queueDisc, hdr);
1480  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetNPackets(),
1481  3,
1482  "unexpected number of packets in the first flow of set one");
1483  g_hash = 10;
1484  AddPacket(queueDisc, hdr);
1485  NS_TEST_ASSERT_MSG_EQ(queueDisc->GetQueueDiscClass(8)->GetQueueDisc()->GetNPackets(),
1486  1,
1487  "unexpected number of packets in the first flow of set two");
1488  Simulator::Destroy();
1489 }
1490 
1499 {
1500  public:
1502  ~FqCoDelQueueDiscL4sMode() override;
1503 
1504  private:
1505  void DoRun() override;
1506 
1513  void AddPacket(Ptr<FqCoDelQueueDisc> queue, Ipv4Header hdr, uint32_t nPkt);
1514 
1523  Ipv4Header hdr,
1524  double delay,
1525  uint32_t nPkt);
1526 
1532  void Dequeue(Ptr<FqCoDelQueueDisc> queue, uint32_t nPkt);
1539  void DequeueWithDelay(Ptr<FqCoDelQueueDisc> queue, double delay, uint32_t nPkt);
1540 };
1541 
1543  : TestCase("Test L4S mode")
1544 {
1545 }
1546 
1548 {
1549 }
1550 
1551 void
1553 {
1554  Address dest;
1555  Ptr<Packet> p = Create<Packet>(100);
1556  for (uint32_t i = 0; i < nPkt; i++)
1557  {
1558  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem>(p, dest, 0, hdr);
1559  queue->Enqueue(item);
1560  }
1561 }
1562 
1563 void
1565  Ipv4Header hdr,
1566  double delay,
1567  uint32_t nPkt)
1568 {
1569  for (uint32_t i = 0; i < nPkt; i++)
1570  {
1571  Simulator::Schedule(Time(Seconds((i + 1) * delay)),
1573  this,
1574  queue,
1575  hdr,
1576  1);
1577  }
1578 }
1579 
1580 void
1582 {
1583  for (uint32_t i = 0; i < nPkt; i++)
1584  {
1585  Ptr<QueueDiscItem> item = queue->Dequeue();
1586  }
1587 }
1588 
1589 void
1591 {
1592  for (uint32_t i = 0; i < nPkt; i++)
1593  {
1594  Simulator::Schedule(Time(Seconds((i + 1) * delay)),
1596  this,
1597  queue,
1598  1);
1599  }
1600 }
1601 
1602 void
1604 {
1605  // Test is divided into 2 sub test cases:
1606  // 1) Without hash collisions
1607  // 2) With hash collisions
1608 
1609  // Test case 1, Without hash collisions
1610  Ptr<FqCoDelQueueDisc> queueDisc =
1611  CreateObjectWithAttributes<FqCoDelQueueDisc>("MaxSize",
1612  StringValue("10240p"),
1613  "UseEcn",
1614  BooleanValue(true),
1615  "Perturbation",
1616  UintegerValue(0),
1617  "UseL4s",
1618  BooleanValue(true),
1619  "CeThreshold",
1620  TimeValue(MilliSeconds(2)));
1621 
1622  queueDisc->SetQuantum(1514);
1623  queueDisc->Initialize();
1624  Ipv4Header hdr;
1625  hdr.SetPayloadSize(100);
1626  hdr.SetSource(Ipv4Address("10.10.1.1"));
1627  hdr.SetDestination(Ipv4Address("10.10.1.2"));
1628  hdr.SetProtocol(7);
1629  hdr.SetEcn(Ipv4Header::ECN_ECT1);
1630 
1631  // Add 70 ECT1 (ECN capable) packets from the first flow
1632  // Set delay = 0.5ms
1633  double delay = 0.0005;
1634  Simulator::Schedule(Time(Seconds(0)),
1636  this,
1637  queueDisc,
1638  hdr,
1639  delay,
1640  70);
1641 
1642  // Add 70 ECT0 (ECN capable) packets from second flow
1643  hdr.SetEcn(Ipv4Header::ECN_ECT0);
1644  hdr.SetDestination(Ipv4Address("10.10.1.10"));
1645  Simulator::Schedule(Time(Seconds(0)),
1647  this,
1648  queueDisc,
1649  hdr,
1650  delay,
1651  70);
1652 
1653  // Dequeue 140 packets with delay 1ms
1654  delay = 0.001;
1655  DequeueWithDelay(queueDisc, delay, 140);
1656  Simulator::Run();
1657  Simulator::Stop(Seconds(8.0));
1658  Ptr<CoDelQueueDisc> q0 =
1659  queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetObject<CoDelQueueDisc>();
1660  Ptr<CoDelQueueDisc> q1 =
1661  queueDisc->GetQueueDiscClass(1)->GetQueueDisc()->GetObject<CoDelQueueDisc>();
1662 
1664  q0->GetStats().GetNMarkedPackets(CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK),
1665  66,
1666  "There should be 66 marked packets"
1667  "4th packet is enqueued at 2ms and dequeued at 4ms hence the delay of 2ms which not "
1668  "greater than CE threshold"
1669  "5th packet is enqueued at 2.5ms and dequeued at 5ms hence the delay of 2.5ms and "
1670  "subsequent packet also do have delay"
1671  "greater than CE threshold so all the packets after 4th packet are marked");
1672  NS_TEST_EXPECT_MSG_EQ(q0->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP),
1673  0,
1674  "There should not be any dropped packets");
1675  NS_TEST_EXPECT_MSG_EQ(q0->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK),
1676  0,
1677  "There should not be any marked packets");
1678  NS_TEST_EXPECT_MSG_EQ(q1->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK),
1679  1,
1680  "There should be 1 marked packets");
1681  NS_TEST_EXPECT_MSG_EQ(q1->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP),
1682  0,
1683  "There should not be any dropped packets");
1684 
1685  Simulator::Destroy();
1686 
1687  // Test case 2, With hash collisions
1688  queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc>("MaxSize",
1689  StringValue("10240p"),
1690  "UseEcn",
1691  BooleanValue(true),
1692  "Perturbation",
1693  UintegerValue(0),
1694  "UseL4s",
1695  BooleanValue(true),
1696  "CeThreshold",
1697  TimeValue(MilliSeconds(2)));
1698 
1699  queueDisc->SetQuantum(1514);
1700  queueDisc->Initialize();
1701  hdr.SetPayloadSize(100);
1702  hdr.SetSource(Ipv4Address("10.10.1.1"));
1703  hdr.SetDestination(Ipv4Address("10.10.1.2"));
1704  hdr.SetProtocol(7);
1705  hdr.SetEcn(Ipv4Header::ECN_ECT1);
1706 
1707  // Add 70 ECT1 (ECN capable) packets from the first flow
1708  // Set delay = 1ms
1709  delay = 0.001;
1710  Simulator::Schedule(Time(Seconds(0.0005)),
1712  this,
1713  queueDisc,
1714  hdr,
1715  1);
1716  Simulator::Schedule(Time(Seconds(0.0005)),
1718  this,
1719  queueDisc,
1720  hdr,
1721  delay,
1722  69);
1723 
1724  // Add 70 ECT0 (ECN capable) packets from first flow
1725  hdr.SetEcn(Ipv4Header::ECN_ECT0);
1726  Simulator::Schedule(Time(Seconds(0)),
1728  this,
1729  queueDisc,
1730  hdr,
1731  delay,
1732  70);
1733 
1734  // Dequeue 140 packets with delay 1ms
1735  DequeueWithDelay(queueDisc, delay, 140);
1736  Simulator::Run();
1737  Simulator::Stop(Seconds(8.0));
1738  q0 = queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetObject<CoDelQueueDisc>();
1739 
1741  q0->GetStats().GetNMarkedPackets(CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK),
1742  68,
1743  "There should be 68 marked packets"
1744  "2nd ECT1 packet is enqueued at 1.5ms and dequeued at 3ms hence the delay of 1.5ms which "
1745  "not greater than CE threshold"
1746  "3rd packet is enqueued at 2.5ms and dequeued at 5ms hence the delay of 2.5ms and "
1747  "subsequent packet also do have delay"
1748  "greater than CE threshold so all the packets after 2nd packet are marked");
1749  NS_TEST_EXPECT_MSG_EQ(q0->GetStats().GetNDroppedPackets(CoDelQueueDisc::TARGET_EXCEEDED_DROP),
1750  0,
1751  "There should not be any dropped packets");
1752  NS_TEST_EXPECT_MSG_EQ(q0->GetStats().GetNMarkedPackets(CoDelQueueDisc::TARGET_EXCEEDED_MARK),
1753  1,
1754  "There should be 1 marked packets");
1755 
1756  Simulator::Destroy();
1757 }
1758 
1765 {
1766  public:
1768 };
1769 
1771  : TestSuite("fq-codel-queue-disc", UNIT)
1772 {
1773  AddTestCase(new FqCoDelQueueDiscNoSuitableFilter, TestCase::QUICK);
1775  AddTestCase(new FqCoDelQueueDiscDeficit, TestCase::QUICK);
1776  AddTestCase(new FqCoDelQueueDiscTCPFlowsSeparation, TestCase::QUICK);
1777  AddTestCase(new FqCoDelQueueDiscUDPFlowsSeparation, TestCase::QUICK);
1778  AddTestCase(new FqCoDelQueueDiscECNMarking, TestCase::QUICK);
1779  AddTestCase(new FqCoDelQueueDiscSetLinearProbing, TestCase::QUICK);
1780  AddTestCase(new FqCoDelQueueDiscL4sMode, TestCase::QUICK);
1781 }
1782 
This class tests the deficit per flow.
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header hdr)
Enqueue a packet.
void DoRun() override
Implementation to actually run this TestCase.
void Dequeue(Ptr< FqCoDelQueueDisc > queue, uint32_t nPkt)
Dequeue some packets.
void DoRun() override
Implementation to actually run this TestCase.
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header hdr, uint32_t nPkt, uint32_t nPktEnqueued, uint32_t nQueueFlows)
Enqueue some packets.
void DequeueWithDelay(Ptr< FqCoDelQueueDisc > queue, double delay, uint32_t nPkt)
Dequeue some packets with delay.
This class tests the IP flows separation and the packet limit.
void DoRun() override
Implementation to actually run this TestCase.
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header hdr)
Enqueue a packet.
void DoRun() override
Implementation to actually run this TestCase.
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header hdr, uint32_t nPkt)
Enqueue some packets.
void AddPacketWithDelay(Ptr< FqCoDelQueueDisc > queue, Ipv4Header hdr, double delay, uint32_t nPkt)
Enqueue some packets with delay.
void DequeueWithDelay(Ptr< FqCoDelQueueDisc > queue, double delay, uint32_t nPkt)
Dequeue some packets with delay.
void Dequeue(Ptr< FqCoDelQueueDisc > queue, uint32_t nPkt)
Dequeue some packets.
This class tests packets for which there is no suitable filter.
void DoRun() override
Implementation to actually run this TestCase.
This class tests linear probing, collision response, and set creation capability of set associative h...
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header hdr)
Enqueue a packet.
void DoRun() override
Implementation to actually run this TestCase.
This class tests the TCP flows separation.
void DoRun() override
Implementation to actually run this TestCase.
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header ipHdr, TcpHeader tcpHdr)
Enqueue a packet.
FQ-CoDel queue disc test suite.
This class tests the UDP flows separation.
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header ipHdr, UdpHeader udpHdr)
Enqueue a packet.
void DoRun() override
Implementation to actually run this TestCase.
Simple test packet filter able to classify IPv4 packets.
bool CheckProtocol(Ptr< QueueDiscItem > item) const override
Check the protocol.
int32_t DoClassify(Ptr< QueueDiscItem > item) const override
Classify a QueueDiscItem.
static TypeId GetTypeId()
Get the type ID.
a polymophic address class
Definition: address.h:101
A CoDel packet queue disc.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
Packet header for IPv4.
Definition: ipv4-header.h:34
void SetDestination(Ipv4Address destination)
Definition: ipv4-header.cc:309
void SetPayloadSize(uint16_t size)
Definition: ipv4-header.cc:57
void SetEcn(EcnType ecn)
Set ECN Field.
Definition: ipv4-header.cc:100
void SetProtocol(uint8_t num)
Definition: ipv4-header.cc:288
void SetSource(Ipv4Address source)
Definition: ipv4-header.cc:295
Ipv4PacketFilter is the abstract base class for filters defined for IPv4 packets.
Packet header for IPv6.
Definition: ipv6-header.h:35
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:268
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
Hold variables of type string.
Definition: string.h:56
Header for the Transmission Control Protocol.
Definition: tcp-header.h:47
void SetDestinationPort(uint16_t port)
Set the destination port.
Definition: tcp-header.cc:70
void SetSourcePort(uint16_t port)
Set the source port.
Definition: tcp-header.cc:64
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
Packet header for UDP packets.
Definition: udp-header.h:41
void SetSourcePort(uint16_t port)
Definition: udp-header.cc:42
void SetDestinationPort(uint16_t port)
Definition: udp-header.cc:36
Hold an unsigned integer type.
Definition: uinteger.h:45
static FqCoDelQueueDiscTestSuite g_fqCoDelQueueDiscTestSuite
Do not forget to allocate an instance of this TestSuite.
static int32_t g_hash
Variable to assign g_hash to a new packet's flow.
@ INACTIVE
Inactive Period or unslotted CSMA-CA.
Definition: lr-wpan-mac.h:104
#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:144
#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:666
#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:251
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
void(* Time)(Time oldValue, Time newValue)
TracedValue callback signature for Time.
Definition: nstime.h:839
Every class exported by the ns3 library is enclosed in the ns3 namespace.