A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Pasquale Imputato <p.imputato@gmail.com>
7 */
8
9/*
10 * This example builds a node with a device in emulation mode in {raw, netmap}.
11 * The aim is to measure the maximum tx rate in pps achievable with
12 * NetmapNetDevice and FdNetDevice on a specific machine.
13 * The emulated device must be connected and in promiscuous mode.
14 *
15 * If you run emulation in netmap mode, you need before to load the
16 * netmap.ko module. The user is responsible for configuring and building
17 * netmap separately.
18 */
19
20#include "ns3/abort.h"
21#include "ns3/applications-module.h"
22#include "ns3/core-module.h"
23#include "ns3/fd-net-device-module.h"
24#include "ns3/internet-apps-module.h"
25#include "ns3/internet-module.h"
26#include "ns3/ipv4-list-routing-helper.h"
27#include "ns3/ipv4-static-routing-helper.h"
28#include "ns3/network-module.h"
29#include "ns3/traffic-control-module.h"
30
31#include <chrono>
32#include <unistd.h>
33
34using namespace ns3;
35
36NS_LOG_COMPONENT_DEFINE("NetmapEmulationSendExample");
37
38// This function sends a number of packets by means of the SendFrom method or
39// the Write method (depending on the level value) of a FdNetDevice or
40// of a NetmapNetDevice (depending on the emulation mode value).
41
42static void
43Send(Ptr<NetDevice> dev, int level, std::string emuMode)
44{
46
47 int packets = 10000000;
48
49 Mac48Address sender("00:00:00:aa:00:01");
50 Mac48Address receiver("ff:ff:ff:ff:ff:ff");
51
52 int packetsSize = 64;
53 Ptr<Packet> packet = Create<Packet>(packetsSize);
54 EthernetHeader header;
55
56 ssize_t len = (size_t)packet->GetSize();
57 auto buffer = (uint8_t*)malloc(len);
58 packet->CopyData(buffer, len);
59
60 int sent = 0;
61 int failed = 0;
62
63 Ptr<NetDeviceQueue> ndq = nullptr;
64 if (emuMode == "netmap")
65 {
67 ndq = ndqi->GetTxQueue(0);
68 }
69
70 std::cout << ((level == 0) ? "Writing" : "Sending") << std::endl;
71
72 // period to print the stats
73 std::chrono::milliseconds period(1000);
74
75 auto t1 = std::chrono::high_resolution_clock::now();
76
77 while (packets > 0)
78 {
79 // in case of netmap emulated device we check for
80 // available slot in the netmap transmission ring
81 if (ndq)
82 {
83 while (ndq->IsStopped())
84 {
85 usleep(10);
86 }
87 }
88
89 if (level == 1)
90 {
91 if (!device->SendFrom(packet, sender, receiver, 0))
92 {
93 failed++;
94 }
95 sent++;
96 packet->RemoveHeader(header);
97 }
98
99 if (level == 0)
100 {
101 if (device->Write(buffer, len) != len)
102 {
103 failed++;
104 }
105 sent++;
106 }
107
108 auto t2 = std::chrono::high_resolution_clock::now();
109
110 if (t2 - t1 >= period)
111 {
112 // print stats
113 std::chrono::duration<double, std::milli> dur = (t2 - t1); // in ms
114 double estimatedThr = ((sent - failed) * packetsSize * 8) / 1000000; // in Mbps
115 std::cout << sent << " packets sent in " << dur.count() << " ms, failed " << failed
116 << " (" << estimatedThr << " Mbps estimated throughput)" << std::endl;
117 sent = 0;
118 failed = 0;
119 t1 = std::chrono::high_resolution_clock::now();
120 }
121 packets--;
122 }
123}
124
125int
126main(int argc, char* argv[])
127{
128 std::string deviceName("eno1");
129 int level = 0;
130
131#ifdef HAVE_PACKET_H
132 std::string emuMode("raw");
133#else // HAVE_NETMAP_USER_H is true (otherwise this example is not compiled)
134 std::string emuMode("netmap");
135#endif
136
138 cmd.AddValue("deviceName", "Device name", deviceName);
139 cmd.AddValue("level", "Enable send (1) or write (0) level test", level);
140 cmd.AddValue("emuMode", "Emulation mode in {raw, netmap}", emuMode);
141
142 cmd.Parse(argc, argv);
143
144 GlobalValue::Bind("SimulatorImplementationType", StringValue("ns3::RealtimeSimulatorImpl"));
145
146 GlobalValue::Bind("ChecksumEnabled", BooleanValue(true));
147
148 NS_LOG_INFO("Create Node");
150
151 NS_LOG_INFO("Create Device");
152
153 FdNetDeviceHelper* helper = nullptr;
154
155#ifdef HAVE_PACKET_H
156 if (emuMode == "raw")
157 {
158 auto raw = new EmuFdNetDeviceHelper;
159 raw->SetDeviceName(deviceName);
160 helper = raw;
161 }
162#endif
163#ifdef HAVE_NETMAP_USER_H
164 if (emuMode == "netmap")
165 {
167 netmap->SetDeviceName(deviceName);
168 helper = netmap;
169 }
170#endif
171
172 if (helper == nullptr)
173 {
174 NS_ABORT_MSG(emuMode << " not supported.");
175 }
176
177 NetDeviceContainer devices = helper->Install(node);
178 Ptr<NetDevice> device = devices.Get(0);
179 device->SetAttribute("Address", Mac48AddressValue(Mac48Address::Allocate()));
180
181 Simulator::Schedule(Seconds(3), &Send, device, level, emuMode);
182
183 NS_LOG_INFO("Run Emulation.");
187 delete helper;
188 NS_LOG_INFO("Done.");
189
190 return 0;
191}
Parse command-line arguments.
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
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.
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition simulator.h:560
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static void Run()
Run the simulation.
Definition simulator.cc:167
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:175
Hold variables of type string.
Definition string.h:45
static void Send(Ptr< NetDevice > dev, int level, std::string emuMode)
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
devices
Definition first.py:31
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580