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 #include <mpi.h>
55 
56 using namespace ns3;
57 
58 NS_LOG_COMPONENT_DEFINE ("SimpleDistributed");
59 
60 int
61 main (int argc, char *argv[])
62 {
63  bool nix = true;
64  bool nullmsg = false;
65  bool tracing = false;
66 
67  // Parse command line
68  CommandLine cmd (__FILE__);
69  cmd.AddValue ("nix", "Enable the use of nix-vector or global routing", nix);
70  cmd.AddValue ("nullmsg", "Enable the use of null-message synchronization", nullmsg);
71  cmd.AddValue ("tracing", "Enable pcap tracing", tracing);
72  cmd.Parse (argc, argv);
73 
74  // Distributed simulation setup; by default use granted time window algorithm.
75  if(nullmsg)
76  {
77  GlobalValue::Bind ("SimulatorImplementationType",
78  StringValue ("ns3::NullMessageSimulatorImpl"));
79  }
80  else
81  {
82  GlobalValue::Bind ("SimulatorImplementationType",
83  StringValue ("ns3::DistributedSimulatorImpl"));
84  }
85 
86  // Enable parallel simulator with the command line arguments
87  MpiInterface::Enable (&argc, &argv);
88 
89  LogComponentEnable ("PacketSink", LOG_LEVEL_INFO);
90 
91  uint32_t systemId = MpiInterface::GetSystemId ();
92  uint32_t systemCount = MpiInterface::GetSize ();
93 
94  // Check for valid distributed parameters.
95  // Must have 2 and only 2 Logical Processors (LPs)
96  if (systemCount != 2)
97  {
98  std::cout << "This simulation requires 2 and only 2 logical processors." << std::endl;
99  return 1;
100  }
101 
102  // Some default values
103  Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (512));
104  Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("1Mbps"));
105  Config::SetDefault ("ns3::OnOffApplication::MaxBytes", UintegerValue (512));
106 
107  // Create leaf nodes on left with system id 0
108  NodeContainer leftLeafNodes;
109  leftLeafNodes.Create (4, 0);
110 
111  // Create router nodes. Left router
112  // with system id 0, right router with
113  // system id 1
114  NodeContainer routerNodes;
115  Ptr<Node> routerNode1 = CreateObject<Node> (0);
116  Ptr<Node> routerNode2 = CreateObject<Node> (1);
117  routerNodes.Add (routerNode1);
118  routerNodes.Add (routerNode2);
119 
120  // Create leaf nodes on right with system id 1
121  NodeContainer rightLeafNodes;
122  rightLeafNodes.Create (4, 1);
123 
124  PointToPointHelper routerLink;
125  routerLink.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
126  routerLink.SetChannelAttribute ("Delay", StringValue ("5ms"));
127 
128  PointToPointHelper leafLink;
129  leafLink.SetDeviceAttribute ("DataRate", StringValue ("1Mbps"));
130  leafLink.SetChannelAttribute ("Delay", StringValue ("2ms"));
131 
132  // Add link connecting routers
133  NetDeviceContainer routerDevices;
134  routerDevices = routerLink.Install (routerNodes);
135 
136  // Add links for left side leaf nodes to left router
137  NetDeviceContainer leftRouterDevices;
138  NetDeviceContainer leftLeafDevices;
139  for (uint32_t i = 0; i < 4; ++i)
140  {
141  NetDeviceContainer temp = leafLink.Install (leftLeafNodes.Get (i), routerNodes.Get (0));
142  leftLeafDevices.Add (temp.Get (0));
143  leftRouterDevices.Add (temp.Get (1));
144  }
145 
146  // Add links for right side leaf nodes to right router
147  NetDeviceContainer rightRouterDevices;
148  NetDeviceContainer rightLeafDevices;
149  for (uint32_t i = 0; i < 4; ++i)
150  {
151  NetDeviceContainer temp = leafLink.Install (rightLeafNodes.Get (i), routerNodes.Get (1));
152  rightLeafDevices.Add (temp.Get (0));
153  rightRouterDevices.Add (temp.Get (1));
154  }
155 
157  if (nix)
158  {
159  Ipv4NixVectorHelper nixRouting;
160  stack.SetRoutingHelper (nixRouting); // has effect on the next Install ()
161  }
162 
163  stack.InstallAll ();
164 
165  Ipv4InterfaceContainer routerInterfaces;
166  Ipv4InterfaceContainer leftLeafInterfaces;
167  Ipv4InterfaceContainer leftRouterInterfaces;
168  Ipv4InterfaceContainer rightLeafInterfaces;
169  Ipv4InterfaceContainer rightRouterInterfaces;
170 
171  Ipv4AddressHelper leftAddress;
172  leftAddress.SetBase ("10.1.1.0", "255.255.255.0");
173 
174  Ipv4AddressHelper routerAddress;
175  routerAddress.SetBase ("10.2.1.0", "255.255.255.0");
176 
177  Ipv4AddressHelper rightAddress;
178  rightAddress.SetBase ("10.3.1.0", "255.255.255.0");
179 
180  // Router-to-Router interfaces
181  routerInterfaces = routerAddress.Assign (routerDevices);
182 
183  // Left interfaces
184  for (uint32_t i = 0; i < 4; ++i)
185  {
186  NetDeviceContainer ndc;
187  ndc.Add (leftLeafDevices.Get (i));
188  ndc.Add (leftRouterDevices.Get (i));
189  Ipv4InterfaceContainer ifc = leftAddress.Assign (ndc);
190  leftLeafInterfaces.Add (ifc.Get (0));
191  leftRouterInterfaces.Add (ifc.Get (1));
192  leftAddress.NewNetwork ();
193  }
194 
195  // Right interfaces
196  for (uint32_t i = 0; i < 4; ++i)
197  {
198  NetDeviceContainer ndc;
199  ndc.Add (rightLeafDevices.Get (i));
200  ndc.Add (rightRouterDevices.Get (i));
201  Ipv4InterfaceContainer ifc = rightAddress.Assign (ndc);
202  rightLeafInterfaces.Add (ifc.Get (0));
203  rightRouterInterfaces.Add (ifc.Get (1));
204  rightAddress.NewNetwork ();
205  }
206 
207  if (!nix)
208  {
210  }
211 
212  if (tracing == true)
213  {
214  if (systemId == 0)
215  {
216  routerLink.EnablePcap("router-left", routerDevices, true);
217  leafLink.EnablePcap("leaf-left", leftLeafDevices, true);
218  }
219 
220  if (systemId == 1)
221  {
222  routerLink.EnablePcap("router-right", routerDevices, true);
223  leafLink.EnablePcap("leaf-right", rightLeafDevices, true);
224  }
225  }
226 
227  // Create a packet sink on the right leafs to receive packets from left leafs
228  uint16_t port = 50000;
229  if (systemId == 1)
230  {
231  Address sinkLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
232  PacketSinkHelper sinkHelper ("ns3::UdpSocketFactory", sinkLocalAddress);
233  ApplicationContainer sinkApp;
234  for (uint32_t i = 0; i < 4; ++i)
235  {
236  sinkApp.Add (sinkHelper.Install (rightLeafNodes.Get (i)));
237  }
238  sinkApp.Start (Seconds (1.0));
239  sinkApp.Stop (Seconds (5));
240  }
241 
242  // Create the OnOff applications to send
243  if (systemId == 0)
244  {
245  OnOffHelper clientHelper ("ns3::UdpSocketFactory", Address ());
246  clientHelper.SetAttribute
247  ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
248  clientHelper.SetAttribute
249  ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
250 
252  for (uint32_t i = 0; i < 4; ++i)
253  {
254  AddressValue remoteAddress
255  (InetSocketAddress (rightLeafInterfaces.GetAddress (i), port));
256  clientHelper.SetAttribute ("Remote", remoteAddress);
257  clientApps.Add (clientHelper.Install (leftLeafNodes.Get (i)));
258  }
259  clientApps.Start (Seconds (1.0));
260  clientApps.Stop (Seconds (5));
261  }
262 
263  Simulator::Stop (Seconds (5));
264  Simulator::Run ();
266  // Exit the MPI execution environment
268  return 0;
269 }
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:172
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
Helper class that adds Nix-vector routing to nodes.
aggregate IP/TCP/UDP functionality to existing Nodes.
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:41
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:361
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:107
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:226
static void Destroy(void)
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:136
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:180
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1278
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:849
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:61
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()
bool tracing
Flag to enable/disable generation of tracing files.
Definition: wifi-bianchi.cc:82
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.