A Discrete-Event Network Simulator
API
traffic-control-helper.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2015 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 * Author: Stefano Avallone <stavallo@unina.it>
19 */
20
21#include "ns3/log.h"
22#include "ns3/abort.h"
23#include "ns3/queue-limits.h"
24#include "ns3/net-device-queue-interface.h"
25#include "ns3/uinteger.h"
26#include "ns3/pointer.h"
27#include "ns3/traffic-control-layer.h"
29
30namespace ns3 {
31
32NS_LOG_COMPONENT_DEFINE ("TrafficControlHelper");
33
35 : m_queueDiscFactory (factory)
36{
37}
38
39void
41{
42 m_internalQueuesFactory.push_back (factory);
43}
44
45void
47{
48 m_packetFiltersFactory.push_back (factory);
49}
50
51uint16_t
53{
54 m_queueDiscClassesFactory.push_back (factory);
55 return static_cast<uint16_t>(m_queueDiscClassesFactory.size () - 1);
56}
57
58void
59QueueDiscFactory::SetChildQueueDisc (uint16_t classId, uint16_t handle)
60{
62 "Cannot attach a queue disc to a non existing class");
63 m_classIdChildHandleMap[classId] = handle;
64}
65
67QueueDiscFactory::CreateQueueDisc (const std::vector<Ptr<QueueDisc> > & queueDiscs)
68{
69 // create the queue disc
71
72 // create and add the internal queues
73 for (std::vector<ObjectFactory>::iterator i = m_internalQueuesFactory.begin ();
74 i != m_internalQueuesFactory.end (); i++ )
75 {
77 }
78
79 // create and add the packet filters
80 for (std::vector<ObjectFactory>::iterator i = m_packetFiltersFactory.begin ();
81 i != m_packetFiltersFactory.end (); i++ )
82 {
83 qd->AddPacketFilter (i->Create<PacketFilter> ());
84 }
85
86 // create and add the queue disc classes
87 for (uint16_t i = 0; i < m_queueDiscClassesFactory.size (); i++)
88 {
89 // the class ID is given by the index i of the vector
91 "Cannot create a queue disc class with no attached queue disc");
92
93 uint16_t handle = m_classIdChildHandleMap[i];
94 NS_ABORT_MSG_IF (handle >= queueDiscs.size () || !queueDiscs[handle],
95 "A queue disc with handle " << handle << " has not been created yet");
96
97 m_queueDiscClassesFactory[i].Set ("QueueDisc", PointerValue (queueDiscs[handle]));
98 qd->AddQueueDiscClass (m_queueDiscClassesFactory[i].Create<QueueDiscClass> ());
99 }
100
101 return qd;
102}
103
104
106{
107}
108
110TrafficControlHelper::Default (std::size_t nTxQueues)
111{
112 NS_LOG_FUNCTION (nTxQueues);
113 NS_ABORT_MSG_IF (nTxQueues == 0, "The device must have at least one queue");
115
116 if (nTxQueues == 1)
117 {
118 helper.SetRootQueueDisc ("ns3::FqCoDelQueueDisc");
119 }
120 else
121 {
122 uint16_t handle = helper.SetRootQueueDisc ("ns3::MqQueueDisc");
123 ClassIdList cls = helper.AddQueueDiscClasses (handle, nTxQueues, "ns3::QueueDiscClass");
124 helper.AddChildQueueDiscs (handle, cls, "ns3::FqCoDelQueueDisc");
125 }
126 return helper;
127}
128
129uint16_t
131{
132 NS_ABORT_MSG_UNLESS (m_queueDiscFactory.empty (), "A root queue disc has been already added to this factory");
133
134 m_queueDiscFactory.push_back (QueueDiscFactory (factory));
135 return 0;
136}
137
138void
139TrafficControlHelper::DoAddInternalQueues (uint16_t handle, uint16_t count, ObjectFactory factory)
140{
141 NS_ABORT_MSG_IF (handle >= m_queueDiscFactory.size (), "A queue disc with handle "
142 << handle << " does not exist");
143
144 for (int i = 0; i < count; i++)
145 {
146 m_queueDiscFactory[handle].AddInternalQueue (factory);
147 }
148}
149
150void
152{
153 NS_ABORT_MSG_IF (handle >= m_queueDiscFactory.size (), "A queue disc with handle "
154 << handle << " does not exist");
155
156 m_queueDiscFactory[handle].AddPacketFilter (factory);
157}
158
160TrafficControlHelper::DoAddQueueDiscClasses (uint16_t handle, uint16_t count, ObjectFactory factory)
161{
162 NS_ABORT_MSG_IF (handle >= m_queueDiscFactory.size (), "A queue disc with handle "
163 << handle << " does not exist");
164
166 uint16_t classId;
167
168 for (int i = 0; i < count; i++)
169 {
170 classId = m_queueDiscFactory[handle].AddQueueDiscClass (factory);
171 list.push_back (classId);
172 }
173 return list;
174}
175
176uint16_t
177TrafficControlHelper::DoAddChildQueueDisc (uint16_t handle, uint16_t classId, ObjectFactory factory)
178{
179 NS_ABORT_MSG_IF (handle >= m_queueDiscFactory.size (), "A queue disc with handle "
180 << handle << " does not exist");
181
182 uint16_t childHandle = static_cast<uint16_t>(m_queueDiscFactory.size ());
183 m_queueDiscFactory.push_back (QueueDiscFactory (factory));
184 m_queueDiscFactory[handle].SetChildQueueDisc (classId, childHandle);
185
186 return childHandle;
187}
188
191 ObjectFactory factory)
192{
194 for (ClassIdList::const_iterator c = classes.begin (); c != classes.end (); c++)
195 {
196 uint16_t childHandle = DoAddChildQueueDisc (handle, *c, factory);
197 list.push_back (childHandle);
198 }
199 return list;
200}
201
204{
205 QueueDiscContainer container;
206
207 // A TrafficControlLayer object is aggregated by the InternetStackHelper, but check
208 // anyway because a queue disc has no effect without a TrafficControlLayer object
209 Ptr<TrafficControlLayer> tc = d->GetNode ()->GetObject<TrafficControlLayer> ();
210 NS_ASSERT (tc);
211
212 // Start from an empty vector of queue discs
213 m_queueDiscs.clear ();
214 m_queueDiscs.resize (m_queueDiscFactory.size ());
215
216 // Create queue discs (from leaves to root)
217 for (auto i = m_queueDiscFactory.size (); i-- > 0; )
218 {
219 m_queueDiscs[i] = m_queueDiscFactory[i].CreateQueueDisc (m_queueDiscs);
220 }
221
222 // Set the root queue disc (if any has been created) on the device
223 if (!m_queueDiscs.empty () && m_queueDiscs[0])
224 {
225 tc->SetRootQueueDiscOnDevice (d, m_queueDiscs[0]);
226 container.Add (m_queueDiscs[0]);
227 }
228
229 // Queue limits objects can only be installed if a netdevice queue interface
230 // has been aggregated to the netdevice. This is normally the case if the
231 // netdevice has been created via helpers. Abort the simulation if not.
233 {
235 NS_ABORT_MSG_IF (!ndqi, "A NetDeviceQueueInterface object has not been"
236 "aggregated to the NetDevice");
237 for (uint8_t i = 0; i < ndqi->GetNTxQueues (); i++)
238 {
240 ndqi->GetTxQueue (i)->SetQueueLimits (ql);
241 }
242 }
243
244 return container;
245}
246
249{
250 QueueDiscContainer container;
251
252 for (NetDeviceContainer::Iterator i = c.Begin (); i != c.End (); ++i)
253 {
254 container.Add (Install (*i));
255 }
256
257 return container;
258}
259
260void
262{
263 Ptr<TrafficControlLayer> tc = d->GetNode ()->GetObject<TrafficControlLayer> ();
264 NS_ASSERT (tc);
265
266 tc->DeleteRootQueueDiscOnDevice (d);
267 // remove the queue limits objects installed on the device transmission queues
269 // if a queue disc has been installed on the device, a netdevice queue interface
270 // must have been aggregated to the device
271 NS_ASSERT (ndqi);
272 for (uint8_t i = 0; i < ndqi->GetNTxQueues (); i++)
273 {
274 ndqi->GetTxQueue (i)->SetQueueLimits (0);
275 }
276}
277
278void
280{
281 for (NetDeviceContainer::Iterator i = c.Begin (); i != c.End (); ++i)
282 {
283 Uninstall (*i);
284 }
285}
286
287
288} // namespace ns3
holds a vector of ns3::NetDevice pointers
std::vector< Ptr< NetDevice > >::const_iterator Iterator
NetDevice container iterator.
Iterator End(void) const
Get an iterator which indicates past-the-last NetDevice in the container.
Iterator Begin(void) const
Get an iterator which refers to the first NetDevice in the container.
Network device transmission queue interface.
Instantiate subclasses of ns3::Object.
TypeId GetTypeId(void) const
Get the TypeId which will be created by this ObjectFactory.
Ptr< Object > Create(void) const
Create an Object instance of the configured TypeId.
PacketFilter is the abstract base class for filters used by queue discs to classify packets.
Definition: packet-filter.h:34
Hold objects of type Ptr<T>.
Definition: pointer.h:37
Introspection did not find any typical Config paths.
Holds a vector of ns3::QueueDisc pointers.
void Add(QueueDiscContainer other)
Append the contents of another QueueDiscContainer to the end of this container.
This class stores object factories required to create a queue disc and all of its components (packet ...
std::vector< ObjectFactory > m_internalQueuesFactory
Vector of factories to create internal queues.
uint16_t AddQueueDiscClass(ObjectFactory factory)
Add a factory to create a queue disc class.
void AddInternalQueue(ObjectFactory factory)
Add a factory to create an internal queue.
void AddPacketFilter(ObjectFactory factory)
Add a factory to create a packet filter.
Ptr< QueueDisc > CreateQueueDisc(const std::vector< Ptr< QueueDisc > > &queueDiscs)
Create a queue disc with the currently stored configuration.
void SetChildQueueDisc(uint16_t classId, uint16_t handle)
Set the (child) queue disc to attach to a class.
std::map< uint16_t, uint16_t > m_classIdChildHandleMap
Map storing the associations between class IDs and child queue disc handles.
std::vector< ObjectFactory > m_packetFiltersFactory
Vector of factories to create packet filters.
ObjectFactory m_queueDiscFactory
Factory to create this queue disc.
std::vector< ObjectFactory > m_queueDiscClassesFactory
Vector of factories to create queue disc classes.
QueueDisc is an abstract base class providing the interface and implementing the operations common to...
Definition: queue-disc.h:181
void AddInternalQueue(Ptr< InternalQueue > queue)
Add an internal queue to the tail of the list of queues.
Definition: queue-disc.cc:579
void AddQueueDiscClass(Ptr< QueueDiscClass > qdClass)
Add a queue disc class to the tail of the list of classes.
Definition: queue-disc.cc:632
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:612
Abstract base class for NetDevice queue length controller.
Definition: queue-limits.h:43
Build a set of QueueDisc objects.
std::vector< uint16_t > HandleList
Container type for Handlers.
QueueDiscContainer Install(NetDeviceContainer c)
std::vector< Ptr< QueueDisc > > m_queueDiscs
Vector of all the created queue discs.
uint16_t DoSetRootQueueDisc(ObjectFactory factory)
Actual implementation of the SetRootQueueDisc method.
uint16_t DoAddChildQueueDisc(uint16_t handle, uint16_t classId, ObjectFactory factory)
Actual implementation of the AddChildQueueDisc method.
TrafficControlHelper()
Create a TrafficControlHelper to make life easier when creating QueueDisc objects.
uint16_t SetRootQueueDisc(const std::string &type, Args &&... args)
Helper function used to set a root queue disc of the given type and with the given attributes.
void DoAddInternalQueues(uint16_t handle, uint16_t count, ObjectFactory factory)
Actual implementation of the AddInternalQueues method.
void DoAddPacketFilter(uint16_t handle, ObjectFactory factory)
Actual implementation of the AddPacketFilter method.
ObjectFactory m_queueLimitsFactory
Factory to create a queue limits object.
void Uninstall(NetDeviceContainer c)
ClassIdList DoAddQueueDiscClasses(uint16_t handle, uint16_t count, ObjectFactory factory)
Actual implementation of the AddQueueDiscClasses method.
std::vector< uint16_t > ClassIdList
Container type for Class IDs.
static TrafficControlHelper Default(std::size_t nTxQueues=1)
ClassIdList AddQueueDiscClasses(uint16_t handle, uint16_t count, const std::string &type, Args &&... args)
Helper function used to add the given number of queue disc classes (of the given type and with the gi...
std::vector< QueueDiscFactory > m_queueDiscFactory
QueueDisc factory, stores the configuration of all the queue discs.
HandleList DoAddChildQueueDiscs(uint16_t handle, const ClassIdList &classes, ObjectFactory factory)
Actual implementation of the AddChildQueueDiscs method.
HandleList AddChildQueueDiscs(uint16_t handle, const ClassIdList &classes, const std::string &type, Args &&... args)
Helper function used to attach a child queue disc (of the given type and with the given attributes) t...
Introspection did not find any typical Config paths.
uint16_t GetUid(void) const
Get the internal id of this TypeId.
Definition: type-id.cc:1184
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
#define NS_ABORT_MSG_UNLESS(cond, msg)
Abnormal program termination if a condition is false, with a message.
Definition: abort.h:144
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:206
#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.
#define list