face: parse face_system.netdev_bound config section

refs #3521

Change-Id: I803a1651d5b44e021ec7bedb8001e216c849b9ab
diff --git a/daemon/face/face-system.cpp b/daemon/face/face-system.cpp
index 872efef..79880da 100644
--- a/daemon/face/face-system.cpp
+++ b/daemon/face/face-system.cpp
@@ -25,6 +25,7 @@
 
 #include "face-system.hpp"
 #include "protocol-factory.hpp"
+#include "netdev-bound.hpp"
 #include "core/global-io.hpp"
 #include "fw/face-table.hpp"
 
@@ -33,6 +34,9 @@
 
 NFD_LOG_INIT(FaceSystem);
 
+static const std::string SECTION_GENERAL = "general";
+static const std::string SECTION_NETDEVBOUND = "netdev_bound";
+
 FaceSystem::FaceSystem(FaceTable& faceTable, shared_ptr<ndn::net::NetworkMonitor> netmon)
   : m_faceTable(faceTable)
   , m_netmon(std::move(netmon))
@@ -42,6 +46,8 @@
     NFD_LOG_TRACE("creating factory " << id);
     m_factories[id] = ProtocolFactory::create(id, pfCtorParams);
   }
+
+  m_netdevBound = make_unique<NetdevBound>(pfCtorParams, *this);
 }
 
 ProtocolFactoryCtorParams
@@ -77,6 +83,12 @@
   return found == m_factoryByScheme.end() ? nullptr : found->second;
 }
 
+bool
+FaceSystem::hasFactoryForScheme(const std::string& scheme) const
+{
+  return m_factoryByScheme.count(scheme) > 0;
+}
+
 void
 FaceSystem::setConfigFile(ConfigFile& configFile)
 {
@@ -90,7 +102,7 @@
   context.isDryRun = isDryRun;
 
   // process general protocol factory config section
-  auto generalSection = configSection.get_child_optional("general");
+  auto generalSection = configSection.get_child_optional(SECTION_GENERAL);
   if (generalSection) {
     for (const auto& pair : *generalSection) {
       const std::string& key = pair.first;
@@ -103,7 +115,7 @@
     }
   }
 
-  // process sections in protocol factories
+  // process in protocol factories
   for (const auto& pair : m_factories) {
     const std::string& sectionName = pair.first;
     ProtocolFactory* factory = pair.second.get();
@@ -127,6 +139,10 @@
     }
   }
 
+  // process netdev_bound section, after factories start providing *+dev schemes
+  auto netdevBoundSection = configSection.get_child_optional(SECTION_NETDEVBOUND);
+  m_netdevBound->processConfig(netdevBoundSection, context);
+
   // process other sections
   std::set<std::string> seenSections;
   for (const auto& pair : configSection) {
@@ -137,12 +153,11 @@
       BOOST_THROW_EXCEPTION(ConfigFile::Error("Duplicate section face_system." + sectionName));
     }
 
-    if (sectionName == "general" || m_factories.count(sectionName) > 0) {
+    if (sectionName == SECTION_GENERAL || sectionName == SECTION_NETDEVBOUND ||
+        m_factories.count(sectionName) > 0) {
       continue;
     }
 
-    ///\todo #3521 nicfaces
-
     BOOST_THROW_EXCEPTION(ConfigFile::Error("Unrecognized option face_system." + sectionName));
   }
 }