fd-net-device: Finalize merge of DPDK and netmap emulation features
* Handle code review comments (due to Rediet and Mohit) * Add attribute to configure netmap sync and notify period
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
DPDK NetDevice
|
||||
-------------------------
|
||||
--------------
|
||||
.. include:: replace.txt
|
||||
.. highlight:: cpp
|
||||
|
||||
@@ -101,12 +101,12 @@ To compile DPDK from source, you need to perform the following 4 steps:
|
||||
1. Download the source
|
||||
######################
|
||||
|
||||
Head over to `DPDK Downloads <https://core.dpdk.org/download/>`_ page to get the latest stable source. (This module has been tested with version 19.11 LTS and DpdkNetDevice will only be enabled if this version is available.)
|
||||
Visit the `DPDK Downloads <https://core.dpdk.org/download/>`_ page to download the latest stable source. (This module has been tested with version 19.11 LTS and DpdkNetDevice will only be enabled if this version is available.)
|
||||
|
||||
2. Configure DPDK as a shared library
|
||||
#####################################
|
||||
|
||||
Goto the DPDK directory, edit ``config/common_base`` file to change following line to compile DPDK as a shared library:
|
||||
In the DPDK directory, edit the ``config/common_base`` file to change the following line to compile DPDK as a shared library:
|
||||
|
||||
.. sourcecode:: text
|
||||
|
||||
@@ -116,7 +116,7 @@ Goto the DPDK directory, edit ``config/common_base`` file to change following li
|
||||
3. Install the source
|
||||
#####################
|
||||
|
||||
Refer `Installation <https://doc.dpdk.org/guides/linux_gsg/build_dpdk.html>`_ for detailed instructions.
|
||||
Refer to `Installation <https://doc.dpdk.org/guides/linux_gsg/build_dpdk.html>`_ for detailed instructions.
|
||||
|
||||
For a 64 bit linux machine with gcc, run:
|
||||
|
||||
@@ -127,7 +127,7 @@ For a 64 bit linux machine with gcc, run:
|
||||
4. Export DPDK Environment variables
|
||||
####################################
|
||||
|
||||
Export following environment variables:
|
||||
Export the following environment variables:
|
||||
|
||||
* RTE_SDK as the your DPDK source folder.
|
||||
* RTE_TARGET as the build target directory.
|
||||
@@ -147,7 +147,7 @@ It is advisable that you export these variables in ``.bashrc`` or similar for re
|
||||
Load DPDK Drivers to kernel
|
||||
===========================
|
||||
|
||||
Execute following:
|
||||
Execute the following:
|
||||
|
||||
.. sourcecode:: text
|
||||
|
||||
@@ -229,7 +229,7 @@ it is found, a user should see:
|
||||
|
||||
``DpdkNetDevice`` does not use a dedicated helper class, but reuses the
|
||||
``EmuFdNetDeviceHelper`` class provided in the ``fd-net-device/helper``
|
||||
directory. The ``EmuFdNetDeviceHelper`` will allows us to set ``dpdkMode``
|
||||
directory. The ``EmuFdNetDeviceHelper`` allows us to set ``dpdkMode``
|
||||
which will launch the ``DpdkNetDevice`` instead of the ``FdNetDevice``.
|
||||
|
||||
.. sourcecode:: text
|
||||
@@ -320,5 +320,5 @@ Examples
|
||||
|
||||
The following examples are provided:
|
||||
|
||||
* ``fd-emu-dpdk-ping.cc``: This example uses the EmuFdNetDeviceHelper in Dpdk mode to send ICMP traffic bypassing the kernel over a real channel.
|
||||
* ``fd-emu-dpdk-onoff.cc``: This example allows us to measure the throughput of the ``DpdkNetDevice`` by sending traffic from the simulated node to a real device using the ``ns3::OnOffApplication`` while leveraging DPDK’s fast packet processing abilities. This is achieved by saturating the channel with TCP/UDP traffic.
|
||||
* ``fd-emu-ping.cc``: This example can be configured to use the EmuFdNetDeviceHelper in DPDK mode to send ICMP traffic bypassing the kernel over a real channel.
|
||||
* ``fd-emu-onoff.cc``: This example can be configured to measure the throughput of the ``DpdkNetDevice`` by sending traffic from the simulated node to a real device using the ``ns3::OnOffApplication`` while leveraging DPDK’s fast packet processing abilities. This is achieved by saturating the channel with TCP/UDP traffic.
|
||||
|
||||
@@ -19,7 +19,7 @@ host networking stack and gains direct access to network device.
|
||||
netmap was developed by Luigi Rizzo [Rizzo2012]_ and is maintained as
|
||||
an open source project on GitHub at https://github.com/luigirizzo/netmap.
|
||||
|
||||
The NetmapNetDevice for ns-3 [Imputato2019]_ was developed by Pasquale Imputato in the 2017-19 timeframe. The use of NetmapNetDevice requires that the
|
||||
The ``NetmapNetDevice`` for |ns3| [Imputato2019]_ was developed by Pasquale Imputato in the 2017-19 timeframe. The use of NetmapNetDevice requires that the
|
||||
host system has netmap support (and for best performance, the drivers
|
||||
must support netmap and must be using a netmap-enabled device driver). Users
|
||||
can expect that emulation support using Netmap will support higher packets
|
||||
@@ -46,7 +46,7 @@ read/write methods, which have to make use of the netmap API to coordinate
|
||||
the exchange of packets with the netmap rings.
|
||||
|
||||
In the initialization stage, the network device is switched to netmap mode,
|
||||
so that ns-3 is able to send/receive packets to/from the
|
||||
so that |ns3| is able to send/receive packets to/from the
|
||||
real network device by writing/reading them to/from the netmap rings.
|
||||
Following the design of the ``FdNetDevice``, a separate reading thread is
|
||||
started during the initialization. The task of the reading thread is
|
||||
@@ -68,18 +68,18 @@ amount of bytes that have been transferred to the network device.
|
||||
|
||||
The read method is called by the reading thread to retrieve new incoming
|
||||
packets stored in the netmap receiver ring and pass them to the appropriate
|
||||
ns-3 protocol handler for further processing within the simulator’s network
|
||||
|ns3| protocol handler for further processing within the simulator’s network
|
||||
stack. After retrieving packets, the reading thread also synchronizes
|
||||
the netmap receiver ring, so that the retrieved packets can be removed
|
||||
from the netmap receiver ring.
|
||||
|
||||
The ``NetmapNetDevice`` also specializes the write method, i.e., the method
|
||||
used to transmit a packet received from the upper layer (the ns-3 traffic
|
||||
used to transmit a packet received from the upper layer (the |ns3| traffic
|
||||
control layer). The write method uses the netmap API to write the packet to a
|
||||
free slot in the netmap
|
||||
transmission ring. After writing a packet, the write method checks whether
|
||||
there is enough room in the netmap transmission ring for another packet.
|
||||
If not, the ``NetmapNetDevice`` stops its queue so that the ns-3 traffic
|
||||
If not, the ``NetmapNetDevice`` stops its queue so that the |ns3| traffic
|
||||
control layer does not attempt to send a packet that could not be stored in
|
||||
the netmap transmission ring.
|
||||
|
||||
@@ -90,7 +90,7 @@ transmission ring. In particular, the sync thread also checks the number of
|
||||
free slots in the netmap transmission ring in case the ``NetmapNetDevice``
|
||||
queue is stopped. If the number of free slots exceeds a configurable value,
|
||||
the sync thread restarts the ``NetmapNetDevice``
|
||||
queue and wakes the associated ns-3 qdisc. The NetmapNetDevice also supports
|
||||
queue and wakes the associated |ns3| qdisc. The NetmapNetDevice also supports
|
||||
BQL: the write method notifies the BQL library of the amount of bytes that
|
||||
have been written to the netmap transmission ring, while the sync thread
|
||||
notifies the BQL library of the amount of bytes that have been removed from
|
||||
@@ -110,10 +110,10 @@ Usage
|
||||
The installation of netmap itself on a host machine is out of scope for
|
||||
this document. Refer to the `netmap GitHub README <https://github.com/luigirizzo/netmap>`_ for instructions.
|
||||
|
||||
The ns-3 netmap code has only been tested on Linux; it is not clear whether
|
||||
The |ns3| netmap code has only been tested on Linux; it is not clear whether
|
||||
other operating systems can be supported.
|
||||
|
||||
If ns-3 is able to detect the presence of netmap on the system, it will
|
||||
If |ns3| is able to detect the presence of netmap on the system, it will
|
||||
report that:
|
||||
|
||||
.. sourcecode:: text
|
||||
@@ -133,15 +133,21 @@ privileges.
|
||||
Helpers
|
||||
=======
|
||||
|
||||
ns-3 netmap support uses a ``NetMapNetDeviceHelper`` helper object to
|
||||
install the NetmapNetDevice. In other respects, the API and use is similar
|
||||
|ns3| netmap support uses a ``NetMapNetDeviceHelper`` helper object to
|
||||
install the ``NetmapNetDevice``. In other respects, the API and use is similar
|
||||
to that of the ``EmuFdNetDeviceHelper``.
|
||||
|
||||
Attributes
|
||||
==========
|
||||
|
||||
The ``NetmapNetDevice`` does not have any specialized attributes, but
|
||||
supports the ``FdNetDevice`` attributes (see the chapter on ``FdNetDevice``).
|
||||
There is one attribute specialized to ``NetmapNetDevice``, named
|
||||
``SyncAndNotifyQueuePeriod``. This value takes an integer number of
|
||||
microseconds, and is used as the period of time after which the device
|
||||
syncs the netmap ring and notifies queue status. The value should be
|
||||
close to the interrupt coalescence period of the real device. Users
|
||||
may want to tune this parameter for their own system; it should be
|
||||
a compromise between CPU usage and accuracy in the ring sync (if it is
|
||||
too high, the device goes into starvation and lower throughput occurs).
|
||||
|
||||
Output
|
||||
======
|
||||
|
||||
@@ -55,9 +55,9 @@
|
||||
// | |
|
||||
// +----------------------------+
|
||||
//
|
||||
// This example is aimed at measuring the throughput of the FdNetDevice (NetmapNetDevice)
|
||||
// when using the EmuFdNetDeviceHelper (NetmapNetDeviceHelper). This is achieved by saturating
|
||||
// the channel with TCP or UDP traffic. Then the throughput can be obtained from
|
||||
// This example is aimed at measuring the throughput of the FdNetDevice
|
||||
// when using the EmuFdNetDeviceHelper. This is achieved by saturating
|
||||
// the channel with TCP traffic. Then the throughput can be obtained from
|
||||
// the generated .pcap files.
|
||||
//
|
||||
// To run this example you will need two hosts (client & server).
|
||||
|
||||
@@ -18,14 +18,15 @@
|
||||
* Author: Pasquale Imputato <p.imputato@gmail.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
/*
|
||||
* This example builds a node with a device in emulation mode in {raw, netmap}.
|
||||
* The aim is to measure the maximum tx rate in pps achievable with NetmapNetDevice and FdNetDevice on a specific machine.
|
||||
* The aim is to measure the maximum tx rate in pps achievable with
|
||||
* NetmapNetDevice and FdNetDevice on a specific machine.
|
||||
* The emulated device must be connected and in promiscuous mode.
|
||||
*
|
||||
* If you run emulation in netmap mode, you need before to load the netmap.ko module.
|
||||
* The user is in charge to configure and build netmap separately.
|
||||
*
|
||||
* If you run emulation in netmap mode, you need before to load the
|
||||
* netmap.ko module. The user is responsible for configuring and building
|
||||
* netmap separately.
|
||||
*/
|
||||
|
||||
#include "ns3/abort.h"
|
||||
@@ -46,25 +47,24 @@ using namespace ns3;
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("NetmapEmulationSendExample");
|
||||
|
||||
// this function sends a number packets by means the SendFrom method or
|
||||
// the Write method (depending from the level value) of a FdNetDevice or of a NetmapNetDevice
|
||||
// (depending from the emulation mode value).
|
||||
// This function sends a number of packets by means of the SendFrom method or
|
||||
// the Write method (depending on the level value) of a FdNetDevice or
|
||||
// of a NetmapNetDevice (depending on the emulation mode value).
|
||||
|
||||
static void
|
||||
Send (Ptr<NetDevice> dev, int level, std::string emuMode)
|
||||
{
|
||||
|
||||
Ptr<FdNetDevice> device = DynamicCast<FdNetDevice> (dev);
|
||||
|
||||
int packets = 10000000;
|
||||
|
||||
Mac48Address sender = Mac48Address("00:00:00:aa:00:01");
|
||||
Mac48Address receiver = Mac48Address("ff:ff:ff:ff:ff:ff");
|
||||
Mac48Address sender = Mac48Address ("00:00:00:aa:00:01");
|
||||
Mac48Address receiver = Mac48Address ("ff:ff:ff:ff:ff:ff");
|
||||
|
||||
int packetsSize = 64;
|
||||
Ptr<Packet> packet = Create<Packet> (packetsSize);
|
||||
EthernetHeader header;
|
||||
|
||||
|
||||
ssize_t len = (size_t) packet->GetSize ();
|
||||
uint8_t *buffer = (uint8_t*)malloc (len);
|
||||
packet->CopyData (buffer, len);
|
||||
@@ -79,13 +79,12 @@ Send (Ptr<NetDevice> dev, int level, std::string emuMode)
|
||||
ndq = ndqi->GetTxQueue (0);
|
||||
}
|
||||
|
||||
|
||||
std::cout << ((level == 0) ? "Writing" : "Sending") << std::endl;
|
||||
|
||||
// period to print the stats
|
||||
std::chrono::milliseconds period (1000);
|
||||
|
||||
auto t1 = std::chrono::high_resolution_clock::now();
|
||||
auto t1 = std::chrono::high_resolution_clock::now ();
|
||||
|
||||
while (packets > 0)
|
||||
{
|
||||
@@ -118,38 +117,27 @@ Send (Ptr<NetDevice> dev, int level, std::string emuMode)
|
||||
sent++;
|
||||
}
|
||||
|
||||
auto t2 = std::chrono::high_resolution_clock::now();
|
||||
auto t2 = std::chrono::high_resolution_clock::now ();
|
||||
|
||||
if (t2 - t1 >= period)
|
||||
{
|
||||
|
||||
// print stats
|
||||
std::chrono::duration<double, std::milli> dur = (t2 - t1); // in ms
|
||||
double estimatedThr = ((sent - failed) * packetsSize * 8) / 1000000; // in Mbps
|
||||
|
||||
std::cout << sent << " packets sent in "<< dur.count () << " ms, failed " << failed <<" (" << estimatedThr << " Mbps estimanted throughput)" << std::endl ;
|
||||
|
||||
std::cout << sent << " packets sent in " << dur.count () << " ms, failed " << failed << " (" << estimatedThr << " Mbps estimated throughput)" << std::endl;
|
||||
sent = 0;
|
||||
failed = 0;
|
||||
t1 = std::chrono::high_resolution_clock::now();
|
||||
|
||||
t1 = std::chrono::high_resolution_clock::now ();
|
||||
}
|
||||
|
||||
packets--;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
NS_LOG_INFO ("Emu Send Example");
|
||||
|
||||
std::string deviceName ("eno1");
|
||||
int level = 0;
|
||||
std::string localAddress ("1.2.3.4");
|
||||
std::string localGateway ("1.2.3.4");
|
||||
|
||||
#ifdef HAVE_PACKET_H
|
||||
std::string emuMode ("raw");
|
||||
@@ -160,18 +148,10 @@ main (int argc, char *argv[])
|
||||
CommandLine cmd;
|
||||
cmd.AddValue ("deviceName", "Device name", deviceName);
|
||||
cmd.AddValue ("level", "Enable send (1) or write (0) level test", level);
|
||||
cmd.AddValue ("localIp", "Local IP address (dotted decimal only please)", localAddress);
|
||||
cmd.AddValue ("gateway", "Gateway address (dotted decimal only please)", localGateway);
|
||||
cmd.AddValue ("emuMode", "Emulation mode in {raw, netmap}", emuMode);
|
||||
|
||||
cmd.Parse (argc, argv);
|
||||
|
||||
Ipv4Address localIp (localAddress.c_str ());
|
||||
NS_ABORT_MSG_IF (localIp == "1.2.3.4", "You must change the local IP address before running this example");
|
||||
|
||||
Ipv4Mask localMask (localGateway.c_str ());
|
||||
NS_ABORT_MSG_IF (localMask == "1.2.3.4", "You must change the local mask before running this example");
|
||||
|
||||
GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::RealtimeSimulatorImpl"));
|
||||
|
||||
GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true));
|
||||
@@ -209,16 +189,6 @@ main (int argc, char *argv[])
|
||||
Ptr<NetDevice> device = devices.Get (0);
|
||||
device->SetAttribute ("Address", Mac48AddressValue (Mac48Address::Allocate ()));
|
||||
|
||||
|
||||
// NS_LOG_INFO ("Add Internet Stack");
|
||||
// InternetStackHelper internetStackHelper;
|
||||
// internetStackHelper.Install (node);
|
||||
|
||||
|
||||
// TrafficControlHelper tch;
|
||||
// tch.SetRootQueueDisc ("ns3::PfifoFastQueueDisc");
|
||||
// tch.Install (devices);
|
||||
|
||||
Simulator::Schedule (Seconds (3), &Send, device, level, emuMode);
|
||||
|
||||
NS_LOG_INFO ("Run Emulation.");
|
||||
|
||||
@@ -31,12 +31,13 @@
|
||||
* 1 Gbps access incoming link | | 100 Mbps bottleneck outgoing link
|
||||
* ----------------------------------- -----------------------------------
|
||||
*
|
||||
* This example builds a node with two interfaces in emulation mode in {raw, netmap}.
|
||||
* The aim is to explore different qdiscs behaviours on the backlog of a device emulated bottleneck side.
|
||||
*
|
||||
* If you run emulation in netmap mode, you need before to load the netmap.ko module.
|
||||
* The user is in charge to configure and build netmap separately.
|
||||
*
|
||||
* This example builds a node with two interfaces in emulation mode in
|
||||
* either {raw, netmap}. The aim is to explore different qdiscs behaviours
|
||||
* on the backlog of a device emulated bottleneck side.
|
||||
*
|
||||
* If you run emulation in netmap mode, you need before to load the
|
||||
* netmap.ko module. The user is responsible for configuring and building
|
||||
* netmap separately.
|
||||
*/
|
||||
|
||||
#include "ns3/abort.h"
|
||||
@@ -56,8 +57,8 @@ void
|
||||
TcPacketsInQueue (Ptr<QueueDisc> q, Ptr<OutputStreamWrapper> stream)
|
||||
{
|
||||
Simulator::Schedule (Seconds (0.001), &TcPacketsInQueue, q, stream);
|
||||
*stream->GetStream () << Simulator::Now ().GetSeconds () << " backlog " << q->GetNPackets () << "p " << q->GetNBytes () << "b "<< " dropped "
|
||||
<< q->GetStats ().nTotalDroppedPackets << "p " << q->GetStats ().nTotalDroppedBytes << "b " << std::endl;
|
||||
*stream->GetStream () << Simulator::Now ().GetSeconds () << " backlog " << q->GetNPackets () << "p " << q->GetNBytes () << "b " << " dropped "
|
||||
<< q->GetStats ().nTotalDroppedPackets << "p " << q->GetStats ().nTotalDroppedBytes << "b " << std::endl;
|
||||
}
|
||||
|
||||
#ifdef HAVE_NETMAP_USER_H
|
||||
@@ -65,7 +66,7 @@ void
|
||||
Inflight (Ptr<NetmapNetDevice> dev, Ptr<OutputStreamWrapper> stream)
|
||||
{
|
||||
Simulator::Schedule (Seconds (0.001), &Inflight, dev, stream);
|
||||
*stream->GetStream () << dev->GetBytesInNetmapTxRing () << std::endl;
|
||||
*stream->GetStream () << dev->GetBytesInNetmapTxRing () << std::endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -66,8 +66,8 @@ NS_LOG_COMPONENT_DEFINE ("EmuFdNetDeviceHelper");
|
||||
EmuFdNetDeviceHelper::EmuFdNetDeviceHelper ()
|
||||
{
|
||||
m_deviceName = "undefined";
|
||||
m_dpdkMode = false;
|
||||
m_hostQdiscBypass = false;
|
||||
m_dpdkMode = false;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -76,6 +76,11 @@ EmuFdNetDeviceHelper::SetDeviceName (std::string deviceName)
|
||||
m_deviceName = deviceName;
|
||||
}
|
||||
|
||||
void
|
||||
EmuFdNetDeviceHelper::HostQdiscBypass (bool hostQdiscBypass)
|
||||
{
|
||||
m_hostQdiscBypass = hostQdiscBypass;
|
||||
}
|
||||
void
|
||||
EmuFdNetDeviceHelper::SetDpdkMode (int argc, char **argv)
|
||||
{
|
||||
@@ -93,12 +98,6 @@ EmuFdNetDeviceHelper::SetDpdkMode (int argc, char **argv)
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
EmuFdNetDeviceHelper::HostQdiscBypass (bool hostQdiscBypass)
|
||||
{
|
||||
m_hostQdiscBypass = hostQdiscBypass;
|
||||
}
|
||||
|
||||
std::string
|
||||
EmuFdNetDeviceHelper::GetDeviceName (void)
|
||||
{
|
||||
|
||||
@@ -69,20 +69,15 @@ public:
|
||||
void HostQdiscBypass (bool hostQdiscBypass);
|
||||
|
||||
/**
|
||||
* Set the device in Dpdk mode.
|
||||
* Set the device in DPDK mode.
|
||||
*
|
||||
* \param argc Dpdk EAL args count.
|
||||
* \param argv Dpdk EAL args list.
|
||||
*/
|
||||
void SetDpdkMode (int argc, char **argv);
|
||||
|
||||
/**
|
||||
* \brief Request host qdisc bypass
|
||||
* \param hostQdiscBypass to enable host qdisc bypass
|
||||
*/
|
||||
void HostQdiscBypass (bool hostQdiscBypass);
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* This method creates an ns3::FdNetDevice attached to a physical network
|
||||
* interface
|
||||
@@ -105,26 +100,25 @@ protected:
|
||||
virtual int CreateFileDescriptor (void) const;
|
||||
|
||||
/**
|
||||
* The unix/linux name of the underlying device (e.g., eth0)
|
||||
* The Unix/Linux name of the underlying device (e.g., eth0)
|
||||
*/
|
||||
std::string m_deviceName;
|
||||
bool m_hostQdiscBypass;
|
||||
|
||||
/**
|
||||
* The dpdk mode of the device.
|
||||
* The DPDK mode of the device.
|
||||
*/
|
||||
bool m_dpdkMode;
|
||||
|
||||
/**
|
||||
* Dpdk EAL arguements count.
|
||||
* DPDK EAL arguments count.
|
||||
*/
|
||||
int m_ealArgc;
|
||||
|
||||
/**
|
||||
* Dpdk EAL arguements list.
|
||||
* DPDK EAL arguments list.
|
||||
*/
|
||||
char **m_ealArgv;
|
||||
|
||||
bool m_hostQdiscBypass;
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -55,12 +55,6 @@ FdNetDeviceHelper::SetAttribute (std::string n1, const AttributeValue &v1)
|
||||
m_deviceFactory.Set (n1, v1);
|
||||
}
|
||||
|
||||
void
|
||||
FdNetDeviceHelper::SetTypeId (std::string type)
|
||||
{
|
||||
m_deviceFactory.SetTypeId (type);
|
||||
}
|
||||
|
||||
void
|
||||
FdNetDeviceHelper::EnablePcapInternal (std::string prefix, Ptr<NetDevice> nd, bool promiscuous, bool explicitFilename)
|
||||
{
|
||||
|
||||
@@ -51,12 +51,12 @@ main (int argc, char *argv[])
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'v':
|
||||
gVerbose = true;
|
||||
break;
|
||||
case 'p':
|
||||
path = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
gVerbose = true;
|
||||
break;
|
||||
case 'p':
|
||||
path = optarg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ NetmapNetDeviceHelper::InstallPriv (Ptr<Node> node) const
|
||||
{
|
||||
Ptr<NetDevice> d = FdNetDeviceHelper::InstallPriv (node);
|
||||
Ptr<FdNetDevice> device = d->GetObject<FdNetDevice> ();
|
||||
|
||||
|
||||
SetDeviceAttributes (device);
|
||||
|
||||
int fd = CreateFileDescriptor ();
|
||||
@@ -96,8 +96,8 @@ NetmapNetDeviceHelper::InstallPriv (Ptr<Node> node) const
|
||||
|
||||
// Aggregate NetDeviceQueueInterface object
|
||||
Ptr<NetDeviceQueueInterface> ndqi = CreateObjectWithAttributes<NetDeviceQueueInterface> (
|
||||
"TxQueuesType", TypeIdValue (NetDeviceQueueLock::GetTypeId ()),
|
||||
"NTxQueues", UintegerValue (1));
|
||||
"TxQueuesType", TypeIdValue (NetDeviceQueueLock::GetTypeId ()),
|
||||
"NTxQueues", UintegerValue (1));
|
||||
|
||||
device->AggregateObject (ndqi);
|
||||
netmapDevice->SetNetDeviceQueue (ndqi->GetTxQueue (0));
|
||||
@@ -156,7 +156,7 @@ NetmapNetDeviceHelper::SetDeviceAttributes (Ptr<FdNetDevice> device) const
|
||||
NS_FATAL_ERROR ("NetmapNetDeviceHelper::SetFileDescriptor (): "
|
||||
<< m_deviceName.c_str ()
|
||||
<< " is not in promiscuous mode. Please config the interface in promiscuous "
|
||||
"mode before to run the simulation.");
|
||||
"mode before to run the simulation.");
|
||||
}
|
||||
|
||||
if ((ifr.ifr_flags & IFF_BROADCAST) != IFF_BROADCAST)
|
||||
|
||||
@@ -47,8 +47,7 @@ public:
|
||||
|
||||
NetmapNetDeviceHelper ();
|
||||
virtual ~NetmapNetDeviceHelper ()
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
/**
|
||||
* \brief Get the device name of this device.
|
||||
|
||||
@@ -473,4 +473,18 @@ DpdkNetDevice::Write (uint8_t *buffer, size_t length)
|
||||
return length;
|
||||
}
|
||||
|
||||
void
|
||||
DpdkNetDevice::DoFinishStoppingDevice (void)
|
||||
{
|
||||
CriticalSection cs (m_pendingReadMutex);
|
||||
|
||||
while (!m_pendingQueue.empty ())
|
||||
{
|
||||
std::pair<uint8_t *, ssize_t> next = m_pendingQueue.front ();
|
||||
m_pendingQueue.pop ();
|
||||
|
||||
FreeBuffer (next.first);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -52,23 +52,23 @@ public:
|
||||
* \brief Get the type ID.
|
||||
* \return the object TypeId
|
||||
*/
|
||||
static TypeId GetTypeId(void);
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
/**
|
||||
* Constructor for the DpdkNetDevice.
|
||||
*/
|
||||
DpdkNetDevice();
|
||||
DpdkNetDevice ();
|
||||
|
||||
/**
|
||||
* Destructor for the DpdkNetDevice.
|
||||
*/
|
||||
~DpdkNetDevice();
|
||||
~DpdkNetDevice ();
|
||||
|
||||
/**
|
||||
* Check the link status of all ports in up to 9s
|
||||
* and print them finally
|
||||
*/
|
||||
void CheckAllPortsLinkStatus(void);
|
||||
void CheckAllPortsLinkStatus (void);
|
||||
|
||||
/**
|
||||
* Initialize Dpdk.
|
||||
@@ -77,42 +77,42 @@ public:
|
||||
* \param argc Dpdk EAL args count.
|
||||
* \param argv Dpdk EAL args list.
|
||||
*/
|
||||
void InitDpdk(int argc, char **argv);
|
||||
void InitDpdk (int argc, char **argv);
|
||||
|
||||
/**
|
||||
* Set device name.
|
||||
*
|
||||
* \param deviceName The device name.
|
||||
*/
|
||||
void SetDeviceName(std::string deviceName);
|
||||
void SetDeviceName (std::string deviceName);
|
||||
|
||||
/**
|
||||
* A signal handler for SIGINT and SIGTERM signals.
|
||||
*
|
||||
* \param signum The signal number.
|
||||
*/
|
||||
static void SignalHandler(int signum);
|
||||
static void SignalHandler (int signum);
|
||||
|
||||
/**
|
||||
* A function to handle rx & tx operations.
|
||||
*/
|
||||
static int LaunchCore(void *arg);
|
||||
static int LaunchCore (void *arg);
|
||||
|
||||
/**
|
||||
* Transmit packets in burst from the tx_buffer to the nic.
|
||||
*/
|
||||
void HandleTx();
|
||||
void HandleTx ();
|
||||
|
||||
/**
|
||||
* Receive packets in burst from the nic to the rx_buffer.
|
||||
*/
|
||||
void HandleRx();
|
||||
void HandleRx ();
|
||||
|
||||
/**
|
||||
* Check the status of the link.
|
||||
* \return Status of the link - up/down as true/false.
|
||||
*/
|
||||
bool IsLinkUp(void) const;
|
||||
bool IsLinkUp (void) const;
|
||||
|
||||
/**
|
||||
* Free the given packet buffer.
|
||||
@@ -122,7 +122,7 @@ public:
|
||||
/**
|
||||
* Allocate packet buffer.
|
||||
*/
|
||||
virtual uint8_t* AllocateBuffer(size_t len);
|
||||
virtual uint8_t* AllocateBuffer (size_t len);
|
||||
|
||||
protected:
|
||||
/**
|
||||
@@ -131,7 +131,7 @@ protected:
|
||||
* \param length The data length.
|
||||
* \return The size of data written.
|
||||
*/
|
||||
ssize_t Write(uint8_t *buffer, size_t length);
|
||||
ssize_t Write (uint8_t *buffer, size_t length);
|
||||
|
||||
/**
|
||||
* The port number of the device to be used.
|
||||
@@ -144,6 +144,7 @@ protected:
|
||||
std::string m_deviceName;
|
||||
|
||||
private:
|
||||
void DoFinishStoppingDevice (void);
|
||||
/**
|
||||
* Condition variable for Dpdk to stop
|
||||
*/
|
||||
@@ -202,4 +203,4 @@ private:
|
||||
|
||||
} //
|
||||
|
||||
#endif /* DPDK_NET_DEVICE_H */
|
||||
#endif /* DPDK_NET_DEVICE_H */
|
||||
|
||||
@@ -618,8 +618,8 @@ FdNetDevice::SendFrom (Ptr<Packet> packet, const Address& src, const Address& de
|
||||
AddPIHeader (buffer, len);
|
||||
}
|
||||
|
||||
ssize_t written = Write (buffer, len);
|
||||
free (buffer);
|
||||
ssize_t written = Write(buffer, len);
|
||||
FreeBuffer (buffer);
|
||||
|
||||
if (written == -1 || (size_t) written != len)
|
||||
{
|
||||
@@ -635,7 +635,8 @@ FdNetDevice::Write (uint8_t *buffer, size_t length)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << buffer << length);
|
||||
|
||||
return write (m_fd, buffer, length);
|
||||
uint32_t ret = write (m_fd, buffer, length);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -198,6 +198,12 @@ public:
|
||||
protected:
|
||||
virtual void DoDispose (void);
|
||||
|
||||
/**
|
||||
* Get the associated file descriptor.
|
||||
* \return the associated file descriptor
|
||||
*/
|
||||
int GetFileDescriptor (void) const;
|
||||
|
||||
/**
|
||||
* Allocate packet buffer.
|
||||
*/
|
||||
@@ -212,11 +218,6 @@ protected:
|
||||
* Callback to invoke when a new frame is received
|
||||
*/
|
||||
void ReceiveCallback (uint8_t *buf, ssize_t len);
|
||||
/**
|
||||
* Get the associated file descriptor.
|
||||
* \return the associated file descriptor
|
||||
*/
|
||||
int GetFileDescriptor (void) const;
|
||||
|
||||
/**
|
||||
* Mutex to increase pending read counter.
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "netmap-net-device.h"
|
||||
#include "ns3/system-thread.h"
|
||||
#include "ns3/uinteger.h"
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -31,19 +32,17 @@ TypeId
|
||||
NetDeviceQueueLock::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::NetDeviceQueueLock")
|
||||
.SetParent<NetDeviceQueue> ()
|
||||
.SetGroupName ("Network")
|
||||
.AddConstructor<NetDeviceQueueLock> ();
|
||||
.SetParent<NetDeviceQueue> ()
|
||||
.SetGroupName ("Network")
|
||||
.AddConstructor<NetDeviceQueueLock> ();
|
||||
return tid;
|
||||
}
|
||||
|
||||
NetDeviceQueueLock::NetDeviceQueueLock ()
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
NetDeviceQueueLock::~NetDeviceQueueLock ()
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
bool
|
||||
NetDeviceQueueLock::IsStopped (void) const
|
||||
@@ -95,10 +94,10 @@ NetDeviceQueueLock::NotifyTransmittedBytes (uint32_t bytes)
|
||||
}
|
||||
|
||||
NetmapNetDeviceFdReader::NetmapNetDeviceFdReader ()
|
||||
: m_bufferSize (65536), // Defaults to maximum TCP window size
|
||||
m_nifp (nullptr)
|
||||
{
|
||||
}
|
||||
: m_bufferSize (65536),
|
||||
// Defaults to maximum TCP window size
|
||||
m_nifp (nullptr)
|
||||
{}
|
||||
|
||||
void
|
||||
NetmapNetDeviceFdReader::SetBufferSize (uint32_t bufferSize)
|
||||
@@ -171,9 +170,14 @@ TypeId
|
||||
NetmapNetDevice::GetTypeId (void)
|
||||
{
|
||||
static TypeId tid = TypeId ("ns3::NetmapNetDevice")
|
||||
.SetParent<FdNetDevice> ()
|
||||
.SetGroupName ("FdNetDevice")
|
||||
.AddConstructor<NetmapNetDevice> ();
|
||||
.SetParent<FdNetDevice> ()
|
||||
.SetGroupName ("FdNetDevice")
|
||||
.AddConstructor<NetmapNetDevice> ()
|
||||
.AddAttribute ("SyncAndNotifyQueuePeriod",
|
||||
"The period of time (in number of us) after which the device syncs the netmap ring and notifies queue status.",
|
||||
UintegerValue (50),
|
||||
MakeUintegerAccessor (&NetmapNetDevice::m_syncAndNotifyQueuePeriod),
|
||||
MakeUintegerChecker<uint8_t> ());
|
||||
return tid;
|
||||
}
|
||||
|
||||
@@ -337,9 +341,7 @@ NetmapNetDevice::SyncAndNotifyQueue ()
|
||||
}
|
||||
}
|
||||
|
||||
// we use a period to sync, check and notify of 200 us; it is a value close to the interrupt coalescence
|
||||
// period of a real device
|
||||
usleep (200);
|
||||
usleep (m_syncAndNotifyQueuePeriod);
|
||||
|
||||
NS_LOG_DEBUG ("Space in the netmap ring of " << nm_ring_space (txring) << " packets");
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ private:
|
||||
|
||||
/**
|
||||
* \ingroup fd-net-device
|
||||
*
|
||||
*
|
||||
* \brief This class performs the actual data reading from the netmap ring.
|
||||
*/
|
||||
class NetmapNetDeviceFdReader : public FdReader
|
||||
@@ -212,6 +212,7 @@ private:
|
||||
uint32_t m_totalQueuedBytes; //!< Total queued bytes
|
||||
Ptr<SystemThread> m_syncAndNotifyQueueThread; //!< Thread used to perform the flow control
|
||||
std::atomic<bool> m_syncAndNotifyQueueThreadRun; //!< Running flag of the flow control thread
|
||||
uint8_t m_syncAndNotifyQueuePeriod; //!< The period of time in us after which the device syncs the netmap ring and notifies queue status
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
Reference in New Issue
Block a user