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 (auto ploc = pcapLocationVec.begin(); ploc != pcapLocationVec.end(); ++ploc)
354  {
355  NS_LOG_INFO("PCAP capture at: <" + *ploc + ">");
356  }
357  }
358 
359  // ======================================================================
360  // Set some simulator-wide values
361  // ======================================================================
362 
363  // ----------------------------------------------------------------------
364  // Set PCAP packet capture maximum packet length
365  // ----------------------------------------------------------------------
366  if (snapLen != PcapFile::SNAPLEN_DEFAULT)
367  {
368  Config::SetDefault("ns3::PcapFileWrapper::CaptureSize", UintegerValue(snapLen));
369  }
370 
371  // ======================================================================
372  // Create the nodes & links required for the topology shown in comments above.
373  // ----------------------------------------------------------------------
374  NS_LOG_INFO("INFO: Create nodes."); // - - - - - - - - - - - - - - - -
375  // Node IP : Description
376  // - - - - - - - - - - - - - - - -
377  Ptr<Node> t2 = CreateObject<Node>(); // 192.168.1.2 : Top multi-switch udp echo client
378  Ptr<Node> t3 = CreateObject<Node>(); // 192.168.1.3 : Top single-switch udp echo server
379  // :
380  Ptr<Node> ts1 = CreateObject<Node>(); // <no IP> : Top switch #1 (bridge)
381  Ptr<Node> ts2 = CreateObject<Node>(); // <no IP> : Top switch #2 (bridge)
382  Ptr<Node> ts3 = CreateObject<Node>(); // <no IP> : Top switch #3 (bridge)
383  Ptr<Node> ts4 = CreateObject<Node>(); // <no IP> : Top switch #4 (bridge)
384  // :
385  Ptr<Node> tr = CreateObject<Node>(); // 192.168.1.1 : Router connecting top LAN & WAN
386  // 76.1.1.1 :
387  // :
388  Ptr<Node> br = CreateObject<Node>(); // 76.1.1.2 : Router connecting WAN & bottom LANs
389  // 192.168.2.1 :
390  // :
391  Ptr<Node> bs1 = CreateObject<Node>(); // <no IP> : Bottom switch #1 (bridge)
392  Ptr<Node> bs2 = CreateObject<Node>(); // <no IP> : Bottom switch #2 (bridge)
393  Ptr<Node> bs3 = CreateObject<Node>(); // <no IP> : Bottom switch #3 (bridge)
394  Ptr<Node> bs4 = CreateObject<Node>(); // <no IP> : Bottom switch #4 (bridge)
395  Ptr<Node> bs5 = CreateObject<Node>(); // <no IP> : Bottom switch #5 (bridge)
396  // :
397  Ptr<Node> b2 = CreateObject<Node>(); // 192.168.2.2 : Bottom multi-switch udp echo server
398 
399  Ptr<Node> b3 = CreateObject<Node>(); // 192.168.2.3 : Bottom single-switch udp echo client
400  // - - - - - - - - - - - - - - - -
401 
402  // ----------------------------------------------------------------------
403  // Give the nodes names
404  // ----------------------------------------------------------------------
405  Names::Add("t2", t2);
406  Names::Add("t3", t3);
407  Names::Add("ts1", ts1);
408  Names::Add("ts2", ts2);
409  Names::Add("ts3", ts3);
410  Names::Add("ts4", ts4);
411  Names::Add("tr", tr);
412  Names::Add("br", br);
413  Names::Add("bs1", bs1);
414  Names::Add("bs2", bs2);
415  Names::Add("bs3", bs3);
416  Names::Add("bs4", bs4);
417  Names::Add("bs5", bs5);
418  Names::Add("b2", b2);
419  Names::Add("b3", b3);
420 
421  // ======================================================================
422  // Create CSMA links to use for connecting LAN nodes together
423  // ----------------------------------------------------------------------
424 
425  // ----------------------------------------
426  // CSMA [X]
427  // ----------------------------------------
428  NS_LOG_INFO("L2: Create a " << csmaXLinkDataRate << " " << csmaXLinkDelay
429  << " CSMA link for csmaX for LANs.");
430  CsmaHelper csmaX;
431  csmaX.SetChannelAttribute("DataRate", StringValue(csmaXLinkDataRate));
432  csmaX.SetChannelAttribute("Delay", StringValue(csmaXLinkDelay));
433 
434  // ----------------------------------------
435  // CSMA [Y]
436  // ----------------------------------------
437  NS_LOG_INFO("L2: Create a " << csmaYLinkDataRate << " " << csmaYLinkDelay
438  << " CSMA link for csmaY for LANs.");
439  CsmaHelper csmaY;
440  csmaY.SetChannelAttribute("DataRate", StringValue(csmaYLinkDataRate));
441  csmaY.SetChannelAttribute("Delay", StringValue(csmaYLinkDelay));
442 
443  // ----------------------------------------------------------------------
444  // Now, connect the top LAN nodes together with csma links.
445  // ----------------------------------------------------------------------
446  NS_LOG_INFO("L2: Connect nodes on top LAN together with half-duplex CSMA links.");
447 
448  // Multi-switch top LAN chain: t2-ts4-ts3-ts2-ts1-tr
449  NetDeviceContainer link_t2_ts4 = csmaX.Install(NodeContainer(t2, ts4));
450  NetDeviceContainer link_ts4_ts3 = csmaY.Install(NodeContainer(ts4, ts3));
451  NetDeviceContainer link_ts3_ts2 = csmaX.Install(NodeContainer(ts3, ts2));
452  NetDeviceContainer link_ts2_ts1 = csmaY.Install(NodeContainer(ts2, ts1));
453 
454  // Single-switch top LAN link: t3-ts1-tr
455  NetDeviceContainer link_t3_ts1 = csmaX.Install(NodeContainer(t3, ts1));
456 
457  // Common link for top LAN between ts1 and tr (for t2 and t3 to get to tr)
458  NetDeviceContainer link_tr_ts1 = csmaY.Install(NodeContainer(tr, ts1));
459 
460  // ----------------------------------------------------------------------
461  // And repeat above steps to connect the bottom LAN nodes together
462  // ----------------------------------------------------------------------
463  NS_LOG_INFO("L2: Connect nodes on bottom LAN together with half-duplex CSMA links.");
464 
465  // Multi-switch bottom LAN chain: b2-bs5-bs4-bs3-bs2-bs1-br
466  NetDeviceContainer link_b2_bs5 = csmaY.Install(NodeContainer(b2, bs5));
467  NetDeviceContainer link_bs5_bs4 = csmaX.Install(NodeContainer(bs5, bs4));
468  NetDeviceContainer link_bs4_bs3 = csmaY.Install(NodeContainer(bs4, bs3));
469  NetDeviceContainer link_bs3_bs2 = csmaX.Install(NodeContainer(bs3, bs2));
470  NetDeviceContainer link_bs2_bs1 = csmaY.Install(NodeContainer(bs2, bs1));
471 
472  // Single-switch bottom LAN link: b3-bs1-br
473  NetDeviceContainer link_b3_bs1 = csmaY.Install(NodeContainer(b3, bs1));
474 
475  // Common link for bottom LAN between bs1 and br (for b2 and b3 to get to br)
476  NetDeviceContainer link_br_bs1 = csmaX.Install(NodeContainer(br, bs1));
477 
478  // ======================================================================
479  // Create a point-to-point link for connecting WAN nodes together
480  // (this type of link is full-duplex)
481  // ----------------------------------------------------------------------
482  NS_LOG_INFO("L2: Create a " << p2pLinkDataRate << " " << p2pLinkDelay
483  << " Point-to-Point link for the WAN.");
484 
486  p2p.SetDeviceAttribute("DataRate", StringValue(p2pLinkDataRate));
487  p2p.SetChannelAttribute("Delay", StringValue(p2pLinkDelay));
488 
489  // ----------------------------------------------------------------------
490  // Now, connect top router to bottom router with a p2p WAN link
491  // ----------------------------------------------------------------------
492  NS_LOG_INFO("L2: Connect the routers together with the Point-to-Point WAN link.");
493 
494  NetDeviceContainer link_tr_br;
495  link_tr_br = p2p.Install(NodeContainer(tr, br));
496 
497  // ======================================================================
498  // Manually create the list of NetDevices for each switch
499  // ----------------------------------------------------------------------
500 
501  // Top Switch 4 NetDevices
502  NetDeviceContainer ts4nd;
503  ts4nd.Add(link_t2_ts4.Get(1));
504  ts4nd.Add(link_ts4_ts3.Get(0));
505 
506  // Top Switch 3 NetDevices
507  NetDeviceContainer ts3nd;
508  ts3nd.Add(link_ts4_ts3.Get(1));
509  ts3nd.Add(link_ts3_ts2.Get(0));
510 
511  // Top Switch 2 NetDevices
512  NetDeviceContainer ts2nd;
513  ts2nd.Add(link_ts3_ts2.Get(1));
514  ts2nd.Add(link_ts2_ts1.Get(0));
515 
516  // Top Switch 1 NetDevices
517  NetDeviceContainer ts1nd;
518  ts1nd.Add(link_ts2_ts1.Get(1));
519  ts1nd.Add(link_t3_ts1.Get(1));
520  ts1nd.Add(link_tr_ts1.Get(1));
521 
522  // Bottom Switch 1 NetDevices
523  NetDeviceContainer bs1nd;
524  bs1nd.Add(link_br_bs1.Get(1));
525  bs1nd.Add(link_bs2_bs1.Get(1));
526  bs1nd.Add(link_b3_bs1.Get(1));
527 
528  // Bottom Switch 2 NetDevices
529  NetDeviceContainer bs2nd;
530  bs2nd.Add(link_bs2_bs1.Get(0));
531  bs2nd.Add(link_bs3_bs2.Get(1));
532 
533  // Bottom Switch 3 NetDevices
534  NetDeviceContainer bs3nd;
535  bs3nd.Add(link_bs3_bs2.Get(0));
536  bs3nd.Add(link_bs4_bs3.Get(1));
537 
538  // Bottom Switch 4 NetDevices
539  NetDeviceContainer bs4nd;
540  bs4nd.Add(link_bs4_bs3.Get(0));
541  bs4nd.Add(link_bs5_bs4.Get(1));
542 
543  // Bottom Switch 5 NetDevices
544  NetDeviceContainer bs5nd;
545  bs5nd.Add(link_bs5_bs4.Get(0));
546  bs5nd.Add(link_b2_bs5.Get(1));
547 
548  // ======================================================================
549  // Install bridging code on each switch
550  // ----------------------------------------------------------------------
551  BridgeHelper bridge;
552 
553  bridge.Install(ts1, ts1nd);
554  bridge.Install(ts2, ts2nd);
555  bridge.Install(ts3, ts3nd);
556  bridge.Install(ts4, ts4nd);
557 
558  bridge.Install(bs1, bs1nd);
559  bridge.Install(bs2, bs2nd);
560  bridge.Install(bs3, bs3nd);
561  bridge.Install(bs4, bs4nd);
562  bridge.Install(bs5, bs5nd);
563 
564  // ======================================================================
565  // Install the L3 internet stack (TCP/IP)
566  // ----------------------------------------------------------------------
567  InternetStackHelper ns3IpStack;
568 
569  // ----------------------------------------------------------------------
570  // Install the L3 internet stack on UDP endpoints
571  // ----------------------------------------------------------------------
572  NS_LOG_INFO("L3: Install the ns3 IP stack on udp client and server nodes.");
573  NodeContainer endpointNodes(t2, t3, b2, b3);
574  ns3IpStack.Install(endpointNodes);
575 
576  // ----------------------------------------------------------------------
577  // Install the L3 internet stack on routers.
578  // ----------------------------------------------------------------------
579  NS_LOG_INFO("L3: Install the ns3 IP stack on routers.");
580  NodeContainer routerNodes(tr, br);
581  ns3IpStack.Install(routerNodes);
582 
583  // ======================================================================
584  // Assign top LAN IP addresses
585  // ----------------------------------------------------------------------
586  NS_LOG_INFO("L3: Assign top LAN IP Addresses.");
587 
588  NetDeviceContainer topLanIpDevices; // - - - - - -- - - - - - -
589  topLanIpDevices.Add(link_tr_ts1.Get(0)); // NOTE: order matters here
590  topLanIpDevices.Add(link_t2_ts4.Get(0)); // for IP address
591  topLanIpDevices.Add(link_t3_ts1.Get(0)); // assignment
592  // - - - - - -- - - - - - -
594  ipv4.SetBase("192.168.1.0", "255.255.255.0");
595  ipv4.Assign(topLanIpDevices);
596 
597  // ----------------------------------------------------------------------
598  // Assign bottom LAN IP addresses
599  // ----------------------------------------------------------------------
600  NS_LOG_INFO("L3: Assign bottom LAN IP Addresses.");
601 
602  NetDeviceContainer botLanIpDevices; // - - - - - -- - - - - - -
603  botLanIpDevices.Add(link_br_bs1.Get(0)); // NOTE: order matters here
604  botLanIpDevices.Add(link_b2_bs5.Get(0)); // for IP address
605  botLanIpDevices.Add(link_b3_bs1.Get(0)); // assignment
606  // - - - - - -- - - - - - -
607 
608  ipv4.SetBase("192.168.2.0", "255.255.255.0");
609  ipv4.Assign(botLanIpDevices);
610 
611  // ----------------------------------------------------------------------
612  // Assign WAN IP addresses
613  // ----------------------------------------------------------------------
614  NS_LOG_INFO("L3: Assign WAN IP Addresses.");
615 
616  ipv4.SetBase("76.1.1.0", "255.255.255.0");
617  ipv4.Assign(link_tr_br);
618 
619  // ======================================================================
620  // Calculate and populate routing tables
621  // ----------------------------------------------------------------------
622  NS_LOG_INFO("L3: Populate routing tables.");
624 
625  // ======================================================================
626  // Multi-Switch UDP traffic generation
627  // ----------------------------------------------------------------------
629 
630  if (enableUdpMultiSW)
631  {
632  // ------------------------------------------------------------------
633  // Install multi-switch UDP echo server on b2
634  // ------------------------------------------------------------------
635  NS_LOG_INFO("APP: Multi-Switch UDP server (on node b2 of bottom LAN)");
636 
637  UdpEchoServerHelper server(udpEchoPort);
638 
639  ApplicationContainer serverApp = server.Install(b2);
640  serverApp.Start(Seconds(0.5));
641  serverApp.Stop(Seconds(simDurationSeconds));
642 
643  // ------------------------------------------------------------------
644  // Install multi-switch UDP echo client on t2
645  // ------------------------------------------------------------------
646  NS_LOG_INFO("APP: Multi-Switch UDP client (on node t2 of top LAN)");
647 
648  Time interPacketInterval = Seconds(0.005);
649  uint32_t packetSize = 1000;
650  uint32_t maxPacketCount = (simDurationSeconds - 2.0) / 0.005;
651 
652  UdpEchoClientHelper client(Ipv4Address("192.168.2.2"), udpEchoPort);
653 
654  client.SetAttribute("MaxPackets", UintegerValue(maxPacketCount));
655  client.SetAttribute("Interval", TimeValue(interPacketInterval));
656  client.SetAttribute("PacketSize", UintegerValue(packetSize));
657 
658  ApplicationContainer clientApp = client.Install(t2);
659  clientApp.Start(Seconds(0.5));
660  clientApp.Stop(Seconds(simDurationSeconds));
661  }
662 
663  // ======================================================================
664  // Single-Switch UDP traffic generation
665  // ----------------------------------------------------------------------
666  if (enableUdpSingleSW)
667  {
668  // ------------------------------------------------------------------
669  // Install single-switch UDP echo server on t3
670  // ------------------------------------------------------------------
671  NS_LOG_INFO("APP: Single-Switch UDP server (on node t3 of top LAN)");
672 
673  UdpEchoServerHelper server(udpEchoPort);
674 
675  ApplicationContainer serverApp = server.Install(t3);
676  serverApp.Start(Seconds(0.5));
677  serverApp.Stop(Seconds(simDurationSeconds));
678 
679  // ------------------------------------------------------------------
680  // Install single-switch UDP echo client on b3
681  // ------------------------------------------------------------------
682  NS_LOG_INFO("APP: Single-Switch UDP client (on node b3 bottom LAN)");
683 
684  Time interPacketInterval = Seconds(0.005);
685  uint32_t packetSize = 1000;
686  uint32_t maxPacketCount = (simDurationSeconds - 2.0) / 0.005;
687 
688  UdpEchoClientHelper client(Ipv4Address("192.168.1.3"), udpEchoPort);
689 
690  client.SetAttribute("MaxPackets", UintegerValue(maxPacketCount));
691  client.SetAttribute("Interval", TimeValue(interPacketInterval));
692  client.SetAttribute("PacketSize", UintegerValue(packetSize));
693 
694  ApplicationContainer clientApp = client.Install(b3);
695  clientApp.Start(Seconds(0.5));
696  clientApp.Stop(Seconds(simDurationSeconds));
697  }
698 
699  // ======================================================================
700  // Print routing tables at T=0.1
701  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
702  // NOTE: Node 0 and Node 13 must have non-empty tables (except for local
703  // loopback and local LAN) if routing is operating correctly.
704  // ----------------------------------------------------------------------
705  NS_LOG_INFO("Set up to print routing tables at T=0.1s");
706 
707  Ptr<OutputStreamWrapper> routingStream =
708  Create<OutputStreamWrapper>("global-routing-multi-switch-plus-router.routes",
709  std::ios::out);
710 
712 
713  // ======================================================================
714  // Configure PCAP traces
715  // ----------------------------------------------------------------------
716  NS_LOG_INFO("Configure PCAP Tracing (if any configured).");
717 
718  // - - - - - - - - - - - - - -
719  // multi-switch UDP echo client
720  // - - - - - - - - - - - - - -
721  if (vssearch("t2", pcapLocationVec))
722  {
723  csmaX.EnablePcap("t2.pcap", topLanIpDevices.Get(1), true, true);
724  }
725 
726  // - - - - - - - - - - - - - -
727  // multi-switch UDP echo server
728  // - - - - - - - - - - - - - -
729  if (vssearch("b2", pcapLocationVec))
730  {
731  csmaY.EnablePcap("b2.pcap", botLanIpDevices.Get(1), true, true);
732  }
733 
734  // - - - - - - - - - - - - - -
735  // single-switch UDP echo client
736  // - - - - - - - - - - - - - -
737  if (vssearch("b3", pcapLocationVec))
738  {
739  csmaY.EnablePcap("b3.pcap", botLanIpDevices.Get(2), true, true);
740  }
741 
742  // - - - - - - - - - - - - - -
743  // single-switch UDP echo server
744  // - - - - - - - - - - - - - -
745  if (vssearch("t3", pcapLocationVec))
746  {
747  csmaX.EnablePcap("t3.pcap", topLanIpDevices.Get(2), true, true);
748  }
749 
750  // - - - - - - - - - - - - - -
751  // top router, LAN side
752  // - - - - - - - - - - - - - -
753  if (vssearch("trlan", pcapLocationVec))
754  {
755  csmaY.EnablePcap("trlan.pcap", topLanIpDevices.Get(0), true, true);
756  }
757 
758  // - - - - - - - - - - - - - -
759  // bottom router, LAN side
760  // - - - - - - - - - - - - - -
761  if (vssearch("brlan", pcapLocationVec))
762  {
763  csmaX.EnablePcap("brlan.pcap", botLanIpDevices.Get(0), true, true);
764  }
765 
766  // - - - - - - - - - - - - - -
767  // top router, WAN side
768  // - - - - - - - - - - - - - -
769  if (vssearch("trwan", pcapLocationVec))
770  {
771  p2p.EnablePcap("trwan.pcap", link_tr_br.Get(0), true, true);
772  }
773 
774  // - - - - - - - - - - - - - -
775  // bottom router, WAN side
776  // - - - - - - - - - - - - - -
777  if (vssearch("brwan", pcapLocationVec))
778  {
779  p2p.EnablePcap("brwan.pcap", link_tr_br.Get(1), true, true);
780  }
781 
782  // ======================================================================
783  // Now, do the actual simulation.
784  // ----------------------------------------------------------------------
785  NS_LOG_INFO("Run Simulation for " << simDurationSeconds << " seconds.");
786 
787  Simulator::Stop(Seconds(simDurationSeconds));
788  Simulator::Run();
789 
791  NS_LOG_INFO("Done.");
792 
793  return 0;
794 }
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.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
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:775
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.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static void Run()
Run the simulation.
Definition: simulator.cc:178
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:186
Hold variables of type string.
Definition: string.h:56
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
Create an application which sends a UDP packet and waits for an echo of this packet.
Create a server application which waits for input UDP packets and sends them back to the original sen...
Hold an unsigned integer type.
Definition: uinteger.h:45
#define vssearch(loc, vec)
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:890
#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:1326
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:302
@ LOG_LEVEL_INFO
LOG_INFO and above.
Definition: log.h:104
cmd
Definition: second.py:40
bool verbose
static const uint32_t packetSize
Packet size generated at the AP.