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