OLD | NEW |
(Empty) | |
| 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/queue.h> |
| 26 #include "ns3/net-device.h" |
| 27 #include <vector> |
| 28 #include "packet-filter.h" |
| 29 |
| 30 namespace ns3 { |
| 31 |
| 32 class Packet; |
| 33 class QueueDisc; |
| 34 |
| 35 /** |
| 36 * \ingroup traffic-control |
| 37 * |
| 38 * QueueDiscItem is the abstract base class for items that are stored in a queue |
| 39 * disc. It is derived from QueueItem (which only consists of a Ptr<Packet>) |
| 40 * to additionally store the destination MAC address, the |
| 41 * L3 protocol number and the transmission queue index, |
| 42 */ |
| 43 class QueueDiscItem : public QueueItem { |
| 44 public: |
| 45 /** |
| 46 * \brief Create a queue disc item. |
| 47 * \param p the packet included in the created item. |
| 48 * \param addr the destination MAC address |
| 49 * \param protocol the L3 protocol number |
| 50 */ |
| 51 QueueDiscItem (Ptr<Packet> p, const Address & addr, uint16_t protocol); |
| 52 |
| 53 virtual ~QueueDiscItem (); |
| 54 |
| 55 /** |
| 56 * \brief Get the MAC address included in this item |
| 57 * \return the MAC address included in this item. |
| 58 */ |
| 59 Address GetAddress (void) const; |
| 60 |
| 61 /** |
| 62 * \brief Get the L3 protocol included in this item |
| 63 * \return the L3 protocol included in this item. |
| 64 */ |
| 65 uint16_t GetProtocol (void) const; |
| 66 |
| 67 /** |
| 68 * \brief Get the transmission queue index included in this item |
| 69 * \return the transmission queue index included in this item. |
| 70 */ |
| 71 uint8_t GetTxQueueIndex (void) const; |
| 72 |
| 73 /** |
| 74 * \brief Set the transmission queue index to store in this item |
| 75 * \param txq the transmission queue index to store in this item. |
| 76 */ |
| 77 void SetTxQueueIndex (uint8_t txq); |
| 78 |
| 79 /** |
| 80 * \brief Add the header to the packet |
| 81 * |
| 82 * Subclasses may keep header and payload separate to allow manipulating the h
eader, |
| 83 * so this method allows to add the header to the packet before sending the pa
cket |
| 84 * to the device. |
| 85 */ |
| 86 virtual void AddHeader (void) = 0; |
| 87 |
| 88 /** |
| 89 * \brief Print the item contents. |
| 90 * \param os output stream in which the data should be printed. |
| 91 */ |
| 92 virtual void Print (std::ostream &os) const; |
| 93 |
| 94 private: |
| 95 /** |
| 96 * \brief Default constructor |
| 97 * |
| 98 * Defined and unimplemented to avoid misuse |
| 99 */ |
| 100 QueueDiscItem (); |
| 101 /** |
| 102 * \brief Copy constructor |
| 103 * |
| 104 * Defined and unimplemented to avoid misuse |
| 105 */ |
| 106 QueueDiscItem (const QueueDiscItem &); |
| 107 /** |
| 108 * \brief Assignment operator |
| 109 * |
| 110 * Defined and unimplemented to avoid misuse |
| 111 * \returns |
| 112 */ |
| 113 QueueDiscItem &operator = (const QueueDiscItem &); |
| 114 |
| 115 Address m_address; //!< MAC destination address |
| 116 uint16_t m_protocol; //!< L3 Protocol number |
| 117 uint8_t m_txq; //!< Transmission queue index |
| 118 }; |
| 119 |
| 120 |
| 121 /** |
| 122 * \ingroup traffic-control |
| 123 * |
| 124 * QueueDiscClass is the base class for classes that are included in a queue |
| 125 * disc. It has a single attribute, QueueDisc, used to set the child queue disc |
| 126 * attached to the class. Classful queue discs needing to set parameters for |
| 127 * their classes can subclass QueueDiscClass and add the required parameters |
| 128 * as attributes. |
| 129 */ |
| 130 class QueueDiscClass : public Object { |
| 131 public: |
| 132 /** |
| 133 * \brief Get the type ID. |
| 134 * \return the object TypeId |
| 135 */ |
| 136 static TypeId GetTypeId (void); |
| 137 |
| 138 QueueDiscClass (); |
| 139 virtual ~QueueDiscClass () {} |
| 140 |
| 141 /** |
| 142 * \brief Get the queue disc attached to this class |
| 143 * \return the queue disc attached to this class. |
| 144 */ |
| 145 Ptr<QueueDisc> GetQueueDisc (void) const; |
| 146 |
| 147 /** |
| 148 * \brief Set the queue disc attached to this class |
| 149 */ |
| 150 void SetQueueDisc (Ptr<QueueDisc> qd); |
| 151 |
| 152 protected: |
| 153 /** |
| 154 * \brief Dispose of the object |
| 155 */ |
| 156 virtual void DoDispose (void); |
| 157 |
| 158 private: |
| 159 Ptr<QueueDisc> m_queueDisc; //!< Queue disc attached to this class |
| 160 }; |
| 161 |
| 162 |
| 163 /** |
| 164 * \ingroup traffic-control |
| 165 * |
| 166 * QueueDisc is an abstract base class providing the interface and implementing |
| 167 * the operations common to all the queueing disciplines. Child classes |
| 168 * need to implement the methods used to enqueue a packet (DoEnqueue), |
| 169 * dequeue a single packet (DoDequeue), get a copy of the next packet |
| 170 * to extract (DoPeek), check whether the current configuration is correct |
| 171 * (CheckConfig). |
| 172 * |
| 173 * As in Linux, a queue disc may contain distinct elements: |
| 174 * - queues, which actually store the packets waiting for transmission |
| 175 * - classes, which allow to reserve a different treatment to different packets |
| 176 * - filters, which determine the queue or class which a packet is destined to |
| 177 * |
| 178 * Notice that a child queue disc must be attached to every class and a packet |
| 179 * filter is only able to classify packets of a single protocol. Also, while in
Linux |
| 180 * some queue discs (e.g., fq-codel) use an internal classifier and do not make
use of |
| 181 * packet filters, in ns-3 every queue disc including multiple queues or multipl
e classes |
| 182 * needs an external filter to classify packets (this is to avoid having the tra
ffic-control |
| 183 * module depend on other modules such as internet). |
| 184 * |
| 185 * Queue disc configuration vary from queue disc to queue disc. A typical taxono
my divides |
| 186 * queue discs in classful (i.e., support classes) and classless (i.e., do not s
upport |
| 187 * classes). More recently, after the appearance of multi-queue devices (such as
Wifi), |
| 188 * some multi-queue aware queue discs have been introduced. Multi-queue aware qu
eue discs |
| 189 * handle as many queues (or queue discs -- without using classes) as the number
of |
| 190 * transmission queues used by the device on which the queue disc is installed. |
| 191 * An attempt is made, also, to enqueue each packet in the "same" queue both wit
hin the |
| 192 * queue disc and within the device. |
| 193 * |
| 194 * The traffic control layer interacts with a queue disc in a simple manner: aft
er requesting |
| 195 * to enqueue a packet, the traffic control layer requests the qdisc to "run", i
.e., to |
| 196 * dequeue a set of packets, until a predefined number ("quota") of packets is d
equeued |
| 197 * or the netdevice stops the queue disc. A netdevice may stop the queue disc wh
en its |
| 198 * transmission queue(s) is/are (almost) full. Also, a netdevice may wake the |
| 199 * queue disc when its transmission queue(s) is/are (almost) empty. Waking a que
ue disc |
| 200 * is equivalent to make it run. |
| 201 * |
| 202 * The design and implementation of this class is heavily inspired by Linux. |
| 203 * For more details, see the traffic-control model page. |
| 204 */ |
| 205 class QueueDisc : public Object { |
| 206 public: |
| 207 /** |
| 208 * \brief Get the type ID. |
| 209 * \return the object TypeId |
| 210 */ |
| 211 static TypeId GetTypeId (void); |
| 212 |
| 213 QueueDisc (); |
| 214 |
| 215 /** |
| 216 * \brief Get the number of packets stored by the queue disc |
| 217 * \return the number of packets stored by the queue disc. |
| 218 * |
| 219 * Note that the number of packets stored by the queue disc is updated as soon |
| 220 * as a packet is received by the queue disc and before actually enqueuing the |
| 221 * packet (i.e., before calling DoEnqueue). Thus, while implementing the DoEnq
ueue |
| 222 * method of a subclass, keep in mind that GetNPackets returns the number of |
| 223 * packets stored in the queue disc, including the packet that we are trying |
| 224 * to enqueue. |
| 225 */ |
| 226 uint32_t GetNPackets (void) const; |
| 227 |
| 228 /** |
| 229 * \brief Get the amount of bytes stored by the queue disc |
| 230 * \return the amount of bytes stored by the queue disc. |
| 231 * |
| 232 * Note that the amount of bytes stored by the queue disc is updated as soon |
| 233 * as a packet is received by the queue disc and before actually enqueuing the |
| 234 * packet (i.e., before calling DoEnqueue). Thus, while implementing the DoEnq
ueue |
| 235 * method of a subclass, keep in mind that GetNBytes returns the amount of |
| 236 * bytes stored in the queue disc, including the size of the packet that we ar
e |
| 237 * trying to enqueue. |
| 238 */ |
| 239 uint32_t GetNBytes (void) const; |
| 240 |
| 241 /** |
| 242 * \brief Get the total number of received packets |
| 243 * \return the total number of received packets. |
| 244 */ |
| 245 uint32_t GetTotalReceivedPackets (void) const; |
| 246 |
| 247 /** |
| 248 * \brief Get the total amount of received bytes |
| 249 * \return the total amount of received bytes. |
| 250 */ |
| 251 uint32_t GetTotalReceivedBytes (void) const; |
| 252 |
| 253 /** |
| 254 * \brief Get the total number of dropped packets |
| 255 * \return the total number of dropped packets. |
| 256 */ |
| 257 uint32_t GetTotalDroppedPackets (void) const; |
| 258 |
| 259 /** |
| 260 * \brief Get the total amount of dropped bytes |
| 261 * \return the total amount of dropped bytes. |
| 262 */ |
| 263 uint32_t GetTotalDroppedBytes (void) const; |
| 264 |
| 265 /** |
| 266 * \brief Get the total number of requeued packets |
| 267 * \return the total number of requeued packets. |
| 268 */ |
| 269 uint32_t GetTotalRequeuedPackets (void) const; |
| 270 |
| 271 /** |
| 272 * \brief Get the total amount of requeued bytes |
| 273 * \return the total amount of requeued bytes. |
| 274 */ |
| 275 uint32_t GetTotalRequeuedBytes (void) const; |
| 276 |
| 277 /** |
| 278 * \brief Set the NetDevice on which this queue discipline is installed. |
| 279 * \param device the NetDevice on which this queue discipline is installed. |
| 280 */ |
| 281 void SetNetDevice (Ptr<NetDevice> device); |
| 282 |
| 283 /** |
| 284 * \brief Get the NetDevice on which this queue discipline is installed |
| 285 * \return the NetDevice on which this queue discipline is installed. |
| 286 */ |
| 287 Ptr<NetDevice> GetNetDevice (void) const; |
| 288 |
| 289 /** |
| 290 * \brief Set the maximum number of dequeue operations following a packet enqu
eue |
| 291 * \param quota the maximum number of dequeue operations following a packet en
queue. |
| 292 */ |
| 293 virtual void SetQuota (const uint32_t quota); |
| 294 |
| 295 /** |
| 296 * \brief Get the maximum number of dequeue operations following a packet enqu
eue |
| 297 * \return the maximum number of dequeue operations following a packet enqueue
. |
| 298 */ |
| 299 virtual uint32_t GetQuota (void) const; |
| 300 |
| 301 /** |
| 302 * Pass a packet to store to the queue discipline. This function only updates |
| 303 * the statistics and calls the (private) DoEnqueue function, which must be |
| 304 * implemented by derived classes. |
| 305 * \param item item to enqueue |
| 306 * \return True if the operation was successful; false otherwise |
| 307 */ |
| 308 bool Enqueue (Ptr<QueueDiscItem> item); |
| 309 |
| 310 /** |
| 311 * Request the queue discipline to extract a packet. This function only update
s |
| 312 * the statistics and calls the (private) DoDequeue function, which must be |
| 313 * implemented by derived classes. |
| 314 * \return 0 if the operation was not successful; the item otherwise. |
| 315 */ |
| 316 Ptr<QueueDiscItem> Dequeue (void); |
| 317 |
| 318 /** |
| 319 * Get a copy of the next packet the queue discipline will extract, without |
| 320 * actually extracting the packet. This function only calls the (private) |
| 321 * DoPeek function, which must be implemented by derived classes. |
| 322 * \return 0 if the operation was not successful; the item otherwise. |
| 323 */ |
| 324 Ptr<const QueueDiscItem> Peek (void) const; |
| 325 |
| 326 /** |
| 327 * Modelled after the Linux function __qdisc_run (net/sched/sch_generic.c) |
| 328 * Dequeues multiple packets, until a quota is exceeded or sending a packet |
| 329 * to the device failed. |
| 330 */ |
| 331 void Run (void); |
| 332 |
| 333 /** |
| 334 * \brief Add an internal queue to the tail of the list of queues. |
| 335 * \param queue the queue to be added |
| 336 */ |
| 337 void AddInternalQueue (Ptr<Queue> queue); |
| 338 |
| 339 /** |
| 340 * \brief Get the i-th internal queue |
| 341 * \param i the index of the queue |
| 342 * \return the i-th internal queue. |
| 343 */ |
| 344 Ptr<Queue> GetInternalQueue (uint32_t i) const; |
| 345 |
| 346 /** |
| 347 * \brief Get the number of internal queues |
| 348 * \return the number of internal queues. |
| 349 */ |
| 350 uint32_t GetNInternalQueues (void) const; |
| 351 |
| 352 /** |
| 353 * \brief Add a packet filter to the tail of the list of filters used to class
ify packets. |
| 354 * \param filter the packet filter to be added |
| 355 */ |
| 356 void AddPacketFilter (Ptr<PacketFilter> filter); |
| 357 |
| 358 /** |
| 359 * \brief Get the i-th packet filter |
| 360 * \param i the index of the packet filter |
| 361 * \return the i-th packet filter. |
| 362 */ |
| 363 Ptr<PacketFilter> GetPacketFilter (uint32_t i) const; |
| 364 |
| 365 /** |
| 366 * \brief Get the number of packet filters |
| 367 * \return the number of packet filters. |
| 368 */ |
| 369 uint32_t GetNPacketFilters (void) const; |
| 370 |
| 371 /** |
| 372 * \brief Add a queue disc class to the tail of the list of classes. |
| 373 * \param qdClass the queue disc class to be added |
| 374 */ |
| 375 void AddQueueDiscClass (Ptr<QueueDiscClass> qdClass); |
| 376 |
| 377 /** |
| 378 * \brief Get the i-th queue disc class |
| 379 * \param i the index of the queue disc class |
| 380 * \return the i-th queue disc class. |
| 381 */ |
| 382 Ptr<QueueDiscClass> GetQueueDiscClass (uint32_t i) const; |
| 383 |
| 384 /** |
| 385 * \brief Get the number of queue disc classes |
| 386 * \return the number of queue disc classes. |
| 387 */ |
| 388 uint32_t GetNQueueDiscClasses (void) const; |
| 389 |
| 390 /** |
| 391 * Classify a packet by calling the packet filters, one at a time, until eithe
r |
| 392 * a filter able to classify the packet is found or all the filters have been |
| 393 * processed. |
| 394 * \param item item to classify |
| 395 * \return -1 if no filter able to classify the packet has been found, the val
ue |
| 396 * returned by first filter found to be able to classify the packet otherwise. |
| 397 */ |
| 398 int32_t Classify (Ptr<QueueDiscItem> item); |
| 399 |
| 400 /** |
| 401 * \enum WakeMode |
| 402 * \brief Used to determine whether the queue disc itself or its children must |
| 403 * be activated when a netdevice wakes a transmission queue |
| 404 */ |
| 405 enum WakeMode |
| 406 { |
| 407 WAKE_ROOT = 0x00, |
| 408 WAKE_CHILD = 0x01 |
| 409 }; |
| 410 |
| 411 /** |
| 412 * When setting up the wake callbacks on the netdevice queues, it is necessary
to |
| 413 * determine which queue disc (the root queue disc or one of its children) sho
uld |
| 414 * be activated when the netdevice wakes one of its transmission queues. The |
| 415 * implementation of this method for the base class returns WAKE_ROOT, i.e., t
he |
| 416 * root queue disc is activated. Subclasses implementing queue discs adopting |
| 417 * a different strategy (e.g., multi-queue aware queue discs such as mq) have |
| 418 * to redefine this method. |
| 419 * |
| 420 * \return the wake mode adopted by this queue disc. |
| 421 */ |
| 422 WakeMode GetWakeMode (void); |
| 423 |
| 424 /** |
| 425 * \brief Check whether the configuration is correct and initialize parameters |
| 426 * |
| 427 * Note that this method is not virtual because it must not be redefined by |
| 428 * subclasses, which instead need to implement CheckConfig and InitializeParam
s. |
| 429 */ |
| 430 void Init (void); |
| 431 |
| 432 protected: |
| 433 /** |
| 434 * \brief Dispose of the object |
| 435 */ |
| 436 virtual void DoDispose (void); |
| 437 |
| 438 /** |
| 439 * \brief Drop a packet |
| 440 * \param item item that was dropped |
| 441 * This method is called by subclasses to notify parent (this class) of packe
t drops. |
| 442 */ |
| 443 void Drop (Ptr<QueueDiscItem> item); |
| 444 |
| 445 private: |
| 446 |
| 447 /** |
| 448 * This function actually enqueues a packet into the queue disc. |
| 449 * \param item item to enqueue |
| 450 * \return True if the operation was successful; false otherwise |
| 451 */ |
| 452 virtual bool DoEnqueue (Ptr<QueueDiscItem> item) = 0; |
| 453 |
| 454 /** |
| 455 * This function actually extracts a packet from the queue disc. |
| 456 * \return 0 if the operation was not successful; the item otherwise. |
| 457 */ |
| 458 virtual Ptr<QueueDiscItem> DoDequeue (void) = 0; |
| 459 |
| 460 /** |
| 461 * This function returns a copy of the next packet the queue disc will extract
. |
| 462 * \return 0 if the operation was not successful; the packet otherwise. |
| 463 */ |
| 464 virtual Ptr<const QueueDiscItem> DoPeek (void) const = 0; |
| 465 |
| 466 /** |
| 467 * Check whether the current configuration is correct. Default objects (such |
| 468 * as internal queues) might be created by this method to ensure the |
| 469 * configuration is correct. |
| 470 * \return true if the configuration is correct, false otherwise |
| 471 */ |
| 472 virtual bool CheckConfig (void) = 0; |
| 473 |
| 474 /** |
| 475 * Initialize parameters (if any) before the first packet is enqueued. |
| 476 */ |
| 477 virtual void InitializeParams (void) = 0; |
| 478 |
| 479 /** |
| 480 * Modelled after the Linux function qdisc_run_begin (include/net/sch_generic.
h). |
| 481 * \return false if the qdisc is already running; otherwise, set the qdisc as
running and return true. |
| 482 */ |
| 483 bool RunBegin (void); |
| 484 |
| 485 /** |
| 486 * Modelled after the Linux function qdisc_run_end (include/net/sch_generic.h)
. |
| 487 * Set the qdisc as not running. |
| 488 */ |
| 489 void RunEnd (void); |
| 490 |
| 491 /** |
| 492 * Modelled after the Linux function qdisc_restart (net/sched/sch_generic.c) |
| 493 * Dequeue a packet (by calling DequeuePacket) and send it to the device (by c
alling Transmit). |
| 494 * \return true if a packet is successfully sent to the device. |
| 495 */ |
| 496 bool Restart (void); |
| 497 |
| 498 /** |
| 499 * Modelled after the Linux function dequeue_skb (net/sched/sch_generic.c) |
| 500 * \return the requeued packet, if any, or the packet dequeued by the queue di
sc, otherwise. |
| 501 */ |
| 502 Ptr<QueueDiscItem> DequeuePacket (void); |
| 503 |
| 504 /** |
| 505 * Modelled after the Linux function dev_requeue_skb (net/sched/sch_generic.c) |
| 506 * Requeues a packet whose transmission failed. |
| 507 * \param p the packet to requeue |
| 508 */ |
| 509 void Requeue (Ptr<QueueDiscItem> p); |
| 510 |
| 511 /** |
| 512 * Modelled after the Linux function sch_direct_xmit (net/sched/sch_generic.c) |
| 513 * Sends a packet to the device and requeues it in case transmission fails. |
| 514 * \param p the packet to transmit |
| 515 * \return true if the transmission succeeded and the queue is not stopped |
| 516 */ |
| 517 bool Transmit (Ptr<QueueDiscItem> p); |
| 518 |
| 519 static const uint32_t DEFAULT_QUOTA = 64; //!< Default quota (as in /proc/sys/
net/core/dev_weight) |
| 520 |
| 521 std::vector<Ptr<Queue> > m_queues; //!< Internal queues |
| 522 std::vector<Ptr<PacketFilter> > m_filters; //!< Packet filters |
| 523 std::vector<Ptr<QueueDiscClass> > m_classes; //!< Classes |
| 524 |
| 525 TracedValue<uint32_t> m_nPackets; //!< Number of packets in the queue |
| 526 TracedValue<uint32_t> m_nBytes; //!< Number of bytes in the queue |
| 527 |
| 528 uint32_t m_nTotalReceivedPackets; //!< Total received packets |
| 529 uint32_t m_nTotalReceivedBytes; //!< Total received bytes |
| 530 uint32_t m_nTotalDroppedPackets; //!< Total dropped packets |
| 531 uint32_t m_nTotalDroppedBytes; //!< Total dropped bytes |
| 532 uint32_t m_nTotalRequeuedPackets; //!< Total requeued packets |
| 533 uint32_t m_nTotalRequeuedBytes; //!< Total requeued bytes |
| 534 uint32_t m_quota; //!< Maximum number of packets dequeued in a
qdisc run |
| 535 Ptr<NetDevice> m_device; //!< The NetDevice on which this queue disci
pline is installed |
| 536 bool m_running; //!< The queue disc is performing multiple d
equeue operations |
| 537 bool m_InitCompleted; //!< True if the config has been verified an
d the parameters initialized |
| 538 Ptr<QueueDiscItem> m_requeued; //!< The last packet that failed to be trans
mitted |
| 539 |
| 540 /// Traced callback: fired when a packet is enqueued |
| 541 TracedCallback<Ptr<const QueueItem> > m_traceEnqueue; |
| 542 /// Traced callback: fired when a packet is dequeued |
| 543 TracedCallback<Ptr<const QueueItem> > m_traceDequeue; |
| 544 /// Traced callback: fired when a packet is requeued |
| 545 TracedCallback<Ptr<const QueueItem> > m_traceRequeue; |
| 546 /// Traced callback: fired when a packet is dropped |
| 547 TracedCallback<Ptr<const QueueItem> > m_traceDrop; |
| 548 }; |
| 549 |
| 550 } // namespace ns3 |
| 551 |
| 552 #endif /* QueueDisc */ |
OLD | NEW |