13#include "ns3/net-device-queue-interface.h"
14#include "ns3/object-map.h"
15#include "ns3/packet.h"
16#include "ns3/socket.h"
31 TypeId(
"ns3::TrafficControlLayer")
33 .SetGroupName(
"TrafficControl")
37 "The list of root queue discs associated to this Traffic Control layer.",
42 .AddTraceSource(
"TcDrop",
43 "Trace source indicating a packet has been dropped by the Traffic "
44 "Control layer because no queue disc is installed on the device, the "
45 "device supports flow control and the device queue is stopped",
47 "ns3::Packet::TracedCallback");
82 if (ndi.second.m_rootQueueDisc)
84 ndi.second.m_rootQueueDisc->Initialize();
93 uint16_t protocolType,
106 NS_LOG_DEBUG(
"Handler for NetDevice: " << device <<
" registered for protocol " << protocolType
122 NS_LOG_DEBUG(
"Checking device " << i <<
" with pointer " << dev <<
" of type "
123 << dev->GetInstanceTypeId().GetName());
127 NS_LOG_DEBUG(
"Pointer to NetDeviceQueueInterface: " << ndqi);
133 NS_LOG_DEBUG(
"Device entry found; installing NetDeviceQueueInterface pointer "
134 << ndqi <<
" to internal map");
135 ndi->second.m_ndqi = ndqi;
144 NS_LOG_DEBUG(
"No device entry found; create entry for device and store pointer to "
145 "NetDeviceQueueInterface: "
152 if (ndi !=
m_netDevices.end() && ndi->second.m_rootQueueDisc)
154 NS_LOG_DEBUG(
"Setting the wake callbacks on NetDevice queues");
155 ndi->second.m_queueDiscsToWake.clear();
159 for (std::size_t i = 0; i < ndqi->GetNTxQueues(); i++)
165 qd = ndi->second.m_rootQueueDisc;
170 ndqi->GetNTxQueues(),
171 "The number of child queue discs does not match the number "
172 "of netdevice queues");
174 qd = ndi->second.m_rootQueueDisc->GetQueueDiscClass(i)->GetQueueDisc();
182 ndi->second.m_queueDiscsToWake.push_back(qd);
187 ndi->second.m_queueDiscsToWake.push_back(ndi->second.m_rootQueueDisc);
192 for (
auto&
q : ndi->second.m_queueDiscsToWake)
194 q->SetNetDeviceQueueInterface(ndqi);
196 dev->Send(item->GetPacket(), item->GetAddress(), item->GetProtocol());
218 "Cannot install a root queue disc on a device already having one. "
219 "Delete the existing queue disc first.");
221 ndi->second.m_rootQueueDisc = qDisc;
236 return ndi->second.m_rootQueueDisc;
254 "No root queue disc installed on device " << device);
257 ndi->second.m_rootQueueDisc =
nullptr;
258 for (
auto&
q : ndi->second.m_queueDiscsToWake)
260 q->SetNetDeviceQueueInterface(
nullptr);
261 q->SetSendCallback(
nullptr);
263 ndi->second.m_queueDiscsToWake.clear();
269 for (std::size_t i = 0; i < ndqi->GetNTxQueues(); i++)
308 return m_node->GetNDevices();
319 NS_LOG_FUNCTION(
this << device << p << protocol << from << to << packetType);
325 if (!i->device || (i->device == device))
327 if (i->protocol == 0 || i->protocol == protocol)
329 NS_LOG_DEBUG(
"Found handler for packet " << p <<
", protocol " << protocol
330 <<
" and NetDevice " << device
331 <<
". Send packet up");
332 i->handler(device, p, protocol, from, to, packetType);
339 "Handler for protocol " << p <<
" and device " << device
340 <<
" not found. It isn't forwarded up; it dies here.");
348 NS_LOG_DEBUG(
"Send packet to device " << device <<
" protocol number " << item->GetProtocol());
355 devQueueIface = ndi->second.m_ndqi;
360 if (devQueueIface && devQueueIface->GetNTxQueues() > 1)
362 txq = devQueueIface->GetSelectQueueCallback()(item);
371 NS_ASSERT(!devQueueIface || txq < devQueueIface->GetNTxQueues());
373 if (ndi ==
m_netDevices.end() || !ndi->second.m_rootQueueDisc)
378 if (!devQueueIface || !devQueueIface->GetTxQueue(txq)->IsStopped())
381 if (!devQueueIface || devQueueIface->GetNTxQueues() == 1)
384 item->GetPacket()->RemovePacketTag(priorityTag);
386 device->Send(item->GetPacket(), item->GetAddress(), item->GetProtocol());
397 item->SetTxQueueIndex(txq);
401 qDisc->Enqueue(item);
a polymophic address class
PacketType
Packet types are used as they are in Linux.
Network device transmission queue interface.
Callback< void, Ptr< NetDevice >, Ptr< const Packet >, uint16_t, const Address &, const Address &, NetDevice::PacketType > ProtocolHandler
A protocol handler.
virtual void NotifyNewAggregate()
Notify all Objects aggregated to this one of a new Object being aggregated.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
virtual void DoInitialize()
Initialize() implementation.
Object()
Caller graph was not generated because of its size.
virtual void DoDispose()
Destructor implementation.
Smart pointer class similar to boost::intrusive_ptr.
void Run()
Modelled after the Linux function __qdisc_run (net/sched/sch_generic.c) Dequeues multiple packets,...
indicates whether the socket has a priority set.
The Traffic Control layer aims at introducing an equivalent of the Linux Traffic Control infrastructu...
void NotifyNewAggregate() override
Notify all Objects aggregated to this one of a new Object being aggregated.
static TypeId GetTypeId()
Get the type ID.
Ptr< QueueDisc > GetRootQueueDiscOnDeviceByIndex(uint32_t index) const
Required by the object map accessor.
void DoInitialize() override
Initialize() implementation.
void DoDispose() override
Destructor implementation.
TracedCallback< Ptr< const Packet > > m_dropped
The trace source fired when the Traffic Control layer drops a packet because no queue disc is install...
ProtocolHandlerList m_handlers
List of upper-layer handlers.
TrafficControlLayer()
Constructor.
Ptr< Node > m_node
The node this TrafficControlLayer object is aggregated to.
uint32_t GetNDevices() const
Required by the object map accessor.
std::map< Ptr< NetDevice >, NetDeviceInfo > m_netDevices
Map storing the required information for each device with a queue disc installed.
virtual void DeleteRootQueueDiscOnDevice(Ptr< NetDevice > device)
This method can be used to remove the root queue disc (and associated filters, classes and queues) in...
std::vector< Ptr< QueueDisc > > QueueDiscVector
Typedef for queue disc vector.
virtual void ScanDevices()
Collect information needed to determine how to handle packets destined to each of the NetDevices of t...
virtual void Send(Ptr< NetDevice > device, Ptr< QueueDiscItem > item)
Called from upper layer to queue a packet for the transmission.
void SetNode(Ptr< Node > node)
Set node associated with this stack.
virtual Ptr< QueueDisc > GetRootQueueDiscOnDevice(Ptr< NetDevice > device) const
This method can be used to get the root queue disc installed on a device.
virtual void Receive(Ptr< NetDevice > device, Ptr< const Packet > p, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType)
Called by NetDevices, incoming packet.
virtual void SetRootQueueDiscOnDevice(Ptr< NetDevice > device, Ptr< QueueDisc > qDisc)
This method can be used to set the root queue disc installed on a device.
void RegisterProtocolHandler(Node::ProtocolHandler handler, uint16_t protocolType, Ptr< NetDevice > device)
Register an IN handler.
~TrafficControlLayer() override
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
ObjectPtrContainerValue ObjectMapValue
ObjectMapValue is an alias for ObjectPtrContainerValue.
Ptr< const AttributeAccessor > MakeObjectMapAccessor(U T::*memberVariable)
MakeAccessorHelper implementation for ObjectVector.
Ptr< const AttributeChecker > MakeObjectMapChecker()
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...
Callback< R, Args... > MakeNullCallback()
Build null Callbacks which take no arguments, for varying number of template arguments,...
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Node::ProtocolHandler handler
the protocol handler
bool promiscuous
true if it is a promiscuous handler
uint16_t protocol
the protocol number
Ptr< NetDevice > device
the NetDevice