rib: Enable Readvertise-to-NLSR

Change-Id: If50ffe740e8137ca2aeed67be219f6487153af9f
refs: #3818
diff --git a/nfd.conf.sample.in b/nfd.conf.sample.in
index b1b704a..819e038 100644
--- a/nfd.conf.sample.in
+++ b/nfd.conf.sample.in
@@ -366,4 +366,8 @@
     ; policy. Initially, the wait time is set to base_retry_wait, then it will be doubled for every
     ; retry unless beyond the max_retry_wait, in which case max_retry_wait is set as the wait time.
   }
+
+  ; If enabled, routes registered with origin=client (typically from auto_prefix_propagate)
+  ; will be readvertised into local NLSR daemon.
+  readvertise_nlsr no
 }
diff --git a/rib/rib-manager.cpp b/rib/rib-manager.cpp
index 653ad28..ae76a81 100644
--- a/rib/rib-manager.cpp
+++ b/rib/rib-manager.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2016,  Regents of the University of California,
+ * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -24,16 +24,29 @@
  */
 
 #include "rib-manager.hpp"
+#include "readvertise/readvertise.hpp"
+#include "readvertise/client-to-nlsr-readvertise-policy.hpp"
+#include "readvertise/nfd-rib-readvertise-destination.hpp"
+
 #include "core/global-io.hpp"
 #include "core/logger.hpp"
 #include "core/scheduler.hpp"
+
 #include <ndn-cxx/lp/tags.hpp>
+#include <ndn-cxx/mgmt/nfd/control-command.hpp>
+#include <ndn-cxx/mgmt/nfd/control-response.hpp>
+#include <ndn-cxx/mgmt/nfd/control-parameters.hpp>
 #include <ndn-cxx/mgmt/nfd/face-status.hpp>
 #include <ndn-cxx/mgmt/nfd/rib-entry.hpp>
 
 namespace nfd {
 namespace rib {
 
+using ndn::nfd::ControlCommand;
+using ndn::nfd::ControlResponse;
+using ndn::nfd::ControlParameters;
+using ndn::nfd::FaceEventNotification;
+
 NFD_LOG_INIT("RibManager");
 
 const Name RibManager::LOCAL_HOST_TOP_PREFIX = "/localhost/nfd";
@@ -41,6 +54,7 @@
 const std::string RibManager::MGMT_MODULE_NAME = "rib";
 const Name RibManager::FACES_LIST_DATASET_PREFIX = "/localhost/nfd/faces/list";
 const time::seconds RibManager::ACTIVE_FACE_FETCH_INTERVAL = time::seconds(300);
+const Name RibManager::READVERTISE_NLSR_PREFIX = "/localhost/nlsr";
 
 RibManager::RibManager(Dispatcher& dispatcher,
                        ndn::Face& face,
@@ -127,6 +141,7 @@
                      const std::string& filename)
 {
   bool isAutoPrefixPropagatorEnabled = false;
+  bool wantReadvertiseToNlsr = false;
 
   for (const auto& item : configSection) {
     if (item.first == "localhost_security") {
@@ -147,6 +162,9 @@
 
       m_prefixPropagator.enable();
     }
+    else if (item.first == "readvertise_nlsr") {
+      wantReadvertiseToNlsr = ConfigFile::parseYesNo(item, "rib.readvertise_nlsr");
+    }
     else {
       BOOST_THROW_EXCEPTION(Error("Unrecognized rib property: " + item.first));
     }
@@ -155,6 +173,18 @@
   if (!isAutoPrefixPropagatorEnabled) {
     m_prefixPropagator.disable();
   }
+
+  if (wantReadvertiseToNlsr && m_readvertiseNlsr == nullptr) {
+    NFD_LOG_DEBUG("Enabling readvertise-to-nlsr.");
+    m_readvertiseNlsr.reset(new Readvertise(
+      m_rib,
+      make_unique<ClientToNlsrReadvertisePolicy>(),
+      make_unique<NfdRibReadvertiseDestination>(m_nfdController, READVERTISE_NLSR_PREFIX, m_rib)));
+  }
+  else if (!wantReadvertiseToNlsr && m_readvertiseNlsr != nullptr) {
+    NFD_LOG_DEBUG("Disabling readvertise-to-nlsr.");
+    m_readvertiseNlsr.reset();
+  }
 }
 
 void
@@ -189,8 +219,7 @@
   route.flags = parameters.getFlags();
 
   if (parameters.hasExpirationPeriod() &&
-      parameters.getExpirationPeriod() != time::milliseconds::max())
-  {
+      parameters.getExpirationPeriod() != time::milliseconds::max()) {
     route.expires = time::steady_clock::now() + parameters.getExpirationPeriod();
 
     // Schedule a new event, the old one will be cancelled during rib insertion.
diff --git a/rib/rib-manager.hpp b/rib/rib-manager.hpp
index a8be263..b074add 100644
--- a/rib/rib-manager.hpp
+++ b/rib/rib-manager.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2014-2016,  Regents of the University of California,
+ * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -26,28 +26,24 @@
 #ifndef NFD_RIB_RIB_MANAGER_HPP
 #define NFD_RIB_RIB_MANAGER_HPP
 
-#include "rib.hpp"
-#include "core/config-file.hpp"
-#include "core/manager-base.hpp"
 #include "auto-prefix-propagator.hpp"
 #include "fib-updater.hpp"
+#include "rib.hpp"
+
+#include "core/config-file.hpp"
+#include "core/manager-base.hpp"
 
 #include <ndn-cxx/encoding/buffer-stream.hpp>
 #include <ndn-cxx/security/validator-config.hpp>
-#include <ndn-cxx/mgmt/nfd/face-monitor.hpp>
 #include <ndn-cxx/mgmt/nfd/controller.hpp>
-#include <ndn-cxx/mgmt/nfd/control-command.hpp>
-#include <ndn-cxx/mgmt/nfd/control-response.hpp>
-#include <ndn-cxx/mgmt/nfd/control-parameters.hpp>
+#include <ndn-cxx/mgmt/nfd/face-event-notification.hpp>
+#include <ndn-cxx/mgmt/nfd/face-monitor.hpp>
 
 namespace nfd {
 namespace rib {
 
-using ndn::nfd::ControlCommand;
-using ndn::nfd::ControlResponse;
-using ndn::nfd::ControlParameters;
-
-using ndn::nfd::FaceEventNotification;
+class AutoPrefixPropagator;
+class Readvertise;
 
 class RibManager : public nfd::ManagerBase
 {
@@ -107,7 +103,7 @@
   void
   setFaceForSelfRegistration(const Interest& request, ControlParameters& parameters);
 
-  virtual ndn::mgmt::Authorization
+  ndn::mgmt::Authorization
   makeAuthorization(const std::string& verb) override;
 
 private: // Face monitor
@@ -138,7 +134,7 @@
    * @param notification
    */
   void
-  onNotification(const FaceEventNotification& notification);
+  onNotification(const ndn::nfd::FaceEventNotification& notification);
 
 private:
   void
@@ -163,6 +159,7 @@
   ndn::ValidatorConfig m_localhopValidator;
   bool m_isLocalhopEnabled;
   AutoPrefixPropagator m_prefixPropagator;
+  unique_ptr<Readvertise> m_readvertiseNlsr;
 
 PUBLIC_WITH_TESTS_ELSE_PRIVATE:
   Rib m_rib;
@@ -175,6 +172,7 @@
   static const Name FACES_LIST_DATASET_PREFIX;
   static const time::seconds ACTIVE_FACE_FETCH_INTERVAL;
   scheduler::EventId m_activeFaceFetchEvent;
+  static const Name READVERTISE_NLSR_PREFIX;
 
   typedef std::set<uint64_t> FaceIdSet;
   /** \brief contains FaceIds with one or more Routes in the RIB