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;
 
