src/routing/olsr/olsr-routing-table.cc
changeset 4379 44c7757fb216
parent 4378 3ad10f8db106
parent 4366 1c3138bce75e
child 4380 bbbc2e622f50
equal deleted inserted replaced
4378:3ad10f8db106 4379:44c7757fb216
     1 /* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
       
     2 /*
       
     3  * Copyright (c) 2004 Francisco J. Ros 
       
     4  * Copyright (c) 2007 INESC Porto
       
     5  *
       
     6  * This program is free software; you can redistribute it and/or modify
       
     7  * it under the terms of the GNU General Public License version 2 as
       
     8  * published by the Free Software Foundation;
       
     9  *
       
    10  * This program is distributed in the hope that it will be useful,
       
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    13  * GNU General Public License for more details.
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License
       
    16  * along with this program; if not, write to the Free Software
       
    17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    18  *
       
    19  * Authors: Francisco J. Ros  <fjrm@dif.um.es>
       
    20  *          Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
       
    21  */
       
    22 
       
    23 ///
       
    24 /// \file	OLSR_rtable.cc
       
    25 /// \brief	Implementation of our routing table.
       
    26 ///
       
    27 
       
    28 #include "olsr-routing-table.h"
       
    29 #include "ns3/packet.h"
       
    30 #include "ns3/ipv4-header.h"
       
    31 #include "ns3/log.h"
       
    32 
       
    33 namespace ns3 { namespace olsr {
       
    34 
       
    35 NS_LOG_COMPONENT_DEFINE ("OlsrRoutingTable");
       
    36 
       
    37 ///
       
    38 /// \brief Clears the routing table and frees the memory assigned to each one of its entries.
       
    39 ///
       
    40 void
       
    41 RoutingTable::Clear ()
       
    42 {
       
    43   NS_LOG_FUNCTION_NOARGS ();
       
    44   m_table.clear ();
       
    45 }
       
    46 
       
    47 ///
       
    48 /// \brief Deletes the entry whose destination address is given.
       
    49 /// \param dest	address of the destination node.
       
    50 ///
       
    51 void
       
    52 RoutingTable::RemoveEntry (Ipv4Address const &dest)
       
    53 {
       
    54   m_table.erase (dest);
       
    55 }
       
    56 
       
    57 ///
       
    58 /// \brief Looks up an entry for the specified destination address.
       
    59 /// \param dest	destination address.
       
    60 /// \param outEntry output parameter to hold the routing entry result, if fuond
       
    61 /// \return	true if found, false if not found
       
    62 ///
       
    63 bool
       
    64 RoutingTable::Lookup (Ipv4Address const &dest,
       
    65                       RoutingTableEntry &outEntry) const
       
    66 {
       
    67   // Get the iterator at "dest" position
       
    68   std::map<Ipv4Address, RoutingTableEntry>::const_iterator it =
       
    69     m_table.find (dest);
       
    70   // If there is no route to "dest", return NULL
       
    71   if (it == m_table.end ())
       
    72     return false;
       
    73   outEntry = it->second;
       
    74   return true;
       
    75 }
       
    76 
       
    77 ///
       
    78 /// \brief	Finds the appropiate entry which must be used in order to forward
       
    79 ///		a data packet to a next hop (given a destination).
       
    80 ///
       
    81 /// Imagine a routing table like this: [A,B] [B,C] [C,C]; being each pair of the
       
    82 /// form [dest addr,next-hop addr]. In this case, if this function is invoked with
       
    83 /// [A,B] then pair [C,C] is returned because C is the next hop that must be used
       
    84 /// to forward a data packet destined to A. That is, C is a neighbor of this node,
       
    85 /// but B isn't. This function finds the appropiate neighbor for forwarding a packet.
       
    86 ///
       
    87 /// \param entry	the routing table entry which indicates the destination node
       
    88 ///			we are interested in.
       
    89 /// \return		the appropiate routing table entry which indicates the next
       
    90 ///			hop which must be used for forwarding a data packet, or NULL
       
    91 ///			if there is no such entry.
       
    92 ///
       
    93 bool
       
    94 RoutingTable::FindSendEntry (RoutingTableEntry const &entry,
       
    95                              RoutingTableEntry &outEntry) const
       
    96 {
       
    97   outEntry = entry;
       
    98   while (outEntry.destAddr != outEntry.nextAddr)
       
    99     {
       
   100       if (not Lookup(outEntry.nextAddr, outEntry))
       
   101         return false;
       
   102     }
       
   103   return true;
       
   104 }
       
   105 
       
   106 
       
   107 bool
       
   108 RoutingTable::RequestRoute (uint32_t interface,
       
   109                             const Ipv4Header &ipHeader,
       
   110                             Ptr<Packet> packet,
       
   111                             RouteReplyCallback routeReply)
       
   112 {
       
   113   RoutingTableEntry entry1, entry2;
       
   114   if (Lookup (ipHeader.GetDestination (), entry1))
       
   115     {
       
   116       bool foundSendEntry = FindSendEntry (entry1, entry2);
       
   117       if (!foundSendEntry)
       
   118         NS_FATAL_ERROR ("FindSendEntry failure");
       
   119 
       
   120       Ipv4Route route = Ipv4Route::CreateHostRouteTo
       
   121         (ipHeader.GetDestination (), entry2.nextAddr, entry2.interface);
       
   122 
       
   123       NS_LOG_DEBUG ("Olsr node " << m_mainAddress
       
   124                     << ": RouteRequest for dest=" << ipHeader.GetDestination ()
       
   125                     << " --> nestHop=" << entry2.nextAddr
       
   126                     << " interface=" << entry2.interface);
       
   127       
       
   128       routeReply (true, route, packet, ipHeader);
       
   129       return true;
       
   130     }
       
   131   else
       
   132     {
       
   133 #ifdef NS3_LOG_ENABLE
       
   134       NS_LOG_DEBUG ("Olsr node " << m_mainAddress
       
   135                     << ": RouteRequest for dest=" << ipHeader.GetDestination ()
       
   136                     << " --> NOT FOUND; ** Dumping routing table...");
       
   137       for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
       
   138            iter != m_table.end (); iter++)
       
   139         {
       
   140           NS_LOG_DEBUG ("dest=" << iter->first << " --> next=" << iter->second.nextAddr
       
   141                         << " via interface " << iter->second.interface);
       
   142         }
       
   143 
       
   144       NS_LOG_DEBUG ("** Routing table dump end.");
       
   145 #endif
       
   146       return false;
       
   147     }
       
   148 }
       
   149 
       
   150 bool
       
   151 RoutingTable::RequestInterface (Ipv4Address destination,
       
   152                               uint32_t& interface)
       
   153 {
       
   154   RoutingTableEntry entry1, entry2;
       
   155   if (Lookup (destination, entry1))
       
   156     {
       
   157       bool foundSendEntry = FindSendEntry (entry1, entry2);
       
   158       if (!foundSendEntry)
       
   159         NS_FATAL_ERROR ("FindSendEntry failure");
       
   160       interface = entry2.interface;
       
   161       return true;
       
   162     }
       
   163   else
       
   164     {
       
   165       return false;
       
   166     }
       
   167 }
       
   168 
       
   169 
       
   170 ///
       
   171 /// \brief Adds a new entry into the routing table.
       
   172 ///
       
   173 /// If an entry for the given destination existed, it is deleted and freed.
       
   174 ///
       
   175 /// \param dest		address of the destination node.
       
   176 /// \param next		address of the next hop node.
       
   177 /// \param iface	address of the local interface.
       
   178 /// \param dist		distance to the destination node.
       
   179 ///
       
   180 void
       
   181 RoutingTable::AddEntry (Ipv4Address const &dest,
       
   182                         Ipv4Address const &next,
       
   183                         uint32_t interface,
       
   184                         uint32_t distance)
       
   185 {
       
   186   NS_LOG_FUNCTION (this << dest << next << interface << distance << m_mainAddress);
       
   187 
       
   188   NS_ASSERT (distance > 0);
       
   189 
       
   190   // Creates a new rt entry with specified values
       
   191   RoutingTableEntry &entry = m_table[dest];
       
   192 
       
   193   entry.destAddr = dest;
       
   194   entry.nextAddr = next;
       
   195   entry.interface = interface;
       
   196   entry.distance = distance;
       
   197 }
       
   198 
       
   199 void
       
   200 RoutingTable::AddEntry (Ipv4Address const &dest,
       
   201                         Ipv4Address const &next,
       
   202                         Ipv4Address const &interfaceAddress,
       
   203                         uint32_t distance)
       
   204 {
       
   205   NS_LOG_FUNCTION (this << dest << next << interfaceAddress << distance << m_mainAddress);
       
   206 
       
   207   NS_ASSERT (distance > 0);
       
   208   NS_ASSERT (m_ipv4);
       
   209 
       
   210   RoutingTableEntry entry;
       
   211   for (uint32_t i = 0; i < m_ipv4->GetNInterfaces (); i++)
       
   212     {
       
   213       for (uint32_t j = 0; j < m_ipv4->GetNAddresses (i); j++)
       
   214         {
       
   215           if (m_ipv4->GetAddress (i,j).GetLocal () == interfaceAddress)
       
   216             {
       
   217               AddEntry (dest, next, i, distance);
       
   218               return;
       
   219             }
       
   220         }
       
   221     }
       
   222   NS_ASSERT (false); // should not be reached
       
   223   AddEntry (dest, next, 0, distance);
       
   224 }
       
   225 
       
   226 void
       
   227 RoutingTable::SetMainAddress (Ipv4Address mainAddress)
       
   228 {
       
   229   m_mainAddress = mainAddress;
       
   230 }
       
   231 
       
   232 void
       
   233 RoutingTable::SetIpv4 (Ptr<Ipv4> ipv4)
       
   234 {
       
   235   m_ipv4 = ipv4;
       
   236 }
       
   237 
       
   238 std::vector<RoutingTableEntry>
       
   239 RoutingTable::GetEntries () const
       
   240 {
       
   241   std::vector<RoutingTableEntry> retval;
       
   242   for (std::map<Ipv4Address, RoutingTableEntry>::const_iterator iter = m_table.begin ();
       
   243        iter != m_table.end (); iter++)
       
   244     {
       
   245       retval.push_back (iter->second);
       
   246     }
       
   247   return retval;
       
   248 }
       
   249 
       
   250 ///
       
   251 /// \brief Returns the number of entries in the routing table.
       
   252 /// \return the number of entries in the routing table.
       
   253 ///
       
   254 // u_int32_t
       
   255 // RoutingTable::size() {
       
   256 // 	return rt_.size();
       
   257 // }
       
   258 
       
   259 }}; // namespace ns3, olsr
       
   260 
       
   261 
       
   262 
       
   263 #ifdef RUN_SELF_TESTS
       
   264 
       
   265 
       
   266 #include "ns3/test.h"
       
   267 
       
   268 
       
   269 namespace ns3 { namespace olsr {
       
   270 
       
   271 class OlsrRoutingTableTest : public ns3::Test {
       
   272 private:
       
   273 public:
       
   274   OlsrRoutingTableTest ();
       
   275   virtual bool RunTests (void);
       
   276 
       
   277 
       
   278 };
       
   279 
       
   280 OlsrRoutingTableTest::OlsrRoutingTableTest ()
       
   281   : ns3::Test ("OlsrRoutingTable")
       
   282 {}
       
   283 
       
   284 
       
   285 bool 
       
   286 OlsrRoutingTableTest::RunTests (void)
       
   287 {
       
   288   bool result = true;
       
   289 
       
   290   RoutingTable table;
       
   291 
       
   292   table.AddEntry (Ipv4Address ("1.2.3.5"),
       
   293                   Ipv4Address ("1.2.3.4"),
       
   294                   0,
       
   295                   1);
       
   296 
       
   297   table.AddEntry (Ipv4Address ("1.2.3.4"),
       
   298                   Ipv4Address ("1.2.3.4"),
       
   299                   0,
       
   300                   1);
       
   301   
       
   302   RoutingTableEntry entry1;
       
   303   NS_TEST_ASSERT (table.Lookup (Ipv4Address ("1.2.3.5"), entry1));
       
   304   NS_TEST_ASSERT_EQUAL (entry1.destAddr, Ipv4Address ("1.2.3.5"));
       
   305   NS_TEST_ASSERT_EQUAL (entry1.nextAddr, Ipv4Address ("1.2.3.4"));
       
   306   NS_TEST_ASSERT_EQUAL (entry1.interface, 0);
       
   307   NS_TEST_ASSERT_EQUAL (entry1.distance, 1);
       
   308 
       
   309   RoutingTableEntry entry2;
       
   310   NS_TEST_ASSERT (table.Lookup (Ipv4Address ("1.2.3.4"), entry2));
       
   311   NS_TEST_ASSERT_EQUAL (entry2.destAddr, Ipv4Address ("1.2.3.4"));
       
   312   NS_TEST_ASSERT_EQUAL (entry2.nextAddr, Ipv4Address ("1.2.3.4"));
       
   313   NS_TEST_ASSERT_EQUAL (entry2.interface, 0);
       
   314   NS_TEST_ASSERT_EQUAL (entry2.distance, 1);
       
   315 
       
   316   RoutingTableEntry sendEntry;
       
   317   NS_TEST_ASSERT (table.FindSendEntry (entry1, sendEntry));
       
   318   NS_TEST_ASSERT_EQUAL (sendEntry.destAddr, Ipv4Address ("1.2.3.4"));
       
   319   NS_TEST_ASSERT_EQUAL (sendEntry.nextAddr, Ipv4Address ("1.2.3.4"));
       
   320   NS_TEST_ASSERT_EQUAL (sendEntry.interface, 0);
       
   321   NS_TEST_ASSERT_EQUAL (sendEntry.distance, 1);
       
   322 
       
   323   table.RemoveEntry (Ipv4Address ("1.2.3.5"));
       
   324   RoutingTableEntry removedEntry;
       
   325   NS_TEST_ASSERT (not table.Lookup (Ipv4Address ("1.2.3.5"), removedEntry));
       
   326 
       
   327   return result;
       
   328 }
       
   329 
       
   330 static OlsrRoutingTableTest gOlsrRoutingTableTest;
       
   331 
       
   332 }}; // namespace
       
   333 
       
   334 
       
   335 #endif /* RUN_SELF_TESTS */