From 4ba116b0f51bb0c8df387d66c95100c46dbe6ffe Mon Sep 17 00:00:00 2001 From: Pavel Boyko Date: Wed, 1 Apr 2009 14:05:21 +0400 Subject: [PATCH 1/3] HwmpRtable unit test + cleanup --- src/devices/mesh/dot11s/hwmp-mac-plugin.cc | 2 +- src/devices/mesh/dot11s/hwmp-protocol.cc | 4 +- src/devices/mesh/dot11s/hwmp-rtable.cc | 184 +++++++++++++++--- src/devices/mesh/dot11s/hwmp-rtable.h | 76 +++++--- src/devices/mesh/dot11s/hwmp-tag.cc | 2 +- .../mesh/dot11s/ie-dot11s-configuration.cc | 2 +- src/devices/mesh/dot11s/ie-dot11s-perr.cc | 2 +- src/devices/mesh/dot11s/ie-dot11s-prep.cc | 2 +- src/devices/mesh/dot11s/peer-link-frame.cc | 2 +- src/devices/mesh/dot11s/peer-link.cc | 2 +- 10 files changed, 219 insertions(+), 59 deletions(-) diff --git a/src/devices/mesh/dot11s/hwmp-mac-plugin.cc b/src/devices/mesh/dot11s/hwmp-mac-plugin.cc index 8ec1504f8..d7b854db0 100644 --- a/src/devices/mesh/dot11s/hwmp-mac-plugin.cc +++ b/src/devices/mesh/dot11s/hwmp-mac-plugin.cc @@ -57,7 +57,7 @@ HwmpMacPlugin::Receive (Ptr packet, const WifiMacHeader & header) { WifiMeshHeader meshHdr; HwmpTag tag; - NS_ASSERT(!packet->RemovePacketTag (tag)); + NS_ASSERT(! packet->PeekPacketTag (tag)); packet->RemoveHeader(meshHdr); //TODO: address extension Mac48Address destination; diff --git a/src/devices/mesh/dot11s/hwmp-protocol.cc b/src/devices/mesh/dot11s/hwmp-protocol.cc index 9489de557..743c1bc54 100644 --- a/src/devices/mesh/dot11s/hwmp-protocol.cc +++ b/src/devices/mesh/dot11s/hwmp-protocol.cc @@ -609,10 +609,10 @@ HwmpProtocol::MakePathError (Mac48Address retransmitter) std::vector > HwmpProtocol::GetPerrReceivers (std::vector failedDest) { - HwmpRtable::PRECURSOR_LIST retval; + HwmpRtable::PrecursorList retval; for (unsigned int i = 0; i < failedDest.size (); i ++) { - HwmpRtable::PRECURSOR_LIST precursors = m_rtable->GetPrecursors(failedDest[i].destination); + HwmpRtable::PrecursorList precursors = m_rtable->GetPrecursors(failedDest[i].destination); m_rtable->DeleteReactivePath (failedDest[i].destination); m_rtable->DeleteProactivePath(failedDest[i].destination); for (unsigned int j = 0; j < precursors.size (); j ++) diff --git a/src/devices/mesh/dot11s/hwmp-rtable.cc b/src/devices/mesh/dot11s/hwmp-rtable.cc index 035227553..e6f7aadce 100644 --- a/src/devices/mesh/dot11s/hwmp-rtable.cc +++ b/src/devices/mesh/dot11s/hwmp-rtable.cc @@ -22,34 +22,43 @@ #include "ns3/object.h" #include "ns3/assert.h" #include "ns3/simulator.h" +#include "ns3/test.h" +#include "ns3/log.h" + #include "hwmp-rtable.h" namespace ns3 { namespace dot11s { +NS_LOG_COMPONENT_DEFINE ("HwmpRtable"); + NS_OBJECT_ENSURE_REGISTERED (HwmpRtable); TypeId HwmpRtable::GetTypeId () { - static TypeId tid = TypeId ("ns3::HwmpRtable") + static TypeId tid = TypeId ("ns3::dot11s::HwmpRtable") .SetParent () .AddConstructor (); return tid; } + HwmpRtable::HwmpRtable () { DeleteProactivePath (); } + HwmpRtable::~HwmpRtable () { DoDispose (); } + void HwmpRtable::DoDispose () { m_routes.clear (); } + void HwmpRtable::AddReactivePath ( Mac48Address destination, @@ -68,7 +77,7 @@ HwmpRtable::AddReactivePath ( } else { - /** + /* * if outinterface differs from stored, routing info is * actual and metric is worse - we ignore this * information @@ -76,7 +85,7 @@ HwmpRtable::AddReactivePath ( if ( (i->second.interface != interface) && (i->second.metric < metric) && - /** + /* * The routing info is actual or it * was received from peer */ @@ -92,12 +101,13 @@ HwmpRtable::AddReactivePath ( if (lifetime != Seconds (0)) i->second.whenExpire = MilliSeconds (Simulator::Now().GetMilliSeconds() + lifetime.GetMilliSeconds()); else - /** + /* * Information about peer does not have lifetime */ i->second.whenExpire = Seconds (0); i->second.seqnum = seqnum; } + void HwmpRtable::AddProactivePath ( uint32_t metric, @@ -115,6 +125,7 @@ HwmpRtable::AddProactivePath ( m_root.seqnum = seqnum; m_root.interface = interface; } + void HwmpRtable::AddPrecursor (Mac48Address destination, uint32_t precursorInterface, Mac48Address precursorAddress) { @@ -126,7 +137,7 @@ HwmpRtable::AddPrecursor (Mac48Address destination, uint32_t precursorInterface, { bool should_add = true; for (unsigned int j = 0 ; j < i->second.precursors.size (); j ++) - //NB: nly one active route may exist, so even d not check + //NB: Only one active route may exist, so do not check //interface ID, just address if (i->second.precursors[j].second == precursorAddress) { @@ -142,6 +153,7 @@ HwmpRtable::AddPrecursor (Mac48Address destination, uint32_t precursorInterface, return; m_root.precursors.push_back(precursor); } + void HwmpRtable::DeleteProactivePath () { @@ -152,12 +164,14 @@ HwmpRtable::DeleteProactivePath () m_root.seqnum = 0; m_root.whenExpire = Simulator::Now (); } + void HwmpRtable::DeleteProactivePath (Mac48Address root) { if(m_root.root == root) DeleteProactivePath (); } + void HwmpRtable::DeleteReactivePath (Mac48Address destination) { @@ -165,34 +179,34 @@ HwmpRtable::DeleteReactivePath (Mac48Address destination) if (i != m_routes.end ()) m_routes.erase (i); } + HwmpRtable::LookupResult HwmpRtable::LookupReactive (Mac48Address destination) { LookupResult result; - result.retransmitter = Mac48Address::GetBroadcast (); - result.metric = MAX_METRIC; - result.ifIndex = INTERFACE_ANY; std::map::iterator i = m_routes.find (destination); if (i == m_routes.end ()) return result; + result.ifIndex = i->second.interface; //Seconds (0) means that this is routing - if (i->second.whenExpire < Simulator::Now ()) - if (i->second.retransmitter != destination) - return result; + if (i->second.whenExpire < Simulator::Now () && i->second.retransmitter != destination) + { + NS_LOG_DEBUG ("Reactive route has expired, sorry."); + return LookupResult();+ + } + result.retransmitter = i->second.retransmitter; result.metric = i->second.metric; result.seqnum = i->second.seqnum; return result; } + HwmpRtable::LookupResult HwmpRtable::LookupReactiveExpired (Mac48Address destination) { LookupResult result; - result.retransmitter = Mac48Address::GetBroadcast (); - result.metric = MAX_METRIC; - result.ifIndex = INTERFACE_ANY; std::map::iterator i = m_routes.find (destination); if (i == m_routes.end ()) @@ -208,24 +222,21 @@ HwmpRtable::LookupResult HwmpRtable::LookupProactive () { if (m_root.whenExpire < Simulator::Now ()) - DeleteProactivePath (); - LookupResult retval; - retval.retransmitter = m_root.retransmitter; - retval.ifIndex = m_root.interface; - retval.metric = m_root.metric; - retval.seqnum = m_root.seqnum; - return retval; + { + NS_LOG_DEBUG ("Proactive route has expired and will be deleted, sorry."); + DeleteProactivePath (); + } + + return LookupProactiveExpired (); } + HwmpRtable::LookupResult HwmpRtable::LookupProactiveExpired () { - LookupResult retval; - retval.retransmitter = m_root.retransmitter; - retval.ifIndex = m_root.interface; - retval.metric = m_root.metric; - retval.seqnum = m_root.seqnum; + LookupResult retval (m_root.retransmitter, m_root.interface, m_root.metric, m_root.seqnum); return retval; } + std::vector HwmpRtable::GetUnreachableDestinations (Mac48Address peerAddress) { @@ -248,11 +259,12 @@ HwmpRtable::GetUnreachableDestinations (Mac48Address peerAddress) } return retval; } -HwmpRtable::PRECURSOR_LIST + +HwmpRtable::PrecursorList HwmpRtable::GetPrecursors (Mac48Address destination) { //We suppose that no dublicates here can be - PRECURSOR_LIST retval; + PrecursorList retval; std::map::iterator route = m_routes.find (destination); if (route != m_routes.end ()) for (unsigned int i = 0; i < route->second.precursors.size (); i ++) @@ -272,5 +284,121 @@ HwmpRtable::GetPrecursors (Mac48Address destination) } return retval; } + +bool HwmpRtable::LookupResult::operator==(const HwmpRtable::LookupResult & o) const +{ + return (retransmitter == o.retransmitter + && ifIndex == o.ifIndex + && metric == o.metric + && seqnum == o.seqnum + ); +} + +bool HwmpRtable::LookupResult::IsValid() const +{ + return !( retransmitter == Mac48Address::GetBroadcast () + && ifIndex == INTERFACE_ANY + && metric == MAX_METRIC + && seqnum == 0 + ); +} + +#ifdef RUN_SELF_TESTS + +/// Unit test for HwmpRtable +class HwmpRtableTest : public Test +{ +public: + HwmpRtableTest (); + virtual bool RunTests(); + +private: + void Test1 (); + void Test2 (); + void Test3 (); + void Test4 (); + +private: + bool result; + + Mac48Address dst; + Mac48Address hop; + uint32_t iface; + uint32_t metric; + uint32_t seqnum; + Time expire; + Ptr table; +}; + +/// Test instance +static HwmpRtableTest g_HwmpRtableTest; + +HwmpRtableTest::HwmpRtableTest () : Test ("Mesh/802.11s/HwmpRtable"), + result(true), + dst ("01:00:00:01:00:01"), + hop ("01:00:00:01:00:03"), + iface (8010), + metric (10), + seqnum (1), + expire (Seconds (10)) +{ +} + +void HwmpRtableTest::Test1 () +{ + HwmpRtable::LookupResult correct (hop, iface, metric, seqnum); + + // Reactive path + table->AddReactivePath (dst, hop, iface, metric, expire, seqnum); + NS_TEST_ASSERT (table->LookupReactive (dst) == correct); + table->DeleteReactivePath (dst); + NS_TEST_ASSERT (! table->LookupReactive (dst).IsValid ()); + + // Proactive + table->AddProactivePath (metric, dst, hop, iface, expire, seqnum); + NS_TEST_ASSERT (table->LookupProactive () == correct); + table->DeleteProactivePath (dst); + NS_TEST_ASSERT (! table->LookupProactive ().IsValid ()); +} + +void HwmpRtableTest::Test2 () +{ + table->AddReactivePath (dst, hop, iface, metric, expire, seqnum); + table->AddProactivePath (metric, dst, hop, iface, expire, seqnum); +} + +void HwmpRtableTest::Test3 () +{ + // this is assumed to be called when path records are already expired + HwmpRtable::LookupResult correct (hop, iface, metric, seqnum); + NS_TEST_ASSERT (table->LookupReactiveExpired (dst) == correct); + NS_TEST_ASSERT (table->LookupProactiveExpired () == correct); + + NS_TEST_ASSERT (! table->LookupReactive (dst).IsValid ()); + NS_TEST_ASSERT (! table->LookupProactive ().IsValid ()); +} + +void HwmpRtableTest::Test4 () +{ + // TODO: test AddPrecursor and GetPrecursors +} + +bool HwmpRtableTest::RunTests () +{ + table = CreateObject (); + + Simulator::Schedule (Seconds (0), & HwmpRtableTest::Test1, this); + Simulator::Schedule (Seconds (1), & HwmpRtableTest::Test2, this); + Simulator::Schedule (expire + Seconds (2), & HwmpRtableTest::Test3, this); + Simulator::Schedule (expire + Seconds (3), & HwmpRtableTest::Test4, this); + + Simulator::Run (); + Simulator::Destroy (); + + return result; +} + +#endif // RUN_SELF_TESTS + } //namespace dot11s } //namespace ns3 diff --git a/src/devices/mesh/dot11s/hwmp-rtable.h b/src/devices/mesh/dot11s/hwmp-rtable.h index 0e6a9787b..ef49e4eaf 100644 --- a/src/devices/mesh/dot11s/hwmp-rtable.h +++ b/src/devices/mesh/dot11s/hwmp-rtable.h @@ -32,16 +32,50 @@ namespace dot11s { * \ingroup dot11s * * \brief Routing table for HWMP -- 802.11s routing protocol - * - * TODO: comment all methods */ class HwmpRtable : public Object { +public: + /// Means all interfaces + const static uint32_t INTERFACE_ANY = 0xffffffff; + /// Maximum (the best?) path metric + const static uint32_t MAX_METRIC = 0xffffffff; + + /// Route lookup result, return type of LookupXXX methods + struct LookupResult + { + Mac48Address retransmitter; + uint32_t ifIndex; + uint32_t metric; + uint32_t seqnum; + + LookupResult(Mac48Address r = Mac48Address::GetBroadcast (), + uint32_t i = INTERFACE_ANY, + uint32_t m = MAX_METRIC, + uint32_t s = 0) + : retransmitter (r), + ifIndex (i), + metric (m), + seqnum (s) + { + } + + /// True for valid route + bool IsValid() const; + /// Compare route lookup results, used by tests + bool operator==(const LookupResult & o) const; + }; + /// Path precursor = {MAC, interface ID} + typedef std::vector > PrecursorList; + public: static TypeId GetTypeId (); HwmpRtable (); ~HwmpRtable (); void DoDispose (); + + ///\name Add/delete paths + //\{ void AddReactivePath ( Mac48Address destination, Mac48Address retransmitter, @@ -59,35 +93,29 @@ public: uint32_t seqnum ); void AddPrecursor (Mac48Address destination, uint32_t precursorInterface, Mac48Address precursorAddress); + PrecursorList GetPrecursors (Mac48Address destination); void DeleteProactivePath (); void DeleteProactivePath (Mac48Address root); void DeleteReactivePath (Mac48Address destination); + //\} - struct LookupResult - { - Mac48Address retransmitter; - uint32_t ifIndex; - uint32_t metric; - uint32_t seqnum; - }; - + ///\name Lookup + //\{ + /// Lookup path to destination LookupResult LookupReactive (Mac48Address destination); + /// Return all reactive paths, including expired LookupResult LookupReactiveExpired (Mac48Address destination); + /// Find proactive path to tree root. Note that calling this method has side effect of deleting expired proactive path LookupResult LookupProactive (); + /// Return all proactive paths, including expired LookupResult LookupProactiveExpired (); - //path error routines: - ///\brief When peer link with a given MAC-address fails - it returns list of unreachable - //destination addresses - std::vector GetUnreachableDestinations (Mac48Address peerAddress); - ///\brief When we talk about multi-interface HWMP, 'precursor' means - //not only address but also an interface ID - //So, when we request "precursor list", we mean that this list will - //consist of interface ID and addresses - typedef std::vector > PRECURSOR_LIST; - PRECURSOR_LIST GetPrecursors (Mac48Address destination); - const static uint32_t INTERFACE_ANY = 0xffffffff; - const static uint32_t MAX_METRIC = 0xffffffff; + //\} + + /// When peer link with a given MAC-address fails - it returns list of unreachable destination addresses + std::vector GetUnreachableDestinations (Mac48Address peerAddress); + private: + /// Route found in reactive mode struct ReactiveRoute { Mac48Address retransmitter; @@ -97,6 +125,7 @@ private: uint32_t seqnum; std::vector > precursors; }; + /// Route fond in proactive mode struct ProactiveRoute { Mac48Address root; @@ -107,7 +136,10 @@ private: uint32_t seqnum; std::vector > precursors; }; + + /// List of routes std::map m_routes; + /// Path to proactive tree root MP ProactiveRoute m_root; }; } //namespace dot11s diff --git a/src/devices/mesh/dot11s/hwmp-tag.cc b/src/devices/mesh/dot11s/hwmp-tag.cc index ee25749e5..772950c90 100644 --- a/src/devices/mesh/dot11s/hwmp-tag.cc +++ b/src/devices/mesh/dot11s/hwmp-tag.cc @@ -85,7 +85,7 @@ HwmpTag::GetSeqno () TypeId HwmpTag::GetTypeId () { - static TypeId tid = TypeId ("ns3::HwmpTag") + static TypeId tid = TypeId ("ns3::dot11s::HwmpTag") .SetParent () .AddConstructor (); return tid; diff --git a/src/devices/mesh/dot11s/ie-dot11s-configuration.cc b/src/devices/mesh/dot11s/ie-dot11s-configuration.cc index c09ed881e..e10267ffa 100644 --- a/src/devices/mesh/dot11s/ie-dot11s-configuration.cc +++ b/src/devices/mesh/dot11s/ie-dot11s-configuration.cc @@ -86,7 +86,7 @@ IeConfiguration::IeConfiguration (): TypeId IeConfiguration::GetTypeId () { - static TypeId tid = TypeId ("ns3::IeConfiguration") + static TypeId tid = TypeId ("ns3::dot11s::IeConfiguration") .SetParent (); return tid; } diff --git a/src/devices/mesh/dot11s/ie-dot11s-perr.cc b/src/devices/mesh/dot11s/ie-dot11s-perr.cc index b015769aa..dfce07583 100644 --- a/src/devices/mesh/dot11s/ie-dot11s-perr.cc +++ b/src/devices/mesh/dot11s/ie-dot11s-perr.cc @@ -32,7 +32,7 @@ IePerr::~IePerr () TypeId IePerr::GetTypeId () { - static TypeId tid = TypeId ("ns3::IePerr") + static TypeId tid = TypeId ("ns3::dot11s::IePerr") .SetParent (); return tid; } diff --git a/src/devices/mesh/dot11s/ie-dot11s-prep.cc b/src/devices/mesh/dot11s/ie-dot11s-prep.cc index b5eb57f5b..6735f430b 100644 --- a/src/devices/mesh/dot11s/ie-dot11s-prep.cc +++ b/src/devices/mesh/dot11s/ie-dot11s-prep.cc @@ -35,7 +35,7 @@ IePrep::~IePrep () TypeId IePrep::GetTypeId () { - static TypeId tid = TypeId ("ns3::IePrep") + static TypeId tid = TypeId ("ns3::dot11s::IePrep") .SetParent (); return tid; } diff --git a/src/devices/mesh/dot11s/peer-link-frame.cc b/src/devices/mesh/dot11s/peer-link-frame.cc index f00de3d25..b957e99fb 100644 --- a/src/devices/mesh/dot11s/peer-link-frame.cc +++ b/src/devices/mesh/dot11s/peer-link-frame.cc @@ -58,7 +58,7 @@ TypeId PeerLinkFrameStart::GetTypeId () { static TypeId tid = - TypeId ("ns3::PeerLinkFrameStart") + TypeId ("ns3::dot11s::PeerLinkFrameStart") .SetParent
() .AddConstructor () ; diff --git a/src/devices/mesh/dot11s/peer-link.cc b/src/devices/mesh/dot11s/peer-link.cc index c73f33f6e..526b8ab88 100644 --- a/src/devices/mesh/dot11s/peer-link.cc +++ b/src/devices/mesh/dot11s/peer-link.cc @@ -35,7 +35,7 @@ NS_OBJECT_ENSURE_REGISTERED(PeerLink); TypeId PeerLink::GetTypeId() { - static TypeId tid = TypeId ("ns3::PeerLink") + static TypeId tid = TypeId ("ns3::dot11s::PeerLink") .SetParent () .AddConstructor () .AddAttribute ("RetryTimeout", "Retry timeout", From dd699e5338b8dfac42317f111858b816eaa5d7f9 Mon Sep 17 00:00:00 2001 From: Pavel Boyko Date: Wed, 1 Apr 2009 14:08:52 +0400 Subject: [PATCH 2/3] Build fix --- src/devices/mesh/dot11s/hwmp-rtable.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devices/mesh/dot11s/hwmp-rtable.cc b/src/devices/mesh/dot11s/hwmp-rtable.cc index e6f7aadce..744c7b80c 100644 --- a/src/devices/mesh/dot11s/hwmp-rtable.cc +++ b/src/devices/mesh/dot11s/hwmp-rtable.cc @@ -194,7 +194,7 @@ HwmpRtable::LookupReactive (Mac48Address destination) if (i->second.whenExpire < Simulator::Now () && i->second.retransmitter != destination) { NS_LOG_DEBUG ("Reactive route has expired, sorry."); - return LookupResult();+ + return LookupResult(); } result.retransmitter = i->second.retransmitter; From df751a24e755755fd990b74f663a39277ef1657f Mon Sep 17 00:00:00 2001 From: Pavel Boyko Date: Wed, 1 Apr 2009 14:12:53 +0400 Subject: [PATCH 3/3] Old HWMP routing table test removed from examples. --- examples/routing-table-test.cc | 293 --------------------------------- examples/wscript | 4 - 2 files changed, 297 deletions(-) delete mode 100644 examples/routing-table-test.cc diff --git a/examples/routing-table-test.cc b/examples/routing-table-test.cc deleted file mode 100644 index eeae80dff..000000000 --- a/examples/routing-table-test.cc +++ /dev/null @@ -1,293 +0,0 @@ -/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ -/* - * Copyright (c) 2009 IITP RAS - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Author: Kirill Andreev - */ - - -#include -#include -#include "ns3/core-module.h" -#include -#include "ns3/mac48-address.h" -#include "ns3/simulator-module.h" -#include -#include "ns3/hwmp-rtable.h" - - - -using namespace ns3; - -NS_LOG_COMPONENT_DEFINE ("RoutingTableTest"); - - -void -aux_function (Ptr ptr, Mac48Address addr, std::vector *results, std::vector