From 8a65a4b9bd3d3d9360463586d5635a02e4b3f7a8 Mon Sep 17 00:00:00 2001 From: Tommaso Pecorella Date: Wed, 2 Dec 2015 23:33:58 +0100 Subject: [PATCH] Bug 2238 - Ipv6 routing reorganization --- RELEASE_NOTES | 4 + examples/routing/ripng-simple-network.cc | 2 + src/internet/helper/internet-stack-helper.cc | 5 +- src/internet/model/ipv6-l3-protocol.cc | 49 +++++++++++- src/internet/model/ipv6-list-routing.cc | 82 +++----------------- src/internet/model/ipv6-static-routing.cc | 35 ++------- src/internet/model/ripng.cc | 34 +------- src/internet/test/ipv6-ripng-test.cc | 15 +--- 8 files changed, 77 insertions(+), 149 deletions(-) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index c79018f4e..3074382db 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -39,6 +39,9 @@ New user-visible features - (internet) Ipv6Address::IsAll[Nodes,Routers]Multicast() now checks the address scope beyond the simple link-local. Nodes are checked for Interface-Local, Link-Local and Realm-Local, Routers for the above plus Site-Local. +- (internet) Ipv6 routing protocols must now *not* forward packets to upper layers + unless for extremey specific cases. The Ipv6L3protocol handles almost all the + packets directed to the host. Bugs fixed ---------- @@ -61,6 +64,7 @@ Bugs fixed - Bug 2208 - Interface index based L4 protocols - Bug 2211 - Ipv{4,6}EndPoint can cause memory corruption - Bug 2219 - SixLowPanNetDevice hangs trying to decode a IPv6 Fragment extension header +- Bug 2238 - Ipv6 routing reorganization Known issues ------------ diff --git a/examples/routing/ripng-simple-network.cc b/examples/routing/ripng-simple-network.cc index 9918d4c88..1c7178459 100644 --- a/examples/routing/ripng-simple-network.cc +++ b/examples/routing/ripng-simple-network.cc @@ -162,6 +162,8 @@ int main (int argc, char **argv) Ipv6ListRoutingHelper listRH; listRH.Add (ripNgRouting, 0); + Ipv6StaticRoutingHelper staticRh; + listRH.Add (staticRh, 5); InternetStackHelper internetv6; internetv6.SetIpv4StackInstall (false); diff --git a/src/internet/helper/internet-stack-helper.cc b/src/internet/helper/internet-stack-helper.cc index 299d62eb6..d7993bb31 100644 --- a/src/internet/helper/internet-stack-helper.cc +++ b/src/internet/helper/internet-stack-helper.cc @@ -169,7 +169,6 @@ #include "ns3/ipv4-list-routing-helper.h" #include "ns3/ipv4-static-routing-helper.h" #include "ns3/ipv4-global-routing-helper.h" -#include "ns3/ipv6-list-routing-helper.h" #include "ns3/ipv6-static-routing-helper.h" #include "ns3/ipv6-extension.h" #include "ns3/ipv6-extension-demux.h" @@ -250,13 +249,11 @@ InternetStackHelper::Initialize () Ipv4StaticRoutingHelper staticRouting; Ipv4GlobalRoutingHelper globalRouting; Ipv4ListRoutingHelper listRouting; - Ipv6ListRoutingHelper listRoutingv6; Ipv6StaticRoutingHelper staticRoutingv6; listRouting.Add (staticRouting, 0); listRouting.Add (globalRouting, -10); - listRoutingv6.Add (staticRoutingv6, 0); SetRoutingHelper (listRouting); - SetRoutingHelper (listRoutingv6); + SetRoutingHelper (staticRoutingv6); } InternetStackHelper::~InternetStackHelper () diff --git a/src/internet/model/ipv6-l3-protocol.cc b/src/internet/model/ipv6-l3-protocol.cc index 19513a632..57f5ac871 100644 --- a/src/internet/model/ipv6-l3-protocol.cc +++ b/src/internet/model/ipv6-l3-protocol.cc @@ -1001,6 +1001,44 @@ void Ipv6L3Protocol::Receive (Ptr device, Ptr p, uint16 } } + // \todo At the moment, forward up any multicast packet. + // This is wrong. We should only forward up what the node is interested into + // and try to route anything other than ff01 or ff02. + if (hdr.GetDestinationAddress ().IsLinkLocalMulticast ()) + { + LocalDeliver (packet, hdr, interface); + return; + } + + /// \todo Configurable option to enable \RFC{1222} Strong End System Model + // Right now, we will be permissive and allow a source to send us + // a packet to one of our other interface addresses; that is, the + // destination unicast address does not match one of the iif addresses, + // but we check our other interfaces. This could be an option + // (to remove the outer loop immediately below and just check iif). + for (uint32_t j = 0; j < GetNInterfaces (); j++) + { + for (uint32_t i = 0; i < GetNAddresses (j); i++) + { + Ipv6InterfaceAddress iaddr = GetAddress (j, i); + Ipv6Address addr = iaddr.GetAddress (); + if (addr.IsEqual (hdr.GetDestinationAddress ())) + { + if (j == interface) + { + NS_LOG_LOGIC ("For me (destination " << addr << " match)"); + } + else + { + NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << hdr.GetDestinationAddress ()); + } + LocalDeliver (packet, hdr, interface); + return; + } + NS_LOG_LOGIC ("Address " << addr << " not a match"); + } + } + if (!m_routingProtocol->RouteInput (packet, hdr, device, MakeCallback (&Ipv6L3Protocol::IpForward, this), MakeCallback (&Ipv6L3Protocol::IpMulticastForward, this), @@ -1008,8 +1046,7 @@ void Ipv6L3Protocol::Receive (Ptr device, Ptr p, uint16 MakeCallback (&Ipv6L3Protocol::RouteInputError, this))) { NS_LOG_WARN ("No route found for forwarding packet. Drop."); - GetIcmpv6 ()->SendErrorDestinationUnreachable (p->Copy (), hdr.GetSourceAddress (), Icmpv6Header::ICMPV6_NO_ROUTE); - m_dropTrace (hdr, packet, DROP_NO_ROUTE, m_node->GetObject (), interface); + // Drop trace and ICMPs are courtesy of RouteInputError } } @@ -1368,7 +1405,15 @@ void Ipv6L3Protocol::RouteInputError (Ptr p, const Ipv6Header& ipH { NS_LOG_FUNCTION (this << p << ipHeader << sockErrno); NS_LOG_LOGIC ("Route input failure-- dropping packet to " << ipHeader << " with errno " << sockErrno); + m_dropTrace (ipHeader, p, DROP_ROUTE_ERROR, m_node->GetObject (), 0); + + if (!ipHeader.GetDestinationAddress ().IsMulticast ()) + { + Ptr packet = p->Copy (); + packet->AddHeader (ipHeader); + GetIcmpv6 ()->SendErrorDestinationUnreachable (packet, ipHeader.GetSourceAddress (), Icmpv6Header::ICMPV6_NO_ROUTE); + } } Ipv6Header Ipv6L3Protocol::BuildHeader (Ipv6Address src, Ipv6Address dst, uint8_t protocol, uint16_t payloadSize, uint8_t ttl, uint8_t tclass) diff --git a/src/internet/model/ipv6-list-routing.cc b/src/internet/model/ipv6-list-routing.cc index aefccaf61..51d5b2bd1 100644 --- a/src/internet/model/ipv6-list-routing.cc +++ b/src/internet/model/ipv6-list-routing.cc @@ -101,101 +101,39 @@ Ipv6ListRouting::RouteInput (Ptr p, const Ipv6Header &header, Ptr< UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb) { - bool retVal = false; NS_LOG_FUNCTION (p << header << idev); NS_LOG_LOGIC ("RouteInput logic for node: " << m_ipv6->GetObject ()->GetId ()); NS_ASSERT (m_ipv6 != 0); // Check if input device supports IP NS_ASSERT (m_ipv6->GetInterfaceForDevice (idev) >= 0); - uint32_t iif = m_ipv6->GetInterfaceForDevice (idev); Ipv6Address dst = header.GetDestinationAddress (); - // Multicast recognition; handle local delivery here - // - if (dst.IsMulticast ()) - { -#ifdef NOTYET - if (m_ipv6->MulticastCheckGroup (iif, dst)) -#endif - if (true) - { - NS_LOG_LOGIC ("Multicast packet for me-- local deliver"); - Ptr packetCopy = p->Copy (); - // Here may want to disable lcb callback in recursive RouteInput - // call below - lcb (packetCopy, header, iif); - // Fall through-- we may also need to forward this - retVal = true; - } - - /* do not forward link-local multicast address */ - if (dst.IsLinkLocalMulticast ()) - { - return retVal; - } - - for (Ipv6RoutingProtocolList::const_iterator rprotoIter = - m_routingProtocols.begin (); rprotoIter != m_routingProtocols.end (); - rprotoIter++) - { - NS_LOG_LOGIC ("Multicast packet for me-- trying to forward"); - if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, lcb, ecb)) - { - retVal = true; - } - } - return retVal; - } - - /// \todo Configurable option to enable \RFC{1222} Strong End System Model - // Right now, we will be permissive and allow a source to send us - // a packet to one of our other interface addresses; that is, the - // destination unicast address does not match one of the iif addresses, - // but we check our other interfaces. This could be an option - // (to remove the outer loop immediately below and just check iif). - for (uint32_t j = 0; j < m_ipv6->GetNInterfaces (); j++) - { - for (uint32_t i = 0; i < m_ipv6->GetNAddresses (j); i++) - { - Ipv6InterfaceAddress iaddr = m_ipv6->GetAddress (j, i); - Ipv6Address addr = iaddr.GetAddress (); - if (addr.IsEqual (header.GetDestinationAddress ())) - { - if (j == iif) - { - NS_LOG_LOGIC ("For me (destination " << addr << " match)"); - } - else - { - NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << header.GetDestinationAddress ()); - } - lcb (p, header, iif); - return true; - } - NS_LOG_LOGIC ("Address " << addr << " not a match"); - } - } // Check if input device supports IP forwarding + uint32_t iif = m_ipv6->GetInterfaceForDevice (idev); if (m_ipv6->IsForwarding (iif) == false) { NS_LOG_LOGIC ("Forwarding disabled for this interface"); ecb (p, header, Socket::ERROR_NOROUTETOHOST); return false; } - // Next, try to find a route - for (Ipv6RoutingProtocolList::const_iterator rprotoIter = - m_routingProtocols.begin (); + + // We disable error callback for the called protocols. + ErrorCallback nullEcb = MakeNullCallback, const Ipv6Header &, Socket::SocketErrno > (); + + for (Ipv6RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin (); rprotoIter != m_routingProtocols.end (); rprotoIter++) { - if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, lcb, ecb)) + if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, lcb, nullEcb)) { return true; } } + // No routing protocol has found a route. - return retVal; + ecb (p, header, Socket::ERROR_NOROUTETOHOST); + return false; } void diff --git a/src/internet/model/ipv6-static-routing.cc b/src/internet/model/ipv6-static-routing.cc index ba7261753..ef329e115 100644 --- a/src/internet/model/ipv6-static-routing.cc +++ b/src/internet/model/ipv6-static-routing.cc @@ -590,12 +590,14 @@ bool Ipv6StaticRouting::RouteInput (Ptr p, const Ipv6Header &heade uint32_t iif = m_ipv6->GetInterfaceForDevice (idev); Ipv6Address dst = header.GetDestinationAddress (); + // Multicast recognition; handle local delivery here if (dst.IsMulticast ()) { NS_LOG_LOGIC ("Multicast destination"); Ptr mrtentry = LookupStatic (header.GetSourceAddress (), header.GetDestinationAddress (), m_ipv6->GetInterfaceForDevice (idev)); + // \todo check if we want to forward up the packet if (mrtentry) { NS_LOG_LOGIC ("Multicast route found"); @@ -609,39 +611,14 @@ bool Ipv6StaticRouting::RouteInput (Ptr p, const Ipv6Header &heade } } - /// \todo Configurable option to enable \RFC{1222} Strong End System Model - // Right now, we will be permissive and allow a source to send us - // a packet to one of our other interface addresses; that is, the - // destination unicast address does not match one of the iif addresses, - // but we check our other interfaces. This could be an option - // (to remove the outer loop immediately below and just check iif). - for (uint32_t j = 0; j < m_ipv6->GetNInterfaces (); j++) - { - for (uint32_t i = 0; i < m_ipv6->GetNAddresses (j); i++) - { - Ipv6InterfaceAddress iaddr = m_ipv6->GetAddress (j, i); - Ipv6Address addr = iaddr.GetAddress (); - if (addr.IsEqual (header.GetDestinationAddress ())) - { - if (j == iif) - { - NS_LOG_LOGIC ("For me (destination " << addr << " match)"); - } - else - { - NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << header.GetDestinationAddress ()); - } - lcb (p, header, iif); - return true; - } - NS_LOG_LOGIC ("Address " << addr << " not a match"); - } - } // Check if input device supports IP forwarding if (m_ipv6->IsForwarding (iif) == false) { NS_LOG_LOGIC ("Forwarding disabled for this interface"); - ecb (p, header, Socket::ERROR_NOROUTETOHOST); + if (!ecb.IsNull ()) + { + ecb (p, header, Socket::ERROR_NOROUTETOHOST); + } return false; } // Next, try to find a route diff --git a/src/internet/model/ripng.cc b/src/internet/model/ripng.cc index 915cc80f5..07a5367d3 100644 --- a/src/internet/model/ripng.cc +++ b/src/internet/model/ripng.cc @@ -219,35 +219,6 @@ bool RipNg::RouteInput (Ptr p, const Ipv6Header &header, PtrGetNInterfaces (); j++) - { - for (uint32_t i = 0; i < m_ipv6->GetNAddresses (j); i++) - { - Ipv6InterfaceAddress iaddr = m_ipv6->GetAddress (j, i); - Ipv6Address addr = iaddr.GetAddress (); - if (addr.IsEqual (header.GetDestinationAddress ())) - { - if (j == iif) - { - NS_LOG_LOGIC ("For me (destination " << addr << " match)"); - } - else - { - NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << header.GetDestinationAddress ()); - } - lcb (p, header, iif); - return true; - } - NS_LOG_LOGIC ("Address " << addr << " not a match"); - } - } - if (header.GetDestinationAddress ().IsLinkLocal () || header.GetSourceAddress ().IsLinkLocal ()) { @@ -260,7 +231,10 @@ bool RipNg::RouteInput (Ptr p, const Ipv6Header &header, PtrIsForwarding (iif) == false) { NS_LOG_LOGIC ("Forwarding disabled for this interface"); - ecb (p, header, Socket::ERROR_NOROUTETOHOST); + if (!ecb.IsNull ()) + { + ecb (p, header, Socket::ERROR_NOROUTETOHOST); + } return false; } // Next, try to find a route diff --git a/src/internet/test/ipv6-ripng-test.cc b/src/internet/test/ipv6-ripng-test.cc index 9a21d88e8..129f01dab 100644 --- a/src/internet/test/ipv6-ripng-test.cc +++ b/src/internet/test/ipv6-ripng-test.cc @@ -38,9 +38,6 @@ #include "ns3/ipv6-l3-protocol.h" #include "ns3/icmpv6-l4-protocol.h" #include "ns3/udp-l4-protocol.h" -#include "ns3/ipv6-static-routing.h" -#include "ns3/ipv6-list-routing.h" -#include "ns3/ipv6-list-routing-helper.h" #include "ns3/ripng.h" #include "ns3/ripng-helper.h" #include "ns3/node-container.h" @@ -115,10 +112,8 @@ Ipv6RipngTest::DoRun (void) NodeContainer all (nodes, routers); RipNgHelper ripNgRouting; - Ipv6ListRoutingHelper listRH; - listRH.Add (ripNgRouting, 0); InternetStackHelper internetv6routers; - internetv6routers.SetRoutingHelper (listRH); + internetv6routers.SetRoutingHelper (ripNgRouting); internetv6routers.Install (routers); InternetStackHelper internetv6nodes; @@ -326,10 +321,8 @@ Ipv6RipngCountToInfinityTest::DoRun (void) ripNgRouting.SetInterfaceMetric (routerB, 2, 10); ripNgRouting.SetInterfaceMetric (routerC, 1, 10); - Ipv6ListRoutingHelper listRH; - listRH.Add (ripNgRouting, 0); InternetStackHelper internetv6routers; - internetv6routers.SetRoutingHelper (listRH); + internetv6routers.SetRoutingHelper (ripNgRouting); internetv6routers.Install (routers); InternetStackHelper internetv6nodes; @@ -543,10 +536,8 @@ Ipv6RipngSplitHorizonStrategyTest::DoRun (void) RipNgHelper ripNgRouting; ripNgRouting.Set ("SplitHorizon", EnumValue (m_setStrategy)); - Ipv6ListRoutingHelper listRH; - listRH.Add (ripNgRouting, 0); InternetStackHelper internetv6routers; - internetv6routers.SetRoutingHelper (listRH); + internetv6routers.SetRoutingHelper (ripNgRouting); internetv6routers.Install (routers); InternetStackHelper internetv6nodes;