Segregate Ipv4GlobalRouting from Ipv4StaticRouting; add API for deleting and recomputing global routes
authorTom Henderson <tomh@tomh.org>
Sun Nov 30 21:21:23 2008 -0800 (14 months ago)
changeset 3959ec65107df095
parent 3958 7658bcc28d8d
child 3960 34908804c029
Segregate Ipv4GlobalRouting from Ipv4StaticRouting; add API for deleting and recomputing global routes
src/internet-stack/wscript
src/routing/global-routing/global-route-manager-impl.cc
src/routing/global-routing/global-route-manager-impl.h
src/routing/global-routing/global-route-manager.cc
src/routing/global-routing/global-route-manager.h
src/routing/global-routing/global-router-interface.cc
     1.1 --- a/src/internet-stack/wscript	Fri Nov 28 07:21:26 2008 -0800
     1.2 +++ b/src/internet-stack/wscript	Sun Nov 30 21:21:23 2008 -0800
     1.3 @@ -131,6 +131,7 @@
     1.4          'ipv4-interface.cc',
     1.5          'ipv4-l3-protocol.cc',
     1.6          'ipv4-static-routing.cc',
     1.7 +        'ipv4-global-routing.cc',
     1.8          'ipv4-end-point.cc',
     1.9          'udp-l4-protocol.cc',
    1.10          'tcp-l4-protocol.cc',
    1.11 @@ -164,6 +165,7 @@
    1.12          'ipv4-interface.h',
    1.13          'ipv4-l3-protocol.h',
    1.14          'ipv4-static-routing.h',
    1.15 +        'ipv4-global-routing.h',
    1.16          'icmpv4.h',
    1.17          ]
    1.18  
     2.1 --- a/src/routing/global-routing/global-route-manager-impl.cc	Fri Nov 28 07:21:26 2008 -0800
     2.2 +++ b/src/routing/global-routing/global-route-manager-impl.cc	Sun Nov 30 21:21:23 2008 -0800
     2.3 @@ -30,6 +30,7 @@
     2.4  #include "ns3/log.h"
     2.5  #include "ns3/node-list.h"
     2.6  #include "ns3/ipv4.h"
     2.7 +#include "ns3/ipv4-global-routing.h"
     2.8  #include "global-router-interface.h"
     2.9  #include "global-route-manager-impl.h"
    2.10  #include "candidate-queue.h"
    2.11 @@ -349,6 +350,35 @@
    2.12    m_lsdb = lsdb;
    2.13  }
    2.14  
    2.15 +  void
    2.16 +GlobalRouteManagerImpl::DeleteGlobalRoutes ()
    2.17 +{
    2.18 +  NS_LOG_FUNCTION_NOARGS ();
    2.19 +  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); i++)
    2.20 +    {
    2.21 +      Ptr<Node> node = *i;
    2.22 +      Ptr<Ipv4GlobalRouting> gr = GetGlobalRoutingProtocol (node->GetId ());
    2.23 +      uint32_t j = 0;
    2.24 +      uint32_t nRoutes = gr->GetNRoutes ();
    2.25 +      NS_LOG_LOGIC ("Deleting " << gr->GetNRoutes ()<< " routes from node " << node->GetId ());
    2.26 +      // Each time we delete route 0, the route index shifts downward
    2.27 +      // We can delete all routes if we delete the route numbered 0
    2.28 +      // nRoutes times
    2.29 +      for (j = 0; j < nRoutes; j++)
    2.30 +        {
    2.31 +          NS_LOG_LOGIC ("Deleting global route " << j << " from node " << node->GetId ());
    2.32 +          gr->RemoveRoute (0);        
    2.33 +        }
    2.34 +      NS_LOG_LOGIC ("Deleted " << j << " global routes from node "<< node->GetId ());
    2.35 +    }
    2.36 +  if (m_lsdb)
    2.37 +    {
    2.38 +      NS_LOG_LOGIC ("Deleting LSDB, creating new one");
    2.39 +      delete m_lsdb;
    2.40 +      m_lsdb = new GlobalRouteManagerLSDB ();
    2.41 +    }
    2.42 +}
    2.43 +
    2.44  //
    2.45  // In order to build the routing database, we need at least one of the nodes
    2.46  // to participate as a router.  This is a convenience function that makes
    2.47 @@ -362,11 +392,25 @@
    2.48    for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); i++)
    2.49      {
    2.50        Ptr<Node> node = *i;
    2.51 -      NS_LOG_LOGIC ("Adding GlobalRouter interface to node " << 
    2.52 -        node->GetId ());
    2.53 +      NS_LOG_LOGIC ("Adding GlobalRouter interface to node " << node->GetId ());
    2.54  
    2.55        Ptr<GlobalRouter> globalRouter = CreateObject<GlobalRouter> ();
    2.56        node->AggregateObject (globalRouter);
    2.57 +
    2.58 +      NS_LOG_LOGIC ("Adding GlobalRouting Protocol to node " << node->GetId ());
    2.59 +      Ptr<Ipv4GlobalRouting> globalRouting = CreateObject<Ipv4GlobalRouting> ();
    2.60 +      // This is the object that will keep the global routes.  We insert it
    2.61 +      // at slightly higher priority than static routing (which is at zero).
    2.62 +      // This means that global routes (e.g. host routes) will be consulted
    2.63 +      // before static routes
    2.64 +      Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
    2.65 +      NS_ASSERT_MSG (ipv4, "GlobalRouteManagerImpl::SelectRouterNodes (): "
    2.66 +        "GetObject for <Ipv4> interface failed");
    2.67 +      // XXX make the below  priority value an attribute
    2.68 +      ipv4->AddRoutingProtocol (globalRouting, 3);  
    2.69 +      // Locally cache the globalRouting pointer; we'll need it later
    2.70 +      // when we add routes
    2.71 +      AddGlobalRoutingProtocol (node->GetId (), globalRouting);
    2.72      }
    2.73  }
    2.74  
    2.75 @@ -382,6 +426,21 @@
    2.76  
    2.77        Ptr<GlobalRouter> globalRouter = CreateObject<GlobalRouter> ();
    2.78        node->AggregateObject (globalRouter);
    2.79 +
    2.80 +      NS_LOG_LOGIC ("Adding GlobalRouting Protocol to node " << node->GetId ());
    2.81 +      Ptr<Ipv4GlobalRouting> globalRouting = CreateObject<Ipv4GlobalRouting> ();
    2.82 +      // This is the object that will keep the global routes.  We insert it
    2.83 +      // at slightly higher priority than static routing (which is at zero).
    2.84 +      // This means that global routes (e.g. host routes) will be consulted
    2.85 +      // before static routes
    2.86 +      Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
    2.87 +      NS_ASSERT_MSG (ipv4, "GlobalRouteManagerImpl::SelectRouterNodes (): "
    2.88 +        "GetObject for <Ipv4> interface failed");
    2.89 +      // XXX make the below  priority value an attribute
    2.90 +      ipv4->AddRoutingProtocol (globalRouting, 3);  
    2.91 +      // Locally cache the globalRouting pointer; we'll need it later
    2.92 +      // when we add routes
    2.93 +      AddGlobalRoutingProtocol (node->GetId (), globalRouting);
    2.94      }
    2.95  }
    2.96  
    2.97 @@ -1289,6 +1348,8 @@
    2.98  // the local side of the point-to-point links found on the node described by
    2.99  // the vertex <v>.
   2.100  //
   2.101 +          NS_LOG_LOGIC (" Node " << node->GetId () <<
   2.102 +             " found " << nLinkRecords << " link records in LSA " << lsa << "with LinkStateId "<< lsa->GetLinkStateId ());
   2.103            for (uint32_t j = 0; j < nLinkRecords; ++j)
   2.104              {
   2.105  //
   2.106 @@ -1317,7 +1378,9 @@
   2.107  // Similarly, the vertex <v> has an m_rootOif (outbound interface index) to
   2.108  // which the packets should be send for forwarding.
   2.109  //
   2.110 -              ipv4->AddHostRouteTo (lr->GetLinkData (), v->GetNextHop (),
   2.111 +              Ptr<Ipv4GlobalRouting> gr = GetGlobalRoutingProtocol (node->GetId ());
   2.112 +              NS_ASSERT (gr);
   2.113 +              gr->AddHostRouteTo (lr->GetLinkData (), v->GetNextHop (),
   2.114                  v->GetOutgoingTypeId ());
   2.115              }
   2.116  //
   2.117 @@ -1399,7 +1462,9 @@
   2.118            Ipv4Mask tempmask = lsa->GetNetworkLSANetworkMask ();
   2.119            Ipv4Address tempip = lsa->GetLinkStateId ();
   2.120            tempip = tempip.CombineMask (tempmask);
   2.121 -          ipv4->AddNetworkRouteTo (tempip, tempmask, v->GetNextHop (),
   2.122 +          Ptr<Ipv4GlobalRouting> gr = GetGlobalRoutingProtocol (node->GetId ());
   2.123 +          NS_ASSERT (gr);
   2.124 +          gr->AddNetworkRouteTo (tempip, tempmask, v->GetNextHop (),
   2.125              v->GetOutgoingTypeId ());
   2.126            NS_LOG_LOGIC ("Node " << node->GetId () <<
   2.127              " add network route to " << tempip <<
   2.128 @@ -1427,6 +1492,29 @@
   2.129    v->GetParent ()->AddChild (v);
   2.130  }
   2.131  
   2.132 +  void 
   2.133 +GlobalRouteManagerImpl::AddGlobalRoutingProtocol (uint32_t nodeId, Ptr<Ipv4GlobalRouting> proto)
   2.134 +{
   2.135 +  NS_LOG_FUNCTION (nodeId);
   2.136 +  m_routingProtocols.push_back
   2.137 +    (std::pair<uint32_t, Ptr<Ipv4GlobalRouting> > (nodeId, proto));
   2.138 +  m_routingProtocols.sort ();
   2.139 +}
   2.140 +
   2.141 +  Ptr<Ipv4GlobalRouting>
   2.142 +GlobalRouteManagerImpl::GetGlobalRoutingProtocol (uint32_t nodeId)
   2.143 +{
   2.144 +  for (Ipv4GlobalRoutingList::const_iterator rprotoIter = m_routingProtocols.begin (); rprotoIter != m_routingProtocols.end (); rprotoIter++)
   2.145 +    {
   2.146 +      if ((*rprotoIter).first == nodeId)
   2.147 +        {
   2.148 +          return (*rprotoIter).second;
   2.149 +        }
   2.150 +    }
   2.151 +  return 0;
   2.152 +}
   2.153 +
   2.154 +
   2.155  } // namespace ns3
   2.156  
   2.157  #ifdef RUN_SELF_TESTS
     3.1 --- a/src/routing/global-routing/global-route-manager-impl.h	Fri Nov 28 07:21:26 2008 -0800
     3.2 +++ b/src/routing/global-routing/global-route-manager-impl.h	Sun Nov 30 21:21:23 2008 -0800
     3.3 @@ -37,6 +37,7 @@
     3.4  const uint32_t SPF_INFINITY = 0xffffffff;
     3.5  
     3.6  class CandidateQueue;
     3.7 +class Ipv4GlobalRouting;
     3.8  
     3.9  /**
    3.10   * @brief Vertex used in shortest path first (SPF) computations. See RFC 2328,
    3.11 @@ -701,6 +702,16 @@
    3.12    GlobalRouteManagerImpl ();
    3.13    virtual ~GlobalRouteManagerImpl ();
    3.14  /**
    3.15 + * @brief Delete all static routes on all nodes that have a
    3.16 + * GlobalRouterInterface
    3.17 + *
    3.18 + * TODO:  separate manually assigned static routes from static routes that
    3.19 + * the global routing code injects, and only delete the latter
    3.20 + * @internal
    3.21 + *
    3.22 + */
    3.23 +  virtual void DeleteGlobalRoutes ();
    3.24 +/**
    3.25   * @brief Select which nodes in the system are to be router nodes and 
    3.26   * aggregate the appropriate interfaces onto those nodes.
    3.27   * @internal
    3.28 @@ -770,6 +781,12 @@
    3.29    void SPFIntraAddTransit (SPFVertex* v);
    3.30    uint32_t FindOutgoingTypeId (Ipv4Address a, 
    3.31      Ipv4Mask amask = Ipv4Mask("255.255.255.255"));
    3.32 +
    3.33 +  // Local cache of the Ipv4GlobalRouting objects, indexed by nodeId
    3.34 +  typedef std::list< std::pair< uint32_t, Ptr<Ipv4GlobalRouting> > > Ipv4GlobalRoutingList;
    3.35 +  void AddGlobalRoutingProtocol (uint32_t nodeId, Ptr<Ipv4GlobalRouting> proto);
    3.36 +  Ptr<Ipv4GlobalRouting> GetGlobalRoutingProtocol (uint32_t nodeId);
    3.37 +  Ipv4GlobalRoutingList m_routingProtocols;
    3.38  };
    3.39  
    3.40  } // namespace ns3
     4.1 --- a/src/routing/global-routing/global-route-manager.cc	Fri Nov 28 07:21:26 2008 -0800
     4.2 +++ b/src/routing/global-routing/global-route-manager.cc	Sun Nov 30 21:21:23 2008 -0800
     4.3 @@ -50,6 +50,21 @@
     4.4  }
     4.5  
     4.6    void
     4.7 +GlobalRouteManager::RecomputeRoutingTables ()
     4.8 +{
     4.9 +  DeleteGlobalRoutes ();
    4.10 +  BuildGlobalRoutingDatabase ();
    4.11 +  InitializeRoutes ();
    4.12 +}
    4.13 +
    4.14 +  void
    4.15 +GlobalRouteManager::DeleteGlobalRoutes ()
    4.16 +{
    4.17 +  SimulationSingleton<GlobalRouteManagerImpl>::Get ()->
    4.18 +    DeleteGlobalRoutes ();
    4.19 +}
    4.20 +
    4.21 +  void
    4.22  GlobalRouteManager::SelectRouterNodes (void) 
    4.23  {
    4.24    SimulationSingleton<GlobalRouteManagerImpl>::Get ()->
     5.1 --- a/src/routing/global-routing/global-route-manager.h	Fri Nov 28 07:21:26 2008 -0800
     5.2 +++ b/src/routing/global-routing/global-route-manager.h	Sun Nov 30 21:21:23 2008 -0800
     5.3 @@ -45,14 +45,33 @@
     5.4   * the nodes in the simulation.  Makes all nodes in the simulation into
     5.5   * routers.
     5.6   *
     5.7 - * All this function does is call  BuildGlobalRoutingDatabase () and
     5.8 + * All this function does is call the three private functions
     5.9 + * SelectRouterNodes (), BuildGlobalRoutingDatabase (), and
    5.10   * InitializeRoutes ().
    5.11   *
    5.12 + * @see SelectRouterNodes ();
    5.13   * @see BuildGlobalRoutingDatabase ();
    5.14   * @see InitializeRoutes ();
    5.15   */
    5.16    static void PopulateRoutingTables ();
    5.17  
    5.18 + /**
    5.19 +  *@brief Remove all routes that were previously installed in a prior call
    5.20 + * to either PopulateRoutingTables() or RecomputeRoutingTables(), and 
    5.21 + * add a new set of routes.  
    5.22 + * 
    5.23 + * This method does not change the set of nodes
    5.24 + * over which GlobalRouting is being used, but it will dynamically update
    5.25 + * its representation of the global topology before recomputing routes.
    5.26 + * Users must first call PopulateRoutingTables() and then may subsequently
    5.27 + * call RecomputeRoutingTables() at any later time in the simulation.
    5.28 + *
    5.29 + * @see DeleteGlobalRoutes ();
    5.30 + * @see BuildGlobalRoutingDatabase ();
    5.31 + * @see InitializeRoutes ();
    5.32 + */
    5.33 + static void RecomputeRoutingTables ();
    5.34 +
    5.35  /**
    5.36   * @brief Build a routing database and initialize the routing tables of
    5.37   * the nodes in the simulation.  Makes the nodes in the provided container
    5.38 @@ -72,6 +91,17 @@
    5.39    static uint32_t AllocateRouterId ();
    5.40  
    5.41  private:
    5.42 +
    5.43 +/**
    5.44 + * @brief Delete all static routes on all nodes that have a 
    5.45 + * GlobalRouterInterface
    5.46 + *
    5.47 + * TODO:  separate manually assigned static routes from static routes that
    5.48 + * the global routing code injects, and only delete the latter
    5.49 + * @internal
    5.50 + */
    5.51 +  static void DeleteGlobalRoutes ();
    5.52 +
    5.53  /**
    5.54   * @brief Select which nodes in the system are to be router nodes and 
    5.55   * aggregate the appropriate interfaces onto those nodes.
     6.1 --- a/src/routing/global-routing/global-router-interface.cc	Fri Nov 28 07:21:26 2008 -0800
     6.2 +++ b/src/routing/global-routing/global-router-interface.cc	Sun Nov 30 21:21:23 2008 -0800
     6.3 @@ -513,7 +513,7 @@
     6.4  
     6.5        *i = 0;
     6.6      }
     6.7 -  NS_LOG_LOGIC ("Clear list");
     6.8 +  NS_LOG_LOGIC ("Clear list of LSAs");
     6.9    m_LSAs.clear();
    6.10  }
    6.11  
    6.12 @@ -599,9 +599,9 @@
    6.13        // IP addresses in routing.
    6.14        //
    6.15        bool isIp = false;
    6.16 -      for (uint32_t i = 0; i < ipv4Local->GetNInterfaces (); ++i )
    6.17 +      for (uint32_t j = 0; j < ipv4Local->GetNInterfaces (); ++j )
    6.18          {
    6.19 -          if (ipv4Local->GetNetDevice (i) == ndLocal) 
    6.20 +          if (ipv4Local->GetNetDevice (j) == ndLocal && ipv4Local->IsUp (j)) 
    6.21              {
    6.22                isIp = true;
    6.23                break;
    6.24 @@ -1007,6 +1007,12 @@
    6.25    rc = FindIfIndexForDevice(nodeRemote, ndRemote, ifIndexRemote);
    6.26    NS_ABORT_MSG_IF (rc == false, "GlobalRouter::ProcessPointToPointLinks(): No interface index associated with remote device");
    6.27  
    6.28 +  if (!ipv4Remote->IsUp (ifIndexRemote))
    6.29 +    {
    6.30 +      NS_LOG_LOGIC ("Remote side interface " << ifIndexRemote << " not up");
    6.31 +      return;
    6.32 +    }
    6.33 + 
    6.34    //
    6.35    // Now that we have the Ipv4 interface, we can get the (remote) address and
    6.36    // mask we need.
    6.37 @@ -1108,8 +1114,15 @@
    6.38              {
    6.39                Ptr<Ipv4> tempIpv4 = tempNode->GetObject<Ipv4> ();
    6.40                NS_ASSERT (tempIpv4);
    6.41 -              Ipv4Address tempAddr = tempIpv4->GetAddress(tempIfIndex);
    6.42 -              pLSA->AddAttachedRouter (tempAddr);
    6.43 +              if (!tempIpv4->IsUp (tempIfIndex))
    6.44 +                {
    6.45 +                  NS_LOG_LOGIC ("Remote side interface " << tempIfIndex << " not up");
    6.46 +                }
    6.47 +              else 
    6.48 +                {
    6.49 +                  Ipv4Address tempAddr = tempIpv4->GetAddress(tempIfIndex);
    6.50 +                  pLSA->AddAttachedRouter (tempAddr);
    6.51 +                }
    6.52              }
    6.53          }
    6.54        m_LSAs.push_back (pLSA);
    6.55 @@ -1180,6 +1193,11 @@
    6.56                if (FindIfIndexForDevice(nodeOther, bnd, ifIndexOther))
    6.57                  {
    6.58                    NS_LOG_LOGIC ("Found router on bridge net device " << bnd);
    6.59 +                  if (!ipv4->IsUp (ifIndexOther))
    6.60 +                    {
    6.61 +                      NS_LOG_LOGIC ("Remote side interface " << ifIndexOther << " not up");
    6.62 +                      continue;
    6.63 +                    }
    6.64                    Ipv4Address addrOther = ipv4->GetAddress (ifIndexOther);
    6.65                    desigRtr = addrOther < desigRtr ? addrOther : desigRtr;
    6.66                    NS_LOG_LOGIC ("designated router now " << desigRtr);
    6.67 @@ -1223,6 +1241,11 @@
    6.68                uint32_t ifIndexOther;
    6.69                if (FindIfIndexForDevice(nodeOther, ndOther, ifIndexOther))
    6.70                  {
    6.71 +                  if (!ipv4->IsUp (ifIndexOther))
    6.72 +                    {
    6.73 +                      NS_LOG_LOGIC ("Remote side interface " << ifIndexOther << " not up");
    6.74 +                      continue;
    6.75 +                    }
    6.76                    NS_LOG_LOGIC ("Found router on net device " << ndOther);
    6.77                    Ipv4Address addrOther = ipv4->GetAddress (ifIndexOther);
    6.78                    desigRtr = addrOther < desigRtr ? addrOther : desigRtr;