A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
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
244using namespace ns3;
245
246// ########################################################################
247// Main routine
248// ########################################################################
249NS_LOG_COMPONENT_DEFINE("GlobalRoutingMultiSwitchPlusRouter");
250
251#define vssearch(loc, vec) std::find((vec).begin(), (vec).end(), (loc)) != (vec).end()
252
253int
254main(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 = "";
268
269 std::string csmaXLinkDataRate = "100Mbps";
270 std::string csmaXLinkDelay = "500ns";
271
272 std::string csmaYLinkDataRate = "10Mbps";
273 std::string csmaYLinkDelay = "500ns";
274
275 std::string p2pLinkDataRate = "5Mbps";
276 std::string p2pLinkDelay = "50ms";
277
278 uint16_t udpEchoPort = 9; // The well-known UDP echo port
279
280 // ----------------------------------------------------------------------
281 // Create command line options and get them
282 // ----------------------------------------------------------------------
283 CommandLine cmd(__FILE__);
284
285 cmd.Usage("NOTE: valid --pcap arguments are: 't2,t3,b2,b3,trlan,trwan,brlan,brwan'");
286
287 cmd.AddValue("verbose", "Enable printing informational messages", verbose);
288
289 cmd.AddValue("duration", "Duration of simulation.", simDurationSeconds);
290
291 cmd.AddValue("udpMultiSW", "Enable udp over multi-switch links", enableUdpMultiSW);
292 cmd.AddValue("udpSingleSW", "Enable udp over single-switch links", enableUdpSingleSW);
293
294 cmd.AddValue("pcap", "Comma separated list of PCAP Locations to tap", pcapLocations);
295 cmd.AddValue("snapLen", "PCAP packet capture length", snapLen);
296
297 cmd.AddValue("csmaXRate", "CSMA X Link data rate", csmaXLinkDataRate);
298 cmd.AddValue("csmaXDelay", "CSMA X Link delay", csmaXLinkDelay);
299
300 cmd.AddValue("csmaYRate", "CSMA Y Link data rate", csmaYLinkDataRate);
301 cmd.AddValue("csmaYDelay", "CSMA Y Link delay", csmaYLinkDelay);
302
303 cmd.AddValue("p2pRate", "P2P Link data rate", p2pLinkDataRate);
304 cmd.AddValue("p2pDelay", "P2P Link delay", p2pLinkDelay);
305
306 cmd.Parse(argc, argv);
307
308 // --------------------------------------------------------------------
309 // Users may find it convenient to turn on explicit debugging
310 // for selected modules; the below lines suggest how to do this
311 // --------------------------------------------------------------------
312 if (verbose)
313 {
314 LogComponentEnable("GlobalRoutingMultiSwitchPlusRouter", LOG_LEVEL_INFO);
315 }
316
317 // ======================================================================
318 // Define the list of valid PCAP taps
319 // ----------------------------------------------------------------------
320 const std::vector<std::string> pcapTaps{
321 "t2", // multi-switch UDP echo client
322 "t3", // single-switch UDP echo server
323 "b2", // multi-switch UDP echo server
324 "b3", // single-switch UDP echo client
325 "trlan", // top router LAN side
326 "trwan", // top router WAN side
327 "brlan", // bottom router LAN side
328 "brwan", // bottom router WAN side
329 };
330
331 // ----------------------------------------------------------------------
332 // Parse the pcapLocations string into pcapLocationVec
333 // ----------------------------------------------------------------------
334 std::vector<std::string> pcapLocationVec;
335 if (!pcapLocations.empty())
336 {
337 std::stringstream sStream(pcapLocations);
338
339 while (sStream.good())
340 {
341 std::string substr;
342 getline(sStream, substr, ',');
343 if (vssearch(substr, pcapTaps))
344 {
345 pcapLocationVec.push_back(substr);
346 }
347 else
348 {
349 NS_LOG_ERROR("WARNING: Unrecognized PCAP location: <" + substr + ">");
350 }
351 }
352
353 for (std::vector<std::string>::const_iterator ploc = pcapLocationVec.begin();
354 ploc != pcapLocationVec.end();
355 ++ploc)
356 {
357 NS_LOG_INFO("PCAP capture at: <" + *ploc + ">");
358 }
359 }
360
361 // ======================================================================
362 // Set some simulator-wide values
363 // ======================================================================
364
365 // ----------------------------------------------------------------------
366 // Set PCAP packet capture maximum packet length
367 // ----------------------------------------------------------------------
368 if (snapLen != PcapFile::SNAPLEN_DEFAULT)
369 {
370 Config::SetDefault("ns3::PcapFileWrapper::CaptureSize", UintegerValue(snapLen));
371 }
372
373 // ======================================================================
374 // Create the nodes & links required for the topology shown in comments above.
375 // ----------------------------------------------------------------------
376 NS_LOG_INFO("INFO: Create nodes."); // - - - - - - - - - - - - - - - -
377 // Node IP : Description
378 // - - - - - - - - - - - - - - - -
379 Ptr<Node> t2 = CreateObject<Node>(); // 192.168.1.2 : Top multi-switch udp echo client
380 Ptr<Node> t3 = CreateObject<Node>(); // 192.168.1.3 : Top single-switch udp echo server
381 // :
382 Ptr<Node> ts1 = CreateObject<Node>(); // <no IP> : Top switch #1 (bridge)
383 Ptr<Node> ts2 = CreateObject<Node>(); // <no IP> : Top switch #2 (bridge)
384 Ptr<Node> ts3 = CreateObject<Node>(); // <no IP> : Top switch #3 (bridge)
385 Ptr<Node> ts4 = CreateObject<Node>(); // <no IP> : Top switch #4 (bridge)
386 // :
387 Ptr<Node> tr = CreateObject<Node>(); // 192.168.1.1 : Router connecting top LAN & WAN
388 // 76.1.1.1 :
389 // :
390 Ptr<Node> br = CreateObject<Node>(); // 76.1.1.2 : Router connecting WAN & bottom LANs
391 // 192.168.2.1 :
392 // :
393 Ptr<Node> bs1 = CreateObject<Node>(); // <no IP> : Bottom switch #1 (bridge)
394 Ptr<Node> bs2 = CreateObject<Node>(); // <no IP> : Bottom switch #2 (bridge)
395 Ptr<Node> bs3 = CreateObject<Node>(); // <no IP> : Bottom switch #3 (bridge)
396 Ptr<Node> bs4 = CreateObject<Node>(); // <no IP> : Bottom switch #4 (bridge)
397 Ptr<Node> bs5 = CreateObject<Node>(); // <no IP> : Bottom switch #5 (bridge)
398 // :
399 Ptr<Node> b2 = CreateObject<Node>(); // 192.168.2.2 : Bottom multi-switch udp echo server
400
401 Ptr<Node> b3 = CreateObject<Node>(); // 192.168.2.3 : Bottom single-switch udp echo client
402 // - - - - - - - - - - - - - - - -
403
404 // ----------------------------------------------------------------------
405 // Give the nodes names
406 // ----------------------------------------------------------------------
407 Names::Add("t2", t2);
408 Names::Add("t3", t3);
409 Names::Add("ts1", ts1);
410 Names::Add("ts2", ts2);
411 Names::Add("ts3", ts3);
412 Names::Add("ts4", ts4);
413 Names::Add("tr", tr);
414 Names::Add("br", br);
415 Names::Add("bs1", bs1);
416 Names::Add("bs2", bs2);
417 Names::Add("bs3", bs3);
418 Names::Add("bs4", bs4);
419 Names::Add("bs5", bs5);
420 Names::Add("b2", b2);
421 Names::Add("b3", b3);
422
423 // ======================================================================
424 // Create CSMA links to use for connecting LAN nodes together
425 // ----------------------------------------------------------------------
426
427 // ----------------------------------------
428 // CSMA [X]
429 // ----------------------------------------
430 NS_LOG_INFO("L2: Create a " << csmaXLinkDataRate << " " << csmaXLinkDelay
431 << " CSMA link for csmaX for LANs.");
432 CsmaHelper csmaX;
433 csmaX.SetChannelAttribute("DataRate", StringValue(csmaXLinkDataRate));
434 csmaX.SetChannelAttribute("Delay", StringValue(csmaXLinkDelay));
435
436 // ----------------------------------------
437 // CSMA [Y]
438 // ----------------------------------------
439 NS_LOG_INFO("L2: Create a " << csmaYLinkDataRate << " " << csmaYLinkDelay
440 << " CSMA link for csmaY for LANs.");
441 CsmaHelper csmaY;
442 csmaY.SetChannelAttribute("DataRate", StringValue(csmaYLinkDataRate));
443 csmaY.SetChannelAttribute("Delay", StringValue(csmaYLinkDelay));
444
445 // ----------------------------------------------------------------------
446 // Now, connect the top LAN nodes together with csma links.
447 // ----------------------------------------------------------------------
448 NS_LOG_INFO("L2: Connect nodes on top LAN together with half-duplex CSMA links.");
449
450 // Multi-switch top LAN chain: t2-ts4-ts3-ts2-ts1-tr
451 NetDeviceContainer link_t2_ts4 = csmaX.Install(NodeContainer(t2, ts4));
452 NetDeviceContainer link_ts4_ts3 = csmaY.Install(NodeContainer(ts4, ts3));
453 NetDeviceContainer link_ts3_ts2 = csmaX.Install(NodeContainer(ts3, ts2));
454 NetDeviceContainer link_ts2_ts1 = csmaY.Install(NodeContainer(ts2, ts1));
455
456 // Single-switch top LAN link: t3-ts1-tr
457 NetDeviceContainer link_t3_ts1 = csmaX.Install(NodeContainer(t3, ts1));
458
459 // Common link for top LAN between ts1 and tr (for t2 and t3 to get to tr)
460 NetDeviceContainer link_tr_ts1 = csmaY.Install(NodeContainer(tr, ts1));
461
462 // ----------------------------------------------------------------------
463 // And repeat above steps to connect the bottom LAN nodes together
464 // ----------------------------------------------------------------------
465 NS_LOG_INFO("L2: Connect nodes on bottom LAN together with half-duplex CSMA links.");
466
467 // Multi-switch bottom LAN chain: b2-bs5-bs4-bs3-bs2-bs1-br
468 NetDeviceContainer link_b2_bs5 = csmaY.Install(NodeContainer(b2, bs5));
469 NetDeviceContainer link_bs5_bs4 = csmaX.Install(NodeContainer(bs5, bs4));
470 NetDeviceContainer link_bs4_bs3 = csmaY.Install(NodeContainer(bs4, bs3));
471 NetDeviceContainer link_bs3_bs2 = csmaX.Install(NodeContainer(bs3, bs2));
472 NetDeviceContainer link_bs2_bs1 = csmaY.Install(NodeContainer(bs2, bs1));
473
474 // Single-switch bottom LAN link: b3-bs1-br
475 NetDeviceContainer link_b3_bs1 = csmaY.Install(NodeContainer(b3, bs1));
476
477 // Common link for bottom LAN between bs1 and br (for b2 and b3 to get to br)
478 NetDeviceContainer link_br_bs1 = csmaX.Install(NodeContainer(br, bs1));
479
480 // ======================================================================
481 // Create a point-to-point link for connecting WAN nodes together
482 // (this type of link is full-duplex)
483 // ----------------------------------------------------------------------
484 NS_LOG_INFO("L2: Create a " << p2pLinkDataRate << " " << p2pLinkDelay
485 << " Point-to-Point link for the WAN.");
486
488 p2p.SetDeviceAttribute("DataRate", StringValue(p2pLinkDataRate));
489 p2p.SetChannelAttribute("Delay", StringValue(p2pLinkDelay));
490
491 // ----------------------------------------------------------------------
492 // Now, connect top router to bottom router with a p2p WAN link
493 // ----------------------------------------------------------------------
494 NS_LOG_INFO("L2: Connect the routers together with the Point-to-Point WAN link.");
495
496 NetDeviceContainer link_tr_br;
497 link_tr_br = p2p.Install(NodeContainer(tr, br));
498
499 // ======================================================================
500 // Manually create the list of NetDevices for each switch
501 // ----------------------------------------------------------------------
502
503 // Top Switch 4 NetDevices
504 NetDeviceContainer ts4nd;
505 ts4nd.Add(link_t2_ts4.Get(1));
506 ts4nd.Add(link_ts4_ts3.Get(0));
507
508 // Top Switch 3 NetDevices
509 NetDeviceContainer ts3nd;
510 ts3nd.Add(link_ts4_ts3.Get(1));
511 ts3nd.Add(link_ts3_ts2.Get(0));
512
513 // Top Switch 2 NetDevices
514 NetDeviceContainer ts2nd;
515 ts2nd.Add(link_ts3_ts2.Get(1));
516 ts2nd.Add(link_ts2_ts1.Get(0));
517
518 // Top Switch 1 NetDevices
519 NetDeviceContainer ts1nd;
520 ts1nd.Add(link_ts2_ts1.Get(1));
521 ts1nd.Add(link_t3_ts1.Get(1));
522 ts1nd.Add(link_tr_ts1.Get(1));
523
524 // Bottom Switch 1 NetDevices
525 NetDeviceContainer bs1nd;
526 bs1nd.Add(link_br_bs1.Get(1));
527 bs1nd.Add(link_bs2_bs1.Get(1));
528 bs1nd.Add(link_b3_bs1.Get(1));
529
530 // Bottom Switch 2 NetDevices
531 NetDeviceContainer bs2nd;
532 bs2nd.Add(link_bs2_bs1.Get(0));
533 bs2nd.Add(link_bs3_bs2.Get(1));
534
535 // Bottom Switch 3 NetDevices
536 NetDeviceContainer bs3nd;
537 bs3nd.Add(link_bs3_bs2.Get(0));
538 bs3nd.Add(link_bs4_bs3.Get(1));
539
540 // Bottom Switch 4 NetDevices
541 NetDeviceContainer bs4nd;
542 bs4nd.Add(link_bs4_bs3.Get(0));
543 bs4nd.Add(link_bs5_bs4.Get(1));
544
545 // Bottom Switch 5 NetDevices
546 NetDeviceContainer bs5nd;
547 bs5nd.Add(link_bs5_bs4.Get(0));
548 bs5nd.Add(link_b2_bs5.Get(1));
549
550 // ======================================================================
551 // Install bridging code on each switch
552 // ----------------------------------------------------------------------
553 BridgeHelper bridge;
554
555 bridge.Install(ts1, ts1nd);
556 bridge.Install(ts2, ts2nd);
557 bridge.Install(ts3, ts3nd);
558 bridge.Install(ts4, ts4nd);
559
560 bridge.Install(bs1, bs1nd);
561 bridge.Install(bs2, bs2nd);
562 bridge.Install(bs3, bs3nd);
563 bridge.Install(bs4, bs4nd);
564 bridge.Install(bs5, bs5nd);
565
566 // ======================================================================
567 // Install the L3 internet stack (TCP/IP)
568 // ----------------------------------------------------------------------
569 InternetStackHelper ns3IpStack;
570
571 // ----------------------------------------------------------------------
572 // Install the L3 internet stack on UDP endpoints
573 // ----------------------------------------------------------------------
574 NS_LOG_INFO("L3: Install the ns3 IP stack on udp client and server nodes.");
575 NodeContainer endpointNodes(t2, t3, b2, b3);
576 ns3IpStack.Install(endpointNodes);
577
578 // ----------------------------------------------------------------------
579 // Install the L3 internet stack on routers.
580 // ----------------------------------------------------------------------
581 NS_LOG_INFO("L3: Install the ns3 IP stack on routers.");
582 NodeContainer routerNodes(tr, br);
583 ns3IpStack.Install(routerNodes);
584
585 // ======================================================================
586 // Assign top LAN IP addresses
587 // ----------------------------------------------------------------------
588 NS_LOG_INFO("L3: Assign top LAN IP Addresses.");
589
590 NetDeviceContainer topLanIpDevices; // - - - - - -- - - - - - -
591 topLanIpDevices.Add(link_tr_ts1.Get(0)); // NOTE: order matters here
592 topLanIpDevices.Add(link_t2_ts4.Get(0)); // for IP address
593 topLanIpDevices.Add(link_t3_ts1.Get(0)); // assignment
594 // - - - - - -- - - - - - -
596 ipv4.SetBase("192.168.1.0", "255.255.255.0");
597 ipv4.Assign(topLanIpDevices);
598
599 // ----------------------------------------------------------------------
600 // Assign bottom LAN IP addresses
601 // ----------------------------------------------------------------------
602 NS_LOG_INFO("L3: Assign bottom LAN IP Addresses.");
603
604 NetDeviceContainer botLanIpDevices; // - - - - - -- - - - - - -
605 botLanIpDevices.Add(link_br_bs1.Get(0)); // NOTE: order matters here
606 botLanIpDevices.Add(link_b2_bs5.Get(0)); // for IP address
607 botLanIpDevices.Add(link_b3_bs1.Get(0)); // assignment
608 // - - - - - -- - - - - - -
609
610 ipv4.SetBase("192.168.2.0", "255.255.255.0");
611 ipv4.Assign(botLanIpDevices);
612
613 // ----------------------------------------------------------------------
614 // Assign WAN IP addresses
615 // ----------------------------------------------------------------------
616 NS_LOG_INFO("L3: Assign WAN IP Addresses.");
617
618 ipv4.SetBase("76.1.1.0", "255.255.255.0");
619 ipv4.Assign(link_tr_br);
620
621 // ======================================================================
622 // Calculate and populate routing tables
623 // ----------------------------------------------------------------------
624 NS_LOG_INFO("L3: Populate routing tables.");
626
627 // ======================================================================
628 // Multi-Switch UDP traffic generation
629 // ----------------------------------------------------------------------
631
632 if (enableUdpMultiSW)
633 {
634 // ------------------------------------------------------------------
635 // Install multi-switch UDP echo server on b2
636 // ------------------------------------------------------------------
637 NS_LOG_INFO("APP: Multi-Switch UDP server (on node b2 of bottom LAN)");
638
639 UdpEchoServerHelper server(udpEchoPort);
640
641 ApplicationContainer serverApp = server.Install(b2);
642 serverApp.Start(Seconds(0.5));
643 serverApp.Stop(Seconds(simDurationSeconds));
644
645 // ------------------------------------------------------------------
646 // Install multi-switch UDP echo client on t2
647 // ------------------------------------------------------------------
648 NS_LOG_INFO("APP: Multi-Switch UDP client (on node t2 of top LAN)");
649
650 Time interPacketInterval = Seconds(0.005);
651 uint32_t packetSize = 1000;
652 uint32_t maxPacketCount = (simDurationSeconds - 2.0) / 0.005;
653
654 UdpEchoClientHelper client(Ipv4Address("192.168.2.2"), udpEchoPort);
655
656 client.SetAttribute("MaxPackets", UintegerValue(maxPacketCount));
657 client.SetAttribute("Interval", TimeValue(interPacketInterval));
658 client.SetAttribute("PacketSize", UintegerValue(packetSize));
659
660 ApplicationContainer clientApp = client.Install(t2);
661 clientApp.Start(Seconds(0.5));
662 clientApp.Stop(Seconds(simDurationSeconds));
663 }
664
665 // ======================================================================
666 // Single-Switch UDP traffic generation
667 // ----------------------------------------------------------------------
668 if (enableUdpSingleSW)
669 {
670 // ------------------------------------------------------------------
671 // Install single-switch UDP echo server on t3
672 // ------------------------------------------------------------------
673 NS_LOG_INFO("APP: Single-Switch UDP server (on node t3 of top LAN)");
674
675 UdpEchoServerHelper server(udpEchoPort);
676
677 ApplicationContainer serverApp = server.Install(t3);
678 serverApp.Start(Seconds(0.5));
679 serverApp.Stop(Seconds(simDurationSeconds));
680
681 // ------------------------------------------------------------------
682 // Install single-switch UDP echo client on b3
683 // ------------------------------------------------------------------
684 NS_LOG_INFO("APP: Single-Switch UDP client (on node b3 bottom LAN)");
685
686 Time interPacketInterval = Seconds(0.005);
687 uint32_t packetSize = 1000;
688 uint32_t maxPacketCount = (simDurationSeconds - 2.0) / 0.005;
689
690 UdpEchoClientHelper client(Ipv4Address("192.168.1.3"), udpEchoPort);
691
692 client.SetAttribute("MaxPackets", UintegerValue(maxPacketCount));
693 client.SetAttribute("Interval", TimeValue(interPacketInterval));
694 client.SetAttribute("PacketSize", UintegerValue(packetSize));
695
696 ApplicationContainer clientApp = client.Install(b3);
697 clientApp.Start(Seconds(0.5));
698 clientApp.Stop(Seconds(simDurationSeconds));
699 }
700
701 // ======================================================================
702 // Print routing tables at T=0.1
703 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
704 // NOTE: Node 0 and Node 13 must have non-empty tables (except for local
705 // loopback and local LAN) if routing is operating correctly.
706 // ----------------------------------------------------------------------
707 NS_LOG_INFO("Set up to print routing tables at T=0.1s");
708
709 Ptr<OutputStreamWrapper> routingStream =
710 Create<OutputStreamWrapper>("global-routing-multi-switch-plus-router.routes",
711 std::ios::out);
712
714
715 // ======================================================================
716 // Configure PCAP traces
717 // ----------------------------------------------------------------------
718 NS_LOG_INFO("Configure PCAP Tracing (if any configured).");
719
720 // - - - - - - - - - - - - - -
721 // multi-switch UDP echo client
722 // - - - - - - - - - - - - - -
723 if (vssearch("t2", pcapLocationVec))
724 {
725 csmaX.EnablePcap("t2.pcap", topLanIpDevices.Get(1), true, true);
726 }
727
728 // - - - - - - - - - - - - - -
729 // multi-switch UDP echo server
730 // - - - - - - - - - - - - - -
731 if (vssearch("b2", pcapLocationVec))
732 {
733 csmaY.EnablePcap("b2.pcap", botLanIpDevices.Get(1), true, true);
734 }
735
736 // - - - - - - - - - - - - - -
737 // single-switch UDP echo client
738 // - - - - - - - - - - - - - -
739 if (vssearch("b3", pcapLocationVec))
740 {
741 csmaY.EnablePcap("b3.pcap", botLanIpDevices.Get(2), true, true);
742 }
743
744 // - - - - - - - - - - - - - -
745 // single-switch UDP echo server
746 // - - - - - - - - - - - - - -
747 if (vssearch("t3", pcapLocationVec))
748 {
749 csmaX.EnablePcap("t3.pcap", topLanIpDevices.Get(2), true, true);
750 }
751
752 // - - - - - - - - - - - - - -
753 // top router, LAN side
754 // - - - - - - - - - - - - - -
755 if (vssearch("trlan", pcapLocationVec))
756 {
757 csmaY.EnablePcap("trlan.pcap", topLanIpDevices.Get(0), true, true);
758 }
759
760 // - - - - - - - - - - - - - -
761 // bottom router, LAN side
762 // - - - - - - - - - - - - - -
763 if (vssearch("brlan", pcapLocationVec))
764 {
765 csmaX.EnablePcap("brlan.pcap", botLanIpDevices.Get(0), true, true);
766 }
767
768 // - - - - - - - - - - - - - -
769 // top router, WAN side
770 // - - - - - - - - - - - - - -
771 if (vssearch("trwan", pcapLocationVec))
772 {
773 p2p.EnablePcap("trwan.pcap", link_tr_br.Get(0), true, true);
774 }
775
776 // - - - - - - - - - - - - - -
777 // bottom router, WAN side
778 // - - - - - - - - - - - - - -
779 if (vssearch("brwan", pcapLocationVec))
780 {
781 p2p.EnablePcap("brwan.pcap", link_tr_br.Get(1), true, true);
782 }
783
784 // ======================================================================
785 // Now, do the actual simulation.
786 // ----------------------------------------------------------------------
787 NS_LOG_INFO("Run Simulation for " << simDurationSeconds << " seconds.");
788
789 Simulator::Stop(Seconds(simDurationSeconds));
791
793 NS_LOG_INFO("Done.");
794
795 return 0;
796}
holds a vector of ns3::Application pointers.
void Start(Time start) const
Start all of the Applications in this container at the start time given as a parameter.
void Stop(Time stop) const
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
Add capability to bridge multiple LAN segments (IEEE 802.1D bridging)
Definition: bridge-helper.h:45
NetDeviceContainer Install(Ptr< Node > node, NetDeviceContainer c)
This method creates an ns3::BridgeNetDevice with the attributes configured by BridgeHelper::SetDevice...
Parse command-line arguments.
Definition: command-line.h:232
build a set of CsmaNetDevice objects
Definition: csma-helper.h:48
void SetChannelAttribute(std::string n1, const AttributeValue &v1)
Definition: csma-helper.cc:56
NetDeviceContainer Install(Ptr< Node > node) const
This method creates an ns3::CsmaChannel with the attributes configured by CsmaHelper::SetChannelAttri...
Definition: csma-helper.cc:226
aggregate IP/TCP/UDP functionality to existing Nodes.
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
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:776
holds a vector of ns3::NetDevice pointers
void Add(NetDeviceContainer other)
Append the contents of another NetDeviceContainer to the end of this container.
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr<NetDevice> stored in this container at a given index.
keep track of a set of node pointers.
static const uint32_t SNAPLEN_DEFAULT
Default value for maximum octets to save per packet.
Definition: pcap-file.h:46
void EnablePcap(std::string prefix, Ptr< NetDevice > nd, bool promiscuous=false, bool explicitFilename=false)
Enable pcap output the indicated net device.
Build a set of PointToPointNetDevice objects.
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:78
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:140
static void Run()
Run the simulation.
Definition: simulator.cc:176
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:184
Hold variables of type string.
Definition: string.h:56
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:105
AttributeValue implementation for Time.
Definition: nstime.h:1423
Create an application which sends a UDP packet and waits for an echo of this packet.
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:891
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:254
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1336
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void LogComponentEnable(const std::string &name, LogLevel level)
Enable the logging output associated with that log component.
Definition: log.cc:302
@ LOG_LEVEL_INFO
LOG_INFO and above.
Definition: log.h:104
bool verbose
static const uint32_t packetSize
Packet size generated at the AP.