diff --git a/daemon/mgmt/face-manager.cpp b/daemon/mgmt/face-manager.cpp
new file mode 100644
index 0000000..2991ee6
--- /dev/null
+++ b/daemon/mgmt/face-manager.cpp
@@ -0,0 +1,917 @@
+/* -*- 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 "face-manager.hpp"
+
+#include "core/network-interface.hpp"
+#include "fw/face-table.hpp"
+#include "face/tcp-factory.hpp"
+#include "face/udp-factory.hpp"
+
+#include <ndn-cxx/management/nfd-face-status.hpp>
+#include <ndn-cxx/management/nfd-channel-status.hpp>
+#include <ndn-cxx/management/nfd-face-event-notification.hpp>
+
+#ifdef HAVE_UNIX_SOCKETS
+#include "face/unix-stream-factory.hpp"
+#endif // HAVE_UNIX_SOCKETS
+
+#ifdef HAVE_LIBPCAP
+#include "face/ethernet-factory.hpp"
+#include "face/ethernet-face.hpp"
+#endif // HAVE_LIBPCAP
+
+#ifdef HAVE_WEBSOCKET
+#include "face/websocket-factory.hpp"
+#endif // HAVE_WEBSOCKET
+
+namespace nfd {
+
+NFD_LOG_INIT("FaceManager");
+
+FaceManager::FaceManager(FaceTable& faceTable,
+                         Dispatcher& dispatcher,
+                         CommandValidator& validator)
+  : ManagerBase(dispatcher, validator, "faces")
+  , m_faceTable(faceTable)
+{
+  registerCommandHandler<ndn::nfd::FaceCreateCommand>("create",
+    bind(&FaceManager::createFace, this, _2, _3, _4, _5));
+
+  registerCommandHandler<ndn::nfd::FaceDestroyCommand>("destroy",
+    bind(&FaceManager::destroyFace, this, _2, _3, _4, _5));
+
+  registerCommandHandler<ndn::nfd::FaceEnableLocalControlCommand>("enable-local-control",
+    bind(&FaceManager::enableLocalControl, this, _2, _3, _4, _5));
+
+  registerCommandHandler<ndn::nfd::FaceDisableLocalControlCommand>("disable-local-control",
+    bind(&FaceManager::disableLocalControl, this, _2, _3, _4, _5));
+
+  registerStatusDatasetHandler("list", bind(&FaceManager::listFaces, this, _1, _2, _3));
+  registerStatusDatasetHandler("channels", bind(&FaceManager::listChannels, this, _1, _2, _3));
+  registerStatusDatasetHandler("query", bind(&FaceManager::queryFaces, this, _1, _2, _3));
+
+  auto postNotification = registerNotificationStream("events");
+  m_faceAddConn =
+    m_faceTable.onAdd.connect(bind(&FaceManager::afterFaceAdded, this, _1, postNotification));
+  m_faceRemoveConn =
+    m_faceTable.onRemove.connect(bind(&FaceManager::afterFaceRemoved, this, _1, postNotification));
+}
+
+void
+FaceManager::setConfigFile(ConfigFile& configFile)
+{
+  configFile.addSectionHandler("face_system", bind(&FaceManager::processConfig, this, _1, _2, _3));
+}
+
+void
+FaceManager::createFace(const Name& topPrefix, const Interest& interest,
+                        const ControlParameters& parameters,
+                        const ndn::mgmt::CommandContinuation& done)
+{
+  FaceUri uri;
+  if (!uri.parse(parameters.getUri())) {
+    NFD_LOG_TRACE("failed to parse URI");
+    return done(ControlResponse(400, "Malformed command"));
+  }
+
+  if (!uri.isCanonical()) {
+    NFD_LOG_TRACE("received non-canonical URI");
+    return done(ControlResponse(400, "Non-canonical URI"));
+  }
+
+  FactoryMap::iterator factory = m_factories.find(uri.getScheme());
+  if (factory == m_factories.end()) {
+    return done(ControlResponse(501, "Unsupported protocol"));
+  }
+
+  try {
+    factory->second->createFace(uri,
+                                parameters.getFacePersistency(),
+                                bind(&FaceManager::afterCreateFaceSuccess,
+                                     this, parameters, _1, done),
+                                bind(&FaceManager::afterCreateFaceFailure,
+                                     this, _1, done));
+  }
+  catch (const std::runtime_error& error) {
+    std::string errorMessage = "Face creation failed: ";
+    errorMessage += error.what();
+
+    NFD_LOG_ERROR(errorMessage);
+    return done(ControlResponse(500, errorMessage));
+  }
+  catch (const std::logic_error& error) {
+    std::string errorMessage = "Face creation failed: ";
+    errorMessage += error.what();
+
+    NFD_LOG_ERROR(errorMessage);
+    return done(ControlResponse(500, errorMessage));
+  }
+}
+
+void
+FaceManager::destroyFace(const Name& topPrefix, const Interest& interest,
+                         const ControlParameters& parameters,
+                         const ndn::mgmt::CommandContinuation& done)
+{
+  shared_ptr<Face> target = m_faceTable.get(parameters.getFaceId());
+  if (target) {
+    target->close();
+  }
+
+  done(ControlResponse(200, "OK").setBody(parameters.wireEncode()));
+}
+
+void
+FaceManager::enableLocalControl(const Name& topPrefix, const Interest& interest,
+                                const ControlParameters& parameters,
+                                const ndn::mgmt::CommandContinuation& done)
+{
+  auto result = extractLocalControlParameters(interest, parameters, done);
+  if (result.isValid) {
+    result.face->setLocalControlHeaderFeature(result.feature, true);
+    return done(ControlResponse(200, "OK").setBody(parameters.wireEncode()));
+  }
+}
+
+void
+FaceManager::disableLocalControl(const Name& topPrefix, const Interest& interest,
+                                 const ControlParameters& parameters,
+                                 const ndn::mgmt::CommandContinuation& done)
+{
+  auto result = extractLocalControlParameters(interest, parameters, done);
+  if (result.isValid) {
+    result.face->setLocalControlHeaderFeature(result.feature, false);
+    return done(ControlResponse(200, "OK").setBody(parameters.wireEncode()));
+  }
+}
+
+void
+FaceManager::afterCreateFaceSuccess(ControlParameters& parameters,
+                                    const shared_ptr<Face>& newFace,
+                                    const ndn::mgmt::CommandContinuation& done)
+{
+  addCreatedFaceToForwarder(newFace);
+  parameters.setFaceId(newFace->getId());
+  parameters.setUri(newFace->getRemoteUri().toString());
+  parameters.setFacePersistency(newFace->getPersistency());
+
+  done(ControlResponse(200, "OK").setBody(parameters.wireEncode()));
+}
+
+void
+FaceManager::afterCreateFaceFailure(const std::string& reason,
+                                    const ndn::mgmt::CommandContinuation& done)
+{
+  NFD_LOG_DEBUG("Failed to create face: " << reason);
+
+  done(ControlResponse(408, "Failed to create face: " + reason));
+}
+
+FaceManager::ExtractLocalControlParametersResult
+FaceManager::extractLocalControlParameters(const Interest& request,
+                                           const ControlParameters& parameters,
+                                           const ndn::mgmt::CommandContinuation& done)
+{
+  ExtractLocalControlParametersResult result;
+  result.isValid = false;
+
+  auto face = m_faceTable.get(request.getIncomingFaceId());
+  if (!static_cast<bool>(face)) {
+    NFD_LOG_DEBUG("command result: faceid " << request.getIncomingFaceId() << " not found");
+    done(ControlResponse(410, "Face not found"));
+    return result;
+  }
+
+  if (!face->isLocal()) {
+    NFD_LOG_DEBUG("command result: cannot enable local control on non-local faceid " <<
+                  face->getId());
+    done(ControlResponse(412, "Face is non-local"));
+    return result;
+  }
+
+  result.isValid = true;
+  result.face = dynamic_pointer_cast<LocalFace>(face);
+  result.feature = static_cast<LocalControlFeature>(parameters.getLocalControlFeature());
+
+  return result;
+}
+
+void
+FaceManager::listFaces(const Name& topPrefix, const Interest& interest,
+                       ndn::mgmt::StatusDatasetContext& context)
+{
+  for (const auto& face : m_faceTable) {
+    context.append(face->getFaceStatus().wireEncode());
+  }
+  context.end();
+}
+
+void
+FaceManager::listChannels(const Name& topPrefix, const Interest& interest,
+                          ndn::mgmt::StatusDatasetContext& context)
+{
+  std::set<shared_ptr<ProtocolFactory>> seenFactories;
+
+  for (auto i = m_factories.begin(); i != m_factories.end(); ++i) {
+    const shared_ptr<ProtocolFactory>& factory = i->second;
+
+    if (seenFactories.find(factory) != seenFactories.end()) {
+      continue;
+    }
+    seenFactories.insert(factory);
+
+    std::list<shared_ptr<const Channel>> channels = factory->getChannels();
+
+    for (auto j = channels.begin(); j != channels.end(); ++j) {
+      ndn::nfd::ChannelStatus entry;
+      entry.setLocalUri((*j)->getUri().toString());
+      context.append(entry.wireEncode());
+    }
+  }
+
+  context.end();
+}
+
+void
+FaceManager::queryFaces(const Name& topPrefix, const Interest& interest,
+                        ndn::mgmt::StatusDatasetContext& context)
+{
+  ndn::nfd::FaceQueryFilter faceFilter;
+  const Name& query = interest.getName();
+  try {
+    faceFilter.wireDecode(query[-1].blockFromValue());
+  }
+  catch (const tlv::Error&) {
+    NFD_LOG_DEBUG("query result: malformed filter");
+    return context.reject(ControlResponse(400, "malformed filter"));
+  }
+
+  for (const auto& face : m_faceTable) {
+    if (doesMatchFilter(faceFilter, face)) {
+      context.append(face->getFaceStatus().wireEncode());
+    }
+  }
+  context.end();
+}
+
+bool
+FaceManager::doesMatchFilter(const ndn::nfd::FaceQueryFilter& filter, shared_ptr<Face> face)
+{
+  if (filter.hasFaceId() &&
+      filter.getFaceId() != static_cast<uint64_t>(face->getId())) {
+    return false;
+  }
+
+  if (filter.hasUriScheme() &&
+      filter.getUriScheme() != face->getRemoteUri().getScheme() &&
+      filter.getUriScheme() != face->getLocalUri().getScheme()) {
+    return false;
+  }
+
+  if (filter.hasRemoteUri() &&
+      filter.getRemoteUri() != face->getRemoteUri().toString()) {
+    return false;
+  }
+
+  if (filter.hasLocalUri() &&
+      filter.getLocalUri() != face->getLocalUri().toString()) {
+    return false;
+  }
+
+  if (filter.hasFaceScope() &&
+      (filter.getFaceScope() == ndn::nfd::FACE_SCOPE_LOCAL) != face->isLocal()) {
+    return false;
+  }
+
+  if (filter.hasFacePersistency() &&
+      filter.getFacePersistency() != face->getPersistency()) {
+    return false;
+  }
+
+  if (filter.hasLinkType() &&
+      (filter.getLinkType() == ndn::nfd::LINK_TYPE_MULTI_ACCESS) != face->isMultiAccess()) {
+    return false;
+  }
+
+  return true;
+}
+
+void
+FaceManager::afterFaceAdded(shared_ptr<Face> face,
+                            const ndn::mgmt::PostNotification& post)
+{
+  ndn::nfd::FaceEventNotification notification;
+  notification.setKind(ndn::nfd::FACE_EVENT_CREATED);
+  face->copyStatusTo(notification);
+
+  post(notification.wireEncode());
+}
+
+void
+FaceManager::afterFaceRemoved(shared_ptr<Face> face,
+                              const ndn::mgmt::PostNotification& post)
+{
+  ndn::nfd::FaceEventNotification notification;
+  notification.setKind(ndn::nfd::FACE_EVENT_DESTROYED);
+  face->copyStatusTo(notification);
+
+  post(notification.wireEncode());
+}
+
+void
+FaceManager::processConfig(const ConfigSection& configSection,
+                           bool isDryRun,
+                           const std::string& filename)
+{
+  bool hasSeenUnix = false;
+  bool hasSeenTcp = false;
+  bool hasSeenUdp = false;
+  bool hasSeenEther = false;
+  bool hasSeenWebSocket = false;
+
+  const std::vector<NetworkInterfaceInfo> nicList(listNetworkInterfaces());
+
+  for (const auto& item : configSection) {
+    if (item.first == "unix") {
+      if (hasSeenUnix) {
+        BOOST_THROW_EXCEPTION(Error("Duplicate \"unix\" section"));
+      }
+      hasSeenUnix = true;
+
+      processSectionUnix(item.second, isDryRun);
+    }
+    else if (item.first == "tcp") {
+      if (hasSeenTcp) {
+        BOOST_THROW_EXCEPTION(Error("Duplicate \"tcp\" section"));
+      }
+      hasSeenTcp = true;
+
+      processSectionTcp(item.second, isDryRun);
+    }
+    else if (item.first == "udp") {
+      if (hasSeenUdp) {
+        BOOST_THROW_EXCEPTION(Error("Duplicate \"udp\" section"));
+      }
+      hasSeenUdp = true;
+
+      processSectionUdp(item.second, isDryRun, nicList);
+    }
+    else if (item.first == "ether") {
+      if (hasSeenEther) {
+        BOOST_THROW_EXCEPTION(Error("Duplicate \"ether\" section"));
+      }
+      hasSeenEther = true;
+
+      processSectionEther(item.second, isDryRun, nicList);
+    }
+    else if (item.first == "websocket") {
+      if (hasSeenWebSocket) {
+        BOOST_THROW_EXCEPTION(Error("Duplicate \"websocket\" section"));
+      }
+      hasSeenWebSocket = true;
+
+      processSectionWebSocket(item.second, isDryRun);
+    }
+    else {
+      BOOST_THROW_EXCEPTION(Error("Unrecognized option \"" + item.first + "\""));
+    }
+  }
+}
+
+void
+FaceManager::processSectionUnix(const ConfigSection& configSection, bool isDryRun)
+{
+  // ; the unix section contains settings of Unix stream faces and channels
+  // unix
+  // {
+  //   path /var/run/nfd.sock ; Unix stream listener path
+  // }
+
+#if defined(HAVE_UNIX_SOCKETS)
+
+  std::string path = "/var/run/nfd.sock";
+
+  for (auto i = configSection.begin(); i != configSection.end(); ++i) {
+    if (i->first == "path") {
+      path = i->second.get_value<std::string>();
+    }
+    else {
+      BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" +
+                                              i->first + "\" in \"unix\" section"));
+    }
+  }
+
+  if (!isDryRun) {
+    if (m_factories.count("unix") > 0) {
+      return;
+    }
+
+    shared_ptr<UnixStreamFactory> factory = make_shared<UnixStreamFactory>();
+    shared_ptr<UnixStreamChannel> unixChannel = factory->createChannel(path);
+
+    // Should acceptFailed callback be used somehow?
+    unixChannel->listen(bind(&FaceTable::add, &m_faceTable, _1),
+                        UnixStreamChannel::ConnectFailedCallback());
+
+    m_factories.insert(std::make_pair("unix", factory));
+  }
+#else
+  BOOST_THROW_EXCEPTION(ConfigFile::Error("NFD was compiled without Unix sockets support, "
+                                          "cannot process \"unix\" section"));
+#endif // HAVE_UNIX_SOCKETS
+}
+
+void
+FaceManager::processSectionTcp(const ConfigSection& configSection, bool isDryRun)
+{
+  // ; the tcp section contains settings of TCP faces and channels
+  // tcp
+  // {
+  //   listen yes ; set to 'no' to disable TCP listener, default 'yes'
+  //   port 6363 ; TCP listener port number
+  // }
+
+  std::string port = "6363";
+  bool needToListen = true;
+  bool enableV4 = true;
+  bool enableV6 = true;
+
+  for (auto i = configSection.begin(); i != configSection.end(); ++i) {
+    if (i->first == "port") {
+      port = i->second.get_value<std::string>();
+      try {
+        uint16_t portNo = boost::lexical_cast<uint16_t>(port);
+        NFD_LOG_TRACE("TCP port set to " << portNo);
+      }
+      catch (const std::bad_cast& error) {
+        BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option " +
+                                                i->first + "\" in \"tcp\" section"));
+      }
+    }
+    else if (i->first == "listen") {
+      needToListen = ConfigFile::parseYesNo(i, i->first, "tcp");
+    }
+    else if (i->first == "enable_v4") {
+      enableV4 = ConfigFile::parseYesNo(i, i->first, "tcp");
+    }
+    else if (i->first == "enable_v6") {
+      enableV6 = ConfigFile::parseYesNo(i, i->first, "tcp");
+    }
+    else {
+      BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" +
+                                              i->first + "\" in \"tcp\" section"));
+    }
+  }
+
+  if (!enableV4 && !enableV6) {
+    BOOST_THROW_EXCEPTION(ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
+                                            " Remove \"tcp\" section to disable TCP channels or"
+                                            " re-enable at least one channel type."));
+  }
+
+  if (!isDryRun) {
+    if (m_factories.count("tcp") > 0) {
+      return;
+    }
+
+    shared_ptr<TcpFactory> factory = make_shared<TcpFactory>(port);
+    m_factories.insert(std::make_pair("tcp", factory));
+
+    if (enableV4) {
+      shared_ptr<TcpChannel> ipv4Channel = factory->createChannel("0.0.0.0", port);
+      if (needToListen) {
+        // Should acceptFailed callback be used somehow?
+        ipv4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
+                            TcpChannel::ConnectFailedCallback());
+      }
+
+      m_factories.insert(std::make_pair("tcp4", factory));
+    }
+
+    if (enableV6) {
+      shared_ptr<TcpChannel> ipv6Channel = factory->createChannel("::", port);
+      if (needToListen) {
+        // Should acceptFailed callback be used somehow?
+        ipv6Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
+                            TcpChannel::ConnectFailedCallback());
+      }
+
+      m_factories.insert(std::make_pair("tcp6", factory));
+    }
+  }
+}
+
+void
+FaceManager::processSectionUdp(const ConfigSection& configSection,
+                               bool isDryRun,
+                               const std::vector<NetworkInterfaceInfo>& nicList)
+{
+  // ; the udp section contains settings of UDP faces and channels
+  // udp
+  // {
+  //   port 6363 ; UDP unicast port number
+  //   idle_timeout 600 ; idle time (seconds) before closing a UDP unicast face
+  //   keep_alive_interval 25 ; interval (seconds) between keep-alive refreshes
+
+  //   ; NFD creates one UDP multicast face per NIC
+  //   mcast yes ; set to 'no' to disable UDP multicast, default 'yes'
+  //   mcast_port 56363 ; UDP multicast port number
+  //   mcast_group 224.0.23.170 ; UDP multicast group (IPv4 only)
+  // }
+
+  std::string port = "6363";
+  bool enableV4 = true;
+  bool enableV6 = true;
+  size_t timeout = 600;
+  size_t keepAliveInterval = 25;
+  bool useMcast = true;
+  std::string mcastGroup = "224.0.23.170";
+  std::string mcastPort = "56363";
+
+
+  for (auto i = configSection.begin(); i != configSection.end(); ++i) {
+    if (i->first == "port") {
+      port = i->second.get_value<std::string>();
+      try {
+        uint16_t portNo = boost::lexical_cast<uint16_t>(port);
+        NFD_LOG_TRACE("UDP port set to " << portNo);
+      }
+      catch (const std::bad_cast& error) {
+        BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option " +
+                                                i->first + "\" in \"udp\" section"));
+      }
+    }
+    else if (i->first == "enable_v4") {
+      enableV4 = ConfigFile::parseYesNo(i, i->first, "udp");
+    }
+    else if (i->first == "enable_v6") {
+      enableV6 = ConfigFile::parseYesNo(i, i->first, "udp");
+    }
+    else if (i->first == "idle_timeout") {
+      try {
+        timeout = i->second.get_value<size_t>();
+      }
+      catch (const std::exception& e) {
+        BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
+                                                i->first + "\" in \"udp\" section"));
+      }
+    }
+    else if (i->first == "keep_alive_interval") {
+      try {
+        keepAliveInterval = i->second.get_value<size_t>();
+
+        /// \todo Make use of keepAliveInterval
+        /// \todo what is keep alive interval used for?
+        (void)(keepAliveInterval);
+      }
+      catch (const std::exception& e) {
+        BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
+                                                i->first + "\" in \"udp\" section"));
+      }
+    }
+    else if (i->first == "mcast") {
+      useMcast = ConfigFile::parseYesNo(i, i->first, "udp");
+    }
+    else if (i->first == "mcast_port") {
+      mcastPort = i->second.get_value<std::string>();
+      try {
+        uint16_t portNo = boost::lexical_cast<uint16_t>(mcastPort);
+        NFD_LOG_TRACE("UDP multicast port set to " << portNo);
+      }
+      catch (const std::bad_cast& error) {
+        BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option " +
+                                                i->first + "\" in \"udp\" section"));
+      }
+    }
+    else if (i->first == "mcast_group") {
+      using namespace boost::asio::ip;
+      mcastGroup = i->second.get_value<std::string>();
+      try {
+        address mcastGroupTest = address::from_string(mcastGroup);
+        if (!mcastGroupTest.is_v4()) {
+          BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
+                                                  i->first + "\" in \"udp\" section"));
+        }
+      }
+      catch(const std::runtime_error& e) {
+        BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
+                                                i->first + "\" in \"udp\" section"));
+      }
+    }
+    else {
+      BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" +
+                                              i->first + "\" in \"udp\" section"));
+    }
+  }
+
+  if (!enableV4 && !enableV6) {
+    BOOST_THROW_EXCEPTION(ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
+                                            " Remove \"udp\" section to disable UDP channels or"
+                                            " re-enable at least one channel type."));
+  }
+  else if (useMcast && !enableV4) {
+    BOOST_THROW_EXCEPTION(ConfigFile::Error("IPv4 multicast requested, but IPv4 channels"
+                                            " have been disabled (conflicting configuration options set)"));
+  }
+
+  if (!isDryRun) {
+    shared_ptr<UdpFactory> factory;
+    bool isReload = false;
+    if (m_factories.count("udp") > 0) {
+      isReload = true;
+      factory = static_pointer_cast<UdpFactory>(m_factories["udp"]);
+    }
+    else {
+      factory = make_shared<UdpFactory>(port);
+      m_factories.insert(std::make_pair("udp", factory));
+    }
+
+    if (!isReload && enableV4) {
+      shared_ptr<UdpChannel> v4Channel =
+        factory->createChannel("0.0.0.0", port, time::seconds(timeout));
+
+      v4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
+                        UdpChannel::ConnectFailedCallback());
+
+      m_factories.insert(std::make_pair("udp4", factory));
+    }
+
+    if (!isReload && enableV6) {
+      shared_ptr<UdpChannel> v6Channel =
+        factory->createChannel("::", port, time::seconds(timeout));
+
+      v6Channel->listen(bind(&FaceTable::add, &m_faceTable, _1),
+                        UdpChannel::ConnectFailedCallback());
+      m_factories.insert(std::make_pair("udp6", factory));
+    }
+
+    if (useMcast && enableV4) {
+      std::vector<NetworkInterfaceInfo> ipv4MulticastInterfaces;
+      for (const auto& nic : nicList) {
+        if (nic.isUp() && nic.isMulticastCapable() && !nic.ipv4Addresses.empty()) {
+          ipv4MulticastInterfaces.push_back(nic);
+        }
+      }
+
+      bool isNicNameNecessary = false;
+#if defined(__linux__)
+      if (ipv4MulticastInterfaces.size() > 1) {
+        // On Linux if we have more than one MulticastUdpFace
+        // we need to specify the name of the interface
+        isNicNameNecessary = true;
+      }
+#endif
+
+      std::list<shared_ptr<MulticastUdpFace> > multicastFacesToRemove;
+      for (auto i = factory->getMulticastFaces().begin();
+           i != factory->getMulticastFaces().end();
+           ++i) {
+        multicastFacesToRemove.push_back(i->second);
+      }
+
+      for (const auto& nic : ipv4MulticastInterfaces) {
+        shared_ptr<MulticastUdpFace> newFace;
+        newFace = factory->createMulticastFace(nic.ipv4Addresses[0].to_string(),
+                                               mcastGroup,
+                                               mcastPort,
+                                               isNicNameNecessary ? nic.name : "");
+        addCreatedFaceToForwarder(newFace);
+        multicastFacesToRemove.remove(newFace);
+      }
+
+      for (auto i = multicastFacesToRemove.begin();
+           i != multicastFacesToRemove.end();
+           ++i) {
+        (*i)->close();
+      }
+    }
+    else {
+      std::list<shared_ptr<MulticastUdpFace>> multicastFacesToRemove;
+      for (auto i = factory->getMulticastFaces().begin();
+           i != factory->getMulticastFaces().end();
+           ++i) {
+        multicastFacesToRemove.push_back(i->second);
+      }
+
+      for (auto i = multicastFacesToRemove.begin();
+           i != multicastFacesToRemove.end();
+           ++i) {
+        (*i)->close();
+      }
+    }
+  }
+}
+
+void
+FaceManager::processSectionEther(const ConfigSection& configSection,
+                                 bool isDryRun,
+                                 const std::vector<NetworkInterfaceInfo>& nicList)
+{
+  // ; the ether section contains settings of Ethernet faces and channels
+  // ether
+  // {
+  //   ; NFD creates one Ethernet multicast face per NIC
+  //   mcast yes ; set to 'no' to disable Ethernet multicast, default 'yes'
+  //   mcast_group 01:00:5E:00:17:AA ; Ethernet multicast group
+  // }
+
+#if defined(HAVE_LIBPCAP)
+  bool useMcast = true;
+  ethernet::Address mcastGroup(ethernet::getDefaultMulticastAddress());
+
+  for (auto i = configSection.begin(); i != configSection.end(); ++i) {
+    if (i->first == "mcast") {
+      useMcast = ConfigFile::parseYesNo(i, i->first, "ether");
+    }
+    else if (i->first == "mcast_group") {
+      mcastGroup = ethernet::Address::fromString(i->second.get_value<std::string>());
+      if (mcastGroup.isNull()) {
+        BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option \"" +
+                                                i->first + "\" in \"ether\" section"));
+      }
+    }
+    else {
+      BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" +
+                                              i->first + "\" in \"ether\" section"));
+    }
+  }
+
+  if (!isDryRun) {
+    shared_ptr<EthernetFactory> factory;
+    if (m_factories.count("ether") > 0) {
+      factory = static_pointer_cast<EthernetFactory>(m_factories["ether"]);
+    }
+    else {
+      factory = make_shared<EthernetFactory>();
+      m_factories.insert(std::make_pair("ether", factory));
+    }
+
+    if (useMcast) {
+      std::list<shared_ptr<EthernetFace> > multicastFacesToRemove;
+      for (auto i = factory->getMulticastFaces().begin();
+           i != factory->getMulticastFaces().end();
+           ++i) {
+        multicastFacesToRemove.push_back(i->second);
+      }
+
+      for (const auto& nic : nicList) {
+        if (nic.isUp() && nic.isMulticastCapable()) {
+          try {
+            shared_ptr<EthernetFace> newFace =
+            factory->createMulticastFace(nic, mcastGroup);
+
+            addCreatedFaceToForwarder(newFace);
+            multicastFacesToRemove.remove(newFace);
+          }
+          catch (const EthernetFactory::Error& factoryError) {
+            NFD_LOG_ERROR(factoryError.what() << ", continuing");
+          }
+          catch (const EthernetFace::Error& faceError) {
+            NFD_LOG_ERROR(faceError.what() << ", continuing");
+          }
+        }
+      }
+
+      for (auto i = multicastFacesToRemove.begin();
+           i != multicastFacesToRemove.end();
+           ++i) {
+        (*i)->close();
+      }
+    }
+    else {
+      std::list<shared_ptr<EthernetFace> > multicastFacesToRemove;
+      for (auto i = factory->getMulticastFaces().begin();
+           i != factory->getMulticastFaces().end();
+           ++i) {
+        multicastFacesToRemove.push_back(i->second);
+      }
+
+      for (auto i = multicastFacesToRemove.begin();
+           i != multicastFacesToRemove.end();
+           ++i) {
+        (*i)->close();
+      }
+    }
+  }
+#else
+  BOOST_THROW_EXCEPTION(ConfigFile::Error("NFD was compiled without libpcap, cannot process \"ether\" section"));
+#endif // HAVE_LIBPCAP
+}
+
+void
+FaceManager::processSectionWebSocket(const ConfigSection& configSection, bool isDryRun)
+{
+  // ; the websocket section contains settings of WebSocket faces and channels
+  // websocket
+  // {
+  //   listen yes ; set to 'no' to disable WebSocket listener, default 'yes'
+  //   port 9696 ; WebSocket listener port number
+  //   enable_v4 yes ; set to 'no' to disable listening on IPv4 socket, default 'yes'
+  //   enable_v6 yes ; set to 'no' to disable listening on IPv6 socket, default 'yes'
+  // }
+
+#if defined(HAVE_WEBSOCKET)
+
+  std::string port = "9696";
+  bool needToListen = true;
+  bool enableV4 = true;
+  bool enableV6 = true;
+
+  for (auto i = configSection.begin(); i != configSection.end(); ++i) {
+    if (i->first == "port") {
+      port = i->second.get_value<std::string>();
+      try {
+        uint16_t portNo = boost::lexical_cast<uint16_t>(port);
+        NFD_LOG_TRACE("WebSocket port set to " << portNo);
+      }
+      catch (const std::bad_cast& error) {
+        BOOST_THROW_EXCEPTION(ConfigFile::Error("Invalid value for option " +
+                                                i->first + "\" in \"websocket\" section"));
+      }
+    }
+    else if (i->first == "listen") {
+      needToListen = ConfigFile::parseYesNo(i, i->first, "websocket");
+    }
+    else if (i->first == "enable_v4") {
+      enableV4 = ConfigFile::parseYesNo(i, i->first, "websocket");
+    }
+    else if (i->first == "enable_v6") {
+      enableV6 = ConfigFile::parseYesNo(i, i->first, "websocket");
+    }
+    else {
+      BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option \"" +
+                                              i->first + "\" in \"websocket\" section"));
+    }
+  }
+
+  if (!enableV4 && !enableV6) {
+    BOOST_THROW_EXCEPTION(ConfigFile::Error("IPv4 and IPv6 channels have been disabled."
+                                            " Remove \"websocket\" section to disable WebSocket channels or"
+                                            " re-enable at least one channel type."));
+  }
+
+  if (!enableV4 && enableV6) {
+    BOOST_THROW_EXCEPTION(ConfigFile::Error("NFD does not allow pure IPv6 WebSocket channel."));
+  }
+
+  if (!isDryRun) {
+    if (m_factories.count("websocket") > 0) {
+      return;
+    }
+
+    shared_ptr<WebSocketFactory> factory = make_shared<WebSocketFactory>(port);
+    m_factories.insert(std::make_pair("websocket", factory));
+
+    if (enableV6 && enableV4) {
+      shared_ptr<WebSocketChannel> ip46Channel = factory->createChannel("::", port);
+      if (needToListen) {
+        ip46Channel->listen(bind(&FaceTable::add, &m_faceTable, _1));
+      }
+
+      m_factories.insert(std::make_pair("websocket46", factory));
+    }
+    else if (enableV4) {
+      shared_ptr<WebSocketChannel> ipv4Channel = factory->createChannel("0.0.0.0", port);
+      if (needToListen) {
+        ipv4Channel->listen(bind(&FaceTable::add, &m_faceTable, _1));
+      }
+
+      m_factories.insert(std::make_pair("websocket4", factory));
+    }
+  }
+#else
+  BOOST_THROW_EXCEPTION(ConfigFile::Error("NFD was compiled without WebSocket, "
+                                          "cannot process \"websocket\" section"));
+#endif // HAVE_WEBSOCKET
+}
+
+void
+FaceManager::addCreatedFaceToForwarder(shared_ptr<Face> newFace)
+{
+  m_faceTable.add(newFace);
+}
+
+} // namespace
diff --git a/daemon/mgmt/face-manager.hpp b/daemon/mgmt/face-manager.hpp
new file mode 100644
index 0000000..f5283d6
--- /dev/null
+++ b/daemon/mgmt/face-manager.hpp
@@ -0,0 +1,164 @@
+/* -*- 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/>.
+ */
+
+#ifndef NFD_DAEMON_MGMT_FACE_MANAGER_HPP
+#define NFD_DAEMON_MGMT_FACE_MANAGER_HPP
+
+#include "manager-base.hpp"
+#include "face/local-face.hpp"
+#include <ndn-cxx/management/nfd-face-query-filter.hpp>
+
+namespace nfd {
+
+class FaceTable;
+class NetworkInterfaceInfo;
+class ProtocolFactory;
+
+/**
+ * @brief implement the Face Management of NFD Management Protocol.
+ * @sa http://redmine.named-data.net/projects/nfd/wiki/FaceMgmt
+ */
+class FaceManager : public ManagerBase
+{
+public:
+  FaceManager(FaceTable& faceTable,
+              Dispatcher& dispatcher,
+              CommandValidator& validator);
+
+  /**
+   * @brief Subscribe to face_system section for the config file
+   */
+  void
+  setConfigFile(ConfigFile& configFile);
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE: // ControlCommand
+  void
+  createFace(const Name& topPrefix, const Interest& interest,
+             const ControlParameters& parameters,
+             const ndn::mgmt::CommandContinuation& done);
+
+  void
+  destroyFace(const Name& topPrefix, const Interest& interest,
+              const ControlParameters& parameters,
+              const ndn::mgmt::CommandContinuation& done);
+
+  void
+  enableLocalControl(const Name& topPrefix, const Interest& interest,
+                     const ControlParameters& parameters,
+                     const ndn::mgmt::CommandContinuation& done);
+
+  void
+  disableLocalControl(const Name& topPrefix, const Interest& interest,
+                      const ControlParameters& parameters,
+                      const ndn::mgmt::CommandContinuation& done);
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE: // helpers for ControlCommand
+  void
+  afterCreateFaceSuccess(ControlParameters& parameters,
+                         const shared_ptr<Face>& newFace,
+                         const ndn::mgmt::CommandContinuation& done);
+
+  void
+  afterCreateFaceFailure(const std::string& reason,
+                         const ndn::mgmt::CommandContinuation& done);
+
+  struct ExtractLocalControlParametersResult
+  {
+    bool isValid;
+    shared_ptr<LocalFace> face;
+    LocalControlFeature feature;
+  };
+
+  ExtractLocalControlParametersResult
+  extractLocalControlParameters(const Interest& request,
+                                const ControlParameters& parameters,
+                                const ndn::mgmt::CommandContinuation& done);
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE: // StatusDataset
+  void
+  listFaces(const Name& topPrefix, const Interest& interest,
+            ndn::mgmt::StatusDatasetContext& context);
+
+  void
+  listChannels(const Name& topPrefix, const Interest& interest,
+               ndn::mgmt::StatusDatasetContext& context);
+
+  void
+  queryFaces(const Name& topPrefix, const Interest& interest,
+             ndn::mgmt::StatusDatasetContext& context);
+
+private: // helpers for StatusDataset handler
+  bool
+  doesMatchFilter(const ndn::nfd::FaceQueryFilter& filter, shared_ptr<Face> face);
+
+private: // NotificationStream
+  void
+  afterFaceAdded(shared_ptr<Face> face,
+                 const ndn::mgmt::PostNotification& post);
+
+  void
+  afterFaceRemoved(shared_ptr<Face> face,
+                   const ndn::mgmt::PostNotification& post);
+
+private: // configuration
+  void
+  processConfig(const ConfigSection& configSection, bool isDryRun, const std::string& filename);
+
+  void
+  processSectionUnix(const ConfigSection& configSection, bool isDryRun);
+
+  void
+  processSectionTcp(const ConfigSection& configSection, bool isDryRun);
+
+  void
+  processSectionUdp(const ConfigSection& configSection,
+                    bool isDryRun,
+                    const std::vector<NetworkInterfaceInfo>& nicList);
+
+  void
+  processSectionEther(const ConfigSection& configSection,
+                      bool isDryRun,
+                      const std::vector<NetworkInterfaceInfo>& nicList);
+
+  void
+  processSectionWebSocket(const ConfigSection& configSection, bool isDryRun);
+
+private: // helpers for configuration
+  void
+  addCreatedFaceToForwarder(shared_ptr<Face> newFace);
+
+PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  typedef std::map<std::string/*protocol*/, shared_ptr<ProtocolFactory>> FactoryMap;
+  FactoryMap m_factories;
+
+private:
+  FaceTable& m_faceTable;
+  signal::ScopedConnection m_faceAddConn;
+  signal::ScopedConnection m_faceRemoveConn;
+};
+
+} // namespace nfd
+
+#endif // NFD_DAEMON_MGMT_FACE_MANAGER_HPP
diff --git a/daemon/nfd.cpp b/daemon/nfd.cpp
index 741e495..14930ca 100644
--- a/daemon/nfd.cpp
+++ b/daemon/nfd.cpp
@@ -34,7 +34,7 @@
 #include "face/internal-face.hpp"
 #include "face/internal-client-face.hpp"
 // #include "mgmt/fib-manager.hpp"
-// #include "mgmt/face-manager.hpp"
+#include "mgmt/face-manager.hpp"
 // #include "mgmt/strategy-choice-manager.hpp"
 // #include "mgmt/status-server.hpp"
 #include "mgmt/general-config-section.hpp"
@@ -142,7 +142,9 @@
   //                                   bind(&Forwarder::getFace, m_forwarder.get(), _1),
   //                                   m_internalFace, m_keyChain));
 
-  // m_faceManager.reset(new FaceManager(m_forwarder->getFaceTable(), m_internalFace, m_keyChain));
+  m_faceManager.reset(new FaceManager(m_forwarder->getFaceTable(),
+                                      *m_dispatcher,
+                                      *m_validator));
 
   // m_strategyChoiceManager.reset(new StrategyChoiceManager(m_forwarder->getStrategyChoice(),
   //                                                         m_internalFace, m_keyChain));
@@ -161,7 +163,7 @@
 
   m_validator->setConfigFile(config);
 
-  // m_faceManager->setConfigFile(config);
+  m_faceManager->setConfigFile(config);
 
   // parse config file
   if (!m_configFile.empty()) {
@@ -202,8 +204,8 @@
 
   tablesConfig.setConfigFile(config);
 
-  // m_faceManager->setConfigFile(config);
   m_validator->setConfigFile(config);
+  m_faceManager->setConfigFile(config);
 
   if (!m_configFile.empty()) {
     config.parse(m_configFile, false);
@@ -218,7 +220,7 @@
 {
   // reload only face_system section of the config file to re-initialize multicast faces
   ConfigFile config(&ConfigFile::ignoreUnknownSection);
-  // m_faceManager->setConfigFile(config);
+  m_faceManager->setConfigFile(config);
 
   if (!m_configFile.empty()) {
     config.parse(m_configFile, false);
diff --git a/daemon/nfd.hpp b/daemon/nfd.hpp
index 7dc7148..eb7e012 100644
--- a/daemon/nfd.hpp
+++ b/daemon/nfd.hpp
@@ -114,7 +114,7 @@
 
   unique_ptr<ndn::mgmt::Dispatcher> m_dispatcher;
   // unique_ptr<FibManager>            m_fibManager;
-  // unique_ptr<FaceManager>           m_faceManager;
+  unique_ptr<FaceManager>           m_faceManager;
   // unique_ptr<StrategyChoiceManager> m_strategyChoiceManager;
   // unique_ptr<StatusServer>          m_statusServer;
 
diff --git a/tests/daemon/mgmt/face-manager-create-face.t.cpp b/tests/daemon/mgmt/face-manager-create-face.t.cpp
new file mode 100644
index 0000000..ffee5aa
--- /dev/null
+++ b/tests/daemon/mgmt/face-manager-create-face.t.cpp
@@ -0,0 +1,461 @@
+/* -*- 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/face-manager.hpp"
+#include "fw/forwarder.hpp"
+
+#include "tests/test-common.hpp"
+
+#include <ndn-cxx/mgmt/dispatcher.hpp>
+#include <ndn-cxx/util/dummy-client-face.hpp>
+
+#include <boost/property_tree/info_parser.hpp>
+
+namespace nfd {
+namespace tests {
+
+
+BOOST_AUTO_TEST_SUITE(Mgmt)
+BOOST_AUTO_TEST_SUITE(TestFaceManager)
+
+BOOST_FIXTURE_TEST_SUITE(CreateFace, BaseFixture)
+
+class FaceManagerNode
+{
+public:
+  FaceManagerNode(ndn::KeyChain& keyChain, const std::string& port = "6363")
+    : face(ndn::util::makeDummyClientFace(getGlobalIoService(), {true, true}))
+    , dispatcher(*face, keyChain, ndn::security::SigningInfo())
+    , manager(forwarder.getFaceTable(), dispatcher, validator)
+  {
+    dispatcher.addTopPrefix("/localhost/nfd");
+
+    std::string basicConfig =
+      "face_system\n"
+      "{\n"
+      "  tcp\n"
+      "  {\n"
+      "    port " + port + "\n"
+      "  }\n"
+      "  udp\n"
+      "  {\n"
+      "    port " + port + "\n"
+      "  }\n"
+      "}\n"
+      "authorizations\n"
+      "{\n"
+      "  authorize\n"
+      "  {\n"
+      "    certfile any\n"
+      "    privileges\n"
+      "    {\n"
+      "      faces\n"
+      "    }\n"
+      "  }\n"
+      "}\n"
+      "\n";
+    std::istringstream input(basicConfig);
+    nfd::ConfigSection configSection;
+    boost::property_tree::read_info(input, configSection);
+
+    ConfigFile config;
+    manager.setConfigFile(config);
+    validator.setConfigFile(config);
+    config.parse(configSection, false, "dummy-config");
+  }
+
+  void
+  closeFaces()
+  {
+    std::vector<shared_ptr<Face>> facesToClose;
+    std::copy(forwarder.getFaceTable().begin(), forwarder.getFaceTable().end(),
+              std::back_inserter(facesToClose));
+    for (auto face : facesToClose) {
+      face->close();
+    }
+  }
+
+public:
+  Forwarder forwarder;
+  shared_ptr<ndn::util::DummyClientFace> face;
+  ndn::mgmt::Dispatcher dispatcher;
+  CommandValidator validator;
+  FaceManager manager;
+};
+
+class FaceManagerFixture : public UnitTestTimeFixture
+{
+public:
+  FaceManagerFixture()
+    : node1(keyChain, "16363")
+    , node2(keyChain, "26363")
+  {
+    advanceClocks(time::milliseconds(1), 100);
+  }
+
+  ~FaceManagerFixture()
+  {
+    node1.closeFaces();
+    node2.closeFaces();
+    advanceClocks(time::milliseconds(1), 100);
+  }
+
+public:
+  ndn::KeyChain keyChain;
+  FaceManagerNode node1; // used to test FaceManager
+  FaceManagerNode node2; // acts as a remote endpoint
+};
+
+class TcpFaceOnDemand
+{
+public:
+  ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("tcp4://127.0.0.1:26363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
+  }
+};
+
+class TcpFacePersistent
+{
+public:
+  ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("tcp4://127.0.0.1:26363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
+  }
+};
+
+class TcpFacePermanent
+{
+public:
+  ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("tcp4://127.0.0.1:26363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERMANENT);
+  }
+};
+
+class UdpFaceOnDemand
+{
+public:
+  ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("udp4://127.0.0.1:26363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_ON_DEMAND);
+  }
+};
+
+class UdpFaceCannotConnect // face that will cause afterCreateFaceFailure to be invoked
+{
+public:
+  ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("udp4://0.0.0.0:16363"); // cannot connect to self
+  }
+};
+
+
+class UdpFacePersistent
+{
+public:
+  ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("udp4://127.0.0.1:26363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
+  }
+};
+
+class UdpFacePermanent
+{
+public:
+  ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("udp4://127.0.0.1:26363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERMANENT);
+  }
+};
+
+class Success
+{
+public:
+  ControlResponse
+  getExpected()
+  {
+    return ControlResponse()
+      .setCode(200)
+      .setText("OK");
+  }
+};
+
+template<int CODE>
+class Failure
+{
+public:
+  ControlResponse
+  getExpected()
+  {
+    return ControlResponse()
+      .setCode(CODE)
+      .setText("Error"); // error description should not be checked
+  }
+};
+
+namespace mpl = boost::mpl;
+
+// pairs of CreateCommand and Success status
+typedef mpl::vector<mpl::pair<TcpFaceOnDemand, Failure<500>>,
+                    mpl::pair<TcpFacePersistent, Success>,
+                    mpl::pair<TcpFacePermanent, Failure<500>>,
+                    mpl::pair<UdpFaceOnDemand, Failure<500>>,
+                    mpl::pair<UdpFacePersistent, Success>,
+                    mpl::pair<UdpFacePermanent, Success>,
+                    mpl::pair<UdpFaceCannotConnect, Failure<408>>> Faces;
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(NewFace, T, Faces, FaceManagerFixture)
+{
+  typedef typename T::first FaceType;
+  typedef typename T::second CreateResult;
+
+  Name commandName("/localhost/nfd/faces");
+  commandName.append("create");
+  commandName.append(FaceType().getParameters().wireEncode());
+
+  shared_ptr<Interest> command(make_shared<Interest>(commandName));
+  this->keyChain.sign(*command);
+
+  bool hasCallbackFired = false;
+  this->node1.face->onSendData.connect([this, command, &hasCallbackFired] (const Data& response) {
+      // std::cout << response << std::endl;
+      if (!command->getName().isPrefixOf(response.getName())) {
+        return;
+      }
+
+      ControlResponse actual(response.getContent().blockFromValue());
+      ControlResponse expected(CreateResult().getExpected());
+      BOOST_CHECK_EQUAL(expected.getCode(), actual.getCode());
+      BOOST_MESSAGE(actual.getText());
+
+      if (actual.getBody().hasWire()) {
+        ControlParameters expectedParams(FaceType().getParameters());
+        ControlParameters actualParams(actual.getBody());
+
+        BOOST_CHECK_EQUAL(expectedParams.getUri(), actualParams.getUri());
+        BOOST_CHECK_EQUAL(expectedParams.getFacePersistency(), actualParams.getFacePersistency());
+      }
+      hasCallbackFired = true;
+    });
+
+  this->node1.face->receive(*command);
+  this->advanceClocks(time::milliseconds(1), 100);
+
+  BOOST_CHECK(hasCallbackFired);
+}
+
+
+typedef mpl::vector<// mpl::pair<mpl::pair<TcpFacePersistent, TcpFacePermanent>, TcpFacePermanent>, // no need to check now
+                    // mpl::pair<mpl::pair<TcpFacePermanent, TcpFacePersistent>, TcpFacePermanent>, // no need to check now
+                    mpl::pair<mpl::pair<UdpFacePersistent, UdpFacePermanent>, UdpFacePermanent>,
+                    mpl::pair<mpl::pair<UdpFacePermanent, UdpFacePersistent>, UdpFacePermanent>> FaceTransitions;
+
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(ExistingFace, T, FaceTransitions, FaceManagerFixture)
+{
+  typedef typename T::first::first FaceType1;
+  typedef typename T::first::second FaceType2;
+  typedef typename T::second FinalFaceType;
+
+  {
+    // create face
+
+    Name commandName("/localhost/nfd/faces");
+    commandName.append("create");
+    commandName.append(FaceType1().getParameters().wireEncode());
+
+    shared_ptr<Interest> command(make_shared<Interest>(commandName));
+    this->keyChain.sign(*command);
+
+    this->node1.face->receive(*command);
+    this->advanceClocks(time::milliseconds(1), 10);
+  }
+
+  //
+  {
+    // re-create face (= change face persistency)
+
+    Name commandName("/localhost/nfd/faces");
+    commandName.append("create");
+    commandName.append(FaceType2().getParameters().wireEncode());
+
+    shared_ptr<Interest> command(make_shared<Interest>(commandName));
+    this->keyChain.sign(*command);
+
+    bool hasCallbackFired = false;
+    this->node1.face->onSendData.connect([this, command, &hasCallbackFired] (const Data& response) {
+        if (!command->getName().isPrefixOf(response.getName())) {
+          return;
+        }
+
+        ControlResponse actual(response.getContent().blockFromValue());
+        BOOST_REQUIRE_EQUAL(actual.getCode(), 200);
+
+        ControlParameters expectedParams(FinalFaceType().getParameters());
+        ControlParameters actualParams(actual.getBody());
+        BOOST_CHECK_EQUAL(expectedParams.getFacePersistency(), actualParams.getFacePersistency());
+
+        hasCallbackFired = true;
+      });
+
+    this->node1.face->receive(*command);
+    this->advanceClocks(time::milliseconds(1), 10);
+
+    BOOST_CHECK(hasCallbackFired);
+  }
+}
+
+
+class UdpFace
+{
+public:
+  ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("udp4://127.0.0.1:16363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
+  }
+};
+
+
+// Note that the transitions from on-demand TcpFace are intentionally not tested.
+// On-demand TcpFace has a remote endpoint with a randomized port number.  Normal face
+// creation operations will not need to create a face toward a remote port not listened by
+// a channel.
+
+typedef mpl::vector<mpl::pair<UdpFace, UdpFacePersistent>,
+                    mpl::pair<UdpFace, UdpFacePermanent>> OnDemandFaceTransitions;
+
+// need a slightly different logic to test transitions from OnDemand state
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(ExistingFaceOnDemand, T, OnDemandFaceTransitions, FaceManagerFixture)
+{
+  typedef typename T::first  OtherNodeFace;
+  typedef typename T::second FaceType;
+
+  {
+    // create on-demand face
+
+    Name commandName("/localhost/nfd/faces");
+    commandName.append("create");
+    commandName.append(OtherNodeFace().getParameters().wireEncode());
+
+    shared_ptr<Interest> command(make_shared<Interest>(commandName));
+    this->keyChain.sign(*command);
+
+    ndn::util::signal::ScopedConnection connection =
+      this->node2.face->onSendData.connect([this, command] (const Data& response) {
+          if (!command->getName().isPrefixOf(response.getName())) {
+            return;
+          }
+
+          ControlResponse controlResponse(response.getContent().blockFromValue());
+          BOOST_REQUIRE_EQUAL(controlResponse.getText(), "OK");
+          BOOST_REQUIRE_EQUAL(controlResponse.getCode(), 200);
+          uint64_t faceId = ControlParameters(controlResponse.getBody()).getFaceId();
+          auto face = this->node2.forwarder.getFace(static_cast<FaceId>(faceId));
+
+          // to force creation of on-demand face
+          auto dummyInterest = make_shared<Interest>("/hello/world");
+          face->sendInterest(*dummyInterest);
+        });
+
+    this->node2.face->receive(*command);
+    this->advanceClocks(time::milliseconds(1), 10);
+  }
+
+  // make sure there is on-demand face
+  bool onDemandFaceFound = false;
+  FaceUri onDemandFaceUri(FaceType().getParameters().getUri());
+  for (auto face : this->node1.forwarder.getFaceTable()) {
+    if (face->getRemoteUri() == onDemandFaceUri) {
+      onDemandFaceFound = true;
+      break;
+    }
+  }
+  BOOST_REQUIRE(onDemandFaceFound);
+
+  //
+  {
+    // re-create face (= change face persistency)
+
+    Name commandName("/localhost/nfd/faces");
+    commandName.append("create");
+    commandName.append(FaceType().getParameters().wireEncode());
+
+    shared_ptr<Interest> command(make_shared<Interest>(commandName));
+    this->keyChain.sign(*command);
+
+    bool hasCallbackFired = false;
+    this->node1.face->onSendData.connect([this, command, &hasCallbackFired] (const Data& response) {
+        if (!command->getName().isPrefixOf(response.getName())) {
+          return;
+        }
+
+        ControlResponse actual(response.getContent().blockFromValue());
+        BOOST_REQUIRE_EQUAL(actual.getCode(), 200);
+
+        ControlParameters expectedParams(FaceType().getParameters());
+        ControlParameters actualParams(actual.getBody());
+        BOOST_CHECK_EQUAL(expectedParams.getFacePersistency(), actualParams.getFacePersistency());
+
+        hasCallbackFired = true;
+      });
+
+    this->node1.face->receive(*command);
+    this->advanceClocks(time::milliseconds(1), 10);
+
+    BOOST_CHECK(hasCallbackFired);
+  }
+}
+
+BOOST_AUTO_TEST_SUITE_END() // CreateFace
+BOOST_AUTO_TEST_SUITE_END() // TestFaceManager
+BOOST_AUTO_TEST_SUITE_END() // Mgmt
+
+} // tests
+} // nfd
diff --git a/tests/daemon/mgmt/face-manager-process-config.t.cpp b/tests/daemon/mgmt/face-manager-process-config.t.cpp
new file mode 100644
index 0000000..9463ac4
--- /dev/null
+++ b/tests/daemon/mgmt/face-manager-process-config.t.cpp
@@ -0,0 +1,438 @@
+/* -*- 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/face-manager.hpp"
+#include "face/udp-factory.hpp"
+
+#ifdef HAVE_LIBPCAP
+#include "face/ethernet-factory.hpp"
+#endif // HAVE_LIBPCAP
+
+#include "manager-common-fixture.hpp"
+
+namespace nfd {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(Mgmt)
+BOOST_AUTO_TEST_SUITE(TestFaceManager)
+
+class FaceManagerProcessConfigFixture : public ManagerCommonFixture
+{
+public:
+  FaceManagerProcessConfigFixture()
+    : m_manager(m_forwarder.getFaceTable(), m_dispatcher, m_validator)
+  {
+    m_manager.setConfigFile(m_config);
+  }
+
+public:
+  void
+  parseConfig(const std::string& type, bool isDryRun)
+  {
+    m_config.parse(type, isDryRun, "test-config");
+  }
+
+protected:
+  FaceManager m_manager;
+  ConfigFile m_config;
+};
+
+
+BOOST_FIXTURE_TEST_SUITE(ProcessConfig, FaceManagerProcessConfigFixture)
+
+#ifdef HAVE_UNIX_SOCKETS
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUnix)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  unix\n"
+    "  {\n"
+    "    path /tmp/nfd.sock\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, true));
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, false));
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUnixUnknownOption)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  unix\n"
+    "  {\n"
+    "    hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+#endif // HAVE_UNIX_SOCKETS
+
+BOOST_AUTO_TEST_CASE(ProcessSectionTcp)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  tcp\n"
+    "  {\n"
+    "    listen yes\n"
+    "    port 16363\n"
+    "    enable_v4 yes\n"
+    "    enable_v6 yes\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, true));
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, false));
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionTcpBadListen)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  tcp\n"
+    "  {\n"
+    "    listen hello\n"
+    "  }\n"
+    "}\n";
+
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionTcpChannelsDisabled)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  tcp\n"
+    "  {\n"
+    "    port 6363\n"
+    "    enable_v4 no\n"
+    "    enable_v6 no\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionTcpUnknownOption)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  tcp\n"
+    "  {\n"
+    "    hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUdp)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    port 6363\n"
+    "    enable_v4 yes\n"
+    "    enable_v6 yes\n"
+    "    idle_timeout 30\n"
+    "    keep_alive_interval 25\n"
+    "    mcast yes\n"
+    "    mcast_port 56363\n"
+    "    mcast_group 224.0.23.170\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, true));
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, false));
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUdpBadIdleTimeout)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    idle_timeout hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUdpBadMcast)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    mcast hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUdpBadMcastGroup)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    mcast no\n"
+    "    mcast_port 50\n"
+    "    mcast_group hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUdpBadMcastGroupV6)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    mcast no\n"
+    "    mcast_port 50\n"
+    "    mcast_group ::1\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUdpChannelsDisabled)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    port 6363\n"
+    "    enable_v4 no\n"
+    "    enable_v6 no\n"
+    "    idle_timeout 30\n"
+    "    keep_alive_interval 25\n"
+    "    mcast yes\n"
+    "    mcast_port 56363\n"
+    "    mcast_group 224.0.23.170\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUdpConflictingMcast)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    port 6363\n"
+    "    enable_v4 no\n"
+    "    enable_v6 yes\n"
+    "    idle_timeout 30\n"
+    "    keep_alive_interval 25\n"
+    "    mcast yes\n"
+    "    mcast_port 56363\n"
+    "    mcast_group 224.0.23.170\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUdpUnknownOption)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+
+BOOST_AUTO_TEST_CASE(ProcessSectionUdpMulticastReinit)
+{
+  const std::string CONFIG_WITH_MCAST =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    mcast yes\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG_WITH_MCAST, false));
+
+  BOOST_REQUIRE(m_manager.m_factories.find("udp") != m_manager.m_factories.end());
+  auto factory = dynamic_pointer_cast<UdpFactory>(m_manager.m_factories.find("udp")->second);
+  BOOST_REQUIRE(factory != nullptr);
+
+  if (factory->getMulticastFaces().size() == 0) {
+    BOOST_TEST_MESSAGE("Destroying multicast faces is not tested because "
+                       "no UDP multicast faces are available");
+    return;
+  }
+  BOOST_CHECK_GT(factory->getMulticastFaces().size(), 0);
+
+  const std::string CONFIG_WITHOUT_MCAST =
+    "face_system\n"
+    "{\n"
+    "  udp\n"
+    "  {\n"
+    "    mcast no\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG_WITHOUT_MCAST, false));
+  BOOST_CHECK_EQUAL(factory->getMulticastFaces().size(), 0);
+}
+
+#ifdef HAVE_LIBPCAP
+
+BOOST_AUTO_TEST_CASE(ProcessSectionEther)
+{
+
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  ether\n"
+    "  {\n"
+    "    mcast yes\n"
+    "    mcast_group 01:00:5E:00:17:AA\n"
+    "  }\n"
+    "}\n";
+
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, true));
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG, false));
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionEtherBadMcast)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  ether\n"
+    "  {\n"
+    "    mcast hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionEtherBadMcastGroup)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  ether\n"
+    "  {\n"
+    "    mcast yes\n"
+    "    mcast_group\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionEtherUnknownOption)
+{
+  const std::string CONFIG =
+    "face_system\n"
+    "{\n"
+    "  ether\n"
+    "  {\n"
+    "    hello\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
+  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
+}
+
+BOOST_AUTO_TEST_CASE(ProcessSectionEtherMulticastReinit)
+{
+  const std::string CONFIG_WITH_MCAST =
+    "face_system\n"
+    "{\n"
+    "  ether\n"
+    "  {\n"
+    "    mcast yes\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG_WITH_MCAST, false));
+
+  BOOST_REQUIRE(m_manager.m_factories.find("ether") != m_manager.m_factories.end());
+  auto factory = dynamic_pointer_cast<EthernetFactory>(m_manager.m_factories.find("ether")->second);
+  BOOST_REQUIRE(factory != nullptr);
+
+  if (factory->getMulticastFaces().size() == 0) {
+    BOOST_TEST_MESSAGE("Destroying multicast faces is not tested because "
+                       "no Ethernet multicast faces are available");
+    return;
+  }
+  BOOST_CHECK_GT(factory->getMulticastFaces().size(), 0);
+
+  const std::string CONFIG_WITHOUT_MCAST =
+    "face_system\n"
+    "{\n"
+    "  ether\n"
+    "  {\n"
+    "    mcast no\n"
+    "  }\n"
+    "}\n";
+  BOOST_CHECK_NO_THROW(parseConfig(CONFIG_WITHOUT_MCAST, false));
+  BOOST_CHECK_EQUAL(factory->getMulticastFaces().size(), 0);
+}
+
+#endif // HAVE_LIBPCAP
+
+BOOST_AUTO_TEST_SUITE_END() // ProcessConfig
+BOOST_AUTO_TEST_SUITE_END() // TestFaceManager
+BOOST_AUTO_TEST_SUITE_END() // Mgmt
+
+} // namespace tests
+} // namespace nfd
diff --git a/tests/daemon/mgmt/face-manager.t.cpp b/tests/daemon/mgmt/face-manager.t.cpp
new file mode 100644
index 0000000..db24029
--- /dev/null
+++ b/tests/daemon/mgmt/face-manager.t.cpp
@@ -0,0 +1,449 @@
+/* -*- 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/face-manager.hpp"
+#include "manager-common-fixture.hpp"
+#include "../face/dummy-face.hpp"
+#include "face/tcp-factory.hpp"
+#include "face/udp-factory.hpp"
+
+#include <ndn-cxx/util/random.hpp>
+#include <ndn-cxx/encoding/tlv.hpp>
+#include <ndn-cxx/management/nfd-channel-status.hpp>
+#include <ndn-cxx/management/nfd-face-event-notification.hpp>
+
+namespace nfd {
+namespace tests {
+
+class FaceManagerFixture : public ManagerCommonFixture
+{
+public:
+  FaceManagerFixture()
+    : m_faceTable(m_forwarder.getFaceTable())
+    , m_manager(m_faceTable, m_dispatcher, m_validator)
+  {
+    setTopPrefixAndPrivilege("/localhost/nfd", "faces");
+  }
+
+public:
+  template<typename Face>
+  shared_ptr<Face>
+  addFace(bool wantRemoveLastNotification = false)
+  {
+    auto face = make_shared<Face>();
+    m_faceTable.add(face);
+    advanceClocks(time::milliseconds(1), 10); // wait for notification posted
+    if (wantRemoveLastNotification) {
+      m_responses.pop_back();
+    }
+    return face;
+  }
+
+protected:
+  FaceTable& m_faceTable;
+  FaceManager m_manager;
+};
+
+BOOST_FIXTURE_TEST_SUITE(Mgmt, FaceManagerFixture)
+BOOST_AUTO_TEST_SUITE(TestFaceManager)
+
+BOOST_AUTO_TEST_SUITE(DestroyFace)
+
+BOOST_AUTO_TEST_CASE(Existing)
+{
+  auto addedFace = addFace<DummyFace>(true); // clear notification for creation
+
+  auto parameters = ControlParameters().setFaceId(addedFace->getId());
+  auto command = makeControlCommandRequest("/localhost/nfd/faces/destroy", parameters);
+
+  receiveInterest(command);
+
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 2); // one response and one notification
+  // notification is already tested, so ignore it
+
+  BOOST_CHECK_EQUAL(checkResponse(1, command->getName(), makeResponse(200, "OK", parameters)),
+                    CheckResponseResult::OK);
+
+  BOOST_CHECK_EQUAL(addedFace->getId(), -1);
+}
+
+BOOST_AUTO_TEST_CASE(NonExisting)
+{
+  auto parameters = ControlParameters().setFaceId(65535);
+  auto command = makeControlCommandRequest("/localhost/nfd/faces/destroy", parameters);
+
+  receiveInterest(command);
+
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+
+  BOOST_CHECK_EQUAL(checkResponse(0, command->getName(), makeResponse(200, "OK", parameters)),
+                    CheckResponseResult::OK);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // DestroyFace
+
+BOOST_AUTO_TEST_CASE(FaceEvents)
+{
+  auto addedFace = addFace<DummyFace>(); // trigger FACE_EVENT_CREATED notification
+  BOOST_CHECK_NE(addedFace->getId(), -1);
+  int64_t faceId = addedFace->getId();
+
+  // check notification
+  {
+    Block payload;
+    ndn::nfd::FaceEventNotification notification;
+    BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
+    BOOST_CHECK_NO_THROW(payload = m_responses[0].getContent().blockFromValue());
+    BOOST_CHECK_EQUAL(payload.type(), ndn::tlv::nfd::FaceEventNotification);
+    BOOST_CHECK_NO_THROW(notification.wireDecode(payload));
+    BOOST_CHECK_EQUAL(notification.getKind(), ndn::nfd::FACE_EVENT_CREATED);
+    BOOST_CHECK_EQUAL(notification.getFaceId(), faceId);
+    BOOST_CHECK_EQUAL(notification.getRemoteUri(), addedFace->getRemoteUri().toString());
+    BOOST_CHECK_EQUAL(notification.getLocalUri(), addedFace->getLocalUri().toString());
+    BOOST_CHECK_EQUAL(notification.getFaceScope(), ndn::nfd::FACE_SCOPE_NON_LOCAL);
+    BOOST_CHECK_EQUAL(notification.getFacePersistency(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
+    BOOST_CHECK_EQUAL(notification.getLinkType(), ndn::nfd::LinkType::LINK_TYPE_POINT_TO_POINT);
+  }
+
+  addedFace->close(); // trigger FaceDestroy FACE_EVENT_DESTROYED
+  advanceClocks(time::milliseconds(1), 10);
+
+  // check notification
+  {
+    Block payload;
+    ndn::nfd::FaceEventNotification notification;
+    BOOST_REQUIRE_EQUAL(m_responses.size(), 2);
+    BOOST_CHECK_NO_THROW(payload = m_responses[1].getContent().blockFromValue());
+    BOOST_CHECK_EQUAL(payload.type(), ndn::tlv::nfd::FaceEventNotification);
+    BOOST_CHECK_NO_THROW(notification.wireDecode(payload));
+    BOOST_CHECK_EQUAL(notification.getKind(), ndn::nfd::FACE_EVENT_DESTROYED);
+    BOOST_CHECK_EQUAL(notification.getFaceId(), faceId);
+    BOOST_CHECK_EQUAL(notification.getRemoteUri(), addedFace->getRemoteUri().toString());
+    BOOST_CHECK_EQUAL(notification.getLocalUri(), addedFace->getLocalUri().toString());
+    BOOST_CHECK_EQUAL(notification.getFaceScope(), ndn::nfd::FACE_SCOPE_NON_LOCAL);
+    BOOST_CHECK_EQUAL(notification.getFacePersistency(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT);
+    BOOST_CHECK_EQUAL(notification.getLinkType(), ndn::nfd::LinkType::LINK_TYPE_POINT_TO_POINT);
+  }
+  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:
+  explicit
+  TestFace(const std::string& uri = "test://")
+    : DummyFace(uri, uri)
+  {
+    getMutableCounters().getNInInterests().set(ndn::random::generateWord64());
+    getMutableCounters().getNInDatas().set(ndn::random::generateWord64());
+    getMutableCounters().getNOutInterests().set(ndn::random::generateWord64());
+    getMutableCounters().getNOutDatas().set(ndn::random::generateWord64());
+    getMutableCounters().getNInBytes().set(ndn::random::generateWord64());
+    getMutableCounters().getNOutBytes().set(ndn::random::generateWord64());
+  }
+};
+
+// @todo Refactor when ndn::nfd::FaceStatus implementes operator!= and operator<<
+class FaceStatus : public ndn::nfd::FaceStatus
+{
+public:
+  FaceStatus(const ndn::nfd::FaceStatus& s)
+    : ndn::nfd::FaceStatus(s)
+  {
+  }
+};
+
+bool
+operator!=(const FaceStatus& left, const FaceStatus& right)
+{
+  return left.getRemoteUri() != right.getRemoteUri() ||
+    left.getLocalUri() != right.getLocalUri() ||
+    left.getFaceScope() != right.getFaceScope() ||
+    left.getFacePersistency() != right.getFacePersistency() ||
+    left.getLinkType() != right.getLinkType() ||
+    left.getNInInterests() != right.getNInInterests() ||
+    left.getNInDatas() != right.getNInDatas() ||
+    left.getNOutInterests() != right.getNOutInterests() ||
+    left.getNOutDatas() != right.getNOutDatas() ||
+    left.getNInBytes() != right.getNInBytes() ||
+    left.getNOutBytes() != right.getNOutBytes();
+}
+
+std::ostream&
+operator<<(std::ostream &os, const FaceStatus& status)
+{
+  os << "[" << status.getRemoteUri() << ", "
+     << status.getLocalUri() << ", "
+     << status.getFacePersistency() << ", "
+     << status.getLinkType() << ", "
+     << status.getNInInterests() << ", "
+     << status.getNInDatas() << ", "
+     << status.getNOutInterests() << ", "
+     << status.getNOutDatas() << ", "
+     << status.getNInBytes() << ", "
+     << status.getNOutBytes() << "]";
+  return os;
+}
+
+BOOST_AUTO_TEST_CASE(FaceDataset)
+{
+  size_t nEntries = 303;
+  for (size_t i = 0 ; i < nEntries ; i ++) {
+    addFace<TestFace>(true);
+  }
+
+  receiveInterest(makeInterest("/localhost/nfd/faces/list"));
+
+  Block content;
+  BOOST_CHECK_NO_THROW(content = concatenateResponses());
+  BOOST_CHECK_NO_THROW(content.parse());
+  BOOST_REQUIRE_EQUAL(content.elements().size(), nEntries);
+
+  std::vector<FaceStatus> expectedStatuses, receivedStatuses;
+  std::set<FaceId> faceIds;
+  for (size_t idx = 0; idx < nEntries; ++idx) {
+    BOOST_TEST_MESSAGE("processing element: " << idx);
+
+    ndn::nfd::FaceStatus decodedStatus;
+    BOOST_REQUIRE_NO_THROW(decodedStatus.wireDecode(content.elements()[idx]));
+    BOOST_REQUIRE(m_faceTable.get(decodedStatus.getFaceId()) != nullptr);
+    faceIds.insert(decodedStatus.getFaceId());
+    receivedStatuses.push_back(decodedStatus);
+    expectedStatuses.push_back(m_faceTable.get(decodedStatus.getFaceId())->getFaceStatus());
+  }
+
+  BOOST_CHECK_EQUAL(faceIds.size(), nEntries);
+  BOOST_CHECK_EQUAL_COLLECTIONS(receivedStatuses.begin(), receivedStatuses.end(),
+                                expectedStatuses.begin(), expectedStatuses.end());
+}
+
+BOOST_AUTO_TEST_CASE(FaceQuery)
+{
+  auto face1 = addFace<DummyFace>(true); // dummy://
+  auto face2 = addFace<DummyLocalFace>(true); // dummy://, local
+  auto face3 = addFace<TestFace>(true); // test://
+
+  auto generateQueryName = [] (const ndn::nfd::FaceQueryFilter& filter) {
+    return Name("/localhost/nfd/faces/query").append(filter.wireEncode());
+  };
+
+  auto querySchemeName =
+    generateQueryName(ndn::nfd::FaceQueryFilter().setUriScheme("dummy"));
+  auto queryIdName =
+    generateQueryName(ndn::nfd::FaceQueryFilter().setFaceId(face1->getId()));
+  auto queryScopeName =
+    generateQueryName(ndn::nfd::FaceQueryFilter().setFaceScope(ndn::nfd::FACE_SCOPE_NON_LOCAL));
+  auto invalidQueryName =
+    Name("/localhost/nfd/faces/query").append(ndn::makeStringBlock(tlv::Content, "invalid"));
+
+  receiveInterest(makeInterest(querySchemeName)); // face1 and face2 expected
+  receiveInterest(makeInterest(queryIdName)); // face1 expected
+  receiveInterest(makeInterest(queryScopeName)); // face1 and face3 expected
+  receiveInterest(makeInterest(invalidQueryName)); // nack expected
+
+  BOOST_REQUIRE_EQUAL(m_responses.size(), 4);
+
+  Block content;
+  ndn::nfd::FaceStatus status;
+
+  content = m_responses[0].getContent();
+  BOOST_CHECK_NO_THROW(content.parse());
+  BOOST_CHECK_EQUAL(content.elements().size(), 2); // face1 and face2
+  BOOST_CHECK_NO_THROW(status.wireDecode(content.elements()[0]));
+  BOOST_CHECK_EQUAL(face1->getId(), status.getFaceId());
+  BOOST_CHECK_NO_THROW(status.wireDecode(content.elements()[1]));
+  BOOST_CHECK_EQUAL(face2->getId(), status.getFaceId());
+
+  content = m_responses[1].getContent();
+  BOOST_CHECK_NO_THROW(content.parse());
+  BOOST_CHECK_EQUAL(content.elements().size(), 1); // face1
+  BOOST_CHECK_NO_THROW(status.wireDecode(content.elements()[0]));
+  BOOST_CHECK_EQUAL(face1->getId(), status.getFaceId());
+
+  content = m_responses[2].getContent();
+  BOOST_CHECK_NO_THROW(content.parse());
+  BOOST_CHECK_EQUAL(content.elements().size(), 2); // face1 and face3
+  BOOST_CHECK_NO_THROW(status.wireDecode(content.elements()[0]));
+  BOOST_CHECK_EQUAL(face1->getId(), status.getFaceId());
+  BOOST_CHECK_NO_THROW(status.wireDecode(content.elements()[1]));
+  BOOST_CHECK_EQUAL(face3->getId(), status.getFaceId());
+
+  ControlResponse expectedResponse(400, "malformed filter"); // nack, 400, malformed filter
+  BOOST_CHECK_EQUAL(checkResponse(3, invalidQueryName, expectedResponse, tlv::ContentType_Nack),
+                    CheckResponseResult::OK);
+}
+
+class TestChannel : public Channel
+{
+public:
+  TestChannel(const std::string& uri)
+  {
+    setUri(FaceUri(uri));
+  }
+};
+
+class TestProtocolFactory : public ProtocolFactory
+{
+public:
+  virtual void
+  createFace(const FaceUri& uri,
+             ndn::nfd::FacePersistency persistency,
+             const FaceCreatedCallback& onCreated,
+             const FaceConnectFailedCallback& onConnectFailed) DECL_OVERRIDE
+  {
+  }
+
+  virtual std::list<shared_ptr<const Channel>>
+  getChannels() const DECL_OVERRIDE
+  {
+    return m_channels;
+  }
+
+public:
+  shared_ptr<TestChannel>
+  addChannel(const std::string& channelUri)
+  {
+    auto channel = make_shared<TestChannel>(channelUri);
+    m_channels.push_back(channel);
+    return channel;
+  }
+
+private:
+  std::list<shared_ptr<const Channel> > m_channels;
+};
+
+BOOST_AUTO_TEST_CASE(ChannelDataset)
+{
+  auto factory = make_shared<TestProtocolFactory>();
+  m_manager.m_factories["test"] = factory;
+
+  std::map<std::string, shared_ptr<TestChannel>> addedChannels;
+  size_t nEntries = 404;
+  for (size_t i = 0 ; i < nEntries ; i ++) {
+    auto channel = factory->addChannel("test" + boost::lexical_cast<std::string>(i) + "://");
+    addedChannels[channel->getUri().toString()] = channel;
+  }
+
+  receiveInterest(makeInterest("/localhost/nfd/faces/channels"));
+
+  Block content;
+  BOOST_CHECK_NO_THROW(content = concatenateResponses());
+  BOOST_CHECK_NO_THROW(content.parse());
+  BOOST_REQUIRE_EQUAL(content.elements().size(), nEntries);
+
+  for (size_t idx = 0; idx < nEntries; ++idx) {
+    BOOST_TEST_MESSAGE("processing element: " << idx);
+
+    ndn::nfd::ChannelStatus decodedStatus;
+    BOOST_CHECK_NO_THROW(decodedStatus.wireDecode(content.elements()[idx]));
+    BOOST_CHECK(addedChannels.find(decodedStatus.getLocalUri()) != addedChannels.end());
+  }
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestFaceManager
+BOOST_AUTO_TEST_SUITE_END() // Mgmt
+
+} // namespace tests
+} // namespace nfd
