1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 2 /* 3 * Copyright (c) 2007, 2014 University of Washington 4 * 2015 Universita' degli Studi di Napoli Federico II 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation; 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 */ 19 20 #ifndef QUEUE_DISC_H 21 #define QUEUE_DISC_H 22 23 #include "ns3/object.h" 24 #include "ns3/traced-value.h" 25 #include "ns3/traced-callback.h" 26 #include "ns3/queue-item.h" 27 #include "ns3/queue-size.h" 28 #include <vector> 29 #include <map> 30 #include <functional> 31 #include <string> 32 #include "packet-filter.h" 33 34 namespace ns3 { 35 36 class QueueDisc; 37 template <typename Item> class Queue; 38 class NetDeviceQueueInterface; 39 40 /** 41 * \ingroup traffic-control 42 * 43 * QueueDiscClass is the base class for classes that are included in a queue 44 * disc. It has a single attribute, QueueDisc, used to set the child queue disc 45 * attached to the class. Classful queue discs needing to set parameters for 46 * their classes can subclass QueueDiscClass and add the required parameters 47 * as attributes. 48 */ 49 class QueueDiscClass : public Object { 50 public: 51 /** 52 * \brief Get the type ID. 53 * \return the object TypeId 54 */ 55 static TypeId GetTypeId (void); 56 57 QueueDiscClass (); 58 virtual ~QueueDiscClass (); 59 60 /** 61 * \brief Get the queue disc attached to this class 62 * \return the queue disc attached to this class. 63 */ 64 Ptr<QueueDisc> GetQueueDisc (void) const; 65 66 /** 67 * \brief Set the queue disc attached to this class 68 * \param qd The queue disc to attach to this class 69 */ 70 void SetQueueDisc (Ptr<QueueDisc> qd); 71 72 protected: 73 /** 74 * \brief Dispose of the object 75 */ 76 virtual void DoDispose (void); 77 78 private: 79 Ptr<QueueDisc> m_queueDisc; //!< Queue disc attached to this class 80 }; 81 82 /** 83 * \ingroup traffic-control 84 * \brief Enumeration of the available policies to handle the queue disc size. 85 * 86 * - SINGLE_INTERNAL_QUEUE is intended to handle the maxSize attribute 87 * of queue discs having a single internal queue. If no internal queue is 88 * yet attached to the queue disc, setting/getting this attribute involves 89 * setting/getting the member variable of the queue disc; otherwise, the 90 * corresponding attribute of the internal queue is set/get. 91 * - SINGLE_CHILD_QUEUE_DISC is intended to handle the maxSize attribute 92 * of queue discs having a single child queue disc. If no child queue disc is 93 * yet attached to the queue disc, setting/getting this attribute involves 94 * setting/getting the member variable of the queue disc; otherwise, the 95 * corresponding attribute of the child queue disc is set/get. 96 * - MULTIPLE_QUEUES is intended to handle the maxSize attribute of queue 97 * discs having multiple internal queues or child queue discs. Setting/getting 98 * this attribute always involves setting/getting the member variable of the 99 * queue disc. Queue discs should warn the user if a packet is dropped by an 100 * internal queue/child queue disc because of lack of space, while the queue 101 * disc limit is not exceeded. 102 */ 103 enum QueueDiscSizePolicy 104 { 105 SINGLE_INTERNAL_QUEUE, /**< Used by queue discs with single internal queue */ 106 SINGLE_CHILD_QUEUE_DISC, /**< Used by queue discs with single child queue disc */ 107 MULTIPLE_QUEUES, /**< Used by queue discs with multiple internal queues/child queue discs */ 108 NO_LIMITS /**< Used by queue discs with unlimited size */ 109 }; 110 111 112 /** 113 * \ingroup traffic-control 114 * 115 * QueueDisc is an abstract base class providing the interface and implementing 116 * the operations common to all the queueing disciplines. Child classes 117 * need to implement the methods used to enqueue a packet (DoEnqueue), 118 * dequeue a single packet (DoDequeue), get a copy of the next packet 119 * to extract (DoPeek), check whether the current configuration is correct 120 * (CheckConfig). 121 * 122 * As in Linux, a queue disc may contain distinct elements: 123 * - queues, which actually store the packets waiting for transmission 124 * - classes, which allow to reserve a different treatment to different packets 125 * - filters, which determine the queue or class which a packet is destined to 126 * 127 * Notice that a child queue disc must be attached to every class and a packet 128 * filter is only able to classify packets of a single protocol. Also, while in Linux 129 * some queue discs (e.g., fq-codel) use an internal classifier and do not make use of 130 * packet filters, in ns-3 every queue disc including multiple queues or multiple classes 131 * needs an external filter to classify packets (this is to avoid having the traffic-control 132 * module depend on other modules such as internet). 133 * 134 * Queue disc configuration vary from queue disc to queue disc. A typical taxonomy divides 135 * queue discs in classful (i.e., support classes) and classless (i.e., do not support 136 * classes). More recently, after the appearance of multi-queue devices (such as Wifi), 137 * some multi-queue aware queue discs have been introduced. Multi-queue aware queue discs 138 * handle as many queues (or queue discs -- without using classes) as the number of 139 * transmission queues used by the device on which the queue disc is installed. 140 * An attempt is made, also, to enqueue each packet in the "same" queue both within the 141 * queue disc and within the device. 142 * 143 * The traffic control layer interacts with a queue disc in a simple manner: after 144 * requesting to enqueue a packet, the traffic control layer requests the qdisc to 145 * "run", i.e., to dequeue a set of packets, until a predefined number ("quota") 146 * of packets is dequeued or the netdevice stops the queue disc. A netdevice shall 147 * stop the queue disc when its transmission queue does not have room for another 148 * packet. Also, a netdevice shall wake the queue disc when it detects that there 149 * is room for another packet in its transmission queue, but the transmission queue 150 * is stopped. Waking a queue disc is equivalent to make it run. 151 * 152 * Every queue disc collects statistics about the total number of packets/bytes 153 * received from the upper layers (in case of root queue disc) or from the parent 154 * queue disc (in case of child queue disc), enqueued, dequeued, requeued, dropped, 155 * dropped before enqueue, dropped after dequeue, queued in the queue disc and 156 * sent to the netdevice or to the parent queue disc. Note that packets that are 157 * dequeued may be requeued, i.e., retained by the traffic control infrastructure, 158 * if the netdevice is not ready to receive them. Requeued packets are not part 159 * of the queue disc. The following identities hold: 160 * - dropped = dropped before enqueue + dropped after dequeue 161 * - received = dropped before enqueue + enqueued 162 * - queued = enqueued - dequeued 163 * - sent = dequeued - dropped after dequeue (- 1 if there is a requeued packet) 164 * 165 * Separate counters are also kept for each possible reason to drop a packet. 166 * When a packet is dropped by an internal queue, e.g., because the queue is full, 167 * the reason is "Dropped by internal queue". When a packet is dropped by a child 168 * queue disc, the reason is "(Dropped by child queue disc) " followed by the 169 * reason why the child queue disc dropped the packet. 170 * 171 * The QueueDisc base class provides the SojournTime trace source, which provides 172 * the sojourn time of every packet dequeued from a queue disc, including packets 173 * that are dropped or requeued after being dequeued. The sojourn time is taken 174 * when the packet is dequeued from the queue disc, hence it does not account for 175 * the additional time the packet is retained within the traffic control 176 * infrastructure in case it is requeued. 177 * 178 * The design and implementation of this class is heavily inspired by Linux. 179 * For more details, see the traffic-control model page. 180 */ 181 class QueueDisc : public Object { 182 public: 183 184 /// \brief Structure that keeps the queue disc statistics 185 struct Stats 186 { 187 /// Total received packets 188 uint32_t nTotalReceivedPackets; 189 /// Total received bytes 190 uint64_t nTotalReceivedBytes; 191 /// Total sent packets -- this value is not kept up to date, call GetStats first 192 uint32_t nTotalSentPackets; 193 /// Total sent bytes -- this value is not kept up to date, call GetStats first 194 uint64_t nTotalSentBytes; 195 /// Total enqueued packets 196 uint32_t nTotalEnqueuedPackets; 197 /// Total enqueued bytes 198 uint64_t nTotalEnqueuedBytes; 199 /// Total dequeued packets 200 uint32_t nTotalDequeuedPackets; 201 /// Total dequeued bytes 202 uint64_t nTotalDequeuedBytes; 203 /// Total dropped packets 204 uint32_t nTotalDroppedPackets; 205 /// Total packets dropped before enqueue 206 uint32_t nTotalDroppedPacketsBeforeEnqueue; 207 /// Packets dropped before enqueue, for each reason 208 std::map<std::string, uint32_t> nDroppedPacketsBeforeEnqueue; 209 /// Total packets dropped after dequeue 210 uint32_t nTotalDroppedPacketsAfterDequeue; 211 /// Packets dropped after dequeue, for each reason 212 std::map<std::string, uint32_t> nDroppedPacketsAfterDequeue; 213 /// Total dropped bytes 214 uint64_t nTotalDroppedBytes; 215 /// Total bytes dropped before enqueue 216 uint64_t nTotalDroppedBytesBeforeEnqueue; 217 /// Bytes dropped before enqueue, for each reason 218 std::map<std::string, uint64_t> nDroppedBytesBeforeEnqueue; 219 /// Total bytes dropped after dequeue 220 uint64_t nTotalDroppedBytesAfterDequeue; 221 /// Bytes dropped after dequeue, for each reason 222 std::map<std::string, uint64_t> nDroppedBytesAfterDequeue; 223 /// Total requeued packets 224 uint32_t nTotalRequeuedPackets; 225 /// Total requeued bytes 226 uint64_t nTotalRequeuedBytes; 227 /// Total marked packets 228 uint32_t nTotalMarkedPackets; 229 /// Marked packets, for each reason 230 std::map<std::string, uint32_t> nMarkedPackets; 231 /// Total marked bytes 232 uint32_t nTotalMarkedBytes; 233 /// Marked bytes, for each reason 234 std::map<std::string, uint64_t> nMarkedBytes; 235 236 /// constructor 237 Stats (); 238 239 /** 240 * \brief Get the number of packets dropped for the given reason 241 * \param reason the reason why packets were dropped 242 * \return the number of packets dropped for the given reason 243 */ 244 uint32_t GetNDroppedPackets (std::string reason) const; 245 /** 246 * \brief Get the amount of bytes dropped for the given reason 247 * \param reason the reason why packets were dropped 248 * \return the amount of bytes dropped for the given reason 249 */ 250 uint64_t GetNDroppedBytes (std::string reason) const; 251 /** 252 * \brief Get the number of packets marked for the given reason 253 * \param reason the reason why packets were marked 254 * \return the number of packets marked for the given reason 255 */ 256 uint32_t GetNMarkedPackets (std::string reason) const; 257 /** 258 * \brief Get the amount of bytes marked for the given reason 259 * \param reason the reason why packets were marked 260 * \return the amount of bytes marked for the given reason 261 */ 262 uint64_t GetNMarkedBytes (std::string reason) const; 263 /** 264 * \brief Print the statistics. 265 * \param os output stream in which the data should be printed. 266 */ 267 void Print (std::ostream &os) const; 268 }; 269 270 /** 271 * \brief Get the type ID. 272 * \return the object TypeId 273 */ 274 static TypeId GetTypeId (void); 275 276 /** 277 * \brief Constructor 278 * \param policy the policy to handle the queue disc size 279 */ 280 QueueDisc (QueueDiscSizePolicy policy = QueueDiscSizePolicy::SINGLE_INTERNAL_QUEUE); 281 282 /** 283 * \brief Constructor 284 * \param policy the policy to handle the queue disc size 285 * \param unit The fixed operating mode of this queue disc 286 */ 287 QueueDisc (QueueDiscSizePolicy policy, QueueSizeUnit unit); 288 289 virtual ~QueueDisc (); 290 291 /** 292 * \brief Get the number of packets stored by the queue disc 293 * \return the number of packets stored by the queue disc. 294 * 295 * The requeued packet, if any, is counted. 296 */ 297 uint32_t GetNPackets (void) const; 298 299 /** 300 * \brief Get the amount of bytes stored by the queue disc 301 * \return the amount of bytes stored by the queue disc. 302 * 303 * The requeued packet, if any, is counted. 304 */ 305 uint32_t GetNBytes (void) const; 306 307 /** 308 * \brief Get the maximum size of the queue disc. 309 * 310 * \returns the maximum size of the queue disc. 311 */ 312 QueueSize GetMaxSize (void) const; 313 314 /** 315 * \brief Set the maximum size of the queue disc. 316 * 317 * Trying to set a null size has no effect. 318 * 319 * \param size the maximum size. 320 * \returns true if setting the size succeeded, false otherwise. 321 */ 322 bool SetMaxSize (QueueSize size); 323 324 /** 325 * \brief Get the current size of the queue disc in bytes, if 326 * operating in bytes mode, or packets, otherwise. 327 * 328 * Do not call this method if the queue disc size is not limited. 329 * 330 * \returns The queue disc size in bytes or packets. 331 */ 332 QueueSize GetCurrentSize (void); 333 334 /** 335 * \brief Retrieve all the collected statistics. 336 * \return the collected statistics. 337 */ 338 const Stats& GetStats (void); 339 340 /** 341 * \param ndqi the NetDeviceQueueInterface aggregated to the receiving object. 342 * 343 * Set the pointer to the NetDeviceQueueInterface object aggregated to the 344 * object receiving the packets dequeued from this queue disc. 345 */ 346 void SetNetDeviceQueueInterface (Ptr<NetDeviceQueueInterface> ndqi); 347 348 /** 349 * \return the NetDeviceQueueInterface aggregated to the receiving object. 350 * 351 * Get the pointer to the NetDeviceQueueInterface object aggregated to the 352 * object receiving the packets dequeued from this queue disc. 353 */ 354 Ptr<NetDeviceQueueInterface> GetNetDeviceQueueInterface (void) const; 355 356 /// Callback invoked to send a packet to the receiving object when Run is called 357 typedef std::function<void (Ptr<QueueDiscItem>)> SendCallback; 358 359 /** 360 * \param func the callback to send a packet to the receiving object. 361 * 362 * Set the callback used by the Transmit method (called eventually by the Run 363 * method) to send a packet to the receiving object. 364 */ 365 void SetSendCallback (SendCallback func); 366 367 /** 368 * \return the callback to send a packet to the receiving object. 369 * 370 * Get the callback used by the Transmit method (called eventually by the Run 371 * method) to send a packet to the receiving object. 372 */ 373 SendCallback GetSendCallback (void) const; 374 375 /** 376 * \brief Set the maximum number of dequeue operations following a packet enqueue 377 * \param quota the maximum number of dequeue operations following a packet enqueue. 378 */ 379 virtual void SetQuota (const uint32_t quota); 380 381 /** 382 * \brief Get the maximum number of dequeue operations following a packet enqueue 383 * \return the maximum number of dequeue operations following a packet enqueue. 384 */ 385 virtual uint32_t GetQuota (void) const; 386 387 /** 388 * Pass a packet to store to the queue discipline. This function only updates 389 * the statistics and calls the (private) DoEnqueue function, which must be 390 * implemented by derived classes. 391 * \param item item to enqueue 392 * \return True if the operation was successful; false otherwise 393 */ 394 bool Enqueue (Ptr<QueueDiscItem> item); 395 396 /** 397 * Extract from the queue disc the packet that has been dequeued by calling 398 * Peek, if any, or call the private DoDequeue method (which must be 399 * implemented by derived classes) to dequeue a packet, otherwise. 400 * 401 * \return 0 if the operation was not successful; the item otherwise. 402 */ 403 Ptr<QueueDiscItem> Dequeue (void); 404 405 /** 406 * Get a copy of the next packet the queue discipline will extract. This 407 * function only calls the (private) DoPeek function. This base class provides 408 * a default implementation of DoPeek, which dequeues the next packet but 409 * retains it into the queue disc. 410 * \return 0 if the operation was not successful; the item otherwise. 411 */ 412 Ptr<const QueueDiscItem> Peek (void); 413 414 /** 415 * Modelled after the Linux function __qdisc_run (net/sched/sch_generic.c) 416 * Dequeues multiple packets, until a quota is exceeded or sending a packet 417 * to the device failed. 418 */ 419 void Run (void); 420 421 /// Internal queues store QueueDiscItem objects 422 typedef Queue<QueueDiscItem> InternalQueue; 423 424 /** 425 * \brief Add an internal queue to the tail of the list of queues. 426 * \param queue the queue to be added 427 */ 428 void AddInternalQueue (Ptr<InternalQueue> queue); 429 430 /** 431 * \brief Get the i-th internal queue 432 * \param i the index of the queue 433 * \return the i-th internal queue. 434 */ 435 Ptr<InternalQueue> GetInternalQueue (std::size_t i) const; 436 437 /** 438 * \brief Get the number of internal queues 439 * \return the number of internal queues. 440 */ 441 std::size_t GetNInternalQueues (void) const; 442 443 /** 444 * \brief Add a packet filter to the tail of the list of filters used to classify packets. 445 * \param filter the packet filter to be added 446 */ 447 void AddPacketFilter (Ptr<PacketFilter> filter); 448 449 /** 450 * \brief Get the i-th packet filter 451 * \param i the index of the packet filter 452 * \return the i-th packet filter. 453 */ 454 Ptr<PacketFilter> GetPacketFilter (std::size_t i) const; 455 456 /** 457 * \brief Get the number of packet filters 458 * \return the number of packet filters. 459 */ 460 std::size_t GetNPacketFilters (void) const; 461 462 /** 463 * \brief Add a queue disc class to the tail of the list of classes. 464 * \param qdClass the queue disc class to be added 465 */ 466 void AddQueueDiscClass (Ptr<QueueDiscClass> qdClass); 467 468 /** 469 * \brief Get the i-th queue disc class 470 * \param i the index of the queue disc class 471 * \return the i-th queue disc class. 472 */ 473 Ptr<QueueDiscClass> GetQueueDiscClass (std::size_t i) const; 474 475 /** 476 * \brief Get the number of queue disc classes 477 * \return the number of queue disc classes. 478 */ 479 std::size_t GetNQueueDiscClasses (void) const; 480 481 /** 482 * Classify a packet by calling the packet filters, one at a time, until either 483 * a filter able to classify the packet is found or all the filters have been 484 * processed. 485 * \param item item to classify 486 * \return -1 if no filter able to classify the packet has been found, the value 487 * returned by first filter found to be able to classify the packet otherwise. 488 */ 489 int32_t Classify (Ptr<QueueDiscItem> item); 490 491 /** 492 * \enum WakeMode 493 * \brief Used to determine whether the queue disc itself or its children must 494 * be activated when a netdevice wakes a transmission queue 495 */ 496 enum WakeMode 497 { 498 WAKE_ROOT = 0x00, 499 WAKE_CHILD = 0x01 500 }; 501 502 /** 503 * When setting up the wake callbacks on the netdevice queues, it is necessary to 504 * determine which queue disc (the root queue disc or one of its children) should 505 * be activated when the netdevice wakes one of its transmission queues. The 506 * implementation of this method for the base class returns WAKE_ROOT, i.e., the 507 * root queue disc is activated. Subclasses implementing queue discs adopting 508 * a different strategy (e.g., multi-queue aware queue discs such as mq) have 509 * to redefine this method. 510 * 511 * \return the wake mode adopted by this queue disc. 512 */ 513 virtual WakeMode GetWakeMode (void) const; 514 515 // Reasons for dropping packets 516 static constexpr const char* INTERNAL_QUEUE_DROP = "Dropped by internal queue"; //!< Packet dropped by an internal queue 517 static constexpr const char* CHILD_QUEUE_DISC_DROP = "(Dropped by child queue disc) "; //!< Packet dropped by a child queue disc 518 static constexpr const char* CHILD_QUEUE_DISC_MARK = "(Marked by child queue disc) "; //!< Packet marked by a child queue disc 519 520 protected: 521 /** 522 * \brief Dispose of the object 523 */ 524 virtual void DoDispose (void); 525 526 /** 527 * \brief Check whether the configuration is correct and initialize parameters 528 * 529 * This method is not virtual to prevent subclasses from redefining it. 530 * Subclasses must instead provide the implementation of the CheckConfig 531 * and InitializeParams methods (which are called by this method). 532 * \sa QueueDisc::InitializeParams 533 * \sa QueueDisc::CheckConfig 534 */ 535 void DoInitialize (void); 536 537 /** 538 * \brief Perform the actions required when the queue disc is notified of 539 * a packet dropped before enqueue 540 * \param item item that was dropped 541 * \param reason the reason why the item was dropped 542 * This method must be called by subclasses to record that a packet was 543 * dropped before enqueue for the specified reason 544 */ 545 void DropBeforeEnqueue (Ptr<const QueueDiscItem> item, const char* reason); 546 547 /** 548 * \brief Perform the actions required when the queue disc is notified of 549 * a packet dropped after dequeue 550 * \param item item that was dropped 551 * \param reason the reason why the item was dropped 552 * This method must be called by subclasses to record that a packet was 553 * dropped after dequeue for the specified reason 554 */ 555 void DropAfterDequeue (Ptr<const QueueDiscItem> item, const char* reason); 556 557 /** 558 * \brief Marks the given packet and, if successful, updates the counters 559 * associated with the given reason 560 * \param item item that has to be marked 561 * \param reason the reason why the item has to be marked 562 * \return true if the item was successfully marked, false otherwise 563 */ 564 bool Mark (Ptr<QueueDiscItem> item, const char* reason); 565 566 private: 567 /** 568 * \brief Copy constructor 569 * \param o object to copy 570 * 571 * Defined and unimplemented to avoid misuse 572 */ 573 QueueDisc (const QueueDisc &o); 574 575 /** 576 * \brief Assignment operator 577 * \param o object to copy 578 * \returns the copied object 579 * 580 * Defined and unimplemented to avoid misuse 581 */ 582 QueueDisc &operator = (const QueueDisc &o); 583 584 /** 585 * This function actually enqueues a packet into the queue disc. 586 * \param item item to enqueue 587 * \return True if the operation was successful; false otherwise 588 */ 589 virtual bool DoEnqueue (Ptr<QueueDiscItem> item) = 0; 590 591 /** 592 * This function actually extracts a packet from the queue disc. 593 * \return 0 if the operation was not successful; the item otherwise. 594 */ 595 virtual Ptr<QueueDiscItem> DoDequeue (void) = 0; 596 597 /** 598 * \brief Return a copy of the next packet the queue disc will extract. 599 * 600 * The implementation of this method is based on the qdisc_peek_dequeued 601 * function of the Linux kernel, which dequeues a packet and retains it in the 602 * queue disc as a requeued packet. The packet is not traced as requeued, nor 603 * is the total count of requeued packets increased. The packet is still 604 * considered to be part of the queue disc and the dequeue trace is fired 605 * when Dequeue is called and the packet is actually extracted from the 606 * queue disc. 607 * 608 * This approach is especially recommended for queue discs for which it is not 609 * obvious what is the next packet that will be dequeued (e.g., queue discs 610 * having multiple internal queues or child queue discs or queue discs that 611 * drop packets after dequeue). Subclasses can however provide their own 612 * implementation of this method that overrides the default one. 613 * 614 * \return 0 if the operation was not successful; the packet otherwise. 615 */ 616 virtual Ptr<const QueueDiscItem> DoPeek (void); 617 618 /** 619 * Check whether the current configuration is correct. Default objects (such 620 * as internal queues) might be created by this method to ensure the 621 * configuration is correct. This method is automatically called at 622 * simulation initialization time, and it is called before 623 * the InitializeParams () method. It is appropriate to promote parameter 624 * initialization to this method if it aids in checking for correct 625 * configuration. 626 * \sa QueueDisc::InitializeParams 627 * \return true if the configuration is correct, false otherwise 628 */ 629 virtual bool CheckConfig (void) = 0; 630 631 /** 632 * Initialize parameters (if any) before the first packet is enqueued. 633 * This method is automatically called at simulation initialization time, 634 * after the CheckConfig() method has been called. 635 * \sa QueueDisc::CheckConfig 636 */ 637 virtual void InitializeParams (void) = 0; 638 639 /** 640 * Modelled after the Linux function qdisc_run_begin (include/net/sch_generic.h). 641 * \return false if the qdisc is already running; otherwise, set the qdisc as running and return true. 642 */ 643 bool RunBegin (void); 644 645 /** 646 * Modelled after the Linux function qdisc_run_end (include/net/sch_generic.h). 647 * Set the qdisc as not running. 648 */ 649 void RunEnd (void); 650 651 /** 652 * Modelled after the Linux function qdisc_restart (net/sched/sch_generic.c) 653 * Dequeue a packet (by calling DequeuePacket) and send it to the device (by calling Transmit). 654 * \return true if a packet is successfully sent to the device. 655 */ 656 bool Restart (void); 657 658 /** 659 * Modelled after the Linux function dequeue_skb (net/sched/sch_generic.c) 660 * \return the requeued packet, if any, or the packet dequeued by the queue disc, otherwise. 661 */ 662 Ptr<QueueDiscItem> DequeuePacket (void); 663 664 /** 665 * Modelled after the Linux function dev_requeue_skb (net/sched/sch_generic.c) 666 * Requeues a packet whose transmission failed. 667 * \param item the packet to requeue 668 */ 669 void Requeue (Ptr<QueueDiscItem> item); 670 671 /** 672 * Modelled after the Linux function sch_direct_xmit (net/sched/sch_generic.c) 673 * Sends a packet to the device if the device queue is not stopped, and requeues 674 * it otherwise. 675 * \param item the packet to transmit 676 * \return true if the device queue is not stopped and the queue disc is not empty 677 */ 678 bool Transmit (Ptr<QueueDiscItem> item); 679 680 /** 681 * \brief Perform the actions required when the queue disc is notified of 682 * a packet enqueue 683 * \param item item that was enqueued 684 */ 685 void PacketEnqueued (Ptr<const QueueDiscItem> item); 686 687 /** 688 * \brief Perform the actions required when the queue disc is notified of 689 * a packet dequeue 690 * \param item item that was dequeued 691 */ 692 void PacketDequeued (Ptr<const QueueDiscItem> item); 693 694 static const uint32_t DEFAULT_QUOTA = 64; //!< Default quota (as in /proc/sys/net/core/dev_weight) 695 696 std::vector<Ptr<InternalQueue> > m_queues; //!< Internal queues 697 std::vector<Ptr<PacketFilter> > m_filters; //!< Packet filters 698 std::vector<Ptr<QueueDiscClass> > m_classes; //!< Classes 699 700 TracedValue<uint32_t> m_nPackets; //!< Number of packets in the queue 701 TracedValue<uint32_t> m_nBytes; //!< Number of bytes in the queue 702 TracedCallback<Time> m_sojourn; //!< Sojourn time of the latest dequeued packet 703 QueueSize m_maxSize; //!< max queue size 704 705 Stats m_stats; //!< The collected statistics 706 uint32_t m_quota; //!< Maximum number of packets dequeued in a qdisc run 707 Ptr<NetDeviceQueueInterface> m_devQueueIface; //!< NetDevice queue interface 708 SendCallback m_send; //!< Callback used to send a packet to the receiving object 709 bool m_running; //!< The queue disc is performing multiple dequeue operations 710 Ptr<QueueDiscItem> m_requeued; //!< The last packet that failed to be transmitted 711 bool m_peeked; //!< A packet was dequeued because Peek was called 712 std::string m_childQueueDiscDropMsg; //!< Reason why a packet was dropped by a child queue disc 713 std::string m_childQueueDiscMarkMsg; //!< Reason why a packet was marked by a child queue disc 714 QueueDiscSizePolicy m_sizePolicy; //!< The queue disc size policy 715 bool m_prohibitChangeMode; //!< True if changing mode is prohibited 716 717 /// Traced callback: fired when a packet is enqueued 718 TracedCallback<Ptr<const QueueDiscItem> > m_traceEnqueue; 719 /// Traced callback: fired when a packet is dequeued 720 TracedCallback<Ptr<const QueueDiscItem> > m_traceDequeue; 721 /// Traced callback: fired when a packet is requeued 722 TracedCallback<Ptr<const QueueDiscItem> > m_traceRequeue; 723 /// Traced callback: fired when a packet is dropped 724 TracedCallback<Ptr<const QueueDiscItem> > m_traceDrop; 725 /// Traced callback: fired when a packet is dropped before enqueue 726 TracedCallback<Ptr<const QueueDiscItem>, const char* > m_traceDropBeforeEnqueue; 727 /// Traced callback: fired when a packet is dropped after dequeue 728 TracedCallback<Ptr<const QueueDiscItem>, const char* > m_traceDropAfterDequeue; 729 /// Traced callback: fired when a packet is marked 730 TracedCallback<Ptr<const QueueDiscItem>, const char* > m_traceMark; 731 732 /// Type for the function objects notifying that a packet has been dropped by an internal queue 733 typedef std::function<void (Ptr<const QueueDiscItem>)> InternalQueueDropFunctor; 734 /// Type for the function objects notifying that a packet has been dropped by a child queue disc 735 typedef std::function<void (Ptr<const QueueDiscItem>, const char*)> ChildQueueDiscDropFunctor; 736 /// Type for the function objects notifying that a packet has been marked by a child queue disc 737 typedef std::function<void (Ptr<const QueueDiscItem>, const char*)> ChildQueueDiscMarkFunctor; 738 739 /// Function object called when an internal queue dropped a packet before enqueue 740 InternalQueueDropFunctor m_internalQueueDbeFunctor; 741 /// Function object called when an internal queue dropped a packet after dequeue 742 InternalQueueDropFunctor m_internalQueueDadFunctor; 743 /// Function object called when a child queue disc dropped a packet before enqueue 744 ChildQueueDiscDropFunctor m_childQueueDiscDbeFunctor; 745 /// Function object called when a child queue disc dropped a packet after dequeue 746 ChildQueueDiscDropFunctor m_childQueueDiscDadFunctor; 747 /// Function object called when a child queue disc marked a packet 748 ChildQueueDiscMarkFunctor m_childQueueDiscMarkFunctor; 749 }; 750 751 /** 752 * \brief Stream insertion operator. 753 * 754 * \param os the stream 755 * \param stats the queue disc statistics 756 * \returns a reference to the stream 757 */ 758 std::ostream& operator<< (std::ostream& os, const QueueDisc::Stats &stats); 759 760 } // namespace ns3 761 762 #endif /* QueueDisc */ 763