A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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
37using namespace ns3;
38
39/// Variable to assign g_hash to a new packet's flow
41
42/**
43 * \ingroup system-tests-tc
44 *
45 * Simple test packet filter able to classify IPv4 packets.
46 */
48{
49 public:
50 /**
51 * \brief Get the type ID.
52 * \return the object TypeId
53 */
54 static TypeId GetTypeId();
55
57 ~Ipv4TestPacketFilter() override;
58
59 private:
60 /**
61 * Classify a QueueDiscItem
62 * \param item The item to classify (unused).
63 * \return a pre-set hash value.
64 */
65 int32_t DoClassify(Ptr<QueueDiscItem> item) const override;
66
67 /**
68 * Check the protocol.
69 * \param item The item to check (unused).
70 * \return true.
71 */
72 bool CheckProtocol(Ptr<QueueDiscItem> item) const override;
73};
74
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
95{
96 return g_hash;
97}
98
99bool
101{
102 return true;
103}
104
105/**
106 * \ingroup system-tests-tc
107 *
108 * This class tests packets for which there is no suitable filter.
109 */
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
129void
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
161}
162
163/**
164 * \ingroup system-tests-tc
165 *
166 * This class tests the IP flows separation and the packet limit.
167 */
169{
170 public:
173
174 private:
175 void DoRun() override;
176 /**
177 * Enqueue a packet.
178 * \param queue The queue disc.
179 * \param hdr The IPv4 header.
180 */
182};
183
185 : TestCase("Test IP flows separation and packet limit")
186{
187}
188
190{
191}
192
193void
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
203void
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
256}
257
258/**
259 * \ingroup system-tests-tc
260 *
261 * This class tests the deficit per flow.
262 */
264{
265 public:
267 ~FqCoDelQueueDiscDeficit() override;
268
269 private:
270 void DoRun() override;
271 /**
272 * Enqueue a packet.
273 * \param queue The queue disc.
274 * \param hdr The IPv4 header.
275 */
277};
278
280 : TestCase("Test credits and flows status")
281{
282}
283
285{
286}
287
288void
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
297void
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(),
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(),
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(),
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(),
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(),
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(),
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(),
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(),
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(),
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(),
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(),
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
482}
483
484/**
485 * \ingroup system-tests-tc
486 *
487 * This class tests the TCP flows separation.
488 */
490{
491 public:
494
495 private:
496 void DoRun() override;
497 /**
498 * Enqueue a packet.
499 * \param queue The queue disc.
500 * \param ipHdr The IPv4 header.
501 * \param tcpHdr The TCP header.
502 */
503 void AddPacket(Ptr<FqCoDelQueueDisc> queue, Ipv4Header ipHdr, TcpHeader tcpHdr);
504};
505
507 : TestCase("Test TCP flows separation")
508{
509}
510
512{
513}
514
515void
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
527void
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
607}
608
609/**
610 * \ingroup system-tests-tc
611 *
612 * This class tests the UDP flows separation
613 */
615{
616 public:
619
620 private:
621 void DoRun() override;
622 /**
623 * Enqueue a packet.
624 * \param queue The queue disc.
625 * \param ipHdr The IPv4 header.
626 * \param udpHdr The UDP header.
627 */
628 void AddPacket(Ptr<FqCoDelQueueDisc> queue, Ipv4Header ipHdr, UdpHeader udpHdr);
629};
630
632 : TestCase("Test UDP flows separation")
633{
634}
635
637{
638}
639
640void
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
652void
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
732}
733
734/**
735 * \ingroup system-tests-tc
736 *
737 * \brief This class tests ECN marking.
738 *
739 * Any future classifier options (e.g. SetAssociativeHash) should be
740 * disabled to prevent a hash collision on this test case.
741 */
743{
744 public:
747
748 private:
749 void DoRun() override;
750 /**
751 * Enqueue some packets.
752 * \param queue The queue disc.
753 * \param hdr The IPv4 header.
754 * \param nPkt The number of packets to enqueue.
755 * \param nPktEnqueued The expected number of queue disc classes.
756 * \param nQueueFlows The expected number of flows in the queue.
757 */
759 Ipv4Header hdr,
760 uint32_t nPkt,
761 uint32_t nPktEnqueued,
762 uint32_t nQueueFlows);
763 /**
764 * Dequeue some packets.
765 * \param queue The queue disc.
766 * \param nPkt The number of packets to dequeue.
767 */
768 void Dequeue(Ptr<FqCoDelQueueDisc> queue, uint32_t nPkt);
769 /**
770 * Dequeue some packets with delay.
771 * \param queue The queue disc.
772 * \param delay Delay [seconds].
773 * \param nPkt The number of packets to dequeue.
774 */
775 void DequeueWithDelay(Ptr<FqCoDelQueueDisc> queue, double delay, uint32_t nPkt);
776};
777
779 : TestCase("Test ECN marking")
780{
781}
782
784{
785}
786
787void
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
809void
811{
812 for (uint32_t i = 0; i < nPkt; i++)
813 {
814 Ptr<QueueDiscItem> item = queue->Dequeue();
815 }
816}
817
818void
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
833void
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);
859
860 // Add 20 ECT0 (ECN capable) packets from the first flow
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"));
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"));
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"));
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"));
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);
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(),
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(),
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(),
1025 "flow queue should have ECT0 packets");
1026
1028
1029 // Test case 2, CeThreshold set to 2ms
1030 queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc>("MaxSize",
1031 StringValue("10240p"),
1032 "UseEcn",
1033 BooleanValue(true),
1034 "CeThreshold",
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"));
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"));
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"));
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"));
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"));
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);
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(),
1178 "flow queue should have ECT0 packets");
1179 pktQ1 = DynamicCast<const Ipv4QueueDiscItem>(q1->Peek());
1180 NS_TEST_EXPECT_MSG_NE(pktQ1->GetHeader().GetEcn(),
1182 "flow queue should have ECT0 packets");
1183 pktQ2 = DynamicCast<const Ipv4QueueDiscItem>(q2->Peek());
1184 NS_TEST_EXPECT_MSG_NE(pktQ2->GetHeader().GetEcn(),
1186 "flow queue should have ECT0 packets");
1187
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",
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"));
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"));
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"));
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"));
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"));
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);
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(),
1341 "flow queue should have ECT0 packets");
1342 pktQ1 = DynamicCast<const Ipv4QueueDiscItem>(q1->Peek());
1343 NS_TEST_EXPECT_MSG_NE(pktQ1->GetHeader().GetEcn(),
1345 "flow queue should have ECT0 packets");
1346 pktQ2 = DynamicCast<const Ipv4QueueDiscItem>(q2->Peek());
1347 NS_TEST_EXPECT_MSG_NE(pktQ2->GetHeader().GetEcn(),
1349 "flow queue should have ECT0 packets");
1350
1352}
1353
1354/**
1355 * \ingroup system-tests-tc
1356 *
1357 * \brief This class tests linear probing, collision response, and set
1358 * creation capability of set associative hashing in FqCodel.
1359 *
1360 * We modified DoClassify () and CheckProtocol () so that we could control
1361 * the hash returned for each packet. In the beginning, we use flow hashes
1362 * ranging from 0 to 7. These must go into different queues in the same set.
1363 * The set number for these is obtained using outerHash, which is 0.
1364 * When a new packet arrives with flow hash 1024, outerHash = 0 is obtained
1365 * and the first set is iteratively searched.
1366 * The packet is eventually added to queue 0 since the tags of queues
1367 * in the set do not match with the hash of the flow. The tag of queue 0 is
1368 * updated as 1024. When a packet with hash 1025 arrives, outerHash = 0
1369 * is obtained and the first set is iteratively searched.
1370 * Since there is no match, it is added to queue 0 and the tag of queue 0 is
1371 * updated to 1025.
1372 *
1373 * The variable outerHash stores the nearest multiple of 8 that is lesser than
1374 * the hash. When a flow hash of 20 arrives, the value of outerHash
1375 * is 16. Since m_flowIndices[16] wasn't previously allotted, a new flow
1376 * is created, and the tag corresponding to this queue is set to 20.
1377 */
1379{
1380 public:
1383
1384 private:
1385 void DoRun() override;
1386 /**
1387 * Enqueue a packet.
1388 * \param queue The queue disc.
1389 * \param hdr The IPv4 header.
1390 */
1392};
1393
1395 : TestCase("Test credits and flows status")
1396{
1397}
1398
1400{
1401}
1402
1403void
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
1412void
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");
1489}
1490
1491/**
1492 * \ingroup system-tests-tc
1493 *
1494 * \brief This class tests L4S mode.
1495 * Any future classifier options (e.g. SetAssociativeHash) should be
1496 * disabled to prevent a hash collision on this test case.
1497 */
1499{
1500 public:
1502 ~FqCoDelQueueDiscL4sMode() override;
1503
1504 private:
1505 void DoRun() override;
1506
1507 /**
1508 * Enqueue some packets.
1509 * \param queue The queue disc.
1510 * \param hdr The IPv4 header.
1511 * \param nPkt The number of packets to enqueue.
1512 */
1513 void AddPacket(Ptr<FqCoDelQueueDisc> queue, Ipv4Header hdr, uint32_t nPkt);
1514
1515 /**
1516 * Enqueue some packets with delay.
1517 * \param queue The queue disc.
1518 * \param hdr The IPv4 header.
1519 * \param delay Delay [seconds].
1520 * \param nPkt The number of packets to enqueue.
1521 */
1523 Ipv4Header hdr,
1524 double delay,
1525 uint32_t nPkt);
1526
1527 /**
1528 * Dequeue some packets.
1529 * \param queue The queue disc.
1530 * \param nPkt The number of packets to dequeue.
1531 */
1532 void Dequeue(Ptr<FqCoDelQueueDisc> queue, uint32_t nPkt);
1533 /**
1534 * Dequeue some packets with delay.
1535 * \param queue The queue disc.
1536 * \param delay Delay [seconds].
1537 * \param nPkt The number of packets to dequeue.
1538 */
1539 void DequeueWithDelay(Ptr<FqCoDelQueueDisc> queue, double delay, uint32_t nPkt);
1540};
1541
1543 : TestCase("Test L4S mode")
1544{
1545}
1546
1548{
1549}
1550
1551void
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
1563void
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
1580void
1582{
1583 for (uint32_t i = 0; i < nPkt; i++)
1584 {
1585 Ptr<QueueDiscItem> item = queue->Dequeue();
1586 }
1587}
1588
1589void
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
1602void
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",
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);
1630
1631 // Add 70 ECT1 (ECN capable) packets from the first flow
1632 // Set delay = 0.5ms
1633 double delay = 0.0005;
1636 this,
1637 queueDisc,
1638 hdr,
1639 delay,
1640 70);
1641
1642 // Add 70 ECT0 (ECN capable) packets from second flow
1644 hdr.SetDestination(Ipv4Address("10.10.1.10"));
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);
1659 queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetObject<CoDelQueueDisc>();
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
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",
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);
1706
1707 // Add 70 ECT1 (ECN capable) packets from the first flow
1708 // Set delay = 1ms
1709 delay = 0.001;
1712 this,
1713 queueDisc,
1714 hdr,
1715 1);
1718 this,
1719 queueDisc,
1720 hdr,
1721 delay,
1722 69);
1723
1724 // Add 70 ECT0 (ECN capable) packets from first flow
1728 this,
1729 queueDisc,
1730 hdr,
1731 delay,
1732 70);
1733
1734 // Dequeue 140 packets with delay 1ms
1735 DequeueWithDelay(queueDisc, delay, 140);
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
1757}
1758
1759/**
1760 * \ingroup system-tests-tc
1761 *
1762 * FQ-CoDel queue disc test suite.
1763 */
1765{
1766 public:
1768};
1769
1771 : TestSuite("fq-codel-queue-disc", Type::UNIT)
1772{
1773 AddTestCase(new FqCoDelQueueDiscNoSuitableFilter, TestCase::Duration::QUICK);
1774 AddTestCase(new FqCoDelQueueDiscIPFlowsSeparationAndPacketLimit, TestCase::Duration::QUICK);
1775 AddTestCase(new FqCoDelQueueDiscDeficit, TestCase::Duration::QUICK);
1776 AddTestCase(new FqCoDelQueueDiscTCPFlowsSeparation, TestCase::Duration::QUICK);
1777 AddTestCase(new FqCoDelQueueDiscUDPFlowsSeparation, TestCase::Duration::QUICK);
1778 AddTestCase(new FqCoDelQueueDiscECNMarking, TestCase::Duration::QUICK);
1779 AddTestCase(new FqCoDelQueueDiscSetLinearProbing, TestCase::Duration::QUICK);
1780 AddTestCase(new FqCoDelQueueDiscL4sMode, TestCase::Duration::QUICK);
1781}
1782
1783/// Do not forget to allocate an instance of this TestSuite.
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
AttributeValue implementation for Boolean.
Definition: boolean.h:37
A CoDel packet queue disc.
static constexpr const char * TARGET_EXCEEDED_DROP
Sojourn time above target.
static constexpr const char * CE_THRESHOLD_EXCEEDED_MARK
Sojourn time above CE threshold.
static constexpr const char * TARGET_EXCEEDED_MARK
Sojourn time above target.
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
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static void Run()
Run the simulation.
Definition: simulator.cc:178
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:186
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:1061
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1268
Type
Type of test.
Definition: test.h:1275
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
AttributeValue implementation for Time.
Definition: nstime.h:1413
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
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.
#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:145
#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:667
#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:252
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
Every class exported by the ns3 library is enclosed in the ns3 namespace.