--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/routing/global-routing-multi-switch-plus-router.cc Thu Mar 10 16:07:51 2016 -0800
@@ -0,0 +1,810 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2015 - Chip Webb
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Chip Webb <ns3 (at) chipwebb.com>
+ *
+ */
+
+// ###################################################################### //
+// Network topology //
+// ---------------------------------------------------------------------- //
+// //
+// This example shows two L2 LANs connected by a WAN link and illustrates //
+// a network that has multiple L2 switches between L3 routers. //
+// //
+// It serves as a test case to verify a patch to global-router-interface //
+// that fixes a previous bug (#2102 in the ns-3 tracker) but is also //
+// another example program. //
+// //
+// The LANs are "top" [192.168.1/24] and "bottom" [192.168.2/24]. //
+// Each LAN network is interconnected by several L2 switches, and each //
+// LAN has its own router to act as a gateway with the WAN. Each LAN //
+// has two endpoints upon which is installed a UDP echo client or server //
+// that are used to test connectivity over the LANs & WAN. //
+// //
+// One pair of UDP endpoints (t3 and b3) have LAN connections with only //
+// one switch between them and their local routers. This path works with //
+// unpatched ns3 code (3.24 & earlier) as well as with the patch applied. //
+// //
+// Another pair of endpoints (t2 and b2) have LAN connections with //
+// a chain of multiple switches between them and their local router. //
+// This path will only work after applying the associated patch. //
+// //
+// The LAN links are modeled by half-duplex Ethernet CSMA links which //
+// have command-line-configurable data rate and latency. //
+// //
+// There are two types of CSMA links: 100Mbit and 10Mbit. The 100Mbit //
+// links are called csmaX, are denoted by [X] in the diagram and can //
+// be controlled with the --csmaXRate and --csmaXDelay command line args. //
+// The 10Mbit links are called csmaY, are denoted by [Y] in the diagram //
+// and can be controlled with the --csmaYRate and --csmaYDelay command //
+// line arguments. Both the top and bottom LAN have a mixture of //
+// 100Mbit/s and 10Mbit/s links. //
+// //
+// The WAN is modeled by a point-to-point link which has configurable //
+// data rate and latency. Unlike many typical home/work networks, //
+// the routers do not perform NAT. //
+// //
+// The WAN link is denoted by [P] in the diagram, and the //
+// speed and latency can be set from the command line with the //
+// --p2pRate and --p2pDelay options. The default for this link is 5Mbit/s //
+// and 50ms delay //
+// //
+// Note: Names in parenthesis after NetDevices are pcap tap locations. //
+// //
+// ---------------------------------------------------------------------- //
+// //
+// 192.168. 192.168. //
+// .1.2 .1.3 //
+// --------- --------- //
+// | t2 | | t3 | //
+// | UDP | | UDP | //
+// | echo | | echo | Node t2 is a UDP echo client (multi-switch) //
+// | client| | server| Node t3 is a UDP echo server (single-switch) //
+// --------- --------- //
+// CSMA(t2) CSMA(t3) //
+// [X] [X] //
+// [X] [X] //
+// CSMA [X] //
+// --------- [X] //
+// | ts4 | [X] Nodes ts1, ts2, ts3 and ts4 are L2 switches //
+// | (sw) | [X] The top LAN is subnet 192.168.1.* //
+// --------- [X] //
+// CSMA [X] The long chain of switches is designed //
+// [Y] [X] to test whether global-router-interface //
+// [Y] [X] can fully enumerate an IP subnet that has //
+// CSMA [X] multiple interconnected L2 switches. //
+// --------- [X] The problem is documented in Bug #2102. //
+// | ts3 | [X] //
+// | (sw) | [X] //
+// --------- [X] //
+// CSMA [X] //
+// [X] [X] //
+// [X] [X] //
+// CSMA [X] //
+// --------- [X] //
+// | ts2 | [X] //
+// | (sw) | [X] //
+// --------- [X] //
+// CSMA [X] //
+// [Y] [X] //
+// [Y] [X] //
+// CSMA CSMA //
+// ------------------ //
+// | ts1 (switch) | //
+// ------------------ //
+// CSMA //
+// [Y] //
+// [Y] //
+// CSMA(trlan) 192.168.1.1 //
+// ------------------ //
+// | tr (router) | Node tr is an L3 router //
+// ------------------ (between 192.168.1.* & 76.1.1.*) //
+// P2P(trwan) 76.1.1.1 //
+// [P] //
+// [P] //
+// [P] //
+// [P] //
+// [P] The WAN is 76.1.1.* //
+// [P] //
+// [P] //
+// [P] //
+// P2P(brwan) 76.1.1.2 //
+// ------------------ //
+// | br (router) | Node br is an L3 router //
+// ------------------ (between 192.168.2.* & 76.1.1.*) //
+// CSMA(brlan) 192.168.2.1 //
+// [X] //
+// [X] //
+// CSMA //
+// ------------------ Nodes bs1 to bs5 are L2 switches //
+// | bs1 (switch) | The bottom LAN is subnet 192.168.2.* //
+// ------------------ //
+// CSMA CSMA //
+// [Y] [Y] //
+// [Y] [Y] //
+// CSMA [Y] //
+// --------- [Y] //
+// | bs2 | [Y] //
+// | (sw) | [Y] //
+// --------- [Y] //
+// CSMA [Y] //
+// [X] [Y] //
+// [X] [Y] //
+// CSMA [Y] //
+// --------- [Y] //
+// | bs3 | [Y] //
+// | (sw) | [Y] //
+// --------- [Y] //
+// CSMA [Y] //
+// [Y] [Y] //
+// [Y] [Y] //
+// CSMA [Y] //
+// --------- [Y] //
+// | bs4 | [Y] //
+// | (sw) | [Y] //
+// --------- [Y] //
+// CSMA [Y] //
+// [X] [Y] //
+// [X] [Y] //
+// CSMA [Y] //
+// --------- [Y] //
+// | bs5 | [Y] //
+// | (sw) | [Y] //
+// --------- [Y] //
+// CSMA [Y] //
+// [Y] [Y] //
+// [Y] [Y] //
+// CSMA(b2) CSMA(b3) //
+// --------- --------- //
+// | b2 | | b3 | //
+// | UDP | | UDP | //
+// | echo | | echo | Node b2 is a UDP echo server (multi-switch) //
+// | server| | client| Node b3 is a UDP echo client (single-switch) //
+// --------- --------- //
+// 192.168. 192.168. //
+// .2.2 .2.3 //
+// //
+// ---------------------------------------------------------------------- //
+// Explanation //
+// ---------------------------------------------------------------------- //
+// //
+// UDP packet flows are configured between nodes on the top and bottom //
+// LANs (using UDP echo client & server). //
+// //
+// The network carrying the "multi switch" UDP flow is connected with //
+// multiple L2 switches between L3 nodes so it should only work if the //
+// global-router-interface source code properly supports bridging. //
+// //
+// The network carrying the "single switch" UDP flow is connected with //
+// only one L2 switch between L3 nodes so it should work with or //
+// without the patch //
+// //
+// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = //
+// Traffic summary: //
+// ---------------------------------------------------------------------- //
+// //
+// - UDP flow from t2 (192.168.1.2) to b2 (192.168.2.2) [Multi Switch] //
+// from b3 (192.168.2.3) to t3 (192.168.1.3) [Single Switch] //
+// //
+// = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = //
+// Node List & IP addresses assigned during simulation //
+// ---------------------------------------------------------------------- //
+// t2 : 192.168.1.2 : Top multi-switch UDP echo client //
+// t3 : 192.168.1.3 : Top single-switch UDP echo server //
+// : //
+// ts1 : <no IP> : Top switch 1 (bridge) //
+// ts2 : <no IP> : Top switch 2 (bridge) //
+// ts3 : <no IP> : Top switch 3 (bridge) //
+// ts4 : <no IP> : Top switch 4 (bridge) //
+// : //
+// tr : 192.168.1.1 : Router connecting top LAN (192.168.1.*) //
+// : 76.1.1.1 : to the WAN //
+// : //
+// br : 76.1.1.2 : Router connecting the WAN //
+// : 192.168.2.1 : to bot LAN (192.168.2.*) //
+// : //
+// bs1 : <no IP> : Bottom switch 1 (bridge) //
+// bs2 : <no IP> : Bottom switch 2 (bridge) //
+// bs3 : <no IP> : Bottom switch 3 (bridge) //
+// bs4 : <no IP> : Bottom switch 4 (bridge) //
+// bs5 : <no IP> : Bottom switch 5 (bridge) //
+// : //
+// b2 : 192.168.2.2 : Bottom multi-switch UDP echo server //
+// b3 : 192.168.2.3 : Bottom single-switch UDP echo client //
+// : //
+// ---------------------------------------------------------------------- //
+// Author: Chip Webb <ns3 (a) chipwebb dot com> //
+// ###################################################################### //
+
+#include <iostream>
+#include <fstream>
+
+#include "ns3/core-module.h"
+#include "ns3/network-module.h"
+#include "ns3/applications-module.h"
+#include "ns3/bridge-module.h"
+#include "ns3/csma-module.h"
+#include "ns3/point-to-point-module.h"
+#include "ns3/internet-module.h"
+
+using namespace ns3;
+
+// ########################################################################
+// Main routine
+// ########################################################################
+NS_LOG_COMPONENT_DEFINE ("GlobalRoutingMultiSwitchPlusRouter");
+
+#define vssearch(loc,vec) std::find ((vec).begin (), (vec).end (), (loc)) != (vec).end ()
+
+int
+main (int argc, char *argv[])
+{
+ // ----------------------------------------------------------------------
+ // Default values for command line arguments
+ // ----------------------------------------------------------------------
+ bool verbose = true;
+
+ int simDurationSeconds = 60;
+
+ bool enableUdpMultiSW = true;
+ bool enableUdpSingleSW = true;
+
+ std::string pcapLocations = "";
+ uint32_t snapLen = PcapFile::SNAPLEN_DEFAULT;
+
+ std::string csmaXLinkDataRate = "100Mbps";
+ std::string csmaXLinkDelay = "500ns";
+
+ std::string csmaYLinkDataRate = "10Mbps";
+ std::string csmaYLinkDelay = "500ns";
+
+ std::string p2pLinkDataRate = "5Mbps";
+ std::string p2pLinkDelay = "50ms";
+
+ uint16_t udpEchoPort = 9; // The well-known UDP echo port
+
+
+ // ----------------------------------------------------------------------
+ // Create command line options and get them
+ // ----------------------------------------------------------------------
+ CommandLine cmd;
+
+ cmd.Usage ("NOTE: valid --pcap arguments are: 't2,t3,b2,b3,trlan,trwan,brlan,brwan'");
+
+ cmd.AddValue ("verbose", "Enable printing informational messages", verbose);
+
+ cmd.AddValue ("duration", "Duration of simulation.", simDurationSeconds);
+
+ cmd.AddValue ("udpMultiSW", "Enable udp over multi-switch links", enableUdpMultiSW);
+ cmd.AddValue ("udpSingleSW", "Enable udp over single-switch links", enableUdpSingleSW);
+
+ cmd.AddValue ("pcap", "Comma separated list of PCAP Locations to tap", pcapLocations);
+ cmd.AddValue ("snapLen", "PCAP packet capture length", snapLen);
+
+ cmd.AddValue ("csmaXRate", "CSMA X Link data rate", csmaXLinkDataRate);
+ cmd.AddValue ("csmaXDelay", "CSMA X Link delay", csmaXLinkDelay);
+
+ cmd.AddValue ("csmaYRate", "CSMA Y Link data rate", csmaYLinkDataRate);
+ cmd.AddValue ("csmaYDelay", "CSMA Y Link delay", csmaYLinkDelay);
+
+ cmd.AddValue ("p2pRate", "P2P Link data rate", p2pLinkDataRate);
+ cmd.AddValue ("p2pDelay", "P2P Link delay", p2pLinkDelay);
+
+ cmd.Parse (argc, argv);
+
+ // --------------------------------------------------------------------
+ // Users may find it convenient to turn on explicit debugging
+ // for selected modules; the below lines suggest how to do this
+ // --------------------------------------------------------------------
+ if (verbose)
+ {
+ LogComponentEnable ("GlobalRoutingMultiSwitchPlusRouter", LOG_LEVEL_INFO);
+ }
+
+
+ // ======================================================================
+ // Define the list of valid PCAP taps
+ // ----------------------------------------------------------------------
+ std::vector<std::string> pcapTaps;
+ pcapTaps.push_back ("t2"); // multi-switch UDP echo client
+ pcapTaps.push_back ("t3"); // single-switch UDP echo server
+ pcapTaps.push_back ("b2"); // multi-switch UDP echo server
+ pcapTaps.push_back ("b3"); // single-switch UDP echo client
+ pcapTaps.push_back ("trlan"); // top router LAN side
+ pcapTaps.push_back ("trwan"); // top router WAN side
+ pcapTaps.push_back ("brlan"); // bottom router LAN side
+ pcapTaps.push_back ("brwan"); // bottom router WAN side
+
+ // ----------------------------------------------------------------------
+ // Parse the pcapLocations string into pcapLocationVec
+ // ----------------------------------------------------------------------
+ std::vector<std::string> pcapLocationVec;
+ if (pcapLocations != "")
+ {
+ std::stringstream sStream (pcapLocations);
+
+ while ( sStream.good () )
+ {
+ std::string substr;
+ getline ( sStream, substr, ',' );
+ if (vssearch (substr,pcapTaps))
+ {
+ pcapLocationVec.push_back ( substr );
+ }
+ else
+ {
+ NS_LOG_ERROR ("WARNING: Unrecognized PCAP location: <" + substr + ">");
+ }
+ }
+
+ for (std::vector<std::string>::const_iterator
+ ploc = pcapLocationVec.begin ();
+ ploc != pcapLocationVec.end ();
+ ++ploc)
+ {
+ NS_LOG_INFO ("PCAP capture at: <" + *ploc + ">");
+ }
+ }
+
+
+ // ======================================================================
+ // Set some simulator-wide values
+ // ======================================================================
+
+ // ----------------------------------------------------------------------
+ // Set PCAP packet capture maximum packet length
+ // ----------------------------------------------------------------------
+ if (snapLen != PcapFile::SNAPLEN_DEFAULT)
+ {
+ Config::SetDefault ("ns3::PcapFileWrapper::CaptureSize", UintegerValue (snapLen));
+ }
+
+ // ======================================================================
+ // Create the nodes & links required for the topology shown in comments above.
+ // ----------------------------------------------------------------------
+ NS_LOG_INFO ("INFO: Create nodes."); // - - - - - - - - - - - - - - - -
+ // Node IP : Description
+ // - - - - - - - - - - - - - - - -
+ Ptr<Node> t2 = CreateObject<Node> (); // 192.168.1.2 : Top multi-switch udp echo client
+ Ptr<Node> t3 = CreateObject<Node> (); // 192.168.1.3 : Top single-switch udp echo server
+ // :
+ Ptr<Node> ts1 = CreateObject<Node> (); // <no IP> : Top switch #1 (bridge)
+ Ptr<Node> ts2 = CreateObject<Node> (); // <no IP> : Top switch #2 (bridge)
+ Ptr<Node> ts3 = CreateObject<Node> (); // <no IP> : Top switch #3 (bridge)
+ Ptr<Node> ts4 = CreateObject<Node> (); // <no IP> : Top switch #4 (bridge)
+ // :
+ Ptr<Node> tr = CreateObject<Node> (); // 192.168.1.1 : Router connecting top LAN & WAN
+ // 76.1.1.1 :
+ // :
+ Ptr<Node> br = CreateObject<Node> (); // 76.1.1.2 : Router connecting WAN & bottom LANs
+ // 192.168.2.1 :
+ // :
+ Ptr<Node> bs1 = CreateObject<Node> (); // <no IP> : Bottom switch #1 (bridge)
+ Ptr<Node> bs2 = CreateObject<Node> (); // <no IP> : Bottom switch #2 (bridge)
+ Ptr<Node> bs3 = CreateObject<Node> (); // <no IP> : Bottom switch #3 (bridge)
+ Ptr<Node> bs4 = CreateObject<Node> (); // <no IP> : Bottom switch #4 (bridge)
+ Ptr<Node> bs5 = CreateObject<Node> (); // <no IP> : Bottom switch #5 (bridge)
+ // :
+ Ptr<Node> b2 = CreateObject<Node> (); // 192.168.2.2 : Bottom multi-switch udp echo server
+
+ Ptr<Node> b3 = CreateObject<Node> (); // 192.168.2.3 : Bottom single-switch udp echo client
+ // - - - - - - - - - - - - - - - -
+
+ // ----------------------------------------------------------------------
+ // Give the nodes names
+ // ----------------------------------------------------------------------
+ Names::Add ("t2", t2);
+ Names::Add ("t3", t3);
+ Names::Add ("ts1", ts1);
+ Names::Add ("ts2", ts2);
+ Names::Add ("ts3", ts3);
+ Names::Add ("ts4", ts4);
+ Names::Add ("tr", tr);
+ Names::Add ("br", br);
+ Names::Add ("bs1", bs1);
+ Names::Add ("bs2", bs2);
+ Names::Add ("bs3", bs3);
+ Names::Add ("bs4", bs4);
+ Names::Add ("bs5", bs5);
+ Names::Add ("b2", b2);
+ Names::Add ("b3", b3);
+
+ // ======================================================================
+ // Create CSMA links to use for connecting LAN nodes together
+ // ----------------------------------------------------------------------
+
+ // ----------------------------------------
+ // CSMA [X]
+ // ----------------------------------------
+ NS_LOG_INFO ("L2: Create a " <<
+ csmaXLinkDataRate << " " <<
+ csmaXLinkDelay << " CSMA link for csmaX for LANs.");
+ CsmaHelper csmaX;
+ csmaX.SetChannelAttribute ("DataRate", StringValue (csmaXLinkDataRate));
+ csmaX.SetChannelAttribute ("Delay", StringValue (csmaXLinkDelay));
+
+ // ----------------------------------------
+ // CSMA [Y]
+ // ----------------------------------------
+ NS_LOG_INFO ("L2: Create a " <<
+ csmaYLinkDataRate << " " <<
+ csmaYLinkDelay << " CSMA link for csmaY for LANs.");
+ CsmaHelper csmaY;
+ csmaY.SetChannelAttribute ("DataRate", StringValue (csmaYLinkDataRate));
+ csmaY.SetChannelAttribute ("Delay", StringValue (csmaYLinkDelay));
+
+ // ----------------------------------------------------------------------
+ // Now, connect the top LAN nodes together with csma links.
+ // ----------------------------------------------------------------------
+ NS_LOG_INFO ("L2: Connect nodes on top LAN together with half-duplex CSMA links.");
+
+ // Multi-switch top LAN chain: t2-ts4-ts3-ts2-ts1-tr
+ NetDeviceContainer link_t2_ts4 = csmaX.Install (NodeContainer (t2, ts4));
+ NetDeviceContainer link_ts4_ts3 = csmaY.Install (NodeContainer (ts4, ts3));
+ NetDeviceContainer link_ts3_ts2 = csmaX.Install (NodeContainer (ts3, ts2));
+ NetDeviceContainer link_ts2_ts1 = csmaY.Install (NodeContainer (ts2, ts1));
+
+ // Single-switch top LAN link: t3-ts1-tr
+ NetDeviceContainer link_t3_ts1 = csmaX.Install (NodeContainer (t3, ts1));
+
+ // Common link for top LAN between ts1 and tr (for t2 and t3 to get to tr)
+ NetDeviceContainer link_tr_ts1 = csmaY.Install (NodeContainer (tr, ts1));
+
+ // ----------------------------------------------------------------------
+ // And repeat above steps to connect the bottom LAN nodes together
+ // ----------------------------------------------------------------------
+ NS_LOG_INFO ("L2: Connect nodes on bottom LAN together with half-duplex CSMA links.");
+
+ // Multi-switch bottom LAN chain: b2-bs5-bs4-bs3-bs2-bs1-br
+ NetDeviceContainer link_b2_bs5 = csmaY.Install (NodeContainer (b2, bs5));
+ NetDeviceContainer link_bs5_bs4 = csmaX.Install (NodeContainer (bs5, bs4));
+ NetDeviceContainer link_bs4_bs3 = csmaY.Install (NodeContainer (bs4, bs3));
+ NetDeviceContainer link_bs3_bs2 = csmaX.Install (NodeContainer (bs3, bs2));
+ NetDeviceContainer link_bs2_bs1 = csmaY.Install (NodeContainer (bs2, bs1));
+
+ // Single-switch bottom LAN link: b3-bs1-br
+ NetDeviceContainer link_b3_bs1 = csmaY.Install (NodeContainer (b3, bs1));
+
+ // Common link for bottom LAN between bs1 and br (for b2 and b3 to get to br)
+ NetDeviceContainer link_br_bs1 = csmaX.Install (NodeContainer (br, bs1));
+
+
+ // ======================================================================
+ // Create a point-to-point link for connecting WAN nodes together
+ // (this type of link is full-duplex)
+ // ----------------------------------------------------------------------
+ NS_LOG_INFO ("L2: Create a " <<
+ p2pLinkDataRate << " " <<
+ p2pLinkDelay << " Point-to-Point link for the WAN.");
+
+ PointToPointHelper p2p;
+ p2p.SetDeviceAttribute ("DataRate", StringValue (p2pLinkDataRate));
+ p2p.SetChannelAttribute ("Delay", StringValue (p2pLinkDelay));
+
+ // ----------------------------------------------------------------------
+ // Now, connect top router to bottom router with a p2p WAN link
+ // ----------------------------------------------------------------------
+ NS_LOG_INFO ("L2: Connect the routers together with the Point-to-Point WAN link.");
+
+ NetDeviceContainer link_tr_br;
+ link_tr_br = p2p.Install (NodeContainer (tr,br));
+
+ // ======================================================================
+ // Manually create the list of NetDevices for each switch
+ // ----------------------------------------------------------------------
+
+ // Top Switch 4 NetDevices
+ NetDeviceContainer ts4nd;
+ ts4nd.Add (link_t2_ts4.Get (1));
+ ts4nd.Add (link_ts4_ts3.Get (0));
+
+ // Top Switch 3 NetDevices
+ NetDeviceContainer ts3nd;
+ ts3nd.Add (link_ts4_ts3.Get (1));
+ ts3nd.Add (link_ts3_ts2.Get (0));
+
+ // Top Switch 2 NetDevices
+ NetDeviceContainer ts2nd;
+ ts2nd.Add (link_ts3_ts2.Get (1));
+ ts2nd.Add (link_ts2_ts1.Get (0));
+
+ // Top Switch 1 NetDevices
+ NetDeviceContainer ts1nd;
+ ts1nd.Add (link_ts2_ts1.Get (1));
+ ts1nd.Add (link_t3_ts1.Get (1));
+ ts1nd.Add (link_tr_ts1.Get (1));
+
+
+ // Bottom Switch 1 NetDevices
+ NetDeviceContainer bs1nd;
+ bs1nd.Add (link_br_bs1.Get (1));
+ bs1nd.Add (link_bs2_bs1.Get (1));
+ bs1nd.Add (link_b3_bs1.Get (1));
+
+ // Bottom Switch 2 NetDevices
+ NetDeviceContainer bs2nd;
+ bs2nd.Add (link_bs2_bs1.Get (0));
+ bs2nd.Add (link_bs3_bs2.Get (1));
+
+ // Bottom Switch 3 NetDevices
+ NetDeviceContainer bs3nd;
+ bs3nd.Add (link_bs3_bs2.Get (0));
+ bs3nd.Add (link_bs4_bs3.Get (1));
+
+ // Bottom Switch 4 NetDevices
+ NetDeviceContainer bs4nd;
+ bs4nd.Add (link_bs4_bs3.Get (0));
+ bs4nd.Add (link_bs5_bs4.Get (1));
+
+ // Bottom Switch 5 NetDevices
+ NetDeviceContainer bs5nd;
+ bs5nd.Add (link_bs5_bs4.Get (0));
+ bs5nd.Add (link_b2_bs5.Get (1));
+
+
+ // ======================================================================
+ // Install bridging code on each switch
+ // ----------------------------------------------------------------------
+ BridgeHelper bridge;
+
+ bridge.Install (ts1, ts1nd);
+ bridge.Install (ts2, ts2nd);
+ bridge.Install (ts3, ts3nd);
+ bridge.Install (ts4, ts4nd);
+
+ bridge.Install (bs1, bs1nd);
+ bridge.Install (bs2, bs2nd);
+ bridge.Install (bs3, bs3nd);
+ bridge.Install (bs4, bs4nd);
+ bridge.Install (bs5, bs5nd);
+
+ // ======================================================================
+ // Install the L3 internet stack (TCP/IP)
+ // ----------------------------------------------------------------------
+ InternetStackHelper ns3IpStack;
+
+ // ----------------------------------------------------------------------
+ // Install the L3 internet stack on UDP endpoints
+ // ----------------------------------------------------------------------
+ NS_LOG_INFO ("L3: Install the ns3 IP stack on udp client and server nodes.");
+ NodeContainer endpointNodes (t2, t3, b2, b3);
+ ns3IpStack.Install (endpointNodes);
+
+ // ----------------------------------------------------------------------
+ // Install the L3 internet stack on routers.
+ // ----------------------------------------------------------------------
+ NS_LOG_INFO ("L3: Install the ns3 IP stack on routers.");
+ NodeContainer routerNodes (tr, br);
+ ns3IpStack.Install (routerNodes);
+
+ // ======================================================================
+ // Assign top LAN IP addresses
+ // ----------------------------------------------------------------------
+ NS_LOG_INFO ("L3: Assign top LAN IP Addresses.");
+
+ NetDeviceContainer topLanIpDevices; // - - - - - -- - - - - - -
+ topLanIpDevices.Add (link_tr_ts1.Get (0)); // NOTE: order matters here
+ topLanIpDevices.Add (link_t2_ts4.Get (0)); // for IP address
+ topLanIpDevices.Add (link_t3_ts1.Get (0)); // assignment
+ // - - - - - -- - - - - - -
+ Ipv4AddressHelper ipv4;
+ ipv4.SetBase ("192.168.1.0", "255.255.255.0");
+ ipv4.Assign (topLanIpDevices);
+
+ // ----------------------------------------------------------------------
+ // Assign bottom LAN IP addresses
+ // ----------------------------------------------------------------------
+ NS_LOG_INFO ("L3: Assign bottom LAN IP Addresses.");
+
+ NetDeviceContainer botLanIpDevices; // - - - - - -- - - - - - -
+ botLanIpDevices.Add (link_br_bs1.Get (0)); // NOTE: order matters here
+ botLanIpDevices.Add (link_b2_bs5.Get (0)); // for IP address
+ botLanIpDevices.Add (link_b3_bs1.Get (0)); // assignment
+ // - - - - - -- - - - - - -
+
+ ipv4.SetBase ("192.168.2.0", "255.255.255.0");
+ ipv4.Assign (botLanIpDevices);
+
+ // ----------------------------------------------------------------------
+ // Assign WAN IP addresses
+ // ----------------------------------------------------------------------
+ NS_LOG_INFO ("L3: Assign WAN IP Addresses.");
+
+ ipv4.SetBase ("76.1.1.0", "255.255.255.0");
+ ipv4.Assign (link_tr_br);
+
+
+ // ======================================================================
+ // Calculate and populate routing tables
+ // ----------------------------------------------------------------------
+ NS_LOG_INFO ("L3: Populate routing tables.");
+ Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
+
+
+ // ======================================================================
+ // Multi-Switch UDP traffic generation
+ // ----------------------------------------------------------------------
+ ApplicationContainer apps;
+
+ if (enableUdpMultiSW)
+ {
+ // ------------------------------------------------------------------
+ // Install multi-switch UDP echo server on b2
+ // ------------------------------------------------------------------
+ NS_LOG_INFO ("APP: Multi-Switch UDP server (on node b2 of bottom LAN)");
+
+ UdpEchoServerHelper server (udpEchoPort);
+
+ ApplicationContainer serverApp = server.Install (b2);
+ serverApp.Start (Seconds (0.5));
+ serverApp.Stop (Seconds (simDurationSeconds));
+
+ // ------------------------------------------------------------------
+ // Install multi-switch UDP echo client on t2
+ // ------------------------------------------------------------------
+ NS_LOG_INFO ("APP: Multi-Switch UDP client (on node t2 of top LAN)");
+
+ Time interPacketInterval = Seconds (0.005);
+ uint32_t packetSize = 1000;
+ uint32_t maxPacketCount = (simDurationSeconds - 2.0) / 0.005;
+
+ UdpEchoClientHelper client (Ipv4Address ("192.168.2.2"), udpEchoPort);
+
+ client.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount));
+ client.SetAttribute ("Interval", TimeValue (interPacketInterval));
+ client.SetAttribute ("PacketSize", UintegerValue (packetSize));
+
+ ApplicationContainer clientApp = client.Install (t2);
+ clientApp.Start (Seconds (0.5));
+ clientApp.Stop (Seconds (simDurationSeconds));
+ }
+
+ // ======================================================================
+ // Single-Switch UDP traffic generation
+ // ----------------------------------------------------------------------
+ if (enableUdpSingleSW)
+ {
+ // ------------------------------------------------------------------
+ // Install single-switch UDP echo server on t3
+ // ------------------------------------------------------------------
+ NS_LOG_INFO ("APP: Single-Switch UDP server (on node t3 of top LAN)");
+
+ UdpEchoServerHelper server (udpEchoPort);
+
+ ApplicationContainer serverApp = server.Install (t3);
+ serverApp.Start (Seconds (0.5));
+ serverApp.Stop (Seconds (simDurationSeconds));
+
+ // ------------------------------------------------------------------
+ // Install single-switch UDP echo client on b3
+ // ------------------------------------------------------------------
+ NS_LOG_INFO ("APP: Single-Switch UDP client (on node b3 bottom LAN)");
+
+ Time interPacketInterval = Seconds (0.005);
+ uint32_t packetSize = 1000;
+ uint32_t maxPacketCount = (simDurationSeconds - 2.0) / 0.005;
+
+ UdpEchoClientHelper client (Ipv4Address ("192.168.1.3"), udpEchoPort);
+
+ client.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount));
+ client.SetAttribute ("Interval", TimeValue (interPacketInterval));
+ client.SetAttribute ("PacketSize", UintegerValue (packetSize));
+
+ ApplicationContainer clientApp = client.Install (b3);
+ clientApp.Start (Seconds (0.5));
+ clientApp.Stop (Seconds (simDurationSeconds));
+ }
+
+
+ // ======================================================================
+ // Print routing tables at T=0.1
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ // NOTE: Node 0 and Node 13 must have non-empty tables (except for local
+ // loopback and local LAN) if routing is operating correctly.
+ // ----------------------------------------------------------------------
+ NS_LOG_INFO ("Set up to print routing tables at T=0.1s");
+
+ Ptr<OutputStreamWrapper> routingStream =
+ Create<OutputStreamWrapper> ("global-routing-multi-switch-plus-router.routes", std::ios::out);
+
+ Ipv4GlobalRoutingHelper g;
+ g.PrintRoutingTableAllAt (Seconds (0.1), routingStream);
+
+
+ // ======================================================================
+ // Configure PCAP traces
+ // ----------------------------------------------------------------------
+ NS_LOG_INFO ("Configure PCAP Tracing (if any configured).");
+
+ // - - - - - - - - - - - - - -
+ // multi-switch UDP echo client
+ // - - - - - - - - - - - - - -
+ if (vssearch ("t2",pcapLocationVec))
+ {
+ csmaX.EnablePcap ("t2.pcap", topLanIpDevices.Get (1), true, true);
+ }
+
+ // - - - - - - - - - - - - - -
+ // multi-switch UDP echo server
+ // - - - - - - - - - - - - - -
+ if (vssearch ("b2",pcapLocationVec))
+ {
+ csmaY.EnablePcap ("b2.pcap", botLanIpDevices.Get (1), true, true);
+ }
+
+ // - - - - - - - - - - - - - -
+ // single-switch UDP echo client
+ // - - - - - - - - - - - - - -
+ if (vssearch ("b3",pcapLocationVec))
+ {
+ csmaY.EnablePcap ("b3.pcap", botLanIpDevices.Get (2), true, true);
+ }
+
+ // - - - - - - - - - - - - - -
+ // single-switch UDP echo server
+ // - - - - - - - - - - - - - -
+ if (vssearch ("t3",pcapLocationVec))
+ {
+ csmaX.EnablePcap ("t3.pcap", topLanIpDevices.Get (2), true, true);
+ }
+
+ // - - - - - - - - - - - - - -
+ // top router, LAN side
+ // - - - - - - - - - - - - - -
+ if (vssearch ("trlan",pcapLocationVec))
+ {
+ csmaY.EnablePcap ("trlan.pcap", topLanIpDevices.Get (0), true, true);
+ }
+
+ // - - - - - - - - - - - - - -
+ // bottom router, LAN side
+ // - - - - - - - - - - - - - -
+ if (vssearch ("brlan",pcapLocationVec))
+ {
+ csmaX.EnablePcap ("brlan.pcap", botLanIpDevices.Get (0), true, true);
+ }
+
+ // - - - - - - - - - - - - - -
+ // top router, WAN side
+ // - - - - - - - - - - - - - -
+ if (vssearch ("trwan",pcapLocationVec))
+ {
+ p2p.EnablePcap ("trwan.pcap", link_tr_br.Get (0), true, true);
+ }
+
+ // - - - - - - - - - - - - - -
+ // bottom router, WAN side
+ // - - - - - - - - - - - - - -
+ if (vssearch ("brwan",pcapLocationVec))
+ {
+ p2p.EnablePcap ("brwan.pcap", link_tr_br.Get (1), true, true);
+ }
+
+
+ // ======================================================================
+ // Now, do the actual simulation.
+ // ----------------------------------------------------------------------
+ NS_LOG_INFO ("Run Simulation for " << simDurationSeconds << " seconds.");
+
+ Simulator::Stop (Seconds (simDurationSeconds));
+ Simulator::Run ();
+
+ Simulator::Destroy ();
+ NS_LOG_INFO ("Done.");
+
+}