fw: replace Link with forwarding hint

Forwarding now processes forwarding hint on Interests,
and no longer considers the Link object.

refs #4055

Change-Id: I0331687ee8ec31afa2f1a105e903670689647c4d
diff --git a/core/common.hpp b/core/common.hpp
index b19a19c..b4da8a7 100644
--- a/core/common.hpp
+++ b/core/common.hpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -57,9 +57,10 @@
 #include <vector>
 
 #include <ndn-cxx/data.hpp>
+#include <ndn-cxx/delegation.hpp>
+#include <ndn-cxx/delegation-list.hpp>
 #include <ndn-cxx/exclude.hpp>
 #include <ndn-cxx/interest.hpp>
-#include <ndn-cxx/link.hpp>
 #include <ndn-cxx/name.hpp>
 #include <ndn-cxx/encoding/block.hpp>
 #include <ndn-cxx/lp/nack.hpp>
@@ -100,12 +101,13 @@
 
 using ndn::Block;
 using ndn::Data;
+using ndn::Delegation;
+using ndn::DelegationList;
 using ndn::Exclude;
 using ndn::FaceUri;
 using ndn::Interest;
 using ndn::Name;
 using ndn::PartialName;
-using ndn::Link;
 
 namespace tlv {
 // Don't write "namespace tlv = ndn::tlv", because NFD can add other members into this namespace.
diff --git a/daemon/fw/forwarder.cpp b/daemon/fw/forwarder.cpp
index 3263b43..9e0b8bb 100644
--- a/daemon/fw/forwarder.cpp
+++ b/daemon/fw/forwarder.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -73,53 +73,6 @@
 Forwarder::~Forwarder() = default;
 
 void
-Forwarder::startProcessInterest(Face& face, const Interest& interest)
-{
-  // check fields used by forwarding are well-formed
-  try {
-    if (interest.hasLink()) {
-      interest.getLink();
-    }
-  }
-  catch (const tlv::Error&) {
-    NFD_LOG_DEBUG("startProcessInterest face=" << face.getId() <<
-                  " interest=" << interest.getName() << " malformed");
-    // It's safe to call interest.getName() because Name has been fully parsed
-    return;
-  }
-
-  this->onIncomingInterest(face, interest);
-}
-
-void
-Forwarder::startProcessData(Face& face, const Data& data)
-{
-  // check fields used by forwarding are well-formed
-  // (none needed)
-
-  this->onIncomingData(face, data);
-}
-
-void
-Forwarder::startProcessNack(Face& face, const lp::Nack& nack)
-{
-  // check fields used by forwarding are well-formed
-  try {
-    if (nack.getInterest().hasLink()) {
-      nack.getInterest().getLink();
-    }
-  }
-  catch (const tlv::Error&) {
-    NFD_LOG_DEBUG("startProcessNack face=" << face.getId() <<
-                  " nack=" << nack.getInterest().getName() <<
-                  "~" << nack.getReason() << " malformed");
-    return;
-  }
-
-  this->onIncomingNack(face, nack);
-}
-
-void
 Forwarder::onIncomingInterest(Face& inFace, const Interest& interest)
 {
   // receive Interest
@@ -146,13 +99,12 @@
     return;
   }
 
-  // strip Link object if Interest has reached producer region
-  if (interest.hasLink() && m_networkRegionTable.isInProducerRegion(interest.getLink())) {
+  // strip forwarding hint if Interest has reached producer region
+  if (!interest.getForwardingHint().empty() &&
+      m_networkRegionTable.isInProducerRegion(interest.getForwardingHint())) {
     NFD_LOG_DEBUG("onIncomingInterest face=" << inFace.getId() <<
                   " interest=" << interest.getName() << " reaching-producer-region");
-    Interest& interestRef = const_cast<Interest&>(interest);
-    interestRef.unsetLink();
-    interestRef.unsetSelectedDelegation();
+    const_cast<Interest&>(interest).setForwardingHint({});
   }
 
   // PIT insert
diff --git a/daemon/fw/forwarder.hpp b/daemon/fw/forwarder.hpp
index b0cc156..d2e73a8 100644
--- a/daemon/fw/forwarder.hpp
+++ b/daemon/fw/forwarder.hpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -106,24 +106,33 @@
 public: // forwarding entrypoints and tables
   /** \brief start incoming Interest processing
    *  \param face face on which Interest is received
-   *  \param interest the incoming Interest, must be created with make_shared
+   *  \param interest the incoming Interest, must be well-formed and created with make_shared
    */
   void
-  startProcessInterest(Face& face, const Interest& interest);
+  startProcessInterest(Face& face, const Interest& interest)
+  {
+    this->onIncomingInterest(face, interest);
+  }
 
   /** \brief start incoming Data processing
    *  \param face face on which Data is received
-   *  \param data the incoming Data, must be created with make_shared
+   *  \param data the incoming Data, must be well-formed and created with make_shared
    */
   void
-  startProcessData(Face& face, const Data& data);
+  startProcessData(Face& face, const Data& data)
+  {
+    this->onIncomingData(face, data);
+  }
 
   /** \brief start incoming Nack processing
    *  \param face face on which Nack is received
-   *  \param nack the incoming Nack, must be created with make_shared
+   *  \param nack the incoming Nack, must be well-formed
    */
   void
-  startProcessNack(Face& face, const lp::Nack& nack);
+  startProcessNack(Face& face, const lp::Nack& nack)
+  {
+    this->onIncomingNack(face, nack);
+  }
 
   NameTree&
   getNameTree()
diff --git a/daemon/fw/strategy.cpp b/daemon/fw/strategy.cpp
index 0419a22..fea2164 100644
--- a/daemon/fw/strategy.cpp
+++ b/daemon/fw/strategy.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -198,54 +198,36 @@
   const Fib& fib = m_forwarder.getFib();
 
   const Interest& interest = pitEntry.getInterest();
-  // has Link object?
-  if (!interest.hasLink()) {
+  // has forwarding hint?
+  if (interest.getForwardingHint().empty()) {
     // FIB lookup with Interest name
     const fib::Entry& fibEntry = fib.findLongestPrefixMatch(pitEntry);
-    NFD_LOG_TRACE("lookupFib noLinkObject found=" << fibEntry.getPrefix());
+    NFD_LOG_TRACE("lookupFib noForwardingHint found=" << fibEntry.getPrefix());
     return fibEntry;
   }
 
-  const Link& link = interest.getLink();
+  const DelegationList& fh = interest.getForwardingHint();
+  // Forwarding hint should have been stripped by incoming Interest pipeline when reaching producer region
+  BOOST_ASSERT(!m_forwarder.getNetworkRegionTable().isInProducerRegion(fh));
 
-  // Link should have been stripped by incoming Interest pipeline when reaching producer region
-  BOOST_ASSERT(!m_forwarder.getNetworkRegionTable().isInProducerRegion(link));
-
-  // has SelectedDelegation?
-  if (interest.hasSelectedDelegation()) {
-    // FIB lookup with SelectedDelegation
-    Name selectedDelegation = interest.getSelectedDelegation();
-    const fib::Entry& fibEntry = fib.findLongestPrefixMatch(selectedDelegation);
-    NFD_LOG_TRACE("lookupFib hasSelectedDelegation=" << selectedDelegation << " found=" << fibEntry.getPrefix());
-    return fibEntry;
-  }
-
-  // FIB lookup with first delegation Name
-  const fib::Entry& fibEntry0 = fib.findLongestPrefixMatch(link.getDelegations().begin()->second);
-  // in default-free zone?
-  bool isDefaultFreeZone = !(fibEntry0.getPrefix().size() == 0 && fibEntry0.hasNextHops());
-  if (!isDefaultFreeZone) {
-    NFD_LOG_TRACE("lookupFib inConsumerRegion found=" << fibEntry0.getPrefix());
-    return fibEntry0;
-  }
-
-  // choose and set SelectedDelegation
-  for (const std::pair<uint32_t, Name>& delegation : link.getDelegations()) {
-    const Name& delegationName = delegation.second;
-    const fib::Entry& fibEntry = fib.findLongestPrefixMatch(delegationName);
-    if (fibEntry.hasNextHops()) {
-      /// \todo Don't modify in-record Interests.
-      ///       Set SelectedDelegation in outgoing Interest pipeline.
-      std::for_each(pitEntry.in_begin(), pitEntry.in_end(),
-        [&delegationName] (const pit::InRecord& inR) {
-          const_cast<Interest&>(inR.getInterest()).setSelectedDelegation(delegationName);
-        });
-      NFD_LOG_TRACE("lookupFib enterDefaultFreeZone setSelectedDelegation=" << delegationName);
-      return fibEntry;
+  const fib::Entry* fibEntry = nullptr;
+  for (const Delegation& del : fh) {
+    fibEntry = &fib.findLongestPrefixMatch(del.name);
+    if (fibEntry->hasNextHops()) {
+      if (fibEntry->getPrefix().size() == 0) {
+        // in consumer region, return the default route
+        NFD_LOG_TRACE("lookupFib inConsumerRegion found=" << fibEntry->getPrefix());
+      }
+      else {
+        // in default-free zone, use the first delegation that finds a FIB entry
+        NFD_LOG_TRACE("lookupFib delegation=" << del.name << " found=" << fibEntry->getPrefix());
+      }
+      return *fibEntry;
     }
+    BOOST_ASSERT(fibEntry->getPrefix().size() == 0); // only ndn:/ FIB entry can have zero nexthop
   }
-  BOOST_ASSERT(false);
-  return fibEntry0;
+  BOOST_ASSERT(fibEntry != nullptr && fibEntry->getPrefix().size() == 0);
+  return *fibEntry; // only occurs if no delegation finds a FIB nexthop
 }
 
 } // namespace fw
diff --git a/daemon/table/network-region-table.cpp b/daemon/table/network-region-table.cpp
index df6ca58..828a35b 100644
--- a/daemon/table/network-region-table.cpp
+++ b/daemon/table/network-region-table.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -29,11 +29,11 @@
 namespace nfd {
 
 bool
-NetworkRegionTable::isInProducerRegion(const Link& link) const
+NetworkRegionTable::isInProducerRegion(const DelegationList& forwardingHint) const
 {
   for (const Name& regionName : *this) {
-    for (const Name& delegationName : boost::adaptors::values(link.getDelegations())) {
-      if (delegationName.isPrefixOf(regionName)) {
+    for (const Delegation& delegation : forwardingHint) {
+      if (delegation.name.isPrefixOf(regionName)) {
         return true;
       }
     }
diff --git a/daemon/table/network-region-table.hpp b/daemon/table/network-region-table.hpp
index 663d2f5..22da902 100644
--- a/daemon/table/network-region-table.hpp
+++ b/daemon/table/network-region-table.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -41,16 +41,16 @@
 {
 public:
   /** \brief determines whether an Interest has reached a producer region
-   *  \param link the Link object on an Interest
+   *  \param forwardingHint forwarding hint of an Interest
    *  \retval true the Interest has reached a producer region
    *  \retval false the Interest has not reached a producer region
    *
-   *  If any delegation names in the Link object is a prefix of any region name,
+   *  If any delegation name in the forwarding hint is a prefix of any region name,
    *  the Interest has reached the producer region and should be forwarded according to ‎its Name;
-   *  otherwise, the Interest should be forwarded according to the delegations.
+   *  otherwise, the Interest should be forwarded according to the forwarding hint.
    */
   bool
-  isInProducerRegion(const Link& link) const;
+  isInProducerRegion(const DelegationList& forwardingHint) const;
 };
 
 } // namespace nfd
diff --git a/tests/daemon/fw/forwarder.t.cpp b/tests/daemon/fw/forwarder.t.cpp
index c669454..c01859f 100644
--- a/tests/daemon/fw/forwarder.t.cpp
+++ b/tests/daemon/fw/forwarder.t.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -588,61 +588,6 @@
   BOOST_CHECK_EQUAL(pit.size(), 0);
 }
 
-
-class MalformedPacketFixture : public UnitTestTimeFixture
-{
-protected:
-  MalformedPacketFixture()
-    : face1(make_shared<DummyFace>())
-    , face2(make_shared<DummyFace>())
-  {
-    forwarder.addFace(face1);
-    forwarder.addFace(face2);
-  }
-
-  void
-  processInterest(shared_ptr<Interest> badInterest)
-  {
-    forwarder.startProcessInterest(*face1, *badInterest);
-    this->continueProcessPacket();
-  }
-
-  // processData
-
-  // processNack
-
-private:
-  void
-  continueProcessPacket()
-  {
-    this->advanceClocks(time::milliseconds(10), time::seconds(6));
-  }
-
-protected:
-  Forwarder forwarder;
-  shared_ptr<DummyFace> face1; // face of incoming bad packet
-  shared_ptr<DummyFace> face2; // another face for setting up states
-};
-
-BOOST_FIXTURE_TEST_SUITE(MalformedPacket, MalformedPacketFixture)
-
-BOOST_AUTO_TEST_CASE(BadLink)
-{
-  shared_ptr<Interest> goodInterest = makeInterest("ndn:/");
-  Block wire = goodInterest->wireEncode();
-  wire.push_back(ndn::encoding::makeEmptyBlock(tlv::Data)); // bad Link
-  wire.encode();
-
-  auto badInterest = make_shared<Interest>();
-  BOOST_REQUIRE_NO_THROW(badInterest->wireDecode(wire));
-  BOOST_REQUIRE(badInterest->hasLink());
-  BOOST_REQUIRE_THROW(badInterest->getLink(), tlv::Error);
-
-  BOOST_CHECK_NO_THROW(this->processInterest(badInterest));
-}
-
-BOOST_AUTO_TEST_SUITE_END() // MalformedPacket
-
 BOOST_AUTO_TEST_SUITE_END()
 BOOST_AUTO_TEST_SUITE_END()
 
diff --git a/tests/daemon/fw/link-forwarding.t.cpp b/tests/daemon/fw/forwarding-hint.t.cpp
similarity index 79%
rename from tests/daemon/fw/link-forwarding.t.cpp
rename to tests/daemon/fw/forwarding-hint.t.cpp
index 8bf1dfb..7d0d37d 100644
--- a/tests/daemon/fw/link-forwarding.t.cpp
+++ b/tests/daemon/fw/forwarding-hint.t.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -34,7 +34,7 @@
 using namespace nfd::tests;
 
 BOOST_AUTO_TEST_SUITE(Fw)
-BOOST_AUTO_TEST_SUITE(TestLinkForwarding)
+BOOST_AUTO_TEST_SUITE(TestForwardingHint)
 
 /**
  *      /arizona/cs/avenir
@@ -95,8 +95,6 @@
     topo.registerPrefix(nodeH, linkHC->getFace(nodeH), "/ucla", 20);
     topo.registerPrefix(nodeC, linkCS->getFace(nodeC), "/ucla", 10);
     topo.registerPrefix(nodeS, linkSQ->getFace(nodeS), "/net/ndnsim", 10);
-
-    linkObject = makeLink("/net/ndnsim", {{10, "/telia/terabits"}, {20, "/ucla/cs"}});
   }
 
   /** \brief express an Interest with Link object from consumerA
@@ -105,7 +103,7 @@
   consumerExpressInterest(int seq)
   {
     auto interest = makeInterest(Name("/net/ndnsim").appendNumber(seq));
-    interest->setLink(linkObject->wireEncode());
+    interest->setForwardingHint({delTelia, delUcla});
     consumerA->getClientFace().expressInterest(*interest, nullptr, nullptr, nullptr);
   }
 
@@ -114,7 +112,9 @@
   TopologyNode nodeA, nodeH, nodeT, nodeP, nodeC, nodeS, nodeQ;
   shared_ptr<TopologyLink> linkAH, linkHT, linkTP, linkHC, linkCS, linkSQ;
   shared_ptr<TopologyAppLink> consumerA, producerP, producerQ;
-  shared_ptr<Link> linkObject;
+
+  Delegation delTelia = {10, "/telia/terabits"};
+  Delegation delUcla = {20, "/ucla/cs"};
 };
 
 BOOST_FIXTURE_TEST_SUITE(NdnsimTeliaUclaTopology, NdnsimTeliaUclaTopologyFixture)
@@ -124,24 +124,20 @@
   this->consumerExpressInterest(1);
   this->advanceClocks(time::milliseconds(11), 20);
 
-  // A forwards Interest according to default route, no change to Link and SelectedDelegation
+  // A forwards Interest according to default route, no change to forwarding hint
   BOOST_CHECK_EQUAL(linkAH->getFace(nodeA).getCounters().nOutInterests, 1);
   const Interest& interestAH = topo.getPcap(linkAH->getFace(nodeA)).sentInterests.at(0);
-  BOOST_CHECK_EQUAL(interestAH.hasLink(), true);
-  BOOST_CHECK_EQUAL(interestAH.hasSelectedDelegation(), false);
+  BOOST_CHECK_EQUAL(interestAH.getForwardingHint(), DelegationList({delTelia, delUcla}));
 
-  // H prefers T, and sets SelectedDelegation
+  // H prefers T, no change to forwarding hint
   BOOST_CHECK_EQUAL(linkHT->getFace(nodeH).getCounters().nOutInterests, 1);
   const Interest& interestHT = topo.getPcap(linkHT->getFace(nodeH)).sentInterests.at(0);
-  BOOST_CHECK_EQUAL(interestHT.hasLink(), true);
-  BOOST_CHECK_EQUAL(interestHT.hasSelectedDelegation(), true);
-  BOOST_CHECK_EQUAL(interestHT.getSelectedDelegation(), "/telia/terabits");
+  BOOST_CHECK_EQUAL(interestHT.getForwardingHint(), DelegationList({delTelia, delUcla}));
 
-  // T forwards to P, Link and SelectedDelegation are stripped when Interest reaches producer region
+  // T forwards to P, forwarding hint stripped when Interest reaches producer region
   BOOST_CHECK_EQUAL(linkTP->getFace(nodeT).getCounters().nOutInterests, 1);
   const Interest& interestTP = topo.getPcap(linkTP->getFace(nodeT)).sentInterests.at(0);
-  BOOST_CHECK_EQUAL(interestTP.hasLink(), false);
-  BOOST_CHECK_EQUAL(interestTP.hasSelectedDelegation(), false);
+  BOOST_CHECK(interestTP.getForwardingHint().empty());
 
   // Data is served by P and reaches A
   BOOST_CHECK_EQUAL(producerP->getForwarderFace().getCounters().nInData, 1);
@@ -157,31 +153,25 @@
   this->consumerExpressInterest(1);
   this->advanceClocks(time::milliseconds(11), 20);
 
-  // A forwards Interest according to default route, no change to Link and SelectedDelegation
+  // A forwards Interest according to default route, no change to forwarding hint
   BOOST_CHECK_EQUAL(linkAH->getFace(nodeA).getCounters().nOutInterests, 1);
   const Interest& interestAH = topo.getPcap(linkAH->getFace(nodeA)).sentInterests.at(0);
-  BOOST_CHECK_EQUAL(interestAH.hasLink(), true);
-  BOOST_CHECK_EQUAL(interestAH.hasSelectedDelegation(), false);
+  BOOST_CHECK_EQUAL(interestAH.getForwardingHint(), DelegationList({delTelia, delUcla}));
 
-  // H forwards to C, and sets SelectedDelegation
+  // H forwards to C, no change to forwarding hint
   BOOST_CHECK_EQUAL(linkHC->getFace(nodeH).getCounters().nOutInterests, 1);
   const Interest& interestHC = topo.getPcap(linkHC->getFace(nodeH)).sentInterests.at(0);
-  BOOST_CHECK_EQUAL(interestHC.hasLink(), true);
-  BOOST_CHECK_EQUAL(interestHC.hasSelectedDelegation(), true);
-  BOOST_CHECK_EQUAL(interestHC.getSelectedDelegation(), "/ucla/cs");
+  BOOST_CHECK_EQUAL(interestHC.getForwardingHint(), DelegationList({delTelia, delUcla}));
 
-  // C forwards to S, no change to Link and SelectedDelegation
+  // C forwards to S, no change to forwarding hint
   BOOST_CHECK_EQUAL(linkCS->getFace(nodeC).getCounters().nOutInterests, 1);
   const Interest& interestCS = topo.getPcap(linkCS->getFace(nodeC)).sentInterests.at(0);
-  BOOST_CHECK_EQUAL(interestCS.hasLink(), true);
-  BOOST_CHECK_EQUAL(interestCS.hasSelectedDelegation(), true);
-  BOOST_CHECK_EQUAL(interestCS.getSelectedDelegation(), "/ucla/cs");
+  BOOST_CHECK_EQUAL(interestCS.getForwardingHint(), DelegationList({delTelia, delUcla}));
 
-  // S forwards to Q, Link and SelectedDelegation are stripped when Interest reaches producer region
+  // S forwards to Q, forwarding hint stripped when Interest reaches producer region
   BOOST_CHECK_EQUAL(linkSQ->getFace(nodeS).getCounters().nOutInterests, 1);
   const Interest& interestSQ = topo.getPcap(linkSQ->getFace(nodeS)).sentInterests.at(0);
-  BOOST_CHECK_EQUAL(interestSQ.hasLink(), false);
-  BOOST_CHECK_EQUAL(interestSQ.hasSelectedDelegation(), false);
+  BOOST_CHECK(interestSQ.getForwardingHint().empty());
 
   // Data is served by Q and reaches A
   BOOST_CHECK_EQUAL(producerQ->getForwarderFace().getCounters().nInData, 1);
@@ -190,7 +180,7 @@
 
 BOOST_AUTO_TEST_SUITE_END() // NdnsimTeliaUclaTopology
 
-BOOST_AUTO_TEST_SUITE_END() // TestLinkForwarding
+BOOST_AUTO_TEST_SUITE_END() // TestForwardingHint
 BOOST_AUTO_TEST_SUITE_END() // Fw
 
 } // namespace tests
diff --git a/tests/daemon/table/network-region-table.t.cpp b/tests/daemon/table/network-region-table.t.cpp
index f4ab6e1..68f1a03 100644
--- a/tests/daemon/table/network-region-table.t.cpp
+++ b/tests/daemon/table/network-region-table.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California,
+/*
+ * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -35,24 +35,24 @@
 
 BOOST_AUTO_TEST_CASE(InProducerRegion)
 {
-  shared_ptr<Link> link = makeLink("/net/ndnsim", {{10, "/telia/terabits"}, {20, "/ucla/cs"}});
+  DelegationList fh{{10, "/telia/terabits"}, {20, "/ucla/cs"}};
 
   NetworkRegionTable nrt1;
   nrt1.insert("/verizon");
-  BOOST_CHECK_EQUAL(nrt1.isInProducerRegion(*link), false);
+  BOOST_CHECK_EQUAL(nrt1.isInProducerRegion(fh), false);
 
   NetworkRegionTable nrt2;
   nrt2.insert("/ucla");
-  BOOST_CHECK_EQUAL(nrt2.isInProducerRegion(*link), false);
+  BOOST_CHECK_EQUAL(nrt2.isInProducerRegion(fh), false);
 
   NetworkRegionTable nrt3;
   nrt3.insert("/ucla/cs");
-  BOOST_CHECK_EQUAL(nrt3.isInProducerRegion(*link), true);
+  BOOST_CHECK_EQUAL(nrt3.isInProducerRegion(fh), true);
 
   NetworkRegionTable nrt4;
   nrt4.insert("/ucla/cs/software");
   nrt4.insert("/ucla/cs/irl");
-  BOOST_CHECK_EQUAL(nrt4.isInProducerRegion(*link), true);
+  BOOST_CHECK_EQUAL(nrt4.isInProducerRegion(fh), true);
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/tests/daemon/table/pit-entry.t.cpp b/tests/daemon/table/pit-entry.t.cpp
index 73cf7de..effb624 100644
--- a/tests/daemon/table/pit-entry.t.cpp
+++ b/tests/daemon/table/pit-entry.t.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -55,8 +55,7 @@
   BOOST_CHECK_EQUAL(entry.canMatch(*interest3), true);
 
   shared_ptr<Interest> interest4 = makeInterest("/A");
-  shared_ptr<Link> link4 = makeLink("/net/ndnsim", {{10, "/telia/terabits"}, {20, "/ucla/cs"}});
-  interest4->setLink(link4->wireEncode());
+  interest4->setForwardingHint({{10, "/telia/terabits"}, {20, "/ucla/cs"}});
   BOOST_CHECK_EQUAL(entry.canMatch(*interest4), false); // expected failure until #3162
 
   shared_ptr<Interest> interest5 = makeInterest("/A");
diff --git a/tests/test-common.cpp b/tests/test-common.cpp
index 2dabe39..2cb747e 100644
--- a/tests/test-common.cpp
+++ b/tests/test-common.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -110,14 +110,6 @@
   return data;
 }
 
-shared_ptr<Link>
-makeLink(const Name& name, std::initializer_list<std::pair<uint32_t, Name>> delegations)
-{
-  auto link = make_shared<Link>(name, delegations);
-  signData(link);
-  return link;
-}
-
 lp::Nack
 makeNack(Interest interest, lp::NackReason reason)
 {
diff --git a/tests/test-common.hpp b/tests/test-common.hpp
index 4d046d2..b365f9b 100644
--- a/tests/test-common.hpp
+++ b/tests/test-common.hpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
@@ -135,13 +135,6 @@
   return data;
 }
 
-/** \brief create a Link object with fake signature
- *  \note Link may be modified afterwards without losing the fake signature.
- *        If a real signature is desired, sign again with KeyChain.
- */
-shared_ptr<Link>
-makeLink(const Name& name, std::initializer_list<std::pair<uint32_t, Name>> delegations);
-
 /** \brief create a Nack
  *  \param interest Interest
  *  \param reason Nack reason