A Discrete-Event Network Simulator
API
fd-emu-send.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Universita' degli Studi di Napoli Federico II
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Pasquale Imputato <p.imputato@gmail.com>
18  */
19 
20 /*
21  * This example builds a node with a device in emulation mode in {raw, netmap}.
22  * The aim is to measure the maximum tx rate in pps achievable with
23  * NetmapNetDevice and FdNetDevice on a specific machine.
24  * The emulated device must be connected and in promiscuous mode.
25  *
26  * If you run emulation in netmap mode, you need before to load the
27  * netmap.ko module. The user is responsible for configuring and building
28  * netmap separately.
29  */
30 
31 #include "ns3/abort.h"
32 #include "ns3/applications-module.h"
33 #include "ns3/core-module.h"
34 #include "ns3/fd-net-device-module.h"
35 #include "ns3/internet-apps-module.h"
36 #include "ns3/internet-module.h"
37 #include "ns3/ipv4-list-routing-helper.h"
38 #include "ns3/ipv4-static-routing-helper.h"
39 #include "ns3/network-module.h"
40 #include "ns3/traffic-control-module.h"
41 
42 #include <chrono>
43 #include <unistd.h>
44 
45 using namespace ns3;
46 
47 NS_LOG_COMPONENT_DEFINE("NetmapEmulationSendExample");
48 
49 // This function sends a number of packets by means of the SendFrom method or
50 // the Write method (depending on the level value) of a FdNetDevice or
51 // of a NetmapNetDevice (depending on the emulation mode value).
52 
53 static void
54 Send(Ptr<NetDevice> dev, int level, std::string emuMode)
55 {
56  Ptr<FdNetDevice> device = DynamicCast<FdNetDevice>(dev);
57 
58  int packets = 10000000;
59 
60  Mac48Address sender("00:00:00:aa:00:01");
61  Mac48Address receiver("ff:ff:ff:ff:ff:ff");
62 
63  int packetsSize = 64;
64  Ptr<Packet> packet = Create<Packet>(packetsSize);
65  EthernetHeader header;
66 
67  ssize_t len = (size_t)packet->GetSize();
68  auto buffer = (uint8_t*)malloc(len);
69  packet->CopyData(buffer, len);
70 
71  int sent = 0;
72  int failed = 0;
73 
74  Ptr<NetDeviceQueue> ndq = nullptr;
75  if (emuMode == "netmap")
76  {
78  ndq = ndqi->GetTxQueue(0);
79  }
80 
81  std::cout << ((level == 0) ? "Writing" : "Sending") << std::endl;
82 
83  // period to print the stats
84  std::chrono::milliseconds period(1000);
85 
86  auto t1 = std::chrono::high_resolution_clock::now();
87 
88  while (packets > 0)
89  {
90  // in case of netmap emulated device we check for
91  // available slot in the netmap transmission ring
92  if (ndq)
93  {
94  while (ndq->IsStopped())
95  {
96  usleep(10);
97  }
98  }
99 
100  if (level == 1)
101  {
102  if (!device->SendFrom(packet, sender, receiver, 0))
103  {
104  failed++;
105  }
106  sent++;
107  packet->RemoveHeader(header);
108  }
109 
110  if (level == 0)
111  {
112  if (device->Write(buffer, len) != len)
113  {
114  failed++;
115  }
116  sent++;
117  }
118 
119  auto t2 = std::chrono::high_resolution_clock::now();
120 
121  if (t2 - t1 >= period)
122  {
123  // print stats
124  std::chrono::duration<double, std::milli> dur = (t2 - t1); // in ms
125  double estimatedThr = ((sent - failed) * packetsSize * 8) / 1000000; // in Mbps
126  std::cout << sent << " packets sent in " << dur.count() << " ms, failed " << failed
127  << " (" << 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  {
169  auto raw = new EmuFdNetDeviceHelper;
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 
201  return 0;
202 }
Parse command-line arguments.
Definition: command-line.h:232
build a set of FdNetDevice objects attached to a physical network interface
void SetDeviceName(std::string deviceName)
Set the device name of this device.
Packet header for Ethernet.
build a set of FdNetDevice objects Normally we eschew multiple inheritance, however,...
virtual NetDeviceContainer Install(Ptr< Node > node) const
This method creates a FdNetDevice and associates it to a node.
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...
an EUI-48 address
Definition: mac48-address.h:46
static Mac48Address Allocate()
Allocate a new Mac48Address.
holds a vector of ns3::NetDevice pointers
Network device transmission queue interface.
build a set of FdNetDevice objects attached to a physical network interface
void SetDeviceName(std::string deviceName)
Set the device name of this device.
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:294
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition: packet.cc:400
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static void Run()
Run the simulation.
Definition: simulator.cc:178
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:186
Hold variables of type string.
Definition: string.h:56
static void Send(Ptr< NetDevice > dev, int level, std::string emuMode)
Definition: fd-emu-send.cc:54
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
devices
Definition: first.py:42
Every class exported by the ns3 library is enclosed in the ns3 namespace.
cmd
Definition: second.py:40