A Discrete-Event Network Simulator
API
fd-emu-onoff.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 University of Washington, 2012 INRIA
3  * 2017 Università' degli Studi di Napoli Federico II
4  * 2019 NITK Surathkal
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation;
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Author: Alina Quereilhac <alina.quereilhac@inria.fr>
20  * Extended by: Pasquale Imputato <p.imputato@gmail.com>
21  * Harsh Patel <thadodaharsh10@gmail.com>
22  * Hrishikesh Hiraskar <hrishihiraskar@gmail.com>
23  * Mohit P. Tahiliani <tahiliani@nitk.edu.in>
24  *
25  */
26 
27 // +----------------------+ +-----------------------+
28 // | client host | | server host |
29 // +----------------------+ +-----------------------+
30 // | ns-3 Node 0 | | ns-3 Node 1 |
31 // | +----------------+ | | +----------------+ |
32 // | | ns-3 TCP | | | | ns-3 TCP | |
33 // | +----------------+ | | +----------------+ |
34 // | | ns-3 IPv4 | | | | ns-3 IPv4 | |
35 // | +----------------+ | | +----------------+ |
36 // | | FdNetDevice | | | | FdNetDevice | |
37 // | | or | | | | or | |
38 // | | NetmapNetDevice| | | | NetmapNetDevice| |
39 // | | or | | | | or | |
40 // | | DpdkNetDevice | | | | DpdkNetDevice | |
41 // | | 10.1.1.1 | | | | 10.1.1.2 | |
42 // | +----------------+ | | +----------------+ |
43 // | | fd | | | | fd | |
44 // | | or | | | | or | |
45 // | | EAL | | | | EAL | |
46 // | +----------------+ | | +----------------+ |
47 // | | eth0 | | | | eth0 | |
48 // | | or | | | | or | |
49 // | | 0000:00.1f | | | | 0000:00.1f | |
50 // +----+------------+----+ +-----+------------+----+
51 //
52 // 10.1.1.11 10.1.1.12
53 //
54 // | |
55 // +----------------------------+
56 //
57 // This example is aimed at measuring the throughput of the FdNetDevice
58 // when using the EmuFdNetDeviceHelper. This is achieved by saturating
59 // the channel with TCP traffic. Then the throughput can be obtained from
60 // the generated .pcap files.
61 //
62 // To run this example you will need two hosts (client & server).
63 // Steps to run the experiment:
64 //
65 // 1 - Connect the 2 computers with an Ethernet cable.
66 // 2 - Set the IP addresses on both Ethernet devices.
67 //
68 // client machine: $ sudo ip addr add dev eth0 10.1.1.11/24
69 // server machine: $ sudo ip addr add dev eth0 10.1.1.12/24
70 //
71 // 3 - Set both Ethernet devices to promiscuous mode.
72 //
73 // both machines: $ sudo ip link set eth0 promisc on
74 //
75 // 3' - If you run emulation in netmap or dpdk mode, you need before to load
76 // the netmap.ko or dpdk modules. The user is in charge to configure and
77 // build netmap/dpdk separately.
78 //
79 // 4 - Give root suid to the raw or netmap socket creator binary.
80 // If the --enable-sudo option was used to configure ns-3 with ns3, then the following
81 // step will not be necessary.
82 //
83 // both hosts: $ sudo chown root.root build/src/fd-net-device/ns3-dev-raw-sock-creator
84 // both hosts: $ sudo chmod 4755 build/src/fd-net-device/ns3-dev-raw-sock-creator
85 //
86 // or (if you run emulation in netmap mode):
87 // both hosts: $ sudo chown root.root build/src/fd-net-device/ns3-dev-netmap-device-creator
88 // both hosts: $ sudo chmod 4755 build/src/fd-net-device/ns3-dev-netmap-device-creator
89 //
90 // 4' - If you run emulation in dpdk mode, you will need to run example as root.
91 //
92 // 5 - In case of DpdkNetDevice, use device address instead of device name
93 //
94 // For example: 0000:00:1f.6 (can be obtained by lspci)
95 //
96 // 6 - Run the server side:
97 //
98 // server host: $ ./ns3 run "fd-emu-onoff --serverMode=1"
99 //
100 // 7 - Run the client side:
101 //
102 // client host: $ ./ns3 run "fd-emu-onoff"
103 //
104 
105 #include "ns3/applications-module.h"
106 #include "ns3/config-store-module.h"
107 #include "ns3/core-module.h"
108 #include "ns3/fd-net-device-module.h"
109 #include "ns3/internet-module.h"
110 #include "ns3/network-module.h"
111 
112 #include <fstream>
113 #include <iostream>
114 #include <string>
115 #include <vector>
116 
117 using namespace ns3;
118 
119 NS_LOG_COMPONENT_DEFINE("EmuFdNetDeviceSaturationExample");
120 
121 int
122 main(int argc, char* argv[])
123 {
124  uint16_t sinkPort = 8000;
125  uint32_t packetSize = 1400; // bytes
126  std::string dataRate("1000Mb/s");
127  bool serverMode = false;
128 
129  std::string deviceName("eth0");
130  std::string client("10.1.1.1");
131  std::string server("10.1.1.2");
132  std::string netmask("255.255.255.0");
133  std::string macClient("00:00:00:00:00:01");
134  std::string macServer("00:00:00:00:00:02");
135  std::string transportProt = "Tcp";
136  std::string socketType;
137 #ifdef HAVE_PACKET_H
138  std::string emuMode("raw");
139 #elif HAVE_NETMAP_USER_H
140  std::string emuMode("netmap");
141 #else // HAVE_DPDK_USER_H is true (otherwise this example is not compiled)
142  std::string emuMode("dpdk");
143 #endif
144 
145  CommandLine cmd(__FILE__);
146  cmd.AddValue("deviceName",
147  "Device name (in raw, netmap mode) or Device address (in dpdk mode, eg: "
148  "0000:00:1f.6). Use `lspci` to find device address.",
149  deviceName);
150  cmd.AddValue("client", "Local IP address (dotted decimal only please)", client);
151  cmd.AddValue("server", "Remote IP address (dotted decimal only please)", server);
152  cmd.AddValue("localmask", "Local mask address (dotted decimal only please)", netmask);
153  cmd.AddValue("serverMode", "1:true, 0:false, default client", serverMode);
154  cmd.AddValue("mac-client", "Mac Address for Server Client : 00:00:00:00:00:01", macClient);
155  cmd.AddValue("mac-server", "Mac Address for Server Default : 00:00:00:00:00:02", macServer);
156  cmd.AddValue("data-rate", "Data rate defaults to 1000Mb/s", dataRate);
157  cmd.AddValue("transportProt", "Transport protocol to use: Tcp, Udp", transportProt);
158  cmd.AddValue("emuMode", "Emulation mode in {raw, netmap}", emuMode);
159  cmd.Parse(argc, argv);
160 
161  if (transportProt == "Tcp")
162  {
163  socketType = "ns3::TcpSocketFactory";
164  }
165  else
166  {
167  socketType = "ns3::UdpSocketFactory";
168  }
169 
170  Ipv4Address remoteIp;
171  Ipv4Address localIp;
172  Mac48AddressValue localMac;
173 
174  Config::SetDefault("ns3::TcpSocket::SegmentSize", UintegerValue(packetSize));
175 
176  if (serverMode)
177  {
178  remoteIp = Ipv4Address(client.c_str());
179  localIp = Ipv4Address(server.c_str());
180  localMac = Mac48AddressValue(macServer.c_str());
181  }
182  else
183  {
184  remoteIp = Ipv4Address(server.c_str());
185  localIp = Ipv4Address(client.c_str());
186  localMac = Mac48AddressValue(macClient.c_str());
187  }
188 
189  Ipv4Mask localMask(netmask.c_str());
190 
191  GlobalValue::Bind("SimulatorImplementationType", StringValue("ns3::RealtimeSimulatorImpl"));
192 
193  GlobalValue::Bind("ChecksumEnabled", BooleanValue(true));
194 
195  NS_LOG_INFO("Create Node");
196  Ptr<Node> node = CreateObject<Node>();
197 
198  NS_LOG_INFO("Create Device");
199  FdNetDeviceHelper* helper = nullptr;
200 
201 #ifdef HAVE_PACKET_H
202  if (emuMode == "raw")
203  {
205  raw->SetDeviceName(deviceName);
206  helper = raw;
207  }
208 #endif
209 #ifdef HAVE_NETMAP_USER_H
210  if (emuMode == "netmap")
211  {
213  netmap->SetDeviceName(deviceName);
214  helper = netmap;
215  }
216 #endif
217 #ifdef HAVE_DPDK_USER_H
218  if (emuMode == "dpdk")
219  {
221  // Use e1000 driver library (this is for IGb PMD supporting Intel 1GbE NIC)
222  // NOTE: DPDK supports multiple Poll Mode Drivers (PMDs) and you can use it
223  // based on your NIC. You just need to set pmd library as follows:
224  dpdk->SetPmdLibrary("librte_pmd_e1000.so");
225  // Set dpdk driver to use for the NIC. `uio_pci_generic` supports most NICs.
226  dpdk->SetDpdkDriver("uio_pci_generic");
227  // Set device name
228  dpdk->SetDeviceName(deviceName);
229  helper = dpdk;
230  }
231 #endif
232 
233  if (helper == nullptr)
234  {
235  NS_ABORT_MSG(emuMode << " not supported.");
236  }
237 
238  NetDeviceContainer devices = helper->Install(node);
239  Ptr<NetDevice> device = devices.Get(0);
240  device->SetAttribute("Address", localMac);
241 
242  NS_LOG_INFO("Add Internet Stack");
243  InternetStackHelper internetStackHelper;
244  internetStackHelper.SetIpv4StackInstall(true);
245  internetStackHelper.Install(node);
246 
247  NS_LOG_INFO("Create IPv4 Interface");
248  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4>();
249  uint32_t interface = ipv4->AddInterface(device);
250  Ipv4InterfaceAddress address = Ipv4InterfaceAddress(localIp, localMask);
251  ipv4->AddAddress(interface, address);
252  ipv4->SetMetric(interface, 1);
253  ipv4->SetUp(interface);
254 
255  if (serverMode)
256  {
257  Address sinkLocalAddress(InetSocketAddress(localIp, sinkPort));
258  PacketSinkHelper sinkHelper(socketType, sinkLocalAddress);
259  ApplicationContainer sinkApp = sinkHelper.Install(node);
260  sinkApp.Start(Seconds(1.0));
261  sinkApp.Stop(Seconds(60.0));
262 
263  helper->EnablePcap("fd-server", device);
264  }
265  else
266  {
267  AddressValue remoteAddress(InetSocketAddress(remoteIp, sinkPort));
268  OnOffHelper onoff(socketType, Address());
269  onoff.SetAttribute("Remote", remoteAddress);
270  onoff.SetAttribute("OnTime", StringValue("ns3::ConstantRandomVariable[Constant=1]"));
271  onoff.SetAttribute("OffTime", StringValue("ns3::ConstantRandomVariable[Constant=0]"));
272  onoff.SetAttribute("DataRate", DataRateValue(dataRate));
273  onoff.SetAttribute("PacketSize", UintegerValue(packetSize));
274 
275  ApplicationContainer clientApps = onoff.Install(node);
276  clientApps.Start(Seconds(4.0));
277  clientApps.Stop(Seconds(58.0));
278 
279  helper->EnablePcap("fd-client", device);
280  }
281 
282  Simulator::Stop(Seconds(61.0));
283  Simulator::Run();
285  delete helper;
286 
287  return 0;
288 }
a polymophic address class
Definition: address.h:100
AttributeValue implementation for Address.
holds a vector of ns3::Application pointers.
void Start(Time start) const
Start all of the Applications in this container at the start time given as a parameter.
void Stop(Time stop) const
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Parse command-line arguments.
Definition: command-line.h:232
AttributeValue implementation for DataRate.
build a DpdkNetDevice object attached to a physical network interface
void SetPmdLibrary(std::string pmdLibrary)
Sets PMD Library to be used for the NIC.
void SetDpdkDriver(std::string dpdkDriver)
Sets DPDK Driver to bind NIC to.
build a set of FdNetDevice objects attached to a physical network interface
void SetDeviceName(std::string deviceName)
Set the device name of this device.
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 Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
void SetIpv4StackInstall(bool enable)
Enable/disable IPv4 stack install.
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:43
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:79
a class to store IPv4 address information on an interface
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:258
AttributeValue implementation for Mac48Address.
holds a vector of ns3::NetDevice pointers
build a set of FdNetDevice objects attached to a physical network interface
void SetDeviceName(std::string deviceName)
Set the device name of this device.
Ptr< T > GetObject() const
Get a pointer to the requested aggregated Object.
Definition: object.h:471
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
Definition: on-off-helper.h:44
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
void EnablePcap(std::string prefix, Ptr< NetDevice > nd, bool promiscuous=false, bool explicitFilename=false)
Enable pcap output the indicated net device.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:140
static void Run()
Run the simulation.
Definition: simulator.cc:176
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:184
Hold variables of type string.
Definition: string.h:56
Hold an unsigned integer type.
Definition: uinteger.h:45
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:891
#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:1336
address
Definition: first.py:40
clientApps
Definition: first.py:58
devices
Definition: first.py:35
Every class exported by the ns3 library is enclosed in the ns3 namespace.
cmd
Definition: second.py:33
static const uint32_t packetSize
Packet size generated at the AP.