From 7e4d58c204fd031c696f8dcd72eb3d8e0d6d5ed0 Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Tue, 8 Mar 2016 10:45:44 -0800 Subject: [PATCH] traffic-control: Add a traffic control helper to ease the installation of queue discs --- .../helper/queue-disc-container.cc | 73 +++ .../helper/queue-disc-container.h | 171 +++++++ .../helper/traffic-control-helper.cc | 393 +++++++++++++++ .../helper/traffic-control-helper.h | 462 ++++++++++++++++++ src/traffic-control/wscript | 8 +- 5 files changed, 1105 insertions(+), 2 deletions(-) create mode 100644 src/traffic-control/helper/queue-disc-container.cc create mode 100644 src/traffic-control/helper/queue-disc-container.h create mode 100644 src/traffic-control/helper/traffic-control-helper.cc create mode 100644 src/traffic-control/helper/traffic-control-helper.h diff --git a/src/traffic-control/helper/queue-disc-container.cc b/src/traffic-control/helper/queue-disc-container.cc new file mode 100644 index 000000000..69c172fca --- /dev/null +++ b/src/traffic-control/helper/queue-disc-container.cc @@ -0,0 +1,73 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2015 Universita' degli Studi di Napoli Federico II + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Stefano Avallone + */ + +#include "queue-disc-container.h" + +namespace ns3 { + +QueueDiscContainer::QueueDiscContainer () +{ +} + +QueueDiscContainer::QueueDiscContainer (Ptr qDisc) +{ + m_queueDiscs.push_back (qDisc); +} + +QueueDiscContainer::ConstIterator +QueueDiscContainer::Begin (void) const +{ + return m_queueDiscs.begin (); +} + +QueueDiscContainer::ConstIterator +QueueDiscContainer::End (void) const +{ + return m_queueDiscs.end (); +} + +uint32_t +QueueDiscContainer::GetN (void) const +{ + return m_queueDiscs.size (); +} + +Ptr +QueueDiscContainer::Get (uint32_t i) const +{ + return m_queueDiscs[i]; +} + +void +QueueDiscContainer::Add (QueueDiscContainer other) +{ + for (ConstIterator i = other.Begin (); i != other.End (); i++) + { + m_queueDiscs.push_back (*i); + } +} + +void +QueueDiscContainer::Add (Ptr qDisc) +{ + m_queueDiscs.push_back (qDisc); +} + +} // namespace ns3 diff --git a/src/traffic-control/helper/queue-disc-container.h b/src/traffic-control/helper/queue-disc-container.h new file mode 100644 index 000000000..8dfe7d81e --- /dev/null +++ b/src/traffic-control/helper/queue-disc-container.h @@ -0,0 +1,171 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2015 Universita' degli Studi di Napoli Federico II + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Stefano Avallone + */ + +#ifndef QUEUE_DISC_CONTAINER_H +#define QUEUE_DISC_CONTAINER_H + +#include +#include +#include "ns3/queue-disc.h" + +namespace ns3 { + +/** + * \ingroup traffic-control + * + * \brief Holds a vector of ns3::QueueDisc pointers. + * + * Typically ns-3 QueueDiscs are installed on net devices using a traffic control + * helper. The helper Install method takes a NetDeviceContainer which holds + * some number of Ptr. For each of the net devices in the + * NetDeviceContainer the helper will instantiate a queue disc and install + * it to the net device. For each of the queue discs, the helper also + * adds the queue disc into a Container for later use by the caller. + * This is that container used to hold the Ptr which are + * instantiated by the traffic control helper. + */ +class QueueDiscContainer +{ +public: + /// QueueDisc container const iterator + typedef std::vector >::const_iterator ConstIterator; + + /** + * Create an empty QueueDiscContainer. + */ + QueueDiscContainer (); + + /** + * \param qDisc a queue disc to add to the container + * + * Create a QueueDiscContainer with exactly one queue disc that has previously + * been instantiated + */ + QueueDiscContainer (Ptr qDisc); + + /** + * \brief Get a const iterator which refers to the first QueueDisc in the + * container. + * + * QueueDiscs can be retrieved from the container in two ways. First, + * directly by an index into the container, and second, using an iterator. + * This method is used in the iterator method and is typically used in a + * for-loop to run through the QueueDiscs + * + * \code + * QueueDiscContainer::ConstIterator i; + * for (i = container.Begin (); i != container.End (); ++i) + * { + * (*i)->method (); // some QueueDisc method + * } + * \endcode + * + * \returns a const iterator which refers to the first QueueDisc in the container. + */ + ConstIterator Begin (void) const; + + /** + * \brief Get a const iterator which indicates past-the-last QueueDisc in the + * container. + * + * QueueDiscs can be retrieved from the container in two ways. First, + * directly by an index into the container, and second, using an iterator. + * This method is used in the iterator method and is typically used in a + * for-loop to run through the QueueDiscs + * + * \code + * QueueDiscContainer::ConstIterator i; + * for (i = container.Begin (); i != container.End (); ++i) + * { + * (*i)->method (); // some QueueDisc method + * } + * \endcode + * + * \returns a const iterator which indicates an ending condition for a loop. + */ + ConstIterator End (void) const; + + /** + * \brief Get the number of Ptr stored in this container. + * + * QueueDiscs can be retrieved from the container in two ways. First, + * directly by an index into the container, and second, using an iterator. + * This method is used in the direct method and is typically used to + * define an ending condition in a for-loop that runs through the stored + * QueueDiscs + * + * \code + * uint32_t nQueueDiscs = container.GetN (); + * for (uint32_t i = 0 i < nQueueDiscs; ++i) + * { + * Ptr p = container.Get (i) + * i->method (); // some QueueDisc method + * } + * \endcode + * + * \returns the number of Ptr stored in this container. + */ + uint32_t GetN (void) const; + + /** + * \brief Get the Ptr stored in this container at a given + * index. + * + * QueueDiscs can be retrieved from the container in two ways. First, + * directly by an index into the container, and second, using an iterator. + * This method is used in the direct method and is used to retrieve the + * indexed Ptr. + * + * \code + * uint32_t nQueueDiscs = container.GetN (); + * for (uint32_t i = 0 i < nQueueDiscs; ++i) + * { + * Ptr p = container.Get (i) + * i->method (); // some QueueDisc method + * } + * \endcode + * + * \param i the index of the requested queue disc pointer. + * \returns the requested queue disc pointer. + */ + Ptr Get (uint32_t i) const; + + /** + * \brief Append the contents of another QueueDiscContainer to the end of + * this container. + * + * \param other The QueueDiscContainer to append. + */ + void Add (QueueDiscContainer other); + + /** + * \brief Append a single Ptr to this container. + * + * \param qDisc The Ptr to append. + */ + void Add (Ptr qDisc); + +private: + std::vector > m_queueDiscs; //!< QueueDiscs smart pointers +}; + +} // namespace ns3 + +#endif /* QUEUE_DISC_CONTAINER_H */ diff --git a/src/traffic-control/helper/traffic-control-helper.cc b/src/traffic-control/helper/traffic-control-helper.cc new file mode 100644 index 000000000..a1b8ce0b8 --- /dev/null +++ b/src/traffic-control/helper/traffic-control-helper.cc @@ -0,0 +1,393 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2015 Universita' degli Studi di Napoli Federico II + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Stefano Avallone + */ + +#include "ns3/log.h" +#include "ns3/abort.h" +#include "ns3/queue-disc.h" +#include "ns3/uinteger.h" +#include "ns3/pointer.h" +#include "ns3/traffic-control-layer.h" +#include "traffic-control-helper.h" + +namespace ns3 { + +NS_LOG_COMPONENT_DEFINE ("TrafficControlHelper"); + +QueueDiscFactory::QueueDiscFactory (ObjectFactory factory) + : m_queueDiscFactory (factory) +{ +} + +void +QueueDiscFactory::AddInternalQueue (ObjectFactory factory) +{ + m_internalQueuesFactory.push_back (factory); +} + +void +QueueDiscFactory::AddPacketFilter (ObjectFactory factory) +{ + m_packetFiltersFactory.push_back (factory); +} + +uint16_t +QueueDiscFactory::AddQueueDiscClass (ObjectFactory factory) +{ + m_queueDiscClassesFactory.push_back (factory); + return m_queueDiscClassesFactory.size () - 1; +} + +void +QueueDiscFactory::SetChildQueueDisc (uint16_t classId, uint16_t handle) +{ + NS_ABORT_MSG_IF (classId >= m_queueDiscClassesFactory.size (), + "Cannot attach a queue disc to a non existing class"); + m_classIdChildHandleMap[classId] = handle; +} + +Ptr +QueueDiscFactory::CreateQueueDisc (const std::vector > & queueDiscs) +{ + // create the queue disc + Ptr qd = m_queueDiscFactory.Create (); + + // create and add the internal queues + for (std::vector::iterator i = m_internalQueuesFactory.begin (); + i != m_internalQueuesFactory.end (); i++ ) + { + qd->AddInternalQueue (i->Create ()); + } + + // create and add the packet filters + for (std::vector::iterator i = m_packetFiltersFactory.begin (); + i != m_packetFiltersFactory.end (); i++ ) + { + qd->AddPacketFilter (i->Create ()); + } + + // create and add the queue disc classes + for (uint32_t i = 0; i < m_queueDiscClassesFactory.size (); i++) + { + // the class ID is given by the index i of the vector + NS_ABORT_MSG_IF (m_classIdChildHandleMap.find (i) == m_classIdChildHandleMap.end (), + "Cannot create a queue disc class with no attached queue disc"); + + uint16_t handle = m_classIdChildHandleMap[i]; + NS_ABORT_MSG_IF (handle >= queueDiscs.size () || queueDiscs[handle] == 0, + "A queue disc with handle " << handle << " has not been created yet"); + + m_queueDiscClassesFactory[i].Set ("QueueDisc", PointerValue (queueDiscs[handle])); + qd->AddQueueDiscClass (m_queueDiscClassesFactory[i].Create ()); + } + + return qd; +} + + +TrafficControlHelper::TrafficControlHelper () +{ +} + +TrafficControlHelper +TrafficControlHelper::Default (void) +{ + TrafficControlHelper helper; + uint16_t handle = helper.SetRootQueueDisc ("ns3::PfifoFastQueueDisc"); + helper.AddInternalQueues (handle, 3, "ns3::DropTailQueue", "MaxPackets", UintegerValue (1000)); + helper.AddPacketFilter (handle, "ns3::PfifoFastIpv4PacketFilter"); + helper.AddPacketFilter (handle, "ns3::PfifoFastIpv6PacketFilter"); + return helper; +} + +uint16_t +TrafficControlHelper::SetRootQueueDisc (std::string type, + std::string n01, const AttributeValue& v01, + std::string n02, const AttributeValue& v02, + std::string n03, const AttributeValue& v03, + std::string n04, const AttributeValue& v04, + std::string n05, const AttributeValue& v05, + std::string n06, const AttributeValue& v06, + std::string n07, const AttributeValue& v07, + std::string n08, const AttributeValue& v08, + std::string n09, const AttributeValue& v09, + std::string n10, const AttributeValue& v10, + std::string n11, const AttributeValue& v11, + std::string n12, const AttributeValue& v12, + std::string n13, const AttributeValue& v13, + std::string n14, const AttributeValue& v14, + std::string n15, const AttributeValue& v15) +{ + NS_ABORT_MSG_UNLESS (m_queueDiscFactory.empty (), "A root queue disc has been already added to this factory"); + + ObjectFactory factory; + factory.SetTypeId (type); + factory.Set (n01, v01); + factory.Set (n02, v02); + factory.Set (n03, v03); + factory.Set (n04, v04); + factory.Set (n05, v05); + factory.Set (n06, v06); + factory.Set (n07, v07); + factory.Set (n08, v08); + factory.Set (n09, v09); + factory.Set (n10, v10); + factory.Set (n11, v11); + factory.Set (n12, v12); + factory.Set (n13, v13); + factory.Set (n14, v14); + factory.Set (n15, v15); + + m_queueDiscFactory.push_back (QueueDiscFactory (factory)); + return 0; +} + +void +TrafficControlHelper::AddInternalQueues (uint16_t handle, uint16_t count, std::string type, + std::string n01, const AttributeValue& v01, + std::string n02, const AttributeValue& v02, + std::string n03, const AttributeValue& v03, + std::string n04, const AttributeValue& v04, + std::string n05, const AttributeValue& v05, + std::string n06, const AttributeValue& v06, + std::string n07, const AttributeValue& v07, + std::string n08, const AttributeValue& v08) +{ + NS_ABORT_MSG_IF (handle >= m_queueDiscFactory.size (), "A queue disc with handle " + << handle << " does not exist"); + + ObjectFactory factory; + factory.SetTypeId (type); + factory.Set (n01, v01); + factory.Set (n02, v02); + factory.Set (n03, v03); + factory.Set (n04, v04); + factory.Set (n05, v05); + factory.Set (n06, v06); + factory.Set (n07, v07); + factory.Set (n08, v08); + + for (int i = 0; i < count; i++) + { + m_queueDiscFactory[handle].AddInternalQueue (factory); + } +} + +void +TrafficControlHelper::AddPacketFilter (uint16_t handle, std::string type, + std::string n01, const AttributeValue& v01, + std::string n02, const AttributeValue& v02, + std::string n03, const AttributeValue& v03, + std::string n04, const AttributeValue& v04, + std::string n05, const AttributeValue& v05, + std::string n06, const AttributeValue& v06, + std::string n07, const AttributeValue& v07, + std::string n08, const AttributeValue& v08) +{ + NS_ABORT_MSG_IF (handle >= m_queueDiscFactory.size (), "A queue disc with handle " + << handle << " does not exist"); + + ObjectFactory factory; + factory.SetTypeId (type); + factory.Set (n01, v01); + factory.Set (n02, v02); + factory.Set (n03, v03); + factory.Set (n04, v04); + factory.Set (n05, v05); + factory.Set (n06, v06); + factory.Set (n07, v07); + factory.Set (n08, v08); + + m_queueDiscFactory[handle].AddPacketFilter (factory); +} + +TrafficControlHelper::ClassIdList +TrafficControlHelper::AddQueueDiscClasses (uint16_t handle, uint16_t count, std::string type, + std::string n01, const AttributeValue& v01, + std::string n02, const AttributeValue& v02, + std::string n03, const AttributeValue& v03, + std::string n04, const AttributeValue& v04, + std::string n05, const AttributeValue& v05, + std::string n06, const AttributeValue& v06, + std::string n07, const AttributeValue& v07, + std::string n08, const AttributeValue& v08) +{ + NS_ABORT_MSG_IF (handle >= m_queueDiscFactory.size (), "A queue disc with handle " + << handle << " does not exist"); + + ObjectFactory factory; + factory.SetTypeId (type); + factory.Set (n01, v01); + factory.Set (n02, v02); + factory.Set (n03, v03); + factory.Set (n04, v04); + factory.Set (n05, v05); + factory.Set (n06, v06); + factory.Set (n07, v07); + factory.Set (n08, v08); + + ClassIdList list; + uint16_t classId; + + for (int i = 0; i < count; i++) + { + classId = m_queueDiscFactory[handle].AddQueueDiscClass (factory); + list.push_back (classId); + } + return list; +} + +uint16_t +TrafficControlHelper::AddChildQueueDisc (uint16_t handle, uint16_t classId, std::string type, + std::string n01, const AttributeValue& v01, + std::string n02, const AttributeValue& v02, + std::string n03, const AttributeValue& v03, + std::string n04, const AttributeValue& v04, + std::string n05, const AttributeValue& v05, + std::string n06, const AttributeValue& v06, + std::string n07, const AttributeValue& v07, + std::string n08, const AttributeValue& v08, + std::string n09, const AttributeValue& v09, + std::string n10, const AttributeValue& v10, + std::string n11, const AttributeValue& v11, + std::string n12, const AttributeValue& v12, + std::string n13, const AttributeValue& v13, + std::string n14, const AttributeValue& v14, + std::string n15, const AttributeValue& v15) +{ + NS_ABORT_MSG_IF (handle >= m_queueDiscFactory.size (), "A queue disc with handle " + << handle << " does not exist"); + + ObjectFactory factory; + factory.SetTypeId (type); + factory.Set (n01, v01); + factory.Set (n02, v02); + factory.Set (n03, v03); + factory.Set (n04, v04); + factory.Set (n05, v05); + factory.Set (n06, v06); + factory.Set (n07, v07); + factory.Set (n08, v08); + factory.Set (n09, v09); + factory.Set (n10, v10); + factory.Set (n11, v11); + factory.Set (n12, v12); + factory.Set (n13, v13); + factory.Set (n14, v14); + factory.Set (n15, v15); + + uint16_t childHandle = m_queueDiscFactory.size (); + m_queueDiscFactory.push_back (QueueDiscFactory (factory)); + m_queueDiscFactory[handle].SetChildQueueDisc (classId, childHandle); + + return childHandle; +} + +TrafficControlHelper::HandleList +TrafficControlHelper::AddChildQueueDiscs (uint16_t handle, const TrafficControlHelper::ClassIdList &classes, + std::string type, + std::string n01, const AttributeValue& v01, + std::string n02, const AttributeValue& v02, + std::string n03, const AttributeValue& v03, + std::string n04, const AttributeValue& v04, + std::string n05, const AttributeValue& v05, + std::string n06, const AttributeValue& v06, + std::string n07, const AttributeValue& v07, + std::string n08, const AttributeValue& v08, + std::string n09, const AttributeValue& v09, + std::string n10, const AttributeValue& v10, + std::string n11, const AttributeValue& v11, + std::string n12, const AttributeValue& v12, + std::string n13, const AttributeValue& v13, + std::string n14, const AttributeValue& v14, + std::string n15, const AttributeValue& v15) +{ + HandleList list; + for (ClassIdList::const_iterator c = classes.begin (); c != classes.end (); c++) + { + uint16_t childHandle = AddChildQueueDisc (handle, *c, type, n01, v01, n02, v02, n03, v03, + n04, v04, n05, v05, n06, v06, n07, v07, n08, v08, n09, v09, + n10, v10, n11, v11, n12, v12, n13, v13, n14, v14, n15, v15); + list.push_back (childHandle); + } + return list; +} + +QueueDiscContainer +TrafficControlHelper::Install (Ptr d) +{ + QueueDiscContainer container; + + // A TrafficControlLayer object is aggregated by the InternetStackHelper, but check + // anyway because a queue disc has no effect without a TrafficControlLayer object + Ptr tc = d->GetNode ()->GetObject (); + NS_ASSERT (tc != 0); + + // Start from an empty vector of queue discs + m_queueDiscs.clear (); + m_queueDiscs.resize (m_queueDiscFactory.size ()); + + // Create queue discs (from leaves to root) + for (int i = m_queueDiscFactory.size () - 1; i >= 0; i--) + { + Ptr q = m_queueDiscFactory[i].CreateQueueDisc (m_queueDiscs); + q->SetNetDevice (d); + m_queueDiscs[i] = q; + container.Add (q); + } + + // Set the root queue disc on the device + tc->SetRootQueueDiscOnDevice (d, m_queueDiscs[0]); + + return container; +} + +QueueDiscContainer +TrafficControlHelper::Install (NetDeviceContainer c) +{ + QueueDiscContainer container; + + for (NetDeviceContainer::Iterator i = c.Begin (); i != c.End (); ++i) + { + container.Add (Install (*i)); + } + + return container; +} + +void +TrafficControlHelper::Uninstall (Ptr d) +{ + Ptr tc = d->GetNode ()->GetObject (); + NS_ASSERT (tc != 0); + + tc->DeleteRootQueueDiscOnDevice (d); +} + +void +TrafficControlHelper::Uninstall (NetDeviceContainer c) +{ + for (NetDeviceContainer::Iterator i = c.Begin (); i != c.End (); ++i) + { + Uninstall (*i); + } +} + + +} // namespace ns3 diff --git a/src/traffic-control/helper/traffic-control-helper.h b/src/traffic-control/helper/traffic-control-helper.h new file mode 100644 index 000000000..761463aa3 --- /dev/null +++ b/src/traffic-control/helper/traffic-control-helper.h @@ -0,0 +1,462 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2015 Universita' degli Studi di Napoli Federico II + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Stefano Avallone + */ +#ifndef TRAFFIC_CONTROL_HELPER_H +#define TRAFFIC_CONTROL_HELPER_H + +#include +#include +#include +#include "ns3/object-factory.h" +#include "ns3/net-device-container.h" +#include "ns3/queue-disc-container.h" + +namespace ns3 { + +class QueueDisc; + +/** + * \ingroup traffic-control + * + * This class stores object factories required to create a queue disc and all of + * its components (packet filters, internal queues, classes). + */ +class QueueDiscFactory +{ +public: + /** + * \brief Constructor + * + * \param factory the factory used to create this queue disc + */ + QueueDiscFactory (ObjectFactory factory); + + virtual ~QueueDiscFactory () {} + + /** + * \brief Add a factory to create an internal queue + * + * \param factory the factory used to create an internal queue + */ + void AddInternalQueue (ObjectFactory factory); + + /** + * \brief Add a factory to create a packet filter + * + * \param factory the factory used to create a packet filter + */ + void AddPacketFilter (ObjectFactory factory); + + /** + * \brief Add a factory to create a queue disc class + * + * \param factory the factory used to create a queue disc class + * \return the class ID of the created queue disc class + */ + uint16_t AddQueueDiscClass (ObjectFactory factory); + + /** + * \brief Set the (child) queue disc to attach to a class + * + * \param classId the id of the class to attach a child queue disc to + * \param handle the handle of the child queue disc to attach to the class + */ + void SetChildQueueDisc (uint16_t classId, uint16_t handle); + + /** + * \brief Create a queue disc with the currently stored configuration. + * + * \param queueDiscs the vector of queue discs held by the helper + * \return the created queue disc + */ + Ptr CreateQueueDisc (const std::vector > & queueDiscs); + +private: + /** + * \brief Default constructor + * + * Defined and unimplemented to avoid misuse + */ + QueueDiscFactory (); + + /// Factory to create this queue disc + ObjectFactory m_queueDiscFactory; + /// Vector of factories to create internal queues + std::vector m_internalQueuesFactory; + /// Vector of factories to create packet filters + std::vector m_packetFiltersFactory; + /// Vector of factories to create queue disc classes + std::vector m_queueDiscClassesFactory; + /// Map storing the associations between class IDs and child queue disc handles + std::map m_classIdChildHandleMap; +}; + + +/** + * \ingroup traffic-control + * + * \brief Build a set of QueueDisc objects + * + * This class can help to create QueueDisc objects and map them to + * the corresponding devices. This map is stored at the Traffic Control + * layer. + */ +class TrafficControlHelper +{ +public: + /** + * Create a TrafficControlHelper to make life easier when creating QueueDisc + * objects. + */ + TrafficControlHelper (); + virtual ~TrafficControlHelper () {} + + /** + * \returns a new TrafficControlHelper with a default configuration + * + * The default configuration is a PfifoFastQueueDisc with three internal queues + * of type DropTailQueue and size 1000 packets, and a PfifoFastIpv4PacketFilter. + */ + static TrafficControlHelper Default (void); + + /** + * Helper function used to set a root queue disc of the given type and with the + * given attributes. To set the InternalQueueList, PacketFilterList and ChildQueueDiscList + * attributes, use the AddInternalQueue, AddPacketFilter and AddChildQueueDisc methods. + * + * \param type the type of queue disc + * \param n01 the name of the attribute to set on the queue disc + * \param v01 the value of the attribute to set on the queue disc + * \param n02 the name of the attribute to set on the queue disc + * \param v02 the value of the attribute to set on the queue disc + * \param n03 the name of the attribute to set on the queue disc + * \param v03 the value of the attribute to set on the queue disc + * \param n04 the name of the attribute to set on the queue disc + * \param v04 the value of the attribute to set on the queue disc + * \param n05 the name of the attribute to set on the queue disc + * \param v05 the value of the attribute to set on the queue disc + * \param n06 the name of the attribute to set on the queue disc + * \param v06 the value of the attribute to set on the queue disc + * \param n07 the name of the attribute to set on the queue disc + * \param v07 the value of the attribute to set on the queue disc + * \param n08 the name of the attribute to set on the queue disc + * \param v08 the value of the attribute to set on the queue disc + * \param n09 the name of the attribute to set on the queue disc + * \param v09 the value of the attribute to set on the queue disc + * \param n10 the name of the attribute to set on the queue disc + * \param v10 the value of the attribute to set on the queue disc + * \param n11 the name of the attribute to set on the queue disc + * \param v11 the value of the attribute to set on the queue disc + * \param n12 the name of the attribute to set on the queue disc + * \param v12 the value of the attribute to set on the queue disc + * \param n13 the name of the attribute to set on the queue disc + * \param v13 the value of the attribute to set on the queue disc + * \param n14 the name of the attribute to set on the queue disc + * \param v14 the value of the attribute to set on the queue disc + * \param n15 the name of the attribute to set on the queue disc + * \param v15 the value of the attribute to set on the queue disc + * \return the handle of the root queue disc (zero) + */ + uint16_t SetRootQueueDisc (std::string type, + std::string n01 = "", const AttributeValue &v01 = EmptyAttributeValue (), + std::string n02 = "", const AttributeValue &v02 = EmptyAttributeValue (), + std::string n03 = "", const AttributeValue &v03 = EmptyAttributeValue (), + std::string n04 = "", const AttributeValue &v04 = EmptyAttributeValue (), + std::string n05 = "", const AttributeValue &v05 = EmptyAttributeValue (), + std::string n06 = "", const AttributeValue &v06 = EmptyAttributeValue (), + std::string n07 = "", const AttributeValue &v07 = EmptyAttributeValue (), + std::string n08 = "", const AttributeValue &v08 = EmptyAttributeValue (), + std::string n09 = "", const AttributeValue &v09 = EmptyAttributeValue (), + std::string n10 = "", const AttributeValue &v10 = EmptyAttributeValue (), + std::string n11 = "", const AttributeValue &v11 = EmptyAttributeValue (), + std::string n12 = "", const AttributeValue &v12 = EmptyAttributeValue (), + std::string n13 = "", const AttributeValue &v13 = EmptyAttributeValue (), + std::string n14 = "", const AttributeValue &v14 = EmptyAttributeValue (), + std::string n15 = "", const AttributeValue &v15 = EmptyAttributeValue ()); + + /** + * Helper function used to add the given number of internal queues (of the given + * type and with the given attributes) to the queue disc having the given handle. + * + * \param handle the handle of the parent queue disc + * \param count the number of queues to add + * \param type the type of queue + * \param n01 the name of the attribute to set on the queue + * \param v01 the value of the attribute to set on the queue + * \param n02 the name of the attribute to set on the queue + * \param v02 the value of the attribute to set on the queue + * \param n03 the name of the attribute to set on the queue + * \param v03 the value of the attribute to set on the queue + * \param n04 the name of the attribute to set on the queue + * \param v04 the value of the attribute to set on the queue + * \param n05 the name of the attribute to set on the queue + * \param v05 the value of the attribute to set on the queue + * \param n06 the name of the attribute to set on the queue + * \param v06 the value of the attribute to set on the queue + * \param n07 the name of the attribute to set on the queue + * \param v07 the value of the attribute to set on the queue + * \param n08 the name of the attribute to set on the queue + * \param v08 the value of the attribute to set on the queue + */ + void AddInternalQueues (uint16_t handle, uint16_t count, std::string type, + std::string n01 = "", const AttributeValue &v01 = EmptyAttributeValue (), + std::string n02 = "", const AttributeValue &v02 = EmptyAttributeValue (), + std::string n03 = "", const AttributeValue &v03 = EmptyAttributeValue (), + std::string n04 = "", const AttributeValue &v04 = EmptyAttributeValue (), + std::string n05 = "", const AttributeValue &v05 = EmptyAttributeValue (), + std::string n06 = "", const AttributeValue &v06 = EmptyAttributeValue (), + std::string n07 = "", const AttributeValue &v07 = EmptyAttributeValue (), + std::string n08 = "", const AttributeValue &v08 = EmptyAttributeValue ()); + + /** + * Helper function used to add a packet filter (of the given type and with + * the given attributes) to the queue disc having the given handle. + * + * \param handle the handle of the parent queue disc + * \param type the type of packet filter + * \param n01 the name of the attribute to set on the packet filter + * \param v01 the value of the attribute to set on the packet filter + * \param n02 the name of the attribute to set on the packet filter + * \param v02 the value of the attribute to set on the packet filter + * \param n03 the name of the attribute to set on the packet filter + * \param v03 the value of the attribute to set on the packet filter + * \param n04 the name of the attribute to set on the packet filter + * \param v04 the value of the attribute to set on the packet filter + * \param n05 the name of the attribute to set on the packet filter + * \param v05 the value of the attribute to set on the packet filter + * \param n06 the name of the attribute to set on the packet filter + * \param v06 the value of the attribute to set on the packet filter + * \param n07 the name of the attribute to set on the packet filter + * \param v07 the value of the attribute to set on the packet filter + * \param n08 the name of the attribute to set on the packet filter + * \param v08 the value of the attribute to set on the packet filter + */ + void AddPacketFilter (uint16_t handle, std::string type, + std::string n01 = "", const AttributeValue &v01 = EmptyAttributeValue (), + std::string n02 = "", const AttributeValue &v02 = EmptyAttributeValue (), + std::string n03 = "", const AttributeValue &v03 = EmptyAttributeValue (), + std::string n04 = "", const AttributeValue &v04 = EmptyAttributeValue (), + std::string n05 = "", const AttributeValue &v05 = EmptyAttributeValue (), + std::string n06 = "", const AttributeValue &v06 = EmptyAttributeValue (), + std::string n07 = "", const AttributeValue &v07 = EmptyAttributeValue (), + std::string n08 = "", const AttributeValue &v08 = EmptyAttributeValue ()); + + typedef std::vector ClassIdList; + + /** + * Helper function used to add the given number of queue disc classes (of the given + * type and with the given attributes) to the queue disc having the given handle. + * + * \param handle the handle of the parent queue disc + * \param count the number of queue disc classes to add + * \param type the type of queue disc class + * \param n01 the name of the attribute to set on the queue disc class + * \param v01 the value of the attribute to set on the queue disc class + * \param n02 the name of the attribute to set on the queue disc class + * \param v02 the value of the attribute to set on the queue disc class + * \param n03 the name of the attribute to set on the queue disc class + * \param v03 the value of the attribute to set on the queue disc class + * \param n04 the name of the attribute to set on the queue disc class + * \param v04 the value of the attribute to set on the queue disc class + * \param n05 the name of the attribute to set on the queue disc class + * \param v05 the value of the attribute to set on the queue disc class + * \param n06 the name of the attribute to set on the queue disc class + * \param v06 the value of the attribute to set on the queue disc class + * \param n07 the name of the attribute to set on the queue disc class + * \param v07 the value of the attribute to set on the queue disc class + * \param n08 the name of the attribute to set on the queue disc class + * \param v08 the value of the attribute to set on the queue disc class + * \return the list of class IDs + */ + ClassIdList AddQueueDiscClasses (uint16_t handle, uint16_t count, std::string type, + std::string n01 = "", const AttributeValue &v01 = EmptyAttributeValue (), + std::string n02 = "", const AttributeValue &v02 = EmptyAttributeValue (), + std::string n03 = "", const AttributeValue &v03 = EmptyAttributeValue (), + std::string n04 = "", const AttributeValue &v04 = EmptyAttributeValue (), + std::string n05 = "", const AttributeValue &v05 = EmptyAttributeValue (), + std::string n06 = "", const AttributeValue &v06 = EmptyAttributeValue (), + std::string n07 = "", const AttributeValue &v07 = EmptyAttributeValue (), + std::string n08 = "", const AttributeValue &v08 = EmptyAttributeValue ()); + + /** + * Helper function used to attach a child queue disc (of the given type and with + * the given attributes) to a given class (included in the queue disc + * having the given handle). + * + * \param handle the handle of the parent queue disc + * \param classId the class ID of the class to attach the queue disc to + * \param type the type of queue disc + * \param n01 the name of the attribute to set on the queue disc + * \param v01 the value of the attribute to set on the queue disc + * \param n02 the name of the attribute to set on the queue disc + * \param v02 the value of the attribute to set on the queue disc + * \param n03 the name of the attribute to set on the queue disc + * \param v03 the value of the attribute to set on the queue disc + * \param n04 the name of the attribute to set on the queue disc + * \param v04 the value of the attribute to set on the queue disc + * \param n05 the name of the attribute to set on the queue disc + * \param v05 the value of the attribute to set on the queue disc + * \param n06 the name of the attribute to set on the queue disc + * \param v06 the value of the attribute to set on the queue disc + * \param n07 the name of the attribute to set on the queue disc + * \param v07 the value of the attribute to set on the queue disc + * \param n08 the name of the attribute to set on the queue disc + * \param v08 the value of the attribute to set on the queue disc + * \param n09 the name of the attribute to set on the queue disc + * \param v09 the value of the attribute to set on the queue disc + * \param n10 the name of the attribute to set on the queue disc + * \param v10 the value of the attribute to set on the queue disc + * \param n11 the name of the attribute to set on the queue disc + * \param v11 the value of the attribute to set on the queue disc + * \param n12 the name of the attribute to set on the queue disc + * \param v12 the value of the attribute to set on the queue disc + * \param n13 the name of the attribute to set on the queue disc + * \param v13 the value of the attribute to set on the queue disc + * \param n14 the name of the attribute to set on the queue disc + * \param v14 the value of the attribute to set on the queue disc + * \param n15 the name of the attribute to set on the queue disc + * \param v15 the value of the attribute to set on the queue disc + * \return the handle of the created child queue disc + */ + uint16_t AddChildQueueDisc (uint16_t handle, uint16_t classId, std::string type, + std::string n01 = "", const AttributeValue &v01 = EmptyAttributeValue (), + std::string n02 = "", const AttributeValue &v02 = EmptyAttributeValue (), + std::string n03 = "", const AttributeValue &v03 = EmptyAttributeValue (), + std::string n04 = "", const AttributeValue &v04 = EmptyAttributeValue (), + std::string n05 = "", const AttributeValue &v05 = EmptyAttributeValue (), + std::string n06 = "", const AttributeValue &v06 = EmptyAttributeValue (), + std::string n07 = "", const AttributeValue &v07 = EmptyAttributeValue (), + std::string n08 = "", const AttributeValue &v08 = EmptyAttributeValue (), + std::string n09 = "", const AttributeValue &v09 = EmptyAttributeValue (), + std::string n10 = "", const AttributeValue &v10 = EmptyAttributeValue (), + std::string n11 = "", const AttributeValue &v11 = EmptyAttributeValue (), + std::string n12 = "", const AttributeValue &v12 = EmptyAttributeValue (), + std::string n13 = "", const AttributeValue &v13 = EmptyAttributeValue (), + std::string n14 = "", const AttributeValue &v14 = EmptyAttributeValue (), + std::string n15 = "", const AttributeValue &v15 = EmptyAttributeValue ()); + + typedef std::vector HandleList; + + /** + * Helper function used to attach a child queue disc (of the given type and with + * the given attributes) to each of the given classes (included in the queue disc + * having the given handle). + * + * \param handle the handle of the parent queue disc + * \param classes the class IDs of the classes to attach a queue disc to + * \param type the type of queue disc + * \param n01 the name of the attribute to set on the queue disc + * \param v01 the value of the attribute to set on the queue disc + * \param n02 the name of the attribute to set on the queue disc + * \param v02 the value of the attribute to set on the queue disc + * \param n03 the name of the attribute to set on the queue disc + * \param v03 the value of the attribute to set on the queue disc + * \param n04 the name of the attribute to set on the queue disc + * \param v04 the value of the attribute to set on the queue disc + * \param n05 the name of the attribute to set on the queue disc + * \param v05 the value of the attribute to set on the queue disc + * \param n06 the name of the attribute to set on the queue disc + * \param v06 the value of the attribute to set on the queue disc + * \param n07 the name of the attribute to set on the queue disc + * \param v07 the value of the attribute to set on the queue disc + * \param n08 the name of the attribute to set on the queue disc + * \param v08 the value of the attribute to set on the queue disc + * \param n09 the name of the attribute to set on the queue disc + * \param v09 the value of the attribute to set on the queue disc + * \param n10 the name of the attribute to set on the queue disc + * \param v10 the value of the attribute to set on the queue disc + * \param n11 the name of the attribute to set on the queue disc + * \param v11 the value of the attribute to set on the queue disc + * \param n12 the name of the attribute to set on the queue disc + * \param v12 the value of the attribute to set on the queue disc + * \param n13 the name of the attribute to set on the queue disc + * \param v13 the value of the attribute to set on the queue disc + * \param n14 the name of the attribute to set on the queue disc + * \param v14 the value of the attribute to set on the queue disc + * \param n15 the name of the attribute to set on the queue disc + * \param v15 the value of the attribute to set on the queue disc + * \return the list of handles of the created child queue discs + */ + HandleList AddChildQueueDiscs (uint16_t handle, const ClassIdList &classes, std::string type, + std::string n01 = "", const AttributeValue &v01 = EmptyAttributeValue (), + std::string n02 = "", const AttributeValue &v02 = EmptyAttributeValue (), + std::string n03 = "", const AttributeValue &v03 = EmptyAttributeValue (), + std::string n04 = "", const AttributeValue &v04 = EmptyAttributeValue (), + std::string n05 = "", const AttributeValue &v05 = EmptyAttributeValue (), + std::string n06 = "", const AttributeValue &v06 = EmptyAttributeValue (), + std::string n07 = "", const AttributeValue &v07 = EmptyAttributeValue (), + std::string n08 = "", const AttributeValue &v08 = EmptyAttributeValue (), + std::string n09 = "", const AttributeValue &v09 = EmptyAttributeValue (), + std::string n10 = "", const AttributeValue &v10 = EmptyAttributeValue (), + std::string n11 = "", const AttributeValue &v11 = EmptyAttributeValue (), + std::string n12 = "", const AttributeValue &v12 = EmptyAttributeValue (), + std::string n13 = "", const AttributeValue &v13 = EmptyAttributeValue (), + std::string n14 = "", const AttributeValue &v14 = EmptyAttributeValue (), + std::string n15 = "", const AttributeValue &v15 = EmptyAttributeValue ()); + + /** + * \param c set of devices + * \returns a QueueDisc container with the queue discs installed on the devices + * + * This method creates a QueueDisc object of the type and with the + * attributes configured by TrafficControlHelper::SetQueueDisc for + * each device in the container. Then, stores the mapping between a + * device and the associated queue disc into the traffic control layer + * of the corresponding node. + */ + QueueDiscContainer Install (NetDeviceContainer c); + + /** + * \param d device + * \returns a QueueDisc container with the queue disc installed on the device + * + * This method creates a QueueDisc object of the type and with the + * attributes configured by TrafficControlHelper::SetQueueDisc for + * the given device. Then, stores the mapping between the device + * and the associated queue disc into the traffic control layer + * of the corresponding node. + */ + QueueDiscContainer Install (Ptr d); + + /** + * \param c set of devices + * + * This method removes the root queue discs (and associated filters, classes + * and queues) installed on the given devices. + */ + void Uninstall (NetDeviceContainer c); + + /** + * \param d device + * + * This method removes the root queue disc (and associated filters, classes + * and queues) installed on the given device. + */ + void Uninstall (Ptr d); + +private: + /// QueueDisc factory, stores the configuration of all the queue discs + std::vector m_queueDiscFactory; + /// Vector of all the created queue discs + std::vector > m_queueDiscs; +}; + +} // namespace ns3 + +#endif /* TRAFFIC_CONTROL_HELPER_H */ diff --git a/src/traffic-control/wscript b/src/traffic-control/wscript index 49c25fb6a..6d4e8d9cf 100644 --- a/src/traffic-control/wscript +++ b/src/traffic-control/wscript @@ -12,7 +12,9 @@ def build(bld): 'model/traffic-control-layer.cc', 'model/packet-filter.cc', 'model/queue-disc.cc', - 'model/pfifo-fast-queue-disc.cc' + 'model/pfifo-fast-queue-disc.cc', + 'helper/traffic-control-helper.cc', + 'helper/queue-disc-container.cc' ] module_test = bld.create_ns3_module_test_library('traffic-control') @@ -25,7 +27,9 @@ def build(bld): 'model/traffic-control-layer.h', 'model/packet-filter.h', 'model/queue-disc.h', - 'model/pfifo-fast-queue-disc.h' + 'model/pfifo-fast-queue-disc.h', + 'helper/traffic-control-helper.h', + 'helper/queue-disc-container.h' ] if bld.env.ENABLE_EXAMPLES: