A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
net-device-queue-interface.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017 Universita' degli Studi di Napoli Federico II
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Stefano Avallone <stefano.avallone@.unina.it>
7 */
8#ifndef NET_DEVICE_QUEUE_INTERFACE_H
9#define NET_DEVICE_QUEUE_INTERFACE_H
10
11#include "ns3/callback.h"
12#include "ns3/log.h"
13#include "ns3/net-device.h"
14#include "ns3/object-factory.h"
15#include "ns3/object.h"
16#include "ns3/ptr.h"
17#include "ns3/simulator.h"
18
19#include <functional>
20#include <vector>
21
22namespace ns3
23{
24
25class QueueLimits;
26class NetDeviceQueueInterface;
27class QueueItem;
28
29/**
30 * @ingroup network
31 * @defgroup netdevice Network Device
32 */
33
34/**
35 * @ingroup netdevice
36 *
37 * @brief Network device transmission queue
38 *
39 * This class stores information about a single transmission queue
40 * of a network device that is exposed to queue discs. Such information
41 * includes the state of the transmission queue (whether it has been
42 * stopped or not) and data used by techniques such as Byte Queue Limits.
43 *
44 * This class roughly models the struct netdev_queue of Linux.
45 */
46class NetDeviceQueue : public Object
47{
48 public:
49 /**
50 * @brief Get the type ID.
51 * @return the object TypeId
52 */
53 static TypeId GetTypeId();
54
56 ~NetDeviceQueue() override;
57
58 /**
59 * Called by the device to start this device transmission queue.
60 * This is the analogous to the netif_tx_start_queue function of the Linux kernel.
61 */
62 virtual void Start();
63
64 /**
65 * Called by the device to stop this device transmission queue.
66 * This is the analogous to the netif_tx_stop_queue function of the Linux kernel.
67 */
68 virtual void Stop();
69
70 /**
71 * Called by the device to wake the queue disc associated with this
72 * device transmission queue. This is done by invoking the wake callback.
73 * This is the analogous to the netif_tx_wake_queue function of the Linux kernel.
74 */
75 virtual void Wake();
76
77 /**
78 * @brief Get the status of the device transmission queue.
79 * @return true if the device transmission queue is stopped.
80 *
81 * Called by queue discs to enquire about the status of a given transmission queue.
82 * This is the analogous to the netif_xmit_stopped function of the Linux kernel.
83 */
84 virtual bool IsStopped() const;
85
86 /**
87 * @brief Notify this NetDeviceQueue that the NetDeviceQueueInterface was
88 * aggregated to an object.
89 *
90 * @param ndqi the NetDeviceQueueInterface.
91 *
92 * This NetDeviceQueue stores a pointer to the NetDevice the NetDeviceQueueInterface
93 * was aggregated to.
94 */
96
97 /// Callback invoked by netdevices to wake upper layers
99
100 /**
101 * @brief Set the wake callback
102 * @param cb the callback to set
103 *
104 * Called by the traffic control layer to set the wake callback. The wake callback
105 * is invoked by the device whenever it is needed to "wake" the upper layers (i.e.,
106 * solicitate the queue disc associated with this transmission queue (in case of
107 * multi-queue aware queue discs) or to the network device (otherwise) to send
108 * packets down to the device).
109 */
110 virtual void SetWakeCallback(WakeCallback cb);
111
112 /**
113 * @brief Called by the netdevice to report the number of bytes queued to the device queue
114 * @param bytes number of bytes queued to the device queue
115 */
116 virtual void NotifyQueuedBytes(uint32_t bytes);
117
118 /**
119 * @brief Called by the netdevice to report the number of bytes it is going to transmit
120 * @param bytes number of bytes the device is going to transmit
121 */
122 virtual void NotifyTransmittedBytes(uint32_t bytes);
123
124 /**
125 * @brief Reset queue limits state
126 */
127 void ResetQueueLimits();
128
129 /**
130 * @brief Set queue limits to this queue
131 * @param ql the queue limits associated to this queue
132 */
134
135 /**
136 * @brief Get queue limits to this queue
137 * @return the queue limits associated to this queue
138 */
140
141 /**
142 * @brief Perform the actions required by flow control and dynamic queue
143 * limits when a packet is enqueued in the queue of a netdevice
144 *
145 * @param queue the device queue
146 * @param item the enqueued packet
147 *
148 * This method must be connected to the "Enqueue" traced callback of a Queue
149 * object (through a bound callback) in order for a netdevice to support
150 * flow control and dynamic queue limits.
151 */
152 template <typename QueueType>
153 void PacketEnqueued(QueueType* queue, Ptr<const typename QueueType::ItemType> item);
154
155 /**
156 * @brief Perform the actions required by flow control and dynamic queue
157 * limits when a packet is dequeued (or dropped after dequeue) from
158 * the queue of a netdevice
159 *
160 * @param queue the device queue
161 * @param item the dequeued packet
162 *
163 * This method must be connected to the "Dequeue" traced callback of a Queue
164 * object (through a bound callback) in order for
165 * a netdevice to support flow control and dynamic queue limits.
166 */
167 template <typename QueueType>
168 void PacketDequeued(QueueType* queue, Ptr<const typename QueueType::ItemType> item);
169
170 /**
171 * @brief Perform the actions required by flow control and dynamic queue
172 * limits when a packet is dropped before being enqueued in the queue
173 * of a netdevice (which likely indicates that the queue is full)
174 *
175 * @param queue the device queue
176 * @param item the dropped packet
177 *
178 * This method must be connected to the "DropBeforeEnqueue" traced callback
179 * of a Queue object (through a bound callback) in order for a netdevice to
180 * support flow control and dynamic queue limits.
181 */
182 template <typename QueueType>
183 void PacketDiscarded(QueueType* queue, Ptr<const typename QueueType::ItemType> item);
184
185 /**
186 * @brief Connect the traced callbacks of a queue to the methods providing support
187 * for flow control and dynamic queue limits. A queue can be any object providing:
188 * - "Enqueue", "Dequeue", "DropBeforeEnqueue" traces
189 * - an ItemType typedef for the type of stored items
190 * - GetCurrentSize and GetMaxSize methods
191 * @param queue the queue
192 */
193 template <typename QueueType>
195
196 private:
197 bool m_stoppedByDevice; //!< True if the queue has been stopped by the device
198 bool m_stoppedByQueueLimits; //!< True if the queue has been stopped by a queue limits object
199 Ptr<QueueLimits> m_queueLimits; //!< Queue limits object
200 WakeCallback m_wakeCallback; //!< Wake callback
201 Ptr<NetDevice> m_device; //!< the netdevice aggregated to the NetDeviceQueueInterface
202
203 NS_LOG_TEMPLATE_DECLARE; //!< redefinition of the log component
204};
205
206/**
207 * @ingroup netdevice
208 *
209 * @brief Network device transmission queue interface
210 *
211 * This interface is used by the traffic control layer and by the aggregated
212 * device to access the transmission queues of the device. Additionally, through
213 * this interface, traffic control aware netdevices can:
214 * - set the number of transmission queues
215 * - set the method used (by upper layers) to determine the transmission queue
216 * in which the netdevice would enqueue a given packet
217 * NetDevice helpers create this interface and aggregate it to the device.
218 */
220{
221 public:
222 /**
223 * @brief Get the type ID.
224 * @return the object TypeId
225 */
226 static TypeId GetTypeId();
227
228 /**
229 * @brief Constructor
230 */
232 ~NetDeviceQueueInterface() override;
233
234 /**
235 * @brief Get the i-th transmission queue of the device.
236 *
237 * @param i the index of the requested queue.
238 * @return the i-th transmission queue of the device.
239 *
240 * The index of the first transmission queue is zero.
241 */
242 Ptr<NetDeviceQueue> GetTxQueue(std::size_t i) const;
243
244 /**
245 * @brief Get the number of device transmission queues.
246 * @return the number of device transmission queues.
247 */
248 std::size_t GetNTxQueues() const;
249
250 /**
251 * @brief Set the type of device transmission queues to create.
252 * @param type type of device transmission queues to create.
253 *
254 * This method is called when the TxQueuesType attribute is set to create
255 * the corresponding type of device transmission queues. It cannot be
256 * called again afterwards.
257 */
258 void SetTxQueuesType(TypeId type);
259
260 /**
261 * @brief Set the number of device transmission queues to create.
262 * @param numTxQueues number of device transmission queues to create.
263 *
264 * This method is called when the NTxQueues attribute is set to create
265 * the corresponding number of device transmission queues. It cannot be
266 * called again afterwards.
267 */
268 void SetNTxQueues(std::size_t numTxQueues);
269
270 /// Callback invoked to determine the tx queue selected for a given packet
271 typedef std::function<std::size_t(Ptr<QueueItem>)> SelectQueueCallback;
272
273 /**
274 * @brief Set the select queue callback.
275 * @param cb the callback to set.
276 *
277 * This method is called to set the select queue callback, i.e., the
278 * method used to select a device transmission queue for a given packet.
279 */
281
282 /**
283 * @brief Get the select queue callback.
284 * @return the select queue callback.
285 *
286 * Called by the traffic control layer to get the select queue callback set
287 * by a multi-queue device.
288 */
290
291 protected:
292 /**
293 * @brief Dispose of the object
294 */
295 void DoDispose() override;
296 /**
297 * @brief Notify that an object was aggregated
298 */
299 void NotifyNewAggregate() override;
300
301 private:
302 ObjectFactory m_txQueues; //!< Device transmission queues TypeId
303 std::vector<Ptr<NetDeviceQueue>> m_txQueuesVector; //!< Device transmission queues
304 SelectQueueCallback m_selectQueueCallback; //!< Select queue callback
305};
306
307/**
308 * Implementation of the templates declared above.
309 */
310
311template <typename QueueType>
312void
314{
315 NS_ASSERT(queue);
316
317 queue->TraceConnectWithoutContext(
318 "Enqueue",
320 queue->TraceConnectWithoutContext(
321 "Dequeue",
323 queue->TraceConnectWithoutContext(
324 "DropBeforeEnqueue",
326}
327
328template <typename QueueType>
329void
331{
332 NS_LOG_FUNCTION(this << queue << item);
333
334 // Inform BQL
335 NotifyQueuedBytes(item->GetSize());
336
337 NS_ASSERT_MSG(m_device, "Aggregated NetDevice not set");
338 // After enqueuing a packet, we need to check whether the queue is able to
339 // store another packet. If not, we stop the queue
340
341 if (queue->WouldOverflow(1, m_device->GetMtu()))
342 {
343 NS_LOG_DEBUG("The device queue is being stopped (" << queue->GetCurrentSize()
344 << " inside)");
345 Stop();
346 }
347}
348
349template <typename QueueType>
350void
352{
353 NS_LOG_FUNCTION(this << queue << item);
354 NS_ASSERT_MSG(m_device, "Aggregated NetDevice not set");
355
356 Simulator::ScheduleNow([=, this]() {
357 // Inform BQL
358 NotifyTransmittedBytes(item->GetSize());
359
360 // After dequeuing a packet, if there is room for another packet we
361 // call Wake () that ensures that the queue is not stopped and restarts
362 // the queue disc if the queue was stopped
363
364 if (!queue->WouldOverflow(1, m_device->GetMtu()))
365 {
366 Wake();
367 }
368 });
369}
370
371template <typename QueueType>
372void
374{
375 NS_LOG_FUNCTION(this << queue << item);
376
377 // This method is called when a packet is discarded before being enqueued in the
378 // device queue, likely because the queue is full. This should not happen if the
379 // device correctly stops the queue. Anyway, stop the tx queue, so that the upper
380 // layers do not send packets until there is room in the queue again.
381
382 NS_LOG_ERROR("BUG! No room in the device queue for the received packet! ("
383 << queue->GetCurrentSize() << " inside)");
384
385 Stop();
386}
387
388} // namespace ns3
389
390#endif /* NET_DEVICE_QUEUE_INTERFACE_H */
Callback template class.
Definition callback.h:422
Network device transmission queue.
bool m_stoppedByQueueLimits
True if the queue has been stopped by a queue limits object.
void ConnectQueueTraces(Ptr< QueueType > queue)
Connect the traced callbacks of a queue to the methods providing support for flow control and dynamic...
virtual void Stop()
Called by the device to stop this device transmission queue.
void NotifyAggregatedObject(Ptr< NetDeviceQueueInterface > ndqi)
Notify this NetDeviceQueue that the NetDeviceQueueInterface was aggregated to an object.
void PacketDiscarded(QueueType *queue, Ptr< const typename QueueType::ItemType > item)
Perform the actions required by flow control and dynamic queue limits when a packet is dropped before...
Ptr< QueueLimits > GetQueueLimits()
Get queue limits to this queue.
Ptr< QueueLimits > m_queueLimits
Queue limits object.
virtual void Wake()
Called by the device to wake the queue disc associated with this device transmission queue.
virtual bool IsStopped() const
Get the status of the device transmission queue.
void SetQueueLimits(Ptr< QueueLimits > ql)
Set queue limits to this queue.
NS_LOG_TEMPLATE_DECLARE
redefinition of the log component
void PacketDequeued(QueueType *queue, Ptr< const typename QueueType::ItemType > item)
Perform the actions required by flow control and dynamic queue limits when a packet is dequeued (or d...
void ResetQueueLimits()
Reset queue limits state.
virtual void Start()
Called by the device to start this device transmission queue.
virtual void NotifyTransmittedBytes(uint32_t bytes)
Called by the netdevice to report the number of bytes it is going to transmit.
virtual void NotifyQueuedBytes(uint32_t bytes)
Called by the netdevice to report the number of bytes queued to the device queue.
Ptr< NetDevice > m_device
the netdevice aggregated to the NetDeviceQueueInterface
WakeCallback m_wakeCallback
Wake callback.
Callback< void > WakeCallback
Callback invoked by netdevices to wake upper layers.
bool m_stoppedByDevice
True if the queue has been stopped by the device.
static TypeId GetTypeId()
Get the type ID.
virtual void SetWakeCallback(WakeCallback cb)
Set the wake callback.
void PacketEnqueued(QueueType *queue, Ptr< const typename QueueType::ItemType > item)
Perform the actions required by flow control and dynamic queue limits when a packet is enqueued in th...
Network device transmission queue interface.
SelectQueueCallback m_selectQueueCallback
Select queue callback.
std::vector< Ptr< NetDeviceQueue > > m_txQueuesVector
Device transmission queues.
std::size_t GetNTxQueues() const
Get the number of device transmission queues.
Ptr< NetDeviceQueue > GetTxQueue(std::size_t i) const
Get the i-th transmission queue of the device.
std::function< std::size_t(Ptr< QueueItem >)> SelectQueueCallback
Callback invoked to determine the tx queue selected for a given packet.
ObjectFactory m_txQueues
Device transmission queues TypeId.
void SetSelectQueueCallback(SelectQueueCallback cb)
Set the select queue callback.
void DoDispose() override
Dispose of the object.
SelectQueueCallback GetSelectQueueCallback() const
Get the select queue callback.
void SetTxQueuesType(TypeId type)
Set the type of device transmission queues to create.
void SetNTxQueues(std::size_t numTxQueues)
Set the number of device transmission queues to create.
void NotifyNewAggregate() override
Notify that an object was aggregated.
static TypeId GetTypeId()
Get the type ID.
Instantiate subclasses of ns3::Object.
A base class which provides memory management and object aggregation.
Definition object.h:78
Smart pointer class similar to boost::intrusive_ptr.
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition simulator.h:594
a unique identifier for an interface.
Definition type-id.h:48
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition assert.h:75
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition log.h:243
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Every class exported by the ns3 library is enclosed in the ns3 namespace.
U * PeekPointer(const Ptr< U > &p)
Definition ptr.h:443
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition callback.h:684