allow static and global routing to deliver local packets (bug 651)

This commit is contained in:
Tom Henderson
2009-10-01 21:51:03 -07:00
parent e03eac3282
commit c0ff56a6e0
5 changed files with 171 additions and 27 deletions

View File

@@ -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

View File

@@ -361,26 +361,76 @@ Ipv4GlobalRouting::RouteOutput (Ptr<Packet> p, const Ipv4Header &header, uint32_
}
bool
Ipv4GlobalRouting::RouteInput (Ptr<const Packet> p, const Ipv4Header &ipHeader, Ptr<const NetDevice> idev, UnicastForwardCallback ucb, MulticastForwardCallback mcb,
Ipv4GlobalRouting::RouteInput (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> 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<Ipv4Route> 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<Ipv4Route> 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

View File

@@ -444,8 +444,6 @@ Ipv4StaticRouting::RouteOutput (Ptr<Packet> 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<const Packet> p, const Ipv4Header &ipHeader, Ptr<const NetDevice> idev,
UnicastForwardCallback ucb, MulticastForwardCallback mcb,
@@ -453,6 +451,13 @@ Ipv4StaticRouting::RouteInput (Ptr<const Packet> 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<const Packet> 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<Ipv4Route> rtentry = LookupStatic (ipHeader.GetDestination ());
if (rtentry != 0)
{

View File

@@ -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

View File

@@ -514,23 +514,28 @@ Ptr<Ipv6Route> Ipv6StaticRouting::RouteOutput (Ptr<Packet> p, const Ipv6Header &
return rtentry;
}
bool Ipv6StaticRouting::RouteInput (Ptr<const Packet> p, const Ipv6Header &ipHeader, Ptr<const NetDevice> idev,
bool Ipv6StaticRouting::RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const NetDevice> 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<Ipv6MulticastRoute> mrtentry = LookupStatic (ipHeader.GetSourceAddress (),
ipHeader.GetDestinationAddress ()
Ptr<Ipv6MulticastRoute> 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<const Packet> 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<Ipv6Route> rtentry = LookupStatic (ipHeader.GetDestinationAddress ());
Ptr<Ipv6Route> 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