]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[850-unable-to-set-not-present-interface-for-a-subnet-via-remote] Addressed comments...
authorFrancis Dupont <fdupont@isc.org>
Mon, 25 Nov 2019 14:57:34 +0000 (15:57 +0100)
committerFrancis Dupont <fdupont@isc.org>
Mon, 25 Nov 2019 16:34:47 +0000 (17:34 +0100)
src/lib/dhcpsrv/parsers/dhcp_parsers.cc
src/lib/dhcpsrv/parsers/dhcp_parsers.h
src/lib/dhcpsrv/parsers/shared_network_parser.cc
src/lib/dhcpsrv/parsers/shared_network_parser.h
src/lib/dhcpsrv/parsers/shared_networks_list_parser.h
src/lib/dhcpsrv/tests/cfg_subnets4_unittest.cc
src/lib/dhcpsrv/tests/cfg_subnets6_unittest.cc
src/lib/dhcpsrv/tests/shared_network_parser_unittest.cc
src/lib/dhcpsrv/tests/shared_networks_list_parser_unittest.cc

index f30b093219442c6e54f08d369702e3ae55e2c686..275138ac6425012af1d58fdfb29a0e2402340805 100644 (file)
@@ -553,18 +553,16 @@ Pools4ListParser::parse(PoolStoragePtr pools, ConstElementPtr pools_list) {
 
 //****************************** SubnetConfigParser *************************
 
-SubnetConfigParser::SubnetConfigParser(uint16_t family)
+SubnetConfigParser::SubnetConfigParser(uint16_t family, bool check_iface)
     : pools_(new PoolStorage()),
       address_family_(family),
       options_(new CfgOption()),
-      check_iface_(true) {
+      check_iface_(check_iface) {
     relay_info_.reset(new isc::dhcp::Network::RelayInfo());
 }
 
 SubnetPtr
-SubnetConfigParser::parse(ConstElementPtr subnet, bool check_iface) {
-
-    check_iface_ = check_iface;
+SubnetConfigParser::parse(ConstElementPtr subnet) {
 
     ConstElementPtr options_params = subnet->get("option-data");
     if (options_params) {
@@ -680,12 +678,12 @@ SubnetConfigParser::createSubnet(ConstElementPtr params) {
 
 //****************************** Subnet4ConfigParser *************************
 
-Subnet4ConfigParser::Subnet4ConfigParser()
-    :SubnetConfigParser(AF_INET) {
+Subnet4ConfigParser::Subnet4ConfigParser(bool check_iface)
+    : SubnetConfigParser(AF_INET, check_iface) {
 }
 
 Subnet4Ptr
-Subnet4ConfigParser::parse(ConstElementPtr subnet, bool check_iface) {
+Subnet4ConfigParser::parse(ConstElementPtr subnet) {
     // Check parameters.
     checkKeywords(SimpleParser4::SUBNET4_PARAMETERS, subnet);
 
@@ -696,7 +694,7 @@ Subnet4ConfigParser::parse(ConstElementPtr subnet, bool check_iface) {
         parser.parse(pools_, pools);
     }
 
-    SubnetPtr generic = SubnetConfigParser::parse(subnet, check_iface);
+    SubnetPtr generic = SubnetConfigParser::parse(subnet);
 
     if (!generic) {
         // Sanity check: not supposed to fail.
@@ -736,7 +734,7 @@ Subnet4ConfigParser::initSubnet(data::ConstElementPtr params,
                                 asiolink::IOAddress addr, uint8_t len) {
     // Subnet ID is optional. If it is not supplied the value of 0 is used,
     // which means autogenerate. The value was inserted earlier by calling
-    // SimpleParser6::setAllDefaults.
+    // SimpleParser4::setAllDefaults.
     SubnetID subnet_id = static_cast<SubnetID>(getInteger(params, "id"));
 
     Subnet4Ptr subnet4(new Subnet4(addr, len, Triplet<uint32_t>(),
@@ -933,15 +931,18 @@ Subnet4ConfigParser::initSubnet(data::ConstElementPtr params,
 
 //**************************** Subnets4ListConfigParser **********************
 
+Subnets4ListConfigParser::Subnets4ListConfigParser(bool check_iface)
+    : check_iface_(check_iface) {
+}
+
 size_t
 Subnets4ListConfigParser::parse(SrvConfigPtr cfg,
-                                ConstElementPtr subnets_list,
-                                bool check_iface) {
+                                ConstElementPtr subnets_list) {
     size_t cnt = 0;
     BOOST_FOREACH(ConstElementPtr subnet_json, subnets_list->listValue()) {
 
-        Subnet4ConfigParser parser;
-        Subnet4Ptr subnet = parser.parse(subnet_json, check_iface);
+        Subnet4ConfigParser parser(check_iface_);
+        Subnet4Ptr subnet = parser.parse(subnet_json);
         if (subnet) {
 
             // Adding a subnet to the Configuration Manager may fail if the
@@ -961,13 +962,12 @@ Subnets4ListConfigParser::parse(SrvConfigPtr cfg,
 
 size_t
 Subnets4ListConfigParser::parse(Subnet4Collection& subnets,
-                                data::ConstElementPtr subnets_list,
-                                bool check_iface) {
+                                data::ConstElementPtr subnets_list) {
     size_t cnt = 0;
     BOOST_FOREACH(ConstElementPtr subnet_json, subnets_list->listValue()) {
 
-        Subnet4ConfigParser parser;
-        Subnet4Ptr subnet = parser.parse(subnet_json, check_iface);
+        Subnet4ConfigParser parser(check_iface_);
+        Subnet4Ptr subnet = parser.parse(subnet_json);
         if (subnet) {
             try {
                 auto ret = subnets.push_back(subnet);
@@ -1116,12 +1116,12 @@ PdPoolsListParser::parse(PoolStoragePtr pools, ConstElementPtr pd_pool_list) {
 
 //**************************** Subnet6ConfigParser ***********************
 
-Subnet6ConfigParser::Subnet6ConfigParser()
-    : SubnetConfigParser(AF_INET6) {
+Subnet6ConfigParser::Subnet6ConfigParser(bool check_iface)
+    : SubnetConfigParser(AF_INET6, check_iface) {
 }
 
 Subnet6Ptr
-Subnet6ConfigParser::parse(ConstElementPtr subnet, bool check_iface) {
+Subnet6ConfigParser::parse(ConstElementPtr subnet) {
     // Check parameters.
     checkKeywords(SimpleParser6::SUBNET6_PARAMETERS, subnet);
 
@@ -1137,7 +1137,7 @@ Subnet6ConfigParser::parse(ConstElementPtr subnet, bool check_iface) {
         parser.parse(pools_, pd_pools);
     }
 
-    SubnetPtr generic = SubnetConfigParser::parse(subnet, check_iface);
+    SubnetPtr generic = SubnetConfigParser::parse(subnet);
 
     if (!generic) {
         // Sanity check: not supposed to fail.
@@ -1328,15 +1328,18 @@ Subnet6ConfigParser::initSubnet(data::ConstElementPtr params,
 
 //**************************** Subnet6ListConfigParser ********************
 
+Subnets6ListConfigParser::Subnets6ListConfigParser(bool check_iface)
+    : check_iface_(check_iface) {
+}
+
 size_t
 Subnets6ListConfigParser::parse(SrvConfigPtr cfg,
-                                ConstElementPtr subnets_list,
-                                bool check_iface) {
+                                ConstElementPtr subnets_list) {
     size_t cnt = 0;
     BOOST_FOREACH(ConstElementPtr subnet_json, subnets_list->listValue()) {
 
-        Subnet6ConfigParser parser;
-        Subnet6Ptr subnet = parser.parse(subnet_json, check_iface);
+        Subnet6ConfigParser parser(check_iface_);
+        Subnet6Ptr subnet = parser.parse(subnet_json);
 
         // Adding a subnet to the Configuration Manager may fail if the
         // subnet id is invalid (duplicate). Thus, we catch exceptions
@@ -1354,13 +1357,12 @@ Subnets6ListConfigParser::parse(SrvConfigPtr cfg,
 
 size_t
 Subnets6ListConfigParser::parse(Subnet6Collection& subnets,
-                                ConstElementPtr subnets_list,
-                                bool check_iface) {
+                                ConstElementPtr subnets_list) {
     size_t cnt = 0;
     BOOST_FOREACH(ConstElementPtr subnet_json, subnets_list->listValue()) {
 
-        Subnet6ConfigParser parser;
-        Subnet6Ptr subnet = parser.parse(subnet_json, check_iface);
+        Subnet6ConfigParser parser(check_iface_);
+        Subnet6Ptr subnet = parser.parse(subnet_json);
         if (subnet) {
             try {
                 auto ret = subnets.push_back(subnet);
index 0c0251e4ed3d646f176da5b9ce3e98f1b6256fca..feebec53a2a537c1218ea15311b97d98bf0b022e 100644 (file)
@@ -474,7 +474,9 @@ public:
     /// @brief constructor
     ///
     /// @param family address family: @c AF_INET or @c AF_INET6
-    explicit SubnetConfigParser(uint16_t family);
+    /// @param check_iface Check if the specified interface exists in
+    /// the system.
+    explicit SubnetConfigParser(uint16_t family, bool check_iface = true);
 
     /// @brief virtual destructor (does nothing)
     virtual ~SubnetConfigParser() { }
@@ -486,13 +488,10 @@ protected:
     /// Subnet6ConfigParser) classes.
     ///
     /// @param subnet pointer to the content of subnet definition
-    /// @param check_iface Check if the specified interface exists in
-    /// the system.
     /// @return a pointer to newly created subnet
     ///
     /// @throw isc::DhcpConfigError if subnet configuration parsing failed.
-    SubnetPtr parse(isc::data::ConstElementPtr subnet,
-                    bool check_iface = true);
+    SubnetPtr parse(isc::data::ConstElementPtr subnet);
 
     /// @brief Instantiates the subnet based on a given IP prefix and prefix
     /// length.
@@ -544,16 +543,17 @@ public:
     /// @brief Constructor
     ///
     /// stores global scope parameters, options, option definitions.
-    Subnet4ConfigParser();
+    ///
+    /// @param check_iface Check if the specified interface exists in
+    /// the system.
+    Subnet4ConfigParser(bool check_iface = true);
 
     /// @brief Parses a single IPv4 subnet configuration and adds to the
     /// Configuration Manager.
     ///
     /// @param subnet A new subnet being configured.
-    /// @param check_iface Check if the specified interface exists in
-    /// the system.
     /// @return a pointer to created Subnet4 object
-    Subnet4Ptr parse(data::ConstElementPtr subnet, bool check_iface = true);
+    Subnet4Ptr parse(data::ConstElementPtr subnet);
 
 protected:
 
@@ -575,6 +575,12 @@ protected:
 class Subnets4ListConfigParser : public isc::data::SimpleParser {
 public:
 
+    /// @brief constructor
+    ///
+    /// @param check_iface Check if the specified interface exists in
+    /// the system.
+    Subnets4ListConfigParser(bool check_iface = true);
+
     /// @brief parses contents of the list
     ///
     /// Iterates over all entries on the list, parses its content
@@ -583,22 +589,21 @@ public:
     ///
     /// @param cfg Pointer to server configuration.
     /// @param subnets_list pointer to a list of IPv4 subnets
-    /// @param check_iface Check if the specified interface exists in
-    /// the system.
     /// @return number of subnets created
-    size_t parse(SrvConfigPtr cfg, data::ConstElementPtr subnets_list,
-                 bool check_iface = true);
+    size_t parse(SrvConfigPtr cfg, data::ConstElementPtr subnets_list);
 
     /// @brief Parses contents of the subnet4 list.
     ///
     /// @param [out] subnets Container where parsed subnets will be stored.
     /// @param subnets_list pointer to a list of IPv4 subnets
-    /// @param check_iface Check if the specified interface exists in
-    /// the system.
     /// @return Number of subnets created.
     size_t parse(Subnet4Collection& subnets,
-                 data::ConstElementPtr subnets_list,
-                 bool check_iface = true);
+                 data::ConstElementPtr subnets_list);
+
+protected:
+
+    /// Check if the specified interface exists in the system.
+    bool check_iface_;
 };
 
 /// @brief Parser for IPv6 pool definitions.
@@ -735,16 +740,17 @@ public:
     /// @brief Constructor
     ///
     /// stores global scope parameters, options, option definitions.
-    Subnet6ConfigParser();
+    ///
+    /// @param check_iface Check if the specified interface exists in
+    /// the system.
+    Subnet6ConfigParser(bool check_iface = true);
 
     /// @brief Parses a single IPv6 subnet configuration and adds to the
     /// Configuration Manager.
     ///
     /// @param subnet A new subnet being configured.
-    /// @param check_iface Check if the specified interface exists in
-    /// the system.
     /// @return a pointer to created Subnet6 object
-    Subnet6Ptr parse(data::ConstElementPtr subnet, bool check_iface = true);
+    Subnet6Ptr parse(data::ConstElementPtr subnet);
 
 protected:
     /// @brief Issues a DHCP6 server specific warning regarding duplicate subnet
@@ -776,6 +782,12 @@ protected:
 class Subnets6ListConfigParser : public isc::data::SimpleParser {
 public:
 
+    /// @brief constructor
+    ///
+    /// @param check_iface Check if the specified interface exists in
+    /// the system.
+    Subnets6ListConfigParser(bool check_iface = true);
+
     /// @brief parses contents of the list
     ///
     /// Iterates over all entries on the list, parses its content
@@ -784,11 +796,8 @@ public:
     ///
     /// @param cfg configuration (parsed subnets will be stored here)
     /// @param subnets_list pointer to a list of IPv6 subnets
-    /// @param check_iface Check if the specified interface exists in
-    /// the system.
     /// @throw DhcpConfigError if CfgMgr rejects the subnet (e.g. subnet-id is a duplicate)
-    size_t parse(SrvConfigPtr cfg, data::ConstElementPtr subnets_list,
-                 bool check_iface = true);
+    size_t parse(SrvConfigPtr cfg, data::ConstElementPtr subnets_list);
 
     /// @brief Parses contents of the subnet6 list.
     ///
@@ -798,9 +807,12 @@ public:
     /// the system.
     /// @return Number of subnets created.
     size_t parse(Subnet6Collection& subnets,
-                 data::ConstElementPtr subnets_list,
-                 bool check_iface = true);
+                 data::ConstElementPtr subnets_list);
 
+protected:
+
+    /// Check if the specified interface exists in the system.
+    bool check_iface_;
 };
 
 /// @brief Parser for  D2ClientConfig
index 40ddcbf09abda79cefb83b7b75f713bc615e9241..a423cb26d251a8552e766d98e55e06b3ad750d27 100644 (file)
@@ -26,9 +26,12 @@ using namespace isc::util;
 namespace isc {
 namespace dhcp {
 
+SharedNetwork4Parser::SharedNetwork4Parser(bool check_iface)
+    : check_iface_(check_iface) {
+}
+
 SharedNetwork4Ptr
-SharedNetwork4Parser::parse(const data::ConstElementPtr& shared_network_data,
-                            bool check_iface) {
+SharedNetwork4Parser::parse(const data::ConstElementPtr& shared_network_data) {
     SharedNetwork4Ptr shared_network;
     try {
 
@@ -49,7 +52,7 @@ SharedNetwork4Parser::parse(const data::ConstElementPtr& shared_network_data,
         if (shared_network_data->contains("interface")) {
             std::string iface = getString(shared_network_data, "interface");
             if (!iface.empty()) {
-                if (check_iface && !IfaceMgr::instance().getIface(iface)) {
+                if (check_iface_ && !IfaceMgr::instance().getIface(iface)) {
                     ConstElementPtr error =
                         shared_network_data->get("interface");
                     isc_throw(DhcpConfigError,
@@ -74,9 +77,9 @@ SharedNetwork4Parser::parse(const data::ConstElementPtr& shared_network_data,
             auto json = shared_network_data->get("subnet4");
 
             // Create parser instance of subnet4.
-            Subnets4ListConfigParser parser;
+            Subnets4ListConfigParser parser(check_iface_);
             Subnet4Collection subnets;
-            parser.parse(subnets, json, check_iface);
+            parser.parse(subnets, json);
 
             // Add all returned subnets into shared network.
             for (auto subnet = subnets.cbegin(); subnet != subnets.cend();
@@ -207,9 +210,12 @@ SharedNetwork4Parser::parse(const data::ConstElementPtr& shared_network_data,
     return (shared_network);
 }
 
+SharedNetwork6Parser::SharedNetwork6Parser(bool check_iface)
+    : check_iface_(check_iface) {
+}
+
 SharedNetwork6Ptr
-SharedNetwork6Parser::parse(const data::ConstElementPtr& shared_network_data,
-                            bool check_iface) {
+SharedNetwork6Parser::parse(const data::ConstElementPtr& shared_network_data) {
     SharedNetwork6Ptr shared_network;
     std::string name;
     try {
@@ -266,7 +272,7 @@ SharedNetwork6Parser::parse(const data::ConstElementPtr& shared_network_data,
         // Set interface name. If it is defined, then subnets are available
         // directly over specified network interface.
         if (!iface.unspecified() && !iface.empty()) {
-            if (check_iface && !IfaceMgr::instance().getIface(iface)) {
+            if (check_iface_ && !IfaceMgr::instance().getIface(iface)) {
                 ConstElementPtr error = shared_network_data->get("interface");
                 isc_throw(DhcpConfigError,
                           "Specified network interface name " << iface
@@ -320,9 +326,9 @@ SharedNetwork6Parser::parse(const data::ConstElementPtr& shared_network_data,
             auto json = shared_network_data->get("subnet6");
 
             // Create parser instance of subnet6.
-            Subnets6ListConfigParser parser;
+            Subnets6ListConfigParser parser(check_iface_);
             Subnet6Collection subnets;
-            parser.parse(subnets, json, check_iface);
+            parser.parse(subnets, json);
 
             // Add all returned subnets into shared network.
             for (auto subnet = subnets.cbegin(); subnet != subnets.cend();
index e8146624516bf914942b681a3e46fc058eeb4382..cc9c9fb02cfab8e7b813755fa09b6a6422b885ca 100644 (file)
@@ -20,24 +20,36 @@ namespace dhcp {
 /// @brief Implements parser for IPv4 shared networks.
 class SharedNetwork4Parser : public BaseNetworkParser {
 public:
+    /// @brief Constructor.
+    ///
+    /// @param check_iface Check if the specified interface exists in
+    /// the system.
+    SharedNetwork4Parser(bool check_iface = true);
 
     /// @brief Parses shared configuration information for IPv4 shared network.
     ///
     /// @param shared_network_data Data element holding shared network
     /// configuration to be parsed.
-    /// @param check_iface Check if the specified interface exists in
-    /// the system.
     ///
     /// @return Pointer to an object representing shared network.
     /// @throw DhcpConfigError when shared network configuration is invalid.
     SharedNetwork4Ptr
-    parse(const data::ConstElementPtr& shared_network_data,
-          bool check_iface = true);
+    parse(const data::ConstElementPtr& shared_network_data);
+
+protected:
+    /// Check if the specified interface exists in the system.
+    bool check_iface_;
 };
 
 /// @brief Implements parser for IPv6 shared networks.
 class SharedNetwork6Parser : public BaseNetworkParser {
 public:
+    /// @brief Constructor.
+    ///
+    /// @param check_iface Check if the specified interface exists in
+    /// the system.
+    SharedNetwork6Parser(bool check_iface = true);
+
     /// @brief Parses shared configuration information for IPv6 shared network.
     ///
     /// @param shared_network_data Data element holding shared network
@@ -48,8 +60,11 @@ public:
     /// @return Pointer to an object representing shared network.
     /// @throw DhcpConfigError when shared network configuration is invalid.
     SharedNetwork6Ptr
-    parse(const data::ConstElementPtr& shared_network_data,
-          bool check_iface = true);
+    parse(const data::ConstElementPtr& shared_network_data);
+
+protected:
+    /// Check if the specified interface exists in the system.
+    bool check_iface_;
 };
 
 } // enf of namespace isc::dhcp
index 2df69bc6383e1f50c1fd654848288e278e71a071..5f49c8b09723ad7546bd2975f4afd3b21707a9e7 100644 (file)
@@ -29,23 +29,29 @@ template<typename SharedNetworkParserType>
 class SharedNetworksListParser : public data::SimpleParser {
 public:
 
+    /// @brief Constructor.
+    ///
+    /// @param check_iface Check if the specified interface exists in
+    /// the system.
+    SharedNetworksListParser(bool check_iface = true)
+        : check_iface_(check_iface) {
+    }
+
     /// @brief Parses a list of shared networks.
     ///
-    /// @tparam Type of the configuration structure into which the result
-    /// will be stored, i.e. @ref CfgSharedNetworks4 or @ref CfgSharedNetworks6.
+    /// @tparam CfgSharedNetworksTypePtr Type of the configuration structure
+    /// into which the result will be stored, i.e. @ref CfgSharedNetworks4
+    /// or @ref CfgSharedNetworks6.
     /// @param [out] cfg Shared networks configuration structure into which
     /// the data should be parsed.
     /// @param shared_networks_list_data List element holding a list of
     /// shared networks.
-    /// @param check_iface Check if the specified interface exists in
-    /// the system.
     ///
     /// @throw DhcpConfigError when error has occurred, e.g. when networks
     /// with duplicated names have been specified.
     template<typename CfgSharedNetworksTypePtr>
     void parse(CfgSharedNetworksTypePtr& cfg,
-               const data::ConstElementPtr& shared_networks_list_data,
-                bool check_iface = true) {
+               const data::ConstElementPtr& shared_networks_list_data) {
         try {
             // Get the C++ vector holding networks.
             const std::vector<data::ElementPtr>& networks_list =
@@ -53,8 +59,8 @@ public:
             // Iterate over all networks and do the parsing.
             for (auto network_element = networks_list.cbegin();
                  network_element != networks_list.cend(); ++network_element) {
-                SharedNetworkParserType parser;
-                auto network = parser.parse(*network_element, check_iface);
+                SharedNetworkParserType parser(check_iface_);
+                auto network = parser.parse(*network_element);
                 cfg->add(network);
             }
         } catch (const DhcpConfigError&) {
@@ -70,6 +76,10 @@ public:
                       << shared_networks_list_data->getPosition() << ")");
         }
     }
+
+protected:
+    /// Check if the specified interface exists in the system.
+    bool check_iface_;
 };
 
 /// @brief Type of the shared networks list parser for IPv4.
index f32e3609aa651b655882dafefcbb6ff5fd7712af..c37e3fd82e524a504c202593356cf8c35e3d0f79 100644 (file)
@@ -1616,7 +1616,7 @@ TEST(CfgSubnets4Test, hostnameSanitizierValidation) {
     }
 }
 
-// This test verifies that an interface which is not in the system is rejected.
+// This test verifies that the optional interface check works as expected.
 TEST(CfgSubnets4Test, iface) {
     // Create a configuration.
     std::string json =
@@ -1630,13 +1630,17 @@ TEST(CfgSubnets4Test, iface) {
     ASSERT_NO_THROW(elems = data::Element::fromJSON(json))
         << "invalid JSON:" << json << "\n test is broken";
 
+    // The interface check can be disabled.
+    Subnet4ConfigParser parser_no_check(false);
+    EXPECT_NO_THROW(parser_no_check.parse(elems));
+
+    // Retry with the interface check enabled.
     Subnet4ConfigParser parser;
-    EXPECT_NO_THROW(parser.parse(elems, false));
     EXPECT_THROW(parser.parse(elems), DhcpConfigError);
 
     // Configure default test interfaces.
     IfaceMgrTestConfig config(true);
-    EXPECT_NO_THROW(parser.parse(elems, false));
+    EXPECT_NO_THROW(parser_no_check.parse(elems));
     EXPECT_NO_THROW(parser.parse(elems));
 }
 
index b9a89b440fe632e24531c18c140de2b08e77fc81..b987210f73802475085a9ec75300ee677d2d9c6c 100644 (file)
@@ -1399,7 +1399,7 @@ TEST(CfgSubnets6Test, hostnameSanitizierValidation) {
     }
 }
 
-// This test verifies that an interface which is not in the system is rejected.
+// This test verifies that the optional interface check works as expected.
 TEST(CfgSubnets6Test, iface) {
     // Create a configuration.
     std::string json =
@@ -1413,13 +1413,17 @@ TEST(CfgSubnets6Test, iface) {
     ASSERT_NO_THROW(elems = data::Element::fromJSON(json))
         << "invalid JSON:" << json << "\n test is broken";
 
+    // The interface check can be disabled.
+    Subnet6ConfigParser parser_no_check(false);
+    EXPECT_NO_THROW(parser_no_check.parse(elems));
+
+    // Retry with the interface check enabled.
     Subnet6ConfigParser parser;
-    EXPECT_NO_THROW(parser.parse(elems, false));
     EXPECT_THROW(parser.parse(elems), DhcpConfigError);
 
     // Configure default test interfaces.
     IfaceMgrTestConfig config(true);
-    EXPECT_NO_THROW(parser.parse(elems, false));
+    EXPECT_NO_THROW(parser_no_check.parse(elems));
     EXPECT_NO_THROW(parser.parse(elems));
 }
 
index a0709c75d6e173121f170d0631e69e4e11b86fd1..cfe4ef1dbce7bc88cecd1bea1d159d5989735380 100644 (file)
@@ -432,22 +432,38 @@ TEST_F(SharedNetwork4ParserTest, relayInfoTests) {
     }
 }
 
-// This test verifies that an interface which is not in the system is rejected.
+// This test verifies that the optional interface check works as expected.
 TEST_F(SharedNetwork4ParserTest, iface) {
     // Basic configuration for shared network.
     std::string config = getWorkingConfig();
     ElementPtr config_element = Element::fromJSON(config);
 
     // Parse configuration specified above.
+
+    // The interface check can be disabled.
+    SharedNetwork4Parser parser_no_check(false);
+    SharedNetwork4Ptr network;
+    EXPECT_NO_THROW(network = parser_no_check.parse(config_element));
+    ASSERT_TRUE(network);
+    EXPECT_FALSE(network->getIface().unspecified());
+    EXPECT_EQ("eth1", network->getIface().get());
+
+    // Retry with the interface check enabled.
     SharedNetwork4Parser parser;
-    EXPECT_NO_THROW(parser.parse(config_element, false));
     EXPECT_THROW(parser.parse(config_element), DhcpConfigError);
 
     // Configure default test interfaces.
     IfaceMgrTestConfig ifmgr(true);
 
-    EXPECT_NO_THROW(parser.parse(config_element, false));
-    EXPECT_NO_THROW(parser.parse(config_element));
+    EXPECT_NO_THROW(network = parser_no_check.parse(config_element));
+    ASSERT_TRUE(network);
+    EXPECT_FALSE(network->getIface().unspecified());
+    EXPECT_EQ("eth1", network->getIface().get());
+
+    EXPECT_NO_THROW(network = parser.parse(config_element));
+    ASSERT_TRUE(network);
+    EXPECT_FALSE(network->getIface().unspecified());
+    EXPECT_EQ("eth1", network->getIface().get());
 }
 
 
@@ -848,22 +864,38 @@ TEST_F(SharedNetwork6ParserTest, relayInfoTests) {
     }
 }
 
-// This test verifies that an interface which is not in the system is rejected.
+// This test verifies that the optional interface check works as expected.
 TEST_F(SharedNetwork6ParserTest, iface) {
     // Basic configuration for shared network.
     std::string config = getWorkingConfig();
     ElementPtr config_element = Element::fromJSON(config);
 
     // Parse configuration specified above.
+
+    // The interface check can be disabled.
+    SharedNetwork6Parser parser_no_check(false);
+    SharedNetwork6Ptr network;
+    EXPECT_NO_THROW(network = parser_no_check.parse(config_element));
+    ASSERT_TRUE(network);
+    EXPECT_FALSE(network->getIface().unspecified());
+    EXPECT_EQ("eth1", network->getIface().get());
+
+    // Retry with the interface check enabled.
     SharedNetwork6Parser parser;
-    EXPECT_NO_THROW(parser.parse(config_element, false));
     EXPECT_THROW(parser.parse(config_element), DhcpConfigError);
 
     // Configure default test interfaces.
     IfaceMgrTestConfig ifmgr(true);
 
-    EXPECT_NO_THROW(parser.parse(config_element, false));
-    EXPECT_NO_THROW(parser.parse(config_element));
+    EXPECT_NO_THROW(network = parser_no_check.parse(config_element));
+    ASSERT_TRUE(network);
+    EXPECT_FALSE(network->getIface().unspecified());
+    EXPECT_EQ("eth1", network->getIface().get());
+
+    EXPECT_NO_THROW(network = parser.parse(config_element));
+    ASSERT_TRUE(network);
+    EXPECT_FALSE(network->getIface().unspecified());
+    EXPECT_EQ("eth1", network->getIface().get());
 }
 
 } // end of anonymous namespace
index bcc5b3314355ef1080d90192fda004483c0c70ac..9bf82dd0697cad66b3dd0c468e2a5df2c495ba70 100644 (file)
@@ -83,7 +83,7 @@ TEST(SharedNetworkListParserTest, duplicatedName) {
     EXPECT_THROW(parser.parse(cfg, config_element), DhcpConfigError);
 }
 
-// This test verifies that an interface which is not in the system is rejected.
+// This test verifies that the optional interface check works as expected.
 TEST(SharedNetworkListParserTest, iface) {
     // Basic configuration with a shared network.
     std::string config = "["
@@ -94,16 +94,21 @@ TEST(SharedNetworkListParserTest, iface) {
         "]";
 
     ElementPtr config_element = Element::fromJSON(config);
-    SharedNetworks6ListParser parser;
+
+    // The interface check can be disabled.
+    SharedNetworks6ListParser parser_no_check(false);
     CfgSharedNetworks6Ptr cfg(new CfgSharedNetworks6());
-    EXPECT_NO_THROW(parser.parse(cfg, config_element, false));
+    EXPECT_NO_THROW(parser_no_check.parse(cfg, config_element));
     cfg.reset(new CfgSharedNetworks6());
+
+    // Retry with the interface check enabled.
+    SharedNetworks6ListParser parser;
     EXPECT_THROW(parser.parse(cfg, config_element), DhcpConfigError);
+    cfg.reset(new CfgSharedNetworks6());
 
     // Configure default test interfaces.
     IfaceMgrTestConfig ifmgr(true);
-    cfg.reset(new CfgSharedNetworks6());
-    EXPECT_NO_THROW(parser.parse(cfg, config_element, false));
+    EXPECT_NO_THROW(parser_no_check.parse(cfg, config_element));
     cfg.reset(new CfgSharedNetworks6());
     EXPECT_NO_THROW(parser.parse(cfg, config_element));
 }