diff --git a/daemon/rib/fib-update.cpp b/daemon/rib/fib-update.cpp
new file mode 100644
index 0000000..25e2a62
--- /dev/null
+++ b/daemon/rib/fib-update.cpp
@@ -0,0 +1,57 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "fib-update.hpp"
+
+namespace nfd {
+namespace rib {
+
+FibUpdate
+FibUpdate::createAddUpdate(const Name& name, const uint64_t faceId, const uint64_t cost)
+{
+  FibUpdate update;
+
+  update.name = name;
+  update.faceId = faceId;
+  update.cost = cost;
+  update.action = ADD_NEXTHOP;
+
+  return update;
+}
+
+FibUpdate
+FibUpdate::createRemoveUpdate(const Name& name, const uint64_t faceId)
+{
+  FibUpdate update;
+
+  update.name = name;
+  update.faceId = faceId;
+  update.action = REMOVE_NEXTHOP;
+
+  return update;
+}
+
+} // namespace rib
+} // namespace nfd
diff --git a/daemon/rib/fib-update.hpp b/daemon/rib/fib-update.hpp
new file mode 100644
index 0000000..5339a37
--- /dev/null
+++ b/daemon/rib/fib-update.hpp
@@ -0,0 +1,96 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_DAEMON_RIB_FIB_UPDATE_HPP
+#define NFD_DAEMON_RIB_FIB_UPDATE_HPP
+
+#include "core/common.hpp"
+
+namespace nfd {
+namespace rib {
+
+/** \class FibUpdate
+ *  \brief represents a FIB update
+ */
+class FibUpdate
+{
+public:
+  FibUpdate()
+    : faceId(0)
+    , cost(0)
+  {
+  }
+
+  bool
+  operator==(const FibUpdate& other) const
+  {
+    return (this->name == other.name &&
+            this->faceId == other.faceId &&
+            this->cost == other.cost &&
+            this->action == other.action);
+  }
+
+  static FibUpdate
+  createAddUpdate(const Name& name, const uint64_t faceId, const uint64_t cost);
+
+  static FibUpdate
+  createRemoveUpdate(const Name& name, const uint64_t faceId);
+
+  enum Action {
+    ADD_NEXTHOP    = 0,
+    REMOVE_NEXTHOP = 1
+  };
+
+public:
+  Name name;
+  uint64_t faceId;
+  uint64_t cost;
+  Action action;
+};
+
+inline std::ostream&
+operator<<(std::ostream& os, const FibUpdate& update)
+{
+  os << "FibUpdate("
+     << " Name: " << update.name << ", "
+     << "faceId: " << update.faceId << ", ";
+
+  if (update.action == FibUpdate::ADD_NEXTHOP) {
+    os << "cost: " << update.cost << ", "
+       << "action: ADD_NEXTHOP";
+  }
+  else {
+    os << "action: REMOVE_NEXTHOP";
+  }
+
+  os << ")";
+
+  return os;
+}
+
+} // namespace rib
+} // namespace nfd
+
+#endif // NFD_DAEMON_RIB_FIB_UPDATE_HPP
diff --git a/daemon/rib/fib-updater.cpp b/daemon/rib/fib-updater.cpp
new file mode 100644
index 0000000..574b5f9
--- /dev/null
+++ b/daemon/rib/fib-updater.cpp
@@ -0,0 +1,716 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "fib-updater.hpp"
+#include "core/logger.hpp"
+
+#include <ndn-cxx/mgmt/nfd/control-parameters.hpp>
+
+namespace nfd {
+namespace rib {
+
+NFD_LOG_INIT(FibUpdater);
+
+using ndn::nfd::ControlParameters;
+
+const unsigned int FibUpdater::MAX_NUM_TIMEOUTS = 10;
+const uint32_t FibUpdater::ERROR_FACE_NOT_FOUND = 410;
+
+FibUpdater::FibUpdater(Rib& rib, ndn::nfd::Controller& controller)
+  : m_rib(rib)
+  , m_controller(controller)
+{
+  rib.setFibUpdater(this);
+}
+
+void
+FibUpdater::computeAndSendFibUpdates(const RibUpdateBatch& batch,
+                                     const FibUpdateSuccessCallback& onSuccess,
+                                     const FibUpdateFailureCallback& onFailure)
+{
+  m_batchFaceId = batch.getFaceId();
+
+  // Erase previously calculated inherited routes
+  m_inheritedRoutes.clear();
+
+  // Erase previously calculated FIB updates
+  m_updatesForBatchFaceId.clear();
+  m_updatesForNonBatchFaceId.clear();
+
+  computeUpdates(batch);
+
+  sendUpdatesForBatchFaceId(onSuccess, onFailure);
+}
+
+void
+FibUpdater::computeUpdates(const RibUpdateBatch& batch)
+{
+  NFD_LOG_DEBUG("Computing updates for batch with faceID: " << batch.getFaceId());
+
+  // Compute updates and add to m_fibUpdates
+  for (const RibUpdate& update : batch) {
+    switch (update.getAction()) {
+      case RibUpdate::REGISTER:
+        computeUpdatesForRegistration(update);
+        break;
+      case RibUpdate::UNREGISTER:
+        computeUpdatesForUnregistration(update);
+        break;
+      case RibUpdate::REMOVE_FACE:
+        computeUpdatesForUnregistration(update);
+
+        // Do not apply updates with the same face ID as the destroyed face
+        // since they will be rejected by the FIB
+        m_updatesForBatchFaceId.clear();
+        break;
+    }
+  }
+}
+
+void
+FibUpdater::computeUpdatesForRegistration(const RibUpdate& update)
+{
+  const Name& prefix = update.getName();
+  const Route& route = update.getRoute();
+
+  Rib::const_iterator it = m_rib.find(prefix);
+
+  // Name prefix exists
+  if (it != m_rib.end()) {
+    shared_ptr<const RibEntry> entry(it->second);
+
+    RibEntry::const_iterator existingRoute = entry->findRoute(route);
+
+    // Route will be new
+    if (existingRoute == entry->end()) {
+      // Will the new route change the namespace's capture flag?
+      bool willCaptureBeTurnedOn = (entry->hasCapture() == false && route.isRibCapture());
+
+      createFibUpdatesForNewRoute(*entry, route, willCaptureBeTurnedOn);
+    }
+    else {
+      // Route already exists
+      RibEntry entryCopy = *entry;
+
+      Route& routeToUpdate = *(entryCopy.findRoute(route));
+
+      routeToUpdate.flags = route.flags;
+      routeToUpdate.cost = route.cost;
+      routeToUpdate.expires = route.expires;
+
+      createFibUpdatesForUpdatedRoute(entryCopy, route, *existingRoute);
+    }
+  }
+  else {
+    // New name in RIB
+    // Find prefix's parent
+    shared_ptr<RibEntry> parent = m_rib.findParent(prefix);
+
+    Rib::RibEntryList descendants = m_rib.findDescendantsForNonInsertedName(prefix);
+    Rib::RibEntryList children;
+
+    for (const auto& descendant : descendants) {
+      // If the child has the same parent as the new entry,
+      // the new entry must be the child's new parent
+      if (descendant->getParent() == parent) {
+        children.push_back(descendant);
+      }
+    }
+
+    createFibUpdatesForNewRibEntry(prefix, route, children);
+  }
+}
+
+void
+FibUpdater::computeUpdatesForUnregistration(const RibUpdate& update)
+{
+  const Name& prefix = update.getName();
+  const Route& route = update.getRoute();
+
+  Rib::const_iterator ribIt = m_rib.find(prefix);
+
+  // Name prefix exists
+  if (ribIt != m_rib.end()) {
+    shared_ptr<const RibEntry> entry(ribIt->second);
+
+    const bool hadCapture = entry->hasCapture();
+
+    RibEntry::const_iterator existing = entry->findRoute(route);
+
+    if (existing != entry->end()) {
+      RibEntry temp = *entry;
+
+      // Erase route in temp entry
+      temp.eraseRoute(route);
+
+      const bool captureWasTurnedOff = (hadCapture && !temp.hasCapture());
+
+      createFibUpdatesForErasedRoute(temp, *existing, captureWasTurnedOff);
+
+      // The RibEntry still has the face ID; need to update FIB
+      // with lowest cost for the same face instead of removing the face from the FIB
+      const Route* next = entry->getRouteWithSecondLowestCostByFaceId(route.faceId);
+
+      if (next != nullptr) {
+        createFibUpdatesForNewRoute(temp, *next, false);
+      }
+
+      // The RibEntry will be empty after this removal
+      if (entry->getNRoutes() == 1) {
+        createFibUpdatesForErasedRibEntry(*entry);
+      }
+    }
+  }
+}
+
+void
+FibUpdater::sendUpdates(const FibUpdateList& updates,
+                        const FibUpdateSuccessCallback& onSuccess,
+                        const FibUpdateFailureCallback& onFailure)
+{
+  std::string updateString = (updates.size() == 1) ? " update" : " updates";
+  NFD_LOG_DEBUG("Applying " << updates.size() << updateString << " to FIB");
+
+  for (const FibUpdate& update : updates) {
+    NFD_LOG_DEBUG("Sending FIB update: " << update);
+
+    if (update.action == FibUpdate::ADD_NEXTHOP) {
+      sendAddNextHopUpdate(update, onSuccess, onFailure);
+    }
+    else if (update.action == FibUpdate::REMOVE_NEXTHOP) {
+      sendRemoveNextHopUpdate(update, onSuccess, onFailure);
+    }
+  }
+}
+
+void
+FibUpdater::sendUpdatesForBatchFaceId(const FibUpdateSuccessCallback& onSuccess,
+                                      const FibUpdateFailureCallback& onFailure)
+{
+  if (m_updatesForBatchFaceId.size() > 0) {
+    sendUpdates(m_updatesForBatchFaceId, onSuccess, onFailure);
+  }
+  else {
+    sendUpdatesForNonBatchFaceId(onSuccess, onFailure);
+  }
+}
+
+void
+FibUpdater::sendUpdatesForNonBatchFaceId(const FibUpdateSuccessCallback& onSuccess,
+                                         const FibUpdateFailureCallback& onFailure)
+{
+  if (m_updatesForNonBatchFaceId.size() > 0) {
+    sendUpdates(m_updatesForNonBatchFaceId, onSuccess, onFailure);
+  }
+  else {
+    onSuccess(m_inheritedRoutes);
+  }
+}
+
+void
+FibUpdater::sendAddNextHopUpdate(const FibUpdate& update,
+                                 const FibUpdateSuccessCallback& onSuccess,
+                                 const FibUpdateFailureCallback& onFailure,
+                                 uint32_t nTimeouts)
+{
+  m_controller.start<ndn::nfd::FibAddNextHopCommand>(
+    ControlParameters()
+      .setName(update.name)
+      .setFaceId(update.faceId)
+      .setCost(update.cost),
+    bind(&FibUpdater::onUpdateSuccess, this, update, onSuccess, onFailure),
+    bind(&FibUpdater::onUpdateError, this, update, onSuccess, onFailure, _1, nTimeouts));
+}
+
+void
+FibUpdater::sendRemoveNextHopUpdate(const FibUpdate& update,
+                                    const FibUpdateSuccessCallback& onSuccess,
+                                    const FibUpdateFailureCallback& onFailure,
+                                    uint32_t nTimeouts)
+{
+  m_controller.start<ndn::nfd::FibRemoveNextHopCommand>(
+    ControlParameters()
+      .setName(update.name)
+      .setFaceId(update.faceId),
+    bind(&FibUpdater::onUpdateSuccess, this, update, onSuccess, onFailure),
+    bind(&FibUpdater::onUpdateError, this, update, onSuccess, onFailure, _1, nTimeouts));
+}
+
+void
+FibUpdater::onUpdateSuccess(const FibUpdate update,
+                            const FibUpdateSuccessCallback& onSuccess,
+                            const FibUpdateFailureCallback& onFailure)
+{
+  if (update.faceId == m_batchFaceId) {
+    m_updatesForBatchFaceId.remove(update);
+
+    if (m_updatesForBatchFaceId.size() == 0) {
+      sendUpdatesForNonBatchFaceId(onSuccess, onFailure);
+    }
+  }
+  else {
+    m_updatesForNonBatchFaceId.remove(update);
+
+    if (m_updatesForNonBatchFaceId.size() == 0) {
+      onSuccess(m_inheritedRoutes);
+    }
+  }
+}
+
+void
+FibUpdater::onUpdateError(const FibUpdate update,
+                          const FibUpdateSuccessCallback& onSuccess,
+                          const FibUpdateFailureCallback& onFailure,
+                          const ndn::nfd::ControlResponse& response, uint32_t nTimeouts)
+{
+  uint32_t code = response.getCode();
+  NFD_LOG_DEBUG("Failed to apply " << update <<
+                " (code: " << code << ", error: " << response.getText() << ")");
+
+  if (code == ndn::nfd::Controller::ERROR_TIMEOUT && nTimeouts < MAX_NUM_TIMEOUTS) {
+    sendAddNextHopUpdate(update, onSuccess, onFailure, ++nTimeouts);
+  }
+  else if (code == ERROR_FACE_NOT_FOUND) {
+    if (update.faceId == m_batchFaceId) {
+      onFailure(code, response.getText());
+    }
+    else {
+      m_updatesForNonBatchFaceId.remove(update);
+
+      if (m_updatesForNonBatchFaceId.size() == 0) {
+        onSuccess(m_inheritedRoutes);
+      }
+    }
+  }
+  else {
+    NDN_THROW(Error("Non-recoverable error: " + response.getText() + " code: " + to_string(code)));
+  }
+}
+
+void
+FibUpdater::addFibUpdate(FibUpdate update)
+{
+  FibUpdateList& updates = (update.faceId == m_batchFaceId) ? m_updatesForBatchFaceId :
+                                                              m_updatesForNonBatchFaceId;
+
+  // If an update with the same name and route already exists,
+  // replace it
+  FibUpdateList::iterator it = std::find_if(updates.begin(), updates.end(),
+    [&update] (const FibUpdate& other) {
+      return update.name == other.name && update.faceId == other.faceId;
+    });
+
+  if (it != updates.end()) {
+    FibUpdate& existingUpdate = *it;
+    existingUpdate.action = update.action;
+    existingUpdate.cost = update.cost;
+  }
+  else {
+    updates.push_back(update);
+  }
+}
+
+void
+FibUpdater::addInheritedRoutes(const RibEntry& entry, const Rib::RouteSet& routesToAdd)
+{
+  for (const Route& route : routesToAdd) {
+    // Don't add an ancestor faceId if the namespace has an entry for that faceId
+    if (!entry.hasFaceId(route.faceId)) {
+      // Create a record of the inherited route so it can be added to the RIB later
+      addInheritedRoute(entry.getName(), route);
+
+      addFibUpdate(FibUpdate::createAddUpdate(entry.getName(), route.faceId, route.cost));
+    }
+  }
+}
+
+void
+FibUpdater::addInheritedRoutes(const Name& name, const Rib::RouteSet& routesToAdd,
+                               const Route& ignore)
+{
+  for (const Route& route : routesToAdd) {
+    if (route.faceId != ignore.faceId) {
+      // Create a record of the inherited route so it can be added to the RIB later
+      addInheritedRoute(name, route);
+
+      addFibUpdate(FibUpdate::createAddUpdate(name, route.faceId, route.cost));
+    }
+  }
+}
+
+void
+FibUpdater::removeInheritedRoutes(const RibEntry& entry, const Rib::Rib::RouteSet& routesToRemove)
+{
+  for (const Route& route : routesToRemove) {
+    // Only remove if the route has been inherited
+    if (entry.hasInheritedRoute(route)) {
+      removeInheritedRoute(entry.getName(), route);
+      addFibUpdate(FibUpdate::createRemoveUpdate(entry.getName(), route.faceId));
+    }
+  }
+}
+
+void
+FibUpdater::createFibUpdatesForNewRibEntry(const Name& name, const Route& route,
+                                           const Rib::RibEntryList& children)
+{
+  // Create FIB update for new entry
+  addFibUpdate(FibUpdate::createAddUpdate(name, route.faceId, route.cost));
+
+  // No flags are set
+  if (!route.isChildInherit() && !route.isRibCapture()) {
+    // Add ancestor routes to self
+    addInheritedRoutes(name, m_rib.getAncestorRoutes(name), route);
+  }
+  else if (route.isChildInherit() && route.isRibCapture()) {
+    // Add route to children
+    Rib::RouteSet routesToAdd;
+    routesToAdd.insert(route);
+
+    // Remove routes blocked by capture and add self to children
+    modifyChildrensInheritedRoutes(children, routesToAdd, m_rib.getAncestorRoutes(name));
+  }
+  else if (route.isChildInherit()) {
+    Rib::RouteSet ancestorRoutes = m_rib.getAncestorRoutes(name);
+
+    // Add ancestor routes to self
+    addInheritedRoutes(name, ancestorRoutes, route);
+
+    // If there is an ancestor route which is the same as the new route, replace it
+    // with the new route
+    Rib::RouteSet::iterator it = ancestorRoutes.find(route);
+
+    // There is a route that needs to be overwritten, erase and then replace
+    if (it != ancestorRoutes.end()) {
+      ancestorRoutes.erase(it);
+    }
+
+    // Add new route to ancestor list so it can be added to children
+    ancestorRoutes.insert(route);
+
+    // Add ancestor routes to children
+    modifyChildrensInheritedRoutes(children, ancestorRoutes, Rib::RouteSet());
+  }
+  else if (route.isRibCapture()) {
+    // Remove routes blocked by capture
+    modifyChildrensInheritedRoutes(children, Rib::RouteSet(), m_rib.getAncestorRoutes(name));
+  }
+}
+
+void
+FibUpdater::createFibUpdatesForNewRoute(const RibEntry& entry, const Route& route,
+                                        bool captureWasTurnedOn)
+{
+  // Only update if the new route has a lower cost than a previously installed route
+  const Route* prevRoute = entry.getRouteWithLowestCostAndChildInheritByFaceId(route.faceId);
+
+  Rib::RouteSet routesToAdd;
+  if (route.isChildInherit()) {
+    // Add to children if this new route doesn't override a previous lower cost, or
+    // add to children if this new route is lower cost than a previous route.
+    // Less than equal, since entry may find this route
+    if (prevRoute == nullptr || route.cost <= prevRoute->cost) {
+      // Add self to children
+      routesToAdd.insert(route);
+    }
+  }
+
+  Rib::RouteSet routesToRemove;
+  if (captureWasTurnedOn) {
+    // Capture flag on
+    routesToRemove = m_rib.getAncestorRoutes(entry);
+
+    // Remove ancestor routes from self
+    removeInheritedRoutes(entry, routesToRemove);
+  }
+
+  modifyChildrensInheritedRoutes(entry.getChildren(), routesToAdd, routesToRemove);
+
+  // If another route with same faceId and lower cost exists, don't update.
+  // Must be done last so that add updates replace removal updates
+  // Create FIB update for new entry
+  const Route* other = entry.getRouteWithLowestCostByFaceId(route.faceId);
+
+  if (other == nullptr || route.cost <= other->cost) {
+    addFibUpdate(FibUpdate::createAddUpdate(entry.getName(), route.faceId, route.cost));
+  }
+}
+
+void
+FibUpdater::createFibUpdatesForUpdatedRoute(const RibEntry& entry, const Route& route,
+                                            const Route& existingRoute)
+{
+  const bool costDidChange = (route.cost != existingRoute.cost);
+
+  // Look for an installed route with the lowest cost and child inherit set
+  const Route* prevRoute = entry.getRouteWithLowestCostAndChildInheritByFaceId(route.faceId);
+
+  // No flags changed and cost didn't change, no change in FIB
+  if (route.flags == existingRoute.flags && !costDidChange) {
+    return;
+  }
+
+  // Cost changed so create update for the entry itself
+  if (costDidChange) {
+    // Create update if this route's cost is lower than other routes
+    if (route.cost <= entry.getRouteWithLowestCostByFaceId(route.faceId)->cost) {
+      // Create FIB update for the updated entry
+      addFibUpdate(FibUpdate::createAddUpdate(entry.getName(), route.faceId, route.cost));
+    }
+    else if (existingRoute.cost < entry.getRouteWithLowestCostByFaceId(route.faceId)->cost) {
+      // Create update if this route used to be the lowest route but is no longer
+      // the lowest cost route.
+      addFibUpdate(FibUpdate::createAddUpdate(entry.getName(), prevRoute->faceId, prevRoute->cost));
+    }
+
+    // If another route with same faceId and lower cost and ChildInherit exists,
+    // don't update children.
+    if (prevRoute == nullptr || route.cost <= prevRoute->cost) {
+      // If no flags changed but child inheritance is set, need to update children
+      // with new cost
+      if ((route.flags == existingRoute.flags) && route.isChildInherit()) {
+        // Add self to children
+        Rib::RouteSet routesToAdd;
+        routesToAdd.insert(route);
+        modifyChildrensInheritedRoutes(entry.getChildren(), routesToAdd, Rib::RouteSet());
+
+        return;
+      }
+    }
+  }
+
+  // Child inherit was turned on
+  if (!existingRoute.isChildInherit() && route.isChildInherit()) {
+    // If another route with same faceId and lower cost and ChildInherit exists,
+    // don't update children.
+    if (prevRoute == nullptr || route.cost <= prevRoute->cost) {
+      // Add self to children
+      Rib::RouteSet routesToAdd;
+      routesToAdd.insert(route);
+      modifyChildrensInheritedRoutes(entry.getChildren(), routesToAdd, Rib::RouteSet());
+    }
+  } // Child inherit was turned off
+  else if (existingRoute.isChildInherit() && !route.isChildInherit()) {
+    // Remove self from children
+    Rib::RouteSet routesToRemove;
+    routesToRemove.insert(route);
+
+    Rib::RouteSet routesToAdd;
+    // If another route with same faceId and ChildInherit exists, update children with this route.
+    if (prevRoute != nullptr) {
+      routesToAdd.insert(*prevRoute);
+    }
+    else {
+      // Look for an ancestor that was blocked previously
+      const Rib::RouteSet ancestorRoutes = m_rib.getAncestorRoutes(entry);
+      Rib::RouteSet::iterator it = ancestorRoutes.find(route);
+
+      // If an ancestor is found, add it to children
+      if (it != ancestorRoutes.end()) {
+        routesToAdd.insert(*it);
+      }
+    }
+
+    modifyChildrensInheritedRoutes(entry.getChildren(), routesToAdd, routesToRemove);
+  }
+
+  // Capture was turned on
+  if (!existingRoute.isRibCapture() && route.isRibCapture()) {
+    Rib::RouteSet ancestorRoutes = m_rib.getAncestorRoutes(entry);
+
+    // Remove ancestor routes from self
+    removeInheritedRoutes(entry, ancestorRoutes);
+
+    // Remove ancestor routes from children
+    modifyChildrensInheritedRoutes(entry.getChildren(), Rib::RouteSet(), ancestorRoutes);
+  }  // Capture was turned off
+  else if (existingRoute.isRibCapture() && !route.isRibCapture()) {
+    Rib::RouteSet ancestorRoutes = m_rib.getAncestorRoutes(entry);
+
+    // Add ancestor routes to self
+    addInheritedRoutes(entry, ancestorRoutes);
+
+    // Add ancestor routes to children
+    modifyChildrensInheritedRoutes(entry.getChildren(), ancestorRoutes, Rib::RouteSet());
+  }
+}
+
+void
+FibUpdater::createFibUpdatesForErasedRoute(const RibEntry& entry, const Route& route,
+                                               const bool captureWasTurnedOff)
+{
+  addFibUpdate(FibUpdate::createRemoveUpdate(entry.getName(), route.faceId));
+
+  if (route.isChildInherit() && route.isRibCapture()) {
+    // Remove self from children
+    Rib::RouteSet routesToRemove;
+    routesToRemove.insert(route);
+
+    // If capture is turned off for the route and another route is installed in the RibEntry,
+    // add ancestors to self
+    Rib::RouteSet routesToAdd;
+    if (captureWasTurnedOff && entry.getNRoutes() != 0) {
+      // Look for an ancestors that were blocked previously
+      routesToAdd = m_rib.getAncestorRoutes(entry);
+
+      // Add ancestor routes to self
+      addInheritedRoutes(entry, routesToAdd);
+    }
+
+    modifyChildrensInheritedRoutes(entry.getChildren(), routesToAdd, routesToRemove);
+  }
+  else if (route.isChildInherit()) {
+    // If not blocked by capture, add inherited routes to children
+    Rib::RouteSet routesToAdd;
+    if (!entry.hasCapture()) {
+      routesToAdd = m_rib.getAncestorRoutes(entry);
+    }
+
+    Rib::RouteSet routesToRemove;
+    routesToRemove.insert(route);
+
+    // Add ancestor routes to children
+    modifyChildrensInheritedRoutes(entry.getChildren(), routesToAdd, routesToRemove);
+  }
+  else if (route.isRibCapture()) {
+    // If capture is turned off for the route and another route is installed in the RibEntry,
+    // add ancestors to self
+    Rib::RouteSet routesToAdd;
+    if (captureWasTurnedOff && entry.getNRoutes() != 0) {
+      // Look for an ancestors that were blocked previously
+      routesToAdd = m_rib.getAncestorRoutes(entry);
+
+      // Add ancestor routes to self
+      addInheritedRoutes(entry, routesToAdd);
+    }
+
+    modifyChildrensInheritedRoutes(entry.getChildren(), routesToAdd, Rib::RouteSet());
+  }
+
+  // Need to check if the removed route was blocking an inherited route
+  Rib::RouteSet ancestorRoutes = m_rib.getAncestorRoutes(entry);
+
+  // If the current entry has capture set or is pending removal, don't add inherited route
+  if (!entry.hasCapture() && entry.getNRoutes() != 0) {
+    // If there is an ancestor route which is the same as the erased route, add that route
+    // to the current entry
+    Rib::RouteSet::iterator it = ancestorRoutes.find(route);
+
+    if (it != ancestorRoutes.end()) {
+      addInheritedRoute(entry.getName(), *it);
+      addFibUpdate(FibUpdate::createAddUpdate(entry.getName(), it->faceId, it->cost));
+    }
+  }
+}
+
+void
+FibUpdater::createFibUpdatesForErasedRibEntry(const RibEntry& entry)
+{
+  for (const Route& route : entry.getInheritedRoutes()) {
+    addFibUpdate(FibUpdate::createRemoveUpdate(entry.getName(), route.faceId));
+  }
+}
+
+void
+FibUpdater::modifyChildrensInheritedRoutes(const Rib::RibEntryList& children,
+                                           const Rib::RouteSet& routesToAdd,
+                                           const Rib::RouteSet& routesToRemove)
+{
+  for (const auto& child : children) {
+    traverseSubTree(*child, routesToAdd, routesToRemove);
+  }
+}
+
+void
+FibUpdater::traverseSubTree(const RibEntry& entry, Rib::Rib::RouteSet routesToAdd,
+                            Rib::Rib::RouteSet routesToRemove)
+{
+  // If a route on the namespace has the capture flag set, ignore self and children
+  if (entry.hasCapture()) {
+    return;
+  }
+
+  // Remove inherited routes from current namespace
+  for (auto removeIt = routesToRemove.begin(); removeIt != routesToRemove.end(); ) {
+    // If a route on the namespace has the same face ID and child inheritance set,
+    // ignore this route
+    if (entry.hasChildInheritOnFaceId(removeIt->faceId)) {
+      removeIt = routesToRemove.erase(removeIt);
+      continue;
+    }
+
+    // Only remove route if it removes an existing inherited route
+    if (entry.hasInheritedRoute(*removeIt)) {
+      removeInheritedRoute(entry.getName(), *removeIt);
+      addFibUpdate(FibUpdate::createRemoveUpdate(entry.getName(), removeIt->faceId));
+    }
+
+    ++removeIt;
+  }
+
+  // Add inherited routes to current namespace
+  for (auto addIt = routesToAdd.begin(); addIt != routesToAdd.end(); ) {
+    // If a route on the namespace has the same face ID and child inherit set, ignore this face
+    if (entry.hasChildInheritOnFaceId(addIt->faceId)) {
+      addIt = routesToAdd.erase(addIt);
+      continue;
+    }
+
+    // Only add route if it does not override an existing route
+    if (!entry.hasFaceId(addIt->faceId)) {
+      addInheritedRoute(entry.getName(), *addIt);
+      addFibUpdate(FibUpdate::createAddUpdate(entry.getName(), addIt->faceId, addIt->cost));
+    }
+
+    ++addIt;
+  }
+
+  modifyChildrensInheritedRoutes(entry.getChildren(), routesToAdd, routesToRemove);
+}
+
+void
+FibUpdater::addInheritedRoute(const Name& name, const Route& route)
+{
+  RibUpdate update;
+  update.setAction(RibUpdate::REGISTER)
+        .setName(name)
+        .setRoute(route);
+
+  m_inheritedRoutes.push_back(update);
+}
+
+void
+FibUpdater::removeInheritedRoute(const Name& name, const Route& route)
+{
+  RibUpdate update;
+  update.setAction(RibUpdate::UNREGISTER)
+        .setName(name)
+        .setRoute(route);
+
+  m_inheritedRoutes.push_back(update);
+}
+
+} // namespace rib
+} // namespace nfd
diff --git a/daemon/rib/fib-updater.hpp b/daemon/rib/fib-updater.hpp
new file mode 100644
index 0000000..a404853
--- /dev/null
+++ b/daemon/rib/fib-updater.hpp
@@ -0,0 +1,275 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_DAEMON_RIB_FIB_UPDATER_HPP
+#define NFD_DAEMON_RIB_FIB_UPDATER_HPP
+
+#include "core/common.hpp"
+#include "fib-update.hpp"
+#include "rib.hpp"
+#include "rib-update-batch.hpp"
+
+#include <ndn-cxx/mgmt/nfd/controller.hpp>
+
+namespace nfd {
+namespace rib {
+
+/** \brief computes FibUpdates based on updates to the RIB and sends them to NFD
+ */
+class FibUpdater : noncopyable
+{
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    using std::runtime_error::runtime_error;
+  };
+
+public:
+  typedef std::list<FibUpdate> FibUpdateList;
+
+  typedef std::function<void(RibUpdateList inheritedRoutes)> FibUpdateSuccessCallback;
+  typedef std::function<void(uint32_t code, const std::string& error)> FibUpdateFailureCallback;
+
+  FibUpdater(Rib& rib, ndn::nfd::Controller& controller);
+
+  /** \brief computes FibUpdates using the provided RibUpdateBatch and then sends the
+   *         updates to NFD's FIB
+   *
+   *  \note  Caller must guarantee that the previous batch has either succeeded or failed
+   *         before calling this method
+   */
+  void
+  computeAndSendFibUpdates(const RibUpdateBatch& batch,
+                           const FibUpdateSuccessCallback& onSuccess,
+                           const FibUpdateFailureCallback& onFailure);
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  /** \brief determines the type of action that will be performed on the RIB and calls the
+  *          corresponding computation method
+  */
+  void
+  computeUpdates(const RibUpdateBatch& batch);
+
+  /** \brief sends the passed updates to NFD
+  *
+  *   onSuccess or onFailure will be called based on the results in
+  *   onUpdateSuccess or onUpdateFailure
+  *
+  *   \see FibUpdater::onUpdateSuccess
+  *   \see FibUpdater::onUpdateFailure
+  */
+  void
+  sendUpdates(const FibUpdateList& updates,
+              const FibUpdateSuccessCallback& onSuccess,
+              const FibUpdateFailureCallback& onFailure);
+
+  /** \brief sends the updates in m_updatesForBatchFaceId to NFD if any exist,
+  *          otherwise calls FibUpdater::sendUpdatesForNonBatchFaceId.
+  */
+  void
+  sendUpdatesForBatchFaceId(const FibUpdateSuccessCallback& onSuccess,
+                            const FibUpdateFailureCallback& onFailure);
+
+  /** \brief sends the updates in m_updatesForNonBatchFaceId to NFD if any exist,
+  *          otherwise calls onSuccess.
+  */
+  void
+  sendUpdatesForNonBatchFaceId(const FibUpdateSuccessCallback& onSuccess,
+                               const FibUpdateFailureCallback& onFailure);
+
+  /** \brief sends a FibAddNextHopCommand to NFD using the parameters supplied by
+  *          the passed update
+  *
+  *   \param nTimeouts the number of times this FibUpdate has failed due to timeout
+  */
+  void
+  sendAddNextHopUpdate(const FibUpdate& update,
+                       const FibUpdateSuccessCallback& onSuccess,
+                       const FibUpdateFailureCallback& onFailure,
+                       uint32_t nTimeouts = 0);
+
+  /** \brief sends a FibRemoveNextHopCommand to NFD using the parameters supplied by
+  *          the passed update
+  *
+  *   \param nTimeouts the number of times this FibUpdate has failed due to timeout
+  */
+  void
+  sendRemoveNextHopUpdate(const FibUpdate& update,
+                          const FibUpdateSuccessCallback& onSuccess,
+                          const FibUpdateFailureCallback& onFailure,
+                          uint32_t nTimeouts = 0);
+
+private:
+  /** \brief calculates the FibUpdates generated by a RIB registration
+  */
+  void
+  computeUpdatesForRegistration(const RibUpdate& update);
+
+  /** \brief calculates the FibUpdates generated by a RIB unregistration
+  */
+  void
+  computeUpdatesForUnregistration(const RibUpdate& update);
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  /** \brief callback used by NfdController when a FibAddNextHopCommand or FibRemoveNextHopCommand
+  *          is successful.
+  *
+  *   If the update has the same Face ID as the batch being processed, the update is
+  *   removed from m_updatesForBatchFaceId. If m_updatesForBatchFaceId becomes empty,
+  *   the updates with a different Face ID than the batch are sent to NFD.
+  *
+  *   If the update has a different Face ID than the batch being processed, the update is
+  *   removed from m_updatesForBatchNonFaceId. If m_updatesForBatchNonFaceId becomes empty,
+  *   the FIB update process is considered a success.
+  */
+  void
+  onUpdateSuccess(const FibUpdate update,
+                  const FibUpdateSuccessCallback& onSuccess,
+                  const FibUpdateFailureCallback& onFailure);
+
+  /** \brief callback used by NfdController when a FibAddNextHopCommand or FibRemoveNextHopCommand
+  *          is successful.
+  *
+  *   If the update has not reached the max number of timeouts allowed, the update
+  *   is retried.
+  *
+  *   If the update failed due to a non-existent face and the update has the same Face ID
+  *   as the update batch, the FIB update process fails.
+  *
+  *   If the update failed due to a non-existent face and the update has a different
+  *   face than the update batch, the update is not retried and the error is
+  *   ignored.
+  *
+  *   Otherwise, a non-recoverable error has occurred and an exception is thrown.
+  */
+  void
+  onUpdateError(const FibUpdate update,
+                const FibUpdateSuccessCallback& onSuccess,
+                const FibUpdateFailureCallback& onFailure,
+                const ndn::nfd::ControlResponse& response, uint32_t nTimeouts);
+
+private:
+  /** \brief adds the update to an update list based on its Face ID
+  *
+  *   If the update has the same Face ID as the update batch, the update is added
+  *   to m_updatesForBatchFaceId.
+  *
+  *   Otherwise, the update is added to m_updatesForBatchNonFaceId.
+  */
+  void
+  addFibUpdate(const FibUpdate update);
+
+  /** \brief creates records of the passed routes added to the entry and creates FIB updates
+  */
+  void
+  addInheritedRoutes(const RibEntry& entry, const Rib::RouteSet& routesToAdd);
+
+  /** \brief creates records of the passed routes added to the name and creates FIB updates.
+  *          Routes in routesToAdd with the same Face ID as ignore will be not be considered.
+  */
+  void
+  addInheritedRoutes(const Name& name, const Rib::RouteSet& routesToAdd, const Route& ignore);
+
+  /** \brief creates records of the passed routes removed from the entry and creates FIB updates
+  */
+  void
+  removeInheritedRoutes(const RibEntry& entry, const Rib::RouteSet& routesToRemove);
+
+  /** \brief calculates updates for a name that will create a new RIB entry
+  */
+  void
+  createFibUpdatesForNewRibEntry(const Name& name, const Route& route,
+                                 const Rib::RibEntryList& children);
+
+  /** \brief calculates updates for a new route added to a RIB entry
+  */
+  void
+  createFibUpdatesForNewRoute(const RibEntry& entry, const Route& route,
+                              const bool captureWasTurnedOn);
+
+  /** \brief calculates updates for changes to an existing route for a RIB entry
+  */
+  void
+  createFibUpdatesForUpdatedRoute(const RibEntry& entry, const Route& route,
+                                  const Route& existingRoute);
+
+  /** \brief calculates updates for a an existing route removed from a RIB entry
+  */
+  void
+  createFibUpdatesForErasedRoute(const RibEntry& entry, const Route& route,
+                                 const bool captureWasTurnedOff);
+
+  /** \brief calculates updates for an entry that will be removed from the RIB
+  */
+  void
+  createFibUpdatesForErasedRibEntry(const RibEntry& entry);
+
+  /** \brief adds and removes passed routes to children's inherited routes
+  */
+  void
+  modifyChildrensInheritedRoutes(const Rib::RibEntryList& children,
+                                 const Rib::RouteSet& routesToAdd,
+                                 const Rib::RouteSet& routesToRemove);
+
+  /** \brief traverses the entry's children adding and removing the passed routes
+  */
+  void
+  traverseSubTree(const RibEntry& entry, Rib::RouteSet routesToAdd, Rib::RouteSet routesToRemove);
+
+private:
+  /** \brief creates a record of a calculated inherited route that should be added to the entry
+  */
+  void
+  addInheritedRoute(const Name& name, const Route& route);
+
+  /** \brief creates a record of an existing inherited route that should be removed from the entry
+  */
+  void
+  removeInheritedRoute(const Name& name, const Route& route);
+
+private:
+  const Rib& m_rib;
+  ndn::nfd::Controller& m_controller;
+  uint64_t m_batchFaceId;
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  FibUpdateList m_updatesForBatchFaceId;
+  FibUpdateList m_updatesForNonBatchFaceId;
+
+  /** \brief list of inherited routes generated during FIB update calculation;
+   *         passed to the RIB when updates are completed successfully
+   */
+  RibUpdateList m_inheritedRoutes;
+
+private:
+  static const unsigned int MAX_NUM_TIMEOUTS;
+  static const uint32_t ERROR_FACE_NOT_FOUND;
+};
+
+} // namespace rib
+} // namespace nfd
+
+#endif // NFD_DAEMON_RIB_FIB_UPDATER_HPP
diff --git a/daemon/rib/readvertise/client-to-nlsr-readvertise-policy.cpp b/daemon/rib/readvertise/client-to-nlsr-readvertise-policy.cpp
new file mode 100644
index 0000000..ca54132
--- /dev/null
+++ b/daemon/rib/readvertise/client-to-nlsr-readvertise-policy.cpp
@@ -0,0 +1,49 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "client-to-nlsr-readvertise-policy.hpp"
+
+namespace nfd {
+namespace rib {
+
+optional<ReadvertiseAction>
+ClientToNlsrReadvertisePolicy::handleNewRoute(const RibRouteRef& ribRoute) const
+{
+  if (ribRoute.route->origin == ndn::nfd::ROUTE_ORIGIN_CLIENT) {
+    return ReadvertiseAction{ribRoute.entry->getName(), ndn::security::SigningInfo()};
+  }
+  else {
+    return nullopt;
+  }
+}
+
+time::milliseconds
+ClientToNlsrReadvertisePolicy::getRefreshInterval() const
+{
+  return 1_h;
+}
+
+} // namespace rib
+} // namespace nfd
diff --git a/daemon/rib/readvertise/client-to-nlsr-readvertise-policy.hpp b/daemon/rib/readvertise/client-to-nlsr-readvertise-policy.hpp
new file mode 100644
index 0000000..b1c5e29
--- /dev/null
+++ b/daemon/rib/readvertise/client-to-nlsr-readvertise-policy.hpp
@@ -0,0 +1,54 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_DAEMON_RIB_READVERTISE_CLIENT_TO_NLSR_READVERTISE_POLICY_HPP
+#define NFD_DAEMON_RIB_READVERTISE_CLIENT_TO_NLSR_READVERTISE_POLICY_HPP
+
+#include "readvertise-policy.hpp"
+
+namespace nfd {
+namespace rib {
+
+/** \brief a policy to readvertise routes registered by end hosts into NLSR
+ */
+class ClientToNlsrReadvertisePolicy : public ReadvertisePolicy
+{
+public:
+  /** \brief advertise if the route's origin is client
+   *
+   *  If the route origin is "client" (typically from auto prefix propagation), readvertise it
+   *  using the default signing identity.
+   */
+  optional<ReadvertiseAction>
+  handleNewRoute(const RibRouteRef& ribRoute) const override;
+
+  time::milliseconds
+  getRefreshInterval() const override;
+};
+
+} // namespace rib
+} // namespace nfd
+
+#endif // NFD_DAEMON_RIB_READVERTISE_CLIENT_TO_NLSR_READVERTISE_POLICY_HPP
diff --git a/daemon/rib/readvertise/host-to-gateway-readvertise-policy.cpp b/daemon/rib/readvertise/host-to-gateway-readvertise-policy.cpp
new file mode 100644
index 0000000..2d508f8
--- /dev/null
+++ b/daemon/rib/readvertise/host-to-gateway-readvertise-policy.cpp
@@ -0,0 +1,91 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "host-to-gateway-readvertise-policy.hpp"
+#include "core/scope-prefix.hpp"
+#include "rib/rib-manager.hpp"
+
+#include <ndn-cxx/security/pib/identity.hpp>
+#include <ndn-cxx/security/signing-helpers.hpp>
+
+namespace nfd {
+namespace rib {
+
+static const name::Component IGNORE_COMPONENT("nrd");
+static const time::seconds DEFAULT_REFRESH_INTERVAL = 25_s;
+
+HostToGatewayReadvertisePolicy::HostToGatewayReadvertisePolicy(const ndn::KeyChain& keyChain,
+                                                               const ConfigSection& section)
+  : m_keyChain(keyChain)
+{
+  auto interval = section.get_optional<uint64_t>("refresh_interval");
+  m_refreshInterval = interval ? time::seconds(*interval) : DEFAULT_REFRESH_INTERVAL;
+}
+
+optional<ReadvertiseAction>
+HostToGatewayReadvertisePolicy::handleNewRoute(const RibRouteRef& ribRoute) const
+{
+  auto ribEntryName = ribRoute.entry->getName();
+  if (scope_prefix::LOCALHOST.isPrefixOf(ribEntryName) ||
+      ribEntryName == RibManager::LOCALHOP_TOP_PREFIX) {
+    return nullopt;
+  }
+
+  // find out the shortest identity whose name is a prefix of the RIB entry name
+  auto prefixToAdvertise = ribEntryName;
+  ndn::security::pib::Identity signingIdentity;
+  bool isFound = false;
+
+  for (const auto& identity : m_keyChain.getPib().getIdentities()) {
+    auto prefix = identity.getName();
+
+    // ignore the identity name's last component if it is "nrd"
+    if (!prefix.empty() && IGNORE_COMPONENT == prefix.at(-1)) {
+      prefix = prefix.getPrefix(-1);
+    }
+
+    if (prefix.isPrefixOf(prefixToAdvertise)) {
+      isFound = true;
+      prefixToAdvertise = prefix;
+      signingIdentity = identity;
+    }
+  }
+
+  if (isFound) {
+    return ReadvertiseAction{prefixToAdvertise, ndn::security::signingByIdentity(signingIdentity)};
+  }
+  else {
+    return nullopt;
+  }
+}
+
+time::milliseconds
+HostToGatewayReadvertisePolicy::getRefreshInterval() const
+{
+  return m_refreshInterval;
+}
+
+} // namespace rib
+} // namespace nfd
diff --git a/daemon/rib/readvertise/host-to-gateway-readvertise-policy.hpp b/daemon/rib/readvertise/host-to-gateway-readvertise-policy.hpp
new file mode 100644
index 0000000..69e914a
--- /dev/null
+++ b/daemon/rib/readvertise/host-to-gateway-readvertise-policy.hpp
@@ -0,0 +1,60 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_DAEMON_RIB_READVERTISE_HOST_TO_GATEWAY_READVERTISE_POLICY_HPP
+#define NFD_DAEMON_RIB_READVERTISE_HOST_TO_GATEWAY_READVERTISE_POLICY_HPP
+
+#include "readvertise-policy.hpp"
+#include "core/config-file.hpp"
+
+#include <ndn-cxx/security/key-chain.hpp>
+
+namespace nfd {
+namespace rib {
+
+/** \brief a policy to readvertise routes registered by local applications into remote gateway
+ */
+class HostToGatewayReadvertisePolicy : public ReadvertisePolicy
+{
+public:
+  HostToGatewayReadvertisePolicy(const ndn::KeyChain& keyChain,
+                                 const ConfigSection& section);
+
+public:
+  optional<ReadvertiseAction>
+  handleNewRoute(const RibRouteRef& ribRoute) const override;
+
+  time::milliseconds
+  getRefreshInterval() const override;
+
+private:
+  const ndn::KeyChain& m_keyChain;
+  time::seconds m_refreshInterval;
+};
+
+} // namespace rib
+} // namespace nfd
+
+#endif // NFD_DAEMON_RIB_READVERTISE_HOST_TO_GATEWAY_READVERTISE_POLICY_HPP
diff --git a/daemon/rib/readvertise/nfd-rib-readvertise-destination.cpp b/daemon/rib/readvertise/nfd-rib-readvertise-destination.cpp
new file mode 100644
index 0000000..f0a0482
--- /dev/null
+++ b/daemon/rib/readvertise/nfd-rib-readvertise-destination.cpp
@@ -0,0 +1,110 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "nfd-rib-readvertise-destination.hpp"
+#include "core/logger.hpp"
+
+#include <ndn-cxx/mgmt/nfd/control-command.hpp>
+#include <ndn-cxx/mgmt/nfd/control-response.hpp>
+
+namespace nfd {
+namespace rib {
+
+NFD_LOG_INIT(NfdRibReadvertiseDestination);
+
+using ndn::nfd::ControlResponse;
+
+NfdRibReadvertiseDestination::NfdRibReadvertiseDestination(ndn::nfd::Controller& controller,
+                                                           Rib& rib,
+                                                           const ndn::nfd::CommandOptions& options,
+                                                           const ndn::nfd::ControlParameters& parameters)
+  : m_controller(controller)
+  , m_commandOptions(options)
+  , m_controlParameters(parameters)
+{
+  m_ribInsertConn = rib.afterInsertEntry.connect(
+    std::bind(&NfdRibReadvertiseDestination::handleRibInsert, this, _1));
+  m_ribEraseConn = rib.afterEraseEntry.connect(
+    std::bind(&NfdRibReadvertiseDestination::handleRibErase, this, _1));
+}
+
+void
+NfdRibReadvertiseDestination::advertise(const nfd::rib::ReadvertisedRoute& rr,
+                                        std::function<void()> successCb,
+                                        std::function<void(const std::string&)> failureCb)
+{
+  NFD_LOG_DEBUG("advertise " << rr.prefix << " on " << m_commandOptions.getPrefix());
+
+  m_controller.start<ndn::nfd::RibRegisterCommand>(
+    getControlParameters().setName(rr.prefix),
+    [=] (const ControlParameters& cp) { successCb(); },
+    [=] (const ControlResponse& cr) { failureCb(cr.getText()); },
+    getCommandOptions().setSigningInfo(rr.signer));
+}
+
+void
+NfdRibReadvertiseDestination::withdraw(const nfd::rib::ReadvertisedRoute& rr,
+                                       std::function<void()> successCb,
+                                       std::function<void(const std::string&)> failureCb)
+{
+  NFD_LOG_DEBUG("withdraw " << rr.prefix << " on " << m_commandOptions.getPrefix());
+
+  m_controller.start<ndn::nfd::RibUnregisterCommand>(
+    getControlParameters().setName(rr.prefix),
+    [=] (const ControlParameters& cp) { successCb(); },
+    [=] (const ControlResponse& cr) { failureCb(cr.getText()); },
+    getCommandOptions().setSigningInfo(rr.signer));
+}
+
+ndn::nfd::ControlParameters
+NfdRibReadvertiseDestination::getControlParameters()
+{
+  return m_controlParameters;
+}
+
+ndn::nfd::CommandOptions
+NfdRibReadvertiseDestination::getCommandOptions()
+{
+  return m_commandOptions;
+}
+
+void
+NfdRibReadvertiseDestination::handleRibInsert(const ndn::Name& name)
+{
+  if (name.isPrefixOf(m_commandOptions.getPrefix())) {
+    setAvailability(true);
+  }
+}
+
+void
+NfdRibReadvertiseDestination::handleRibErase(const ndn::Name& name)
+{
+  if (name.isPrefixOf(m_commandOptions.getPrefix())) {
+    setAvailability(false);
+  }
+}
+
+} // namespace rib
+} // namespace nfd
diff --git a/daemon/rib/readvertise/nfd-rib-readvertise-destination.hpp b/daemon/rib/readvertise/nfd-rib-readvertise-destination.hpp
new file mode 100644
index 0000000..9c5bce6
--- /dev/null
+++ b/daemon/rib/readvertise/nfd-rib-readvertise-destination.hpp
@@ -0,0 +1,92 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_DAEMON_RIB_READVERTISE_NFD_RIB_READVERTISE_DESTINATION_HPP
+#define NFD_DAEMON_RIB_READVERTISE_NFD_RIB_READVERTISE_DESTINATION_HPP
+
+#include "readvertise-destination.hpp"
+#include "rib/rib.hpp"
+
+#include <ndn-cxx/mgmt/nfd/command-options.hpp>
+#include <ndn-cxx/mgmt/nfd/controller.hpp>
+#include <ndn-cxx/mgmt/nfd/control-parameters.hpp>
+
+namespace nfd {
+namespace rib {
+
+/** \brief a readvertise destination using NFD RIB management protocol
+ */
+class NfdRibReadvertiseDestination : public ReadvertiseDestination
+{
+public:
+  NfdRibReadvertiseDestination(ndn::nfd::Controller& controller,
+                               Rib& rib,
+                               const ndn::nfd::CommandOptions& options = ndn::nfd::CommandOptions(),
+                               const ndn::nfd::ControlParameters& parameters =
+                                 ndn::nfd::ControlParameters()
+                                   .setOrigin(ndn::nfd::ROUTE_ORIGIN_CLIENT));
+
+  /** \brief add a name prefix into NFD RIB
+   */
+  void
+  advertise(const ReadvertisedRoute& rr,
+            std::function<void()> successCb,
+            std::function<void(const std::string&)> failureCb) override;
+
+  /** \brief remove a name prefix from NFD RIB
+   */
+  void
+  withdraw(const ReadvertisedRoute& rr,
+           std::function<void()> successCb,
+           std::function<void(const std::string&)> failureCb) override;
+
+protected:
+  ndn::nfd::ControlParameters
+  getControlParameters();
+
+  ndn::nfd::CommandOptions
+  getCommandOptions();
+
+private:
+  void
+  handleRibInsert(const Name& name);
+
+  void
+  handleRibErase(const Name& name);
+
+private:
+  ndn::nfd::Controller& m_controller;
+
+  signal::ScopedConnection m_ribInsertConn;
+  signal::ScopedConnection m_ribEraseConn;
+
+  ndn::nfd::CommandOptions m_commandOptions;
+  ndn::nfd::ControlParameters m_controlParameters;
+};
+
+} // namespace rib
+} // namespace nfd
+
+#endif // NFD_DAEMON_RIB_READVERTISE_NFD_RIB_READVERTISE_DESTINATION_HPP
diff --git a/daemon/rib/readvertise/readvertise-destination.cpp b/daemon/rib/readvertise/readvertise-destination.cpp
new file mode 100644
index 0000000..a687a8a
--- /dev/null
+++ b/daemon/rib/readvertise/readvertise-destination.cpp
@@ -0,0 +1,50 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "readvertise-destination.hpp"
+#include "core/logger.hpp"
+
+namespace nfd {
+namespace rib {
+
+NFD_LOG_INIT(ReadvertiseDestination);
+
+void
+ReadvertiseDestination::setAvailability(bool isAvailable)
+{
+  if (m_isAvailable != isAvailable) {
+    if (isAvailable) {
+      NFD_LOG_DEBUG("Destination has become available.");
+    }
+    else {
+      NFD_LOG_DEBUG("Destinatino has become unavailable.");
+    }
+    m_isAvailable = isAvailable;
+    afterAvailabilityChange(isAvailable);
+  }
+}
+
+} // namespace rib
+} // namespace nfd
diff --git a/daemon/rib/readvertise/readvertise-destination.hpp b/daemon/rib/readvertise/readvertise-destination.hpp
new file mode 100644
index 0000000..1c4fb76
--- /dev/null
+++ b/daemon/rib/readvertise/readvertise-destination.hpp
@@ -0,0 +1,74 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_DAEMON_RIB_READVERTISE_READVERTISE_DESTINATION_HPP
+#define NFD_DAEMON_RIB_READVERTISE_READVERTISE_DESTINATION_HPP
+
+#include "readvertised-route.hpp"
+
+namespace nfd {
+namespace rib {
+
+/** \brief a destination to readvertise into
+ */
+class ReadvertiseDestination : noncopyable
+{
+public:
+  virtual
+  ~ReadvertiseDestination() = default;
+
+  virtual void
+  advertise(const ReadvertisedRoute& rr,
+            std::function<void()> successCb,
+            std::function<void(const std::string&)> failureCb) = 0;
+
+  virtual void
+  withdraw(const ReadvertisedRoute& rr,
+           std::function<void()> successCb,
+           std::function<void(const std::string&)> failureCb) = 0;
+
+  bool
+  isAvailable() const
+  {
+    return m_isAvailable;
+  }
+
+protected:
+  void
+  setAvailability(bool isAvailable);
+
+public:
+  /** \brief signals when the destination becomes available or unavailable
+   */
+  signal::Signal<ReadvertiseDestination, bool> afterAvailabilityChange;
+
+private:
+  bool m_isAvailable = false;
+};
+
+} // namespace rib
+} // namespace nfd
+
+#endif // NFD_DAEMON_RIB_READVERTISE_READVERTISE_DESTINATION_HPP
diff --git a/daemon/rib/readvertise/readvertise-policy.hpp b/daemon/rib/readvertise/readvertise-policy.hpp
new file mode 100644
index 0000000..99deccb
--- /dev/null
+++ b/daemon/rib/readvertise/readvertise-policy.hpp
@@ -0,0 +1,66 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_DAEMON_RIB_READVERTISE_READVERTISE_POLICY_HPP
+#define NFD_DAEMON_RIB_READVERTISE_READVERTISE_POLICY_HPP
+
+#include "rib/rib.hpp"
+
+#include <ndn-cxx/security/signing-info.hpp>
+
+namespace nfd {
+namespace rib {
+
+/** \brief a decision made by readvertise policy
+ */
+struct ReadvertiseAction
+{
+  Name prefix; ///< the prefix that should be readvertised
+  ndn::security::SigningInfo signer; ///< credentials for command signing
+};
+
+/** \brief a policy to decide whether to readvertise a route, and what prefix to readvertise
+ */
+class ReadvertisePolicy : noncopyable
+{
+public:
+  virtual
+  ~ReadvertisePolicy() = default;
+
+  /** \brief decide whether to readvertise a route, and what prefix to readvertise
+   */
+  virtual optional<ReadvertiseAction>
+  handleNewRoute(const RibRouteRef& ribRoute) const = 0;
+
+  /** \return how often readvertisements made by this policy should be refreshed.
+   */
+  virtual time::milliseconds
+  getRefreshInterval() const = 0;
+};
+
+} // namespace rib
+} // namespace nfd
+
+#endif // NFD_DAEMON_RIB_READVERTISE_READVERTISE_POLICY_HPP
diff --git a/daemon/rib/readvertise/readvertise.cpp b/daemon/rib/readvertise/readvertise.cpp
new file mode 100644
index 0000000..454ab20
--- /dev/null
+++ b/daemon/rib/readvertise/readvertise.cpp
@@ -0,0 +1,201 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "readvertise.hpp"
+#include "core/logger.hpp"
+
+#include <ndn-cxx/util/random.hpp>
+
+namespace nfd {
+namespace rib {
+
+NFD_LOG_INIT(Readvertise);
+
+const time::milliseconds Readvertise::RETRY_DELAY_MIN = 50_s;
+const time::milliseconds Readvertise::RETRY_DELAY_MAX = 3600_s;
+
+static time::milliseconds
+randomizeTimer(time::milliseconds baseTimer)
+{
+  std::uniform_int_distribution<> dist(-5, 5);
+  auto newTime = baseTimer + time::milliseconds(dist(ndn::random::getRandomNumberEngine()));
+  return std::max(newTime, 0_ms);
+}
+
+Readvertise::Readvertise(Rib& rib, ndn::util::Scheduler& scheduler,
+                         unique_ptr<ReadvertisePolicy> policy,
+                         unique_ptr<ReadvertiseDestination> destination)
+  : m_scheduler(scheduler)
+  , m_policy(std::move(policy))
+  , m_destination(std::move(destination))
+{
+  m_addRouteConn = rib.afterAddRoute.connect([this] (const auto& r) { this->afterAddRoute(r); });
+  m_removeRouteConn = rib.beforeRemoveRoute.connect([this] (const auto& r) { this->beforeRemoveRoute(r); });
+
+  m_destination->afterAvailabilityChange.connect([this] (bool isAvailable) {
+    if (isAvailable) {
+      this->afterDestinationAvailable();
+    }
+    else {
+      this->afterDestinationUnavailable();
+    }
+  });
+}
+
+void
+Readvertise::afterAddRoute(const RibRouteRef& ribRoute)
+{
+  optional<ReadvertiseAction> action = m_policy->handleNewRoute(ribRoute);
+  if (!action) {
+    NFD_LOG_DEBUG("add-route " << ribRoute.entry->getName() << '(' << ribRoute.route->faceId <<
+                  ',' << ribRoute.route->origin << ") not-readvertising");
+    return;
+  }
+
+  ReadvertisedRouteContainer::iterator rrIt;
+  bool isNew = false;
+  std::tie(rrIt, isNew) = m_rrs.emplace(action->prefix);
+
+  if (!isNew && rrIt->signer != action->signer) {
+    NFD_LOG_WARN("add-route " << ribRoute.entry->getName() << '(' << ribRoute.route->faceId <<
+                  ',' << ribRoute.route->origin << ") readvertising-as " << action->prefix <<
+                 " old-signer " << rrIt->signer << " new-signer " << action->signer);
+  }
+  rrIt->signer = action->signer;
+
+  RouteRrIndex::iterator indexIt;
+  std::tie(indexIt, isNew) = m_routeToRr.emplace(ribRoute, rrIt);
+  BOOST_ASSERT(isNew);
+
+  if (rrIt->nRibRoutes++ > 0) {
+    NFD_LOG_DEBUG("add-route " << ribRoute.entry->getName() << '(' << ribRoute.route->faceId <<
+                  ',' << ribRoute.route->origin << ") already-readvertised-as " << action->prefix);
+    return;
+  }
+
+  NFD_LOG_DEBUG("add-route " << ribRoute.entry->getName() << '(' << ribRoute.route->faceId <<
+                ',' << ribRoute.route->origin << ") readvertising-as " << action->prefix <<
+                " signer " << action->signer);
+  rrIt->retryDelay = RETRY_DELAY_MIN;
+  this->advertise(rrIt);
+}
+
+void
+Readvertise::beforeRemoveRoute(const RibRouteRef& ribRoute)
+{
+  auto indexIt = m_routeToRr.find(ribRoute);
+  if (indexIt == m_routeToRr.end()) {
+    NFD_LOG_DEBUG("remove-route " << ribRoute.entry->getName() << '(' << ribRoute.route->faceId <<
+                  ',' << ribRoute.route->origin << ") not-readvertised");
+    return;
+  }
+
+  auto rrIt = indexIt->second;
+  m_routeToRr.erase(indexIt);
+
+  if (--rrIt->nRibRoutes > 0) {
+    NFD_LOG_DEBUG("remove-route " << ribRoute.entry->getName() << '(' << ribRoute.route->faceId <<
+                  ',' << ribRoute.route->origin << ") needed-by " << rrIt->nRibRoutes);
+    return;
+  }
+
+  rrIt->retryDelay = RETRY_DELAY_MIN;
+  this->withdraw(rrIt);
+}
+
+void
+Readvertise::afterDestinationAvailable()
+{
+  for (auto rrIt = m_rrs.begin(); rrIt != m_rrs.end(); ++rrIt) {
+    rrIt->retryDelay = RETRY_DELAY_MIN;
+    this->advertise(rrIt);
+  }
+}
+
+void
+Readvertise::afterDestinationUnavailable()
+{
+  for (auto rrIt = m_rrs.begin(); rrIt != m_rrs.end();) {
+    if (rrIt->nRibRoutes > 0) {
+      rrIt->retryEvt.cancel(); // stop retrying or refreshing
+      ++rrIt;
+    }
+    else {
+      rrIt = m_rrs.erase(rrIt); // assume withdraw has completed
+    }
+  }
+}
+
+void
+Readvertise::advertise(ReadvertisedRouteContainer::iterator rrIt)
+{
+  BOOST_ASSERT(rrIt->nRibRoutes > 0);
+
+  if (!m_destination->isAvailable()) {
+    NFD_LOG_DEBUG("advertise " << rrIt->prefix << " destination-unavailable");
+    return;
+  }
+
+  m_destination->advertise(*rrIt,
+    [=] {
+      NFD_LOG_DEBUG("advertise " << rrIt->prefix << " success");
+      rrIt->retryDelay = RETRY_DELAY_MIN;
+      rrIt->retryEvt = m_scheduler.scheduleEvent(randomizeTimer(m_policy->getRefreshInterval()),
+                                                 [=] { advertise(rrIt); });
+    },
+    [=] (const std::string& msg) {
+      NFD_LOG_DEBUG("advertise " << rrIt->prefix << " failure " << msg);
+      rrIt->retryDelay = std::min(RETRY_DELAY_MAX, rrIt->retryDelay * 2);
+      rrIt->retryEvt = m_scheduler.scheduleEvent(randomizeTimer(rrIt->retryDelay),
+                                                 [=] { advertise(rrIt); });
+    });
+}
+
+void
+Readvertise::withdraw(ReadvertisedRouteContainer::iterator rrIt)
+{
+  BOOST_ASSERT(rrIt->nRibRoutes == 0);
+
+  if (!m_destination->isAvailable()) {
+    NFD_LOG_DEBUG("withdraw " << rrIt->prefix << " destination-unavailable");
+    m_rrs.erase(rrIt);
+    return;
+  }
+
+  m_destination->withdraw(*rrIt,
+    [=] {
+      NFD_LOG_DEBUG("withdraw " << rrIt->prefix << " success");
+      m_rrs.erase(rrIt);
+    },
+    [=] (const std::string& msg) {
+      NFD_LOG_DEBUG("withdraw " << rrIt->prefix << " failure " << msg);
+      rrIt->retryDelay = std::min(RETRY_DELAY_MAX, rrIt->retryDelay * 2);
+      rrIt->retryEvt = m_scheduler.scheduleEvent(randomizeTimer(rrIt->retryDelay),
+                                                 [=] { withdraw(rrIt); });
+    });
+}
+
+} // namespace rib
+} // namespace nfd
diff --git a/daemon/rib/readvertise/readvertise.hpp b/daemon/rib/readvertise/readvertise.hpp
new file mode 100644
index 0000000..80dbbc7
--- /dev/null
+++ b/daemon/rib/readvertise/readvertise.hpp
@@ -0,0 +1,94 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_DAEMON_RIB_READVERTISE_READVERTISE_HPP
+#define NFD_DAEMON_RIB_READVERTISE_READVERTISE_HPP
+
+#include "readvertise-destination.hpp"
+#include "readvertise-policy.hpp"
+#include "readvertised-route.hpp"
+#include "rib/rib.hpp"
+
+namespace nfd {
+namespace rib {
+
+/** \brief readvertise a subset of routes to a destination according to a policy
+ *
+ *  The Readvertise class allows RIB routes to be readvertised to a destination such as a routing
+ *  protocol daemon or another NFD-RIB. It monitors the RIB for route additions and removals,
+ *  asks the ReadvertisePolicy to make decision on whether to readvertise each new route and what
+ *  prefix to readvertise as, and invokes a ReadvertiseDestination to send the commands.
+ */
+class Readvertise : noncopyable
+{
+
+public:
+  Readvertise(Rib& rib,
+              ndn::util::Scheduler& scheduler,
+              unique_ptr<ReadvertisePolicy> policy,
+              unique_ptr<ReadvertiseDestination> destination);
+
+private:
+  void
+  afterAddRoute(const RibRouteRef& ribRoute);
+
+  void
+  beforeRemoveRoute(const RibRouteRef& ribRoute);
+
+  void
+  afterDestinationAvailable();
+
+  void
+  afterDestinationUnavailable();
+
+  void
+  advertise(ReadvertisedRouteContainer::iterator rrIt);
+
+  void
+  withdraw(ReadvertisedRouteContainer::iterator rrIt);
+
+private:
+  /** \brief maps from RIB route to readvertised route derived from RIB route(s)
+   */
+  using RouteRrIndex = std::map<RibRouteRef, ReadvertisedRouteContainer::iterator>;
+
+  static const time::milliseconds RETRY_DELAY_MIN;
+  static const time::milliseconds RETRY_DELAY_MAX;
+
+  ndn::util::Scheduler& m_scheduler;
+  unique_ptr<ReadvertisePolicy> m_policy;
+  unique_ptr<ReadvertiseDestination> m_destination;
+
+  ReadvertisedRouteContainer m_rrs;
+  RouteRrIndex m_routeToRr;
+
+  signal::ScopedConnection m_addRouteConn;
+  signal::ScopedConnection m_removeRouteConn;
+};
+
+} // namespace rib
+} // namespace nfd
+
+#endif // NFD_DAEMON_RIB_READVERTISE_READVERTISE_HPP
diff --git a/daemon/rib/readvertise/readvertised-route.hpp b/daemon/rib/readvertise/readvertised-route.hpp
new file mode 100644
index 0000000..7dc02ae
--- /dev/null
+++ b/daemon/rib/readvertise/readvertised-route.hpp
@@ -0,0 +1,69 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_DAEMON_RIB_READVERTISE_READVERTISED_ROUTE_HPP
+#define NFD_DAEMON_RIB_READVERTISE_READVERTISED_ROUTE_HPP
+
+#include "core/common.hpp"
+
+#include <ndn-cxx/security/signing-info.hpp>
+#include <ndn-cxx/util/scheduler.hpp>
+
+namespace nfd {
+namespace rib {
+
+/** \brief state of a readvertised route
+ */
+class ReadvertisedRoute : noncopyable
+{
+public:
+  explicit
+  ReadvertisedRoute(const Name& prefix)
+    : prefix(prefix)
+    , nRibRoutes(0)
+    , retryDelay(0)
+  {
+  }
+
+public:
+  Name prefix; ///< readvertised prefix
+  mutable ndn::security::SigningInfo signer; ///< signer for commands
+  mutable size_t nRibRoutes; ///< number of RIB routes that cause the readvertisement
+  mutable time::milliseconds retryDelay; ///< retry interval (not used for refresh)
+  mutable ndn::util::scheduler::ScopedEventId retryEvt; ///< retry or refresh event
+};
+
+inline bool
+operator<(const ReadvertisedRoute& lhs, const ReadvertisedRoute& rhs)
+{
+  return lhs.prefix < rhs.prefix;
+}
+
+using ReadvertisedRouteContainer = std::set<ReadvertisedRoute>;
+
+} // namespace rib
+} // namespace nfd
+
+#endif // NFD_DAEMON_RIB_READVERTISE_READVERTISED_ROUTE_HPP
diff --git a/daemon/rib/rib-entry.cpp b/daemon/rib/rib-entry.cpp
new file mode 100644
index 0000000..008ac4f
--- /dev/null
+++ b/daemon/rib/rib-entry.cpp
@@ -0,0 +1,290 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "rib-entry.hpp"
+#include "core/logger.hpp"
+
+#include <ndn-cxx/mgmt/nfd/control-command.hpp>
+
+namespace nfd {
+namespace rib {
+
+NFD_LOG_INIT(RibEntry);
+
+RibEntry::RouteList::iterator
+RibEntry::findRoute(const Route& route)
+{
+  return std::find_if(begin(), end(), bind(&compareFaceIdAndOrigin, _1, route));
+}
+
+RibEntry::RouteList::const_iterator
+RibEntry::findRoute(const Route& route) const
+{
+  return std::find_if(begin(), end(), bind(&compareFaceIdAndOrigin, _1, route));
+}
+
+std::pair<RibEntry::iterator, bool>
+RibEntry::insertRoute(const Route& route)
+{
+  iterator it = findRoute(route);
+
+  if (it == end()) {
+    if (route.flags & ndn::nfd::ROUTE_FLAG_CAPTURE) {
+      m_nRoutesWithCaptureSet++;
+    }
+
+    m_routes.push_back(route);
+    return {std::prev(m_routes.end()), true};
+  }
+
+  return {it, false};
+}
+
+void
+RibEntry::eraseRoute(const Route& route)
+{
+  RibEntry::iterator it = findRoute(route);
+  eraseRoute(it);
+}
+
+bool
+RibEntry::hasRoute(const Route& route)
+{
+  RibEntry::const_iterator it = findRoute(route);
+
+  return it != end();
+}
+
+bool
+RibEntry::hasFaceId(const uint64_t faceId) const
+{
+  RibEntry::const_iterator it = std::find_if(begin(), end(), bind(&compareFaceId, _1, faceId));
+
+  return it != end();
+}
+
+size_t
+RibEntry::getNRoutes() const
+{
+  return m_routes.size();
+}
+
+void
+RibEntry::addChild(shared_ptr<RibEntry> child)
+{
+  BOOST_ASSERT(!child->getParent());
+  child->setParent(this->shared_from_this());
+  m_children.push_back(std::move(child));
+}
+
+void
+RibEntry::removeChild(shared_ptr<RibEntry> child)
+{
+  BOOST_ASSERT(child->getParent().get() == this);
+  child->setParent(nullptr);
+  m_children.remove(child);
+}
+
+RibEntry::RouteList::iterator
+RibEntry::eraseRoute(RouteList::iterator route)
+{
+  if (route != m_routes.end()) {
+    if (route->flags & ndn::nfd::ROUTE_FLAG_CAPTURE) {
+      m_nRoutesWithCaptureSet--;
+    }
+
+    // Cancel any scheduled event
+    NFD_LOG_TRACE("Cancelling expiration event: " << route->getExpirationEvent());
+    route->cancelExpirationEvent();
+
+    return m_routes.erase(route);
+  }
+
+  return m_routes.end();
+}
+
+void
+RibEntry::addInheritedRoute(const Route& route)
+{
+  m_inheritedRoutes.push_back(route);
+}
+
+void
+RibEntry::removeInheritedRoute(const Route& route)
+{
+  m_inheritedRoutes.remove_if(bind(&compareFaceId, _1, route.faceId));
+}
+
+RibEntry::RouteList::const_iterator
+RibEntry::findInheritedRoute(const Route& route) const
+{
+  return std::find_if(m_inheritedRoutes.begin(), m_inheritedRoutes.end(),
+                      bind(&compareFaceId, _1, route.faceId));
+}
+
+bool
+RibEntry::hasInheritedRoute(const Route& route) const
+{
+  return findInheritedRoute(route) != m_inheritedRoutes.end();
+}
+
+bool
+RibEntry::hasCapture() const
+{
+  return m_nRoutesWithCaptureSet > 0;
+}
+
+bool
+RibEntry::hasChildInheritOnFaceId(uint64_t faceId) const
+{
+  for (const Route& route : m_routes) {
+    if (route.faceId == faceId && (route.flags & ndn::nfd::ROUTE_FLAG_CHILD_INHERIT)) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+const Route*
+RibEntry::getRouteWithLowestCostByFaceId(uint64_t faceId) const
+{
+  const Route* candidate = nullptr;
+
+  for (const Route& route : m_routes) {
+    // Matching face ID
+    if (route.faceId == faceId) {
+      // If this is the first route with this Face ID found
+      if (candidate == nullptr) {
+        candidate = &route;
+      }
+      else if (route.cost < candidate->cost) {
+        // Found a route with a lower cost
+        candidate = &route;
+      }
+    }
+  }
+
+  return candidate;
+}
+
+const Route*
+RibEntry::getRouteWithSecondLowestCostByFaceId(uint64_t faceId) const
+{
+  std::vector<const Route*> matches;
+
+  // Copy routes which have faceId
+  for (const Route& route : m_routes) {
+    if (route.faceId == faceId) {
+      matches.push_back(&route);
+    }
+  }
+
+  // If there are less than 2 routes, there is no second lowest
+  if (matches.size() < 2) {
+    return nullptr;
+  }
+
+  // Get second lowest cost
+  std::nth_element(matches.begin(), matches.begin() + 1, matches.end(),
+    [] (const Route* lhs, const Route* rhs) { return lhs->cost < rhs->cost; });
+
+  return matches.at(1);
+}
+
+const Route*
+RibEntry::getRouteWithLowestCostAndChildInheritByFaceId(uint64_t faceId) const
+{
+  const Route* candidate = nullptr;
+
+  for (const Route& route : m_routes) {
+    // Correct face ID and Child Inherit flag set
+    if (route.faceId == faceId &&
+        (route.flags & ndn::nfd::ROUTE_FLAG_CHILD_INHERIT) == ndn::nfd::ROUTE_FLAG_CHILD_INHERIT)
+    {
+      // If this is the first route with this Face ID found
+      if (candidate == nullptr) {
+        candidate = &route;
+      }
+      else if (route.cost < candidate->cost) {
+        // Found a route with a lower cost
+        candidate = &route;
+      }
+    }
+  }
+
+  return candidate;
+}
+
+ndn::PrefixAnnouncement
+RibEntry::getPrefixAnnouncement(time::milliseconds minExpiration,
+                                time::milliseconds maxExpiration) const
+{
+  const Route* bestAnnRoute = nullptr;
+  auto entryExpiry = time::steady_clock::TimePoint::min();
+
+  for (const Route& route : *this) {
+    if (route.expires) {
+      entryExpiry = std::max(entryExpiry, *route.expires);
+      if (route.announcement) {
+        if (bestAnnRoute == nullptr || *route.expires > *bestAnnRoute->expires) {
+          bestAnnRoute = &route;
+        }
+      }
+    }
+    else {
+      entryExpiry = time::steady_clock::TimePoint::max();
+    }
+  }
+
+  if (bestAnnRoute != nullptr) {
+    return *bestAnnRoute->announcement;
+  }
+
+  ndn::PrefixAnnouncement ann;
+  ann.setAnnouncedName(m_name);
+  ann.setExpiration(ndn::clamp(
+    time::duration_cast<time::milliseconds>(entryExpiry - time::steady_clock::now()),
+    minExpiration, maxExpiration));
+  return ann;
+}
+
+std::ostream&
+operator<<(std::ostream& os, const RibEntry& entry)
+{
+  os << "RibEntry {\n";
+  os << "  Name: " << entry.getName() << "\n";
+
+  for (const Route& route : entry) {
+    os << "  " << route << "\n";
+  }
+
+  os << "}";
+
+  return os;
+}
+
+} // namespace rib
+} // namespace nfd
diff --git a/daemon/rib/rib-entry.hpp b/daemon/rib/rib-entry.hpp
new file mode 100644
index 0000000..45d5a87
--- /dev/null
+++ b/daemon/rib/rib-entry.hpp
@@ -0,0 +1,288 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_DAEMON_RIB_RIB_ENTRY_HPP
+#define NFD_DAEMON_RIB_RIB_ENTRY_HPP
+
+#include "route.hpp"
+
+#include <list>
+
+namespace nfd {
+namespace rib {
+
+/** \brief Represents a RIB entry, which contains one or more Routes with the same prefix.
+ */
+class RibEntry : public std::enable_shared_from_this<RibEntry>
+{
+public:
+  typedef std::list<Route> RouteList;
+  typedef RouteList::iterator iterator;
+  typedef RouteList::const_iterator const_iterator;
+
+  RibEntry()
+    : m_nRoutesWithCaptureSet(0)
+  {
+  }
+
+  void
+  setName(const Name& prefix);
+
+  const Name&
+  getName() const;
+
+  shared_ptr<RibEntry>
+  getParent() const;
+
+  bool
+  hasParent() const;
+
+  void
+  addChild(shared_ptr<RibEntry> child);
+
+  void
+  removeChild(shared_ptr<RibEntry> child);
+
+  const std::list<shared_ptr<RibEntry>>&
+  getChildren() const;
+
+  bool
+  hasChildren() const;
+
+  /** \brief inserts a new route into the entry's route list
+   *  If another route already exists with the same faceId and origin,
+   *  the new route is not inserted.
+   *  \return a pair, whose first element is the iterator to the newly
+   *  inserted element if the insert succeeds and to the
+   *  previously-existing element otherwise, and whose second element
+   *  is true if the insert succeeds and false otherwise.
+   */
+  std::pair<RibEntry::iterator, bool>
+  insertRoute(const Route& route);
+
+  /** \brief erases a Route with the same faceId and origin
+   */
+  void
+  eraseRoute(const Route& route);
+
+  /** \brief erases a Route with the passed iterator
+   *  \return{ an iterator to the element that followed the erased iterator }
+   */
+  iterator
+  eraseRoute(RouteList::iterator route);
+
+  bool
+  hasFaceId(const uint64_t faceId) const;
+
+  const RouteList&
+  getRoutes() const;
+
+  size_t
+  getNRoutes() const;
+
+  iterator
+  findRoute(const Route& route);
+
+  const_iterator
+  findRoute(const Route& route) const;
+
+  bool
+  hasRoute(const Route& route);
+
+  void
+  addInheritedRoute(const Route& route);
+
+  void
+  removeInheritedRoute(const Route& route);
+
+  /** \brief Returns the routes this namespace has inherited.
+   *  The inherited routes returned represent inherited routes this namespace has in the FIB.
+   *  \return{ routes inherited by this namespace }
+   */
+  const RouteList&
+  getInheritedRoutes() const;
+
+  /** \brief Finds an inherited route with a matching face ID.
+   *  \return{ An iterator to the matching route if one is found;
+   *           otherwise, an iterator to the end of the entry's
+   *           inherited route list }
+   */
+  RouteList::const_iterator
+  findInheritedRoute(const Route& route) const;
+
+  /** \brief Determines if the entry has an inherited route with a matching face ID.
+   *  \return{ True, if a matching inherited route is found; otherwise, false. }
+   */
+  bool
+  hasInheritedRoute(const Route& route) const;
+
+  bool
+  hasCapture() const;
+
+  /** \brief Determines if the entry has an inherited route with the passed
+   *         face ID and its child inherit flag set.
+   *  \return{ True, if a matching inherited route is found; otherwise, false. }
+   */
+  bool
+  hasChildInheritOnFaceId(uint64_t faceId) const;
+
+  /** \brief Returns the route with the lowest cost that has the passed face ID.
+   *  \return{ The route with the lowest cost that has the passed face ID}
+   */
+  const Route*
+  getRouteWithLowestCostByFaceId(uint64_t faceId) const;
+
+  const Route*
+  getRouteWithSecondLowestCostByFaceId(uint64_t faceId) const;
+
+  /** \brief Returns the route with the lowest cost that has the passed face ID
+   *         and its child inherit flag set.
+   *  \return{ The route with the lowest cost that has the passed face ID
+   *           and its child inherit flag set }
+   */
+  const Route*
+  getRouteWithLowestCostAndChildInheritByFaceId(uint64_t faceId) const;
+
+  /** \brief Retrieve a prefix announcement suitable for readvertising this route.
+   *
+   *  If one or more routes in this RIB entry contains a prefix announcement, this method returns
+   *  the announcement from the route that expires last.
+   *
+   *  If this RIB entry does not have a route containing a prefix announcement, this method creates
+   *  a new announcement. Its expiration period reflects the remaining lifetime of this RIB entry,
+   *  confined within [\p minExpiration, \p maxExpiration] range. The caller is expected to sign
+   *  this announcement.
+   *
+   *  \warning (minExpiration > maxExpiration) triggers undefined behavior.
+   */
+  ndn::PrefixAnnouncement
+  getPrefixAnnouncement(time::milliseconds minExpiration = 15_s,
+                        time::milliseconds maxExpiration = 1_h) const;
+
+  const_iterator
+  begin() const;
+
+  const_iterator
+  end() const;
+
+  iterator
+  begin();
+
+  iterator
+  end();
+
+private:
+  void
+  setParent(shared_ptr<RibEntry> parent);
+
+private:
+  Name m_name;
+  std::list<shared_ptr<RibEntry>> m_children;
+  shared_ptr<RibEntry> m_parent;
+  RouteList m_routes;
+  RouteList m_inheritedRoutes;
+
+  /** \brief The number of routes on this namespace with the capture flag set.
+   *
+   *  This count is used to check if the namespace will block inherited routes.
+   *  If the number is greater than zero, a route on the namespace has its capture
+   *  flag set which means the namespace should not inherit any routes.
+   */
+  uint64_t m_nRoutesWithCaptureSet;
+};
+
+inline void
+RibEntry::setName(const Name& prefix)
+{
+  m_name = prefix;
+}
+
+inline const Name&
+RibEntry::getName() const
+{
+  return m_name;
+}
+
+inline void
+RibEntry::setParent(shared_ptr<RibEntry> parent)
+{
+  m_parent = parent;
+}
+
+inline shared_ptr<RibEntry>
+RibEntry::getParent() const
+{
+  return m_parent;
+}
+
+inline const std::list<shared_ptr<RibEntry>>&
+RibEntry::getChildren() const
+{
+  return m_children;
+}
+
+inline const RibEntry::RouteList&
+RibEntry::getRoutes() const
+{
+  return m_routes;
+}
+
+inline const RibEntry::RouteList&
+RibEntry::getInheritedRoutes() const
+{
+  return m_inheritedRoutes;
+}
+
+inline RibEntry::const_iterator
+RibEntry::begin() const
+{
+  return m_routes.begin();
+}
+
+inline RibEntry::const_iterator
+RibEntry::end() const
+{
+  return m_routes.end();
+}
+
+inline RibEntry::iterator
+RibEntry::begin()
+{
+  return m_routes.begin();
+}
+
+inline RibEntry::iterator
+RibEntry::end()
+{
+  return m_routes.end();
+}
+
+std::ostream&
+operator<<(std::ostream& os, const RibEntry& entry);
+
+} // namespace rib
+} // namespace nfd
+
+#endif // NFD_DAEMON_RIB_RIB_ENTRY_HPP
diff --git a/daemon/rib/rib-manager.cpp b/daemon/rib/rib-manager.cpp
new file mode 100644
index 0000000..4477ebc
--- /dev/null
+++ b/daemon/rib/rib-manager.cpp
@@ -0,0 +1,500 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "rib-manager.hpp"
+
+#include "core/fib-max-depth.hpp"
+#include "core/logger.hpp"
+
+#include <ndn-cxx/lp/tags.hpp>
+#include <ndn-cxx/mgmt/nfd/control-command.hpp>
+#include <ndn-cxx/mgmt/nfd/control-parameters.hpp>
+#include <ndn-cxx/mgmt/nfd/control-response.hpp>
+#include <ndn-cxx/mgmt/nfd/face-status.hpp>
+#include <ndn-cxx/mgmt/nfd/rib-entry.hpp>
+
+namespace nfd {
+namespace rib {
+
+NFD_LOG_INIT(RibManager);
+
+static const std::string MGMT_MODULE_NAME = "rib";
+static const Name LOCALHOST_TOP_PREFIX = "/localhost/nfd";
+static const time::seconds ACTIVE_FACE_FETCH_INTERVAL = 5_min;
+
+const Name RibManager::LOCALHOP_TOP_PREFIX = "/localhop/nfd";
+
+RibManager::RibManager(Rib& rib, ndn::Face& face, ndn::KeyChain& keyChain,
+                       ndn::nfd::Controller& nfdController, Dispatcher& dispatcher,
+                       ndn::util::Scheduler& scheduler)
+  : ManagerBase(dispatcher, MGMT_MODULE_NAME)
+  , m_rib(rib)
+  , m_keyChain(keyChain)
+  , m_nfdController(nfdController)
+  , m_dispatcher(dispatcher)
+  , m_scheduler(scheduler)
+  , m_faceMonitor(face)
+  , m_localhostValidator(face)
+  , m_localhopValidator(face)
+  , m_isLocalhopEnabled(false)
+{
+  registerCommandHandler<ndn::nfd::RibRegisterCommand>("register",
+    bind(&RibManager::registerEntry, this, _2, _3, _4, _5));
+  registerCommandHandler<ndn::nfd::RibUnregisterCommand>("unregister",
+    bind(&RibManager::unregisterEntry, this, _2, _3, _4, _5));
+
+  registerStatusDatasetHandler("list", bind(&RibManager::listEntries, this, _1, _2, _3));
+}
+
+void
+RibManager::applyLocalhostConfig(const ConfigSection& section, const std::string& filename)
+{
+  m_localhostValidator.load(section, filename);
+}
+
+void
+RibManager::enableLocalhop(const ConfigSection& section, const std::string& filename)
+{
+  m_localhopValidator.load(section, filename);
+  m_isLocalhopEnabled = true;
+}
+
+void
+RibManager::disableLocalhop()
+{
+  m_isLocalhopEnabled = false;
+}
+
+void
+RibManager::registerWithNfd()
+{
+  registerTopPrefix(LOCALHOST_TOP_PREFIX);
+
+  if (m_isLocalhopEnabled) {
+    registerTopPrefix(LOCALHOP_TOP_PREFIX);
+  }
+
+  NFD_LOG_INFO("Start monitoring face create/destroy events");
+  m_faceMonitor.onNotification.connect(bind(&RibManager::onNotification, this, _1));
+  m_faceMonitor.start();
+
+  scheduleActiveFaceFetch(ACTIVE_FACE_FETCH_INTERVAL);
+}
+
+void
+RibManager::enableLocalFields()
+{
+  m_nfdController.start<ndn::nfd::FaceUpdateCommand>(
+    ControlParameters().setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, true),
+    [] (const ControlParameters&) {
+      NFD_LOG_DEBUG("Local fields enabled");
+    },
+    [] (const ControlResponse& res) {
+      NDN_THROW(Error("Couldn't enable local fields (" + to_string(res.getCode()) +
+                      " " + res.getText() + ")"));
+    });
+}
+
+void
+RibManager::beginAddRoute(const Name& name, Route route, optional<time::nanoseconds> expires,
+                          const std::function<void(RibUpdateResult)>& done)
+{
+  if (expires) {
+    route.expires = time::steady_clock::now() + *expires;
+  }
+  else if (route.expires) {
+    expires = *route.expires - time::steady_clock::now();
+  }
+
+  if (expires && *expires <= 0_s) {
+    m_rib.onRouteExpiration(name, route);
+    return done(RibUpdateResult::EXPIRED);
+  }
+
+  NFD_LOG_INFO("Adding route " << name << " nexthop=" << route.faceId <<
+               " origin=" << route.origin << " cost=" << route.cost);
+
+  if (expires) {
+    auto event = m_scheduler.scheduleEvent(*expires, [=] { m_rib.onRouteExpiration(name, route); });
+    route.setExpirationEvent(event);
+    NFD_LOG_TRACE("Scheduled unregistration at: " << *route.expires);
+  }
+
+  m_registeredFaces.insert(route.faceId);
+
+  RibUpdate update;
+  update.setAction(RibUpdate::REGISTER)
+        .setName(name)
+        .setRoute(route);
+  beginRibUpdate(update, done);
+}
+
+void
+RibManager::beginRemoveRoute(const Name& name, const Route& route,
+                             const std::function<void(RibUpdateResult)>& done)
+{
+  NFD_LOG_INFO("Removing route " << name << " nexthop=" << route.faceId <<
+               " origin=" << route.origin);
+
+  RibUpdate update;
+  update.setAction(RibUpdate::UNREGISTER)
+        .setName(name)
+        .setRoute(route);
+  beginRibUpdate(update, done);
+}
+
+void
+RibManager::beginRibUpdate(const RibUpdate& update,
+                           const std::function<void(RibUpdateResult)>& done)
+{
+  m_rib.beginApplyUpdate(update,
+    [=] {
+      NFD_LOG_DEBUG("RIB update succeeded for " << update);
+      done(RibUpdateResult::OK);
+    },
+    [=] (uint32_t code, const std::string& error) {
+      NFD_LOG_DEBUG("RIB update failed for " << update << " (" << code << " " << error << ")");
+
+      // Since the FIB rejected the update, clean up invalid routes
+      scheduleActiveFaceFetch(1_s);
+
+      done(RibUpdateResult::ERROR);
+    });
+}
+
+void
+RibManager::registerTopPrefix(const Name& topPrefix)
+{
+  // add FIB nexthop
+  m_nfdController.start<ndn::nfd::FibAddNextHopCommand>(
+    ControlParameters().setName(Name(topPrefix).append(MGMT_MODULE_NAME))
+                       .setFaceId(0),
+    [=] (const ControlParameters& res) {
+      NFD_LOG_DEBUG("Successfully registered " << topPrefix << " with NFD");
+
+      // Routes must be inserted into the RIB so route flags can be applied
+      Route route;
+      route.faceId = res.getFaceId();
+      route.origin = ndn::nfd::ROUTE_ORIGIN_APP;
+      route.flags = ndn::nfd::ROUTE_FLAG_CHILD_INHERIT;
+
+      m_rib.insert(topPrefix, route);
+
+      m_registeredFaces.insert(route.faceId);
+    },
+    [=] (const ControlResponse& res) {
+      NDN_THROW(Error("Cannot add FIB entry " + topPrefix.toUri() + " (" +
+                      to_string(res.getCode()) + " " + res.getText() + ")"));
+    });
+
+  // add top prefix to the dispatcher without prefix registration
+  m_dispatcher.addTopPrefix(topPrefix, false);
+}
+
+void
+RibManager::registerEntry(const Name& topPrefix, const Interest& interest,
+                          ControlParameters parameters,
+                          const ndn::mgmt::CommandContinuation& done)
+{
+  if (parameters.getName().size() > FIB_MAX_DEPTH) {
+    done(ControlResponse(414, "Route prefix cannot exceed " + ndn::to_string(FIB_MAX_DEPTH) +
+                              " components"));
+    return;
+  }
+
+  setFaceForSelfRegistration(interest, parameters);
+
+  // Respond since command is valid and authorized
+  done(ControlResponse(200, "Success").setBody(parameters.wireEncode()));
+
+  Route route;
+  route.faceId = parameters.getFaceId();
+  route.origin = parameters.getOrigin();
+  route.cost = parameters.getCost();
+  route.flags = parameters.getFlags();
+
+  optional<time::nanoseconds> expires;
+  if (parameters.hasExpirationPeriod() &&
+      parameters.getExpirationPeriod() != time::milliseconds::max()) {
+    expires = time::duration_cast<time::nanoseconds>(parameters.getExpirationPeriod());
+  }
+
+  beginAddRoute(parameters.getName(), std::move(route), expires, [] (RibUpdateResult) {});
+}
+
+void
+RibManager::unregisterEntry(const Name& topPrefix, const Interest& interest,
+                            ControlParameters parameters,
+                            const ndn::mgmt::CommandContinuation& done)
+{
+  setFaceForSelfRegistration(interest, parameters);
+
+  // Respond since command is valid and authorized
+  done(ControlResponse(200, "Success").setBody(parameters.wireEncode()));
+
+  Route route;
+  route.faceId = parameters.getFaceId();
+  route.origin = parameters.getOrigin();
+
+  beginRemoveRoute(parameters.getName(), route, [] (RibUpdateResult) {});
+}
+
+void
+RibManager::listEntries(const Name& topPrefix, const Interest& interest,
+                        ndn::mgmt::StatusDatasetContext& context)
+{
+  auto now = time::steady_clock::now();
+  for (const auto& kv : m_rib) {
+    const RibEntry& entry = *kv.second;
+    ndn::nfd::RibEntry item;
+    item.setName(entry.getName());
+    for (const Route& route : entry.getRoutes()) {
+      ndn::nfd::Route r;
+      r.setFaceId(route.faceId);
+      r.setOrigin(route.origin);
+      r.setCost(route.cost);
+      r.setFlags(route.flags);
+      if (route.expires) {
+        r.setExpirationPeriod(time::duration_cast<time::milliseconds>(*route.expires - now));
+      }
+      item.addRoute(r);
+    }
+    context.append(item.wireEncode());
+  }
+  context.end();
+}
+
+void
+RibManager::setFaceForSelfRegistration(const Interest& request, ControlParameters& parameters)
+{
+  bool isSelfRegistration = (parameters.getFaceId() == 0);
+  if (isSelfRegistration) {
+    shared_ptr<lp::IncomingFaceIdTag> incomingFaceIdTag = request.getTag<lp::IncomingFaceIdTag>();
+    // NDNLPv2 says "application MUST be prepared to receive a packet without IncomingFaceId field",
+    // but it's fine to assert IncomingFaceId is available, because InternalFace lives inside NFD
+    // and is initialized synchronously with IncomingFaceId field enabled.
+    BOOST_ASSERT(incomingFaceIdTag != nullptr);
+    parameters.setFaceId(*incomingFaceIdTag);
+  }
+}
+
+ndn::mgmt::Authorization
+RibManager::makeAuthorization(const std::string& verb)
+{
+  return [this] (const Name& prefix, const Interest& interest,
+                 const ndn::mgmt::ControlParameters* params,
+                 const ndn::mgmt::AcceptContinuation& accept,
+                 const ndn::mgmt::RejectContinuation& reject) {
+    BOOST_ASSERT(params != nullptr);
+    BOOST_ASSERT(typeid(*params) == typeid(ndn::nfd::ControlParameters));
+    BOOST_ASSERT(prefix == LOCALHOST_TOP_PREFIX || prefix == LOCALHOP_TOP_PREFIX);
+
+    ndn::ValidatorConfig& validator = prefix == LOCALHOST_TOP_PREFIX ?
+                                      m_localhostValidator : m_localhopValidator;
+    validator.validate(interest,
+                       bind([&interest, this, accept] { extractRequester(interest, accept); }),
+                       bind([reject] { reject(ndn::mgmt::RejectReply::STATUS403); }));
+  };
+}
+
+std::ostream&
+operator<<(std::ostream& os, RibManager::SlAnnounceResult res)
+{
+  switch (res) {
+    case RibManager::SlAnnounceResult::OK:
+      return os << "OK";
+    case RibManager::SlAnnounceResult::ERROR:
+      return os << "ERROR";
+    case RibManager::SlAnnounceResult::VALIDATION_FAILURE:
+      return os << "VALIDATION_FAILURE";
+    case RibManager::SlAnnounceResult::EXPIRED:
+      return os << "EXPIRED";
+    case RibManager::SlAnnounceResult::NOT_FOUND:
+      return os << "NOT_FOUND";
+  }
+  BOOST_ASSERT_MSG(false, "bad SlAnnounceResult");
+  return os;
+}
+
+RibManager::SlAnnounceResult
+RibManager::getSlAnnounceResultFromRibUpdateResult(RibUpdateResult r)
+{
+  switch (r) {
+  case RibUpdateResult::OK:
+    return SlAnnounceResult::OK;
+  case RibUpdateResult::ERROR:
+    return SlAnnounceResult::ERROR;
+  case RibUpdateResult::EXPIRED:
+    return SlAnnounceResult::EXPIRED;
+  default:
+    BOOST_ASSERT(false);
+    return SlAnnounceResult::ERROR;
+  }
+}
+
+void
+RibManager::slAnnounce(const ndn::PrefixAnnouncement& pa, uint64_t faceId,
+                       time::milliseconds maxLifetime, const SlAnnounceCallback& cb)
+{
+  BOOST_ASSERT(pa.getData());
+
+  if (!m_isLocalhopEnabled) {
+    NFD_LOG_INFO("slAnnounce " << pa.getAnnouncedName() << " " << faceId <<
+                 ": localhop_security unconfigured");
+    cb(SlAnnounceResult::VALIDATION_FAILURE);
+    return;
+  }
+
+  m_localhopValidator.validate(*pa.getData(),
+    [=] (const Data&) {
+      Route route(pa, faceId);
+      route.expires = std::min(route.annExpires, time::steady_clock::now() + maxLifetime);
+      beginAddRoute(pa.getAnnouncedName(), route, nullopt,
+        [=] (RibUpdateResult ribRes) {
+          auto res = getSlAnnounceResultFromRibUpdateResult(ribRes);
+          NFD_LOG_INFO("slAnnounce " << pa.getAnnouncedName() << " " << faceId << ": " << res);
+          cb(res);
+        });
+    },
+    [=] (const Data&, ndn::security::v2::ValidationError err) {
+      NFD_LOG_INFO("slAnnounce " << pa.getAnnouncedName() << " " << faceId <<
+                   " validation error: " << err);
+      cb(SlAnnounceResult::VALIDATION_FAILURE);
+    }
+  );
+}
+
+void
+RibManager::slRenew(const Name& name, uint64_t faceId, time::milliseconds maxLifetime,
+                    const SlAnnounceCallback& cb)
+{
+  Route routeQuery;
+  routeQuery.faceId = faceId;
+  routeQuery.origin = ndn::nfd::ROUTE_ORIGIN_PREFIXANN;
+  Route* oldRoute = m_rib.findLongestPrefix(name, routeQuery);
+
+  if (oldRoute == nullptr || !oldRoute->announcement) {
+    NFD_LOG_DEBUG("slRenew " << name << " " << faceId << ": not found");
+    return cb(SlAnnounceResult::NOT_FOUND);
+  }
+  Name routeName = oldRoute->announcement->getAnnouncedName();
+
+  Route route = *oldRoute;
+  route.expires = std::min(route.annExpires, time::steady_clock::now() + maxLifetime);
+  beginAddRoute(routeName, route, nullopt,
+    [=] (RibUpdateResult ribRes) {
+      auto res = getSlAnnounceResultFromRibUpdateResult(ribRes);
+      NFD_LOG_INFO("slRenew " << name << " " << faceId << ": " << res << " " << routeName);
+      cb(res);
+    });
+}
+
+void
+RibManager::slFindAnn(const Name& name, const SlFindAnnCallback& cb) const
+{
+  shared_ptr<RibEntry> entry;
+  auto exactMatch = m_rib.find(name);
+  if (exactMatch != m_rib.end()) {
+    entry = exactMatch->second;
+  }
+  else {
+    entry = m_rib.findParent(name);
+  }
+  if (entry == nullptr) {
+    return cb(nullopt);
+  }
+
+  auto pa = entry->getPrefixAnnouncement();
+  pa.toData(m_keyChain);
+  cb(pa);
+}
+
+void
+RibManager::fetchActiveFaces()
+{
+  NFD_LOG_DEBUG("Fetching active faces");
+
+  m_nfdController.fetch<ndn::nfd::FaceDataset>(
+    bind(&RibManager::removeInvalidFaces, this, _1),
+    bind(&RibManager::onFetchActiveFacesFailure, this, _1, _2),
+    ndn::nfd::CommandOptions());
+}
+
+void
+RibManager::onFetchActiveFacesFailure(uint32_t code, const std::string& reason)
+{
+  NFD_LOG_DEBUG("Face Status Dataset request failure " << code << " " << reason);
+  scheduleActiveFaceFetch(ACTIVE_FACE_FETCH_INTERVAL);
+}
+
+void
+RibManager::onFaceDestroyedEvent(uint64_t faceId)
+{
+  m_rib.beginRemoveFace(faceId);
+  m_registeredFaces.erase(faceId);
+}
+
+void
+RibManager::scheduleActiveFaceFetch(const time::seconds& timeToWait)
+{
+  m_activeFaceFetchEvent = m_scheduler.scheduleEvent(timeToWait, [this] { fetchActiveFaces(); });
+}
+
+void
+RibManager::removeInvalidFaces(const std::vector<ndn::nfd::FaceStatus>& activeFaces)
+{
+  NFD_LOG_DEBUG("Checking for invalid face registrations");
+
+  FaceIdSet activeFaceIds;
+  for (const auto& faceStatus : activeFaces) {
+    activeFaceIds.insert(faceStatus.getFaceId());
+  }
+
+  // Look for face IDs that were registered but not active to find missed
+  // face destroyed events
+  for (auto faceId : m_registeredFaces) {
+    if (activeFaceIds.count(faceId) == 0) {
+      NFD_LOG_DEBUG("Removing invalid face ID: " << faceId);
+      m_scheduler.scheduleEvent(0_ns, [this, faceId] { this->onFaceDestroyedEvent(faceId); });
+    }
+  }
+
+  // Reschedule the check for future clean up
+  scheduleActiveFaceFetch(ACTIVE_FACE_FETCH_INTERVAL);
+}
+
+void
+RibManager::onNotification(const ndn::nfd::FaceEventNotification& notification)
+{
+  NFD_LOG_TRACE("onNotification: " << notification);
+
+  if (notification.getKind() == ndn::nfd::FACE_EVENT_DESTROYED) {
+    NFD_LOG_DEBUG("Received notification for destroyed faceId: " << notification.getFaceId());
+    m_scheduler.scheduleEvent(0_ns, [this, id = notification.getFaceId()] { onFaceDestroyedEvent(id); });
+  }
+}
+
+} // namespace rib
+} // namespace nfd
diff --git a/daemon/rib/rib-manager.hpp b/daemon/rib/rib-manager.hpp
new file mode 100644
index 0000000..503dc2f
--- /dev/null
+++ b/daemon/rib/rib-manager.hpp
@@ -0,0 +1,268 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_DAEMON_RIB_RIB_MANAGER_HPP
+#define NFD_DAEMON_RIB_RIB_MANAGER_HPP
+
+#include "fib-updater.hpp"
+#include "rib.hpp"
+
+#include "core/config-file.hpp"
+#include "core/manager-base.hpp"
+
+#include <ndn-cxx/security/validator-config.hpp>
+#include <ndn-cxx/mgmt/nfd/controller.hpp>
+#include <ndn-cxx/mgmt/nfd/face-event-notification.hpp>
+#include <ndn-cxx/mgmt/nfd/face-monitor.hpp>
+#include <ndn-cxx/util/scheduler.hpp>
+
+namespace nfd {
+namespace rib {
+
+/**
+ * @brief Serve commands and datasets in NFD RIB management protocol.
+ */
+class RibManager : public nfd::ManagerBase
+{
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    using std::runtime_error::runtime_error;
+  };
+
+  RibManager(Rib& rib, ndn::Face& face, ndn::KeyChain& keyChain, ndn::nfd::Controller& nfdController,
+             Dispatcher& dispatcher, ndn::util::Scheduler& scheduler);
+
+  /**
+   * @brief Apply localhost_security configuration.
+   */
+  void
+  applyLocalhostConfig(const ConfigSection& section, const std::string& filename);
+
+  /**
+   * @brief Apply localhop_security configuration and allow accepting commands on
+   *        /localhop/nfd/rib prefix.
+   */
+  void
+  enableLocalhop(const ConfigSection& section, const std::string& filename);
+
+  /**
+   * @brief Disallow accepting commands on /localhop/nfd/rib prefix.
+   */
+  void
+  disableLocalhop();
+
+  /**
+   * @brief Start accepting commands and dataset requests.
+   */
+  void
+  registerWithNfd();
+
+  /**
+   * @brief Enable NDNLP IncomingFaceId field in order to support self-registration commands.
+   */
+  void
+  enableLocalFields();
+
+public: // self-learning support
+  enum class SlAnnounceResult {
+    OK,                 ///< RIB and FIB have been updated
+    ERROR,              ///< unspecified error
+    VALIDATION_FAILURE, ///< the announcement cannot be verified against the trust schema
+    EXPIRED,            ///< the announcement has expired
+    NOT_FOUND,          ///< route does not exist (slRenew only)
+  };
+
+  using SlAnnounceCallback = std::function<void(SlAnnounceResult res)>;
+  using SlFindAnnCallback = std::function<void(optional<ndn::PrefixAnnouncement>)>;
+
+  /** \brief Insert a route by prefix announcement from self-learning strategy.
+   *  \param pa A prefix announcement. It must contain the Data.
+   *  \param faceId Face on which the announcement arrives.
+   *  \param maxLifetime Maximum route lifetime as imposed by self-learning strategy.
+   *  \param cb Callback to receive the operation result.
+   *
+   *  If \p pa passes validation and is unexpired, inserts or replaces a route for the announced
+   *  name and faceId whose lifetime is set to the earlier of now+maxLifetime or prefix
+   *  announcement expiration time, updates FIB, and invokes \p cb with SlAnnounceResult::OK.
+   *  In case \p pa expires when validation completes, invokes \p cb with SlAnnounceResult::EXPIRED.
+   *  If \p pa cannot be verified by the trust schema given in rib.localhop_security config key,
+   *  or the relevant config has not been loaded via \c enableLocalHop, invokes \p cb with
+   *  SlAnnounceResult::VALIDATION_FAILURE.
+   *
+   *  Self-learning strategy invokes this method after receiving a Data carrying a prefix
+   *  announcement.
+   */
+  void
+  slAnnounce(const ndn::PrefixAnnouncement& pa, uint64_t faceId, time::milliseconds maxLifetime,
+             const SlAnnounceCallback& cb);
+
+  /** \brief Renew a route created by prefix announcement from self-learning strategy.
+   *  \param name Data name, for finding RIB entry by longest-prefix-match.
+   *  \param faceId Nexthop face.
+   *  \param maxLifetime Maximum route lifetime as imposed by self-learning strategy.
+   *  \param cb Callback to receive the operation result.
+   *
+   *  If the specified route exists, prolongs its lifetime to the earlier of now+maxLifetime or
+   *  prefix announcement expiration time, and invokes \p cb with SlAnnounceResult::OK.
+   *  If the prefix announcement has expired, invokes \p cb with SlAnnounceResult::EXPIRED.
+   *  If the route is not found, invokes \p cb with SlAnnounceResult::NOT_FOUND.
+   *
+   *  Self-learning strategy invokes this method after an Interest forwarded via a learned route
+   *  is satisfied.
+   *
+   *  \bug In current implementation, if an slAnnounce operation is in progress to create a Route
+   *       or replace a prefix announcement, slRenew could fail because Route does not exist in
+   *       existing RIB, or overwrite the new prefix announcement with an old one.
+   */
+  void
+  slRenew(const Name& name, uint64_t faceId, time::milliseconds maxLifetime,
+          const SlAnnounceCallback& cb);
+
+  /** \brief Retrieve an outgoing prefix announcement for self-learning strategy.
+   *  \param name Data name.
+   *  \param cb Callback to receive a prefix announcement that announces a prefix of \p name, or
+   *            nullopt if no RIB entry is found by longest-prefix-match of \p name.
+   *
+   *  Self-learning strategy invokes this method before sending a Data in reply to a discovery
+   *  Interest, so as to attach a prefix announcement onto that Data.
+   *
+   *  \bug In current implementation, if an slAnnounce operation is in progress, slFindAnn does not
+   *       wait for that operation to complete and its result reflects the prior RIB state.
+   */
+  void
+  slFindAnn(const Name& name, const SlFindAnnCallback& cb) const;
+
+private: // RIB and FibUpdater actions
+  enum class RibUpdateResult
+  {
+    OK,
+    ERROR,
+    EXPIRED,
+  };
+
+  static SlAnnounceResult
+  getSlAnnounceResultFromRibUpdateResult(RibUpdateResult r);
+
+  /** \brief Start adding a route to RIB and FIB.
+   *  \param name route name
+   *  \param route route parameters; may contain absolute expiration time
+   *  \param expires relative expiration time; if specified, overwrites \c route.expires
+   *  \param done completion callback
+   */
+  void
+  beginAddRoute(const Name& name, Route route, optional<time::nanoseconds> expires,
+                const std::function<void(RibUpdateResult)>& done);
+
+  /** \brief Start removing a route from RIB and FIB.
+   *  \param name route name
+   *  \param route route parameters
+   *  \param done completion callback
+   */
+  void
+  beginRemoveRoute(const Name& name, const Route& route,
+                   const std::function<void(RibUpdateResult)>& done);
+
+  void
+  beginRibUpdate(const RibUpdate& update, const std::function<void(RibUpdateResult)>& done);
+
+private: // management Dispatcher related
+  void
+  registerTopPrefix(const Name& topPrefix);
+
+  /** \brief Serve rib/register command.
+   */
+  void
+  registerEntry(const Name& topPrefix, const Interest& interest,
+                ControlParameters parameters,
+                const ndn::mgmt::CommandContinuation& done);
+
+  /** \brief Serve rib/unregister command.
+   */
+  void
+  unregisterEntry(const Name& topPrefix, const Interest& interest,
+                  ControlParameters parameters,
+                  const ndn::mgmt::CommandContinuation& done);
+
+  /** \brief Serve rib/list dataset.
+   */
+  void
+  listEntries(const Name& topPrefix, const Interest& interest,
+              ndn::mgmt::StatusDatasetContext& context);
+
+  void
+  setFaceForSelfRegistration(const Interest& request, ControlParameters& parameters);
+
+  ndn::mgmt::Authorization
+  makeAuthorization(const std::string& verb) override;
+
+private: // Face monitor
+  void
+  fetchActiveFaces();
+
+  void
+  onFetchActiveFacesFailure(uint32_t code, const std::string& reason);
+
+  void
+  onFaceDestroyedEvent(uint64_t faceId);
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  void
+  scheduleActiveFaceFetch(const time::seconds& timeToWait);
+
+  void
+  removeInvalidFaces(const std::vector<ndn::nfd::FaceStatus>& activeFaces);
+
+  void
+  onNotification(const ndn::nfd::FaceEventNotification& notification);
+
+public:
+  static const Name LOCALHOP_TOP_PREFIX;
+
+private:
+  Rib& m_rib;
+  ndn::KeyChain& m_keyChain;
+  ndn::nfd::Controller& m_nfdController;
+  Dispatcher& m_dispatcher;
+  ndn::util::Scheduler& m_scheduler;
+
+  ndn::nfd::FaceMonitor m_faceMonitor;
+  ndn::ValidatorConfig m_localhostValidator;
+  ndn::ValidatorConfig m_localhopValidator;
+  bool m_isLocalhopEnabled;
+
+  ndn::util::scheduler::ScopedEventId m_activeFaceFetchEvent;
+  using FaceIdSet = std::set<uint64_t>;
+  FaceIdSet m_registeredFaces; ///< contains FaceIds with one or more Routes in the RIB
+};
+
+std::ostream&
+operator<<(std::ostream& os, RibManager::SlAnnounceResult res);
+
+} // namespace rib
+} // namespace nfd
+
+#endif // NFD_DAEMON_RIB_RIB_MANAGER_HPP
diff --git a/daemon/rib/rib-update-batch.cpp b/daemon/rib/rib-update-batch.cpp
new file mode 100644
index 0000000..e639ae3
--- /dev/null
+++ b/daemon/rib/rib-update-batch.cpp
@@ -0,0 +1,63 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "rib-update-batch.hpp"
+
+namespace nfd {
+namespace rib {
+
+RibUpdateBatch::RibUpdateBatch(uint64_t faceId)
+  : m_faceId(faceId)
+{
+}
+
+void
+RibUpdateBatch::add(const RibUpdate& update)
+{
+  BOOST_ASSERT(m_faceId == update.getRoute().faceId);
+
+  m_updates.push_back(update);
+}
+
+RibUpdateBatch::const_iterator
+RibUpdateBatch::begin() const
+{
+  return m_updates.begin();
+}
+
+RibUpdateBatch::const_iterator
+RibUpdateBatch::end() const
+{
+  return m_updates.end();
+}
+
+size_t
+RibUpdateBatch::size() const
+{
+  return m_updates.size();
+}
+
+} // namespace rib
+} // namespace nfd
diff --git a/daemon/rib/rib-update-batch.hpp b/daemon/rib/rib-update-batch.hpp
new file mode 100644
index 0000000..f72a9e8
--- /dev/null
+++ b/daemon/rib/rib-update-batch.hpp
@@ -0,0 +1,77 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_DAEMON_RIB_RIB_UPDATE_BATCH_HPP
+#define NFD_DAEMON_RIB_RIB_UPDATE_BATCH_HPP
+
+#include "rib-update.hpp"
+
+#include <list>
+
+namespace nfd {
+namespace rib {
+
+typedef std::list<RibUpdate> RibUpdateList;
+
+/** \brief Represents a collection of RibUpdates to be applied to a single FaceId.
+ */
+class RibUpdateBatch
+{
+public:
+  typedef RibUpdateList::const_iterator const_iterator;
+
+  explicit
+  RibUpdateBatch(uint64_t faceId);
+
+  uint64_t
+  getFaceId() const;
+
+  void
+  add(const RibUpdate& update);
+
+  const_iterator
+  begin() const;
+
+  const_iterator
+  end() const;
+
+  size_t
+  size() const;
+
+private:
+  uint64_t m_faceId;
+  RibUpdateList m_updates;
+};
+
+inline uint64_t
+RibUpdateBatch::getFaceId() const
+{
+  return m_faceId;
+}
+
+} // namespace rib
+} // namespace nfd
+
+#endif // NFD_DAEMON_RIB_RIB_UPDATE_BATCH_HPP
diff --git a/daemon/rib/rib-update.cpp b/daemon/rib/rib-update.cpp
new file mode 100644
index 0000000..8efe327
--- /dev/null
+++ b/daemon/rib/rib-update.cpp
@@ -0,0 +1,68 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "rib-update.hpp"
+
+namespace nfd {
+namespace rib {
+
+RibUpdate::RibUpdate()
+{
+
+}
+
+std::ostream&
+operator<<(std::ostream& os, const RibUpdate::Action action)
+{
+  switch (action) {
+  case RibUpdate::REGISTER:
+    os << "REGISTER";
+    break;
+  case RibUpdate::UNREGISTER:
+    os << "UNREGISTER";
+    break;
+  case RibUpdate::REMOVE_FACE:
+    os << "REMOVE_FACE";
+    break;
+  }
+
+  return os;
+}
+
+std::ostream&
+operator<<(std::ostream& os, const RibUpdate& update)
+{
+  os << "RibUpdate {\n";
+  os << "  Name: " << update.getName() << "\n";
+  os << "  Action: " << update.getAction() << "\n";
+  os << "  " << update.getRoute() << "\n";
+  os << "}";
+
+  return os;
+}
+
+
+} // namespace rib
+} // namespace nfd
diff --git a/daemon/rib/rib-update.hpp b/daemon/rib/rib-update.hpp
new file mode 100644
index 0000000..ad5a390
--- /dev/null
+++ b/daemon/rib/rib-update.hpp
@@ -0,0 +1,128 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_DAEMON_RIB_RIB_UPDATE_HPP
+#define NFD_DAEMON_RIB_RIB_UPDATE_HPP
+
+#include "core/common.hpp"
+#include "route.hpp"
+
+namespace nfd {
+namespace rib {
+
+/** RibUpdate
+ *  \brief represents a route that will be added to or removed from a namespace
+ *
+ *  \note This type is copyable so that it can be stored in STL containers.
+ */
+class RibUpdate
+{
+public:
+  enum Action {
+    REGISTER     = 0,
+    UNREGISTER   = 1,
+
+    /** \brief An update triggered by a face destruction notification
+     *
+     *  \note indicates a Route needs to be removed after a face is destroyed
+     */
+    REMOVE_FACE = 2
+  };
+
+  RibUpdate();
+
+  RibUpdate&
+  setAction(Action action);
+
+  Action
+  getAction() const;
+
+  RibUpdate&
+  setName(const Name& name);
+
+  const Name&
+  getName() const;
+
+  RibUpdate&
+  setRoute(const Route& route);
+
+  const Route&
+  getRoute() const;
+
+private:
+  Action m_action;
+  Name m_name;
+  Route m_route;
+};
+
+inline RibUpdate&
+RibUpdate::setAction(Action action)
+{
+  m_action = action;
+  return *this;
+}
+
+inline RibUpdate::Action
+RibUpdate::getAction() const
+{
+  return m_action;
+}
+
+inline RibUpdate&
+RibUpdate::setName(const Name& name)
+{
+  m_name = name;
+  return *this;
+}
+
+inline const Name&
+RibUpdate::getName() const
+{
+  return m_name;
+}
+
+inline RibUpdate&
+RibUpdate::setRoute(const Route& route)
+{
+  m_route = route;
+  return *this;
+}
+
+inline const Route&
+RibUpdate::getRoute() const
+{
+  return m_route;
+}
+
+std::ostream&
+operator<<(std::ostream& os, const RibUpdate::Action action);
+
+std::ostream&
+operator<<(std::ostream& os, const RibUpdate& update);
+
+} // namespace rib
+} // namespace nfd
+
+#endif // NFD_DAEMON_RIB_RIB_UPDATE_HPP
diff --git a/daemon/rib/rib.cpp b/daemon/rib/rib.cpp
new file mode 100644
index 0000000..bbd72f1
--- /dev/null
+++ b/daemon/rib/rib.cpp
@@ -0,0 +1,528 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "rib.hpp"
+#include "fib-updater.hpp"
+#include "core/logger.hpp"
+
+namespace nfd {
+namespace rib {
+
+NFD_LOG_INIT(Rib);
+
+bool
+operator<(const RibRouteRef& lhs, const RibRouteRef& rhs)
+{
+  return std::tie(lhs.entry->getName(), lhs.route->faceId, lhs.route->origin) <
+         std::tie(rhs.entry->getName(), rhs.route->faceId, rhs.route->origin);
+}
+
+static inline bool
+sortRoutes(const Route& lhs, const Route& rhs)
+{
+  return lhs.faceId < rhs.faceId;
+}
+
+Rib::Rib()
+  : m_nItems(0)
+  , m_isUpdateInProgress(false)
+{
+}
+
+void
+Rib::setFibUpdater(FibUpdater* updater)
+{
+  m_fibUpdater = updater;
+}
+
+Rib::const_iterator
+Rib::find(const Name& prefix) const
+{
+  return m_rib.find(prefix);
+}
+
+Route*
+Rib::find(const Name& prefix, const Route& route) const
+{
+  auto ribIt = m_rib.find(prefix);
+
+  // Name prefix exists
+  if (ribIt != m_rib.end()) {
+    shared_ptr<RibEntry> entry = ribIt->second;
+    auto routeIt = entry->findRoute(route);
+    if (routeIt != entry->end()) {
+      return &*routeIt;
+    }
+  }
+
+  return nullptr;
+}
+
+Route*
+Rib::findLongestPrefix(const Name& prefix, const Route& route) const
+{
+  Route* existingRoute = find(prefix, route);
+  if (existingRoute == nullptr) {
+    auto parent = findParent(prefix);
+    if (parent) {
+      existingRoute = find(parent->getName(), route);
+    }
+  }
+
+  return existingRoute;
+}
+
+void
+Rib::insert(const Name& prefix, const Route& route)
+{
+  auto ribIt = m_rib.find(prefix);
+
+  // Name prefix exists
+  if (ribIt != m_rib.end()) {
+    shared_ptr<RibEntry> entry(ribIt->second);
+
+    RibEntry::iterator entryIt;
+    bool didInsert = false;
+    std::tie(entryIt, didInsert) = entry->insertRoute(route);
+
+    if (didInsert) {
+      // The route was new and we successfully inserted it.
+      m_nItems++;
+
+      afterAddRoute(RibRouteRef{entry, entryIt});
+
+      // Register with face lookup table
+      m_faceMap[route.faceId].push_back(entry);
+    }
+    else {
+      // Route exists, update fields
+      // First cancel old scheduled event, if any, then set the EventId to new one
+      if (entryIt->getExpirationEvent()) {
+        NFD_LOG_TRACE("Cancelling expiration event for " << entry->getName() << " " << *entryIt);
+        entryIt->cancelExpirationEvent();
+      }
+
+      *entryIt = route;
+    }
+  }
+  else {
+    // New name prefix
+    auto entry = make_shared<RibEntry>();
+
+    m_rib[prefix] = entry;
+    m_nItems++;
+
+    entry->setName(prefix);
+    auto routeIt = entry->insertRoute(route).first;
+
+    // Find prefix's parent
+    shared_ptr<RibEntry> parent = findParent(prefix);
+
+    // Add self to parent's children
+    if (parent != nullptr) {
+      parent->addChild(entry);
+    }
+
+    RibEntryList children = findDescendants(prefix);
+
+    for (const auto& child : children) {
+      if (child->getParent() == parent) {
+        // Remove child from parent and inherit parent's child
+        if (parent != nullptr) {
+          parent->removeChild(child);
+        }
+
+        entry->addChild(child);
+      }
+    }
+
+    // Register with face lookup table
+    m_faceMap[route.faceId].push_back(entry);
+
+    // do something after inserting an entry
+    afterInsertEntry(prefix);
+    afterAddRoute(RibRouteRef{entry, routeIt});
+  }
+}
+
+void
+Rib::erase(const Name& prefix, const Route& route)
+{
+  auto ribIt = m_rib.find(prefix);
+
+  // Name prefix exists
+  if (ribIt != m_rib.end()) {
+    shared_ptr<RibEntry> entry = ribIt->second;
+    auto routeIt = entry->findRoute(route);
+
+    if (routeIt != entry->end()) {
+      beforeRemoveRoute(RibRouteRef{entry, routeIt});
+
+      auto faceId = route.faceId;
+      entry->eraseRoute(routeIt);
+      m_nItems--;
+
+      // If this RibEntry no longer has this faceId, unregister from face lookup table
+      if (!entry->hasFaceId(faceId)) {
+        m_faceMap[faceId].remove(entry);
+      }
+
+      // If a RibEntry's route list is empty, remove it from the tree
+      if (entry->getRoutes().empty()) {
+        eraseEntry(ribIt);
+      }
+    }
+  }
+}
+
+void
+Rib::onRouteExpiration(const Name& prefix, const Route& route)
+{
+  NFD_LOG_DEBUG(route << " for " << prefix << " has expired");
+
+  RibUpdate update;
+  update.setAction(RibUpdate::UNREGISTER)
+        .setName(prefix)
+        .setRoute(route);
+
+  beginApplyUpdate(update, nullptr, nullptr);
+}
+
+shared_ptr<RibEntry>
+Rib::findParent(const Name& prefix) const
+{
+  for (int i = prefix.size() - 1; i >= 0; i--) {
+    auto it = m_rib.find(prefix.getPrefix(i));
+    if (it != m_rib.end()) {
+      return it->second;
+    }
+  }
+
+  return nullptr;
+}
+
+std::list<shared_ptr<RibEntry>>
+Rib::findDescendants(const Name& prefix) const
+{
+  std::list<shared_ptr<RibEntry>> children;
+
+  RibTable::const_iterator it = m_rib.find(prefix);
+  if (it != m_rib.end()) {
+    ++it;
+    for (; it != m_rib.end(); ++it) {
+      if (prefix.isPrefixOf(it->first)) {
+        children.push_back((it->second));
+      }
+      else {
+        break;
+      }
+    }
+  }
+
+  return children;
+}
+
+std::list<shared_ptr<RibEntry>>
+Rib::findDescendantsForNonInsertedName(const Name& prefix) const
+{
+  std::list<shared_ptr<RibEntry>> children;
+
+  for (const auto& pair : m_rib) {
+    if (prefix.isPrefixOf(pair.first)) {
+      children.push_back(pair.second);
+    }
+  }
+
+  return children;
+}
+
+Rib::RibTable::iterator
+Rib::eraseEntry(RibTable::iterator it)
+{
+  // Entry does not exist
+  if (it == m_rib.end()) {
+    return m_rib.end();
+  }
+
+  shared_ptr<RibEntry> entry(it->second);
+
+  shared_ptr<RibEntry> parent = entry->getParent();
+
+  // Remove self from parent's children
+  if (parent != nullptr) {
+    parent->removeChild(entry);
+  }
+
+  for (auto childIt = entry->getChildren().begin(); childIt != entry->getChildren().end(); ) {
+    shared_ptr<RibEntry> child = *childIt;
+
+    // Advance iterator so it is not invalidated by removal
+    ++childIt;
+
+    // Remove children from self
+    entry->removeChild(child);
+
+    // Update parent's children
+    if (parent != nullptr) {
+      parent->addChild(child);
+    }
+  }
+
+  auto nextIt = m_rib.erase(it);
+
+  // do something after erasing an entry.
+  afterEraseEntry(entry->getName());
+
+  return nextIt;
+}
+
+Rib::RouteSet
+Rib::getAncestorRoutes(const RibEntry& entry) const
+{
+  RouteSet ancestorRoutes(&sortRoutes);
+
+  shared_ptr<RibEntry> parent = entry.getParent();
+
+  while (parent != nullptr) {
+    for (const Route& route : parent->getRoutes()) {
+      if (route.isChildInherit()) {
+        ancestorRoutes.insert(route);
+      }
+    }
+
+    if (parent->hasCapture()) {
+      break;
+    }
+
+    parent = parent->getParent();
+  }
+
+  return ancestorRoutes;
+}
+
+Rib::RouteSet
+Rib::getAncestorRoutes(const Name& name) const
+{
+  RouteSet ancestorRoutes(&sortRoutes);
+
+  shared_ptr<RibEntry> parent = findParent(name);
+
+  while (parent != nullptr) {
+    for (const Route& route : parent->getRoutes()) {
+      if (route.isChildInherit()) {
+        ancestorRoutes.insert(route);
+      }
+    }
+
+    if (parent->hasCapture()) {
+      break;
+    }
+
+    parent = parent->getParent();
+  }
+
+  return ancestorRoutes;
+}
+
+void
+Rib::beginApplyUpdate(const RibUpdate& update,
+                      const Rib::UpdateSuccessCallback& onSuccess,
+                      const Rib::UpdateFailureCallback& onFailure)
+{
+  BOOST_ASSERT(m_fibUpdater != nullptr);
+
+  addUpdateToQueue(update, onSuccess, onFailure);
+
+  sendBatchFromQueue();
+}
+
+void
+Rib::beginRemoveFace(uint64_t faceId)
+{
+  for (const auto& nameAndRoute : findRoutesWithFaceId(faceId)) {
+    RibUpdate update;
+    update.setAction(RibUpdate::REMOVE_FACE)
+          .setName(nameAndRoute.first)
+          .setRoute(nameAndRoute.second);
+
+    addUpdateToQueue(update, nullptr, nullptr);
+  }
+
+  sendBatchFromQueue();
+}
+
+void
+Rib::addUpdateToQueue(const RibUpdate& update,
+                      const Rib::UpdateSuccessCallback& onSuccess,
+                      const Rib::UpdateFailureCallback& onFailure)
+{
+  RibUpdateBatch batch(update.getRoute().faceId);
+  batch.add(update);
+
+  UpdateQueueItem item{batch, onSuccess, onFailure};
+  m_updateBatches.push_back(std::move(item));
+}
+
+void
+Rib::sendBatchFromQueue()
+{
+  if (m_updateBatches.empty() || m_isUpdateInProgress) {
+    return;
+  }
+
+  m_isUpdateInProgress = true;
+
+  UpdateQueueItem item = std::move(m_updateBatches.front());
+  m_updateBatches.pop_front();
+
+  RibUpdateBatch& batch = item.batch;
+
+  // Until task #1698, each RibUpdateBatch contains exactly one RIB update
+  BOOST_ASSERT(batch.size() == 1);
+
+  auto fibSuccessCb = bind(&Rib::onFibUpdateSuccess, this, batch, _1, item.managerSuccessCallback);
+  auto fibFailureCb = bind(&Rib::onFibUpdateFailure, this, item.managerFailureCallback, _1, _2);
+
+#ifdef WITH_TESTS
+  if (mockFibResponse != nullptr) {
+    m_fibUpdater->computeAndSendFibUpdates(batch, bind([]{}), bind([]{}));
+    bool shouldFibSucceed = mockFibResponse(batch);
+    if (wantMockFibResponseOnce) {
+      mockFibResponse = nullptr;
+    }
+    if (shouldFibSucceed) {
+      fibSuccessCb(m_fibUpdater->m_inheritedRoutes);
+    }
+    else {
+      fibFailureCb(504, "mocked failure");
+    }
+    return;
+  }
+#endif
+
+  m_fibUpdater->computeAndSendFibUpdates(batch, fibSuccessCb, fibFailureCb);
+}
+
+void
+Rib::onFibUpdateSuccess(const RibUpdateBatch& batch,
+                        const RibUpdateList& inheritedRoutes,
+                        const Rib::UpdateSuccessCallback& onSuccess)
+{
+  for (const RibUpdate& update : batch) {
+    switch (update.getAction()) {
+    case RibUpdate::REGISTER:
+      insert(update.getName(), update.getRoute());
+      break;
+    case RibUpdate::UNREGISTER:
+    case RibUpdate::REMOVE_FACE:
+      erase(update.getName(), update.getRoute());
+      break;
+    }
+  }
+
+  // Add and remove precalculated inherited routes to RibEntries
+  modifyInheritedRoutes(inheritedRoutes);
+
+  m_isUpdateInProgress = false;
+
+  if (onSuccess != nullptr) {
+    onSuccess();
+  }
+
+  // Try to advance the batch queue
+  sendBatchFromQueue();
+}
+
+void
+Rib::onFibUpdateFailure(const Rib::UpdateFailureCallback& onFailure,
+                        uint32_t code, const std::string& error)
+{
+  m_isUpdateInProgress = false;
+
+  if (onFailure != nullptr) {
+    onFailure(code, error);
+  }
+
+  // Try to advance the batch queue
+  sendBatchFromQueue();
+}
+
+void
+Rib::modifyInheritedRoutes(const RibUpdateList& inheritedRoutes)
+{
+  for (const RibUpdate& update : inheritedRoutes) {
+    auto ribIt = m_rib.find(update.getName());
+    BOOST_ASSERT(ribIt != m_rib.end());
+    shared_ptr<RibEntry> entry(ribIt->second);
+
+    switch (update.getAction()) {
+    case RibUpdate::REGISTER:
+      entry->addInheritedRoute(update.getRoute());
+      break;
+    case RibUpdate::UNREGISTER:
+      entry->removeInheritedRoute(update.getRoute());
+      break;
+    case RibUpdate::REMOVE_FACE:
+      break;
+    }
+  }
+}
+
+std::list<Rib::NameAndRoute>
+Rib::findRoutesWithFaceId(uint64_t faceId)
+{
+  std::list<NameAndRoute> routes;
+
+  auto lookupIt = m_faceMap.find(faceId);
+  if (lookupIt == m_faceMap.end()) {
+    // No RIB entries have this face
+    return routes;
+  }
+
+  // For each RIB entry that has faceId
+  for (const auto& entry : lookupIt->second) {
+    // Find the routes in the entry
+    for (const Route& route : *entry) {
+      if (route.faceId == faceId) {
+        routes.emplace_back(entry->getName(), route);
+      }
+    }
+  }
+
+  return routes;
+}
+
+std::ostream&
+operator<<(std::ostream& os, const Rib& rib)
+{
+  for (const auto& item : rib) {
+    os << *item.second << "\n";
+  }
+
+  return os;
+}
+
+} // namespace rib
+} // namespace nfd
diff --git a/daemon/rib/rib.hpp b/daemon/rib/rib.hpp
new file mode 100644
index 0000000..ea848f8
--- /dev/null
+++ b/daemon/rib/rib.hpp
@@ -0,0 +1,307 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_DAEMON_RIB_RIB_HPP
+#define NFD_DAEMON_RIB_RIB_HPP
+
+#include "rib-entry.hpp"
+#include "rib-update-batch.hpp"
+
+#include <ndn-cxx/mgmt/nfd/control-parameters.hpp>
+
+namespace nfd {
+namespace rib {
+
+using ndn::nfd::ControlParameters;
+
+class FibUpdater;
+
+/** \brief references a route
+ */
+struct RibRouteRef
+{
+  shared_ptr<RibEntry> entry;
+  RibEntry::const_iterator route;
+};
+
+bool
+operator<(const RibRouteRef& lhs, const RibRouteRef& rhs);
+
+/** \brief represents the Routing Information Base
+
+    The Routing Information Base contains a collection of Routes, each
+    represents a piece of static or dynamic routing information
+    registered by applications, operators, or NFD itself. Routes
+    associated with the same namespace are collected into a RIB entry.
+ */
+class Rib : noncopyable
+{
+public:
+  typedef std::list<shared_ptr<RibEntry>> RibEntryList;
+  typedef std::map<Name, shared_ptr<RibEntry>> RibTable;
+  typedef RibTable::const_iterator const_iterator;
+  typedef std::map<uint64_t, std::list<shared_ptr<RibEntry>>> FaceLookupTable;
+  typedef bool (*RouteComparePredicate)(const Route&, const Route&);
+  typedef std::set<Route, RouteComparePredicate> RouteSet;
+
+  Rib();
+
+  void
+  setFibUpdater(FibUpdater* updater);
+
+  const_iterator
+  find(const Name& prefix) const;
+
+  Route*
+  find(const Name& prefix, const Route& route) const;
+
+  Route*
+  findLongestPrefix(const Name& prefix, const Route& route) const;
+
+  const_iterator
+  begin() const;
+
+  const_iterator
+  end() const;
+
+  size_t
+  size() const;
+
+  bool
+  empty() const;
+
+  shared_ptr<RibEntry>
+  findParent(const Name& prefix) const;
+
+  /** \brief finds namespaces under the passed prefix
+   *  \return{ a list of entries which are under the passed prefix }
+   */
+  std::list<shared_ptr<RibEntry>>
+  findDescendants(const Name& prefix) const;
+
+  /** \brief finds namespaces under the passed prefix
+   *
+   *  \note Unlike findDescendants, needs to find where prefix would fit in tree
+   *  before collecting list of descendant prefixes
+   *
+   *  \return{ a list of entries which would be under the passed prefix if the prefix
+   *  existed in the RIB }
+   */
+  std::list<shared_ptr<RibEntry>>
+  findDescendantsForNonInsertedName(const Name& prefix) const;
+
+public:
+  using UpdateSuccessCallback = std::function<void()>;
+  using UpdateFailureCallback = std::function<void(uint32_t code, const std::string& error)>;
+
+  /** \brief passes the provided RibUpdateBatch to FibUpdater to calculate and send FibUpdates.
+   *
+   *  If the FIB is updated successfully, onFibUpdateSuccess() will be called, and the
+   *  RIB will be updated
+   *
+   *  If the FIB update fails, onFibUpdateFailure() will be called, and the RIB will not
+   *  be updated.
+   */
+  void
+  beginApplyUpdate(const RibUpdate& update,
+                   const UpdateSuccessCallback& onSuccess,
+                   const UpdateFailureCallback& onFailure);
+
+  /** \brief starts the FIB update process when a face has been destroyed
+   */
+  void
+  beginRemoveFace(uint64_t faceId);
+
+  void
+  onFibUpdateSuccess(const RibUpdateBatch& batch,
+                     const RibUpdateList& inheritedRoutes,
+                     const Rib::UpdateSuccessCallback& onSuccess);
+
+  void
+  onFibUpdateFailure(const Rib::UpdateFailureCallback& onFailure,
+                     uint32_t code, const std::string& error);
+
+  void
+  onRouteExpiration(const Name& prefix, const Route& route);
+
+  void
+  insert(const Name& prefix, const Route& route);
+
+private:
+  /** \brief adds the passed update to a RibUpdateBatch and adds the batch to
+  *          the end of the update queue.
+  *
+  *   If an update is not in progress, the front update batch in the queue will be
+  *   processed by the RIB.
+  *
+  *   If an update is in progress, the added update will eventually be processed
+  *   when it reaches the front of the queue; after other update batches are
+  *   processed, the queue is advanced.
+  */
+  void
+  addUpdateToQueue(const RibUpdate& update,
+                   const Rib::UpdateSuccessCallback& onSuccess,
+                   const Rib::UpdateFailureCallback& onFailure);
+
+  /** \brief Attempts to send the front update batch in the queue.
+  *
+  *   If an update is not in progress, the front update batch in the queue will be
+  *   sent to the RIB for processing.
+  *
+  *   If an update is in progress, nothing will be done.
+  */
+  void
+  sendBatchFromQueue();
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+#ifdef WITH_TESTS
+  /** \brief In unit tests, mock FIB update result.
+   *
+   *  If the callback is not nullptr, sendBatchFromQueue() immediately succeeds or fails according
+   *  to the return value of callback function.
+   */
+  std::function<bool(const RibUpdateBatch&)> mockFibResponse;
+
+  bool wantMockFibResponseOnce = false; ///< if true, mockFibResponse is cleared after every use.
+#endif
+
+  void
+  erase(const Name& prefix, const Route& route);
+
+private:
+  RibTable::iterator
+  eraseEntry(RibTable::iterator it);
+
+  void
+  updateRib(const RibUpdateBatch& batch);
+
+  /** \brief returns routes inherited from the entry's ancestors
+   *
+   *  \return{ a list of inherited routes }
+   */
+  RouteSet
+  getAncestorRoutes(const RibEntry& entry) const;
+
+  /** \brief returns routes inherited from the parent of the name and the parent's ancestors
+   *
+   *  \note A parent is first found for the passed name before inherited routes are collected
+   *
+   *  \return{ a list of inherited routes }
+   */
+  RouteSet
+  getAncestorRoutes(const Name& name) const;
+
+  /** \brief applies the passed inheritedRoutes and their actions to the corresponding RibEntries'
+   *  inheritedRoutes lists
+   */
+  void
+  modifyInheritedRoutes(const RibUpdateList& inheritedRoutes);
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  using NameAndRoute = std::pair<const Name&, const Route&>;
+
+  std::list<NameAndRoute>
+  findRoutesWithFaceId(uint64_t faceId);
+
+public:
+  /** \brief signals after a RIB entry is inserted
+   *
+   *  A RIB entry is inserted when the first route associated with a
+   *  certain namespace is added.
+   */
+  ndn::util::signal::Signal<Rib, Name> afterInsertEntry;
+
+  /** \brief signals after a RIB entry is erased
+   *
+   *  A RIB entry is erased when the last route associated with a
+   *  certain namespace is removed.
+   */
+
+  ndn::util::signal::Signal<Rib, Name> afterEraseEntry;
+
+  /** \brief signals after a Route is added
+   */
+  ndn::util::signal::Signal<Rib, RibRouteRef> afterAddRoute;
+
+  /** \brief signals before a route is removed
+   */
+  ndn::util::signal::Signal<Rib, RibRouteRef> beforeRemoveRoute;
+
+private:
+  RibTable m_rib;
+  FaceLookupTable m_faceMap;
+  FibUpdater* m_fibUpdater;
+
+  size_t m_nItems;
+
+  friend class FibUpdater;
+
+private:
+  struct UpdateQueueItem
+  {
+    RibUpdateBatch batch;
+    const Rib::UpdateSuccessCallback managerSuccessCallback;
+    const Rib::UpdateFailureCallback managerFailureCallback;
+  };
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  typedef std::list<UpdateQueueItem> UpdateQueue;
+  UpdateQueue m_updateBatches;
+
+private:
+  bool m_isUpdateInProgress;
+};
+
+inline Rib::const_iterator
+Rib::begin() const
+{
+  return m_rib.begin();
+}
+
+inline Rib::const_iterator
+Rib::end() const
+{
+  return m_rib.end();
+}
+
+inline size_t
+Rib::size() const
+{
+  return m_nItems;
+}
+
+inline bool
+Rib::empty() const
+{
+  return m_rib.empty();
+}
+
+std::ostream&
+operator<<(std::ostream& os, const Rib& rib);
+
+} // namespace rib
+} // namespace nfd
+
+#endif // NFD_DAEMON_RIB_RIB_HPP
diff --git a/daemon/rib/route.cpp b/daemon/rib/route.cpp
new file mode 100644
index 0000000..04999bb
--- /dev/null
+++ b/daemon/rib/route.cpp
@@ -0,0 +1,96 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2018,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "route.hpp"
+#include <ndn-cxx/util/string-helper.hpp>
+
+namespace nfd {
+namespace rib {
+
+const uint64_t PA_ROUTE_COST = 2048; ///< cost of route created by prefix announcement
+
+static time::steady_clock::TimePoint
+computeExpiration(const ndn::PrefixAnnouncement& ann)
+{
+  time::steady_clock::Duration validityEnd = time::steady_clock::Duration::max();
+  if (ann.getValidityPeriod()) {
+    auto now = time::system_clock::now();
+    if (!ann.getValidityPeriod()->isValid(now)) {
+      validityEnd = time::steady_clock::Duration::zero();
+    }
+    else {
+      validityEnd = ann.getValidityPeriod()->getPeriod().second - now;
+    }
+  }
+  return time::steady_clock::now() +
+    std::min(validityEnd, time::duration_cast<time::steady_clock::Duration>(ann.getExpiration()));
+}
+
+Route::Route(const ndn::PrefixAnnouncement& ann, uint64_t faceId)
+  : faceId(faceId)
+  , origin(ndn::nfd::ROUTE_ORIGIN_PREFIXANN)
+  , cost(PA_ROUTE_COST)
+  , flags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT)
+  , expires(computeExpiration(ann))
+  , announcement(ann)
+  , annExpires(*expires)
+{
+}
+
+bool
+operator==(const Route& lhs, const Route& rhs)
+{
+  return lhs.faceId == rhs.faceId &&
+         lhs.origin == rhs.origin &&
+         lhs.flags == rhs.flags &&
+         lhs.cost == rhs.cost &&
+         lhs.expires == rhs.expires &&
+         lhs.announcement == rhs.announcement;
+}
+
+std::ostream&
+operator<<(std::ostream& os, const Route& route)
+{
+  os << "Route("
+     << "faceid: " << route.faceId
+     << ", origin: " << route.origin
+     << ", cost: " << route.cost
+     << ", flags: " << ndn::AsHex{route.flags};
+  if (route.expires) {
+    os << ", expires in: " << time::duration_cast<time::milliseconds>(*route.expires - time::steady_clock::now());
+  }
+  else {
+    os << ", never expires";
+  }
+  if (route.announcement) {
+    os << ", announcement: (" << *route.announcement << ')';
+  }
+  os << ')';
+
+  return os;
+}
+
+} // namespace rib
+} // namespace nfd
diff --git a/daemon/rib/route.hpp b/daemon/rib/route.hpp
new file mode 100644
index 0000000..f38fbab
--- /dev/null
+++ b/daemon/rib/route.hpp
@@ -0,0 +1,134 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_DAEMON_RIB_ROUTE_HPP
+#define NFD_DAEMON_RIB_ROUTE_HPP
+
+#include "core/common.hpp"
+
+#include <ndn-cxx/encoding/nfd-constants.hpp>
+#include <ndn-cxx/mgmt/nfd/route-flags-traits.hpp>
+#include <ndn-cxx/prefix-announcement.hpp>
+#include <ndn-cxx/util/scheduler.hpp>
+
+#include <type_traits>
+
+namespace nfd {
+namespace rib {
+
+/** \brief represents a route for a name prefix
+ */
+class Route : public ndn::nfd::RouteFlagsTraits<Route>
+{
+public:
+  /** \brief default constructor
+   */
+  Route() = default;
+
+  /** \brief construct from a prefix announcement
+   *  \param ann a prefix announcement that has passed verification
+   *  \param faceId the face on which \p ann arrived
+   */
+  Route(const ndn::PrefixAnnouncement& ann, uint64_t faceId);
+
+  const ndn::util::scheduler::EventId&
+  getExpirationEvent() const
+  {
+    return m_expirationEvent;
+  }
+
+  void
+  setExpirationEvent(const ndn::util::scheduler::EventId& eid)
+  {
+    m_expirationEvent = eid;
+  }
+
+  void
+  cancelExpirationEvent()
+  {
+    m_expirationEvent.cancel();
+  }
+
+  std::underlying_type_t<ndn::nfd::RouteFlags>
+  getFlags() const
+  {
+    return flags;
+  }
+
+public:
+  uint64_t faceId = 0;
+  ndn::nfd::RouteOrigin origin = ndn::nfd::ROUTE_ORIGIN_APP;
+  uint64_t cost = 0;
+  std::underlying_type_t<ndn::nfd::RouteFlags> flags = ndn::nfd::ROUTE_FLAGS_NONE;
+  optional<time::steady_clock::TimePoint> expires;
+
+  /** \brief The prefix announcement that caused the creation of this route.
+   *
+   *  This is nullopt if this route is not created by a prefix announcement.
+   */
+  optional<ndn::PrefixAnnouncement> announcement;
+
+  /** \brief Expiration time of the prefix announcement.
+   *
+   *  Valid only if announcement is not nullopt.
+   *
+   *  If this field is before or equal the current time, it indicates the prefix announcement is
+   *  not yet valid or has expired. In this case, the exact value of this field does not matter.
+   *  If this field is after the current time, it indicates when the prefix announcement expires.
+   */
+  time::steady_clock::TimePoint annExpires;
+
+private:
+  ndn::util::scheduler::EventId m_expirationEvent;
+};
+
+bool
+operator==(const Route& lhs, const Route& rhs);
+
+inline bool
+operator!=(const Route& lhs, const Route& rhs)
+{
+  return !(lhs == rhs);
+}
+
+inline bool
+compareFaceIdAndOrigin(const Route& lhs, const Route& rhs)
+{
+  return (lhs.faceId == rhs.faceId && lhs.origin == rhs.origin);
+}
+
+inline bool
+compareFaceId(const Route& route, const uint64_t faceId)
+{
+  return (route.faceId == faceId);
+}
+
+std::ostream&
+operator<<(std::ostream& os, const Route& route);
+
+} // namespace rib
+} // namespace nfd
+
+#endif // NFD_DAEMON_RIB_ROUTE_HPP
diff --git a/daemon/rib/service.cpp b/daemon/rib/service.cpp
new file mode 100644
index 0000000..35c092d
--- /dev/null
+++ b/daemon/rib/service.cpp
@@ -0,0 +1,256 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "service.hpp"
+
+#include "fib-updater.hpp"
+#include "readvertise/client-to-nlsr-readvertise-policy.hpp"
+#include "readvertise/host-to-gateway-readvertise-policy.hpp"
+#include "readvertise/nfd-rib-readvertise-destination.hpp"
+#include "readvertise/readvertise.hpp"
+
+#include "core/global-io.hpp"
+#include "core/logger.hpp"
+
+#include <boost/property_tree/info_parser.hpp>
+#include <ndn-cxx/transport/tcp-transport.hpp>
+#include <ndn-cxx/transport/unix-transport.hpp>
+
+namespace nfd {
+namespace rib {
+
+NFD_LOG_INIT(RibService);
+
+Service* Service::s_instance = nullptr;
+
+static const std::string CFG_SECTION = "rib";
+static const std::string CFG_LOCALHOST_SECURITY = "localhost_security";
+static const std::string CFG_LOCALHOP_SECURITY = "localhop_security";
+static const std::string CFG_PREFIX_PROPAGATE = "auto_prefix_propagate";
+static const std::string CFG_READVERTISE_NLSR = "readvertise_nlsr";
+static const Name READVERTISE_NLSR_PREFIX = "/localhost/nlsr";
+static const uint64_t PROPAGATE_DEFAULT_COST = 15;
+static const time::milliseconds PROPAGATE_DEFAULT_TIMEOUT = 10_s;
+
+static ConfigSection
+loadConfigSectionFromFile(const std::string& filename)
+{
+  ConfigSection config;
+  // Any format errors should have been caught already
+  boost::property_tree::read_info(filename, config);
+  return config;
+}
+
+/**
+ * \brief Look into the config file and construct appropriate transport to communicate with NFD
+ * If NFD-RIB instance was initialized with config file, INFO format is assumed
+ */
+static shared_ptr<ndn::Transport>
+makeLocalNfdTransport(const ConfigSection& config)
+{
+  if (config.get_child_optional("face_system.unix")) {
+    // default socket path should be the same as in UnixStreamFactory::processConfig
+    auto path = config.get<std::string>("face_system.unix.path", "/var/run/nfd.sock");
+    return make_shared<ndn::UnixTransport>(path);
+  }
+  else if (config.get_child_optional("face_system.tcp") &&
+           config.get<std::string>("face_system.tcp.listen", "yes") == "yes") {
+    // default port should be the same as in TcpFactory::processConfig
+    auto port = config.get<std::string>("face_system.tcp.port", "6363");
+    return make_shared<ndn::TcpTransport>("localhost", port);
+  }
+  else {
+    NDN_THROW(ConfigFile::Error("No transport is available to communicate with NFD"));
+  }
+}
+
+Service::Service(const std::string& configFile, ndn::KeyChain& keyChain)
+  : Service(keyChain, makeLocalNfdTransport(loadConfigSectionFromFile(configFile)),
+            [&configFile] (ConfigFile& config, bool isDryRun) {
+              config.parse(configFile, isDryRun);
+            })
+{
+}
+
+Service::Service(const ConfigSection& configSection, ndn::KeyChain& keyChain)
+  : Service(keyChain, makeLocalNfdTransport(configSection),
+            [&configSection] (ConfigFile& config, bool isDryRun) {
+              config.parse(configSection, isDryRun, "internal://nfd.conf");
+            })
+{
+}
+
+template<typename ConfigParseFunc>
+Service::Service(ndn::KeyChain& keyChain, shared_ptr<ndn::Transport> localNfdTransport,
+                 const ConfigParseFunc& configParse)
+  : m_keyChain(keyChain)
+  , m_face(std::move(localNfdTransport), getGlobalIoService(), m_keyChain)
+  , m_scheduler(m_face.getIoService())
+  , m_nfdController(m_face, m_keyChain)
+  , m_fibUpdater(m_rib, m_nfdController)
+  , m_dispatcher(m_face, m_keyChain)
+  , m_ribManager(m_rib, m_face, m_keyChain, m_nfdController, m_dispatcher, m_scheduler)
+{
+  if (s_instance != nullptr) {
+    NDN_THROW(std::logic_error("RIB service cannot be instantiated more than once"));
+  }
+  if (&getGlobalIoService() != &getRibIoService()) {
+    NDN_THROW(std::logic_error("RIB service must run on RIB thread"));
+  }
+  s_instance = this;
+
+  ConfigFile config(ConfigFile::ignoreUnknownSection);
+  config.addSectionHandler(CFG_SECTION, bind(&Service::processConfig, this, _1, _2, _3));
+  configParse(config, true);
+  configParse(config, false);
+
+  m_ribManager.registerWithNfd();
+  m_ribManager.enableLocalFields();
+}
+
+Service::~Service()
+{
+  s_instance = nullptr;
+}
+
+Service&
+Service::get()
+{
+  if (s_instance == nullptr) {
+    NDN_THROW(std::logic_error("RIB service is not instantiated"));
+  }
+  if (&getGlobalIoService() != &getRibIoService()) {
+    NDN_THROW(std::logic_error("Must get RIB service on RIB thread"));
+  }
+  return *s_instance;
+}
+
+void
+Service::processConfig(const ConfigSection& section, bool isDryRun, const std::string& filename)
+{
+  if (isDryRun) {
+    checkConfig(section, filename);
+  }
+  else {
+    applyConfig(section, filename);
+  }
+}
+
+void
+Service::checkConfig(const ConfigSection& section, const std::string& filename)
+{
+  for (const auto& item : section) {
+    const std::string& key = item.first;
+    const ConfigSection& value = item.second;
+    if (key == CFG_LOCALHOST_SECURITY || key == CFG_LOCALHOP_SECURITY) {
+      ndn::ValidatorConfig testValidator(m_face);
+      testValidator.load(value, filename);
+    }
+    else if (key == CFG_PREFIX_PROPAGATE) {
+      // AutoPrefixPropagator does not support config dry-run
+    }
+    else if (key == CFG_READVERTISE_NLSR) {
+      ConfigFile::parseYesNo(item, CFG_SECTION + "." + CFG_READVERTISE_NLSR);
+    }
+    else {
+      NDN_THROW(ConfigFile::Error("Unrecognized option " + CFG_SECTION + "." + key));
+    }
+  }
+}
+
+void
+Service::applyConfig(const ConfigSection& section, const std::string& filename)
+{
+  bool wantPrefixPropagate = false;
+  bool wantReadvertiseNlsr = false;
+
+  for (const auto& item : section) {
+    const std::string& key = item.first;
+    const ConfigSection& value = item.second;
+    if (key == CFG_LOCALHOST_SECURITY) {
+      m_ribManager.applyLocalhostConfig(value, filename);
+    }
+    else if (key == CFG_LOCALHOP_SECURITY) {
+      m_ribManager.enableLocalhop(value, filename);
+    }
+    else if (key == CFG_PREFIX_PROPAGATE) {
+      wantPrefixPropagate = true;
+
+      if (!m_readvertisePropagation) {
+        NFD_LOG_DEBUG("Enabling automatic prefix propagation");
+
+        auto parameters = ndn::nfd::ControlParameters()
+          .setCost(PROPAGATE_DEFAULT_COST)
+          .setOrigin(ndn::nfd::ROUTE_ORIGIN_CLIENT);
+        auto cost = item.second.get_optional<uint64_t>("cost");
+        if (cost) {
+          parameters.setCost(*cost);
+        }
+
+        auto options = ndn::nfd::CommandOptions()
+          .setPrefix(RibManager::LOCALHOP_TOP_PREFIX)
+          .setTimeout(PROPAGATE_DEFAULT_TIMEOUT);
+        auto timeout = item.second.get_optional<uint64_t>("timeout");
+        if (timeout) {
+          options.setTimeout(time::milliseconds(*timeout));
+        }
+
+        m_readvertisePropagation = make_unique<Readvertise>(
+          m_rib,
+          m_scheduler,
+          make_unique<HostToGatewayReadvertisePolicy>(m_keyChain, item.second),
+          make_unique<NfdRibReadvertiseDestination>(m_nfdController, m_rib, options, parameters));
+      }
+    }
+    else if (key == CFG_READVERTISE_NLSR) {
+      wantReadvertiseNlsr = ConfigFile::parseYesNo(item, CFG_SECTION + "." + CFG_READVERTISE_NLSR);
+    }
+    else {
+      NDN_THROW(ConfigFile::Error("Unrecognized option " + CFG_SECTION + "." + key));
+    }
+  }
+
+  if (!wantPrefixPropagate && m_readvertisePropagation != nullptr) {
+    NFD_LOG_DEBUG("Disabling automatic prefix propagation");
+    m_readvertisePropagation.reset();
+  }
+
+  if (wantReadvertiseNlsr && m_readvertiseNlsr == nullptr) {
+    NFD_LOG_DEBUG("Enabling readvertise-to-nlsr");
+    auto options = ndn::nfd::CommandOptions().setPrefix(READVERTISE_NLSR_PREFIX);
+    m_readvertiseNlsr = make_unique<Readvertise>(
+      m_rib,
+      m_scheduler,
+      make_unique<ClientToNlsrReadvertisePolicy>(),
+      make_unique<NfdRibReadvertiseDestination>(m_nfdController, m_rib, options));
+  }
+  else if (!wantReadvertiseNlsr && m_readvertiseNlsr != nullptr) {
+    NFD_LOG_DEBUG("Disabling readvertise-to-nlsr");
+    m_readvertiseNlsr.reset();
+  }
+}
+
+} // namespace rib
+} // namespace nfd
diff --git a/daemon/rib/service.hpp b/daemon/rib/service.hpp
new file mode 100644
index 0000000..0d6a71a
--- /dev/null
+++ b/daemon/rib/service.hpp
@@ -0,0 +1,127 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD 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
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_DAEMON_RIB_SERVICE_HPP
+#define NFD_DAEMON_RIB_SERVICE_HPP
+
+#include "rib-manager.hpp"
+
+#include "core/config-file.hpp"
+
+#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/mgmt/dispatcher.hpp>
+#include <ndn-cxx/mgmt/nfd/controller.hpp>
+#include <ndn-cxx/security/key-chain.hpp>
+#include <ndn-cxx/transport/transport.hpp>
+#include <ndn-cxx/util/scheduler.hpp>
+
+namespace nfd {
+namespace rib {
+
+class Readvertise;
+
+/**
+ * \brief initializes and executes NFD-RIB service thread
+ *
+ * Only one instance of this class can be created at any time.
+ * After initialization, NFD-RIB instance can be started by running the global io_service.
+ */
+class Service : noncopyable
+{
+public:
+  /**
+   * \brief create NFD-RIB service
+   * \param configFile absolute or relative path of configuration file
+   * \param keyChain the KeyChain
+   * \throw std::logic_error Instance of rib::Service has been already constructed
+   * \throw std::logic_error Instance of rib::Service is not constructed on RIB thread
+   */
+  Service(const std::string& configFile, ndn::KeyChain& keyChain);
+
+  /**
+   * \brief create NFD-RIB service
+   * \param configSection parsed configuration section
+   * \param keyChain the KeyChain
+   * \note This constructor overload is more appropriate for integrated environments,
+   *       such as NS-3 or android. Error messages related to configuration file
+   *       will use "internal://nfd.conf" as configuration filename.
+   * \throw std::logic_error Instance of rib::Service has been already constructed
+   * \throw std::logic_error Instance of rib::Service is not constructed on RIB thread
+   */
+  Service(const ConfigSection& configSection, ndn::KeyChain& keyChain);
+
+  /**
+   * \brief Destructor
+   */
+  ~Service();
+
+  /**
+   * \brief Get a reference to the only instance of this class
+   * \throw std::logic_error No instance has been constructed
+   * \throw std::logic_error This function is invoked on a thread other than the RIB thread
+   */
+  static Service&
+  get();
+
+  RibManager&
+  getRibManager()
+  {
+    return m_ribManager;
+  }
+
+private:
+  template<typename ConfigParseFunc>
+  Service(ndn::KeyChain& keyChain, shared_ptr<ndn::Transport> localNfdTransport,
+          const ConfigParseFunc& configParse);
+
+  void
+  processConfig(const ConfigSection& section, bool isDryRun, const std::string& filename);
+
+  void
+  checkConfig(const ConfigSection& section, const std::string& filename);
+
+  void
+  applyConfig(const ConfigSection& section, const std::string& filename);
+
+private:
+  static Service* s_instance;
+
+  ndn::KeyChain& m_keyChain;
+  ndn::Face m_face;
+  ndn::util::Scheduler m_scheduler;
+  ndn::nfd::Controller m_nfdController;
+
+  Rib m_rib;
+  FibUpdater m_fibUpdater;
+  unique_ptr<Readvertise> m_readvertiseNlsr;
+  unique_ptr<Readvertise> m_readvertisePropagation;
+  ndn::mgmt::Dispatcher m_dispatcher;
+  RibManager m_ribManager;
+};
+
+} // namespace rib
+} // namespace nfd
+
+#endif // NFD_DAEMON_RIB_SERVICE_HPP
