From decb42890ff2f07e2d22cb16de79d6deb7fd9e0d Mon Sep 17 00:00:00 2001 From: Tom Henderson Date: Sat, 13 Jun 2009 14:59:35 -0700 Subject: [PATCH] Fix bug 587 for ListRoutingProtocol bug; add unit test --- src/internet-stack/ipv4-list-routing.cc | 120 +++++++++++++++++++++--- src/internet-stack/ipv4-list-routing.h | 7 +- 2 files changed, 112 insertions(+), 15 deletions(-) diff --git a/src/internet-stack/ipv4-list-routing.cc b/src/internet-stack/ipv4-list-routing.cc index f4fa2a33b..2bd38848b 100644 --- a/src/internet-stack/ipv4-list-routing.cc +++ b/src/internet-stack/ipv4-list-routing.cc @@ -74,9 +74,10 @@ Ipv4ListRouting::RouteOutput (const Ipv4Header &header, uint32_t oif, enum Socke NS_LOG_FUNCTION (this << header.GetDestination () << " " << header.GetSource () << " " << oif); Ptr route; - for (Ipv4RoutingProtocolList::const_iterator i = m_routingProtocols.begin (); - i != m_routingProtocols.end (); - i++) + // Sorted lists are stored in lowest to highest order, so since we + // want to iterate from highest to lowest, use a reverse iterator + for (Ipv4RoutingProtocolList::const_reverse_iterator i = m_routingProtocols.rbegin (); + i != m_routingProtocols.rend (); i++) { NS_LOG_LOGIC ("Checking protocol " << (*i).second->GetInstanceTypeId () << " with priority " << (*i).first); NS_LOG_LOGIC ("Requesting source address for destination " << header.GetDestination ()); @@ -124,9 +125,11 @@ Ipv4ListRouting::RouteInput (Ptr p, const Ipv4Header &header, Ptr< // Fall through-- we may also need to forward this retVal = true; } - for (Ipv4RoutingProtocolList::const_iterator rprotoIter = - m_routingProtocols.begin (); - rprotoIter != m_routingProtocols.end (); + // Sorted lists are stored in lowest to highest order, so since we + // want to iterate from highest to lowest, use a reverse iterator + for (Ipv4RoutingProtocolList::const_reverse_iterator rprotoIter = + m_routingProtocols.rbegin (); + rprotoIter != m_routingProtocols.rend (); rprotoIter++) { NS_LOG_LOGIC ("Multicast packet for me-- trying to forward"); @@ -179,10 +182,12 @@ Ipv4ListRouting::RouteInput (Ptr p, const Ipv4Header &header, Ptr< NS_LOG_LOGIC ("Address "<< addr << " not a match"); } } - // Next, try to find a route - for (Ipv4RoutingProtocolList::const_iterator rprotoIter = - m_routingProtocols.begin (); - rprotoIter != m_routingProtocols.end (); + // Next, try to find a route + // Sorted lists are stored in lowest to highest order, so since we + // want to iterate from highest to lowest, use a reverse iterator + for (Ipv4RoutingProtocolList::const_reverse_iterator rprotoIter = + m_routingProtocols.rbegin (); + rprotoIter != m_routingProtocols.rend (); rprotoIter++) { if ((*rprotoIter).second->RouteInput (p, header, idev, ucb, mcb, lcb, ecb)) @@ -261,7 +266,7 @@ void Ipv4ListRouting::AddRoutingProtocol (Ptr routingProtocol, int16_t priority) { NS_LOG_FUNCTION (this << routingProtocol->GetInstanceTypeId () << priority); - m_routingProtocols.push_back (std::make_pair (-priority, routingProtocol)); + m_routingProtocols.push_back (std::make_pair (priority, routingProtocol)); m_routingProtocols.sort (); if (m_ipv4 != 0) { @@ -285,8 +290,10 @@ Ipv4ListRouting::GetRoutingProtocol (uint32_t index, int16_t& priority) const NS_FATAL_ERROR ("Ipv4ListRouting::GetRoutingProtocol(): index " << index << " out of range"); } uint32_t i = 0; - for (Ipv4RoutingProtocolList::const_iterator rprotoIter = m_routingProtocols.begin (); - rprotoIter != m_routingProtocols.end (); rprotoIter++, i++) + // Sorted lists are stored in lowest to highest order, so since we + // want to iterate from highest to lowest, use a reverse iterator + for (Ipv4RoutingProtocolList::const_reverse_iterator rprotoIter = m_routingProtocols.rbegin (); + rprotoIter != m_routingProtocols.rend (); rprotoIter++, i++) { if (i == index) { @@ -318,4 +325,89 @@ Ipv4ListRouting::GetStaticRouting (void) const } -}//namespace ns3 +} // namespace ns3 + +#ifdef RUN_SELF_TESTS + +#include "ns3/test.h" +#include "ipv4-list-routing.h" +#include "ns3/ipv4-routing-protocol.h" + +namespace ns3 { + +class Ipv4ARouting : public Ipv4RoutingProtocol { +public: + Ptr RouteOutput (const Ipv4Header &header, uint32_t oif, Socket::SocketErrno &sockerr) { return 0;} + bool RouteInput (Ptr p, const Ipv4Header &header, Ptr idev, + UnicastForwardCallback ucb, MulticastForwardCallback mcb, + LocalDeliverCallback lcb, ErrorCallback ecb) {return false;} + void NotifyInterfaceUp (uint32_t interface) {} + void NotifyInterfaceDown (uint32_t interface) {} + void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address) {} + void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address) {} + void SetIpv4 (Ptr ipv4) {} +}; + +class Ipv4BRouting : public Ipv4RoutingProtocol { +public: + Ptr RouteOutput (const Ipv4Header &header, uint32_t oif, Socket::SocketErrno &sockerr) { return 0;} + bool RouteInput (Ptr p, const Ipv4Header &header, Ptr idev, + UnicastForwardCallback ucb, MulticastForwardCallback mcb, + LocalDeliverCallback lcb, ErrorCallback ecb) {return false;} + void NotifyInterfaceUp (uint32_t interface) {} + void NotifyInterfaceDown (uint32_t interface) {} + void NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address) {} + void NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address) {} + void SetIpv4 (Ptr ipv4) {} +}; + +class Ipv4ListRoutingTest: public Test { +public: + virtual bool RunTests (void); + Ipv4ListRoutingTest (); +}; + +Ipv4ListRoutingTest::Ipv4ListRoutingTest () + : Test ("Ipv4ListRouting") {} + +bool +Ipv4ListRoutingTest::RunTests (void) +{ + bool result = true; + Ptr lr = CreateObject (); + Ptr aRouting = CreateObject (); + Ptr bRouting = CreateObject (); + // The Ipv4ARouting should be added with higher priority (larger integer + // value) and will be fetched first below + lr->AddRoutingProtocol (aRouting, 10); + lr->AddRoutingProtocol (bRouting, 5); + int16_t first = 3; + int16_t second = 3; + uint32_t num = lr->GetNRoutingProtocols (); + NS_TEST_ASSERT_EQUAL (num, 2); + Ptr firstRp = lr->GetRoutingProtocol (0, first); + NS_TEST_ASSERT_EQUAL (10, first); + NS_TEST_ASSERT_EQUAL (firstRp, aRouting); + Ptr secondRp = lr->GetRoutingProtocol (1, second); + NS_TEST_ASSERT_EQUAL (5, second); + NS_TEST_ASSERT_EQUAL (secondRp, bRouting); + + // Test negative values + lr = CreateObject (); + // The Ipv4BRouting should be added with higher priority (larger integer value) + lr->AddRoutingProtocol (aRouting, -10); + lr->AddRoutingProtocol (bRouting, -5); + num = lr->GetNRoutingProtocols (); + NS_TEST_ASSERT_EQUAL (num, 2); + firstRp = lr->GetRoutingProtocol (0, first); + NS_TEST_ASSERT_EQUAL (-5, first); + NS_TEST_ASSERT_EQUAL (firstRp, bRouting); + + return result; +} + +static Ipv4ListRoutingTest gIpv4ListRoutingTest; + +} // namespace ns3 + +#endif /* RUN_SELF_TESTS */ diff --git a/src/internet-stack/ipv4-list-routing.h b/src/internet-stack/ipv4-list-routing.h index e350f9b4d..f49a54f5a 100644 --- a/src/internet-stack/ipv4-list-routing.h +++ b/src/internet-stack/ipv4-list-routing.h @@ -32,7 +32,7 @@ class Ipv4StaticRouting; * This class is a specialization of Ipv4RoutingProtocol that allows * other instances of Ipv4RoutingProtocol to be inserted in a * prioritized list. Routing protocols in the list are consulted one - * by one, from highest to lowest proirity, until a routing protocol + * by one, from highest to lowest priority, until a routing protocol * is found that will take the packet (this corresponds to a non-zero * return value to RouteOutput, or a return value of true to RouteInput). * The order by which routing protocols with the same priority value @@ -60,6 +60,11 @@ public: */ virtual uint32_t GetNRoutingProtocols (void) const; /** + * Return pointer to routing protocol stored at index, with the + * first protocol (index 0) the highest priority, the next one (index 1) + * the second highest priority, and so on. The priority parameter is an + * output parameter and it returns the integer priority of the protocol. + * * \return pointer to routing protocol indexed by * \param index index of protocol to return * \param priority output parameter, set to the priority of the protocol