Commit 6cfae24d authored by Marcin Siodelski's avatar Marcin Siodelski

[5022] It is now possible to specify options for a prefix pool.

parent 9f76f165
......@@ -151,7 +151,8 @@ public:
/// upon "commit"
PdPoolParser(const std::string&, PoolStoragePtr pools)
: uint32_values_(new Uint32Storage()),
string_values_(new StringStorage()), pools_(pools) {
string_values_(new StringStorage()), pools_(pools),
options_(new CfgOption()) {
if (!pools_) {
isc_throw(isc::dhcp::DhcpConfigError,
"PdPoolParser context storage may not be NULL");
......@@ -180,6 +181,12 @@ public:
Uint32ParserPtr code_parser(new Uint32Parser(entry,
uint32_values_));
parser = code_parser;
} else if (entry == "option-data") {
OptionDataListParserPtr option_parser(new OptionDataListParser(entry,
options_,
AF_INET6));
parser = option_parser;
} else {
isc_throw(DhcpConfigError, "unsupported parameter: " << entry
<< " (" << param.second->getPosition() << ")");
......@@ -229,6 +236,9 @@ protected:
/// Pointer to storage to which the local pool is written upon commit.
isc::dhcp::PoolStoragePtr pools_;
/// A storage for pool specific option values.
CfgOptionPtr options_;
};
/// @brief Parser for a list of prefix delegation pools.
......
......@@ -2556,6 +2556,110 @@ TEST_F(Dhcp6ParserTest, optionDataInMultipleSubnets) {
sizeof(user_class_expected));
}
TEST_F(Dhcp6ParserTest, optionDataInMultiplePools) {
ConstElementPtr x;
string config = "{ " + genIfaceConfig() + ","
"\"preferred-lifetime\": 3000,"
"\"rebind-timer\": 2000, "
"\"renew-timer\": 1000, "
"\"subnet6\": [ { "
" \"pools\": [ { "
" \"pool\": \"2001:db8:1::10 - 2001:db8:1::100\""
/* " \"option-data\": [ {"
" \"name\": \"subscriber-id\","
" \"data\": \"0102030405060708090A\","
" \"csv-format\": False"
" } ]" */
" },"
" {"
" \"pool\": \"2001:db8:1::300 - 2001:db8:1::400\""
/* " \"option-data\": [ {"
" \"name\": \"user-class\","
" \"data\": \"FFFEFDFCFB\","
" \"csv-format\": False"
" } ]" */
" } ],"
" \"pd-pools\": [ { "
" \"prefix\": \"3000::\","
" \"prefix-len\": 48,"
" \"delegated-len\": 64,"
" \"option-data\": [ {"
" \"name\": \"subscriber-id\","
" \"data\": \"112233445566\","
" \"csv-format\": False"
" } ]"
" },"
" {"
" \"prefix\": \"3001::\","
" \"prefix-len\": 48,"
" \"delegated-len\": 64,"
" \"option-data\": [ {"
" \"name\": \"user-class\","
" \"data\": \"aabbccddee\","
" \"csv-format\": False"
" } ]"
" } ],"
" \"subnet\": \"2001:db8:1::/64\""
" } ],"
"\"valid-lifetime\": 4000 }";
ElementPtr json = Element::fromJSON(config);
EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
checkResult(x, 0);
Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
selectSubnet(IOAddress("2001:db8:1::5"), classify_);
ASSERT_TRUE(subnet);
PoolPtr pool = subnet->getPool(Lease::TYPE_PD, IOAddress("3000::"), false);
ASSERT_TRUE(pool);
Pool6Ptr pool6 = boost::dynamic_pointer_cast<Pool6>(pool);
OptionContainerPtr options1 = pool6->getCfgOption()->getAll("dhcp6");
ASSERT_EQ(1, options1->size());
// Get the search index. Index #1 is to search using option code.
const OptionContainerTypeIndex& idx1 = options1->get<1>();
// Get the options for specified index. Expecting one option to be
// returned but in theory we may have multiple options with the same
// code so we get the range.
std::pair<OptionContainerTypeIndex::const_iterator,
OptionContainerTypeIndex::const_iterator> range1 =
idx1.equal_range(D6O_SUBSCRIBER_ID);
// Expect single option with the code equal to 38.
ASSERT_EQ(1, std::distance(range1.first, range1.second));
const uint8_t subid_expected[] = {
0x01, 0x02, 0x03, 0x04, 0x05,
0x06, 0x07, 0x08, 0x09, 0x0A
};
// Check if option is valid in terms of code and carried data.
testOption(*range1.first, D6O_SUBSCRIBER_ID, subid_expected,
sizeof(subid_expected));
/* // Test another subnet in the same way.
Subnet6Ptr subnet2 = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
selectSubnet(IOAddress("2001:db8:2::4"), classify_);
ASSERT_TRUE(subnet2);
OptionContainerPtr options2 = subnet2->getCfgOption()->getAll("dhcp6");
ASSERT_EQ(1, options2->size());
const OptionContainerTypeIndex& idx2 = options2->get<1>();
std::pair<OptionContainerTypeIndex::const_iterator,
OptionContainerTypeIndex::const_iterator> range2 =
idx2.equal_range(D6O_USER_CLASS);
ASSERT_EQ(1, std::distance(range2.first, range2.second));
const uint8_t user_class_expected[] = {
0xFF, 0xFE, 0xFD, 0xFC, 0xFB
};
testOption(*range2.first, D6O_USER_CLASS, user_class_expected,
sizeof(user_class_expected)); */
}
// The goal of this test is to check that the option carrying a boolean
// value can be configured using one of the values: "true", "false", "0"
// or "1".
......
// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
......@@ -17,7 +17,7 @@ namespace dhcp {
Pool::Pool(Lease::Type type, const isc::asiolink::IOAddress& first,
const isc::asiolink::IOAddress& last)
:id_(getNextID()), first_(first), last_(last), type_(type),
capacity_(0) {
capacity_(0), cfg_option_(new CfgOption()) {
}
bool Pool::inRange(const isc::asiolink::IOAddress& addr) const {
......
// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
......@@ -9,6 +9,7 @@
#include <asiolink/io_address.h>
#include <boost/shared_ptr.hpp>
#include <dhcpsrv/cfg_option.h>
#include <dhcpsrv/lease.h>
#include <vector>
......@@ -79,6 +80,18 @@ public:
uint64_t getCapacity() const {
return (capacity_);
}
/// @brief Returns pointer to the option data configuration for this pool.
CfgOptionPtr getCfgOption() {
return (cfg_option_);
}
/// @brief Returns const pointer to the option data configuration for
/// this pool.
ConstCfgOptionPtr getCfgOption() const {
return (cfg_option_);
}
protected:
/// @brief protected constructor
......@@ -128,6 +141,9 @@ protected:
/// the result. Note that for very large pools, the number is capped at
/// max value of uint64_t.
uint64_t capacity_;
/// @brief Pointer to the option data configuration for this pool.
CfgOptionPtr cfg_option_;
};
/// @brief Pool information for IPv4 addresses
......
// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
......@@ -282,5 +282,55 @@ TEST(Pool6Test, leasesCount) {
EXPECT_EQ(65536, pool2.getCapacity());
}
// This test checks that it is possible to specify pool specific options.
TEST(Pool6Test, addOptions) {
// Create a pool to add options to it.
Pool6Ptr pool(new Pool6(Lease::TYPE_PD, IOAddress("3000::"), 64, 128));
// Differentiate options by their codes (100-109)
for (uint16_t code = 100; code < 110; ++code) {
OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
ASSERT_NO_THROW(pool->getCfgOption()->add(option, false, "dhcp6"));
}
// Add 7 options to another option space. The option codes partially overlap
// with option codes that we have added to dhcp6 option space.
for (uint16_t code = 105; code < 112; ++code) {
OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
ASSERT_NO_THROW(pool->getCfgOption()->add(option, false, "isc"));
}
// Get options from the pool and check if all 10 are there.
OptionContainerPtr options = pool->getCfgOption()->getAll("dhcp6");
ASSERT_TRUE(options);
ASSERT_EQ(10, options->size());
// Validate codes of options added to dhcp6 option space.
uint16_t expected_code = 100;
for (OptionContainer::const_iterator option_desc = options->begin();
option_desc != options->end(); ++option_desc) {
ASSERT_TRUE(option_desc->option_);
EXPECT_EQ(expected_code, option_desc->option_->getType());
++expected_code;
}
options = pool->getCfgOption()->getAll("isc");
ASSERT_TRUE(options);
ASSERT_EQ(7, options->size());
// Validate codes of options added to isc option space.
expected_code = 105;
for (OptionContainer::const_iterator option_desc = options->begin();
option_desc != options->end(); ++option_desc) {
ASSERT_TRUE(option_desc->option_);
EXPECT_EQ(expected_code, option_desc->option_->getType());
++expected_code;
}
// Try to get options from a non-existing option space.
options = pool->getCfgOption()->getAll("abcd");
ASSERT_TRUE(options);
EXPECT_TRUE(options->empty());
}
}; // end of anonymous namespace
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