Add metric and longest prefix match support for IPv6.
1.1 --- a/CHANGES.html Mon Sep 07 11:59:10 2009 +0100
1.2 +++ b/CHANGES.html Mon Sep 07 18:03:01 2009 +0200
1.3 @@ -52,7 +52,7 @@
1.4
1.5 <h2>New API:</h2>
1.6 <ul>
1.7 -<li><b>Longest prefix match, support for metrics, for Ipv4StaticRouting</b>
1.8 +<li><b>Longest prefix match, support for metrics, for Ipv4StaticRouting and Ipv6StaticRouting</b>
1.9 <p>When performing route lookup, first match for longest prefix, and then
1.10 based on metrics (default metric = 0). If metrics are equal, most recent
1.11 addition is picked. Extends API for support of metrics but preserves
2.1 --- a/examples/radvd-two-prefix.cc Mon Sep 07 11:59:10 2009 +0100
2.2 +++ b/examples/radvd-two-prefix.cc Mon Sep 07 18:03:01 2009 +0200
2.3 @@ -77,7 +77,7 @@
2.4 routing = routingHelper.GetStaticRouting (ipv6);
2.5
2.6 std::cout << "Routing table of " << n << " : " << std::endl;
2.7 - std::cout << "Destination\t\t\t\t" << "Gateway\t\t\t\t\t" << "Interface\t" << std::endl;
2.8 + std::cout << "Destination\t\t\t\t" << "Gateway\t\t\t\t\t" << "Interface\t" << "Prefix to use" << std::endl;
2.9
2.10 nbRoutes = routing->GetNRoutes ();
2.11 for (uint32_t i = 0 ; i < nbRoutes ; i++)
2.12 @@ -85,7 +85,9 @@
2.13 route = routing->GetRoute (i);
2.14 std::cout << route.GetDest () << "\t"
2.15 << route.GetGateway () << "\t"
2.16 - << route.GetInterface () << "\t" << std::endl;
2.17 + << route.GetInterface () << "\t"
2.18 + << route.GetPrefixToUse () << "\t"
2.19 + << std::endl;
2.20 }
2.21 }
2.22 };
3.1 --- a/examples/simple-routing-ping6.cc Mon Sep 07 11:59:10 2009 +0100
3.2 +++ b/examples/simple-routing-ping6.cc Mon Sep 07 18:03:01 2009 +0200
3.3 @@ -33,12 +33,59 @@
3.4 #include "ns3/simulator-module.h"
3.5 #include "ns3/helper-module.h"
3.6
3.7 +#include "ns3/ipv6-routing-table-entry.h"
3.8 +
3.9 using namespace ns3;
3.10
3.11 NS_LOG_COMPONENT_DEFINE ("SimpleRoutingPing6Example");
3.12
3.13 -int
3.14 -main (int argc, char** argv)
3.15 +class StackHelper
3.16 +{
3.17 + public:
3.18 +
3.19 + /**
3.20 + * \brief Add an address to a IPv6 node.
3.21 + * \param n node
3.22 + * \param interface interface index
3.23 + * \param address IPv6 address to add
3.24 + */
3.25 + inline void AddAddress (Ptr<Node>& n, uint32_t interface, Ipv6Address address)
3.26 + {
3.27 + Ptr<Ipv6> ipv6 = n->GetObject<Ipv6> ();
3.28 + ipv6->AddAddress (interface, address);
3.29 + }
3.30 +
3.31 + /**
3.32 + * \brief Print the routing table.
3.33 + * \param n the node
3.34 + */
3.35 + inline void PrintRoutingTable (Ptr<Node>& n)
3.36 + {
3.37 + Ptr<Ipv6StaticRouting> routing = 0;
3.38 + Ipv6StaticRoutingHelper routingHelper;
3.39 + Ptr<Ipv6> ipv6 = n->GetObject<Ipv6> ();
3.40 + uint32_t nbRoutes = 0;
3.41 + Ipv6RoutingTableEntry route;
3.42 +
3.43 + routing = routingHelper.GetStaticRouting (ipv6);
3.44 +
3.45 + std::cout << "Routing table of " << n << " : " << std::endl;
3.46 + std::cout << "Destination\t\t\t\t" << "Gateway\t\t\t\t\t" << "Interface\t" << "Prefix to use" << std::endl;
3.47 +
3.48 + nbRoutes = routing->GetNRoutes ();
3.49 + for (uint32_t i = 0 ; i < nbRoutes ; i++)
3.50 + {
3.51 + route = routing->GetRoute (i);
3.52 + std::cout << route.GetDest () << "\t"
3.53 + << route.GetGateway () << "\t"
3.54 + << route.GetInterface () << "\t"
3.55 + << route.GetPrefixToUse () << "\t"
3.56 + << std::endl;
3.57 + }
3.58 + }
3.59 +};
3.60 +
3.61 +int main (int argc, char** argv)
3.62 {
3.63 #if 0
3.64 LogComponentEnable ("Ipv6L3Protocol", LOG_LEVEL_ALL);
3.65 @@ -50,6 +97,8 @@
3.66
3.67 CommandLine cmd;
3.68 cmd.Parse (argc, argv);
3.69 +
3.70 + StackHelper stackHelper;
3.71
3.72 NS_LOG_INFO ("Create nodes.");
3.73 Ptr<Node> n0 = CreateObject<Node> ();
3.74 @@ -80,6 +129,8 @@
3.75 Ipv6InterfaceContainer i2 = ipv6.Assign (d2);
3.76 i2.SetRouter (0, true);
3.77
3.78 + stackHelper.PrintRoutingTable(n0);
3.79 +
3.80 /* Create a Ping6 application to send ICMPv6 echo request from n0 to n1 via r */
3.81 uint32_t packetSize = 1024;
3.82 uint32_t maxPacketCount = 5;
3.83 @@ -88,7 +139,6 @@
3.84
3.85 ping6.SetLocal (i1.GetAddress (0, 1));
3.86 ping6.SetRemote (i2.GetAddress (1, 1));
3.87 - /* ping6.SetRemote (Ipv6Address::GetAllNodesMulticast ()); */
3.88
3.89 ping6.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount));
3.90 ping6.SetAttribute ("Interval", TimeValue (interPacketInterval));
4.1 --- a/src/internet-stack/icmpv6-l4-protocol.cc Mon Sep 07 11:59:10 2009 +0100
4.2 +++ b/src/internet-stack/icmpv6-l4-protocol.cc Mon Sep 07 18:03:01 2009 +0200
4.3 @@ -1086,6 +1086,19 @@
4.4 return cache;
4.5 }
4.6
4.7 +bool Icmpv6L4Protocol::Lookup (Ipv6Address dst, Ptr<NetDevice> device, Ptr<NdiscCache> cache, Address* hardwareDestination)
4.8 +{
4.9 + NS_LOG_FUNCTION (this << dst << device << hardwareDestination);
4.10 +
4.11 + if (!cache)
4.12 + {
4.13 + /* try to find the cache */
4.14 + cache = FindCache (device);
4.15 + }
4.16 +
4.17 + return cache->Lookup (dst);
4.18 +}
4.19 +
4.20 bool Icmpv6L4Protocol::Lookup (Ptr<Packet> p, Ipv6Address dst, Ptr<NetDevice> device, Ptr<NdiscCache> cache, Address* hardwareDestination)
4.21 {
4.22 NS_LOG_FUNCTION (this << p << dst << device << hardwareDestination);
5.1 --- a/src/internet-stack/icmpv6-l4-protocol.h Mon Sep 07 11:59:10 2009 +0100
5.2 +++ b/src/internet-stack/icmpv6-l4-protocol.h Mon Sep 07 18:03:01 2009 +0200
5.3 @@ -226,7 +226,6 @@
5.4 * \param id id of the packet
5.5 * \param seq sequence number
5.6 * \param data auxiliary data
5.7 - * \todo Change data to be a char[], change it too in icmpv6-header.
5.8 */
5.9 void SendEchoReply (Ipv6Address src, Ipv6Address dst, uint16_t id, uint16_t seq, Ptr<Packet> data);
5.10
5.11 @@ -350,7 +349,19 @@
5.12 static void FunctionDadTimeout (Ptr<Icmpv6L4Protocol> icmpv6, Ipv6Interface* interface, Ipv6Address addr);
5.13
5.14 /**
5.15 + * \brief Lookup in the ND cache for the IPv6 address
5.16 + * \param dst destination address
5.17 + * \param device device
5.18 + * \param cache the neighbor cache
5.19 + * \param hardwareDestination hardware address
5.20 + * \note Unlike other Lookup method, it does not send NS request!
5.21 + */
5.22 + bool Lookup (Ipv6Address dst, Ptr<NetDevice> device, Ptr<NdiscCache> cache, Address* hardwareDestination);
5.23 +
5.24 + /**
5.25 * \brief Lookup in the ND cache for the IPv6 address (similar as ARP protocol).
5.26 + *
5.27 + * It also send NS request to target and store the waiting packet.
5.28 * \param p the packet
5.29 * \param dst destination address
5.30 * \param device device
6.1 --- a/src/internet-stack/ipv6-l3-protocol.cc Mon Sep 07 11:59:10 2009 +0100
6.2 +++ b/src/internet-stack/ipv6-l3-protocol.cc Mon Sep 07 18:03:01 2009 +0200
6.3 @@ -269,12 +269,6 @@
6.4 (*it)->StopPreferredTimer ();
6.5 (*it)->StopValidTimer ();
6.6 (*it)->StartPreferredTimer ();
6.7 -
6.8 - /* Suppose a link with two prefixes advertised,
6.9 - * when first prefix (which is the default route) expires,
6.10 - * the second ones router has to be default router
6.11 - */
6.12 - GetRoutingProtocol ()->NotifyAddRoute (Ipv6Address::GetAny (), Ipv6Prefix ((uint8_t)0), defaultRouter, interface, network);
6.13 return;
6.14 }
6.15 }
6.16 @@ -284,10 +278,7 @@
6.17 AddAddress (interface, address);
6.18
6.19 /* add default router
6.20 - * check to know if default route already exists is done
6.21 - * in Ipv6StaticRouting class
6.22 - *
6.23 - * If default route is already set, this function does nothing.
6.24 + * if a previous default route exists, the new ones is simply added
6.25 */
6.26 GetRoutingProtocol ()->NotifyAddRoute (Ipv6Address::GetAny (), Ipv6Prefix ((uint8_t)0), defaultRouter, interface, network);
6.27
6.28 @@ -327,7 +318,7 @@
6.29 }
6.30 }
6.31
6.32 - GetRoutingProtocol ()->NotifyRemoveRoute (Ipv6Address::GetAny (), Ipv6Prefix ((uint8_t)0), defaultRouter, interface);
6.33 + GetRoutingProtocol ()->NotifyRemoveRoute (Ipv6Address::GetAny (), Ipv6Prefix ((uint8_t)0), defaultRouter, interface, network);
6.34 }
6.35
6.36 bool Ipv6L3Protocol::AddAddress (uint32_t i, Ipv6InterfaceAddress address)
6.37 @@ -811,7 +802,7 @@
6.38
6.39 copy->AddHeader (header);
6.40
6.41 - if (icmpv6->Lookup (copy, target, rtentry->GetOutputDevice (), 0, &hardwareTarget))
6.42 + if (icmpv6->Lookup (target, rtentry->GetOutputDevice (), 0, &hardwareTarget))
6.43 {
6.44 icmpv6->SendRedirection (copy, src, target, dst, hardwareTarget);
6.45 }
6.46 @@ -820,7 +811,7 @@
6.47 icmpv6->SendRedirection (copy, src, target, dst, Address ());
6.48 }
6.49 }
6.50 -
6.51 +
6.52 SendRealOut (rtentry, packet, ipHeader);
6.53 }
6.54
7.1 --- a/src/node/inet6-socket-address.h Mon Sep 07 11:59:10 2009 +0100
7.2 +++ b/src/node/inet6-socket-address.h Mon Sep 07 18:03:01 2009 +0200
7.3 @@ -28,6 +28,7 @@
7.4 namespace ns3 {
7.5
7.6 /**
7.7 + * \ingroup address
7.8 * \class Inet6SocketAddress
7.9 * \brief An Inet6 address class.
7.10 */
8.1 --- a/src/node/ipv6-address.cc Mon Sep 07 11:59:10 2009 +0100
8.2 +++ b/src/node/ipv6-address.cc Mon Sep 07 18:03:01 2009 +0200
8.3 @@ -483,6 +483,12 @@
8.4 return loopback;
8.5 }
8.6
8.7 +Ipv6Address Ipv6Address::GetOnes ()
8.8 +{
8.9 + static Ipv6Address ones ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
8.10 + return ones;
8.11 +}
8.12 +
8.13 void Ipv6Address::GetBytes (uint8_t buf[16]) const
8.14 {
8.15 memcpy (buf, m_address, 16);
8.16 @@ -491,7 +497,7 @@
8.17 bool Ipv6Address::IsLinkLocal () const
8.18 {
8.19 Ipv6Address linkLocal ("fe80::0");
8.20 - if (!IsMulticast () && ((Ipv6Address*)this)->CombinePrefix (Ipv6Prefix (64))==linkLocal)
8.21 + if (!IsMulticast () && ((Ipv6Address*)this)->CombinePrefix (Ipv6Prefix (64)) == linkLocal)
8.22 {
8.23 return true;
8.24 }
8.25 @@ -627,6 +633,12 @@
8.26 return prefix;
8.27 }
8.28
8.29 +Ipv6Prefix Ipv6Prefix::GetOnes ()
8.30 +{
8.31 + static Ipv6Prefix ones ((uint8_t)128);
8.32 + return ones;
8.33 +}
8.34 +
8.35 Ipv6Prefix Ipv6Prefix::GetZero ()
8.36 {
8.37 Ipv6Prefix prefix ((uint8_t)0);
8.38 @@ -638,6 +650,25 @@
8.39 memcpy (buf, m_prefix, 16);
8.40 }
8.41
8.42 +uint8_t Ipv6Prefix::GetPrefixLength () const
8.43 +{
8.44 + uint8_t i = 0;
8.45 + uint8_t prefixLength = 0;
8.46 +
8.47 + for(i = 0 ; i < 16 ; i++)
8.48 + {
8.49 + uint8_t mask = m_prefix[i];
8.50 +
8.51 + while(mask != 0)
8.52 + {
8.53 + mask = mask << 1;
8.54 + prefixLength++;
8.55 + }
8.56 + }
8.57 +
8.58 + return prefixLength;
8.59 +}
8.60 +
8.61 bool Ipv6Prefix::IsEqual (const Ipv6Prefix& other) const
8.62 {
8.63 if (!memcmp (m_prefix, other.m_prefix, 16))
9.1 --- a/src/node/ipv6-address.h Mon Sep 07 11:59:10 2009 +0100
9.2 +++ b/src/node/ipv6-address.h Mon Sep 07 18:03:01 2009 +0200
9.3 @@ -35,6 +35,7 @@
9.4 class Mac48Address;
9.5
9.6 /**
9.7 + * \ingroup address
9.8 * \class Ipv6Address
9.9 * \brief Describes an IPv6 address.
9.10 * \see Ipv6Prefix
9.11 @@ -254,6 +255,12 @@
9.12 static Ipv6Address GetLoopback ();
9.13
9.14 /**
9.15 + * \brief Get the "all-1" IPv6 address (ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff).
9.16 + * \return all-1 Ipv6Address representation
9.17 + */
9.18 + static Ipv6Address GetOnes ();
9.19 +
9.20 + /**
9.21 * \brief Get the bytes corresponding to the address.
9.22 * \param buf buffer to store the data
9.23 * \return bytes of the address
9.24 @@ -284,6 +291,7 @@
9.25 };
9.26
9.27 /**
9.28 + * \ingroup address
9.29 * \class Ipv6Prefix
9.30 * \brief Describes an IPv6 prefix. It is just a bitmask like Ipv4Mask.
9.31 * \see Ipv6Address
9.32 @@ -347,6 +355,12 @@
9.33 void GetBytes (uint8_t buf[16]) const;
9.34
9.35 /**
9.36 + * \brief Get prefix length.
9.37 + * \return prefix length
9.38 + */
9.39 + uint8_t GetPrefixLength () const;
9.40 +
9.41 + /**
9.42 * \brief Comparison operation between two Ipv6Prefix.
9.43 * \param other the IPv6 prefix to which to compare this prefix
9.44 * \return true if the prefixes are equal, false otherwise
9.45 @@ -368,6 +382,12 @@
9.46 static Ipv6Prefix GetLoopback ();
9.47
9.48 /**
9.49 + * \brief Get the "all-1" IPv6 mask (ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff).
9.50 + * \return /128 Ipv6Prefix representation
9.51 + */
9.52 + static Ipv6Prefix GetOnes ();
9.53 +
9.54 + /**
9.55 * \brief Get the zero prefix ( /0).
9.56 * \return an Ipv6Prefix
9.57 */
10.1 --- a/src/node/ipv6-routing-protocol.h Mon Sep 07 11:59:10 2009 +0100
10.2 +++ b/src/node/ipv6-routing-protocol.h Mon Sep 07 18:03:01 2009 +0200
10.3 @@ -37,14 +37,16 @@
10.4
10.5 /**
10.6 * \ingroup node
10.7 - * \defgroup ipv6Routing Ipv6 Routing
10.8 - *
10.9 - * Abstract base class for Ipv6 routing protocols. Defines two
10.10 - * virtual functions for packet routing and forwarding. The first,
10.11 + * \defgroup ipv6Routing Ipv6RoutingProtocol
10.12 + */
10.13 +/**
10.14 + * \ingroup ipv6Routing
10.15 + * \brief Abstract base class for Ipv6 routing protocols.
10.16 + *
10.17 + * Defines two virtual functions for packet routing and forwarding. The first,
10.18 * RouteOutput (), is used for locally originated packets, and the second,
10.19 * RouteInput (), is used for forwarding and/or delivering received packets.
10.20 * Also defines the signatures of four callbacks used in RouteInput ().
10.21 - *
10.22 */
10.23 class Ipv6RoutingProtocol : public Object
10.24 {
10.25 @@ -153,8 +155,9 @@
10.26 * \param mask destination mask
10.27 * \param nextHop nextHop for this destination
10.28 * \param interface output interface
10.29 + * \param prefixToUse prefix to use as source with this route
10.30 */
10.31 - virtual void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface) = 0;
10.32 + virtual void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ()) = 0;
10.33
10.34 /**
10.35 * \param ipv6 the ipv6 object this routing protocol is being associated with
11.1 --- a/src/routing/list-routing/ipv6-list-routing.cc Mon Sep 07 11:59:10 2009 +0100
11.2 +++ b/src/routing/list-routing/ipv6-list-routing.cc Mon Sep 07 18:03:01 2009 +0200
11.3 @@ -257,7 +257,7 @@
11.4 }
11.5 }
11.6
11.7 -void Ipv6ListRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface)
11.8 +void Ipv6ListRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
11.9 {
11.10 NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
11.11 for (Ipv6RoutingProtocolList::const_iterator rprotoIter =
11.12 @@ -265,7 +265,7 @@
11.13 rprotoIter != m_routingProtocols.end ();
11.14 rprotoIter++)
11.15 {
11.16 - (*rprotoIter).second->NotifyRemoveRoute (dst, mask, nextHop, interface);
11.17 + (*rprotoIter).second->NotifyRemoveRoute (dst, mask, nextHop, interface, prefixToUse);
11.18 }
11.19 }
11.20
11.21 @@ -352,7 +352,7 @@
11.22 void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
11.23 void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
11.24 void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ()) {}
11.25 - void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface) {}
11.26 + void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse) {}
11.27 void SetIpv6 (Ptr<Ipv6> ipv6) {}
11.28 };
11.29
11.30 @@ -367,7 +367,7 @@
11.31 void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
11.32 void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address) {}
11.33 void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ()) {}
11.34 - void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface) {}
11.35 + void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse) {}
11.36 void SetIpv6 (Ptr<Ipv6> ipv6) {}
11.37 };
11.38
12.1 --- a/src/routing/list-routing/ipv6-list-routing.h Mon Sep 07 11:59:10 2009 +0100
12.2 +++ b/src/routing/list-routing/ipv6-list-routing.h Mon Sep 07 18:03:01 2009 +0200
12.3 @@ -85,7 +85,7 @@
12.4 virtual void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address);
12.5 virtual void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address);
12.6 virtual void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
12.7 - virtual void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface);
12.8 + virtual void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
12.9 virtual void SetIpv6 (Ptr<Ipv6> ipv6);
12.10
12.11 protected:
13.1 --- a/src/routing/static-routing/ipv6-routing-table-entry.cc Mon Sep 07 11:59:10 2009 +0100
13.2 +++ b/src/routing/static-routing/ipv6-routing-table-entry.cc Mon Sep 07 18:03:01 2009 +0200
13.3 @@ -57,7 +57,7 @@
13.4
13.5 Ipv6RoutingTableEntry::Ipv6RoutingTableEntry (Ipv6Address dest, uint32_t interface)
13.6 : m_dest (dest),
13.7 - m_destNetworkPrefix (Ipv6Prefix (128)),
13.8 + m_destNetworkPrefix (Ipv6Prefix::GetOnes ()),
13.9 m_gateway (Ipv6Address::GetZero ()),
13.10 m_interface (interface),
13.11 m_prefixToUse (Ipv6Address ("::"))
13.12 @@ -107,8 +107,7 @@
13.13
13.14 bool Ipv6RoutingTableEntry::IsHost () const
13.15 {
13.16 - static Ipv6Prefix prefix (128);
13.17 - if (m_destNetworkPrefix.IsEqual (prefix))
13.18 + if (m_destNetworkPrefix.IsEqual (Ipv6Prefix::GetOnes ()))
13.19 {
13.20 return true;
13.21 }
13.22 @@ -170,7 +169,7 @@
13.23
13.24 Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateHostRouteTo (Ipv6Address dest, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
13.25 {
13.26 - return Ipv6RoutingTableEntry (dest, Ipv6Prefix (128), nextHop, interface, prefixToUse);
13.27 + return Ipv6RoutingTableEntry (dest, Ipv6Prefix::GetOnes (), nextHop, interface, prefixToUse);
13.28 }
13.29
13.30 Ipv6RoutingTableEntry Ipv6RoutingTableEntry::CreateHostRouteTo (Ipv6Address dest, uint32_t interface)
14.1 --- a/src/routing/static-routing/ipv6-static-routing.cc Mon Sep 07 11:59:10 2009 +0100
14.2 +++ b/src/routing/static-routing/ipv6-static-routing.cc Mon Sep 07 18:03:01 2009 +0200
14.3 @@ -40,9 +40,8 @@
14.4 return tid;
14.5 }
14.6
14.7 -Ipv6StaticRouting::Ipv6StaticRouting ()
14.8 - : m_defaultRoute (0),
14.9 - m_ipv6 (0)
14.10 + Ipv6StaticRouting::Ipv6StaticRouting ()
14.11 +: m_ipv6 (0)
14.12 {
14.13 NS_LOG_FUNCTION_NOARGS ();
14.14 }
14.15 @@ -58,7 +57,7 @@
14.16 NS_ASSERT (m_ipv6 == 0 && ipv6 != 0);
14.17 uint32_t i = 0;
14.18 m_ipv6 = ipv6;
14.19 -
14.20 +
14.21 for (i = 0 ; i < m_ipv6->GetNInterfaces () ; i++)
14.22 {
14.23 if (m_ipv6->IsUp (i))
14.24 @@ -72,65 +71,47 @@
14.25 }
14.26 }
14.27
14.28 -void Ipv6StaticRouting::AddHostRouteTo (Ipv6Address dst, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
14.29 +void Ipv6StaticRouting::AddHostRouteTo (Ipv6Address dst, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
14.30 {
14.31 - NS_LOG_FUNCTION (this << dst << nextHop << interface << prefixToUse);
14.32 - Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
14.33 - *route = Ipv6RoutingTableEntry::CreateHostRouteTo (dst, nextHop, interface, prefixToUse);
14.34 - m_hostRoutes.push_back (route);
14.35 + NS_LOG_FUNCTION (this << dst << nextHop << interface << prefixToUse << metric);
14.36 + AddNetworkRouteTo (dst, Ipv6Prefix::GetOnes (), nextHop, interface, prefixToUse, metric);
14.37 }
14.38
14.39 -void Ipv6StaticRouting::AddHostRouteTo (Ipv6Address dst, uint32_t interface)
14.40 +void Ipv6StaticRouting::AddHostRouteTo (Ipv6Address dst, uint32_t interface, uint32_t metric)
14.41 {
14.42 - NS_LOG_FUNCTION (this << dst << interface);
14.43 - Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
14.44 - *route = Ipv6RoutingTableEntry::CreateHostRouteTo (dst, interface);
14.45 - m_hostRoutes.push_back (route);
14.46 + NS_LOG_FUNCTION (this << dst << interface << metric);
14.47 + AddNetworkRouteTo (dst, Ipv6Prefix::GetOnes (), interface, metric);
14.48 }
14.49
14.50 -void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface)
14.51 +void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, uint32_t metric)
14.52 {
14.53 - NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface);
14.54 + NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface << metric);
14.55 Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
14.56 *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface);
14.57 - m_networkRoutes.push_back (route);
14.58 + m_networkRoutes.push_back (std::make_pair (route, metric));
14.59 }
14.60
14.61 -void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
14.62 +void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
14.63 {
14.64 - NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface << prefixToUse);
14.65 + NS_LOG_FUNCTION (this << network << networkPrefix << nextHop << interface << prefixToUse << metric);
14.66 Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
14.67 *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, nextHop, interface, prefixToUse);
14.68 - m_networkRoutes.push_back (route);
14.69 + m_networkRoutes.push_back (std::make_pair (route, metric));
14.70 }
14.71
14.72
14.73 -void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface)
14.74 +void Ipv6StaticRouting::AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface, uint32_t metric)
14.75 {
14.76 NS_LOG_FUNCTION (this << network << networkPrefix << interface);
14.77 Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
14.78 *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkPrefix, interface);
14.79 - m_networkRoutes.push_back (route);
14.80 + m_networkRoutes.push_back (std::make_pair (route, metric));
14.81 }
14.82
14.83 -void Ipv6StaticRouting::SetDefaultRoute (Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
14.84 +void Ipv6StaticRouting::SetDefaultRoute (Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric)
14.85 {
14.86 NS_LOG_FUNCTION (this << nextHop << interface << prefixToUse);
14.87 - Ipv6RoutingTableEntry* route = new Ipv6RoutingTableEntry ();
14.88 - *route = Ipv6RoutingTableEntry::CreateDefaultRoute (nextHop, interface);
14.89 - route->SetPrefixToUse (prefixToUse);
14.90 - delete m_defaultRoute;
14.91 - m_defaultRoute = route;
14.92 -}
14.93 -
14.94 -void Ipv6StaticRouting::RemoveDefaultRoute ()
14.95 -{
14.96 - NS_LOG_FUNCTION_NOARGS ();
14.97 - if (m_defaultRoute)
14.98 - {
14.99 - delete m_defaultRoute;
14.100 - m_defaultRoute = 0;
14.101 - }
14.102 + AddNetworkRouteTo (Ipv6Address ("::"), Ipv6Prefix::GetZero (), nextHop, interface, prefixToUse, metric);
14.103 }
14.104
14.105 void Ipv6StaticRouting::AddMulticastRoute (Ipv6Address origin, Ipv6Address group, uint32_t inputInterface, std::vector<uint32_t> outputInterfaces)
14.106 @@ -148,7 +129,7 @@
14.107 Ipv6Address network = Ipv6Address ("ff00::"); /* RFC 3513 */
14.108 Ipv6Prefix networkMask = Ipv6Prefix (8);
14.109 *route = Ipv6RoutingTableEntry::CreateNetworkRouteTo (network, networkMask, outputInterface);
14.110 - m_networkRoutes.push_back (route);
14.111 + m_networkRoutes.push_back (std::make_pair (route, 0));
14.112 }
14.113
14.114 uint32_t Ipv6StaticRouting::GetNMulticastRoutes () const
14.115 @@ -199,7 +180,7 @@
14.116 {
14.117 NS_LOG_FUNCTION (this << index);
14.118 uint32_t tmp = 0;
14.119 -
14.120 +
14.121 for (MulticastRoutesI i = m_multicastRoutes.begin () ; i != m_multicastRoutes.end () ; i++)
14.122 {
14.123 if (tmp == index)
14.124 @@ -219,11 +200,11 @@
14.125 /* in the network table */
14.126 for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j++)
14.127 {
14.128 - NS_ASSERT ((*j)->IsNetwork ());
14.129 - Ipv6Prefix prefix = (*j)->GetDestNetworkPrefix ();
14.130 - Ipv6Address entry = (*j)->GetDestNetwork ();
14.131 + Ipv6RoutingTableEntry* rtentry = j->first;
14.132 + Ipv6Prefix prefix = rtentry->GetDestNetworkPrefix ();
14.133 + Ipv6Address entry = rtentry->GetDestNetwork ();
14.134
14.135 - if (prefix.IsMatch (network, entry) && (*j)->GetInterface () == interfaceIndex)
14.136 + if (prefix.IsMatch (network, entry) && rtentry->GetInterface () == interfaceIndex)
14.137 {
14.138 return true;
14.139 }
14.140 @@ -237,10 +218,12 @@
14.141 {
14.142 NS_LOG_FUNCTION (this << dst << interface);
14.143 Ptr<Ipv6Route> rtentry = 0;
14.144 + uint16_t longestMask = 0;
14.145 + uint32_t shortestMetric = 0xffffffff;
14.146
14.147 /* when sending on link-local multicast, there have to be interface specified */
14.148 if (dst == Ipv6Address::GetAllNodesMulticast () || dst.IsSolicitedMulticast () ||
14.149 - dst == Ipv6Address::GetAllRoutersMulticast () || dst == Ipv6Address::GetAllHostsMulticast ())
14.150 + dst == Ipv6Address::GetAllRoutersMulticast () || dst == Ipv6Address::GetAllHostsMulticast ())
14.151 {
14.152 NS_ASSERT_MSG (interface > 0, "Try to send on link-local multicast address, and no interface index is given!");
14.153 rtentry = Create<Ipv6Route> ();
14.154 @@ -251,110 +234,81 @@
14.155 return rtentry;
14.156 }
14.157
14.158 - /* is the destination in hosts table */
14.159 - for (HostRoutesCI i = m_hostRoutes.begin () ; i != m_hostRoutes.end () ; i++)
14.160 + for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
14.161 {
14.162 - NS_ASSERT ((*i)->IsHost ());
14.163 - if ((*i)->GetDest ().IsEqual (dst))
14.164 + Ipv6RoutingTableEntry* j = it->first;
14.165 + uint32_t metric = it->second;
14.166 + Ipv6Prefix mask = j->GetDestNetworkPrefix ();
14.167 + uint16_t maskLen = mask.GetPrefixLength ();
14.168 + Ipv6Address entry = j->GetDestNetwork ();
14.169 +
14.170 + NS_LOG_LOGIC ("Searching for route to " << dst << ", mask length " << maskLen << ", metric " << metric);
14.171 +
14.172 + if (mask.IsMatch (dst, entry))
14.173 {
14.174 - if (!interface || interface == (*i)->GetInterface ())
14.175 + NS_LOG_LOGIC ("Found global network route " << j << ", mask length " << maskLen << ", metric " << metric);
14.176 +
14.177 + /* if interface is given, check the route will output on this interface */
14.178 + if (!interface || interface == j->GetInterface ())
14.179 {
14.180 - NS_LOG_LOGIC ("Found global host route " << *i);
14.181 - Ipv6RoutingTableEntry* route = (*i);
14.182 + if (maskLen < longestMask)
14.183 + {
14.184 + NS_LOG_LOGIC ("Previous match longer, skipping");
14.185 + continue;
14.186 + }
14.187 +
14.188 + if (maskLen > longestMask)
14.189 + {
14.190 + shortestMetric = 0xffffffff;
14.191 + }
14.192 +
14.193 + longestMask = maskLen;
14.194 + if (metric > shortestMetric)
14.195 + {
14.196 + NS_LOG_LOGIC ("Equal mask length, but previous metric shorter, skipping");
14.197 + continue;
14.198 + }
14.199 +
14.200 + shortestMetric = metric;
14.201 + Ipv6RoutingTableEntry* route = j;
14.202 + uint32_t interfaceIdx = route->GetInterface ();
14.203 rtentry = Create<Ipv6Route> ();
14.204 - uint32_t interfaceIdx = route->GetInterface ();
14.205 - rtentry->SetDestination (route->GetDest ());
14.206 +
14.207
14.208 if (route->GetGateway ().IsAny ())
14.209 {
14.210 rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetDest ()));
14.211 }
14.212 + else if (route->GetDest ().IsAny ()) /* default route */
14.213 + {
14.214 + rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetPrefixToUse ().IsAny () ? route->GetGateway () : route->GetPrefixToUse ()));
14.215 + }
14.216 else
14.217 {
14.218 rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetGateway ()));
14.219 }
14.220
14.221 + rtentry->SetDestination (route->GetDest ());
14.222 rtentry->SetGateway (route->GetGateway ());
14.223 rtentry->SetOutputDevice (m_ipv6->GetNetDevice (interfaceIdx));
14.224 - return rtentry;
14.225 }
14.226 }
14.227 }
14.228
14.229 - /* or in the network table */
14.230 - for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j++)
14.231 - {
14.232 - NS_ASSERT ((*j)->IsNetwork ());
14.233 - Ipv6Prefix prefix = (*j)->GetDestNetworkPrefix ();
14.234 - Ipv6Address entry = (*j)->GetDestNetwork ();
14.235 -
14.236 - if (prefix.IsMatch (dst, entry))
14.237 - {
14.238 - /* if interface is given, check the route will output on this interface */
14.239 - if (!interface || interface == (*j)->GetInterface ())
14.240 - {
14.241 - NS_LOG_LOGIC ("Found global network route " << *j);
14.242 - Ipv6RoutingTableEntry* route = (*j);
14.243 - rtentry = Create<Ipv6Route>();
14.244 - uint32_t interfaceIdx = route->GetInterface ();
14.245 - rtentry->SetDestination (route->GetDest ());
14.246 -
14.247 - if (route->GetGateway ().IsAny ())
14.248 - {
14.249 - rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetDest ()));
14.250 - }
14.251 - else
14.252 - {
14.253 - rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetGateway ()));
14.254 - }
14.255 -
14.256 - rtentry->SetGateway (route->GetGateway ());
14.257 - rtentry->SetOutputDevice (m_ipv6->GetNetDevice (interfaceIdx));
14.258 - return rtentry;
14.259 - }
14.260 - }
14.261 - }
14.262 -
14.263 - /* not found, return the default route if any */
14.264 - if (m_defaultRoute != 0)
14.265 - {
14.266 - NS_ASSERT (m_defaultRoute->IsDefault ());
14.267 - NS_LOG_LOGIC ("Found global network route via default route " << m_defaultRoute);
14.268 - Ipv6RoutingTableEntry* route = m_defaultRoute;
14.269 - rtentry = Create<Ipv6Route>();
14.270 - uint32_t interfaceIdx = route->GetInterface ();
14.271 - rtentry->SetDestination (route->GetDest ());
14.272 - rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetPrefixToUse ().IsAny () ? route->GetGateway () : route->GetPrefixToUse ()));
14.273 - rtentry->SetGateway (route->GetGateway ());
14.274 - rtentry->SetOutputDevice (m_ipv6->GetNetDevice (interfaceIdx));
14.275 - return rtentry;
14.276 - }
14.277 -
14.278 - /* beuh!!! not route at all */
14.279 - return 0;
14.280 + NS_LOG_LOGIC ("Matching route via " << rtentry->GetDestination () << " (throught " << rtentry->GetGateway () << ") at the end");
14.281 + return rtentry;
14.282 }
14.283
14.284 void Ipv6StaticRouting::DoDispose ()
14.285 {
14.286 NS_LOG_FUNCTION_NOARGS ();
14.287 - for (HostRoutesI i = m_hostRoutes.begin () ; i != m_hostRoutes.end () ; i = m_hostRoutes.erase (i))
14.288 - {
14.289 - delete (*i);
14.290 - }
14.291 - m_hostRoutes.clear ();
14.292 -
14.293 +
14.294 for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j = m_networkRoutes.erase (j))
14.295 {
14.296 - delete (*j);
14.297 + delete j->first;
14.298 }
14.299 m_networkRoutes.clear ();
14.300 -
14.301 - if (m_defaultRoute != 0)
14.302 - {
14.303 - delete m_defaultRoute;
14.304 - m_defaultRoute = 0;
14.305 - }
14.306 -
14.307 +
14.308 for (MulticastRoutesI i = m_multicastRoutes.begin () ; i != m_multicastRoutes.end () ; i = m_multicastRoutes.erase (i))
14.309 {
14.310 delete (*i);
14.311 @@ -392,23 +346,23 @@
14.312
14.313 if (group == route->GetGroup ())
14.314 {
14.315 - if (interface == Ipv6::IF_ANY || interface == route->GetInputInterface ())
14.316 - {
14.317 - NS_LOG_LOGIC ("Found multicast route" << *i);
14.318 - mrtentry = Create<Ipv6MulticastRoute>();
14.319 - mrtentry->SetGroup (route->GetGroup ());
14.320 - mrtentry->SetOrigin (route->GetOrigin ());
14.321 - mrtentry->SetParent (route->GetInputInterface ());
14.322 - for (uint32_t j = 0 ; j < route->GetNOutputInterfaces () ; j++)
14.323 + if (interface == Ipv6::IF_ANY || interface == route->GetInputInterface ())
14.324 + {
14.325 + NS_LOG_LOGIC ("Found multicast route" << *i);
14.326 + mrtentry = Create<Ipv6MulticastRoute> ();
14.327 + mrtentry->SetGroup (route->GetGroup ());
14.328 + mrtentry->SetOrigin (route->GetOrigin ());
14.329 + mrtentry->SetParent (route->GetInputInterface ());
14.330 + for (uint32_t j = 0 ; j < route->GetNOutputInterfaces () ; j++)
14.331 + {
14.332 + if (route->GetOutputInterface (j))
14.333 {
14.334 - if (route->GetOutputInterface (j))
14.335 - {
14.336 - NS_LOG_LOGIC ("Setting output interface index " << route->GetOutputInterface (j));
14.337 - mrtentry->SetOutputTtl (route->GetOutputInterface (j), Ipv6MulticastRoute::MAX_TTL - 1);
14.338 - }
14.339 + NS_LOG_LOGIC ("Setting output interface index " << route->GetOutputInterface (j));
14.340 + mrtentry->SetOutputTtl (route->GetOutputInterface (j), Ipv6MulticastRoute::MAX_TTL - 1);
14.341 }
14.342 - return mrtentry;
14.343 - }
14.344 + }
14.345 + return mrtentry;
14.346 + }
14.347 }
14.348 }
14.349 return mrtentry;
14.350 @@ -416,23 +370,40 @@
14.351
14.352 uint32_t Ipv6StaticRouting::GetNRoutes ()
14.353 {
14.354 - NS_LOG_FUNCTION_NOARGS ();
14.355 - uint32_t n = 0;
14.356 - if (m_defaultRoute != 0)
14.357 - {
14.358 - n++;
14.359 - }
14.360 - n += m_hostRoutes.size ();
14.361 - n += m_networkRoutes.size ();
14.362 - return n;
14.363 + return m_networkRoutes.size ();
14.364 }
14.365
14.366 Ipv6RoutingTableEntry Ipv6StaticRouting::GetDefaultRoute ()
14.367 {
14.368 NS_LOG_FUNCTION_NOARGS ();
14.369 - if (m_defaultRoute != 0)
14.370 + Ipv6Address dst ("::");
14.371 + uint32_t shortestMetric = 0xffffffff;
14.372 + Ipv6RoutingTableEntry* result = 0;
14.373 +
14.374 + for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
14.375 {
14.376 - return *m_defaultRoute;
14.377 + Ipv6RoutingTableEntry* j = it->first;
14.378 + uint32_t metric = it->second;
14.379 + Ipv6Prefix mask = j->GetDestNetworkPrefix ();
14.380 + uint16_t maskLen = mask.GetPrefixLength ();
14.381 + Ipv6Address entry = j->GetDestNetwork ();
14.382 +
14.383 + if (maskLen)
14.384 + {
14.385 + continue;
14.386 + }
14.387 +
14.388 + if (metric > shortestMetric)
14.389 + {
14.390 + continue;
14.391 + }
14.392 + shortestMetric = metric;
14.393 + result = j;
14.394 + }
14.395 +
14.396 + if (result)
14.397 + {
14.398 + return result;
14.399 }
14.400 else
14.401 {
14.402 @@ -443,38 +414,13 @@
14.403 Ipv6RoutingTableEntry Ipv6StaticRouting::GetRoute (uint32_t index)
14.404 {
14.405 NS_LOG_FUNCTION (this << index);
14.406 -
14.407 - if (index == 0 && m_defaultRoute != 0)
14.408 - {
14.409 - return *m_defaultRoute;
14.410 - }
14.411 -
14.412 - if (index > 0 && m_defaultRoute != 0)
14.413 - {
14.414 - index--;
14.415 - }
14.416 -
14.417 - if (index < m_hostRoutes.size ())
14.418 - {
14.419 - uint32_t tmp = 0;
14.420 - for (HostRoutesCI i = m_hostRoutes.begin () ; i != m_hostRoutes.end () ; i++)
14.421 - {
14.422 - if (tmp == index)
14.423 - {
14.424 - return *i;
14.425 - }
14.426 - tmp++;
14.427 - }
14.428 - }
14.429 -
14.430 - index -= m_hostRoutes.size ();
14.431 uint32_t tmp = 0;
14.432
14.433 - for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j++)
14.434 + for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
14.435 {
14.436 if (tmp == index)
14.437 {
14.438 - return *j;
14.439 + return it->first;
14.440 }
14.441 tmp++;
14.442 }
14.443 @@ -483,43 +429,36 @@
14.444 return 0;
14.445 }
14.446
14.447 +uint32_t Ipv6StaticRouting::GetMetric (uint32_t index)
14.448 +{
14.449 + NS_LOG_FUNCTION_NOARGS ();
14.450 + uint32_t tmp = 0;
14.451 +
14.452 + for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
14.453 + {
14.454 + if (tmp == index)
14.455 + {
14.456 + return it->second;
14.457 + }
14.458 + tmp++;
14.459 + }
14.460 + NS_ASSERT (false);
14.461 + // quiet compiler.
14.462 + return 0;
14.463 +}
14.464 +
14.465 +
14.466 void Ipv6StaticRouting::RemoveRoute (uint32_t index)
14.467 {
14.468 NS_LOG_FUNCTION (this << index);
14.469 - if (index == 0 && m_defaultRoute != 0)
14.470 - {
14.471 - delete m_defaultRoute;
14.472 - m_defaultRoute = 0;
14.473 - }
14.474 -
14.475 - if (index > 0 && m_defaultRoute != 0)
14.476 - {
14.477 - index--;
14.478 - }
14.479 -
14.480 - if (index < m_hostRoutes.size ())
14.481 - {
14.482 - uint32_t tmp = 0;
14.483 - for (HostRoutesI i = m_hostRoutes.begin () ; i != m_hostRoutes.end () ; i++)
14.484 - {
14.485 - if (tmp == index)
14.486 - {
14.487 - delete *i;
14.488 - m_hostRoutes.erase (i);
14.489 - return;
14.490 - }
14.491 - tmp++;
14.492 - }
14.493 - }
14.494 - index -= m_hostRoutes.size ();
14.495 uint32_t tmp = 0;
14.496 -
14.497 - for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j++)
14.498 +
14.499 + for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
14.500 {
14.501 if (tmp == index)
14.502 {
14.503 - delete *j;
14.504 - m_networkRoutes.erase (j);
14.505 + delete it->first;
14.506 + m_networkRoutes.erase (it);
14.507 return;
14.508 }
14.509 tmp++;
14.510 @@ -527,15 +466,18 @@
14.511 NS_ASSERT (false);
14.512 }
14.513
14.514 -void Ipv6StaticRouting::RemoveRoute (Ipv6Address network, Ipv6Prefix prefix, uint32_t ifIndex)
14.515 +void Ipv6StaticRouting::RemoveRoute (Ipv6Address network, Ipv6Prefix prefix, uint32_t ifIndex, Ipv6Address prefixToUse)
14.516 {
14.517 NS_LOG_FUNCTION (this << network << prefix << ifIndex);
14.518 - for (NetworkRoutesI i = m_networkRoutes.begin () ; i != m_networkRoutes.end () ; i++)
14.519 +
14.520 + for (NetworkRoutesI it = m_networkRoutes.begin () ; it != m_networkRoutes.end () ; it++)
14.521 {
14.522 - if (network == (*i)->GetDest () and (*i)->GetInterface () == ifIndex)
14.523 + Ipv6RoutingTableEntry* rtentry = it->first;
14.524 + if (network == rtentry->GetDest () && rtentry->GetInterface () == ifIndex &&
14.525 + rtentry->GetPrefixToUse () == prefixToUse)
14.526 {
14.527 - delete *i;
14.528 - m_networkRoutes.erase (i);
14.529 + delete it->first;
14.530 + m_networkRoutes.erase (it);
14.531 return;
14.532 }
14.533 }
14.534 @@ -557,7 +499,7 @@
14.535 // So, we just log it and fall through to LookupStatic ()
14.536 NS_LOG_LOGIC ("RouteOutput ()::Multicast destination");
14.537 }
14.538 -
14.539 +
14.540 rtentry = LookupStatic (destination, oif);
14.541 if (rtentry)
14.542 {
14.543 @@ -580,7 +522,8 @@
14.544 {
14.545 NS_LOG_LOGIC ("Multicast destination");
14.546 Ptr<Ipv6MulticastRoute> mrtentry = LookupStatic (ipHeader.GetSourceAddress (),
14.547 - ipHeader.GetDestinationAddress (), m_ipv6->GetInterfaceForDevice (idev));
14.548 + ipHeader.GetDestinationAddress ()
14.549 + , m_ipv6->GetInterfaceForDevice (idev));
14.550
14.551 if (mrtentry)
14.552 {
14.553 @@ -594,9 +537,9 @@
14.554 return false; // Let other routing protocols try to handle this
14.555 }
14.556 }
14.557 -//
14.558 -// This is a unicast packet. Check to see if we have a route for it.
14.559 -//
14.560 + //
14.561 + // This is a unicast packet. Check to see if we have a route for it.
14.562 + //
14.563 NS_LOG_LOGIC ("Unicast destination");
14.564 Ptr<Ipv6Route> rtentry = LookupStatic (ipHeader.GetDestinationAddress ());
14.565
14.566 @@ -618,7 +561,7 @@
14.567 for (uint32_t j = 0 ; j < m_ipv6->GetNAddresses (i) ; j++)
14.568 {
14.569 if (m_ipv6->GetAddress (i, j).GetAddress () != Ipv6Address () &&
14.570 - m_ipv6->GetAddress (i, j).GetPrefix () != Ipv6Prefix ())
14.571 + m_ipv6->GetAddress (i, j).GetPrefix () != Ipv6Prefix ())
14.572 {
14.573 if (m_ipv6->GetAddress (i, j).GetPrefix () == Ipv6Prefix (128))
14.574 {
14.575 @@ -628,7 +571,7 @@
14.576 else
14.577 {
14.578 AddNetworkRouteTo (m_ipv6->GetAddress (i, j).GetAddress ().CombinePrefix (m_ipv6->GetAddress (i, j).GetPrefix ()),
14.579 - m_ipv6->GetAddress (i, j).GetPrefix (), i);
14.580 + m_ipv6->GetAddress (i, j).GetPrefix (), i);
14.581 }
14.582 }
14.583 }
14.584 @@ -636,8 +579,12 @@
14.585
14.586 void Ipv6StaticRouting::NotifyInterfaceDown (uint32_t i)
14.587 {
14.588 + NS_LOG_FUNCTION (this << i);
14.589 + uint32_t j = 0;
14.590 + uint32_t max = GetNRoutes ();
14.591 +
14.592 /* remove all static routes that are going through this interface */
14.593 - for (uint32_t j = 0 ; j < GetNRoutes () ; j++)
14.594 + while (j < max)
14.595 {
14.596 Ipv6RoutingTableEntry route = GetRoute (j);
14.597
14.598 @@ -645,6 +592,10 @@
14.599 {
14.600 RemoveRoute (j);
14.601 }
14.602 + else
14.603 + {
14.604 + j++;
14.605 + }
14.606 }
14.607 }
14.608
14.609 @@ -673,13 +624,13 @@
14.610
14.611 Ipv6Address networkAddress = address.GetAddress ().CombinePrefix (address.GetPrefix ());
14.612 Ipv6Prefix networkMask = address.GetPrefix ();
14.613 -
14.614 +
14.615 // Remove all static routes that are going through this interface
14.616 // which reference this network
14.617 for (uint32_t j = 0 ; j < GetNRoutes () ; j++)
14.618 {
14.619 Ipv6RoutingTableEntry route = GetRoute (j);
14.620 -
14.621 +
14.622 if (route.GetInterface () == interface &&
14.623 route.IsNetwork () &&
14.624 route.GetDestNetwork () == networkAddress &&
14.625 @@ -693,11 +644,7 @@
14.626 void Ipv6StaticRouting::NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
14.627 {
14.628 NS_LOG_INFO (this << dst << mask << nextHop << interface << prefixToUse);
14.629 - if (mask == Ipv6Prefix (128))
14.630 - {
14.631 - AddHostRouteTo (dst, nextHop, interface);
14.632 - }
14.633 - else if (dst != Ipv6Address::GetZero ())
14.634 + if (dst != Ipv6Address::GetZero ())
14.635 {
14.636 AddNetworkRouteTo (dst, mask, nextHop, interface);
14.637 }
14.638 @@ -706,40 +653,24 @@
14.639 /* this case is mainly used by configuring default route following RA processing,
14.640 * in case of multipe prefix in RA, the first will configured default route
14.641 */
14.642 - if (!m_defaultRoute)
14.643 - {
14.644 - SetDefaultRoute (nextHop, interface, prefixToUse);
14.645 - }
14.646 + SetDefaultRoute (nextHop, interface, prefixToUse);
14.647 }
14.648 }
14.649
14.650 -void Ipv6StaticRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface)
14.651 +void Ipv6StaticRouting::NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse)
14.652 {
14.653 NS_LOG_FUNCTION (this << dst << mask << nextHop << interface);
14.654 - if (mask == Ipv6Prefix (128))
14.655 - {
14.656 - for (HostRoutesI j = m_hostRoutes.begin () ; j != m_hostRoutes.end () ; j++)
14.657 - {
14.658 - Ipv6Prefix prefix = (*j)->GetDestNetworkPrefix ();
14.659 - Ipv6Address entry = (*j)->GetDestNetwork ();
14.660 -
14.661 - if (dst == entry && prefix == mask && (*j)->GetInterface () == interface)
14.662 - {
14.663 - delete (*j);
14.664 - m_hostRoutes.erase (j);
14.665 - }
14.666 - }
14.667 - }
14.668 - else if (dst != Ipv6Address::GetZero ())
14.669 + if (dst != Ipv6Address::GetZero ())
14.670 {
14.671 for (NetworkRoutesI j = m_networkRoutes.begin () ; j != m_networkRoutes.end () ; j++)
14.672 {
14.673 - Ipv6Prefix prefix = (*j)->GetDestNetworkPrefix ();
14.674 - Ipv6Address entry = (*j)->GetDestNetwork ();
14.675 + Ipv6RoutingTableEntry* rtentry = j->first;
14.676 + Ipv6Prefix prefix = rtentry->GetDestNetworkPrefix ();
14.677 + Ipv6Address entry = rtentry->GetDestNetwork ();
14.678
14.679 - if (dst == entry && prefix == mask && (*j)->GetInterface () == interface)
14.680 + if (dst == entry && prefix == mask && rtentry->GetInterface () == interface)
14.681 {
14.682 - delete (*j);
14.683 + delete j->first;
14.684 m_networkRoutes.erase (j);
14.685 }
14.686 }
14.687 @@ -747,17 +678,7 @@
14.688 else
14.689 {
14.690 /* default route case */
14.691 - if (!m_defaultRoute)
14.692 - {
14.693 - return;
14.694 - }
14.695 -
14.696 - if (m_defaultRoute->GetInterface () == interface && m_defaultRoute->GetGateway () == nextHop)
14.697 - {
14.698 - NS_LOG_LOGIC ("Remove default route (maybe because autoconfigured address expired)");
14.699 - delete m_defaultRoute;
14.700 - m_defaultRoute = 0;
14.701 - }
14.702 + RemoveRoute (dst, mask, interface, prefixToUse);
14.703 }
14.704 }
14.705
14.706 @@ -785,7 +706,7 @@
14.707 return test.GetAddress ();
14.708 }
14.709 }
14.710 -
14.711 +
14.712 return ret;
14.713 }
14.714
15.1 --- a/src/routing/static-routing/ipv6-static-routing.h Mon Sep 07 11:59:10 2009 +0100
15.2 +++ b/src/routing/static-routing/ipv6-static-routing.h Mon Sep 07 18:03:01 2009 +0200
15.3 @@ -44,6 +44,9 @@
15.4 /**
15.5 * \ingroup routing
15.6 * \defgroup ipv6StaticRouting Ipv6StaticRouting
15.7 + */
15.8 +/**
15.9 + * \ingroup ipv6StaticRouting
15.10 * \class Ipv6StaticRouting
15.11 * \brief Static routing protocol for IP version 6 stack.
15.12 * \see Ipv6RoutingProtocol
15.13 @@ -74,15 +77,17 @@
15.14 * \param nextHop next hop address to route the packet
15.15 * \param interface interface index
15.16 * \param prefixToUse prefix that should be used for source address for this destination
15.17 + * \param metric metric of route in case of multiple routes to same destination
15.18 */
15.19 - void AddHostRouteTo (Ipv6Address dest, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address ("::"));
15.20 + void AddHostRouteTo (Ipv6Address dest, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address ("::"), uint32_t metric = 0);
15.21
15.22 /**
15.23 * \brief Add route to host.
15.24 * \param dest destination address.
15.25 * \param interface interface index
15.26 + * \param metric metric of route in case of multiple routes to same destination
15.27 */
15.28 - void AddHostRouteTo (Ipv6Address dest, uint32_t interface);
15.29 + void AddHostRouteTo (Ipv6Address dest, uint32_t interface, uint32_t metric = 0);
15.30
15.31 /**
15.32 * \brief Add route to network.
15.33 @@ -90,8 +95,9 @@
15.34 * \param networkPrefix network prefix*
15.35 * \param nextHop next hop address to route the packet
15.36 * \param interface interface index
15.37 + * \param metric metric of route in case of multiple routes to same destination
15.38 */
15.39 - void AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface);
15.40 + void AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, uint32_t metric = 0);
15.41
15.42 /**
15.43 * \brief Add route to network.
15.44 @@ -100,29 +106,27 @@
15.45 * \param nextHop next hop address to route the packet
15.46 * \param interface interface index
15.47 * \param prefixToUse prefix that should be used for source address for this destination
15.48 + * \param metric metric of route in case of multiple routes to same destination
15.49 */
15.50 - void AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse);
15.51 + void AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse, uint32_t metric = 0);
15.52
15.53 /**
15.54 * \brief Add route to network.
15.55 * \param network network address
15.56 * \param networkPrefix network prefix
15.57 * \param interface interface index
15.58 + * \param metric metric of route in case of multiple routes to same destination
15.59 */
15.60 - void AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface);
15.61 + void AddNetworkRouteTo (Ipv6Address network, Ipv6Prefix networkPrefix, uint32_t interface, uint32_t metric = 0);
15.62
15.63 /**
15.64 * \brief Set the default route.
15.65 * \param nextHop next hop address to route the packet
15.66 * \param interface interface index
15.67 * \param prefixToUse prefix to use (i.e for multihoming)
15.68 + * \param metric metric of route in case of multiple routes to same destination
15.69 */
15.70 - void SetDefaultRoute (Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address ("::"));
15.71 -
15.72 - /**
15.73 - * \brief Remove the default route.
15.74 - */
15.75 - void RemoveDefaultRoute ();
15.76 + void SetDefaultRoute (Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address ("::"), uint32_t metric = 0);
15.77
15.78 /**
15.79 * \brief Get the number or entries in the routing table.
15.80 @@ -132,6 +136,8 @@
15.81
15.82 /**
15.83 * \brief Get the default route.
15.84 + *
15.85 + * If multiple default routes exist, the one with lowest metric is returned.
15.86 * \return default Ipv6Route
15.87 */
15.88 Ipv6RoutingTableEntry GetDefaultRoute ();
15.89 @@ -143,6 +149,13 @@
15.90 */
15.91 Ipv6RoutingTableEntry GetRoute (uint32_t i);
15.92
15.93 + /**
15.94 + * \brief Get a metric for route from the static unicast routing table.
15.95 + * \param index The index (into the routing table) of the route to retrieve.
15.96 + * \return If route is set, the metric is returned. If not, an infinity metric (0xffffffff) is returned
15.97 + */
15.98 + uint32_t GetMetric (uint32_t index);
15.99 +
15.100 /**
15.101 * \brief Remove a route from the routing table.
15.102 * \param i index
15.103 @@ -154,8 +167,9 @@
15.104 * \param network IPv6 network
15.105 * \param prefix IPv6 prefix
15.106 * \param ifIndex interface index
15.107 + * \param prefixToUse IPv6 prefix to use with this route (multihoming)
15.108 */
15.109 - void RemoveRoute (Ipv6Address network, Ipv6Prefix prefix, uint32_t ifIndex);
15.110 + void RemoveRoute (Ipv6Address network, Ipv6Prefix prefix, uint32_t ifIndex, Ipv6Address prefixToUse);
15.111
15.112 /**
15.113 * \brief Add a multicast route for a given multicast source and group.
15.114 @@ -219,7 +233,7 @@
15.115 virtual void NotifyAddAddress (uint32_t interface, Ipv6InterfaceAddress address);
15.116 virtual void NotifyRemoveAddress (uint32_t interface, Ipv6InterfaceAddress address);
15.117 virtual void NotifyAddRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
15.118 - virtual void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface);
15.119 + virtual void NotifyRemoveRoute (Ipv6Address dst, Ipv6Prefix mask, Ipv6Address nextHop, uint32_t interface, Ipv6Address prefixToUse = Ipv6Address::GetZero ());
15.120 virtual void SetIpv6 (Ptr<Ipv6> ipv6);
15.121
15.122 protected:
15.123 @@ -229,12 +243,9 @@
15.124 void DoDispose ();
15.125
15.126 private:
15.127 - typedef std::list<Ipv6RoutingTableEntry *> HostRoutes;
15.128 - typedef std::list<Ipv6RoutingTableEntry *>::const_iterator HostRoutesCI;
15.129 - typedef std::list<Ipv6RoutingTableEntry *>::iterator HostRoutesI;
15.130 - typedef std::list<Ipv6RoutingTableEntry *> NetworkRoutes;
15.131 - typedef std::list<Ipv6RoutingTableEntry *>::const_iterator NetworkRoutesCI;
15.132 - typedef std::list<Ipv6RoutingTableEntry *>::iterator NetworkRoutesI;
15.133 + typedef std::list<std::pair <Ipv6RoutingTableEntry *, uint32_t> > NetworkRoutes;
15.134 + typedef std::list<std::pair <Ipv6RoutingTableEntry *, uint32_t> >::const_iterator NetworkRoutesCI;
15.135 + typedef std::list<std::pair <Ipv6RoutingTableEntry *, uint32_t> >::iterator NetworkRoutesI;
15.136
15.137 typedef std::list<Ipv6MulticastRoutingTableEntry *> MulticastRoutes;
15.138 typedef std::list<Ipv6MulticastRoutingTableEntry *>::const_iterator MulticastRoutesCI;
15.139 @@ -266,21 +277,11 @@
15.140 Ipv6Address SourceAddressSelection (uint32_t interface, Ipv6Address dest);
15.141
15.142 /**
15.143 - * \brief the forwarding table for hosts.
15.144 - */
15.145 - HostRoutes m_hostRoutes;
15.146 -
15.147 - /**
15.148 * \brief the forwarding table for network.
15.149 */
15.150 NetworkRoutes m_networkRoutes;
15.151
15.152 /**
15.153 - * \brief the default route.
15.154 - */
15.155 - Ipv6RoutingTableEntry *m_defaultRoute;
15.156 -
15.157 - /**
15.158 * \brief the forwarding table for multicast.
15.159 */
15.160 MulticastRoutes m_multicastRoutes;