A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
simple-distributed.cc
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  // Distributed simulation setup
70  MpiInterface::Enable (&argc, &argv);
71  GlobalValue::Bind ("SimulatorImplementationType",
72  StringValue ("ns3::DistributedSimulatorImpl"));
73 
74  LogComponentEnable ("PacketSink", LOG_LEVEL_INFO);
75 
76  uint32_t systemId = MpiInterface::GetSystemId ();
77  uint32_t systemCount = MpiInterface::GetSize ();
78 
79  // Check for valid distributed parameters.
80  // Must have 2 and only 2 Logical Processors (LPs)
81  if (systemCount != 2)
82  {
83  std::cout << "This simulation requires 2 and only 2 logical processors." << std::endl;
84  return 1;
85  }
86 
87  // Some default values
88  Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (512));
89  Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("1Mbps"));
90  Config::SetDefault ("ns3::OnOffApplication::MaxBytes", UintegerValue (512));
91  bool nix = true;
92 
93  // Parse command line
94  CommandLine cmd;
95  cmd.AddValue ("nix", "Enable the use of nix-vector or global routing", nix);
96  cmd.Parse (argc, argv);
97 
98  // Create leaf nodes on left with system id 0
99  NodeContainer leftLeafNodes;
100  leftLeafNodes.Create (4, 0);
101 
102  // Create router nodes. Left router
103  // with system id 0, right router with
104  // system id 1
105  NodeContainer routerNodes;
106  Ptr<Node> routerNode1 = CreateObject<Node> (0);
107  Ptr<Node> routerNode2 = CreateObject<Node> (1);
108  routerNodes.Add (routerNode1);
109  routerNodes.Add (routerNode2);
110 
111  // Create leaf nodes on left with system id 1
112  NodeContainer rightLeafNodes;
113  rightLeafNodes.Create (4, 1);
114 
115  PointToPointHelper routerLink;
116  routerLink.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
117  routerLink.SetChannelAttribute ("Delay", StringValue ("5ms"));
118 
119  PointToPointHelper leafLink;
120  leafLink.SetDeviceAttribute ("DataRate", StringValue ("1Mbps"));
121  leafLink.SetChannelAttribute ("Delay", StringValue ("2ms"));
122 
123  // Add link connecting routers
124  NetDeviceContainer routerDevices;
125  routerDevices = routerLink.Install (routerNodes);
126 
127  // Add links for left side leaf nodes to left router
128  NetDeviceContainer leftRouterDevices;
129  NetDeviceContainer leftLeafDevices;
130  for (uint32_t i = 0; i < 4; ++i)
131  {
132  NetDeviceContainer temp = leafLink.Install (leftLeafNodes.Get (i), routerNodes.Get (0));
133  leftLeafDevices.Add (temp.Get (0));
134  leftRouterDevices.Add (temp.Get (1));
135  }
136 
137  // Add links for right side leaf nodes to right router
138  NetDeviceContainer rightRouterDevices;
139  NetDeviceContainer rightLeafDevices;
140  for (uint32_t i = 0; i < 4; ++i)
141  {
142  NetDeviceContainer temp = leafLink.Install (rightLeafNodes.Get (i), routerNodes.Get (1));
143  rightLeafDevices.Add (temp.Get (0));
144  rightRouterDevices.Add (temp.Get (1));
145  }
146 
147  InternetStackHelper stack;
148  Ipv4NixVectorHelper nixRouting;
149  Ipv4StaticRoutingHelper staticRouting;
150 
152  list.Add (staticRouting, 0);
153  list.Add (nixRouting, 10);
154 
155  if (nix)
156  {
157  stack.SetRoutingHelper (list); // has effect on the next Install ()
158  }
159 
160  stack.InstallAll ();
161 
162  Ipv4InterfaceContainer routerInterfaces;
163  Ipv4InterfaceContainer leftLeafInterfaces;
164  Ipv4InterfaceContainer leftRouterInterfaces;
165  Ipv4InterfaceContainer rightLeafInterfaces;
166  Ipv4InterfaceContainer rightRouterInterfaces;
167 
168  Ipv4AddressHelper leftAddress;
169  leftAddress.SetBase ("10.1.1.0", "255.255.255.0");
170 
171  Ipv4AddressHelper routerAddress;
172  routerAddress.SetBase ("10.2.1.0", "255.255.255.0");
173 
174  Ipv4AddressHelper rightAddress;
175  rightAddress.SetBase ("10.3.1.0", "255.255.255.0");
176 
177  // Router-to-Router interfaces
178  routerInterfaces = routerAddress.Assign (routerDevices);
179 
180  // Left interfaces
181  for (uint32_t i = 0; i < 4; ++i)
182  {
183  NetDeviceContainer ndc;
184  ndc.Add (leftLeafDevices.Get (i));
185  ndc.Add (leftRouterDevices.Get (i));
186  Ipv4InterfaceContainer ifc = leftAddress.Assign (ndc);
187  leftLeafInterfaces.Add (ifc.Get (0));
188  leftRouterInterfaces.Add (ifc.Get (1));
189  leftAddress.NewNetwork ();
190  }
191 
192  // Right interfaces
193  for (uint32_t i = 0; i < 4; ++i)
194  {
195  NetDeviceContainer ndc;
196  ndc.Add (rightLeafDevices.Get (i));
197  ndc.Add (rightRouterDevices.Get (i));
198  Ipv4InterfaceContainer ifc = rightAddress.Assign (ndc);
199  rightLeafInterfaces.Add (ifc.Get (0));
200  rightRouterInterfaces.Add (ifc.Get (1));
201  rightAddress.NewNetwork ();
202  }
203 
204  if (!nix)
205  {
207  }
208 
209  // Create a packet sink on the right leafs to receive packets from left leafs
210  uint16_t port = 50000;
211  if (systemId == 1)
212  {
213  Address sinkLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
214  PacketSinkHelper sinkHelper ("ns3::UdpSocketFactory", sinkLocalAddress);
215  ApplicationContainer sinkApp;
216  for (uint32_t i = 0; i < 4; ++i)
217  {
218  sinkApp.Add (sinkHelper.Install (rightLeafNodes.Get (i)));
219  }
220  sinkApp.Start (Seconds (1.0));
221  sinkApp.Stop (Seconds (5));
222  }
223 
224  // Create the OnOff applications to send
225  if (systemId == 0)
226  {
227  OnOffHelper clientHelper ("ns3::UdpSocketFactory", Address ());
228  clientHelper.SetAttribute
229  ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
230  clientHelper.SetAttribute
231  ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
232 
233  ApplicationContainer clientApps;
234  for (uint32_t i = 0; i < 4; ++i)
235  {
236  AddressValue remoteAddress
237  (InetSocketAddress (rightLeafInterfaces.GetAddress (i), port));
238  clientHelper.SetAttribute ("Remote", remoteAddress);
239  clientApps.Add (clientHelper.Install (leftLeafNodes.Get (i)));
240  }
241  clientApps.Start (Seconds (1.0));
242  clientApps.Stop (Seconds (5));
243  }
244 
245  Simulator::Stop (Seconds (5));
246  Simulator::Run ();
248  // Exit the MPI execution environment
250  return 0;
251 #else
252  NS_FATAL_ERROR ("Can't use distributed simulator without MPI compiled in");
253 #endif
254 }
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
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. Makes all nodes in the simulation into routers.
hold variables of type string
Definition: string.h:19
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> 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)
Definition: simulator.cc:157
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
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...
static void Disable()
Build a set of PointToPointNetDevice objects.
void SetDeviceAttribute(std::string name, const AttributeValue &value)
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
Definition: on-off-helper.h:41
#define NS_FATAL_ERROR(msg)
fatal error handling
Definition: fatal-error.h:72
a polymophic address class
Definition: address.h:86
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
static void Enable(int *pargc, char ***pargv)
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 argumentsInstances of this class can be used to parse command-line arguments: user...
Definition: command-line.h:50
static void Destroy(void)
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)
void SetChannelAttribute(std::string name, const AttributeValue &value)
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...
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Definition: nstime.h:586
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)
Definition: command-line.h:134
static void Stop(void)
Definition: simulator.cc:164
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
void Parse(int argc, char *argv[]) const
Definition: command-line.cc:84
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.
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)
static uint32_t GetSize()
void SetRoutingHelper(const Ipv4RoutingHelper &routing)
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