A Discrete-Event Network Simulator
API
global-routing-multi-switch-plus-router.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 - Chip Webb
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Chip Webb <ns3 (at) chipwebb.com>
18  *
19  */
20 
21 // ###################################################################### //
22 // Network topology //
23 // ---------------------------------------------------------------------- //
24 // //
25 // This example shows two L2 LANs connected by a WAN link and illustrates //
26 // a network that has multiple L2 switches between L3 routers. //
27 // //
28 // It serves as a test case to verify a patch to global-router-interface //
29 // that fixes a previous bug (#2102 in the ns-3 tracker) but is also //
30 // another example program. //
31 // //
32 // The LANs are "top" [192.168.1/24] and "bottom" [192.168.2/24]. //
33 // Each LAN network is interconnected by several L2 switches, and each //
34 // LAN has its own router to act as a gateway with the WAN. Each LAN //
35 // has two endpoints upon which is installed a UDP echo client or server //
36 // that are used to test connectivity over the LANs & WAN. //
37 // //
38 // One pair of UDP endpoints (t3 and b3) have LAN connections with only //
39 // one switch between them and their local routers. This path works with //
40 // unpatched ns3 code (3.24 & earlier) as well as with the patch applied. //
41 // //
42 // Another pair of endpoints (t2 and b2) have LAN connections with //
43 // a chain of multiple switches between them and their local router. //
44 // This path will only work after applying the associated patch. //
45 // //
46 // The LAN links are modeled by half-duplex Ethernet CSMA links which //
47 // have command-line-configurable data rate and latency. //
48 // //
49 // There are two types of CSMA links: 100Mbit and 10Mbit. The 100Mbit //
50 // links are called csmaX, are denoted by [X] in the diagram and can //
51 // be controlled with the --csmaXRate and --csmaXDelay command line args. //
52 // The 10Mbit links are called csmaY, are denoted by [Y] in the diagram //
53 // and can be controlled with the --csmaYRate and --csmaYDelay command //
54 // line arguments. Both the top and bottom LAN have a mixture of //
55 // 100Mbit/s and 10Mbit/s links. //
56 // //
57 // The WAN is modeled by a point-to-point link which has configurable //
58 // data rate and latency. Unlike many typical home/work networks, //
59 // the routers do not perform NAT. //
60 // //
61 // The WAN link is denoted by [P] in the diagram, and the //
62 // speed and latency can be set from the command line with the //
63 // --p2pRate and --p2pDelay options. The default for this link is 5Mbit/s //
64 // and 50ms delay //
65 // //
66 // Note: Names in parenthesis after NetDevices are pcap tap locations. //
67 // //
68 // ---------------------------------------------------------------------- //
69 // //
70 // 192.168. 192.168. //
71 // .1.2 .1.3 //
72 // --------- --------- //
73 // | t2 | | t3 | //
74 // | UDP | | UDP | //
75 // | echo | | echo | Node t2 is a UDP echo client (multi-switch) //
76 // | client| | server| Node t3 is a UDP echo server (single-switch) //
77 // --------- --------- //
78 // CSMA(t2) CSMA(t3) //
79 // [X] [X] //
80 // [X] [X] //
81 // CSMA [X] //
82 // --------- [X] //
83 // | ts4 | [X] Nodes ts1, ts2, ts3 and ts4 are L2 switches //
84 // | (sw) | [X] The top LAN is subnet 192.168.1.* //
85 // --------- [X] //
86 // CSMA [X] The long chain of switches is designed //
87 // [Y] [X] to test whether global-router-interface //
88 // [Y] [X] can fully enumerate an IP subnet that has //
89 // CSMA [X] multiple interconnected L2 switches. //
90 // --------- [X] The problem is documented in Bug #2102. //
91 // | ts3 | [X] //
92 // | (sw) | [X] //
93 // --------- [X] //
94 // CSMA [X] //
95 // [X] [X] //
96 // [X] [X] //
97 // CSMA [X] //
98 // --------- [X] //
99 // | ts2 | [X] //
100 // | (sw) | [X] //
101 // --------- [X] //
102 // CSMA [X] //
103 // [Y] [X] //
104 // [Y] [X] //
105 // CSMA CSMA //
106 // ------------------ //
107 // | ts1 (switch) | //
108 // ------------------ //
109 // CSMA //
110 // [Y] //
111 // [Y] //
112 // CSMA(trlan) 192.168.1.1 //
113 // ------------------ //
114 // | tr (router) | Node tr is an L3 router //
115 // ------------------ (between 192.168.1.* & 76.1.1.*) //
116 // P2P(trwan) 76.1.1.1 //
117 // [P] //
118 // [P] //
119 // [P] //
120 // [P] //
121 // [P] The WAN is 76.1.1.* //
122 // [P] //
123 // [P] //
124 // [P] //
125 // P2P(brwan) 76.1.1.2 //
126 // ------------------ //
127 // | br (router) | Node br is an L3 router //
128 // ------------------ (between 192.168.2.* & 76.1.1.*) //
129 // CSMA(brlan) 192.168.2.1 //
130 // [X] //
131 // [X] //
132 // CSMA //
133 // ------------------ Nodes bs1 to bs5 are L2 switches //
134 // | bs1 (switch) | The bottom LAN is subnet 192.168.2.* //
135 // ------------------ //
136 // CSMA CSMA //
137 // [Y] [Y] //
138 // [Y] [Y] //
139 // CSMA [Y] //
140 // --------- [Y] //
141 // | bs2 | [Y] //
142 // | (sw) | [Y] //
143 // --------- [Y] //
144 // CSMA [Y] //
145 // [X] [Y] //
146 // [X] [Y] //
147 // CSMA [Y] //
148 // --------- [Y] //
149 // | bs3 | [Y] //
150 // | (sw) | [Y] //
151 // --------- [Y] //
152 // CSMA [Y] //
153 // [Y] [Y] //
154 // [Y] [Y] //
155 // CSMA [Y] //
156 // --------- [Y] //
157 // | bs4 | [Y] //
158 // | (sw) | [Y] //
159 // --------- [Y] //
160 // CSMA [Y] //
161 // [X] [Y] //
162 // [X] [Y] //
163 // CSMA [Y] //
164 // --------- [Y] //
165 // | bs5 | [Y] //
166 // | (sw) | [Y] //
167 // --------- [Y] //
168 // CSMA [Y] //
169 // [Y] [Y] //
170 // [Y] [Y] //
171 // CSMA(b2) CSMA(b3) //
172 // --------- --------- //
173 // | b2 | | b3 | //
174 // | UDP | | UDP | //
175 // | echo | | echo | Node b2 is a UDP echo server (multi-switch) //
176 // | server| | client| Node b3 is a UDP echo client (single-switch) //
177 // --------- --------- //
178 // 192.168. 192.168. //
179 // .2.2 .2.3 //
180 // //
181 // ---------------------------------------------------------------------- //
182 // Explanation //
183 // ---------------------------------------------------------------------- //
184 // //
185 // UDP packet flows are configured between nodes on the top and bottom //
186 // LANs (using UDP echo client & server). //
187 // //
188 // The network carrying the "multi switch" UDP flow is connected with //
189 // multiple L2 switches between L3 nodes so it should only work if the //
190 // global-router-interface source code properly supports bridging. //
191 // //
192 // The network carrying the "single switch" UDP flow is connected with //
193 // only one L2 switch between L3 nodes so it should work with or //
194 // without the patch //
195 // //
196 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = //
197 // Traffic summary: //
198 // ---------------------------------------------------------------------- //
199 // //
200 // - UDP flow from t2 (192.168.1.2) to b2 (192.168.2.2) [Multi Switch] //
201 // from b3 (192.168.2.3) to t3 (192.168.1.3) [Single Switch] //
202 // //
203 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = //
204 // Node List & IP addresses assigned during simulation //
205 // ---------------------------------------------------------------------- //
206 // t2 : 192.168.1.2 : Top multi-switch UDP echo client //
207 // t3 : 192.168.1.3 : Top single-switch UDP echo server //
208 // : //
209 // ts1 : <no IP> : Top switch 1 (bridge) //
210 // ts2 : <no IP> : Top switch 2 (bridge) //
211 // ts3 : <no IP> : Top switch 3 (bridge) //
212 // ts4 : <no IP> : Top switch 4 (bridge) //
213 // : //
214 // tr : 192.168.1.1 : Router connecting top LAN (192.168.1.*) //
215 // : 76.1.1.1 : to the WAN //
216 // : //
217 // br : 76.1.1.2 : Router connecting the WAN //
218 // : 192.168.2.1 : to bot LAN (192.168.2.*) //
219 // : //
220 // bs1 : <no IP> : Bottom switch 1 (bridge) //
221 // bs2 : <no IP> : Bottom switch 2 (bridge) //
222 // bs3 : <no IP> : Bottom switch 3 (bridge) //
223 // bs4 : <no IP> : Bottom switch 4 (bridge) //
224 // bs5 : <no IP> : Bottom switch 5 (bridge) //
225 // : //
226 // b2 : 192.168.2.2 : Bottom multi-switch UDP echo server //
227 // b3 : 192.168.2.3 : Bottom single-switch UDP echo client //
228 // : //
229 // ---------------------------------------------------------------------- //
230 // Author: Chip Webb <ns3 (a) chipwebb dot com> //
231 // ###################################################################### //
232 
233 #include "ns3/applications-module.h"
234 #include "ns3/bridge-module.h"
235 #include "ns3/core-module.h"
236 #include "ns3/csma-module.h"
237 #include "ns3/internet-module.h"
238 #include "ns3/network-module.h"
239 #include "ns3/point-to-point-module.h"
240 
241 #include <fstream>
242 #include <iostream>
243 
244 using namespace ns3;
245 
246 // ########################################################################
247 // Main routine
248 // ########################################################################
249 NS_LOG_COMPONENT_DEFINE("GlobalRoutingMultiSwitchPlusRouter");
250 
251 #define vssearch(loc, vec) std::find((vec).begin(), (vec).end(), (loc)) != (vec).end()
252 
253 int
254 main(int argc, char* argv[])
255 {
256  // ----------------------------------------------------------------------
257  // Default values for command line arguments
258  // ----------------------------------------------------------------------
259  bool verbose = true;
260 
261  int simDurationSeconds = 60;
262 
263  bool enableUdpMultiSW = true;
264  bool enableUdpSingleSW = true;
265 
266  std::string pcapLocations = "";
267  uint32_t snapLen = PcapFile::SNAPLEN_DEFAULT;
268 
269  std::string csmaXLinkDataRate = "100Mbps";
270  std::string csmaXLinkDelay = "500ns";
271 
272  std::string csmaYLinkDataRate = "10Mbps";
273  std::string csmaYLinkDelay = "500ns";
274 
275  std::string p2pLinkDataRate = "5Mbps";
276  std::string p2pLinkDelay = "50ms";
277 
278  uint16_t udpEchoPort = 9; // The well-known UDP echo port
279 
280  // ----------------------------------------------------------------------
281  // Create command line options and get them
282  // ----------------------------------------------------------------------
283  CommandLine cmd(__FILE__);
284 
285  cmd.Usage("NOTE: valid --pcap arguments are: 't2,t3,b2,b3,trlan,trwan,brlan,brwan'");
286 
287  cmd.AddValue("verbose", "Enable printing informational messages", verbose);
288 
289  cmd.AddValue("duration", "Duration of simulation.", simDurationSeconds);
290 
291  cmd.AddValue("udpMultiSW", "Enable udp over multi-switch links", enableUdpMultiSW);
292  cmd.AddValue("udpSingleSW", "Enable udp over single-switch links", enableUdpSingleSW);
293 
294  cmd.AddValue("pcap", "Comma separated list of PCAP Locations to tap", pcapLocations);
295  cmd.AddValue("snapLen", "PCAP packet capture length", snapLen);
296 
297  cmd.AddValue("csmaXRate", "CSMA X Link data rate", csmaXLinkDataRate);
298  cmd.AddValue("csmaXDelay", "CSMA X Link delay", csmaXLinkDelay);
299 
300  cmd.AddValue("csmaYRate", "CSMA Y Link data rate", csmaYLinkDataRate);
301  cmd.AddValue("csmaYDelay", "CSMA Y Link delay", csmaYLinkDelay);
302 
303  cmd.AddValue("p2pRate", "P2P Link data rate", p2pLinkDataRate);
304  cmd.AddValue("p2pDelay", "P2P Link delay", p2pLinkDelay);
305 
306  cmd.Parse(argc, argv);
307 
308  // --------------------------------------------------------------------
309  // Users may find it convenient to turn on explicit debugging
310  // for selected modules; the below lines suggest how to do this
311  // --------------------------------------------------------------------
312  if (verbose)
313  {
314  LogComponentEnable("GlobalRoutingMultiSwitchPlusRouter", LOG_LEVEL_INFO);
315  }
316 
317  // ======================================================================
318  // Define the list of valid PCAP taps
319  // ----------------------------------------------------------------------
320  const std::vector<std::string> pcapTaps{
321  "t2", // multi-switch UDP echo client
322  "t3", // single-switch UDP echo server
323  "b2", // multi-switch UDP echo server
324  "b3", // single-switch UDP echo client
325  "trlan", // top router LAN side
326  "trwan", // top router WAN side
327  "brlan", // bottom router LAN side
328  "brwan", // bottom router WAN side
329  };
330 
331  // ----------------------------------------------------------------------
332  // Parse the pcapLocations string into pcapLocationVec
333  // ----------------------------------------------------------------------
334  std::vector<std::string> pcapLocationVec;
335  if (!pcapLocations.empty())
336  {
337  std::stringstream sStream(pcapLocations);
338 
339  while (sStream.good())
340  {
341  std::string substr;
342  getline(sStream, substr, ',');
343  if (vssearch(substr, pcapTaps))
344  {
345  pcapLocationVec.push_back(substr);
346  }
347  else
348  {
349  NS_LOG_ERROR("WARNING: Unrecognized PCAP location: <" + substr + ">");
350  }
351  }
352 
353  for (std::vector<std::string>::const_iterator ploc = pcapLocationVec.begin();
354  ploc != pcapLocationVec.end();
355  ++ploc)
356  {
357  NS_LOG_INFO("PCAP capture at: <" + *ploc + ">");
358  }
359  }
360 
361  // ======================================================================
362  // Set some simulator-wide values
363  // ======================================================================
364 
365  // ----------------------------------------------------------------------
366  // Set PCAP packet capture maximum packet length
367  // ----------------------------------------------------------------------
368  if (snapLen != PcapFile::SNAPLEN_DEFAULT)
369  {
370  Config::SetDefault("ns3::PcapFileWrapper::CaptureSize", UintegerValue(snapLen));
371  }
372 
373  // ======================================================================
374  // Create the nodes & links required for the topology shown in comments above.
375  // ----------------------------------------------------------------------
376  NS_LOG_INFO("INFO: Create nodes."); // - - - - - - - - - - - - - - - -
377  // Node IP : Description
378  // - - - - - - - - - - - - - - - -
379  Ptr<Node> t2 = CreateObject<Node>(); // 192.168.1.2 : Top multi-switch udp echo client
380  Ptr<Node> t3 = CreateObject<Node>(); // 192.168.1.3 : Top single-switch udp echo server
381  // :
382  Ptr<Node> ts1 = CreateObject<Node>(); // <no IP> : Top switch #1 (bridge)
383  Ptr<Node> ts2 = CreateObject<Node>(); // <no IP> : Top switch #2 (bridge)
384  Ptr<Node> ts3 = CreateObject<Node>(); // <no IP> : Top switch #3 (bridge)
385  Ptr<Node> ts4 = CreateObject<Node>(); // <no IP> : Top switch #4 (bridge)
386  // :
387  Ptr<Node> tr = CreateObject<Node>(); // 192.168.1.1 : Router connecting top LAN & WAN
388  // 76.1.1.1 :
389  // :
390  Ptr<Node> br = CreateObject<Node>(); // 76.1.1.2 : Router connecting WAN & bottom LANs
391  // 192.168.2.1 :
392  // :
393  Ptr<Node> bs1 = CreateObject<Node>(); // <no IP> : Bottom switch #1 (bridge)
394  Ptr<Node> bs2 = CreateObject<Node>(); // <no IP> : Bottom switch #2 (bridge)
395  Ptr<Node> bs3 = CreateObject<Node>(); // <no IP> : Bottom switch #3 (bridge)
396  Ptr<Node> bs4 = CreateObject<Node>(); // <no IP> : Bottom switch #4 (bridge)
397  Ptr<Node> bs5 = CreateObject<Node>(); // <no IP> : Bottom switch #5 (bridge)
398  // :
399  Ptr<Node> b2 = CreateObject<Node>(); // 192.168.2.2 : Bottom multi-switch udp echo server
400 
401  Ptr<Node> b3 = CreateObject<Node>(); // 192.168.2.3 : Bottom single-switch udp echo client
402  // - - - - - - - - - - - - - - - -
403 
404  // ----------------------------------------------------------------------
405  // Give the nodes names
406  // ----------------------------------------------------------------------
407  Names::Add("t2", t2);
408  Names::Add("t3", t3);
409  Names::Add("ts1", ts1);
410  Names::Add("ts2", ts2);
411  Names::Add("ts3", ts3);
412  Names::Add("ts4", ts4);
413  Names::Add("tr", tr);
414  Names::Add("br", br);
415  Names::Add("bs1", bs1);
416  Names::Add("bs2", bs2);
417  Names::Add("bs3", bs3);
418  Names::Add("bs4", bs4);
419  Names::Add("bs5", bs5);
420  Names::Add("b2", b2);
421  Names::Add("b3", b3);
422 
423  // ======================================================================
424  // Create CSMA links to use for connecting LAN nodes together
425  // ----------------------------------------------------------------------
426 
427  // ----------------------------------------
428  // CSMA [X]
429  // ----------------------------------------
430  NS_LOG_INFO("L2: Create a " << csmaXLinkDataRate << " " << csmaXLinkDelay
431  << " CSMA link for csmaX for LANs.");
432  CsmaHelper csmaX;
433  csmaX.SetChannelAttribute("DataRate", StringValue(csmaXLinkDataRate));
434  csmaX.SetChannelAttribute("Delay", StringValue(csmaXLinkDelay));
435 
436  // ----------------------------------------
437  // CSMA [Y]
438  // ----------------------------------------
439  NS_LOG_INFO("L2: Create a " << csmaYLinkDataRate << " " << csmaYLinkDelay
440  << " CSMA link for csmaY for LANs.");
441  CsmaHelper csmaY;
442  csmaY.SetChannelAttribute("DataRate", StringValue(csmaYLinkDataRate));
443  csmaY.SetChannelAttribute("Delay", StringValue(csmaYLinkDelay));
444 
445  // ----------------------------------------------------------------------
446  // Now, connect the top LAN nodes together with csma links.
447  // ----------------------------------------------------------------------
448  NS_LOG_INFO("L2: Connect nodes on top LAN together with half-duplex CSMA links.");
449 
450  // Multi-switch top LAN chain: t2-ts4-ts3-ts2-ts1-tr
451  NetDeviceContainer link_t2_ts4 = csmaX.Install(NodeContainer(t2, ts4));
452  NetDeviceContainer link_ts4_ts3 = csmaY.Install(NodeContainer(ts4, ts3));
453  NetDeviceContainer link_ts3_ts2 = csmaX.Install(NodeContainer(ts3, ts2));
454  NetDeviceContainer link_ts2_ts1 = csmaY.Install(NodeContainer(ts2, ts1));
455 
456  // Single-switch top LAN link: t3-ts1-tr
457  NetDeviceContainer link_t3_ts1 = csmaX.Install(NodeContainer(t3, ts1));
458 
459  // Common link for top LAN between ts1 and tr (for t2 and t3 to get to tr)
460  NetDeviceContainer link_tr_ts1 = csmaY.Install(NodeContainer(tr, ts1));
461 
462  // ----------------------------------------------------------------------
463  // And repeat above steps to connect the bottom LAN nodes together
464  // ----------------------------------------------------------------------
465  NS_LOG_INFO("L2: Connect nodes on bottom LAN together with half-duplex CSMA links.");
466 
467  // Multi-switch bottom LAN chain: b2-bs5-bs4-bs3-bs2-bs1-br
468  NetDeviceContainer link_b2_bs5 = csmaY.Install(NodeContainer(b2, bs5));
469  NetDeviceContainer link_bs5_bs4 = csmaX.Install(NodeContainer(bs5, bs4));
470  NetDeviceContainer link_bs4_bs3 = csmaY.Install(NodeContainer(bs4, bs3));
471  NetDeviceContainer link_bs3_bs2 = csmaX.Install(NodeContainer(bs3, bs2));
472  NetDeviceContainer link_bs2_bs1 = csmaY.Install(NodeContainer(bs2, bs1));
473 
474  // Single-switch bottom LAN link: b3-bs1-br
475  NetDeviceContainer link_b3_bs1 = csmaY.Install(NodeContainer(b3, bs1));
476 
477  // Common link for bottom LAN between bs1 and br (for b2 and b3 to get to br)
478  NetDeviceContainer link_br_bs1 = csmaX.Install(NodeContainer(br, bs1));
479 
480  // ======================================================================
481  // Create a point-to-point link for connecting WAN nodes together
482  // (this type of link is full-duplex)
483  // ----------------------------------------------------------------------
484  NS_LOG_INFO("L2: Create a " << p2pLinkDataRate << " " << p2pLinkDelay
485  << " Point-to-Point link for the WAN.");
486 
487  PointToPointHelper p2p;
488  p2p.SetDeviceAttribute("DataRate", StringValue(p2pLinkDataRate));
489  p2p.SetChannelAttribute("Delay", StringValue(p2pLinkDelay));
490 
491  // ----------------------------------------------------------------------
492  // Now, connect top router to bottom router with a p2p WAN link
493  // ----------------------------------------------------------------------
494  NS_LOG_INFO("L2: Connect the routers together with the Point-to-Point WAN link.");
495 
496  NetDeviceContainer link_tr_br;
497  link_tr_br = p2p.Install(NodeContainer(tr, br));
498 
499  // ======================================================================
500  // Manually create the list of NetDevices for each switch
501  // ----------------------------------------------------------------------
502 
503  // Top Switch 4 NetDevices
504  NetDeviceContainer ts4nd;
505  ts4nd.Add(link_t2_ts4.Get(1));
506  ts4nd.Add(link_ts4_ts3.Get(0));
507 
508  // Top Switch 3 NetDevices
509  NetDeviceContainer ts3nd;
510  ts3nd.Add(link_ts4_ts3.Get(1));
511  ts3nd.Add(link_ts3_ts2.Get(0));
512 
513  // Top Switch 2 NetDevices
514  NetDeviceContainer ts2nd;
515  ts2nd.Add(link_ts3_ts2.Get(1));
516  ts2nd.Add(link_ts2_ts1.Get(0));
517 
518  // Top Switch 1 NetDevices
519  NetDeviceContainer ts1nd;
520  ts1nd.Add(link_ts2_ts1.Get(1));
521  ts1nd.Add(link_t3_ts1.Get(1));
522  ts1nd.Add(link_tr_ts1.Get(1));
523 
524  // Bottom Switch 1 NetDevices
525  NetDeviceContainer bs1nd;
526  bs1nd.Add(link_br_bs1.Get(1));
527  bs1nd.Add(link_bs2_bs1.Get(1));
528  bs1nd.Add(link_b3_bs1.Get(1));
529 
530  // Bottom Switch 2 NetDevices
531  NetDeviceContainer bs2nd;
532  bs2nd.Add(link_bs2_bs1.Get(0));
533  bs2nd.Add(link_bs3_bs2.Get(1));
534 
535  // Bottom Switch 3 NetDevices
536  NetDeviceContainer bs3nd;
537  bs3nd.Add(link_bs3_bs2.Get(0));
538  bs3nd.Add(link_bs4_bs3.Get(1));
539 
540  // Bottom Switch 4 NetDevices
541  NetDeviceContainer bs4nd;
542  bs4nd.Add(link_bs4_bs3.Get(0));
543  bs4nd.Add(link_bs5_bs4.Get(1));
544 
545  // Bottom Switch 5 NetDevices
546  NetDeviceContainer bs5nd;
547  bs5nd.Add(link_bs5_bs4.Get(0));
548  bs5nd.Add(link_b2_bs5.Get(1));
549 
550  // ======================================================================
551  // Install bridging code on each switch
552  // ----------------------------------------------------------------------
553  BridgeHelper bridge;
554 
555  bridge.Install(ts1, ts1nd);
556  bridge.Install(ts2, ts2nd);
557  bridge.Install(ts3, ts3nd);
558  bridge.Install(ts4, ts4nd);
559 
560  bridge.Install(bs1, bs1nd);
561  bridge.Install(bs2, bs2nd);
562  bridge.Install(bs3, bs3nd);
563  bridge.Install(bs4, bs4nd);
564  bridge.Install(bs5, bs5nd);
565 
566  // ======================================================================
567  // Install the L3 internet stack (TCP/IP)
568  // ----------------------------------------------------------------------
569  InternetStackHelper ns3IpStack;
570 
571  // ----------------------------------------------------------------------
572  // Install the L3 internet stack on UDP endpoints
573  // ----------------------------------------------------------------------
574  NS_LOG_INFO("L3: Install the ns3 IP stack on udp client and server nodes.");
575  NodeContainer endpointNodes(t2, t3, b2, b3);
576  ns3IpStack.Install(endpointNodes);
577 
578  // ----------------------------------------------------------------------
579  // Install the L3 internet stack on routers.
580  // ----------------------------------------------------------------------
581  NS_LOG_INFO("L3: Install the ns3 IP stack on routers.");
582  NodeContainer routerNodes(tr, br);
583  ns3IpStack.Install(routerNodes);
584 
585  // ======================================================================
586  // Assign top LAN IP addresses
587  // ----------------------------------------------------------------------
588  NS_LOG_INFO("L3: Assign top LAN IP Addresses.");
589 
590  NetDeviceContainer topLanIpDevices; // - - - - - -- - - - - - -
591  topLanIpDevices.Add(link_tr_ts1.Get(0)); // NOTE: order matters here
592  topLanIpDevices.Add(link_t2_ts4.Get(0)); // for IP address
593  topLanIpDevices.Add(link_t3_ts1.Get(0)); // assignment
594  // - - - - - -- - - - - - -
595  Ipv4AddressHelper ipv4;
596  ipv4.SetBase("192.168.1.0", "255.255.255.0");
597  ipv4.Assign(topLanIpDevices);
598 
599  // ----------------------------------------------------------------------
600  // Assign bottom LAN IP addresses
601  // ----------------------------------------------------------------------
602  NS_LOG_INFO("L3: Assign bottom LAN IP Addresses.");
603 
604  NetDeviceContainer botLanIpDevices; // - - - - - -- - - - - - -
605  botLanIpDevices.Add(link_br_bs1.Get(0)); // NOTE: order matters here
606  botLanIpDevices.Add(link_b2_bs5.Get(0)); // for IP address
607  botLanIpDevices.Add(link_b3_bs1.Get(0)); // assignment
608  // - - - - - -- - - - - - -
609 
610  ipv4.SetBase("192.168.2.0", "255.255.255.0");
611  ipv4.Assign(botLanIpDevices);
612 
613  // ----------------------------------------------------------------------
614  // Assign WAN IP addresses
615  // ----------------------------------------------------------------------
616  NS_LOG_INFO("L3: Assign WAN IP Addresses.");
617 
618  ipv4.SetBase("76.1.1.0", "255.255.255.0");
619  ipv4.Assign(link_tr_br);
620 
621  // ======================================================================
622  // Calculate and populate routing tables
623  // ----------------------------------------------------------------------
624  NS_LOG_INFO("L3: Populate routing tables.");
626 
627  // ======================================================================
628  // Multi-Switch UDP traffic generation
629  // ----------------------------------------------------------------------
631 
632  if (enableUdpMultiSW)
633  {
634  // ------------------------------------------------------------------
635  // Install multi-switch UDP echo server on b2
636  // ------------------------------------------------------------------
637  NS_LOG_INFO("APP: Multi-Switch UDP server (on node b2 of bottom LAN)");
638 
639  UdpEchoServerHelper server(udpEchoPort);
640 
641  ApplicationContainer serverApp = server.Install(b2);
642  serverApp.Start(Seconds(0.5));
643  serverApp.Stop(Seconds(simDurationSeconds));
644 
645  // ------------------------------------------------------------------
646  // Install multi-switch UDP echo client on t2
647  // ------------------------------------------------------------------
648  NS_LOG_INFO("APP: Multi-Switch UDP client (on node t2 of top LAN)");
649 
650  Time interPacketInterval = Seconds(0.005);
651  uint32_t packetSize = 1000;
652  uint32_t maxPacketCount = (simDurationSeconds - 2.0) / 0.005;
653 
654  UdpEchoClientHelper client(Ipv4Address("192.168.2.2"), udpEchoPort);
655 
656  client.SetAttribute("MaxPackets", UintegerValue(maxPacketCount));
657  client.SetAttribute("Interval", TimeValue(interPacketInterval));
658  client.SetAttribute("PacketSize", UintegerValue(packetSize));
659 
660  ApplicationContainer clientApp = client.Install(t2);
661  clientApp.Start(Seconds(0.5));
662  clientApp.Stop(Seconds(simDurationSeconds));
663  }
664 
665  // ======================================================================
666  // Single-Switch UDP traffic generation
667  // ----------------------------------------------------------------------
668  if (enableUdpSingleSW)
669  {
670  // ------------------------------------------------------------------
671  // Install single-switch UDP echo server on t3
672  // ------------------------------------------------------------------
673  NS_LOG_INFO("APP: Single-Switch UDP server (on node t3 of top LAN)");
674 
675  UdpEchoServerHelper server(udpEchoPort);
676 
677  ApplicationContainer serverApp = server.Install(t3);
678  serverApp.Start(Seconds(0.5));
679  serverApp.Stop(Seconds(simDurationSeconds));
680 
681  // ------------------------------------------------------------------
682  // Install single-switch UDP echo client on b3
683  // ------------------------------------------------------------------
684  NS_LOG_INFO("APP: Single-Switch UDP client (on node b3 bottom LAN)");
685 
686  Time interPacketInterval = Seconds(0.005);
687  uint32_t packetSize = 1000;
688  uint32_t maxPacketCount = (simDurationSeconds - 2.0) / 0.005;
689 
690  UdpEchoClientHelper client(Ipv4Address("192.168.1.3"), udpEchoPort);
691 
692  client.SetAttribute("MaxPackets", UintegerValue(maxPacketCount));
693  client.SetAttribute("Interval", TimeValue(interPacketInterval));
694  client.SetAttribute("PacketSize", UintegerValue(packetSize));
695 
696  ApplicationContainer clientApp = client.Install(b3);
697  clientApp.Start(Seconds(0.5));
698  clientApp.Stop(Seconds(simDurationSeconds));
699  }
700 
701  // ======================================================================
702  // Print routing tables at T=0.1
703  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
704  // NOTE: Node 0 and Node 13 must have non-empty tables (except for local
705  // loopback and local LAN) if routing is operating correctly.
706  // ----------------------------------------------------------------------
707  NS_LOG_INFO("Set up to print routing tables at T=0.1s");
708 
709  Ptr<OutputStreamWrapper> routingStream =
710  Create<OutputStreamWrapper>("global-routing-multi-switch-plus-router.routes",
711  std::ios::out);
712 
714 
715  // ======================================================================
716  // Configure PCAP traces
717  // ----------------------------------------------------------------------
718  NS_LOG_INFO("Configure PCAP Tracing (if any configured).");
719 
720  // - - - - - - - - - - - - - -
721  // multi-switch UDP echo client
722  // - - - - - - - - - - - - - -
723  if (vssearch("t2", pcapLocationVec))
724  {
725  csmaX.EnablePcap("t2.pcap", topLanIpDevices.Get(1), true, true);
726  }
727 
728  // - - - - - - - - - - - - - -
729  // multi-switch UDP echo server
730  // - - - - - - - - - - - - - -
731  if (vssearch("b2", pcapLocationVec))
732  {
733  csmaY.EnablePcap("b2.pcap", botLanIpDevices.Get(1), true, true);
734  }
735 
736  // - - - - - - - - - - - - - -
737  // single-switch UDP echo client
738  // - - - - - - - - - - - - - -
739  if (vssearch("b3", pcapLocationVec))
740  {
741  csmaY.EnablePcap("b3.pcap", botLanIpDevices.Get(2), true, true);
742  }
743 
744  // - - - - - - - - - - - - - -
745  // single-switch UDP echo server
746  // - - - - - - - - - - - - - -
747  if (vssearch("t3", pcapLocationVec))
748  {
749  csmaX.EnablePcap("t3.pcap", topLanIpDevices.Get(2), true, true);
750  }
751 
752  // - - - - - - - - - - - - - -
753  // top router, LAN side
754  // - - - - - - - - - - - - - -
755  if (vssearch("trlan", pcapLocationVec))
756  {
757  csmaY.EnablePcap("trlan.pcap", topLanIpDevices.Get(0), true, true);
758  }
759 
760  // - - - - - - - - - - - - - -
761  // bottom router, LAN side
762  // - - - - - - - - - - - - - -
763  if (vssearch("brlan", pcapLocationVec))
764  {
765  csmaX.EnablePcap("brlan.pcap", botLanIpDevices.Get(0), true, true);
766  }
767 
768  // - - - - - - - - - - - - - -
769  // top router, WAN side
770  // - - - - - - - - - - - - - -
771  if (vssearch("trwan", pcapLocationVec))
772  {
773  p2p.EnablePcap("trwan.pcap", link_tr_br.Get(0), true, true);
774  }
775 
776  // - - - - - - - - - - - - - -
777  // bottom router, WAN side
778  // - - - - - - - - - - - - - -
779  if (vssearch("brwan", pcapLocationVec))
780  {
781  p2p.EnablePcap("brwan.pcap", link_tr_br.Get(1), true, true);
782  }
783 
784  // ======================================================================
785  // Now, do the actual simulation.
786  // ----------------------------------------------------------------------
787  NS_LOG_INFO("Run Simulation for " << simDurationSeconds << " seconds.");
788 
789  Simulator::Stop(Seconds(simDurationSeconds));
790  Simulator::Run();
791 
793  NS_LOG_INFO("Done.");
794 
795  return 0;
796 }
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.
Add capability to bridge multiple LAN segments (IEEE 802.1D bridging)
Definition: bridge-helper.h:45
NetDeviceContainer Install(Ptr< Node > node, NetDeviceContainer c)
This method creates an ns3::BridgeNetDevice with the attributes configured by BridgeHelper::SetDevice...
Parse command-line arguments.
Definition: command-line.h:232
build a set of CsmaNetDevice objects
Definition: csma-helper.h:48
void SetChannelAttribute(std::string n1, const AttributeValue &v1)
Definition: csma-helper.cc:56
NetDeviceContainer Install(Ptr< Node > node) const
This method creates an ns3::CsmaChannel with the attributes configured by CsmaHelper::SetChannelAttri...
Definition: csma-helper.cc:226
aggregate IP/TCP/UDP functionality to existing Nodes.
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Ipv4InterfaceContainer Assign(const NetDeviceContainer &c)
Assign IP addresses to the net devices specified in the container based on the current network prefix...
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:43
static void PopulateRoutingTables()
Build a routing database and initialize the routing tables of the nodes in the simulation.
static void PrintRoutingTableAllAt(Time printTime, Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S)
prints the routing tables of all nodes at a particular time.
static void Add(std::string name, Ptr< Object > object)
Add the association between the string "name" and the Ptr<Object> obj.
Definition: names.cc:776
holds a vector of ns3::NetDevice pointers
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
keep track of a set of node pointers.
static const uint32_t SNAPLEN_DEFAULT
Default value for maximum octets to save per packet.
Definition: pcap-file.h:46
void EnablePcap(std::string prefix, Ptr< NetDevice > nd, bool promiscuous=false, bool explicitFilename=false)
Enable pcap output the indicated net device.
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.
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
NetDeviceContainer Install(NodeContainer c)
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:140
static void Run()
Run the simulation.
Definition: simulator.cc:176
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:184
Hold variables of type string.
Definition: string.h:56
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
AttributeValue implementation for Time.
Definition: nstime.h:1423
Create an application which sends a UDP packet and waits for an echo of this packet.
void SetAttribute(std::string name, const AttributeValue &value)
Record an attribute to be set in each Application after it is is created.
ApplicationContainer Install(Ptr< Node > node) const
Create a udp echo client application on the specified node.
Create a server application which waits for input UDP packets and sends them back to the original sen...
ApplicationContainer Install(Ptr< Node > node) const
Create a UdpEchoServerApplication on the specified Node.
Hold an unsigned integer type.
Definition: uinteger.h:45
#define vssearch(loc, vec)
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:891
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
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:305
@ LOG_LEVEL_INFO
LOG_INFO and above.
Definition: log.h:107
cmd
Definition: second.py:33
bool verbose
static const uint32_t packetSize
Packet size generated at the AP.