face: use IncomingFaceId, NextHopFaceId, CachePolicy tags

This commit replaces all LocalControlHeader usages with these tags,
and deletes LocalFace.

This commit also does minor improvements in RIB test suites.

refs #3339

Change-Id: I14cbfc296a6723a5860bf8bd95d9804d3bac3da5
diff --git a/tests/daemon/face/dummy-face.hpp b/tests/daemon/face/dummy-face.hpp
index 2991afb..6ed7d46 100644
--- a/tests/daemon/face/dummy-face.hpp
+++ b/tests/daemon/face/dummy-face.hpp
@@ -27,25 +27,19 @@
 #define NFD_TESTS_DAEMON_FACE_DUMMY_FACE_HPP
 
 #include "face/face.hpp"
-#include "face/local-face.hpp"
 
 namespace nfd {
 namespace tests {
 
-/** \class DummyFace
- *  \brief a Face for unit testing
+/** \brief a Face for unit testing
  */
-template<class FaceBase>
-class DummyFaceImpl : public FaceBase
+class DummyFace : public Face
 {
 public:
-  DummyFaceImpl()
-    : FaceBase(FaceUri("dummy://"), FaceUri("dummy://"))
-  {
-  }
-
-  DummyFaceImpl(const std::string& remoteUri, const std::string& localUri)
-    : FaceBase(FaceUri(remoteUri), FaceUri(localUri))
+  explicit
+  DummyFace(const std::string& remoteUri = "dummy://", const std::string& localUri = "dummy://",
+            bool isLocal = false)
+    : Face(FaceUri(remoteUri), FaceUri(localUri), isLocal)
   {
   }
 
@@ -83,15 +77,22 @@
     this->emitSignal(onReceiveData, data);
   }
 
-  signal::Signal<DummyFaceImpl<FaceBase>> afterSend;
+  signal::Signal<DummyFace> afterSend;
 
 public:
   std::vector<Interest> m_sentInterests;
   std::vector<Data> m_sentDatas;
 };
 
-typedef DummyFaceImpl<Face> DummyFace;
-typedef DummyFaceImpl<LocalFace> DummyLocalFace;
+class DummyLocalFace : public DummyFace
+{
+public:
+  explicit
+  DummyLocalFace(const std::string& remoteUri = "dummy://", const std::string& localUri = "dummy://")
+    : DummyFace(remoteUri, localUri, true)
+  {
+  }
+};
 
 } // namespace tests
 } // namespace nfd
diff --git a/tests/daemon/face/face.t.cpp b/tests/daemon/face/face.t.cpp
index 6ed17bf..4a94a58 100644
--- a/tests/daemon/face/face.t.cpp
+++ b/tests/daemon/face/face.t.cpp
@@ -24,7 +24,6 @@
  */
 
 #include "face/face.hpp"
-#include "face/local-face.hpp"
 #include "dummy-face.hpp"
 
 #include "tests/test-common.hpp"
@@ -41,24 +40,6 @@
   BOOST_CHECK_EQUAL(face.getDescription(), "3pFsKrvWr");
 }
 
-BOOST_AUTO_TEST_CASE(LocalControlHeaderEnabled)
-{
-  DummyLocalFace face;
-
-  BOOST_CHECK_EQUAL(face.isLocalControlHeaderEnabled(), false);
-
-  face.setLocalControlHeaderFeature(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID, true);
-  BOOST_CHECK_EQUAL(face.isLocalControlHeaderEnabled(), true);
-  BOOST_CHECK_EQUAL(face.isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID), true);
-  BOOST_CHECK_EQUAL(face.isLocalControlHeaderEnabled(
-                         LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID), false);
-
-  face.setLocalControlHeaderFeature(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID, false);
-  BOOST_CHECK_EQUAL(face.isLocalControlHeaderEnabled(), false);
-  BOOST_CHECK_EQUAL(face.isLocalControlHeaderEnabled(
-                         LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID), false);
-}
-
 class FaceFailTestFace : public DummyFace
 {
 public:
diff --git a/tests/daemon/face/generic-link-service.t.cpp b/tests/daemon/face/generic-link-service.t.cpp
index f3c3c7b..70e078d 100644
--- a/tests/daemon/face/generic-link-service.t.cpp
+++ b/tests/daemon/face/generic-link-service.t.cpp
@@ -407,8 +407,9 @@
   transport->receivePacket(packet.wireEncode());
 
   BOOST_REQUIRE_EQUAL(receivedInterests.size(), 1);
-  BOOST_REQUIRE(receivedInterests.back().getLocalControlHeader().hasNextHopFaceId());
-  BOOST_CHECK_EQUAL(receivedInterests.back().getNextHopFaceId(), 1000);
+  shared_ptr<lp::NextHopFaceIdTag> tag = receivedInterests.back().getTag<lp::NextHopFaceIdTag>();
+  BOOST_REQUIRE(tag != nullptr);
+  BOOST_CHECK_EQUAL(*tag, 1000);
 }
 
 BOOST_AUTO_TEST_CASE(ReceiveNextHopFaceIdDisabled)
@@ -474,16 +475,14 @@
 
   shared_ptr<Data> data = makeData("/12345678");
   lp::Packet packet(data->wireEncode());
-  lp::CachePolicy policy;
-  policy.setPolicy(lp::CachePolicyType::NO_CACHE);
-  packet.set<lp::CachePolicyField>(policy);
+  packet.set<lp::CachePolicyField>(lp::CachePolicy().setPolicy(lp::CachePolicyType::NO_CACHE));
 
   transport->receivePacket(packet.wireEncode());
 
   BOOST_REQUIRE_EQUAL(receivedData.size(), 1);
-  BOOST_REQUIRE(receivedData.back().getLocalControlHeader().hasCachingPolicy());
-  BOOST_CHECK_EQUAL(receivedData.back().getCachingPolicy(),
-                    ndn::nfd::LocalControlHeader::CachingPolicy::NO_CACHE);
+  shared_ptr<lp::CachePolicyTag> tag = receivedData.back().getTag<lp::CachePolicyTag>();
+  BOOST_REQUIRE(tag != nullptr);
+  BOOST_CHECK_EQUAL(tag->get().getPolicy(), lp::CachePolicyType::NO_CACHE);
 }
 
 BOOST_AUTO_TEST_CASE(ReceiveCacheControlDisabled)
@@ -503,7 +502,7 @@
 
   BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 0); // not an error
   BOOST_REQUIRE_EQUAL(receivedData.size(), 1);
-  BOOST_CHECK(!receivedData.back().getLocalControlHeader().hasCachingPolicy());
+  BOOST_CHECK(receivedData.back().getTag<lp::CachePolicyTag>() == nullptr);
 }
 
 BOOST_AUTO_TEST_CASE(ReceiveCacheControlDropInterest)
@@ -553,7 +552,7 @@
   initialize(options);
 
   shared_ptr<Interest> interest = makeInterest("/12345678");
-  interest->setIncomingFaceId(1000);
+  interest->setTag(make_shared<lp::IncomingFaceIdTag>(1000));
 
   face->sendInterest(*interest);
 
@@ -571,7 +570,7 @@
   initialize(options);
 
   shared_ptr<Interest> interest = makeInterest("/12345678");
-  interest->setIncomingFaceId(1000);
+  interest->setTag(make_shared<lp::IncomingFaceIdTag>(1000));
 
   face->sendInterest(*interest);
 
@@ -595,7 +594,7 @@
 
   BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 0); // not an error
   BOOST_REQUIRE_EQUAL(receivedInterests.size(), 1);
-  BOOST_CHECK(!receivedInterests.back().getLocalControlHeader().hasIncomingFaceId());
+  BOOST_CHECK(receivedInterests.back().getTag<lp::IncomingFaceIdTag>() == nullptr);
 }
 
 BOOST_AUTO_TEST_CASE(ReceiveIncomingFaceIdIgnoreData)
@@ -613,7 +612,7 @@
 
   BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 0); // not an error
   BOOST_REQUIRE_EQUAL(receivedData.size(), 1);
-  BOOST_CHECK(!receivedData.back().getLocalControlHeader().hasIncomingFaceId());
+  BOOST_CHECK(receivedData.back().getTag<lp::IncomingFaceIdTag>() == nullptr);
 }
 
 BOOST_AUTO_TEST_CASE(ReceiveIncomingFaceIdIgnoreNack)
@@ -632,7 +631,7 @@
 
   BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 0); // not an error
   BOOST_REQUIRE_EQUAL(receivedNacks.size(), 1);
-  BOOST_CHECK(!receivedNacks.back().getLocalControlHeader().hasIncomingFaceId());
+  BOOST_CHECK(receivedNacks.back().getTag<lp::IncomingFaceIdTag>() == nullptr);
 }
 
 BOOST_AUTO_TEST_SUITE_END() // LocalFields
diff --git a/tests/daemon/face/unix-stream.t.cpp b/tests/daemon/face/unix-stream.t.cpp
index 47610af..fc528c2 100644
--- a/tests/daemon/face/unix-stream.t.cpp
+++ b/tests/daemon/face/unix-stream.t.cpp
@@ -340,187 +340,6 @@
   BOOST_CHECK_EQUAL(face2_receivedDatas    [0].getName(), data1->getName());
 }
 
-//BOOST_FIXTURE_TEST_CASE(UnixStreamTransportLocalControlHeader, EndToEndFixture)
-//{
-//  UnixStreamFactory factory;
-//
-//  shared_ptr<UnixStreamChannel> channel1 = factory.createChannel(CHANNEL_PATH1);
-//  channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated,   this, _1),
-//                   bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
-//
-//  UnixStreamTransport::protocol::socket client(g_io);
-//  client.async_connect(UnixStreamTransport::protocol::endpoint(CHANNEL_PATH1),
-//                       bind(&EndToEndFixture::client_onConnect, this, _1));
-//
-//  BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS, "Connect");
-//
-//  BOOST_REQUIRE(static_cast<bool>(face1));
-//
-//  face2 = makeFace(std::move(client));
-//  face2->onReceiveInterest.connect(bind(&EndToEndFixture::face2_onReceiveInterest, this, _1));
-//  face2->onReceiveData.connect(bind(&EndToEndFixture::face2_onReceiveData, this, _1));
-//
-//  shared_ptr<Interest> interest1 = makeInterest("ndn:/TpnzGvW9R");
-//  shared_ptr<Data>     data1     = makeData("ndn:/KfczhUqVix");
-
-//  face1->setLocalControlHeaderFeature(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID);
-//  face1->setLocalControlHeaderFeature(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID);
-//
-//  BOOST_CHECK(face1->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID));
-//  BOOST_CHECK(face1->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
-
-//  face2->setLocalControlHeaderFeature(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID);
-//  face2->setLocalControlHeaderFeature(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID);
-
-//  BOOST_CHECK(face2->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID));
-//  BOOST_CHECK(face2->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
-
-  ////////////////////////////////////////////////////////
-
-//  interest1->setIncomingFaceId(11);
-//  interest1->setNextHopFaceId(111);
-//  face1->sendInterest(*interest1);
-
-//  data1->setIncomingFaceId(22);
-//  data1->getLocalControlHeader().setNextHopFaceId(222);
-//  face1->sendData(*data1);
-
-//  BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS,
-//                      "Regular send/receive");
-
-//  BOOST_REQUIRE_EQUAL(face2_receivedInterests.size(), 1);
-//  BOOST_REQUIRE_EQUAL(face2_receivedDatas    .size(), 1);
-
-//  sending allows only IncomingFaceId, receiving allows only NextHopFaceId
-//  BOOST_CHECK_EQUAL(face2_receivedInterests[0].getLocalControlHeader().hasIncomingFaceId(), false);
-//  BOOST_CHECK_EQUAL(face2_receivedInterests[0].getLocalControlHeader().hasNextHopFaceId(), false);
-
-//  BOOST_CHECK_EQUAL(face2_receivedDatas[0].getLocalControlHeader().hasIncomingFaceId(), false);
-//  BOOST_CHECK_EQUAL(face2_receivedDatas[0].getLocalControlHeader().hasNextHopFaceId(), false);
-
-//  face1->close();
-//  face1.reset();
-
-  ////////////////////////////////////////////////////////
-
-//  client.async_connect(UnixStreamTransport::protocol::endpoint(CHANNEL_PATH1),
-//                       bind(&EndToEndFixture::client_onConnect, this, _1));
-
-//  BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS, "Connect");
-
-//  BOOST_REQUIRE(static_cast<bool>(face1));
-//  face1->setLocalControlHeaderFeature(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID);
-//  face1->setLocalControlHeaderFeature(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID);
-
-//  Block iHeader = interest1->getLocalControlHeader()
-//                  .wireEncode(*interest1, ndn::nfd::LocalControlHeader::ENCODE_INCOMING_FACE_ID |
-//                                          ndn::nfd::LocalControlHeader::ENCODE_NEXT_HOP);
-//  Block iPayload = interest1->wireEncode();
-
-//  Block dHeader = data1->getLocalControlHeader()
-//                  .wireEncode(*data1, ndn::nfd::LocalControlHeader::ENCODE_INCOMING_FACE_ID |
-//                                      ndn::nfd::LocalControlHeader::ENCODE_NEXT_HOP);
-//  Block dPayload = data1->wireEncode();
-
-//  client.async_send(std::vector<boost::asio::const_buffer>{iHeader, iPayload},
-//                    [] (const boost::system::error_code& error, size_t nBytesSent) {
-//                      BOOST_CHECK_MESSAGE(!error, error.message());
-//                    });
-//  client.async_send(std::vector<boost::asio::const_buffer>{dHeader, dPayload},
-//                    [] (const boost::system::error_code& error, size_t nBytesSent) {
-//                      BOOST_CHECK_MESSAGE(!error, error.message());
-//                    });
-
-//  BOOST_CHECK_MESSAGE(limitedIo.run(2, time::seconds(1)) == LimitedIo::EXCEED_OPS,
-//                      "Send/receive with LocalControlHeader");
-
-//  BOOST_REQUIRE_EQUAL(face1_receivedInterests.size(), 1);
-//  BOOST_REQUIRE_EQUAL(face1_receivedDatas    .size(), 1);
-
-//  BOOST_CHECK_EQUAL(face1_receivedInterests[0].getLocalControlHeader().hasIncomingFaceId(), false);
-//  BOOST_CHECK_EQUAL(face1_receivedInterests[0].getLocalControlHeader().hasNextHopFaceId(), true);
-//  BOOST_CHECK_EQUAL(face1_receivedInterests[0].getNextHopFaceId(), 111);
-
-//  BOOST_CHECK_EQUAL(face1_receivedDatas[0].getLocalControlHeader().hasIncomingFaceId(), false);
-//  BOOST_CHECK_EQUAL(face1_receivedDatas[0].getLocalControlHeader().hasNextHopFaceId(), false);
-//}
-
-
-//class SimpleEndToEndFixture : protected BaseFixture
-//{
-//public:
-//  void
-//  onFaceCreated(const shared_ptr<Face>& face)
-//  {
-//    face->onReceiveInterest.connect(bind(&SimpleEndToEndFixture::onReceiveInterest, this, _1));
-//    face->onReceiveData.connect(bind(&SimpleEndToEndFixture::onReceiveData, this, _1));
-//    face->onFail.connect(bind(&SimpleEndToEndFixture::onFail, this, face));
-
-//    if (static_cast<bool>(dynamic_pointer_cast<LocalFace>(face))) {
-//    static_pointer_cast<LocalFace>(face)->setLocalControlHeaderFeature(
-//     LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID);
-
-//    static_pointer_cast<LocalFace>(face)->setLocalControlHeaderFeature(
-//      LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID);
-//  }
-
-//    limitedIo.afterOp();
-//  }
-
-//  void
-//  onConnectFailed(const std::string& reason)
-//  {
-//    BOOST_CHECK_MESSAGE(false, reason);
-
-//    limitedIo.afterOp();
-//  }
-
-//  void
-//  onReceiveInterest(const Interest& interest)
-//  {
-//    receivedInterests.push_back(interest);
-
-//    limitedIo.afterOp();
-//  }
-
-//  void
-//  onReceiveData(const Data& data)
-//  {
-//    receivedDatas.push_back(data);
-
-//    limitedIo.afterOp();
-//  }
-
-//  void
-//  onFail(const shared_ptr<Face>& face)
-//  {
-//    limitedIo.afterOp();
-//  }
-
-//public:
-//  LimitedIo limitedIo;
-
-//  std::vector<Interest> receivedInterests;
-//  std::vector<Data> receivedDatas;
-//};
-
-
-//BOOST_FIXTURE_TEST_CASE_TEMPLATE(CorruptedInput, Dataset,
-//                                 CorruptedPackets, SimpleEndToEndFixture)
-//{
-//  UnixStreamFactory factory;
-
-//  shared_ptr<UnixStreamChannel> channel = factory.createChannel(CHANNEL_PATH1);
-//  channel->listen(bind(&SimpleEndToEndFixture::onFaceCreated,   this, _1),
-//                  bind(&SimpleEndToEndFixture::onConnectFailed, this, _1));
-
-//  DummyStreamSender<UnixStreamTransport::protocol, Dataset> sender;
-//  sender.start(UnixStreamTransport::protocol::endpoint(CHANNEL_PATH1));
-
-//  BOOST_CHECK_MESSAGE(limitedIo.run(LimitedIo::UNLIMITED_OPS, time::seconds(1)) == LimitedIo::EXCEED_TIME,
-//                      "Exception thrown for " + Dataset::getName());
-//}
-
 BOOST_AUTO_TEST_SUITE_END() // TestUnixStream
 BOOST_AUTO_TEST_SUITE_END() // Face
 
diff --git a/tests/daemon/fw/client-control-strategy.t.cpp b/tests/daemon/fw/client-control-strategy.t.cpp
index 189d42f..8f0870b 100644
--- a/tests/daemon/fw/client-control-strategy.t.cpp
+++ b/tests/daemon/fw/client-control-strategy.t.cpp
@@ -48,7 +48,6 @@
   shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
   shared_ptr<DummyFace> face3 = make_shared<DummyFace>();
   shared_ptr<DummyLocalFace> face4 = make_shared<DummyLocalFace>();
-  face4->setLocalControlHeaderFeature(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID);
   forwarder.addFace(face1);
   forwarder.addFace(face2);
   forwarder.addFace(face3);
@@ -62,7 +61,7 @@
 
   // Interest with valid NextHopFaceId
   shared_ptr<Interest> interest1 = makeInterest("ndn:/0z8r6yDDe");
-  interest1->setNextHopFaceId(face1->getId());
+  interest1->setTag(make_shared<lp::NextHopFaceIdTag>(face1->getId()));
   shared_ptr<pit::Entry> pitEntry1 = pit.insert(*interest1).first;
   pitEntry1->insertOrUpdateInRecord(face4, *interest1);
 
@@ -83,7 +82,7 @@
 
   // Interest with invalid NextHopFaceId
   shared_ptr<Interest> interest3 = makeInterest("ndn:/0z8r6yDDe");
-  interest3->setNextHopFaceId(face3->getId());
+  interest3->setTag(make_shared<lp::NextHopFaceIdTag>(face3->getId()));
   shared_ptr<pit::Entry> pitEntry3 = pit.insert(*interest3).first;
   pitEntry3->insertOrUpdateInRecord(face4, *interest3);
 
diff --git a/tests/daemon/fw/forwarder.t.cpp b/tests/daemon/fw/forwarder.t.cpp
index e40b5ad..67bce49 100644
--- a/tests/daemon/fw/forwarder.t.cpp
+++ b/tests/daemon/fw/forwarder.t.cpp
@@ -68,7 +68,8 @@
   BOOST_CHECK_EQUAL(limitedIo.run(1, time::seconds(1)), LimitedIo::EXCEED_OPS);
   BOOST_REQUIRE_EQUAL(face2->m_sentInterests.size(), 1);
   BOOST_CHECK_EQUAL(face2->m_sentInterests[0].getName(), nameAB);
-  BOOST_CHECK_EQUAL(face2->m_sentInterests[0].getIncomingFaceId(), face1->getId());
+  BOOST_REQUIRE(face2->m_sentInterests[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
+  BOOST_CHECK_EQUAL(*face2->m_sentInterests[0].getTag<lp::IncomingFaceIdTag>(), face1->getId());
   BOOST_CHECK_EQUAL(forwarder.getCounters().nInInterests, 1);
   BOOST_CHECK_EQUAL(forwarder.getCounters().nOutInterests, 1);
 
@@ -78,7 +79,8 @@
   BOOST_CHECK_EQUAL(limitedIo.run(1, time::seconds(1)), LimitedIo::EXCEED_OPS);
   BOOST_REQUIRE_EQUAL(face1->m_sentDatas.size(), 1);
   BOOST_CHECK_EQUAL(face1->m_sentDatas[0].getName(), nameABC);
-  BOOST_CHECK_EQUAL(face1->m_sentDatas[0].getIncomingFaceId(), face2->getId());
+  BOOST_REQUIRE(face1->m_sentDatas[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
+  BOOST_CHECK_EQUAL(*face1->m_sentDatas[0].getTag<lp::IncomingFaceIdTag>(), face2->getId());
   BOOST_CHECK_EQUAL(forwarder.getCounters().nInData, 1);
   BOOST_CHECK_EQUAL(forwarder.getCounters().nOutData, 1);
 }
@@ -98,7 +100,7 @@
   shared_ptr<Interest> interestA = makeInterest("ndn:/A");
   interestA->setInterestLifetime(time::seconds(4));
   shared_ptr<Data> dataA = makeData("ndn:/A");
-  dataA->setIncomingFaceId(face3->getId());
+  dataA->setTag(make_shared<lp::IncomingFaceIdTag>(face3->getId()));
 
   Fib& fib = forwarder.getFib();
   shared_ptr<fib::Entry> fibEntry = fib.insert(Name("ndn:/A")).first;
@@ -117,7 +119,8 @@
 
   BOOST_REQUIRE_EQUAL(face1->m_sentDatas.size(), 1);
   // IncomingFaceId field should be reset to represent CS
-  BOOST_CHECK_EQUAL(face1->m_sentDatas[0].getIncomingFaceId(), FACEID_CONTENT_STORE);
+  BOOST_REQUIRE(face1->m_sentDatas[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
+  BOOST_CHECK_EQUAL(*face1->m_sentDatas[0].getTag<lp::IncomingFaceIdTag>(), FACEID_CONTENT_STORE);
 
   limitedIo.run(LimitedIo::UNLIMITED_OPS, time::milliseconds(500));
   // PIT entry should not be left behind
diff --git a/tests/daemon/mgmt/face-manager.t.cpp b/tests/daemon/mgmt/face-manager.t.cpp
index 8e4da1f..02bcd78 100644
--- a/tests/daemon/mgmt/face-manager.t.cpp
+++ b/tests/daemon/mgmt/face-manager.t.cpp
@@ -149,86 +149,6 @@
   BOOST_CHECK_EQUAL(addedFace->getId(), -1);
 }
 
-BOOST_AUTO_TEST_CASE(EnableDisableLocalControl)
-{
-  auto nonLocalFace = addFace<DummyFace>(true); // clear notification
-  auto localFace = addFace<DummyLocalFace>(true); // clear notification
-  BOOST_CHECK(localFace->isLocal());
-  BOOST_CHECK(!nonLocalFace->isLocal());
-
-  std::vector<Name> commandNames;
-  auto testLocalControl = [&] (const Name& name, const ControlParameters& params, uint64_t faceId) {
-    auto command = makeControlCommandRequest(name, params,
-                                             [faceId] (shared_ptr<Interest> interest) {
-                                               interest->setIncomingFaceId(faceId);
-                                             });
-    receiveInterest(command);
-    commandNames.push_back(command->getName());
-  };
-
-  auto paramsF = ControlParameters().setLocalControlFeature(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID);
-  auto paramsN = ControlParameters().setLocalControlFeature(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID);
-
-  // non-existing face: 0~3
-  testLocalControl("/localhost/nfd/faces/enable-local-control", paramsF, FACEID_NULL);
-  testLocalControl("/localhost/nfd/faces/disable-local-control", paramsF, FACEID_NULL);
-  testLocalControl("/localhost/nfd/faces/enable-local-control", paramsN, FACEID_NULL);
-  testLocalControl("/localhost/nfd/faces/disable-local-control", paramsN, FACEID_NULL);
-
-  // non-local face: 4~7
-  testLocalControl("/localhost/nfd/faces/enable-local-control", paramsF, nonLocalFace->getId());
-  testLocalControl("/localhost/nfd/faces/disable-local-control", paramsF, nonLocalFace->getId());
-  testLocalControl("/localhost/nfd/faces/enable-local-control", paramsN, nonLocalFace->getId());
-  testLocalControl("/localhost/nfd/faces/disable-local-control", paramsN, nonLocalFace->getId());
-
-  // enableLocalControl for Incoming FaceId on existing local face:
-  testLocalControl("/localhost/nfd/faces/enable-local-control", paramsF, localFace->getId()); // 8
-  BOOST_CHECK(localFace->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID));
-  BOOST_CHECK(!localFace->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
-
-  // disableLocalControl for Incoming FaceId on existing local face
-  testLocalControl("/localhost/nfd/faces/disable-local-control", paramsF, localFace->getId()); // 9
-  BOOST_CHECK(!localFace->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID));
-  BOOST_CHECK(!localFace->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
-
-  // enableLocalControl for NextHop ID on existing local face
-  testLocalControl("/localhost/nfd/faces/enable-local-control", paramsN, localFace->getId()); // 10
-  BOOST_CHECK(!localFace->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID));
-  BOOST_CHECK(localFace->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
-
-  // disableLocalControl for NextHop ID on existing local face
-  testLocalControl("/localhost/nfd/faces/disable-local-control", paramsN, localFace->getId()); // 11
-  BOOST_CHECK(!localFace->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_INCOMING_FACE_ID));
-  BOOST_CHECK(!localFace->isLocalControlHeaderEnabled(LOCAL_CONTROL_FEATURE_NEXT_HOP_FACE_ID));
-
-  // check responses
-  BOOST_REQUIRE_EQUAL(m_responses.size(), 12);
-  BOOST_CHECK_EQUAL(checkResponse(0,  commandNames[0],  ControlResponse(410, "Face not found")),
-                    CheckResponseResult::OK);
-  BOOST_CHECK_EQUAL(checkResponse(1,  commandNames[1],  ControlResponse(410, "Face not found")),
-                    CheckResponseResult::OK);
-  BOOST_CHECK_EQUAL(checkResponse(2,  commandNames[2],  ControlResponse(410, "Face not found")),
-                    CheckResponseResult::OK);
-  BOOST_CHECK_EQUAL(checkResponse(3,  commandNames[3],  ControlResponse(410, "Face not found")),
-                    CheckResponseResult::OK);
-  BOOST_CHECK_EQUAL(checkResponse(4,  commandNames[4],  ControlResponse(412, "Face is non-local")),
-                    CheckResponseResult::OK);
-  BOOST_CHECK_EQUAL(checkResponse(5,  commandNames[5],  ControlResponse(412, "Face is non-local")),
-                    CheckResponseResult::OK);
-  BOOST_CHECK_EQUAL(checkResponse(6,  commandNames[6],  ControlResponse(412, "Face is non-local")),
-                    CheckResponseResult::OK);
-  BOOST_CHECK_EQUAL(checkResponse(7,  commandNames[7],  ControlResponse(412, "Face is non-local")),
-                    CheckResponseResult::OK);
-  BOOST_CHECK_EQUAL(checkResponse(8,  commandNames[8],  makeResponse(200, "OK", paramsF)),
-                    CheckResponseResult::OK);
-  BOOST_CHECK_EQUAL(checkResponse(9,  commandNames[9],  makeResponse(200, "OK", paramsF)),
-                    CheckResponseResult::OK);
-  BOOST_CHECK_EQUAL(checkResponse(10, commandNames[10], makeResponse(200, "OK", paramsN)),
-                    CheckResponseResult::OK);
-  BOOST_CHECK_EQUAL(checkResponse(11, commandNames[11], makeResponse(200, "OK", paramsN)),
-                    CheckResponseResult::OK);
-}
-
 class TestFace : public DummyFace
 {
 public:
diff --git a/tests/daemon/mgmt/fib-manager.t.cpp b/tests/daemon/mgmt/fib-manager.t.cpp
index 513536c..945a07e 100644
--- a/tests/daemon/mgmt/fib-manager.t.cpp
+++ b/tests/daemon/mgmt/fib-manager.t.cpp
@@ -180,9 +180,9 @@
   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);
-                                             });
+                   [&faceId] (shared_ptr<Interest> interest) {
+                     interest->setTag(make_shared<lp::IncomingFaceIdTag>(faceId));
+                   });
     m_responses.clear();
     expectedName = command->getName();
     expectedResponse = makeResponse(200, "Success", parameters.setFaceId(faceId));
@@ -328,9 +328,9 @@
   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);
-                                             });
+                   [face] (shared_ptr<Interest> interest) {
+                     interest->setTag(make_shared<lp::IncomingFaceIdTag>(face));
+                   });
     expectedName = command->getName();
     expectedResponse = makeResponse(200, "Success", parameters.setFaceId(face));
     receiveInterest(command);
diff --git a/tests/daemon/table/cs-policy-lru.t.cpp b/tests/daemon/table/cs-policy-lru.t.cpp
index 02ce3c0..a4e76a8 100644
--- a/tests/daemon/table/cs-policy-lru.t.cpp
+++ b/tests/daemon/table/cs-policy-lru.t.cpp
@@ -23,8 +23,8 @@
  * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "table/cs.hpp"
 #include "table/cs-policy-lru.hpp"
+#include "table/cs.hpp"
 #include <ndn-cxx/util/crypto.hpp>
 
 #include "tests/test-common.hpp"
@@ -34,7 +34,6 @@
 namespace tests {
 
 using namespace nfd::tests;
-using ndn::nfd::LocalControlHeader;
 
 BOOST_AUTO_TEST_SUITE(CsLru)
 
diff --git a/tests/daemon/table/cs-policy-priority-fifo.t.cpp b/tests/daemon/table/cs-policy-priority-fifo.t.cpp
index 8fd1746..8f365d4 100644
--- a/tests/daemon/table/cs-policy-priority-fifo.t.cpp
+++ b/tests/daemon/table/cs-policy-priority-fifo.t.cpp
@@ -23,8 +23,8 @@
  * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "table/cs.hpp"
 #include "table/cs-policy-priority-fifo.hpp"
+#include "table/cs.hpp"
 #include <ndn-cxx/util/crypto.hpp>
 
 #include "tests/test-common.hpp"
@@ -34,7 +34,6 @@
 namespace tests {
 
 using namespace nfd::tests;
-using ndn::nfd::LocalControlHeader;
 
 BOOST_AUTO_TEST_SUITE(CsPriorityFifo)
 
diff --git a/tests/daemon/table/cs.t.cpp b/tests/daemon/table/cs.t.cpp
index 0b3bebb..63caa44 100644
--- a/tests/daemon/table/cs.t.cpp
+++ b/tests/daemon/table/cs.t.cpp
@@ -35,7 +35,6 @@
 namespace tests {
 
 using namespace nfd::tests;
-using ndn::nfd::LocalControlHeader;
 
 BOOST_FIXTURE_TEST_SUITE(TableCs, BaseFixture)
 
@@ -316,13 +315,16 @@
 
 BOOST_AUTO_TEST_SUITE_END()
 
-BOOST_AUTO_TEST_CASE(CachingPolicyNoCache)
+BOOST_AUTO_TEST_CASE(CachePolicyNoCache)
 {
   Cs cs(3);
 
   shared_ptr<Data> dataA = makeData("ndn:/A");
-  dataA->getLocalControlHeader().setCachingPolicy(LocalControlHeader::CachingPolicy::NO_CACHE);
   dataA->wireEncode();
+
+  dataA->setTag(make_shared<lp::CachePolicyTag>(
+                lp::CachePolicy().setPolicy(lp::CachePolicyType::NO_CACHE)));
+
   BOOST_CHECK_EQUAL(cs.insert(*dataA), false);
 
   cs.find(Interest("ndn:/A"),
diff --git a/tests/rib/auto-prefix-propagator.t.cpp b/tests/rib/auto-prefix-propagator.t.cpp
index 67e7b1b..3699815 100644
--- a/tests/rib/auto-prefix-propagator.t.cpp
+++ b/tests/rib/auto-prefix-propagator.t.cpp
@@ -457,15 +457,15 @@
   BOOST_REQUIRE_EQUAL(m_requests.size(), 1);
   BOOST_CHECK_EQUAL(checkRequest(0, "register", "/test/A"), CheckRequestResult::OK);
 
-  advanceClocks(time::milliseconds(1), 1050); // wait for the 1st retry
+  advanceClocks(time::milliseconds(10), time::milliseconds(1050)); // wait for the 1st retry
   BOOST_REQUIRE_EQUAL(m_requests.size(), 2);
   BOOST_CHECK_EQUAL(checkRequest(1, "register", "/test/A"), CheckRequestResult::OK);
 
-  advanceClocks(time::milliseconds(1), 2050); // wait for the 2nd retry, 2 times
+  advanceClocks(time::milliseconds(10), time::milliseconds(2050)); // wait for the 2nd retry, 2 times
   BOOST_REQUIRE_EQUAL(m_requests.size(), 3);
   BOOST_CHECK_EQUAL(checkRequest(2, "register", "/test/A"), CheckRequestResult::OK);
 
-  advanceClocks(time::milliseconds(1), 2050); // wait for the 3rd retry, reach the upper bound
+  advanceClocks(time::milliseconds(10), time::milliseconds(2050)); // wait for the 3rd retry, reach the upper bound
   BOOST_REQUIRE_EQUAL(m_requests.size(), 4);
   BOOST_CHECK_EQUAL(checkRequest(3, "register", "/test/A"), CheckRequestResult::OK);
 }
diff --git a/tests/rib/rib-manager.t.cpp b/tests/rib/rib-manager.t.cpp
index 94a37af..1287284 100644
--- a/tests/rib/rib-manager.t.cpp
+++ b/tests/rib/rib-manager.t.cpp
@@ -28,29 +28,25 @@
 #include "rib/rib-status-publisher-common.hpp"
 
 #include "tests/test-common.hpp"
-#include "tests/limited-io.hpp"
 #include <ndn-cxx/util/dummy-client-face.hpp>
 
 namespace nfd {
 namespace rib {
 namespace tests {
 
-class RibManagerFixture : public nfd::tests::BaseFixture
+using namespace nfd::tests;
+
+class RibManagerFixture : public UnitTestTimeFixture
 {
 public:
   RibManagerFixture()
-    : COMMAND_PREFIX("/localhost/nfd/rib")
-    , ADD_NEXTHOP_VERB("add-nexthop")
-    , REMOVE_NEXTHOP_VERB("remove-nexthop")
-    , REGISTER_COMMAND("/localhost/nfd/rib/register")
-    , UNREGISTER_COMMAND("/localhost/nfd/rib/unregister")
   {
-    face = ndn::util::makeDummyClientFace();
+    face = ndn::util::makeDummyClientFace(g_io);
 
     manager = make_shared<RibManager>(*face, keyChain);
     manager->registerWithNfd();
 
-    face->processEvents(time::milliseconds(1));
+    advanceClocks(time::milliseconds(1));
     face->sentInterests.clear();
   }
 
@@ -73,18 +69,20 @@
   }
 
   void
-  receiveCommandInterest(const Name& name, ControlParameters& parameters)
+  receiveCommandInterest(const Name& name, ControlParameters& parameters,
+                         uint64_t incomingFaceId = DEFAULT_INCOMING_FACE_ID)
   {
     Name commandName = name;
     commandName.append(parameters.wireEncode());
 
     Interest commandInterest(commandName);
+    commandInterest.setTag(make_shared<lp::IncomingFaceIdTag>(incomingFaceId));
 
     manager->m_managedRib.m_onSendBatchFromQueue = bind(&RibManagerFixture::onSendBatchFromQueue,
                                                         this, _1, parameters);
 
     face->receive(commandInterest);
-    face->processEvents(time::milliseconds(1));
+    advanceClocks(time::milliseconds(1));
   }
 
   void
@@ -109,14 +107,23 @@
   shared_ptr<ndn::util::DummyClientFace> face;
   ndn::KeyChain keyChain;
 
-  const Name COMMAND_PREFIX;
-  const Name::Component ADD_NEXTHOP_VERB;
-  const Name::Component REMOVE_NEXTHOP_VERB;
+  static const uint64_t DEFAULT_INCOMING_FACE_ID;
 
-  const Name REGISTER_COMMAND;
-  const Name UNREGISTER_COMMAND;
+  static const Name COMMAND_PREFIX;
+  static const name::Component ADD_NEXTHOP_VERB;
+  static const name::Component REMOVE_NEXTHOP_VERB;
+
+  static const Name REGISTER_COMMAND;
+  static const Name UNREGISTER_COMMAND;
 };
 
+const uint64_t RibManagerFixture::DEFAULT_INCOMING_FACE_ID = 25122;
+const Name RibManagerFixture::COMMAND_PREFIX("/localhost/nfd/rib");
+const name::Component RibManagerFixture::ADD_NEXTHOP_VERB("add-nexthop");
+const name::Component RibManagerFixture::REMOVE_NEXTHOP_VERB("remove-nexthop");
+const Name RibManagerFixture::REGISTER_COMMAND("/localhost/nfd/rib/register");
+const Name RibManagerFixture::UNREGISTER_COMMAND("/localhost/nfd/rib/unregister");
+
 class AuthorizedRibManager : public RibManagerFixture
 {
 public:
@@ -232,6 +239,55 @@
   BOOST_CHECK_EQUAL(extractedParameters.getFaceId(), removeParameters.getFaceId());
 }
 
+BOOST_FIXTURE_TEST_CASE(SelfRegister, AuthorizedRibManager)
+{
+  ControlParameters parameters;
+  parameters
+    .setName("/hello");
+
+  receiveCommandInterest(REGISTER_COMMAND, parameters, 10129);
+
+  BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
+
+  Interest& request = face->sentInterests[0];
+
+  ControlParameters extractedParameters;
+  Name::Component verb;
+  extractParameters(request, verb, extractedParameters);
+
+  BOOST_CHECK_EQUAL(verb, ADD_NEXTHOP_VERB);
+  BOOST_CHECK_EQUAL(extractedParameters.getName(), parameters.getName());
+  BOOST_CHECK_EQUAL(extractedParameters.getFaceId(), 10129);
+}
+
+BOOST_FIXTURE_TEST_CASE(SelfUnregister, AuthorizedRibManager)
+{
+  ControlParameters addParameters;
+  addParameters
+    .setName("/hello")
+    .setFaceId(10129);
+
+  receiveCommandInterest(REGISTER_COMMAND, addParameters);
+  face->sentInterests.clear();
+
+  ControlParameters removeParameters;
+  removeParameters
+    .setName("/hello");
+
+  receiveCommandInterest(UNREGISTER_COMMAND, removeParameters, 10129);
+
+  BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
+
+  Interest& request = face->sentInterests[0];
+
+  ControlParameters extractedParameters;
+  Name::Component verb;
+  extractParameters(request, verb, extractedParameters);
+
+  BOOST_CHECK_EQUAL(verb, REMOVE_NEXTHOP_VERB);
+  BOOST_CHECK_EQUAL(extractedParameters.getName(), removeParameters.getName());
+  BOOST_CHECK_EQUAL(extractedParameters.getFaceId(), 10129);
+}
 
 BOOST_FIXTURE_TEST_CASE(UnauthorizedCommand, UnauthorizedRibManager)
 {
@@ -264,7 +320,7 @@
   manager->m_managedRib.insert(prefix, route);
 
   face->receive(Interest("/localhost/nfd/rib/list"));
-  face->processEvents(time::milliseconds(1));
+  advanceClocks(time::milliseconds(1));
 
   BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
   RibStatusPublisherFixture::decodeRibEntryBlock(face->sentDatas[0], prefix, route);
@@ -298,8 +354,7 @@
   addParameters.setExpirationPeriod(ndn::time::milliseconds::max());
   receiveCommandInterest(REGISTER_COMMAND, addParameters);
 
-  nfd::tests::LimitedIo limitedIo;
-  limitedIo.run(nfd::tests::LimitedIo::UNLIMITED_OPS, time::seconds(1));
+  advanceClocks(time::milliseconds(100), time::seconds(1));
 
   BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 1);
 }
@@ -338,8 +393,7 @@
   manager->removeInvalidFaces(buffer);
 
   // Run scheduler
-  nfd::tests::LimitedIo limitedIo;
-  limitedIo.run(nfd::tests::LimitedIo::UNLIMITED_OPS, time::seconds(1));
+  advanceClocks(time::milliseconds(100), time::seconds(1));
 
   BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 1);
 
@@ -399,8 +453,7 @@
   BOOST_REQUIRE_EQUAL(manager->m_managedRib.size(), 1);
 
   // Route should expire
-  nfd::tests::LimitedIo limitedIo;
-  limitedIo.run(nfd::tests::LimitedIo::UNLIMITED_OPS, time::seconds(1));
+  advanceClocks(time::milliseconds(100), time::seconds(1));
 
   BOOST_CHECK_EQUAL(manager->m_managedRib.size(), 0);
 }
diff --git a/tests/rib/rib-status-publisher-common.hpp b/tests/rib/rib-status-publisher-common.hpp
index c4055d5..eee9a5e 100644
--- a/tests/rib/rib-status-publisher-common.hpp
+++ b/tests/rib/rib-status-publisher-common.hpp
@@ -34,6 +34,7 @@
 #include <ndn-cxx/management/nfd-control-parameters.hpp>
 #include <ndn-cxx/management/nfd-rib-entry.hpp>
 #include <ndn-cxx/encoding/tlv.hpp>
+#include <ndn-cxx/encoding/tlv-nfd.hpp>
 
 namespace nfd {
 namespace rib {
diff --git a/tests/rib/rib.t.cpp b/tests/rib/rib.t.cpp
index 25440dd..91445c4 100644
--- a/tests/rib/rib.t.cpp
+++ b/tests/rib/rib.t.cpp
@@ -24,6 +24,7 @@
  */
 
 #include "rib/rib.hpp"
+#include <ndn-cxx/encoding/tlv-nfd.hpp>
 
 #include "tests/test-common.hpp"