src/devices/mesh/dot11s/hwmp-rtable.cc
changeset 5129 5688b8da4526
parent 5079 245215e5e6ed
child 5130 b5062e8e0da1
equal deleted inserted replaced
5128:d6e168eba404 5129:5688b8da4526
    16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    17  *
    17  *
    18  * Author: Kirill Andreev <andreev@iitp.ru>
    18  * Author: Kirill Andreev <andreev@iitp.ru>
    19  */
    19  */
    20 
    20 
    21 
       
    22 #include "ns3/object.h"
    21 #include "ns3/object.h"
    23 #include "ns3/assert.h"
    22 #include "ns3/assert.h"
    24 #include "ns3/simulator.h"
    23 #include "ns3/simulator.h"
    25 #include "ns3/test.h"
    24 #include "ns3/test.h"
    26 #include "ns3/log.h"
    25 #include "ns3/log.h"
    27 
    26 
    28 #include "hwmp-rtable.h"
    27 #include "hwmp-rtable.h"
    29 
    28 
    30 namespace ns3 {
    29 namespace ns3
    31 namespace dot11s {
    30 {
       
    31 namespace dot11s
       
    32 {
    32 
    33 
    33 NS_LOG_COMPONENT_DEFINE ("HwmpRtable");
    34 NS_LOG_COMPONENT_DEFINE ("HwmpRtable");
    34   
    35 
    35 NS_OBJECT_ENSURE_REGISTERED (HwmpRtable);
    36 NS_OBJECT_ENSURE_REGISTERED (HwmpRtable);
    36 
    37 
    37 TypeId
    38 TypeId
    38 HwmpRtable::GetTypeId ()
    39 HwmpRtable::GetTypeId ()
    39 {
    40 {
    53 HwmpRtable::DoDispose ()
    54 HwmpRtable::DoDispose ()
    54 {
    55 {
    55   m_routes.clear ();
    56   m_routes.clear ();
    56 }
    57 }
    57 void
    58 void
    58 HwmpRtable::AddReactivePath (
    59 HwmpRtable::AddReactivePath (Mac48Address destination, Mac48Address retransmitter, uint32_t interface,
    59   Mac48Address destination,
    60     uint32_t metric, Time lifetime, uint32_t seqnum)
    60   Mac48Address retransmitter,
       
    61   uint32_t interface,
       
    62   uint32_t metric,
       
    63   Time  lifetime,
       
    64   uint32_t seqnum
       
    65 )
       
    66 {
    61 {
    67   std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.find (destination);
    62   std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.find (destination);
    68   if (i == m_routes.end ())
    63   if (i == m_routes.end ())
    69     {
    64     {
    70       ReactiveRoute newroute;
    65       ReactiveRoute newroute;
    71       m_routes[destination] = newroute;
    66       m_routes[destination] = newroute;
    72     }
    67     }
    73   i = m_routes.find (destination);
    68   i = m_routes.find (destination);
    74   NS_ASSERT (i != m_routes.end());
    69   NS_ASSERT (i != m_routes.end ());
    75   i->second.retransmitter = retransmitter;
    70   i->second.retransmitter = retransmitter;
    76   i->second.interface = interface;
    71   i->second.interface = interface;
    77   i->second.metric = metric;
    72   i->second.metric = metric;
    78   i->second.whenExpire = Simulator::Now() + lifetime;
    73   i->second.whenExpire = Simulator::Now () + lifetime;
    79   i->second.seqnum = seqnum;
    74   i->second.seqnum = seqnum;
    80 }
    75 }
    81 void
    76 void
    82 HwmpRtable::AddProactivePath (
    77 HwmpRtable::AddProactivePath (uint32_t metric, Mac48Address root, Mac48Address retransmitter,
    83   uint32_t metric,
    78     uint32_t interface, Time lifetime, uint32_t seqnum)
    84   Mac48Address root,
       
    85   Mac48Address retransmitter,
       
    86   uint32_t interface,
       
    87   Time  lifetime,
       
    88   uint32_t seqnum
       
    89 )
       
    90 {
    79 {
    91   m_root.root = root;
    80   m_root.root = root;
    92   m_root.retransmitter = retransmitter;
    81   m_root.retransmitter = retransmitter;
    93   m_root.metric = metric;
    82   m_root.metric = metric;
    94   m_root.whenExpire = Simulator::Now() + lifetime;
    83   m_root.whenExpire = Simulator::Now () + lifetime;
    95   m_root.seqnum = seqnum;
    84   m_root.seqnum = seqnum;
    96   m_root.interface = interface;
    85   m_root.interface = interface;
    97 }
    86 }
    98 void
    87 void
    99 HwmpRtable::AddPrecursor (Mac48Address destination, uint32_t precursorInterface, Mac48Address precursorAddress)
    88 HwmpRtable::AddPrecursor (Mac48Address destination, uint32_t precursorInterface,
       
    89     Mac48Address precursorAddress)
   100 {
    90 {
   101   std::pair<uint32_t, Mac48Address> precursor;
    91   std::pair<uint32_t, Mac48Address> precursor;
   102   precursor.first = precursorInterface;
    92   precursor.first = precursorInterface;
   103   precursor.second = precursorAddress;
    93   precursor.second = precursorAddress;
   104   std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.find (destination);
    94   std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.find (destination);
   105   if (i != m_routes.end ())
    95   if (i != m_routes.end ())
   106     {
    96     {
   107       bool should_add = true;
    97       bool should_add = true;
   108       for (unsigned int j = 0 ; j < i->second.precursors.size (); j ++)
    98       for (unsigned int j = 0; j < i->second.precursors.size (); j++)
   109         //NB: Only one active route may exist, so do not check
    99         //NB: Only one active route may exist, so do not check
   110         //interface ID, just address
   100         //interface ID, just address
   111         if (i->second.precursors[j].second == precursorAddress)
   101         if (i->second.precursors[j].second == precursorAddress)
   112           {
   102           {
   113             should_add = false;
   103             should_add = false;
   114             break;
   104             break;
   115           }
   105           }
   116       if (should_add)
   106       if (should_add)
   117         i->second.precursors.push_back (precursor);
   107         {
   118     }
   108           i->second.precursors.push_back (precursor);
   119   if(m_root.root == destination)
   109         }
   120     for (unsigned int j = 0 ; j < m_root.precursors.size (); j ++)
   110     }
   121       if (m_root.precursors[j].second == precursorAddress)
   111   if (m_root.root == destination)
   122         return;
   112     {
   123   m_root.precursors.push_back(precursor);
   113       for (unsigned int j = 0; j < m_root.precursors.size (); j++)
       
   114         {
       
   115           if (m_root.precursors[j].second == precursorAddress)
       
   116             {
       
   117               return;
       
   118             }
       
   119         }
       
   120     }
       
   121   m_root.precursors.push_back (precursor);
   124 }
   122 }
   125 void
   123 void
   126 HwmpRtable::DeleteProactivePath ()
   124 HwmpRtable::DeleteProactivePath ()
   127 {
   125 {
   128   m_root.precursors.clear ();
   126   m_root.precursors.clear ();
   133   m_root.whenExpire = Simulator::Now ();
   131   m_root.whenExpire = Simulator::Now ();
   134 }
   132 }
   135 void
   133 void
   136 HwmpRtable::DeleteProactivePath (Mac48Address root)
   134 HwmpRtable::DeleteProactivePath (Mac48Address root)
   137 {
   135 {
   138   if(m_root.root == root)
   136   if (m_root.root == root)
   139     DeleteProactivePath ();
   137     DeleteProactivePath ();
   140 }
   138 }
   141 void
   139 void
   142 HwmpRtable::DeleteReactivePath (Mac48Address destination)
   140 HwmpRtable::DeleteReactivePath (Mac48Address destination)
   143 {
   141 {
   144   std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.find (destination);
   142   std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.find (destination);
   145   if (i != m_routes.end ())
   143   if (i != m_routes.end ())
   146     m_routes.erase (i);
   144     {
       
   145       m_routes.erase (i);
       
   146     }
   147 }
   147 }
   148 HwmpRtable::LookupResult
   148 HwmpRtable::LookupResult
   149 HwmpRtable::LookupReactive (Mac48Address destination)
   149 HwmpRtable::LookupReactive (Mac48Address destination)
   150 {
   150 {
   151   std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.find (destination);
   151   std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.find (destination);
   152   if (i == m_routes.end ())
   152   if (i == m_routes.end ())
   153     return LookupResult ();
   153     {
       
   154       return LookupResult ();
       
   155     }
   154   if ((i->second.whenExpire < Simulator::Now ()) && (i->second.whenExpire != Seconds (0)))
   156   if ((i->second.whenExpire < Simulator::Now ()) && (i->second.whenExpire != Seconds (0)))
   155     {
   157     {
   156       NS_LOG_DEBUG ("Reactive route has expired, sorry.");
   158       NS_LOG_DEBUG ("Reactive route has expired, sorry.");
   157       return LookupResult();
   159       return LookupResult ();
   158     }
   160     }
   159   return LookupReactiveExpired (destination);
   161   return LookupReactiveExpired (destination);
   160 }
   162 }
   161 HwmpRtable::LookupResult
   163 HwmpRtable::LookupResult
   162 HwmpRtable::LookupReactiveExpired (Mac48Address destination)
   164 HwmpRtable::LookupReactiveExpired (Mac48Address destination)
   163 {
   165 {
   164   std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.find (destination);
   166   std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.find (destination);
   165   if (i == m_routes.end ())
   167   if (i == m_routes.end ())
   166     return LookupResult ();
   168     {
   167   return LookupResult (
   169       return LookupResult ();
   168       i->second.retransmitter,
   170     }
   169       i->second.interface,
   171   return LookupResult (i->second.retransmitter, i->second.interface, i->second.metric, i->second.seqnum,
   170       i->second.metric, i->second.seqnum,
   172       i->second.whenExpire - Simulator::Now ());
   171       i->second.whenExpire - Simulator::Now ()
       
   172       );
       
   173 }
   173 }
   174 HwmpRtable::LookupResult
   174 HwmpRtable::LookupResult
   175 HwmpRtable::LookupProactive ()
   175 HwmpRtable::LookupProactive ()
   176 {
   176 {
   177   if (m_root.whenExpire < Simulator::Now ())
   177   if (m_root.whenExpire < Simulator::Now ())
   182   return LookupProactiveExpired ();
   182   return LookupProactiveExpired ();
   183 }
   183 }
   184 HwmpRtable::LookupResult
   184 HwmpRtable::LookupResult
   185 HwmpRtable::LookupProactiveExpired ()
   185 HwmpRtable::LookupProactiveExpired ()
   186 {
   186 {
   187   return LookupResult(m_root.retransmitter, m_root.interface, m_root.metric, m_root.seqnum, m_root.whenExpire - Simulator::Now ());
   187   return LookupResult (m_root.retransmitter, m_root.interface, m_root.metric, m_root.seqnum,
       
   188       m_root.whenExpire - Simulator::Now ());
   188 }
   189 }
   189 std::vector<IePerr::FailedDestination>
   190 std::vector<IePerr::FailedDestination>
   190 HwmpRtable::GetUnreachableDestinations (Mac48Address peerAddress)
   191 HwmpRtable::GetUnreachableDestinations (Mac48Address peerAddress)
   191 {
   192 {
   192   IePerr::FailedDestination dst;
   193   IePerr::FailedDestination dst;
   193   std::vector<IePerr::FailedDestination> retval;
   194   std::vector<IePerr::FailedDestination> retval;
   194   for (std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.begin (); i != m_routes.end(); i++)
   195   for (std::map<Mac48Address, ReactiveRoute>::iterator i = m_routes.begin (); i != m_routes.end (); i++)
   195     if (i->second.retransmitter == peerAddress)
   196     if (i->second.retransmitter == peerAddress)
   196       {
   197       {
   197         dst.destination = i->first;
   198         dst.destination = i->first;
   198         i->second.seqnum ++;
   199         i->second.seqnum++;
   199         dst.seqnum = i->second.seqnum;
   200         dst.seqnum = i->second.seqnum;
   200         retval.push_back (dst);
   201         retval.push_back (dst);
   201       }
   202       }
   202   //Lookup a path to root
   203   //Lookup a path to root
   203   if (m_root.retransmitter == peerAddress)
   204   if (m_root.retransmitter == peerAddress)
   213 {
   214 {
   214   //We suppose that no duplicates here can be
   215   //We suppose that no duplicates here can be
   215   PrecursorList retval;
   216   PrecursorList retval;
   216   std::map<Mac48Address, ReactiveRoute>::iterator route = m_routes.find (destination);
   217   std::map<Mac48Address, ReactiveRoute>::iterator route = m_routes.find (destination);
   217   if (route != m_routes.end ())
   218   if (route != m_routes.end ())
   218     for (unsigned int i = 0; i < route->second.precursors.size (); i ++)
   219     {
   219       retval.push_back(route->second.precursors[i]);
   220       for (unsigned int i = 0; i < route->second.precursors.size (); i++)
       
   221         {
       
   222           retval.push_back (route->second.precursors[i]);
       
   223         }
       
   224     }
   220   if (m_root.root == destination)
   225   if (m_root.root == destination)
   221     for (unsigned int i = 0; i < m_root.precursors.size (); i ++)
   226     {
   222     {
   227       for (unsigned int i = 0; i < m_root.precursors.size (); i++)
   223       bool should_add = true;
   228         {
   224       for(unsigned int j = 0; j < retval.size(); j ++)
   229           bool should_add = true;
   225         if(retval[j].second == m_root.precursors[i].second)
   230           for (unsigned int j = 0; j < retval.size (); j++)
   226          {
   231             if (retval[j].second == m_root.precursors[i].second)
   227             should_add = false;
   232               {
   228             break;
   233                 should_add = false;
   229          }
   234                 break;
   230       if(should_add)
   235               }
   231         retval.push_back(m_root.precursors[i]);
   236           if (should_add)
       
   237             retval.push_back (m_root.precursors[i]);
       
   238         }
   232     }
   239     }
   233   return retval;
   240   return retval;
   234 }
   241 }
   235 bool HwmpRtable::LookupResult::operator==(const HwmpRtable::LookupResult & o) const
   242 bool
   236 {
   243 HwmpRtable::LookupResult::operator== (const HwmpRtable::LookupResult & o) const
   237   return (retransmitter == o.retransmitter
   244 {
   238       && ifIndex == o.ifIndex 
   245   return (retransmitter == o.retransmitter && ifIndex == o.ifIndex && metric == o.metric && seqnum
   239       && metric  == o.metric
   246       == o.seqnum);
   240       && seqnum  == o.seqnum
   247 }
   241     );
   248 bool
   242 }
   249 HwmpRtable::LookupResult::IsValid () const
   243 bool HwmpRtable::LookupResult::IsValid() const
   250 {
   244 {
   251   return !(retransmitter == Mac48Address::GetBroadcast () && ifIndex == INTERFACE_ANY && metric == MAX_METRIC
   245   return !( retransmitter == Mac48Address::GetBroadcast ()
   252       && seqnum == 0);
   246         &&  ifIndex == INTERFACE_ANY
       
   247         &&  metric == MAX_METRIC
       
   248         &&  seqnum == 0
       
   249       );
       
   250 }
   253 }
   251 #ifdef RUN_SELF_TESTS
   254 #ifdef RUN_SELF_TESTS
   252 /// Unit test for HwmpRtable
   255 /// Unit test for HwmpRtable
   253 class HwmpRtableTest : public Test 
   256 class HwmpRtableTest : public Test
   254 {
   257 {
   255 public:
   258 public:
   256   HwmpRtableTest ();
   259   HwmpRtableTest ();
   257   virtual bool RunTests(); 
   260   virtual bool
   258   
   261   RunTests ();
       
   262 
   259 private:
   263 private:
   260   /// Test Add apth and lookup path;
   264   /// Test Add apth and lookup path;
   261   void TestLookup ();
   265   void
       
   266   TestLookup ();
   262   /**
   267   /**
   263    * \name Test add path and try to lookup after entry has expired
   268    * \name Test add path and try to lookup after entry has expired
   264    * \{
   269    * \{
   265    */
   270    */
   266   void TestAddPath ();
   271   void
   267   void TestExpire ();
   272   TestAddPath ();
       
   273   void
       
   274   TestExpire ();
   268   ///\}
   275   ///\}
   269   /**
   276   /**
   270    * \name Test add precursors and find precursor list in rtable
   277    * \name Test add precursors and find precursor list in rtable
   271    * \{
   278    * \{
   272    */
   279    */
   273   void TestPrecursorAdd ();
   280   void
   274   void TestPrecursorFind ();
   281   TestPrecursorAdd ();
       
   282   void
       
   283   TestPrecursorFind ();
   275   ///\}
   284   ///\}
   276 private:
   285 private:
   277   bool result;
   286   bool result;
   278   
   287 
   279   Mac48Address dst;
   288   Mac48Address dst;
   280   Mac48Address hop;
   289   Mac48Address hop;
   281   uint32_t iface;
   290   uint32_t iface;
   282   uint32_t metric;
   291   uint32_t metric;
   283   uint32_t seqnum;
   292   uint32_t seqnum;
   286   std::vector<Mac48Address> precursors;
   295   std::vector<Mac48Address> precursors;
   287 };
   296 };
   288 /// Test instance
   297 /// Test instance
   289 static HwmpRtableTest g_HwmpRtableTest;
   298 static HwmpRtableTest g_HwmpRtableTest;
   290 
   299 
   291 HwmpRtableTest::HwmpRtableTest ()  : Test ("Mesh/802.11s/HwmpRtable"), 
   300 HwmpRtableTest::HwmpRtableTest () :
   292   result(true),
   301   Test ("Mesh/802.11s/HwmpRtable"), result (true), dst ("01:00:00:01:00:01"), hop ("01:00:00:01:00:03"),
   293   dst ("01:00:00:01:00:01"),
   302       iface (8010), metric (10), seqnum (1), expire (Seconds (10))
   294   hop ("01:00:00:01:00:03"),
       
   295   iface (8010),
       
   296   metric (10),
       
   297   seqnum (1),
       
   298   expire (Seconds (10)) 
       
   299 {
   303 {
   300   precursors.push_back (Mac48Address ("00:10:20:30:40:50"));
   304   precursors.push_back (Mac48Address ("00:10:20:30:40:50"));
   301   precursors.push_back (Mac48Address ("00:11:22:33:44:55"));
   305   precursors.push_back (Mac48Address ("00:11:22:33:44:55"));
   302   precursors.push_back (Mac48Address ("00:01:02:03:04:05"));
   306   precursors.push_back (Mac48Address ("00:01:02:03:04:05"));
   303 }
   307 }
   304 void HwmpRtableTest::TestLookup ()
   308 void
       
   309 HwmpRtableTest::TestLookup ()
   305 {
   310 {
   306   HwmpRtable::LookupResult correct (hop, iface, metric, seqnum);
   311   HwmpRtable::LookupResult correct (hop, iface, metric, seqnum);
   307   
   312 
   308   // Reactive path
   313   // Reactive path
   309   table->AddReactivePath (dst, hop, iface, metric, expire, seqnum);
   314   table->AddReactivePath (dst, hop, iface, metric, expire, seqnum);
   310   NS_TEST_ASSERT (table->LookupReactive (dst) == correct);
   315   NS_TEST_ASSERT (table->LookupReactive (dst) == correct);
   311   table->DeleteReactivePath (dst);
   316   table->DeleteReactivePath (dst);
   312   NS_TEST_ASSERT (! table->LookupReactive (dst).IsValid ());
   317   NS_TEST_ASSERT (!table->LookupReactive (dst).IsValid ());
   313   
   318 
   314   // Proactive
   319   // Proactive
   315   table->AddProactivePath (metric, dst, hop, iface, expire, seqnum);
   320   table->AddProactivePath (metric, dst, hop, iface, expire, seqnum);
   316   NS_TEST_ASSERT (table->LookupProactive () == correct);
   321   NS_TEST_ASSERT (table->LookupProactive () == correct);
   317   table->DeleteProactivePath (dst);
   322   table->DeleteProactivePath (dst);
   318   NS_TEST_ASSERT (! table->LookupProactive ().IsValid ());
   323   NS_TEST_ASSERT (!table->LookupProactive ().IsValid ());
   319 }
   324 }
   320 void HwmpRtableTest::TestAddPath ()
   325 void
       
   326 HwmpRtableTest::TestAddPath ()
   321 {
   327 {
   322   table->AddReactivePath (dst, hop, iface, metric, expire, seqnum);
   328   table->AddReactivePath (dst, hop, iface, metric, expire, seqnum);
   323   table->AddProactivePath (metric, dst, hop, iface, expire, seqnum);
   329   table->AddProactivePath (metric, dst, hop, iface, expire, seqnum);
   324 }
   330 }
   325 void HwmpRtableTest::TestExpire ()
   331 void
       
   332 HwmpRtableTest::TestExpire ()
   326 {
   333 {
   327   // this is assumed to be called when path records are already expired
   334   // this is assumed to be called when path records are already expired
   328   HwmpRtable::LookupResult correct (hop, iface, metric, seqnum);
   335   HwmpRtable::LookupResult correct (hop, iface, metric, seqnum);
   329   NS_TEST_ASSERT (table->LookupReactiveExpired (dst) == correct);
   336   NS_TEST_ASSERT (table->LookupReactiveExpired (dst) == correct);
   330   NS_TEST_ASSERT (table->LookupProactiveExpired () == correct);
   337   NS_TEST_ASSERT (table->LookupProactiveExpired () == correct);
   331   
   338 
   332   NS_TEST_ASSERT (! table->LookupReactive (dst).IsValid ());
   339   NS_TEST_ASSERT (!table->LookupReactive (dst).IsValid ());
   333   NS_TEST_ASSERT (! table->LookupProactive ().IsValid ());
   340   NS_TEST_ASSERT (!table->LookupProactive ().IsValid ());
   334 }
   341 }
   335 void HwmpRtableTest::TestPrecursorAdd ()
   342 void
   336 {
   343 HwmpRtableTest::TestPrecursorAdd ()
   337   for (std::vector<Mac48Address>::const_iterator i = precursors.begin (); i != precursors.end (); i ++)
   344 {
   338   {
   345   for (std::vector<Mac48Address>::const_iterator i = precursors.begin (); i != precursors.end (); i++)
   339     table->AddPrecursor (dst, iface, *i);
   346     {
   340     // Check that duplicates are filtered
   347       table->AddPrecursor (dst, iface, *i);
   341     table->AddPrecursor (dst, iface, *i);
   348       // Check that duplicates are filtered
   342   }
   349       table->AddPrecursor (dst, iface, *i);
   343 }
   350     }
   344 void HwmpRtableTest::TestPrecursorFind ()
   351 }
       
   352 void
       
   353 HwmpRtableTest::TestPrecursorFind ()
   345 {
   354 {
   346   HwmpRtable::PrecursorList precursorList = table->GetPrecursors (dst);
   355   HwmpRtable::PrecursorList precursorList = table->GetPrecursors (dst);
   347   NS_TEST_ASSERT(precursors.size () == precursorList.size ());
   356   NS_TEST_ASSERT (precursors.size () == precursorList.size ());
   348   for(unsigned int i = 0; i < precursors.size (); i ++)
   357   for (unsigned int i = 0; i < precursors.size (); i++)
   349   {
   358     {
   350     NS_TEST_ASSERT(precursorList[i].first == iface);
   359       NS_TEST_ASSERT (precursorList[i].first == iface);
   351     NS_TEST_ASSERT(precursorList[i].second == precursors[i]);
   360       NS_TEST_ASSERT (precursorList[i].second == precursors[i]);
   352   }
   361     }
   353 }
   362 }
   354 bool HwmpRtableTest::RunTests ()
   363 bool
       
   364 HwmpRtableTest::RunTests ()
   355 {
   365 {
   356   table = CreateObject<HwmpRtable> ();
   366   table = CreateObject<HwmpRtable> ();
   357   
   367 
   358   Simulator::Schedule (Seconds (0), & HwmpRtableTest::TestLookup, this);
   368   Simulator::Schedule (Seconds (0), &HwmpRtableTest::TestLookup, this);
   359   Simulator::Schedule (Seconds (1), & HwmpRtableTest::TestAddPath, this);
   369   Simulator::Schedule (Seconds (1), &HwmpRtableTest::TestAddPath, this);
   360   Simulator::Schedule (Seconds (2), & HwmpRtableTest::TestPrecursorAdd, this);
   370   Simulator::Schedule (Seconds (2), &HwmpRtableTest::TestPrecursorAdd, this);
   361   Simulator::Schedule (expire + Seconds (2), & HwmpRtableTest::TestExpire, this);
   371   Simulator::Schedule (expire + Seconds (2), &HwmpRtableTest::TestExpire, this);
   362   Simulator::Schedule (expire + Seconds (3), & HwmpRtableTest::TestPrecursorFind, this);
   372   Simulator::Schedule (expire + Seconds (3), &HwmpRtableTest::TestPrecursorFind, this);
   363   
   373 
   364   Simulator::Run ();
   374   Simulator::Run ();
   365   Simulator::Destroy ();
   375   Simulator::Destroy ();
   366   
   376 
   367   return result;
   377   return result;
   368 }
   378 }
   369 #endif // RUN_SELF_TESTS
   379 #endif // RUN_SELF_TESTS
   370 } //namespace dot11s
   380 } //namespace dot11s
   371 } //namespace ns3
   381 } //namespace ns3