branch merge
authorTom Henderson <tomh@tomh.org>
Mon Dec 01 21:33:52 2008 -0800 (14 months ago)
changeset 3964cb1f2beeee9c
parent 3963 8a40a7ab4744
parent 3961 a31b0b04a8ac
child 3965 1210035e1828
branch merge
src/internet-stack/ipv4-l3-protocol.cc
     1.1 --- a/src/internet-stack/ipv4-l3-protocol.cc	Mon Dec 01 21:29:59 2008 -0800
     1.2 +++ b/src/internet-stack/ipv4-l3-protocol.cc	Mon Dec 01 21:33:52 2008 -0800
     1.3 @@ -522,8 +522,17 @@
     1.4        ipv4Interface = *i;
     1.5        if (ipv4Interface->GetDevice () == device)
     1.6          {
     1.7 -          m_rxTrace (packet, index);
     1.8 -          break;
     1.9 +          if (ipv4Interface->IsUp ())
    1.10 +            {
    1.11 +              m_rxTrace (packet, index);
    1.12 +              break;
    1.13 +            } 
    1.14 +          else
    1.15 +            {
    1.16 +              NS_LOG_LOGIC ("Dropping received packet-- interface is down");
    1.17 +              m_dropTrace (packet);
    1.18 +              return;
    1.19 +            }
    1.20          }
    1.21        index++;
    1.22      }
    1.23 @@ -1074,7 +1083,7 @@
    1.24    Ptr<Ipv4Interface> interface = GetInterface (ifaceIndex);
    1.25    interface->SetDown ();
    1.26  
    1.27 -  // Remove all routes that are going through this interface
    1.28 +  // Remove all static routes that are going through this interface
    1.29    bool modified = true;
    1.30    while (modified)
    1.31      {
     2.1 --- a/src/internet-stack/wscript	Mon Dec 01 21:29:59 2008 -0800
     2.2 +++ b/src/internet-stack/wscript	Mon Dec 01 21:33:52 2008 -0800
     2.3 @@ -131,6 +131,7 @@
     2.4          'ipv4-interface.cc',
     2.5          'ipv4-l3-protocol.cc',
     2.6          'ipv4-static-routing.cc',
     2.7 +        'ipv4-global-routing.cc',
     2.8          'ipv4-end-point.cc',
     2.9          'udp-l4-protocol.cc',
    2.10          'tcp-l4-protocol.cc',
    2.11 @@ -164,6 +165,7 @@
    2.12          'ipv4-interface.h',
    2.13          'ipv4-l3-protocol.h',
    2.14          'ipv4-static-routing.h',
    2.15 +        'ipv4-global-routing.h',
    2.16          'icmpv4.h',
    2.17          ]
    2.18  
     3.1 --- a/src/routing/global-routing/global-route-manager-impl.cc	Mon Dec 01 21:29:59 2008 -0800
     3.2 +++ b/src/routing/global-routing/global-route-manager-impl.cc	Mon Dec 01 21:33:52 2008 -0800
     3.3 @@ -30,6 +30,7 @@
     3.4  #include "ns3/log.h"
     3.5  #include "ns3/node-list.h"
     3.6  #include "ns3/ipv4.h"
     3.7 +#include "ns3/ipv4-global-routing.h"
     3.8  #include "global-router-interface.h"
     3.9  #include "global-route-manager-impl.h"
    3.10  #include "candidate-queue.h"
    3.11 @@ -52,7 +53,8 @@
    3.12    m_rootOif (SPF_INFINITY),
    3.13    m_nextHop ("0.0.0.0"),
    3.14    m_parent (0),
    3.15 -  m_children ()
    3.16 +  m_children (),
    3.17 +  m_vertexProcessed (false)
    3.18  {
    3.19    NS_LOG_FUNCTION_NOARGS ();
    3.20  }
    3.21 @@ -64,7 +66,8 @@
    3.22    m_rootOif (SPF_INFINITY),
    3.23    m_nextHop ("0.0.0.0"),
    3.24    m_parent (0),
    3.25 -  m_children ()
    3.26 +  m_children (),
    3.27 +  m_vertexProcessed (false)
    3.28  {
    3.29    NS_LOG_FUNCTION_NOARGS ();
    3.30    if (lsa->GetLSType () == GlobalRoutingLSA::RouterLSA) 
    3.31 @@ -226,6 +229,19 @@
    3.32    return m_children.size ();
    3.33  }
    3.34  
    3.35 +void 
    3.36 +SPFVertex::SetVertexProcessed (bool value)
    3.37 +{
    3.38 +  m_vertexProcessed = value;
    3.39 +}
    3.40 +
    3.41 +bool 
    3.42 +SPFVertex::IsVertexProcessed (void) const
    3.43 +{
    3.44 +  return m_vertexProcessed;
    3.45 +}
    3.46 +
    3.47 +
    3.48  // ---------------------------------------------------------------------------
    3.49  //
    3.50  // GlobalRouteManagerLSDB Implementation
    3.51 @@ -349,6 +365,35 @@
    3.52    m_lsdb = lsdb;
    3.53  }
    3.54  
    3.55 +  void
    3.56 +GlobalRouteManagerImpl::DeleteGlobalRoutes ()
    3.57 +{
    3.58 +  NS_LOG_FUNCTION_NOARGS ();
    3.59 +  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); i++)
    3.60 +    {
    3.61 +      Ptr<Node> node = *i;
    3.62 +      Ptr<Ipv4GlobalRouting> gr = GetGlobalRoutingProtocol (node->GetId ());
    3.63 +      uint32_t j = 0;
    3.64 +      uint32_t nRoutes = gr->GetNRoutes ();
    3.65 +      NS_LOG_LOGIC ("Deleting " << gr->GetNRoutes ()<< " routes from node " << node->GetId ());
    3.66 +      // Each time we delete route 0, the route index shifts downward
    3.67 +      // We can delete all routes if we delete the route numbered 0
    3.68 +      // nRoutes times
    3.69 +      for (j = 0; j < nRoutes; j++)
    3.70 +        {
    3.71 +          NS_LOG_LOGIC ("Deleting global route " << j << " from node " << node->GetId ());
    3.72 +          gr->RemoveRoute (0);        
    3.73 +        }
    3.74 +      NS_LOG_LOGIC ("Deleted " << j << " global routes from node "<< node->GetId ());
    3.75 +    }
    3.76 +  if (m_lsdb)
    3.77 +    {
    3.78 +      NS_LOG_LOGIC ("Deleting LSDB, creating new one");
    3.79 +      delete m_lsdb;
    3.80 +      m_lsdb = new GlobalRouteManagerLSDB ();
    3.81 +    }
    3.82 +}
    3.83 +
    3.84  //
    3.85  // In order to build the routing database, we need at least one of the nodes
    3.86  // to participate as a router.  This is a convenience function that makes
    3.87 @@ -362,11 +407,25 @@
    3.88    for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); i++)
    3.89      {
    3.90        Ptr<Node> node = *i;
    3.91 -      NS_LOG_LOGIC ("Adding GlobalRouter interface to node " << 
    3.92 -        node->GetId ());
    3.93 +      NS_LOG_LOGIC ("Adding GlobalRouter interface to node " << node->GetId ());
    3.94  
    3.95        Ptr<GlobalRouter> globalRouter = CreateObject<GlobalRouter> ();
    3.96        node->AggregateObject (globalRouter);
    3.97 +
    3.98 +      NS_LOG_LOGIC ("Adding GlobalRouting Protocol to node " << node->GetId ());
    3.99 +      Ptr<Ipv4GlobalRouting> globalRouting = CreateObject<Ipv4GlobalRouting> ();
   3.100 +      // This is the object that will keep the global routes.  We insert it
   3.101 +      // at slightly higher priority than static routing (which is at zero).
   3.102 +      // This means that global routes (e.g. host routes) will be consulted
   3.103 +      // before static routes
   3.104 +      Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
   3.105 +      NS_ASSERT_MSG (ipv4, "GlobalRouteManagerImpl::SelectRouterNodes (): "
   3.106 +        "GetObject for <Ipv4> interface failed");
   3.107 +      // XXX make the below  priority value an attribute
   3.108 +      ipv4->AddRoutingProtocol (globalRouting, 3);  
   3.109 +      // Locally cache the globalRouting pointer; we'll need it later
   3.110 +      // when we add routes
   3.111 +      AddGlobalRoutingProtocol (node->GetId (), globalRouting);
   3.112      }
   3.113  }
   3.114  
   3.115 @@ -382,6 +441,21 @@
   3.116  
   3.117        Ptr<GlobalRouter> globalRouter = CreateObject<GlobalRouter> ();
   3.118        node->AggregateObject (globalRouter);
   3.119 +
   3.120 +      NS_LOG_LOGIC ("Adding GlobalRouting Protocol to node " << node->GetId ());
   3.121 +      Ptr<Ipv4GlobalRouting> globalRouting = CreateObject<Ipv4GlobalRouting> ();
   3.122 +      // This is the object that will keep the global routes.  We insert it
   3.123 +      // at slightly higher priority than static routing (which is at zero).
   3.124 +      // This means that global routes (e.g. host routes) will be consulted
   3.125 +      // before static routes
   3.126 +      Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
   3.127 +      NS_ASSERT_MSG (ipv4, "GlobalRouteManagerImpl::SelectRouterNodes (): "
   3.128 +        "GetObject for <Ipv4> interface failed");
   3.129 +      // XXX make the below  priority value an attribute
   3.130 +      ipv4->AddRoutingProtocol (globalRouting, 3);  
   3.131 +      // Locally cache the globalRouting pointer; we'll need it later
   3.132 +      // when we add routes
   3.133 +      AddGlobalRoutingProtocol (node->GetId (), globalRouting);
   3.134      }
   3.135  }
   3.136  
   3.137 @@ -1115,11 +1189,11 @@
   3.138  //
   3.139  // Iterate the algorithm by returning to Step 2 until there are no more
   3.140  // candidate vertices.
   3.141 -//
   3.142 -    }
   3.143 -//
   3.144 -// Second stage of SPF calculation procedure's  
   3.145 -// NOTYET:  ospf_spf_process_stubs (area, area->spf, new_table);
   3.146 +
   3.147 +    }  // end for loop
   3.148 +
   3.149 +// Second stage of SPF calculation procedure  
   3.150 +  SPFProcessStubs (m_spfroot);
   3.151  //
   3.152  // We're all done setting the routing information for the node at the root of
   3.153  // the SPF tree.  Delete all of the vertices and corresponding resources.  Go
   3.154 @@ -1129,6 +1203,155 @@
   3.155    m_spfroot = 0;
   3.156  }
   3.157  
   3.158 +// Processing logic from RFC 2328, page 166 and quagga ospf_spf_process_stubs ()
   3.159 +// stub link records will exist for point-to-point interfaces and for
   3.160 +// broadcast interfaces for which no neighboring router can be found
   3.161 +void
   3.162 +GlobalRouteManagerImpl::SPFProcessStubs (SPFVertex* v)
   3.163 +{
   3.164 +  NS_LOG_FUNCTION_NOARGS ();
   3.165 +  NS_LOG_LOGIC ("Processing stubs for " << v->GetVertexId ());
   3.166 +  if (v->GetVertexType () == SPFVertex::VertexRouter)
   3.167 +    {
   3.168 +      GlobalRoutingLSA *rlsa = v->GetLSA ();
   3.169 +      NS_LOG_LOGIC ("Processing router LSA with id " << rlsa->GetLinkStateId ());
   3.170 +      for (uint32_t i = 0; i < rlsa->GetNLinkRecords (); i++)
   3.171 +        {
   3.172 +          NS_LOG_LOGIC ("Examining link " << i << " of " << 
   3.173 +            v->GetVertexId () << "'s " <<
   3.174 +            v->GetLSA ()->GetNLinkRecords () << " link records");
   3.175 +          GlobalRoutingLinkRecord *l = v->GetLSA ()->GetLinkRecord (i);
   3.176 +          if (l->GetLinkType () == GlobalRoutingLinkRecord::StubNetwork)
   3.177 +            {
   3.178 +              NS_LOG_LOGIC ("Found a Stub record to " << l->GetLinkId ());
   3.179 +              SPFIntraAddStub (l, v);
   3.180 +              continue;
   3.181 +            }
   3.182 +        }
   3.183 +    }
   3.184 +    for (uint32_t i = 0; i < v->GetNChildren (); i++)
   3.185 +      {
   3.186 +        if (!v->GetChild (i)->IsVertexProcessed ())
   3.187 +          {
   3.188 +            SPFProcessStubs (v->GetChild (i));
   3.189 +            v->GetChild (i)->SetVertexProcessed (true);
   3.190 +          }
   3.191 +      }
   3.192 +}
   3.193 +
   3.194 +// RFC2328 16.1. second stage. 
   3.195 +void
   3.196 +GlobalRouteManagerImpl::SPFIntraAddStub (GlobalRoutingLinkRecord *l, SPFVertex* v)
   3.197 +{
   3.198 +  NS_LOG_FUNCTION_NOARGS ();
   3.199 +
   3.200 +  NS_ASSERT_MSG (m_spfroot, 
   3.201 +    "GlobalRouteManagerImpl::SPFIntraAddStub (): Root pointer not set");
   3.202 +
   3.203 +  // XXX simplifed logic for the moment.  There are two cases to consider:
   3.204 +  // 1) the stub network is on this router; do nothing for now
   3.205 +  //    (already handled above)
   3.206 +  // 2) the stub network is on a remote router, so I should use the
   3.207 +  // same next hop that I use to get to vertex v
   3.208 +  if (v->GetVertexId () == m_spfroot->GetVertexId ())
   3.209 +    {
   3.210 +      NS_LOG_LOGIC ("Stub is on local host: " << v->GetVertexId () << "; returning");
   3.211 +      return;
   3.212 +    }
   3.213 +      NS_LOG_LOGIC ("Stub is on remote host: " << v->GetVertexId () << "; installing");
   3.214 +//
   3.215 +// The root of the Shortest Path First tree is the router to which we are 
   3.216 +// going to write the actual routing table entries.  The vertex corresponding
   3.217 +// to this router has a vertex ID which is the router ID of that node.  We're
   3.218 +// going to use this ID to discover which node it is that we're actually going
   3.219 +// to update.
   3.220 +//
   3.221 +  Ipv4Address routerId = m_spfroot->GetVertexId ();
   3.222 +
   3.223 +  NS_LOG_LOGIC ("Vertex ID = " << routerId);
   3.224 +//
   3.225 +// We need to walk the list of nodes looking for the one that has the router
   3.226 +// ID corresponding to the root vertex.  This is the one we're going to write
   3.227 +// the routing information to.
   3.228 +//
   3.229 +  NodeList::Iterator i = NodeList::Begin (); 
   3.230 +  for (; i != NodeList::End (); i++)
   3.231 +    {
   3.232 +      Ptr<Node> node = *i;
   3.233 +//
   3.234 +// The router ID is accessible through the GlobalRouter interface, so we need
   3.235 +// to QI for that interface.  If there's no GlobalRouter interface, the node
   3.236 +// in question cannot be the router we want, so we continue.
   3.237 +// 
   3.238 +      Ptr<GlobalRouter> rtr = 
   3.239 +        node->GetObject<GlobalRouter> ();
   3.240 +
   3.241 +      if (rtr == 0)
   3.242 +        {
   3.243 +          NS_LOG_LOGIC ("No GlobalRouter interface on node " << 
   3.244 +            node->GetId ());
   3.245 +          continue;
   3.246 +        }
   3.247 +//
   3.248 +// If the router ID of the current node is equal to the router ID of the 
   3.249 +// root of the SPF tree, then this node is the one for which we need to 
   3.250 +// write the routing tables.
   3.251 +//
   3.252 +      NS_LOG_LOGIC ("Considering router " << rtr->GetRouterId ());
   3.253 +
   3.254 +      if (rtr->GetRouterId () == routerId)
   3.255 +        {
   3.256 +          NS_LOG_LOGIC ("Setting routes for node " << node->GetId ());
   3.257 +//
   3.258 +// Routing information is updated using the Ipv4 interface.  We need to QI
   3.259 +// for that interface.  If the node is acting as an IP version 4 router, it
   3.260 +// should absolutely have an Ipv4 interface.
   3.261 +//
   3.262 +          Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
   3.263 +          NS_ASSERT_MSG (ipv4, 
   3.264 +            "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
   3.265 +            "QI for <Ipv4> interface failed");
   3.266 +//
   3.267 +// Get the Global Router Link State Advertisement from the vertex we're
   3.268 +// adding the routes to.  The LSA will have a number of attached Global Router
   3.269 +// Link Records corresponding to links off of that vertex / node.  We're going
   3.270 +// to be interested in the records corresponding to point-to-point links.
   3.271 +//
   3.272 +          GlobalRoutingLSA *lsa = v->GetLSA ();
   3.273 +          NS_ASSERT_MSG (lsa, 
   3.274 +            "GlobalRouteManagerImpl::SPFIntraAddRouter (): "
   3.275 +            "Expected valid LSA in SPFVertex* v");
   3.276 +          //Address tempaddr = Address (l->GetLinkData);
   3.277 +          Ipv4Mask tempmask ("255.255.255.0");
   3.278 +          Ipv4Address tempip = l->GetLinkId ();
   3.279 +          tempip = tempip.CombineMask (tempmask);
   3.280 +
   3.281 +          NS_LOG_LOGIC (" Node " << node->GetId () <<
   3.282 +            " add route to " << tempip <<
   3.283 +            " with mask " << tempmask <<
   3.284 +            " using next hop " << v->GetNextHop () <<
   3.285 +            " via interface " << v->GetOutgoingTypeId ());
   3.286 +//
   3.287 +// Here's why we did all of that work.  We're going to add a host route to the
   3.288 +// host address found in the m_linkData field of the point-to-point link
   3.289 +// record.  In the case of a point-to-point link, this is the local IP address
   3.290 +// of the node connected to the link.  Each of these point-to-point links
   3.291 +// will correspond to a local interface that has an IP address to which
   3.292 +// the node at the root of the SPF tree can send packets.  The vertex <v> 
   3.293 +// (corresponding to the node that has these links and interfaces) has 
   3.294 +// an m_nextHop address precalculated for us that is the address to which the
   3.295 +// root node should send packets to be forwarded to these IP addresses.
   3.296 +// Similarly, the vertex <v> has an m_rootOif (outbound interface index) to
   3.297 +// which the packets should be send for forwarding.
   3.298 +//
   3.299 +          Ptr<Ipv4GlobalRouting> gr = GetGlobalRoutingProtocol (node->GetId ());
   3.300 +          NS_ASSERT (gr);
   3.301 +          gr->AddNetworkRouteTo (tempip, tempmask, v->GetNextHop (), v->GetOutgoingTypeId ());
   3.302 +          return;
   3.303 +        } // if
   3.304 +    } // for
   3.305 +}
   3.306 +
   3.307  //
   3.308  // Return the interface index corresponding to a given IP address
   3.309  // This is a wrapper around GetIfIndexByIpv4Address(), but we first
   3.310 @@ -1289,6 +1512,8 @@
   3.311  // the local side of the point-to-point links found on the node described by
   3.312  // the vertex <v>.
   3.313  //
   3.314 +          NS_LOG_LOGIC (" Node " << node->GetId () <<
   3.315 +             " found " << nLinkRecords << " link records in LSA " << lsa << "with LinkStateId "<< lsa->GetLinkStateId ());
   3.316            for (uint32_t j = 0; j < nLinkRecords; ++j)
   3.317              {
   3.318  //
   3.319 @@ -1317,7 +1542,9 @@
   3.320  // Similarly, the vertex <v> has an m_rootOif (outbound interface index) to
   3.321  // which the packets should be send for forwarding.
   3.322  //
   3.323 -              ipv4->AddHostRouteTo (lr->GetLinkData (), v->GetNextHop (),
   3.324 +              Ptr<Ipv4GlobalRouting> gr = GetGlobalRoutingProtocol (node->GetId ());
   3.325 +              NS_ASSERT (gr);
   3.326 +              gr->AddHostRouteTo (lr->GetLinkData (), v->GetNextHop (),
   3.327                  v->GetOutgoingTypeId ());
   3.328              }
   3.329  //
   3.330 @@ -1399,7 +1626,9 @@
   3.331            Ipv4Mask tempmask = lsa->GetNetworkLSANetworkMask ();
   3.332            Ipv4Address tempip = lsa->GetLinkStateId ();
   3.333            tempip = tempip.CombineMask (tempmask);
   3.334 -          ipv4->AddNetworkRouteTo (tempip, tempmask, v->GetNextHop (),
   3.335 +          Ptr<Ipv4GlobalRouting> gr = GetGlobalRoutingProtocol (node->GetId ());
   3.336 +          NS_ASSERT (gr);
   3.337 +          gr->AddNetworkRouteTo (tempip, tempmask, v->GetNextHop (),
   3.338              v->GetOutgoingTypeId ());
   3.339            NS_LOG_LOGIC ("Node " << node->GetId () <<
   3.340              " add network route to " << tempip <<
   3.341 @@ -1427,6 +1656,29 @@
   3.342    v->GetParent ()->AddChild (v);
   3.343  }
   3.344  
   3.345 +  void 
   3.346 +GlobalRouteManagerImpl::AddGlobalRoutingProtocol (uint32_t nodeId, Ptr<Ipv4GlobalRouting> proto)
   3.347 +{
   3.348 +  NS_LOG_FUNCTION (nodeId);
   3.349 +  m_routingProtocols.push_back
   3.350 +    (std::pair<uint32_t, Ptr<Ipv4GlobalRouting> > (nodeId, proto));
   3.351 +  m_routingProtocols.sort ();
   3.352 +}
   3.353 +
   3.354 +  Ptr<Ipv4GlobalRouting>
   3.355 +GlobalRouteManagerImpl::GetGlobalRoutingProtocol (uint32_t nodeId)
   3.356 +{
   3.357 +  for (Ipv4GlobalRoutingList::const_iterator rprotoIter = m_routingProtocols.begin (); rprotoIter != m_routingProtocols.end (); rprotoIter++)
   3.358 +    {
   3.359 +      if ((*rprotoIter).first == nodeId)
   3.360 +        {
   3.361 +          return (*rprotoIter).second;
   3.362 +        }
   3.363 +    }
   3.364 +  return 0;
   3.365 +}
   3.366 +
   3.367 +
   3.368  } // namespace ns3
   3.369  
   3.370  #ifdef RUN_SELF_TESTS
     4.1 --- a/src/routing/global-routing/global-route-manager-impl.h	Mon Dec 01 21:29:59 2008 -0800
     4.2 +++ b/src/routing/global-routing/global-route-manager-impl.h	Mon Dec 01 21:33:52 2008 -0800
     4.3 @@ -37,6 +37,7 @@
     4.4  const uint32_t SPF_INFINITY = 0xffffffff;
     4.5  
     4.6  class CandidateQueue;
     4.7 +class Ipv4GlobalRouting;
     4.8  
     4.9  /**
    4.10   * @brief Vertex used in shortest path first (SPF) computations. See RFC 2328,
    4.11 @@ -546,6 +547,23 @@
    4.12   */
    4.13    uint32_t AddChild (SPFVertex* child);
    4.14  
    4.15 +  /**
    4.16 +   * @brief Set the value of the VertexProcessed flag
    4.17 +   *
    4.18 +   * Flag to note whether vertex has been processed in stage two of 
    4.19 +   * SPF computation
    4.20 +   * @param value boolean value to set the flag
    4.21 +   */ 
    4.22 +  void SetVertexProcessed (bool value);
    4.23 +
    4.24 +  /**
    4.25 +   * @brief Check the value of the VertexProcessed flag
    4.26 +   *
    4.27 +   * Flag to note whether vertex has been processed in stage two of 
    4.28 +   * SPF computation
    4.29 +   * @returns value of underlying flag
    4.30 +   */ 
    4.31 +  bool IsVertexProcessed (void) const;
    4.32  private:
    4.33    VertexType m_vertexType;
    4.34    Ipv4Address m_vertexId;
    4.35 @@ -556,6 +574,7 @@
    4.36    SPFVertex* m_parent;
    4.37    typedef std::list<SPFVertex*> ListOfSPFVertex_t;
    4.38    ListOfSPFVertex_t m_children;
    4.39 +  bool m_vertexProcessed; 
    4.40  
    4.41  /**
    4.42   * @brief The SPFVertex copy construction is disallowed.  There's no need for
    4.43 @@ -701,6 +720,16 @@
    4.44    GlobalRouteManagerImpl ();
    4.45    virtual ~GlobalRouteManagerImpl ();
    4.46  /**
    4.47 + * @brief Delete all static routes on all nodes that have a
    4.48 + * GlobalRouterInterface
    4.49 + *
    4.50 + * TODO:  separate manually assigned static routes from static routes that
    4.51 + * the global routing code injects, and only delete the latter
    4.52 + * @internal
    4.53 + *
    4.54 + */
    4.55 +  virtual void DeleteGlobalRoutes ();
    4.56 +/**
    4.57   * @brief Select which nodes in the system are to be router nodes and 
    4.58   * aggregate the appropriate interfaces onto those nodes.
    4.59   * @internal
    4.60 @@ -760,6 +789,7 @@
    4.61    SPFVertex* m_spfroot;
    4.62    GlobalRouteManagerLSDB* m_lsdb;
    4.63    void SPFCalculate (Ipv4Address root);
    4.64 +  void SPFProcessStubs (SPFVertex* v);
    4.65    void SPFNext (SPFVertex*, CandidateQueue&);
    4.66    int SPFNexthopCalculation (SPFVertex* v, SPFVertex* w, 
    4.67      GlobalRoutingLinkRecord* l, uint32_t distance);
    4.68 @@ -768,8 +798,15 @@
    4.69      GlobalRoutingLinkRecord* prev_link);
    4.70    void SPFIntraAddRouter (SPFVertex* v);
    4.71    void SPFIntraAddTransit (SPFVertex* v);
    4.72 +  void SPFIntraAddStub (GlobalRoutingLinkRecord *l, SPFVertex* v);
    4.73    uint32_t FindOutgoingTypeId (Ipv4Address a, 
    4.74      Ipv4Mask amask = Ipv4Mask("255.255.255.255"));
    4.75 +
    4.76 +  // Local cache of the Ipv4GlobalRouting objects, indexed by nodeId
    4.77 +  typedef std::list< std::pair< uint32_t, Ptr<Ipv4GlobalRouting> > > Ipv4GlobalRoutingList;
    4.78 +  void AddGlobalRoutingProtocol (uint32_t nodeId, Ptr<Ipv4GlobalRouting> proto);
    4.79 +  Ptr<Ipv4GlobalRouting> GetGlobalRoutingProtocol (uint32_t nodeId);
    4.80 +  Ipv4GlobalRoutingList m_routingProtocols;
    4.81  };
    4.82  
    4.83  } // namespace ns3
     5.1 --- a/src/routing/global-routing/global-route-manager.cc	Mon Dec 01 21:29:59 2008 -0800
     5.2 +++ b/src/routing/global-routing/global-route-manager.cc	Mon Dec 01 21:33:52 2008 -0800
     5.3 @@ -50,6 +50,21 @@
     5.4  }
     5.5  
     5.6    void
     5.7 +GlobalRouteManager::RecomputeRoutingTables ()
     5.8 +{
     5.9 +  DeleteGlobalRoutes ();
    5.10 +  BuildGlobalRoutingDatabase ();
    5.11 +  InitializeRoutes ();
    5.12 +}
    5.13 +
    5.14 +  void
    5.15 +GlobalRouteManager::DeleteGlobalRoutes ()
    5.16 +{
    5.17 +  SimulationSingleton<GlobalRouteManagerImpl>::Get ()->
    5.18 +    DeleteGlobalRoutes ();
    5.19 +}
    5.20 +
    5.21 +  void
    5.22  GlobalRouteManager::SelectRouterNodes (void) 
    5.23  {
    5.24    SimulationSingleton<GlobalRouteManagerImpl>::Get ()->
     6.1 --- a/src/routing/global-routing/global-route-manager.h	Mon Dec 01 21:29:59 2008 -0800
     6.2 +++ b/src/routing/global-routing/global-route-manager.h	Mon Dec 01 21:33:52 2008 -0800
     6.3 @@ -45,9 +45,11 @@
     6.4   * the nodes in the simulation.  Makes all nodes in the simulation into
     6.5   * routers.
     6.6   *
     6.7 - * All this function does is call  BuildGlobalRoutingDatabase () and
     6.8 + * All this function does is call the three functions
     6.9 + * SelectRouterNodes (), BuildGlobalRoutingDatabase (), and
    6.10   * InitializeRoutes ().
    6.11   *
    6.12 + * @see SelectRouterNodes ();
    6.13   * @see BuildGlobalRoutingDatabase ();
    6.14   * @see InitializeRoutes ();
    6.15   */
    6.16 @@ -58,20 +60,40 @@
    6.17   * the nodes in the simulation.  Makes the nodes in the provided container
    6.18   * into routers.
    6.19   *
    6.20 - * All this function does is call  BuildGlobalRoutingDatabase () and
    6.21 + * All this function does is call the three functions
    6.22 + * SelectRouterNodes (), BuildGlobalRoutingDatabase (), and
    6.23   * InitializeRoutes ().
    6.24   *
    6.25 + * @see SelectRouterNodes (Node Container c);
    6.26   * @see BuildGlobalRoutingDatabase ();
    6.27   * @see InitializeRoutes ();
    6.28   */
    6.29    static void PopulateRoutingTables (NodeContainer c);
    6.30  
    6.31 + /**
    6.32 +  *@brief Remove all routes that were previously installed in a prior call
    6.33 + * to either PopulateRoutingTables() or RecomputeRoutingTables(), and 
    6.34 + * add a new set of routes.  
    6.35 + * 
    6.36 + * This method does not change the set of nodes
    6.37 + * over which GlobalRouting is being used, but it will dynamically update
    6.38 + * its representation of the global topology before recomputing routes.
    6.39 + * Users must first call PopulateRoutingTables() and then may subsequently
    6.40 + * call RecomputeRoutingTables() at any later time in the simulation.
    6.41 + *
    6.42 + * @see DeleteGlobalRoutes ();
    6.43 + * @see BuildGlobalRoutingDatabase ();
    6.44 + * @see InitializeRoutes ();
    6.45 + */
    6.46 + static void RecomputeRoutingTables ();
    6.47 +
    6.48  /**
    6.49 - * @brief Allocate a 32-bit router ID from monotonically increasing counter.
    6.50 + * @brief Delete all static routes on all nodes that have a 
    6.51 + * GlobalRouterInterface
    6.52 + *
    6.53   */
    6.54 -  static uint32_t AllocateRouterId ();
    6.55 +  static void DeleteGlobalRoutes ();
    6.56  
    6.57 -private:
    6.58  /**
    6.59   * @brief Select which nodes in the system are to be router nodes and 
    6.60   * aggregate the appropriate interfaces onto those nodes.
    6.61 @@ -89,6 +111,13 @@
    6.62    static void SelectRouterNodes (NodeContainer c);
    6.63  
    6.64  /**
    6.65 + * @brief Allocate a 32-bit router ID from monotonically increasing counter.
    6.66 + */
    6.67 +  static uint32_t AllocateRouterId ();
    6.68 +
    6.69 +private:
    6.70 +
    6.71 +/**
    6.72   * @brief Build the routing database by gathering Link State Advertisements
    6.73   * from each node exporting a GlobalRouter interface.
    6.74   * @internal
     7.1 --- a/src/routing/global-routing/global-router-interface.cc	Mon Dec 01 21:29:59 2008 -0800
     7.2 +++ b/src/routing/global-routing/global-router-interface.cc	Mon Dec 01 21:33:52 2008 -0800
     7.3 @@ -413,23 +413,30 @@
     7.4  
     7.5            os << "---------- RouterLSA Link Record ----------" << std::endl;
     7.6            os << "m_linkType = " << p->m_linkType;
     7.7 -          if (p->m_linkType == GlobalRoutingLinkRecord::TransitNetwork)
     7.8 +          if (p->m_linkType == GlobalRoutingLinkRecord::PointToPoint)
     7.9 +            {
    7.10 +              os << " (GlobalRoutingLinkRecord::PointToPoint)" << std::endl;
    7.11 +              os << "m_linkId = " << p->m_linkId << std::endl;
    7.12 +              os << "m_linkData = " << p->m_linkData << std::endl;
    7.13 +              os << "m_metric = " << p->m_metric << std::endl;
    7.14 +            }
    7.15 +          else if (p->m_linkType == GlobalRoutingLinkRecord::TransitNetwork)
    7.16              {
    7.17                os << " (GlobalRoutingLinkRecord::TransitNetwork)" << std::endl;
    7.18                os << "m_linkId = " << p->m_linkId << " (Designated router for network)" << std::endl;
    7.19                os << "m_linkData = " << p->m_linkData << " (This router's IP address)" << std::endl;
    7.20                os << "m_metric = " << p->m_metric << std::endl;
    7.21              }
    7.22 -          else if (p->GetLinkType () == GlobalRoutingLinkRecord::StubNetwork)
    7.23 +          else if (p->m_linkType == GlobalRoutingLinkRecord::StubNetwork)
    7.24              {
    7.25 -              os << "(GlobalRoutingLinkRecord::StubNetwork)" << std::endl;
    7.26 +              os << " (GlobalRoutingLinkRecord::StubNetwork)" << std::endl;
    7.27                os << "m_linkId = " << p->m_linkId << " (Network number of attached network)" << std::endl;
    7.28                os << "m_linkData = " << p->m_linkData << " (Network mask of attached network)" << std::endl;
    7.29                os << "m_metric = " << p->m_metric << std::endl;
    7.30              }
    7.31            else
    7.32              {
    7.33 -              os << "(Unknown LinkType)" << std::endl;
    7.34 +              os << " (Unknown LinkType)" << std::endl;
    7.35                os << "m_linkId = " << p->m_linkId << std::endl;
    7.36                os << "m_linkData = " << p->m_linkData << std::endl;
    7.37                os << "m_metric = " << p->m_metric << std::endl;
    7.38 @@ -513,7 +520,7 @@
    7.39  
    7.40        *i = 0;
    7.41      }
    7.42 -  NS_LOG_LOGIC ("Clear list");
    7.43 +  NS_LOG_LOGIC ("Clear list of LSAs");
    7.44    m_LSAs.clear();
    7.45  }
    7.46  
    7.47 @@ -599,9 +606,9 @@
    7.48        // IP addresses in routing.
    7.49        //
    7.50        bool isIp = false;
    7.51 -      for (uint32_t i = 0; i < ipv4Local->GetNInterfaces (); ++i )
    7.52 +      for (uint32_t j = 0; j < ipv4Local->GetNInterfaces (); ++j )
    7.53          {
    7.54 -          if (ipv4Local->GetNetDevice (i) == ndLocal) 
    7.55 +          if (ipv4Local->GetNetDevice (j) == ndLocal && ipv4Local->IsUp (j)) 
    7.56              {
    7.57                isIp = true;
    7.58                break;
    7.59 @@ -621,7 +628,7 @@
    7.60        // the segment.  We add the appropriate link record to the LSA.
    7.61        //
    7.62        // If the device is a point to point link, we treat it separately.  In
    7.63 -      // that case, there always two link records added.
    7.64 +      // that case, there may be one or two link records added.
    7.65        //
    7.66        if (ndLocal->IsBroadcast () && !ndLocal->IsPointToPoint () )
    7.67          {
    7.68 @@ -1020,15 +1027,22 @@
    7.69    // link records; the first is a point-to-point record describing the link and
    7.70    // the second is a stub network record with the network number.
    7.71    //
    7.72 -  GlobalRoutingLinkRecord *plr = new GlobalRoutingLinkRecord;
    7.73 -  NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessPointToPointLink(): Can't alloc link record");
    7.74 -  plr->SetLinkType (GlobalRoutingLinkRecord::PointToPoint);
    7.75 -  plr->SetLinkId (rtrIdRemote);
    7.76 -  plr->SetLinkData (addrLocal);
    7.77 -  plr->SetMetric (metricLocal);
    7.78 -  pLSA->AddLinkRecord (plr);
    7.79 -  plr = 0;
    7.80 +  GlobalRoutingLinkRecord *plr;
    7.81 +  if (ipv4Remote->IsUp (ifIndexRemote))
    7.82 +    {
    7.83 +      NS_LOG_LOGIC ("Remote side interface " << ifIndexRemote << " is up-- add a type 1 link");
    7.84 + 
    7.85 +      plr  = new GlobalRoutingLinkRecord;
    7.86 +      NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessPointToPointLink(): Can't alloc link record");
    7.87 +      plr->SetLinkType (GlobalRoutingLinkRecord::PointToPoint);
    7.88 +      plr->SetLinkId (rtrIdRemote);
    7.89 +      plr->SetLinkData (addrLocal);
    7.90 +      plr->SetMetric (metricLocal);
    7.91 +      pLSA->AddLinkRecord (plr);
    7.92 +      plr = 0;
    7.93 +    }
    7.94  
    7.95 +  // Regardless of state of peer, add a type 3 link (RFC 2328: 12.4.1.1)
    7.96    plr = new GlobalRoutingLinkRecord;
    7.97    NS_ABORT_MSG_IF (plr == 0, "GlobalRouter::ProcessPointToPointLink(): Can't alloc link record");
    7.98    plr->SetLinkType (GlobalRoutingLinkRecord::StubNetwork);
    7.99 @@ -1108,8 +1122,15 @@
   7.100              {
   7.101                Ptr<Ipv4> tempIpv4 = tempNode->GetObject<Ipv4> ();
   7.102                NS_ASSERT (tempIpv4);
   7.103 -              Ipv4Address tempAddr = tempIpv4->GetAddress(tempIfIndex);
   7.104 -              pLSA->AddAttachedRouter (tempAddr);
   7.105 +              if (!tempIpv4->IsUp (tempIfIndex))
   7.106 +                {
   7.107 +                  NS_LOG_LOGIC ("Remote side interface " << tempIfIndex << " not up");
   7.108 +                }
   7.109 +              else 
   7.110 +                {
   7.111 +                  Ipv4Address tempAddr = tempIpv4->GetAddress(tempIfIndex);
   7.112 +                  pLSA->AddAttachedRouter (tempAddr);
   7.113 +                }
   7.114              }
   7.115          }
   7.116        m_LSAs.push_back (pLSA);
   7.117 @@ -1180,6 +1201,11 @@
   7.118                if (FindIfIndexForDevice(nodeOther, bnd, ifIndexOther))
   7.119                  {
   7.120                    NS_LOG_LOGIC ("Found router on bridge net device " << bnd);
   7.121 +                  if (!ipv4->IsUp (ifIndexOther))
   7.122 +                    {
   7.123 +                      NS_LOG_LOGIC ("Remote side interface " << ifIndexOther << " not up");
   7.124 +                      continue;
   7.125 +                    }
   7.126                    Ipv4Address addrOther = ipv4->GetAddress (ifIndexOther);
   7.127                    desigRtr = addrOther < desigRtr ? addrOther : desigRtr;
   7.128                    NS_LOG_LOGIC ("designated router now " << desigRtr);
   7.129 @@ -1223,6 +1249,11 @@
   7.130                uint32_t ifIndexOther;
   7.131                if (FindIfIndexForDevice(nodeOther, ndOther, ifIndexOther))
   7.132                  {
   7.133 +                  if (!ipv4->IsUp (ifIndexOther))
   7.134 +                    {
   7.135 +                      NS_LOG_LOGIC ("Remote side interface " << ifIndexOther << " not up");
   7.136 +                      continue;
   7.137 +                    }
   7.138                    NS_LOG_LOGIC ("Found router on net device " << ndOther);
   7.139                    Ipv4Address addrOther = ipv4->GetAddress (ifIndexOther);
   7.140                    desigRtr = addrOther < desigRtr ? addrOther : desigRtr;