traffic-control: Allow to disable flow control for devices supporting it

This commit is contained in:
Stefano Avallone
2020-04-12 10:27:32 +02:00
parent 4dc0ec0682
commit 7fd2d476ba
11 changed files with 126 additions and 20 deletions

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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
=======

View File

@@ -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);

View File

@@ -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;

View File

@@ -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