A Discrete-Event Network Simulator
API
simple-distributed.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License version 2 as
5  * published by the Free Software Foundation;
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software
14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15  *
16  *
17  * TestDistributed creates a dumbbell topology and logically splits it in
18  * half. The left half is placed on logical processor 0 and the right half
19  * is placed on logical processor 1.
20  *
21  * ------- -------
22  * RANK 0 RANK 1
23  * ------- | -------
24  * |
25  * n0 ---------| | |---------- n6
26  * | | |
27  * n1 -------\ | | | /------- n7
28  * n4 ----------|---------- n5
29  * n2 -------/ | | | \------- n8
30  * | | |
31  * n3 ---------| | |---------- n9
32  *
33  *
34  * OnOff clients are placed on each left leaf node. Each right leaf node
35  * is a packet sink for a left leaf node. As a packet travels from one
36  * logical processor to another (the link between n4 and n5), MPI messages
37  * are passed containing the serialized packet. The message is then
38  * deserialized into a new packet and sent on as normal.
39  *
40  * One packet is sent from each left leaf node. The packet sinks on the
41  * right leaf nodes output logging information when they receive the packet.
42  */
43 
44 #include "ns3/core-module.h"
45 #include "ns3/network-module.h"
46 #include "ns3/mpi-interface.h"
47 #include "ns3/ipv4-global-routing-helper.h"
48 #include "ns3/point-to-point-helper.h"
49 #include "ns3/internet-stack-helper.h"
50 #include "ns3/ipv4-nix-vector-helper.h"
51 #include "ns3/ipv4-address-helper.h"
52 #include "ns3/on-off-helper.h"
53 #include "ns3/packet-sink-helper.h"
54 
55 #ifdef NS3_MPI
56 #include <mpi.h>
57 #endif
58 
59 using namespace ns3;
60 
61 NS_LOG_COMPONENT_DEFINE ("SimpleDistributed");
62 
63 int
64 main (int argc, char *argv[])
65 {
66 #ifdef NS3_MPI
67 
68  bool nix = true;
69  bool nullmsg = false;
70  bool tracing = false;
71 
72  // Parse command line
74  cmd.AddValue ("nix", "Enable the use of nix-vector or global routing", nix);
75  cmd.AddValue ("nullmsg", "Enable the use of null-message synchronization", nullmsg);
76  cmd.AddValue ("tracing", "Enable pcap tracing", tracing);
77  cmd.Parse (argc, argv);
78 
79  // Distributed simulation setup; by default use granted time window algorithm.
80  if(nullmsg)
81  {
82  GlobalValue::Bind ("SimulatorImplementationType",
83  StringValue ("ns3::NullMessageSimulatorImpl"));
84  }
85  else
86  {
87  GlobalValue::Bind ("SimulatorImplementationType",
88  StringValue ("ns3::DistributedSimulatorImpl"));
89  }
90 
91  // Enable parallel simulator with the command line arguments
92  MpiInterface::Enable (&argc, &argv);
93 
94  LogComponentEnable ("PacketSink", LOG_LEVEL_INFO);
95 
96  uint32_t systemId = MpiInterface::GetSystemId ();
97  uint32_t systemCount = MpiInterface::GetSize ();
98 
99  // Check for valid distributed parameters.
100  // Must have 2 and only 2 Logical Processors (LPs)
101  if (systemCount != 2)
102  {
103  std::cout << "This simulation requires 2 and only 2 logical processors." << std::endl;
104  return 1;
105  }
106 
107  // Some default values
108  Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (512));
109  Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("1Mbps"));
110  Config::SetDefault ("ns3::OnOffApplication::MaxBytes", UintegerValue (512));
111 
112  // Create leaf nodes on left with system id 0
113  NodeContainer leftLeafNodes;
114  leftLeafNodes.Create (4, 0);
115 
116  // Create router nodes. Left router
117  // with system id 0, right router with
118  // system id 1
119  NodeContainer routerNodes;
120  Ptr<Node> routerNode1 = CreateObject<Node> (0);
121  Ptr<Node> routerNode2 = CreateObject<Node> (1);
122  routerNodes.Add (routerNode1);
123  routerNodes.Add (routerNode2);
124 
125  // Create leaf nodes on left with system id 1
126  NodeContainer rightLeafNodes;
127  rightLeafNodes.Create (4, 1);
128 
129  PointToPointHelper routerLink;
130  routerLink.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
131  routerLink.SetChannelAttribute ("Delay", StringValue ("5ms"));
132 
133  PointToPointHelper leafLink;
134  leafLink.SetDeviceAttribute ("DataRate", StringValue ("1Mbps"));
135  leafLink.SetChannelAttribute ("Delay", StringValue ("2ms"));
136 
137  // Add link connecting routers
138  NetDeviceContainer routerDevices;
139  routerDevices = routerLink.Install (routerNodes);
140 
141  // Add links for left side leaf nodes to left router
142  NetDeviceContainer leftRouterDevices;
143  NetDeviceContainer leftLeafDevices;
144  for (uint32_t i = 0; i < 4; ++i)
145  {
146  NetDeviceContainer temp = leafLink.Install (leftLeafNodes.Get (i), routerNodes.Get (0));
147  leftLeafDevices.Add (temp.Get (0));
148  leftRouterDevices.Add (temp.Get (1));
149  }
150 
151  // Add links for right side leaf nodes to right router
152  NetDeviceContainer rightRouterDevices;
153  NetDeviceContainer rightLeafDevices;
154  for (uint32_t i = 0; i < 4; ++i)
155  {
156  NetDeviceContainer temp = leafLink.Install (rightLeafNodes.Get (i), routerNodes.Get (1));
157  rightLeafDevices.Add (temp.Get (0));
158  rightRouterDevices.Add (temp.Get (1));
159  }
160 
162  if (nix)
163  {
164  Ipv4NixVectorHelper nixRouting;
165  stack.SetRoutingHelper (nixRouting); // has effect on the next Install ()
166  }
167 
168  stack.InstallAll ();
169 
170  Ipv4InterfaceContainer routerInterfaces;
171  Ipv4InterfaceContainer leftLeafInterfaces;
172  Ipv4InterfaceContainer leftRouterInterfaces;
173  Ipv4InterfaceContainer rightLeafInterfaces;
174  Ipv4InterfaceContainer rightRouterInterfaces;
175 
176  Ipv4AddressHelper leftAddress;
177  leftAddress.SetBase ("10.1.1.0", "255.255.255.0");
178 
179  Ipv4AddressHelper routerAddress;
180  routerAddress.SetBase ("10.2.1.0", "255.255.255.0");
181 
182  Ipv4AddressHelper rightAddress;
183  rightAddress.SetBase ("10.3.1.0", "255.255.255.0");
184 
185  // Router-to-Router interfaces
186  routerInterfaces = routerAddress.Assign (routerDevices);
187 
188  // Left interfaces
189  for (uint32_t i = 0; i < 4; ++i)
190  {
191  NetDeviceContainer ndc;
192  ndc.Add (leftLeafDevices.Get (i));
193  ndc.Add (leftRouterDevices.Get (i));
194  Ipv4InterfaceContainer ifc = leftAddress.Assign (ndc);
195  leftLeafInterfaces.Add (ifc.Get (0));
196  leftRouterInterfaces.Add (ifc.Get (1));
197  leftAddress.NewNetwork ();
198  }
199 
200  // Right interfaces
201  for (uint32_t i = 0; i < 4; ++i)
202  {
203  NetDeviceContainer ndc;
204  ndc.Add (rightLeafDevices.Get (i));
205  ndc.Add (rightRouterDevices.Get (i));
206  Ipv4InterfaceContainer ifc = rightAddress.Assign (ndc);
207  rightLeafInterfaces.Add (ifc.Get (0));
208  rightRouterInterfaces.Add (ifc.Get (1));
209  rightAddress.NewNetwork ();
210  }
211 
212  if (!nix)
213  {
215  }
216 
217  if (tracing == true)
218  {
219  if (systemId == 0)
220  {
221  routerLink.EnablePcap("router-left", routerDevices, true);
222  leafLink.EnablePcap("leaf-left", leftLeafDevices, true);
223  }
224 
225  if (systemId == 1)
226  {
227  routerLink.EnablePcap("router-right", routerDevices, true);
228  leafLink.EnablePcap("leaf-right", rightLeafDevices, true);
229  }
230  }
231 
232  // Create a packet sink on the right leafs to receive packets from left leafs
233  uint16_t port = 50000;
234  if (systemId == 1)
235  {
236  Address sinkLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
237  PacketSinkHelper sinkHelper ("ns3::UdpSocketFactory", sinkLocalAddress);
238  ApplicationContainer sinkApp;
239  for (uint32_t i = 0; i < 4; ++i)
240  {
241  sinkApp.Add (sinkHelper.Install (rightLeafNodes.Get (i)));
242  }
243  sinkApp.Start (Seconds (1.0));
244  sinkApp.Stop (Seconds (5));
245  }
246 
247  // Create the OnOff applications to send
248  if (systemId == 0)
249  {
250  OnOffHelper clientHelper ("ns3::UdpSocketFactory", Address ());
251  clientHelper.SetAttribute
252  ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
253  clientHelper.SetAttribute
254  ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
255 
257  for (uint32_t i = 0; i < 4; ++i)
258  {
259  AddressValue remoteAddress
260  (InetSocketAddress (rightLeafInterfaces.GetAddress (i), port));
261  clientHelper.SetAttribute ("Remote", remoteAddress);
262  clientApps.Add (clientHelper.Install (leftLeafNodes.Get (i)));
263  }
264  clientApps.Start (Seconds (1.0));
265  clientApps.Stop (Seconds (5));
266  }
267 
268  Simulator::Stop (Seconds (5));
269  Simulator::Run ();
271  // Exit the MPI execution environment
273  return 0;
274 #else
275  NS_FATAL_ERROR ("Can't use distributed simulator without MPI compiled in");
276 #endif
277 }
holds a vector of ns3::Application pointers.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
an Inet address class
static Ipv4Address GetAny(void)
holds a vector of std::pair of Ptr<Ipv4> and interface index.
static void PopulateRoutingTables(void)
Build a routing database and initialize the routing tables of the nodes in the simulation.
Hold variables of type string.
Definition: string.h:41
NetDeviceContainer Install(NodeContainer c)
void Add(ApplicationContainer other)
Append the contents of another ApplicationContainer to the end of this container. ...
void Add(const Ipv4InterfaceContainer &other)
Concatenate the entries in the other container with ours.
static void Run(void)
Run the simulation.
Definition: simulator.cc:226
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
Helper class that adds Nix-vector routing to nodes.
aggregate IP/TCP/UDP functionality to existing Nodes.
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:162
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes...
cmd
Definition: second.py:35
static void Disable()
Terminates the parallel environment.
Build a set of PointToPointNetDevice objects.
void SetDeviceAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each NetDevice created by the helper.
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
Definition: on-off-helper.h:42
stack
Definition: first.py:34
uint16_t port
Definition: dsdv-manet.cc:45
a polymophic address class
Definition: address.h:90
void LogComponentEnable(char const *name, enum LogLevel level)
Enable the logging output associated with that log component.
Definition: log.cc:369
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
static void Enable(int *pargc, char ***pargv)
Sets up parallel communication interface.
Hold an unsigned integer type.
Definition: uinteger.h:44
LOG_INFO and above.
Definition: log.h:104
holds a vector of ns3::NetDevice pointers
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...
void Start(Time start)
Arrange for all of the Applications in this container to Start() at the Time given as a parameter...
Parse command-line arguments.
Definition: command-line.h:213
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:190
Every class exported by the ns3 library is enclosed in the ns3 namespace.
keep track of a set of node pointers.
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
AttributeValue implementation for Address.
Definition: address.h:278
void Stop(Time stop)
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter...
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
void Add(NodeContainer other)
Append the contents of another NodeContainer to the end of this container.
static uint32_t GetSystemId()
static void Stop(void)
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:234
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1014
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:782
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
Ipv4Address NewNetwork(void)
Increment the network number and reset the IP address counter to the base value provided in the SetBa...
clientApps
Definition: first.py:54
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
void EnablePcap(std::string prefix, Ptr< NetDevice > nd, bool promiscuous=false, bool explicitFilename=false)
Enable pcap output the indicated net device.
std::pair< Ptr< Ipv4 >, uint32_t > Get(uint32_t i) const
Get the std::pair of an Ptr<Ipv4> and interface stored at the location specified by the index...
static uint32_t GetSize()
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.