diff --git a/daemon/mgmt/face-manager.cpp b/daemon/mgmt/face-manager.cpp
index 768f1b9..164df04 100644
--- a/daemon/mgmt/face-manager.cpp
+++ b/daemon/mgmt/face-manager.cpp
@@ -26,24 +26,9 @@
 #include "face-manager.hpp"
 
 #include "core/logger.hpp"
-#include "core/network-interface.hpp"
-#include "fw/face-table.hpp"
-#include "face/tcp-factory.hpp"
-#include "face/udp-factory.hpp"
 #include "core/config-file.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
+#include "face/protocol-factory.hpp"
+#include "fw/face-table.hpp"
 
 #include <ndn-cxx/management/nfd-face-event-notification.hpp>
 #include <ndn-cxx/management/nfd-face-query-filter.hpp>
@@ -160,686 +145,10 @@
                       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)
-            throw Error("Duplicate \"unix\" section");
-          hasSeenUnix = true;
-
-          processSectionUnix(item.second, isDryRun);
-        }
-      else if (item.first == "tcp")
-        {
-          if (hasSeenTcp)
-            throw Error("Duplicate \"tcp\" section");
-          hasSeenTcp = true;
-
-          processSectionTcp(item.second, isDryRun);
-        }
-      else if (item.first == "udp")
-        {
-          if (hasSeenUdp)
-            throw Error("Duplicate \"udp\" section");
-          hasSeenUdp = true;
-
-          processSectionUdp(item.second, isDryRun, nicList);
-        }
-      else if (item.first == "ether")
-        {
-          if (hasSeenEther)
-            throw Error("Duplicate \"ether\" section");
-          hasSeenEther = true;
-
-          processSectionEther(item.second, isDryRun, nicList);
-        }
-      else if (item.first == "websocket")
-        {
-          if (hasSeenWebSocket)
-            throw Error("Duplicate \"websocket\" section");
-          hasSeenWebSocket = true;
-
-          processSectionWebSocket(item.second, isDryRun);
-        }
-      else
-        {
-          throw Error("Unrecognized option \"" + item.first + "\"");
-        }
-    }
+  throw Error("Not supported");
 }
 
 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 (ConfigSection::const_iterator i = configSection.begin();
-       i != configSection.end();
-       ++i)
-    {
-      if (i->first == "path")
-        {
-          path = i->second.get_value<std::string>();
-        }
-      else
-        {
-          throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"unix\" section");
-        }
-    }
-
-  if (!isDryRun)
-    {
-      if (m_factories.count("unix") > 0)
-        {
-          return;
-          // shared_ptr<UnixStreamFactory> factory
-          //   = static_pointer_cast<UnixStreamFactory>(m_factories["unix"]);
-          // shared_ptr<UnixStreamChannel> unixChannel = factory->findChannel(path);
-
-          // if (static_cast<bool>(unixChannel))
-          //   {
-          //     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
-  throw 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 (ConfigSection::const_iterator 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)
-            {
-              throw ConfigFile::Error("Invalid value for option " +
-                                      i->first + "\" in \"tcp\" section");
-            }
-        }
-      else if (i->first == "listen")
-        {
-          needToListen = parseYesNo(i, i->first, "tcp");
-        }
-      else if (i->first == "enable_v4")
-        {
-          enableV4 = parseYesNo(i, i->first, "tcp");
-        }
-      else if (i->first == "enable_v6")
-        {
-          enableV6 = parseYesNo(i, i->first, "tcp");
-        }
-      else
-        {
-          throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"tcp\" section");
-        }
-    }
-
-  if (!enableV4 && !enableV6)
-    {
-      throw 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 30 ; 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 = 30;
-  size_t keepAliveInterval = 25;
-  bool useMcast = true;
-  std::string mcastGroup = "224.0.23.170";
-  std::string mcastPort = "56363";
-
-
-  for (ConfigSection::const_iterator 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)
-            {
-              throw ConfigFile::Error("Invalid value for option " +
-                                      i->first + "\" in \"udp\" section");
-            }
-        }
-      else if (i->first == "enable_v4")
-        {
-          enableV4 = parseYesNo(i, i->first, "udp");
-        }
-      else if (i->first == "enable_v6")
-        {
-          enableV6 = parseYesNo(i, i->first, "udp");
-        }
-      else if (i->first == "idle_timeout")
-        {
-          try
-            {
-              timeout = i->second.get_value<size_t>();
-            }
-          catch (const std::exception& e)
-            {
-              throw 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
-              (void)(keepAliveInterval);
-            }
-          catch (const std::exception& e)
-            {
-              throw ConfigFile::Error("Invalid value for option \"" +
-                                      i->first + "\" in \"udp\" section");
-            }
-        }
-      else if (i->first == "mcast")
-        {
-          useMcast = 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)
-            {
-              throw 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())
-                {
-                  throw ConfigFile::Error("Invalid value for option \"" +
-                                          i->first + "\" in \"udp\" section");
-                }
-            }
-          catch(const std::runtime_error& e)
-            {
-              throw ConfigFile::Error("Invalid value for option \"" +
-                                      i->first + "\" in \"udp\" section");
-            }
-        }
-      else
-        {
-          throw ConfigFile::Error("Unrecognized option \"" + i->first + "\" in \"udp\" section");
-        }
-    }
-
-  if (!enableV4 && !enableV6)
-    {
-      throw 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)
-    {
-      throw ConfigFile::Error("IPv4 multicast requested, but IPv4 channels"
-                              " have been disabled (conflicting configuration options set)");
-    }
-
-  /// \todo what is keep alive interval used for?
-
-  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 (UdpFactory::MulticastFaceMap::const_iterator 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 (std::list<shared_ptr<MulticastUdpFace> >::iterator i =
-                 multicastFacesToRemove.begin();
-               i != multicastFacesToRemove.end();
-               ++i)
-            {
-              (*i)->close();
-            }
-        }
-      else
-        {
-          std::list<shared_ptr<MulticastUdpFace> > multicastFacesToRemove;
-          for (UdpFactory::MulticastFaceMap::const_iterator i =
-                 factory->getMulticastFaces().begin();
-               i != factory->getMulticastFaces().end();
-               ++i)
-            {
-              multicastFacesToRemove.push_back(i->second);
-            }
-
-          for (std::list<shared_ptr<MulticastUdpFace> >::iterator 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 (ConfigSection::const_iterator i = configSection.begin();
-       i != configSection.end();
-       ++i)
-    {
-      if (i->first == "mcast")
-        {
-          useMcast = parseYesNo(i, i->first, "ether");
-        }
-
-      else if (i->first == "mcast_group")
-        {
-          mcastGroup = ethernet::Address::fromString(i->second.get_value<std::string>());
-          if (mcastGroup.isNull())
-            {
-              throw ConfigFile::Error("Invalid value for option \"" +
-                                      i->first + "\" in \"ether\" section");
-            }
-        }
-      else
-        {
-          throw 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 (EthernetFactory::MulticastFaceMap::const_iterator 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 (std::list<shared_ptr<EthernetFace> >::iterator i =
-                 multicastFacesToRemove.begin();
-               i != multicastFacesToRemove.end();
-               ++i)
-            {
-              (*i)->close();
-            }
-        }
-      else
-        {
-          std::list<shared_ptr<EthernetFace> > multicastFacesToRemove;
-          for (EthernetFactory::MulticastFaceMap::const_iterator i =
-                 factory->getMulticastFaces().begin();
-               i != factory->getMulticastFaces().end();
-               ++i)
-            {
-              multicastFacesToRemove.push_back(i->second);
-            }
-
-          for (std::list<shared_ptr<EthernetFace> >::iterator i =
-                 multicastFacesToRemove.begin();
-               i != multicastFacesToRemove.end();
-               ++i)
-            {
-              (*i)->close();
-            }
-        }
-    }
-#else
-  throw 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 (ConfigSection::const_iterator 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)
-            {
-              throw ConfigFile::Error("Invalid value for option " +
-                                      i->first + "\" in \"websocket\" section");
-            }
-        }
-      else if (i->first == "listen")
-        {
-          needToListen = parseYesNo(i, i->first, "websocket");
-        }
-      else if (i->first == "enable_v4")
-        {
-          enableV4 = parseYesNo(i, i->first, "websocket");
-        }
-      else if (i->first == "enable_v6")
-        {
-          enableV6 = parseYesNo(i, i->first, "websocket");
-        }
-      else
-        {
-          throw ConfigFile::Error("Unrecognized option \"" +
-                                  i->first + "\" in \"websocket\" section");
-        }
-    }
-
-  if (!enableV4 && !enableV6)
-    {
-      throw 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)
-    {
-      throw 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
-  throw ConfigFile::Error("NFD was compiled without WebSocket, "
-                          "cannot process \"websocket\" section");
-#endif // HAVE_WEBSOCKET
-}
-
-
-void
 FaceManager::onFaceRequest(const Interest& request)
 {
   const Name& command = request.getName();
diff --git a/daemon/mgmt/face-manager.hpp b/daemon/mgmt/face-manager.hpp
index 75477bf..eb375fc 100644
--- a/daemon/mgmt/face-manager.hpp
+++ b/daemon/mgmt/face-manager.hpp
@@ -139,25 +139,6 @@
   void
   onConfig(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);
-
   /** \brief parse a config option that can be either "yes" or "no"
    *  \throw ConfigFile::Error value is neither "yes" nor "no"
    *  \return true if "yes", false if "no"
