A Discrete-Event Network Simulator
API
fq-codel-queue-disc-test-suite.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2016 Universita' degli Studi di Napoli Federico II
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Authors: Pasquale Imputato <p.imputato@gmail.com>
19  * Stefano Avallone <stefano.avallone@unina.it>
20 */
21 
22 #include "ns3/test.h"
23 #include "ns3/simulator.h"
24 #include "ns3/fq-codel-queue-disc.h"
25 #include "ns3/codel-queue-disc.h"
26 #include "ns3/ipv4-header.h"
27 #include "ns3/ipv4-packet-filter.h"
28 #include "ns3/ipv4-queue-disc-item.h"
29 #include "ns3/ipv4-address.h"
30 #include "ns3/ipv6-header.h"
31 #include "ns3/ipv6-packet-filter.h"
32 #include "ns3/ipv6-queue-disc-item.h"
33 #include "ns3/tcp-header.h"
34 #include "ns3/udp-header.h"
35 #include "ns3/string.h"
36 #include "ns3/pointer.h"
37 
38 using namespace ns3;
39 
41 static int32_t g_hash;
42 
49 public:
54  static TypeId GetTypeId (void);
55 
57  virtual ~Ipv4TestPacketFilter ();
58 
59 private:
65  virtual int32_t DoClassify (Ptr<QueueDiscItem> item) const;
66 
72  virtual bool CheckProtocol (Ptr<QueueDiscItem> item) const;
73 };
74 
75 TypeId
77 {
78  static TypeId tid = TypeId ("ns3::Ipv4TestPacketFilter")
80  .SetGroupName ("Internet")
81  .AddConstructor<Ipv4TestPacketFilter> ()
82  ;
83  return tid;
84 }
85 
87 {
88 }
89 
91 {
92 }
93 
94 int32_t
96 {
97  return g_hash;
98 }
99 
100 bool
102 {
103  return true;
104 }
105 
112 {
113 public:
116 
117 private:
118  virtual void DoRun (void);
119 };
120 
122  : TestCase ("Test packets that are not classified by any filter")
123 {
124 }
125 
127 {
128 }
129 
130 void
132 {
133  // Packets that cannot be classified by the available filters should be dropped
134  Ptr<FqCoDelQueueDisc> queueDisc = 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 (), 0, "no flow queue should have been created");
150 
151  p = Create<Packet> (reinterpret_cast<const uint8_t*> ("hello, world"), 12);
152  item = Create<Ipv6QueueDiscItem> (p, dest, 0, ipv6Header);
153  queueDisc->Enqueue (item);
154  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetNQueueDiscClasses (), 0, "no flow queue should have been created");
155 
156  Simulator::Destroy ();
157 }
158 
165 {
166 public:
169 
170 private:
171  virtual void DoRun (void);
177  void AddPacket (Ptr<FqCoDelQueueDisc> queue, Ipv4Header hdr);
178 };
179 
181  : TestCase ("Test IP flows separation and packet limit")
182 {
183 }
184 
186 {
187 }
188 
189 void
191 {
192  Ptr<Packet> p = Create<Packet> (100);
193  Address dest;
194  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, hdr);
195  queue->Enqueue (item);
196 }
197 
198 void
200 {
201  Ptr<FqCoDelQueueDisc> queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc> ("MaxSize", StringValue ("4p"));
202 
203  queueDisc->SetQuantum (1500);
204  queueDisc->Initialize ();
205 
206  Ipv4Header hdr;
207  hdr.SetPayloadSize (100);
208  hdr.SetSource (Ipv4Address ("10.10.1.1"));
209  hdr.SetDestination (Ipv4Address ("10.10.1.2"));
210  hdr.SetProtocol (7);
211 
212  // Add three packets from the first flow
213  AddPacket (queueDisc, hdr);
214  AddPacket (queueDisc, hdr);
215  AddPacket (queueDisc, hdr);
216  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 3, "unexpected number of packets in the queue disc");
217  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the flow queue");
218 
219  // Add two packets from the second flow
220  hdr.SetDestination (Ipv4Address ("10.10.1.7"));
221  // Add the first packet
222  AddPacket (queueDisc, hdr);
223  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 4, "unexpected number of packets in the queue disc");
224  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the flow queue");
225  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the flow queue");
226  // Add the second packet that causes two packets to be dropped from the fat flow (max backlog = 300, threshold = 150)
227  AddPacket (queueDisc, hdr);
228  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 3, "unexpected number of packets in the queue disc");
229  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the flow queue");
230  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the flow queue");
231 
232  Simulator::Destroy ();
233 }
234 
241 {
242 public:
244  virtual ~FqCoDelQueueDiscDeficit ();
245 
246 private:
247  virtual void DoRun (void);
253  void AddPacket (Ptr<FqCoDelQueueDisc> queue, Ipv4Header hdr);
254 };
255 
257  : TestCase ("Test credits and flows status")
258 {
259 }
260 
262 {
263 }
264 
265 void
267 {
268  Ptr<Packet> p = Create<Packet> (100);
269  Address dest;
270  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, hdr);
271  queue->Enqueue (item);
272 }
273 
274 void
276 {
277  Ptr<FqCoDelQueueDisc> queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc> ();
278 
279  queueDisc->SetQuantum (90);
280  queueDisc->Initialize ();
281 
282  Ipv4Header hdr;
283  hdr.SetPayloadSize (100);
284  hdr.SetSource (Ipv4Address ("10.10.1.1"));
285  hdr.SetDestination (Ipv4Address ("10.10.1.2"));
286  hdr.SetProtocol (7);
287 
288  // Add a packet from the first flow
289  AddPacket (queueDisc, hdr);
290  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 1, "unexpected number of packets in the queue disc");
291  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the first flow queue");
292  Ptr<FqCoDelFlow> flow1 = StaticCast<FqCoDelFlow> (queueDisc->GetQueueDiscClass (0));
293  NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), static_cast<int32_t> (queueDisc->GetQuantum ()), "the deficit of the first flow must equal the quantum");
294  NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqCoDelFlow::NEW_FLOW, "the first flow must be in the list of new queues");
295  // Dequeue a packet
296  queueDisc->Dequeue ();
297  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 0, "unexpected number of packets in the queue disc");
298  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 0, "unexpected number of packets in the first flow queue");
299  // the deficit for the first flow becomes 90 - (100+20) = -30
300  NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), -30, "unexpected deficit for the first flow");
301 
302  // Add two packets from the first flow
303  AddPacket (queueDisc, hdr);
304  AddPacket (queueDisc, hdr);
305  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 2, "unexpected number of packets in the queue disc");
306  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the first flow queue");
307  NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqCoDelFlow::NEW_FLOW, "the first flow must still be in the list of new queues");
308 
309  // Add two packets from the second flow
310  hdr.SetDestination (Ipv4Address ("10.10.1.10"));
311  AddPacket (queueDisc, hdr);
312  AddPacket (queueDisc, hdr);
313  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 4, "unexpected number of packets in the queue disc");
314  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the first flow queue");
315  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the second flow queue");
316  Ptr<FqCoDelFlow> flow2 = StaticCast<FqCoDelFlow> (queueDisc->GetQueueDiscClass (1));
317  NS_TEST_ASSERT_MSG_EQ (flow2->GetDeficit (), static_cast<int32_t> (queueDisc->GetQuantum ()), "the deficit of the second flow must equal the quantum");
318  NS_TEST_ASSERT_MSG_EQ (flow2->GetStatus (), FqCoDelFlow::NEW_FLOW, "the second flow must be in the list of new queues");
319 
320  // Dequeue a packet (from the second flow, as the first flow has a negative deficit)
321  queueDisc->Dequeue ();
322  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 3, "unexpected number of packets in the queue disc");
323  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the first flow queue");
324  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
325  // the first flow got a quantum of deficit (-30+90=60) and has been moved to the end of the list of old queues
326  NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), 60, "unexpected deficit for the first flow");
327  NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqCoDelFlow::OLD_FLOW, "the first flow must be in the list of old queues");
328  // the second flow has a negative deficit (-30) and is still in the list of new queues
329  NS_TEST_ASSERT_MSG_EQ (flow2->GetDeficit (), -30, "unexpected deficit for the second flow");
330  NS_TEST_ASSERT_MSG_EQ (flow2->GetStatus (), FqCoDelFlow::NEW_FLOW, "the second flow must be in the list of new queues");
331 
332  // Dequeue a packet (from the first flow, as the second flow has a negative deficit)
333  queueDisc->Dequeue ();
334  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 2, "unexpected number of packets in the queue disc");
335  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the first flow queue");
336  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
337  // the first flow has a negative deficit (60-(100+20)= -60) and stays in the list of old queues
338  NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), -60, "unexpected deficit for the first flow");
339  NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqCoDelFlow::OLD_FLOW, "the first flow must be in the list of old queues");
340  // the second flow got a quantum of deficit (-30+90=60) and has been moved to the end of the list of old queues
341  NS_TEST_ASSERT_MSG_EQ (flow2->GetDeficit (), 60, "unexpected deficit for the second flow");
342  NS_TEST_ASSERT_MSG_EQ (flow2->GetStatus (), FqCoDelFlow::OLD_FLOW, "the second flow must be in the list of new queues");
343 
344  // Dequeue a packet (from the second flow, as the first flow has a negative deficit)
345  queueDisc->Dequeue ();
346  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 1, "unexpected number of packets in the queue disc");
347  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the first flow queue");
348  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 0, "unexpected number of packets in the second flow queue");
349  // the first flow got a quantum of deficit (-60+90=30) and has been moved to the end of the list of old queues
350  NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), 30, "unexpected deficit for the first flow");
351  NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqCoDelFlow::OLD_FLOW, "the first flow must be in the list of old queues");
352  // the second flow has a negative deficit (60-(100+20)= -60)
353  NS_TEST_ASSERT_MSG_EQ (flow2->GetDeficit (), -60, "unexpected deficit for the second flow");
354  NS_TEST_ASSERT_MSG_EQ (flow2->GetStatus (), FqCoDelFlow::OLD_FLOW, "the second flow must be in the list of new queues");
355 
356  // Dequeue a packet (from the first flow, as the second flow has a negative deficit)
357  queueDisc->Dequeue ();
358  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 0, "unexpected number of packets in the queue disc");
359  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 0, "unexpected number of packets in the first flow queue");
360  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 0, "unexpected number of packets in the second flow queue");
361  // the first flow has a negative deficit (30-(100+20)= -90)
362  NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), -90, "unexpected deficit for the first flow");
363  NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqCoDelFlow::OLD_FLOW, "the first flow must be in the list of old queues");
364  // the second flow got a quantum of deficit (-60+90=30) and has been moved to the end of the list of old queues
365  NS_TEST_ASSERT_MSG_EQ (flow2->GetDeficit (), 30, "unexpected deficit for the second flow");
366  NS_TEST_ASSERT_MSG_EQ (flow2->GetStatus (), FqCoDelFlow::OLD_FLOW, "the second flow must be in the list of new queues");
367 
368  // Dequeue a packet
369  queueDisc->Dequeue ();
370  // the first flow is at the head of the list of old queues but has a negative deficit, thus it gets a quantun
371  // of deficit (-90+90=0) and is moved to the end of the list of old queues. Then, the second flow (which has a
372  // positive deficit) is selected, but the second flow is empty and thus it is set to inactive. The first flow is
373  // reconsidered, but it has a null deficit, hence it gets another quantum of deficit (0+90=90). Then, the first
374  // flow is reconsidered again, now it has a positive deficit and hence it is selected. But, it is empty and
375  // therefore is set to inactive, too.
376  NS_TEST_ASSERT_MSG_EQ (flow1->GetDeficit (), 90, "unexpected deficit for the first flow");
377  NS_TEST_ASSERT_MSG_EQ (flow1->GetStatus (), FqCoDelFlow::INACTIVE, "the first flow must be inactive");
378  NS_TEST_ASSERT_MSG_EQ (flow2->GetDeficit (), 30, "unexpected deficit for the second flow");
379  NS_TEST_ASSERT_MSG_EQ (flow2->GetStatus (), FqCoDelFlow::INACTIVE, "the second flow must be inactive");
380 
381  Simulator::Destroy ();
382 }
383 
390 {
391 public:
394 
395 private:
396  virtual void DoRun (void);
403  void AddPacket (Ptr<FqCoDelQueueDisc> queue, Ipv4Header ipHdr, TcpHeader tcpHdr);
404 };
405 
407  : TestCase ("Test TCP flows separation")
408 {
409 }
410 
412 {
413 }
414 
415 void
417 {
418  Ptr<Packet> p = Create<Packet> (100);
419  p->AddHeader (tcpHdr);
420  Address dest;
421  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, ipHdr);
422  queue->Enqueue (item);
423 }
424 
425 void
427 {
428  Ptr<FqCoDelQueueDisc> queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc> ("MaxSize", StringValue ("10p"));
429 
430  queueDisc->SetQuantum (1500);
431  queueDisc->Initialize ();
432 
433  Ipv4Header hdr;
434  hdr.SetPayloadSize (100);
435  hdr.SetSource (Ipv4Address ("10.10.1.1"));
436  hdr.SetDestination (Ipv4Address ("10.10.1.2"));
437  hdr.SetProtocol (6);
438 
439  TcpHeader tcpHdr;
440  tcpHdr.SetSourcePort (7);
441  tcpHdr.SetDestinationPort (27);
442 
443  // Add three packets from the first flow
444  AddPacket (queueDisc, hdr, tcpHdr);
445  AddPacket (queueDisc, hdr, tcpHdr);
446  AddPacket (queueDisc, hdr, tcpHdr);
447  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 3, "unexpected number of packets in the queue disc");
448  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
449 
450  // Add a packet from the second flow
451  tcpHdr.SetSourcePort (8);
452  AddPacket (queueDisc, hdr, tcpHdr);
453  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 4, "unexpected number of packets in the queue disc");
454  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
455  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
456 
457  // Add a packet from the third flow
458  tcpHdr.SetDestinationPort (28);
459  AddPacket (queueDisc, hdr, tcpHdr);
460  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 5, "unexpected number of packets in the queue disc");
461  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
462  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
463  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the third flow queue");
464 
465  // Add two packets from the fourth flow
466  tcpHdr.SetSourcePort (7);
467  AddPacket (queueDisc, hdr, tcpHdr);
468  AddPacket (queueDisc, hdr, tcpHdr);
469  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 7, "unexpected number of packets in the queue disc");
470  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
471  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
472  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the third flow queue");
473  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (3)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the third flow queue");
474 
475  Simulator::Destroy ();
476 }
477 
484 {
485 public:
488 
489 private:
490  virtual void DoRun (void);
497  void AddPacket (Ptr<FqCoDelQueueDisc> queue, Ipv4Header ipHdr, UdpHeader udpHdr);
498 };
499 
501  : TestCase ("Test UDP flows separation")
502 {
503 }
504 
506 {
507 }
508 
509 void
511 {
512  Ptr<Packet> p = Create<Packet> (100);
513  p->AddHeader (udpHdr);
514  Address dest;
515  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, ipHdr);
516  queue->Enqueue (item);
517 }
518 
519 void
521 {
522  Ptr<FqCoDelQueueDisc> queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc> ("MaxSize", StringValue ("10p"));
523 
524  queueDisc->SetQuantum (1500);
525  queueDisc->Initialize ();
526 
527  Ipv4Header hdr;
528  hdr.SetPayloadSize (100);
529  hdr.SetSource (Ipv4Address ("10.10.1.1"));
530  hdr.SetDestination (Ipv4Address ("10.10.1.2"));
531  hdr.SetProtocol (17);
532 
533  UdpHeader udpHdr;
534  udpHdr.SetSourcePort (7);
535  udpHdr.SetDestinationPort (27);
536 
537  // Add three packets from the first flow
538  AddPacket (queueDisc, hdr, udpHdr);
539  AddPacket (queueDisc, hdr, udpHdr);
540  AddPacket (queueDisc, hdr, udpHdr);
541  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 3, "unexpected number of packets in the queue disc");
542  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
543 
544  // Add a packet from the second flow
545  udpHdr.SetSourcePort (8);
546  AddPacket (queueDisc, hdr, udpHdr);
547  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 4, "unexpected number of packets in the queue disc");
548  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
549  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
550 
551  // Add a packet from the third flow
552  udpHdr.SetDestinationPort (28);
553  AddPacket (queueDisc, hdr, udpHdr);
554  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 5, "unexpected number of packets in the queue disc");
555  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
556  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
557  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the third flow queue");
558 
559  // Add two packets from the fourth flow
560  udpHdr.SetSourcePort (7);
561  AddPacket (queueDisc, hdr, udpHdr);
562  AddPacket (queueDisc, hdr, udpHdr);
563  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 7, "unexpected number of packets in the queue disc");
564  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3, "unexpected number of packets in the first flow queue");
565  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the second flow queue");
566  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetNPackets (), 1, "unexpected number of packets in the third flow queue");
567  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (3)->GetQueueDisc ()->GetNPackets (), 2, "unexpected number of packets in the third flow queue");
568 
569  Simulator::Destroy ();
570 }
571 
581 {
582 public:
584  virtual ~FqCoDelQueueDiscECNMarking ();
585 
586 private:
587  virtual void DoRun (void);
596  void AddPacket (Ptr<FqCoDelQueueDisc> queue, Ipv4Header hdr, uint32_t nPkt, uint32_t nPktEnqueued, uint32_t nQueueFlows);
602  void Dequeue (Ptr<FqCoDelQueueDisc> queue, uint32_t nPkt);
609  void DequeueWithDelay (Ptr<FqCoDelQueueDisc> queue, double delay, uint32_t nPkt);
610 };
611 
613  : TestCase ("Test ECN marking")
614 {
615 }
616 
618 {
619 }
620 
621 void
622 FqCoDelQueueDiscECNMarking::AddPacket (Ptr<FqCoDelQueueDisc> queue, Ipv4Header hdr, uint32_t nPkt, uint32_t nPktEnqueued, uint32_t nQueueFlows)
623 {
624  Address dest;
625  Ptr<Packet> p = Create<Packet> (100);
626  for (uint32_t i = 0; i < nPkt; i++)
627  {
628  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, hdr);
629  queue->Enqueue (item);
630  }
631  NS_TEST_EXPECT_MSG_EQ (queue->GetNQueueDiscClasses (), nQueueFlows, "unexpected number of flow queues");
632  NS_TEST_EXPECT_MSG_EQ (queue->GetNPackets (), nPktEnqueued, "unexpected number of enqueued packets");
633 }
634 
635 void
637 {
638  for (uint32_t i = 0; i < nPkt; i++)
639  {
640  Ptr<QueueDiscItem> item = queue->Dequeue ();
641  }
642 }
643 
644 void
646 {
647  for (uint32_t i = 0; i < nPkt; i++)
648  {
649  Simulator::Schedule (Time (Seconds ((i + 1) * delay)), &FqCoDelQueueDiscECNMarking::Dequeue, this, queue, 1);
650  }
651 }
652 
653 void
655 {
656  // Test is divided into 3 sub test cases:
657  // 1) CeThreshold disabled
658  // 2) CeThreshold enabled
659  // 3) Same as 2 but with higher queue delay, leading to both mark types, and checks that the same packet is not marked twice
660 
661  // Test case 1, CeThreshold disabled
662  Ptr<FqCoDelQueueDisc> queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc> ("MaxSize", StringValue ("10240p"), "UseEcn", BooleanValue (true),
663  "Perturbation", UintegerValue (0));
664 
665  queueDisc->SetQuantum (1514);
666  queueDisc->Initialize ();
667  Ipv4Header hdr;
668  hdr.SetPayloadSize (100);
669  hdr.SetSource (Ipv4Address ("10.10.1.1"));
670  hdr.SetDestination (Ipv4Address ("10.10.1.2"));
671  hdr.SetProtocol (7);
672  hdr.SetEcn (Ipv4Header::ECN_ECT0);
673 
674  // Add 20 ECT0 (ECN capable) packets from the first flow
675  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 20, 1);
676 
677  // Add 20 ECT0 (ECN capable) packets from second flow
678  hdr.SetDestination (Ipv4Address ("10.10.1.10"));
679  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 40, 2);
680 
681  // Add 20 ECT0 (ECN capable) packets from third flow
682  hdr.SetDestination (Ipv4Address ("10.10.1.20"));
683  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 60, 3);
684 
685  // Add 20 NotECT packets from fourth flow
686  hdr.SetDestination (Ipv4Address ("10.10.1.30"));
687  hdr.SetEcn (Ipv4Header::ECN_NotECT);
688  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 80, 4);
689 
690  // Add 20 NotECT packets from fifth flow
691  hdr.SetDestination (Ipv4Address ("10.10.1.40"));
692  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 100, 5);
693 
694  //Dequeue 60 packets with delay 110ms to induce packet drops and keep some remaining packets in each queue
695  DequeueWithDelay (queueDisc, 0.11, 60);
696  Simulator::Run ();
697  Simulator::Stop (Seconds (8.0));
698  Ptr<CoDelQueueDisc> q0 = queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
699  Ptr<CoDelQueueDisc> q1 = queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
700  Ptr<CoDelQueueDisc> q2 = queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
701  Ptr<CoDelQueueDisc> q3 = queueDisc->GetQueueDiscClass (3)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
702  Ptr<CoDelQueueDisc> q4 = queueDisc->GetQueueDiscClass (4)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
703 
704 
705  //Ensure there are some remaining packets in the flow queues to check for flow queues with ECN capable packets
706  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
707  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
708  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
709  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (3)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
710  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (4)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
711 
712  // As packets in flow queues are ECN capable
713  NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK), 6, "There should be 6 marked packets"
714  "with 20 packets, total bytes in the queue = 120 * 20 = 2400. First packet dequeues at 110ms which is greater than"
715  "test's default target value 5ms. Sojourn time has just gone above target from below, need to stay above for at"
716  "least q->interval before packet can be dropped. Second packet dequeues at 220ms which is greater than last dequeue"
717  "time plus q->interval(test default 100ms) so the packet is marked. Third packet dequeues at 330ms and the sojourn"
718  "time stayed above the target and dropnext value is less than 320 hence the packet is marked. 4 subsequent packets"
719  "are marked as the sojourn time stays above the target. With 8th dequeue number of bytes in queue = 120 * 12 = 1440"
720  "which is less m_minBytes(test's default value 1500 bytes) hence the packets stop getting marked");
721  NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
722  NS_TEST_EXPECT_MSG_EQ (q1->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK), 6, "There should be 6 marked packets");
723  NS_TEST_EXPECT_MSG_EQ (q1->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
724  NS_TEST_EXPECT_MSG_EQ (q2->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK), 6, "There should be 6 marked packets");
725  NS_TEST_EXPECT_MSG_EQ (q2->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
726 
727  // As packets in flow queues are not ECN capable
728  NS_TEST_EXPECT_MSG_EQ (q3->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 4, "There should be 4 dropped packets"
729  "with 20 packets, total bytes in the queue = 120 * 20 = 2400. First packet dequeues at 110ms which is greater than"
730  "test's default target value 5ms. Sojourn time has just gone above target from below, need to stay above for at"
731  "least q->interval before packet can be dropped. Second packet dequeues at 220ms which is greater than last dequeue"
732  "time plus q->interval(test default 100ms) so packet is dropped and next is dequeued. 4th packet dequeues at 330ms"
733  "and the sojourn time stayed above the target and dropnext value is less than 320 hence the packet is dropped and next"
734  "packet is dequeued. 6th packet dequeues at 440ms and 2 more packets are dropped as dropnext value is increased twice."
735  "12 Packets remaining in the queue, total number of bytes int the queue = 120 * 12 = 1440 which is less"
736  "m_minBytes(test's default value 1500 bytes) hence the packets stop getting dropped");
737  NS_TEST_EXPECT_MSG_EQ (q3->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK), 0, "There should not be any marked packets");
738  NS_TEST_EXPECT_MSG_EQ (q4->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 4, "There should be 4 dropped packets");
739  NS_TEST_EXPECT_MSG_EQ (q4->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK), 0, "There should not be any marked packets");
740  // Ensure flow queue 0,1 and 2 have ECN capable packets
741  // Peek () changes the stats of the queue and that is reason to be keep this test at last
742  Ptr<const Ipv4QueueDiscItem> pktQ0 = DynamicCast<const Ipv4QueueDiscItem> (q0->Peek ());
743  NS_TEST_EXPECT_MSG_NE (pktQ0->GetHeader ().GetEcn (), Ipv4Header::ECN_NotECT,"flow queue should have ECT0 packets");
744  Ptr<const Ipv4QueueDiscItem> pktQ1 = DynamicCast<const Ipv4QueueDiscItem> (q1->Peek ());
745  NS_TEST_EXPECT_MSG_NE (pktQ1->GetHeader ().GetEcn (), Ipv4Header::ECN_NotECT,"flow queue should have ECT0 packets");
746  Ptr<const Ipv4QueueDiscItem> pktQ2 = DynamicCast<const Ipv4QueueDiscItem> (q2->Peek ());
747  NS_TEST_EXPECT_MSG_NE (pktQ2->GetHeader ().GetEcn (), Ipv4Header::ECN_NotECT,"flow queue should have ECT0 packets");
748 
749  Simulator::Destroy ();
750 
751  // Test case 2, CeThreshold set to 2ms
752  queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc> ("MaxSize", StringValue ("10240p"), "UseEcn", BooleanValue (true),
753  "CeThreshold", TimeValue (MilliSeconds (2)));
754  queueDisc->SetQuantum (1514);
755  queueDisc->Initialize ();
756 
757  // Add 20 ECT0 (ECN capable) packets from first flow
758  hdr.SetDestination (Ipv4Address ("10.10.1.2"));
759  hdr.SetEcn (Ipv4Header::ECN_ECT0);
760  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 20, 1);
761 
762  // Add 20 ECT0 (ECN capable) packets from second flow
763  hdr.SetDestination (Ipv4Address ("10.10.1.10"));
764  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 40, 2);
765 
766  // Add 20 ECT0 (ECN capable) packets from third flow
767  hdr.SetDestination (Ipv4Address ("10.10.1.20"));
768  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 60, 3);
769 
770  // Add 20 NotECT packets from fourth flow
771  hdr.SetDestination (Ipv4Address ("10.10.1.30"));
772  hdr.SetEcn (Ipv4Header::ECN_NotECT);
773  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 80, 4);
774 
775  // Add 20 NotECT packets from fifth flow
776  hdr.SetDestination (Ipv4Address ("10.10.1.40"));
777  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 100, 5);
778 
779  //Dequeue 60 packets with delay 0.1ms to induce packet drops and keep some remaining packets in each queue
780  DequeueWithDelay (queueDisc, 0.0001, 60);
781  Simulator::Run ();
782  Simulator::Stop (Seconds (8.0));
783  q0 = queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
784  q1 = queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
785  q2 = queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
786  q3 = queueDisc->GetQueueDiscClass (3)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
787  q4 = queueDisc->GetQueueDiscClass (4)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
788 
789  //Ensure there are some remaining packets in the flow queues to check for flow queues with ECN capable packets
790  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
791  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
792  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
793  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (3)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
794  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (4)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
795 
796  // As packets in flow queues are ECN capable
797  NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
798  NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK), 0, "There should not be any marked packets"
799  "with quantum of 1514, 13 packets of size 120 bytes can be dequeued. sojourn time of 13th packet is 1.3ms which is"
800  "less than CE threshold");
801  NS_TEST_EXPECT_MSG_EQ (q1->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
802  NS_TEST_EXPECT_MSG_EQ (q1->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK), 6, "There should be 6 marked packets"
803  "with quantum of 1514, 13 packets of size 120 bytes can be dequeued. sojourn time of 8th packet is 2.1ms which is greater"
804  "than CE threshold and subsequent packet also have sojourn time more 8th packet hence remaining packet are marked.");
805  NS_TEST_EXPECT_MSG_EQ (q2->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
806  NS_TEST_EXPECT_MSG_EQ (q2->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK), 13, "There should be 13 marked packets"
807  "with quantum of 1514, 13 packets of size 120 bytes can be dequeued and all of them have sojourn time more than CE threshold");
808 
809  // As packets in flow queues are not ECN capable
810  NS_TEST_EXPECT_MSG_EQ (q3->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK), 0, "There should not be any marked packets");
811  NS_TEST_EXPECT_MSG_EQ (q3->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
812  NS_TEST_EXPECT_MSG_EQ (q4->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK), 0, "There should not be any marked packets");
813  NS_TEST_EXPECT_MSG_EQ (q4->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
814 
815  // Ensure flow queue 0,1 and 2 have ECN capable packets
816  // Peek () changes the stats of the queue and that is reason to be keep this test at last
817  pktQ0 = DynamicCast<const Ipv4QueueDiscItem> (q0->Peek ());
818  NS_TEST_EXPECT_MSG_NE (pktQ0->GetHeader ().GetEcn (), Ipv4Header::ECN_NotECT,"flow queue should have ECT0 packets");
819  pktQ1 = DynamicCast<const Ipv4QueueDiscItem> (q1->Peek ());
820  NS_TEST_EXPECT_MSG_NE (pktQ1->GetHeader ().GetEcn (), Ipv4Header::ECN_NotECT,"flow queue should have ECT0 packets");
821  pktQ2 = DynamicCast<const Ipv4QueueDiscItem> (q2->Peek ());
822  NS_TEST_EXPECT_MSG_NE (pktQ2->GetHeader ().GetEcn (), Ipv4Header::ECN_NotECT,"flow queue should have ECT0 packets");
823 
824  Simulator::Destroy ();
825 
826  // Test case 3, CeThreshold set to 2ms with higher queue delay
827  queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc> ("MaxSize", StringValue ("10240p"), "UseEcn", BooleanValue (true),
828  "CeThreshold", TimeValue (MilliSeconds (2)));
829  queueDisc->SetQuantum (1514);
830  queueDisc->Initialize ();
831 
832  // Add 20 ECT0 (ECN capable) packets from first flow
833  hdr.SetDestination (Ipv4Address ("10.10.1.2"));
834  hdr.SetEcn (Ipv4Header::ECN_ECT0);
835  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 20, 1);
836 
837  // Add 20 ECT0 (ECN capable) packets from second flow
838  hdr.SetDestination (Ipv4Address ("10.10.1.10"));
839  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 40, 2);
840 
841  // Add 20 ECT0 (ECN capable) packets from third flow
842  hdr.SetDestination (Ipv4Address ("10.10.1.20"));
843  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 60, 3);
844 
845  // Add 20 NotECT packets from fourth flow
846  hdr.SetDestination (Ipv4Address ("10.10.1.30"));
847  hdr.SetEcn (Ipv4Header::ECN_NotECT);
848  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 80, 4);
849 
850  // Add 20 NotECT packets from fifth flow
851  hdr.SetDestination (Ipv4Address ("10.10.1.40"));
852  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscECNMarking::AddPacket, this, queueDisc, hdr, 20, 100, 5);
853 
854  //Dequeue 60 packets with delay 110ms to induce packet drops and keep some remaining packets in each queue
855  DequeueWithDelay (queueDisc, 0.110, 60);
856  Simulator::Run ();
857  Simulator::Stop (Seconds (8.0));
858  q0 = queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
859  q1 = queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
860  q2 = queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
861  q3 = queueDisc->GetQueueDiscClass (3)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
862  q4 = queueDisc->GetQueueDiscClass (4)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
863 
864  //Ensure there are some remaining packets in the flow queues to check for flow queues with ECN capable packets
865  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
866  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
867  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
868  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (3)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
869  NS_TEST_EXPECT_MSG_NE (queueDisc->GetQueueDiscClass (4)->GetQueueDisc ()->GetNPackets (), 0, "There should be some remaining packets");
870 
871  // As packets in flow queues are ECN capable
872  NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
873  NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK) +
874  q0->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK), 20 - q0->GetNPackets (), "Number of CE threshold"
875  " exceeded marks plus Number of Target exceeded marks should be equal to total number of packets dequeued");
876  NS_TEST_EXPECT_MSG_EQ (q1->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
877  NS_TEST_EXPECT_MSG_EQ (q1->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK) +
878  q1->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK), 20 - q1->GetNPackets (), "Number of CE threshold"
879  " exceeded marks plus Number of Target exceeded marks should be equal to total number of packets dequeued");
880  NS_TEST_EXPECT_MSG_EQ (q2->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
881  NS_TEST_EXPECT_MSG_EQ (q2->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK) +
882  q2->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK), 20 - q2->GetNPackets (), "Number of CE threshold"
883  " exceeded marks plus Number of Target exceeded marks should be equal to total number of packets dequeued");
884 
885  // As packets in flow queues are not ECN capable
886  NS_TEST_EXPECT_MSG_EQ (q3->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK), 0, "There should not be any marked packets");
887  NS_TEST_EXPECT_MSG_EQ (q3->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 4, "There should be 4 dropped packets"
888  " As queue delay is same as in test case 1, number of dropped packets should also be same");
889  NS_TEST_EXPECT_MSG_EQ (q4->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK), 0, "There should not be any marked packets");
890  NS_TEST_EXPECT_MSG_EQ (q4->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 4, "There should be 4 dropped packets");
891 
892  // Ensure flow queue 0,1 and 2 have ECN capable packets
893  // Peek () changes the stats of the queue and that is reason to be keep this test at last
894  pktQ0 = DynamicCast<const Ipv4QueueDiscItem> (q0->Peek ());
895  NS_TEST_EXPECT_MSG_NE (pktQ0->GetHeader ().GetEcn (), Ipv4Header::ECN_NotECT,"flow queue should have ECT0 packets");
896  pktQ1 = DynamicCast<const Ipv4QueueDiscItem> (q1->Peek ());
897  NS_TEST_EXPECT_MSG_NE (pktQ1->GetHeader ().GetEcn (), Ipv4Header::ECN_NotECT,"flow queue should have ECT0 packets");
898  pktQ2 = DynamicCast<const Ipv4QueueDiscItem> (q2->Peek ());
899  NS_TEST_EXPECT_MSG_NE (pktQ2->GetHeader ().GetEcn (), Ipv4Header::ECN_NotECT,"flow queue should have ECT0 packets");
900 
901  Simulator::Destroy ();
902 }
903 
929 {
930 public:
933 private:
934  virtual void DoRun (void);
940  void AddPacket (Ptr<FqCoDelQueueDisc> queue, Ipv4Header hdr);
941 };
942 
944  : TestCase ("Test credits and flows status")
945 {
946 }
947 
949 {
950 }
951 
952 void
954 {
955  Ptr<Packet> p = Create<Packet> (100);
956  Address dest;
957  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, hdr);
958  queue->Enqueue (item);
959 }
960 
961 void
963 {
964  Ptr<FqCoDelQueueDisc> queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc> ("EnableSetAssociativeHash", BooleanValue (true));
965  queueDisc->SetQuantum (90);
966  queueDisc->Initialize ();
967 
968  Ptr<Ipv4TestPacketFilter> filter = CreateObject<Ipv4TestPacketFilter> ();
969  queueDisc->AddPacketFilter (filter);
970 
971  Ipv4Header hdr;
972  hdr.SetPayloadSize (100);
973  hdr.SetSource (Ipv4Address ("10.10.1.1"));
974  hdr.SetDestination (Ipv4Address ("10.10.1.2"));
975  hdr.SetProtocol (7);
976 
977  g_hash = 0;
978  AddPacket (queueDisc, hdr);
979  g_hash = 1;
980  AddPacket (queueDisc, hdr);
981  AddPacket (queueDisc, hdr);
982  g_hash = 2;
983  AddPacket (queueDisc, hdr);
984  g_hash = 3;
985  AddPacket (queueDisc, hdr);
986  g_hash = 4;
987  AddPacket (queueDisc, hdr);
988  AddPacket (queueDisc, hdr);
989  g_hash = 5;
990  AddPacket (queueDisc, hdr);
991  g_hash = 6;
992  AddPacket (queueDisc, hdr);
993  g_hash = 7;
994  AddPacket (queueDisc, hdr);
995  g_hash = 1024;
996  AddPacket (queueDisc, hdr);
997 
998  NS_TEST_ASSERT_MSG_EQ (queueDisc->QueueDisc::GetNPackets (), 11,
999  "unexpected number of packets in the queue disc");
1000  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 2,
1001  "unexpected number of packets in the first flow queue of set one");
1002  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetNPackets (), 2,
1003  "unexpected number of packets in the second flow queue of set one");
1004  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (2)->GetQueueDisc ()->GetNPackets (), 1,
1005  "unexpected number of packets in the third flow queue of set one");
1006  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (3)->GetQueueDisc ()->GetNPackets (), 1,
1007  "unexpected number of packets in the fourth flow queue of set one");
1008  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (4)->GetQueueDisc ()->GetNPackets (), 2,
1009  "unexpected number of packets in the fifth flow queue of set one");
1010  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (5)->GetQueueDisc ()->GetNPackets (), 1,
1011  "unexpected number of packets in the sixth flow queue of set one");
1012  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (6)->GetQueueDisc ()->GetNPackets (), 1,
1013  "unexpected number of packets in the seventh flow queue of set one");
1014  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (7)->GetQueueDisc ()->GetNPackets (), 1,
1015  "unexpected number of packets in the eighth flow queue of set one");
1016  g_hash = 1025;
1017  AddPacket (queueDisc, hdr);
1018  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetNPackets (), 3,
1019  "unexpected number of packets in the first flow of set one");
1020  g_hash = 10;
1021  AddPacket (queueDisc, hdr);
1022  NS_TEST_ASSERT_MSG_EQ (queueDisc->GetQueueDiscClass (8)->GetQueueDisc ()->GetNPackets (), 1,
1023  "unexpected number of packets in the first flow of set two");
1024  Simulator::Destroy ();
1025 }
1026 
1027 
1036 {
1037 public:
1039  virtual ~FqCoDelQueueDiscL4sMode ();
1040 
1041 private:
1042  virtual void DoRun (void);
1043 
1050  void AddPacket (Ptr<FqCoDelQueueDisc> queue, Ipv4Header hdr, uint32_t nPkt);
1051 
1059  void AddPacketWithDelay (Ptr<FqCoDelQueueDisc> queue,Ipv4Header hdr, double delay, uint32_t nPkt);
1060 
1066  void Dequeue (Ptr<FqCoDelQueueDisc> queue, uint32_t nPkt);
1073  void DequeueWithDelay (Ptr<FqCoDelQueueDisc> queue, double delay, uint32_t nPkt);
1074 };
1075 
1077  : TestCase ("Test L4S mode")
1078 {
1079 }
1080 
1082 {
1083 }
1084 
1085 void
1087 {
1088  Address dest;
1089  Ptr<Packet> p = Create<Packet> (100);
1090  for (uint32_t i = 0; i < nPkt; i++)
1091  {
1092  Ptr<Ipv4QueueDiscItem> item = Create<Ipv4QueueDiscItem> (p, dest, 0, hdr);
1093  queue->Enqueue (item);
1094  }
1095 }
1096 
1097 void
1099 {
1100  for (uint32_t i = 0; i < nPkt; i++)
1101  {
1102  Simulator::Schedule (Time (Seconds ((i + 1) * delay)), &FqCoDelQueueDiscL4sMode::AddPacket, this, queue, hdr, 1);
1103  }
1104 }
1105 
1106 void
1108 {
1109  for (uint32_t i = 0; i < nPkt; i++)
1110  {
1111  Ptr<QueueDiscItem> item = queue->Dequeue ();
1112  }
1113 }
1114 
1115 void
1117 {
1118  for (uint32_t i = 0; i < nPkt; i++)
1119  {
1120  Simulator::Schedule (Time (Seconds ((i + 1) * delay)), &FqCoDelQueueDiscL4sMode::Dequeue, this, queue, 1);
1121  }
1122 }
1123 
1124 void
1126 {
1127  // Test is divided into 2 sub test cases:
1128  // 1) Without hash collisions
1129  // 2) With hash collisions
1130 
1131  // Test case 1, Without hash collisions
1132  Ptr<FqCoDelQueueDisc> queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc> ("MaxSize", StringValue ("10240p"), "UseEcn", BooleanValue (true),
1133  "Perturbation", UintegerValue (0), "UseL4s", BooleanValue (true),
1134  "CeThreshold", TimeValue (MilliSeconds (2)));
1135 
1136  queueDisc->SetQuantum (1514);
1137  queueDisc->Initialize ();
1138  Ipv4Header hdr;
1139  hdr.SetPayloadSize (100);
1140  hdr.SetSource (Ipv4Address ("10.10.1.1"));
1141  hdr.SetDestination (Ipv4Address ("10.10.1.2"));
1142  hdr.SetProtocol (7);
1143  hdr.SetEcn (Ipv4Header::ECN_ECT1);
1144 
1145  // Add 70 ECT1 (ECN capable) packets from the first flow
1146  // Set delay = 0.5ms
1147  double delay = 0.0005;
1148  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscL4sMode::AddPacketWithDelay, this, queueDisc, hdr, delay, 70);
1149 
1150  // Add 70 ECT0 (ECN capable) packets from second flow
1151  hdr.SetEcn (Ipv4Header::ECN_ECT0);
1152  hdr.SetDestination (Ipv4Address ("10.10.1.10"));
1153  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscL4sMode::AddPacketWithDelay, this, queueDisc, hdr, delay, 70);
1154 
1155  //Dequeue 140 packets with delay 1ms
1156  delay = 0.001;
1157  DequeueWithDelay (queueDisc, delay, 140);
1158  Simulator::Run ();
1159  Simulator::Stop (Seconds (8.0));
1160  Ptr<CoDelQueueDisc> q0 = queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
1161  Ptr<CoDelQueueDisc> q1 = queueDisc->GetQueueDiscClass (1)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
1162 
1163  NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK), 66, "There should be 66 marked packets"
1164  "4th packet is enqueued at 2ms and dequeued at 4ms hence the delay of 2ms which not greater than CE threshold"
1165  "5th packet is enqueued at 2.5ms and dequeued at 5ms hence the delay of 2.5ms and subsequent packet also do have delay"
1166  "greater than CE threshold so all the packets after 4th packet are marked");
1167  NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
1168  NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK), 0, "There should not be any marked packets");
1169  NS_TEST_EXPECT_MSG_EQ (q1->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK), 1, "There should be 1 marked packets");
1170  NS_TEST_EXPECT_MSG_EQ (q1->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
1171 
1172  Simulator::Destroy ();
1173 
1174  // Test case 2, With hash collisions
1175  queueDisc = CreateObjectWithAttributes<FqCoDelQueueDisc> ("MaxSize", StringValue ("10240p"), "UseEcn", BooleanValue (true),
1176  "Perturbation", UintegerValue (0), "UseL4s", BooleanValue (true),
1177  "CeThreshold", TimeValue (MilliSeconds (2)));
1178 
1179  queueDisc->SetQuantum (1514);
1180  queueDisc->Initialize ();
1181  hdr.SetPayloadSize (100);
1182  hdr.SetSource (Ipv4Address ("10.10.1.1"));
1183  hdr.SetDestination (Ipv4Address ("10.10.1.2"));
1184  hdr.SetProtocol (7);
1185  hdr.SetEcn (Ipv4Header::ECN_ECT1);
1186 
1187  // Add 70 ECT1 (ECN capable) packets from the first flow
1188  // Set delay = 1ms
1189  delay = 0.001;
1190  Simulator::Schedule (Time (Seconds (0.0005)), &FqCoDelQueueDiscL4sMode::AddPacket, this, queueDisc, hdr, 1);
1191  Simulator::Schedule (Time (Seconds (0.0005)), &FqCoDelQueueDiscL4sMode::AddPacketWithDelay, this, queueDisc, hdr, delay, 69);
1192 
1193  // Add 70 ECT0 (ECN capable) packets from first flow
1194  hdr.SetEcn (Ipv4Header::ECN_ECT0);
1195  Simulator::Schedule (Time (Seconds (0)), &FqCoDelQueueDiscL4sMode::AddPacketWithDelay, this, queueDisc, hdr, delay, 70);
1196 
1197  //Dequeue 140 packets with delay 1ms
1198  DequeueWithDelay (queueDisc, delay, 140);
1199  Simulator::Run ();
1200  Simulator::Stop (Seconds (8.0));
1201  q0 = queueDisc->GetQueueDiscClass (0)->GetQueueDisc ()->GetObject <CoDelQueueDisc> ();
1202 
1203  NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNMarkedPackets (CoDelQueueDisc::CE_THRESHOLD_EXCEEDED_MARK), 68, "There should be 68 marked packets"
1204  "2nd ECT1 packet is enqueued at 1.5ms and dequeued at 3ms hence the delay of 1.5ms which not greater than CE threshold"
1205  "3rd packet is enqueued at 2.5ms and dequeued at 5ms hence the delay of 2.5ms and subsequent packet also do have delay"
1206  "greater than CE threshold so all the packets after 2nd packet are marked");
1207  NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNDroppedPackets (CoDelQueueDisc::TARGET_EXCEEDED_DROP), 0, "There should not be any dropped packets");
1208  NS_TEST_EXPECT_MSG_EQ (q0->GetStats ().GetNMarkedPackets (CoDelQueueDisc::TARGET_EXCEEDED_MARK), 1, "There should be 1 marked packets");
1209 
1210  Simulator::Destroy ();
1211 
1212 }
1213 
1214 
1221 {
1222 public:
1224 };
1225 
1227  : TestSuite ("fq-codel-queue-disc", UNIT)
1228 {
1229  AddTestCase (new FqCoDelQueueDiscNoSuitableFilter, TestCase::QUICK);
1231  AddTestCase (new FqCoDelQueueDiscDeficit, TestCase::QUICK);
1232  AddTestCase (new FqCoDelQueueDiscTCPFlowsSeparation, TestCase::QUICK);
1233  AddTestCase (new FqCoDelQueueDiscUDPFlowsSeparation, TestCase::QUICK);
1234  AddTestCase (new FqCoDelQueueDiscECNMarking, TestCase::QUICK);
1235  AddTestCase (new FqCoDelQueueDiscSetLinearProbing, TestCase::QUICK);
1236  AddTestCase (new FqCoDelQueueDiscL4sMode, TestCase::QUICK);
1237 }
1238 
This class tests the deficit per flow.
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header hdr)
Enqueue a packet.
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual void DoRun(void)
Implementation to actually run this TestCase.
void Dequeue(Ptr< FqCoDelQueueDisc > queue, uint32_t nPkt)
Dequeue some packets.
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 AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header hdr)
Enqueue a packet.
virtual void DoRun(void)
Implementation to actually run this TestCase.
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header hdr, uint32_t nPkt)
Enqueue some packets.
virtual void DoRun(void)
Implementation to actually run this TestCase.
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.
virtual void DoRun(void)
Implementation to actually run this TestCase.
This class tests linear probing, collision response, and set creation capability of set associative h...
virtual void DoRun(void)
Implementation to actually run this TestCase.
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header hdr)
Enqueue a packet.
This class tests the TCP flows separation.
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header ipHdr, TcpHeader tcpHdr)
Enqueue a packet.
virtual void DoRun(void)
Implementation to actually run this TestCase.
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.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Simple test packet filter able to classify IPv4 packets.
virtual int32_t DoClassify(Ptr< QueueDiscItem > item) const
Classify a QueueDiscItem.
virtual bool CheckProtocol(Ptr< QueueDiscItem > item) const
Check the protocol.
static TypeId GetTypeId(void)
Get the type ID.
a polymophic address class
Definition: address.h:91
AttributeValue implementation for Boolean.
Definition: boolean.h:37
A CoDel packet queue disc.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
Packet header for IPv4.
Definition: ipv4-header.h:34
void SetDestination(Ipv4Address destination)
Definition: ipv4-header.cc:298
void SetPayloadSize(uint16_t size)
Definition: ipv4-header.cc:56
void SetEcn(EcnType ecn)
Set ECN Field.
Definition: ipv4-header.cc:97
void SetProtocol(uint8_t num)
Definition: ipv4-header.cc:278
void SetSource(Ipv4Address source)
Definition: ipv4-header.cc:285
Ipv4PacketFilter is the abstract base class for filters defined for IPv4 packets.
Packet header for IPv6.
Definition: ipv6-header.h:36
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
Hold variables of type string.
Definition: string.h:41
Header for the Transmission Control Protocol.
Definition: tcp-header.h:45
void SetDestinationPort(uint16_t port)
Set the destination port.
Definition: tcp-header.cc:95
void SetSourcePort(uint16_t port)
Set the source port.
Definition: tcp-header.cc:89
encapsulates test code
Definition: test.h:994
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
A suite of tests to run.
Definition: test.h:1188
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:103
AttributeValue implementation for Time.
Definition: nstime.h:1308
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
Packet header for UDP packets.
Definition: udp-header.h:40
void SetSourcePort(uint16_t port)
Definition: udp-header.cc:60
void SetDestinationPort(uint16_t port)
Definition: udp-header.cc:55
Hold an unsigned integer type.
Definition: uinteger.h:44
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:93
#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:141
#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:636
#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:240
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1252
Every class exported by the ns3 library is enclosed in the ns3 namespace.