A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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/ipv4-static-routing-helper.h"
49 #include "ns3/ipv4-list-routing-helper.h"
50 #include "ns3/point-to-point-helper.h"
51 #include "ns3/internet-stack-helper.h"
52 #include "ns3/ipv4-nix-vector-helper.h"
53 #include "ns3/ipv4-address-helper.h"
54 #include "ns3/on-off-helper.h"
55 #include "ns3/packet-sink-helper.h"
56 
57 #ifdef NS3_MPI
58 #include <mpi.h>
59 #endif
60 
61 using namespace ns3;
62 
63 NS_LOG_COMPONENT_DEFINE ("SimpleDistributed");
64 
65 int
66 main (int argc, char *argv[])
67 {
68 #ifdef NS3_MPI
69 
70  bool nix = true;
71  bool nullmsg = false;
72  bool tracing = false;
73 
74  // Parse command line
75  CommandLine cmd;
76  cmd.AddValue ("nix", "Enable the use of nix-vector or global routing", nix);
77  cmd.AddValue ("nullmsg", "Enable the use of null-message synchronization", nullmsg);
78  cmd.AddValue ("tracing", "Enable pcap tracing", tracing);
79  cmd.Parse (argc, argv);
80 
81  // Distributed simulation setup; by default use granted time window algorithm.
82  if(nullmsg)
83  {
84  GlobalValue::Bind ("SimulatorImplementationType",
85  StringValue ("ns3::NullMessageSimulatorImpl"));
86  }
87  else
88  {
89  GlobalValue::Bind ("SimulatorImplementationType",
90  StringValue ("ns3::DistributedSimulatorImpl"));
91  }
92 
93  // Enable parallel simulator with the command line arguments
94  MpiInterface::Enable (&argc, &argv);
95 
96  LogComponentEnable ("PacketSink", LOG_LEVEL_INFO);
97 
98  uint32_t systemId = MpiInterface::GetSystemId ();
99  uint32_t systemCount = MpiInterface::GetSize ();
100 
101  // Check for valid distributed parameters.
102  // Must have 2 and only 2 Logical Processors (LPs)
103  if (systemCount != 2)
104  {
105  std::cout << "This simulation requires 2 and only 2 logical processors." << std::endl;
106  return 1;
107  }
108 
109  // Some default values
110  Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (512));
111  Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("1Mbps"));
112  Config::SetDefault ("ns3::OnOffApplication::MaxBytes", UintegerValue (512));
113 
114  // Create leaf nodes on left with system id 0
115  NodeContainer leftLeafNodes;
116  leftLeafNodes.Create (4, 0);
117 
118  // Create router nodes. Left router
119  // with system id 0, right router with
120  // system id 1
121  NodeContainer routerNodes;
122  Ptr<Node> routerNode1 = CreateObject<Node> (0);
123  Ptr<Node> routerNode2 = CreateObject<Node> (1);
124  routerNodes.Add (routerNode1);
125  routerNodes.Add (routerNode2);
126 
127  // Create leaf nodes on left with system id 1
128  NodeContainer rightLeafNodes;
129  rightLeafNodes.Create (4, 1);
130 
131  PointToPointHelper routerLink;
132  routerLink.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
133  routerLink.SetChannelAttribute ("Delay", StringValue ("5ms"));
134 
135  PointToPointHelper leafLink;
136  leafLink.SetDeviceAttribute ("DataRate", StringValue ("1Mbps"));
137  leafLink.SetChannelAttribute ("Delay", StringValue ("2ms"));
138 
139  // Add link connecting routers
140  NetDeviceContainer routerDevices;
141  routerDevices = routerLink.Install (routerNodes);
142 
143  // Add links for left side leaf nodes to left router
144  NetDeviceContainer leftRouterDevices;
145  NetDeviceContainer leftLeafDevices;
146  for (uint32_t i = 0; i < 4; ++i)
147  {
148  NetDeviceContainer temp = leafLink.Install (leftLeafNodes.Get (i), routerNodes.Get (0));
149  leftLeafDevices.Add (temp.Get (0));
150  leftRouterDevices.Add (temp.Get (1));
151  }
152 
153  // Add links for right side leaf nodes to right router
154  NetDeviceContainer rightRouterDevices;
155  NetDeviceContainer rightLeafDevices;
156  for (uint32_t i = 0; i < 4; ++i)
157  {
158  NetDeviceContainer temp = leafLink.Install (rightLeafNodes.Get (i), routerNodes.Get (1));
159  rightLeafDevices.Add (temp.Get (0));
160  rightRouterDevices.Add (temp.Get (1));
161  }
162 
164  Ipv4NixVectorHelper nixRouting;
165  Ipv4StaticRoutingHelper staticRouting;
166 
168  list.Add (staticRouting, 0);
169  list.Add (nixRouting, 10);
170 
171  if (nix)
172  {
173  stack.SetRoutingHelper (list); // has effect on the next Install ()
174  }
175 
176  stack.InstallAll ();
177 
178  Ipv4InterfaceContainer routerInterfaces;
179  Ipv4InterfaceContainer leftLeafInterfaces;
180  Ipv4InterfaceContainer leftRouterInterfaces;
181  Ipv4InterfaceContainer rightLeafInterfaces;
182  Ipv4InterfaceContainer rightRouterInterfaces;
183 
184  Ipv4AddressHelper leftAddress;
185  leftAddress.SetBase ("10.1.1.0", "255.255.255.0");
186 
187  Ipv4AddressHelper routerAddress;
188  routerAddress.SetBase ("10.2.1.0", "255.255.255.0");
189 
190  Ipv4AddressHelper rightAddress;
191  rightAddress.SetBase ("10.3.1.0", "255.255.255.0");
192 
193  // Router-to-Router interfaces
194  routerInterfaces = routerAddress.Assign (routerDevices);
195 
196  // Left interfaces
197  for (uint32_t i = 0; i < 4; ++i)
198  {
199  NetDeviceContainer ndc;
200  ndc.Add (leftLeafDevices.Get (i));
201  ndc.Add (leftRouterDevices.Get (i));
202  Ipv4InterfaceContainer ifc = leftAddress.Assign (ndc);
203  leftLeafInterfaces.Add (ifc.Get (0));
204  leftRouterInterfaces.Add (ifc.Get (1));
205  leftAddress.NewNetwork ();
206  }
207 
208  // Right interfaces
209  for (uint32_t i = 0; i < 4; ++i)
210  {
211  NetDeviceContainer ndc;
212  ndc.Add (rightLeafDevices.Get (i));
213  ndc.Add (rightRouterDevices.Get (i));
214  Ipv4InterfaceContainer ifc = rightAddress.Assign (ndc);
215  rightLeafInterfaces.Add (ifc.Get (0));
216  rightRouterInterfaces.Add (ifc.Get (1));
217  rightAddress.NewNetwork ();
218  }
219 
220  if (!nix)
221  {
223  }
224 
225  if (tracing == true)
226  {
227  if (systemId == 0)
228  {
229  routerLink.EnablePcap("router-left", routerDevices, true);
230  leafLink.EnablePcap("leaf-left", leftLeafDevices, true);
231  }
232 
233  if (systemId == 1)
234  {
235  routerLink.EnablePcap("router-right", routerDevices, true);
236  leafLink.EnablePcap("leaf-right", rightLeafDevices, true);
237  }
238  }
239 
240  // Create a packet sink on the right leafs to receive packets from left leafs
241  uint16_t port = 50000;
242  if (systemId == 1)
243  {
244  Address sinkLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
245  PacketSinkHelper sinkHelper ("ns3::UdpSocketFactory", sinkLocalAddress);
246  ApplicationContainer sinkApp;
247  for (uint32_t i = 0; i < 4; ++i)
248  {
249  sinkApp.Add (sinkHelper.Install (rightLeafNodes.Get (i)));
250  }
251  sinkApp.Start (Seconds (1.0));
252  sinkApp.Stop (Seconds (5));
253  }
254 
255  // Create the OnOff applications to send
256  if (systemId == 0)
257  {
258  OnOffHelper clientHelper ("ns3::UdpSocketFactory", Address ());
259  clientHelper.SetAttribute
260  ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
261  clientHelper.SetAttribute
262  ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
263 
265  for (uint32_t i = 0; i < 4; ++i)
266  {
267  AddressValue remoteAddress
268  (InetSocketAddress (rightLeafInterfaces.GetAddress (i), port));
269  clientHelper.SetAttribute ("Remote", remoteAddress);
270  clientApps.Add (clientHelper.Install (leftLeafNodes.Get (i)));
271  }
272  clientApps.Start (Seconds (1.0));
273  clientApps.Stop (Seconds (5));
274  }
275 
276  Simulator::Stop (Seconds (5));
277  Simulator::Run ();
279  // Exit the MPI execution environment
281  return 0;
282 #else
283  NS_FATAL_ERROR ("Can't use distributed simulator without MPI compiled in");
284 #endif
285 }
holds a vector of ns3::Application pointers.
an Inet address class
static Ipv4Address GetAny(void)
std::pair< Ptr< Ipv4 >, uint32_t > Get(uint32_t i) const
Get the std::pair of an Ptr and interface stored at the location specified by the index...
NS_LOG_COMPONENT_DEFINE("GrantedTimeWindowMpiInterface")
holds a vector of std::pair of Ptr 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:19
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr stored in this container at a given index.
NetDeviceContainer Install(NodeContainer c)
void Add(ApplicationContainer other)
Append the contents of another ApplicationContainer to the end of this container. ...
static void Run(void)
Run the simulation until one of:
Definition: simulator.cc:157
Helper class that adds Nix-vector routing to nodes.
aggregate IP/TCP/UDP functionality to existing Nodes.
int main(int argc, char *argv[])
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes...
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
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
uint16_t port
Definition: dsdv-manet.cc:44
a polymophic address class
Definition: address.h:86
tuple clientApps
Definition: first.py:53
void InstallAll(void) const
Aggregate IPv4, IPv6, UDP, and TCP stacks to all nodes in the simulation.
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:46
holds a vector of ns3::NetDevice pointers
static void Bind(std::string name, const AttributeValue &value)
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:152
#define list
static void Destroy(void)
Every event scheduled by the Simulator::insertAtDestroy method is invoked.
Definition: simulator.cc:121
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:667
keep track of a set of node pointers.
void Add(const Ipv4RoutingHelper &routing, int16_t priority)
tuple stack
Definition: first.py:34
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
hold objects of type ns3::Address
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()
Helper class that adds ns3::Ipv4StaticRouting objects.
void AddValue(const std::string &name, const std::string &help, T &value)
Add a program argument, assigning to POD.
Definition: command-line.h:408
static void Stop(void)
If an event invokes this method, it will be the last event scheduled by the Simulator::run method bef...
Definition: simulator.cc:165
Ptr< Node > Get(uint32_t i) const
Get the Ptr 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...
Helper class that adds ns3::Ipv4ListRouting objects.
ApplicationContainer Install(NodeContainer c) const
Install an ns3::PacketSinkApplication on each node of the input container configured with all the att...
void Parse(int argc, char *argv[])
Parse the program arguments.
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 Add(Ipv4InterfaceContainer other)
Concatenate the entries in the other container with ours.
void EnablePcap(std::string prefix, Ptr< NetDevice > nd, bool promiscuous=false, bool explicitFilename=false)
Enable pcap output the indicated net device.
ApplicationContainer Install(NodeContainer c) const
Install an ns3::OnOffApplication on each node of the input container configured with all the attribut...
static uint32_t GetSize()
void SetRoutingHelper(const Ipv4RoutingHelper &routing)
void SetAttribute(std::string name, const AttributeValue &value)
Helper function used to set the underlying application attributes.
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
void LogComponentEnable(char const *name, enum LogLevel level)
Definition: log.cc:311
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const