face: more robust handling of multicast face creation errors

Refs: #5030, #5297
Change-Id: I3ca985498d9d3756cbff94873063f3734bcea288
diff --git a/daemon/face/ethernet-factory.hpp b/daemon/face/ethernet-factory.hpp
index 607c965..d8d49c9 100644
--- a/daemon/face/ethernet-factory.hpp
+++ b/daemon/face/ethernet-factory.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2022,  Regents of the University of California,
+ * Copyright (c) 2014-2023,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -28,10 +28,12 @@
 
 #include "protocol-factory.hpp"
 #include "ethernet-channel.hpp"
+#include "network-predicate.hpp"
 
 namespace nfd::face {
 
-/** \brief Protocol factory for Ethernet.
+/**
+ * \brief Protocol factory for Ethernet.
  */
 class EthernetFactory final : public ProtocolFactory
 {
@@ -48,7 +50,7 @@
    * If this method is called twice with the same endpoint, only one channel
    * will be created. The second call will just return the existing channel.
    *
-   * \return always a valid pointer to a EthernetChannel object, an exception
+   * \return Always a valid pointer to a EthernetChannel object, an exception
    *         is thrown if it cannot be created.
    * \throw PcapHelper::Error channel creation failed
    */
@@ -65,7 +67,7 @@
    * \param localEndpoint local network interface
    * \param group multicast group address
    *
-   * \throw EthernetTransport::Error transport creation fails
+   * \throw std::runtime_error %Face creation failed
    */
   shared_ptr<Face>
   createMulticastFace(const ndn::net::NetworkInterface& localEndpoint,
@@ -84,14 +86,16 @@
   std::vector<shared_ptr<const Channel>>
   doGetChannels() const final;
 
-  /** \brief Create EthernetChannel on \p netif if requested by \p m_unicastConfig.
-   *  \return new or existing channel, or nullptr if no channel should be created
+  /**
+   * \brief Create EthernetChannel on \p netif if requested by \p m_unicastConfig.
+   * \return New or existing channel, or nullptr if no channel should be created.
    */
   shared_ptr<EthernetChannel>
   applyUnicastConfigToNetif(const shared_ptr<const ndn::net::NetworkInterface>& netif);
 
-  /** \brief Create Ethernet multicast face on \p netif if requested by \p m_mcastConfig.
-   *  \return new or existing face, or nullptr if no face should be created
+  /**
+   * \brief Create Ethernet multicast face on \p netif if requested by \p m_mcastConfig.
+   * \return New or existing face, or nullptr if no face should be created.
    */
   shared_ptr<Face>
   applyMcastConfigToNetif(const ndn::net::NetworkInterface& netif);
@@ -100,7 +104,8 @@
   applyConfig(const FaceSystem::ConfigContext& context);
 
 private:
-  std::map<std::string, shared_ptr<EthernetChannel>> m_channels; ///< ifname => channel
+  // ifname => channel
+  std::map<std::string, shared_ptr<EthernetChannel>> m_channels;
 
   struct UnicastConfig
   {