|
@@ -60,6 +60,8 @@ typedef std::map<string, string> StringStorage;
|
|
/// no subnet object created yet to store them.
|
|
/// no subnet object created yet to store them.
|
|
typedef std::vector<Pool6Ptr> PoolStorage;
|
|
typedef std::vector<Pool6Ptr> PoolStorage;
|
|
|
|
|
|
|
|
+typedef std::vector<OptionPtr> OptionStorage;
|
|
|
|
+
|
|
/// @brief Global uint32 parameters that will be used as defaults.
|
|
/// @brief Global uint32 parameters that will be used as defaults.
|
|
Uint32Storage uint32_defaults;
|
|
Uint32Storage uint32_defaults;
|
|
|
|
|
|
@@ -451,6 +453,10 @@ public:
|
|
OptionDataParser(const std::string&) {
|
|
OptionDataParser(const std::string&) {
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ void setStorage(OptionStorage* storage) {
|
|
|
|
+ options_ = storage;
|
|
|
|
+ }
|
|
|
|
+
|
|
void build(ConstElementPtr option_value) {
|
|
void build(ConstElementPtr option_value) {
|
|
BOOST_FOREACH(ConfigPair param, option_value->mapValue()) {
|
|
BOOST_FOREACH(ConfigPair param, option_value->mapValue()) {
|
|
ParserPtr parser;
|
|
ParserPtr parser;
|
|
@@ -461,7 +467,6 @@ public:
|
|
name_parser->setStorage(&string_values_);
|
|
name_parser->setStorage(&string_values_);
|
|
parser = name_parser;
|
|
parser = name_parser;
|
|
}
|
|
}
|
|
- // @todo: what if this is NULL pointer. Shouldn't we throw exception?
|
|
|
|
} else if (param.first == "code") {
|
|
} else if (param.first == "code") {
|
|
boost::shared_ptr<Uint32Parser>
|
|
boost::shared_ptr<Uint32Parser>
|
|
code_parser(dynamic_cast<Uint32Parser*>(Uint32Parser::Factory(param.first)));
|
|
code_parser(dynamic_cast<Uint32Parser*>(Uint32Parser::Factory(param.first)));
|
|
@@ -484,6 +489,7 @@ public:
|
|
parser->build(param.second);
|
|
parser->build(param.second);
|
|
parsers_.push_back(parser);
|
|
parsers_.push_back(parser);
|
|
}
|
|
}
|
|
|
|
+ createOption();
|
|
}
|
|
}
|
|
|
|
|
|
void commit() {
|
|
void commit() {
|
|
@@ -491,9 +497,49 @@ public:
|
|
|
|
|
|
private:
|
|
private:
|
|
|
|
|
|
|
|
+ void createOption() {
|
|
|
|
+ uint32_t option_code = getUint32Param("code");
|
|
|
|
+ if (option_code > std::numeric_limits<uint16_t>::max()) {
|
|
|
|
+ isc_throw(Dhcp6ConfigError, "Parser error: value of 'code' must not"
|
|
|
|
+ << " exceed " << std::numeric_limits<uint16_t>::max());
|
|
|
|
+ }
|
|
|
|
+ std::string option_name = getStringParam("name");
|
|
|
|
+ if (option_name.empty()) {
|
|
|
|
+ isc_throw(Dhcp6ConfigError, "Parser error: option name must not be"
|
|
|
|
+ << " empty");
|
|
|
|
+ } else if (option_name.find(" ") != std::string::npos) {
|
|
|
|
+ isc_throw(Dhcp6ConfigError, "Parser error: option name must not contain"
|
|
|
|
+ << " spaces");
|
|
|
|
+ }
|
|
|
|
+ /// @todo more sanity checks on option name are needed.
|
|
|
|
+ OptionPtr option(new Option(Option::V6, static_cast<uint16_t>(option_code),
|
|
|
|
+ OptionBuffer()));
|
|
|
|
+ options_->push_back(option);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ std::string getStringParam(const std::string& param_id) const {
|
|
|
|
+ StringStorage::const_iterator param = string_values_.find(param_id);
|
|
|
|
+ if (param == string_values_.end()) {
|
|
|
|
+ isc_throw(Dhcp6ConfigError, "Parser error: option-data parameter"
|
|
|
|
+ << " '" << param_id << "' not specified");
|
|
|
|
+ }
|
|
|
|
+ return (param->second);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ uint32_t getUint32Param(const std::string& param_id) const {
|
|
|
|
+ Uint32Storage::const_iterator param = uint32_values_.find(param_id);
|
|
|
|
+ if (param == uint32_values_.end()) {
|
|
|
|
+ isc_throw(Dhcp6ConfigError, "Parser error: option-data parameter"
|
|
|
|
+ << " '" << param_id << "' not specified");
|
|
|
|
+ }
|
|
|
|
+ return (param->second);
|
|
|
|
+ }
|
|
|
|
+
|
|
Uint32Storage uint32_values_;
|
|
Uint32Storage uint32_values_;
|
|
StringStorage string_values_;
|
|
StringStorage string_values_;
|
|
|
|
|
|
|
|
+ OptionStorage* options_;
|
|
|
|
+
|
|
ParserCollection parsers_;
|
|
ParserCollection parsers_;
|
|
};
|
|
};
|
|
|
|
|
|
@@ -519,15 +565,20 @@ public:
|
|
|
|
|
|
// No need to define FactoryMap here. There's only one type
|
|
// No need to define FactoryMap here. There's only one type
|
|
// used: Subnet6ConfigParser
|
|
// used: Subnet6ConfigParser
|
|
-
|
|
|
|
BOOST_FOREACH(ConstElementPtr option_value, option_value_list->listValue()) {
|
|
BOOST_FOREACH(ConstElementPtr option_value, option_value_list->listValue()) {
|
|
|
|
|
|
- ParserPtr parser(new OptionDataParser("option-data"));
|
|
|
|
|
|
+ boost::shared_ptr<OptionDataParser> parser(new OptionDataParser("option-data"));
|
|
|
|
+ parser->setStorage(options_);
|
|
parser->build(option_value);
|
|
parser->build(option_value);
|
|
option_values_.push_back(parser);
|
|
option_values_.push_back(parser);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ void setStorage(OptionStorage* storage) {
|
|
|
|
+ options_ = storage;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
/// @brief commits subnets definitions.
|
|
/// @brief commits subnets definitions.
|
|
///
|
|
///
|
|
/// Iterates over all Subnet6 parsers. Each parser contains definitions
|
|
/// Iterates over all Subnet6 parsers. Each parser contains definitions
|
|
@@ -552,6 +603,8 @@ public:
|
|
return (new OptionDataListParser(param_name));
|
|
return (new OptionDataListParser(param_name));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ OptionStorage* options_;
|
|
|
|
+
|
|
ParserCollection option_values_;
|
|
ParserCollection option_values_;
|
|
};
|
|
};
|
|
|
|
|
|
@@ -596,8 +649,9 @@ public:
|
|
if (poolParser) {
|
|
if (poolParser) {
|
|
poolParser->setStorage(&pools_);
|
|
poolParser->setStorage(&pools_);
|
|
} else {
|
|
} else {
|
|
- boost::shared_ptr<OptionDataParser> option_data_parser =
|
|
|
|
- boost::dynamic_pointer_cast<OptionDataParser>(parser);
|
|
|
|
|
|
+ boost::shared_ptr<OptionDataListParser> option_data_list_parser =
|
|
|
|
+ boost::dynamic_pointer_cast<OptionDataListParser>(parser);
|
|
|
|
+ option_data_list_parser->setStorage(&options_);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -653,6 +707,10 @@ public:
|
|
subnet->addPool6(*it);
|
|
subnet->addPool6(*it);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ BOOST_FOREACH(OptionPtr option, options_) {
|
|
|
|
+ subnet->addOption(option);
|
|
|
|
+ }
|
|
|
|
+
|
|
CfgMgr::instance().addSubnet6(subnet);
|
|
CfgMgr::instance().addSubnet6(subnet);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -739,6 +797,9 @@ protected:
|
|
/// storage for pools belonging to this subnet
|
|
/// storage for pools belonging to this subnet
|
|
PoolStorage pools_;
|
|
PoolStorage pools_;
|
|
|
|
|
|
|
|
+ /// storage for options belonging to this subnet
|
|
|
|
+ OptionStorage options_;
|
|
|
|
+
|
|
/// parsers are stored here
|
|
/// parsers are stored here
|
|
ParserCollection parsers_;
|
|
ParserCollection parsers_;
|
|
};
|
|
};
|