A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
fd-emu-tc.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 * node
22 * --------------------------------------------------
23 * | |
24 * | pfifo_fast queueDiscType [pfifo_fast]|
25 * | bql [false] |
26 * | interface 0 interface 1 |
27 * | | | |
28 * --------------------------------------------------
29 * | |
30 * 1 Gbps access incoming link | | 100 Mbps bottleneck outgoing link
31 * ----------------------------------- -----------------------------------
32 *
33 * This example builds a node with two interfaces in emulation mode in
34 * either {raw, netmap}. The aim is to explore different qdiscs behaviours
35 * on the backlog of a device emulated bottleneck side.
36 *
37 * If you run emulation in netmap mode, you need before to load the
38 * netmap.ko module. The user is responsible for configuring and building
39 * netmap separately.
40 */
41
42#include "ns3/abort.h"
43#include "ns3/core-module.h"
44#include "ns3/fd-net-device-module.h"
45#include "ns3/internet-apps-module.h"
46#include "ns3/internet-module.h"
47#include "ns3/ipv4-list-routing-helper.h"
48#include "ns3/network-module.h"
49#include "ns3/traffic-control-module.h"
50
51using namespace ns3;
52
53NS_LOG_COMPONENT_DEFINE("TrafficControlEmu");
54
55void
57{
58 Simulator::Schedule(Seconds(0.001), &TcPacketsInQueue, q, stream);
59 *stream->GetStream() << Simulator::Now().GetSeconds() << " backlog " << q->GetNPackets() << "p "
60 << q->GetNBytes() << "b "
61 << " dropped " << q->GetStats().nTotalDroppedPackets << "p "
62 << q->GetStats().nTotalDroppedBytes << "b " << std::endl;
63}
64
65#ifdef HAVE_NETMAP_USER_H
66void
68{
69 Simulator::Schedule(Seconds(0.001), &Inflight, dev, stream);
70 *stream->GetStream() << dev->GetBytesInNetmapTxRing() << std::endl;
71}
72#endif
73
74int
75main(int argc, char* argv[])
76{
77 NS_LOG_INFO("Traffic Control Emulation Example");
78
79 std::string deviceName0("enx503f56005a2a");
80 std::string deviceName1("eno1");
81 std::string ip0("10.0.1.2");
82 std::string ip1("10.0.2.1");
83 std::string mask0("255.255.255.0");
84 std::string mask1("255.255.255.0");
85 std::string m0("00:00:00:aa:00:01");
86 std::string m1("00:00:00:aa:00:02");
87 std::string queueDiscType = "PfifoFast";
88 bool bql = false;
89
90 uint32_t index = 0;
91 bool writer = true;
92#ifdef HAVE_PACKET_H
93 std::string emuMode("raw");
94#else // HAVE_NETMAP_USER_H is true (otherwise this example is not compiled)
95 std::string emuMode("netmap");
96#endif
97
99 cmd.AddValue("deviceName0", "Device name", deviceName0);
100 cmd.AddValue("deviceName1", "Device name", deviceName1);
101 cmd.AddValue("ip0", "Local IP address", ip0);
102 cmd.AddValue("ip1", "Local IP address", ip1);
103 cmd.AddValue("mask0", "Local mask", mask0);
104 cmd.AddValue("mask1", "Local mask", mask1);
105 cmd.AddValue("m0", "Mac address", m0);
106 cmd.AddValue("m1", "Mac address", m1);
107 cmd.AddValue("writer", "Enable write stats", writer);
108 cmd.AddValue("queueDiscType",
109 "Bottleneck queue disc type in {PfifoFast, ARED, CoDel, FqCoDel, PIE}",
110 queueDiscType);
111 cmd.AddValue("bql", "Enable byte queue limits on bottleneck netdevice", bql);
112 cmd.AddValue("index", "Experiment index", index);
113 cmd.AddValue("emuMode", "Emulation mode in {raw, netmap}", emuMode);
114 cmd.Parse(argc, argv);
115
116 Ipv4Address localIp0(ip0.c_str());
117 Ipv4Address localIp1(ip1.c_str());
118 Ipv4Mask netmask0(mask0.c_str());
119 Ipv4Mask netmask1(mask1.c_str());
120 Mac48AddressValue mac0(m0.c_str());
121 Mac48AddressValue mac1(m1.c_str());
122
123 //
124 // Since we are using a real piece of hardware we need to use the realtime
125 // simulator.
126 //
127 GlobalValue::Bind("SimulatorImplementationType", StringValue("ns3::RealtimeSimulatorImpl"));
128
129 //
130 // Since we are going to be talking to real-world machines, we need to enable
131 // calculation of checksums in our protocols.
132 //
133 GlobalValue::Bind("ChecksumEnabled", BooleanValue(true));
134
135 //
136 // In such a simple topology, the use of the helper API can be a hindrance
137 // so we drop down into the low level API and do it manually.
138 //
139 // First we need a single node.
140 //
141 NS_LOG_INFO("Create Node");
142 Ptr<Node> node = CreateObject<Node>();
143
144 //
145 // Create an emu device, allocate a MAC address and point the device to the
146 // Linux device name. The device needs a transmit queueing discipline so
147 // create a droptail queue and give it to the device. Finally, "install"
148 // the device into the node.
149 //
150 // Do understand that the ns-3 allocated MAC address will be sent out over
151 // your network since the emu net device will spoof it. By default, this
152 // address will have an Organizationally Unique Identifier (OUI) of zero.
153 // The Internet Assigned Number Authority IANA
154 //
155 // https://www.iana.org/assignments/ieee-802-numbers/ieee-802-numbers.txt
156 //
157 // reports that this OUI is unassigned, and so should not conflict with
158 // real hardware on your net. It may raise all kinds of red flags in a
159 // real environment to have packets from a device with an obviously bogus
160 // OUI flying around. Be aware.
161 //
162
163 NS_LOG_INFO("Create Devices");
164
165 FdNetDeviceHelper* helper0 = nullptr;
166 FdNetDeviceHelper* helper1 = nullptr;
167
168#ifdef HAVE_PACKET_H
169 if (emuMode == "raw")
170 {
171 auto raw0 = new EmuFdNetDeviceHelper;
172 raw0->SetDeviceName(deviceName0);
173 helper0 = raw0;
174
175 auto raw1 = new EmuFdNetDeviceHelper;
176 raw1->SetDeviceName(deviceName1);
177 helper1 = raw1;
178 }
179#endif
180#ifdef HAVE_NETMAP_USER_H
181 if (emuMode == "netmap")
182 {
184 netmap0->SetDeviceName(deviceName0);
185 helper0 = netmap0;
186
188 netmap1->SetDeviceName(deviceName1);
189 helper1 = netmap1;
190 }
191#endif
192
193 if ((helper0 == nullptr) || (helper1 == nullptr))
194 {
195 NS_ABORT_MSG(emuMode << " not supported.");
196 }
197
198 NetDeviceContainer devices0 = helper0->Install(node);
199 NetDeviceContainer devices1 = helper1->Install(node);
200
201 Ptr<NetDevice> device0 = devices0.Get(0);
202 device0->SetAttribute("Address", mac0);
203
204 Ptr<NetDevice> device1 = devices1.Get(0);
205 device1->SetAttribute("Address", mac1);
206
207 //
208 // Add a default internet stack to the node. This gets us the ns-3 versions
209 // of ARP, IPv4, ICMP, UDP and TCP.
210 //
211 NS_LOG_INFO("Add Internet Stack");
212 InternetStackHelper internetStackHelper;
213 internetStackHelper.Install(node);
214
215 Ptr<Ipv4> ipv4 = node->GetObject<Ipv4>();
216
217 NS_LOG_INFO("Create IPv4 Interface 0");
218 uint32_t interface0 = ipv4->AddInterface(device0);
219 Ipv4InterfaceAddress address0 = Ipv4InterfaceAddress(localIp0, netmask0);
220 ipv4->AddAddress(interface0, address0);
221 ipv4->SetMetric(interface0, 0);
222 ipv4->SetForwarding(interface0, true);
223 ipv4->SetUp(interface0);
224
225 NS_LOG_INFO("Create IPv4 Interface 1");
226 uint32_t interface1 = ipv4->AddInterface(device1);
227 Ipv4InterfaceAddress address1 = Ipv4InterfaceAddress(localIp1, netmask1);
228 ipv4->AddAddress(interface1, address1);
229 ipv4->SetMetric(interface1, 0);
230 ipv4->SetForwarding(interface1, true);
231 ipv4->SetUp(interface1);
232
234
235 // Traffic control configurations
236 // Access link side
238 tch0.SetRootQueueDisc("ns3::PfifoFastQueueDisc", "MaxSize", StringValue("1000p"));
239 tch0.Install(devices0);
240
241 // Bottleneck link side
243
244 if (queueDiscType == "PfifoFast")
245 {
246 tch1.SetRootQueueDisc("ns3::PfifoFastQueueDisc", "MaxSize", StringValue("1000p"));
247 }
248 else if (queueDiscType == "ARED")
249 {
250 tch1.SetRootQueueDisc("ns3::RedQueueDisc");
251 Config::SetDefault("ns3::RedQueueDisc::ARED", BooleanValue(true));
252 Config::SetDefault("ns3::RedQueueDisc::MaxSize",
253 QueueSizeValue(QueueSize(QueueSizeUnit::BYTES, 1000000)));
254 Config::SetDefault("ns3::RedQueueDisc::MeanPktSize", UintegerValue(1000));
255 Config::SetDefault("ns3::RedQueueDisc::LinkBandwidth", StringValue("100Mbps"));
256 Config::SetDefault("ns3::RedQueueDisc::MinTh", DoubleValue(83333));
257 Config::SetDefault("ns3::RedQueueDisc::MinTh", DoubleValue(250000));
258 }
259 else if (queueDiscType == "CoDel")
260 {
261 tch1.SetRootQueueDisc("ns3::CoDelQueueDisc");
262 }
263 else if (queueDiscType == "FqCoDel")
264 {
265 tch1.SetRootQueueDisc("ns3::FqCoDelQueueDisc");
266 }
267 else if (queueDiscType == "PIE")
268 {
269 tch1.SetRootQueueDisc("ns3::PieQueueDisc");
270 Config::SetDefault("ns3::PieQueueDisc::MaxSize",
271 QueueSizeValue(QueueSize(QueueSizeUnit::PACKETS, 1000)));
272 Config::SetDefault("ns3::PieQueueDisc::QueueDelayReference", TimeValue(Seconds(0.02)));
273 Config::SetDefault("ns3::PieQueueDisc::Tupdate", TimeValue(Seconds(0.032)));
274 Config::SetDefault("ns3::PieQueueDisc::A", DoubleValue(2));
275 Config::SetDefault("ns3::PieQueueDisc::B", DoubleValue(20));
276 }
277 else
278 {
279 NS_ABORT_MSG("--queueDiscType not valid");
280 }
281
282 if (bql)
283 {
284 tch1.SetQueueLimits("ns3::DynamicQueueLimits");
285 }
286
287 QueueDiscContainer qdiscs = tch1.Install(devices1);
288 Ptr<QueueDisc> q = qdiscs.Get(0);
289
290 if (writer)
291 {
292 AsciiTraceHelper ascii;
294 ascii.CreateFileStream("exp-" + std::to_string(index) + "-router-tc-stats.txt");
295 Simulator::Schedule(Seconds(0.001), &TcPacketsInQueue, q, stream);
296
297#ifdef HAVE_NETMAP_USER_H
298 if (emuMode.compare("netmap") == 0)
299 {
300 Ptr<NetmapNetDevice> dev = StaticCast<NetmapNetDevice>(device1);
302 ascii.CreateFileStream("exp-" + std::to_string(index) + "-router-inflight.txt");
303 Simulator::Schedule(Seconds(0.001), &Inflight, dev, stream2);
304 }
305#endif
306
307 Ptr<OutputStreamWrapper> routingStream =
308 Create<OutputStreamWrapper>("router-routes.txt", std::ios::out);
310 }
311
312 NS_LOG_INFO("Run Emulation.");
316 delete helper0;
317 delete helper1;
318 NS_LOG_INFO("Done.");
319
320 return 0;
321}
Manage ASCII trace files for device models.
Definition: trace-helper.h:174
Ptr< OutputStreamWrapper > CreateFileStream(std::string filename, std::ios::openmode filemode=std::ios::out)
Create and initialize an output stream object we'll use to write the traced bits.
AttributeValue implementation for Boolean.
Definition: boolean.h:37
Parse command-line arguments.
Definition: command-line.h:232
This class can be used to hold variables of floating point type such as 'double' or 'float'.
Definition: double.h:42
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...
aggregate IP/TCP/UDP functionality to existing Nodes.
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:42
static void PopulateRoutingTables()
Build a routing database and initialize the routing tables of the nodes in the simulation.
Access to the IPv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:80
a class to store IPv4 address information on an interface
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:257
static void PrintRoutingTableAllAt(Time printTime, Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S)
prints the routing tables of all nodes at a particular time.
AttributeValue implementation for Mac48Address.
holds a vector of ns3::NetDevice pointers
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
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.
Definition: ptr.h:77
Holds a vector of ns3::QueueDisc pointers.
Ptr< QueueDisc > Get(std::size_t i) const
Get the Ptr<QueueDisc> stored in this container at a given index.
Class for representing queue sizes.
Definition: queue-size.h:96
AttributeValue implementation for QueueSize.
Definition: queue-size.h:221
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 Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
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
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:403
AttributeValue implementation for Time.
Definition: nstime.h:1413
Build a set of QueueDisc objects.
QueueDiscContainer Install(NetDeviceContainer c)
uint16_t SetRootQueueDisc(const std::string &type, Args &&... args)
Helper function used to set a root queue disc of the given type and with the given attributes.
void SetQueueLimits(std::string type, Args &&... args)
Helper function used to add a queue limits object to the transmission queues of the devices.
Hold an unsigned integer type.
Definition: uinteger.h:45
void TcPacketsInQueue(Ptr< QueueDisc > q, Ptr< OutputStreamWrapper > stream)
Definition: fd-emu-tc.cc:56
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:894
#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
const double m1
First component modulus, 232 - 209.
Definition: rng-stream.cc:60
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ns cmd
Definition: second.py:40