From ed30b42b1f7bf66b6dc3fea98716f157589648fd Mon Sep 17 00:00:00 2001 From: Chip Webb Date: Thu, 10 Mar 2016 16:07:51 -0800 Subject: [PATCH] internet: Add global routing bridged topology example --- ...global-routing-multi-switch-plus-router.cc | 810 ++++++++++++++++++ examples/routing/wscript | 3 + 2 files changed, 813 insertions(+) create mode 100644 examples/routing/global-routing-multi-switch-plus-router.cc diff --git a/examples/routing/global-routing-multi-switch-plus-router.cc b/examples/routing/global-routing-multi-switch-plus-router.cc new file mode 100644 index 000000000..e1bb77b9f --- /dev/null +++ b/examples/routing/global-routing-multi-switch-plus-router.cc @@ -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 + * + */ + +// ###################################################################### // +// 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 : : Top switch 1 (bridge) // +// ts2 : : Top switch 2 (bridge) // +// ts3 : : Top switch 3 (bridge) // +// ts4 : : 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 : : Bottom switch 1 (bridge) // +// bs2 : : Bottom switch 2 (bridge) // +// bs3 : : Bottom switch 3 (bridge) // +// bs4 : : Bottom switch 4 (bridge) // +// bs5 : : 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 // +// ###################################################################### // + +#include +#include + +#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 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 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::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 t2 = CreateObject (); // 192.168.1.2 : Top multi-switch udp echo client + Ptr t3 = CreateObject (); // 192.168.1.3 : Top single-switch udp echo server + // : + Ptr ts1 = CreateObject (); // : Top switch #1 (bridge) + Ptr ts2 = CreateObject (); // : Top switch #2 (bridge) + Ptr ts3 = CreateObject (); // : Top switch #3 (bridge) + Ptr ts4 = CreateObject (); // : Top switch #4 (bridge) + // : + Ptr tr = CreateObject (); // 192.168.1.1 : Router connecting top LAN & WAN + // 76.1.1.1 : + // : + Ptr br = CreateObject (); // 76.1.1.2 : Router connecting WAN & bottom LANs + // 192.168.2.1 : + // : + Ptr bs1 = CreateObject (); // : Bottom switch #1 (bridge) + Ptr bs2 = CreateObject (); // : Bottom switch #2 (bridge) + Ptr bs3 = CreateObject (); // : Bottom switch #3 (bridge) + Ptr bs4 = CreateObject (); // : Bottom switch #4 (bridge) + Ptr bs5 = CreateObject (); // : Bottom switch #5 (bridge) + // : + Ptr b2 = CreateObject (); // 192.168.2.2 : Bottom multi-switch udp echo server + + Ptr b3 = CreateObject (); // 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 routingStream = + Create ("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."); + +} diff --git a/examples/routing/wscript b/examples/routing/wscript index bc91acb26..597001bd6 100644 --- a/examples/routing/wscript +++ b/examples/routing/wscript @@ -47,3 +47,6 @@ def build(bld): ['csma', 'internet', 'internet-apps']) obj.source = 'rip-simple-network.cc' + obj = bld.create_ns3_program('global-routing-multi-switch-plus-router', + ['core', 'network', 'applications', 'internet', 'bridge', 'csma', 'point-to-point', 'csma', 'internet']) + obj.source = 'global-routing-multi-switch-plus-router.cc'