diff --git a/tests/daemon/mgmt/fib-manager.t.cpp b/tests/daemon/mgmt/fib-manager.t.cpp
new file mode 100644
index 0000000..513536c
--- /dev/null
+++ b/tests/daemon/mgmt/fib-manager.t.cpp
@@ -0,0 +1,491 @@
+/* -*- 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 "mgmt/fib-manager.hpp"
+
+#include "manager-common-fixture.hpp"
+#include "table/fib-nexthop.hpp"
+#include "../face/dummy-face.hpp"
+#include <ndn-cxx/management/nfd-fib-entry.hpp>
+
+namespace nfd {
+namespace tests {
+
+class FibManagerFixture : public ManagerCommonFixture
+{
+public:
+  FibManagerFixture()
+    : m_fib(m_forwarder.getFib())
+    , m_faceTable(m_forwarder.getFaceTable())
+    , m_manager(m_fib, bind(&Forwarder::getFace, &m_forwarder, _1), m_dispatcher, m_validator)
+  {
+    setTopPrefixAndPrivilege("/localhost/nfd", "fib");
+  }
+
+public: // for test
+  ControlParameters
+  makeParameters(const Name& name, const FaceId& id)
+  {
+    return ControlParameters().setName(name).setFaceId(id);
+  }
+
+  ControlParameters
+  makeParameters(const Name& name, const FaceId& id, const uint32_t& cost)
+  {
+    return ControlParameters().setName(name).setFaceId(id).setCost(cost);
+  }
+
+  FaceId
+  addFace()
+  {
+    auto face = make_shared<DummyFace>();
+    m_faceTable.add(face);
+    advanceClocks(time::milliseconds(1), 10);
+    m_responses.clear(); // clear all event notifications, if any
+    return face->getId();
+  }
+
+public: // for check
+  enum class CheckNextHopResult
+  {
+    OK,
+    NO_FIB_ENTRY,
+    WRONG_N_NEXTHOPS,
+    NO_NEXTHOP,
+    WRONG_COST
+   };
+
+  /**
+   * @brief check whether the nexthop record is added / removed properly
+   *
+   * @param expectedNNextHops use -1 to skip this check
+   * @param faceId use FACEID_NULL to skip NextHopRecord checks
+   * @param expectedCost use -1 to skip this check
+   *
+   * @retval OK FIB entry is found by exact match and has the expected number of nexthops;
+   *            NextHopRe record for faceId is found and has the expected cost
+   * @retval NO_FIB_ENTRY FIB entry is not found
+   * @retval WRONG_N_NEXTHOPS FIB entry is found but has wrong number of nexthops
+   * @retval NO_NEXTHOP NextHopRecord for faceId is not found
+   * @retval WRONG_COST NextHopRecord for faceId has wrong cost
+   */
+  CheckNextHopResult
+  checkNextHop(const Name& prefix, ssize_t expectedNNextHops = -1,
+               FaceId faceId = FACEID_NULL, int32_t expectedCost = -1)
+  {
+    auto entry = m_fib.findExactMatch(prefix);
+    if (!static_cast<bool>(entry)) {
+      return CheckNextHopResult::NO_FIB_ENTRY;
+    }
+
+    auto nextHops = entry->getNextHops();
+    if (expectedNNextHops != -1 && nextHops.size() != static_cast<size_t>(expectedNNextHops)) {
+      return CheckNextHopResult::WRONG_N_NEXTHOPS;
+    }
+
+    if (faceId != FACEID_NULL) {
+      for (auto&& record : nextHops) {
+        if (record.getFace()->getId() == faceId) {
+          return expectedCost != -1 && record.getCost() != static_cast<uint32_t>(expectedCost) ?
+            CheckNextHopResult::WRONG_COST : CheckNextHopResult::OK;
+        }
+      }
+
+      return CheckNextHopResult::NO_NEXTHOP;
+    }
+
+    return CheckNextHopResult::OK;
+  }
+
+protected:
+  Fib&       m_fib;
+  FaceTable& m_faceTable;
+  FibManager m_manager;
+};
+
+std::ostream&
+operator<<(std::ostream &os, const FibManagerFixture::CheckNextHopResult& result)
+{
+  switch (result) {
+  case FibManagerFixture::CheckNextHopResult::OK:
+    os << "OK";
+    break;
+  case FibManagerFixture::CheckNextHopResult::NO_FIB_ENTRY:
+    os << "NO_FIB_ENTRY";
+    break;
+  case FibManagerFixture::CheckNextHopResult::WRONG_N_NEXTHOPS:
+    os << "WRONG_N_NEXTHOPS";
+    break;
+  case FibManagerFixture::CheckNextHopResult::NO_NEXTHOP:
+    os << "NO_NEXTHOP";
+    break;
+  case FibManagerFixture::CheckNextHopResult::WRONG_COST:
+    os << "WRONG_COST";
+    break;
+  default:
+    break;
+  };
+
+  return os;
+}
+
+BOOST_FIXTURE_TEST_SUITE(Mgmt, FibManagerFixture)
+BOOST_AUTO_TEST_SUITE(TestFibManager)
+
+BOOST_AUTO_TEST_SUITE(AddNextHop)
+
+BOOST_AUTO_TEST_CASE(UnknownFaceId)
+{
+  auto command = makeControlCommandRequest("/localhost/nfd/fib/add-nexthop",
+                                           makeParameters("hello", FACEID_NULL, 101));
+  receiveInterest(command);
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+
+  // check response
+  BOOST_CHECK_EQUAL(checkResponse(0, command->getName(), ControlResponse(410, "Face not found")),
+                    CheckResponseResult::OK);
+
+  // double check that the next hop was not added
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", -1, FACEID_NULL, 101), CheckNextHopResult::NO_FIB_ENTRY);
+}
+
+BOOST_AUTO_TEST_CASE(ImplicitFaceId)
+{
+  auto face1 = addFace();
+  auto face2 = addFace();
+  BOOST_REQUIRE(face1 != INVALID_FACEID && face2 != INVALID_FACEID);
+
+  Name expectedName;
+  ControlResponse expectedResponse;
+  auto testAddNextHop = [&] (ControlParameters parameters, const FaceId& faceId) {
+    auto command = makeControlCommandRequest("/localhost/nfd/fib/add-nexthop", parameters,
+                                             [&faceId] (shared_ptr<Interest> interest) {
+                                               interest->setIncomingFaceId(faceId);
+                                             });
+    m_responses.clear();
+    expectedName = command->getName();
+    expectedResponse = makeResponse(200, "Success", parameters.setFaceId(faceId));
+    receiveInterest(command);
+  };
+
+  testAddNextHop(ControlParameters().setName("/hello").setCost(100).setFaceId(0), face1);
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, face1, 100), CheckNextHopResult::OK);
+
+  testAddNextHop(ControlParameters().setName("/hello").setCost(100), face2);
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", 2, face2, 100), CheckNextHopResult::OK);
+}
+
+BOOST_AUTO_TEST_CASE(InitialAdd)
+{
+  FaceId addedFaceId = addFace();
+  BOOST_REQUIRE(addedFaceId != INVALID_FACEID);
+
+  auto parameters = makeParameters("hello", addedFaceId, 101);
+  auto command = makeControlCommandRequest("/localhost/nfd/fib/add-nexthop", parameters);
+
+  receiveInterest(command);
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, command->getName(), makeResponse(200, "Success", parameters)),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, addedFaceId, 101), CheckNextHopResult::OK);
+}
+
+BOOST_AUTO_TEST_CASE(ImplicitCost)
+{
+  FaceId addedFaceId = addFace();
+  BOOST_REQUIRE(addedFaceId != INVALID_FACEID);
+
+  auto originalParameters = ControlParameters().setName("/hello").setFaceId(addedFaceId);
+  auto parameters = makeParameters("/hello", addedFaceId, 0);
+  auto command = makeControlCommandRequest("/localhost/nfd/fib/add-nexthop", originalParameters);
+
+  receiveInterest(command);
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, command->getName(), makeResponse(200, "Success", parameters)),
+                    CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, addedFaceId, 0), CheckNextHopResult::OK);
+}
+
+BOOST_AUTO_TEST_CASE(AddToExisting)
+{
+  FaceId face = addFace();
+  BOOST_CHECK(face != INVALID_FACEID);
+
+  Name expectedName;
+  ControlResponse expectedResponse;
+  auto testAddNextHop = [&] (const ControlParameters& parameters) {
+    m_responses.clear();
+    auto command = makeControlCommandRequest("/localhost/nfd/fib/add-nexthop", parameters);
+    expectedName = command->getName();
+    expectedResponse = makeResponse(200, "Success", parameters);
+    receiveInterest(command);
+  };
+
+  // add initial, succeeds
+  testAddNextHop(makeParameters("/hello", face, 101));
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
+
+  // add to existing --> update cost, succeeds
+  testAddNextHop(makeParameters("/hello", face, 102));
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
+
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", 2, face, 102), CheckNextHopResult::WRONG_N_NEXTHOPS);
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, face, 101), CheckNextHopResult::WRONG_COST);
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, face, 102), CheckNextHopResult::OK);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // AddNextHop
+
+BOOST_AUTO_TEST_SUITE(RemoveNextHop)
+
+BOOST_AUTO_TEST_CASE(Basic)
+{
+  Name expectedName;
+  ControlResponse expectedResponse;
+  auto testRemoveNextHop = [&] (const ControlParameters& parameters) {
+    m_responses.clear();
+    auto command = makeControlCommandRequest("/localhost/nfd/fib/remove-nexthop", parameters);
+    expectedName = command->getName();
+    expectedResponse = makeResponse(200, "Success", parameters);
+    receiveInterest(command);
+  };
+
+  FaceId face1 = addFace();
+  FaceId face2 = addFace();
+  FaceId face3 = addFace();
+  BOOST_REQUIRE(face1 != INVALID_FACEID && face2 != INVALID_FACEID && face3 != INVALID_FACEID);
+
+  shared_ptr<fib::Entry> entry = m_fib.insert("/hello").first;
+  entry->addNextHop(m_faceTable.get(face1), 101);
+  entry->addNextHop(m_faceTable.get(face2), 202);
+  entry->addNextHop(m_faceTable.get(face3), 303);
+
+  testRemoveNextHop(makeParameters("/hello", face1));
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", 2, face1, 101), CheckNextHopResult::NO_NEXTHOP);
+
+  testRemoveNextHop(makeParameters("/hello", face2));
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, face2, 202), CheckNextHopResult::NO_NEXTHOP);
+
+  testRemoveNextHop(makeParameters("/hello", face3));
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", 0, face3, 303), CheckNextHopResult::NO_FIB_ENTRY);
+}
+
+BOOST_AUTO_TEST_CASE(PrefixNotFound)
+{
+  FaceId addedFaceId = addFace();
+  BOOST_CHECK(addedFaceId != INVALID_FACEID);
+
+  auto parameters = makeParameters("hello", addedFaceId);
+  auto command = makeControlCommandRequest("/localhost/nfd/fib/remove-nexthop", parameters);
+  auto response = makeResponse(200, "Success", parameters);
+
+  receiveInterest(command);
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, command->getName(), response), CheckResponseResult::OK);
+}
+
+BOOST_AUTO_TEST_CASE(ImplicitFaceId)
+{
+  auto face1 = addFace();
+  auto face2 = addFace();
+  BOOST_REQUIRE(face1 != INVALID_FACEID && face2 != INVALID_FACEID);
+
+  Name expectedName;
+  ControlResponse expectedResponse;
+  auto testWithImplicitFaceId = [&] (ControlParameters parameters, FaceId face) {
+    m_responses.clear();
+    auto command = makeControlCommandRequest("/localhost/nfd/fib/remove-nexthop", parameters,
+                                             [face] (shared_ptr<Interest> interest) {
+                                               interest->setIncomingFaceId(face);
+                                             });
+    expectedName = command->getName();
+    expectedResponse = makeResponse(200, "Success", parameters.setFaceId(face));
+    receiveInterest(command);
+  };
+
+  shared_ptr<fib::Entry> entry = m_fib.insert("/hello").first;
+  entry->addNextHop(m_faceTable.get(face1), 101);
+  entry->addNextHop(m_faceTable.get(face2), 202);
+
+  testWithImplicitFaceId(ControlParameters().setName("/hello").setFaceId(0), face1);
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", 1, face1, 101), CheckNextHopResult::NO_NEXTHOP);
+
+  testWithImplicitFaceId(ControlParameters().setName("/hello"), face2);
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+  BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", 0, face2, 202), CheckNextHopResult::NO_FIB_ENTRY);
+}
+
+BOOST_AUTO_TEST_CASE(RecordNotExist)
+{
+  auto face1 = addFace();
+  auto face2 = addFace();
+  BOOST_REQUIRE(face1 != INVALID_FACEID && face2 != INVALID_FACEID);
+
+  Name expectedName;
+  ControlResponse expectedResponse;
+  auto testRemoveNextHop = [&] (ControlParameters parameters) {
+    m_responses.clear();
+    auto command = makeControlCommandRequest("/localhost/nfd/fib/remove-nexthop", parameters);
+    expectedName = command->getName();
+    expectedResponse = makeResponse(200, "Success", parameters);
+    receiveInterest(command);
+  };
+
+  m_fib.insert("/hello").first->addNextHop(m_faceTable.get(face1), 101);
+
+  testRemoveNextHop(makeParameters("/hello", face2 + 100));
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1); // face does not exist
+  BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", -1, face2 + 100), CheckNextHopResult::NO_NEXTHOP);
+
+  testRemoveNextHop(makeParameters("/hello", face2));
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1); // record does not exist
+  BOOST_CHECK_EQUAL(checkResponse(0, expectedName, expectedResponse), CheckResponseResult::OK);
+  BOOST_CHECK_EQUAL(checkNextHop("/hello", -1, face2), CheckNextHopResult::NO_NEXTHOP);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // RemoveNextHop
+
+// @todo Remove when ndn::nfd::FibEntry implements operator!= and operator<<
+class FibEntry : public ndn::nfd::FibEntry
+{
+public:
+  FibEntry() = default;
+
+  FibEntry(const ndn::nfd::FibEntry& entry)
+    : ndn::nfd::FibEntry(entry)
+  {
+  }
+};
+
+bool
+operator!=(const FibEntry& left, const FibEntry& right)
+{
+  if (left.getPrefix() != right.getPrefix()) {
+    return true;
+  }
+
+  auto leftNextHops = left.getNextHopRecords();
+  auto rightNextHops = right.getNextHopRecords();
+  if (leftNextHops.size() != rightNextHops.size()) {
+    return true;
+  }
+
+  for (auto&& nexthop : leftNextHops) {
+    auto hitEntry =
+      std::find_if(rightNextHops.begin(), rightNextHops.end(), [&] (const ndn::nfd::NextHopRecord& record) {
+          return nexthop.getCost() == record.getCost() && nexthop.getFaceId() == record.getFaceId();
+        });
+
+    if (hitEntry == rightNextHops.end()) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+std::ostream&
+operator<<(std::ostream &os, const FibEntry& entry)
+{
+  const auto& nexthops = entry.getNextHopRecords();
+  os << "[" << entry.getPrefix() << ", " << nexthops.size() << ": ";
+  for (auto record : nexthops) {
+    os << "{" << record.getFaceId() << ", " << record.getCost() << "} ";
+  }
+  os << "]";
+
+  return os;
+}
+
+BOOST_AUTO_TEST_CASE(FibDataset)
+{
+  const size_t nEntries = 108;
+  std::set<Name> actualPrefixes;
+  for (size_t i = 0 ; i < nEntries ; i ++) {
+    Name prefix = Name("test").appendSegment(i);
+    actualPrefixes.insert(prefix);
+    auto fibEntry = m_fib.insert(prefix).first;
+    fibEntry->addNextHop(m_faceTable.get(addFace()), std::numeric_limits<uint8_t>::max() - 1);
+    fibEntry->addNextHop(m_faceTable.get(addFace()), std::numeric_limits<uint8_t>::max() - 2);
+  }
+
+  receiveInterest(makeInterest("/localhost/nfd/fib/list"));
+
+  Block content;
+  BOOST_CHECK_NO_THROW(content = concatenateResponses());
+  BOOST_CHECK_NO_THROW(content.parse());
+  BOOST_REQUIRE_EQUAL(content.elements().size(), nEntries);
+
+  std::vector<FibEntry> receivedRecords, expectedRecords;
+  for (size_t idx = 0; idx < nEntries; ++idx) {
+    BOOST_TEST_MESSAGE("processing element: " << idx);
+
+    FibEntry decodedEntry;
+    BOOST_REQUIRE_NO_THROW(decodedEntry.wireDecode(content.elements()[idx]));
+    receivedRecords.push_back(decodedEntry);
+
+    actualPrefixes.erase(decodedEntry.getPrefix());
+
+    auto matchedEntry = m_fib.findExactMatch(decodedEntry.getPrefix());
+    BOOST_REQUIRE(matchedEntry != nullptr);
+
+    FibEntry record;
+    record.setPrefix(matchedEntry->getPrefix());
+    const auto& nextHops = matchedEntry->getNextHops();
+    for (auto&& next : nextHops) {
+      ndn::nfd::NextHopRecord nextHopRecord;
+      nextHopRecord.setFaceId(next.getFace()->getId());
+      nextHopRecord.setCost(next.getCost());
+      record.addNextHopRecord(nextHopRecord);
+    }
+    expectedRecords.push_back(record);
+  }
+
+  BOOST_CHECK_EQUAL(actualPrefixes.size(), 0);
+
+  BOOST_CHECK_EQUAL_COLLECTIONS(receivedRecords.begin(), receivedRecords.end(),
+                                expectedRecords.begin(), expectedRecords.end());
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestFibManager
+BOOST_AUTO_TEST_SUITE_END() // Mgmt
+
+} // namespace tests
+} // namespace nfd
