traffic-control: Allow to disable flow control for devices supporting it
This commit is contained in:
@@ -54,7 +54,7 @@ us a note on ns-developers mailing list.</p>
|
||||
<h1>Changes from ns-3.35 to ns-3.36</h1>
|
||||
<h2>New API:</h2>
|
||||
<ul>
|
||||
<li></li>
|
||||
<li>The helpers of the NetDevices supporting flow control (PointToPointHelper, CsmaHelper, SimpleNetDeviceHelper, WifiHelper) now provide a <b>DisableFlowControl</b> 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)</li>
|
||||
</ul>
|
||||
<h2>Changes to existing API:</h2>
|
||||
<ul>
|
||||
|
||||
@@ -44,6 +44,7 @@ CsmaHelper::CsmaHelper ()
|
||||
m_queueFactory.SetTypeId ("ns3::DropTailQueue<Packet>");
|
||||
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<NetDevice> nd, bool promiscuous, bool explicitFilename)
|
||||
{
|
||||
@@ -310,11 +317,13 @@ CsmaHelper::InstallPriv (Ptr<Node> node, Ptr<CsmaChannel> channel) const
|
||||
Ptr<Queue<Packet> > queue = m_queueFactory.Create<Queue<Packet> > ();
|
||||
device->SetQueue (queue);
|
||||
device->Attach (channel);
|
||||
// Aggregate a NetDeviceQueueInterface object
|
||||
Ptr<NetDeviceQueueInterface> ndqi = CreateObject<NetDeviceQueueInterface> ();
|
||||
ndqi->GetTxQueue (0)->ConnectQueueTraces (queue);
|
||||
device->AggregateObject (ndqi);
|
||||
|
||||
if (m_enableFlowControl)
|
||||
{
|
||||
// Aggregate a NetDeviceQueueInterface object
|
||||
Ptr<NetDeviceQueueInterface> ndqi = CreateObject<NetDeviceQueueInterface> ();
|
||||
ndqi->GetTxQueue (0)->ConnectQueueTraces (queue);
|
||||
device->AggregateObject (ndqi);
|
||||
}
|
||||
return device;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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> node) const
|
||||
{
|
||||
@@ -141,10 +148,13 @@ SimpleNetDeviceHelper::InstallPriv (Ptr<Node> node, Ptr<SimpleChannel> channel)
|
||||
Ptr<Queue<Packet> > queue = m_queueFactory.Create<Queue<Packet> > ();
|
||||
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<NetDeviceQueueInterface> ndqi = CreateObject<NetDeviceQueueInterface> ();
|
||||
ndqi->GetTxQueue (0)->ConnectQueueTraces (queue);
|
||||
device->AggregateObject (ndqi);
|
||||
if (m_enableFlowControl)
|
||||
{
|
||||
// Aggregate a NetDeviceQueueInterface object
|
||||
Ptr<NetDeviceQueueInterface> ndqi = CreateObject<NetDeviceQueueInterface> ();
|
||||
ndqi->GetTxQueue (0)->ConnectQueueTraces (queue);
|
||||
device->AggregateObject (ndqi);
|
||||
}
|
||||
return device;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -47,6 +47,7 @@ PointToPointHelper::PointToPointHelper ()
|
||||
m_queueFactory.SetTypeId ("ns3::DropTailQueue<Packet>");
|
||||
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<NetDevice> nd, bool promiscuous, bool explicitFilename)
|
||||
{
|
||||
@@ -240,13 +247,16 @@ PointToPointHelper::Install (Ptr<Node> a, Ptr<Node> b)
|
||||
b->AddDevice (devB);
|
||||
Ptr<Queue<Packet> > queueB = m_queueFactory.Create<Queue<Packet> > ();
|
||||
devB->SetQueue (queueB);
|
||||
// Aggregate NetDeviceQueueInterface objects
|
||||
Ptr<NetDeviceQueueInterface> ndqiA = CreateObject<NetDeviceQueueInterface> ();
|
||||
ndqiA->GetTxQueue (0)->ConnectQueueTraces (queueA);
|
||||
devA->AggregateObject (ndqiA);
|
||||
Ptr<NetDeviceQueueInterface> ndqiB = CreateObject<NetDeviceQueueInterface> ();
|
||||
ndqiB->GetTxQueue (0)->ConnectQueueTraces (queueB);
|
||||
devB->AggregateObject (ndqiB);
|
||||
if (m_enableFlowControl)
|
||||
{
|
||||
// Aggregate NetDeviceQueueInterface objects
|
||||
Ptr<NetDeviceQueueInterface> ndqiA = CreateObject<NetDeviceQueueInterface> ();
|
||||
ndqiA->GetTxQueue (0)->ConnectQueueTraces (queueA);
|
||||
devA->AggregateObject (ndqiA);
|
||||
Ptr<NetDeviceQueueInterface> ndqiB = CreateObject<NetDeviceQueueInterface> ();
|
||||
ndqiB->GetTxQueue (0)->ConnectQueueTraces (queueB);
|
||||
devB->AggregateObject (ndqiB);
|
||||
}
|
||||
|
||||
Ptr<PointToPointChannel> channel = 0;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
=======
|
||||
|
||||
|
||||
@@ -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<NetDevice> d);
|
||||
|
||||
|
||||
@@ -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<MobilityModel> ());
|
||||
// Aggregate a NetDeviceQueueInterface object if a RegularWifiMac is installed
|
||||
Ptr<RegularWifiMac> rmac = DynamicCast<RegularWifiMac> (mac);
|
||||
if (rmac)
|
||||
if (rmac && m_enableFlowControl)
|
||||
{
|
||||
Ptr<NetDeviceQueueInterface> ndqi;
|
||||
BooleanValue qosSupported;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user