BIND 10 master, updated. 79a22be33825bafa1a0cdfa24d5cb751ab1ae2d3 [master] Merge branch 'trac3151'
BIND 10 source code commits
bind10-changes at lists.isc.org
Fri Sep 27 12:05:08 UTC 2013
The branch, master has been updated
via 79a22be33825bafa1a0cdfa24d5cb751ab1ae2d3 (commit)
via aa37f6861c45ad16577f327441f1dc2b546e258f (commit)
via 4a4a6098ba06773512cb4e20033b58c8353c8201 (commit)
via b5f8586097eb7bb1961fce2c767a71f534923d2b (commit)
via f67708b12cc011dcaa6a6352792b42f154527bec (commit)
from 66158f78882b882fb8fcc1be29e2969b0dbae75b (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 79a22be33825bafa1a0cdfa24d5cb751ab1ae2d3
Merge: 66158f7 aa37f68
Author: Thomas Markwalder <tmark at isc.org>
Date: Fri Sep 27 07:46:53 2013 -0400
[master] Merge branch 'trac3151'
Adds configuration support prefix delegation pools in IPv6 subnets to b10-dhcp6.
-----------------------------------------------------------------------
Summary of changes:
configure.ac | 1 +
doc/guide/bind10-guide.xml | 21 ++
src/bin/dhcp6/config_parser.cc | 184 ++++++++++++
src/bin/dhcp6/dhcp6.spec | 36 ++-
src/bin/dhcp6/tests/config_parser_unittest.cc | 305 ++++++++++++++++++++
.../tests/test_data_files_config.h.in | 12 +-
6 files changed, 554 insertions(+), 5 deletions(-)
copy src/bin/{d2 => dhcp6}/tests/test_data_files_config.h.in (73%)
-----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index 2cc91660..66381dd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1463,6 +1463,7 @@ AC_OUTPUT([doc/version.ent
src/bin/auth/gen-statisticsitems.py.pre
src/bin/dhcp4/spec_config.h.pre
src/bin/dhcp6/spec_config.h.pre
+ src/bin/dhcp6/tests/test_data_files_config.h
src/bin/d2/spec_config.h.pre
src/bin/d2/tests/test_data_files_config.h
src/bin/tests/process_rename_test.py
diff --git a/doc/guide/bind10-guide.xml b/doc/guide/bind10-guide.xml
index 6c538cd..83c50b6 100644
--- a/doc/guide/bind10-guide.xml
+++ b/doc/guide/bind10-guide.xml
@@ -4725,6 +4725,27 @@ Dhcp6/subnet6/ list
</para>
</section>
+ <section>
+<!-- @todo: add real meat to the prefix delegation config this is just place holder stuff -->
+ <title>Subnet and Prefix Delegation Pools</title>
+ <para>
+ Subnets may also be configured to delegate address prefixes....
+ A subnet may have one or more prefix delegation pools. Each pool has
+ a prefixed address, which is specified as a prefix and a prefix length,
+ as well as a delegated prefix length. A sample configuration is shown
+ below:
+ <screen>
+> <userinput>config add Dhcp6/subnet6</userinput>
+> <userinput>config set Dhcp6/subnet6[0]/subnet "2001:db8:1::/64"</userinput>
+> <userinput>config show Dhcp6/subnet6[0]</userinput>
+> <userinput>config add Dhcp6/subnet6[0]/pd-pools</userinput>
+> <userinput>config set Dhcp6/subnet6[0]/pd-pools[0]/prefix "2001:db8:1::"</userinput>
+> <userinput>config set Dhcp6/subnet6[0]/pd-pools[0]/prefix-len 64</userinput>
+> <userinput>config set Dhcp6/subnet6[0]/pd-pools[0]/delegated-len 96</userinput>
+> <userinput>config commit</userinput></screen>
+ </para>
+ </section>
+
<section id="dhcp6-std-options">
<title>Standard DHCPv6 options</title>
<para>
diff --git a/src/bin/dhcp6/config_parser.cc b/src/bin/dhcp6/config_parser.cc
index 57af60e..fdf0bae 100644
--- a/src/bin/dhcp6/config_parser.cc
+++ b/src/bin/dhcp6/config_parser.cc
@@ -166,6 +166,188 @@ protected:
}
};
+/// @brief Parser for IPv6 prefix delegation definitions.
+///
+/// This class handles prefix delegation pool definitions for IPv6 subnets
+/// Pool6 objects are created and stored in the given PoolStorage container.
+///
+/// PdPool defintions currently support three elements: prefix, prefix-len,
+/// and delegated-len, as shown in the example JSON text below:
+///
+/// @code
+///
+/// {
+/// "prefix": "2001:db8:1::",
+/// "prefix-len": 64,
+/// "delegated-len": 128
+/// }
+/// @endcode
+///
+class PdPoolParser : public DhcpConfigParser {
+public:
+
+ /// @brief Constructor.
+ ///
+ /// @param param_name name of the parameter. Note, it is passed through
+ /// but unused, parameter is currently always "Dhcp6/subnet6[X]/pool"
+ /// @param pools storage container in which to store the parsed pool
+ /// upon "commit"
+ PdPoolParser(const std::string&, PoolStoragePtr pools)
+ : uint32_values_(new Uint32Storage()),
+ string_values_(new StringStorage()), pools_(pools) {
+ if (!pools_) {
+ isc_throw(isc::dhcp::DhcpConfigError,
+ "PdPoolParser context storage may not be NULL");
+ }
+ }
+
+ /// @brief Builds a prefix delegation pool from the given configuration
+ ///
+ /// This function parses configuration entries and creates an instance
+ /// of a dhcp::Pool6 configured for prefix delegation.
+ ///
+ /// @param pd_pool_ pointer to an element that holds configuration entries
+ /// that define a prefix delegation pool.
+ ///
+ /// @throw DhcpConfigError if configuration parsing fails.
+ virtual void build(ConstElementPtr pd_pool_) {
+ // Parse the elements that make up the option definition.
+ BOOST_FOREACH(ConfigPair param, pd_pool_->mapValue()) {
+ std::string entry(param.first);
+ ParserPtr parser;
+ if (entry == "prefix") {
+ StringParserPtr str_parser(new StringParser(entry,
+ string_values_));
+ parser = str_parser;
+ } else if (entry == "prefix-len" || entry == "delegated-len") {
+ Uint32ParserPtr code_parser(new Uint32Parser(entry,
+ uint32_values_));
+ parser = code_parser;
+ } else {
+ isc_throw(DhcpConfigError, "invalid parameter: " << entry);
+ }
+
+ parser->build(param.second);
+ parser->commit();
+ }
+
+ try {
+ // We should now have all of the pool elements we need to create
+ // the pool. Fetch them and pass them into the Pool6 constructor.
+ // The constructor is expected to enforce any value validation.
+ const std::string addr_str = string_values_->getParam("prefix");
+ IOAddress addr(addr_str);
+
+ uint32_t prefix_len = uint32_values_->getParam("prefix-len");
+
+ uint32_t delegated_len = uint32_values_->getParam("delegated-len");
+
+ // Attempt to construct the local pool.
+ pool_.reset(new Pool6(Lease::TYPE_PD, addr, prefix_len,
+ delegated_len));
+ } catch (const std::exception& ex) {
+ isc_throw(isc::dhcp::DhcpConfigError,
+ "PdPoolParser failed to build pool: " << ex.what());
+ }
+ }
+
+ // @brief Commits the constructed local pool to the pool storage.
+ virtual void commit() {
+ // Add the local pool to the external storage ptr.
+ pools_->push_back(pool_);
+ }
+
+protected:
+ /// Storage for subnet-specific integer values.
+ Uint32StoragePtr uint32_values_;
+
+ /// Storage for subnet-specific string values.
+ StringStoragePtr string_values_;
+
+ /// Parsers are stored here.
+ ParserCollection parsers_;
+
+ /// Pointer to the created pool object.
+ isc::dhcp::Pool6Ptr pool_;
+
+ /// Pointer to storage to which the local pool is written upon commit.
+ isc::dhcp::PoolStoragePtr pools_;
+};
+
+/// @brief Parser for a list of prefix delegation pools.
+///
+/// This parser iterates over a list of prefix delegation pool entries and
+/// creates pool instances for each one. If the parsing is successful, the
+/// collection of pools is committed to the provided storage.
+class PdPoolListParser : public DhcpConfigParser {
+public:
+ /// @brief Constructor.
+ ///
+ /// @param dummy first argument is ignored, all Parser constructors
+ /// accept string as first argument.
+ /// @param storage is the pool storage in which to store the parsed
+ /// pools in this list
+ /// @throw isc::dhcp::DhcpConfigError if storage is null.
+ PdPoolListParser(const std::string&, PoolStoragePtr pools)
+ : local_pools_(new PoolStorage()), pools_(pools) {
+ if (!pools_) {
+ isc_throw(isc::dhcp::DhcpConfigError,
+ "PdPoolListParser pools storage may not be NULL");
+ }
+ }
+
+ /// @brief Parse configuration entries.
+ ///
+ /// This function parses configuration entries and creates instances
+ /// of prefix delegation pools .
+ ///
+ /// @param pd_pool_list pointer to an element that holds entries
+ /// that define a prefix delegation pool.
+ ///
+ /// @throw DhcpConfigError if configuration parsing fails.
+ void build(isc::data::ConstElementPtr pd_pool_list) {
+ // Make sure the local list is empty.
+ local_pools_.reset(new PoolStorage());
+
+ // Make sure we have a configuration elements to parse.
+ if (!pd_pool_list) {
+ isc_throw(DhcpConfigError,
+ "PdPoolListParser: list of pool definitions is empty");
+ }
+
+ // Loop through the list of pd pools.
+ BOOST_FOREACH(ConstElementPtr pd_pool, pd_pool_list->listValue()) {
+ boost::shared_ptr<PdPoolParser>
+ // Create the PdPool parser.
+ parser(new PdPoolParser("pd-pool", local_pools_));
+ // Build the pool instance
+ parser->build(pd_pool);
+ // Commit the pool to the local list of pools.
+ parser->commit();
+ }
+ }
+
+ /// @brief Commits the pools created to the external storage area.
+ ///
+ /// Note that this method adds the local list of pools to the storage area
+ /// rather than replacing its contents. This permits other parsers to
+ /// contribute to the set of pools.
+ void commit() {
+ // local_pools_ holds the values produced by the build function.
+ // At this point parsing should have completed successfully so
+ // we can append new data to the supplied storage.
+ pools_->insert(pools_->end(), local_pools_->begin(),
+ local_pools_->end());
+ }
+
+private:
+ /// @brief storage for local pools
+ PoolStoragePtr local_pools_;
+
+ /// @brief External storage where pools are stored upon list commit.
+ PoolStoragePtr pools_;
+};
+
/// @brief This class parses a single IPv6 subnet.
///
/// This is the IPv6 derivation of the SubnetConfigParser class and it parses
@@ -219,6 +401,8 @@ protected:
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("pd-pools") == 0) {
+ parser = new PdPoolListParser(config_id, pools_);
} else if (config_id.compare("option-data") == 0) {
parser = new OptionDataListParser(config_id, options_,
global_context_,
diff --git a/src/bin/dhcp6/dhcp6.spec b/src/bin/dhcp6/dhcp6.spec
index 634b046..3810fad 100644
--- a/src/bin/dhcp6/dhcp6.spec
+++ b/src/bin/dhcp6/dhcp6.spec
@@ -16,7 +16,7 @@
"item_default": ""
}
},
-
+
{ "item_name": "interfaces",
"item_type": "list",
"item_optional": false,
@@ -254,6 +254,38 @@
"item_default": ""
}
},
+ {
+ "item_name": "pd-pools",
+ "item_type": "list",
+ "item_optional": true,
+ "item_default": [],
+ "list_item_spec":
+ {
+ "item_name": "pd-pool",
+ "item_type": "map",
+ "item_optional": false,
+ "item_default": {},
+ "map_item_spec": [
+ {
+ "item_name": "prefix",
+ "item_type": "string",
+ "item_optional": false,
+ "item_default": ""
+ },
+ {
+ "item_name": "prefix-len",
+ "item_type": "integer",
+ "item_optional": false,
+ "item_default": 128
+ },
+ {
+ "item_name": "delegated-len",
+ "item_type": "integer",
+ "item_optional": false,
+ "item_default": 128
+ }]
+ }
+ },
{ "item_name": "option-data",
"item_type": "list",
"item_optional": false,
@@ -313,7 +345,7 @@
{
"command_name": "libreload",
- "command_description": "Reloads the current hooks libraries.",
+ "command_description": "Reloads the current hooks libraries.",
"command_args": []
}
]
diff --git a/src/bin/dhcp6/tests/config_parser_unittest.cc b/src/bin/dhcp6/tests/config_parser_unittest.cc
index 0c46d26..acfc270 100644
--- a/src/bin/dhcp6/tests/config_parser_unittest.cc
+++ b/src/bin/dhcp6/tests/config_parser_unittest.cc
@@ -22,10 +22,12 @@
#include <dhcp/option_int.h>
#include <dhcp6/config_parser.h>
#include <dhcp6/dhcp6_srv.h>
+#include <dhcpsrv/addr_utilities.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/subnet.h>
#include <hooks/hooks_manager.h>
+#include "test_data_files_config.h"
#include "test_libraries.h"
#include "marker_file.h"
@@ -53,6 +55,17 @@ using namespace std;
namespace {
+std::string specfile(const std::string& name) {
+ return (std::string(DHCP6_SRC_DIR) + "/" + name);
+}
+
+/// @brief Tests that the spec file is valid.
+/// Verifies that the DHCP6 configuration specification file is valid.
+TEST(Dhcp6SpecTest, basicSpec) {
+ ASSERT_NO_THROW(isc::config::
+ moduleSpecFromFile(specfile("dhcp6.spec")));
+}
+
class Dhcp6ParserTest : public ::testing::Test {
public:
Dhcp6ParserTest() :rcode_(-1), srv_(0) {
@@ -682,6 +695,8 @@ TEST_F(Dhcp6ParserTest, poolOutOfSubnet) {
// Goal of this test is to verify if pools can be defined
// using prefix/length notation. There is no separate test for min-max
// notation as it was tested in several previous tests.
+// Note this test also verifies that subnets can be configured without
+// prefix delegation pools.
TEST_F(Dhcp6ParserTest, poolPrefixLen) {
ConstElementPtr x;
@@ -712,6 +727,296 @@ TEST_F(Dhcp6ParserTest, poolPrefixLen) {
EXPECT_EQ(4000, subnet->getValid());
}
+// Goal of this test is to verify the basic parsing of a prefix delegation
+// pool. It uses a single, valid pd pool.
+TEST_F(Dhcp6ParserTest, pdPoolBasics) {
+
+ ConstElementPtr x;
+
+ // Define a single valid pd pool.
+ string config =
+ "{ \"interfaces\": [ \"*\" ],"
+ "\"preferred-lifetime\": 3000,"
+ "\"rebind-timer\": 2000, "
+ "\"renew-timer\": 1000, "
+ "\"subnet6\": [ { "
+ " \"subnet\": \"2001:db8:1::/64\","
+ " \"pd-pools\": ["
+ " { \"prefix\": \"2001:db8:1::\", "
+ " \"prefix-len\": 64, "
+ " \"delegated-len\": 128"
+ " } ],"
+ "\"valid-lifetime\": 4000 }"
+ "] }";
+
+ // Convert the JSON string into Elements.
+ ElementPtr json;
+ ASSERT_NO_THROW(json = Element::fromJSON(config));
+
+ // Verify that DHCP6 configuration processing succeeds.
+ // Returned value must be non-empty ConstElementPtr to config result.
+ // rcode should be 0 which indicates successful configuration processing.
+ EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
+ ASSERT_TRUE(x);
+ comment_ = parseAnswer(rcode_, x);
+ EXPECT_EQ(0, rcode_);
+
+ // Test that we can retrieve the subnet.
+ Subnet6Ptr subnet = CfgMgr::
+ instance().getSubnet6(IOAddress("2001:db8:1::5"));
+
+ ASSERT_TRUE(subnet);
+
+ // Fetch the collection of PD pools. It should have 1 entry.
+ PoolCollection pc;
+ ASSERT_NO_THROW(pc = subnet->getPools(Lease::TYPE_PD));
+ EXPECT_EQ(1, pc.size());
+
+ // Get a pointer to the pd pool instance, and verify its contents.
+ Pool6Ptr p6;
+ ASSERT_NO_THROW(p6 = boost::dynamic_pointer_cast<Pool6>(pc[0]));
+ ASSERT_TRUE(p6);
+ EXPECT_EQ("2001:db8:1::", p6->getFirstAddress().toText());
+ EXPECT_EQ(128, p6->getLength());
+
+ // prefix-len is not directly accessible after pool construction, so
+ // verify that it was interpreted correctly by checking the last address
+ // value.
+ isc::asiolink::IOAddress prefixAddress("2001:db8:1::");
+ EXPECT_EQ(lastAddrInPrefix(prefixAddress, 64).toText(),
+ p6->getLastAddress().toText());
+}
+
+// Goal of this test is verify that a list of PD pools can be configured.
+// It also verifies that a subnet may be configured with both regular pools
+// and pd pools.
+TEST_F(Dhcp6ParserTest, pdPoolList) {
+
+ ConstElementPtr x;
+
+ const char* prefixes[] = {
+ "2001:db8:1:1::",
+ "2001:db8:1:2::",
+ "2001:db8:1:3::"
+ };
+
+ string config =
+ "{ \"interfaces\": [ \"*\" ],"
+ "\"preferred-lifetime\": 3000,"
+ "\"rebind-timer\": 2000, "
+ "\"renew-timer\": 1000, "
+ "\"subnet6\": [ { "
+ " \"pool\": [ \"2001:db8:1:04::/80\" ],"
+ " \"subnet\": \"2001:db8:1::/40\","
+ " \"pd-pools\": ["
+ " { \"prefix\": \"2001:db8:1:01::\", "
+ " \"prefix-len\": 72, "
+ " \"delegated-len\": 80"
+ " },"
+ " { \"prefix\": \"2001:db8:1:02::\", "
+ " \"prefix-len\": 72, "
+ " \"delegated-len\": 88"
+ " },"
+ " { \"prefix\": \"2001:db8:1:03::\", "
+ " \"prefix-len\": 72, "
+ " \"delegated-len\": 96"
+ " }"
+ "],"
+ "\"valid-lifetime\": 4000 }"
+ "] }";
+
+ // Convert the JSON string into Elements.
+ ElementPtr json = Element::fromJSON(config);
+ ASSERT_NO_THROW(json = Element::fromJSON(config));
+
+ // Verify that DHCP6 configuration processing succeeds.
+ // Returned value must be non-empty ConstElementPtr to config result.
+ // rcode should be 0 which indicates successful configuration processing.
+ EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
+ ASSERT_TRUE(x);
+ comment_ = parseAnswer(rcode_, x);
+ EXPECT_EQ(0, rcode_);
+
+ // Test that we can retrieve the subnet.
+ Subnet6Ptr subnet = CfgMgr::
+ instance().getSubnet6(IOAddress("2001:db8:1::5"));
+ ASSERT_TRUE(subnet);
+
+ // Fetch the collection of NA pools. It should have 1 entry.
+ PoolCollection pc;
+ ASSERT_NO_THROW(pc = subnet->getPools(Lease::TYPE_NA));
+ EXPECT_EQ(1, pc.size());
+
+ // Fetch the collection of PD pools. It should have 3 entries.
+ ASSERT_NO_THROW(pc = subnet->getPools(Lease::TYPE_PD));
+ EXPECT_EQ(3, pc.size());
+
+ // Loop through the pools and verify their contents.
+ for (int i = 0; i < 3; i++) {
+ Pool6Ptr p6;
+ ASSERT_NO_THROW(p6 = boost::dynamic_pointer_cast<Pool6>(pc[i]));
+ ASSERT_TRUE(p6);
+ EXPECT_EQ(prefixes[i], p6->getFirstAddress().toText());
+ EXPECT_EQ((80 + (i * 8)), p6->getLength());
+ }
+}
+
+// Goal of this test is to verify the a whole prefix can be delegated and that
+// a whole subnet can be delegated.
+TEST_F(Dhcp6ParserTest, subnetAndPrefixDelegated) {
+
+ ConstElementPtr x;
+
+ // Define a single valid pd pool.
+ string config =
+ "{ \"interfaces\": [ \"*\" ],"
+ "\"preferred-lifetime\": 3000,"
+ "\"rebind-timer\": 2000, "
+ "\"renew-timer\": 1000, "
+ "\"subnet6\": [ { "
+ " \"subnet\": \"2001:db8:1::/64\","
+ " \"pd-pools\": ["
+ " { \"prefix\": \"2001:db8:1::\", "
+ " \"prefix-len\": 64, "
+ " \"delegated-len\": 64"
+ " } ],"
+ "\"valid-lifetime\": 4000 }"
+ "] }";
+
+ // Convert the JSON string into Elements.
+ ElementPtr json;
+ ASSERT_NO_THROW(json = Element::fromJSON(config));
+
+ // Verify that DHCP6 configuration processing succeeds.
+ // Returned value must be non-empty ConstElementPtr to config result.
+ // rcode should be 0 which indicates successful configuration processing.
+ EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
+ ASSERT_TRUE(x);
+ comment_ = parseAnswer(rcode_, x);
+ EXPECT_EQ(0, rcode_);
+
+ // Test that we can retrieve the subnet.
+ Subnet6Ptr subnet = CfgMgr::
+ instance().getSubnet6(IOAddress("2001:db8:1::5"));
+
+ ASSERT_TRUE(subnet);
+
+ // Fetch the collection of PD pools. It should have 1 entry.
+ PoolCollection pc;
+ ASSERT_NO_THROW(pc = subnet->getPools(Lease::TYPE_PD));
+ EXPECT_EQ(1, pc.size());
+
+ // Get a pointer to the pd pool instance, and verify its contents.
+ Pool6Ptr p6;
+ ASSERT_NO_THROW(p6 = boost::dynamic_pointer_cast<Pool6>(pc[0]));
+ ASSERT_TRUE(p6);
+ EXPECT_EQ("2001:db8:1::", p6->getFirstAddress().toText());
+ EXPECT_EQ(64, p6->getLength());
+
+ // prefix-len is not directly accessible after pool construction, so
+ // verify that it was interpreted correctly by checking the last address
+ // value.
+ isc::asiolink::IOAddress prefixAddress("2001:db8:1::");
+ EXPECT_EQ(lastAddrInPrefix(prefixAddress, 64).toText(),
+ p6->getLastAddress().toText());
+}
+
+
+// Goal of this test is check for proper handling of invalid prefix delegation
+// pool configuration. It uses an array of invalid configurations to check
+// a variety of configuration errors.
+TEST_F(Dhcp6ParserTest, invalidPdPools) {
+
+ ConstElementPtr x;
+
+ const char *config[] = {
+ // No prefix.
+ "{ \"interfaces\": [ \"*\" ],"
+ "\"preferred-lifetime\": 3000,"
+ "\"rebind-timer\": 2000, "
+ "\"renew-timer\": 1000, "
+ "\"subnet6\": [ { "
+ " \"subnet\": \"2001:db8:1::/64\","
+ " \"pd-pools\": ["
+ " { "
+ " \"prefix-len\": 64, "
+ " \"delegated-len\": 128"
+ " } ],"
+ "\"valid-lifetime\": 4000 }"
+ "] }",
+ // No prefix-len.
+ "{ \"interfaces\": [ \"*\" ],"
+ "\"preferred-lifetime\": 3000,"
+ "\"rebind-timer\": 2000, "
+ "\"renew-timer\": 1000, "
+ "\"subnet6\": [ { "
+ " \"subnet\": \"2001:db8:1::/64\","
+ " \"pd-pools\": ["
+ " { \"prefix\": \"2001:db8:1::\", "
+ " \"delegated-len\": 128"
+ " } ],"
+ "\"valid-lifetime\": 4000 }"
+ "] }",
+ // No delegated-len.
+ "{ \"interfaces\": [ \"*\" ],"
+ "\"preferred-lifetime\": 3000,"
+ "\"rebind-timer\": 2000, "
+ "\"renew-timer\": 1000, "
+ "\"subnet6\": [ { "
+ " \"subnet\": \"2001:db8:1::/64\","
+ " \"pd-pools\": ["
+ " { \"prefix\": \"2001:db8:1::\", "
+ " \"prefix-len\": 64 "
+ " } ],"
+ "\"valid-lifetime\": 4000 }"
+ "] }",
+ // Delegated length is too short.
+ "{ \"interfaces\": [ \"*\" ],"
+ "\"preferred-lifetime\": 3000,"
+ "\"rebind-timer\": 2000, "
+ "\"renew-timer\": 1000, "
+ "\"subnet6\": [ { "
+ " \"subnet\": \"2001:db8:1::/64\","
+ " \"pd-pools\": ["
+ " { \"prefix\": \"2001:db8:1::\", "
+ " \"prefix-len\": 128, "
+ " \"delegated-len\": 64"
+ " } ],"
+ "\"valid-lifetime\": 4000 }"
+ "] }",
+ // Pool is not within the subnet.
+ "{ \"interfaces\": [ \"*\" ],"
+ "\"preferred-lifetime\": 3000,"
+ "\"rebind-timer\": 2000, "
+ "\"renew-timer\": 1000, "
+ "\"subnet6\": [ { "
+ " \"subnet\": \"2001:db8:1::/64\","
+ " \"pd-pools\": ["
+ " { \"prefix\": \"2001:db8:77::\", "
+ " \"prefix-len\": 64, "
+ " \"delegated-len\": 128"
+ " } ],"
+ "\"valid-lifetime\": 4000 }"
+ "] }"
+ };
+
+ ElementPtr json;
+ int num_msgs = sizeof(config)/sizeof(char*);
+ for (int i = 0; i < num_msgs; i++) {
+ // Convert JSON string to Elements.
+ ASSERT_NO_THROW(json = Element::fromJSON(config[i]));
+
+ // Configuration processing should fail without a throw.
+ ASSERT_NO_THROW(x = configureDhcp6Server(srv_, json));
+
+ // Returned value must be non-empty ConstElementPtr to config result.
+ // rcode should be 1 which indicates configuration error.
+ ASSERT_TRUE(x);
+ comment_ = parseAnswer(rcode_, x);
+ EXPECT_EQ(1, rcode_);
+ }
+}
+
// The goal of this test is to check whether an option definition
// that defines an option carrying an IPv6 address can be created.
TEST_F(Dhcp6ParserTest, optionDefIpv6Address) {
diff --git a/src/bin/dhcp6/tests/test_data_files_config.h.in b/src/bin/dhcp6/tests/test_data_files_config.h.in
new file mode 100644
index 0000000..8b09164
--- /dev/null
+++ b/src/bin/dhcp6/tests/test_data_files_config.h.in
@@ -0,0 +1,23 @@
+// Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+/// @brief Path to DHCP6 source dir so tests against the dhcp6.spec file
+/// can find it reliably.
+
+#ifndef TEST_DATA_FILES_CONFIG_H
+#define TEST_DATA_FILES_CONFIG_H
+
+#define DHCP6_SRC_DIR "@abs_top_srcdir@/src/bin/dhcp6"
+
+#endif
More information about the bind10-changes
mailing list