/* * 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 "ns3/applications-module.h" #include "ns3/bridge-module.h" #include "ns3/core-module.h" #include "ns3/csma-module.h" #include "ns3/internet-module.h" #include "ns3/network-module.h" #include "ns3/point-to-point-module.h" #include #include 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(__FILE__); 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 // ---------------------------------------------------------------------- const std::vector pcapTaps{ "t2", // multi-switch UDP echo client "t3", // single-switch UDP echo server "b2", // multi-switch UDP echo server "b3", // single-switch UDP echo client "trlan", // top router LAN side "trwan", // top router WAN side "brlan", // bottom router LAN side "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."); return 0; }