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