diff --git a/CHANGES.html b/CHANGES.html
index d17e894d5..18716badd 100644
--- a/CHANGES.html
+++ b/CHANGES.html
@@ -54,7 +54,7 @@ us a note on ns-developers mailing list.
Changes from ns-3.35 to ns-3.36
New API:
-
+- The helpers of the NetDevices supporting flow control (PointToPointHelper, CsmaHelper, SimpleNetDeviceHelper, WifiHelper) now provide a DisableFlowControl method to disable flow control. If flow control is disabled, the Traffic Control layer forwards packets down to the NetDevice even if there is no room for them in the NetDevice queue(s)
Changes to existing API:
diff --git a/src/csma/helper/csma-helper.cc b/src/csma/helper/csma-helper.cc
index ee776651d..0dfad96d5 100644
--- a/src/csma/helper/csma-helper.cc
+++ b/src/csma/helper/csma-helper.cc
@@ -44,6 +44,7 @@ CsmaHelper::CsmaHelper ()
m_queueFactory.SetTypeId ("ns3::DropTailQueue");
m_deviceFactory.SetTypeId ("ns3::CsmaNetDevice");
m_channelFactory.SetTypeId ("ns3::CsmaChannel");
+ m_enableFlowControl = true;
}
void
@@ -74,6 +75,12 @@ CsmaHelper::SetChannelAttribute (std::string n1, const AttributeValue &v1)
m_channelFactory.Set (n1, v1);
}
+void
+CsmaHelper::DisableFlowControl (void)
+{
+ m_enableFlowControl = false;
+}
+
void
CsmaHelper::EnablePcapInternal (std::string prefix, Ptr nd, bool promiscuous, bool explicitFilename)
{
@@ -310,11 +317,13 @@ CsmaHelper::InstallPriv (Ptr node, Ptr channel) const
Ptr > queue = m_queueFactory.Create > ();
device->SetQueue (queue);
device->Attach (channel);
- // Aggregate a NetDeviceQueueInterface object
- Ptr ndqi = CreateObject ();
- ndqi->GetTxQueue (0)->ConnectQueueTraces (queue);
- device->AggregateObject (ndqi);
-
+ if (m_enableFlowControl)
+ {
+ // Aggregate a NetDeviceQueueInterface object
+ Ptr ndqi = CreateObject ();
+ ndqi->GetTxQueue (0)->ConnectQueueTraces (queue);
+ device->AggregateObject (ndqi);
+ }
return device;
}
diff --git a/src/csma/helper/csma-helper.h b/src/csma/helper/csma-helper.h
index 42c8b5cc1..08b1f5a6a 100644
--- a/src/csma/helper/csma-helper.h
+++ b/src/csma/helper/csma-helper.h
@@ -90,6 +90,16 @@ public:
*/
void SetChannelAttribute (std::string n1, const AttributeValue &v1);
+ /**
+ * Disable flow control only if you know what you are doing. By disabling
+ * flow control, this NetDevice will be sent packets even if there is no
+ * room for them (such packets will be likely dropped by this NetDevice).
+ * Also, any queue disc installed on this NetDevice will have no effect,
+ * as every packet enqueued to the traffic control layer queue disc will
+ * be immediately dequeued.
+ */
+ void DisableFlowControl (void);
+
/**
* This method creates an ns3::CsmaChannel with the attributes configured by
* CsmaHelper::SetChannelAttribute, an ns3::CsmaNetDevice with the attributes
@@ -250,6 +260,7 @@ private:
ObjectFactory m_queueFactory; //!< factory for the queues
ObjectFactory m_deviceFactory; //!< factory for the NetDevices
ObjectFactory m_channelFactory; //!< factory for the channel
+ bool m_enableFlowControl; //!< whether to enable flow control
};
} // namespace ns3
diff --git a/src/network/helper/simple-net-device-helper.cc b/src/network/helper/simple-net-device-helper.cc
index 80c43963c..4570968c4 100644
--- a/src/network/helper/simple-net-device-helper.cc
+++ b/src/network/helper/simple-net-device-helper.cc
@@ -46,6 +46,7 @@ SimpleNetDeviceHelper::SimpleNetDeviceHelper ()
m_deviceFactory.SetTypeId ("ns3::SimpleNetDevice");
m_channelFactory.SetTypeId ("ns3::SimpleChannel");
m_pointToPointMode = false;
+ m_enableFlowControl = true;
}
void
@@ -96,6 +97,12 @@ SimpleNetDeviceHelper::SetNetDevicePointToPointMode (bool pointToPointMode)
m_pointToPointMode = pointToPointMode;
}
+void
+SimpleNetDeviceHelper::DisableFlowControl (void)
+{
+ m_enableFlowControl = false;
+}
+
NetDeviceContainer
SimpleNetDeviceHelper::Install (Ptr node) const
{
@@ -141,10 +148,13 @@ SimpleNetDeviceHelper::InstallPriv (Ptr node, Ptr channel)
Ptr > queue = m_queueFactory.Create > ();
device->SetQueue (queue);
NS_ASSERT_MSG (!m_pointToPointMode || (channel->GetNDevices () <= 2), "Device set to PointToPoint and more than 2 devices on the channel.");
- // Aggregate a NetDeviceQueueInterface object
- Ptr ndqi = CreateObject ();
- ndqi->GetTxQueue (0)->ConnectQueueTraces (queue);
- device->AggregateObject (ndqi);
+ if (m_enableFlowControl)
+ {
+ // Aggregate a NetDeviceQueueInterface object
+ Ptr ndqi = CreateObject ();
+ ndqi->GetTxQueue (0)->ConnectQueueTraces (queue);
+ device->AggregateObject (ndqi);
+ }
return device;
}
diff --git a/src/network/helper/simple-net-device-helper.h b/src/network/helper/simple-net-device-helper.h
index a524d55ef..5522a95b9 100644
--- a/src/network/helper/simple-net-device-helper.h
+++ b/src/network/helper/simple-net-device-helper.h
@@ -120,6 +120,16 @@ public:
*/
void SetNetDevicePointToPointMode (bool pointToPointMode);
+ /**
+ * Disable flow control only if you know what you are doing. By disabling
+ * flow control, this NetDevice will be sent packets even if there is no
+ * room for them (such packets will be likely dropped by this NetDevice).
+ * Also, any queue disc installed on this NetDevice will have no effect,
+ * as every packet enqueued to the traffic control layer queue disc will
+ * be immediately dequeued.
+ */
+ void DisableFlowControl (void);
+
/**
* This method creates an ns3::SimpleChannel with the attributes configured by
* SimpleNetDeviceHelper::SetChannelAttribute, an ns3::SimpleNetDevice with the attributes
@@ -182,7 +192,7 @@ private:
ObjectFactory m_deviceFactory; //!< NetDevice factory
ObjectFactory m_channelFactory; //!< Channel factory
bool m_pointToPointMode; //!< Install PointToPoint SimpleNetDevice or Broadcast ones
-
+ bool m_enableFlowControl; //!< whether to enable flow control
};
} // namespace ns3
diff --git a/src/point-to-point/helper/point-to-point-helper.cc b/src/point-to-point/helper/point-to-point-helper.cc
index 9b5c3df8a..cbc6c034c 100644
--- a/src/point-to-point/helper/point-to-point-helper.cc
+++ b/src/point-to-point/helper/point-to-point-helper.cc
@@ -47,6 +47,7 @@ PointToPointHelper::PointToPointHelper ()
m_queueFactory.SetTypeId ("ns3::DropTailQueue");
m_deviceFactory.SetTypeId ("ns3::PointToPointNetDevice");
m_channelFactory.SetTypeId ("ns3::PointToPointChannel");
+ m_enableFlowControl = true;
}
void
@@ -77,6 +78,12 @@ PointToPointHelper::SetChannelAttribute (std::string n1, const AttributeValue &v
m_channelFactory.Set (n1, v1);
}
+void
+PointToPointHelper::DisableFlowControl (void)
+{
+ m_enableFlowControl = false;
+}
+
void
PointToPointHelper::EnablePcapInternal (std::string prefix, Ptr nd, bool promiscuous, bool explicitFilename)
{
@@ -240,13 +247,16 @@ PointToPointHelper::Install (Ptr a, Ptr b)
b->AddDevice (devB);
Ptr > queueB = m_queueFactory.Create > ();
devB->SetQueue (queueB);
- // Aggregate NetDeviceQueueInterface objects
- Ptr ndqiA = CreateObject ();
- ndqiA->GetTxQueue (0)->ConnectQueueTraces (queueA);
- devA->AggregateObject (ndqiA);
- Ptr ndqiB = CreateObject ();
- ndqiB->GetTxQueue (0)->ConnectQueueTraces (queueB);
- devB->AggregateObject (ndqiB);
+ if (m_enableFlowControl)
+ {
+ // Aggregate NetDeviceQueueInterface objects
+ Ptr ndqiA = CreateObject ();
+ ndqiA->GetTxQueue (0)->ConnectQueueTraces (queueA);
+ devA->AggregateObject (ndqiA);
+ Ptr ndqiB = CreateObject ();
+ ndqiB->GetTxQueue (0)->ConnectQueueTraces (queueB);
+ devB->AggregateObject (ndqiB);
+ }
Ptr channel = 0;
diff --git a/src/point-to-point/helper/point-to-point-helper.h b/src/point-to-point/helper/point-to-point-helper.h
index 052081327..2f287999b 100644
--- a/src/point-to-point/helper/point-to-point-helper.h
+++ b/src/point-to-point/helper/point-to-point-helper.h
@@ -99,6 +99,16 @@ public:
*/
void SetChannelAttribute (std::string name, const AttributeValue &value);
+ /**
+ * Disable flow control only if you know what you are doing. By disabling
+ * flow control, this NetDevice will be sent packets even if there is no
+ * room for them (such packets will be likely dropped by this NetDevice).
+ * Also, any queue disc installed on this NetDevice will have no effect,
+ * as every packet enqueued to the traffic control layer queue disc will
+ * be immediately dequeued.
+ */
+ void DisableFlowControl (void);
+
/**
* \param c a set of nodes
* \return a NetDeviceContainer for nodes
@@ -184,6 +194,7 @@ private:
ObjectFactory m_queueFactory; //!< Queue Factory
ObjectFactory m_channelFactory; //!< Channel Factory
ObjectFactory m_deviceFactory; //!< Device Factory
+ bool m_enableFlowControl; //!< whether to enable flow control
};
} // namespace ns3
diff --git a/src/traffic-control/doc/queue-discs.rst b/src/traffic-control/doc/queue-discs.rst
index d54d5edd9..ab2f76af7 100644
--- a/src/traffic-control/doc/queue-discs.rst
+++ b/src/traffic-control/doc/queue-discs.rst
@@ -187,6 +187,20 @@ Uninstall method of the TrafficControlHelper C++ class, and then installing a di
queue disc on the device. By uninstalling without adding a new queue disc, it is also possible
to have no queue disc installed on a device.
+Note that if no queue disc is installed on an underlying device, the traffic
+control layer will still respect flow control signals provided by the device, if
+any. Specifically, if no queue disc is installed on a device, and the device is
+stopped, then any packet for that device will be dropped in the traffic control
+layer, and the device's drop trace will not record the drop -- instead, the TcDrop
+drop trace in the traffic control layer will record the drop.
+
+Flow control can be disabled for the devices that support it by using the
+``DisableFlowControl`` method of their helpers. If there is no queue disc
+installed on the device, and the device is not performing flow control, then
+packets will immediately transit the traffic control layer and be sent to the
+device, regardless or not of whether the device's internal queue can accept it,
+and the traffic control layer's TcDrop trace will not be called.
+
Helpers
=======
diff --git a/src/traffic-control/helper/traffic-control-helper.h b/src/traffic-control/helper/traffic-control-helper.h
index 78cd17a38..621c78182 100644
--- a/src/traffic-control/helper/traffic-control-helper.h
+++ b/src/traffic-control/helper/traffic-control-helper.h
@@ -273,6 +273,12 @@ public:
*
* This method removes the root queue discs (and associated filters, classes
* and queues) installed on the given devices.
+ * Note that the traffic control layer will continue to perform flow control
+ * if the device has an aggregated NetDeviceQueueInterface. If you really
+ * want that the Traffic Control layer forwards packets down to the NetDevice
+ * even if there is no room for them in the NetDevice queue(s), then disable
+ * the flow control by using the DisableFlowControl method of the NetDevice
+ * helper.
*/
void Uninstall (NetDeviceContainer c);
@@ -281,6 +287,12 @@ public:
*
* This method removes the root queue disc (and associated filters, classes
* and queues) installed on the given device.
+ * Note that the traffic control layer will continue to perform flow control
+ * if the device has an aggregated NetDeviceQueueInterface. If you really
+ * want that the Traffic Control layer forwards packets down to the NetDevice
+ * even if there is no room for them in the NetDevice queue(s), then disable
+ * the flow control by using the DisableFlowControl method of the NetDevice
+ * helper.
*/
void Uninstall (Ptr d);
diff --git a/src/wifi/helper/wifi-helper.cc b/src/wifi/helper/wifi-helper.cc
index b56e9e341..0bf36a7df 100644
--- a/src/wifi/helper/wifi-helper.cc
+++ b/src/wifi/helper/wifi-helper.cc
@@ -712,7 +712,8 @@ WifiHelper::~WifiHelper ()
WifiHelper::WifiHelper ()
: m_standard (WIFI_STANDARD_80211a),
- m_selectQueueCallback (&SelectQueueByDSField)
+ m_selectQueueCallback (&SelectQueueByDSField),
+ m_enableFlowControl (true)
{
SetRemoteStationManager ("ns3::ArfWifiManager");
}
@@ -769,6 +770,12 @@ WifiHelper::SetStandard (WifiStandard standard)
m_standard = standard;
}
+void
+WifiHelper::DisableFlowControl (void)
+{
+ m_enableFlowControl = false;
+}
+
void
WifiHelper::SetSelectQueueCallback (SelectQueueCallback f)
{
@@ -825,7 +832,7 @@ WifiHelper::Install (const WifiPhyHelper &phyHelper,
NS_LOG_DEBUG ("node=" << node << ", mob=" << node->GetObject ());
// Aggregate a NetDeviceQueueInterface object if a RegularWifiMac is installed
Ptr rmac = DynamicCast (mac);
- if (rmac)
+ if (rmac && m_enableFlowControl)
{
Ptr ndqi;
BooleanValue qosSupported;
diff --git a/src/wifi/helper/wifi-helper.h b/src/wifi/helper/wifi-helper.h
index f4bfcd11e..6baf8fa54 100644
--- a/src/wifi/helper/wifi-helper.h
+++ b/src/wifi/helper/wifi-helper.h
@@ -408,6 +408,17 @@ public:
* to the WifiNetDevice, in case RegularWifiMac with QoS enabled is used
*/
void SetSelectQueueCallback (SelectQueueCallback f);
+
+ /**
+ * Disable flow control only if you know what you are doing. By disabling
+ * flow control, this NetDevice will be sent packets even if there is no
+ * room for them (such packets will be likely dropped by this NetDevice).
+ * Also, any queue disc installed on this NetDevice will have no effect,
+ * as every packet enqueued to the traffic control layer queue disc will
+ * be immediately dequeued.
+ */
+ void DisableFlowControl (void);
+
/**
* \param phy the PHY helper to create PHY objects
* \param mac the MAC helper to create MAC objects
@@ -498,6 +509,7 @@ protected:
WifiStandard m_standard; ///< wifi standard
SelectQueueCallback m_selectQueueCallback; ///< select queue callback
ObjectFactory m_obssPdAlgorithm; ///< OBSS_PD algorithm
+ bool m_enableFlowControl; //!< whether to enable flow control
};
} //namespace ns3