Add metric and longest prefix match support for IPv6.
This commit is contained in:
@@ -52,7 +52,7 @@ us a note on ns-developers mailing list. </p>
|
||||
|
||||
<h2>New API:</h2>
|
||||
<ul>
|
||||
<li><b>Longest prefix match, support for metrics, for Ipv4StaticRouting</b>
|
||||
<li><b>Longest prefix match, support for metrics, for Ipv4StaticRouting and Ipv6StaticRouting</b>
|
||||
<p>When performing route lookup, first match for longest prefix, and then
|
||||
based on metrics (default metric = 0). If metrics are equal, most recent
|
||||
addition is picked. Extends API for support of metrics but preserves
|
||||
|
||||
@@ -77,7 +77,7 @@ class StackHelper
|
||||
routing = routingHelper.GetStaticRouting (ipv6);
|
||||
|
||||
std::cout << "Routing table of " << n << " : " << std::endl;
|
||||
std::cout << "Destination\t\t\t\t" << "Gateway\t\t\t\t\t" << "Interface\t" << std::endl;
|
||||
std::cout << "Destination\t\t\t\t" << "Gateway\t\t\t\t\t" << "Interface\t" << "Prefix to use" << std::endl;
|
||||
|
||||
nbRoutes = routing->GetNRoutes ();
|
||||
for (uint32_t i = 0 ; i < nbRoutes ; i++)
|
||||
@@ -85,7 +85,9 @@ class StackHelper
|
||||
route = routing->GetRoute (i);
|
||||
std::cout << route.GetDest () << "\t"
|
||||
<< route.GetGateway () << "\t"
|
||||
<< route.GetInterface () << "\t" << std::endl;
|
||||
<< route.GetInterface () << "\t"
|
||||
<< route.GetPrefixToUse () << "\t"
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -33,12 +33,59 @@
|
||||
#include "ns3/simulator-module.h"
|
||||
#include "ns3/helper-module.h"
|
||||
|
||||
#include "ns3/ipv6-routing-table-entry.h"
|
||||
|
||||
using namespace ns3;
|
||||
|
||||
NS_LOG_COMPONENT_DEFINE ("SimpleRoutingPing6Example");
|
||||
|
||||
int
|
||||
main (int argc, char** argv)
|
||||
class StackHelper
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Add an address to a IPv6 node.
|
||||
* \param n node
|
||||
* \param interface interface index
|
||||
* \param address IPv6 address to add
|
||||
*/
|
||||
inline void AddAddress (Ptr<Node>& n, uint32_t interface, Ipv6Address address)
|
||||
{
|
||||
Ptr<Ipv6> ipv6 = n->GetObject<Ipv6> ();
|
||||
ipv6->AddAddress (interface, address);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Print the routing table.
|
||||
* \param n the node
|
||||
*/
|
||||
inline void PrintRoutingTable (Ptr<Node>& n)
|
||||
{
|
||||
Ptr<Ipv6StaticRouting> routing = 0;
|
||||
Ipv6StaticRoutingHelper routingHelper;
|
||||
Ptr<Ipv6> ipv6 = n->GetObject<Ipv6> ();
|
||||
uint32_t nbRoutes = 0;
|
||||
Ipv6RoutingTableEntry route;
|
||||
|
||||
routing = routingHelper.GetStaticRouting (ipv6);
|
||||
|
||||
std::cout << "Routing table of " << n << " : " << std::endl;
|
||||
std::cout << "Destination\t\t\t\t" << "Gateway\t\t\t\t\t" << "Interface\t" << "Prefix to use" << std::endl;
|
||||
|
||||
nbRoutes = routing->GetNRoutes ();
|
||||
for (uint32_t i = 0 ; i < nbRoutes ; i++)
|
||||
{
|
||||
route = routing->GetRoute (i);
|
||||
std::cout << route.GetDest () << "\t"
|
||||
<< route.GetGateway () << "\t"
|
||||
<< route.GetInterface () << "\t"
|
||||
<< route.GetPrefixToUse () << "\t"
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
#if 0
|
||||
LogComponentEnable ("Ipv6L3Protocol", LOG_LEVEL_ALL);
|
||||
@@ -50,6 +97,8 @@ main (int argc, char** argv)
|
||||
|
||||
CommandLine cmd;
|
||||
cmd.Parse (argc, argv);
|
||||
|
||||
StackHelper stackHelper;
|
||||
|
||||
NS_LOG_INFO ("Create nodes.");
|
||||
Ptr<Node> n0 = CreateObject<Node> ();
|
||||
@@ -80,6 +129,8 @@ main (int argc, char** argv)
|
||||
Ipv6InterfaceContainer i2 = ipv6.Assign (d2);
|
||||
i2.SetRouter (0, true);
|
||||
|
||||
stackHelper.PrintRoutingTable(n0);
|
||||
|
||||
/* Create a Ping6 application to send ICMPv6 echo request from n0 to n1 via r */
|
||||
uint32_t packetSize = 1024;
|
||||
uint32_t maxPacketCount = 5;
|
||||
@@ -88,7 +139,6 @@ main (int argc, char** argv)
|
||||
|
||||
ping6.SetLocal (i1.GetAddress (0, 1));
|
||||
ping6.SetRemote (i2.GetAddress (1, 1));
|
||||
/* ping6.SetRemote (Ipv6Address::GetAllNodesMulticast ()); */
|
||||
|
||||
ping6.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount));
|
||||
ping6.SetAttribute ("Interval", TimeValue (interPacketInterval));
|
||||
|
||||
@@ -1086,6 +1086,19 @@ Ptr<NdiscCache> Icmpv6L4Protocol::CreateCache (Ptr<NetDevice> device, Ptr<Ipv6In
|
||||
return cache;
|
||||
}
|
||||
|
||||
bool Icmpv6L4Protocol::Lookup (Ipv6Address dst, Ptr<NetDevice> device, Ptr<NdiscCache> cache, Address* hardwareDestination)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << dst << device << hardwareDestination);
|
||||
|
||||
if (!cache)
|
||||
{
|
||||
/* try to find the cache */
|
||||
cache = FindCache (device);
|
||||
}
|
||||
|
||||
return cache->Lookup (dst);
|
||||
}
|
||||
|
||||
bool Icmpv6L4Protocol::Lookup (Ptr<Packet> p, Ipv6Address dst, Ptr<NetDevice> device, Ptr<NdiscCache> cache, Address* hardwareDestination)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << p << dst << device << hardwareDestination);
|
||||
|
||||
@@ -226,7 +226,6 @@ class Icmpv6L4Protocol : public Ipv6L4Protocol
|
||||
* \param id id of the packet
|
||||
* \param seq sequence number
|
||||
* \param data auxiliary data
|
||||
* \todo Change data to be a char[], change it too in icmpv6-header.
|
||||
*/
|
||||
void SendEchoReply (Ipv6Address src, Ipv6Address dst, uint16_t id, uint16_t seq, Ptr<Packet> data);
|
||||
|
||||
@@ -349,8 +348,20 @@ class Icmpv6L4Protocol : public Ipv6L4Protocol
|
||||
*/
|
||||
static void FunctionDadTimeout (Ptr<Icmpv6L4Protocol> icmpv6, Ipv6Interface* interface, Ipv6Address addr);
|
||||
|
||||
/**
|
||||
* \brief Lookup in the ND cache for the IPv6 address
|
||||
* \param dst destination address
|
||||
* \param device device
|
||||
* \param cache the neighbor cache
|
||||
* \param hardwareDestination hardware address
|
||||
* \note Unlike other Lookup method, it does not send NS request!
|
||||
*/
|
||||
bool Lookup (Ipv6Address dst, Ptr<NetDevice> device, Ptr<NdiscCache> cache, Address* hardwareDestination);
|
||||
|
||||
/**
|
||||
* \brief Lookup in the ND cache for the IPv6 address (similar as ARP protocol).
|
||||
*
|
||||
* It also send NS request to target and store the waiting packet.
|
||||
* \param p the packet
|
||||
* \param dst destination address
|
||||
* \param device device
|
||||
|
||||
@@ -269,12 +269,6 @@ void Ipv6L3Protocol::AddAutoconfiguredAddress (uint32_t interface, Ipv6Address n
|
||||
(*it)->StopPreferredTimer ();
|
||||
(*it)->StopValidTimer ();
|
||||
(*it)->StartPreferredTimer ();
|
||||
|
||||
/* Suppose a link with two prefixes advertised,
|
||||
* when first prefix (which is the default route) expires,
|
||||
* the second ones router has to be default router
|
||||
*/
|
||||
GetRoutingProtocol ()->NotifyAddRoute (Ipv6Address::GetAny (), Ipv6Prefix ((uint8_t)0), defaultRouter, interface, network);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -284,10 +278,7 @@ void Ipv6L3Protocol::AddAutoconfiguredAddress (uint32_t interface, Ipv6Address n
|
||||
AddAddress (interface, address);
|
||||
|
||||
/* add default router
|
||||
* check to know if default route already exists is done
|
||||
* in Ipv6StaticRouting class
|
||||
*
|
||||
* If default route is already set, this function does nothing.
|
||||
* if a previous default route exists, the new ones is simply added
|
||||
*/
|
||||
GetRoutingProtocol ()->NotifyAddRoute (Ipv6Address::GetAny (), Ipv6Prefix ((uint8_t)0), defaultRouter, interface, network);
|
||||
|
||||
@@ -327,7 +318,7 @@ void Ipv6L3Protocol::RemoveAutoconfiguredAddress (uint32_t interface, Ipv6Addres
|
||||
}
|
||||
}
|
||||
|
||||
GetRoutingProtocol ()->NotifyRemoveRoute (Ipv6Address::GetAny (), Ipv6Prefix ((uint8_t)0), defaultRouter, interface);
|
||||
GetRoutingProtocol ()->NotifyRemoveRoute (Ipv6Address::GetAny (), Ipv6Prefix ((uint8_t)0), defaultRouter, interface, network);
|
||||
}
|
||||
|
||||
bool Ipv6L3Protocol::AddAddress (uint32_t i, Ipv6InterfaceAddress address)
|
||||
@@ -811,7 +802,7 @@ void Ipv6L3Protocol::IpForward (Ptr<Ipv6Route> rtentry, Ptr<const Packet> p, con
|
||||
|
||||
copy->AddHeader (header);
|
||||
|
||||
if (icmpv6->Lookup (copy, target, rtentry->GetOutputDevice (), 0, &hardwareTarget))
|
||||
if (icmpv6->Lookup (target, rtentry->GetOutputDevice (), 0, &hardwareTarget))
|
||||
{
|
||||
icmpv6->SendRedirection (copy, src, target, dst, hardwareTarget);
|
||||
}
|
||||
@@ -820,7 +811,7 @@ void Ipv6L3Protocol::IpForward (Ptr<Ipv6Route> rtentry, Ptr<const Packet> p, con
|
||||
icmpv6->SendRedirection (copy, src, target, dst, Address ());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SendRealOut (rtentry, packet, ipHeader);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* \ingroup address
|
||||
* \class Inet6SocketAddress
|
||||
* \brief An Inet6 address class.
|
||||
*/
|
||||
|
||||
@@ -483,6 +483,12 @@ Ipv6Address Ipv6Address::GetLoopback ()
|
||||
return loopback;
|
||||
}
|
||||
|
||||
Ipv6Address Ipv6Address::GetOnes ()
|
||||
{
|
||||
static Ipv6Address ones ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
|
||||
return ones;
|
||||
}
|
||||
|
||||
void Ipv6Address::GetBytes (uint8_t buf[16]) const
|
||||
{
|
||||
memcpy (buf, m_address, 16);
|
||||
@@ -491,7 +497,7 @@ void Ipv6Address::GetBytes (uint8_t buf[16]) const
|
||||
bool Ipv6Address::IsLinkLocal () const
|
||||
{
|
||||
Ipv6Address linkLocal ("fe80::0");
|
||||
if (!IsMulticast () && ((Ipv6Address*)this)->CombinePrefix (Ipv6Prefix (64))==linkLocal)
|
||||
if (!IsMulticast () && ((Ipv6Address*)this)->CombinePrefix (Ipv6Prefix (64)) == linkLocal)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -627,6 +633,12 @@ Ipv6Prefix Ipv6Prefix::GetLoopback ()
|
||||
return prefix;
|
||||
}
|
||||
|
||||
Ipv6Prefix Ipv6Prefix::GetOnes ()
|
||||
{
|
||||
static Ipv6Prefix ones ((uint8_t)128);
|
||||
return ones;
|
||||
}
|
||||
|
||||
Ipv6Prefix Ipv6Prefix::GetZero ()
|
||||
{
|
||||
Ipv6Prefix prefix ((uint8_t)0);
|
||||
@@ -638,6 +650,25 @@ void Ipv6Prefix::GetBytes (uint8_t buf[16]) const
|
||||
memcpy (buf, m_prefix, 16);
|
||||
}
|
||||
|
||||
uint8_t Ipv6Prefix::GetPrefixLength () const
|
||||
{
|
||||
uint8_t i = 0;
|
||||
uint8_t prefixLength = 0;
|
||||
|
||||
for(i = 0 ; i < 16 ; i++)
|
||||
{
|
||||
uint8_t mask = m_prefix[i];
|
||||
|
||||
while(mask != 0)
|
||||
{
|
||||
mask = mask << 1;
|
||||
prefixLength++;
|
||||
}
|
||||
}
|
||||
|
||||
return prefixLength;
|
||||
}
|
||||
|
||||
bool Ipv6Prefix::IsEqual (const Ipv6Prefix& other) const
|
||||
{
|
||||
if (!memcmp (m_prefix, other.m_prefix, 16))
|
||||
|
||||
@@ -35,6 +35,7 @@ class Ipv6Prefix;
|
||||
class Mac48Address;
|
||||
|
||||
/**
|
||||
* \ingroup address
|
||||
* \class Ipv6Address
|
||||
* \brief Describes an IPv6 address.
|
||||
* \see Ipv6Prefix
|
||||
@@ -253,6 +254,12 @@ class Ipv6Address
|
||||
*/
|
||||
static Ipv6Address GetLoopback ();
|
||||
|
||||
/**
|
||||
* \brief Get the "all-1" IPv6 address (ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff).
|
||||
* \return all-1 Ipv6Address representation
|
||||
*/
|
||||
static Ipv6Address GetOnes ();
|
||||
|
||||
/**
|
||||
* \brief Get the bytes corresponding to the address.
|
||||
* \param buf buffer to store the data
|
||||
@@ -284,6 +291,7 @@ class Ipv6Address
|
||||
};
|
||||
|
||||
/**
|
||||
* \ingroup address
|
||||
* \class Ipv6Prefix
|
||||
* \brief Describes an IPv6 prefix. It is just a bitmask like Ipv4Mask.
|
||||
* \see Ipv6Address
|
||||
@@ -346,6 +354,12 @@ class Ipv6Prefix
|
||||
*/
|
||||
void GetBytes (uint8_t buf[16]) const;
|
||||
|
||||
/**
|
||||
* \brief Get prefix length.
|
||||
* \return prefix length
|
||||
*/
|
||||
uint8_t GetPrefixLength () const;
|
||||
|
||||
/**
|
||||
* \brief Comparison operation between two Ipv6Prefix.
|
||||
* \param other the IPv6 prefix to which to compare this prefix
|
||||
@@ -367,6 +381,12 @@ class Ipv6Prefix
|
||||
*/
|
||||
static Ipv6Prefix GetLoopback ();
|
||||
|
||||
/**
|
||||
* \brief Get the "all-1" IPv6 mask (ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff).
|
||||
* \return /128 Ipv6Prefix representation
|
||||
*/
|
||||
static Ipv6Prefix GetOnes ();
|
||||
|
||||
/**
|
||||
* \brief Get the zero prefix ( /0).
|
||||
* \return an Ipv6Prefix
|
||||
|
||||
@@ -37,14 +37,16 @@ class NetDevice;
|
||||
|
||||
/**
|
||||
* \ingroup node
|
||||
* \defgroup ipv6Routing Ipv6 Routing
|
||||
*
|
||||
* Abstract base class for Ipv6 routing protocols. Defines two
|
||||
* virtual functions for packet routing and forwarding. The first,
|
||||
* \defgroup ipv6Routing Ipv6RoutingProtocol
|
||||
*/
|
||||
/**
|
||||
* \ingroup ipv6Routing
|
||||
* \brief Abstract base class for Ipv6 routing protocols.
|
||||
*
|
||||
* Defines two virtual functions for packet routing and forwarding. The first,
|
||||
* RouteOutput (), is used for locally originated packets, and the second,
|
||||
* RouteInput (), is used for forwarding and/or delivering received packets.
|
||||
* Also defines the signatures of four callbacks used in RouteInput ().
|
||||
*
|
||||
*/
|
||||
class Ipv6RoutingProtocol : public Object
|
||||
{
|
||||
@@ -153,8 +155,9 @@ public:
|
||||
* \param mask destination mask
|
||||
* \param nextHop nextHop for this destination
|
||||
* \param interface output interface
|
||||
* \param prefixToUse prefix to use as source with this route
|
||||
*/
|
||||
virtual void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface) = 0;
|
||||
virtual void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ()) = 0;
|
||||
|
||||
/**
|
||||
* \param ipv6 the ipv6 object this routing protocol is being associated with
|
||||
|
||||
@@ -257,7 +257,7 @@ void Ipv6ListRouting::NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Addr
|
||||
}
|
||||
}
|
||||
|
||||
void Ipv6ListRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface)
|
||||
void Ipv6ListRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
|
||||
for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
|
||||
@@ -265,7 +265,7 @@ void Ipv6ListRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6A
|
||||
rprotoIter != m_routingProtocols.end ();
|
||||
rprotoIter++)
|
||||
{
|
||||
(*rprotoIter).second->NotifyRemoveRoute (dst, mask, nextHop, interface);
|
||||
(*rprotoIter).second->NotifyRemoveRoute (dst, mask, nextHop, interface, prefixToUse);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,7 +352,7 @@ public:
|
||||
void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
|
||||
void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
|
||||
void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ()) {}
|
||||
void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface) {}
|
||||
void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse) {}
|
||||
void SetIpv6 (Ptr<Ipv6> ipv6) {}
|
||||
};
|
||||
|
||||
@@ -367,7 +367,7 @@ public:
|
||||
void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
|
||||
void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
|
||||
void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ()) {}
|
||||
void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface) {}
|
||||
void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse) {}
|
||||
void SetIpv6 (Ptr<Ipv6> ipv6) {}
|
||||
};
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ public:
|
||||
virtual void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address);
|
||||
virtual void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address);
|
||||
virtual void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
|
||||
virtual void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface);
|
||||
virtual void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
|
||||
virtual void SetIpv6 (Ptr<Ipv6> ipv6);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -57,7 +57,7 @@ Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address dest, Ipv6Address gate
|
||||
|
||||
Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address dest, uint32_t interface)
|
||||
: m_dest (dest),
|
||||
m_destNetworkPrefix (Ipv6Prefix (128)),
|
||||
m_destNetworkPrefix (Ipv6Prefix::GetOnes ()),
|
||||
m_gateway (Ipv6Address::GetZero ()),
|
||||
m_interface (interface),
|
||||
m_prefixToUse (Ipv6Address ("::"))
|
||||
@@ -107,8 +107,7 @@ Ipv6RoutingTableEntry::~Ipv6RoutingTableEntry ()
|
||||
|
||||
bool Ipv6RoutingTableEntry::IsHost () const
|
||||
{
|
||||
static Ipv6Prefix prefix (128);
|
||||
if (m_destNetworkPrefix.IsEqual (prefix))
|
||||
if (m_destNetworkPrefix.IsEqual (Ipv6Prefix::GetOnes ()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -170,7 +169,7 @@ Ipv6Address Ipv6RoutingTableEntry::GetGateway () const
|
||||
|
||||
Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateHostRouteTo (Ipv6Address dest, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
|
||||
{
|
||||
return Ipv6RoutingTableEntry (dest, Ipv6Prefix (128), nextHop, interface, prefixToUse);
|
||||
return Ipv6RoutingTableEntry (dest, Ipv6Prefix::GetOnes (), nextHop, interface, prefixToUse);
|
||||
}
|
||||
|
||||
Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateHostRouteTo (Ipv6Address dest, uint32_t interface)
|
||||
|
||||
@@ -40,9 +40,8 @@ TypeId Ipv6StaticRouting::GetTypeId ()
|
||||
return tid;
|
||||
}
|
||||
|
||||
Ipv6StaticRouting::Ipv6StaticRouting ()
|
||||
: m_defaultRoute (0),
|
||||
m_ipv6 (0)
|
||||
Ipv6StaticRouting::Ipv6StaticRouting ()
|
||||
: m_ipv6 (0)
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
}
|
||||
@@ -58,7 +57,7 @@ void Ipv6StaticRouting::SetIpv6 (Ptr<Ipv6> ipv6)
|
||||
NS_ASSERT (m_ipv6 == 0 && ipv6 != 0);
|
||||
uint32_t i = 0;
|
||||
m_ipv6 = ipv6;
|
||||
|
||||
|
||||
for (i = 0 ; i < m_ipv6->GetNInterfaces () ; i++)
|
||||
{
|
||||
if (m_ipv6->IsUp (i))
|
||||
@@ -72,65 +71,47 @@ void Ipv6StaticRouting::SetIpv6 (Ptr<Ipv6> ipv6)
|
||||
}
|
||||
}
|
||||
|
||||
void Ipv6StaticRouting::AddHostRouteTo (Ipv6Address dst, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
|
||||
void Ipv6StaticRouting::AddHostRouteTo (Ipv6Address dst, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << dst << nextHop << interface << prefixToUse);
|
||||
Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
|
||||
*route = Ipv6RoutingTableEntry::CreateHostRouteTo (dst, nextHop, interface, prefixToUse);
|
||||
m_hostRoutes.push_back (route);
|
||||
NS_LOG_FUNCTION (this << dst << nextHop << interface << prefixToUse << metric);
|
||||
AddNetworkRouteTo (dst, Ipv6Prefix::GetOnes (), nextHop, interface, prefixToUse, metric);
|
||||
}
|
||||
|
||||
void Ipv6StaticRouting::AddHostRouteTo (Ipv6Address dst, uint32_t interface)
|
||||
void Ipv6StaticRouting::AddHostRouteTo (Ipv6Address dst, uint32_t interface, uint32_t metric)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << dst << interface);
|
||||
Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
|
||||
*route = Ipv6RoutingTableEntry::CreateHostRouteTo (dst, interface);
|
||||
m_hostRoutes.push_back (route);
|
||||
NS_LOG_FUNCTION (this << dst << interface << metric);
|
||||
AddNetworkRouteTo (dst, Ipv6Prefix::GetOnes (), interface, metric);
|
||||
}
|
||||
|
||||
void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface)
|
||||
void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, uint32_t metric)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface);
|
||||
NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface << metric);
|
||||
Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
|
||||
*route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface);
|
||||
m_networkRoutes.push_back (route);
|
||||
m_networkRoutes.push_back (std::make_pair (route, metric));
|
||||
}
|
||||
|
||||
void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
|
||||
void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface << prefixToUse);
|
||||
NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface << prefixToUse << metric);
|
||||
Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
|
||||
*route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface, prefixToUse);
|
||||
m_networkRoutes.push_back (route);
|
||||
m_networkRoutes.push_back (std::make_pair (route, metric));
|
||||
}
|
||||
|
||||
|
||||
void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface)
|
||||
void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface, uint32_t metric)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << network << networkPrefix << interface);
|
||||
Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
|
||||
*route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, interface);
|
||||
m_networkRoutes.push_back (route);
|
||||
m_networkRoutes.push_back (std::make_pair (route, metric));
|
||||
}
|
||||
|
||||
void Ipv6StaticRouting::SetDefaultRoute (Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
|
||||
void Ipv6StaticRouting::SetDefaultRoute (Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << nextHop << interface << prefixToUse);
|
||||
Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
|
||||
*route = Ipv6RoutingTableEntry::CreateDefaultRoute (nextHop, interface);
|
||||
route->SetPrefixToUse (prefixToUse);
|
||||
delete m_defaultRoute;
|
||||
m_defaultRoute = route;
|
||||
}
|
||||
|
||||
void Ipv6StaticRouting::RemoveDefaultRoute ()
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
if (m_defaultRoute)
|
||||
{
|
||||
delete m_defaultRoute;
|
||||
m_defaultRoute = 0;
|
||||
}
|
||||
AddNetworkRouteTo (Ipv6Address ("::"), Ipv6Prefix::GetZero (), nextHop, interface, prefixToUse, metric);
|
||||
}
|
||||
|
||||
void Ipv6StaticRouting::AddMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces)
|
||||
@@ -148,7 +129,7 @@ void Ipv6StaticRouting::SetDefaultMulticastRoute (uint32_t outputInterface)
|
||||
Ipv6Address network = Ipv6Address ("ff00::"); /* RFC 3513 */
|
||||
Ipv6Prefix networkMask = Ipv6Prefix (8);
|
||||
*route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkMask, outputInterface);
|
||||
m_networkRoutes.push_back (route);
|
||||
m_networkRoutes.push_back (std::make_pair (route, 0));
|
||||
}
|
||||
|
||||
uint32_t Ipv6StaticRouting::GetNMulticastRoutes () const
|
||||
@@ -199,7 +180,7 @@ void Ipv6StaticRouting::RemoveMulticastRoute (uint32_t index)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << index);
|
||||
uint32_t tmp = 0;
|
||||
|
||||
|
||||
for (MulticastRoutesI i = m_multicastRoutes.begin () ; i != m_multicastRoutes.end () ; i++)
|
||||
{
|
||||
if (tmp == index)
|
||||
@@ -219,11 +200,11 @@ bool Ipv6StaticRouting::HasNetworkDest (Ipv6Address network, uint32_t interfaceI
|
||||
/* in the network table */
|
||||
for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j++)
|
||||
{
|
||||
NS_ASSERT ((*j)->IsNetwork ());
|
||||
Ipv6Prefix prefix = (*j)->GetDestNetworkPrefix ();
|
||||
Ipv6Address entry = (*j)->GetDestNetwork ();
|
||||
Ipv6RoutingTableEntry* rtentry = j->first;
|
||||
Ipv6Prefix prefix = rtentry->GetDestNetworkPrefix ();
|
||||
Ipv6Address entry = rtentry->GetDestNetwork ();
|
||||
|
||||
if (prefix.IsMatch (network, entry) && (*j)->GetInterface () == interfaceIndex)
|
||||
if (prefix.IsMatch (network, entry) && rtentry->GetInterface () == interfaceIndex)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -237,10 +218,12 @@ Ptr<Ipv6Route> Ipv6StaticRouting::LookupStatic (Ipv6Address dst, uint32_t interf
|
||||
{
|
||||
NS_LOG_FUNCTION (this << dst << interface);
|
||||
Ptr<Ipv6Route> rtentry = 0;
|
||||
uint16_t longestMask = 0;
|
||||
uint32_t shortestMetric = 0xffffffff;
|
||||
|
||||
/* when sending on link-local multicast, there have to be interface specified */
|
||||
if (dst == Ipv6Address::GetAllNodesMulticast () || dst.IsSolicitedMulticast () ||
|
||||
dst == Ipv6Address::GetAllRoutersMulticast () || dst == Ipv6Address::GetAllHostsMulticast ())
|
||||
dst == Ipv6Address::GetAllRoutersMulticast () || dst == Ipv6Address::GetAllHostsMulticast ())
|
||||
{
|
||||
NS_ASSERT_MSG (interface > 0, "Try to send on link-local multicast address, and no interface index is given!");
|
||||
rtentry = Create<Ipv6Route> ();
|
||||
@@ -251,110 +234,81 @@ Ptr<Ipv6Route> Ipv6StaticRouting::LookupStatic (Ipv6Address dst, uint32_t interf
|
||||
return rtentry;
|
||||
}
|
||||
|
||||
/* is the destination in hosts table */
|
||||
for (HostRoutesCI i = m_hostRoutes.begin () ; i != m_hostRoutes.end () ; i++)
|
||||
for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
|
||||
{
|
||||
NS_ASSERT ((*i)->IsHost ());
|
||||
if ((*i)->GetDest ().IsEqual (dst))
|
||||
Ipv6RoutingTableEntry* j = it->first;
|
||||
uint32_t metric = it->second;
|
||||
Ipv6Prefix mask = j->GetDestNetworkPrefix ();
|
||||
uint16_t maskLen = mask.GetPrefixLength ();
|
||||
Ipv6Address entry = j->GetDestNetwork ();
|
||||
|
||||
NS_LOG_LOGIC ("Searching for route to " << dst << ", mask length " << maskLen << ", metric " << metric);
|
||||
|
||||
if (mask.IsMatch (dst, entry))
|
||||
{
|
||||
if (!interface || interface == (*i)->GetInterface ())
|
||||
{
|
||||
NS_LOG_LOGIC ("Found global host route " << *i);
|
||||
Ipv6RoutingTableEntry* route = (*i);
|
||||
rtentry = Create<Ipv6Route> ();
|
||||
uint32_t interfaceIdx = route->GetInterface ();
|
||||
rtentry->SetDestination (route->GetDest ());
|
||||
NS_LOG_LOGIC ("Found global network route " << j << ", mask length " << maskLen << ", metric " << metric);
|
||||
|
||||
if (route->GetGateway ().IsAny ())
|
||||
{
|
||||
rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetDest ()));
|
||||
}
|
||||
else
|
||||
{
|
||||
rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetGateway ()));
|
||||
}
|
||||
|
||||
rtentry->SetGateway (route->GetGateway ());
|
||||
rtentry->SetOutputDevice (m_ipv6->GetNetDevice (interfaceIdx));
|
||||
return rtentry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* or in the network table */
|
||||
for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j++)
|
||||
{
|
||||
NS_ASSERT ((*j)->IsNetwork ());
|
||||
Ipv6Prefix prefix = (*j)->GetDestNetworkPrefix ();
|
||||
Ipv6Address entry = (*j)->GetDestNetwork ();
|
||||
|
||||
if (prefix.IsMatch (dst, entry))
|
||||
{
|
||||
/* if interface is given, check the route will output on this interface */
|
||||
if (!interface || interface == (*j)->GetInterface ())
|
||||
if (!interface || interface == j->GetInterface ())
|
||||
{
|
||||
NS_LOG_LOGIC ("Found global network route " << *j);
|
||||
Ipv6RoutingTableEntry* route = (*j);
|
||||
rtentry = Create<Ipv6Route>();
|
||||
if (maskLen < longestMask)
|
||||
{
|
||||
NS_LOG_LOGIC ("Previous match longer, skipping");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (maskLen > longestMask)
|
||||
{
|
||||
shortestMetric = 0xffffffff;
|
||||
}
|
||||
|
||||
longestMask = maskLen;
|
||||
if (metric > shortestMetric)
|
||||
{
|
||||
NS_LOG_LOGIC ("Equal mask length, but previous metric shorter, skipping");
|
||||
continue;
|
||||
}
|
||||
|
||||
shortestMetric = metric;
|
||||
Ipv6RoutingTableEntry* route = j;
|
||||
uint32_t interfaceIdx = route->GetInterface ();
|
||||
rtentry->SetDestination (route->GetDest ());
|
||||
|
||||
rtentry = Create<Ipv6Route> ();
|
||||
|
||||
|
||||
if (route->GetGateway ().IsAny ())
|
||||
{
|
||||
rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetDest ()));
|
||||
}
|
||||
else if (route->GetDest ().IsAny ()) /* default route */
|
||||
{
|
||||
rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetPrefixToUse ().IsAny () ? route->GetGateway () : route->GetPrefixToUse ()));
|
||||
}
|
||||
else
|
||||
{
|
||||
rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetGateway ()));
|
||||
}
|
||||
|
||||
rtentry->SetDestination (route->GetDest ());
|
||||
rtentry->SetGateway (route->GetGateway ());
|
||||
rtentry->SetOutputDevice (m_ipv6->GetNetDevice (interfaceIdx));
|
||||
return rtentry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* not found, return the default route if any */
|
||||
if (m_defaultRoute != 0)
|
||||
{
|
||||
NS_ASSERT (m_defaultRoute->IsDefault ());
|
||||
NS_LOG_LOGIC ("Found global network route via default route " << m_defaultRoute);
|
||||
Ipv6RoutingTableEntry* route = m_defaultRoute;
|
||||
rtentry = Create<Ipv6Route>();
|
||||
uint32_t interfaceIdx = route->GetInterface ();
|
||||
rtentry->SetDestination (route->GetDest ());
|
||||
rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetPrefixToUse ().IsAny () ? route->GetGateway () : route->GetPrefixToUse ()));
|
||||
rtentry->SetGateway (route->GetGateway ());
|
||||
rtentry->SetOutputDevice (m_ipv6->GetNetDevice (interfaceIdx));
|
||||
return rtentry;
|
||||
}
|
||||
|
||||
/* beuh!!! not route at all */
|
||||
return 0;
|
||||
NS_LOG_LOGIC ("Matching route via " << rtentry->GetDestination () << " (throught " << rtentry->GetGateway () << ") at the end");
|
||||
return rtentry;
|
||||
}
|
||||
|
||||
void Ipv6StaticRouting::DoDispose ()
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
for (HostRoutesI i = m_hostRoutes.begin () ; i != m_hostRoutes.end () ; i = m_hostRoutes.erase (i))
|
||||
{
|
||||
delete (*i);
|
||||
}
|
||||
m_hostRoutes.clear ();
|
||||
|
||||
|
||||
for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j = m_networkRoutes.erase (j))
|
||||
{
|
||||
delete (*j);
|
||||
delete j->first;
|
||||
}
|
||||
m_networkRoutes.clear ();
|
||||
|
||||
if (m_defaultRoute != 0)
|
||||
{
|
||||
delete m_defaultRoute;
|
||||
m_defaultRoute = 0;
|
||||
}
|
||||
|
||||
|
||||
for (MulticastRoutesI i = m_multicastRoutes.begin () ; i != m_multicastRoutes.end () ; i = m_multicastRoutes.erase (i))
|
||||
{
|
||||
delete (*i);
|
||||
@@ -392,23 +346,23 @@ Ptr<Ipv6MulticastRoute> Ipv6StaticRouting::LookupStatic (Ipv6Address origin, Ipv
|
||||
|
||||
if (group == route->GetGroup ())
|
||||
{
|
||||
if (interface == Ipv6::IF_ANY || interface == route->GetInputInterface ())
|
||||
{
|
||||
NS_LOG_LOGIC ("Found multicast route" << *i);
|
||||
mrtentry = Create<Ipv6MulticastRoute>();
|
||||
mrtentry->SetGroup (route->GetGroup ());
|
||||
mrtentry->SetOrigin (route->GetOrigin ());
|
||||
mrtentry->SetParent (route->GetInputInterface ());
|
||||
for (uint32_t j = 0 ; j < route->GetNOutputInterfaces () ; j++)
|
||||
if (interface == Ipv6::IF_ANY || interface == route->GetInputInterface ())
|
||||
{
|
||||
NS_LOG_LOGIC ("Found multicast route" << *i);
|
||||
mrtentry = Create<Ipv6MulticastRoute> ();
|
||||
mrtentry->SetGroup (route->GetGroup ());
|
||||
mrtentry->SetOrigin (route->GetOrigin ());
|
||||
mrtentry->SetParent (route->GetInputInterface ());
|
||||
for (uint32_t j = 0 ; j < route->GetNOutputInterfaces () ; j++)
|
||||
{
|
||||
if (route->GetOutputInterface (j))
|
||||
{
|
||||
if (route->GetOutputInterface (j))
|
||||
{
|
||||
NS_LOG_LOGIC ("Setting output interface index " << route->GetOutputInterface (j));
|
||||
mrtentry->SetOutputTtl (route->GetOutputInterface (j), Ipv6MulticastRoute::MAX_TTL - 1);
|
||||
}
|
||||
NS_LOG_LOGIC ("Setting output interface index " << route->GetOutputInterface (j));
|
||||
mrtentry->SetOutputTtl (route->GetOutputInterface (j), Ipv6MulticastRoute::MAX_TTL - 1);
|
||||
}
|
||||
return mrtentry;
|
||||
}
|
||||
}
|
||||
return mrtentry;
|
||||
}
|
||||
}
|
||||
}
|
||||
return mrtentry;
|
||||
@@ -416,23 +370,40 @@ Ptr<Ipv6MulticastRoute> Ipv6StaticRouting::LookupStatic (Ipv6Address origin, Ipv
|
||||
|
||||
uint32_t Ipv6StaticRouting::GetNRoutes ()
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
uint32_t n = 0;
|
||||
if (m_defaultRoute != 0)
|
||||
{
|
||||
n++;
|
||||
}
|
||||
n += m_hostRoutes.size ();
|
||||
n += m_networkRoutes.size ();
|
||||
return n;
|
||||
return m_networkRoutes.size ();
|
||||
}
|
||||
|
||||
Ipv6RoutingTableEntry Ipv6StaticRouting::GetDefaultRoute ()
|
||||
{
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
if (m_defaultRoute != 0)
|
||||
Ipv6Address dst ("::");
|
||||
uint32_t shortestMetric = 0xffffffff;
|
||||
Ipv6RoutingTableEntry* result = 0;
|
||||
|
||||
for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
|
||||
{
|
||||
return *m_defaultRoute;
|
||||
Ipv6RoutingTableEntry* j = it->first;
|
||||
uint32_t metric = it->second;
|
||||
Ipv6Prefix mask = j->GetDestNetworkPrefix ();
|
||||
uint16_t maskLen = mask.GetPrefixLength ();
|
||||
Ipv6Address entry = j->GetDestNetwork ();
|
||||
|
||||
if (maskLen)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (metric > shortestMetric)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
shortestMetric = metric;
|
||||
result = j;
|
||||
}
|
||||
|
||||
if (result)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -443,38 +414,13 @@ Ipv6RoutingTableEntry Ipv6StaticRouting::GetDefaultRoute ()
|
||||
Ipv6RoutingTableEntry Ipv6StaticRouting::GetRoute (uint32_t index)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << index);
|
||||
|
||||
if (index == 0 && m_defaultRoute != 0)
|
||||
{
|
||||
return *m_defaultRoute;
|
||||
}
|
||||
|
||||
if (index > 0 && m_defaultRoute != 0)
|
||||
{
|
||||
index--;
|
||||
}
|
||||
|
||||
if (index < m_hostRoutes.size ())
|
||||
{
|
||||
uint32_t tmp = 0;
|
||||
for (HostRoutesCI i = m_hostRoutes.begin () ; i != m_hostRoutes.end () ; i++)
|
||||
{
|
||||
if (tmp == index)
|
||||
{
|
||||
return *i;
|
||||
}
|
||||
tmp++;
|
||||
}
|
||||
}
|
||||
|
||||
index -= m_hostRoutes.size ();
|
||||
uint32_t tmp = 0;
|
||||
|
||||
for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j++)
|
||||
for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
|
||||
{
|
||||
if (tmp == index)
|
||||
{
|
||||
return *j;
|
||||
return it->first;
|
||||
}
|
||||
tmp++;
|
||||
}
|
||||
@@ -483,43 +429,36 @@ Ipv6RoutingTableEntry Ipv6StaticRouting::GetRoute (uint32_t index)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Ipv6StaticRouting::RemoveRoute (uint32_t index)
|
||||
uint32_t Ipv6StaticRouting::GetMetric (uint32_t index)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << index);
|
||||
if (index == 0 && m_defaultRoute != 0)
|
||||
{
|
||||
delete m_defaultRoute;
|
||||
m_defaultRoute = 0;
|
||||
}
|
||||
|
||||
if (index > 0 && m_defaultRoute != 0)
|
||||
{
|
||||
index--;
|
||||
}
|
||||
|
||||
if (index < m_hostRoutes.size ())
|
||||
{
|
||||
uint32_t tmp = 0;
|
||||
for (HostRoutesI i = m_hostRoutes.begin () ; i != m_hostRoutes.end () ; i++)
|
||||
{
|
||||
if (tmp == index)
|
||||
{
|
||||
delete *i;
|
||||
m_hostRoutes.erase (i);
|
||||
return;
|
||||
}
|
||||
tmp++;
|
||||
}
|
||||
}
|
||||
index -= m_hostRoutes.size ();
|
||||
NS_LOG_FUNCTION_NOARGS ();
|
||||
uint32_t tmp = 0;
|
||||
|
||||
for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j++)
|
||||
|
||||
for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
|
||||
{
|
||||
if (tmp == index)
|
||||
{
|
||||
delete *j;
|
||||
m_networkRoutes.erase (j);
|
||||
return it->second;
|
||||
}
|
||||
tmp++;
|
||||
}
|
||||
NS_ASSERT (false);
|
||||
// quiet compiler.
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Ipv6StaticRouting::RemoveRoute (uint32_t index)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << index);
|
||||
uint32_t tmp = 0;
|
||||
|
||||
for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
|
||||
{
|
||||
if (tmp == index)
|
||||
{
|
||||
delete it->first;
|
||||
m_networkRoutes.erase (it);
|
||||
return;
|
||||
}
|
||||
tmp++;
|
||||
@@ -527,15 +466,18 @@ void Ipv6StaticRouting::RemoveRoute (uint32_t index)
|
||||
NS_ASSERT (false);
|
||||
}
|
||||
|
||||
void Ipv6StaticRouting::RemoveRoute (Ipv6Address network, Ipv6Prefix prefix, uint32_t ifIndex)
|
||||
void Ipv6StaticRouting::RemoveRoute (Ipv6Address network, Ipv6Prefix prefix, uint32_t ifIndex, Ipv6Address prefixToUse)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << network << prefix << ifIndex);
|
||||
for (NetworkRoutesI i = m_networkRoutes.begin () ; i != m_networkRoutes.end () ; i++)
|
||||
|
||||
for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
|
||||
{
|
||||
if (network == (*i)->GetDest () and (*i)->GetInterface () == ifIndex)
|
||||
Ipv6RoutingTableEntry* rtentry = it->first;
|
||||
if (network == rtentry->GetDest () && rtentry->GetInterface () == ifIndex &&
|
||||
rtentry->GetPrefixToUse () == prefixToUse)
|
||||
{
|
||||
delete *i;
|
||||
m_networkRoutes.erase (i);
|
||||
delete it->first;
|
||||
m_networkRoutes.erase (it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -557,7 +499,7 @@ Ptr<Ipv6Route> Ipv6StaticRouting::RouteOutput (Ptr<Packet> p, const Ipv6Header &
|
||||
// So, we just log it and fall through to LookupStatic ()
|
||||
NS_LOG_LOGIC ("RouteOutput ()::Multicast destination");
|
||||
}
|
||||
|
||||
|
||||
rtentry = LookupStatic (destination, oif);
|
||||
if (rtentry)
|
||||
{
|
||||
@@ -580,7 +522,8 @@ bool Ipv6StaticRouting::RouteInput (Ptr<const Packet> p, const Ipv6Header &ipHea
|
||||
{
|
||||
NS_LOG_LOGIC ("Multicast destination");
|
||||
Ptr<Ipv6MulticastRoute> mrtentry = LookupStatic (ipHeader.GetSourceAddress (),
|
||||
ipHeader.GetDestinationAddress (), m_ipv6->GetInterfaceForDevice (idev));
|
||||
ipHeader.GetDestinationAddress ()
|
||||
, m_ipv6->GetInterfaceForDevice (idev));
|
||||
|
||||
if (mrtentry)
|
||||
{
|
||||
@@ -594,9 +537,9 @@ 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.
|
||||
//
|
||||
//
|
||||
// This is a unicast packet. Check to see if we have a route for it.
|
||||
//
|
||||
NS_LOG_LOGIC ("Unicast destination");
|
||||
Ptr<Ipv6Route> rtentry = LookupStatic (ipHeader.GetDestinationAddress ());
|
||||
|
||||
@@ -618,7 +561,7 @@ void Ipv6StaticRouting::NotifyInterfaceUp (uint32_t i)
|
||||
for (uint32_t j = 0 ; j < m_ipv6->GetNAddresses (i) ; j++)
|
||||
{
|
||||
if (m_ipv6->GetAddress (i, j).GetAddress () != Ipv6Address () &&
|
||||
m_ipv6->GetAddress (i, j).GetPrefix () != Ipv6Prefix ())
|
||||
m_ipv6->GetAddress (i, j).GetPrefix () != Ipv6Prefix ())
|
||||
{
|
||||
if (m_ipv6->GetAddress (i, j).GetPrefix () == Ipv6Prefix (128))
|
||||
{
|
||||
@@ -628,7 +571,7 @@ void Ipv6StaticRouting::NotifyInterfaceUp (uint32_t i)
|
||||
else
|
||||
{
|
||||
AddNetworkRouteTo (m_ipv6->GetAddress (i, j).GetAddress ().CombinePrefix (m_ipv6->GetAddress (i, j).GetPrefix ()),
|
||||
m_ipv6->GetAddress (i, j).GetPrefix (), i);
|
||||
m_ipv6->GetAddress (i, j).GetPrefix (), i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -636,8 +579,12 @@ void Ipv6StaticRouting::NotifyInterfaceUp (uint32_t i)
|
||||
|
||||
void Ipv6StaticRouting::NotifyInterfaceDown (uint32_t i)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << i);
|
||||
uint32_t j = 0;
|
||||
uint32_t max = GetNRoutes ();
|
||||
|
||||
/* remove all static routes that are going through this interface */
|
||||
for (uint32_t j = 0 ; j < GetNRoutes () ; j++)
|
||||
while (j < max)
|
||||
{
|
||||
Ipv6RoutingTableEntry route = GetRoute (j);
|
||||
|
||||
@@ -645,6 +592,10 @@ void Ipv6StaticRouting::NotifyInterfaceDown (uint32_t i)
|
||||
{
|
||||
RemoveRoute (j);
|
||||
}
|
||||
else
|
||||
{
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -673,13 +624,13 @@ void Ipv6StaticRouting::NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAd
|
||||
|
||||
Ipv6Address networkAddress = address.GetAddress ().CombinePrefix (address.GetPrefix ());
|
||||
Ipv6Prefix networkMask = address.GetPrefix ();
|
||||
|
||||
|
||||
// Remove all static routes that are going through this interface
|
||||
// which reference this network
|
||||
for (uint32_t j = 0 ; j < GetNRoutes () ; j++)
|
||||
{
|
||||
Ipv6RoutingTableEntry route = GetRoute (j);
|
||||
|
||||
|
||||
if (route.GetInterface () == interface &&
|
||||
route.IsNetwork () &&
|
||||
route.GetDestNetwork () == networkAddress &&
|
||||
@@ -693,11 +644,7 @@ void Ipv6StaticRouting::NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAd
|
||||
void Ipv6StaticRouting::NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
|
||||
{
|
||||
NS_LOG_INFO (this << dst << mask << nextHop << interface << prefixToUse);
|
||||
if (mask == Ipv6Prefix (128))
|
||||
{
|
||||
AddHostRouteTo (dst, nextHop, interface);
|
||||
}
|
||||
else if (dst != Ipv6Address::GetZero ())
|
||||
if (dst != Ipv6Address::GetZero ())
|
||||
{
|
||||
AddNetworkRouteTo (dst, mask, nextHop, interface);
|
||||
}
|
||||
@@ -706,40 +653,24 @@ void Ipv6StaticRouting::NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Ad
|
||||
/* this case is mainly used by configuring default route following RA processing,
|
||||
* in case of multipe prefix in RA, the first will configured default route
|
||||
*/
|
||||
if (!m_defaultRoute)
|
||||
{
|
||||
SetDefaultRoute (nextHop, interface, prefixToUse);
|
||||
}
|
||||
SetDefaultRoute (nextHop, interface, prefixToUse);
|
||||
}
|
||||
}
|
||||
|
||||
void Ipv6StaticRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface)
|
||||
void Ipv6StaticRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
|
||||
if (mask == Ipv6Prefix (128))
|
||||
{
|
||||
for (HostRoutesI j = m_hostRoutes.begin () ; j != m_hostRoutes.end () ; j++)
|
||||
{
|
||||
Ipv6Prefix prefix = (*j)->GetDestNetworkPrefix ();
|
||||
Ipv6Address entry = (*j)->GetDestNetwork ();
|
||||
|
||||
if (dst == entry && prefix == mask && (*j)->GetInterface () == interface)
|
||||
{
|
||||
delete (*j);
|
||||
m_hostRoutes.erase (j);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (dst != Ipv6Address::GetZero ())
|
||||
if (dst != Ipv6Address::GetZero ())
|
||||
{
|
||||
for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j++)
|
||||
{
|
||||
Ipv6Prefix prefix = (*j)->GetDestNetworkPrefix ();
|
||||
Ipv6Address entry = (*j)->GetDestNetwork ();
|
||||
Ipv6RoutingTableEntry* rtentry = j->first;
|
||||
Ipv6Prefix prefix = rtentry->GetDestNetworkPrefix ();
|
||||
Ipv6Address entry = rtentry->GetDestNetwork ();
|
||||
|
||||
if (dst == entry && prefix == mask && (*j)->GetInterface () == interface)
|
||||
if (dst == entry && prefix == mask && rtentry->GetInterface () == interface)
|
||||
{
|
||||
delete (*j);
|
||||
delete j->first;
|
||||
m_networkRoutes.erase (j);
|
||||
}
|
||||
}
|
||||
@@ -747,17 +678,7 @@ void Ipv6StaticRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv
|
||||
else
|
||||
{
|
||||
/* default route case */
|
||||
if (!m_defaultRoute)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_defaultRoute->GetInterface () == interface && m_defaultRoute->GetGateway () == nextHop)
|
||||
{
|
||||
NS_LOG_LOGIC ("Remove default route (maybe because autoconfigured address expired)");
|
||||
delete m_defaultRoute;
|
||||
m_defaultRoute = 0;
|
||||
}
|
||||
RemoveRoute (dst, mask, interface, prefixToUse);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -785,7 +706,7 @@ Ipv6Address Ipv6StaticRouting::SourceAddressSelection (uint32_t interface, Ipv6A
|
||||
return test.GetAddress ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,9 @@ class Ipv6MulticastRoutingTableEntry;
|
||||
/**
|
||||
* \ingroup routing
|
||||
* \defgroup ipv6StaticRouting Ipv6StaticRouting
|
||||
*/
|
||||
/**
|
||||
* \ingroup ipv6StaticRouting
|
||||
* \class Ipv6StaticRouting
|
||||
* \brief Static routing protocol for IP version 6 stack.
|
||||
* \see Ipv6RoutingProtocol
|
||||
@@ -74,15 +77,17 @@ class Ipv6StaticRouting : public Ipv6RoutingProtocol
|
||||
* \param nextHop next hop address to route the packet
|
||||
* \param interface interface index
|
||||
* \param prefixToUse prefix that should be used for source address for this destination
|
||||
* \param metric metric of route in case of multiple routes to same destination
|
||||
*/
|
||||
void AddHostRouteTo (Ipv6Address dest, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address ("::"));
|
||||
void AddHostRouteTo (Ipv6Address dest, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address ("::"), uint32_t metric = 0);
|
||||
|
||||
/**
|
||||
* \brief Add route to host.
|
||||
* \param dest destination address.
|
||||
* \param interface interface index
|
||||
* \param metric metric of route in case of multiple routes to same destination
|
||||
*/
|
||||
void AddHostRouteTo (Ipv6Address dest, uint32_t interface);
|
||||
void AddHostRouteTo (Ipv6Address dest, uint32_t interface, uint32_t metric = 0);
|
||||
|
||||
/**
|
||||
* \brief Add route to network.
|
||||
@@ -90,8 +95,9 @@ class Ipv6StaticRouting : public Ipv6RoutingProtocol
|
||||
* \param networkPrefix network prefix*
|
||||
* \param nextHop next hop address to route the packet
|
||||
* \param interface interface index
|
||||
* \param metric metric of route in case of multiple routes to same destination
|
||||
*/
|
||||
void AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface);
|
||||
void AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, uint32_t metric = 0);
|
||||
|
||||
/**
|
||||
* \brief Add route to network.
|
||||
@@ -100,29 +106,27 @@ class Ipv6StaticRouting : public Ipv6RoutingProtocol
|
||||
* \param nextHop next hop address to route the packet
|
||||
* \param interface interface index
|
||||
* \param prefixToUse prefix that should be used for source address for this destination
|
||||
* \param metric metric of route in case of multiple routes to same destination
|
||||
*/
|
||||
void AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse);
|
||||
void AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric = 0);
|
||||
|
||||
/**
|
||||
* \brief Add route to network.
|
||||
* \param network network address
|
||||
* \param networkPrefix network prefix
|
||||
* \param interface interface index
|
||||
* \param metric metric of route in case of multiple routes to same destination
|
||||
*/
|
||||
void AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface);
|
||||
void AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface, uint32_t metric = 0);
|
||||
|
||||
/**
|
||||
* \brief Set the default route.
|
||||
* \param nextHop next hop address to route the packet
|
||||
* \param interface interface index
|
||||
* \param prefixToUse prefix to use (i.e for multihoming)
|
||||
* \param metric metric of route in case of multiple routes to same destination
|
||||
*/
|
||||
void SetDefaultRoute (Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address ("::"));
|
||||
|
||||
/**
|
||||
* \brief Remove the default route.
|
||||
*/
|
||||
void RemoveDefaultRoute ();
|
||||
void SetDefaultRoute (Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address ("::"), uint32_t metric = 0);
|
||||
|
||||
/**
|
||||
* \brief Get the number or entries in the routing table.
|
||||
@@ -132,6 +136,8 @@ class Ipv6StaticRouting : public Ipv6RoutingProtocol
|
||||
|
||||
/**
|
||||
* \brief Get the default route.
|
||||
*
|
||||
* If multiple default routes exist, the one with lowest metric is returned.
|
||||
* \return default Ipv6Route
|
||||
*/
|
||||
Ipv6RoutingTableEntry GetDefaultRoute ();
|
||||
@@ -143,6 +149,13 @@ class Ipv6StaticRouting : public Ipv6RoutingProtocol
|
||||
*/
|
||||
Ipv6RoutingTableEntry GetRoute (uint32_t i);
|
||||
|
||||
/**
|
||||
* \brief Get a metric for route from the static unicast routing table.
|
||||
* \param index The index (into the routing table) of the route to retrieve.
|
||||
* \return If route is set, the metric is returned. If not, an infinity metric (0xffffffff) is returned
|
||||
*/
|
||||
uint32_t GetMetric (uint32_t index);
|
||||
|
||||
/**
|
||||
* \brief Remove a route from the routing table.
|
||||
* \param i index
|
||||
@@ -154,8 +167,9 @@ class Ipv6StaticRouting : public Ipv6RoutingProtocol
|
||||
* \param network IPv6 network
|
||||
* \param prefix IPv6 prefix
|
||||
* \param ifIndex interface index
|
||||
* \param prefixToUse IPv6 prefix to use with this route (multihoming)
|
||||
*/
|
||||
void RemoveRoute (Ipv6Address network, Ipv6Prefix prefix, uint32_t ifIndex);
|
||||
void RemoveRoute (Ipv6Address network, Ipv6Prefix prefix, uint32_t ifIndex, Ipv6Address prefixToUse);
|
||||
|
||||
/**
|
||||
* \brief Add a multicast route for a given multicast source and group.
|
||||
@@ -219,7 +233,7 @@ class Ipv6StaticRouting : public Ipv6RoutingProtocol
|
||||
virtual void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address);
|
||||
virtual void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address);
|
||||
virtual void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
|
||||
virtual void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface);
|
||||
virtual void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
|
||||
virtual void SetIpv6 (Ptr<Ipv6> ipv6);
|
||||
|
||||
protected:
|
||||
@@ -229,12 +243,9 @@ class Ipv6StaticRouting : public Ipv6RoutingProtocol
|
||||
void DoDispose ();
|
||||
|
||||
private:
|
||||
typedef std::list<Ipv6RoutingTableEntry *> HostRoutes;
|
||||
typedef std::list<Ipv6RoutingTableEntry *>::const_iterator HostRoutesCI;
|
||||
typedef std::list<Ipv6RoutingTableEntry *>::iterator HostRoutesI;
|
||||
typedef std::list<Ipv6RoutingTableEntry *> NetworkRoutes;
|
||||
typedef std::list<Ipv6RoutingTableEntry *>::const_iterator NetworkRoutesCI;
|
||||
typedef std::list<Ipv6RoutingTableEntry *>::iterator NetworkRoutesI;
|
||||
typedef std::list<std::pair <Ipv6RoutingTableEntry *, uint32_t> > NetworkRoutes;
|
||||
typedef std::list<std::pair <Ipv6RoutingTableEntry *, uint32_t> >::const_iterator NetworkRoutesCI;
|
||||
typedef std::list<std::pair <Ipv6RoutingTableEntry *, uint32_t> >::iterator NetworkRoutesI;
|
||||
|
||||
typedef std::list<Ipv6MulticastRoutingTableEntry *> MulticastRoutes;
|
||||
typedef std::list<Ipv6MulticastRoutingTableEntry *>::const_iterator MulticastRoutesCI;
|
||||
@@ -265,21 +276,11 @@ class Ipv6StaticRouting : public Ipv6RoutingProtocol
|
||||
*/
|
||||
Ipv6Address SourceAddressSelection (uint32_t interface, Ipv6Address dest);
|
||||
|
||||
/**
|
||||
* \brief the forwarding table for hosts.
|
||||
*/
|
||||
HostRoutes m_hostRoutes;
|
||||
|
||||
/**
|
||||
* \brief the forwarding table for network.
|
||||
*/
|
||||
NetworkRoutes m_networkRoutes;
|
||||
|
||||
/**
|
||||
* \brief the default route.
|
||||
*/
|
||||
Ipv6RoutingTableEntry *m_defaultRoute;
|
||||
|
||||
/**
|
||||
* \brief the forwarding table for multicast.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user