/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2011 UCLA
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation;
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Author:  Alexander Afanasyev <alexander.afanasyev@ucla.edu>
 *          Ilya Moiseenko <iliamo@cs.ucla.edu> 
 */

/**
 * \ingroup ccnx
 * \defgroup CcnxStackModel Ccnx Stack Model
 *
 * \section CcnxStackTracingModel Tracing in the Ccnx Stack
 *
 * The ccnx stack provides a number of trace sources in its various
 * protocol implementations.  These trace sources can be hooked using your own 
 * custom trace code, or you can use our helper functions in some cases to 
 * arrange for tracing to be enabled.
 *
 * \subsection CcnxStackCcnxTracingModel Tracing in Ccnx
 *
 * The Ccnx layer three protocol provides three trace hooks.  These are the 
 * "Tx" (ns3::CcnxL3Protocol::m_txTrace), "Rx" (ns3::CcnxL3Protocol::m_rxTrace) 
 * and "Drop" (ns3::CcnxL3Protocol::m_dropTrace) trace sources.
 *
 * The "Tx" trace is fired in a number of situations, all of which indicate that
 * a given packet is about to be sent down to a given ns3::CcnxFace.
 *
 * - \todo list Tx trace events
 *
 * The "Rx" trace is fired when a packet is passed from the device up to the
 * ns3::CcnxL3Protocol::Receive function.
 *
 * - In the receive function, the CcnxFaceList is iterated, and if the
 *   CcnxFace corresponding to the receiving device is found to be in the
 *   UP state, the trace is fired.
 *
 * The "Drop" trace is fired in any case where the packet is dropped (in both
 * the transmit and receive paths).
 *
 * - \todo list Drop trace events
 */

#include "ns3/assert.h"
#include "ns3/log.h"
#include "ns3/object.h"
#include "ns3/names.h"
#include "ns3/packet-socket-factory.h"
#include "ns3/config.h"
#include "ns3/simulator.h"
#include "ns3/string.h"
#include "ns3/net-device.h"
#include "ns3/callback.h"
#include "ns3/node.h"
#include "ns3/core-config.h"
#include "ns3/point-to-point-net-device.h"
#include "ns3/point-to-point-helper.h"

#include "../model/ccnx-forwarding-strategy.h"
#include "../model/ccnx-net-device-face.h"
#include "../model/ccnx-l3-protocol.h"
#include "../model/ccnx-fib.h"

#include "ns3/node-list.h"
#include "ns3/loopback-net-device.h"
#include "ns3/global-router-interface.h"
#include "ns3/ipv4.h"
#include "ns3/ipv4-global-routing.h"
#include "../utils/ipv4-global-routing-ordered-nexthops.h"

#include "ns3/ipv4-routing-helper.h"
#include "ns3/ipv4-global-routing-helper.h"
#include "ns3/data-rate.h"

#include "ccnx-face-container.h"
#include "ccnx-stack-helper.h"

#include <limits>
#include <map>
#include <boost/foreach.hpp>

#define NDN_DEFAULT_DATA_SIZE      1024

NS_LOG_COMPONENT_DEFINE ("CcnxStackHelper");

namespace ns3 {

// Things are going to work differently here with respect to trace
// file handling than in most places because the Tx and Rx trace
// sources we are interested in are going to multiplex receive and
// transmit callbacks for all Ccnx and face pairs through one
// callback.  We want packets to or from each distinct pair to go to
// an individual file, so we have got to demultiplex the Ccnx and face
// pair into a corresponding Ptr<PcapFileWrapper> at the callback.
//
// A complication in this situation is that the trace sources are
// hooked on a protocol basis.  There is no trace source hooked by an
// Ccnx and face pair.  This means that if we naively proceed to hook,
// say, a drop trace for a given Ccnx with face 0, and then hook for
// Ccnx with face 1 we will hook the drop trace twice and get two
// callbacks per event.  What we need to do is to hook the event once,
// and that will result in a single callback per drop event, and the
// trace source will provide the face which we filter on in the trace
// sink.
// 
// This has got to continue to work properly after the helper has been
// destroyed; but must be cleaned up at the end of time to avoid
// leaks.  Global maps of protocol/face pairs to file objects seems to
// fit the bill.
//
// typedef std::pair<Ptr<Ccnx>, uint32_t> FacePairCcnx; 
// typedef std::map<FacePairCcnx, Ptr<PcapFileWrapper> > FaceFileMapCcnx;
// typedef std::map<FacePairCcnx, Ptr<OutputStreamWrapper> > FaceStreamMapCcnx;

// static FaceFileMapCcnx g_faceFileMapCcnx; /**< A mapping of Ccnx/face pairs to pcap files */
// static FaceStreamMapCcnx g_faceStreamMapCcnx; /**< A mapping of Ccnx/face pairs to ascii streams */

    
CcnxStackHelper::CcnxStackHelper ()
  : m_limitsEnabled (false)
  , m_needSetDefaultRoutes (false)
{
  m_strategyFactory.SetTypeId ("ns3::CcnxFloodingStrategy");
}
    
CcnxStackHelper::~CcnxStackHelper ()
{
}

void 
CcnxStackHelper::SetForwardingStrategy (std::string strategy)
{
  m_strategyFactory.SetTypeId (strategy);
}


void
CcnxStackHelper::SetDefaultRoutes (bool needSet)
{
  NS_LOG_FUNCTION (this << needSet);
  m_needSetDefaultRoutes = needSet;
}

void
CcnxStackHelper::EnableLimits (bool enable/* = true*/, Time avgRtt/*=Seconds(0.1)*/, uint32_t avgContentObject/*=1100*/, uint32_t avgInterest/*=40*/)
{
  NS_LOG_INFO ("EnableLimits: " << enable);
  m_limitsEnabled = enable;
  m_avgRtt = avgRtt;
  m_avgContentObjectSize = avgContentObject;
  m_avgInterestSize = avgInterest;
}

Ptr<CcnxFaceContainer>
CcnxStackHelper::Install (NodeContainer c) const
{
  Ptr<CcnxFaceContainer> faces = Create<CcnxFaceContainer> ();
  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
    {
      faces->AddAll (Install (*i));
    }
  return faces;
}

Ptr<CcnxFaceContainer>
CcnxStackHelper::InstallAll (void) const
{
  return Install (NodeContainer::GetGlobal ());
}

Ptr<CcnxFaceContainer>
CcnxStackHelper::Install (Ptr<Node> node) const
{
  // NS_ASSERT_MSG (m_forwarding, "SetForwardingHelper() should be set prior calling Install() method");
  Ptr<CcnxFaceContainer> faces = Create<CcnxFaceContainer> ();
  
  if (node->GetObject<Ccnx> () != 0)
    {
      NS_FATAL_ERROR ("CcnxStackHelper::Install (): Installing " 
                      "a CcnxStack to a node with an existing Ccnx object");
      return 0;
    }

  Ptr<CcnxFib> fib = CreateObject<CcnxFib> ();
  node->AggregateObject (fib);

  Ptr<CcnxL3Protocol> ccnx = CreateObject<CcnxL3Protocol> ();
  node->AggregateObject (ccnx);

  ccnx->SetForwardingStrategy (m_strategyFactory.Create<CcnxForwardingStrategy> ());
  
  for (uint32_t index=0; index < node->GetNDevices (); index++)
    {
      Ptr<NetDevice> device = node->GetDevice (index);
      if (DynamicCast<LoopbackNetDevice> (device) != 0)
        continue; // don't create face for a LoopbackNetDevice

      Ptr<CcnxNetDeviceFace> face = CreateObject<CcnxNetDeviceFace> (node, device);

      ccnx->AddFace (face);
      NS_LOG_LOGIC ("Node " << node->GetId () << ": added CcnxNetDeviceFace as face #" << *face);

      if (m_needSetDefaultRoutes)
        {
          // default route with lowest priority possible
          AddRoute (node, "/", face, std::numeric_limits<int32_t>::max ()); 
        }
      
      if (m_limitsEnabled)
        {
          NS_LOG_INFO ("Limits are enabled");
          Ptr<PointToPointNetDevice> p2p = DynamicCast<PointToPointNetDevice> (device);
          if (p2p == 0)
            {
              NS_LOG_INFO ("Non p2p interface");
              continue; // only PointToPointNetDevice supports limits
            }

          // Setup bucket filtering
          // Assume that we know average data packet size, and this size is equal default size
          // Set maximum buckets (averaging over 1 second)
      
          DataRateValue dataRate; device->GetAttribute ("DataRate", dataRate);
          
          NS_LOG_INFO("DataRate for this link is " << dataRate.Get());

          double maxInterestPackets = 1.0  * dataRate.Get ().GetBitRate () / 8.0 / m_avgContentObjectSize;
          NS_LOG_INFO ("Max packets per second: " << maxInterestPackets);
          NS_LOG_INFO ("Max burst: " << m_avgRtt.ToDouble (Time::S) * maxInterestPackets);

          // Set bucket max to BDP
          face->SetBucketMax (m_avgRtt.ToDouble (Time::S) * maxInterestPackets); // number of interests allowed
          face->SetBucketLeak (maxInterestPackets);
        }
        
      face->SetUp ();
      faces->Add (face);
    }
    
  return faces;
}

Ptr<CcnxFaceContainer>
CcnxStackHelper::Install (std::string nodeName) const
{
  Ptr<Node> node = Names::Find<Node> (nodeName);
  return Install (node);
}


void
CcnxStackHelper::AddRoute (Ptr<Node> node, std::string prefix, Ptr<CcnxFace> face, int32_t metric) const
{
  NS_LOG_LOGIC ("[" << node->GetId () << "]$ route add " << prefix << " via " << *face << " metric " << metric);

  Ptr<CcnxFib>  fib  = node->GetObject<CcnxFib> ();

  CcnxNameComponentsValue prefixValue;
  prefixValue.DeserializeFromString (prefix, MakeCcnxNameComponentsChecker ());
  fib->Add (prefixValue.Get (), face, metric);
}

void
CcnxStackHelper::AddRoute (std::string nodeName, std::string prefix, uint32_t faceId, int32_t metric) const
{
  Ptr<Node> node = Names::Find<Node> (nodeName);
  NS_ASSERT_MSG (node != 0, "Node [" << nodeName << "] does not exist");
  
  Ptr<Ccnx>     ccnx = node->GetObject<Ccnx> ();
  NS_ASSERT_MSG (ccnx != 0, "Ccnx stack should be installed on the node");

  Ptr<CcnxFace> face = ccnx->GetFace (faceId);
  NS_ASSERT_MSG (face != 0, "Face with ID [" << faceId << "] does not exist on node [" << nodeName << "]");

  AddRoute (node, prefix, face, metric);
}

/*
  void
  CcnxStackHelper::AddRoute (Ptr<Node> node, std::string prefix, uint32_t faceId, int32_t metric)
  {
  NS_LOG_LOGIC ("[" << nodeName << "]$ route add " << prefix << " via " << faceId << " metric " << metric);
    
  NS_ASSERT_MSG (node != 0, "Node does not exist");
        
  Ptr<Ccnx>     ccnx = node->GetObject<Ccnx> ();
  Ptr<CcnxFib>  fib  = node->GetObject<CcnxFib> ();
  Ptr<CcnxFace> face = ccnx->GetFace (faceId);
  NS_ASSERT_MSG (node != 0, "Face with ID [" << faceId << "] does not exist on node [" << nodeName << "]");
        
  CcnxNameComponentsValue prefixValue;
  prefixValue.DeserializeFromString (prefix, MakeCcnxNameComponentsChecker ());
  fib->Add (prefixValue.Get (), face, metric);
  }
*/

// static void
// CcnxL3ProtocolRxTxSink (Ptr<const Packet> p, Ptr<Ccnx> ccnx, uint32_t face)
// {
//   NS_LOG_FUNCTION (p << ccnx << face);

//   //
//   // Since trace sources are independent of face, if we hook a source
//   // on a particular protocol we will get traces for all of its faces.
//   // We need to filter this to only report faces for which the user 
//   // has expressed interest.
//   //
//   FacePairCcnx pair = std::make_pair (ccnx, face);
//   if (g_faceFileMapCcnx.find (pair) == g_faceFileMapCcnx.end ())
//     {
//       NS_LOG_INFO ("Ignoring packet to/from face " << face);
//       return;
//     }

//   Ptr<PcapFileWrapper> file = g_faceFileMapCcnx[pair];
//   file->Write (Simulator::Now (), p);
// }

// bool
// CcnxStackHelper::PcapHooked (Ptr<Ccnx> ccnx)
// {
//   for (FaceFileMapCcnx::const_iterator i = g_faceFileMapCcnx.begin (); 
//        i != g_faceFileMapCcnx.end (); 
//        ++i)
//     {
//       if ((*i).first.first == ccnx)
//         {
//           return true;
//         }
//     }
//   return false;
// }

// void 
// CcnxStackHelper::EnablePcapCcnxInternal (std::string prefix, Ptr<Ccnx> ccnx, uint32_t face, bool explicitFilename)
// {
//   NS_LOG_FUNCTION (prefix << ccnx << face);

//   //
//   // We have to create a file and a mapping from protocol/face to file 
//   // irrespective of how many times we want to trace a particular protocol.
//   //
//   PcapHelper pcapHelper;

//   std::string filename;
//   if (explicitFilename)
//     {
//       filename = prefix;
//     }
//   else
//     {
//       filename = pcapHelper.GetFilenameFromInterfacePair (prefix, ccnx, face);
//     }

//   Ptr<PcapFileWrapper> file = pcapHelper.CreateFile (filename, std::ios::out, PcapHelper::DLT_RAW);

//   //
//   // However, we only hook the trace source once to avoid multiple trace sink
//   // calls per event (connect is independent of face).
//   //
//   if (!PcapHooked (ccnx))
//     {
//       //
//       // Ptr<Ccnx> is aggregated to node and CcnxL3Protocol is aggregated to 
//       // node so we can get to CcnxL3Protocol through Ccnx.
//       //
//       Ptr<CcnxL3Protocol> ccnxL3Protocol = ccnx->GetObject<CcnxL3Protocol> ();
//       NS_ASSERT_MSG (ccnxL3Protocol, "CcnxStackHelper::EnablePcapCcnxInternal(): "
//                      "m_ccnxEnabled and ccnxL3Protocol inconsistent");

//       bool result = ccnxL3Protocol->TraceConnectWithoutContext ("Tx", MakeCallback (&CcnxL3ProtocolRxTxSink));
//       NS_ASSERT_MSG (result == true, "CcnxStackHelper::EnablePcapCcnxInternal():  "
//                      "Unable to connect ccnxL3Protocol \"Tx\"");

//       result = ccnxL3Protocol->TraceConnectWithoutContext ("Rx", MakeCallback (&CcnxL3ProtocolRxTxSink));
//       NS_ASSERT_MSG (result == true, "CcnxStackHelper::EnablePcapCcnxInternal():  "
//                      "Unable to connect ccnxL3Protocol \"Rx\"");
//       // cast result to void, to suppress ‘result’ set but not used compiler-warning
//       // for optimized builds
//       (void) result;
//     }

//   g_faceFileMapCcnx[std::make_pair (ccnx, face)] = file;
// }

// static void
// CcnxL3ProtocolDropSinkWithoutContext (
//   Ptr<OutputStreamWrapper> stream,
//   Ptr<const Packet> packet,
//   CcnxL3Protocol::DropReason reason, 
//   Ptr<Ccnx> ccnx, 
//   uint32_t face)
// {
//   //
//   // Since trace sources are independent of face, if we hook a source
//   // on a particular protocol we will get traces for all of its faces.
//   // We need to filter this to only report faces for which the user 
//   // has expressed interest.
//   //
//   FacePairCcnx pair = std::make_pair (ccnx, face);
//   if (g_faceStreamMapCcnx.find (pair) == g_faceStreamMapCcnx.end ())
//     {
//       NS_LOG_INFO ("Ignoring packet to/from face " << face);
//       return;
//     }

//   *stream->GetStream () << "d " << Simulator::Now ().GetSeconds () << " " << *packet << std::endl;
// }

// static void
// CcnxL3ProtocolDropSinkWithContext (
//   Ptr<OutputStreamWrapper> stream,
//   std::string context,
//   Ptr<const Packet> packet,
//   CcnxL3Protocol::DropReason reason, 
//   Ptr<Ccnx> ccnx, 
//   uint32_t face)
// {
//   //
//   // Since trace sources are independent of face, if we hook a source
//   // on a particular protocol we will get traces for all of its faces.
//   // We need to filter this to only report faces for which the user 
//   // has expressed interest.
//   //
//   FacePairCcnx pair = std::make_pair (ccnx, face);
//   if (g_faceStreamMapCcnx.find (pair) == g_faceStreamMapCcnx.end ())
//     {
//       NS_LOG_INFO ("Ignoring packet to/from face " << face);
//       return;
//     }

//   *stream->GetStream () << "d " << Simulator::Now ().GetSeconds () << " " << context << "(" << face << ") " 
//                         << *packet << std::endl;
// }

// bool
// CcnxStackHelper::AsciiHooked (Ptr<Ccnx> ccnx)
// {
//   for (  FaceStreamMapCcnx::const_iterator i = g_faceStreamMapCcnx.begin (); 
//          i != g_faceStreamMapCcnx.end (); 
//          ++i)
//     {
//       if ((*i).first.first == ccnx)
//         {
//           return true;
//         }
//     }
//   return false;
// }

// void 
// CcnxStackHelper::EnableAsciiCcnxInternal (
//   Ptr<OutputStreamWrapper> stream, 
//   std::string prefix, 
//   Ptr<Ccnx> ccnx, 
//   uint32_t face,
//   bool explicitFilename)
// {
//   //
//   // Our trace sinks are going to use packet printing, so we have to 
//   // make sure that is turned on.
//   //
//   Packet::EnablePrinting ();

//   //
//   // If we are not provided an OutputStreamWrapper, we are expected to create 
//   // one using the usual trace filename conventions and hook WithoutContext
//   // since there will be one file per context and therefore the context would
//   // be redundant.
//   //
//   if (stream == 0)
//     {
//       //
//       // Set up an output stream object to deal with private ofstream copy 
//       // constructor and lifetime issues.  Let the helper decide the actual
//       // name of the file given the prefix.
//       //
//       // We have to create a stream and a mapping from protocol/face to 
//       // stream irrespective of how many times we want to trace a particular 
//       // protocol.
//       //
//       AsciiTraceHelper asciiTraceHelper;

//       std::string filename;
//       if (explicitFilename)
//         {
//           filename = prefix;
//         }
//       else
//         {
//           filename = asciiTraceHelper.GetFilenameFromInterfacePair (prefix, ccnx, face);
//         }

//       Ptr<OutputStreamWrapper> theStream = asciiTraceHelper.CreateFileStream (filename);

//       //
//       // However, we only hook the trace sources once to avoid multiple trace sink
//       // calls per event (connect is independent of face).
//       //
//       if (!AsciiHooked (ccnx))
//         {
//           //
//           // The drop sink for the CcnxL3Protocol uses a different signature than
//           // the default sink, so we have to cook one up for ourselves.  We can get
//           // to the Ptr<CcnxL3Protocol> through our Ptr<Ccnx> since they must both 
//           // be aggregated to the same node.
//           //
//           Ptr<CcnxL3Protocol> ccnxL3Protocol = ccnx->GetObject<CcnxL3Protocol> ();
//           bool __attribute__ ((unused)) result = ccnxL3Protocol->TraceConnectWithoutContext ("Drop", 
//                                                                                              MakeBoundCallback (&CcnxL3ProtocolDropSinkWithoutContext, theStream));
//           NS_ASSERT_MSG (result == true, "CcnxStackHelper::EanableAsciiCcnxInternal():  "
//                          "Unable to connect ccnxL3Protocol \"Drop\"");
//         }

//       g_faceStreamMapCcnx[std::make_pair (ccnx, face)] = theStream;
//       return;
//     }

//   //
//   // If we are provided an OutputStreamWrapper, we are expected to use it, and
//   // to provide a context.  We are free to come up with our own context if we
//   // want, and use the AsciiTraceHelper Hook*WithContext functions, but for 
//   // compatibility and simplicity, we just use Config::Connect and let it deal
//   // with the context.
//   //
//   // We need to associate the ccnx/face with a stream to express interest
//   // in tracing events on that pair, however, we only hook the trace sources 
//   // once to avoid multiple trace sink calls per event (connect is independent
//   // of face).
//   //
//   if (!AsciiHooked (ccnx))
//     {
//       Ptr<Node> node = ccnx->GetObject<Node> ();
//       std::ostringstream oss;

//       //
//       // This has all kinds of parameters coming with, so we have to cook up our
//       // own sink.
//       //
//       oss.str ("");
//       oss << "/NodeList/" << node->GetId () << "/$ns3::CcnxL3Protocol/Drop";
//       Config::Connect (oss.str (), MakeBoundCallback (&CcnxL3ProtocolDropSinkWithContext, stream));
//     }

//   g_faceStreamMapCcnx[std::make_pair (ccnx, face)] = stream;
// }

void
CcnxStackHelper::InstallFakeGlobalRoutes ()
{
  for (NodeList::Iterator node = NodeList::Begin ();
       node != NodeList::End ();
       node ++)
    {
      NS_ASSERT_MSG ((*node)->GetObject<Ipv4> () != 0,
                     "InternetStack should be installed on all nodes");

      NS_ASSERT_MSG (Ipv4RoutingHelper::GetRouting<Ipv4GlobalRoutingOrderedNexthops>
                     (
                      (*node)->GetObject<Ipv4> ()->GetRoutingProtocol ()
                      ),
                     "InternetStack should have Ipv4GlobalRoutingOrderedNexthops as routing protocol");
      // Example:
      //
      // Ipv4GlobalRoutingHelper ipv4RoutingHelper ("ns3::Ipv4GlobalRoutingUnorderedNexthops");
      // stack.SetRoutingHelper (ipv4RoutingHelper);
      //
      
      Ptr<GlobalRouter> globalRouter = (*node)->GetObject<GlobalRouter> ();
      if (globalRouter == 0) continue;

      globalRouter->InjectRoute (Ipv4Address((*node)->GetId ()), Ipv4Mask("255.255.255.255"));
    }

  Ipv4GlobalRoutingHelper::PopulateAllPossibleRoutingTables ();
}

void
CcnxStackHelper::InstallRouteTo (Ptr<Node> destNode)
{
  std::ostringstream destPrefix;
  destPrefix << "/" << destNode->GetId ();

  Ipv4Address destIpv4 = Ipv4Address(destNode->GetId ());
  
  for (NodeList::Iterator node = NodeList::Begin ();
       node != NodeList::End ();
       node ++)
    {
      if (destNode == *node) continue;
      
      Ptr<Ccnx> ccnx = (*node)->GetObject<Ccnx> ();
      NS_ASSERT_MSG (ccnx != 0, "CCNx stack should be installed on all nodes");

      Ptr<Ipv4> ipv4 = (*node)->GetObject<Ipv4> ();
      NS_ASSERT_MSG (ipv4 != 0,
                     "InternetStack should be installed on all nodes");
      
      Ptr<Ipv4GlobalRoutingOrderedNexthops> routing =
        Ipv4RoutingHelper::GetRouting<Ipv4GlobalRoutingOrderedNexthops> (ipv4->GetRoutingProtocol ());
      NS_ASSERT_MSG (routing != 0, "Ipv4GlobalRoutingOrderedNexthops should be used in InternetStack");

      Ptr<Ipv4GlobalRoutingOrderedNexthops::EntryContainer>
        routes = routing->Lookup (destIpv4);

      NS_ASSERT_MSG (routes != 0, "Should not happen... Call the developer");

      BOOST_FOREACH (const Ipv4RoutingTableEntry &entry, *routes)
        {
          Ptr<NetDevice> netDevice = ipv4->GetNetDevice (entry.GetInterface ());
          NS_ASSERT_MSG (netDevice != 0, "Should never happen. Call the popos");
          
          Ptr<CcnxFace> face = ccnx->GetFaceByNetDevice (netDevice);
          NS_ASSERT_MSG (face != 0, "Definitely should never happen. Call the president");
            
          AddRoute (*node, destPrefix.str(), face, entry.GetMetric ());
        }
    }
}

void
CcnxStackHelper::InstallRoutesToAll ()
{
  for (NodeList::Iterator node = NodeList::Begin ();
       node != NodeList::End ();
       node ++)
    {
      InstallRouteTo (*node);
    }
}


} // namespace ns3
