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.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
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
NetDeviceContainer Install(NodeContainer c)
ApplicationContainer Install(Ptr< Node > node) const
Create a UdpEchoServerApplication on the specified Node.
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:202
aggregate IP/TCP/UDP functionality to existing Nodes.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:278
cmd
Definition: second.py:35
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.
static void Add(std::string name, Ptr< Object > object)
Add the association between the string "name" and the Ptr<Object> obj.
Definition: names.cc:770
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:1076
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
LOG_INFO and above.
Definition: log.h:104
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:213
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.
ApplicationContainer Install(Ptr< Node > node) const
Create a udp echo client application on the specified node.
static const uint32_t SNAPLEN_DEFAULT
Default value for maximum octets to save per packet.
Definition: pcap-file.h:46
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.
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
NetDeviceContainer Install(Ptr< Node > node) const
This method creates an ns3::CsmaChannel with the attributes configured by CsmaHelper::SetChannelAttri...
Definition: csma-helper.cc:217
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...
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:1014
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:782
Helper class that adds ns3::Ipv4GlobalRouting objects.
#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:254
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.
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
bool verbose