OLD | NEW |
(Empty) | |
| 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 /* |
| 23 * The example is an extension of the fd-emu-ping example. |
| 24 * |
| 25 * This example shows how to use the netmap emulation capabilities. It pings |
| 26 * a real host by means the netmap emulated device on the simulation host. |
| 27 * Also, this example is used to functional testing of the netmap emulation |
| 28 * features on real device in ns-3. |
| 29 * |
| 30 * The output of this example will be a ping response in presence of UDP backgro
und |
| 31 * traffic, the backlog in packets in traffic-control qdisc and the bytes inflig
ht in the |
| 32 * netmap transmission ring. |
| 33 * |
| 34 * The user can enable BQL to reduce the bytes in flight in the netmap transmiss
ion ring |
| 35 * and keep more backlog in traffic-control qdisc. |
| 36 * |
| 37 * ... |
| 38 * 64 bytes from 10.0.1.2: icmp_seq=17 ttl=64 time=124 ms |
| 39 * 992 packets in the traffic-control queue disc |
| 40 * 366268 bytes in the netmap tx ring |
| 41 * 64 bytes from 10.0.1.2: icmp_seq=18 ttl=64 time=145 ms |
| 42 * 991 packets in the traffic-control queue disc |
| 43 * 366268 bytes in the netmap tx ring |
| 44 * 64 bytes from 10.0.1.2: icmp_seq=19 ttl=64 time=145 ms |
| 45 * 979 packets in the traffic-control queue disc |
| 46 * 366268 bytes in the netmap tx ring |
| 47 * 64 bytes from 10.0.1.2: icmp_seq=20 ttl=64 time=146 ms |
| 48 * 979 packets in the traffic-control queue disc |
| 49 * 366268 bytes in the netmap tx ring |
| 50 * 64 bytes from 10.0.1.2: icmp_seq=21 ttl=64 time=145 ms |
| 51 * 986 packets in the traffic-control queue disc |
| 52 * 366268 bytes in the netmap tx ring |
| 53 * 64 bytes from 10.0.1.2: icmp_seq=22 ttl=64 time=146 ms |
| 54 * 0 packets in the traffic-control queue disc |
| 55 * 0 bytes in the netmap tx ring |
| 56 * ... |
| 57 * |
| 58 * Requirements |
| 59 * ************ |
| 60 * This script can be used if the host machine provides a netmap installation |
| 61 * and the ns-3 configuration was made with the --enable-sudo option. |
| 62 * |
| 63 * Before to use this script, the user must load the netmap kernel module and se
t the |
| 64 * interface in promisc mode. |
| 65 * |
| 66 * Finally, the emulation in netmap mode requires that the ns-3 IP for the emula
ted interface |
| 67 * must be different from the OS IP for that interface but on the same subnet. C
onversely, the packets |
| 68 * destinated to the OS IP for that interface will be placed in the sw rings of
the netmap. |
| 69 * |
| 70 */ |
| 71 |
| 72 #include "ns3/abort.h" |
| 73 #include "ns3/core-module.h" |
| 74 #include "ns3/internet-module.h" |
| 75 #include "ns3/network-module.h" |
| 76 #include "ns3/fd-net-device-module.h" |
| 77 #include "ns3/internet-apps-module.h" |
| 78 #include "ns3/ipv4-static-routing-helper.h" |
| 79 #include "ns3/ipv4-list-routing-helper.h" |
| 80 #include "ns3/applications-module.h" |
| 81 #include "ns3/traffic-control-module.h" |
| 82 |
| 83 using namespace ns3; |
| 84 |
| 85 NS_LOG_COMPONENT_DEFINE ("NetmapEmulationPingExample"); |
| 86 |
| 87 static void |
| 88 StatsSampling (Ptr<QueueDisc> qdisc, Ptr<NetDevice> device, double samplingPerio
d) |
| 89 { |
| 90 Simulator::Schedule (Seconds (samplingPeriod), &StatsSampling, qdisc, device,
samplingPeriod); |
| 91 Ptr<NetmapNetDevice> d = DynamicCast<NetmapNetDevice> (device); |
| 92 |
| 93 std::cout << qdisc->GetNPackets () << " packets in the traffic-control queue d
isc" << std::endl; |
| 94 if (d) |
| 95 { |
| 96 std::cout << d->GetBytesInNetmapTxRing () << " bytes inflight in the netma
p tx ring" << std::endl; |
| 97 } |
| 98 } |
| 99 |
| 100 static void |
| 101 PingRtt (std::string context, Time rtt) |
| 102 { |
| 103 NS_LOG_UNCOND ("Received Response with RTT = " << rtt); |
| 104 } |
| 105 |
| 106 int |
| 107 main (int argc, char *argv[]) |
| 108 { |
| 109 NS_LOG_INFO ("Netmap Emulation Ping Example"); |
| 110 |
| 111 std::string deviceName ("eno1"); |
| 112 // ping a real host connected back-to-back through the ethernet interfaces |
| 113 std::string remote ("10.0.1.2"); |
| 114 |
| 115 double samplingPeriod = 0.5; // s |
| 116 uint32_t packetsSize = 1400; // bytes |
| 117 bool bql = false; |
| 118 |
| 119 CommandLine cmd; |
| 120 cmd.AddValue ("deviceName", "Device name", deviceName); |
| 121 cmd.AddValue ("remote", "Remote IP address (dotted decimal only please)", remo
te); |
| 122 cmd.AddValue ("bql", "Enable byte queue limits", bql); |
| 123 cmd.Parse (argc, argv); |
| 124 |
| 125 Ipv4Address remoteIp (remote.c_str ()); |
| 126 // the OS IP for the eth0 interfaces is 10.0.1.1, and we set the ns-3 IP for e
th0 to 10.0.1.11 |
| 127 Ipv4Address localIp ("10.0.1.11"); |
| 128 NS_ABORT_MSG_IF (localIp == "1.2.3.4", "You must change the local IP address b
efore running this example"); |
| 129 |
| 130 Ipv4Mask localMask ("255.255.255.0"); |
| 131 |
| 132 // |
| 133 // Since we are using a real piece of hardware we need to use the realtime |
| 134 // simulator. |
| 135 // |
| 136 GlobalValue::Bind ("SimulatorImplementationType", StringValue ("ns3::RealtimeS
imulatorImpl")); |
| 137 |
| 138 // |
| 139 // Since we are going to be talking to real-world machines, we need to enable |
| 140 // calculation of checksums in our protocols. |
| 141 // |
| 142 GlobalValue::Bind ("ChecksumEnabled", BooleanValue (true)); |
| 143 |
| 144 // |
| 145 // In such a simple topology, the use of the helper API can be a hindrance |
| 146 // so we drop down into the low level API and do it manually. |
| 147 // |
| 148 // First we need a single node. |
| 149 // |
| 150 NS_LOG_INFO ("Create Node"); |
| 151 Ptr<Node> node = CreateObject<Node> (); |
| 152 |
| 153 // |
| 154 // Create an emu device, allocate a MAC address and point the device to the |
| 155 // Linux device name. The device needs a transmit queueing discipline so |
| 156 // create a droptail queue and give it to the device. Finally, "install" |
| 157 // the device into the node. |
| 158 // |
| 159 // Do understand that the ns-3 allocated MAC address will be sent out over |
| 160 // your network since the emu net device will spoof it. By default, this |
| 161 // address will have an Organizationally Unique Identifier (OUI) of zero. |
| 162 // The Internet Assigned Number Authority IANA |
| 163 // |
| 164 // http://www.iana.org/assignments/ethernet-numbers |
| 165 // |
| 166 // reports that this OUI is unassigned, and so should not conflict with |
| 167 // real hardware on your net. It may raise all kinds of red flags in a |
| 168 // real environment to have packets from a device with an obviously bogus |
| 169 // OUI flying around. Be aware. |
| 170 // |
| 171 NS_LOG_INFO ("Create Device"); |
| 172 EmuFdNetDeviceHelper emu; |
| 173 |
| 174 // set the netmap emulation mode |
| 175 emu.SetNetmapMode (); |
| 176 |
| 177 emu.SetDeviceName (deviceName); |
| 178 NetDeviceContainer devices = emu.Install (node); |
| 179 Ptr<NetDevice> device = devices.Get (0); |
| 180 device->SetAttribute ("Address", Mac48AddressValue (Mac48Address::Allocate ())
); |
| 181 |
| 182 //Ptr<Queue> queue = CreateObject<DropTailQueue> (); |
| 183 //device->SetQueue (queue); |
| 184 //node->AddDevice (device); |
| 185 |
| 186 // |
| 187 // Add a default internet stack to the node. This gets us the ns-3 versions |
| 188 // of ARP, IPv4, ICMP, UDP and TCP. |
| 189 // |
| 190 NS_LOG_INFO ("Add Internet Stack"); |
| 191 InternetStackHelper internetStackHelper; |
| 192 internetStackHelper.Install (node); |
| 193 |
| 194 // we install the pfifo_fast queue disc on the netmap emulated device and we s
ample the |
| 195 // queue disc backlog in packets and the inflight in the netmap tx ring in byt
es |
| 196 TrafficControlHelper tch; |
| 197 tch.SetRootQueueDisc ("ns3::PfifoFastQueueDisc"); |
| 198 if (bql) |
| 199 { |
| 200 tch.SetQueueLimits ("ns3::DynamicQueueLimits"); |
| 201 } |
| 202 |
| 203 QueueDiscContainer qdiscs = tch.Install (devices); |
| 204 Simulator::Schedule (Seconds (samplingPeriod), &StatsSampling, qdiscs.Get (0),
device, samplingPeriod); |
| 205 |
| 206 NS_LOG_INFO ("Create IPv4 Interface"); |
| 207 Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> (); |
| 208 uint32_t interface = ipv4->AddInterface (device); |
| 209 Ipv4InterfaceAddress address = Ipv4InterfaceAddress (localIp, localMask); |
| 210 ipv4->AddAddress (interface, address); |
| 211 ipv4->SetMetric (interface, 1); |
| 212 ipv4->SetUp (interface); |
| 213 |
| 214 // |
| 215 // When the ping application sends its ICMP packet, it will happily send it |
| 216 // down the ns-3 protocol stack. We set the IP address of the destination |
| 217 // to the address corresponding to example.com above. This address is off |
| 218 // our local network so we have got to provide some kind of default route |
| 219 // to ns-3 to be able to get that ICMP packet forwarded off of our network. |
| 220 // |
| 221 // You have got to provide an IP address of a real host that you can send |
| 222 // real packets to and have them forwarded off of your local network. One |
| 223 // thing you could do is a 'netstat -rn' command and find the IP address of |
| 224 // the default gateway on your host and add it below, replacing the |
| 225 // "1.2.3.4" string. |
| 226 // |
| 227 Ipv4Address gateway ("10.0.1.2"); |
| 228 NS_ABORT_MSG_IF (gateway == "1.2.3.4", "You must change the gateway IP address
before running this example"); |
| 229 |
| 230 Ipv4StaticRoutingHelper ipv4RoutingHelper; |
| 231 Ptr<Ipv4StaticRouting> staticRouting = ipv4RoutingHelper.GetStaticRouting (ipv
4); |
| 232 staticRouting->SetDefaultRoute (gateway, interface); |
| 233 |
| 234 // |
| 235 // Create the ping application. This application knows how to send |
| 236 // ICMP echo requests. Setting up the packet sink manually is a bit |
| 237 // of a hassle and since there is no law that says we cannot mix the |
| 238 // helper API with the low level API, let's just use the helper. |
| 239 // |
| 240 NS_LOG_INFO ("Create V4Ping Appliation"); |
| 241 Ptr<V4Ping> app = CreateObject<V4Ping> (); |
| 242 app->SetAttribute ("Remote", Ipv4AddressValue (remoteIp)); |
| 243 app->SetAttribute ("Verbose", BooleanValue (true) ); |
| 244 app->SetAttribute ("Interval", TimeValue (Seconds (samplingPeriod))); |
| 245 node->AddApplication (app); |
| 246 app->SetStartTime (Seconds (1.0)); |
| 247 app->SetStopTime (Seconds (21.0)); |
| 248 |
| 249 // |
| 250 // Give the application a name. This makes life much easier when constructing |
| 251 // config paths. |
| 252 // |
| 253 Names::Add ("app", app); |
| 254 |
| 255 // |
| 256 // Hook a trace to print something when the response comes back. |
| 257 // |
| 258 Config::Connect ("/Names/app/Rtt", MakeCallback (&PingRtt)); |
| 259 |
| 260 Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (packetsSize)
); |
| 261 |
| 262 // UDP traffic load |
| 263 OnOffHelper onoff ("ns3::UdpSocketFactory", Ipv4Address::GetAny ()); |
| 264 onoff.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Const
ant=1]")); |
| 265 onoff.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Const
ant=0]")); |
| 266 onoff.SetAttribute ("PacketSize", UintegerValue (packetsSize)); |
| 267 onoff.SetAttribute ("DataRate", StringValue ("100Mbps")); |
| 268 ApplicationContainer apps; |
| 269 |
| 270 InetSocketAddress rmt (remoteIp, 7000); |
| 271 // rmt.SetTos (0xb8); |
| 272 AddressValue remoteAddress (rmt); |
| 273 onoff.SetAttribute ("Remote", remoteAddress); |
| 274 |
| 275 apps.Add (onoff.Install (node)); |
| 276 apps.Start (Seconds (7.0)); |
| 277 apps.Stop (Seconds (12.0)); |
| 278 |
| 279 // |
| 280 // Enable a promiscuous pcap trace to see what is coming and going on our devi
ce. |
| 281 // |
| 282 emu.EnablePcap ("netmap-emu-ping", device, true); |
| 283 |
| 284 // |
| 285 // Now, do the actual emulation. |
| 286 // |
| 287 NS_LOG_INFO ("Run Emulation."); |
| 288 Simulator::Stop (Seconds (22.0)); |
| 289 Simulator::Run (); |
| 290 Simulator::Destroy (); |
| 291 NS_LOG_INFO ("Done."); |
| 292 } |
OLD | NEW |