Segregate Ipv4GlobalRouting from Ipv4StaticRouting; add API for deleting and recomputing global routes
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;