Finalizing BGL-implementation of ccnx global routing controller. Also, several extensions in CcnxFib
diff --git a/model/ccnx-fib.cc b/model/ccnx-fib.cc
index b068954..bfcb961 100644
--- a/model/ccnx-fib.cc
+++ b/model/ccnx-fib.cc
@@ -33,6 +33,7 @@
 #define NDN_RTO_BETA 0.25
 #define NDN_RTO_K 4
 
+#include <boost/ref.hpp>
 #include <boost/lambda/lambda.hpp>
 #include <boost/lambda/bind.hpp>
 namespace ll = boost::lambda;
@@ -138,14 +139,36 @@
     }
   else
   {
-    m_faces.modify (record,
-                    (&ll::_1)->*&CcnxFibFaceMetric::m_routingCost = metric);
+    // don't update metric to higher value
+    if (record->m_routingCost > metric || record->m_status == CcnxFibFaceMetric::NDN_FIB_RED)
+      {
+        m_faces.modify (record,
+                        (&ll::_1)->*&CcnxFibFaceMetric::m_routingCost = metric);
+
+        m_faces.modify (record,
+                        (&ll::_1)->*&CcnxFibFaceMetric::m_status = CcnxFibFaceMetric::NDN_FIB_YELLOW);
+      }
   }
   
   // reordering random access index same way as by metric index
   m_faces.get<i_nth> ().rearrange (m_faces.get<i_metric> ().begin ());
 }
 
+void
+CcnxFibEntry::Invalidate ()
+{
+  for (CcnxFibFaceMetricByFace::type::iterator face = m_faces.begin ();
+       face != m_faces.end ();
+       face++)
+    {
+      m_faces.modify (face,
+                      (&ll::_1)->*&CcnxFibFaceMetric::m_routingCost = std::numeric_limits<uint16_t>::max ());
+
+      m_faces.modify (face,
+                      (&ll::_1)->*&CcnxFibFaceMetric::m_status = CcnxFibFaceMetric::NDN_FIB_RED);
+    }
+}
+
 const CcnxFibFaceMetric &
 CcnxFibEntry::FindBestCandidate (uint32_t skip/* = 0*/) const
 {
@@ -197,9 +220,15 @@
 CcnxFibEntryContainer::type::iterator
 CcnxFib::Add (const CcnxNameComponents &prefix, Ptr<CcnxFace> face, int32_t metric)
 {
+  return Add (Create<CcnxNameComponents> (prefix), face, metric);
+}
+  
+CcnxFibEntryContainer::type::iterator
+CcnxFib::Add (const Ptr<const CcnxNameComponents> &prefix, Ptr<CcnxFace> face, int32_t metric)
+{
 // CcnxFibFaceMetric
-  NS_LOG_FUNCTION(this << prefix << face << metric);
-  CcnxFibEntryContainer::type::iterator entry = m_fib.find (prefix);
+  NS_LOG_FUNCTION(this->GetObject<Node> ()->GetId () << boost::cref(*prefix) << boost::cref(*face) << metric);
+  CcnxFibEntryContainer::type::iterator entry = m_fib.find (*prefix);
   if (entry == m_fib.end ())
     {
       entry = m_fib.insert (m_fib.end (), CcnxFibEntry (prefix));
@@ -212,7 +241,43 @@
     
   return entry;
 }
-    
+
+void
+CcnxFib::Remove (const Ptr<const CcnxNameComponents> &prefix)
+{
+  NS_LOG_FUNCTION (this->GetObject<Node> ()->GetId () << boost::cref(*prefix));
+  CcnxFibEntryContainer::type::iterator entry = m_fib.find (*prefix);
+  if (entry != m_fib.end ())
+    m_fib.erase (entry);
+}
+
+void
+CcnxFib::Invalidate (const Ptr<const CcnxNameComponents> &prefix)
+{
+  NS_LOG_FUNCTION (this->GetObject<Node> ()->GetId () << boost::cref(*prefix));
+
+  CcnxFibEntryContainer::type::iterator entry = m_fib.find (*prefix);
+  if (entry == m_fib.end ())
+    return; // nothing to invalidate
+
+  m_fib.modify (entry,
+                ll::bind (&CcnxFibEntry::Invalidate, ll::_1));
+}
+
+void
+CcnxFib::InvalidateAll ()
+{
+  NS_LOG_FUNCTION (this->GetObject<Node> ()->GetId ());
+
+  for (CcnxFibEntryContainer::type::iterator entry = m_fib.begin ();
+       entry != m_fib.end ();
+       entry ++)
+    {
+      m_fib.modify (entry,
+                    ll::bind (&CcnxFibEntry::Invalidate, ll::_1));
+    }
+}
+
 void
 CcnxFib::Remove (const CcnxFibEntry &entry, Ptr<CcnxFace> face)
 {
@@ -232,7 +297,8 @@
   NS_LOG_FUNCTION (this);
 
   for_each (m_fib.begin (), m_fib.end (), 
-            ll::bind (&CcnxFib::Remove, this, ll::_1, face));
+            ll::bind (static_cast< void (CcnxFib::*) (const CcnxFibEntry &, Ptr<CcnxFace>) > (&CcnxFib::Remove),
+                      this, ll::_1, face));
 }
 
 /**
diff --git a/model/ccnx-fib.h b/model/ccnx-fib.h
index 318bc54..36e4d6e 100644
--- a/model/ccnx-fib.h
+++ b/model/ccnx-fib.h
@@ -147,20 +147,20 @@
  * \brief Structure for FIB table entry, holding indexed list of
  *        available faces and their respective metrics
  */
-class CcnxFibEntry : public SimpleRefCount<CcnxFibEntry>
+class CcnxFibEntry // : public SimpleRefCount<CcnxFibEntry>
 {
 public:
   class NoFaces {};
   
   /**
    * \brief Constructor
-   * \param prefix Prefix for the FIB entry
+   * \param prefix smart pointer to the prefix for the FIB entry
    */
-  CcnxFibEntry (const CcnxNameComponents &prefix)
-  : m_prefix (Create<CcnxNameComponents> (prefix))
+  CcnxFibEntry (const Ptr<const CcnxNameComponents> &prefix)
+  : m_prefix (prefix)
   , m_needsProbing (false)
   { }
-	
+  
   /**
    * \brief Update status of FIB next hop
    * \param status Status to set on the FIB entry
@@ -175,6 +175,14 @@
   void AddOrUpdateRoutingMetric (Ptr<CcnxFace> face, int32_t metric);
 
   /**
+   * @brief Invalidate face
+   *
+   * Set routing metric on all faces to max and status to RED
+   */
+  void
+  Invalidate ();
+
+  /**
    * @brief Update RTT averages for the face
    */
   void
@@ -207,7 +215,7 @@
   friend std::ostream& operator<< (std::ostream& os, const CcnxFibEntry &entry);
 
 public:
-  Ptr<CcnxNameComponents> m_prefix; ///< \brief Prefix of the FIB entry
+  Ptr<const CcnxNameComponents> m_prefix; ///< \brief Prefix of the FIB entry
   CcnxFibFaceMetricContainer::type m_faces; ///< \brief Indexed list of faces
 
   bool m_needsProbing;      ///< \brief flag indicating that probing should be performed 
@@ -289,6 +297,46 @@
   Add (const CcnxNameComponents &prefix, Ptr<CcnxFace> face, int32_t metric);
 
   /**
+   * \brief Add or update FIB entry using smart pointer to prefix
+   *
+   * If the entry exists, metric will be updated. Otherwise, new entry will be created
+   *
+   * Entries in FIB never deleted. They can be invalidated with metric==NETWORK_UNREACHABLE
+   *
+   * @param name	Smart pointer to prefix
+   * @param face	Forwarding face
+   * @param metric	Routing metric
+   */
+  CcnxFibEntryContainer::type::iterator
+  Add (const Ptr<const CcnxNameComponents> &prefix, Ptr<CcnxFace> face, int32_t metric);
+
+  /**
+   * @brief Remove FIB entry
+   *
+   * ! ATTENTION ! Use with caution.  All PIT entries referencing the corresponding FIB entry will become invalid.
+   * So, simulation may crash.
+   *
+   * @param name	Smart pointer to prefix
+   */
+  void
+  Remove (const Ptr<const CcnxNameComponents> &prefix);
+
+  /**
+   * @brief Invalidate FIB entry ("Safe" version of Remove)
+   *
+   * All faces for the entry will be assigned maximum routing metric and NDN_FIB_RED status   
+   * @param name	Smart pointer to prefix
+   */
+  void
+  Invalidate (const Ptr<const CcnxNameComponents> &prefix);
+
+  /**
+   * @brief Invalidate all FIB entries
+   */
+  void
+  InvalidateAll ();
+  
+  /**
    * @brief Remove reference to a face from the entry. If entry had only this face, the whole
    * entry will be removed
    */
diff --git a/model/ccnx-global-router.cc b/model/ccnx-global-router.cc
index c61169b..8a4f767 100644
--- a/model/ccnx-global-router.cc
+++ b/model/ccnx-global-router.cc
@@ -90,6 +90,12 @@
   return m_incidencies;
 }
 
+const CcnxGlobalRouter::LocalPrefixList &
+CcnxGlobalRouter::GetLocalPrefixes () const
+{
+  return m_localPrefixes;
+}
+
 // void
 // CcnxGlobalRouter::AddIncidencyChannel (Ptr< CcnxFace > face, Ptr< Channel > channel)
 // {
diff --git a/model/ccnx-global-router.h b/model/ccnx-global-router.h
index ac7f2d6..53c9d04 100644
--- a/model/ccnx-global-router.h
+++ b/model/ccnx-global-router.h
@@ -39,6 +39,7 @@
 public:
   typedef boost::tuple< Ptr< CcnxGlobalRouter >, Ptr< CcnxFace >, Ptr< CcnxGlobalRouter > > Incidency;
   typedef std::list< Incidency > IncidencyList;
+  typedef std::list< Ptr<CcnxNameComponents> > LocalPrefixList;
   
   /**
    * \brief Interface ID
@@ -68,6 +69,9 @@
   IncidencyList &
   GetIncidencies ();
 
+  const LocalPrefixList &
+  GetLocalPrefixes () const;
+
   // ??
 protected:
   virtual void
@@ -77,7 +81,7 @@
   uint32_t m_id;
   
   Ptr<Ccnx> m_ccnx;
-  std::list< Ptr<CcnxNameComponents> > m_localPrefixes;
+  LocalPrefixList m_localPrefixes;
   IncidencyList m_incidencies;
 
   static uint32_t m_idCounter;
diff --git a/model/ccnx-net-device-face.cc b/model/ccnx-net-device-face.cc
index c09e6b2..d14e136 100644
--- a/model/ccnx-net-device-face.cc
+++ b/model/ccnx-net-device-face.cc
@@ -115,7 +115,7 @@
 std::ostream&
 CcnxNetDeviceFace::Print (std::ostream& os) const
 {
-  os << "dev=net(" << GetId () << ")";
+  os << "dev[" << GetNode ()->GetId () << "]=net(" << GetId () << ")";
   return os;
 }