}
};
-/// @brief Parser for IPv4 pool definitions.
+/// @brief Parser for IPv6 pool definitions.
///
/// This is the IPv6 derivation of the PoolParser class and handles pool
/// definitions, i.e. a list of entries of one of two syntaxes: min-max and
}
};
+class Pools6ListParser : public PoolsListParser {
+public:
+ Pools6ListParser(const std::string& dummy, PoolStoragePtr pools)
+ :PoolsListParser(dummy, pools) {
+ }
+
+protected:
+ virtual ParserPtr poolParserMaker(PoolStoragePtr storage) {
+ return (ParserPtr(new Pool6Parser("pool", storage)));
+ }
+};
+
/// @brief Parser for IPv6 prefix delegation definitions.
///
/// This class handles prefix delegation pool definitions for IPv6 subnets
(config_id.compare("client-class") == 0) ||
(config_id.compare("interface-id") == 0)) {
parser = new StringParser(config_id, string_values_);
- } else if (config_id.compare("pool") == 0) {
- parser = new Pool6Parser(config_id, pools_);
+ } else if (config_id.compare("pools") == 0) {
+ parser = new Pools6ListParser(config_id, pools_);
} else if (config_id.compare("relay") == 0) {
parser = new RelayInfoParser(config_id, relay_info_, Option::V6);
} else if (config_id.compare("pd-pools") == 0) {
*storage_ = local_;
}
+//****************************** PoolsListParser ********************************
+PoolsListParser::PoolsListParser(const std::string& dummy, PoolStoragePtr pools)
+ :pools_(pools), local_pools_(new PoolStorage()) {
+ if (!pools_) {
+ isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
+ << "storage may not be NULL");
+ }
+}
+
+void
+PoolsListParser::build(ConstElementPtr pools) {
+ BOOST_FOREACH(ConstElementPtr pool, pools->listValue()) {
+
+ // Iterate over every structure on the pools list and invoke
+ // a separate parser for it.
+ ParserPtr parser = poolParserMaker(local_pools_);
+
+ parser->build(pool);
+
+ // Before we can create a pool, we need to ask the pool parser
+ // to create it.
+ parser->commit();
+ }
+}
+
+void PoolsListParser::commit() {
+ if (pools_) {
+ // local_pools_ holds the values produced by the build function.
+ // At this point parsing should have completed successfuly so
+ // we can append new data to the supplied storage.
+ pools_->insert(pools_->end(), local_pools_->begin(), local_pools_->end());
+ }
+}
+
//****************************** PoolParser ********************************
PoolParser::PoolParser(const std::string&, PoolStoragePtr pools)
:pools_(pools) {
}
void
-PoolParser::build(ConstElementPtr pools_list) {
- BOOST_FOREACH(ConstElementPtr text_pool, pools_list->listValue()) {
- // That should be a single pool representation. It should contain
- // text is form prefix/len or first - last. Note that spaces
- // are allowed
- string txt = text_pool->stringValue();
-
- // first let's remove any whitespaces
- boost::erase_all(txt, " "); // space
- boost::erase_all(txt, "\t"); // tabulation
-
- // Is this prefix/len notation?
- size_t pos = txt.find("/");
- if (pos != string::npos) {
- isc::asiolink::IOAddress addr("::");
- uint8_t len = 0;
- try {
- addr = isc::asiolink::IOAddress(txt.substr(0, pos));
-
- // start with the first character after /
- string prefix_len = txt.substr(pos + 1);
-
- // It is lexical cast to int and then downcast to uint8_t.
- // Direct cast to uint8_t (which is really an unsigned char)
- // will result in interpreting the first digit as output
- // value and throwing exception if length is written on two
- // digits (because there are extra characters left over).
-
- // No checks for values over 128. Range correctness will
- // be checked in Pool4 constructor.
- len = boost::lexical_cast<int>(prefix_len);
- } catch (...) {
- isc_throw(DhcpConfigError, "Failed to parse pool "
- "definition: " << text_pool->stringValue()
- << " (" << text_pool->getPosition() << ")");
- }
+PoolParser::build(ConstElementPtr pool_structure) {
- PoolPtr pool(poolMaker(addr, len));
- local_pools_.push_back(pool);
- continue;
- }
+ ConstElementPtr text_pool = pool_structure->get("pool");
- // Is this min-max notation?
- pos = txt.find("-");
- if (pos != string::npos) {
- // using min-max notation
- isc::asiolink::IOAddress min(txt.substr(0,pos));
- isc::asiolink::IOAddress max(txt.substr(pos + 1));
+ // That should be a single pool representation. It should contain
+ // text is form prefix/len or first - last. Note that spaces
+ // are allowed
+ string txt = text_pool->stringValue();
- PoolPtr pool(poolMaker(min, max));
- local_pools_.push_back(pool);
- continue;
- }
+ // first let's remove any whitespaces
+ boost::erase_all(txt, " "); // space
+ boost::erase_all(txt, "\t"); // tabulation
- isc_throw(DhcpConfigError, "invalid pool definition: "
- << text_pool->stringValue() <<
- ". There are two acceptable formats <min address-max address>"
- " or <prefix/len> ("
- << text_pool->getPosition() << ")");
+ // Is this prefix/len notation?
+ size_t pos = txt.find("/");
+ if (pos != string::npos) {
+ isc::asiolink::IOAddress addr("::");
+ uint8_t len = 0;
+ try {
+ addr = isc::asiolink::IOAddress(txt.substr(0, pos));
+
+ // start with the first character after /
+ string prefix_len = txt.substr(pos + 1);
+
+ // It is lexical cast to int and then downcast to uint8_t.
+ // Direct cast to uint8_t (which is really an unsigned char)
+ // will result in interpreting the first digit as output
+ // value and throwing exception if length is written on two
+ // digits (because there are extra characters left over).
+
+ // No checks for values over 128. Range correctness will
+ // be checked in Pool4 constructor.
+ len = boost::lexical_cast<int>(prefix_len);
+ } catch (...) {
+ isc_throw(DhcpConfigError, "Failed to parse pool "
+ "definition: " << text_pool->stringValue()
+ << " (" << text_pool->getPosition() << ")");
}
+
+ PoolPtr pool(poolMaker(addr, len));
+ local_pools_.push_back(pool);
+ return;
+ }
+
+ // Is this min-max notation?
+ pos = txt.find("-");
+ if (pos != string::npos) {
+ // using min-max notation
+ isc::asiolink::IOAddress min(txt.substr(0,pos));
+ isc::asiolink::IOAddress max(txt.substr(pos + 1));
+
+ PoolPtr pool(poolMaker(min, max));
+ local_pools_.push_back(pool);
+ return;
+ }
+
+ isc_throw(DhcpConfigError, "invalid pool definition: "
+ << text_pool->stringValue() <<
+ ". There are two acceptable formats <min address-max address>"
+ " or <prefix/len> ("
+ << text_pool->getPosition() << ")");
}
void
typedef std::vector<PoolPtr> PoolStorage;
typedef boost::shared_ptr<PoolStorage> PoolStoragePtr;
-/// @brief parser for pool definition
+/// @brief parser for a signle pool definition
///
/// This abstract parser handles pool definitions, i.e. a list of entries of one
/// of two syntaxes: min-max and prefix/len. Pool objects are created
/// and stored in chosen PoolStorage container.
///
-/// It is useful for parsing Dhcp<4/6>/subnet<4/6>[X]/pool parameters.
+/// It is useful for parsing Dhcp<4/6>/subnet<4/6>[X]/pools[X] structure.
class PoolParser : public DhcpConfigParser {
public:
/// @throw isc::dhcp::DhcpConfigError if storage is null.
PoolParser(const std::string& dummy, PoolStoragePtr pools);
- /// @brief parses the actual list
+ /// @brief parses the actual structure
///
/// This method parses the actual list of interfaces.
/// No validation is done at this stage, everything is interpreted as
/// interface name.
- /// @param pools_list list of pools defined for a subnet
+ /// @param pool_structure a signle entry on a list of pools
/// @throw isc::dhcp::DhcpConfigError when pool parsing fails
- virtual void build(isc::data::ConstElementPtr pools_list);
+ virtual void build(isc::data::ConstElementPtr pool_structure);
/// @brief Stores the parsed values in a storage provided
/// by an upper level parser.
PoolStorage local_pools_;
};
+/// @brief Parser for a list of pools
+///
+/// This parser parses a list pools. Each element on that list gets its own
+/// parser, created with poolParserMaker() method. That method must be specified
+/// for each protocol family (v4 or v6) separately.
+///
+/// This class is not intended to be used directly. Instead, derived classes
+/// should implement poolParserMaker() method.
+class PoolsListParser : public DhcpConfigParser {
+public:
+
+ /// @brief constructor.
+ ///
+ /// @param dummy first argument is ignored, all Parser constructors
+ /// accept string as first argument.
+ /// @param pools is the storage in which to store the parsed pool
+ /// upon "commit".
+ /// @throw isc::dhcp::DhcpConfigError if storage is null.
+ PoolsListParser(const std::string& dummy, PoolStoragePtr pools);
+
+ /// @brief parses the actual structure
+ ///
+ /// This method parses the actual list of pools. It creates a parser
+ /// for each structure using poolParserMaker().
+ ///
+ /// @param pools_list a list of pool structures
+ /// @throw isc::dhcp::DhcpConfigError when pool parsing fails
+ virtual void build(isc::data::ConstElementPtr pools_list);
+
+ /// @brief Stores the parsed values in a storage provided
+ /// by an upper level parser.
+ virtual void commit();
+
+protected:
+
+ /// @brief Creates a PoolParser object
+ ///
+ /// Instantiates appropriate (v4 or v6) PoolParser object.
+ /// @param storage parameter that is passed to ParserMaker() constructor.
+ virtual ParserPtr poolParserMaker(PoolStoragePtr storage) = 0;
+
+ /// @brief pointer to the actual Pools storage
+ ///
+ /// That is typically a storage somewhere in Subnet parser
+ /// (an upper level parser).
+ PoolStoragePtr pools_;
+
+ /// A temporary storage for pools configuration. It is a
+ /// storage where pools are stored by build function.
+ PoolStoragePtr local_pools_;
+};
+
/// @brief parser for additional relay information
///
/// This concrete parser handles RelayInfo structure defintions.