diff --git a/daemon/fw/access-strategy.cpp b/daemon/fw/access-strategy.cpp
index 84bac93..ace5426 100644
--- a/daemon/fw/access-strategy.cpp
+++ b/daemon/fw/access-strategy.cpp
@@ -78,7 +78,7 @@
                   " new-interest mi=" << miName);
 
     // send to last working nexthop
-    bool isSentToLastNexthop = this->sendToLastNexthop(inFace, pitEntry, *mi, fibEntry);
+    bool isSentToLastNexthop = this->sendToLastNexthop(inFace, interest, pitEntry, *mi, fibEntry);
 
     if (isSentToLastNexthop) {
       return;
@@ -92,7 +92,11 @@
   // no measurements, or last working nexthop unavailable
 
   // multicast to all nexthops except incoming face
-  this->multicast(pitEntry, fibEntry, {inFace.getId()});
+  int nMulticastSent = this->multicast(inFace, interest, pitEntry, fibEntry);
+
+  if (nMulticastSent < 1) {
+    this->rejectPendingInterest(pitEntry);
+  }
 }
 
 void
@@ -101,12 +105,13 @@
 {
   const fib::Entry& fibEntry = this->lookupFib(*pitEntry);
   NFD_LOG_DEBUG(interest << " interestFrom " << inFace.getId() << " retx-forward");
-  this->multicast(pitEntry, fibEntry, {inFace.getId()});
+  this->multicast(inFace, interest, pitEntry, fibEntry);
 }
 
 bool
-AccessStrategy::sendToLastNexthop(const Face& inFace, const shared_ptr<pit::Entry>& pitEntry,
-                                  MtInfo& mi, const fib::Entry& fibEntry)
+AccessStrategy::sendToLastNexthop(const Face& inFace, const Interest& interest,
+                                  const shared_ptr<pit::Entry>& pitEntry, MtInfo& mi,
+                                  const fib::Entry& fibEntry)
 {
   if (mi.lastNexthop == face::INVALID_FACEID) {
     NFD_LOG_DEBUG(pitEntry->getInterest() << " no-last-nexthop");
@@ -118,13 +123,13 @@
     return false;
   }
 
-  Face* face = this->getFace(mi.lastNexthop);
-  if (face == nullptr || !fibEntry.hasNextHop(*face)) {
+  Face* outFace = this->getFace(mi.lastNexthop);
+  if (outFace == nullptr || !fibEntry.hasNextHop(*outFace)) {
     NFD_LOG_DEBUG(pitEntry->getInterest() << " last-nexthop-gone");
     return false;
   }
 
-  if (violatesScope(*pitEntry, *face)) {
+  if (wouldViolateScope(inFace, interest, *outFace)) {
     NFD_LOG_DEBUG(pitEntry->getInterest() << " last-nexthop-violates-scope");
     return false;
   }
@@ -133,7 +138,7 @@
   NFD_LOG_DEBUG(pitEntry->getInterest() << " interestTo " << mi.lastNexthop <<
                 " last-nexthop rto=" << time::duration_cast<time::microseconds>(rto).count());
 
-  this->sendInterest(pitEntry, *face);
+  this->sendInterest(pitEntry, *outFace, interest);
 
   // schedule RTO timeout
   PitInfo* pi = pitEntry->insertStrategyInfo<PitInfo>().first;
@@ -145,32 +150,52 @@
 }
 
 void
-AccessStrategy::afterRtoTimeout(weak_ptr<pit::Entry> pitWeak, FaceId inFace, FaceId firstOutFace)
+AccessStrategy::afterRtoTimeout(weak_ptr<pit::Entry> pitWeak, FaceId inFaceId, FaceId firstOutFaceId)
 {
   shared_ptr<pit::Entry> pitEntry = pitWeak.lock();
   BOOST_ASSERT(pitEntry != nullptr);
-  // pitEntry can't become nullptr, because RTO timer should be cancelled upon pitEntry destruction
+  // if pitEntry is gone, RTO timer should have been cancelled
+
+  Face* inFace = this->getFace(inFaceId);
+  if (inFace == nullptr) {
+    NFD_LOG_DEBUG(pitEntry->getInterest() << " timeoutFrom " << firstOutFaceId <<
+                  " inFace-gone " << inFaceId);
+    return;
+  }
+
+  pit::InRecordCollection::iterator inRecord = pitEntry->getInRecord(*inFace);
+  BOOST_ASSERT(inRecord != pitEntry->in_end());
+  // in-record is erased only if Interest is satisfied, and RTO timer should have been cancelled
+  // note: if this strategy is extended to send Nacks, that would also erase in-record,
+  //       and RTO timer should be cancelled in that case as well
+
+  const Interest& interest = inRecord->getInterest();
 
   const fib::Entry& fibEntry = this->lookupFib(*pitEntry);
 
-  NFD_LOG_DEBUG(pitEntry->getInterest() << " timeoutFrom " << firstOutFace <<
-                " multicast-except " << inFace << ',' << firstOutFace);
-  this->multicast(pitEntry, fibEntry, {inFace, firstOutFace});
+  NFD_LOG_DEBUG(pitEntry->getInterest() << " timeoutFrom " << firstOutFaceId <<
+                " multicast-except " << firstOutFaceId);
+  this->multicast(*inFace, interest, pitEntry, fibEntry, firstOutFaceId);
 }
 
-void
-AccessStrategy::multicast(const shared_ptr<pit::Entry>& pitEntry, const fib::Entry& fibEntry,
-                          std::unordered_set<FaceId> exceptFaces)
+int
+AccessStrategy::multicast(const Face& inFace, const Interest& interest,
+                          const shared_ptr<pit::Entry>& pitEntry, const fib::Entry& fibEntry,
+                          FaceId exceptFace)
 {
+  int nSent = 0;
   for (const fib::NextHop& nexthop : fibEntry.getNextHops()) {
-    Face& face = nexthop.getFace();
-    if (exceptFaces.count(face.getId()) > 0) {
+    Face& outFace = nexthop.getFace();
+    if (&outFace == &inFace || outFace.getId() == exceptFace ||
+        wouldViolateScope(inFace, interest, outFace)) {
       continue;
     }
-    NFD_LOG_DEBUG(pitEntry->getInterest() << " interestTo " << face.getId() <<
+    NFD_LOG_DEBUG(pitEntry->getInterest() << " interestTo " << outFace.getId() <<
                   " multicast");
-    this->sendInterest(pitEntry, face);
+    this->sendInterest(pitEntry, outFace, interest);
+    ++nSent;
   }
+  return nSent;
 }
 
 void
diff --git a/daemon/fw/access-strategy.hpp b/daemon/fw/access-strategy.hpp
index 223d596..a9a1150 100644
--- a/daemon/fw/access-strategy.hpp
+++ b/daemon/fw/access-strategy.hpp
@@ -135,18 +135,21 @@
    *  \return whether an Interest is sent
    */
   bool
-  sendToLastNexthop(const Face& inFace, const shared_ptr<pit::Entry>& pitEntry, MtInfo& mi,
+  sendToLastNexthop(const Face& inFace, const Interest& interest,
+                    const shared_ptr<pit::Entry>& pitEntry, MtInfo& mi,
                     const fib::Entry& fibEntry);
 
   void
-  afterRtoTimeout(weak_ptr<pit::Entry> pitWeak, FaceId inFace, FaceId firstOutFace);
+  afterRtoTimeout(weak_ptr<pit::Entry> pitWeak, FaceId inFaceId, FaceId firstOutFaceId);
 
   /** \brief multicast to all nexthops
-   *  \param exceptFaces don't forward to those faces
+   *  \param exceptFace don't forward to this face; also, inFace is always excluded
+   *  \return how many Interests are sent
    */
-  void
-  multicast(const shared_ptr<pit::Entry>& pitEntry, const fib::Entry& fibEntry,
-            std::unordered_set<FaceId> exceptFaces = std::unordered_set<FaceId>());
+  int
+  multicast(const Face& inFace, const Interest& interest,
+            const shared_ptr<pit::Entry>& pitEntry, const fib::Entry& fibEntry,
+            FaceId exceptFace = face::INVALID_FACEID);
 
   void
   updateMeasurements(const Face& inFace, const Data& data,
diff --git a/tests/daemon/fw/strategy-scope-control.t.cpp b/tests/daemon/fw/strategy-scope-control.t.cpp
new file mode 100644
index 0000000..b27fdcd
--- /dev/null
+++ b/tests/daemon/fw/strategy-scope-control.t.cpp
@@ -0,0 +1,303 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2016,  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/>.
+ */
+
+/** \file
+ *  This test suite tests localhost and localhop scope control in strategies.
+ */
+
+// Strategies implementing namespace-based scope control, sorted alphabetically.
+#include "fw/access-strategy.hpp"
+#include "fw/best-route-strategy2.hpp"
+
+#include "tests/test-common.hpp"
+#include "tests/limited-io.hpp"
+#include "strategy-tester.hpp"
+#include "tests/daemon/face/dummy-face.hpp"
+#include <boost/mpl/copy_if.hpp>
+#include <boost/mpl/vector.hpp>
+
+namespace nfd {
+namespace fw {
+namespace tests {
+
+using namespace nfd::tests;
+
+template<typename S>
+class StrategyScopeControlFixture : public UnitTestTimeFixture
+{
+public:
+  StrategyScopeControlFixture()
+    : limitedIo(this)
+    , nStrategyActions(0)
+    , strategy(forwarder)
+    , fib(forwarder.getFib())
+    , pit(forwarder.getPit())
+    , nonLocalFace1(make_shared<DummyFace>("dummy://1", "dummy://1", ndn::nfd::FACE_SCOPE_NON_LOCAL))
+    , nonLocalFace2(make_shared<DummyFace>("dummy://2", "dummy://2", ndn::nfd::FACE_SCOPE_NON_LOCAL))
+    , localFace3(make_shared<DummyFace>("dummy://3", "dummy://3", ndn::nfd::FACE_SCOPE_LOCAL))
+    , localFace4(make_shared<DummyFace>("dummy://4", "dummy://4", ndn::nfd::FACE_SCOPE_LOCAL))
+  {
+    this->strategy.afterAction.connect([this] {
+      limitedIo.afterOp();
+      ++nStrategyActions;
+    });
+
+    forwarder.addFace(nonLocalFace1);
+    forwarder.addFace(nonLocalFace2);
+    forwarder.addFace(localFace3);
+    forwarder.addFace(localFace4);
+  }
+
+  /** \brief execute f and wait for a number of strategy actions
+   *  \note The actions may occur either during f() invocation or afterwards.
+   */
+  void
+  waitForStrategyAction(const std::function<void()>& f, int nExpectedActions = 1)
+  {
+    nStrategyActions = 0;
+    f();
+    if (nStrategyActions < nExpectedActions) {
+      BOOST_REQUIRE_EQUAL(limitedIo.run(nExpectedActions - nStrategyActions, LimitedIo::UNLIMITED_TIME),
+                          LimitedIo::EXCEED_OPS);
+    }
+  }
+
+public:
+  LimitedIo limitedIo;
+  int nStrategyActions;
+
+  Forwarder forwarder;
+  StrategyTester<S> strategy;
+  Fib& fib;
+  Pit& pit;
+
+  shared_ptr<Face> nonLocalFace1;
+  shared_ptr<Face> nonLocalFace2;
+  shared_ptr<Face> localFace3;
+  shared_ptr<Face> localFace4;
+};
+
+BOOST_AUTO_TEST_SUITE(Fw)
+BOOST_AUTO_TEST_SUITE(TestStrategyScopeControl)
+
+class AccessStrategyTest
+{
+public:
+  using S = AccessStrategy;
+
+  static bool
+  willSendNackNoRoute()
+  {
+    return false;
+  }
+
+  static bool
+  canProcessNack()
+  {
+    return false;
+  }
+};
+
+class BestRouteStrategy2Test
+{
+public:
+  using S = BestRouteStrategy2;
+
+  static bool
+  willSendNackNoRoute()
+  {
+    return true;
+  }
+
+  static bool
+  canProcessNack()
+  {
+    return true;
+  }
+};
+
+using Tests = boost::mpl::vector<
+  AccessStrategyTest,
+  BestRouteStrategy2Test
+>;
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(LocalhostInterestToLocal,
+                                 T, Tests, StrategyScopeControlFixture<typename T::S>)
+{
+  fib::Entry* fibEntry = this->fib.insert("/localhost/A").first;
+  fibEntry->addNextHop(*this->localFace4, 10);
+
+  shared_ptr<Interest> interest = makeInterest("/localhost/A/1");
+  shared_ptr<pit::Entry> pitEntry = this->pit.insert(*interest).first;
+  pitEntry->insertOrUpdateInRecord(*this->localFace3, *interest);
+
+  this->waitForStrategyAction(
+    [&] { this->strategy.afterReceiveInterest(*this->localFace3, *interest, pitEntry); });
+
+  BOOST_CHECK_EQUAL(this->strategy.sendInterestHistory.size(), 1);
+  BOOST_CHECK_EQUAL(this->strategy.rejectPendingInterestHistory.size(), 0);
+  BOOST_CHECK_EQUAL(this->strategy.sendNackHistory.size(), 0);
+}
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(LocalhostInterestToNonLocal,
+                                 T, Tests, StrategyScopeControlFixture<typename T::S>)
+{
+  fib::Entry* fibEntry = this->fib.insert("/localhost/A").first;
+  fibEntry->addNextHop(*this->nonLocalFace2, 10);
+
+  shared_ptr<Interest> interest = makeInterest("/localhost/A/1");
+  shared_ptr<pit::Entry> pitEntry = this->pit.insert(*interest).first;
+  pitEntry->insertOrUpdateInRecord(*this->localFace3, *interest);
+
+  this->waitForStrategyAction(
+    [&] { this->strategy.afterReceiveInterest(*this->localFace3, *interest, pitEntry); },
+    1 + T::willSendNackNoRoute());
+
+  BOOST_CHECK_EQUAL(this->strategy.sendInterestHistory.size(), 0);
+  BOOST_CHECK_EQUAL(this->strategy.rejectPendingInterestHistory.size(), 1);
+  if (T::willSendNackNoRoute()) {
+    BOOST_REQUIRE_EQUAL(this->strategy.sendNackHistory.size(), 1);
+    BOOST_CHECK_EQUAL(this->strategy.sendNackHistory.back().header.getReason(), lp::NackReason::NO_ROUTE);
+  }
+}
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(LocalhostInterestToLocalAndNonLocal,
+                                 T, Tests, StrategyScopeControlFixture<typename T::S>)
+{
+  fib::Entry* fibEntry = this->fib.insert("/localhost/A").first;
+  fibEntry->addNextHop(*this->nonLocalFace2, 10);
+  fibEntry->addNextHop(*this->localFace4, 20);
+
+  shared_ptr<Interest> interest = makeInterest("/localhost/A/1");
+  shared_ptr<pit::Entry> pitEntry = this->pit.insert(*interest).first;
+  pitEntry->insertOrUpdateInRecord(*this->localFace3, *interest);
+
+  this->waitForStrategyAction(
+    [&] { this->strategy.afterReceiveInterest(*this->localFace3, *interest, pitEntry); });
+
+  BOOST_REQUIRE_EQUAL(this->strategy.sendInterestHistory.size(), 1);
+  BOOST_CHECK_EQUAL(this->strategy.sendInterestHistory.back().outFaceId, this->localFace4->getId());
+  BOOST_CHECK_EQUAL(this->strategy.rejectPendingInterestHistory.size(), 0);
+  BOOST_CHECK_EQUAL(this->strategy.sendNackHistory.size(), 0);
+}
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(LocalhopInterestToNonLocal,
+                                 T, Tests, StrategyScopeControlFixture<typename T::S>)
+{
+  fib::Entry* fibEntry = this->fib.insert("/localhop/A").first;
+  fibEntry->addNextHop(*this->nonLocalFace2, 10);
+
+  shared_ptr<Interest> interest = makeInterest("/localhop/A/1");
+  shared_ptr<pit::Entry> pitEntry = this->pit.insert(*interest).first;
+  pitEntry->insertOrUpdateInRecord(*this->nonLocalFace1, *interest);
+
+  this->waitForStrategyAction(
+    [&] { this->strategy.afterReceiveInterest(*this->nonLocalFace1, *interest, pitEntry); },
+    1 + T::willSendNackNoRoute());
+
+  BOOST_CHECK_EQUAL(this->strategy.sendInterestHistory.size(), 0);
+  BOOST_CHECK_EQUAL(this->strategy.rejectPendingInterestHistory.size(), 1);
+  if (T::willSendNackNoRoute()) {
+    BOOST_REQUIRE_EQUAL(this->strategy.sendNackHistory.size(), 1);
+    BOOST_CHECK_EQUAL(this->strategy.sendNackHistory.back().header.getReason(), lp::NackReason::NO_ROUTE);
+  }
+}
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(LocalhopInterestToNonLocalAndLocal,
+                                 T, Tests, StrategyScopeControlFixture<typename T::S>)
+{
+  fib::Entry* fibEntry = this->fib.insert("/localhop/A").first;
+  fibEntry->addNextHop(*this->nonLocalFace2, 10);
+  fibEntry->addNextHop(*this->localFace4, 20);
+
+  shared_ptr<Interest> interest = makeInterest("/localhop/A/1");
+  shared_ptr<pit::Entry> pitEntry = this->pit.insert(*interest).first;
+  pitEntry->insertOrUpdateInRecord(*this->nonLocalFace1, *interest);
+
+  this->waitForStrategyAction(
+    [&] { this->strategy.afterReceiveInterest(*this->nonLocalFace1, *interest, pitEntry); });
+
+  BOOST_REQUIRE_EQUAL(this->strategy.sendInterestHistory.size(), 1);
+  BOOST_CHECK_EQUAL(this->strategy.sendInterestHistory.back().outFaceId, this->localFace4->getId());
+  BOOST_CHECK_EQUAL(this->strategy.rejectPendingInterestHistory.size(), 0);
+  BOOST_CHECK_EQUAL(this->strategy.sendNackHistory.size(), 0);
+}
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(LocalhostNackToNonLocal,
+                                 T, Tests, StrategyScopeControlFixture<typename T::S>)
+{
+  fib::Entry* fibEntry = this->fib.insert("/localhost/A").first;
+  fibEntry->addNextHop(*this->localFace4, 10);
+  fibEntry->addNextHop(*this->nonLocalFace2, 20);
+
+  shared_ptr<Interest> interest = makeInterest("/localhost/A/1", 1460);
+  shared_ptr<pit::Entry> pitEntry = this->pit.insert(*interest).first;
+  pitEntry->insertOrUpdateInRecord(*this->localFace3, *interest);
+  lp::Nack nack = makeNack("/localhost/A/1", 1460, lp::NackReason::NO_ROUTE);
+  pitEntry->insertOrUpdateOutRecord(*this->localFace4, *interest)->setIncomingNack(nack);
+
+  this->waitForStrategyAction(
+    [&] { this->strategy.afterReceiveNack(*this->localFace4, nack, pitEntry); },
+    T::canProcessNack());
+
+  BOOST_CHECK_EQUAL(this->strategy.sendInterestHistory.size(), 0);
+  BOOST_CHECK_EQUAL(this->strategy.rejectPendingInterestHistory.size(), 0);
+  if (T::canProcessNack()) {
+    BOOST_REQUIRE_EQUAL(this->strategy.sendNackHistory.size(), 1);
+    BOOST_CHECK_EQUAL(this->strategy.sendNackHistory.back().header.getReason(), lp::NackReason::NO_ROUTE);
+  }
+}
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(LocalhopNackToNonLocal,
+                                 T, Tests, StrategyScopeControlFixture<typename T::S>)
+{
+  fib::Entry* fibEntry = this->fib.insert("/localhop/A").first;
+  fibEntry->addNextHop(*this->localFace4, 10);
+  fibEntry->addNextHop(*this->nonLocalFace2, 20);
+
+  shared_ptr<Interest> interest = makeInterest("/localhop/A/1", 1377);
+  shared_ptr<pit::Entry> pitEntry = this->pit.insert(*interest).first;
+  pitEntry->insertOrUpdateInRecord(*this->nonLocalFace1, *interest);
+  lp::Nack nack = makeNack("/localhop/A/1", 1377, lp::NackReason::NO_ROUTE);
+  pitEntry->insertOrUpdateOutRecord(*this->localFace4, *interest)->setIncomingNack(nack);
+
+  this->waitForStrategyAction(
+    [&] { this->strategy.afterReceiveNack(*this->localFace4, nack, pitEntry); },
+    T::canProcessNack());
+
+  BOOST_CHECK_EQUAL(this->strategy.sendInterestHistory.size(), 0);
+  BOOST_CHECK_EQUAL(this->strategy.rejectPendingInterestHistory.size(), 0);
+  if (T::canProcessNack()) {
+    BOOST_REQUIRE_EQUAL(this->strategy.sendNackHistory.size(), 1);
+    BOOST_CHECK_EQUAL(this->strategy.sendNackHistory.back().header.getReason(), lp::NackReason::NO_ROUTE);
+  }
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestStrategyScopeControl
+BOOST_AUTO_TEST_SUITE_END() // Fw
+
+} // namespace tests
+} // namespace fw
+} // namespace nfd
