/* * Copyright (c) 2016 Universita' di Firenze, Italy * * 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: Tommaso Pecorella */ // Network topology // // SRC // |<=== source network // A-----B // \ / \ all networks have cost 1, except // \ / | for the direct link from C to D, which // C / has cost 10 // | / // |/ // D // |<=== target network // DST // // // A, B, C and D are RIPng routers. // A and D are configured with static addresses. // SRC and DST will exchange packets. // // After about 3 seconds, the topology is built, and Echo Reply will be received. // After 40 seconds, the link between B and D will break, causing a route failure. // After 44 seconds from the failure, the routers will recovery from the failure. // Split Horizoning should affect the recovery time, but it is not. See the manual // for an explanation of this effect. // // If "showPings" is enabled, the user will see: // 1) if the ping has been acknowledged // 2) if a Destination Unreachable has been received by the sender // 3) nothing, when the Echo Request has been received by the destination but // the Echo Reply is unable to reach the sender. // Examining the .pcap files with Wireshark can confirm this effect. #include "ns3/core-module.h" #include "ns3/csma-module.h" #include "ns3/internet-apps-module.h" #include "ns3/internet-module.h" #include "ns3/ipv4-routing-table-entry.h" #include "ns3/ipv4-static-routing-helper.h" #include using namespace ns3; NS_LOG_COMPONENT_DEFINE("RipSimpleRouting"); void TearDownLink(Ptr nodeA, Ptr nodeB, uint32_t interfaceA, uint32_t interfaceB) { nodeA->GetObject()->SetDown(interfaceA); nodeB->GetObject()->SetDown(interfaceB); } int main(int argc, char** argv) { bool verbose = false; bool printRoutingTables = false; bool showPings = false; std::string SplitHorizon("PoisonReverse"); CommandLine cmd(__FILE__); cmd.AddValue("verbose", "turn on log components", verbose); cmd.AddValue("printRoutingTables", "Print routing tables at 30, 60 and 90 seconds", printRoutingTables); cmd.AddValue("showPings", "Show Ping6 reception", showPings); cmd.AddValue("splitHorizonStrategy", "Split Horizon strategy to use (NoSplitHorizon, SplitHorizon, PoisonReverse)", SplitHorizon); cmd.Parse(argc, argv); if (verbose) { LogComponentEnableAll(LogLevel(LOG_PREFIX_TIME | LOG_PREFIX_NODE)); LogComponentEnable("RipSimpleRouting", LOG_LEVEL_INFO); LogComponentEnable("Rip", LOG_LEVEL_ALL); LogComponentEnable("Ipv4Interface", LOG_LEVEL_ALL); LogComponentEnable("Icmpv4L4Protocol", LOG_LEVEL_ALL); LogComponentEnable("Ipv4L3Protocol", LOG_LEVEL_ALL); LogComponentEnable("ArpCache", LOG_LEVEL_ALL); LogComponentEnable("V4Ping", LOG_LEVEL_ALL); } if (SplitHorizon == "NoSplitHorizon") { Config::SetDefault("ns3::Rip::SplitHorizon", EnumValue(RipNg::NO_SPLIT_HORIZON)); } else if (SplitHorizon == "SplitHorizon") { Config::SetDefault("ns3::Rip::SplitHorizon", EnumValue(RipNg::SPLIT_HORIZON)); } else { Config::SetDefault("ns3::Rip::SplitHorizon", EnumValue(RipNg::POISON_REVERSE)); } NS_LOG_INFO("Create nodes."); Ptr src = CreateObject(); Names::Add("SrcNode", src); Ptr dst = CreateObject(); Names::Add("DstNode", dst); Ptr a = CreateObject(); Names::Add("RouterA", a); Ptr b = CreateObject(); Names::Add("RouterB", b); Ptr c = CreateObject(); Names::Add("RouterC", c); Ptr d = CreateObject(); Names::Add("RouterD", d); NodeContainer net1(src, a); NodeContainer net2(a, b); NodeContainer net3(a, c); NodeContainer net4(b, c); NodeContainer net5(c, d); NodeContainer net6(b, d); NodeContainer net7(d, dst); NodeContainer routers(a, b, c, d); NodeContainer nodes(src, dst); NS_LOG_INFO("Create channels."); CsmaHelper csma; csma.SetChannelAttribute("DataRate", DataRateValue(5000000)); csma.SetChannelAttribute("Delay", TimeValue(MilliSeconds(2))); NetDeviceContainer ndc1 = csma.Install(net1); NetDeviceContainer ndc2 = csma.Install(net2); NetDeviceContainer ndc3 = csma.Install(net3); NetDeviceContainer ndc4 = csma.Install(net4); NetDeviceContainer ndc5 = csma.Install(net5); NetDeviceContainer ndc6 = csma.Install(net6); NetDeviceContainer ndc7 = csma.Install(net7); NS_LOG_INFO("Create IPv4 and routing"); RipHelper ripRouting; // Rule of thumb: // Interfaces are added sequentially, starting from 0 // However, interface 0 is always the loopback... ripRouting.ExcludeInterface(a, 1); ripRouting.ExcludeInterface(d, 3); ripRouting.SetInterfaceMetric(c, 3, 10); ripRouting.SetInterfaceMetric(d, 1, 10); Ipv4ListRoutingHelper listRH; listRH.Add(ripRouting, 0); // Ipv4StaticRoutingHelper staticRh; // listRH.Add (staticRh, 5); InternetStackHelper internet; internet.SetIpv6StackInstall(false); internet.SetRoutingHelper(listRH); internet.Install(routers); InternetStackHelper internetNodes; internetNodes.SetIpv6StackInstall(false); internetNodes.Install(nodes); // Assign addresses. // The source and destination networks have global addresses // The "core" network just needs link-local addresses for routing. // We assign global addresses to the routers as well to receive // ICMPv6 errors. NS_LOG_INFO("Assign IPv4 Addresses."); Ipv4AddressHelper ipv4; ipv4.SetBase(Ipv4Address("10.0.0.0"), Ipv4Mask("255.255.255.0")); Ipv4InterfaceContainer iic1 = ipv4.Assign(ndc1); ipv4.SetBase(Ipv4Address("10.0.1.0"), Ipv4Mask("255.255.255.0")); Ipv4InterfaceContainer iic2 = ipv4.Assign(ndc2); ipv4.SetBase(Ipv4Address("10.0.2.0"), Ipv4Mask("255.255.255.0")); Ipv4InterfaceContainer iic3 = ipv4.Assign(ndc3); ipv4.SetBase(Ipv4Address("10.0.3.0"), Ipv4Mask("255.255.255.0")); Ipv4InterfaceContainer iic4 = ipv4.Assign(ndc4); ipv4.SetBase(Ipv4Address("10.0.4.0"), Ipv4Mask("255.255.255.0")); Ipv4InterfaceContainer iic5 = ipv4.Assign(ndc5); ipv4.SetBase(Ipv4Address("10.0.5.0"), Ipv4Mask("255.255.255.0")); Ipv4InterfaceContainer iic6 = ipv4.Assign(ndc6); ipv4.SetBase(Ipv4Address("10.0.6.0"), Ipv4Mask("255.255.255.0")); Ipv4InterfaceContainer iic7 = ipv4.Assign(ndc7); Ptr staticRouting; staticRouting = Ipv4RoutingHelper::GetRouting( src->GetObject()->GetRoutingProtocol()); staticRouting->SetDefaultRoute("10.0.0.2", 1); staticRouting = Ipv4RoutingHelper::GetRouting( dst->GetObject()->GetRoutingProtocol()); staticRouting->SetDefaultRoute("10.0.6.1", 1); if (printRoutingTables) { RipHelper routingHelper; Ptr routingStream = Create(&std::cout); routingHelper.PrintRoutingTableAt(Seconds(30.0), a, routingStream); routingHelper.PrintRoutingTableAt(Seconds(30.0), b, routingStream); routingHelper.PrintRoutingTableAt(Seconds(30.0), c, routingStream); routingHelper.PrintRoutingTableAt(Seconds(30.0), d, routingStream); routingHelper.PrintRoutingTableAt(Seconds(60.0), a, routingStream); routingHelper.PrintRoutingTableAt(Seconds(60.0), b, routingStream); routingHelper.PrintRoutingTableAt(Seconds(60.0), c, routingStream); routingHelper.PrintRoutingTableAt(Seconds(60.0), d, routingStream); routingHelper.PrintRoutingTableAt(Seconds(90.0), a, routingStream); routingHelper.PrintRoutingTableAt(Seconds(90.0), b, routingStream); routingHelper.PrintRoutingTableAt(Seconds(90.0), c, routingStream); routingHelper.PrintRoutingTableAt(Seconds(90.0), d, routingStream); } NS_LOG_INFO("Create Applications."); uint32_t packetSize = 1024; Time interPacketInterval = Seconds(1.0); V4PingHelper ping("10.0.6.2"); ping.SetAttribute("Interval", TimeValue(interPacketInterval)); ping.SetAttribute("Size", UintegerValue(packetSize)); if (showPings) { ping.SetAttribute("Verbose", BooleanValue(true)); } ApplicationContainer apps = ping.Install(src); apps.Start(Seconds(1.0)); apps.Stop(Seconds(110.0)); AsciiTraceHelper ascii; csma.EnableAsciiAll(ascii.CreateFileStream("rip-simple-routing.tr")); csma.EnablePcapAll("rip-simple-routing", true); Simulator::Schedule(Seconds(40), &TearDownLink, b, d, 3, 2); /* Now, do the actual simulation. */ NS_LOG_INFO("Run Simulation."); Simulator::Stop(Seconds(131.0)); Simulator::Run(); Simulator::Destroy(); NS_LOG_INFO("Done."); return 0; }