rib: move entire subdir to daemon/rib

Refs: #4528
Change-Id: I7de03631ddef0f014f12f979373aa449f42486d1
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