A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
virtual-net-device-example.cc
Go to the documentation of this file.
1/*
2 * SPDX-License-Identifier: GPL-2.0-only
3 *
4 * Based on simple-global-routing.cc
5 * The Tunnel class adds two tunnels, n0<=>n3 and n1<=>n3
6 */
7
8// Network topology
9//
10// n0
11// \ 5 Mb/s, 2ms
12// \ 1.5Mb/s, 10ms
13// n2 -------------------------n3
14// /
15// / 5 Mb/s, 2ms
16// n1
17//
18// - all links are point-to-point links with indicated one-way BW/delay
19// - Tracing of queues and packet receptions to file "virtual-net-device.tr"
20
21// Tunneling changes (relative to the simple-global-routing example):
22// - n0 will receive an extra virtual interface with hardcoded inner-tunnel address 11.0.0.1
23// - n1 will also receive an extra virtual interface with the same inner-tunnel address 11.0.0.1
24// - n3 will receive an extra virtual interface with inner-tunnel address 11.0.0.254
25// - The flows will be between 11.0.0.x (inner-tunnel) addresses instead of 10.1.x.y ones
26// - n3 will decide, on a per-packet basis, via random number, whether to
27// send the packet to n0 or to n1.
28//
29// Note: here we create a tunnel where IP packets are tunneled over
30// UDP/IP, but tunneling directly IP-over-IP would also be possible;
31// see src/node/ipv4-raw-socket-factory.h.
32
33#include "ns3/applications-module.h"
34#include "ns3/core-module.h"
35#include "ns3/internet-module.h"
36#include "ns3/network-module.h"
37#include "ns3/point-to-point-module.h"
38#include "ns3/virtual-net-device.h"
39
40#include <cassert>
41#include <fstream>
42#include <iostream>
43#include <string>
44
45using namespace ns3;
46
47NS_LOG_COMPONENT_DEFINE("VirtualNetDeviceExample");
48
49/**
50 * \ingroup virtual-net-device
51 *
52 * Tunnel class - its goal is to create and manage the tunnels between endpoints.
53 */
54class Tunnel
55{
56 Ptr<Socket> m_n3Socket; //!< Socket on the N3 node
57 Ptr<Socket> m_n0Socket; //!< Socket on the N0 node
58 Ptr<Socket> m_n1Socket; //!< Socket on the N1 node
59 Ipv4Address m_n3Address; //!< Address of the N3 node
60 Ipv4Address m_n0Address; //!< Address of the N0 node
61 Ipv4Address m_n1Address; //!< Address of the N1 node
62 Ptr<UniformRandomVariable> m_rng; //!< Random number generator
63 Ptr<VirtualNetDevice> m_n0Tap; //!< VirtualNetDevice on the N0 node
64 Ptr<VirtualNetDevice> m_n1Tap; //!< VirtualNetDevice on the N1 node
65 Ptr<VirtualNetDevice> m_n3Tap; //!< VirtualNetDevice on the N3 node
66
67 /**
68 * Send a packet through the N0 VirtualNetDevice
69 * \param packet Packet to send
70 * \param source Source IPv4 address
71 * \param dest Destination IPv4 address
72 * \param protocolNumber Protocol number
73 * \return true (always)
74 */
76 const Address& source,
77 const Address& dest,
78 uint16_t protocolNumber)
79 {
80 NS_LOG_DEBUG("Send to " << m_n3Address << ": " << *packet);
82 return true;
83 }
84
85 /**
86 * Send a packet through the N1 VirtualNetDevice
87 * \param packet Packet to send
88 * \param source Source IPv4 address
89 * \param dest Destination IPv4 address
90 * \param protocolNumber Protocol number
91 * \return true (always)
92 */
94 const Address& source,
95 const Address& dest,
96 uint16_t protocolNumber)
97 {
98 NS_LOG_DEBUG("Send to " << m_n3Address << ": " << *packet);
100 return true;
101 }
102
103 /**
104 * Send a packet through the N3 VirtualNetDevice
105 * \param packet Packet to send
106 * \param source Source IPv4 address
107 * \param dest Destination IPv4 address
108 * \param protocolNumber Protocol number
109 * \return true (always)
110 */
112 const Address& source,
113 const Address& dest,
114 uint16_t protocolNumber)
115 {
116 if (m_rng->GetValue() < 0.25)
117 {
118 NS_LOG_DEBUG("Send to " << m_n0Address << ": " << *packet);
120 }
121 else
122 {
123 NS_LOG_DEBUG("Send to " << m_n1Address << ": " << *packet);
125 }
126 return true;
127 }
128
129 /**
130 * Receive a packet on the N3 VirtualNetDevice
131 * \param socket Receiving socket
132 */
134 {
135 Ptr<Packet> packet = socket->Recv(65535, 0);
136 NS_LOG_DEBUG("N3SocketRecv: " << *packet);
137 m_n3Tap->Receive(packet,
138 0x0800,
139 m_n3Tap->GetAddress(),
140 m_n3Tap->GetAddress(),
142 }
143
144 /**
145 * Receive a packet on the N0 VirtualNetDevice
146 * \param socket Receiving socket
147 */
149 {
150 Ptr<Packet> packet = socket->Recv(65535, 0);
151 NS_LOG_DEBUG("N0SocketRecv: " << *packet);
152 m_n0Tap->Receive(packet,
153 0x0800,
154 m_n0Tap->GetAddress(),
155 m_n0Tap->GetAddress(),
157 }
158
159 /**
160 * Receive a packet on the N1 VirtualNetDevice
161 * \param socket Receiving socket
162 */
164 {
165 Ptr<Packet> packet = socket->Recv(65535, 0);
166 NS_LOG_DEBUG("N1SocketRecv: " << *packet);
167 m_n1Tap->Receive(packet,
168 0x0800,
169 m_n1Tap->GetAddress(),
170 m_n1Tap->GetAddress(),
172 }
173
174 public:
175 /**
176 * Constructor
177 * \param n3 Pointer of Node 3
178 * \param n0 Pointer of Node 0
179 * \param n1 Pointer of Node 1
180 * \param n3Addr IPv4 address of Node 3
181 * \param n0Addr IPv4 address of Node 0
182 * \param n1Addr IPv4 address of Node 1
183 */
185 Ptr<Node> n0,
186 Ptr<Node> n1,
187 Ipv4Address n3Addr,
188 Ipv4Address n0Addr,
189 Ipv4Address n1Addr)
190 : m_n3Address(n3Addr),
191 m_n0Address(n0Addr),
192 m_n1Address(n1Addr)
193 {
195 m_n3Socket = Socket::CreateSocket(n3, TypeId::LookupByName("ns3::UdpSocketFactory"));
198
199 m_n0Socket = Socket::CreateSocket(n0, TypeId::LookupByName("ns3::UdpSocketFactory"));
202
203 m_n1Socket = Socket::CreateSocket(n1, TypeId::LookupByName("ns3::UdpSocketFactory"));
206
207 // n0 tap device
209 m_n0Tap->SetAddress(Mac48Address("11:00:01:02:03:01"));
210 m_n0Tap->SetSendCallback(MakeCallback(&Tunnel::N0VirtualSend, this));
211 n0->AddDevice(m_n0Tap);
212 Ptr<Ipv4> ipv4 = n0->GetObject<Ipv4>();
213 uint32_t i = ipv4->AddInterface(m_n0Tap);
214 ipv4->AddAddress(i,
215 Ipv4InterfaceAddress(Ipv4Address("11.0.0.1"), Ipv4Mask("255.255.255.0")));
216 ipv4->SetUp(i);
217
218 // n1 tap device
220 m_n1Tap->SetAddress(Mac48Address("11:00:01:02:03:02"));
221 m_n1Tap->SetSendCallback(MakeCallback(&Tunnel::N1VirtualSend, this));
222 n1->AddDevice(m_n1Tap);
223 ipv4 = n1->GetObject<Ipv4>();
224 i = ipv4->AddInterface(m_n1Tap);
225 ipv4->AddAddress(i,
226 Ipv4InterfaceAddress(Ipv4Address("11.0.0.1"), Ipv4Mask("255.255.255.0")));
227 ipv4->SetUp(i);
228
229 // n3 tap device
231 m_n3Tap->SetAddress(Mac48Address("11:00:01:02:03:04"));
232 m_n3Tap->SetSendCallback(MakeCallback(&Tunnel::N3VirtualSend, this));
233 n3->AddDevice(m_n3Tap);
234 ipv4 = n3->GetObject<Ipv4>();
235 i = ipv4->AddInterface(m_n3Tap);
236 ipv4->AddAddress(
237 i,
238 Ipv4InterfaceAddress(Ipv4Address("11.0.0.254"), Ipv4Mask("255.255.255.0")));
239 ipv4->SetUp(i);
240 }
241};
242
243int
244main(int argc, char* argv[])
245{
246 // Users may find it convenient to turn on explicit logging
247 // for selected modules; the below lines suggest how to do this
248#if 0
249 LogComponentEnable ("VirtualNetDeviceExample", LOG_LEVEL_INFO);
250#endif
252
253 // Set up some default values for the simulation. Use the
254 Config::SetDefault("ns3::OnOffApplication::PacketSize", UintegerValue(210));
255 Config::SetDefault("ns3::OnOffApplication::DataRate", StringValue("448kb/s"));
256
257 // Allow the user to override any of the defaults and the above
258 // Config::SetDefault ()s at run-time, via command-line arguments
259 CommandLine cmd(__FILE__);
260 cmd.Parse(argc, argv);
261
262 NS_LOG_INFO("Create nodes.");
264 c.Create(4);
265 NodeContainer n0n2 = NodeContainer(c.Get(0), c.Get(2));
266 NodeContainer n1n2 = NodeContainer(c.Get(1), c.Get(2));
267 NodeContainer n3n2 = NodeContainer(c.Get(3), c.Get(2));
268
270 internet.Install(c);
271
272 // We create the channels first without any IP addressing information
273 NS_LOG_INFO("Create channels.");
275 p2p.SetDeviceAttribute("DataRate", StringValue("5Mbps"));
276 p2p.SetChannelAttribute("Delay", StringValue("2ms"));
277 NetDeviceContainer d0d2 = p2p.Install(n0n2);
278
279 NetDeviceContainer d1d2 = p2p.Install(n1n2);
280
281 p2p.SetDeviceAttribute("DataRate", StringValue("1500kbps"));
282 p2p.SetChannelAttribute("Delay", StringValue("10ms"));
283 NetDeviceContainer d3d2 = p2p.Install(n3n2);
284
285 // Later, we add IP addresses.
286 NS_LOG_INFO("Assign IP Addresses.");
288 ipv4.SetBase("10.1.1.0", "255.255.255.0");
289 Ipv4InterfaceContainer i0i2 = ipv4.Assign(d0d2);
290
291 ipv4.SetBase("10.1.2.0", "255.255.255.0");
292 Ipv4InterfaceContainer i1i2 = ipv4.Assign(d1d2);
293
294 ipv4.SetBase("10.1.3.0", "255.255.255.0");
295 Ipv4InterfaceContainer i3i2 = ipv4.Assign(d3d2);
296
297 // Create router nodes, initialize routing database and set up the routing
298 // tables in the nodes.
300
301 // Add the tunnels n0<=>n3 and n1<=>n3
302 Tunnel tunnel(c.Get(3),
303 c.Get(0),
304 c.Get(1),
305 i3i2.GetAddress(0),
306 i0i2.GetAddress(0),
307 i1i2.GetAddress(0));
308
309 // Create the OnOff application to send UDP datagrams of size
310 // 210 bytes at a rate of 448 Kb/s
311 NS_LOG_INFO("Create Applications.");
312 uint16_t port = 9; // Discard port (RFC 863)
313 OnOffHelper onoff("ns3::UdpSocketFactory",
314 Address(InetSocketAddress(Ipv4Address("11.0.0.254"), port)));
315 onoff.SetConstantRate(DataRate("448kb/s"));
316 ApplicationContainer apps = onoff.Install(c.Get(0));
317 apps.Start(Seconds(1.0));
318 apps.Stop(Seconds(10.0));
319
320 // Create a packet sink to receive these packets
321 PacketSinkHelper sink("ns3::UdpSocketFactory",
323 apps = sink.Install(c.Get(3));
324 apps.Start(Seconds(1.0));
325 // apps.Stop (Seconds (10.0));
326
327 // Create a similar flow from n3 to n1, starting at time 1.1 seconds
328 onoff.SetAttribute("Remote", AddressValue(InetSocketAddress(Ipv4Address("11.0.0.1"), port)));
329 apps = onoff.Install(c.Get(3));
330 apps.Start(Seconds(1.1));
331 apps.Stop(Seconds(10.0));
332
333 // Create a packet sink to receive these packets
334 apps = sink.Install(c.Get(1));
335 apps.Start(Seconds(1.1));
336 // apps.Stop (Seconds (10.0));
337
338 AsciiTraceHelper ascii;
339 p2p.EnableAsciiAll(ascii.CreateFileStream("virtual-net-device.tr"));
340 p2p.EnablePcapAll("virtual-net-device");
341
342 NS_LOG_INFO("Run Simulation.");
345 NS_LOG_INFO("Done.");
346
347 return 0;
348}
Ipv4InterfaceContainer i0i2
IPv4 interface container i0 + i2.
NodeContainer n1n2
Nodecontainer n1 + n2.
Ipv4InterfaceContainer i1i2
IPv4 interface container i1 + i2.
NodeContainer n0n2
Nodecontainer n0 + n2.
Tunnel class - its goal is to create and manage the tunnels between endpoints.
void N0SocketRecv(Ptr< Socket > socket)
Receive a packet on the N0 VirtualNetDevice.
bool N0VirtualSend(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber)
Send a packet through the N0 VirtualNetDevice.
Ptr< Socket > m_n3Socket
Socket on the N3 node.
void N3SocketRecv(Ptr< Socket > socket)
Receive a packet on the N3 VirtualNetDevice.
Ptr< Socket > m_n1Socket
Socket on the N1 node.
Ipv4Address m_n1Address
Address of the N1 node.
Ipv4Address m_n3Address
Address of the N3 node.
Ipv4Address m_n0Address
Address of the N0 node.
bool N3VirtualSend(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber)
Send a packet through the N3 VirtualNetDevice.
Ptr< UniformRandomVariable > m_rng
Random number generator.
void N1SocketRecv(Ptr< Socket > socket)
Receive a packet on the N1 VirtualNetDevice.
Ptr< VirtualNetDevice > m_n0Tap
VirtualNetDevice on the N0 node.
Ptr< VirtualNetDevice > m_n3Tap
VirtualNetDevice on the N3 node.
bool N1VirtualSend(Ptr< Packet > packet, const Address &source, const Address &dest, uint16_t protocolNumber)
Send a packet through the N1 VirtualNetDevice.
Ptr< Socket > m_n0Socket
Socket on the N0 node.
Ptr< VirtualNetDevice > m_n1Tap
VirtualNetDevice on the N1 node.
Tunnel(Ptr< Node > n3, Ptr< Node > n0, Ptr< Node > n1, Ipv4Address n3Addr, Ipv4Address n0Addr, Ipv4Address n1Addr)
Constructor.
a polymophic address class
Definition address.h:90
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.
Manage ASCII trace files for device models.
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.
Parse command-line arguments.
Class for representing data rates.
Definition data-rate.h:78
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
Ipv4 addresses are stored in host order in this class.
static Ipv4Address GetAny()
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:69
a class to store IPv4 address information on an interface
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
a class to represent an Ipv4 address mask
an EUI-48 address
holds a vector of ns3::NetDevice pointers
@ PACKET_HOST
Packet addressed to us.
Definition net-device.h:290
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
static void EnablePrinting()
Enable printing packets metadata.
Definition packet.cc:585
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
Build a set of PointToPointNetDevice objects.
Smart pointer class similar to boost::intrusive_ptr.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static void Run()
Run the simulation.
Definition simulator.cc:167
void SetRecvCallback(Callback< void, Ptr< Socket > > receivedData)
Notify application when new data is available to be read.
Definition socket.cc:117
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
Definition socket.cc:61
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)=0
Send data to a specified peer.
Hold variables of type string.
Definition string.h:45
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition type-id.cc:872
Hold an unsigned integer type.
Definition uinteger.h:34
uint16_t port
Definition dsdv-manet.cc:33
void SetDefault(std::string name, const AttributeValue &value)
Definition config.cc:883
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#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
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void LogComponentEnable(const std::string &name, LogLevel level)
Enable the logging output associated with that log component.
Definition log.cc:291
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition callback.h:684
@ LOG_LEVEL_INFO
LOG_INFO and above.
Definition log.h:93
Ptr< PacketSink > sink
Pointer to the packet sink application.
Definition wifi-tcp.cc:44