diff --git a/helper/ndn-scenario-helper.cpp b/helper/ndn-scenario-helper.cpp
index 1d441d6..0c661da 100644
--- a/helper/ndn-scenario-helper.cpp
+++ b/helper/ndn-scenario-helper.cpp
@@ -62,6 +62,30 @@
 }
 
 void
+ScenarioHelper::disableRibManager()
+{
+  ndnHelper.disableRibManager();
+}
+
+void
+ScenarioHelper::disableFaceManager()
+{
+  ndnHelper.disableFaceManager();
+}
+
+void
+ScenarioHelper::disableStrategyChoiceManager()
+{
+  ndnHelper.disableStrategyChoiceManager();
+}
+
+void
+ScenarioHelper::disableStatusServer()
+{
+  ndnHelper.disableStatusServer();
+}
+
+void
 ScenarioHelper::addRoutes(std::initializer_list<ScenarioHelper::RouteInfo> routes)
 {
   for (auto&& route : routes) {
diff --git a/helper/ndn-scenario-helper.hpp b/helper/ndn-scenario-helper.hpp
index 0085f58..5131daa 100644
--- a/helper/ndn-scenario-helper.hpp
+++ b/helper/ndn-scenario-helper.hpp
@@ -17,6 +17,9 @@
  * ndnSIM, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
  **/
 
+#ifndef NDNSIM_HELPER_NDN_SCENARIO_HELPER_HPP
+#define NDNSIM_HELPER_NDN_SCENARIO_HELPER_HPP
+
 #include "ndn-stack-helper.hpp"
 
 #include "ns3/net-device.h"
@@ -154,6 +157,30 @@
   shared_ptr<Face>
   getFace(const std::string& node1, const std::string& node2);
 
+  /**
+   * \brief Disable RIB Manager
+   */
+  void
+  disableRibManager();
+
+  /**
+   * \brief Disable Face Manager
+   */
+  void
+  disableFaceManager();
+
+  /**
+   * \brief Disable Strategy Choice Manager
+   */
+  void
+  disableStrategyChoiceManager();
+
+  /**
+   * \brief Disable Status Server
+   */
+  void
+  disableStatusServer();
+
 private:
   Ptr<Node>
   getOrCreateNode(const std::string& nodeName);
@@ -167,3 +194,5 @@
 
 } // namespace ndn
 } // namespace ns3
+
+#endif // NDNSIM_HELPER_NDN_SCENARIO_HELPER_HPP
diff --git a/helper/ndn-stack-helper.cpp b/helper/ndn-stack-helper.cpp
index b0f138c..7211639 100644
--- a/helper/ndn-stack-helper.cpp
+++ b/helper/ndn-stack-helper.cpp
@@ -42,6 +42,10 @@
 StackHelper::StackHelper()
   : m_needSetDefaultRoutes(false)
   , m_maxCsSize(100)
+  , m_isRibManagerDisabled(false)
+  , m_isFaceManagerDisabled(false)
+  , m_isStatusServerDisabled(false)
+  , m_isStrategyChoiceManagerDisabled(false)
 {
   setCustomNdnCxxClocks();
 
@@ -149,6 +153,23 @@
   }
 
   Ptr<L3Protocol> ndn = m_ndnFactory.Create<L3Protocol>();
+
+  if (m_isRibManagerDisabled) {
+    ndn->getConfig().put("ndnSIM.disable_rib_manager", true);
+  }
+
+  if (m_isFaceManagerDisabled) {
+    ndn->getConfig().put("ndnSIM.disable_face_manager", true);
+  }
+
+  if (m_isStatusServerDisabled) {
+    ndn->getConfig().put("ndnSIM.disable_status_server", true);
+  }
+
+  if (m_isStrategyChoiceManagerDisabled) {
+    ndn->getConfig().put("ndnSIM.disable_strategy_choice_manager", true);
+  }
+
   ndn->getConfig().put("tables.cs_max_packets", (m_maxCsSize == 0) ? 1 : m_maxCsSize);
 
   // Create and aggregate content store if NFD's contest store has been disabled
@@ -303,5 +324,29 @@
   return face;
 }
 
+void
+StackHelper::disableRibManager()
+{
+  m_isRibManagerDisabled = true;
+}
+
+void
+StackHelper::disableFaceManager()
+{
+  m_isFaceManagerDisabled = true;
+}
+
+void
+StackHelper::disableStrategyChoiceManager()
+{
+  m_isStrategyChoiceManagerDisabled = true;
+}
+
+void
+StackHelper::disableStatusServer()
+{
+  m_isStatusServerDisabled = true;
+}
+
 } // namespace ndn
 } // namespace ns3
diff --git a/helper/ndn-stack-helper.hpp b/helper/ndn-stack-helper.hpp
index 472f0ab..4b6f38b 100644
--- a/helper/ndn-stack-helper.hpp
+++ b/helper/ndn-stack-helper.hpp
@@ -212,6 +212,30 @@
   void
   UpdateAll();
 
+  /**
+   *\brief Disable the RIB manager of NFD
+   */
+  void
+  disableRibManager();
+
+  /**
+   * \brief Disable Face Manager
+   */
+  void
+  disableFaceManager();
+
+  /**
+   * \brief Disable Strategy Choice Manager
+   */
+  void
+  disableStrategyChoiceManager();
+
+  /**
+   * \brief Disable Status Server
+   */
+  void
+  disableStatusServer();
+
 private:
   shared_ptr<NetDeviceFace>
   DefaultNetDeviceCallback(Ptr<Node> node, Ptr<L3Protocol> ndn, Ptr<NetDevice> netDevice) const;
@@ -222,6 +246,11 @@
   shared_ptr<NetDeviceFace>
   createAndRegisterFace(Ptr<Node> node, Ptr<L3Protocol> ndn, Ptr<NetDevice> device) const;
 
+  bool m_isRibManagerDisabled;
+  bool m_isFaceManagerDisabled;
+  bool m_isStatusServerDisabled;
+  bool m_isStrategyChoiceManagerDisabled;
+
 public:
   void
   setCustomNdnCxxClocks();
diff --git a/model/ndn-l3-protocol.cpp b/model/ndn-l3-protocol.cpp
index f8c037a..8f77b72 100644
--- a/model/ndn-l3-protocol.cpp
+++ b/model/ndn-l3-protocol.cpp
@@ -186,7 +186,10 @@
   m_impl->m_forwarder = make_shared<nfd::Forwarder>();
 
   initializeManagement();
-  Simulator::ScheduleWithContext(m_node->GetId(), Seconds(0), &L3Protocol::initializeRibManager, this);
+
+  if (!this->getConfig().get<bool>("ndnSIM.disable_rib_manager", false)) {
+    Simulator::ScheduleWithContext(m_node->GetId(), Seconds(0), &L3Protocol::initializeRibManager, this);
+  }
 
   m_impl->m_forwarder->getFaceTable().addReserved(make_shared<nfd::NullFace>(), nfd::FACEID_NULL);
 
@@ -228,20 +231,32 @@
                                                  bind(&Forwarder::getFace, forwarder.get(), _1),
                                                  m_impl->m_internalFace, keyChain);
 
-  m_impl->m_faceManager = make_shared<FaceManager>(std::ref(forwarder->getFaceTable()),
-                                                   m_impl->m_internalFace,
-                                                   keyChain);
-
-  m_impl->m_strategyChoiceManager =
-    make_shared<StrategyChoiceManager>(std::ref(forwarder->getStrategyChoice()),
-                                       m_impl->m_internalFace,
-                                       keyChain);
-
-  m_impl->m_statusServer = make_shared<StatusServer>(m_impl->m_internalFace,
-                                                     ref(*forwarder),
+  if (!this->getConfig().get<bool>("ndnSIM.disable_face_manager", false)) {
+    m_impl->m_faceManager = make_shared<FaceManager>(std::ref(forwarder->getFaceTable()),
+                                                     m_impl->m_internalFace,
                                                      keyChain);
+  }
+  else {
+    this->getConfig().get_child("authorizations").get_child("authorize").get_child("privileges").erase("faces");
+  }
 
-  ConfigFile config((IgnoreSections({"general", "log", "rib"})));
+  if (!this->getConfig().get<bool>("ndnSIM.disable_strategy_choice_manager", false)) {
+    m_impl->m_strategyChoiceManager =
+      make_shared<StrategyChoiceManager>(std::ref(forwarder->getStrategyChoice()),
+                                         m_impl->m_internalFace,
+                                         keyChain);
+  }
+  else {
+    this->getConfig().get_child("authorizations").get_child("authorize").get_child("privileges").erase("strategy-choice");
+  }
+
+  if (!this->getConfig().get<bool>("ndnSIM.disable_status_server", false)) {
+    m_impl->m_statusServer = make_shared<StatusServer>(m_impl->m_internalFace,
+                                                       ref(*forwarder),
+                                                       keyChain);
+  }
+
+  ConfigFile config((IgnoreSections({"general", "log", "rib", "ndnSIM"})));
 
   TablesConfigSection tablesConfig(forwarder->getCs(),
                                    forwarder->getPit(),
diff --git a/tests/unit-tests/model/ndn-l3-protocol.t.cpp b/tests/unit-tests/model/ndn-l3-protocol.t.cpp
new file mode 100644
index 0000000..c594139
--- /dev/null
+++ b/tests/unit-tests/model/ndn-l3-protocol.t.cpp
@@ -0,0 +1,155 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2011-2015  Regents of the University of California.
+ *
+ * This file is part of ndnSIM. See AUTHORS for complete list of ndnSIM authors and
+ * contributors.
+ *
+ * ndnSIM 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.
+ *
+ * ndnSIM 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
+ * ndnSIM, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#include "helper/ndn-scenario-helper.hpp"
+#include "helper/ndn-app-helper.hpp"
+
+#include <ndn-cxx/face.hpp>
+
+#include "../tests-common.hpp"
+
+namespace ns3 {
+namespace ndn {
+
+BOOST_FIXTURE_TEST_SUITE(ModelNdnL3Protocol, ScenarioHelperWithCleanupFixture)
+
+class TesterApp
+{
+public:
+  TesterApp(const std::function<void(::ndn::Face& face)>& func)
+  {
+    func(m_face);
+  }
+
+protected:
+  ::ndn::Face m_face;
+};
+
+class ManagerCheckFixture : public ScenarioHelperWithCleanupFixture
+{
+public:
+  void
+  setupAndRun()
+  {
+    createTopology({
+        {"1"},
+          });
+
+    requestedDatasets = {
+      "/localhost/nfd/rib/list",
+      "/localhost/nfd/faces/list",
+      "/localhost/nfd/strategy-choice/list",
+      "/localhost/nfd/status"
+    };
+
+    FactoryCallbackApp::Install(getNode("1"), [this] () -> shared_ptr<void> {
+        return make_shared<TesterApp>([this] (::ndn::Face& face) {
+            for (const Name& dataset : requestedDatasets) {
+              face.expressInterest(dataset, [&] (const Interest& i, Data& data) {
+                  BOOST_TEST_MESSAGE(data.getName());
+                  receivedDatasets.insert(data.getName().getPrefix(-2));
+                },
+                std::bind([]{}));
+            }
+          });
+      })
+      .Start(Seconds(0.01));
+
+    Simulator::Stop(Seconds(1.0));
+    Simulator::Run();
+  }
+
+public:
+  std::set<Name> requestedDatasets;
+  std::set<Name> receivedDatasets;
+};
+
+BOOST_FIXTURE_TEST_SUITE(ManagerCheck, ManagerCheckFixture)
+
+BOOST_AUTO_TEST_CASE(AllEnabled)
+{
+  setupAndRun();
+
+  BOOST_CHECK_EQUAL(requestedDatasets.size(), receivedDatasets.size());
+  BOOST_CHECK_EQUAL_COLLECTIONS(requestedDatasets.begin(), requestedDatasets.end(),
+                                receivedDatasets.begin(), receivedDatasets.end());
+}
+
+BOOST_AUTO_TEST_CASE(DisabledRibManager)
+{
+  // Disable RIB manager
+  disableRibManager();
+
+  setupAndRun();
+
+  BOOST_CHECK_EQUAL(requestedDatasets.size(), receivedDatasets.size() + 1);
+
+  requestedDatasets.erase("/localhost/nfd/rib/list");
+  BOOST_CHECK_EQUAL_COLLECTIONS(requestedDatasets.begin(), requestedDatasets.end(),
+                                receivedDatasets.begin(), receivedDatasets.end());
+}
+
+BOOST_AUTO_TEST_CASE(DisabledFaceManager)
+{
+  // Disable Face manager
+  disableFaceManager();
+
+  setupAndRun();
+
+  BOOST_CHECK_EQUAL(requestedDatasets.size(), receivedDatasets.size() + 1);
+
+  requestedDatasets.erase("/localhost/nfd/faces/list");
+  BOOST_CHECK_EQUAL_COLLECTIONS(requestedDatasets.begin(), requestedDatasets.end(),
+                                receivedDatasets.begin(), receivedDatasets.end());
+}
+
+BOOST_AUTO_TEST_CASE(DisabledStrategyChoiceManager)
+{
+  // Disable Strategy Choice Manager manager
+  disableStrategyChoiceManager();
+
+  setupAndRun();
+
+  BOOST_CHECK_EQUAL(requestedDatasets.size(), receivedDatasets.size() + 1);
+
+  requestedDatasets.erase("/localhost/nfd/strategy-choice/list");
+  BOOST_CHECK_EQUAL_COLLECTIONS(requestedDatasets.begin(), requestedDatasets.end(),
+                                receivedDatasets.begin(), receivedDatasets.end());
+}
+
+BOOST_AUTO_TEST_CASE(DisabledStatusServer)
+{
+  // Disable Status Server manager
+  disableStatusServer();
+
+  setupAndRun();
+
+  BOOST_CHECK_EQUAL(requestedDatasets.size(), receivedDatasets.size() + 1);
+
+  requestedDatasets.erase("/localhost/nfd/status");
+  BOOST_CHECK_EQUAL_COLLECTIONS(requestedDatasets.begin(), requestedDatasets.end(),
+                                receivedDatasets.begin(), receivedDatasets.end());
+}
+
+BOOST_AUTO_TEST_SUITE_END() // ManagerCheck
+
+BOOST_AUTO_TEST_SUITE_END() // ModelNdnL3Protocol
+
+} // namespace ndn
+} // namespace ns3
