Commit 353cb225 authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰
Browse files

[3274] RelayInfo parser implemented.

parent 406df0ff
......@@ -811,6 +811,53 @@ OptionDefListParser::commit() {
}
}
//****************************** PoolParser ********************************
RelayInfoParser::RelayInfoParser(const std::string&,
const isc::dhcp::Subnet::RelayInfoPtr& relay_info,
const asiolink::IOAddress& default_addr)
:storage_(relay_info), local_(default_addr),
string_values_(new StringStorage()) {
if (!relay_info) {
isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
<< "relay-info storage may not be NULL");
}
};
void
RelayInfoParser::build(ConstElementPtr relay_info) {
BOOST_FOREACH(ConfigPair param, relay_info->mapValue()) {
ParserPtr parser(createConfigParser(param.first));
parser->build(param.second);
parser->commit();
}
// Get the IP address
asiolink::IOAddress ip(string_values_->getParam("ip-address"));
local_.addr_ = ip;
}
isc::dhcp::ParserPtr
RelayInfoParser::createConfigParser(const std::string& parameter) {
DhcpConfigParser* parser = NULL;
if (parameter.compare("ip-address") == 0) {
parser = new StringParser(parameter, string_values_);
} else {
isc_throw(NotImplemented,
"parser error: RelayInfoParser parameter not supported: "
<< parameter);
}
return (isc::dhcp::ParserPtr(parser));
}
void
RelayInfoParser::commit() {
*storage_ = local_;
}
//****************************** PoolParser ********************************
PoolParser::PoolParser(const std::string&, PoolStoragePtr pools)
:pools_(pools) {
......
......@@ -754,6 +754,46 @@ protected:
PoolStorage local_pools_;
};
/// @brief parser for additional relay information
///
/// This concrete parser handles RelayInfo structure defintions.
/// So far that structure holds only relay IP (v4 or v6) address, but it
/// is expected that the number of parameters will increase over time.
///
/// It is useful for parsing Dhcp<4/6>/subnet<4/6>[x]/relay parameters.
class RelayInfoParser : public DhcpConfigParser {
public:
/// @brief constructor
/// @param dummy first argument is ignored, all Parser constructors
/// accept string as first argument.
/// @param relay_info is the storage in which to store the parsed
/// relay information upon "commit".
RelayInfoParser(const std::string& dummy,
const isc::dhcp::Subnet::RelayInfoPtr& relay_info,
const asiolink::IOAddress& default_addr);
/// @brief parses the actual relay parameters
/// @param relay_info JSON strcture holding relay parameters to parse
virtual void build(isc::data::ConstElementPtr relay_info);
/// @brief stores parsed info in relay_info
virtual void commit();
protected:
isc::dhcp::ParserPtr
createConfigParser(const std::string& parser);
/// Parsed data will be stored there on commit()
isc::dhcp::Subnet::RelayInfoPtr storage_;
/// Local storage information (for temporary values)
isc::dhcp::Subnet::RelayInfo local_;
/// Storage for subnet-specific string values.
StringStoragePtr string_values_;
};
/// @brief this class parses a single subnet
///
/// This class parses the whole subnet definition. It creates parsers
......
......@@ -154,7 +154,7 @@ public:
>
> OptionContainer;
// Pointer to the OptionContainer object.
/// Pointer to the OptionContainer object.
typedef boost::shared_ptr<OptionContainer> OptionContainerPtr;
/// Type of the index #1 - option type.
typedef OptionContainer::nth_index<1>::type OptionContainerTypeIndex;
......@@ -183,6 +183,9 @@ public:
isc::asiolink::IOAddress addr_;
};
/// Pointer to the RelayInfo structure
typedef boost::shared_ptr<Subnet::RelayInfo> RelayInfoPtr;
/// @brief checks if specified address is in range
bool inRange(const isc::asiolink::IOAddress& addr) const;
......
......@@ -1267,3 +1267,50 @@ TEST_F(ParserContextTest, copyConstruct) {
TEST_F(ParserContextTest, copyConstructNull) {
testCopyAssignmentNull(true);
}
/// @brief Checks that a valid relay info structure for IPv4 can be handled
TEST_F(ParseConfigTest, validRelayInfo4) {
// Relay information structure. Very simple for now.
std::string config_str =
" {"
" \"ip-address\" : \"192.0.2.1\""
" }";
ElementPtr json = Element::fromJSON(config_str);
// We need to set the default ip-address to something.
Subnet::RelayInfoPtr result(new Subnet::RelayInfo(asiolink::IOAddress("0.0.0.0")));
boost::shared_ptr<RelayInfoParser> parser;
// Subnet4 parser will pass 0.0.0.0 to the RelayInfoParser
EXPECT_NO_THROW(parser.reset(new RelayInfoParser("ignored", result,
asiolink::IOAddress("0.0.0.0"))));
EXPECT_NO_THROW(parser->build(json));
EXPECT_NO_THROW(parser->commit());
EXPECT_EQ("192.0.2.1", result->addr_.toText());
}
/// @brief Checks that a valid relay info structure for IPv6 can be handled
TEST_F(ParseConfigTest, validRelayInfo6) {
// Relay information structure. Very simple for now.
std::string config_str =
" {"
" \"ip-address\" : \"2001:db8::1\""
" }";
ElementPtr json = Element::fromJSON(config_str);
// We need to set the default ip-address to something.
Subnet::RelayInfoPtr result(new Subnet::RelayInfo(asiolink::IOAddress("::")));
boost::shared_ptr<RelayInfoParser> parser;
// Subnet4 parser will pass :: to the RelayInfoParser
EXPECT_NO_THROW(parser.reset(new RelayInfoParser("ignored", result,
asiolink::IOAddress("::"))));
EXPECT_NO_THROW(parser->build(json));
EXPECT_NO_THROW(parser->commit());
EXPECT_EQ("2001:db8::1", result->addr_.toText());
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment