Static routing with support for metrics and longest prefix match
authorAntti Makela <zarhan@cc.hut.fi>
Mon Aug 31 23:35:16 2009 -0700 (5 months ago)
changeset 47473dc675bb8b20
parent 4746 bfec2b0fa57d
child 4748 2362df525d86
Static routing with support for metrics and longest prefix match
CHANGES.html
src/routing/static-routing/ipv4-routing-table-entry.cc
src/routing/static-routing/ipv4-static-routing.cc
src/routing/static-routing/ipv4-static-routing.h
     1.1 --- a/CHANGES.html	Mon Aug 31 23:11:29 2009 -0700
     1.2 +++ b/CHANGES.html	Mon Aug 31 23:35:16 2009 -0700
     1.3 @@ -52,6 +52,15 @@
     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 +<p>When performing route lookup, first match for longest prefix, and then
     1.9 +based on metrics (default metric = 0).  If metrics are equal, most recent
    1.10 +addition is picked.  Extends API for support of metrics but preserves
    1.11 +backward compatibility.  One small change is that the default route
    1.12 +is no longer stored as index 0 route in the host route table so 
    1.13 +GetDefaultRoute () must be used.
    1.14 +</p>
    1.15 +</li>
    1.16  <li><b>Route injection for global routing</b>
    1.17  <p>Add ability to inject and withdraw routes to Ipv4GlobalRouting.  This
    1.18  allows a user to insert a route and have it redistributed like an OSPF
     2.1 --- a/src/routing/static-routing/ipv4-routing-table-entry.cc	Mon Aug 31 23:11:29 2009 -0700
     2.2 +++ b/src/routing/static-routing/ipv4-routing-table-entry.cc	Mon Aug 31 23:35:16 2009 -0700
     2.3 @@ -48,14 +48,14 @@
     2.4                        Ipv4Address gateway,
     2.5                        uint32_t interface)
     2.6    : m_dest (dest),
     2.7 -    m_destNetworkMask (Ipv4Mask::GetZero ()),
     2.8 +    m_destNetworkMask (Ipv4Mask::GetOnes ()),
     2.9      m_gateway (gateway),
    2.10      m_interface (interface)
    2.11  {}
    2.12  Ipv4RoutingTableEntry::Ipv4RoutingTableEntry (Ipv4Address dest,
    2.13                        uint32_t interface)
    2.14    : m_dest (dest),
    2.15 -    m_destNetworkMask (Ipv4Mask::GetZero ()),
    2.16 +    m_destNetworkMask (Ipv4Mask::GetOnes ()),
    2.17      m_gateway (Ipv4Address::GetZero ()),
    2.18      m_interface (interface)
    2.19  {}
    2.20 @@ -80,7 +80,7 @@
    2.21  bool 
    2.22  Ipv4RoutingTableEntry::IsHost (void) const
    2.23  {
    2.24 -  if (m_destNetworkMask.IsEqual (Ipv4Mask::GetZero ())) 
    2.25 +  if (m_destNetworkMask.IsEqual (Ipv4Mask::GetOnes ())) 
    2.26      {
    2.27        return true;
    2.28      } 
     3.1 --- a/src/routing/static-routing/ipv4-static-routing.cc	Mon Aug 31 23:11:29 2009 -0700
     3.2 +++ b/src/routing/static-routing/ipv4-static-routing.cc	Mon Aug 31 23:35:16 2009 -0700
     3.3 @@ -27,6 +27,8 @@
     3.4  
     3.5  NS_LOG_COMPONENT_DEFINE ("Ipv4StaticRouting");
     3.6  
     3.7 +using std::make_pair;
     3.8 +
     3.9  namespace ns3 {
    3.10  
    3.11  NS_OBJECT_ENSURE_REGISTERED (Ipv4StaticRouting);
    3.12 @@ -42,37 +44,17 @@
    3.13  }
    3.14  
    3.15  Ipv4StaticRouting::Ipv4StaticRouting () 
    3.16 -: m_defaultRoute (0), m_ipv4 (0)
    3.17 +: m_ipv4 (0)
    3.18  {
    3.19    NS_LOG_FUNCTION_NOARGS ();
    3.20  }
    3.21  
    3.22  void 
    3.23 -Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest, 
    3.24 -                                   Ipv4Address nextHop, 
    3.25 -                                   uint32_t interface)
    3.26 -{
    3.27 -  NS_LOG_FUNCTION_NOARGS ();
    3.28 -  Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
    3.29 -  *route = Ipv4RoutingTableEntry::CreateHostRouteTo (dest, nextHop, interface);
    3.30 -  m_hostRoutes.push_back (route);
    3.31 -}
    3.32 -
    3.33 -void 
    3.34 -Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest, 
    3.35 -                                   uint32_t interface)
    3.36 -{
    3.37 -  NS_LOG_FUNCTION_NOARGS ();
    3.38 -  Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
    3.39 -  *route = Ipv4RoutingTableEntry::CreateHostRouteTo (dest, interface);
    3.40 -  m_hostRoutes.push_back (route);
    3.41 -}
    3.42 -
    3.43 -void 
    3.44  Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network, 
    3.45                                        Ipv4Mask networkMask, 
    3.46                                        Ipv4Address nextHop, 
    3.47 -                                      uint32_t interface)
    3.48 +                                      uint32_t interface,
    3.49 +                                      uint32_t metric)
    3.50  {
    3.51    NS_LOG_FUNCTION_NOARGS ();
    3.52    Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
    3.53 @@ -80,31 +62,49 @@
    3.54                                              networkMask,
    3.55                                              nextHop,
    3.56                                              interface);
    3.57 -  m_networkRoutes.push_back (route);
    3.58 +  m_networkRoutes.push_back (make_pair(route,metric));
    3.59  }
    3.60  
    3.61  void 
    3.62  Ipv4StaticRouting::AddNetworkRouteTo (Ipv4Address network, 
    3.63                                        Ipv4Mask networkMask, 
    3.64 -                                      uint32_t interface)
    3.65 +                                      uint32_t interface,
    3.66 +                                      uint32_t metric)
    3.67  {
    3.68    NS_LOG_FUNCTION_NOARGS ();
    3.69    Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
    3.70    *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
    3.71                                              networkMask,
    3.72                                              interface);
    3.73 -  m_networkRoutes.push_back (route);
    3.74 +  m_networkRoutes.push_back (make_pair (route,metric));
    3.75 +}
    3.76 +
    3.77 +void 
    3.78 +Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest, 
    3.79 +                                     Ipv4Address nextHop, 
    3.80 +                                     uint32_t interface,
    3.81 +                                     uint32_t metric)
    3.82 +{
    3.83 +  NS_LOG_FUNCTION_NOARGS ();
    3.84 +  AddNetworkRouteTo (dest, Ipv4Mask::GetOnes (), nextHop, interface, metric);
    3.85 +}
    3.86 +
    3.87 +void 
    3.88 +Ipv4StaticRouting::AddHostRouteTo (Ipv4Address dest, 
    3.89 +                                     uint32_t interface,
    3.90 +                                     uint32_t metric)
    3.91 +{
    3.92 +  NS_LOG_FUNCTION_NOARGS ();
    3.93 +  AddNetworkRouteTo (dest, Ipv4Mask::GetOnes (), interface, metric);
    3.94  }
    3.95  
    3.96  void 
    3.97  Ipv4StaticRouting::SetDefaultRoute (Ipv4Address nextHop, 
    3.98 -                                    uint32_t interface)
    3.99 +                                    uint32_t interface,
   3.100 +                                    uint32_t metric)
   3.101  {
   3.102    NS_LOG_FUNCTION_NOARGS ();
   3.103 -  Ipv4RoutingTableEntry *route = new Ipv4RoutingTableEntry ();
   3.104 -  *route = Ipv4RoutingTableEntry::CreateDefaultRoute (nextHop, interface);
   3.105 -  delete m_defaultRoute;
   3.106 -  m_defaultRoute = route;
   3.107 +  AddNetworkRouteTo (Ipv4Address ("0.0.0.0"), Ipv4Mask::GetZero (), nextHop, interface, metric);
   3.108  }
   3.109  
   3.110  void 
   3.111 @@ -133,7 +133,7 @@
   3.112    *route = Ipv4RoutingTableEntry::CreateNetworkRouteTo (network,
   3.113                                              networkMask,
   3.114                                              outputInterface);
   3.115 -  m_networkRoutes.push_back (route);
   3.116 +  m_networkRoutes.push_back (make_pair(route,0));
   3.117  }
   3.118  
   3.119  uint32_t 
   3.120 @@ -214,58 +214,48 @@
   3.121  {
   3.122    NS_LOG_FUNCTION_NOARGS ();
   3.123    Ptr<Ipv4Route> rtentry = 0;
   3.124 -  for (HostRoutesCI i = m_hostRoutes.begin (); 
   3.125 -       i != m_hostRoutes.end (); 
   3.126 +  uint16_t longest_mask = 0;
   3.127 +  uint32_t shortest_metric = 0xffffffff;
   3.128 +  for (NetworkRoutesI i = m_networkRoutes.begin (); 
   3.129 +       i != m_networkRoutes.end (); 
   3.130         i++) 
   3.131      {
   3.132 -      NS_ASSERT ((*i)->IsHost ());
   3.133 -      if ((*i)->GetDest ().IsEqual (dest)) 
   3.134 +      Ipv4RoutingTableEntry *j=i->first;
   3.135 +      uint32_t metric =i->second;
   3.136 +      Ipv4Mask mask = (j)->GetDestNetworkMask ();
   3.137 +      uint16_t masklen = mask.GetPrefixLength ();
   3.138 +      Ipv4Address entry = (j)->GetDestNetwork ();
   3.139 +      NS_LOG_LOGIC ("Searching for route to " << dest << ", checking against route to " << entry << "/" << masklen);
   3.140 +      if (mask.IsMatch (dest, entry)) 
   3.141          {
   3.142 -          NS_LOG_LOGIC ("Found global host route" << *i);
   3.143 -          Ipv4RoutingTableEntry* route = (*i);
   3.144 +          NS_LOG_LOGIC ("Found global network route " << j << ", mask length " << masklen << ", metric " << metric);
   3.145 +          if (masklen < longest_mask) // Not interested if got shorter mask
   3.146 +            {
   3.147 +              NS_LOG_LOGIC ("Previous match longer, skipping");
   3.148 +              continue;
   3.149 +            }
   3.150 +          if (masklen > longest_mask) // Reset metric if longer masklen
   3.151 +            {
   3.152 +              shortest_metric = 0xffffffff;
   3.153 +            }
   3.154 +          longest_mask = masklen;
   3.155 +          if (metric > shortest_metric)
   3.156 +            {
   3.157 +              NS_LOG_LOGIC ("Equal mask length, but previous metric shorter, skipping");
   3.158 +              continue;
   3.159 +            }
   3.160 +          shortest_metric = metric;
   3.161 +          Ipv4RoutingTableEntry* route = (j);
   3.162 +          uint32_t interfaceIdx = route->GetInterface ();
   3.163            rtentry = Create<Ipv4Route> ();
   3.164 -          uint32_t interfaceIdx = route->GetInterface ();
   3.165            rtentry->SetDestination (route->GetDest ());
   3.166            rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetDest ()));
   3.167            rtentry->SetGateway (route->GetGateway ());
   3.168            rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));
   3.169 -          return rtentry;
   3.170          }
   3.171      }
   3.172 -  for (NetworkRoutesI j = m_networkRoutes.begin (); 
   3.173 -       j != m_networkRoutes.end (); 
   3.174 -       j++) 
   3.175 -    {
   3.176 -      NS_ASSERT ((*j)->IsNetwork ());
   3.177 -      Ipv4Mask mask = (*j)->GetDestNetworkMask ();
   3.178 -      Ipv4Address entry = (*j)->GetDestNetwork ();
   3.179 -      if (mask.IsMatch (dest, entry)) 
   3.180 -        {
   3.181 -          NS_LOG_LOGIC ("Found global network route" << *j);
   3.182 -          Ipv4RoutingTableEntry* route = (*j);
   3.183 -          rtentry = Create<Ipv4Route> ();
   3.184 -          uint32_t interfaceIdx = route->GetInterface ();
   3.185 -          rtentry->SetDestination (route->GetDest ());
   3.186 -          rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetDest ()));
   3.187 -          rtentry->SetGateway (route->GetGateway ());
   3.188 -          rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));
   3.189 -          return rtentry;
   3.190 -        }
   3.191 -    }
   3.192 -  if (m_defaultRoute != 0) 
   3.193 -    {
   3.194 -      NS_ASSERT (m_defaultRoute->IsDefault ());
   3.195 -      NS_LOG_LOGIC ("Found global network route" << m_defaultRoute);
   3.196 -      Ipv4RoutingTableEntry* route = m_defaultRoute;
   3.197 -      rtentry = Create<Ipv4Route> ();
   3.198 -      uint32_t interfaceIdx = route->GetInterface ();
   3.199 -      rtentry->SetDestination (route->GetDest ());
   3.200 -      rtentry->SetSource (SourceAddressSelection (interfaceIdx, route->GetDest ()));
   3.201 -      rtentry->SetGateway (route->GetGateway ());
   3.202 -      rtentry->SetOutputDevice (m_ipv4->GetNetDevice (interfaceIdx));
   3.203 -      return rtentry;
   3.204 -    }
   3.205 -  return 0;
   3.206 +  NS_LOG_LOGIC ("Matching route via " << rtentry << " at the end");
   3.207 +  return rtentry;
   3.208  }
   3.209  
   3.210  Ptr<Ipv4MulticastRoute>
   3.211 @@ -324,23 +314,40 @@
   3.212  Ipv4StaticRouting::GetNRoutes (void)
   3.213  {
   3.214    NS_LOG_FUNCTION_NOARGS ();
   3.215 -  uint32_t n = 0;
   3.216 -  if (m_defaultRoute != 0)
   3.217 -    {
   3.218 -      n++;
   3.219 -    }
   3.220 -  n += m_hostRoutes.size ();
   3.221 -  n += m_networkRoutes.size ();
   3.222 -  return n;
   3.223 +  return m_networkRoutes.size ();;
   3.224  }
   3.225  
   3.226  Ipv4RoutingTableEntry
   3.227  Ipv4StaticRouting::GetDefaultRoute ()
   3.228  {
   3.229    NS_LOG_FUNCTION_NOARGS ();
   3.230 -  if (m_defaultRoute != 0)
   3.231 +  // Basically a repeat of LookupStatic, retained for backward compatibility
   3.232 +  Ipv4Address dest ("0.0.0.0");
   3.233 +  uint32_t shortest_metric = 0xffffffff;
   3.234 +  Ipv4RoutingTableEntry *result = 0;
   3.235 +  for (NetworkRoutesI i = m_networkRoutes.begin (); 
   3.236 +       i != m_networkRoutes.end (); 
   3.237 +       i++) 
   3.238      {
   3.239 -      return *m_defaultRoute;
   3.240 +    Ipv4RoutingTableEntry *j = i->first;
   3.241 +    uint32_t metric = i->second;
   3.242 +    Ipv4Mask mask = (j)->GetDestNetworkMask ();
   3.243 +    uint16_t masklen = mask.GetPrefixLength ();
   3.244 +    Ipv4Address entry = (j)->GetDestNetwork ();
   3.245 +    if (masklen != 0)
   3.246 +      {
   3.247 +        continue;
   3.248 +      }
   3.249 +    if (metric > shortest_metric)
   3.250 +      {
   3.251 +        continue;
   3.252 +      }
   3.253 +    shortest_metric = metric;
   3.254 +    result = j;
   3.255 +  }
   3.256 +  if (result)
   3.257 +    {
   3.258 +      return result;
   3.259      }
   3.260    else
   3.261      {
   3.262 @@ -352,29 +359,26 @@
   3.263  Ipv4StaticRouting::GetRoute (uint32_t index)
   3.264  {
   3.265    NS_LOG_FUNCTION_NOARGS ();
   3.266 -  if (index == 0 && m_defaultRoute != 0)
   3.267 -    {
   3.268 -      return *m_defaultRoute;
   3.269 -    }
   3.270 -  if (index > 0 && m_defaultRoute != 0)
   3.271 -    {
   3.272 -      index--;
   3.273 -    }
   3.274 -  if (index < m_hostRoutes.size ())
   3.275 -    {
   3.276        uint32_t tmp = 0;
   3.277 -      for (HostRoutesCI i = m_hostRoutes.begin (); 
   3.278 -           i != m_hostRoutes.end (); 
   3.279 -           i++) 
   3.280 +  for (NetworkRoutesI j = m_networkRoutes.begin (); 
   3.281 +       j != m_networkRoutes.end (); 
   3.282 +       j++) 
   3.283          {
   3.284            if (tmp  == index)
   3.285              {
   3.286 -              return *i;
   3.287 +          return j->first;
   3.288              }
   3.289            tmp++;
   3.290          }
   3.291 -    }
   3.292 -  index -= m_hostRoutes.size ();
   3.293 +  NS_ASSERT (false);
   3.294 +  // quiet compiler.
   3.295 +  return 0;
   3.296 +}
   3.297 +
   3.298 +uint32_t
   3.299 +Ipv4StaticRouting::GetMetric (uint32_t index)
   3.300 +{
   3.301 +  NS_LOG_FUNCTION_NOARGS ();
   3.302    uint32_t tmp = 0;
   3.303    for (NetworkRoutesI j = m_networkRoutes.begin (); 
   3.304         j != m_networkRoutes.end (); 
   3.305 @@ -382,7 +386,7 @@
   3.306      {
   3.307        if (tmp == index)
   3.308          {
   3.309 -          return *j;
   3.310 +          return j->second;
   3.311          }
   3.312        tmp++;
   3.313      }
   3.314 @@ -394,32 +398,6 @@
   3.315  Ipv4StaticRouting::RemoveRoute (uint32_t index)
   3.316  {
   3.317    NS_LOG_FUNCTION_NOARGS ();
   3.318 -  if (index == 0 && m_defaultRoute != 0)
   3.319 -    {
   3.320 -      delete m_defaultRoute;
   3.321 -      m_defaultRoute = 0;
   3.322 -    }
   3.323 -  if (index > 0 && m_defaultRoute != 0)
   3.324 -    {
   3.325 -      index--;
   3.326 -    }
   3.327 -  if (index < m_hostRoutes.size ())
   3.328 -    {
   3.329 -      uint32_t tmp = 0;
   3.330 -      for (HostRoutesI i = m_hostRoutes.begin (); 
   3.331 -           i != m_hostRoutes.end (); 
   3.332 -           i++) 
   3.333 -        {
   3.334 -          if (tmp  == index)
   3.335 -            {
   3.336 -              delete *i;
   3.337 -              m_hostRoutes.erase (i);
   3.338 -              return;
   3.339 -            }
   3.340 -          tmp++;
   3.341 -        }
   3.342 -    }
   3.343 -  index -= m_hostRoutes.size ();
   3.344    uint32_t tmp = 0;
   3.345    for (NetworkRoutesI j = m_networkRoutes.begin (); 
   3.346         j != m_networkRoutes.end (); 
   3.347 @@ -427,7 +405,7 @@
   3.348      {
   3.349        if (tmp == index)
   3.350          {
   3.351 -          delete *j;
   3.352 +          delete j->first;
   3.353            m_networkRoutes.erase (j);
   3.354            return;
   3.355          }
   3.356 @@ -520,22 +498,11 @@
   3.357  Ipv4StaticRouting::DoDispose (void)
   3.358  {
   3.359    NS_LOG_FUNCTION_NOARGS ();
   3.360 -  for (HostRoutesI i = m_hostRoutes.begin (); 
   3.361 -       i != m_hostRoutes.end (); 
   3.362 -       i = m_hostRoutes.erase (i)) 
   3.363 -    {
   3.364 -      delete (*i);
   3.365 -    }
   3.366    for (NetworkRoutesI j = m_networkRoutes.begin (); 
   3.367         j != m_networkRoutes.end (); 
   3.368         j = m_networkRoutes.erase (j)) 
   3.369      {
   3.370 -      delete (*j);
   3.371 -    }
   3.372 -  if (m_defaultRoute != 0)
   3.373 -    {
   3.374 -      delete m_defaultRoute;
   3.375 -      m_defaultRoute = 0;
   3.376 +      delete (j->first);
   3.377      }
   3.378    for (MulticastRoutesI i = m_multicastRoutes.begin (); 
   3.379         i != m_multicastRoutes.end (); 
   3.380 @@ -568,13 +535,18 @@
   3.381  Ipv4StaticRouting::NotifyInterfaceDown (uint32_t i)
   3.382  {
   3.383    // Remove all static routes that are going through this interface
   3.384 -  for (uint32_t j = 0; j < GetNRoutes (); j++)
   3.385 +  uint32_t j = 0;
   3.386 +  while (j < GetNRoutes())
   3.387      {
   3.388        Ipv4RoutingTableEntry route = GetRoute (j);
   3.389        if (route.GetInterface () == i)
   3.390          {
   3.391            RemoveRoute (j);
   3.392          }
   3.393 +      else
   3.394 +        {
   3.395 +          j++;
   3.396 +        }
   3.397      }
   3.398  }
   3.399  
     4.1 --- a/src/routing/static-routing/ipv4-static-routing.h	Mon Aug 31 23:11:29 2009 -0700
     4.2 +++ b/src/routing/static-routing/ipv4-static-routing.h	Mon Aug 31 23:35:16 2009 -0700
     4.3 @@ -23,6 +23,7 @@
     4.4  #define IPV4_STATIC_ROUTING_H
     4.5  
     4.6  #include <list>
     4.7 +#include <utility>
     4.8  #include <stdint.h>
     4.9  #include "ns3/ipv4-address.h"
    4.10  #include "ns3/ipv4-header.h"
    4.11 @@ -87,31 +88,6 @@
    4.12    virtual void SetIpv4 (Ptr<Ipv4> ipv4);
    4.13  
    4.14  /**
    4.15 - * \brief Add a host route to the static routing table.
    4.16 - *
    4.17 - * \param dest The Ipv4Address destination for this route.
    4.18 - * \param nextHop The Ipv4Address of the next hop in the route.
    4.19 - * \param interface The network interface index used to send packets to the
    4.20 - * destination.
    4.21 - *
    4.22 - * \see Ipv4Address
    4.23 - */
    4.24 -  void AddHostRouteTo (Ipv4Address dest, 
    4.25 -                       Ipv4Address nextHop, 
    4.26 -                       uint32_t interface);
    4.27 -/**
    4.28 - * \brief Add a host route to the static routing table.
    4.29 - *
    4.30 - * \param dest The Ipv4Address destination for this route.
    4.31 - * \param interface The network interface index used to send packets to the
    4.32 - * destination.
    4.33 - *
    4.34 - * \see Ipv4Address
    4.35 - */
    4.36 -  void AddHostRouteTo (Ipv4Address dest, 
    4.37 -                       uint32_t interface);
    4.38 -
    4.39 -/**
    4.40   * \brief Add a network route to the static routing table.
    4.41   *
    4.42   * \param network The Ipv4Address network for this route.
    4.43 @@ -119,13 +95,15 @@
    4.44   * \param nextHop The next hop in the route to the destination network.
    4.45   * \param interface The network interface index used to send packets to the
    4.46   * destination.
    4.47 + * \param metric Metric of route in case of multiple routes to same destination
    4.48   *
    4.49   * \see Ipv4Address
    4.50   */
    4.51    void AddNetworkRouteTo (Ipv4Address network, 
    4.52                            Ipv4Mask networkMask, 
    4.53                            Ipv4Address nextHop, 
    4.54 -                          uint32_t interface);
    4.55 +                          uint32_t interface,
    4.56 +                          uint32_t metric = 0);
    4.57  
    4.58  /**
    4.59   * \brief Add a network route to the static routing table.
    4.60 @@ -134,14 +112,44 @@
    4.61   * \param networkMask The Ipv4Mask to extract the network.
    4.62   * \param interface The network interface index used to send packets to the
    4.63   * destination.
    4.64 + * \param metric Metric of route in case of multiple routes to same destination
    4.65   *
    4.66   * \see Ipv4Address
    4.67   */
    4.68    void AddNetworkRouteTo (Ipv4Address network, 
    4.69                            Ipv4Mask networkMask, 
    4.70 -                          uint32_t interface);
    4.71 +                          uint32_t interface,
    4.72 +                          uint32_t metric = 0);
    4.73  
    4.74  /**
    4.75 + * \brief Add a host route to the static routing table.
    4.76 + *
    4.77 + * \param dest The Ipv4Address destination for this route.
    4.78 + * \param nextHop The Ipv4Address of the next hop in the route.
    4.79 + * \param interface The network interface index used to send packets to the
    4.80 + * destination.
    4.81 + * \param metric Metric of route in case of multiple routes to same destination
    4.82 + *
    4.83 + * \see Ipv4Address
    4.84 + */
    4.85 +  void AddHostRouteTo (Ipv4Address dest, 
    4.86 +                       Ipv4Address nextHop, 
    4.87 +                       uint32_t interface,
    4.88 +                       uint32_t metric = 0);
    4.89 +/**
    4.90 + * \brief Add a host route to the static routing table.
    4.91 + *
    4.92 + * \param dest The Ipv4Address destination for this route.
    4.93 + * \param interface The network interface index used to send packets to the
    4.94 + * destination.
    4.95 + * \param metric Metric of route in case of multiple routes to same destination
    4.96 + *
    4.97 + * \see Ipv4Address
    4.98 + */
    4.99 +  void AddHostRouteTo (Ipv4Address dest, 
   4.100 +                       uint32_t interface,
   4.101 +                       uint32_t metric = 0);
   4.102 +/**
   4.103   * \brief Add a default route to the static routing table.
   4.104   *
   4.105   * This method tells the routing system what to do in the case where a specific
   4.106 @@ -155,12 +163,14 @@
   4.107   * \param nextHop The Ipv4Address to send packets to in the hope that they
   4.108   * will be forwarded correctly.
   4.109   * \param interface The network interface index used to send packets.
   4.110 + * \param metric Metric of route in case of multiple routes to same destination
   4.111   *
   4.112   * \see Ipv4Address
   4.113   * \see Ipv4StaticRouting::Lookup
   4.114   */
   4.115    void SetDefaultRoute (Ipv4Address nextHop, 
   4.116 -                        uint32_t interface);
   4.117 +                        uint32_t interface,
   4.118 +                        uint32_t metric = 0);
   4.119  
   4.120  /**
   4.121   * \brief Get the number of individual unicast routes that have been added
   4.122 @@ -171,10 +181,11 @@
   4.123    uint32_t GetNRoutes (void);
   4.124  
   4.125  /**
   4.126 - * \brief Get the default route from the static routing table.
   4.127 + * \brief Get the default route with lowest metric from the static routing table.
   4.128   *
   4.129   * \return If the default route is set, a pointer to that Ipv4RoutingTableEntry is
   4.130 - * returned, otherwise a zero pointer is returned.
   4.131 + * returned, otherwise an empty routing table entry is returned. 
   4.132 +*  If multiple default routes exist, the one with lowest metric is returned.
   4.133   *
   4.134   * \see Ipv4RoutingTableEntry
   4.135   */
   4.136 @@ -184,16 +195,9 @@
   4.137   * \brief Get a route from the static unicast routing table.
   4.138   *
   4.139   * Externally, the unicast static routing table appears simply as a table with
   4.140 - * n entries.  The one sublety of note is that if a default route has been set
   4.141 - * it will appear as the zeroth entry in the table.  This means that if you
   4.142 - * add only a default route, the table will have one entry that can be accessed
   4.143 - * either by explicity calling GetDefaultRoute () or by calling GetRoute (0).
   4.144 - * 
   4.145 - * Similarly, if the default route has been set, calling RemoveRoute (0) will
   4.146 - * remove the default route.
   4.147 + * n entries.  
   4.148   *
   4.149 - * \param i The index (into the routing table) of the route to retrieve.  If
   4.150 - * the default route has been set, it will occupy index zero.
   4.151 + * \param i The index (into the routing table) of the route to retrieve.  
   4.152   * \return If route is set, a pointer to that Ipv4RoutingTableEntry is returned, otherwise
   4.153   * a zero pointer is returned.
   4.154   *
   4.155 @@ -203,16 +207,21 @@
   4.156    Ipv4RoutingTableEntry GetRoute (uint32_t i);
   4.157  
   4.158  /**
   4.159 + * \brief Get a metric for route from the static unicast routing table.
   4.160 + *
   4.161 + * \param i The index (into the routing table) of the route to retrieve.  
   4.162 + * \return If route is set, the metric is returned. If not, an infinity metric (0xffffffff) is returned
   4.163 + *
   4.164 + */
   4.165 +  uint32_t GetMetric (uint32_t index);
   4.166 +  
   4.167 +/**
   4.168   * \brief Remove a route from the static unicast routing table.
   4.169   *
   4.170   * Externally, the unicast static routing table appears simply as a table with
   4.171 - * n entries.  The one sublety of note is that if a default route has been set
   4.172 - * it will appear as the zeroth entry in the table.  This means that if the
   4.173 - * default route has been set, calling RemoveRoute (0) will remove the
   4.174 - * default route.
   4.175 + * n entries.  
   4.176   *
   4.177 - * \param i The index (into the routing table) of the route to remove.  If
   4.178 - * the default route has been set, it will occupy index zero.
   4.179 + * \param i The index (into the routing table) of the route to remove.  
   4.180   *
   4.181   * \see Ipv4RoutingTableEntry
   4.182   * \see Ipv4StaticRouting::GetRoute
   4.183 @@ -366,12 +375,9 @@
   4.184    virtual void DoDispose (void);
   4.185  
   4.186  private:
   4.187 -  typedef std::list<Ipv4RoutingTableEntry *> HostRoutes;
   4.188 -  typedef std::list<Ipv4RoutingTableEntry *>::const_iterator HostRoutesCI;
   4.189 -  typedef std::list<Ipv4RoutingTableEntry *>::iterator HostRoutesI;
   4.190 -  typedef std::list<Ipv4RoutingTableEntry *> NetworkRoutes;
   4.191 -  typedef std::list<Ipv4RoutingTableEntry *>::const_iterator NetworkRoutesCI;
   4.192 -  typedef std::list<Ipv4RoutingTableEntry *>::iterator NetworkRoutesI;
   4.193 +  typedef std::list<std::pair <Ipv4RoutingTableEntry *, uint32_t> > NetworkRoutes;
   4.194 +  typedef std::list<std::pair <Ipv4RoutingTableEntry *, uint32_t> >::const_iterator NetworkRoutesCI;
   4.195 +  typedef std::list<std::pair <Ipv4RoutingTableEntry *, uint32_t> >::iterator NetworkRoutesI;
   4.196  
   4.197    typedef std::list<Ipv4MulticastRoutingTableEntry *> MulticastRoutes;
   4.198    typedef std::list<Ipv4MulticastRoutingTableEntry *>::const_iterator MulticastRoutesCI;
   4.199 @@ -383,9 +389,7 @@
   4.200  
   4.201    Ipv4Address SourceAddressSelection (uint32_t interface, Ipv4Address dest);
   4.202  
   4.203 -  HostRoutes m_hostRoutes;
   4.204    NetworkRoutes m_networkRoutes;
   4.205 -  Ipv4RoutingTableEntry *m_defaultRoute;
   4.206    MulticastRoutes m_multicastRoutes;
   4.207  
   4.208    Ptr<Ipv4> m_ipv4;