//****************************** 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) {
//****************************** 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);
parser.parse(pools_, pools);
}
- SubnetPtr generic = SubnetConfigParser::parse(subnet, check_iface);
+ SubnetPtr generic = SubnetConfigParser::parse(subnet);
if (!generic) {
// Sanity check: not supposed to fail.
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>(),
//**************************** 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
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);
//**************************** 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);
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.
//**************************** 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
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);
/// @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() { }
/// 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.
/// @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:
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
///
/// @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.
/// @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
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
///
/// @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.
///
/// 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
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 {
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,
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();
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 {
// 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
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();
/// @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
/// @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
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 =
// 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&) {
<< 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.
}
}
-// 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 =
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));
}
}
}
-// 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 =
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));
}
}
}
-// 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());
}
}
}
-// 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
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 = "["
"]";
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));
}