diff --git a/NFD/daemon/mgmt/face-manager.cpp b/NFD/daemon/mgmt/face-manager.cpp
index 768f1b9..164df04 100644
--- a/NFD/daemon/mgmt/face-manager.cpp
+++ b/NFD/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/NFD/daemon/mgmt/face-manager.hpp b/NFD/daemon/mgmt/face-manager.hpp
index 75477bf..eb375fc 100644
--- a/NFD/daemon/mgmt/face-manager.hpp
+++ b/NFD/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"
