Bug 2238 - Ipv6 routing reorganization

This commit is contained in:
Tommaso Pecorella
2015-12-02 23:33:58 +01:00
parent 71088849cc
commit 8a65a4b9bd
8 changed files with 77 additions and 149 deletions

View File

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

View File

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

View File

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

View File

@@ -1001,6 +1001,44 @@ void Ipv6L3Protocol::Receive (Ptr<NetDevice> device, Ptr<const Packet> 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<NetDevice> device, Ptr<const Packet> 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<Ipv6> (), interface);
// Drop trace and ICMPs are courtesy of RouteInputError
}
}
@@ -1368,7 +1405,15 @@ void Ipv6L3Protocol::RouteInputError (Ptr<const Packet> 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<Ipv6> (), 0);
if (!ipHeader.GetDestinationAddress ().IsMulticast ())
{
Ptr<Packet> 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)

View File

@@ -101,101 +101,39 @@ Ipv6ListRouting::RouteInput (Ptr<const Packet> 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<Node> ()->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<Packet> 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<void, Ptr<const Packet>, 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

View File

@@ -590,12 +590,14 @@ bool Ipv6StaticRouting::RouteInput (Ptr<const Packet> 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<Ipv6MulticastRoute> 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<const Packet> 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

View File

@@ -219,35 +219,6 @@ bool RipNg::RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const
return false; // Let other routing protocols try to handle this
}
/// \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");
}
}
if (header.GetDestinationAddress ().IsLinkLocal () ||
header.GetSourceAddress ().IsLinkLocal ())
{
@@ -260,7 +231,10 @@ bool RipNg::RouteInput (Ptr<const Packet> p, const Ipv6Header &header, Ptr<const
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

View File

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