Bug 2238 - Ipv6 routing reorganization
This commit is contained in:
@@ -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
|
||||
------------
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 ()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user