From c0ff56a6e0df5a045bae8fc79c2d37c5f40496ec Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Thu, 1 Oct 2009 21:51:03 -0700 Subject: [PATCH] allow static and global routing to deliver local packets (bug 651) --- doc/manual/routing.texi | 5 ++ .../global-routing/ipv4-global-routing.cc | 66 ++++++++++++++++--- .../static-routing/ipv4-static-routing.cc | 61 +++++++++++++++-- .../static-routing/ipv4-static-routing.h | 5 +- .../static-routing/ipv6-static-routing.cc | 61 +++++++++++++---- 5 files changed, 171 insertions(+), 27 deletions(-) diff --git a/doc/manual/routing.texi b/doc/manual/routing.texi index 45d885f6e..323a81e24 100644 --- a/doc/manual/routing.texi +++ b/doc/manual/routing.texi @@ -280,6 +280,11 @@ Once instantiated, the agent can be started with the Start() command, and the OLSR "main interface" can be set with the SetMainInterface() command. A number of protocol constants are defined in olsr-agent-impl.cc. +Presently, OLSR is limited to use with an Ipv4ListRouting object, and +does not respond to dynamic changes to a device's IP address or link up/down +notifications; i.e. the topology changes are due to loss/gain of connectivity +over a wireless channel. + @node Multicast routing @section Multicast routing diff --git a/src/routing/global-routing/ipv4-global-routing.cc b/src/routing/global-routing/ipv4-global-routing.cc index de562453d..bc1ee7ac4 100644 --- a/src/routing/global-routing/ipv4-global-routing.cc +++ b/src/routing/global-routing/ipv4-global-routing.cc @@ -361,26 +361,76 @@ Ipv4GlobalRouting::RouteOutput (Ptr p, const Ipv4Header &header, uint32_ } bool -Ipv4GlobalRouting::RouteInput (Ptr p, const Ipv4Header &ipHeader, Ptr idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb, +Ipv4GlobalRouting::RouteInput (Ptr p, const Ipv4Header &header, Ptr idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb) { - NS_LOG_FUNCTION (this << p << ipHeader << ipHeader.GetSource () << ipHeader.GetDestination () << idev); + NS_LOG_FUNCTION (this << p << header << header.GetSource () << header.GetDestination () << idev); + // Check if input device supports IP + NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0); + uint32_t iif = m_ipv4->GetInterfaceForDevice (idev); - if (ipHeader.GetDestination ().IsMulticast ()) + if (header.GetDestination ().IsMulticast ()) { NS_LOG_LOGIC ("Multicast destination-- returning false"); return false; // Let other routing protocols try to handle this } -// This is a unicast packet. Check to see if we have a route for it. -// - NS_LOG_LOGIC ("Unicast destination- looking up"); - Ptr rtentry = LookupGlobal (ipHeader.GetDestination ()); + if (header.GetDestination ().IsBroadcast ()) + { + NS_LOG_LOGIC ("For me (Ipv4Addr broadcast address)"); + // TODO: Local Deliver for broadcast + // TODO: Forward broadcast + } + + // 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_ipv4->GetNInterfaces (); j++) + { + for (uint32_t i = 0; i < m_ipv4->GetNAddresses (j); i++) + { + Ipv4InterfaceAddress iaddr = m_ipv4->GetAddress (j, i); + Ipv4Address addr = iaddr.GetLocal (); + if (addr.IsEqual (header.GetDestination ())) + { + if (j == iif) + { + NS_LOG_LOGIC ("For me (destination " << addr << " match)"); + } + else + { + NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << header.GetDestination ()); + } + lcb (p, header, iif); + return true; + } + if (header.GetDestination ().IsEqual (iaddr.GetBroadcast ())) + { + NS_LOG_LOGIC ("For me (interface broadcast address)"); + lcb (p, header, iif); + return true; + } + NS_LOG_LOGIC ("Address "<< addr << " not a match"); + } + } + // Check if input device supports IP forwarding + if (m_ipv4->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 + NS_LOG_LOGIC ("Unicast destination- looking up global route"); + Ptr rtentry = LookupGlobal (header.GetDestination ()); if (rtentry != 0) { NS_LOG_LOGIC ("Found unicast destination- calling unicast callback"); - ucb (rtentry, p, ipHeader); + ucb (rtentry, p, header); return true; } else diff --git a/src/routing/static-routing/ipv4-static-routing.cc b/src/routing/static-routing/ipv4-static-routing.cc index ddecb66fd..023c52a07 100644 --- a/src/routing/static-routing/ipv4-static-routing.cc +++ b/src/routing/static-routing/ipv4-static-routing.cc @@ -444,8 +444,6 @@ Ipv4StaticRouting::RouteOutput (Ptr p, const Ipv4Header &header, uint32_ return rtentry; } -// XXX this method not robust enough to work outside of ListRouting context -// because it will not perform local delivery bool Ipv4StaticRouting::RouteInput (Ptr p, const Ipv4Header &ipHeader, Ptr idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb, @@ -453,6 +451,13 @@ Ipv4StaticRouting::RouteInput (Ptr p, const Ipv4Header &ipHeader, { NS_LOG_FUNCTION (this << p << ipHeader << ipHeader.GetSource () << ipHeader.GetDestination () << idev); + NS_ASSERT (m_ipv4 != 0); + // Check if input device supports IP + NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0); + uint32_t iif = m_ipv4->GetInterfaceForDevice (idev); + + // Multicast recognition; handle local delivery here + // if (ipHeader.GetDestination ().IsMulticast ()) { NS_LOG_LOGIC ("Multicast destination"); @@ -471,10 +476,56 @@ Ipv4StaticRouting::RouteInput (Ptr p, const Ipv4Header &ipHeader, return false; // Let other routing protocols try to handle this } } -// -// This is a unicast packet. Check to see if we have a route for it. -// + if (ipHeader.GetDestination ().IsBroadcast ()) + { + NS_LOG_LOGIC ("For me (Ipv4Addr broadcast address)"); + // TODO: Local Deliver for broadcast + // TODO: Forward broadcast + } + NS_LOG_LOGIC ("Unicast destination"); + // 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_ipv4->GetNInterfaces (); j++) + { + for (uint32_t i = 0; i < m_ipv4->GetNAddresses (j); i++) + { + Ipv4InterfaceAddress iaddr = m_ipv4->GetAddress (j, i); + Ipv4Address addr = iaddr.GetLocal (); + if (addr.IsEqual (ipHeader.GetDestination ())) + { + if (j == iif) + { + NS_LOG_LOGIC ("For me (destination " << addr << " match)"); + } + else + { + NS_LOG_LOGIC ("For me (destination " << addr << " match) on another interface " << ipHeader.GetDestination ()); + } + lcb (p, ipHeader, iif); + return true; + } + if (ipHeader.GetDestination ().IsEqual (iaddr.GetBroadcast ())) + { + NS_LOG_LOGIC ("For me (interface broadcast address)"); + lcb (p, ipHeader, iif); + return true; + } + NS_LOG_LOGIC ("Address "<< addr << " not a match"); + } + } + // Check if input device supports IP forwarding + if (m_ipv4->IsForwarding (iif) == false) + { + NS_LOG_LOGIC ("Forwarding disabled for this interface"); + ecb (p, ipHeader, Socket::ERROR_NOROUTETOHOST); + return false; + } + // Next, try to find a route Ptr rtentry = LookupStatic (ipHeader.GetDestination ()); if (rtentry != 0) { diff --git a/src/routing/static-routing/ipv4-static-routing.h b/src/routing/static-routing/ipv4-static-routing.h index 5d956ca4f..6547ede7e 100644 --- a/src/routing/static-routing/ipv4-static-routing.h +++ b/src/routing/static-routing/ipv4-static-routing.h @@ -55,9 +55,8 @@ class Node; * This class provides a basic set of methods for inserting static * unicast and multicast routes into the Ipv4 routing system. * This particular protocol is designed to be inserted into an - * Ipv4ListRouting protocol and at present cannot be inserted as the - * only routing protocol into Ipv4 (i.e. it must be added to an - * Ipv4ListRouting). + * Ipv4ListRouting protocol but can be used also as a standalone + * protocol. * * The Ipv4StaticRouting class inherits from the abstract base class * Ipv4RoutingProtocol that defines the interface methods that a routing diff --git a/src/routing/static-routing/ipv6-static-routing.cc b/src/routing/static-routing/ipv6-static-routing.cc index d2f439f44..e3d3f5938 100644 --- a/src/routing/static-routing/ipv6-static-routing.cc +++ b/src/routing/static-routing/ipv6-static-routing.cc @@ -514,23 +514,28 @@ Ptr Ipv6StaticRouting::RouteOutput (Ptr p, const Ipv6Header & return rtentry; } -bool Ipv6StaticRouting::RouteInput (Ptr p, const Ipv6Header &ipHeader, Ptr idev, +bool Ipv6StaticRouting::RouteInput (Ptr p, const Ipv6Header &header, Ptr idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb) { - NS_LOG_FUNCTION (this << p << ipHeader << ipHeader.GetSourceAddress () << ipHeader.GetDestinationAddress () << idev); + NS_LOG_FUNCTION (this << p << header << header.GetSourceAddress () << header.GetDestinationAddress () << idev); + 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 (); - if (ipHeader.GetDestinationAddress ().IsMulticast ()) + if (dst.IsMulticast ()) { NS_LOG_LOGIC ("Multicast destination"); - Ptr mrtentry = LookupStatic (ipHeader.GetSourceAddress (), - ipHeader.GetDestinationAddress () + Ptr mrtentry = LookupStatic (header.GetSourceAddress (), + header.GetDestinationAddress () , m_ipv6->GetInterfaceForDevice (idev)); if (mrtentry) { NS_LOG_LOGIC ("Multicast route found"); - mcb (mrtentry, p, ipHeader); // multicast forwarding callback + mcb (mrtentry, p, header); // multicast forwarding callback return true; } else @@ -539,16 +544,50 @@ bool Ipv6StaticRouting::RouteInput (Ptr p, const Ipv6Header &ipHea return false; // Let other routing protocols try to handle this } } - // - // This is a unicast packet. Check to see if we have a route for it. - // + + // 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); + return false; + } + // Next, try to find a route NS_LOG_LOGIC ("Unicast destination"); - Ptr rtentry = LookupStatic (ipHeader.GetDestinationAddress ()); + Ptr rtentry = LookupStatic (header.GetDestinationAddress ()); if (rtentry != 0) { NS_LOG_LOGIC ("Found unicast destination- calling unicast callback"); - ucb (rtentry, p, ipHeader); // unicast forwarding callback + ucb (rtentry, p, header); // unicast forwarding callback return true; } else