///
/// stores global scope parameters, options, option definitions.
Subnet4ConfigParser()
- :SubnetConfigParser("", globalContext(), IOAddress("0.0.0.0")) {
+ :SubnetConfigParser(AF_INET) {
}
/// @brief Parses a single IPv4 subnet configuration and adds to the
protected:
- /// @brief Creates parsers for entries in subnet definition.
- ///
- /// @param config_id name of the entry
- ///
- /// @return parser object for specified entry name. Note the caller is
- /// responsible for deleting the parser created.
- /// @throw isc::dhcp::DhcpConfigError if trying to create a parser
- /// for unknown config element
- DhcpConfigParser* createSubnetConfigParser(const std::string& config_id) {
- DhcpConfigParser* parser = NULL;
- if ((config_id.compare("valid-lifetime") == 0) ||
- (config_id.compare("renew-timer") == 0) ||
- (config_id.compare("rebind-timer") == 0) ||
- (config_id.compare("id") == 0)) {
- parser = new Uint32Parser(config_id, uint32_values_);
- } else if ((config_id.compare("subnet") == 0) ||
- (config_id.compare("interface") == 0) ||
- (config_id.compare("client-class") == 0) ||
- (config_id.compare("next-server") == 0) ||
- (config_id.compare("reservation-mode") == 0)) {
- parser = new StringParser(config_id, string_values_);
- // pools has been converted to SimpleParser already.
- // relay has been converted to SimpleParser already.
- // option-data has been converted to SimpleParser already.
- } else if (config_id.compare("match-client-id") == 0) {
- parser = new BooleanParser(config_id, boolean_values_);
- } else if (config_id.compare("4o6-subnet") == 0) {
- parser = new StringParser(config_id, string_values_);
- } else if (config_id.compare("4o6-interface") == 0) {
- parser = new StringParser(config_id, string_values_);
- } else if (config_id.compare("4o6-interface-id") == 0) {
- parser = new StringParser(config_id, string_values_);
- } else {
- isc_throw(NotImplemented, "unsupported parameter: " << config_id);
- }
-
- return (parser);
- }
-
/// @brief Instantiates the IPv4 Subnet based on a given IPv4 address
/// and prefix length.
///
// Should fail with a syntax error
EXPECT_EQ("{ \"result\": 1, "
- "\"text\": \"unsupported parameter: BOGUS (<string>:20:26)\" }",
+ "\"text\": \"subnet configuration failed (<string>:20:17): String parameter subnet not found(<string>:20:17)\" }",
response);
// Check that the config was not lost
///
/// stores global scope parameters, options, option definitions.
Subnet6ConfigParser()
- :SubnetConfigParser("", globalContext(), IOAddress("::")) {
+ :SubnetConfigParser(AF_INET6) {
}
/// @brief Parses a single IPv6 subnet configuration and adds to the
}
protected:
-
- /// @brief creates parsers for entries in subnet definition
- ///
- /// @param config_id name of the entry
- ///
- /// @return parser object for specified entry name. Note the caller is
- /// responsible for deleting the parser created.
- /// @throw isc::dhcp::DhcpConfigError if trying to create a parser
- /// for unknown config element
- DhcpConfigParser* createSubnetConfigParser(const std::string& config_id) {
- DhcpConfigParser* parser = NULL;
- if ((config_id.compare("preferred-lifetime") == 0) ||
- (config_id.compare("valid-lifetime") == 0) ||
- (config_id.compare("renew-timer") == 0) ||
- (config_id.compare("rebind-timer") == 0) ||
- (config_id.compare("id") == 0)) {
- parser = new Uint32Parser(config_id, uint32_values_);
- } else if ((config_id.compare("subnet") == 0) ||
- (config_id.compare("interface") == 0) ||
- (config_id.compare("client-class") == 0) ||
- (config_id.compare("interface-id") == 0) ||
- (config_id.compare("reservation-mode") == 0)) {
- parser = new StringParser(config_id, string_values_);
- // pools has been converted to SimpleParser.
- // relay has been converted to SimpleParser.
- // pd-pools has been converted to SimpleParser.
- // option-data was here, but it is now converted to SimpleParser
- } else if (config_id.compare("rapid-commit") == 0) {
- parser = new BooleanParser(config_id, boolean_values_);
- } else {
- isc_throw(NotImplemented, "unsupported parameter: " << config_id);
- }
-
- return (parser);
- }
-
/// @brief Issues a DHCP6 server specific warning regarding duplicate subnet
/// options.
///
// Should fail with a syntax error
EXPECT_EQ("{ \"result\": 1, "
- "\"text\": \"unsupported parameter: BOGUS (<string>:21:26)\" }",
+ "\"text\": \"subnet configuration failed (<string>:21:17): String parameter subnet not found(<string>:21:17)\" }",
response);
// Check that the config was not lost
//****************************** SubnetConfigParser *************************
-SubnetConfigParser::SubnetConfigParser(const std::string&,
- ParserContextPtr global_context,
- const isc::asiolink::IOAddress& default_addr)
- : uint32_values_(new Uint32Storage()),
- string_values_(new StringStorage()),
- boolean_values_(new BooleanStorage()),
- pools_(new PoolStorage()),
- global_context_(global_context),
- relay_info_(new isc::dhcp::Subnet::RelayInfo(default_addr)),
+SubnetConfigParser::SubnetConfigParser(uint16_t family)
+ : pools_(new PoolStorage()),
+ address_family_(family),
options_(new CfgOption()) {
- // The first parameter should always be "subnet", but we don't check
- // against that here in case some wants to reuse this parser somewhere.
- if (!global_context_) {
- isc_throw(isc::dhcp::DhcpConfigError, "parser logic error: "
- << "context storage may not be NULL");
- }
-
+ string addr = family == AF_INET ? "0.0.0.0" : "::";
+ relay_info_.reset(new isc::dhcp::Subnet::RelayInfo(IOAddress(addr)));
}
SubnetPtr
SubnetConfigParser::parse(ConstElementPtr subnet) {
- BOOST_FOREACH(ConfigPair param, subnet->mapValue()) {
- // Pools has been converted to SimpleParser.
- if (param.first == "pools") {
- continue;
- }
-
- // PdPools has been converted to SimpleParser.
- if ((param.first == "pd-pools") &&
- (global_context_->universe_ == Option::V6)) {
- continue;
- }
-
- // Host reservations must be parsed after subnet specific parameters.
- // Note that the reservation parsing will be invoked by the build()
- // in the derived classes, i.e. Subnet4ConfigParser and
- // Subnet6ConfigParser.
- if (param.first == "reservations") {
- continue;
- }
- if (param.first == "option-data") {
- uint16_t family = global_context_->universe_ == Option::V4 ? AF_INET : AF_INET6;
- OptionDataListParser opt_parser(family);
- opt_parser.parse(options_, param.second);
- continue;
- }
-
- if (param.first == "relay") {
- RelayInfoParser parser(global_context_->universe_);
- parser.parse(relay_info_, param.second);
- continue;
- }
-
- ParserPtr parser;
- // When unsupported parameter is specified, the function called
- // below will thrown an exception. We have to catch this exception
- // to append the line number where the parameter is.
- try {
- parser.reset(createSubnetConfigParser(param.first));
-
- } catch (const std::exception& ex) {
- isc_throw(DhcpConfigError, ex.what() << " ("
- << param.second->getPosition() << ")");
- }
- parser->build(param.second);
- parsers_.push_back(parser);
+ ConstElementPtr options_params = subnet->find("option-data");
+ if (options_params) {
+ OptionDataListParser opt_parser(address_family_);
+ opt_parser.parse(options_, options_params);
}
- // In order to create new subnet we need to get the data out
- // of the child parsers first. The only way to do it is to
- // invoke commit on them because it will make them write
- // parsed data into storages we have supplied.
- // Note that triggering commits on child parsers does not
- // affect global data because we supplied pointers to storages
- // local to this object. Thus, even if this method fails
- // later on, the configuration remains consistent.
- BOOST_FOREACH(ParserPtr parser, parsers_) {
- parser->commit();
+ ConstElementPtr relay_params = subnet->find("relay");
+ if (relay_params) {
+ Option::Universe u = (address_family_ == AF_INET) ? Option::V4 : Option::V6;
+ RelayInfoParser parser(u);
+ parser.parse(relay_info_, relay_params);
}
// Create a subnet.
// need to get all characters preceding "/".
size_t pos = subnet_txt.find("/");
if (pos == string::npos) {
+ ConstElementPtr elem = params->find("subnet");
isc_throw(DhcpConfigError,
"Invalid subnet syntax (prefix/len expected):" << subnet_txt
- << " (" << string_values_->getPosition("subnet") << ")");
+ << " (" << elem->getPosition() << ")");
}
// Try to create the address object. It also validates that
std::string iface = getString(params, "interface");
if (!iface.empty()) {
if (!IfaceMgr::instance().getIface(iface)) {
+ ConstElementPtr error = params->find("interface");
isc_throw(DhcpConfigError, "Specified network interface name " << iface
<< " for subnet " << subnet_->toText()
<< " is not present" << " in the system ("
- << string_values_->getPosition("interface") << ")");
+ << error->getPosition() << ")");
}
subnet_->setIface(iface);
options_->copyTo(*subnet_->getCfgOption());
}
-isc::dhcp::Triplet<uint32_t>
-SubnetConfigParser::getParam(const std::string& name) {
- uint32_t value = 0;
- try {
- // look for local value
- value = uint32_values_->getParam(name);
- } catch (const DhcpConfigError &) {
- try {
- // no local, use global value
- value = global_context_->uint32_values_->getParam(name);
- } catch (const DhcpConfigError &) {
- isc_throw(DhcpConfigError, "Mandatory parameter " << name
- << " missing (no global default and no subnet-"
- << "specific value)");
- }
- }
-
- return (Triplet<uint32_t>(value));
-}
-
-isc::dhcp::Triplet<uint32_t>
-SubnetConfigParser::getOptionalParam(const std::string& name) {
- try {
- return (getParam(name));
- } catch (const DhcpConfigError &) {
- // No error. We will return an unspecified value.
- }
- return (Triplet<uint32_t>());
-}
-
//**************************** D2ClientConfigParser **********************
uint32_t
///
/// @param global_context
/// @param default_addr default IP address (0.0.0.0 for IPv4, :: for IPv6)
- SubnetConfigParser(const std::string&, ParserContextPtr global_context,
- const isc::asiolink::IOAddress& default_addr);
+ /// @param family address family: @c AF_INET or @c AF_INET6
+ SubnetConfigParser(uint16_t family);
/// @brief virtual destructor (does nothing)
virtual ~SubnetConfigParser() { }
/// @throw isc::DhcpConfigError if subnet configuration parsing failed.
SubnetPtr parse(isc::data::ConstElementPtr subnet);
- /// @brief creates parsers for entries in subnet definition
- ///
- /// @param config_id name of the entry
- ///
- /// @return parser object for specified entry name
- /// @throw isc::dhcp::DhcpConfigError if trying to create a parser
- /// for unknown config element
- virtual DhcpConfigParser*
- createSubnetConfigParser(const std::string& config_id) = 0;
-
/// @brief Instantiates the subnet based on a given IP prefix and prefix
/// length.
///
virtual void initSubnet(isc::data::ConstElementPtr params,
isc::asiolink::IOAddress addr, uint8_t len) = 0;
- /// @brief Returns value for a given parameter (after using inheritance)
- ///
- /// This method implements inheritance. For a given parameter name, it first
- /// checks if there is a global value for it and overwrites it with specific
- /// value if such value was defined in subnet.
- ///
- /// @param name name of the parameter
- /// @return triplet with the parameter name
- /// @throw DhcpConfigError when requested parameter is not present
- isc::dhcp::Triplet<uint32_t> getParam(const std::string& name);
-
- /// @brief Returns optional value for a given parameter.
- ///
- /// This method checks if an optional parameter has been specified for
- /// a subnet. If not, it will try to use a global value. If the global
- /// value is not specified it will return an object representing an
- /// unspecified value.
- ///
- /// @param name name of the configuration parameter.
- /// @return An optional value or a @c Triplet object representing
- /// unspecified value.
- isc::dhcp::Triplet<uint32_t> getOptionalParam(const std::string& name);
-
/// @brief Attempts to convert text representation to HRMode enum.
///
/// Allowed values are "disabled", "off" (alias for disabled),
protected:
- /// Storage for subnet-specific integer values.
- Uint32StoragePtr uint32_values_;
-
- /// Storage for subnet-specific string values.
- StringStoragePtr string_values_;
-
- /// Storage for subnet-specific boolean values.
- BooleanStoragePtr boolean_values_;
-
/// Storage for pools belonging to this subnet.
PoolStoragePtr pools_;
- /// Parsers are stored here.
- ParserCollection parsers_;
-
/// Pointer to the created subnet object.
isc::dhcp::SubnetPtr subnet_;
- /// Parsing context which contains global values, options and option
- /// definitions.
- ParserContextPtr global_context_;
+ /// @brief Address family: @c AF_INET or @c AF_INET6
+ uint16_t address_family_;
/// Pointer to relay information
isc::dhcp::Subnet::RelayInfoPtr relay_info_;