A Discrete-Event Network Simulator
API
fd-emu-send.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2017 Universita' degli Studi di Napoli Federico II
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Pasquale Imputato <p.imputato@gmail.com>
19  */
20 
21 /*
22  * This example builds a node with a device in emulation mode in {raw, netmap}.
23  * The aim is to measure the maximum tx rate in pps achievable with
24  * NetmapNetDevice and FdNetDevice on a specific machine.
25  * The emulated device must be connected and in promiscuous mode.
26  *
27  * If you run emulation in netmap mode, you need before to load the
28  * netmap.ko module. The user is responsible for configuring and building
29  * netmap separately.
30  */
31 
32 #include "ns3/abort.h"
33 #include "ns3/core-module.h"
34 #include "ns3/internet-module.h"
35 #include "ns3/network-module.h"
36 #include "ns3/fd-net-device-module.h"
37 #include "ns3/internet-apps-module.h"
38 #include "ns3/ipv4-static-routing-helper.h"
39 #include "ns3/ipv4-list-routing-helper.h"
40 #include "ns3/applications-module.h"
41 #include "ns3/traffic-control-module.h"
42 
43 #include <chrono>
44 #include <unistd.h>
45 
46 using namespace ns3;
47 
48 NS_LOG_COMPONENT_DEFINE ("NetmapEmulationSendExample");
49 
50 // This function sends a number of packets by means of the SendFrom method or
51 // the Write method (depending on the level value) of a FdNetDevice or
52 // of a NetmapNetDevice (depending on the emulation mode value).
53 
54 static void
55 Send (Ptr<NetDevice> dev, int level, std::string emuMode)
56 {
57  Ptr<FdNetDevice> device = DynamicCast<FdNetDevice> (dev);
58 
59  int packets = 10000000;
60 
61  Mac48Address sender = Mac48Address ("00:00:00:aa:00:01");
62  Mac48Address receiver = Mac48Address ("ff:ff:ff:ff:ff:ff");
63 
64  int packetsSize = 64;
65  Ptr<Packet> packet = Create<Packet> (packetsSize);
66  EthernetHeader header;
67 
68  ssize_t len = (size_t) packet->GetSize ();
69  uint8_t *buffer = (uint8_t*)malloc (len);
70  packet->CopyData (buffer, len);
71 
72  int sent = 0;
73  int failed = 0;
74 
75  Ptr<NetDeviceQueue> ndq = nullptr;
76  if (emuMode == "netmap")
77  {
79  ndq = ndqi->GetTxQueue (0);
80  }
81 
82  std::cout << ((level == 0) ? "Writing" : "Sending") << std::endl;
83 
84  // period to print the stats
85  std::chrono::milliseconds period (1000);
86 
87  auto t1 = std::chrono::high_resolution_clock::now ();
88 
89  while (packets > 0)
90  {
91  // in case of netmap emulated device we check for
92  // available slot in the netmap transmission ring
93  if (ndq)
94  {
95  while (ndq->IsStopped ())
96  {
97  usleep (10);
98  }
99  }
100 
101  if (level == 1)
102  {
103  if (device->SendFrom (packet, sender, receiver, 0) == false)
104  {
105  failed++;
106  }
107  sent++;
108  packet->RemoveHeader (header);
109  }
110 
111  if (level == 0)
112  {
113  if (device->Write (buffer, len) != len)
114  {
115  failed++;
116  }
117  sent++;
118  }
119 
120  auto t2 = std::chrono::high_resolution_clock::now ();
121 
122  if (t2 - t1 >= period)
123  {
124  // print stats
125  std::chrono::duration<double, std::milli> dur = (t2 - t1); // in ms
126  double estimatedThr = ((sent - failed) * packetsSize * 8) / 1000000; // in Mbps
127  std::cout << sent << " packets sent in " << dur.count () << " ms, failed " << failed << " (" << estimatedThr << " Mbps estimated throughput)" << std::endl;
128  sent = 0;
129  failed = 0;
130  t1 = std::chrono::high_resolution_clock::now ();
131  }
132  packets--;
133  }
134 }
135 
136 int
137 main (int argc, char *argv[])
138 {
139  std::string deviceName ("eno1");
140  int level = 0;
141 
142 #ifdef HAVE_PACKET_H
143  std::string emuMode ("raw");
144 #else // HAVE_NETMAP_USER_H is true (otherwise this example is not compiled)
145  std::string emuMode ("netmap");
146 #endif
147 
149  cmd.AddValue ("deviceName", "Device name", deviceName);
150  cmd.AddValue ("level", "Enable send (1) or write (0) level test", level);
151  cmd.AddValue ("emuMode", "Emulation mode in {raw, netmap}", emuMode);
152 
153  cmd.Parse (argc, argv);
154 
155  GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::RealtimeSimulatorImpl"));
156 
157  GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true));
158 
159  NS_LOG_INFO ("Create Node");
160  Ptr<Node> node = CreateObject<Node> ();
161 
162  NS_LOG_INFO ("Create Device");
163 
164  FdNetDeviceHelper* helper = nullptr;
165 
166 #ifdef HAVE_PACKET_H
167  if (emuMode == "raw")
168  {
170  raw->SetDeviceName (deviceName);
171  helper = raw;
172  }
173 #endif
174 #ifdef HAVE_NETMAP_USER_H
175  if (emuMode == "netmap")
176  {
178  netmap->SetDeviceName (deviceName);
179  helper = netmap;
180  }
181 #endif
182 
183  if (helper == nullptr)
184  {
185  NS_ABORT_MSG (emuMode << " not supported.");
186  }
187 
188  NetDeviceContainer devices = helper->Install (node);
189  Ptr<NetDevice> device = devices.Get (0);
190  device->SetAttribute ("Address", Mac48AddressValue (Mac48Address::Allocate ()));
191 
192  Simulator::Schedule (Seconds (3), &Send, device, level, emuMode);
193 
194  NS_LOG_INFO ("Run Emulation.");
195  Simulator::Stop (Seconds (6.0));
196  Simulator::Run ();
198  delete helper;
199  NS_LOG_INFO ("Done.");
200 }
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:280
static void Send(Ptr< NetDevice > dev, int level, std::string emuMode)
Definition: fd-emu-send.cc:55
static EventId Schedule(Time const &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:557
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:73
AttributeValue implementation for Boolean.
Definition: boolean.h:36
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:50
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
Hold variables of type string.
Definition: string.h:41
virtual bool SendFrom(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber)
static void Run(void)
Run the simulation.
Definition: simulator.cc:172
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
build a set of FdNetDevice objects Normally we eschew multiple inheritance, however, the classes PcapUserHelperForDevice and AsciiTraceUserHelperForDevice are treated as "mixins".
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
cmd
Definition: second.py:35
virtual bool IsStopped(void) const
Get the status of the device transmission queue.
virtual ssize_t Write(uint8_t *buffer, size_t length)
Write packet data to device.
virtual NetDeviceContainer Install(Ptr< Node > node) const
This method creates a FdNetDevice and associates it to a node.
static Mac48Address Allocate(void)
Allocate a new Mac48Address.
holds a vector of ns3::NetDevice pointers
static void Bind(std::string name, const AttributeValue &value)
Iterate over the set of GlobalValues until a matching name is found and then set its value with Globa...
Network device transmission queue interface.
Parse command-line arguments.
Definition: command-line.h:227
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:136
Ptr< T > GetObject(void) const
Get a pointer to the requested aggregated Object.
Definition: object.h:470
void SetDeviceName(std::string deviceName)
Set the device name of this device.
build a set of FdNetDevice objects attached to a physical network interface
Every class exported by the ns3 library is enclosed in the ns3 namespace.
an EUI-48 address
Definition: mac48-address.h:43
Packet header for Ethernet.
void SetDeviceName(std::string deviceName)
Set the device name of this device.
AttributeValue implementation for Mac48Address.
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:180
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition: packet.cc:378
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1289
Ptr< NetDeviceQueue > GetTxQueue(std::size_t i) const
Get the i-th transmission queue of the device.
devices
Definition: first.py:39
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185
build a set of FdNetDevice objects attached to a physical network interface