]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#3578] added more UTs to config_parser_unittest
authorRazvan Becheriu <razvan@isc.org>
Fri, 27 Sep 2024 21:00:10 +0000 (00:00 +0300)
committerRazvan Becheriu <razvan@isc.org>
Mon, 30 Sep 2024 14:40:59 +0000 (14:40 +0000)
src/bin/dhcp4/tests/config_parser_unittest.cc
src/bin/dhcp4/tests/get_config_unittest.cc
src/bin/dhcp6/tests/config_parser_unittest.cc
src/bin/dhcp6/tests/get_config_unittest.cc

index fe2894b66869554fd08a86d7daa491ce16f27e53..99124e4120ac38be190c1cb8acd5409c5be7b18d 100644 (file)
@@ -6,49 +6,55 @@
 
 #include <config.h>
 
-#include <arpa/inet.h>
-#include <gtest/gtest.h>
-
 #include <cc/command_interpreter.h>
 #include <config/http_command_config.h>
-#include <dhcp4/dhcp4_srv.h>
-#include <dhcp4/ctrl_dhcp4_srv.h>
-#include <dhcp4/json_config_parser.h>
-#include <dhcp/option4_addrlst.h>
+#include <dhcp/docsis3_option_defs.h>
+#include <dhcp/libdhcp++.h>
+#include <dhcp/iface_mgr.h>
 #include <dhcp/option_custom.h>
 #include <dhcp/option_int.h>
-#include <dhcp/docsis3_option_defs.h>
+#include <dhcp/option4_addrlst.h>
 #include <dhcp/classify.h>
 #include <dhcp/testutils/iface_mgr_test_config.h>
-#include <dhcpsrv/subnet.h>
+#include <dhcp4/json_config_parser.h>
+#include <dhcp4/dhcp4_srv.h>
+#include <dhcp4/ctrl_dhcp4_srv.h>
+#include <asiolink/addr_utilities.h>
 #include <dhcpsrv/cfgmgr.h>
 #include <dhcpsrv/cfg_expiration.h>
 #include <dhcpsrv/cfg_hosts.h>
 #include <dhcpsrv/cfg_subnets4.h>
 #include <dhcpsrv/parsers/simple_parser4.h>
+#include <dhcpsrv/subnet.h>
+#include <dhcpsrv/subnet_selector.h>
 #include <dhcpsrv/testutils/config_result_check.h>
 #include <dhcpsrv/testutils/test_config_backend_dhcp4.h>
-#include <process/config_ctl_info.h>
 #include <hooks/hooks_manager.h>
+#include <process/config_ctl_info.h>
 #include <stats/stats_mgr.h>
-#include <testutils/log_utils.h>
 #include <testutils/gtest_utils.h>
+#include <testutils/log_utils.h>
 #include <testutils/test_to_element.h>
 #include <util/chrono_time_utils.h>
 #include <util/doubles.h>
-
 #include "marker_file.h"
-#include "test_libraries.h"
 #include "test_data_files_config.h"
+#include "test_libraries.h"
 #include "dhcp4_test_utils.h"
 #include "get_config_unittest.h"
+#include <gtest/gtest.h>
 
+#include <boost/foreach.hpp>
 #include <boost/scoped_ptr.hpp>
-
-#include <iostream>
 #include <fstream>
+#include <iostream>
 #include <sstream>
+#include <string>
+#include <vector>
+
+#include <arpa/inet.h>
 #include <limits.h>
+#include <unistd.h>
 
 using namespace isc;
 using namespace isc::asiolink;
@@ -169,7 +175,33 @@ const char* PARSER_CONFIGS[] = {
     "    ]"
     "}",
 
-    // Configuration 5 for comments
+    // Configuration 5: config databases
+    "{ \n"
+    "    \"interfaces-config\": { \n"
+    "        \"interfaces\": [\"*\" ] \n"
+    "    }, \n"
+    "    \"valid-lifetime\": 4000, \n"
+    "    \"rebind-timer\": 2000, \n"
+    "    \"renew-timer\": 1000, \n"
+    "    \"config-control\": { \n"
+    "       \"config-fetch-wait-time\": 10, \n"
+    "       \"config-databases\": [ { \n"
+    "               \"type\": \"mysql\", \n"
+    "               \"name\": \"keatest1\", \n"
+    "               \"user\": \"keatest\", \n"
+    "               \"password\": \"keatest\" \n"
+    "           },{ \n"
+    "               \"type\": \"mysql\", \n"
+    "               \"name\": \"keatest2\", \n"
+    "               \"user\": \"keatest\", \n"
+    "               \"retry-on-startup\": true, \n"
+    "               \"password\": \"keatest\" \n"
+    "           } \n"
+    "       ] \n"
+    "   } \n"
+    "} \n",
+
+    // Configuration 6 for comments
     "{"
     "    \"comment\": \"A DHCPv4 server\","
     "    \"interfaces-config\": {"
@@ -260,33 +292,7 @@ const char* PARSER_CONFIGS[] = {
     "        \"comment\": \"No dynamic DNS\","
     "        \"enable-updates\": false"
     "    }"
-    "}",
-
-    // Configuration 6: config databases
-    "{ \n"
-    "    \"interfaces-config\": { \n"
-    "        \"interfaces\": [\"*\" ] \n"
-    "    }, \n"
-    "    \"valid-lifetime\": 4000, \n"
-    "    \"rebind-timer\": 2000, \n"
-    "    \"renew-timer\": 1000, \n"
-    "    \"config-control\": { \n"
-    "       \"config-fetch-wait-time\": 10, \n"
-    "       \"config-databases\": [ { \n"
-    "               \"type\": \"mysql\", \n"
-    "               \"name\": \"keatest1\", \n"
-    "               \"user\": \"keatest\", \n"
-    "               \"password\": \"keatest\" \n"
-    "           },{ \n"
-    "               \"type\": \"mysql\", \n"
-    "               \"name\": \"keatest2\", \n"
-    "               \"user\": \"keatest\", \n"
-    "               \"retry-on-startup\": true, \n"
-    "               \"password\": \"keatest\" \n"
-    "           } \n"
-    "       ] \n"
-    "   } \n"
-    "} \n"
+    "}"
 };
 
 class Dhcp4ParserTest : public LogContentTest {
@@ -301,17 +307,40 @@ protected:
     }
 
 public:
-    Dhcp4ParserTest()
-    : rcode_(-1) {
-        // Open port 0 means to not do anything at all. We don't want to
+    Dhcp4ParserTest() : rcode_(-1) {
+        // Open port 0 means to not open any sockets. We don't want to
         // deal with sockets here, just check if configuration handling
         // is sane.
         srv_.reset(new ControlledDhcpv4Srv(0));
-        // Create fresh context.
+
+        const IfaceCollection& ifaces = IfaceMgr::instance().getIfaces();
+
+        // There must be some interface detected
+        if (ifaces.empty()) {
+            // We can't use ASSERT in constructor
+            ADD_FAILURE() << "No interfaces detected.";
+        }
+
+        valid_iface_ = (*ifaces.begin())->getName();
+        bogus_iface_ = "nonexisting0";
+
+        if (IfaceMgr::instance().getIface(bogus_iface_)) {
+            ADD_FAILURE() << "The '" << bogus_iface_ << "' exists on this system"
+                          << " while the test assumes that it doesn't, to execute"
+                          << " some negative scenarios. Can't continue this test.";
+        }
+        // Reset configuration for each test.
         resetConfiguration();
     }
 
-public:
+    ~Dhcp4ParserTest() {
+        // Reset configuration database after each test.
+        resetConfiguration();
+
+        // ... and delete the hooks library marker files if present
+        static_cast<void>(remove(LOAD_MARKER_FILE));
+        static_cast<void>(remove(UNLOAD_MARKER_FILE));
+    };
 
     // Checks if the result of DHCP server configuration has
     // expected code (0 for success, other for failures).
@@ -328,7 +357,7 @@ public:
     void checkResult(ConstElementPtr status, int expected_code,
                      string expected_txt) {
         ASSERT_TRUE(status);
-        comment_ = parseAnswer(rcode_, status);
+        comment_ = parseAnswerText(rcode_, status);
         EXPECT_EQ(expected_code, rcode_) << "error text:" << comment_->stringValue();
         ASSERT_TRUE(comment_);
         ASSERT_EQ(Element::string, comment_->getType());
@@ -345,11 +374,7 @@ public:
     void configure(std::string config, int expected_code,
                    std::string exp_error = "") {
         ConstElementPtr json;
-        try {
-            json = parseDHCP4(config, true);
-        } catch(const std::exception& ex) {
-            ADD_FAILURE() << "parseDHCP4 failed: " << ex.what();
-        }
+        ASSERT_NO_THROW(json = parseDHCP4(config, true));
 
         ConstElementPtr status;
         EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json));
@@ -374,14 +399,6 @@ public:
         }
     }
 
-    ~Dhcp4ParserTest() {
-        resetConfiguration();
-
-        // ... and delete the hooks library marker files if present
-        static_cast<void>(remove(LOAD_MARKER_FILE));
-        static_cast<void>(remove(UNLOAD_MARKER_FILE));
-    };
-
     /// @brief Returns an interface configuration used by the most of the
     /// unit tests.
     std::string genIfaceConfig() const {
@@ -447,7 +464,8 @@ public:
     /// @params params map holding parameters and their values.
     /// @return configuration string containing custom values of parameters
     /// describing an option.
-    std::string createConfigWithOption(const std::map<std::string, std::string>& params) {
+    std::string createConfigWithOption(const std::map<std::string,
+                                       std::string>& params) {
         std::ostringstream stream;
         stream << "{ " << genIfaceConfig() << "," <<
             "\"rebind-timer\": 2000, "
@@ -470,7 +488,7 @@ public:
             } else if (param.first == "space") {
                 stream << "\"space\": \"" << param.second << "\"";
             } else if (param.first == "code") {
-                stream << "\"code\": " << param.second << "";
+                stream << "\"code\": " << param.second;
             } else if (param.first == "data") {
                 stream << "\"data\": \"" << param.second << "\"";
             } else if (param.first == "csv-format") {
@@ -506,10 +524,10 @@ public:
         Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
             getCfgSubnets4()->selectSubnet(subnet_address);
         if (!subnet) {
-            /// @todo replace toText() with the use of operator <<.
             ADD_FAILURE() << "A subnet for the specified address "
-                          << subnet_address.toText()
-                          << "does not exist in Config Manager";
+                          << subnet_address
+                          << " does not exist in Config Manager";
+            return (OptionDescriptor(false, false));
         }
         OptionContainerPtr options =
             subnet->getCfgOption()->getAll(DHCP4_OPTION_SPACE);
@@ -559,6 +577,7 @@ public:
         EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json));
         checkResult(x, 1);
         EXPECT_TRUE(errorContainsPosition(x, "<string>"));
+        CfgMgr::instance().clear();
     }
 
     /// @brief Test invalid option parameter value.
@@ -576,6 +595,7 @@ public:
         EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json));
         checkResult(x, 1);
         EXPECT_TRUE(errorContainsPosition(x, "<string>"));
+        CfgMgr::instance().clear();
     }
 
     /// @brief Test option against given code and data.
@@ -615,7 +635,8 @@ public:
         }
         // Verify that the data is correct. Do not verify suboptions and a header.
         const uint8_t* data = buf.getData();
-        EXPECT_EQ(0, memcmp(expected_data, data + option_desc.option_->getHeaderLen(),
+        EXPECT_EQ(0, memcmp(expected_data,
+                            data + option_desc.option_->getHeaderLen(),
                             expected_data_len));
     }
 
@@ -643,13 +664,17 @@ public:
                            const uint16_t option_code,
                            const uint8_t* expected_data,
                            const size_t expected_data_len) {
+        CfgMgr::instance().clear();
+
         std::string config = createConfigWithOption(params);
         ASSERT_TRUE(executeConfiguration(config, "parse option configuration"));
+
         // The subnet should now hold one option with the specified option code.
         OptionDescriptor desc =
             getOptionFromSubnet(IOAddress("192.0.2.24"), option_code);
         ASSERT_TRUE(desc.option_);
         testOption(desc, option_code, expected_data, expected_data_len);
+        CfgMgr::instance().clear();
     }
 
     /// @brief Parse and Execute configuration
@@ -707,14 +732,17 @@ public:
 
     /// @brief Reset configuration database.
     ///
-    /// This function resets configuration data base by
-    /// removing all subnets and option-data. Reset must
-    /// be performed after each test to make sure that
-    /// contents of the database do not affect result of
-    /// subsequent tests.
+    /// This function resets configuration data base by removing all subnets
+    /// option-data, and hooks libraries. The reset must be performed after each
+    /// test to make sure that contents of the database do not affect the
+    /// results of subsequent tests.
     void resetConfiguration() {
-        string config = "{ " + genIfaceConfig() + "," +
-            "\"hooks-libraries\": [ ], "
+        string config = "{ \"interfaces-config\": {"
+            "    \"interfaces\": [ ]"
+            "},"
+            "\"hooks-libraries\": [ ],"
+            "\"rebind-timer\": 2000, "
+            "\"renew-timer\": 1000, "
             "\"valid-lifetime\": 4000, "
             "\"subnet4\": [ ], "
             "\"dhcp-ddns\": { \"enable-updates\" : false }, "
@@ -723,6 +751,10 @@ public:
         CfgMgr::instance().rollback();
         static_cast<void>(executeConfiguration(config,
                                                "reset configuration database"));
+        // The default setting is to listen on all interfaces. In order to
+        // properly test interface configuration we disable listening on
+        // all interfaces before each test and later check that this setting
+        // has been overridden by the configuration used in the test.
         CfgMgr::instance().clear();
     }
 
@@ -852,9 +884,11 @@ public:
                                                << isc::data::prettyPrint(exp_value);
     }
 
-    boost::scoped_ptr<Dhcpv4Srv> srv_;  ///< DHCP4 server under test
     int rcode_;                         ///< Return code from element parsing
-    ConstElementPtr comment_;           ///< Reason for parse fail
+    boost::scoped_ptr<Dhcpv4Srv> srv_;  ///< Instance of the Dhcpv4Srv used during tests
+    ConstElementPtr comment_; ///< Comment (see @ref isc::config::parseAnswer)
+    string valid_iface_; ///< Valid network interface name (present in system)
+    string bogus_iface_; ///< invalid network interface name (not in system)
     isc::dhcp::ClientClasses classify_; ///< used in client classification
 };
 
@@ -878,7 +912,8 @@ TEST_F(Dhcp4ParserTest, bogusCommand) {
 TEST_F(Dhcp4ParserTest, emptyInterfaceConfig) {
 
     ConstElementPtr json;
-    EXPECT_NO_THROW(json = parseDHCP4("{ \"rebind-timer\": 2000, "
+    EXPECT_NO_THROW(json = parseDHCP4("{ "
+                                      "\"rebind-timer\": 2000, "
                                       "\"renew-timer\": 1000, "
                                       "\"valid-lifetime\": 4000 }"));
 
@@ -889,33 +924,12 @@ TEST_F(Dhcp4ParserTest, emptyInterfaceConfig) {
     checkResult(status, 0);
 }
 
-/// The goal of this test is to verify if configuration without any
-/// subnets defined can be accepted.
-TEST_F(Dhcp4ParserTest, emptySubnet) {
-
-    std::string config = "{ " + genIfaceConfig() + "," +
-        "\"rebind-timer\": 2000, "
-        "\"renew-timer\": 1000, "
-        "\"subnet4\": [  ], "
-        "\"valid-lifetime\": 4000 }";
-
-    ConstElementPtr json;
-    EXPECT_NO_THROW(json = parseDHCP4(config));
-    extractConfig(config);
-
-    ConstElementPtr status;
-    EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json));
-
-    // returned value should be 0 (success)
-    checkResult(status, 0);
-}
-
 /// Check that valid-lifetime must be between min-valid-lifetime and
 /// max-valid-lifetime when a bound is specified, *AND* a subnet is
 /// specified (boundary check is done when lifetimes are applied).
 TEST_F(Dhcp4ParserTest, outBoundValidLifetime) {
 
-    string too_small =  "{ " + genIfaceConfig() + "," +
+    string too_small =  "{ " + genIfaceConfig() + ","
         "\"subnet4\": [ { "
         "    \"id\": 1,"
         "    \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
@@ -933,7 +947,7 @@ TEST_F(Dhcp4ParserTest, outBoundValidLifetime) {
     checkResult(status, 1, expected);
     resetConfiguration();
 
-    string too_large =  "{ " + genIfaceConfig() + "," +
+    string too_large =  "{ " + genIfaceConfig() + ","
         "\"subnet4\": [ { "
         "    \"id\": 1,"
         "    \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
@@ -948,7 +962,7 @@ TEST_F(Dhcp4ParserTest, outBoundValidLifetime) {
     checkResult(status, 1, expected);
     resetConfiguration();
 
-    string before =  "{ " + genIfaceConfig() + "," +
+    string before =  "{ " + genIfaceConfig() + ","
         "\"subnet4\": [ { "
         "    \"id\": 1,"
         "    \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
@@ -964,7 +978,7 @@ TEST_F(Dhcp4ParserTest, outBoundValidLifetime) {
     checkResult(status, 1, expected);
     resetConfiguration();
 
-    string after =  "{ " + genIfaceConfig() + "," +
+    string after =  "{ " + genIfaceConfig() + ","
         "\"subnet4\": [ { "
         "    \"id\": 1,"
         "    \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
@@ -980,7 +994,7 @@ TEST_F(Dhcp4ParserTest, outBoundValidLifetime) {
     checkResult(status, 1, expected);
     resetConfiguration();
 
-    string crossed =  "{ " + genIfaceConfig() + "," +
+    string crossed =  "{ " + genIfaceConfig() + ","
         "\"subnet4\": [ { "
         "    \"id\": 1,"
         "    \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
@@ -1001,7 +1015,7 @@ TEST_F(Dhcp4ParserTest, outBoundValidLifetime) {
 /// parameters only.
 TEST_F(Dhcp4ParserTest, outBoundGlobalValidLifetime) {
 
-    string too_small =  "{ " + genIfaceConfig() + "," +
+    string too_small =  "{ " + genIfaceConfig() + ","
         "\"valid-lifetime\": 1000, \"min-valid-lifetime\": 2000 }";
 
     ConstElementPtr json;
@@ -1015,7 +1029,7 @@ TEST_F(Dhcp4ParserTest, outBoundGlobalValidLifetime) {
     checkResult(status, 1, expected);
     resetConfiguration();
 
-    string too_large =  "{ " + genIfaceConfig() + "," +
+    string too_large =  "{ " + genIfaceConfig() + ","
         "\"valid-lifetime\": 2000, \"max-valid-lifetime\": 1000 }";
 
     ASSERT_NO_THROW(json = parseDHCP4(too_large));
@@ -1026,7 +1040,7 @@ TEST_F(Dhcp4ParserTest, outBoundGlobalValidLifetime) {
     checkResult(status, 1, expected);
     resetConfiguration();
 
-    string before =  "{ " + genIfaceConfig() + "," +
+    string before =  "{ " + genIfaceConfig() + ","
         "\"valid-lifetime\": 1000, \"min-valid-lifetime\": 2000, "
         "\"max-valid-lifetime\": 4000 }";
 
@@ -1038,7 +1052,7 @@ TEST_F(Dhcp4ParserTest, outBoundGlobalValidLifetime) {
     checkResult(status, 1, expected);
     resetConfiguration();
 
-    string after =  "{ " + genIfaceConfig() + "," +
+    string after =  "{ " + genIfaceConfig() + ","
         "\"valid-lifetime\": 5000, \"min-valid-lifetime\": 1000, "
         "\"max-valid-lifetime\": 4000 }";
 
@@ -1050,7 +1064,7 @@ TEST_F(Dhcp4ParserTest, outBoundGlobalValidLifetime) {
     checkResult(status, 1, expected);
     resetConfiguration();
 
-    string crossed =  "{ " + genIfaceConfig() + "," +
+    string crossed =  "{ " + genIfaceConfig() + ","
         "\"valid-lifetime\": 1500, \"min-valid-lifetime\": 2000, "
         "\"max-valid-lifetime\": 1000 }";
 
@@ -1066,7 +1080,7 @@ TEST_F(Dhcp4ParserTest, outBoundGlobalValidLifetime) {
 /// it is marked unspecified in the Subnet.
 TEST_F(Dhcp4ParserTest, unspecifiedRenewTimer) {
 
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"subnet4\": [ { "
         "    \"id\": 1,"
@@ -1101,7 +1115,7 @@ TEST_F(Dhcp4ParserTest, unspecifiedRenewTimer) {
 /// it is marked unspecified in the Subnet.
 TEST_F(Dhcp4ParserTest, unspecifiedRebindTimer) {
 
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
         "    \"id\": 1,"
@@ -1131,11 +1145,32 @@ TEST_F(Dhcp4ParserTest, unspecifiedRebindTimer) {
     EXPECT_EQ(1, subnet->getID());
 }
 
+/// The goal of this test is to verify if configuration without any
+/// subnets defined can be accepted.
+TEST_F(Dhcp4ParserTest, emptySubnet) {
+
+    string config = "{ " + genIfaceConfig() + ","
+        "\"rebind-timer\": 2000, "
+        "\"renew-timer\": 1000, "
+        "\"subnet4\": [  ], "
+        "\"valid-lifetime\": 4000 }";
+
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP4(config));
+    extractConfig(config);
+
+    ConstElementPtr status;
+    EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json));
+
+    // returned value should be 0 (success)
+    checkResult(status, 0);
+}
+
 /// The goal of this test is to verify if defined subnet uses global
 /// parameter timer definitions.
 TEST_F(Dhcp4ParserTest, subnetGlobalDefaults) {
 
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -1175,36 +1210,37 @@ TEST_F(Dhcp4ParserTest, subnetGlobalDefaults) {
 TEST_F(Dhcp4ParserTest, multipleSubnetsExplicitIDs) {
     ConstElementPtr x;
     // Four subnets with arbitrary subnet ids.
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
         "    \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
         "    \"subnet\": \"192.0.2.0/24\", "
-        "    \"id\": 1024 "
+        "    \"id\": 1024"
         " },"
         " {"
         "    \"pools\": [ { \"pool\": \"192.0.3.101 - 192.0.3.150\" } ],"
         "    \"subnet\": \"192.0.3.0/24\", "
-        "    \"id\": 100 "
+        "    \"id\": 100"
         " },"
         " {"
         "    \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],"
         "    \"subnet\": \"192.0.4.0/24\", "
-        "    \"id\": 1 "
+        "    \"id\": 1"
         " },"
         " {"
         "    \"pools\": [ { \"pool\": \"192.0.5.101 - 192.0.5.150\" } ],"
         "    \"subnet\": \"192.0.5.0/24\", "
-        "    \"id\": 34 "
+        "    \"id\": 34"
         " } ],"
         "\"valid-lifetime\": 4000 }";
 
+    int cnt = 0; // Number of reconfigurations
+
     ConstElementPtr json;
     ASSERT_NO_THROW(json = parseDHCP4(config));
     extractConfig(config);
 
-    int cnt = 0; // Number of reconfigurations
     do {
         EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json));
         checkResult(x, 0);
@@ -1229,32 +1265,32 @@ TEST_F(Dhcp4ParserTest, multipleSubnetsExplicitIDs) {
     } while (++cnt < 3);
 }
 
-// Check that the configuration with two subnets having the same id is rejected.
+// Check that the configuration with two subnets having the same ID is rejected.
 TEST_F(Dhcp4ParserTest, multipleSubnetsOverlappingIDs) {
     ConstElementPtr x;
-    // Four subnets, two of them having the same id.
-    string config = "{ " + genIfaceConfig() + "," +
+    // Four subnets, two of them have the same id.
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
         "    \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
         "    \"subnet\": \"192.0.2.0/24\", "
-        "    \"id\": 1024 "
+        "    \"id\": 1024"
         " },"
         " {"
         "    \"pools\": [ { \"pool\": \"192.0.3.101 - 192.0.3.150\" } ],"
         "    \"subnet\": \"192.0.3.0/24\", "
-        "    \"id\": 100 "
+        "    \"id\": 100"
         " },"
         " {"
         "    \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],"
         "    \"subnet\": \"192.0.4.0/24\", "
-        "    \"id\": 1024 "
+        "    \"id\": 1024"
         " },"
         " {"
         "    \"pools\": [ { \"pool\": \"192.0.5.101 - 192.0.5.150\" } ],"
         "    \"subnet\": \"192.0.5.0/24\", "
-        "    \"id\": 34 "
+        "    \"id\": 34"
         " } ],"
         "\"valid-lifetime\": 4000 }";
 
@@ -1272,70 +1308,70 @@ TEST_F(Dhcp4ParserTest, reconfigureRemoveSubnet) {
     ConstElementPtr x;
 
     // All four subnets
-    string config4 = "{ " + genIfaceConfig() + "," +
+    string config4 = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
         "    \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
         "    \"subnet\": \"192.0.2.0/24\", "
-        "    \"id\": 1 "
+        "    \"id\": 1"
         " },"
         " {"
         "    \"pools\": [ { \"pool\": \"192.0.3.101 - 192.0.3.150\" } ],"
         "    \"subnet\": \"192.0.3.0/24\", "
-        "    \"id\": 2 "
+        "    \"id\": 2"
         " },"
         " {"
         "    \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],"
         "    \"subnet\": \"192.0.4.0/24\", "
-        "    \"id\": 3 "
+        "    \"id\": 3"
         " },"
         " {"
         "    \"pools\": [ { \"pool\": \"192.0.5.101 - 192.0.5.150\" } ],"
         "    \"subnet\": \"192.0.5.0/24\", "
-        "    \"id\": 4 "
+        "    \"id\": 4"
         " } ],"
         "\"valid-lifetime\": 4000 }";
 
     // Three subnets (the last one removed)
-    string config_first3 = "{ " + genIfaceConfig() + "," +
+    string config_first3 = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
         "    \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
         "    \"subnet\": \"192.0.2.0/24\", "
-        "    \"id\": 1 "
+        "    \"id\": 1"
         " },"
         " {"
         "    \"pools\": [ { \"pool\":  \"192.0.3.101 - 192.0.3.150\" } ],"
         "    \"subnet\": \"192.0.3.0/24\", "
-        "    \"id\": 2 "
+        "    \"id\": 2"
         " },"
         " {"
         "    \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],"
         "    \"subnet\": \"192.0.4.0/24\", "
-        "    \"id\": 3 "
+        "    \"id\": 3"
         " } ],"
         "\"valid-lifetime\": 4000 }";
 
     // Second subnet removed
-    string config_second_removed = "{ " + genIfaceConfig() + "," +
+    string config_second_removed = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
         "    \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
         "    \"subnet\": \"192.0.2.0/24\", "
-        "    \"id\": 1 "
+        "    \"id\": 1"
         " },"
         " {"
         "    \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],"
         "    \"subnet\": \"192.0.4.0/24\", "
-        "    \"id\": 3 "
+        "    \"id\": 3"
         " },"
         " {"
         "    \"pools\": [ { \"pool\": \"192.0.5.101 - 192.0.5.150\" } ],"
         "    \"subnet\": \"192.0.5.0/24\", "
-        "    \"id\": 4 "
+        "    \"id\": 4"
         " } ],"
         "\"valid-lifetime\": 4000 }";
 
@@ -1344,11 +1380,14 @@ TEST_F(Dhcp4ParserTest, reconfigureRemoveSubnet) {
 
     ConstElementPtr json;
     ASSERT_NO_THROW(json = parseDHCP4(config4));
+    extractConfig(config4);
     EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json));
     checkResult(x, 0);
 
+    CfgMgr::instance().commit();
+
     const Subnet4Collection* subnets =
-        CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->getAll();
+        CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getAll();
     ASSERT_TRUE(subnets);
     ASSERT_EQ(4, subnets->size()); // We expect 4 subnets
 
@@ -1359,7 +1398,9 @@ TEST_F(Dhcp4ParserTest, reconfigureRemoveSubnet) {
     EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json));
     checkResult(x, 0);
 
-    subnets = CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->getAll();
+    CfgMgr::instance().commit();
+
+    subnets = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getAll();
     ASSERT_TRUE(subnets);
     ASSERT_EQ(3, subnets->size()); // We expect 3 subnets now (4th is removed)
 
@@ -1377,22 +1418,24 @@ TEST_F(Dhcp4ParserTest, reconfigureRemoveSubnet) {
     EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json));
     checkResult(x, 0);
 
-    CfgMgr::instance().clear();
+    CfgMgr::instance().commit();
 
     // Do reconfiguration
     ASSERT_NO_THROW(json = parseDHCP4(config_second_removed));
     EXPECT_NO_THROW(x = Dhcpv4SrvTest::configure(*srv_, json));
     checkResult(x, 0);
 
-    subnets = CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->getAll();
+    CfgMgr::instance().commit();
+
+    subnets = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getAll();
     ASSERT_TRUE(subnets);
     ASSERT_EQ(3, subnets->size()); // We expect 4 subnets
 
-    auto subnet_it = subnets->begin();
-    EXPECT_EQ(1, (*subnet_it)->getID());
+    subnet = subnets->begin();
+    EXPECT_EQ(1, (*subnet)->getID());
     // The second subnet (with subnet-id = 2) is no longer there
-    EXPECT_EQ(3, (*++subnet_it)->getID());
-    EXPECT_EQ(4, (*++subnet_it)->getID());
+    EXPECT_EQ(3, (*++subnet)->getID());
+    EXPECT_EQ(4, (*++subnet)->getID());
 }
 
 /// @todo: implement subnet removal test as part of #3281.
@@ -1401,7 +1444,7 @@ TEST_F(Dhcp4ParserTest, reconfigureRemoveSubnet) {
 // global parameter are taken into consideration.
 TEST_F(Dhcp4ParserTest, nextServerGlobal) {
 
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"next-server\": \"1.2.3.4\", "
@@ -1441,7 +1484,7 @@ TEST_F(Dhcp4ParserTest, nextServerGlobal) {
 // subnet parameter are taken into consideration.
 TEST_F(Dhcp4ParserTest, nextServerSubnet) {
 
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -1479,7 +1522,7 @@ TEST_F(Dhcp4ParserTest, nextServerNegative) {
     IfaceMgrTestConfig test_config(true);
 
     // Config with junk instead of next-server address
-    string config_bogus1 = "{ " + genIfaceConfig() + "," +
+    string config_bogus1 = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -1492,7 +1535,7 @@ TEST_F(Dhcp4ParserTest, nextServerNegative) {
         "\"valid-lifetime\": 4000 }";
 
     // Config with IPv6 next server address
-    string config_bogus2 = "{ " + genIfaceConfig() + "," +
+    string config_bogus2 = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -1505,7 +1548,7 @@ TEST_F(Dhcp4ParserTest, nextServerNegative) {
         "\"valid-lifetime\": 4000 }";
 
     // Config with empty next server address
-    string config_bogus3 = "{ " + genIfaceConfig() + "," +
+    string config_bogus3 = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -1519,7 +1562,7 @@ TEST_F(Dhcp4ParserTest, nextServerNegative) {
 
     // Config with too large server-hostname
     string bigsname(Pkt4::MAX_SNAME_LEN + 1, ' ');
-    string config_bogus4 = "{ " + genIfaceConfig() + "," +
+    string config_bogus4 = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -1533,7 +1576,7 @@ TEST_F(Dhcp4ParserTest, nextServerNegative) {
 
     // Config with too large boot-file-hostname
     string bigfilename(Pkt4::MAX_FILE_LEN + 1, ' ');
-    string config_bogus5 = "{ " + genIfaceConfig() + "," +
+    string config_bogus5 = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -1591,7 +1634,7 @@ TEST_F(Dhcp4ParserTest, nextServerNegative) {
 // specific value.
 TEST_F(Dhcp4ParserTest, nextServerOverride) {
 
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"next-server\": \"192.0.0.1\", "
@@ -1629,7 +1672,7 @@ TEST_F(Dhcp4ParserTest, nextServerOverride) {
 // Check whether it is possible to configure echo-client-id
 TEST_F(Dhcp4ParserTest, echoClientId) {
 
-    string config_false = "{ " + genIfaceConfig() + "," +
+    string config_false = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"echo-client-id\": false,"
@@ -1639,7 +1682,7 @@ TEST_F(Dhcp4ParserTest, echoClientId) {
         "    \"subnet\": \"192.0.2.0/24\" } ],"
         "\"valid-lifetime\": 4000 }";
 
-    string config_true = "{ " + genIfaceConfig() + "," +
+    string config_true = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"echo-client-id\": true,"
@@ -1678,7 +1721,7 @@ TEST_F(Dhcp4ParserTest, echoClientId) {
 
 // Check whether it is possible to configure compatibility flags.
 TEST_F(Dhcp4ParserTest, compatibility) {
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"compatibility\": { "
@@ -1716,7 +1759,7 @@ TEST_F(Dhcp4ParserTest, compatibility) {
 
 // Check that unknown compatibility flag raises error.
 TEST_F(Dhcp4ParserTest, compatibilityUnknown) {
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"compatibility\": { "
@@ -1743,7 +1786,7 @@ TEST_F(Dhcp4ParserTest, compatibilityUnknown) {
 
 // Check that not boolean compatibility flag value raises error.
 TEST_F(Dhcp4ParserTest, compatibilityNotBool) {
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"compatibility\": { "
@@ -1771,7 +1814,7 @@ TEST_F(Dhcp4ParserTest, compatibilityNotBool) {
 // This test checks that the global match-client-id parameter is optional
 // and that values under the subnet are used.
 TEST_F(Dhcp4ParserTest, matchClientIdNoGlobal) {
-    std::string config = "{ " + genIfaceConfig() + "," +
+    std::string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ "
@@ -1819,7 +1862,7 @@ TEST_F(Dhcp4ParserTest, matchClientIdNoGlobal) {
 // when there is no such parameter under subnet and that the parameter
 // specified for a subnet overrides the global setting.
 TEST_F(Dhcp4ParserTest, matchClientIdGlobal) {
-    std::string config = "{ " + genIfaceConfig() + "," +
+    std::string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"match-client-id\": true,"
@@ -1866,7 +1909,7 @@ TEST_F(Dhcp4ParserTest, matchClientIdGlobal) {
 // This test checks that the global authoritative parameter is optional
 // and that values under the subnet are used.
 TEST_F(Dhcp4ParserTest, authoritativeNoGlobal) {
-    std::string config = "{ " + genIfaceConfig() + "," +
+    std::string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ "
@@ -1914,7 +1957,7 @@ TEST_F(Dhcp4ParserTest, authoritativeNoGlobal) {
 // when there is no such parameter under subnet and that the parameter
 // specified for a subnet overrides the global setting.
 TEST_F(Dhcp4ParserTest, authoritativeGlobal) {
-    std::string config = "{ " + genIfaceConfig() + "," +
+    std::string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"authoritative\": true,"
@@ -1962,7 +2005,7 @@ TEST_F(Dhcp4ParserTest, authoritativeGlobal) {
 // on a per subnet basis.
 TEST_F(Dhcp4ParserTest, subnetLocal) {
 
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -1998,81 +2041,57 @@ TEST_F(Dhcp4ParserTest, subnetLocal) {
     EXPECT_EQ(5, subnet->getValid().getMax());
 }
 
-// This test checks that multiple pools can be defined and handled properly.
-// The test defines 2 subnets, each with 2 pools.
-TEST_F(Dhcp4ParserTest, multiplePools) {
+// This test checks if it is possible to define a subnet with an
+// interface defined.
+TEST_F(Dhcp4ParserTest, subnetInterface) {
+
+    // There should be at least one interface
+    // As far as I can tell, this is the first lambda in Kea code. Cool.
+    auto config = [this](string iface) {
+        return ("{ " + genIfaceConfig() + ","
+                "\"rebind-timer\": 2000, "
+                "\"renew-timer\": 1000, "
+                "\"subnet4\": [ { "
+                "    \"id\": 1,"
+                "    \"pools\": [ { "
+                "        \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
+                "    \"interface\": \"" + iface + "\","
+                "    \"subnet\": \"192.0.2.0/24\" } ],"
+                "\"valid-lifetime\": 4000 }"); };
+    cout << config(valid_iface_) << endl;
 
-    // Collection with two subnets, each with 2 pools.
-    string config = "{ " + genIfaceConfig() + "," +
-        "\"rebind-timer\": 2000, "
-        "\"renew-timer\": 1000, "
-        "\"subnet4\": [ { "
-        "    \"id\": 1,"
-        "    \"pools\": [ "
-        "        { \"pool\": \"192.0.2.0/28\" },"
-        "        { \"pool\": \"192.0.2.200-192.0.2.255\" }"
-        "    ],"
-        "    \"subnet\": \"192.0.2.0/24\" "
-        " },"
-        " {"
-        "    \"id\": 2,"
-        "    \"pools\": [ "
-        "    { \"pool\": \"192.0.3.0/25\" },"
-        "    { \"pool\": \"192.0.3.128/25\" }"
-        "    ],"
-        "    \"subnet\": \"192.0.3.0/24\""
-        " } ],"
-        "\"valid-lifetime\": 4000 }";
     ConstElementPtr json;
-    ASSERT_NO_THROW(json = parseDHCP4(config));
-    extractConfig(config);
+    ASSERT_NO_THROW(json = parseDHCP4(config(valid_iface_)));
+    extractConfig(config("eth0"));
 
     ConstElementPtr status;
-    ASSERT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json));
-    checkResult(status, 0);
-
-    const Subnet4Collection* subnets =
-        CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->getAll();
-    ASSERT_TRUE(subnets);
-    ASSERT_EQ(2, subnets->size()); // We expect 2 subnets
+    EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json));
 
-    // Check the first subnet
-    auto subnet = subnets->begin();
-    const PoolCollection& pools1 = (*subnet)->getPools(Lease::TYPE_V4);
-    ASSERT_EQ(2, pools1.size());
-    EXPECT_EQ("type=V4, 192.0.2.0-192.0.2.15",
-              pools1[0]->toText());
-    EXPECT_EQ("type=V4, 192.0.2.200-192.0.2.255",
-              pools1[1]->toText());
-    // There shouldn't be any TA or PD pools
-    EXPECT_THROW((*subnet)->getPools(Lease::TYPE_TA), BadValue);
-    EXPECT_THROW((*subnet)->getPools(Lease::TYPE_PD), BadValue);
+    // returned value should be 0 (configuration success)
+    checkResult(status, 0);
 
-    // Check the second subnet
-    ++subnet;
-    const PoolCollection& pools2 = (*subnet)->getPools(Lease::TYPE_V4);
-    ASSERT_EQ(2, pools2.size());
-    EXPECT_EQ("type=V4, 192.0.3.0-192.0.3.127",
-              pools2[0]->toText());
-    EXPECT_EQ("type=V4, 192.0.3.128-192.0.3.255",
-              pools2[1]->toText());
-    // There shouldn't be any TA or PD pools
-    EXPECT_THROW((*subnet)->getPools(Lease::TYPE_TA), BadValue);
-    EXPECT_THROW((*subnet)->getPools(Lease::TYPE_PD), BadValue);
+    Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->
+        selectSubnet(IOAddress("192.0.2.200"), classify_);
+    ASSERT_TRUE(subnet);
+    EXPECT_EQ(valid_iface_, subnet->getIface().get());
 }
 
-// Test verifies that a subnet with pool values that do not belong to that
-// pool are rejected.
-TEST_F(Dhcp4ParserTest, poolOutOfSubnet) {
+// This test checks if invalid interface name will be rejected in
+// Subnet4 definition.
+TEST_F(Dhcp4ParserTest, subnetInterfaceBogus) {
 
-    string config = "{ " + genIfaceConfig() + "," +
+    // There should be at least one interface
+
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
         "    \"id\": 1,"
-        "    \"pools\": [ { \"pool\": \"192.0.4.0/28\" } ],"
+        "    \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
+        "    \"interface\": \"" + bogus_iface_ + "\","
         "    \"subnet\": \"192.0.2.0/24\" } ],"
         "\"valid-lifetime\": 4000 }";
+    cout << config << endl;
 
     ConstElementPtr json;
     ASSERT_NO_THROW(json = parseDHCP4(config));
@@ -2080,27 +2099,212 @@ TEST_F(Dhcp4ParserTest, poolOutOfSubnet) {
     ConstElementPtr status;
     EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json));
 
-    // returned value must be 1 (values error)
-    // as the pool does not belong to that subnet
+    // returned value should be 1 (configuration error)
     checkResult(status, 1);
     EXPECT_TRUE(errorContainsPosition(status, "<string>"));
+
+    Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->
+        selectSubnet(IOAddress("192.0.2.200"), classify_);
+    EXPECT_FALSE(subnet);
 }
 
-// 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.
-TEST_F(Dhcp4ParserTest, poolPrefixLen) {
+// This test checks if it is not allowed to define global interface
+// parameter.
+TEST_F(Dhcp4ParserTest, interfaceGlobal) {
 
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
+        "\"interface\": \"" + valid_iface_ + "\"," // Not valid. Can be defined in subnet only
         "\"subnet4\": [ { "
         "    \"id\": 1,"
-        "    \"pools\": [ { \"pool\": \"192.0.2.128/28\" } ],"
+        "    \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
         "    \"subnet\": \"192.0.2.0/24\" } ],"
         "\"valid-lifetime\": 4000 }";
+    cout << config << endl;
 
-    ConstElementPtr json;
+    ConstElementPtr json = parseJSON(config);
+
+    ConstElementPtr status;
+    EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json));
+
+    // returned value should be 1 (parse error)
+    checkResult(status, 1);
+    EXPECT_TRUE(errorContainsPosition(status, "<string>"));
+
+    EXPECT_THROW(parseDHCP4(config), Dhcp4ParseError);
+}
+
+// Goal of this test is to verify that invalid subnet fails to be parsed.
+TEST_F(Dhcp4ParserTest, badSubnetValues) {
+
+    // Contains parts needed for a single test scenario.
+    struct Scenario {
+        std::string description_;
+        std::string config_json_;
+        std::string exp_error_msg_;
+    };
+
+    // Vector of scenarios.
+    std::vector<Scenario> scenarios = {
+        {
+        "IP is not an address",
+        "{ \"subnet4\": [ { "
+        "    \"subnet\": \"not an address/24\" } ],"
+        "\"valid-lifetime\": 4000 }",
+        "subnet configuration failed: "
+        "Failed to convert string to address 'notanaddress': Invalid argument"
+        },
+        {
+        "IP is Invalid",
+        "{ \"subnet4\": [ { "
+        "    \"subnet\": \"256.16.1.0/24\" } ],"
+        "\"valid-lifetime\": 4000 }",
+        "subnet configuration failed: "
+        "Failed to convert string to address '256.16.1.0': Invalid argument"
+        },
+        {
+        "Missing prefix",
+        "{ \"subnet4\": [ { "
+        "    \"subnet\": \"192.0.2.0\" } ],"
+        "\"valid-lifetime\": 4000 }",
+        "subnet configuration failed: "
+        "Invalid subnet syntax (prefix/len expected):192.0.2.0 (<string>:1:32)"
+        },
+        {
+        "Prefix not an integer (2 slashes)",
+        "{ \"subnet4\": [ { "
+        "    \"subnet\": \"192.0.2.0//24\" } ],"
+        "\"valid-lifetime\": 4000 }",
+        "subnet configuration failed: "
+        "prefix length: '/24' is not an integer (<string>:1:32)"
+        },
+        {
+        "Prefix value is insane",
+        "{ \"subnet4\": [ { "
+        "    \"subnet\": \"192.0.2.0/45938\" } ],"
+        "\"valid-lifetime\": 4000 }",
+        "subnet configuration failed: "
+        "Invalid prefix length specified for subnet: 45938 (<string>:1:32)"
+        }
+    };
+
+    // Iterate over the list of scenarios.  Each should fail to parse with
+    // a specific error message.
+    for (auto const& scenario : scenarios) {
+        SCOPED_TRACE(scenario.description_);
+        ConstElementPtr config;
+        ASSERT_NO_THROW(config = parseDHCP4(scenario.config_json_))
+                        << "invalid json, broken test";
+        ConstElementPtr status;
+        EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, config));
+        checkResult(status, 1);
+        ASSERT_TRUE(comment_);
+        EXPECT_EQ(comment_->stringValue(), scenario.exp_error_msg_);
+    }
+}
+
+// This test checks that multiple pools can be defined and handled properly.
+// The test defines 2 subnets, each with 2 pools.
+TEST_F(Dhcp4ParserTest, multiplePools) {
+    // Collection with two subnets, each with 2 pools.
+    string config = "{ " + genIfaceConfig() + ","
+        "\"rebind-timer\": 2000, "
+        "\"renew-timer\": 1000, "
+        "\"subnet4\": [ { "
+        "    \"id\": 1,"
+        "    \"pools\": [ "
+        "        { \"pool\": \"192.0.2.0/28\" },"
+        "        { \"pool\": \"192.0.2.200-192.0.2.255\" }"
+        "    ],"
+        "    \"subnet\": \"192.0.2.0/24\" "
+        " },"
+        " {"
+        "    \"id\": 2,"
+        "    \"pools\": [ "
+        "    { \"pool\": \"192.0.3.0/25\" },"
+        "    { \"pool\": \"192.0.3.128/25\" }"
+        "    ],"
+        "    \"subnet\": \"192.0.3.0/24\""
+        " } ],"
+        "\"valid-lifetime\": 4000 }";
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP4(config));
+    extractConfig(config);
+
+    ConstElementPtr status;
+    ASSERT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json));
+    checkResult(status, 0);
+
+    const Subnet4Collection* subnets =
+        CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->getAll();
+    ASSERT_TRUE(subnets);
+    ASSERT_EQ(2, subnets->size()); // We expect 2 subnets
+
+    // Check the first subnet
+    auto subnet = subnets->begin();
+    const PoolCollection& pools1 = (*subnet)->getPools(Lease::TYPE_V4);
+    ASSERT_EQ(2, pools1.size());
+    EXPECT_EQ("type=V4, 192.0.2.0-192.0.2.15",
+              pools1[0]->toText());
+    EXPECT_EQ("type=V4, 192.0.2.200-192.0.2.255",
+              pools1[1]->toText());
+    // There shouldn't be any TA or PD pools
+    EXPECT_THROW((*subnet)->getPools(Lease::TYPE_TA), BadValue);
+    EXPECT_THROW((*subnet)->getPools(Lease::TYPE_PD), BadValue);
+
+    // Check the second subnet
+    ++subnet;
+    const PoolCollection& pools2 = (*subnet)->getPools(Lease::TYPE_V4);
+    ASSERT_EQ(2, pools2.size());
+    EXPECT_EQ("type=V4, 192.0.3.0-192.0.3.127",
+              pools2[0]->toText());
+    EXPECT_EQ("type=V4, 192.0.3.128-192.0.3.255",
+              pools2[1]->toText());
+    // There shouldn't be any TA or PD pools
+    EXPECT_THROW((*subnet)->getPools(Lease::TYPE_TA), BadValue);
+    EXPECT_THROW((*subnet)->getPools(Lease::TYPE_PD), BadValue);
+}
+
+// Test verifies that a subnet with pool values that do not belong to that
+// pool are rejected.
+TEST_F(Dhcp4ParserTest, poolOutOfSubnet) {
+
+    string config = "{ " + genIfaceConfig() + ","
+        "\"rebind-timer\": 2000, "
+        "\"renew-timer\": 1000, "
+        "\"subnet4\": [ { "
+        "    \"id\": 1,"
+        "    \"pools\": [ { \"pool\": \"192.0.4.0/28\" } ],"
+        "    \"subnet\": \"192.0.2.0/24\" } ],"
+        "\"valid-lifetime\": 4000 }";
+
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP4(config));
+
+    ConstElementPtr status;
+    EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json));
+
+    // returned value must be 1 (values error)
+    // as the pool does not belong to that subnet
+    checkResult(status, 1);
+    EXPECT_TRUE(errorContainsPosition(status, "<string>"));
+}
+
+// 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.
+TEST_F(Dhcp4ParserTest, poolPrefixLen) {
+    string config = "{ " + genIfaceConfig() + ","
+        "\"rebind-timer\": 2000, "
+        "\"renew-timer\": 1000, "
+        "\"subnet4\": [ { "
+        "    \"id\": 1,"
+        "    \"pools\": [ { \"pool\": \"192.0.2.128/28\" } ],"
+        "    \"subnet\": \"192.0.2.0/24\" } ],"
+        "\"valid-lifetime\": 4000 }";
+
+    ConstElementPtr json;
     ASSERT_NO_THROW(json = parseDHCP4(config));
     extractConfig(config);
 
@@ -2123,7 +2327,7 @@ TEST_F(Dhcp4ParserTest, poolPrefixLen) {
 TEST_F(Dhcp4ParserTest, badPools) {
 
     // not a prefix
-    string config_bogus1 = "{ " + genIfaceConfig() + "," +
+    string config_bogus1 = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -2133,7 +2337,7 @@ TEST_F(Dhcp4ParserTest, badPools) {
         "\"valid-lifetime\": 4000 }";
 
     // not a length
-    string config_bogus2 = "{ " + genIfaceConfig() + "," +
+    string config_bogus2 = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -2143,7 +2347,7 @@ TEST_F(Dhcp4ParserTest, badPools) {
         "\"valid-lifetime\": 4000 }";
 
     // invalid prefix length
-    string config_bogus3 = "{ " + genIfaceConfig() + "," +
+    string config_bogus3 = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -2153,7 +2357,7 @@ TEST_F(Dhcp4ParserTest, badPools) {
         "\"valid-lifetime\": 4000 }";
 
     // not a prefix nor a min-max
-    string config_bogus4 = "{ " + genIfaceConfig() + "," +
+    string config_bogus4 = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -2163,7 +2367,7 @@ TEST_F(Dhcp4ParserTest, badPools) {
         "\"valid-lifetime\": 4000 }";
 
     // not an address
-    string config_bogus5 = "{ " + genIfaceConfig() + "," +
+    string config_bogus5 = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -2173,7 +2377,7 @@ TEST_F(Dhcp4ParserTest, badPools) {
         "\"valid-lifetime\": 4000 }";
 
     // min > max
-    string config_bogus6 = "{ " + genIfaceConfig() + "," +
+    string config_bogus6 = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -2183,7 +2387,7 @@ TEST_F(Dhcp4ParserTest, badPools) {
         "\"valid-lifetime\": 4000 }";
 
     // out of range prefix length (new check)
-    string config_bogus7 = "{ " + genIfaceConfig() + "," +
+    string config_bogus7 = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -2256,7 +2460,7 @@ TEST_F(Dhcp4ParserTest, badPools) {
 TEST_F(Dhcp4ParserTest, noPools) {
 
     // Configuration string.
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -2268,81 +2472,13 @@ TEST_F(Dhcp4ParserTest, noPools) {
     EXPECT_THROW(parseDHCP4(config, true), Dhcp4ParseError);
 }
 
-// Goal of this test is to verify that invalid subnet fails to be parsed.
-TEST_F(Dhcp4ParserTest, badSubnetValues) {
-
-    // Contains parts needed for a single test scenario.
-    struct Scenario {
-        std::string description_;
-        std::string config_json_;
-        std::string exp_error_msg_;
-    };
-
-    // Vector of scenarios.
-    std::vector<Scenario> scenarios = {
-        {
-        "IP is not an address",
-        "{ \"subnet4\": [ { "
-        "    \"subnet\": \"not an address/24\" } ],"
-        "\"valid-lifetime\": 4000 }",
-        "subnet configuration failed: "
-        "Failed to convert string to address 'notanaddress': Invalid argument"
-        },
-        {
-        "IP is Invalid",
-        "{ \"subnet4\": [ { "
-        "    \"subnet\": \"256.16.1.0/24\" } ],"
-        "\"valid-lifetime\": 4000 }",
-        "subnet configuration failed: "
-        "Failed to convert string to address '256.16.1.0': Invalid argument"
-        },
-        {
-        "Missing prefix",
-        "{ \"subnet4\": [ { "
-        "    \"subnet\": \"192.0.2.0\" } ],"
-        "\"valid-lifetime\": 4000 }",
-        "subnet configuration failed: "
-        "Invalid subnet syntax (prefix/len expected):192.0.2.0 (<string>:1:32)"
-        },
-        {
-        "Prefix not an integer (2 slashes)",
-        "{ \"subnet4\": [ { "
-        "    \"subnet\": \"192.0.2.0//24\" } ],"
-        "\"valid-lifetime\": 4000 }",
-        "subnet configuration failed: "
-        "prefix length: '/24' is not an integer (<string>:1:32)"
-        },
-        {
-        "Prefix value is insane",
-        "{ \"subnet4\": [ { "
-        "    \"subnet\": \"192.0.2.0/45938\" } ],"
-        "\"valid-lifetime\": 4000 }",
-        "subnet configuration failed: "
-        "Invalid prefix length specified for subnet: 45938 (<string>:1:32)"
-        }
-    };
-
-    // Iterate over the list of scenarios.  Each should fail to parse with
-    // a specific error message.
-    for (auto const& scenario : scenarios) {
-        SCOPED_TRACE(scenario.description_);
-        ConstElementPtr config;
-        ASSERT_NO_THROW(config = parseDHCP4(scenario.config_json_))
-                        << "invalid json, broken test";
-        ConstElementPtr status;
-        EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, config));
-        checkResult(status, 1);
-        ASSERT_TRUE(comment_);
-        EXPECT_EQ(comment_->stringValue(), scenario.exp_error_msg_);
-    }
-}
 
 // Goal of this test is to verify that unknown interface fails
 // to be parsed.
 TEST_F(Dhcp4ParserTest, unknownInterface) {
 
     // Configuration string.
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -2869,8 +3005,9 @@ TEST_F(Dhcp4ParserTest, optionDefEncapsulateOwnSpace) {
 /// used by any of the standard options.
 TEST_F(Dhcp4ParserTest, optionStandardDefOverride) {
 
-    // Configuration string. The option code 109 is unassigned so it
-    // can be used for a custom option definition in dhcp4 option space.
+    // Configuration string. The option code 109 is unassigned
+    // so it can be used for a custom option definition in
+    // dhcp4 option space.
     std::string config =
         "{ \"option-def\": [ {"
         "      \"name\": \"foo\","
@@ -2904,9 +3041,9 @@ TEST_F(Dhcp4ParserTest, optionStandardDefOverride) {
     EXPECT_EQ(OPT_STRING_TYPE, def->getType());
     EXPECT_FALSE(def->getArrayType());
 
-    // The combination of option space and code is invalid. The 'dhcp4' option
-    // space groups standard options and the code 3 is reserved for one of
-    // them.
+    // The combination of option space and code is invalid. The 'dhcp4'
+    // option space groups standard options and the code 3 is reserved
+    // for one of them.
     config =
         "{ \"option-def\": [ {"
         "      \"name\": \"routers\","
@@ -2956,7 +3093,7 @@ TEST_F(Dhcp4ParserTest, optionStandardDefOverride) {
 // Goal of this test is to verify that global option data is configured
 TEST_F(Dhcp4ParserTest, optionDataDefaultsGlobal) {
     ConstElementPtr x;
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000,"
         "\"renew-timer\": 1000,"
         "\"option-data\": [ {"
@@ -3028,7 +3165,7 @@ TEST_F(Dhcp4ParserTest, optionDataDefaultsGlobal) {
 // Goal of this test is to verify that subnet option data is configured
 TEST_F(Dhcp4ParserTest, optionDataDefaultsSubnet) {
     ConstElementPtr x;
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000,"
         "\"renew-timer\": 1000,"
         "\"subnet4\": [ { "
@@ -3104,7 +3241,7 @@ TEST_F(Dhcp4ParserTest, optionDataTwoSpaces) {
     // The definition is not required for the option that
     // belongs to the 'dhcp4' option space as it is the
     // standard option.
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"valid-lifetime\": 4000,"
         "\"rebind-timer\": 2000,"
         "\"renew-timer\": 1000,"
@@ -3153,8 +3290,8 @@ TEST_F(Dhcp4ParserTest, optionDataTwoSpaces) {
     EXPECT_EQ(56, desc1.option_->getType());
     // Try to get the non-existing option from the non-existing
     // option space and  expect that option is not returned.
-    OptionDescriptor desc3 =
-        CfgMgr::instance().getStagingCfg()->getCfgOption()->get("non-existing", 56);
+    OptionDescriptor desc3 = CfgMgr::instance().getStagingCfg()->
+        getCfgOption()->get("non-existing", 56);
     ASSERT_FALSE(desc3.option_);
 }
 
@@ -3167,8 +3304,8 @@ TEST_F(Dhcp4ParserTest, optionDataTwoSpaces) {
 TEST_F(Dhcp4ParserTest, optionDataEncapsulate) {
 
     // @todo DHCP configurations has many dependencies between
-    // parameters. First of all, configuration for subnet was
-    // inherited from the global values. Thus subnet had to be
+    // parameters. First of all, configuration for subnet is
+    // inherited from the global values. Thus subnet has to be
     // configured when all global values have been configured.
     // Also, an option can encapsulate another option only
     // if the latter has been configured. For this reason in this
@@ -3179,7 +3316,7 @@ TEST_F(Dhcp4ParserTest, optionDataEncapsulate) {
     // at the very end (when all other parameters are configured).
 
     // Starting stage 1. Configure sub-options and their definitions.
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"valid-lifetime\": 4000,"
         "\"rebind-timer\": 2000,"
         "\"renew-timer\": 1000,"
@@ -3222,7 +3359,7 @@ TEST_F(Dhcp4ParserTest, optionDataEncapsulate) {
     // the configuration from the stage 2 is repeated because Kea
     // configuration manager sends whole configuration for the lists
     // where at least one element is being modified or added.
-    config = "{ " + genIfaceConfig() + "," +
+    config = "{ " + genIfaceConfig() + ","
         "\"valid-lifetime\": 3000,"
         "\"rebind-timer\": 2000,"
         "\"renew-timer\": 1000,"
@@ -3303,7 +3440,7 @@ TEST_F(Dhcp4ParserTest, optionDataEncapsulate) {
 // option setting.
 TEST_F(Dhcp4ParserTest, optionDataInSingleSubnet) {
     ConstElementPtr x;
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"option-data\": [ {"
@@ -3384,8 +3521,7 @@ TEST_F(Dhcp4ParserTest, optionDataBoolean) {
                                      " boolean value"));
 
     // The subnet should now hold one option with the code 19.
-    OptionDescriptor desc = getOptionFromSubnet(IOAddress("192.0.2.24"),
-                                                        19);
+    OptionDescriptor desc = getOptionFromSubnet(IOAddress("192.0.2.24"), 19);
     ASSERT_TRUE(desc.option_);
 
     // This option should be set to "true", represented as 0x1 in the option
@@ -3447,14 +3583,13 @@ TEST_F(Dhcp4ParserTest, optionDataBoolean) {
     params["data"] = "01";
     testConfiguration(params, 19, expected_option_data,
                       sizeof(expected_option_data));
-
 }
 
 // Goal of this test is to verify options configuration
 // for multiple subnets.
 TEST_F(Dhcp4ParserTest, optionDataInMultipleSubnets) {
     ConstElementPtr x;
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -3593,6 +3728,7 @@ TEST_F(Dhcp4ParserTest, optionDataSinglePool) {
     range = idx.equal_range(23);
     ASSERT_EQ(1, std::distance(range.first, range.second));
     // Do another round of testing with second option.
+
     const uint8_t foo2_expected[] = {
         0x01
     };
@@ -3713,6 +3849,13 @@ TEST_F(Dhcp4ParserTest, optionCodeNonUint8) {
     testInvalidOptionParam("257", "code");
 }
 
+// Verify that out of bounds option code is rejected in the configuration.
+TEST_F(Dhcp4ParserTest, optionCodeHighNonUint8) {
+    // Another check for uint16_t overflow but this time
+    // let's pass even greater option code value.
+    testInvalidOptionParam("500", "code");
+}
+
 // Verify that zero option code is rejected in the configuration.
 TEST_F(Dhcp4ParserTest, optionCodeZero) {
     // Option code 0 is reserved and should not be accepted
@@ -3763,7 +3906,9 @@ TEST_F(Dhcp4ParserTest, optionDataValidHexLiterals) {
         // 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> range = idx.equal_range(56);
+                OptionContainerTypeIndex::const_iterator> range =
+                    idx.equal_range(56);
+
         // Expect single option with the code equal to 100.
         ASSERT_EQ(1, std::distance(range.first, range.second));
         const uint8_t foo_expected[] = { 0x0A, 0x0B, 0x0C, 0x0D };
@@ -3799,8 +3944,7 @@ TEST_F(Dhcp4ParserTest, stdOptionData) {
     Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
         getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.5"));
     ASSERT_TRUE(subnet);
-    OptionContainerPtr options =
-        subnet->getCfgOption()->getAll(DHCP4_OPTION_SPACE);
+    OptionContainerPtr options = subnet->getCfgOption()->getAll(DHCP4_OPTION_SPACE);
     ASSERT_TRUE(options);
     ASSERT_EQ(1, options->size());
 
@@ -3901,7 +4045,7 @@ TEST_F(Dhcp4ParserTest, domainSearchOption) {
 // slp-service-scope without option scope list
 TEST_F(Dhcp4ParserTest, slpOptions) {
     ConstElementPtr x;
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000,"
         "\"renew-timer\": 1000,"
         "\"option-data\": [ {"
@@ -3965,7 +4109,7 @@ TEST_F(Dhcp4ParserTest, stdOptionDataEncapsulate) {
     // In the first stage we create definitions of suboptions
     // that we will add to the base option.
     // Let's create some dummy options: foo and foo2.
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"valid-lifetime\": 4000,"
         "\"rebind-timer\": 2000,"
         "\"renew-timer\": 1000,"
@@ -4012,7 +4156,7 @@ TEST_F(Dhcp4ParserTest, stdOptionDataEncapsulate) {
     // We add our dummy options to this option space and thus
     // they should be included as sub-options in the
     // 'vendor-encapsulated-options' option.
-    config = "{ " + genIfaceConfig() + "," +
+    config = "{ " + genIfaceConfig() + ","
         "\"valid-lifetime\": 3000,"
         "\"rebind-timer\": 2000,"
         "\"renew-timer\": 1000,"
@@ -4100,13 +4244,13 @@ TEST_F(Dhcp4ParserTest, stdOptionDataEncapsulate) {
 }
 
 // This test checks if vendor options can be specified in the config file
-// (in hex format), and later retrieved
+// (in hex format), and later retrieved from configured subnet
 TEST_F(Dhcp4ParserTest, vendorOptionsHex) {
 
     // This configuration string is to configure two options
     // sharing the code 1 and belonging to the different vendor spaces.
     // (different vendor-id values).
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"valid-lifetime\": 4000,"
         "\"rebind-timer\": 2000,"
         "\"renew-timer\": 1000,"
@@ -4140,6 +4284,7 @@ TEST_F(Dhcp4ParserTest, vendorOptionsHex) {
     ASSERT_TRUE(status);
     checkResult(status, 0);
 
+    // Options should be now available
     // Try to get the option from the vendor space 4491
     OptionDescriptor desc1 = CfgMgr::instance().getStagingCfg()->
         getCfgOption()->get(VENDOR_ID_CABLE_LABS, 100);
@@ -4159,13 +4304,13 @@ TEST_F(Dhcp4ParserTest, vendorOptionsHex) {
 }
 
 // This test checks if vendor options can be specified in the config file,
-// (in csv format), and later retrieved
+// (in csv format), and later retrieved from configured subnet
 TEST_F(Dhcp4ParserTest, vendorOptionsCsv) {
 
     // This configuration string is to configure two options
     // sharing the code 1 and belonging to the different vendor spaces.
     // (different vendor-id values).
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"valid-lifetime\": 4000,"
         "\"rebind-timer\": 2000,"
         "\"renew-timer\": 1000,"
@@ -4188,15 +4333,17 @@ TEST_F(Dhcp4ParserTest, vendorOptionsCsv) {
         " } ]"
         "}";
 
+    ConstElementPtr status;
+
     ConstElementPtr json;
     ASSERT_NO_THROW(json = parseDHCP4(config));
     extractConfig(config);
 
-    ConstElementPtr status;
     EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json));
     ASSERT_TRUE(status);
     checkResult(status, 0);
 
+    // Options should be now available.
     // Try to get the option from the vendor space 4491
     OptionDescriptor desc1 = CfgMgr::instance().getStagingCfg()->
         getCfgOption()->get(VENDOR_ID_CABLE_LABS, 100);
@@ -4219,20 +4366,22 @@ TEST_F(Dhcp4ParserTest, vendorOptionsCsv) {
 std::string
 buildHooksLibrariesConfig(const std::vector<std::string>& libraries = {},
                           bool multi_threading = true) {
+    const string lbrace("{");
+    const string rbrace("}");
+    const string liblabel("\"library\": ");
+    const string quote("\"");
 
     // Create the first part of the configuration string.
     string config =
-        "{  \"interfaces-config\": {"
-            "    \"interfaces\": [ \"*\" ]"
-            "},"
-            "\"hooks-libraries\": [";
+        "{ \"interfaces-config\": { \"interfaces\": [] },"
+           "\"hooks-libraries\": [";
 
     // Append the libraries (separated by commas if needed)
     for (unsigned int i = 0; i < libraries.size(); ++i) {
         if (i > 0) {
             config += string(", ");
         }
-        config += (string("{ \"library\": \"") + libraries[i] + string("\" }"));
+        config += (lbrace + liblabel + quote + libraries[i] + quote + rbrace);
     }
 
     // Append the remainder of the configuration.
@@ -4297,6 +4446,7 @@ TEST_F(Dhcp4ParserTest, InvalidLibrary) {
 
     ConstElementPtr json;
     ASSERT_NO_THROW(json = parseDHCP4(config));
+
     ConstElementPtr status;
     ASSERT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json));
 
@@ -4417,7 +4567,11 @@ TEST_F(Dhcp4ParserTest, IncompatibleLibrary3Specified) {
 TEST_F(Dhcp4ParserTest, selectedInterfaces) {
     IfaceMgrTestConfig test_config(true);
 
-    ConstElementPtr x;
+    // Make sure the config manager is clean and there is no hanging
+    // interface configuration.
+    ASSERT_FALSE(test_config.socketOpen("eth0", AF_INET));
+    ASSERT_FALSE(test_config.socketOpen("eth1", AF_INET));
+
     string config = "{ \"interfaces-config\": {"
         "  \"interfaces\": [ \"eth0\", \"eth1\" ]"
         "},"
@@ -4430,15 +4584,10 @@ TEST_F(Dhcp4ParserTest, selectedInterfaces) {
     extractConfig(config);
 
     ConstElementPtr status;
-
-    // Make sure the config manager is clean and there is no hanging
-    // interface configuration.
-    EXPECT_FALSE(test_config.socketOpen("eth0", AF_INET));
-    EXPECT_FALSE(test_config.socketOpen("eth1", AF_INET));
-
     // Apply configuration.
     EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json));
     ASSERT_TRUE(status);
+    // returned value must be 0 (configuration accepted)
     checkResult(status, 0);
 
     CfgMgr::instance().getStagingCfg()->getCfgIface()->openSockets(AF_INET, 10000);
@@ -4453,7 +4602,10 @@ TEST_F(Dhcp4ParserTest, selectedInterfaces) {
 TEST_F(Dhcp4ParserTest, allInterfaces) {
     IfaceMgrTestConfig test_config(true);
 
-    ConstElementPtr x;
+    // Make sure there is no old configuration.
+    ASSERT_FALSE(test_config.socketOpen("eth0", AF_INET));
+    ASSERT_FALSE(test_config.socketOpen("eth1", AF_INET));
+
     // This configuration specifies two interfaces on which server should listen
     // but it also includes asterisk. The asterisk switches server into the
     // mode when it listens on all interfaces regardless of what interface names
@@ -4471,10 +4623,6 @@ TEST_F(Dhcp4ParserTest, allInterfaces) {
 
     ConstElementPtr status;
 
-    // Make sure there is no old configuration.
-    ASSERT_FALSE(test_config.socketOpen("eth0", AF_INET));
-    ASSERT_FALSE(test_config.socketOpen("eth1", AF_INET));
-
     // Apply configuration.
     EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json));
     ASSERT_TRUE(status);
@@ -4527,129 +4675,11 @@ TEST_F(Dhcp4ParserTest, selectedInterfacesAndAddresses) {
     EXPECT_FALSE(test_config.socketOpen("eth1", "192.0.2.5"));
 }
 
-// This test verifies that valid d2CliengConfig works correctly.
-TEST_F(Dhcp4ParserTest, d2ClientConfigValid) {
-    ConstElementPtr status;
-
-    // Verify that the D2 configuration can be fetched and is set to disabled.
-    D2ClientConfigPtr d2_client_config = CfgMgr::instance().getD2ClientConfig();
-    EXPECT_FALSE(d2_client_config->getEnableUpdates());
-
-    // Verify that the convenience method agrees.
-    ASSERT_FALSE(CfgMgr::instance().ddnsEnabled());
-
-    string config_str = "{ " + genIfaceConfig() + "," +
-        "\"rebind-timer\": 2000, "
-        "\"renew-timer\": 1000, "
-        "\"subnet4\": [ { "
-        "    \"id\": 1,"
-        "    \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
-        "    \"subnet\": \"192.0.2.0/24\" } ],"
-        " \"dhcp-ddns\" : {"
-        "     \"enable-updates\" : true, "
-        "     \"server-ip\" : \"192.168.2.1\", "
-        "     \"server-port\" : 777, "
-        "     \"sender-ip\" : \"192.168.2.2\", "
-        "     \"sender-port\" : 778, "
-        "     \"max-queue-size\" : 2048, "
-        "     \"ncr-protocol\" : \"UDP\", "
-        "     \"ncr-format\" : \"JSON\"}, "
-        "\"valid-lifetime\": 4000 }";
-
-    // Convert the JSON string to configuration elements.
-    ConstElementPtr config;
-    ASSERT_NO_THROW(config = parseDHCP4(config_str, true));
-    extractConfig(config_str);
-
-    // Pass the configuration in for parsing.
-    EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, config));
-
-    // check if returned status is OK
-    checkResult(status, 0);
-
-    // Verify that DHCP-DDNS updating is enabled.
-    EXPECT_TRUE(CfgMgr::instance().ddnsEnabled());
-
-    // Verify that the D2 configuration can be retrieved.
-    d2_client_config = CfgMgr::instance().getD2ClientConfig();
-    ASSERT_TRUE(d2_client_config);
-
-    // Verify that the configuration values are correct.
-    EXPECT_TRUE(d2_client_config->getEnableUpdates());
-    EXPECT_EQ("192.168.2.1", d2_client_config->getServerIp().toText());
-    EXPECT_EQ(777, d2_client_config->getServerPort());
-    EXPECT_EQ("192.168.2.2", d2_client_config->getSenderIp().toText());
-    EXPECT_EQ(778, d2_client_config->getSenderPort());
-    EXPECT_EQ(2048, d2_client_config->getMaxQueueSize());
-    EXPECT_EQ(dhcp_ddns::NCR_UDP, d2_client_config->getNcrProtocol());
-    EXPECT_EQ(dhcp_ddns::FMT_JSON, d2_client_config->getNcrFormat());
-
-    // ddns-send-updates should be global default
-    checkGlobal("ddns-send-updates", true);
-    checkGlobal("ddns-conflict-resolution-mode", "check-with-dhcid");
-
-    // The following, deprecated dhcp-ddns parameters,
-    // should all have global default values.
-    checkGlobal("ddns-override-no-update", false);
-    checkGlobal("ddns-override-client-update", false);
-    checkGlobal("ddns-replace-client-name", "never");
-    checkGlobal("ddns-generated-prefix", "myhost");
-    checkGlobal("ddns-qualifying-suffix", "");
-}
-
-// This test checks the ability of the server to handle a configuration
-// containing an invalid dhcp-ddns (D2ClientConfig) entry.
-TEST_F(Dhcp4ParserTest, invalidD2ClientConfig) {
-    ConstElementPtr status;
-
-    // Configuration string with an invalid D2 client config,
-    // "server-ip" is invalid.
-    string config_str = "{ " + genIfaceConfig() + "," +
-        "\"rebind-timer\": 2000, "
-        "\"renew-timer\": 1000, "
-        "\"ddns-override-no-update\" : true, "
-        "\"ddns-override-client-update\" : true, "
-        "\"ddns-replace-client-name\" : \"when-present\", "
-        "\"ddns-generated-prefix\" : \"test.prefix\", "
-        "\"ddns-qualifying-suffix\" : \"test.suffix.\", "
-        "\"subnet4\": [ { "
-        "    \"id\": 1,"
-        "    \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
-        "    \"subnet\": \"192.0.2.0/24\" } ],"
-        " \"dhcp-ddns\" : {"
-        "     \"enable-updates\" : true, "
-        "     \"server-ip\" : \"bogus-value\", "
-        "     \"server-port\" : 5301, "
-        "     \"ncr-protocol\" : \"UDP\", "
-        "     \"ncr-format\" : \"JSON\"},"
-        "\"valid-lifetime\": 4000 }";
-
-    // Convert the JSON string to configuration elements.
-    ConstElementPtr config;
-    ASSERT_NO_THROW(config = parseDHCP4(config_str));
-
-    // Configuration should not throw, but should fail.
-    EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, config));
-
-    // check if returned status is failed.
-    checkResult(status, 1);
-    EXPECT_TRUE(errorContainsPosition(status, "<string>"));
-
-    // Verify that the D2 configuration can be fetched and is set to disabled.
-    D2ClientConfigPtr d2_client_config = CfgMgr::instance().getD2ClientConfig();
-    EXPECT_FALSE(d2_client_config->getEnableUpdates());
-
-    // Verify that the convenience method agrees.
-    ASSERT_FALSE(CfgMgr::instance().ddnsEnabled());
-}
-
 // This test checks if it is possible to specify relay information
 TEST_F(Dhcp4ParserTest, subnetRelayInfo) {
 
-    ConstElementPtr status;
-
     // A config with relay information.
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -4668,6 +4698,7 @@ TEST_F(Dhcp4ParserTest, subnetRelayInfo) {
     ASSERT_NO_THROW(json = parseDHCP4(config));
     extractConfig(config);
 
+    ConstElementPtr status;
     EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json));
 
     // returned value should be 0 (configuration success)
@@ -4683,11 +4714,8 @@ TEST_F(Dhcp4ParserTest, subnetRelayInfo) {
 
 // This test checks if it is possible to specify a list of relays
 TEST_F(Dhcp4ParserTest, subnetRelayInfoList) {
-
-    ConstElementPtr status;
-
     // A config with relay information.
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -4706,6 +4734,7 @@ TEST_F(Dhcp4ParserTest, subnetRelayInfoList) {
     ASSERT_NO_THROW(json = parseDHCP4(config));
     extractConfig(config);
 
+    ConstElementPtr status;
     EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json));
 
     // returned value should be 0 (configuration success)
@@ -4727,7 +4756,7 @@ TEST_F(Dhcp4ParserTest, subnetRelayInfoList) {
 // with defined client classes.
 TEST_F(Dhcp4ParserTest, classifySubnets) {
     ConstElementPtr x;
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -4823,7 +4852,7 @@ TEST_F(Dhcp4ParserTest, classifySubnets) {
 // with defined client classes.
 TEST_F(Dhcp4ParserTest, classifyPools) {
     ConstElementPtr x;
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -4861,59 +4890,172 @@ TEST_F(Dhcp4ParserTest, classifyPools) {
     const PoolCollection& pools = (*subnets->begin())->getPools(Lease::TYPE_V4);
     ASSERT_EQ(4, pools.size()); // We expect 4 pools
 
-    // Let's check if client belonging to alpha class is supported in pool[0]
-    // and not supported in any other pool (except pool[3], which allows
-    // everyone).
-    ClientClasses classes;
-    classes.insert("alpha");
-    EXPECT_TRUE(pools.at(0)->clientSupported(classes));
-    EXPECT_FALSE(pools.at(1)->clientSupported(classes));
-    EXPECT_FALSE(pools.at(2)->clientSupported(classes));
-    EXPECT_TRUE(pools.at(3)->clientSupported(classes));
+    // Let's check if client belonging to alpha class is supported in pool[0]
+    // and not supported in any other pool (except pool[3], which allows
+    // everyone).
+    ClientClasses classes;
+    classes.insert("alpha");
+    EXPECT_TRUE(pools.at(0)->clientSupported(classes));
+    EXPECT_FALSE(pools.at(1)->clientSupported(classes));
+    EXPECT_FALSE(pools.at(2)->clientSupported(classes));
+    EXPECT_TRUE(pools.at(3)->clientSupported(classes));
+
+    // Let's check if client belonging to beta class is supported in pool[1]
+    // and not supported in any other pool  (except pool[3], which allows
+    // everyone).
+    classes.clear();
+    classes.insert("beta");
+    EXPECT_FALSE(pools.at(0)->clientSupported(classes));
+    EXPECT_TRUE(pools.at(1)->clientSupported(classes));
+    EXPECT_FALSE(pools.at(2)->clientSupported(classes));
+    EXPECT_TRUE(pools.at(3)->clientSupported(classes));
+
+    // Let's check if client belonging to gamma class is supported in pool[2]
+    // and not supported in any other pool  (except pool[3], which allows
+    // everyone).
+    classes.clear();
+    classes.insert("gamma");
+    EXPECT_FALSE(pools.at(0)->clientSupported(classes));
+    EXPECT_FALSE(pools.at(1)->clientSupported(classes));
+    EXPECT_TRUE(pools.at(2)->clientSupported(classes));
+    EXPECT_TRUE(pools.at(3)->clientSupported(classes));
+
+    // Let's check if client belonging to some other class (not mentioned in
+    // the config) is supported only in pool[3], which allows everyone.
+    classes.clear();
+    classes.insert("delta");
+    EXPECT_FALSE(pools.at(0)->clientSupported(classes));
+    EXPECT_FALSE(pools.at(1)->clientSupported(classes));
+    EXPECT_FALSE(pools.at(2)->clientSupported(classes));
+    EXPECT_TRUE(pools.at(3)->clientSupported(classes));
+
+    // Finally, let's check class-less client. He should be allowed only in
+    // the last pool, which does not have any class restrictions.
+    classes.clear();
+    EXPECT_FALSE(pools.at(0)->clientSupported(classes));
+    EXPECT_FALSE(pools.at(1)->clientSupported(classes));
+    EXPECT_FALSE(pools.at(2)->clientSupported(classes));
+    EXPECT_TRUE(pools.at(3)->clientSupported(classes));
+}
+
+// This test verifies that valid d2CliengConfig works correctly.
+TEST_F(Dhcp4ParserTest, d2ClientConfigValid) {
+    // Verify that the D2 configuration can be fetched and is set to disabled.
+    D2ClientConfigPtr d2_client_config = CfgMgr::instance().getD2ClientConfig();
+    EXPECT_FALSE(d2_client_config->getEnableUpdates());
+
+    // Verify that the convenience method agrees.
+    ASSERT_FALSE(CfgMgr::instance().ddnsEnabled());
+
+    string config_str = "{ " + genIfaceConfig() + ","
+        "\"rebind-timer\": 2000, "
+        "\"renew-timer\": 1000, "
+        "\"subnet4\": [ { "
+        "    \"id\": 1,"
+        "    \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
+        "    \"subnet\": \"192.0.2.0/24\" } ],"
+        " \"dhcp-ddns\" : {"
+        "     \"enable-updates\" : true, "
+        "     \"server-ip\" : \"192.168.2.1\", "
+        "     \"server-port\" : 777, "
+        "     \"sender-ip\" : \"192.168.2.2\", "
+        "     \"sender-port\" : 778, "
+        "     \"max-queue-size\" : 2048, "
+        "     \"ncr-protocol\" : \"UDP\", "
+        "     \"ncr-format\" : \"JSON\"}, "
+        "\"valid-lifetime\": 4000 }";
+
+    // Convert the JSON string to configuration elements.
+    ConstElementPtr config;
+    ASSERT_NO_THROW(config = parseDHCP4(config_str, true));
+    extractConfig(config_str);
+
+    // Pass the configuration in for parsing.
+    ConstElementPtr status;
+    EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, config));
+
+    // check if returned status is OK
+    checkResult(status, 0);
+
+    // Verify that DHCP-DDNS updating is enabled.
+    EXPECT_TRUE(CfgMgr::instance().ddnsEnabled());
+
+    // Verify that the D2 configuration can be retrieved.
+    d2_client_config = CfgMgr::instance().getD2ClientConfig();
+    ASSERT_TRUE(d2_client_config);
+
+    // Verify that the configuration values are correct.
+    EXPECT_TRUE(d2_client_config->getEnableUpdates());
+    EXPECT_EQ("192.168.2.1", d2_client_config->getServerIp().toText());
+    EXPECT_EQ(777, d2_client_config->getServerPort());
+    EXPECT_EQ("192.168.2.2", d2_client_config->getSenderIp().toText());
+    EXPECT_EQ(778, d2_client_config->getSenderPort());
+    EXPECT_EQ(2048, d2_client_config->getMaxQueueSize());
+    EXPECT_EQ(dhcp_ddns::NCR_UDP, d2_client_config->getNcrProtocol());
+    EXPECT_EQ(dhcp_ddns::FMT_JSON, d2_client_config->getNcrFormat());
+
+    // ddns-send-updates should be global default
+    checkGlobal("ddns-send-updates", true);
+    checkGlobal("ddns-conflict-resolution-mode", "check-with-dhcid");
+
+    // The following, deprecated dhcp-ddns parameters,
+    // should all have global default values.
+    checkGlobal("ddns-override-no-update", false);
+    checkGlobal("ddns-override-client-update", false);
+    checkGlobal("ddns-replace-client-name", "never");
+    checkGlobal("ddns-generated-prefix", "myhost");
+    checkGlobal("ddns-qualifying-suffix", "");
+}
+
+// This test checks the ability of the server to handle a configuration
+// containing an invalid dhcp-ddns (D2ClientConfig) entry.
+TEST_F(Dhcp4ParserTest, invalidD2ClientConfig) {
+    // Configuration string with an invalid D2 client config,
+    // "server-ip" is invalid.
+    string config_str = "{ " + genIfaceConfig() + ","
+        "\"rebind-timer\": 2000, "
+        "\"renew-timer\": 1000, "
+        "\"ddns-override-no-update\" : true, "
+        "\"ddns-override-client-update\" : true, "
+        "\"ddns-replace-client-name\" : \"when-present\", "
+        "\"ddns-generated-prefix\" : \"test.prefix\", "
+        "\"ddns-qualifying-suffix\" : \"test.suffix.\", "
+        "\"subnet4\": [ { "
+        "    \"id\": 1,"
+        "    \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
+        "    \"subnet\": \"192.0.2.0/24\" } ],"
+        " \"dhcp-ddns\" : {"
+        "     \"enable-updates\" : true, "
+        "     \"server-ip\" : \"bogus-value\", "
+        "     \"server-port\" : 5301, "
+        "     \"ncr-protocol\" : \"UDP\", "
+        "     \"ncr-format\" : \"JSON\"},"
+        "\"valid-lifetime\": 4000 }";
+
+    // Convert the JSON string to configuration elements.
+    ConstElementPtr config;
+    ASSERT_NO_THROW(config = parseDHCP4(config_str));
 
-    // Let's check if client belonging to beta class is supported in pool[1]
-    // and not supported in any other pool  (except pools[3], which allows
-    // everyone).
-    classes.clear();
-    classes.insert("beta");
-    EXPECT_FALSE(pools.at(0)->clientSupported(classes));
-    EXPECT_TRUE(pools.at(1)->clientSupported(classes));
-    EXPECT_FALSE(pools.at(2)->clientSupported(classes));
-    EXPECT_TRUE(pools.at(3)->clientSupported(classes));
+    // Configuration should not throw, but should fail.
+    ConstElementPtr status;
+    EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, config));
 
-    // Let's check if client belonging to gamma class is supported in pool[2]
-    // and not supported in any other pool  (except pool[3], which allows
-    // everyone).
-    classes.clear();
-    classes.insert("gamma");
-    EXPECT_FALSE(pools.at(0)->clientSupported(classes));
-    EXPECT_FALSE(pools.at(1)->clientSupported(classes));
-    EXPECT_TRUE(pools.at(2)->clientSupported(classes));
-    EXPECT_TRUE(pools.at(3)->clientSupported(classes));
+    // check if returned status is failed.
+    checkResult(status, 1);
+    EXPECT_TRUE(errorContainsPosition(status, "<string>"));
 
-    // Let's check if client belonging to some other class (not mentioned in
-    // the config) is supported only in pool[3], which allows everyone.
-    classes.clear();
-    classes.insert("delta");
-    EXPECT_FALSE(pools.at(0)->clientSupported(classes));
-    EXPECT_FALSE(pools.at(1)->clientSupported(classes));
-    EXPECT_FALSE(pools.at(2)->clientSupported(classes));
-    EXPECT_TRUE(pools.at(3)->clientSupported(classes));
+    // Verify that the D2 configuration can be fetched and is set to disabled.
+    D2ClientConfigPtr d2_client_config = CfgMgr::instance().getD2ClientConfig();
+    EXPECT_FALSE(d2_client_config->getEnableUpdates());
 
-    // Finally, let's check class-less client. He should be allowed only in
-    // the last pool, which does not have any class restrictions.
-    classes.clear();
-    EXPECT_FALSE(pools.at(0)->clientSupported(classes));
-    EXPECT_FALSE(pools.at(1)->clientSupported(classes));
-    EXPECT_FALSE(pools.at(2)->clientSupported(classes));
-    EXPECT_TRUE(pools.at(3)->clientSupported(classes));
+    // Verify that the convenience method agrees.
+    ASSERT_FALSE(CfgMgr::instance().ddnsEnabled());
 }
-
 // This test verifies that the host reservations can be specified for
 // respective IPv4 subnets.
 TEST_F(Dhcp4ParserTest, reservations) {
     ConstElementPtr x;
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ "
@@ -4992,7 +5134,8 @@ TEST_F(Dhcp4ParserTest, reservations) {
         "        \"hostname\": \"\""
         "      }"
         "    ]"
-        " } ],"
+        " } "
+        "], "
         "\"valid-lifetime\": 4000 }";
 
     ConstElementPtr json;
@@ -5072,6 +5215,7 @@ TEST_F(Dhcp4ParserTest, reservations) {
                            circuit_id.size());
     EXPECT_TRUE(host);
     EXPECT_EQ("192.0.4.102", host->getIPv4Reservation().toText());
+
     // This reservation must not belong to other subnets.
     EXPECT_FALSE(hosts_cfg->get4(123, Host::IDENT_CIRCUIT_ID,
                                  &circuit_id[0], circuit_id.size()));
@@ -5083,6 +5227,7 @@ TEST_F(Dhcp4ParserTest, reservations) {
     host = hosts_cfg->get4(542, Host::IDENT_DUID, &duid_r[0], duid_r.size());
     ASSERT_TRUE(host);
     EXPECT_EQ("192.0.4.101", host->getIPv4Reservation().toText());
+
     EXPECT_FALSE(hosts_cfg->get4(123, Host::IDENT_DUID,
                                  &duid_r[0], duid_r.size()));
     EXPECT_FALSE(hosts_cfg->get4(234, Host::IDENT_DUID,
@@ -5117,7 +5262,7 @@ TEST_F(Dhcp4ParserTest, reservationWithOptionDefinition) {
     // The following configuration contains host declaration in which
     // a non-standard option is used. This option has option definition
     // specified in the configuration.
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"option-def\": [ {"
@@ -5144,9 +5289,9 @@ TEST_F(Dhcp4ParserTest, reservationWithOptionDefinition) {
         "    \"pools\": [ { \"pool\": \"192.0.3.101 - 192.0.3.150\" } ],"
         "    \"subnet\": \"192.0.3.0/24\", "
         "    \"id\": 234"
-        " } ],"
-        "\"valid-lifetime\": 4000"
-        "}";
+        " }"
+        "],"
+        "\"valid-lifetime\": 4000 }";
 
     ConstElementPtr json;
     ASSERT_NO_THROW(json = parseDHCP4(config, true));
@@ -5166,8 +5311,8 @@ TEST_F(Dhcp4ParserTest, reservationWithOptionDefinition) {
         duid.push_back(static_cast<uint8_t>(i));
     }
     // Retrieve the reservation and sanity check the address reserved.
-    ConstHostPtr host =
-        hosts_cfg->get4(234, Host::IDENT_DUID, &duid[0], duid.size());
+    ConstHostPtr host = hosts_cfg->get4(234, Host::IDENT_DUID,
+                                        &duid[0], duid.size());
     ASSERT_TRUE(host);
     EXPECT_EQ("192.0.3.112", host->getIPv4Reservation().toText());
 
@@ -5184,7 +5329,7 @@ TEST_F(Dhcp4ParserTest, reservationWithOptionDefinition) {
 TEST_F(Dhcp4ParserTest, reservationBogus) {
     // Case 1: misspelled hw-address parameter.
     ConstElementPtr x;
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ "
@@ -5199,7 +5344,8 @@ TEST_F(Dhcp4ParserTest, reservationBogus) {
         "        \"hostname\": \"\""
         "      }"
         "    ]"
-        " } ],"
+        " } "
+        "], "
         "\"valid-lifetime\": 4000 }";
 
     ConstElementPtr json;
@@ -5213,7 +5359,7 @@ TEST_F(Dhcp4ParserTest, reservationBogus) {
     EXPECT_THROW(parseDHCP4(config), Dhcp4ParseError);
 
     // Case 2: DUID and HW Address both specified.
-    config = "{ " + genIfaceConfig() + "," +
+    config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ "
@@ -5241,7 +5387,7 @@ TEST_F(Dhcp4ParserTest, reservationBogus) {
     checkResult(x, 1);
 
     // Case 3: Broken specification of option data.
-    config = "{ " + genIfaceConfig() + "," +
+    config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ "
@@ -5260,7 +5406,8 @@ TEST_F(Dhcp4ParserTest, reservationBogus) {
         "        ]"
         "      }"
         "    ]"
-        " } ],"
+        " } "
+        "], "
         "\"valid-lifetime\": 4000 }";
 
     ASSERT_NO_THROW(json = parseDHCP4(config));
@@ -5287,7 +5434,7 @@ TEST_F(Dhcp4ParserTest, hostReservationPerSubnet) {
     ///       - 192.0.6.0/24 (global + all enabled)
     ///       - 192.0.7.0/24 (global + out-of-pool enabled)
     const char* hr_config =
-        "{ "
+        "{"
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -5346,14 +5493,16 @@ TEST_F(Dhcp4ParserTest, hostReservationPerSubnet) {
     ConstElementPtr json;
     ASSERT_NO_THROW(json = parseDHCP4(hr_config));
     extractConfig(hr_config);
-    ConstElementPtr result;
-    EXPECT_NO_THROW(result = Dhcpv4SrvTest::configure(*srv_, json));
+
+    ConstElementPtr status;
+    EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json));
 
     // returned value should be 0 (success)
-    checkResult(result, 0);
+    checkResult(status, 0);
+    CfgMgr::instance().commit();
 
     // Let's get all subnets and check that there are 7 of them.
-    ConstCfgSubnets4Ptr subnets = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
+    ConstCfgSubnets4Ptr subnets = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4();
     ASSERT_TRUE(subnets);
     const Subnet4Collection* subnet_col = subnets->getAll();
     ASSERT_EQ(7, subnet_col->size()); // We expect 7 subnets
@@ -5421,7 +5570,7 @@ TEST_F(Dhcp4ParserTest, hostReservationGlobal) {
     ///       - 192.0.2.0/24 (all reservations enabled)
     ///       - 192.0.3.0/24 (reservations not specified)
     const char* hr_config =
-        "{ "
+        "{"
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"reservations-global\": false,"
@@ -5445,14 +5594,16 @@ TEST_F(Dhcp4ParserTest, hostReservationGlobal) {
     ConstElementPtr json;
     ASSERT_NO_THROW(json = parseDHCP4(hr_config));
     extractConfig(hr_config);
-    ConstElementPtr result;
-    EXPECT_NO_THROW(result = Dhcpv4SrvTest::configure(*srv_, json));
+
+    ConstElementPtr status;
+    EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json));
 
     // returned value should be 0 (success)
-    checkResult(result, 0);
+    checkResult(status, 0);
+    CfgMgr::instance().commit();
 
     // Let's get all subnets and check that there are 4 of them.
-    ConstCfgSubnets4Ptr subnets = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
+    ConstCfgSubnets4Ptr subnets = CfgMgr::instance().getCurrentCfg()->getCfgSubnets4();
     ASSERT_TRUE(subnets);
     const Subnet4Collection* subnet_col = subnets->getAll();
     ASSERT_EQ(2, subnet_col->size()); // We expect 2 subnets
@@ -5465,7 +5616,7 @@ TEST_F(Dhcp4ParserTest, hostReservationGlobal) {
     ASSERT_TRUE(subnet);
     // Reset the fetch global function to staging (vs current) config.
     subnet->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
-        return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
+        return (CfgMgr::instance().getCurrentCfg()->getConfiguredGlobals());
     });
     EXPECT_FALSE(subnet->getReservationsGlobal());
     EXPECT_TRUE(subnet->getReservationsInSubnet());
@@ -5476,7 +5627,7 @@ TEST_F(Dhcp4ParserTest, hostReservationGlobal) {
     ASSERT_TRUE(subnet);
     // Reset the fetch global function to staging (vs current) config.
     subnet->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
-        return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
+        return (CfgMgr::instance().getCurrentCfg()->getConfiguredGlobals());
     });
     EXPECT_FALSE(subnet->getReservationsGlobal());
     EXPECT_TRUE(subnet->getReservationsInSubnet());
@@ -5486,16 +5637,16 @@ TEST_F(Dhcp4ParserTest, hostReservationGlobal) {
 /// Check that the decline-probation-period has a default value when not
 /// specified.
 TEST_F(Dhcp4ParserTest, declineTimerDefault) {
-    ConstElementPtr status;
 
-    string config = "{ " + genIfaceConfig() + "," +
-        "\"subnet4\": [ ]"
+    string config = "{ " + genIfaceConfig() + ","
+        "\"subnet4\": [  ] "
         "}";
 
     ConstElementPtr json;
     ASSERT_NO_THROW(json = parseDHCP4(config));
     extractConfig(config);
 
+    ConstElementPtr status;
     EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json));
 
     // returned value should be 0 (success)
@@ -5532,9 +5683,7 @@ TEST_F(Dhcp4ParserTest, dhcp4o6portDefault) {
 
 /// Check that the decline-probation-period value can be set properly.
 TEST_F(Dhcp4ParserTest, declineTimer) {
-    ConstElementPtr status;
-
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"decline-probation-period\": 12345,"
         "\"subnet4\": [ ]"
         "}";
@@ -5543,6 +5692,7 @@ TEST_F(Dhcp4ParserTest, declineTimer) {
     ASSERT_NO_THROW(json = parseDHCP4(config));
     extractConfig(config);
 
+    ConstElementPtr status;
     EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json));
 
     // returned value should be 0 (success)
@@ -5556,9 +5706,7 @@ TEST_F(Dhcp4ParserTest, declineTimer) {
 
 /// Check that an incorrect decline-probation-period value will be caught.
 TEST_F(Dhcp4ParserTest, declineTimerError) {
-    ConstElementPtr status;
-
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"decline-probation-period\": \"soon\","
         "\"subnet4\": [ ]"
         "}";
@@ -5566,6 +5714,7 @@ TEST_F(Dhcp4ParserTest, declineTimerError) {
     ConstElementPtr json;
     ASSERT_NO_THROW(json = parseJSON(config));
 
+    ConstElementPtr status;
     EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json));
 
     // returned value should be 1 (error)
@@ -5582,7 +5731,7 @@ TEST_F(Dhcp4ParserTest, declineTimerError) {
 // specified.
 TEST_F(Dhcp4ParserTest, expiredLeasesProcessing) {
     // Create basic configuration with the expiration specific parameters.
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"expired-leases-processing\": "
         "{"
         "    \"reclaim-timer-wait-time\": 20,"
@@ -5624,7 +5773,7 @@ TEST_F(Dhcp4ParserTest, expiredLeasesProcessing) {
 TEST_F(Dhcp4ParserTest, expiredLeasesProcessingError) {
     // Create basic configuration with the expiration specific parameters.
     // One of the parameters holds invalid value.
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"expired-leases-processing\": "
         "{"
         "    \"reclaim-timer-wait-time\": -5,"
@@ -5657,7 +5806,7 @@ TEST_F(Dhcp4ParserTest, 4o6default) {
     ConstElementPtr status;
 
     // Just a plain v4 config (no 4o6 parameters)
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -5692,7 +5841,7 @@ TEST_F(Dhcp4ParserTest, 4o6subnet) {
     ConstElementPtr status;
 
     // Just a plain v4 config (no 4o6 parameters)
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -5732,7 +5881,7 @@ TEST_F(Dhcp4ParserTest, 4o6subnetBogus) {
     // Just a plain v4 config (no 4o6 parameters)
     string config[] = {
         // Bogus configuration 1: missing / in subnet
-        "{ " + genIfaceConfig() + "," +
+        "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -5743,7 +5892,7 @@ TEST_F(Dhcp4ParserTest, 4o6subnetBogus) {
         "\"valid-lifetime\": 4000 }",
 
         // Bogus configuration 2: incorrect address
-                "{ " + genIfaceConfig() + "," +
+                "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -5754,7 +5903,7 @@ TEST_F(Dhcp4ParserTest, 4o6subnetBogus) {
         "\"valid-lifetime\": 4000 }",
 
         // Bogus configuration 3: incorrect prefix length
-        "{ " + genIfaceConfig() + "," +
+        "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -5792,7 +5941,7 @@ TEST_F(Dhcp4ParserTest, 4o6iface) {
     ConstElementPtr status;
 
     // Just a plain v4 config (no 4o6 parameters)
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -5829,7 +5978,7 @@ TEST_F(Dhcp4ParserTest, 4o6subnetIface) {
     ConstElementPtr status;
 
     // Just a plain v4 config (no 4o6 parameters)
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -5870,7 +6019,7 @@ TEST_F(Dhcp4ParserTest, 4o6subnetInterfaceId) {
     ConstElementPtr status;
 
     // Just a plain v4 config (no 4o6 parameters)
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ { "
@@ -5909,7 +6058,7 @@ TEST_F(Dhcp4ParserTest, 4o6subnetInterfaceId) {
 // Verifies that simple list of valid classes parses and
 // is staged for commit.
 TEST_F(Dhcp4ParserTest, validClientClassDictionary) {
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"valid-lifetime\": 4000, \n"
         "\"rebind-timer\": 2000, \n"
         "\"renew-timer\": 1000, \n"
@@ -5958,7 +6107,7 @@ TEST_F(Dhcp4ParserTest, validClientClassDictionary) {
 // Verifies that a class list containing an invalid
 // class definition causes a configuration error.
 TEST_F(Dhcp4ParserTest, invalidClientClassDictionary) {
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"valid-lifetime\": 4000, \n"
         "\"rebind-timer\": 2000, \n"
         "\"renew-timer\": 1000, \n"
@@ -5981,7 +6130,7 @@ TEST_F(Dhcp4ParserTest, invalidClientClassDictionary) {
 // Verifies that simple list of valid classes parses and
 // is staged for commit.
 TEST_F(Dhcp4ParserTest, clientClassValidLifetime) {
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"client-classes\" : [ \n"
         "   { \n"
         "       \"name\": \"one\", \n"
@@ -6037,7 +6186,7 @@ TEST_F(Dhcp4ParserTest, clientClassValidLifetime) {
 // Verifies that simple list of valid template classes parses and
 // is staged for commit.
 TEST_F(Dhcp4ParserTest, templateClientClassValidLifetime) {
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"client-classes\" : [ \n"
         "   { \n"
         "       \"name\": \"one\", \n"
@@ -6155,7 +6304,7 @@ TEST_F(Dhcp4ParserTest, poolUserContextData) {
 
 // Test verifies that it's possible to specify parameters in the user context
 // in the min-max address pool.
-TEST_F(Dhcp4ParserTest, pooMinMaxlUserContext) {
+TEST_F(Dhcp4ParserTest, poolMinMaxUserContext) {
     extractConfig(PARSER_CONFIGS[3]);
     PoolPtr pool;
     getPool(string(PARSER_CONFIGS[3]), 0, 0, pool);
@@ -6314,12 +6463,10 @@ TEST_F(Dhcp4ParserTest, sharedNetworksName) {
 }
 
 // Test verifies that a degenerated shared-network (just one subnet) is
-// accepted.
+// accepted. Also tests that, unless explicitly specified, the subnet
+// gets default values.
 TEST_F(Dhcp4ParserTest, sharedNetworks1subnet) {
     string config = "{\n"
-        "\"valid-lifetime\": 4000, \n"
-        "\"rebind-timer\": 2000, \n"
-        "\"renew-timer\": 1000, \n"
         "\"shared-networks\": [ {\n"
         "    \"name\": \"foo\"\n,"
         "    \"subnet4\": [ { \n"
@@ -6346,11 +6493,11 @@ TEST_F(Dhcp4ParserTest, sharedNetworks1subnet) {
     ASSERT_TRUE(net);
     EXPECT_EQ("foo", net->getName());
 
-    // It should have one subnet.
+    // It should have one subnet. The subnet should have default values.
     const Subnet4SimpleCollection* subs = net->getAllSubnets();
     ASSERT_TRUE(subs);
     EXPECT_EQ(1, subs->size());
-    checkSubnet(*subs, "192.0.2.0/24", 1000, 2000, 4000);
+    checkSubnet(*subs, "192.0.2.0/24", 0, 0, 7200);
 
     // Now make sure the subnet was added to global list of subnets.
     CfgSubnets4Ptr subnets4 = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
@@ -6358,7 +6505,7 @@ TEST_F(Dhcp4ParserTest, sharedNetworks1subnet) {
 
     const Subnet4Collection* gsubs = subnets4->getAll();
     ASSERT_TRUE(gsubs);
-    checkSubnet(*gsubs, "192.0.2.0/24", 1000, 2000, 4000);
+    checkSubnet(*gsubs, "192.0.2.0/24", 0, 0, 7200);
 }
 
 // Test verifies that a proper shared-network (three subnets) is
@@ -6374,8 +6521,8 @@ TEST_F(Dhcp4ParserTest, sharedNetworks3subnets) {
         "\"valid-lifetime\": 4000, \n"
         "\"min-valid-lifetime\": 3000, \n"
         "\"max-valid-lifetime\": 5000, \n"
-        "\"rebind-timer\": 2000, \n"
         "\"renew-timer\": 1000, \n"
+        "\"rebind-timer\": 2000, \n"
         "\"shared-networks\": [ {\n"
         "    \"name\": \"foo\"\n,"
         "    \"subnet4\": [\n"
@@ -6532,6 +6679,7 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDerive) {
     ASSERT_TRUE(nets);
     ASSERT_EQ(2, nets->size());
 
+    // Let's check the first one.
     SharedNetwork4Ptr net = nets->at(0);
     ASSERT_TRUE(net);
 
@@ -6603,6 +6751,130 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDerive) {
     EXPECT_FALSE(s->getReservationsOutOfPool());
 }
 
+// Since it is not allowed to define both interface-id and interface
+// for the same subnet, we need dedicated test that will check
+// interface separately.
+TEST_F(Dhcp4ParserTest, sharedNetworksDeriveInterfaces) {
+
+    // We need to fake the interfaces present, because we want to test
+    // interface names inheritance. However, there are sanity checks
+    // on subnet level that would refuse the value if the interface
+    // is not present.
+    IfaceMgrTestConfig iface_config(true);
+
+    string config = "{\n"
+        "\"shared-networks\": [ {\n"
+        "    \"name\": \"foo\"\n,"
+        "    \"interface\": \"eth0\",\n"
+        "    \"rebind-timer\": 10, \n"
+        "    \"subnet4\": [\n"
+        "    { \n"
+        "        \"id\": 1, \n"
+        "        \"subnet\": \"192.0.1.0/24\",\n"
+        "        \"pools\": [ { \"pool\": \"192.0.1.1-192.0.1.10\" } ]\n"
+        "    },\n"
+        "    { \n"
+        "        \"id\": 2, \n"
+        "        \"subnet\": \"192.0.2.0/24\",\n"
+        "        \"rebind-timer\": 100, \n"
+        "        \"pools\": [ { \"pool\": \"192.0.2.1-192.0.2.10\" } ],\n"
+        "        \"interface\": \"eth0\"\n"
+        "    }\n"
+        "    ]\n"
+        " },\n"
+        "{ // second shared-network starts here\n"
+        "    \"name\": \"bar\",\n"
+        "    \"subnet4\": [\n"
+        "    {\n"
+        "        \"id\": 3, \n"
+        "        \"subnet\": \"192.0.3.0/24\",\n"
+        "        \"pools\": [ { \"pool\": \"192.0.3.1-192.0.3.10\" } ]\n"
+        "    }\n"
+        "    ]\n"
+        "} ]\n"
+        "} \n";
+
+    configure(config, CONTROL_RESULT_SUCCESS, "");
+
+    // Now verify that the shared network was indeed configured.
+    CfgSharedNetworks4Ptr cfg_net = CfgMgr::instance().getStagingCfg()
+        ->getCfgSharedNetworks4();
+
+    // Two shared networks are expected.
+    ASSERT_TRUE(cfg_net);
+    const SharedNetwork4Collection* nets = cfg_net->getAll();
+    ASSERT_TRUE(nets);
+    ASSERT_EQ(2, nets->size());
+
+    // Let's check the first one.
+    SharedNetwork4Ptr net = nets->at(0);
+    ASSERT_TRUE(net);
+
+    const Subnet4SimpleCollection* subs = net->getAllSubnets();
+    ASSERT_TRUE(subs);
+    EXPECT_EQ(2, subs->size());
+
+    // For the first subnet, the rebind-timer should be 10, because it was
+    // derived from shared-network level. Other parameters a derived
+    // from global scope to shared-network level and later again to
+    // subnet4 level.
+    Subnet4Ptr s = checkSubnet(*subs, "192.0.1.0/24", 0, 10, 7200);
+    ASSERT_TRUE(s);
+    EXPECT_EQ("eth0", s->getIface().get());
+
+    // For the second subnet, the rebind-timer should be 100, because it
+    // was specified explicitly. Other parameters a derived
+    // from global scope to shared-network level and later again to
+    // subnet4 level.
+    checkSubnet(*subs, "192.0.2.0/24", 0, 100, 7200);
+    EXPECT_EQ("eth0", s->getIface().get());
+
+    // Ok, now check the second shared subnet.
+    net = nets->at(1);
+    ASSERT_TRUE(net);
+
+    subs = net->getAllSubnets();
+    ASSERT_TRUE(subs);
+    EXPECT_EQ(1, subs->size());
+
+    // This subnet should derive its rebind-timer from global scope.
+    s = checkSubnet(*subs, "192.0.3.0/24", 0, 0, 7200);
+    EXPECT_EQ("", s->getIface().get());
+}
+
+// It is not allowed to have different values for interfaces names is subnets
+// in the same shared network.
+TEST_F(Dhcp4ParserTest, sharedNetworksInterfacesMixed) {
+
+    // We need to fake the interfaces present, because we want to test
+    // interface names inheritance. However, there are sanity checks
+    // on subnet level that would refuse the value if the interface
+    // is not present.
+    IfaceMgrTestConfig iface_config(true);
+
+    string config = "{\n"
+        "\"shared-networks\": [ {\n"
+        "    \"name\": \"foo\"\n,"
+        "    \"subnet4\": [\n"
+        "    { \n"
+        "        \"id\": 1, \n"
+        "        \"subnet\": \"192.0.1.0/24\",\n"
+        "        \"interface\": \"eth0\"\n"
+        "    },\n"
+        "    { \n"
+        "        \"id\": 2, \n"
+        "        \"subnet\": \"192.0.2.0/24\",\n"
+        "        \"interface\": \"eth1\"\n"
+        "    }\n"
+        "    ]\n"
+        " } ]\n"
+        "} \n";
+
+    configure(config, CONTROL_RESULT_ERROR, "Subnet 192.0.2.0/24 has specified "
+              "interface eth1, but earlier subnet in the same shared-network "
+              "or the shared-network itself used eth0");
+}
+
 // This test checks if client-class is derived properly.
 TEST_F(Dhcp4ParserTest, sharedNetworksDeriveClientClass) {
 
@@ -6639,7 +6911,6 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDeriveClientClass) {
         "        \"pools\": [ { \"pool\": \"192.0.3.1-192.0.3.10\" } ]\n"
         "    }\n"
         "    ]\n"
-
         " } ]\n"
         "} \n";
 
@@ -6655,6 +6926,7 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDeriveClientClass) {
     ASSERT_TRUE(nets);
     ASSERT_EQ(2, nets->size());
 
+    // Let's check the first one.
     SharedNetwork4Ptr net = nets->at(0);
     ASSERT_TRUE(net);
 
@@ -6674,11 +6946,12 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDeriveClientClass) {
     // For the second subnet, the values are overridden on subnet level.
     // The value should not be inherited.
     s = checkSubnet(*subs, "192.0.2.0/24", 1, 2, 4);
+    ASSERT_TRUE(s);
     EXPECT_EQ("beta", s->getClientClass().get()); // beta defined on subnet level
 
-    // Ok, now check the second shared network. It doesn't have anything defined
-    // on shared-network or subnet level, so everything should have default
-    // values.
+    // Ok, now check the second shared network. It doesn't have
+    // anything defined on shared-network or subnet level, so
+    // everything should have default values.
     net = nets->at(1);
     ASSERT_TRUE(net);
 
@@ -6686,6 +6959,7 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDeriveClientClass) {
     ASSERT_TRUE(subs);
     EXPECT_EQ(1, subs->size());
 
+    // This subnet should derive its renew-timer from global scope.
     s = checkSubnet(*subs, "192.0.3.0/24", 1, 2, 4);
     EXPECT_TRUE(s->getClientClass().empty());
 }
@@ -6711,7 +6985,7 @@ TEST_F(Dhcp4ParserTest, hostsDatabases) {
 // This test checks comments. Please keep it last.
 TEST_F(Dhcp4ParserTest, comments) {
 
-    string config = PARSER_CONFIGS[5];
+    string config = PARSER_CONFIGS[6];
     extractConfig(config);
     configure(config, CONTROL_RESULT_SUCCESS, "");
 
@@ -6961,22 +7235,12 @@ TEST_F(Dhcp4ParserTest, comments) {
     ASSERT_EQ(1, ctx_d2->size());
     ASSERT_TRUE(ctx_d2->get("comment"));
     EXPECT_EQ("\"No dynamic DNS\"", ctx_d2->get("comment")->str());
-
-#if 0
-    // Loggers section supports comments too.
-
-    string logging = "{\n"
-        "\"loggers\": [ {\n"
-        "    \"comment\": \"A logger\",\n"
-        "    \"name\": \"kea-dhcp4\"\n"
-        "} ]\n";
-#endif
 }
 
-// This test verifies that the global host reservations can be specified
+// This test verifies that the global host reservations can be specified.
 TEST_F(Dhcp4ParserTest, globalReservations) {
     ConstElementPtr x;
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, \n"
         "\"renew-timer\": 1000,\n"
         "\"reservations\": [\n"
@@ -7021,9 +7285,9 @@ TEST_F(Dhcp4ParserTest, globalReservations) {
         "    \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],\n"
         "    \"subnet\": \"192.0.4.0/24\",\n"
         "    \"id\": 542\n"
-        " } ],\n"
-        "\"valid-lifetime\": 4000"
-        "}\n";
+        " }\n"
+        "],\n"
+        "\"valid-lifetime\": 4000 }\n";
 
     ConstElementPtr json;
     ASSERT_NO_THROW(json = parseDHCP4(config));
@@ -7056,7 +7320,14 @@ TEST_F(Dhcp4ParserTest, globalReservations) {
     ASSERT_TRUE(host);
     EXPECT_EQ("global2", host->getHostname());
 
-    // Check that options are stored correctly.
+    // This reservation should be solely assigned to the subnet 234,
+    // and not to other two.
+    EXPECT_FALSE(hosts_cfg->get4(123, Host::IDENT_HWADDR,
+                                 &hwaddr[0], hwaddr.size()));
+
+    EXPECT_FALSE(hosts_cfg->get4(542, Host::IDENT_HWADDR,
+                                 &hwaddr[0], hwaddr.size()));
+    // Check that options are assigned correctly.
     Option4AddrLstPtr opt_dns =
         retrieveOption<Option4AddrLstPtr>(*host, DHO_NAME_SERVERS);
     ASSERT_TRUE(opt_dns);
@@ -7068,14 +7339,6 @@ TEST_F(Dhcp4ParserTest, globalReservations) {
     ASSERT_TRUE(opt_ttl);
     EXPECT_EQ(11, static_cast<int>(opt_ttl->getValue()));
 
-    // This reservation should be global solely and not assigned to
-    // either subnet
-    EXPECT_FALSE(hosts_cfg->get4(123, Host::IDENT_HWADDR,
-                                 &hwaddr[0], hwaddr.size()));
-
-    EXPECT_FALSE(hosts_cfg->get4(542, Host::IDENT_HWADDR,
-                                 &hwaddr[0], hwaddr.size()));
-
     // Do the same test for the DUID based reservation.
     std::vector<uint8_t> duid;
     for (unsigned int i = 1; i < 0xb; ++i) {
@@ -7107,7 +7370,7 @@ TEST_F(Dhcp4ParserTest, globalReservations) {
 // reporting as disabled and thereby drawing attention to them.
 // This test verifies that configuration control with unsupported type fails
 TEST_F(Dhcp4ParserTest, configControlInfoNoFactory) {
-    string config = PARSER_CONFIGS[6];
+    string config = PARSER_CONFIGS[5];
 
     // Unregister "mysql" and ignore the return value.
     static_cast<void>(TestConfigBackendDHCPv4::
@@ -7123,7 +7386,7 @@ TEST_F(Dhcp4ParserTest, configControlInfoNoFactory) {
 
 // This test verifies that configuration control info gets populated.
 TEST_F(Dhcp4ParserTest, configControlInfo) {
-    string config = PARSER_CONFIGS[6];
+    string config = PARSER_CONFIGS[5];
 
     // Should be able to register a backend factory for "mysql".
     ASSERT_TRUE(TestConfigBackendDHCPv4::
@@ -7158,18 +7421,18 @@ TEST_F(Dhcp4ParserTest, configControlInfo) {
 // Check whether it is possible to configure server-tag
 TEST_F(Dhcp4ParserTest, serverTag) {
     // Config without server-tag
-    string config_no_tag = "{ " + genIfaceConfig() + "," +
+    string config_no_tag = "{ " + genIfaceConfig() + ","
         "\"subnet4\": [  ] "
         "}";
 
     // Config with server-tag
-    string config_tag = "{ " + genIfaceConfig() + "," +
+    string config_tag = "{ " + genIfaceConfig() + ","
         "\"server-tag\": \"boo\", "
         "\"subnet4\": [  ] "
         "}";
 
     // Config with an invalid server-tag
-    string bad_tag = "{ " + genIfaceConfig() + "," +
+    string bad_tag = "{ " + genIfaceConfig() + ","
         "\"server-tag\": 777, "
         "\"subnet4\": [  ] "
         "}";
@@ -7411,7 +7674,7 @@ TEST_F(Dhcp4ParserTest, calculateTeeTimesInheritence) {
         "        {  \n"
         "            \"id\": 200, \n"
         "            \"subnet\": \"192.0.2.0/24\", \n"
-        "            \"pools\": [ { \"pool\": \"192.0.2.1-192.0.2.10\"} ] \n"
+        "            \"pools\": [ { \"pool\": \"192.0.2.1-192.0.2.10\" } ] \n"
         "        } \n"
         "        ] \n"
         "     } ], \n"
@@ -7437,7 +7700,7 @@ TEST_F(Dhcp4ParserTest, calculateTeeTimesInheritence) {
     // Subnet 200 should use the shared-network values.
     subnet4 = subnets4->getBySubnetId(200);
     ASSERT_TRUE(subnet4);
-    EXPECT_EQ(true, subnet4->getCalculateTeeTimes());
+    EXPECT_TRUE(subnet4->getCalculateTeeTimes());
     EXPECT_TRUE(util::areDoublesEquivalent(0.4, subnet4->getT1Percent()));
     EXPECT_TRUE(util::areDoublesEquivalent(0.75, subnet4->getT2Percent()));
 
@@ -7452,7 +7715,7 @@ TEST_F(Dhcp4ParserTest, calculateTeeTimesInheritence) {
 // This test checks that the global store-extended-info parameter is optional
 // and that values under the subnet are used.
 TEST_F(Dhcp4ParserTest, storeExtendedInfoNoGlobal) {
-    std::string config = "{ " + genIfaceConfig() + "," +
+    const string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ "
@@ -7478,29 +7741,31 @@ TEST_F(Dhcp4ParserTest, storeExtendedInfoNoGlobal) {
     ASSERT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json));
     checkResult(status, 0);
 
+    // First subnet should use global default.
     CfgSubnets4Ptr cfg = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
-    Subnet4Ptr subnet1 = cfg->selectSubnet(IOAddress("192.0.2.1"));
-    ASSERT_TRUE(subnet1);
+    Subnet4Ptr subnet = cfg->selectSubnet(IOAddress("192.0.2.1"));
+    ASSERT_TRUE(subnet);
     // Reset the fetch global function to staging (vs current) config.
-    subnet1->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
+    subnet->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
         return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
     });
-    EXPECT_TRUE(subnet1->getStoreExtendedInfo());
+    EXPECT_TRUE(subnet->getStoreExtendedInfo());
 
-    Subnet4Ptr subnet2 = cfg->selectSubnet(IOAddress("192.0.3.1"));
-    ASSERT_TRUE(subnet2);
+    // Second subnet should use its own value.
+    subnet = cfg->selectSubnet(IOAddress("192.0.3.1"));
+    ASSERT_TRUE(subnet);
     // Reset the fetch global function to staging (vs current) config.
-    subnet2->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
+    subnet->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
         return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
     });
-    EXPECT_FALSE(subnet2->getStoreExtendedInfo());
+    EXPECT_FALSE(subnet->getStoreExtendedInfo());
 }
 
 // This test checks that the global store-extended-info parameter is used
 // when there is no such parameter under subnet and that the parameter
 // specified for a subnet overrides the global setting.
 TEST_F(Dhcp4ParserTest, storeExtendedInfoGlobal) {
-    std::string config = "{ " + genIfaceConfig() + "," +
+    const string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"store-extended-info\": true,"
@@ -7526,6 +7791,7 @@ TEST_F(Dhcp4ParserTest, storeExtendedInfoGlobal) {
     ASSERT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json));
     checkResult(status, 0);
 
+    // First subnet should override the global value.
     CfgSubnets4Ptr cfg = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
     Subnet4Ptr subnet1 = cfg->selectSubnet(IOAddress("192.0.2.1"));
     ASSERT_TRUE(subnet1);
@@ -7535,6 +7801,7 @@ TEST_F(Dhcp4ParserTest, storeExtendedInfoGlobal) {
     });
     EXPECT_FALSE(subnet1->getStoreExtendedInfo());
 
+    // Second subnet should use the global value.
     Subnet4Ptr subnet2 = cfg->selectSubnet(IOAddress("192.0.3.1"));
     ASSERT_TRUE(subnet2);
     // Reset the fetch global function to staging (vs current) config.
@@ -7547,7 +7814,7 @@ TEST_F(Dhcp4ParserTest, storeExtendedInfoGlobal) {
 /// This test checks that the statistic-default-sample-count and age
 /// global parameters are committed to the stats manager as expected.
 TEST_F(Dhcp4ParserTest, statsDefaultLimits) {
-    std::string config = "{ " + genIfaceConfig() + "," +
+    std::string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"statistic-default-sample-count\": 10, "
@@ -7572,7 +7839,7 @@ TEST_F(Dhcp4ParserTest, statsDefaultLimits) {
 
 // This test checks that using default multi threading settings works.
 TEST_F(Dhcp4ParserTest, multiThreadingDefaultSettings) {
-    std::string config = "{ " + genIfaceConfig() + "," +
+    std::string config = "{ " + genIfaceConfig() + ","
         "\"subnet4\": [  ]"
         "}";
 
@@ -7609,7 +7876,7 @@ TEST_F(Dhcp4ParserTest, multiThreadingSettings) {
         "    \"thread-pool-size\": 48,\n"
         "    \"packet-queue-size\": 1024\n"
         "}";
-    std::string config = "{ " + genIfaceConfig() + "," +
+    std::string config = "{ " + genIfaceConfig() + ","
         "\"subnet4\": [  ], "
         "\"multi-threading\": " + content_json + "}";
 
@@ -7636,18 +7903,18 @@ TEST_F(Dhcp4ParserTest, multiThreadingSettings) {
 // is correct.
 TEST_F(Dhcp4ParserTest, parkedPacketLimit) {
     // Config without parked-packet-limit
-    string config_no_limit = "{ " + genIfaceConfig() + "," +
+    string config_no_limit = "{ " + genIfaceConfig() + ","
         "\"subnet4\": [  ] "
         "}";
 
     // Config with parked-packet-limit
-    string config_limit = "{ " + genIfaceConfig() + "," +
+    string config_limit = "{ " + genIfaceConfig() + ","
         "\"parked-packet-limit\": 777, "
         "\"subnet4\": [  ] "
         "}";
 
     // Config with an invalid parked-packet-limit
-    string bad_limit = "{ " + genIfaceConfig() + "," +
+    string bad_limit = "{ " + genIfaceConfig() + ","
         "\"parked-packet-limit\": \"boo\", "
         "\"subnet4\": [  ] "
         "}";
@@ -7677,7 +7944,7 @@ TEST_F(Dhcp4ParserTest, parkedPacketLimit) {
 // This test checks that ddns-conflict-resolution-mode value can be specified at
 // global and subnet levels.
 TEST_F(Dhcp4ParserTest, storeDdnsConflictResolutionMode) {
-    std::string config = "{ " + genIfaceConfig() + "," +
+    std::string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet4\": [ "
index da34cb48b3378245140d8df99ca9373b7fd77887..eb5da71a505b73cdc55a1d7ce006864148c777c8 100644 (file)
@@ -76,17 +76,6 @@ const char* EXTRACTED_CONFIGS[] = {
 "            \"re-detect\": false\n"
 "        },\n"
 "        \"rebind-timer\": 2000,\n"
-"        \"renew-timer\": 1000,\n"
-"        \"subnet4\": [ ],\n"
-"        \"valid-lifetime\": 4000\n"
-"    }\n",
-    // CONFIGURATION 1
-"{\n"
-"        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ],\n"
-"            \"re-detect\": false\n"
-"        },\n"
-"        \"rebind-timer\": 2000,\n"
 "        \"subnet4\": [\n"
 "            {\n"
 "                \"id\": 1,\n"
@@ -100,7 +89,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 2
+    // CONFIGURATION 1
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -119,6 +108,17 @@ const char* EXTRACTED_CONFIGS[] = {
 "            }\n"
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
+"    }\n",
+    // CONFIGURATION 2
+"{\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"rebind-timer\": 2000,\n"
+"        \"renew-timer\": 1000,\n"
+"        \"subnet4\": [ ],\n"
+"        \"valid-lifetime\": 4000\n"
 "    }\n",
     // CONFIGURATION 3
 "{\n"
@@ -193,6 +193,54 @@ const char* EXTRACTED_CONFIGS[] = {
 "    }\n",
     // CONFIGURATION 5
 "{\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"rebind-timer\": 2000,\n"
+"        \"renew-timer\": 1000,\n"
+"        \"subnet4\": [\n"
+"            {\n"
+"                \"id\": 1,\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"pool\": \"192.0.2.1 - 192.0.2.100\"\n"
+"                    }\n"
+"                ],\n"
+"                \"subnet\": \"192.0.2.0/24\"\n"
+"            },\n"
+"            {\n"
+"                \"id\": 2,\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"pool\": \"192.0.3.101 - 192.0.3.150\"\n"
+"                    }\n"
+"                ],\n"
+"                \"subnet\": \"192.0.3.0/24\"\n"
+"            },\n"
+"            {\n"
+"                \"id\": 3,\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"pool\": \"192.0.4.101 - 192.0.4.150\"\n"
+"                    }\n"
+"                ],\n"
+"                \"subnet\": \"192.0.4.0/24\"\n"
+"            },\n"
+"            {\n"
+"                \"id\": 4,\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"pool\": \"192.0.5.101 - 192.0.5.150\"\n"
+"                    }\n"
+"                ],\n"
+"                \"subnet\": \"192.0.5.0/24\"\n"
+"            }\n"
+"        ],\n"
+"        \"valid-lifetime\": 4000\n"
+"    }\n",
+    // CONFIGURATION 6
+"{\n"
 "        \"boot-file-name\": \"bar\",\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -215,7 +263,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 6
+    // CONFIGURATION 7
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -239,7 +287,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 7
+    // CONFIGURATION 8
 "{\n"
 "        \"boot-file-name\": \"nofile\",\n"
 "        \"interfaces-config\": {\n"
@@ -266,7 +314,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 8
+    // CONFIGURATION 9
 "{\n"
 "        \"echo-client-id\": false,\n"
 "        \"interfaces-config\": {\n"
@@ -288,7 +336,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 9
+    // CONFIGURATION 10
 "{\n"
 "        \"echo-client-id\": true,\n"
 "        \"interfaces-config\": {\n"
@@ -310,7 +358,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 10
+    // CONFIGURATION 11
 "{\n"
 "        \"compatibility\": {\n"
 "            \"exclude-first-last-24\": true,\n"
@@ -337,7 +385,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 11
+    // CONFIGURATION 12
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -369,7 +417,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 12
+    // CONFIGURATION 13
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -401,7 +449,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 13
+    // CONFIGURATION 14
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -433,7 +481,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 14
+    // CONFIGURATION 15
 "{\n"
 "        \"authoritative\": true,\n"
 "        \"interfaces-config\": {\n"
@@ -465,7 +513,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 15
+    // CONFIGURATION 16
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -493,7 +541,29 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 16
+    // CONFIGURATION 17
+"{\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"rebind-timer\": 2000,\n"
+"        \"renew-timer\": 1000,\n"
+"        \"subnet4\": [\n"
+"            {\n"
+"                \"id\": 1,\n"
+"                \"interface\": \"eth0\",\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"pool\": \"192.0.2.1 - 192.0.2.100\"\n"
+"                    }\n"
+"                ],\n"
+"                \"subnet\": \"192.0.2.0/24\"\n"
+"            }\n"
+"        ],\n"
+"        \"valid-lifetime\": 4000\n"
+"    }\n",
+    // CONFIGURATION 18
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -529,7 +599,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 17
+    // CONFIGURATION 19
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -550,7 +620,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 18
+    // CONFIGURATION 20
 "{\n"
 "        \"option-def\": [\n"
 "            {\n"
@@ -561,7 +631,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "            }\n"
 "        ]\n"
 "    }\n",
-    // CONFIGURATION 19
+    // CONFIGURATION 21
 "{\n"
 "        \"option-def\": [\n"
 "            {\n"
@@ -573,7 +643,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "            }\n"
 "        ]\n"
 "    }\n",
-    // CONFIGURATION 20
+    // CONFIGURATION 22
 "{\n"
 "        \"option-def\": [\n"
 "            {\n"
@@ -590,7 +660,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "            }\n"
 "        ]\n"
 "    }\n",
-    // CONFIGURATION 21
+    // CONFIGURATION 23
 "{\n"
 "        \"option-def\": [\n"
 "            {\n"
@@ -602,7 +672,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "            }\n"
 "        ]\n"
 "    }\n",
-    // CONFIGURATION 22
+    // CONFIGURATION 24
 "{\n"
 "        \"option-def\": [\n"
 "            {\n"
@@ -614,7 +684,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "            }\n"
 "        ]\n"
 "    }\n",
-    // CONFIGURATION 23
+    // CONFIGURATION 25
 "{\n"
 "        \"option-def\": [\n"
 "            {\n"
@@ -625,7 +695,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "            }\n"
 "        ]\n"
 "    }\n",
-    // CONFIGURATION 24
+    // CONFIGURATION 26
 "{\n"
 "        \"option-def\": [\n"
 "            {\n"
@@ -636,7 +706,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "            }\n"
 "        ]\n"
 "    }\n",
-    // CONFIGURATION 25
+    // CONFIGURATION 27
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -669,7 +739,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 26
+    // CONFIGURATION 28
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -702,7 +772,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 27
+    // CONFIGURATION 29
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -743,7 +813,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 28
+    // CONFIGURATION 30
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -779,7 +849,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        \"renew-timer\": 1000,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 29
+    // CONFIGURATION 31
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -837,7 +907,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 3000\n"
 "    }\n",
-    // CONFIGURATION 30
+    // CONFIGURATION 32
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -877,7 +947,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 31
+    // CONFIGURATION 33
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -921,7 +991,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 32
+    // CONFIGURATION 34
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -954,7 +1024,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 33
+    // CONFIGURATION 35
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -992,7 +1062,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 34
+    // CONFIGURATION 36
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1023,7 +1093,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 35
+    // CONFIGURATION 37
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1059,7 +1129,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        \"renew-timer\": 1000,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 36
+    // CONFIGURATION 38
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1112,7 +1182,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 3000\n"
 "    }\n",
-    // CONFIGURATION 37
+    // CONFIGURATION 39
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1149,7 +1219,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 38
+    // CONFIGURATION 40
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1186,7 +1256,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 39
+    // CONFIGURATION 41
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"eth0\", \"eth1\" ],\n"
@@ -1196,7 +1266,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        \"renew-timer\": 1000,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 40
+    // CONFIGURATION 42
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"eth0\", \"*\", \"eth1\" ],\n"
@@ -1206,38 +1276,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        \"renew-timer\": 1000,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 41
-"{\n"
-"        \"dhcp-ddns\": {\n"
-"            \"enable-updates\": true,\n"
-"            \"max-queue-size\": 2048,\n"
-"            \"ncr-format\": \"JSON\",\n"
-"            \"ncr-protocol\": \"UDP\",\n"
-"            \"sender-ip\": \"192.168.2.2\",\n"
-"            \"sender-port\": 778,\n"
-"            \"server-ip\": \"192.168.2.1\",\n"
-"            \"server-port\": 777\n"
-"        },\n"
-"        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ],\n"
-"            \"re-detect\": false\n"
-"        },\n"
-"        \"rebind-timer\": 2000,\n"
-"        \"renew-timer\": 1000,\n"
-"        \"subnet4\": [\n"
-"            {\n"
-"                \"id\": 1,\n"
-"                \"pools\": [\n"
-"                    {\n"
-"                        \"pool\": \"192.0.2.1 - 192.0.2.100\"\n"
-"                    }\n"
-"                ],\n"
-"                \"subnet\": \"192.0.2.0/24\"\n"
-"            }\n"
-"        ],\n"
-"        \"valid-lifetime\": 4000\n"
-"    }\n",
-    // CONFIGURATION 42
+    // CONFIGURATION 43
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1264,7 +1303,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 43
+    // CONFIGURATION 44
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1291,7 +1330,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 44
+    // CONFIGURATION 45
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1342,7 +1381,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 45
+    // CONFIGURATION 46
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1375,7 +1414,38 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 46
+    // CONFIGURATION 47
+"{\n"
+"        \"dhcp-ddns\": {\n"
+"            \"enable-updates\": true,\n"
+"            \"max-queue-size\": 2048,\n"
+"            \"ncr-format\": \"JSON\",\n"
+"            \"ncr-protocol\": \"UDP\",\n"
+"            \"sender-ip\": \"192.168.2.2\",\n"
+"            \"sender-port\": 778,\n"
+"            \"server-ip\": \"192.168.2.1\",\n"
+"            \"server-port\": 777\n"
+"        },\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"rebind-timer\": 2000,\n"
+"        \"renew-timer\": 1000,\n"
+"        \"subnet4\": [\n"
+"            {\n"
+"                \"id\": 1,\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"pool\": \"192.0.2.1 - 192.0.2.100\"\n"
+"                    }\n"
+"                ],\n"
+"                \"subnet\": \"192.0.2.0/24\"\n"
+"            }\n"
+"        ],\n"
+"        \"valid-lifetime\": 4000\n"
+"    }\n",
+    // CONFIGURATION 48
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1474,7 +1544,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 47
+    // CONFIGURATION 49
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1516,7 +1586,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 48
+    // CONFIGURATION 50
 "{\n"
 "        \"rebind-timer\": 2000,\n"
 "        \"renew-timer\": 1000,\n"
@@ -1603,7 +1673,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 49
+    // CONFIGURATION 51
 "{\n"
 "        \"rebind-timer\": 2000,\n"
 "        \"renew-timer\": 1000,\n"
@@ -1635,7 +1705,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 50
+    // CONFIGURATION 52
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1643,7 +1713,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        },\n"
 "        \"subnet4\": [ ]\n"
 "    }\n",
-    // CONFIGURATION 51
+    // CONFIGURATION 53
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1651,7 +1721,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        },\n"
 "        \"subnet4\": [ ]\n"
 "    }\n",
-    // CONFIGURATION 52
+    // CONFIGURATION 54
 "{\n"
 "        \"decline-probation-period\": 12345,\n"
 "        \"interfaces-config\": {\n"
@@ -1660,7 +1730,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        },\n"
 "        \"subnet4\": [ ]\n"
 "    }\n",
-    // CONFIGURATION 53
+    // CONFIGURATION 55
 "{\n"
 "        \"expired-leases-processing\": {\n"
 "            \"flush-reclaimed-timer-wait-time\": 35,\n"
@@ -1676,7 +1746,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        },\n"
 "        \"subnet4\": [ ]\n"
 "    }\n",
-    // CONFIGURATION 54
+    // CONFIGURATION 56
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1697,7 +1767,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 55
+    // CONFIGURATION 57
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1719,7 +1789,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 56
+    // CONFIGURATION 58
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1741,7 +1811,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 57
+    // CONFIGURATION 59
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1764,7 +1834,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 58
+    // CONFIGURATION 60
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1786,7 +1856,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 59
+    // CONFIGURATION 61
 "{\n"
 "        \"client-classes\": [\n"
 "            {\n"
@@ -1818,7 +1888,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 60
+    // CONFIGURATION 62
 "{\n"
 "        \"client-classes\": [\n"
 "            {\n"
@@ -1847,7 +1917,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "            }\n"
 "        ]\n"
 "    }\n",
-    // CONFIGURATION 61
+    // CONFIGURATION 63
 "{\n"
 "        \"client-classes\": [\n"
 "            {\n"
@@ -1878,7 +1948,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "            }\n"
 "        ]\n"
 "    }\n",
-    // CONFIGURATION 62
+    // CONFIGURATION 64
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1899,7 +1969,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 63
+    // CONFIGURATION 65
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1921,7 +1991,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 64
+    // CONFIGURATION 66
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1947,7 +2017,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 65
+    // CONFIGURATION 67
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1973,7 +2043,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 66
+    // CONFIGURATION 68
 "{\n"
 "        \"hosts-databases\": [\n"
 "            {\n"
@@ -1998,7 +2068,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        \"renew-timer\": 1000,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 67
+    // CONFIGURATION 69
 "{\n"
 "        \"client-classes\": [\n"
 "            {\n"
@@ -2132,7 +2202,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "            \"comment\": \"A DHCPv4 server\"\n"
 "        }\n"
 "    }\n",
-    // CONFIGURATION 68
+    // CONFIGURATION 70
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -2194,7 +2264,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 69
+    // CONFIGURATION 71
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -2244,7 +2314,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 70
+    // CONFIGURATION 72
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -2276,7 +2346,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 71
+    // CONFIGURATION 73
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -2308,7 +2378,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 72
+    // CONFIGURATION 74
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -2320,7 +2390,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        \"statistic-default-sample-count\": 10,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 73
+    // CONFIGURATION 75
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -2328,7 +2398,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        },\n"
 "        \"subnet4\": [ ]\n"
 "    }\n",
-    // CONFIGURATION 74
+    // CONFIGURATION 76
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -2341,7 +2411,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        },\n"
 "        \"subnet4\": [ ]\n"
 "    }\n",
-    // CONFIGURATION 75
+    // CONFIGURATION 77
 "{\n"
 "        \"ddns-conflict-resolution-mode\": \"no-check-with-dhcid\",\n"
 "        \"interfaces-config\": {\n"
@@ -2471,7 +2541,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"option-def\": [ ],\n"
 "        \"parked-packet-limit\": 256,\n"
 "        \"rebind-timer\": 2000,\n"
-"        \"renew-timer\": 1000,\n"
 "        \"reservations-global\": false,\n"
 "        \"reservations-in-subnet\": true,\n"
 "        \"reservations-lookup-first\": false,\n"
@@ -2487,7 +2556,35 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"statistic-default-sample-age\": 0,\n"
 "        \"statistic-default-sample-count\": 20,\n"
 "        \"store-extended-info\": false,\n"
-"        \"subnet4\": [ ],\n"
+"        \"subnet4\": [\n"
+"            {\n"
+"                \"4o6-interface\": \"\",\n"
+"                \"4o6-interface-id\": \"\",\n"
+"                \"4o6-subnet\": \"\",\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": false,\n"
+"                \"id\": 1,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"192.0.2.1-192.0.2.100\"\n"
+"                    }\n"
+"                ],\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"192.0.2.0/24\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.875,\n"
+"                \"valid-lifetime\": 4000\n"
+"            }\n"
+"        ],\n"
 "        \"t1-percent\": 0.5,\n"
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
@@ -2555,7 +2652,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"option-data\": [ ],\n"
 "        \"option-def\": [ ],\n"
 "        \"parked-packet-limit\": 256,\n"
-"        \"rebind-timer\": 2000,\n"
+"        \"renew-timer\": 1000,\n"
 "        \"reservations-global\": false,\n"
 "        \"reservations-in-subnet\": true,\n"
 "        \"reservations-lookup-first\": false,\n"
@@ -2588,10 +2685,10 @@ const char* UNPARSED_CONFIGS[] = {
 "                        \"pool\": \"192.0.2.1-192.0.2.100\"\n"
 "                    }\n"
 "                ],\n"
-"                \"rebind-timer\": 2000,\n"
 "                \"relay\": {\n"
 "                    \"ip-addresses\": [ ]\n"
 "                },\n"
+"                \"renew-timer\": 1000,\n"
 "                \"reservations\": [ ],\n"
 "                \"store-extended-info\": false,\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
@@ -2667,6 +2764,94 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"option-data\": [ ],\n"
 "        \"option-def\": [ ],\n"
 "        \"parked-packet-limit\": 256,\n"
+"        \"rebind-timer\": 2000,\n"
+"        \"renew-timer\": 1000,\n"
+"        \"reservations-global\": false,\n"
+"        \"reservations-in-subnet\": true,\n"
+"        \"reservations-lookup-first\": false,\n"
+"        \"reservations-out-of-pool\": false,\n"
+"        \"sanity-checks\": {\n"
+"            \"extended-info-checks\": \"fix\",\n"
+"            \"lease-checks\": \"warn\"\n"
+"        },\n"
+"        \"server-hostname\": \"\",\n"
+"        \"server-tag\": \"\",\n"
+"        \"shared-networks\": [ ],\n"
+"        \"stash-agent-options\": false,\n"
+"        \"statistic-default-sample-age\": 0,\n"
+"        \"statistic-default-sample-count\": 20,\n"
+"        \"store-extended-info\": false,\n"
+"        \"subnet4\": [ ],\n"
+"        \"t1-percent\": 0.5,\n"
+"        \"t2-percent\": 0.875,\n"
+"        \"valid-lifetime\": 4000\n"
+"    }\n",
+    // CONFIGURATION 3
+"{\n"
+"        \"allocator\": \"iterative\",\n"
+"        \"authoritative\": false,\n"
+"        \"boot-file-name\": \"\",\n"
+"        \"calculate-tee-times\": false,\n"
+"        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
+"        \"ddns-generated-prefix\": \"myhost\",\n"
+"        \"ddns-override-client-update\": false,\n"
+"        \"ddns-override-no-update\": false,\n"
+"        \"ddns-qualifying-suffix\": \"\",\n"
+"        \"ddns-replace-client-name\": \"never\",\n"
+"        \"ddns-send-updates\": true,\n"
+"        \"ddns-update-on-renew\": false,\n"
+"        \"decline-probation-period\": 86400,\n"
+"        \"dhcp-ddns\": {\n"
+"            \"enable-updates\": false,\n"
+"            \"max-queue-size\": 1024,\n"
+"            \"ncr-format\": \"JSON\",\n"
+"            \"ncr-protocol\": \"UDP\",\n"
+"            \"sender-ip\": \"0.0.0.0\",\n"
+"            \"sender-port\": 0,\n"
+"            \"server-ip\": \"127.0.0.1\",\n"
+"            \"server-port\": 53001\n"
+"        },\n"
+"        \"dhcp-queue-control\": {\n"
+"            \"capacity\": 64,\n"
+"            \"enable-queue\": false,\n"
+"            \"queue-type\": \"kea-ring4\"\n"
+"        },\n"
+"        \"dhcp4o6-port\": 0,\n"
+"        \"early-global-reservations-lookup\": false,\n"
+"        \"echo-client-id\": true,\n"
+"        \"expired-leases-processing\": {\n"
+"            \"flush-reclaimed-timer-wait-time\": 25,\n"
+"            \"hold-reclaimed-time\": 3600,\n"
+"            \"max-reclaim-leases\": 100,\n"
+"            \"max-reclaim-time\": 250,\n"
+"            \"reclaim-timer-wait-time\": 10,\n"
+"            \"unwarned-reclaim-cycles\": 5\n"
+"        },\n"
+"        \"hooks-libraries\": [ ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
+"        \"hostname-char-replacement\": \"\",\n"
+"        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"ip-reservations-unique\": true,\n"
+"        \"lease-database\": {\n"
+"            \"type\": \"memfile\"\n"
+"        },\n"
+"        \"match-client-id\": true,\n"
+"        \"max-valid-lifetime\": 5000,\n"
+"        \"min-valid-lifetime\": 3000,\n"
+"        \"multi-threading\": {\n"
+"            \"enable-multi-threading\": true,\n"
+"            \"packet-queue-size\": 64,\n"
+"            \"thread-pool-size\": 0\n"
+"        },\n"
+"        \"next-server\": \"0.0.0.0\",\n"
+"        \"option-data\": [ ],\n"
+"        \"option-def\": [ ],\n"
+"        \"parked-packet-limit\": 256,\n"
+"        \"rebind-timer\": 2000,\n"
 "        \"renew-timer\": 1000,\n"
 "        \"reservations-global\": false,\n"
 "        \"reservations-in-subnet\": true,\n"
@@ -2691,8 +2876,8 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"allocator\": \"iterative\",\n"
 "                \"calculate-tee-times\": false,\n"
 "                \"id\": 1,\n"
-"                \"max-valid-lifetime\": 4000,\n"
-"                \"min-valid-lifetime\": 4000,\n"
+"                \"max-valid-lifetime\": 5000,\n"
+"                \"min-valid-lifetime\": 3000,\n"
 "                \"option-data\": [ ],\n"
 "                \"pools\": [\n"
 "                    {\n"
@@ -2700,6 +2885,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                        \"pool\": \"192.0.2.1-192.0.2.100\"\n"
 "                    }\n"
 "                ],\n"
+"                \"rebind-timer\": 2000,\n"
 "                \"relay\": {\n"
 "                    \"ip-addresses\": [ ]\n"
 "                },\n"
@@ -2716,7 +2902,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 3
+    // CONFIGURATION 4
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -2770,8 +2956,6 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"type\": \"memfile\"\n"
 "        },\n"
 "        \"match-client-id\": true,\n"
-"        \"max-valid-lifetime\": 5000,\n"
-"        \"min-valid-lifetime\": 3000,\n"
 "        \"multi-threading\": {\n"
 "            \"enable-multi-threading\": true,\n"
 "            \"packet-queue-size\": 64,\n"
@@ -2806,8 +2990,92 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"allocator\": \"iterative\",\n"
 "                \"calculate-tee-times\": false,\n"
 "                \"id\": 1,\n"
-"                \"max-valid-lifetime\": 5000,\n"
-"                \"min-valid-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"192.0.4.101-192.0.4.150\"\n"
+"                    }\n"
+"                ],\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"192.0.4.0/24\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.875,\n"
+"                \"valid-lifetime\": 4000\n"
+"            },\n"
+"            {\n"
+"                \"4o6-interface\": \"\",\n"
+"                \"4o6-interface-id\": \"\",\n"
+"                \"4o6-subnet\": \"\",\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": false,\n"
+"                \"id\": 34,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"192.0.5.101-192.0.5.150\"\n"
+"                    }\n"
+"                ],\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"192.0.5.0/24\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.875,\n"
+"                \"valid-lifetime\": 4000\n"
+"            },\n"
+"            {\n"
+"                \"4o6-interface\": \"\",\n"
+"                \"4o6-interface-id\": \"\",\n"
+"                \"4o6-subnet\": \"\",\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": false,\n"
+"                \"id\": 100,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"192.0.3.101-192.0.3.150\"\n"
+"                    }\n"
+"                ],\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"192.0.3.0/24\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.875,\n"
+"                \"valid-lifetime\": 4000\n"
+"            },\n"
+"            {\n"
+"                \"4o6-interface\": \"\",\n"
+"                \"4o6-interface-id\": \"\",\n"
+"                \"4o6-subnet\": \"\",\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": false,\n"
+"                \"id\": 1024,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
 "                \"option-data\": [ ],\n"
 "                \"pools\": [\n"
 "                    {\n"
@@ -2832,7 +3100,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 4
+    // CONFIGURATION 5
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -2926,7 +3194,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"pools\": [\n"
 "                    {\n"
 "                        \"option-data\": [ ],\n"
-"                        \"pool\": \"192.0.4.101-192.0.4.150\"\n"
+"                        \"pool\": \"192.0.2.1-192.0.2.100\"\n"
 "                    }\n"
 "                ],\n"
 "                \"rebind-timer\": 2000,\n"
@@ -2936,7 +3204,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"reservations\": [ ],\n"
 "                \"store-extended-info\": false,\n"
-"                \"subnet\": \"192.0.4.0/24\",\n"
+"                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"t1-percent\": 0.5,\n"
 "                \"t2-percent\": 0.875,\n"
 "                \"valid-lifetime\": 4000\n"
@@ -2947,14 +3215,14 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-subnet\": \"\",\n"
 "                \"allocator\": \"iterative\",\n"
 "                \"calculate-tee-times\": false,\n"
-"                \"id\": 34,\n"
+"                \"id\": 2,\n"
 "                \"max-valid-lifetime\": 4000,\n"
 "                \"min-valid-lifetime\": 4000,\n"
 "                \"option-data\": [ ],\n"
 "                \"pools\": [\n"
 "                    {\n"
 "                        \"option-data\": [ ],\n"
-"                        \"pool\": \"192.0.5.101-192.0.5.150\"\n"
+"                        \"pool\": \"192.0.3.101-192.0.3.150\"\n"
 "                    }\n"
 "                ],\n"
 "                \"rebind-timer\": 2000,\n"
@@ -2964,7 +3232,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"reservations\": [ ],\n"
 "                \"store-extended-info\": false,\n"
-"                \"subnet\": \"192.0.5.0/24\",\n"
+"                \"subnet\": \"192.0.3.0/24\",\n"
 "                \"t1-percent\": 0.5,\n"
 "                \"t2-percent\": 0.875,\n"
 "                \"valid-lifetime\": 4000\n"
@@ -2975,14 +3243,14 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-subnet\": \"\",\n"
 "                \"allocator\": \"iterative\",\n"
 "                \"calculate-tee-times\": false,\n"
-"                \"id\": 100,\n"
+"                \"id\": 3,\n"
 "                \"max-valid-lifetime\": 4000,\n"
 "                \"min-valid-lifetime\": 4000,\n"
 "                \"option-data\": [ ],\n"
 "                \"pools\": [\n"
 "                    {\n"
 "                        \"option-data\": [ ],\n"
-"                        \"pool\": \"192.0.3.101-192.0.3.150\"\n"
+"                        \"pool\": \"192.0.4.101-192.0.4.150\"\n"
 "                    }\n"
 "                ],\n"
 "                \"rebind-timer\": 2000,\n"
@@ -2992,7 +3260,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"reservations\": [ ],\n"
 "                \"store-extended-info\": false,\n"
-"                \"subnet\": \"192.0.3.0/24\",\n"
+"                \"subnet\": \"192.0.4.0/24\",\n"
 "                \"t1-percent\": 0.5,\n"
 "                \"t2-percent\": 0.875,\n"
 "                \"valid-lifetime\": 4000\n"
@@ -3003,14 +3271,14 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-subnet\": \"\",\n"
 "                \"allocator\": \"iterative\",\n"
 "                \"calculate-tee-times\": false,\n"
-"                \"id\": 1024,\n"
+"                \"id\": 4,\n"
 "                \"max-valid-lifetime\": 4000,\n"
 "                \"min-valid-lifetime\": 4000,\n"
 "                \"option-data\": [ ],\n"
 "                \"pools\": [\n"
 "                    {\n"
 "                        \"option-data\": [ ],\n"
-"                        \"pool\": \"192.0.2.1-192.0.2.100\"\n"
+"                        \"pool\": \"192.0.5.101-192.0.5.150\"\n"
 "                    }\n"
 "                ],\n"
 "                \"rebind-timer\": 2000,\n"
@@ -3020,7 +3288,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"reservations\": [ ],\n"
 "                \"store-extended-info\": false,\n"
-"                \"subnet\": \"192.0.2.0/24\",\n"
+"                \"subnet\": \"192.0.5.0/24\",\n"
 "                \"t1-percent\": 0.5,\n"
 "                \"t2-percent\": 0.875,\n"
 "                \"valid-lifetime\": 4000\n"
@@ -3030,7 +3298,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 5
+    // CONFIGURATION 6
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -3144,7 +3412,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 6
+    // CONFIGURATION 7
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -3261,7 +3529,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 7
+    // CONFIGURATION 8
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -3378,7 +3646,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 8
+    // CONFIGURATION 9
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -3492,7 +3760,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 9
+    // CONFIGURATION 10
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -3606,7 +3874,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 10
+    // CONFIGURATION 11
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -3699,14 +3967,158 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-subnet\": \"\",\n"
 "                \"allocator\": \"iterative\",\n"
 "                \"calculate-tee-times\": false,\n"
-"                \"id\": 1,\n"
+"                \"id\": 1,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"192.0.2.1-192.0.2.100\"\n"
+"                    }\n"
+"                ],\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"192.0.2.0/24\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.875,\n"
+"                \"valid-lifetime\": 4000\n"
+"            }\n"
+"        ],\n"
+"        \"t1-percent\": 0.5,\n"
+"        \"t2-percent\": 0.875,\n"
+"        \"valid-lifetime\": 4000\n"
+"    }\n",
+    // CONFIGURATION 12
+"{\n"
+"        \"allocator\": \"iterative\",\n"
+"        \"authoritative\": false,\n"
+"        \"boot-file-name\": \"\",\n"
+"        \"calculate-tee-times\": false,\n"
+"        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
+"        \"ddns-generated-prefix\": \"myhost\",\n"
+"        \"ddns-override-client-update\": false,\n"
+"        \"ddns-override-no-update\": false,\n"
+"        \"ddns-qualifying-suffix\": \"\",\n"
+"        \"ddns-replace-client-name\": \"never\",\n"
+"        \"ddns-send-updates\": true,\n"
+"        \"ddns-update-on-renew\": false,\n"
+"        \"decline-probation-period\": 86400,\n"
+"        \"dhcp-ddns\": {\n"
+"            \"enable-updates\": false,\n"
+"            \"max-queue-size\": 1024,\n"
+"            \"ncr-format\": \"JSON\",\n"
+"            \"ncr-protocol\": \"UDP\",\n"
+"            \"sender-ip\": \"0.0.0.0\",\n"
+"            \"sender-port\": 0,\n"
+"            \"server-ip\": \"127.0.0.1\",\n"
+"            \"server-port\": 53001\n"
+"        },\n"
+"        \"dhcp-queue-control\": {\n"
+"            \"capacity\": 64,\n"
+"            \"enable-queue\": false,\n"
+"            \"queue-type\": \"kea-ring4\"\n"
+"        },\n"
+"        \"dhcp4o6-port\": 0,\n"
+"        \"early-global-reservations-lookup\": false,\n"
+"        \"echo-client-id\": true,\n"
+"        \"expired-leases-processing\": {\n"
+"            \"flush-reclaimed-timer-wait-time\": 25,\n"
+"            \"hold-reclaimed-time\": 3600,\n"
+"            \"max-reclaim-leases\": 100,\n"
+"            \"max-reclaim-time\": 250,\n"
+"            \"reclaim-timer-wait-time\": 10,\n"
+"            \"unwarned-reclaim-cycles\": 5\n"
+"        },\n"
+"        \"hooks-libraries\": [ ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
+"        \"hostname-char-replacement\": \"\",\n"
+"        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"ip-reservations-unique\": true,\n"
+"        \"lease-database\": {\n"
+"            \"type\": \"memfile\"\n"
+"        },\n"
+"        \"match-client-id\": true,\n"
+"        \"multi-threading\": {\n"
+"            \"enable-multi-threading\": true,\n"
+"            \"packet-queue-size\": 64,\n"
+"            \"thread-pool-size\": 0\n"
+"        },\n"
+"        \"next-server\": \"0.0.0.0\",\n"
+"        \"option-data\": [ ],\n"
+"        \"option-def\": [ ],\n"
+"        \"parked-packet-limit\": 256,\n"
+"        \"rebind-timer\": 2000,\n"
+"        \"renew-timer\": 1000,\n"
+"        \"reservations-global\": false,\n"
+"        \"reservations-in-subnet\": true,\n"
+"        \"reservations-lookup-first\": false,\n"
+"        \"reservations-out-of-pool\": false,\n"
+"        \"sanity-checks\": {\n"
+"            \"extended-info-checks\": \"fix\",\n"
+"            \"lease-checks\": \"warn\"\n"
+"        },\n"
+"        \"server-hostname\": \"\",\n"
+"        \"server-tag\": \"\",\n"
+"        \"shared-networks\": [ ],\n"
+"        \"stash-agent-options\": false,\n"
+"        \"statistic-default-sample-age\": 0,\n"
+"        \"statistic-default-sample-count\": 20,\n"
+"        \"store-extended-info\": false,\n"
+"        \"subnet4\": [\n"
+"            {\n"
+"                \"4o6-interface\": \"\",\n"
+"                \"4o6-interface-id\": \"\",\n"
+"                \"4o6-subnet\": \"\",\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": false,\n"
+"                \"id\": 1,\n"
+"                \"match-client-id\": true,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"192.0.2.1-192.0.2.100\"\n"
+"                    }\n"
+"                ],\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"192.0.2.0/24\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.875,\n"
+"                \"valid-lifetime\": 4000\n"
+"            },\n"
+"            {\n"
+"                \"4o6-interface\": \"\",\n"
+"                \"4o6-interface-id\": \"\",\n"
+"                \"4o6-subnet\": \"\",\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": false,\n"
+"                \"id\": 2,\n"
+"                \"match-client-id\": false,\n"
 "                \"max-valid-lifetime\": 4000,\n"
 "                \"min-valid-lifetime\": 4000,\n"
 "                \"option-data\": [ ],\n"
 "                \"pools\": [\n"
 "                    {\n"
 "                        \"option-data\": [ ],\n"
-"                        \"pool\": \"192.0.2.1-192.0.2.100\"\n"
+"                        \"pool\": \"192.0.3.1-192.0.3.100\"\n"
 "                    }\n"
 "                ],\n"
 "                \"rebind-timer\": 2000,\n"
@@ -3716,7 +4128,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"reservations\": [ ],\n"
 "                \"store-extended-info\": false,\n"
-"                \"subnet\": \"192.0.2.0/24\",\n"
+"                \"subnet\": \"192.0.3.0/24\",\n"
 "                \"t1-percent\": 0.5,\n"
 "                \"t2-percent\": 0.875,\n"
 "                \"valid-lifetime\": 4000\n"
@@ -3726,7 +4138,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 11
+    // CONFIGURATION 13
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -3814,7 +4226,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"allocator\": \"iterative\",\n"
 "                \"calculate-tee-times\": false,\n"
 "                \"id\": 1,\n"
-"                \"match-client-id\": true,\n"
+"                \"match-client-id\": false,\n"
 "                \"max-valid-lifetime\": 4000,\n"
 "                \"min-valid-lifetime\": 4000,\n"
 "                \"option-data\": [ ],\n"
@@ -3843,7 +4255,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"allocator\": \"iterative\",\n"
 "                \"calculate-tee-times\": false,\n"
 "                \"id\": 2,\n"
-"                \"match-client-id\": false,\n"
 "                \"max-valid-lifetime\": 4000,\n"
 "                \"min-valid-lifetime\": 4000,\n"
 "                \"option-data\": [ ],\n"
@@ -3870,7 +4281,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 12
+    // CONFIGURATION 14
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -3956,9 +4367,9 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"allocator\": \"iterative\",\n"
+"                \"authoritative\": true,\n"
 "                \"calculate-tee-times\": false,\n"
 "                \"id\": 1,\n"
-"                \"match-client-id\": false,\n"
 "                \"max-valid-lifetime\": 4000,\n"
 "                \"min-valid-lifetime\": 4000,\n"
 "                \"option-data\": [ ],\n"
@@ -3985,6 +4396,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"allocator\": \"iterative\",\n"
+"                \"authoritative\": false,\n"
 "                \"calculate-tee-times\": false,\n"
 "                \"id\": 2,\n"
 "                \"max-valid-lifetime\": 4000,\n"
@@ -4013,10 +4425,10 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 13
+    // CONFIGURATION 15
 "{\n"
 "        \"allocator\": \"iterative\",\n"
-"        \"authoritative\": false,\n"
+"        \"authoritative\": true,\n"
 "        \"boot-file-name\": \"\",\n"
 "        \"calculate-tee-times\": false,\n"
 "        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
@@ -4099,7 +4511,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"allocator\": \"iterative\",\n"
-"                \"authoritative\": true,\n"
+"                \"authoritative\": false,\n"
 "                \"calculate-tee-times\": false,\n"
 "                \"id\": 1,\n"
 "                \"max-valid-lifetime\": 4000,\n"
@@ -4128,7 +4540,6 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"allocator\": \"iterative\",\n"
-"                \"authoritative\": false,\n"
 "                \"calculate-tee-times\": false,\n"
 "                \"id\": 2,\n"
 "                \"max-valid-lifetime\": 4000,\n"
@@ -4157,10 +4568,10 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 14
+    // CONFIGURATION 16
 "{\n"
 "        \"allocator\": \"iterative\",\n"
-"        \"authoritative\": true,\n"
+"        \"authoritative\": false,\n"
 "        \"boot-file-name\": \"\",\n"
 "        \"calculate-tee-times\": false,\n"
 "        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
@@ -4211,6 +4622,8 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"type\": \"memfile\"\n"
 "        },\n"
 "        \"match-client-id\": true,\n"
+"        \"max-valid-lifetime\": 5000,\n"
+"        \"min-valid-lifetime\": 3000,\n"
 "        \"multi-threading\": {\n"
 "            \"enable-multi-threading\": true,\n"
 "            \"packet-queue-size\": 64,\n"
@@ -4243,11 +4656,10 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
 "                \"allocator\": \"iterative\",\n"
-"                \"authoritative\": false,\n"
 "                \"calculate-tee-times\": false,\n"
 "                \"id\": 1,\n"
-"                \"max-valid-lifetime\": 4000,\n"
-"                \"min-valid-lifetime\": 4000,\n"
+"                \"max-valid-lifetime\": 5,\n"
+"                \"min-valid-lifetime\": 3,\n"
 "                \"option-data\": [ ],\n"
 "                \"pools\": [\n"
 "                    {\n"
@@ -4255,52 +4667,24 @@ const char* UNPARSED_CONFIGS[] = {
 "                        \"pool\": \"192.0.2.1-192.0.2.100\"\n"
 "                    }\n"
 "                ],\n"
-"                \"rebind-timer\": 2000,\n"
+"                \"rebind-timer\": 2,\n"
 "                \"relay\": {\n"
 "                    \"ip-addresses\": [ ]\n"
 "                },\n"
-"                \"renew-timer\": 1000,\n"
+"                \"renew-timer\": 1,\n"
 "                \"reservations\": [ ],\n"
 "                \"store-extended-info\": false,\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"t1-percent\": 0.5,\n"
 "                \"t2-percent\": 0.875,\n"
-"                \"valid-lifetime\": 4000\n"
-"            },\n"
-"            {\n"
-"                \"4o6-interface\": \"\",\n"
-"                \"4o6-interface-id\": \"\",\n"
-"                \"4o6-subnet\": \"\",\n"
-"                \"allocator\": \"iterative\",\n"
-"                \"calculate-tee-times\": false,\n"
-"                \"id\": 2,\n"
-"                \"max-valid-lifetime\": 4000,\n"
-"                \"min-valid-lifetime\": 4000,\n"
-"                \"option-data\": [ ],\n"
-"                \"pools\": [\n"
-"                    {\n"
-"                        \"option-data\": [ ],\n"
-"                        \"pool\": \"192.0.3.1-192.0.3.100\"\n"
-"                    }\n"
-"                ],\n"
-"                \"rebind-timer\": 2000,\n"
-"                \"relay\": {\n"
-"                    \"ip-addresses\": [ ]\n"
-"                },\n"
-"                \"renew-timer\": 1000,\n"
-"                \"reservations\": [ ],\n"
-"                \"store-extended-info\": false,\n"
-"                \"subnet\": \"192.0.3.0/24\",\n"
-"                \"t1-percent\": 0.5,\n"
-"                \"t2-percent\": 0.875,\n"
-"                \"valid-lifetime\": 4000\n"
+"                \"valid-lifetime\": 4\n"
 "            }\n"
 "        ],\n"
 "        \"t1-percent\": 0.5,\n"
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 15
+    // CONFIGURATION 17
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -4354,8 +4738,6 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"type\": \"memfile\"\n"
 "        },\n"
 "        \"match-client-id\": true,\n"
-"        \"max-valid-lifetime\": 5000,\n"
-"        \"min-valid-lifetime\": 3000,\n"
 "        \"multi-threading\": {\n"
 "            \"enable-multi-threading\": true,\n"
 "            \"packet-queue-size\": 64,\n"
@@ -4390,8 +4772,9 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"allocator\": \"iterative\",\n"
 "                \"calculate-tee-times\": false,\n"
 "                \"id\": 1,\n"
-"                \"max-valid-lifetime\": 5,\n"
-"                \"min-valid-lifetime\": 3,\n"
+"                \"interface\": \"eth0\",\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
 "                \"option-data\": [ ],\n"
 "                \"pools\": [\n"
 "                    {\n"
@@ -4399,24 +4782,24 @@ const char* UNPARSED_CONFIGS[] = {
 "                        \"pool\": \"192.0.2.1-192.0.2.100\"\n"
 "                    }\n"
 "                ],\n"
-"                \"rebind-timer\": 2,\n"
+"                \"rebind-timer\": 2000,\n"
 "                \"relay\": {\n"
 "                    \"ip-addresses\": [ ]\n"
 "                },\n"
-"                \"renew-timer\": 1,\n"
+"                \"renew-timer\": 1000,\n"
 "                \"reservations\": [ ],\n"
 "                \"store-extended-info\": false,\n"
 "                \"subnet\": \"192.0.2.0/24\",\n"
 "                \"t1-percent\": 0.5,\n"
 "                \"t2-percent\": 0.875,\n"
-"                \"valid-lifetime\": 4\n"
+"                \"valid-lifetime\": 4000\n"
 "            }\n"
 "        ],\n"
 "        \"t1-percent\": 0.5,\n"
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 16
+    // CONFIGURATION 18
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -4566,7 +4949,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 17
+    // CONFIGURATION 19
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -4680,7 +5063,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 18
+    // CONFIGURATION 20
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -4773,7 +5156,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 19
+    // CONFIGURATION 21
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -4866,7 +5249,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 20
+    // CONFIGURATION 22
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -4968,7 +5351,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 21
+    // CONFIGURATION 23
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -5061,7 +5444,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 22
+    // CONFIGURATION 24
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -5154,7 +5537,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 23
+    // CONFIGURATION 25
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -5247,7 +5630,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 24
+    // CONFIGURATION 26
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -5340,7 +5723,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 25
+    // CONFIGURATION 27
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -5473,7 +5856,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 26
+    // CONFIGURATION 28
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -5606,7 +5989,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 27
+    // CONFIGURATION 29
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -5749,7 +6132,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 28
+    // CONFIGURATION 30
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -5872,7 +6255,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 29
+    // CONFIGURATION 31
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -6042,7 +6425,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 3000\n"
 "    }\n",
-    // CONFIGURATION 30
+    // CONFIGURATION 32
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -6185,7 +6568,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 31
+    // CONFIGURATION 33
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -6347,7 +6730,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 32
+    // CONFIGURATION 34
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -6480,7 +6863,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 33
+    // CONFIGURATION 35
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -6618,7 +7001,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 34
+    // CONFIGURATION 36
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -6751,7 +7134,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 35
+    // CONFIGURATION 37
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -6874,7 +7257,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 36
+    // CONFIGURATION 38
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -7035,7 +7418,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 3000\n"
 "    }\n",
-    // CONFIGURATION 37
+    // CONFIGURATION 39
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -7166,7 +7549,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 38
+    // CONFIGURATION 40
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -7271,121 +7654,36 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"4o6-interface\": \"\",\n"
 "                \"4o6-interface-id\": \"\",\n"
 "                \"4o6-subnet\": \"\",\n"
-"                \"allocator\": \"iterative\",\n"
-"                \"calculate-tee-times\": false,\n"
-"                \"id\": 1,\n"
-"                \"max-valid-lifetime\": 4000,\n"
-"                \"min-valid-lifetime\": 4000,\n"
-"                \"option-data\": [ ],\n"
-"                \"pools\": [\n"
-"                    {\n"
-"                        \"option-data\": [ ],\n"
-"                        \"pool\": \"192.0.2.1-192.0.2.100\"\n"
-"                    }\n"
-"                ],\n"
-"                \"rebind-timer\": 2000,\n"
-"                \"relay\": {\n"
-"                    \"ip-addresses\": [ ]\n"
-"                },\n"
-"                \"renew-timer\": 1000,\n"
-"                \"reservations\": [ ],\n"
-"                \"store-extended-info\": false,\n"
-"                \"subnet\": \"192.0.2.0/24\",\n"
-"                \"t1-percent\": 0.5,\n"
-"                \"t2-percent\": 0.875,\n"
-"                \"valid-lifetime\": 4000\n"
-"            }\n"
-"        ],\n"
-"        \"t1-percent\": 0.5,\n"
-"        \"t2-percent\": 0.875,\n"
-"        \"valid-lifetime\": 4000\n"
-"    }\n",
-    // CONFIGURATION 39
-"{\n"
-"        \"allocator\": \"iterative\",\n"
-"        \"authoritative\": false,\n"
-"        \"boot-file-name\": \"\",\n"
-"        \"calculate-tee-times\": false,\n"
-"        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
-"        \"ddns-generated-prefix\": \"myhost\",\n"
-"        \"ddns-override-client-update\": false,\n"
-"        \"ddns-override-no-update\": false,\n"
-"        \"ddns-qualifying-suffix\": \"\",\n"
-"        \"ddns-replace-client-name\": \"never\",\n"
-"        \"ddns-send-updates\": true,\n"
-"        \"ddns-update-on-renew\": false,\n"
-"        \"decline-probation-period\": 86400,\n"
-"        \"dhcp-ddns\": {\n"
-"            \"enable-updates\": false,\n"
-"            \"max-queue-size\": 1024,\n"
-"            \"ncr-format\": \"JSON\",\n"
-"            \"ncr-protocol\": \"UDP\",\n"
-"            \"sender-ip\": \"0.0.0.0\",\n"
-"            \"sender-port\": 0,\n"
-"            \"server-ip\": \"127.0.0.1\",\n"
-"            \"server-port\": 53001\n"
-"        },\n"
-"        \"dhcp-queue-control\": {\n"
-"            \"capacity\": 64,\n"
-"            \"enable-queue\": false,\n"
-"            \"queue-type\": \"kea-ring4\"\n"
-"        },\n"
-"        \"dhcp4o6-port\": 0,\n"
-"        \"early-global-reservations-lookup\": false,\n"
-"        \"echo-client-id\": true,\n"
-"        \"expired-leases-processing\": {\n"
-"            \"flush-reclaimed-timer-wait-time\": 25,\n"
-"            \"hold-reclaimed-time\": 3600,\n"
-"            \"max-reclaim-leases\": 100,\n"
-"            \"max-reclaim-time\": 250,\n"
-"            \"reclaim-timer-wait-time\": 10,\n"
-"            \"unwarned-reclaim-cycles\": 5\n"
-"        },\n"
-"        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
-"        \"hostname-char-replacement\": \"\",\n"
-"        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
-"        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"eth0\", \"eth1\" ],\n"
-"            \"re-detect\": false\n"
-"        },\n"
-"        \"ip-reservations-unique\": true,\n"
-"        \"lease-database\": {\n"
-"            \"type\": \"memfile\"\n"
-"        },\n"
-"        \"match-client-id\": true,\n"
-"        \"multi-threading\": {\n"
-"            \"enable-multi-threading\": true,\n"
-"            \"packet-queue-size\": 64,\n"
-"            \"thread-pool-size\": 0\n"
-"        },\n"
-"        \"next-server\": \"0.0.0.0\",\n"
-"        \"option-data\": [ ],\n"
-"        \"option-def\": [ ],\n"
-"        \"parked-packet-limit\": 256,\n"
-"        \"rebind-timer\": 2000,\n"
-"        \"renew-timer\": 1000,\n"
-"        \"reservations-global\": false,\n"
-"        \"reservations-in-subnet\": true,\n"
-"        \"reservations-lookup-first\": false,\n"
-"        \"reservations-out-of-pool\": false,\n"
-"        \"sanity-checks\": {\n"
-"            \"extended-info-checks\": \"fix\",\n"
-"            \"lease-checks\": \"warn\"\n"
-"        },\n"
-"        \"server-hostname\": \"\",\n"
-"        \"server-tag\": \"\",\n"
-"        \"shared-networks\": [ ],\n"
-"        \"stash-agent-options\": false,\n"
-"        \"statistic-default-sample-age\": 0,\n"
-"        \"statistic-default-sample-count\": 20,\n"
-"        \"store-extended-info\": false,\n"
-"        \"subnet4\": [ ],\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": false,\n"
+"                \"id\": 1,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"192.0.2.1-192.0.2.100\"\n"
+"                    }\n"
+"                ],\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"192.0.2.0/24\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.875,\n"
+"                \"valid-lifetime\": 4000\n"
+"            }\n"
+"        ],\n"
 "        \"t1-percent\": 0.5,\n"
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 40
+    // CONFIGURATION 41
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -7431,7 +7729,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hostname-char-replacement\": \"\",\n"
 "        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\", \"eth0\", \"eth1\" ],\n"
+"            \"interfaces\": [ \"eth0\", \"eth1\" ],\n"
 "            \"re-detect\": false\n"
 "        },\n"
 "        \"ip-reservations-unique\": true,\n"
@@ -7470,7 +7768,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 41
+    // CONFIGURATION 42
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -7486,14 +7784,14 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"ddns-update-on-renew\": false,\n"
 "        \"decline-probation-period\": 86400,\n"
 "        \"dhcp-ddns\": {\n"
-"            \"enable-updates\": true,\n"
-"            \"max-queue-size\": 2048,\n"
+"            \"enable-updates\": false,\n"
+"            \"max-queue-size\": 1024,\n"
 "            \"ncr-format\": \"JSON\",\n"
 "            \"ncr-protocol\": \"UDP\",\n"
-"            \"sender-ip\": \"192.168.2.2\",\n"
-"            \"sender-port\": 778,\n"
-"            \"server-ip\": \"192.168.2.1\",\n"
-"            \"server-port\": 777\n"
+"            \"sender-ip\": \"0.0.0.0\",\n"
+"            \"sender-port\": 0,\n"
+"            \"server-ip\": \"127.0.0.1\",\n"
+"            \"server-port\": 53001\n"
 "        },\n"
 "        \"dhcp-queue-control\": {\n"
 "            \"capacity\": 64,\n"
@@ -7516,7 +7814,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hostname-char-replacement\": \"\",\n"
 "        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ],\n"
+"            \"interfaces\": [ \"*\", \"eth0\", \"eth1\" ],\n"
 "            \"re-detect\": false\n"
 "        },\n"
 "        \"ip-reservations-unique\": true,\n"
@@ -7550,41 +7848,12 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"statistic-default-sample-age\": 0,\n"
 "        \"statistic-default-sample-count\": 20,\n"
 "        \"store-extended-info\": false,\n"
-"        \"subnet4\": [\n"
-"            {\n"
-"                \"4o6-interface\": \"\",\n"
-"                \"4o6-interface-id\": \"\",\n"
-"                \"4o6-subnet\": \"\",\n"
-"                \"allocator\": \"iterative\",\n"
-"                \"calculate-tee-times\": false,\n"
-"                \"id\": 1,\n"
-"                \"max-valid-lifetime\": 4000,\n"
-"                \"min-valid-lifetime\": 4000,\n"
-"                \"option-data\": [ ],\n"
-"                \"pools\": [\n"
-"                    {\n"
-"                        \"option-data\": [ ],\n"
-"                        \"pool\": \"192.0.2.1-192.0.2.100\"\n"
-"                    }\n"
-"                ],\n"
-"                \"rebind-timer\": 2000,\n"
-"                \"relay\": {\n"
-"                    \"ip-addresses\": [ ]\n"
-"                },\n"
-"                \"renew-timer\": 1000,\n"
-"                \"reservations\": [ ],\n"
-"                \"store-extended-info\": false,\n"
-"                \"subnet\": \"192.0.2.0/24\",\n"
-"                \"t1-percent\": 0.5,\n"
-"                \"t2-percent\": 0.875,\n"
-"                \"valid-lifetime\": 4000\n"
-"            }\n"
-"        ],\n"
+"        \"subnet4\": [ ],\n"
 "        \"t1-percent\": 0.5,\n"
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 42
+    // CONFIGURATION 43
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -7698,7 +7967,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 43
+    // CONFIGURATION 44
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -7812,7 +8081,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 44
+    // CONFIGURATION 45
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -8013,7 +8282,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 45
+    // CONFIGURATION 46
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -8142,7 +8411,121 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 46
+    // CONFIGURATION 47
+"{\n"
+"        \"allocator\": \"iterative\",\n"
+"        \"authoritative\": false,\n"
+"        \"boot-file-name\": \"\",\n"
+"        \"calculate-tee-times\": false,\n"
+"        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
+"        \"ddns-generated-prefix\": \"myhost\",\n"
+"        \"ddns-override-client-update\": false,\n"
+"        \"ddns-override-no-update\": false,\n"
+"        \"ddns-qualifying-suffix\": \"\",\n"
+"        \"ddns-replace-client-name\": \"never\",\n"
+"        \"ddns-send-updates\": true,\n"
+"        \"ddns-update-on-renew\": false,\n"
+"        \"decline-probation-period\": 86400,\n"
+"        \"dhcp-ddns\": {\n"
+"            \"enable-updates\": true,\n"
+"            \"max-queue-size\": 2048,\n"
+"            \"ncr-format\": \"JSON\",\n"
+"            \"ncr-protocol\": \"UDP\",\n"
+"            \"sender-ip\": \"192.168.2.2\",\n"
+"            \"sender-port\": 778,\n"
+"            \"server-ip\": \"192.168.2.1\",\n"
+"            \"server-port\": 777\n"
+"        },\n"
+"        \"dhcp-queue-control\": {\n"
+"            \"capacity\": 64,\n"
+"            \"enable-queue\": false,\n"
+"            \"queue-type\": \"kea-ring4\"\n"
+"        },\n"
+"        \"dhcp4o6-port\": 0,\n"
+"        \"early-global-reservations-lookup\": false,\n"
+"        \"echo-client-id\": true,\n"
+"        \"expired-leases-processing\": {\n"
+"            \"flush-reclaimed-timer-wait-time\": 25,\n"
+"            \"hold-reclaimed-time\": 3600,\n"
+"            \"max-reclaim-leases\": 100,\n"
+"            \"max-reclaim-time\": 250,\n"
+"            \"reclaim-timer-wait-time\": 10,\n"
+"            \"unwarned-reclaim-cycles\": 5\n"
+"        },\n"
+"        \"hooks-libraries\": [ ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
+"        \"hostname-char-replacement\": \"\",\n"
+"        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"ip-reservations-unique\": true,\n"
+"        \"lease-database\": {\n"
+"            \"type\": \"memfile\"\n"
+"        },\n"
+"        \"match-client-id\": true,\n"
+"        \"multi-threading\": {\n"
+"            \"enable-multi-threading\": true,\n"
+"            \"packet-queue-size\": 64,\n"
+"            \"thread-pool-size\": 0\n"
+"        },\n"
+"        \"next-server\": \"0.0.0.0\",\n"
+"        \"option-data\": [ ],\n"
+"        \"option-def\": [ ],\n"
+"        \"parked-packet-limit\": 256,\n"
+"        \"rebind-timer\": 2000,\n"
+"        \"renew-timer\": 1000,\n"
+"        \"reservations-global\": false,\n"
+"        \"reservations-in-subnet\": true,\n"
+"        \"reservations-lookup-first\": false,\n"
+"        \"reservations-out-of-pool\": false,\n"
+"        \"sanity-checks\": {\n"
+"            \"extended-info-checks\": \"fix\",\n"
+"            \"lease-checks\": \"warn\"\n"
+"        },\n"
+"        \"server-hostname\": \"\",\n"
+"        \"server-tag\": \"\",\n"
+"        \"shared-networks\": [ ],\n"
+"        \"stash-agent-options\": false,\n"
+"        \"statistic-default-sample-age\": 0,\n"
+"        \"statistic-default-sample-count\": 20,\n"
+"        \"store-extended-info\": false,\n"
+"        \"subnet4\": [\n"
+"            {\n"
+"                \"4o6-interface\": \"\",\n"
+"                \"4o6-interface-id\": \"\",\n"
+"                \"4o6-subnet\": \"\",\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": false,\n"
+"                \"id\": 1,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"192.0.2.1-192.0.2.100\"\n"
+"                    }\n"
+"                ],\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"192.0.2.0/24\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.875,\n"
+"                \"valid-lifetime\": 4000\n"
+"            }\n"
+"        ],\n"
+"        \"t1-percent\": 0.5,\n"
+"        \"t2-percent\": 0.875,\n"
+"        \"valid-lifetime\": 4000\n"
+"    }\n",
+    // CONFIGURATION 48
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -8421,7 +8804,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 47
+    // CONFIGURATION 49
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -8566,7 +8949,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 48
+    // CONFIGURATION 50
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -8864,7 +9247,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 49
+    // CONFIGURATION 51
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -9009,7 +9392,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 50
+    // CONFIGURATION 52
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -9092,7 +9475,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 51
+    // CONFIGURATION 53
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -9175,7 +9558,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 52
+    // CONFIGURATION 54
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -9258,7 +9641,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 53
+    // CONFIGURATION 55
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -9341,7 +9724,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 54
+    // CONFIGURATION 56
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -9455,7 +9838,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 55
+    // CONFIGURATION 57
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -9569,7 +9952,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 56
+    // CONFIGURATION 58
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -9683,7 +10066,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 57
+    // CONFIGURATION 59
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -9797,7 +10180,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 58
+    // CONFIGURATION 60
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -9911,7 +10294,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 59
+    // CONFIGURATION 61
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -10051,7 +10434,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 60
+    // CONFIGURATION 62
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -10182,7 +10565,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 61
+    // CONFIGURATION 63
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -10315,7 +10698,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 62
+    // CONFIGURATION 64
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -10429,7 +10812,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 63
+    // CONFIGURATION 65
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -10544,7 +10927,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 64
+    // CONFIGURATION 66
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -10663,7 +11046,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 65
+    // CONFIGURATION 67
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -10782,7 +11165,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 66
+    // CONFIGURATION 68
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -10882,7 +11265,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 67
+    // CONFIGURATION 69
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -11147,7 +11530,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        },\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 68
+    // CONFIGURATION 70
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -11348,7 +11731,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 69
+    // CONFIGURATION 71
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -11528,7 +11911,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 70
+    // CONFIGURATION 72
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -11670,7 +12053,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 71
+    // CONFIGURATION 73
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -11812,7 +12195,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 72
+    // CONFIGURATION 74
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -11897,7 +12280,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 73
+    // CONFIGURATION 75
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -11980,7 +12363,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 74
+    // CONFIGURATION 76
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
@@ -12063,7 +12446,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.875,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 75
+    // CONFIGURATION 77
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"authoritative\": false,\n"
index d60f09d8e86e14546641fa442b3b37809177b9b4..9f98f07ce0883df41cc471c4397a6e6617c18641 100644 (file)
@@ -15,6 +15,7 @@
 #include <dhcp/option_custom.h>
 #include <dhcp/option_int.h>
 #include <dhcp/option6_addrlst.h>
+#include <dhcp/classify.h>
 #include <dhcp/testutils/iface_mgr_test_config.h>
 #include <dhcp6/json_config_parser.h>
 #include <dhcp6/dhcp6_srv.h>
@@ -23,6 +24,7 @@
 #include <dhcpsrv/cfgmgr.h>
 #include <dhcpsrv/cfg_expiration.h>
 #include <dhcpsrv/cfg_hosts.h>
+#include <dhcpsrv/cfg_subnets6.h>
 #include <dhcpsrv/parsers/simple_parser6.h>
 #include <dhcpsrv/subnet.h>
 #include <dhcpsrv/subnet_selector.h>
 #include <testutils/log_utils.h>
 #include <testutils/test_to_element.h>
 #include <util/chrono_time_utils.h>
-
+#include <util/doubles.h>
+#include "marker_file.h"
 #include "test_data_files_config.h"
 #include "test_libraries.h"
-#include "marker_file.h"
 #include "dhcp6_test_utils.h"
 #include "get_config_unittest.h"
-
 #include <gtest/gtest.h>
 
 #include <boost/foreach.hpp>
+#include <boost/scoped_ptr.hpp>
 #include <fstream>
 #include <iostream>
 #include <sstream>
@@ -52,6 +54,7 @@
 #include <vector>
 
 #include <arpa/inet.h>
+#include <limits.h>
 #include <unistd.h>
 
 using namespace isc;
@@ -249,7 +252,7 @@ const char* PARSER_CONFIGS[] = {
     "    ]"
     "}",
 
-    // Configuration 8: config control
+    // Configuration 8: config database
     "{ \n"
     "    \"interfaces-config\": { \n"
     "        \"interfaces\": [\"*\" ] \n"
@@ -296,7 +299,7 @@ const char* PARSER_CONFIGS[] = {
     "        \"comment\": \"Set option value\","
     "        \"name\": \"subscriber-id\","
     "        \"data\": \"ABCDEF0105\","
-    "            \"csv-format\": false"
+    "        \"csv-format\": false"
     "     } ],"
     "    \"client-classes\": ["
     "        {"
@@ -393,8 +396,8 @@ protected:
     }
 
 public:
-    Dhcp6ParserTest() :rcode_(-1), srv_(0) {
-        // srv_(0) means to not open any sockets. We don't want to
+    Dhcp6ParserTest() : rcode_(-1), srv_(0) {
+        // Open port 0 means to not open any sockets. We don't want to
         // deal with sockets here, just check if configuration handling
         // is sane.
 
@@ -414,7 +417,6 @@ public:
                           << " while the test assumes that it doesn't, to execute"
                           << " some negative scenarios. Can't continue this test.";
         }
-
         // Reset configuration for each test.
         resetConfiguration();
     }
@@ -428,16 +430,13 @@ public:
         static_cast<void>(remove(UNLOAD_MARKER_FILE));
     };
 
-    // Checks if config_result (result of DHCP server configuration) has
+    // Checks if the result of DHCP server configuration has
     // expected code (0 for success, other for failures).
     // Also stores result in rcode_ and comment_.
     void checkResult(ConstElementPtr status, int expected_code) {
         ASSERT_TRUE(status);
         comment_ = parseAnswerText(rcode_, status);
-        EXPECT_EQ(expected_code, rcode_);
-        if (expected_code != rcode_) {
-            cout << "The comment returned was: [" << comment_->stringValue() << "]" << endl;
-        }
+        EXPECT_EQ(expected_code, rcode_) << "error text:" << comment_->stringValue();
     }
 
     // Checks if the result of DHCP server configuration has
@@ -488,51 +487,6 @@ public:
         }
     }
 
-    /// @brief Checks if specified subnet is part of the collection
-    ///
-    /// @tparam CollectionType type of subnet6 collections i.e.
-    /// either Subnet6SimpleCollection or Subnet6Collection
-    /// @param col collection of subnets to be inspected
-    /// @param subnet text notation (e.g. 192.0.2.0/24)
-    /// @param t1 expected renew-timer value
-    /// @param t2 expected rebind-timer value
-    /// @param preferred expected preferred-lifetime value
-    /// @param valid expected valid-lifetime value
-    /// @param min_preferred expected min-preferred-lifetime value
-    ///        (0 (default) means same as preferred)
-    /// @param max_preferred expected max-preferred-lifetime value
-    ///        (0 (default) means same as preferred)
-    /// @param min_valid expected min-valid-lifetime value
-    ///        (0 (default) means same as valid)
-    /// @param max_valid expected max-valid-lifetime value
-    ///        (0 (default) means same as valid)
-    /// @return the subnet that was examined
-    template <typename CollectionType>
-    Subnet6Ptr
-    checkSubnet(const CollectionType& col, std::string subnet,
-                uint32_t t1, uint32_t t2, uint32_t pref, uint32_t valid,
-                uint32_t min_pref = 0, uint32_t max_pref = 0,
-                uint32_t min_valid = 0, uint32_t max_valid = 0) {
-        auto const& index = col.template get<SubnetPrefixIndexTag>();
-        auto subnet_it = index.find(subnet);
-        if (subnet_it == index.cend()) {
-            ADD_FAILURE() << "Unable to find expected subnet " << subnet;
-            return (Subnet6Ptr());
-        }
-        Subnet6Ptr s = *subnet_it;
-
-        EXPECT_EQ(t1, s->getT1().get());
-        EXPECT_EQ(t2, s->getT2().get());
-        EXPECT_EQ(pref, s->getPreferred().get());
-        EXPECT_EQ(valid, s->getValid().get());
-        EXPECT_EQ(min_pref ? min_pref : pref, s->getPreferred().getMin());
-        EXPECT_EQ(max_pref ? max_pref : pref, s->getPreferred().getMax());
-        EXPECT_EQ(min_valid ? min_valid : valid, s->getValid().getMin());
-        EXPECT_EQ(max_valid ? max_valid : valid, s->getValid().getMax());
-
-        return (s);
-    }
-
     /// @brief Returns an interface configuration used by the most of the
     /// unit tests.
     std::string genIfaceConfig() const {
@@ -551,6 +505,8 @@ public:
     /// injected into the configuration string.
     /// @param parameter name of the parameter to be configured with
     /// param value.
+    /// @return configuration string containing custom values of parameters
+    /// describing an option.
     std::string createConfigWithOption(const std::string& param_value,
                                        const std::string& parameter) {
         std::map<std::string, std::string> params;
@@ -597,10 +553,9 @@ public:
     /// @return configuration string containing custom values of parameters
     /// describing an option.
     std::string createConfigWithOption(const std::map<std::string,
-                                       std::string>& params)
-    {
+                                       std::string>& params) {
         std::ostringstream stream;
-        stream << "{ " << genIfaceConfig() << ","
+        stream << "{ " << genIfaceConfig() << "," <<
             "\"preferred-lifetime\": 3000,"
             "\"rebind-timer\": 2000, "
             "\"renew-timer\": 1000, "
@@ -611,7 +566,7 @@ public:
             "  \"space\": \"dhcp6\""
             "} ],"
             "\"subnet6\": [ { "
-            "    \"id\": 1, "
+            "    \"id\": 1,"
             "    \"pools\": [ { \"pool\": \"2001:db8:1::/80\" } ],"
             "    \"subnet\": \"2001:db8:1::/64\", "
             "    \"option-data\": [ {";
@@ -628,7 +583,7 @@ public:
             } else if (param.first == "space") {
                 stream << "\"space\": \"" << param.second << "\"";
             } else if (param.first == "code") {
-                stream << "\"code\": " << param.second;;
+                stream << "\"code\": " << param.second;
             } else if (param.first == "data") {
                 stream << "\"data\": \"" << param.second << "\"";
             } else if (param.first == "csv-format") {
@@ -661,8 +616,8 @@ public:
     getOptionFromSubnet(const IOAddress& subnet_address,
                         const uint16_t option_code,
                         const uint16_t expected_options_count = 1) {
-        Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
-            selectSubnet(subnet_address, classify_);
+        Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->
+            getCfgSubnets6()->selectSubnet(subnet_address, classify_);
         if (!subnet) {
             ADD_FAILURE() << "A subnet for the specified address "
                           << subnet_address
@@ -699,126 +654,6 @@ public:
         return (*range.first);
     }
 
-    /// @brief Parse and Execute configuration
-    ///
-    /// Parses a configuration and executes a configuration of the server.
-    /// If the operation fails, the current test will register a failure.
-    ///
-    /// @param config Configuration to parse
-    /// @param operation Operation being performed.  In the case of an error,
-    ///        the error text will include the string "unable to <operation>.".
-    ///
-    /// @return true if the configuration succeeded, false if not.  In the
-    ///         latter case, a failure will have been added to the current test.
-    bool
-    executeConfiguration(const std::string& config, const char* operation) {
-        ConstElementPtr json;
-        ConstElementPtr status;
-        try {
-            json = parseJSON(config);
-            status = Dhcpv6SrvTest::configure(srv_, json);
-
-        } catch (const std::exception& ex) {
-            ADD_FAILURE() << "Unable to " << operation << ". "
-                   << "The following configuration was used: " << std::endl
-                   << config << std::endl
-                   << " and the following error message was returned:"
-                   << ex.what() << std::endl;
-            return (false);
-        }
-
-        // The status object must not be NULL
-        if (!status) {
-            ADD_FAILURE() << "Unable to " << operation << ". "
-                   << "The configuration function returned a null pointer.";
-            return (false);
-        }
-
-        // Store the answer if we need it.
-
-        // Returned value should be 0 (configuration success)
-        comment_ = parseAnswerText(rcode_, status);
-        if (rcode_ != 0) {
-            string reason = "";
-            if (comment_) {
-                reason = string(" (") + comment_->stringValue() + string(")");
-            }
-            ADD_FAILURE() << "Unable to " << operation << ". "
-                   << "The configuration function returned error code "
-                   << rcode_ << reason;
-            return (false);
-        }
-
-        return (true);
-    }
-
-    /// @brief Reset configuration database.
-    ///
-    /// This function resets configuration data base by removing all subnets
-    /// option-data, and hooks libraries. The reset must be performed after each
-    /// test to make sure that contents of the database do not affect the
-    /// results of subsequent tests.
-    void resetConfiguration() {
-        string config = "{ \"interfaces-config\": {"
-            "    \"interfaces\": [ ]"
-            "},"
-            "\"hooks-libraries\": [ ],"
-            "\"preferred-lifetime\": 3000,"
-            "\"rebind-timer\": 2000, "
-            "\"renew-timer\": 1000, "
-            "\"valid-lifetime\": 4000, "
-            "\"subnet6\": [ ], "
-            "\"dhcp-ddns\": { \"enable-updates\" : false }, "
-            "\"option-def\": [ ], "
-            "\"option-data\": [ ] }";
-        CfgMgr::instance().rollback();
-        static_cast<void>(executeConfiguration(config,
-                                               "reset configuration database"));
-        // The default setting is to listen on all interfaces. In order to
-        // properly test interface configuration we disable listening on
-        // all interfaces before each test and later check that this setting
-        // has been overridden by the configuration used in the test.
-        CfgMgr::instance().clear();
-    }
-
-    /// @brief Retrieve an option associated with a host.
-    ///
-    /// The option is retrieved from the "dhcp6" option space.
-    ///
-    /// @param host Reference to a host for which an option should be retrieved.
-    /// @param option_code Option code.
-    /// @tparam ReturnType Type of the pointer object returned.
-    ///
-    /// @return Pointer to an option or NULL pointer if not found.
-    template<typename ReturnType>
-    ReturnType
-    retrieveOption(const Host& host, const uint16_t option_code) const {
-        return (retrieveOption<ReturnType>(host, DHCP6_OPTION_SPACE, option_code));
-    }
-
-    /// @brief Retrieve an option associated with a host.
-    ///
-    /// @param host Reference to a host for which an option should be retrieved.
-    /// @param space Option space from which option should be retrieved.
-    /// @param option_code Option code.
-    /// @tparam ReturnType Type of the pointer object returned.
-    ///
-    /// @return Pointer to an option or NULL pointer if not found.
-    template<typename ReturnType>
-    ReturnType
-    retrieveOption(const Host& host, const std::string& space,
-                   const uint16_t option_code) const {
-        ConstCfgOptionPtr cfg_option = host.getCfgOption6();
-        if (cfg_option) {
-            OptionDescriptor opt_desc = cfg_option->get(space, option_code);
-            if (opt_desc.option_) {
-                return (boost::dynamic_pointer_cast<
-                        typename ReturnType::element_type>(opt_desc.option_));
-            }
-        }
-        return (ReturnType());
-    }
-
     /// @brief Test invalid option parameter value.
     ///
     /// This test function constructs the simple configuration
@@ -929,7 +764,7 @@ public:
         std::string config = createConfigWithOption(params);
         ASSERT_TRUE(executeConfiguration(config, "parse option configuration"));
 
-        // The subnet should now hold one option with the specified code.
+        // The subnet should now hold one option with the specified option code.
         OptionDescriptor desc =
             getOptionFromSubnet(IOAddress("2001:db8:1::5"), option_code);
         ASSERT_TRUE(desc.option_);
@@ -971,50 +806,214 @@ public:
         // Clear any existing configuration.
         CfgMgr::instance().clear();
     }
-
-    /// @brief This utility method attempts to configure using specified
-    ///        config and then returns requested pool from requested subnet
+    /// @brief Parse and Execute configuration
     ///
-    /// @param config configuration to be applied
-    /// @param subnet_index index of the subnet to be returned (0 - the first subnet)
-    /// @param pool_index index of the pool within a subnet (0 - the first pool)
-    /// @param type Pool type (TYPE_NA or TYPE_PD)
-    /// @param pool [out] Pool pointer will be stored here (if found)
-    void getPool(const std::string& config, size_t subnet_index,
-                 size_t pool_index, Lease::Type type, PoolPtr& pool) {
-        ConstElementPtr status;
+    /// Parses a configuration and executes a configuration of the server.
+    /// If the operation fails, the current test will register a failure.
+    ///
+    /// @param config Configuration to parse
+    /// @param operation Operation being performed.  In the case of an error,
+    ///        the error text will include the string "unable to <operation>.".
+    ///
+    /// @return true if the configuration succeeded, false if not.  In the
+    ///         latter case, a failure will have been added to the current test.
+    bool
+    executeConfiguration(const std::string& config, const char* operation) {
+        CfgMgr::instance().clear();
         ConstElementPtr json;
+        ConstElementPtr status;
+        try {
+            json = parseJSON(config);
+            status = Dhcpv6SrvTest::configure(srv_, json);
+        } catch (const std::exception& ex) {
+            ADD_FAILURE() << "Unable to " << operation << ". "
+                   << "The following configuration was used: " << std::endl
+                   << config << std::endl
+                   << " and the following error message was returned:"
+                   << ex.what() << std::endl;
+            return (false);
+        }
 
-        EXPECT_NO_THROW(json = parseDHCP6(config, true));
-        EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json));
-        ASSERT_TRUE(status);
-        checkResult(status, 0);
-
-        ConstCfgSubnets6Ptr subnets6 = CfgMgr::instance().getStagingCfg()->getCfgSubnets6();
-        ASSERT_TRUE(subnets6);
+        // The status object must not be NULL
+        if (!status) {
+            ADD_FAILURE() << "Unable to " << operation << ". "
+                   << "The configuration function returned a null pointer.";
+            return (false);
+        }
 
-        const Subnet6Collection* subnets = subnets6->getAll();
-        ASSERT_TRUE(subnets);
-        ASSERT_GE(subnets->size(), subnet_index + 1);
+        // Store the answer if we need it.
 
-        auto subnet = subnets->begin();
-        // std::advance is not available for subnets iterators.
-        for (size_t i = 0; i < subnet_index; ++i) {
-            subnet = std::next(subnet);
+        // Returned value should be 0 (configuration success)
+        comment_ = parseAnswerText(rcode_, status);
+        if (rcode_ != 0) {
+            string reason = "";
+            if (comment_) {
+                reason = string(" (") + comment_->stringValue() + string(")");
+            }
+            ADD_FAILURE() << "Unable to " << operation << ". "
+                   << "The configuration function returned error code "
+                   << rcode_ << reason;
+            return (false);
         }
-        const PoolCollection pools = (*subnet)->getPools(type);
-        ASSERT_GE(pools.size(), pool_index + 1);
 
-        pool = pools.at(pool_index);
-        EXPECT_TRUE(pool);
+        return (true);
     }
 
-    /// @brief Tests if the current config has a given global parameter value
-    /// @param name name of the global parameter expected to exist
-    /// @param value expected value of the global parameter
-    template <typename ValueType>
-    void checkGlobal(const std::string name, ValueType value) {
-        ConstElementPtr param;
+    /// @brief Reset configuration database.
+    ///
+    /// This function resets configuration data base by removing all subnets
+    /// option-data, and hooks libraries. The reset must be performed after each
+    /// test to make sure that contents of the database do not affect the
+    /// results of subsequent tests.
+    void resetConfiguration() {
+        string config = "{ \"interfaces-config\": {"
+            "    \"interfaces\": [ ]"
+            "},"
+            "\"hooks-libraries\": [ ],"
+            "\"preferred-lifetime\": 3000,"
+            "\"rebind-timer\": 2000, "
+            "\"renew-timer\": 1000, "
+            "\"valid-lifetime\": 4000, "
+            "\"subnet6\": [ ], "
+            "\"dhcp-ddns\": { \"enable-updates\" : false }, "
+            "\"option-def\": [ ], "
+            "\"option-data\": [ ] }";
+        CfgMgr::instance().rollback();
+        static_cast<void>(executeConfiguration(config,
+                                               "reset configuration database"));
+        // The default setting is to listen on all interfaces. In order to
+        // properly test interface configuration we disable listening on
+        // all interfaces before each test and later check that this setting
+        // has been overridden by the configuration used in the test.
+        CfgMgr::instance().clear();
+    }
+
+    /// @brief Retrieve an option associated with a host.
+    ///
+    /// The option is retrieved from the "dhcp6" option space.
+    ///
+    /// @param host Reference to a host for which an option should be retrieved.
+    /// @param option_code Option code.
+    /// @tparam ReturnType Type of the pointer object returned.
+    ///
+    /// @return Pointer to an option or NULL pointer if not found.
+    template<typename ReturnType>
+    ReturnType
+    retrieveOption(const Host& host, const uint16_t option_code) const {
+        return (retrieveOption<ReturnType>(host, DHCP6_OPTION_SPACE, option_code));
+    }
+
+    /// @brief Retrieve an option associated with a host.
+    ///
+    /// @param host Reference to a host for which an option should be retrieved.
+    /// @param space Option space from which option should be retrieved.
+    /// @param option_code Option code.
+    /// @tparam ReturnType Type of the pointer object returned.
+    ///
+    /// @return Pointer to an option or NULL pointer if not found.
+    template<typename ReturnType>
+    ReturnType
+    retrieveOption(const Host& host, const std::string& space,
+                   const uint16_t option_code) const {
+        ConstCfgOptionPtr cfg_option = host.getCfgOption6();
+        if (cfg_option) {
+            OptionDescriptor opt_desc = cfg_option->get(space, option_code);
+            if (opt_desc.option_) {
+                return (boost::dynamic_pointer_cast<
+                        typename ReturnType::element_type>(opt_desc.option_));
+            }
+        }
+        return (ReturnType());
+    }
+
+    /// @brief Checks if specified subnet is part of the collection
+    ///
+    /// @tparam CollectionType type of subnet6 collections i.e.
+    /// either Subnet6SimpleCollection or Subnet6Collection
+    /// @param col collection of subnets to be inspected
+    /// @param subnet text notation (e.g. 192.0.2.0/24)
+    /// @param t1 expected renew-timer value
+    /// @param t2 expected rebind-timer value
+    /// @param preferred expected preferred-lifetime value
+    /// @param valid expected valid-lifetime value
+    /// @param min_preferred expected min-preferred-lifetime value
+    ///        (0 (default) means same as preferred)
+    /// @param max_preferred expected max-preferred-lifetime value
+    ///        (0 (default) means same as preferred)
+    /// @param min_valid expected min-valid-lifetime value
+    ///        (0 (default) means same as valid)
+    /// @param max_valid expected max-valid-lifetime value
+    ///        (0 (default) means same as valid)
+    /// @return the subnet that was examined
+    template <typename CollectionType>
+    Subnet6Ptr
+    checkSubnet(const CollectionType& col, std::string subnet,
+                uint32_t t1, uint32_t t2, uint32_t pref, uint32_t valid,
+                uint32_t min_pref = 0, uint32_t max_pref = 0,
+                uint32_t min_valid = 0, uint32_t max_valid = 0) {
+        auto const& index = col.template get<SubnetPrefixIndexTag>();
+        auto subnet_it = index.find(subnet);
+        if (subnet_it == index.cend()) {
+            ADD_FAILURE() << "Unable to find expected subnet " << subnet;
+            return (Subnet6Ptr());
+        }
+        Subnet6Ptr s = *subnet_it;
+
+        EXPECT_EQ(t1, s->getT1().get());
+        EXPECT_EQ(t2, s->getT2().get());
+        EXPECT_EQ(pref, s->getPreferred().get());
+        EXPECT_EQ(valid, s->getValid().get());
+        EXPECT_EQ(min_pref ? min_pref : pref, s->getPreferred().getMin());
+        EXPECT_EQ(max_pref ? max_pref : pref, s->getPreferred().getMax());
+        EXPECT_EQ(min_valid ? min_valid : valid, s->getValid().getMin());
+        EXPECT_EQ(max_valid ? max_valid : valid, s->getValid().getMax());
+
+        return (s);
+    }
+
+    /// @brief This utility method attempts to configure using specified
+    ///        config and then returns requested pool from requested subnet
+    ///
+    /// @param config configuration to be applied
+    /// @param subnet_index index of the subnet to be returned (0 - the first subnet)
+    /// @param pool_index index of the pool within a subnet (0 - the first pool)
+    /// @param type Pool type (TYPE_NA or TYPE_PD)
+    /// @param pool [out] Pool pointer will be stored here (if found)
+    void getPool(const std::string& config, size_t subnet_index,
+                 size_t pool_index, Lease::Type type, PoolPtr& pool) {
+        ConstElementPtr status;
+        ConstElementPtr json;
+
+        EXPECT_NO_THROW(json = parseDHCP6(config, true));
+        EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json));
+        ASSERT_TRUE(status);
+        checkResult(status, 0);
+
+        ConstCfgSubnets6Ptr subnets6 = CfgMgr::instance().getStagingCfg()->getCfgSubnets6();
+        ASSERT_TRUE(subnets6);
+
+        const Subnet6Collection* subnets = subnets6->getAll();
+        ASSERT_TRUE(subnets);
+        ASSERT_GE(subnets->size(), subnet_index + 1);
+
+        auto subnet = subnets->begin();
+        // std::advance is not available for subnets iterators.
+        for (size_t i = 0; i < subnet_index; ++i) {
+            subnet = std::next(subnet);
+        }
+        const PoolCollection pools = (*subnet)->getPools(type);
+        ASSERT_GE(pools.size(), pool_index + 1);
+
+        pool = pools.at(pool_index);
+        EXPECT_TRUE(pool);
+    }
+
+    /// @brief Tests if the current config has a given global parameter value
+    /// @param name name of the global parameter expected to exist
+    /// @param value expected value of the global parameter
+    template <typename ValueType>
+    void checkGlobal(const std::string name, ValueType value) {
+        ConstElementPtr param;
         ConstElementPtr exp_value;
         param = CfgMgr::instance().getStagingCfg()->getConfiguredGlobal(name);
         ASSERT_TRUE(param) << "global: " << name << ", expected but not found";
@@ -1025,7 +1024,7 @@ public:
                                                << isc::data::prettyPrint(exp_value);
     }
 
-    int rcode_; ///< Return code (see @ref isc::config::parseAnswer)
+    int rcode_;                         ///< Return code from element parsing
     ControlledDhcpv6Srv srv_; ///< Instance of the ControlledDhcp6Srv used during tests
     ConstElementPtr comment_; ///< Comment (see @ref isc::config::parseAnswer)
     string valid_iface_; ///< Valid network interface name (present in system)
@@ -1053,7 +1052,8 @@ TEST_F(Dhcp6ParserTest, bogusCommand) {
 TEST_F(Dhcp6ParserTest, emptyInterfaceConfig) {
 
     ConstElementPtr json;
-    EXPECT_NO_THROW(json = parseDHCP6("{ \"preferred-lifetime\": 3000,"
+    EXPECT_NO_THROW(json = parseDHCP6("{ "
+                                      "\"preferred-lifetime\": 3000,"
                                       "\"rebind-timer\": 2000, "
                                       "\"renew-timer\": 1000, "
                                       "\"valid-lifetime\": 4000 }"));
@@ -1070,7 +1070,7 @@ TEST_F(Dhcp6ParserTest, emptyInterfaceConfig) {
 /// specified (boundary check is done when lifetimes are applied).
 TEST_F(Dhcp6ParserTest, outBoundValidLifetime) {
 
-    string too_small =  "{ " + genIfaceConfig() + "," +
+    string too_small =  "{ " + genIfaceConfig() + ","
         "\"subnet6\": [ { "
         "    \"id\": 1,"
         "    \"pools\": [ { \"pool\": \"2001:db8::/64\" } ],"
@@ -1088,7 +1088,7 @@ TEST_F(Dhcp6ParserTest, outBoundValidLifetime) {
     checkResult(status, 1, expected);
     resetConfiguration();
 
-    string too_large =  "{ " + genIfaceConfig() + "," +
+    string too_large =  "{ " + genIfaceConfig() + ","
         "\"subnet6\": [ { "
         "    \"id\": 1,"
         "    \"pools\": [ { \"pool\": \"2001:db8::/64\" } ],"
@@ -1103,7 +1103,7 @@ TEST_F(Dhcp6ParserTest, outBoundValidLifetime) {
     checkResult(status, 1, expected);
     resetConfiguration();
 
-    string before =  "{ " + genIfaceConfig() + "," +
+    string before =  "{ " + genIfaceConfig() + ","
         "\"subnet6\": [ { "
         "    \"id\": 1,"
         "    \"pools\": [ { \"pool\": \"2001:db8::/64\" } ],"
@@ -1119,7 +1119,7 @@ TEST_F(Dhcp6ParserTest, outBoundValidLifetime) {
     checkResult(status, 1, expected);
     resetConfiguration();
 
-    string after =  "{ " + genIfaceConfig() + "," +
+    string after =  "{ " + genIfaceConfig() + ","
         "\"subnet6\": [ { "
         "    \"id\": 1,"
         "    \"pools\": [ { \"pool\": \"2001:db8::/64\" } ],"
@@ -1135,7 +1135,7 @@ TEST_F(Dhcp6ParserTest, outBoundValidLifetime) {
     checkResult(status, 1, expected);
     resetConfiguration();
 
-    string crossed =  "{ " + genIfaceConfig() + "," +
+    string crossed =  "{ " + genIfaceConfig() + ","
         "\"subnet6\": [ { "
         "    \"id\": 1,"
         "    \"pools\": [ { \"pool\": \"2001:db8::/64\" } ],"
@@ -1156,7 +1156,7 @@ TEST_F(Dhcp6ParserTest, outBoundValidLifetime) {
 /// parameters only.
 TEST_F(Dhcp6ParserTest, outBoundGlobalValidLifetime) {
 
-    string too_small =  "{ " + genIfaceConfig() + "," +
+    string too_small =  "{ " + genIfaceConfig() + ","
         "\"valid-lifetime\": 1000, \"min-valid-lifetime\": 2000 }";
 
     ConstElementPtr json;
@@ -1170,7 +1170,7 @@ TEST_F(Dhcp6ParserTest, outBoundGlobalValidLifetime) {
     checkResult(status, 1, expected);
     resetConfiguration();
 
-    string too_large =  "{ " + genIfaceConfig() + "," +
+    string too_large =  "{ " + genIfaceConfig() + ","
         "\"valid-lifetime\": 2000, \"max-valid-lifetime\": 1000 }";
 
     ASSERT_NO_THROW(json = parseDHCP6(too_large));
@@ -1181,7 +1181,7 @@ TEST_F(Dhcp6ParserTest, outBoundGlobalValidLifetime) {
     checkResult(status, 1, expected);
     resetConfiguration();
 
-    string before =  "{ " + genIfaceConfig() + "," +
+    string before =  "{ " + genIfaceConfig() + ","
         "\"valid-lifetime\": 1000, \"min-valid-lifetime\": 2000, "
         "\"max-valid-lifetime\": 4000 }";
 
@@ -1193,7 +1193,7 @@ TEST_F(Dhcp6ParserTest, outBoundGlobalValidLifetime) {
     checkResult(status, 1, expected);
     resetConfiguration();
 
-    string after =  "{ " + genIfaceConfig() + "," +
+    string after =  "{ " + genIfaceConfig() + ","
         "\"valid-lifetime\": 5000, \"min-valid-lifetime\": 1000, "
         "\"max-valid-lifetime\": 4000 }";
 
@@ -1205,7 +1205,7 @@ TEST_F(Dhcp6ParserTest, outBoundGlobalValidLifetime) {
     checkResult(status, 1, expected);
     resetConfiguration();
 
-    string crossed =  "{ " + genIfaceConfig() + "," +
+    string crossed =  "{ " + genIfaceConfig() + ","
         "\"valid-lifetime\": 1500, \"min-valid-lifetime\": 2000, "
         "\"max-valid-lifetime\": 1000 }";
 
@@ -1217,12 +1217,81 @@ TEST_F(Dhcp6ParserTest, outBoundGlobalValidLifetime) {
     checkResult(status, 1, expected);
 }
 
+/// Check that the renew-timer doesn't have to be specified, in which case
+/// it is marked unspecified in the Subnet.
+TEST_F(Dhcp6ParserTest, unspecifiedRenewTimer) {
+
+    string config = "{ " + genIfaceConfig() + ","
+        "\"rebind-timer\": 2000, "
+        "\"subnet6\": [ { "
+        "    \"id\": 1,"
+        "    \"pools\": [ { \"pool\": \"2001:db8::/64\" } ],"
+        "    \"subnet\": \"2001:db8::/32\" } ],"
+        "\"valid-lifetime\": 4000 }";
+
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
+    extractConfig(config);
+
+    ConstElementPtr status;
+    EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json));
+
+    // returned value should be 0 (success)
+    checkResult(status, 0);
+
+    Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->
+        getCfgSubnets6()->selectSubnet(IOAddress("2001:db8::1"));
+    ASSERT_TRUE(subnet);
+
+    EXPECT_TRUE(subnet->getT1().unspecified());
+    EXPECT_FALSE(subnet->getT2().unspecified());
+    EXPECT_EQ(2000, subnet->getT2().get());
+    EXPECT_EQ(4000, subnet->getValid().get());
+
+    // Check that subnet-id is 1
+    EXPECT_EQ(1, subnet->getID());
+}
+
+/// Check that the rebind-timer doesn't have to be specified, in which case
+/// it is marked unspecified in the Subnet.
+TEST_F(Dhcp6ParserTest, unspecifiedRebindTimer) {
+
+    string config = "{ " + genIfaceConfig() + ","
+        "\"renew-timer\": 1000, "
+        "\"subnet6\": [ { "
+        "    \"id\": 1,"
+        "    \"pools\": [ { \"pool\": \"2001:db8::/64\" } ],"
+        "    \"subnet\": \"2001:db8::/32\" } ],"
+        "\"valid-lifetime\": 4000 }";
+
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
+    extractConfig(config);
+
+    ConstElementPtr status;
+    EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json));
+
+    // returned value should be 0 (success)
+    checkResult(status, 0);
+
+    Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->
+        getCfgSubnets6()->selectSubnet(IOAddress("2001:db8::1"));
+    ASSERT_TRUE(subnet);
+    EXPECT_FALSE(subnet->getT1().unspecified());
+    EXPECT_EQ(1000, subnet->getT1().get());
+    EXPECT_TRUE(subnet->getT2().unspecified());
+    EXPECT_EQ(4000, subnet->getValid().get());
+
+    // Check that subnet-id is 1
+    EXPECT_EQ(1, subnet->getID());
+}
+
 /// Check that preferred-lifetime must be between min-preferred-lifetime and
 /// max-preferred-lifetime when a bound is specified, *AND* a subnet is
 /// specified (boundary check is done when lifetimes are applied).
 TEST_F(Dhcp6ParserTest, outBoundPreferredLifetime) {
 
-    string too_small =  "{ " + genIfaceConfig() + "," +
+    string too_small =  "{ " + genIfaceConfig() + ","
         "\"subnet6\": [ { "
         "    \"id\": 1,"
         "    \"pools\": [ { \"pool\": \"2001:db8::/64\" } ],"
@@ -1240,7 +1309,7 @@ TEST_F(Dhcp6ParserTest, outBoundPreferredLifetime) {
     checkResult(status, 1, expected);
     resetConfiguration();
 
-    string too_large =  "{ " + genIfaceConfig() + "," +
+    string too_large =  "{ " + genIfaceConfig() + ","
         "\"subnet6\": [ { "
         "    \"id\": 1,"
         "    \"pools\": [ { \"pool\": \"2001:db8::/64\" } ],"
@@ -1255,7 +1324,7 @@ TEST_F(Dhcp6ParserTest, outBoundPreferredLifetime) {
     checkResult(status, 1, expected);
     resetConfiguration();
 
-    string before =  "{ " + genIfaceConfig() + "," +
+    string before =  "{ " + genIfaceConfig() + ","
         "\"subnet6\": [ { "
         "    \"id\": 1,"
         "    \"pools\": [ { \"pool\": \"2001:db8::/64\" } ],"
@@ -1271,7 +1340,7 @@ TEST_F(Dhcp6ParserTest, outBoundPreferredLifetime) {
     checkResult(status, 1, expected);
     resetConfiguration();
 
-    string after =  "{ " + genIfaceConfig() + "," +
+    string after =  "{ " + genIfaceConfig() + ","
         "\"subnet6\": [ { "
         "    \"id\": 1,"
         "    \"pools\": [ { \"pool\": \"2001:db8::/64\" } ],"
@@ -1287,7 +1356,7 @@ TEST_F(Dhcp6ParserTest, outBoundPreferredLifetime) {
     checkResult(status, 1, expected);
     resetConfiguration();
 
-    string crossed =  "{ " + genIfaceConfig() + "," +
+    string crossed =  "{ " + genIfaceConfig() + ","
         "\"subnet6\": [ { "
         "    \"id\": 1,"
         "    \"pools\": [ { \"pool\": \"2001:db8::/64\" } ],"
@@ -1308,7 +1377,7 @@ TEST_F(Dhcp6ParserTest, outBoundPreferredLifetime) {
 /// parameters only.
 TEST_F(Dhcp6ParserTest, outBoundGlobalPreferredLifetime) {
 
-    string too_small =  "{ " + genIfaceConfig() + "," +
+    string too_small =  "{ " + genIfaceConfig() + ","
         "\"preferred-lifetime\": 1000, \"min-preferred-lifetime\": 2000 }";
 
     ConstElementPtr json;
@@ -1322,7 +1391,7 @@ TEST_F(Dhcp6ParserTest, outBoundGlobalPreferredLifetime) {
     checkResult(status, 1, expected);
     resetConfiguration();
 
-    string too_large =  "{ " + genIfaceConfig() + "," +
+    string too_large =  "{ " + genIfaceConfig() + ","
         "\"preferred-lifetime\": 2000, \"max-preferred-lifetime\": 1000 }";
 
     ASSERT_NO_THROW(json = parseDHCP6(too_large));
@@ -1333,7 +1402,7 @@ TEST_F(Dhcp6ParserTest, outBoundGlobalPreferredLifetime) {
     checkResult(status, 1, expected);
     resetConfiguration();
 
-    string before =  "{ " + genIfaceConfig() + "," +
+    string before =  "{ " + genIfaceConfig() + ","
         "\"preferred-lifetime\": 1000, \"min-preferred-lifetime\": 2000, "
         "\"max-preferred-lifetime\": 4000 }";
 
@@ -1345,7 +1414,7 @@ TEST_F(Dhcp6ParserTest, outBoundGlobalPreferredLifetime) {
     checkResult(status, 1, expected);
     resetConfiguration();
 
-    string after =  "{ " + genIfaceConfig() + "," +
+    string after =  "{ " + genIfaceConfig() + ","
         "\"preferred-lifetime\": 5000, \"min-preferred-lifetime\": 1000, "
         "\"max-preferred-lifetime\": 4000 }";
 
@@ -1357,7 +1426,7 @@ TEST_F(Dhcp6ParserTest, outBoundGlobalPreferredLifetime) {
     checkResult(status, 1, expected);
     resetConfiguration();
 
-    string crossed =  "{ " + genIfaceConfig() + "," +
+    string crossed =  "{ " + genIfaceConfig() + ","
         "\"preferred-lifetime\": 1500, \"min-preferred-lifetime\": 2000, "
         "\"max-preferred-lifetime\": 1000 }";
 
@@ -1421,8 +1490,8 @@ TEST_F(Dhcp6ParserTest, subnetGlobalDefaults) {
 
     // Now check if the configuration was indeed handled and we have
     // expected pool configured.
-    Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
-        selectSubnet(IOAddress("2001:db8:1::5"), classify_);
+    Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->
+        getCfgSubnets6()->selectSubnet(IOAddress("2001:db8:1::5"), classify_);
     ASSERT_TRUE(subnet);
     EXPECT_EQ(1000, subnet->getT1().get());
     EXPECT_EQ(2000, subnet->getT2().get());
@@ -1484,7 +1553,7 @@ TEST_F(Dhcp6ParserTest, multipleSubnetsExplicitIDs) {
         ASSERT_TRUE(subnets);
         ASSERT_EQ(4, subnets->size()); // We expect 4 subnets
 
-        // Check that subnet ids are as expected.
+        // Verify that subnet ids are as expected.
         // Now the subnet order is the subnet id one.
         auto subnet = subnets->begin();
         EXPECT_EQ(1, (*subnet)->getID());
@@ -1541,7 +1610,7 @@ TEST_F(Dhcp6ParserTest, reconfigureRemoveSubnet) {
     ConstElementPtr x;
 
     // All four subnets
-    string config4 = "{ " + genIfaceConfig() + ","
+    string config6 = "{ " + genIfaceConfig() + ","
         "\"preferred-lifetime\": 3000,"
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
@@ -1615,8 +1684,8 @@ TEST_F(Dhcp6ParserTest, reconfigureRemoveSubnet) {
     // last one.
 
     ConstElementPtr json;
-    ASSERT_NO_THROW(json = parseDHCP6(config4));
-    extractConfig(config4);
+    ASSERT_NO_THROW(json = parseDHCP6(config6));
+    extractConfig(config6);
     EXPECT_NO_THROW(x = Dhcpv6SrvTest::configure(srv_, json));
     checkResult(x, 0);
 
@@ -1627,6 +1696,8 @@ TEST_F(Dhcp6ParserTest, reconfigureRemoveSubnet) {
     ASSERT_TRUE(subnets);
     ASSERT_EQ(4, subnets->size()); // We expect 4 subnets
 
+    CfgMgr::instance().clear();
+
     // Do the reconfiguration (the last subnet is removed)
     ASSERT_NO_THROW(json = parseDHCP6(config_first3));
     EXPECT_NO_THROW(x = Dhcpv6SrvTest::configure(srv_, json));
@@ -1638,15 +1709,17 @@ TEST_F(Dhcp6ParserTest, reconfigureRemoveSubnet) {
     ASSERT_TRUE(subnets);
     ASSERT_EQ(3, subnets->size()); // We expect 3 subnets now (4th is removed)
 
+    // Check subnet-ids of each subnet (it should be monotonously increasing)
     auto subnet = subnets->begin();
     EXPECT_EQ(1, (*subnet)->getID());
     EXPECT_EQ(2, (*++subnet)->getID());
     EXPECT_EQ(3, (*++subnet)->getID());
 
+    CfgMgr::instance().clear();
+
     /// CASE 2: Configure 4 subnets, then reconfigure and remove one
     /// from in between (not first, not last)
-
-    ASSERT_NO_THROW(json = parseDHCP6(config4));
+    ASSERT_NO_THROW(json = parseDHCP6(config6));
     EXPECT_NO_THROW(x = Dhcpv6SrvTest::configure(srv_, json));
     checkResult(x, 0);
 
@@ -1672,7 +1745,7 @@ TEST_F(Dhcp6ParserTest, reconfigureRemoveSubnet) {
 
 // Check whether it is possible to configure compatibility flags.
 TEST_F(Dhcp6ParserTest, compatibility) {
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"preferred-lifetime\": 3000,"
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
@@ -1702,7 +1775,7 @@ TEST_F(Dhcp6ParserTest, compatibility) {
 
 // Check that unknown compatibility flag raises error.
 TEST_F(Dhcp6ParserTest, compatibilityUnknown) {
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"preferred-lifetime\": 3000,"
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
@@ -1730,7 +1803,7 @@ TEST_F(Dhcp6ParserTest, compatibilityUnknown) {
 
 // Check that not boolean compatibility flag value raises error.
 TEST_F(Dhcp6ParserTest, compatibilityNotBool) {
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"preferred-lifetime\": 3000,"
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
@@ -1792,8 +1865,8 @@ TEST_F(Dhcp6ParserTest, subnetLocal) {
     // returned value should be 0 (configuration success)
     checkResult(status, 0);
 
-    Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
-        selectSubnet(IOAddress("2001:db8:1::5"), classify_);
+    Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->
+        getCfgSubnets6()->selectSubnet(IOAddress("2001:db8:1::5"), classify_);
     ASSERT_TRUE(subnet);
     EXPECT_EQ(1, subnet->getT1().get());
     EXPECT_EQ(2, subnet->getT2().get());
@@ -1981,7 +2054,8 @@ TEST_F(Dhcp6ParserTest, interfaceIdGlobal) {
 // interface (i.e. local subnet) and interface-id (remote subnet) defined.
 TEST_F(Dhcp6ParserTest, subnetInterfaceAndInterfaceId) {
 
-    const string config = "{ \"preferred-lifetime\": 3000,"
+    const string config = "{"
+        "\"preferred-lifetime\": 3000,"
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet6\": [ { "
@@ -2018,35 +2092,40 @@ TEST_F(Dhcp6ParserTest, badSubnetValues) {
         {
         "IP is not an address",
         "{ \"subnet6\": [ { "
-        "  \"subnet\": \"not an address/64\" } ]}",
+        "  \"subnet\": \"not an address/64\" } ],"
+        "\"valid-lifetime\": 4000 }",
         "subnet configuration failed: "
         "Failed to convert string to address 'notanaddress': Invalid argument"
         },
         {
         "IP is Invalid",
         "{ \"subnet6\": [ { "
-        "  \"subnet\": \"200175:db8::/64\" } ]}",
+        "  \"subnet\": \"200175:db8::/64\" } ],"
+        "\"valid-lifetime\": 4000 }",
         "subnet configuration failed: "
         "Failed to convert string to address '200175:db8::': Invalid argument"
         },
         {
         "Missing prefix",
         "{ \"subnet6\": [ { "
-        "  \"subnet\": \"2001:db8::\" } ]}",
+        "  \"subnet\": \"2001:db8::\" } ],"
+        "\"valid-lifetime\": 4000 }",
         "subnet configuration failed: "
         "Invalid subnet syntax (prefix/len expected):2001:db8:: (<string>:1:30)"
         },
         {
         "Prefix not an integer (2 slashes)",
         "{ \"subnet6\": [ { "
-        "  \"subnet\": \"2001:db8:://64\" } ]}",
+        "  \"subnet\": \"2001:db8:://64\" } ],"
+        "\"valid-lifetime\": 4000 }",
         "subnet configuration failed: "
         "prefix length: '/64' is not an integer (<string>:1:30)"
         },
         {
         "Prefix value is insane",
         "{ \"subnet6\": [ { "
-        "  \"subnet\": \"2001:db8::/43225\" } ]}",
+        "  \"subnet\": \"2001:db8::/43225\" } ],"
+        "\"valid-lifetime\": 4000 }",
         "subnet configuration failed: "
         "Invalid prefix length specified for subnet: 43225 (<string>:1:30)"
         }
@@ -2062,6 +2141,7 @@ TEST_F(Dhcp6ParserTest, badSubnetValues) {
         ConstElementPtr status;
         EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, config));
         checkResult(status, 1);
+        ASSERT_TRUE(comment_);
         EXPECT_EQ(comment_->stringValue(), scenario.exp_error_msg_);
     }
 }
@@ -2212,9 +2292,6 @@ TEST_F(Dhcp6ParserTest, poolOutOfSubnet) {
 // Note this test also verifies that subnets can be configured without
 // prefix delegation pools.
 TEST_F(Dhcp6ParserTest, poolPrefixLen) {
-
-    ConstElementPtr x;
-
     string config = "{ " + genIfaceConfig() + ","
         "\"preferred-lifetime\": 3000,"
         "\"rebind-timer\": 2000, "
@@ -2229,13 +2306,14 @@ TEST_F(Dhcp6ParserTest, poolPrefixLen) {
     ASSERT_NO_THROW(json = parseDHCP6(config));
     extractConfig(config);
 
-    EXPECT_NO_THROW(x = Dhcpv6SrvTest::configure(srv_, json));
+    ConstElementPtr status;
+    EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json));
 
-    // returned value must be 1 (configuration parse error)
-    checkResult(x, 0);
+    // returned value must be 0 (configuration accepted)
+    checkResult(status, 0);
 
-    Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
-        selectSubnet(IOAddress("2001:db8:1::5"), classify_);
+    Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->
+        getCfgSubnets6()->selectSubnet(IOAddress("2001:db8:1::5"), classify_);
     ASSERT_TRUE(subnet);
     EXPECT_EQ(1000, subnet->getT1().get());
     EXPECT_EQ(2000, subnet->getT2().get());
@@ -2383,6 +2461,24 @@ TEST_F(Dhcp6ParserTest, badPools) {
     EXPECT_TRUE(errorContainsPosition(status, "<string>"));
 }
 
+// Goal of this test is to verify no pool definitions is invalid
+// and returns a location in the error message.
+TEST_F(Dhcp6ParserTest, noPools) {
+
+    // Configuration string.
+    string config = "{ " + genIfaceConfig() + ","
+        "\"preferred-lifetime\": 3000,"
+        "\"rebind-timer\": 2000, "
+        "\"renew-timer\": 1000, "
+        "\"subnet6\": [ { "
+        "    \"id\": 1,"
+        "    \"pools\": [ { \"user-context\": { } } ],"
+        "    \"subnet\": \"2001:db8:1::/64\" } ],"
+        "\"valid-lifetime\": 4000 }";
+
+    EXPECT_THROW(parseDHCP6(config, true), Dhcp6ParseError);
+}
+
 // 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) {
@@ -2732,14 +2828,38 @@ TEST_F(Dhcp6ParserTest, invalidPdPools) {
     }
 }
 
-// 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) {
+// Goal of this test is to verify that unknown interface fails
+// to be parsed.
+TEST_F(Dhcp6ParserTest, unknownInterface) {
 
     // Configuration string.
-    std::string config =
-        "{ \"option-def\": [ {"
-        "      \"name\": \"foo\","
+    string config = "{ " + genIfaceConfig() + ","
+        "\"preferred-lifetime\": 3000,"
+        "\"rebind-timer\": 2000, "
+        "\"renew-timer\": 1000, "
+        "\"subnet6\": [ { "
+        "    \"id\": 1,"
+        "    \"pools\": [ ],"
+        "    \"subnet\": \"2001:db8:1::/64\","
+        "    \"interface\": \"ethX\" } ],"
+        "\"valid-lifetime\": 4000 }";
+
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config, true));
+    ConstElementPtr status;
+    EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json));
+    checkResult(status, 1);
+    EXPECT_TRUE(errorContainsPosition(status, "<string>"));
+}
+
+// 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) {
+
+    // Configuration string.
+    std::string config =
+        "{ \"option-def\": [ {"
+        "      \"name\": \"foo\","
         "      \"code\": 100,"
         "      \"type\": \"ipv6-address\","
         "      \"space\": \"isc\""
@@ -2774,6 +2894,7 @@ TEST_F(Dhcp6ParserTest, optionDefIpv6Address) {
     EXPECT_EQ(100, def->getCode());
     EXPECT_FALSE(def->getArrayType());
     EXPECT_EQ(OPT_IPV6_ADDRESS_TYPE, def->getType());
+    EXPECT_TRUE(def->getEncapsulatedSpace().empty());
 
     // The copy of the option definition should be available in the libdhcp++.
     OptionDefinitionPtr def_libdhcp = LibDHCP::getRuntimeOptionDef("isc", 100);
@@ -2833,6 +2954,7 @@ TEST_F(Dhcp6ParserTest, optionDefRecord) {
     EXPECT_EQ(100, def->getCode());
     EXPECT_EQ(OPT_RECORD_TYPE, def->getType());
     EXPECT_FALSE(def->getArrayType());
+    EXPECT_TRUE(def->getEncapsulatedSpace().empty());
 
     // The option comprises the record of data fields. Verify that all
     // fields are present and they are of the expected types.
@@ -2889,6 +3011,7 @@ TEST_F(Dhcp6ParserTest, optionDefMultiple) {
     EXPECT_EQ(100, def1->getCode());
     EXPECT_EQ(OPT_UINT32_TYPE, def1->getType());
     EXPECT_FALSE(def1->getArrayType());
+    EXPECT_TRUE(def1->getEncapsulatedSpace().empty());
 
     // Check the second option definition we have created.
     OptionDefinitionPtr def2 = CfgMgr::instance().getStagingCfg()->
@@ -2900,6 +3023,7 @@ TEST_F(Dhcp6ParserTest, optionDefMultiple) {
     EXPECT_EQ(101, def2->getCode());
     EXPECT_EQ(OPT_IPV4_ADDRESS_TYPE, def2->getType());
     EXPECT_FALSE(def2->getArrayType());
+    EXPECT_TRUE(def2->getEncapsulatedSpace().empty());
 }
 
 // The goal of this test is to verify that the duplicated option
@@ -2993,7 +3117,8 @@ TEST_F(Dhcp6ParserTest, optionDefArray) {
     checkResult(status, 0);
 
     // The option definition should now be available in the CfgMgr.
-    def = CfgMgr::instance().getStagingCfg()->getCfgOptionDef()->get("isc", 100);
+    def = CfgMgr::instance().getStagingCfg()->
+        getCfgOptionDef()->get("isc", 100);
     ASSERT_TRUE(def);
 
     // Check the option data.
@@ -3001,6 +3126,7 @@ TEST_F(Dhcp6ParserTest, optionDefArray) {
     EXPECT_EQ(100, def->getCode());
     EXPECT_EQ(OPT_UINT32_TYPE, def->getType());
     EXPECT_TRUE(def->getArrayType());
+    EXPECT_TRUE(def->getEncapsulatedSpace().empty());
 }
 
 // The purpose of this test to verify that encapsulated option
@@ -3034,7 +3160,8 @@ TEST_F(Dhcp6ParserTest, optionDefEncapsulate) {
     checkResult(status, 0);
 
     // The option definition should now be available in the CfgMgr.
-    def = CfgMgr::instance().getStagingCfg()->getCfgOptionDef()->get("isc", 100);
+    def = CfgMgr::instance().getStagingCfg()->
+        getCfgOptionDef()->get("isc", 100);
     ASSERT_TRUE(def);
 
     // Check the option data.
@@ -3247,6 +3374,7 @@ TEST_F(Dhcp6ParserTest, optionStandardDefOverride) {
         "}";
     ConstElementPtr json;
     ASSERT_NO_THROW(json = parseOPTION_DEFS(config));
+    extractConfig(config);
 
     OptionDefinitionPtr def = CfgMgr::instance().getStagingCfg()->
         getCfgOptionDef()->get(DHCP6_OPTION_SPACE, 100);
@@ -3280,7 +3408,7 @@ TEST_F(Dhcp6ParserTest, optionStandardDefOverride) {
         "      \"space\": \"dhcp6\""
         "  } ]"
         "}";
-    json = parseOPTION_DEFS(config);
+    ASSERT_NO_THROW(json = parseOPTION_DEFS(config));
 
     // Use the configuration string to create new option definition.
     EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json));
@@ -3302,7 +3430,8 @@ TEST_F(Dhcp6ParserTest, optionStandardDefOverride) {
         "      \"space\": \"dhcp6\""
         "  } ]"
         "}";
-    json = parseOPTION_DEFS(config);
+    ASSERT_NO_THROW(json = parseOPTION_DEFS(config));
+    extractConfig(config);
 
     // Use the configuration string to create new option definition.
     EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json));
@@ -3352,8 +3481,8 @@ TEST_F(Dhcp6ParserTest, optionDataDefaultsGlobal) {
     checkResult(x, 0);
 
     // These options are global
-    Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
-        selectSubnet(IOAddress("2001:db8:1::5"), classify_);
+    Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->
+        getCfgSubnets6()->selectSubnet(IOAddress("2001:db8:1::5"), classify_);
     ASSERT_TRUE(subnet);
     OptionContainerPtr options = subnet->getCfgOption()->getAll(DHCP6_OPTION_SPACE);
     ASSERT_EQ(0, options->size());
@@ -3430,8 +3559,8 @@ TEST_F(Dhcp6ParserTest, optionDataDefaultsSubnet) {
         CfgMgr::instance().getStagingCfg()->getCfgOption()->getAll(DHCP6_OPTION_SPACE);
     ASSERT_EQ(0, options->size());
 
-    Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
-        selectSubnet(IOAddress("2001:db8:1::5"), classify_);
+    Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->
+        getCfgSubnets6()->selectSubnet(IOAddress("2001:db8:1::5"), classify_);
     ASSERT_TRUE(subnet);
     options = subnet->getCfgOption()->getAll(DHCP6_OPTION_SPACE);
     ASSERT_EQ(2, options->size());
@@ -3599,7 +3728,7 @@ TEST_F(Dhcp6ParserTest, optionDataEncapsulate) {
     CfgMgr::instance().clear();
 
     // Stage 2. Configure base option and a subnet. Please note that
-    // the configuration from the stage 2 is repeated because BIND
+    // the configuration from the stage 2 is repeated because Kea
     // configuration manager sends whole configuration for the lists
     // where at least one element is being modified or added.
     config = "{ " + genIfaceConfig() + ","
@@ -3667,7 +3796,7 @@ TEST_F(Dhcp6ParserTest, optionDataEncapsulate) {
     EXPECT_EQ(100, desc.option_->getType());
 
     // This option should comprise two sub-options.
-    // Onf of them is 'foo' with code 110.
+    // One of them is 'foo' with code 110.
     OptionPtr option_foo = desc.option_->getOption(110);
     ASSERT_TRUE(option_foo);
     EXPECT_EQ(110, option_foo->getType());
@@ -3678,6 +3807,159 @@ TEST_F(Dhcp6ParserTest, optionDataEncapsulate) {
     EXPECT_EQ(111, option_foo2->getType());
 }
 
+// Goal of this test is to verify options configuration
+// for a single subnet. In particular this test checks
+// that local options configuration overrides global
+// option setting.
+TEST_F(Dhcp6ParserTest, optionDataInSingleSubnet) {
+    ConstElementPtr x;
+    string config = "{ " + genIfaceConfig() + ","
+        "\"preferred-lifetime\": 3000,"
+        "\"rebind-timer\": 2000, "
+        "\"renew-timer\": 1000, "
+        "\"option-data\": [ {"
+        "      \"name\": \"subscriber-id\","
+        "      \"data\": \"AB\","
+        "      \"csv-format\": false"
+        " } ],"
+        "\"subnet6\": [ { "
+        "    \"id\": 1,"
+        "    \"pools\": [ { \"pool\": \"2001:db8:1::/80\" } ],"
+        "    \"subnet\": \"2001:db8:1::/64\", "
+        "    \"option-data\": [ {"
+        "          \"name\": \"subscriber-id\","
+        "          \"data\": \"ABCDEF0105\","
+        "          \"csv-format\": false"
+        "        },"
+        "        {"
+        "          \"name\": \"user-class\","
+        "          \"data\": \"FFFEFDFCFB\","
+        "          \"csv-format\": false"
+        "        } ]"
+        " } ],"
+        "\"valid-lifetime\": 4000 }";
+
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
+    extractConfig(config);
+
+    EXPECT_NO_THROW(x = Dhcpv6SrvTest::configure(srv_, json));
+    checkResult(x, 0);
+
+    Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->
+        getCfgSubnets6()->selectSubnet(IOAddress("2001:db8:1::5"), classify_);
+    ASSERT_TRUE(subnet);
+    OptionContainerPtr options = subnet->getCfgOption()->getAll(DHCP6_OPTION_SPACE);
+    ASSERT_EQ(2, options->size());
+
+    // Get the search index. Index #1 is to search using option code.
+    const OptionContainerTypeIndex& idx = options->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> range =
+        idx.equal_range(D6O_SUBSCRIBER_ID);
+    // Expect single option with the code equal to 100.
+    ASSERT_EQ(1, std::distance(range.first, range.second));
+    const uint8_t subid_expected[] = {
+        0xAB, 0xCD, 0xEF, 0x01, 0x05
+    };
+    // Check if option is valid in terms of code and carried data.
+    testOption(*range.first, D6O_SUBSCRIBER_ID, subid_expected, sizeof(subid_expected));
+
+    range = idx.equal_range(D6O_USER_CLASS);
+    ASSERT_EQ(1, std::distance(range.first, range.second));
+    // Do another round of testing with second option.
+    const uint8_t user_class_expected[] = {
+        0xFF, 0xFE, 0xFD, 0xFC, 0xFB
+    };
+    testOption(*range.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".
+TEST_F(Dhcp6ParserTest, optionDataBoolean) {
+    // Create configuration. Use standard option 1000.
+    std::map<std::string, std::string> params;
+    params["name"] = "bool-option";
+    params["space"] = DHCP6_OPTION_SPACE;
+    params["code"] = "1000";
+    params["data"] = "true";
+    params["csv-format"] = "true";
+
+    std::string config = createConfigWithOption(params);
+    ASSERT_TRUE(executeConfiguration(config, "parse configuration with a"
+                                     " boolean value"));
+
+    // The subnet should now hold one option with the code 1000.
+    OptionDescriptor desc = getOptionFromSubnet(IOAddress("2001:db8:1::5"), 1000);
+    ASSERT_TRUE(desc.option_);
+
+    // This option should be set to "true", represented as 0x1 in the option
+    // buffer.
+    uint8_t expected_option_data[] = {
+        0x1
+    };
+    testConfiguration(params, 1000, expected_option_data,
+                      sizeof(expected_option_data));
+
+    // Configure the option with the "1" value. This should have the same
+    // effect as if "true" was specified.
+    params["data"] = "1";
+    testConfiguration(params, 1000, expected_option_data,
+                      sizeof(expected_option_data));
+
+    // The value of "1" with a few leading zeros should work too.
+    params["data"] = "00001";
+    testConfiguration(params, 1000, expected_option_data,
+                      sizeof(expected_option_data));
+
+    // Configure the option with the "false" value.
+    params["data"] = "false";
+    // The option buffer should now hold the value of 0.
+    expected_option_data[0] = 0;
+    testConfiguration(params, 1000, expected_option_data,
+                      sizeof(expected_option_data));
+
+    // Specifying "0" should have the same effect as "false".
+    params["data"] = "0";
+    testConfiguration(params, 1000, expected_option_data,
+                      sizeof(expected_option_data));
+
+    // The same effect should be for multiple 0 chars.
+    params["data"] = "00000";
+    testConfiguration(params, 1000, expected_option_data,
+                      sizeof(expected_option_data));
+
+    // Bogus values should not be accepted.
+    params["data"] = "bogus";
+    testInvalidOptionParam(params);
+
+    params["data"] = "2";
+    testInvalidOptionParam(params);
+
+    // Now let's test that it is possible to use binary format.
+    params["data"] = "0";
+    params["csv-format"] = "false";
+    testConfiguration(params, 1000, expected_option_data,
+                      sizeof(expected_option_data));
+
+    // The binary 1 should work as well.
+    params["data"] = "1";
+    expected_option_data[0] = 1;
+    testConfiguration(params, 1000, expected_option_data,
+                      sizeof(expected_option_data));
+
+    // As well as an even number of digits.
+    params["data"] = "01";
+    testConfiguration(params, 1000, expected_option_data,
+                      sizeof(expected_option_data));
+}
+
 // Goal of this test is to verify options configuration
 // for multiple subnets.
 TEST_F(Dhcp6ParserTest, optionDataInMultipleSubnets) {
@@ -3715,8 +3997,8 @@ TEST_F(Dhcp6ParserTest, optionDataInMultipleSubnets) {
     EXPECT_NO_THROW(x = Dhcpv6SrvTest::configure(srv_, json));
     checkResult(x, 0);
 
-    Subnet6Ptr subnet1 = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
-        selectSubnet(IOAddress("2001:db8:1::5"), classify_);
+    Subnet6Ptr subnet1 = CfgMgr::instance().getStagingCfg()->
+        getCfgSubnets6()->selectSubnet(IOAddress("2001:db8:1::5"), classify_);
     ASSERT_TRUE(subnet1);
     OptionContainerPtr options1 = subnet1->getCfgOption()->getAll(DHCP6_OPTION_SPACE);
     ASSERT_EQ(1, options1->size());
@@ -3741,8 +4023,8 @@ TEST_F(Dhcp6ParserTest, optionDataInMultipleSubnets) {
                sizeof(subid_expected));
 
     // Test another subnet in the same way.
-    Subnet6Ptr subnet2 = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
-        selectSubnet(IOAddress("2001:db8:2::4"), classify_);
+    Subnet6Ptr subnet2 = CfgMgr::instance().getStagingCfg()->
+        getCfgSubnets6()->selectSubnet(IOAddress("2001:db8:2::4"), classify_);
     ASSERT_TRUE(subnet2);
     OptionContainerPtr options2 = subnet2->getCfgOption()->getAll(DHCP6_OPTION_SPACE);
     ASSERT_EQ(1, options2->size());
@@ -3762,6 +4044,82 @@ TEST_F(Dhcp6ParserTest, optionDataInMultipleSubnets) {
 
 // This test verifies that it is possible to specify options on
 // pool levels.
+TEST_F(Dhcp6ParserTest, optionDataSinglePool) {
+    ConstElementPtr x;
+    string config = "{ " + genIfaceConfig() + ","
+        "\"preferred-lifetime\": 3000,"
+        "\"rebind-timer\": 2000, "
+        "\"renew-timer\": 1000, "
+        "\"subnet6\": [ { "
+        "    \"id\": 1,"
+        "    \"pools\": [ { "
+        "        \"pool\": \"2001:db8:1::10 - 2001:db8:1::100\","
+        "        \"option-data\": [ {"
+        "            \"name\": \"subscriber-id\","
+        "            \"data\": \"0102030405060708090A\","
+        "            \"csv-format\": false"
+        "        },"
+        "        {"
+        "          \"name\": \"user-class\","
+        "          \"data\": \"FFFEFDFCFB\","
+        "          \"csv-format\": false"
+        "        } ]"
+        "    } ],"
+        "    \"subnet\": \"2001:db8:1::/64\""
+        " } ],"
+        "\"valid-lifetime\": 4000 }";
+
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
+    extractConfig(config);
+
+    EXPECT_NO_THROW(x = Dhcpv6SrvTest::configure(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_NA, IOAddress("2001:db8:1::10"), false);
+    ASSERT_TRUE(pool);
+    Pool6Ptr pool6 = boost::dynamic_pointer_cast<Pool6>(pool);
+    ASSERT_TRUE(pool6);
+
+    OptionContainerPtr options =
+        pool6->getCfgOption()->getAll(DHCP6_OPTION_SPACE);
+    ASSERT_EQ(2, options->size());
+
+    // Get the search index. Index #1 is to search using option code.
+    const OptionContainerTypeIndex& idx = options->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> range =
+        idx.equal_range(D6O_SUBSCRIBER_ID);
+    // Expect a single Subscriber ID option instance.
+    ASSERT_EQ(1, std::distance(range.first, range.second));
+    const uint8_t subscriber_id_expected[] = {
+        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A
+    };
+    // Check if option is valid in terms of code and carried data.
+    testOption(*range.first, D6O_SUBSCRIBER_ID, subscriber_id_expected,
+               sizeof(subscriber_id_expected));
+
+    range = idx.equal_range(D6O_USER_CLASS);
+    ASSERT_EQ(1, std::distance(range.first, range.second));
+    // Do another round of testing with second option.
+
+    const uint8_t user_class_expected[] = {
+        0xFF, 0xFE, 0xFD, 0xFC, 0xFB
+    };
+    testOption(*range.first, D6O_USER_CLASS, user_class_expected,
+               sizeof(user_class_expected));
+}
+
+// This test verifies that it's possible to define different options in
+// different pools and those options are not confused.
 TEST_F(Dhcp6ParserTest, optionDataMultiplePools) {
     ConstElementPtr x;
     string config = "{ " + genIfaceConfig() + ","
@@ -3914,89 +4272,6 @@ TEST_F(Dhcp6ParserTest, optionDataMultiplePools) {
                sizeof(user_class_expected2));
 }
 
-// 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".
-TEST_F(Dhcp6ParserTest, optionDataBoolean) {
-    // Create configuration. Use standard option 1000.
-    std::map<std::string, std::string> params;
-    params["name"] = "bool-option";
-    params["space"] = DHCP6_OPTION_SPACE;
-    params["code"] = "1000";
-    params["data"] = "true";
-    params["csv-format"] = "true";
-
-    std::string config = createConfigWithOption(params);
-    ASSERT_TRUE(executeConfiguration(config, "parse configuration with a"
-                                     " boolean value"));
-
-    // The subnet should now hold one option with the code 1000.
-    OptionDescriptor desc =
-        getOptionFromSubnet(IOAddress("2001:db8:1::5"), 1000);
-    ASSERT_TRUE(desc.option_);
-
-    // This option should be set to "true", represented as 0x1 in the option
-    // buffer.
-    uint8_t expected_option_data[] = {
-        0x1
-    };
-    testConfiguration(params, 1000, expected_option_data,
-                      sizeof(expected_option_data));
-
-    // Configure the option with the "1" value. This should have the same
-    // effect as if "true" was specified.
-    params["data"] = "1";
-    testConfiguration(params, 1000, expected_option_data,
-                      sizeof(expected_option_data));
-
-    // The value of "1" with a few leading zeros should work too.
-    params["data"] = "00001";
-    testConfiguration(params, 1000, expected_option_data,
-                      sizeof(expected_option_data));
-
-    // Configure the option with the "false" value.
-    params["data"] = "false";
-    // The option buffer should now hold the value of 0.
-    expected_option_data[0] = 0;
-    testConfiguration(params, 1000, expected_option_data,
-                      sizeof(expected_option_data));
-
-    // Specifying "0" should have the same effect as "false".
-    params["data"] = "0";
-    testConfiguration(params, 1000, expected_option_data,
-                      sizeof(expected_option_data));
-
-    // The same effect should be for multiple 0 chars.
-    params["data"] = "00000";
-    testConfiguration(params, 1000, expected_option_data,
-                      sizeof(expected_option_data));
-
-    // Bogus values should not be accepted.
-    params["data"] = "bogus";
-    testInvalidOptionParam(params);
-
-    params["data"] = "2";
-    testInvalidOptionParam(params);
-
-    // Now let's test that it is possible to use binary format.
-    params["data"] = "0";
-    params["csv-format"] = "false";
-    testConfiguration(params, 1000, expected_option_data,
-                      sizeof(expected_option_data));
-
-    // The binary 1 should work as well.
-    params["data"] = "1";
-    expected_option_data[0] = 1;
-    testConfiguration(params, 1000, expected_option_data,
-                      sizeof(expected_option_data));
-
-    // As well as an even number of digits.
-    params["data"] = "01";
-    testConfiguration(params, 1000, expected_option_data,
-                      sizeof(expected_option_data));
-
-}
-
 // Verify that empty option name is rejected in the configuration.
 TEST_F(Dhcp6ParserTest, optionNameEmpty) {
     // Empty option names not allowed.
@@ -4068,8 +4343,8 @@ TEST_F(Dhcp6ParserTest, optionDataValidHexLiterals) {
         EXPECT_NO_THROW(x = Dhcpv6SrvTest::configure(srv_, json));
         checkResult(x, 0);
 
-        Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
-                            selectSubnet(IOAddress("2001:db8:1::5"), classify_);
+        Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->
+            getCfgSubnets6()->selectSubnet(IOAddress("2001:db8:1::5"), classify_);
         ASSERT_TRUE(subnet);
         OptionContainerPtr options = subnet->getCfgOption()->getAll(DHCP6_OPTION_SPACE);
         ASSERT_EQ(1, options->size());
@@ -4081,8 +4356,8 @@ TEST_F(Dhcp6ParserTest, optionDataValidHexLiterals) {
         // 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> range =
-                 idx.equal_range(D6O_SUBSCRIBER_ID);
+                OptionContainerTypeIndex::const_iterator> range =
+                    idx.equal_range(D6O_SUBSCRIBER_ID);
 
         // Expect single option with the code equal to 38.
         ASSERT_EQ(1, std::distance(range.first, range.second));
@@ -4105,19 +4380,22 @@ TEST_F(Dhcp6ParserTest, stdOptionData) {
     params["space"] = DHCP6_OPTION_SPACE;
     // Option code 3 means OPTION_IA_NA.
     params["code"] = "3";
+    // Specify option values in a CSV (user friendly) format.
     params["data"] = "12345, 6789, 1516";
     params["csv-format"] = "true";
 
     std::string config = createConfigWithOption(params);
-    ConstElementPtr json = parseDHCP6(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
 
     EXPECT_NO_THROW(x = Dhcpv6SrvTest::configure(srv_, json));
     checkResult(x, 0);
 
-    Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
-        selectSubnet(IOAddress("2001:db8:1::5"), classify_);
+    Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->
+        getCfgSubnets6()->selectSubnet(IOAddress("2001:db8:1::5"), classify_);
     ASSERT_TRUE(subnet);
     OptionContainerPtr options = subnet->getCfgOption()->getAll(DHCP6_OPTION_SPACE);
+    ASSERT_TRUE(options);
     ASSERT_EQ(1, options->size());
 
     // Get the search index. Index #1 is to search using option code.
@@ -4209,122 +4487,6 @@ TEST_F(Dhcp6ParserTest, rdnssOption) {
     EXPECT_EQ("example.com.", optionCustom->readFqdn(4));
 }
 
-// This test checks if vendor options can be specified in the config file
-// (in hex format), and later retrieved from configured subnet
-TEST_F(Dhcp6ParserTest, vendorOptionsHex) {
-
-    // This configuration string is to configure two options
-    // sharing the code 1 and belonging to the different vendor spaces.
-    // (different vendor-id values).
-    string config = "{ " + genIfaceConfig() + ","
-        "\"preferred-lifetime\": 3000,"
-        "\"valid-lifetime\": 4000,"
-        "\"rebind-timer\": 2000,"
-        "\"renew-timer\": 1000,"
-        "\"option-data\": [ {"
-        "    \"name\": \"option-one\","
-        "    \"space\": \"vendor-4491\","
-        "    \"code\": 100,"
-        "    \"data\": \"ABCDEF0105\","
-        "    \"csv-format\": false"
-        " },"
-        " {"
-        "    \"name\": \"option-two\","
-        "    \"space\": \"vendor-1234\","
-        "    \"code\": 100,"
-        "    \"data\": \"1234\","
-        "    \"csv-format\": false"
-        " } ],"
-        "\"subnet6\": [ { "
-        "    \"id\": 1,"
-        "    \"pools\": [ { \"pool\": \"2001:db8:1::/80\" } ],"
-        "    \"subnet\": \"2001:db8:1::/64\""
-        " } ]"
-        "}";
-
-    ConstElementPtr json;
-    ASSERT_NO_THROW(json = parseDHCP6(config));
-    extractConfig(config);
-
-    ConstElementPtr status;
-    EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json));
-    ASSERT_TRUE(status);
-    checkResult(status, 0);
-
-    // Options should be now available
-    // Try to get the option from the vendor space 4491
-    OptionDescriptor desc1 =
-        CfgMgr::instance().getStagingCfg()->getCfgOption()->get(VENDOR_ID_CABLE_LABS, 100);
-    ASSERT_TRUE(desc1.option_);
-    EXPECT_EQ(100, desc1.option_->getType());
-    // Try to get the option from the vendor space 1234
-    OptionDescriptor desc2 =
-        CfgMgr::instance().getStagingCfg()->getCfgOption()->get(1234, 100);
-    ASSERT_TRUE(desc2.option_);
-    EXPECT_EQ(100, desc1.option_->getType());
-
-    // Try to get the non-existing option from the non-existing
-    // option space and  expect that option is not returned.
-    OptionDescriptor desc3 =
-        CfgMgr::instance().getStagingCfg()->getCfgOption()->get(5678, 38);
-    ASSERT_FALSE(desc3.option_);
-}
-
-// This test checks if vendor options can be specified in the config file,
-// (in csv format), and later retrieved from configured subnet
-TEST_F(Dhcp6ParserTest, vendorOptionsCsv) {
-
-    // This configuration string is to configure two options
-    // sharing the code 1 and belonging to the different vendor spaces.
-    // (different vendor-id values).
-    string config = "{ " + genIfaceConfig() + ","
-        "\"preferred-lifetime\": 3000,"
-        "\"valid-lifetime\": 4000,"
-        "\"rebind-timer\": 2000,"
-        "\"renew-timer\": 1000,"
-        "\"option-data\": [ {"
-        "    \"name\": \"foo\","
-        "    \"space\": \"vendor-4491\","
-        "    \"code\": 100,"
-        "    \"data\": \"this is a string vendor-opt\""
-        " } ],"
-        "\"option-def\": [ {"
-        "    \"name\": \"foo\","
-        "    \"code\": 100,"
-        "    \"type\": \"string\","
-        "    \"space\": \"vendor-4491\""
-        " } ],"
-        "\"subnet6\": [ { "
-        "    \"id\": 1,"
-        "    \"pools\": [ { \"pool\": \"2001:db8:1::/80\" } ],"
-        "    \"subnet\": \"2001:db8:1::/64\""
-        " } ]"
-        "}";
-
-    ConstElementPtr status;
-
-    ConstElementPtr json;
-    ASSERT_NO_THROW(json = parseDHCP6(config));
-    extractConfig(config);
-
-    EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json));
-    ASSERT_TRUE(status);
-    checkResult(status, 0);
-
-    // Options should be now available.
-    // Try to get the option from the vendor space 4491
-    OptionDescriptor desc1 =
-        CfgMgr::instance().getStagingCfg()->getCfgOption()->get(VENDOR_ID_CABLE_LABS, 100);
-    ASSERT_TRUE(desc1.option_);
-    EXPECT_EQ(100, desc1.option_->getType());
-
-    // Try to get the non-existing option from the non-existing
-    // option space and  expect that option is not returned.
-    OptionDescriptor desc2 =
-        CfgMgr::instance().getStagingCfg()->getCfgOption()->get(5678, 100);
-    ASSERT_FALSE(desc2.option_);
-}
-
 /// @todo add tests similar to vendorOptionsCsv and vendorOptionsHex, but for
 ///       vendor options defined in a subnet.
 
@@ -4389,6 +4551,7 @@ TEST_F(Dhcp6ParserTest, DISABLED_stdOptionDataEncapsulate) {
     // they should be included as sub-options in the 'vendor-opts'
     // option.
     config = "{ " + genIfaceConfig() + ","
+        "\"valid-lifetime\": 3000,"
         "\"rebind-timer\": 2000,"
         "\"renew-timer\": 1000,"
         "\"option-data\": [ {"
@@ -4426,6 +4589,7 @@ TEST_F(Dhcp6ParserTest, DISABLED_stdOptionDataEncapsulate) {
 
     ASSERT_NO_THROW(json = parseDHCP6(config));
     extractConfig(config);
+
     EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json));
     ASSERT_TRUE(status);
     checkResult(status, 0);
@@ -4458,20 +4622,136 @@ TEST_F(Dhcp6ParserTest, DISABLED_stdOptionDataEncapsulate) {
     // Validate the value according to the configuration.
     EXPECT_EQ(1234, option_foo_uint32->getValue());
 
-    // Option with the code 111 should be added as a sub-option.
-    OptionPtr option_foo2 = desc.option_->getOption(111);
-    ASSERT_TRUE(option_foo2);
-    EXPECT_EQ(111, option_foo2->getType());
-    // This option comprises the IPV4 address. Such option is
-    // represented by OptionCustom object.
-    OptionCustomPtr option_foo2_v4 =
-        boost::dynamic_pointer_cast<OptionCustom>(option_foo2);
-    ASSERT_TRUE(option_foo2_v4);
-    // Get the IP address carried by this option and validate it.
-    EXPECT_EQ("192.168.2.1", option_foo2_v4->readAddress().toText());
+    // Option with the code 111 should be added as a sub-option.
+    OptionPtr option_foo2 = desc.option_->getOption(111);
+    ASSERT_TRUE(option_foo2);
+    EXPECT_EQ(111, option_foo2->getType());
+    // This option comprises the IPV4 address. Such option is
+    // represented by OptionCustom object.
+    OptionCustomPtr option_foo2_v4 =
+        boost::dynamic_pointer_cast<OptionCustom>(option_foo2);
+    ASSERT_TRUE(option_foo2_v4);
+    // Get the IP address carried by this option and validate it.
+    EXPECT_EQ("192.168.2.1", option_foo2_v4->readAddress().toText());
+
+    // Option with the code 112 should not be added.
+    EXPECT_FALSE(desc.option_->getOption(112));
+}
+
+// This test checks if vendor options can be specified in the config file
+// (in hex format), and later retrieved from configured subnet
+TEST_F(Dhcp6ParserTest, vendorOptionsHex) {
+
+    // This configuration string is to configure two options
+    // sharing the code 1 and belonging to the different vendor spaces.
+    // (different vendor-id values).
+    string config = "{ " + genIfaceConfig() + ","
+        "\"preferred-lifetime\": 3000,"
+        "\"valid-lifetime\": 4000,"
+        "\"rebind-timer\": 2000,"
+        "\"renew-timer\": 1000,"
+        "\"option-data\": [ {"
+        "    \"name\": \"option-one\","
+        "    \"space\": \"vendor-4491\"," // VENDOR_ID_CABLE_LABS = 4491
+        "    \"code\": 100," // just a random code
+        "    \"data\": \"ABCDEF0105\","
+        "    \"csv-format\": false"
+        " },"
+        " {"
+        "    \"name\": \"option-two\","
+        "    \"space\": \"vendor-1234\","
+        "    \"code\": 100,"
+        "    \"data\": \"1234\","
+        "    \"csv-format\": false"
+        " } ],"
+        "\"subnet6\": [ { "
+        "    \"id\": 1,"
+        "    \"pools\": [ { \"pool\": \"2001:db8:1::/80\" } ],"
+        "    \"subnet\": \"2001:db8:1::/64\""
+        " } ]"
+        "}";
+
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
+    extractConfig(config);
+
+    ConstElementPtr status;
+    EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json));
+    ASSERT_TRUE(status);
+    checkResult(status, 0);
+
+    // Options should be now available
+    // Try to get the option from the vendor space 4491
+    OptionDescriptor desc1 = CfgMgr::instance().getStagingCfg()->
+        getCfgOption()->get(VENDOR_ID_CABLE_LABS, 100);
+    ASSERT_TRUE(desc1.option_);
+    EXPECT_EQ(100, desc1.option_->getType());
+    // Try to get the option from the vendor space 1234
+    OptionDescriptor desc2 =
+        CfgMgr::instance().getStagingCfg()->getCfgOption()->get(1234, 100);
+    ASSERT_TRUE(desc2.option_);
+    EXPECT_EQ(100, desc1.option_->getType());
+
+    // Try to get the non-existing option from the non-existing
+    // option space and  expect that option is not returned.
+    OptionDescriptor desc3 =
+        CfgMgr::instance().getStagingCfg()->getCfgOption()->get(5678, 38);
+    ASSERT_FALSE(desc3.option_);
+}
+
+// This test checks if vendor options can be specified in the config file,
+// (in csv format), and later retrieved from configured subnet
+TEST_F(Dhcp6ParserTest, vendorOptionsCsv) {
+
+    // This configuration string is to configure two options
+    // sharing the code 1 and belonging to the different vendor spaces.
+    // (different vendor-id values).
+    string config = "{ " + genIfaceConfig() + ","
+        "\"preferred-lifetime\": 3000,"
+        "\"valid-lifetime\": 4000,"
+        "\"rebind-timer\": 2000,"
+        "\"renew-timer\": 1000,"
+        "\"option-data\": [ {"
+        "    \"name\": \"foo\","
+        "    \"space\": \"vendor-4491\","
+        "    \"code\": 100,"
+        "    \"data\": \"this is a string vendor-opt\""
+        " } ],"
+        "\"option-def\": [ {"
+        "    \"name\": \"foo\","
+        "    \"code\": 100,"
+        "    \"type\": \"string\","
+        "    \"space\": \"vendor-4491\""
+        " } ],"
+        "\"subnet6\": [ { "
+        "    \"id\": 1,"
+        "    \"pools\": [ { \"pool\": \"2001:db8:1::/80\" } ],"
+        "    \"subnet\": \"2001:db8:1::/64\""
+        " } ]"
+        "}";
+
+    ConstElementPtr status;
+
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
+    extractConfig(config);
+
+    EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json));
+    ASSERT_TRUE(status);
+    checkResult(status, 0);
 
-    // Option with the code 112 should not be added.
-    EXPECT_FALSE(desc.option_->getOption(112));
+    // Options should be now available.
+    // Try to get the option from the vendor space 4491
+    OptionDescriptor desc1 = CfgMgr::instance().getStagingCfg()->
+        getCfgOption()->get(VENDOR_ID_CABLE_LABS, 100);
+    ASSERT_TRUE(desc1.option_);
+    EXPECT_EQ(100, desc1.option_->getType());
+
+    // Try to get the non-existing option from the non-existing
+    // option space and  expect that option is not returned.
+    OptionDescriptor desc2 =
+        CfgMgr::instance().getStagingCfg()->getCfgOption()->get(5678, 100);
+    ASSERT_FALSE(desc2.option_);
 }
 
 // Tests of the hooks libraries configuration.  All tests have the pre-
@@ -4504,6 +4784,7 @@ buildHooksLibrariesConfig(const std::vector<std::string>& libraries = {},
     // Append the remainder of the configuration.
     config += string(
         "],"
+        "\"valid-lifetime\": 4000,"
         "\"rebind-timer\": 2000,"
         "\"renew-timer\": 1000,"
         "\"option-data\": [ {"
@@ -4582,6 +4863,7 @@ TEST_F(Dhcp6ParserTest, LibrariesSpecified) {
     EXPECT_FALSE(checkMarkerFileExists(UNLOAD_MARKER_FILE));
 
     // Set up the configuration with two libraries and load them.
+    // Disable multi-threading since one of the libraries is single-threaded.
     string config = buildHooksLibrariesConfig({CALLOUT_LIBRARY_1, CALLOUT_LIBRARY_2},
                                               /* multi_threading = */ false);
     ASSERT_TRUE(executeConfiguration(config,
@@ -4594,6 +4876,8 @@ TEST_F(Dhcp6ParserTest, LibrariesSpecified) {
     EXPECT_TRUE(checkMarkerFile(LOAD_MARKER_FILE, "12"));
     EXPECT_FALSE(checkMarkerFileExists(UNLOAD_MARKER_FILE));
 
+    // Commit the changes so as we get the fresh configuration for the
+    // second part of this test.
     CfgMgr::instance().commit();
 
     // Unload the libraries.  The load file should not have changed, but
@@ -4675,12 +4959,14 @@ TEST_F(Dhcp6ParserTest, IncompatibleLibrary3Specified) {
     libraries = HooksManager::getLibraryNames();
     EXPECT_TRUE(libraries.empty());
 }
-// This test verifies that it is possible to select subset of interfaces on
-// which server should listen.
+
+// This test verifies that it is possible to select subset of interfaces
+// on which server should listen.
 TEST_F(Dhcp6ParserTest, selectedInterfaces) {
     IfaceMgrTestConfig test_config(true);
 
-    // Make sure there is no garbage interface configuration in the CfgMgr.
+    // Make sure the config manager is clean and there is no hanging
+    // interface configuration.
     ASSERT_FALSE(test_config.socketOpen("eth0", AF_INET6));
     ASSERT_FALSE(test_config.socketOpen("eth1", AF_INET6));
 
@@ -4697,10 +4983,10 @@ TEST_F(Dhcp6ParserTest, selectedInterfaces) {
     extractConfig(config);
 
     ConstElementPtr status;
+    // Apply configuration.
     EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json));
-
-    // returned value must be 1 (values error)
-    // as the pool does not belong to that subnet
+    ASSERT_TRUE(status);
+    // returned value must be 0 (configuration accepted)
     checkResult(status, 0);
 
     CfgMgr::instance().getStagingCfg()->getCfgIface()->openSockets(AF_INET6, 10000);
@@ -4710,16 +4996,17 @@ TEST_F(Dhcp6ParserTest, selectedInterfaces) {
     EXPECT_FALSE(test_config.socketOpen("eth1", AF_INET6));
 }
 
-// This test verifies that it is possible to configure the server to listen on
-// all interfaces.
+// This test verifies that it is possible to configure the server in such a way
+// that it listens on all interfaces.
 TEST_F(Dhcp6ParserTest, allInterfaces) {
     IfaceMgrTestConfig test_config(true);
 
+    // Make sure there is no old configuration.
     ASSERT_FALSE(test_config.socketOpen("eth0", AF_INET6));
     ASSERT_FALSE(test_config.socketOpen("eth1", AF_INET6));
 
     // This configuration specifies two interfaces on which server should listen
-    // but also includes '*'. This keyword switches server into the
+    // but it also includes asterisk. The asterisk switches server into the
     // mode when it listens on all interfaces regardless of what interface names
     // were specified in the "interfaces" parameter.
     string config = "{ \"interfaces-config\": {"
@@ -4735,13 +5022,53 @@ TEST_F(Dhcp6ParserTest, allInterfaces) {
     extractConfig(config);
 
     ConstElementPtr status;
+
+    // Apply configuration.
     EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json));
+    ASSERT_TRUE(status);
     checkResult(status, 0);
 
     CfgMgr::instance().getStagingCfg()->getCfgIface()->openSockets(AF_INET6, 10000);
 
     // All interfaces should be now active.
+    ASSERT_TRUE(test_config.socketOpen("eth0", AF_INET6));
+    ASSERT_TRUE(test_config.socketOpen("eth1", AF_INET6));
+}
+
+// This test verifies that it is possible to select subset of interfaces
+// and addresses.
+TEST_F(Dhcp6ParserTest, selectedInterfacesAndAddresses) {
+    IfaceMgrTestConfig test_config(true);
+
+    ConstElementPtr x;
+    string config = "{ \"interfaces-config\": {"
+        "    \"interfaces\": [ \"eth0/2001:db8:1::1\", \"eth1/fe80::3a60:77ff:fed5:abcd\" ]"
+        "},"
+        "\"preferred-lifetime\": 3000,"
+        "\"rebind-timer\": 2000, "
+        "\"renew-timer\": 1000, "
+        "\"valid-lifetime\": 4000 }";
+
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
+
+    ConstElementPtr status;
+
+    // Make sure the config manager is clean and there is no hanging
+    // interface configuration.
+    ASSERT_FALSE(test_config.socketOpen("eth0", AF_INET6));
+    ASSERT_FALSE(test_config.socketOpen("eth1", AF_INET6));
+
+    // Apply configuration.
+    EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json));
+    ASSERT_TRUE(status);
+    checkResult(status, 0);
+
+    CfgMgr::instance().getStagingCfg()->getCfgIface()->openSockets(AF_INET6, 10000);
+
+    // An address on eth0 was selected
     EXPECT_TRUE(test_config.socketOpen("eth0", AF_INET6));
+    // The 2001:db8:1::1 address on eth1 was selected.
     EXPECT_TRUE(test_config.socketOpen("eth1", AF_INET6));
 }
 
@@ -4755,6 +5082,9 @@ TEST_F(Dhcp6ParserTest, subnetRelayInfo) {
         "\"subnet6\": [ { "
         "    \"id\": 1,"
         "    \"pools\": [ { \"pool\": \"2001:db8:1::1 - 2001:db8:1::ffff\" } ],"
+        "    \"renew-timer\": 1, "
+        "    \"rebind-timer\": 2, "
+        "    \"valid-lifetime\": 4,"
         "    \"relay\": { "
         "        \"ip-addresses\": [ \"2001:db8:1::abcd\" ]"
         "    },"
@@ -4772,8 +5102,8 @@ TEST_F(Dhcp6ParserTest, subnetRelayInfo) {
     // returned value should be 0 (configuration success)
     checkResult(status, 0);
 
-    Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
-        selectSubnet(IOAddress("2001:db8:1::1"), classify_);
+    Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->
+        getCfgSubnets6()->selectSubnet(IOAddress("2001:db8:1::1"), classify_);
     ASSERT_TRUE(subnet);
 
     EXPECT_TRUE(subnet->hasRelays());
@@ -4789,6 +5119,9 @@ TEST_F(Dhcp6ParserTest, subnetRelayInfoList) {
         "\"subnet6\": [ { "
         "    \"id\": 1,"
         "    \"pools\": [ { \"pool\": \"2001:db8:1::1 - 2001:db8:1::ffff\" } ],"
+        "    \"renew-timer\": 1, "
+        "    \"rebind-timer\": 2, "
+        "    \"valid-lifetime\": 4,"
         "    \"relay\": { "
         "        \"ip-addresses\": [ \"2001:db9::abcd\", \"2001:db9::abce\" ]"
         "    },"
@@ -4806,8 +5139,8 @@ TEST_F(Dhcp6ParserTest, subnetRelayInfoList) {
     // returned value should be 0 (configuration success)
     checkResult(status, 0);
 
-    Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
-        selectSubnet(IOAddress("2001:db9::abcd"), classify_, true);
+    Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->
+        getCfgSubnets6()->selectSubnet(IOAddress("2001:db9::abcd"), classify_, true);
     ASSERT_TRUE(subnet);
 
     EXPECT_TRUE(subnet->hasRelays());
@@ -4960,10 +5293,10 @@ TEST_F(Dhcp6ParserTest, classifyPools) {
     // everyone).
     ClientClasses classes;
     classes.insert("alpha");
-    EXPECT_TRUE (pools.at(0)->clientSupported(classes));
+    EXPECT_TRUE(pools.at(0)->clientSupported(classes));
     EXPECT_FALSE(pools.at(1)->clientSupported(classes));
     EXPECT_FALSE(pools.at(2)->clientSupported(classes));
-    EXPECT_TRUE (pools.at(3)->clientSupported(classes));
+    EXPECT_TRUE(pools.at(3)->clientSupported(classes));
 
     // Let's check if client belonging to beta class is supported in pool[1]
     // and not supported in any other pool  (except pool[3], which allows
@@ -4971,9 +5304,9 @@ TEST_F(Dhcp6ParserTest, classifyPools) {
     classes.clear();
     classes.insert("beta");
     EXPECT_FALSE(pools.at(0)->clientSupported(classes));
-    EXPECT_TRUE (pools.at(1)->clientSupported(classes));
+    EXPECT_TRUE(pools.at(1)->clientSupported(classes));
     EXPECT_FALSE(pools.at(2)->clientSupported(classes));
-    EXPECT_TRUE (pools.at(3)->clientSupported(classes));
+    EXPECT_TRUE(pools.at(3)->clientSupported(classes));
 
     // Let's check if client belonging to gamma class is supported in pool[2]
     // and not supported in any other pool  (except pool[3], which allows
@@ -4982,8 +5315,8 @@ TEST_F(Dhcp6ParserTest, classifyPools) {
     classes.insert("gamma");
     EXPECT_FALSE(pools.at(0)->clientSupported(classes));
     EXPECT_FALSE(pools.at(1)->clientSupported(classes));
-    EXPECT_TRUE (pools.at(2)->clientSupported(classes));
-    EXPECT_TRUE (pools.at(3)->clientSupported(classes));
+    EXPECT_TRUE(pools.at(2)->clientSupported(classes));
+    EXPECT_TRUE(pools.at(3)->clientSupported(classes));
 
     // Let's check if client belonging to some other class (not mentioned in
     // the config) is supported only in pool[3], which allows everyone.
@@ -4992,7 +5325,7 @@ TEST_F(Dhcp6ParserTest, classifyPools) {
     EXPECT_FALSE(pools.at(0)->clientSupported(classes));
     EXPECT_FALSE(pools.at(1)->clientSupported(classes));
     EXPECT_FALSE(pools.at(2)->clientSupported(classes));
-    EXPECT_TRUE (pools.at(3)->clientSupported(classes));
+    EXPECT_TRUE(pools.at(3)->clientSupported(classes));
 
     // Finally, let's check class-less client. He should be allowed only in
     // the last pool, which does not have any class restrictions.
@@ -5000,7 +5333,7 @@ TEST_F(Dhcp6ParserTest, classifyPools) {
     EXPECT_FALSE(pools.at(0)->clientSupported(classes));
     EXPECT_FALSE(pools.at(1)->clientSupported(classes));
     EXPECT_FALSE(pools.at(2)->clientSupported(classes));
-    EXPECT_TRUE (pools.at(3)->clientSupported(classes));
+    EXPECT_TRUE(pools.at(3)->clientSupported(classes));
 }
 
 // Goal of this test is to verify that multiple pdpools can be configured
@@ -5059,10 +5392,10 @@ TEST_F(Dhcp6ParserTest, classifyPdPools) {
     // everyone).
     ClientClasses classes;
     classes.insert("alpha");
-    EXPECT_TRUE (pools.at(0)->clientSupported(classes));
+    EXPECT_TRUE(pools.at(0)->clientSupported(classes));
     EXPECT_FALSE(pools.at(1)->clientSupported(classes));
     EXPECT_FALSE(pools.at(2)->clientSupported(classes));
-    EXPECT_TRUE (pools.at(3)->clientSupported(classes));
+    EXPECT_TRUE(pools.at(3)->clientSupported(classes));
 
     // Let's check if client belonging to beta class is supported in pool[1]
     // and not supported in any other pool  (except pool[3], which allows
@@ -5070,9 +5403,9 @@ TEST_F(Dhcp6ParserTest, classifyPdPools) {
     classes.clear();
     classes.insert("beta");
     EXPECT_FALSE(pools.at(0)->clientSupported(classes));
-    EXPECT_TRUE (pools.at(1)->clientSupported(classes));
+    EXPECT_TRUE(pools.at(1)->clientSupported(classes));
     EXPECT_FALSE(pools.at(2)->clientSupported(classes));
-    EXPECT_TRUE (pools.at(3)->clientSupported(classes));
+    EXPECT_TRUE(pools.at(3)->clientSupported(classes));
 
     // Let's check if client belonging to gamma class is supported in pool[2]
     // and not supported in any other pool  (except pool[3], which allows
@@ -5081,8 +5414,8 @@ TEST_F(Dhcp6ParserTest, classifyPdPools) {
     classes.insert("gamma");
     EXPECT_FALSE(pools.at(0)->clientSupported(classes));
     EXPECT_FALSE(pools.at(1)->clientSupported(classes));
-    EXPECT_TRUE (pools.at(2)->clientSupported(classes));
-    EXPECT_TRUE (pools.at(3)->clientSupported(classes));
+    EXPECT_TRUE(pools.at(2)->clientSupported(classes));
+    EXPECT_TRUE(pools.at(3)->clientSupported(classes));
 
     // Let's check if client belonging to some other class (not mentioned in
     // the config) is supported only in pool[3], which allows everyone.
@@ -5091,7 +5424,7 @@ TEST_F(Dhcp6ParserTest, classifyPdPools) {
     EXPECT_FALSE(pools.at(0)->clientSupported(classes));
     EXPECT_FALSE(pools.at(1)->clientSupported(classes));
     EXPECT_FALSE(pools.at(2)->clientSupported(classes));
-    EXPECT_TRUE (pools.at(3)->clientSupported(classes));
+    EXPECT_TRUE(pools.at(3)->clientSupported(classes));
 
     // Finally, let's check class-less client. He should be allowed only in
     // the last pool, which does not have any class restrictions.
@@ -5099,7 +5432,7 @@ TEST_F(Dhcp6ParserTest, classifyPdPools) {
     EXPECT_FALSE(pools.at(0)->clientSupported(classes));
     EXPECT_FALSE(pools.at(1)->clientSupported(classes));
     EXPECT_FALSE(pools.at(2)->clientSupported(classes));
-    EXPECT_TRUE (pools.at(3)->clientSupported(classes));
+    EXPECT_TRUE(pools.at(3)->clientSupported(classes));
 }
 
 // This test verifies that valid d2CliengConfig works correctly.
@@ -5496,6 +5829,11 @@ TEST_F(Dhcp6ParserTest, reservationWithOptionDefinition) {
     ConstHostPtr host = hosts_cfg->get6(234, Host::IDENT_DUID,
                                         &duid[0], duid.size());
     ASSERT_TRUE(host);
+    IPv6ResrvRange resrv = host->getIPv6Reservations(IPv6Resrv::TYPE_NA);
+    ASSERT_EQ(1, std::distance(resrv.first, resrv.second));
+    EXPECT_TRUE(reservationExists(IPv6Resrv(IPv6Resrv::TYPE_NA,
+                                            IOAddress("2001:db8:2::1234")),
+                                  resrv));
 
     // Check if the option has been parsed.
     OptionUint32Ptr opt_foo = retrieveOption<OptionUint32Ptr>(*host, "isc",
@@ -5530,7 +5868,10 @@ TEST_F(Dhcp6ParserTest, reservationBogus) {
         "\"preferred-lifetime\": 3000,"
         "\"valid-lifetime\": 4000 }";
 
-    ConstElementPtr json = parseJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseJSON(config));
+
+    CfgMgr::instance().clear();
 
     EXPECT_NO_THROW(x = Dhcpv6SrvTest::configure(srv_, json));
     checkResult(x, 1);
@@ -5592,7 +5933,7 @@ TEST_F(Dhcp6ParserTest, reservationBogus) {
         "\"preferred-lifetime\": 3000,"
         "\"valid-lifetime\": 4000 }";
 
-    json = parseDHCP6(config);
+    ASSERT_NO_THROW(json = parseDHCP6(config));
 
     // Remove existing configuration, if any.
     CfgMgr::instance().clear();
@@ -5840,7 +6181,6 @@ TEST_F(Dhcp6ParserTest, hostReservationPerSubnet) {
     EXPECT_TRUE(subnet->getReservationsGlobal());
     EXPECT_TRUE(subnet->getReservationsInSubnet());
     EXPECT_TRUE(subnet->getReservationsOutOfPool());
-
 }
 
 /// The goal of this test is to verify that Host Reservation flags can be
@@ -5898,6 +6238,10 @@ TEST_F(Dhcp6ParserTest, hostReservationGlobal) {
     Subnet6Ptr subnet;
     subnet = subnets->selectSubnet(IOAddress("2001:db8:1::1"));
     ASSERT_TRUE(subnet);
+    // Reset the fetch global function to staging (vs current) config.
+    subnet->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
+        return (CfgMgr::instance().getCurrentCfg()->getConfiguredGlobals());
+    });
     EXPECT_FALSE(subnet->getReservationsGlobal());
     EXPECT_TRUE(subnet->getReservationsInSubnet());
     EXPECT_FALSE(subnet->getReservationsOutOfPool());
@@ -5905,11 +6249,39 @@ TEST_F(Dhcp6ParserTest, hostReservationGlobal) {
     // Subnet 2
     subnet = subnets->selectSubnet(IOAddress("2001:db8:2::1"));
     ASSERT_TRUE(subnet);
+    // Reset the fetch global function to staging (vs current) config.
+    subnet->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
+        return (CfgMgr::instance().getCurrentCfg()->getConfiguredGlobals());
+    });
     EXPECT_FALSE(subnet->getReservationsGlobal());
     EXPECT_TRUE(subnet->getReservationsInSubnet());
     EXPECT_TRUE(subnet->getReservationsOutOfPool());
 }
 
+/// Check that the decline-probation-period has a default value when not
+/// specified.
+TEST_F(Dhcp6ParserTest, declineTimerDefault) {
+
+    string config = "{ " + genIfaceConfig() + ","
+        "\"subnet6\": [  ] "
+        "}";
+
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
+    extractConfig(config);
+
+    ConstElementPtr status;
+    EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json));
+
+    // returned value should be 0 (success)
+    checkResult(status, 0);
+
+    // The value of decline-probation-period must be equal to the
+    // default value (86400). The default value is defined in GLOBAL6_DEFAULTS in
+    // simple_parser6.cc.
+    EXPECT_EQ(86400, CfgMgr::instance().getStagingCfg()->getDeclinePeriod());
+}
+
 /// The goal of this test is to verify that configuration can include
 /// Relay Supplied options (specified as numbers).
 TEST_F(Dhcp6ParserTest, rsooNumbers) {
@@ -6104,29 +6476,6 @@ TEST_F(Dhcp6ParserTest, testDataDir) {
     EXPECT_NE(original_datadir, string(CfgMgr::instance().getDataDir()));
 }
 
-/// Check that the decline-probation-period value has a default value if not
-/// specified explicitly.
-TEST_F(Dhcp6ParserTest, declineTimerDefault) {
-
-    string config_txt = "{ " + genIfaceConfig() + ","
-        "\"subnet6\": [  ] "
-        "}";
-    ConstElementPtr config;
-    ASSERT_NO_THROW(config = parseDHCP6(config_txt));
-    extractConfig(config_txt);
-
-    ConstElementPtr status;
-    EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, config));
-
-    // returned value should be 0 (success)
-    checkResult(status, 0);
-
-    // The value of decline-probation-period must be equal to the
-    // default value (86400). The default value is defined in GLOBAL6_DEFAULTS in
-    // simple_parser6.cc.
-    EXPECT_EQ(86400, CfgMgr::instance().getStagingCfg()->getDeclinePeriod());
-}
-
 /// Check that the dhcp4o6-port default value has a default value if not
 /// specified explicitly.
 TEST_F(Dhcp6ParserTest, dhcp4o6portDefault) {
@@ -6152,7 +6501,7 @@ TEST_F(Dhcp6ParserTest, dhcp4o6portDefault) {
 
 /// Check that the decline-probation-period value can be set properly.
 TEST_F(Dhcp6ParserTest, declineTimer) {
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"decline-probation-period\": 12345,"
         "\"subnet6\": [ ]"
         "}";
@@ -6175,12 +6524,13 @@ TEST_F(Dhcp6ParserTest, declineTimer) {
 
 /// Check that an incorrect decline-probation-period value will be caught.
 TEST_F(Dhcp6ParserTest, declineTimerError) {
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"decline-probation-period\": \"soon\","
         "\"subnet6\": [ ]"
         "}";
 
-    ConstElementPtr json = parseJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseJSON(config));
 
     ConstElementPtr status;
     EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json));
@@ -6199,7 +6549,7 @@ TEST_F(Dhcp6ParserTest, declineTimerError) {
 // specified.
 TEST_F(Dhcp6ParserTest, expiredLeasesProcessing) {
     // Create basic configuration with the expiration specific parameters.
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"expired-leases-processing\": "
         "{"
         "    \"reclaim-timer-wait-time\": 20,"
@@ -6241,7 +6591,7 @@ TEST_F(Dhcp6ParserTest, expiredLeasesProcessing) {
 TEST_F(Dhcp6ParserTest, expiredLeasesProcessingError) {
     // Create basic configuration with the expiration specific parameters.
     // One of the parameters holds invalid value.
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"expired-leases-processing\": "
         "{"
         "    \"reclaim-timer-wait-time\": -5,"
@@ -6267,36 +6617,165 @@ TEST_F(Dhcp6ParserTest, expiredLeasesProcessingError) {
     EXPECT_TRUE(errorContainsPosition(status, "<string>"));
 }
 
-// Verifies that simple list of valid classes parses and
+// Verifies that simple list of valid classes parses and
+// is staged for commit.
+TEST_F(Dhcp6ParserTest, validClientClassDictionary) {
+    string config = "{ " + genIfaceConfig() + ","
+        "\"preferred-lifetime\": 3000, \n"
+        "\"valid-lifetime\": 4000, \n"
+        "\"rebind-timer\": 2000,  \n"
+        "\"renew-timer\": 1000,  \n"
+        "\"client-classes\" : [ \n"
+        "   { \n"
+        "       \"name\": \"one\" \n"
+        "   }, \n"
+        "   { \n"
+        "       \"name\": \"two\" \n"
+        "   }, \n"
+        "   { \n"
+        "       \"name\": \"three\" \n"
+        "   } \n"
+        "], \n"
+        "\"subnet6\": [ {  \n"
+        "    \"id\": 1, \n"
+        "    \"pools\": [ { \"pool\": \"2001:db8:1::1 - 2001:db8:1::ffff\" } ], \n"
+        "    \"subnet\": \"2001:db8:1::/64\"  \n"
+        " } ] \n"
+        "} \n";
+
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
+    extractConfig(config);
+
+    ConstElementPtr status;
+    EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json));
+    ASSERT_TRUE(status);
+    checkResult(status, 0);
+
+    // We check staging config because CfgMgr::commit hasn't been executed.
+    ClientClassDictionaryPtr dictionary;
+    dictionary = CfgMgr::instance().getStagingCfg()->getClientClassDictionary();
+    ASSERT_TRUE(dictionary);
+    EXPECT_EQ(3, dictionary->getClasses()->size());
+
+    // Execute the commit
+    ASSERT_NO_THROW(CfgMgr::instance().commit());
+
+    // Verify that after commit, the current config has the correct dictionary
+    dictionary = CfgMgr::instance().getCurrentCfg()->getClientClassDictionary();
+    ASSERT_TRUE(dictionary);
+    EXPECT_EQ(3, dictionary->getClasses()->size());
+}
+
+// Verifies that a class list containing an invalid
+// class definition causes a configuration error.
+TEST_F(Dhcp6ParserTest, invalidClientClassDictionary) {
+    string config = "{ " + genIfaceConfig() + ","
+        "\"valid-lifetime\": 4000, \n"
+        "\"rebind-timer\": 2000, \n"
+        "\"renew-timer\": 1000, \n"
+        "\"client-classes\" : [ \n"
+        "   { \n"
+        "       \"name\": \"one\", \n"
+        "       \"bogus\": \"bad\" \n"
+        "   } \n"
+        "], \n"
+        "\"subnet6\": [ {  \n"
+        "    \"id\": 1, \n"
+        "    \"pools\": [ { \"pool\":  \"2001:db8::1 - 2001:db8::ffff\" } ], \n"
+        "    \"subnet\": \"2001:db8::/64\"  \n"
+        " } ] \n"
+        "} \n";
+
+    EXPECT_THROW(parseDHCP6(config), Dhcp6ParseError);
+}
+
+// Verifies that simple list of valid classes parses and
+// is staged for commit.
+TEST_F(Dhcp6ParserTest, clientClassValidLifetime) {
+    string config = "{ " + genIfaceConfig() + ","
+        "\"client-classes\" : [ \n"
+        "   { \n"
+        "       \"name\": \"one\", \n"
+        "       \"min-valid-lifetime\": 1000, \n"
+        "       \"valid-lifetime\": 2000, \n"
+        "       \"max-valid-lifetime\": 3000 \n"
+        "   }, \n"
+        "   { \n"
+        "       \"name\": \"two\" \n"
+        "   } \n"
+        "], \n"
+        "\"subnet6\": [ {  \n"
+        "    \"id\": 1, \n"
+        "    \"pools\": [ { \"pool\":  \"2001:db8::1 - 2001:db8::ffff\" } ], \n"
+        "    \"subnet\": \"2001:db8::/64\"  \n"
+        " } ] \n"
+        "} \n";
+
+    ConstElementPtr json;
+    ASSERT_NO_THROW_LOG(json = parseDHCP6(config));
+    extractConfig(config);
+
+    ConstElementPtr status;
+    ASSERT_NO_THROW_LOG(status = Dhcpv6SrvTest::configure(srv_, json));
+    ASSERT_TRUE(status);
+    checkResult(status, 0);
+
+    // We check staging config because CfgMgr::commit hasn't been executed.
+    ClientClassDictionaryPtr dictionary;
+    dictionary = CfgMgr::instance().getStagingCfg()->getClientClassDictionary();
+    ASSERT_TRUE(dictionary);
+    EXPECT_EQ(2, dictionary->getClasses()->size());
+
+    // Execute the commit
+    ASSERT_NO_THROW(CfgMgr::instance().commit());
+
+    // Verify that after commit, the current config has the correct dictionary
+    dictionary = CfgMgr::instance().getCurrentCfg()->getClientClassDictionary();
+    ASSERT_TRUE(dictionary);
+    EXPECT_EQ(2, dictionary->getClasses()->size());
+
+    ClientClassDefPtr class_def = dictionary->findClass("one");
+    ASSERT_TRUE(class_def);
+    EXPECT_EQ(class_def->getValid().getMin(), 1000);
+    EXPECT_EQ(class_def->getValid().get(), 2000);
+    EXPECT_EQ(class_def->getValid().getMax(), 3000);
+
+    class_def = dictionary->findClass("two");
+    ASSERT_TRUE(class_def);
+    EXPECT_TRUE(class_def->getValid().unspecified());
+}
+
+// Verifies that simple list of valid template classes parses and
 // is staged for commit.
-TEST_F(Dhcp6ParserTest, validClientClassDictionary) {
+TEST_F(Dhcp6ParserTest, templateClientClassValidLifetime) {
     string config = "{ " + genIfaceConfig() + ","
-        "\"preferred-lifetime\": 3000, \n"
-        "\"rebind-timer\": 2000,  \n"
-        "\"renew-timer\": 1000,  \n"
         "\"client-classes\" : [ \n"
         "   { \n"
-        "       \"name\": \"one\" \n"
-        "   }, \n"
-        "   { \n"
-        "       \"name\": \"two\" \n"
+        "       \"name\": \"one\", \n"
+        "       \"min-valid-lifetime\": 1000, \n"
+        "       \"valid-lifetime\": 2000, \n"
+        "       \"max-valid-lifetime\": 3000, \n"
+        "       \"template-test\": \"''\" \n"
         "   }, \n"
         "   { \n"
-        "       \"name\": \"three\" \n"
+        "       \"name\": \"two\", \n"
+        "       \"template-test\": \"''\" \n"
         "   } \n"
         "], \n"
         "\"subnet6\": [ {  \n"
         "    \"id\": 1, \n"
-        "    \"pools\": [ { \"pool\": \"2001:db8:1::1 - 2001:db8:1::ffff\" } ], \n"
-        "    \"subnet\": \"2001:db8:1::/64\" } ], \n"
-        "\"valid-lifetime\": 4000 } \n";
+        "    \"pools\": [ { \"pool\":  \"2001:db8::1 - 2001:db8::ffff\" } ], \n"
+        "    \"subnet\": \"2001:db8::/64\"  \n"
+        " } ] \n"
+        "} \n";
 
     ConstElementPtr json;
-    ASSERT_NO_THROW(json = parseDHCP6(config));
+    ASSERT_NO_THROW_LOG(json = parseDHCP6(config));
     extractConfig(config);
 
     ConstElementPtr status;
-    EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json));
+    ASSERT_NO_THROW_LOG(status = Dhcpv6SrvTest::configure(srv_, json));
     ASSERT_TRUE(status);
     checkResult(status, 0);
 
@@ -6304,7 +6783,7 @@ TEST_F(Dhcp6ParserTest, validClientClassDictionary) {
     ClientClassDictionaryPtr dictionary;
     dictionary = CfgMgr::instance().getStagingCfg()->getClientClassDictionary();
     ASSERT_TRUE(dictionary);
-    EXPECT_EQ(3, dictionary->getClasses()->size());
+    EXPECT_EQ(2, dictionary->getClasses()->size());
 
     // Execute the commit
     ASSERT_NO_THROW(CfgMgr::instance().commit());
@@ -6312,30 +6791,19 @@ TEST_F(Dhcp6ParserTest, validClientClassDictionary) {
     // Verify that after commit, the current config has the correct dictionary
     dictionary = CfgMgr::instance().getCurrentCfg()->getClientClassDictionary();
     ASSERT_TRUE(dictionary);
-    EXPECT_EQ(3, dictionary->getClasses()->size());
-}
+    EXPECT_EQ(2, dictionary->getClasses()->size());
 
-// Verifies that a class list containing an invalid
-// class definition causes a configuration error.
-TEST_F(Dhcp6ParserTest, invalidClientClassDictionary) {
-    string config = "{ " + genIfaceConfig() + "," +
-        "\"valid-lifetime\": 4000, \n"
-        "\"rebind-timer\": 2000, \n"
-        "\"renew-timer\": 1000, \n"
-        "\"client-classes\" : [ \n"
-        "   { \n"
-        "       \"name\": \"one\", \n"
-        "       \"bogus\": \"bad\" \n"
-        "   } \n"
-        "], \n"
-        "\"subnet6\": [ {  \n"
-        "    \"id\": 1, \n"
-        "    \"pools\": [ { \"pool\":  \"2001:db8::1 - 2001:db8::ffff\" } ], \n"
-        "    \"subnet\": \"2001:db8::/64\"  \n"
-        " } ] \n"
-        "} \n";
+    ClientClassDefPtr class_def = dictionary->findClass("one");
+    ASSERT_TRUE(class_def);
+    ASSERT_TRUE(dynamic_cast<TemplateClientClassDef*>(class_def.get()));
+    EXPECT_EQ(class_def->getValid().getMin(), 1000);
+    EXPECT_EQ(class_def->getValid().get(), 2000);
+    EXPECT_EQ(class_def->getValid().getMax(), 3000);
 
-    EXPECT_THROW(parseDHCP6(config), Dhcp6ParseError);
+    class_def = dictionary->findClass("two");
+    ASSERT_TRUE(class_def);
+    ASSERT_TRUE(dynamic_cast<TemplateClientClassDef*>(class_def.get()));
+    EXPECT_TRUE(class_def->getValid().unspecified());
 }
 
 // Test verifies that regular configuration does not provide any user context
@@ -6403,6 +6871,46 @@ TEST_F(Dhcp6ParserTest, poolUserContextlw4over6) {
     EXPECT_EQ(56L, int_value);
 }
 
+// Test verifies that it's possible to specify parameters in the user context
+// in the address pool.
+TEST_F(Dhcp6ParserTest, poolUserContextData) {
+    extractConfig(PARSER_CONFIGS[2]);
+    PoolPtr pool;
+    getPool(string(PARSER_CONFIGS[2]), 0, 0, Lease::TYPE_NA, pool);
+    ASSERT_TRUE(pool);
+    ConstElementPtr ctx = pool->getContext();
+    ASSERT_TRUE(ctx);
+
+    // The context should be of type map and contain 4 parameters.
+    EXPECT_EQ(Element::map, ctx->getType());
+    EXPECT_EQ(4, ctx->size());
+    ConstElementPtr ratio   = ctx->get("lw4over6-sharing-ratio");
+    ConstElementPtr v4pool  = ctx->get("lw4over6-v4-pool");
+    ConstElementPtr exclude = ctx->get("lw4over6-sysports-exclude");
+    ConstElementPtr v6len   = ctx->get("lw4over6-bind-prefix-len");
+
+    ASSERT_TRUE(ratio);
+    ASSERT_EQ(Element::integer, ratio->getType());
+    int64_t int_value;
+    EXPECT_NO_THROW(ratio->getValue(int_value));
+    EXPECT_EQ(64L, int_value);
+
+    ASSERT_TRUE(v4pool);
+    ASSERT_EQ(Element::string, v4pool->getType());
+    EXPECT_EQ("192.0.2.0/24", v4pool->stringValue());
+
+    ASSERT_TRUE(exclude);
+    bool bool_value;
+    ASSERT_EQ(Element::boolean, exclude->getType());
+    EXPECT_NO_THROW(exclude->getValue(bool_value));
+    EXPECT_EQ(true, bool_value);
+
+    ASSERT_TRUE(v6len);
+    ASSERT_EQ(Element::integer, v6len->getType());
+    EXPECT_NO_THROW(v6len->getValue(int_value));
+    EXPECT_EQ(56L, int_value);
+}
+
 // Test verifies that it's possible to specify parameters in the user context
 // in the min-max address pool.
 TEST_F(Dhcp6ParserTest, poolMinMaxUserContext) {
@@ -6523,21 +7031,10 @@ TEST_F(Dhcp6ParserTest, invalidPoolRange) {
         " } ] \n"
         "} \n";
 
-    ConstElementPtr json;
-    ASSERT_NO_THROW(json = parseDHCP6(config, true));
-
-    ConstElementPtr status;
-    EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json));
-    ASSERT_TRUE(status);
-    int rcode;
-    ConstElementPtr comment = parseAnswerText(rcode, status);
-    string text;
-    ASSERT_NO_THROW(text = comment->stringValue());
-
-    EXPECT_EQ(1, rcode);
     string expected = "Failed to create pool defined by: "
         "2001:db8::-200:1db8::ffff (<string>:8:26)";
-    EXPECT_EQ(expected, text);
+
+    configure(config, CONTROL_RESULT_ERROR, expected);
 }
 
 // Test verifies the error message for an outside subnet pool range
@@ -6555,23 +7052,12 @@ TEST_F(Dhcp6ParserTest, outsideSubnetPool) {
         " } ] \n"
         "} \n";
 
-    ConstElementPtr json;
-    ASSERT_NO_THROW(json = parseDHCP6(config, true));
-
-    ConstElementPtr status;
-    EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json));
-    ASSERT_TRUE(status);
-    int rcode;
-    ConstElementPtr comment = parseAnswerText(rcode, status);
-    string text;
-    ASSERT_NO_THROW(text = comment->stringValue());
-
-    EXPECT_EQ(1, rcode);
     string expected = "subnet configuration failed: "
         "a pool of type IA_NA, with the following address range: "
         "2001:db8::-2001:db8::ffff does not match the prefix of a subnet: "
         "2001:dc8::/32 to which it is being added (<string>:6:14)";
-    EXPECT_EQ(expected, text);
+
+    configure(config, CONTROL_RESULT_ERROR, expected);
 }
 
 // Test verifies that empty shared networks are accepted.
@@ -6582,6 +7068,7 @@ TEST_F(Dhcp6ParserTest, sharedNetworksEmpty) {
         "\"renew-timer\": 1000, \n"
         "\"subnet6\": [ {  \n"
         "    \"id\": 1, \n"
+        "    \"pools\": [ { \"pool\": \"2001:db8:: - 2001:db8::ffff\" } ], \n"
         "    \"subnet\": \"2001:db8::/48\"  \n"
         " } ],\n"
         "\"shared-networks\": [ ]\n"
@@ -6599,6 +7086,7 @@ TEST_F(Dhcp6ParserTest, sharedNetworksNoName) {
         "\"renew-timer\": 1000, \n"
         "\"subnet6\": [ {  \n"
         "    \"id\": 1, \n"
+        "    \"pools\": [ { \"pool\": \"2001:db8:: - 2001:db8::ffff\" } ], \n"
         "    \"subnet\": \"2001:db8::/48\"  \n"
         " } ],\n"
         "\"shared-networks\": [ { } ]\n"
@@ -6615,6 +7103,7 @@ TEST_F(Dhcp6ParserTest, sharedNetworksEmptyName) {
         "\"renew-timer\": 1000, \n"
         "\"subnet6\": [ {  \n"
         "    \"id\": 1, \n"
+        "    \"pools\": [ { \"pool\": \"2001:db8:: - 2001:db8::ffff\" } ], \n"
         "    \"subnet\": \"2001:db8::/48\"  \n"
         " } ],\n"
         "\"shared-networks\": [ { \"name\": \"\" } ]\n"
@@ -6630,8 +7119,8 @@ TEST_F(Dhcp6ParserTest, sharedNetworksName) {
     string config = "{\n"
         "\"subnet6\": [ {  \n"
         "    \"id\": 1, \n"
-        "    \"subnet\": \"2001:db8::/48\",\n"
-        "    \"pools\": [ { \"pool\": \"2001:db8::1 - 2001:db8::ffff\" } ]\n"
+        "    \"pools\": [ { \"pool\": \"2001:db8:: - 2001:db8::ffff\" } ], \n"
+        "    \"subnet\": \"2001:db8::/48\"\n"
         " } ],\n"
         "\"shared-networks\": [ { \"name\": \"foo\" } ]\n"
         "} \n";
@@ -6663,7 +7152,7 @@ TEST_F(Dhcp6ParserTest, sharedNetworks1subnet) {
         "\"shared-networks\": [ {\n"
         "    \"name\": \"foo\"\n,"
         "    \"subnet6\": [ { \n"
-        "        \"id\": 1, \n"
+        "        \"id\": 1,\n"
         "        \"subnet\": \"2001:db8::/48\",\n"
         "        \"pools\": [ { \"pool\": \"2001:db8::1 - 2001:db8::ffff\" } ]\n"
         "    } ]\n"
@@ -6711,24 +7200,24 @@ TEST_F(Dhcp6ParserTest, sharedNetworks1subnet) {
 // - that overridden parameters only affect one subnet and not others
 TEST_F(Dhcp6ParserTest, sharedNetworks3subnets) {
     string config = "{\n"
+        "\"valid-lifetime\": 4000, \n"
+        "\"min-valid-lifetime\": 3000, \n"
+        "\"max-valid-lifetime\": 5000, \n"
         "\"renew-timer\": 1000, \n"
         "\"rebind-timer\": 2000, \n"
         "\"preferred-lifetime\": 3000, \n"
         "\"min-preferred-lifetime\": 2000, \n"
         "\"max-preferred-lifetime\": 4000, \n"
-        "\"valid-lifetime\": 4000, \n"
-        "\"min-valid-lifetime\": 3000, \n"
-        "\"max-valid-lifetime\": 5000, \n"
         "\"shared-networks\": [ {\n"
         "    \"name\": \"foo\"\n,"
         "    \"subnet6\": [\n"
         "    { \n"
-        "        \"id\": 1, \n"
+        "        \"id\": 1,\n"
         "        \"subnet\": \"2001:db1::/48\",\n"
         "        \"pools\": [ { \"pool\": \"2001:db1::/64\" } ]\n"
         "    },\n"
         "    { \n"
-        "        \"id\": 2, \n"
+        "        \"id\": 2,\n"
         "        \"subnet\": \"2001:db2::/48\",\n"
         "        \"pools\": [ { \"pool\": \"2001:db2::/64\" } ],\n"
         "        \"renew-timer\": 2,\n"
@@ -6741,7 +7230,7 @@ TEST_F(Dhcp6ParserTest, sharedNetworks3subnets) {
         "        \"max-valid-lifetime\": 3333\n"
         "    },\n"
         "    { \n"
-        "        \"id\": 3, \n"
+        "        \"id\": 3,\n"
         "        \"subnet\": \"2001:db3::/48\",\n"
         "        \"pools\": [ { \"pool\": \"2001:db3::/64\" } ]\n"
         "    }\n"
@@ -6817,7 +7306,7 @@ TEST_F(Dhcp6ParserTest, sharedNetworksDerive) {
     Option iface_id2(Option::V6, D6O_INTERFACE_ID, buffer2);
 
     string config = "{\n"
-        "\"renew-timer\": 1, \n"
+        "\"renew-timer\": 1, \n" // global values here
         "\"rebind-timer\": 2, \n"
         "\"preferred-lifetime\": 3,\n"
         "\"min-preferred-lifetime\": 2,\n"
@@ -6826,7 +7315,7 @@ TEST_F(Dhcp6ParserTest, sharedNetworksDerive) {
         "\"min-valid-lifetime\": 3, \n"
         "\"max-valid-lifetime\": 5, \n"
         "\"shared-networks\": [ {\n"
-        "    \"name\": \"foo\"\n,"
+        "    \"name\": \"foo\"\n," // shared network values here
         "    \"renew-timer\": 10,\n"
         "    \"rebind-timer\": 20, \n"
         "    \"preferred-lifetime\": 30,\n"
@@ -6845,12 +7334,12 @@ TEST_F(Dhcp6ParserTest, sharedNetworksDerive) {
         "    \"reservations-in-subnet\": false,\n"
         "    \"subnet6\": [\n"
         "    { \n"
-        "        \"id\": 1, \n"
+        "        \"id\": 1,\n"
         "        \"subnet\": \"2001:db1::/48\",\n"
         "        \"pools\": [ { \"pool\": \"2001:db1::/64\" } ]\n"
         "    },\n"
         "    { \n"
-        "        \"id\": 2, \n"
+        "        \"id\": 2,\n"
         "        \"subnet\": \"2001:db2::/48\",\n"
         "        \"pools\": [ { \"pool\": \"2001:db2::/64\" } ],\n"
         "        \"renew-timer\": 100\n,"
@@ -6876,12 +7365,12 @@ TEST_F(Dhcp6ParserTest, sharedNetworksDerive) {
         "    \"name\": \"bar\",\n"
         "    \"subnet6\": [\n"
         "    {\n"
-        "        \"id\": 3, \n"
+        "        \"id\": 3,\n"
         "        \"subnet\": \"2001:db3::/48\",\n"
         "        \"pools\": [ { \"pool\": \"2001:db3::/64\" } ]\n"
         "    }\n"
         "    ]\n"
-        "} ]\n"
+        " } ]\n"
         "} \n";
 
     configure(config, CONTROL_RESULT_SUCCESS, "");
@@ -6900,6 +7389,7 @@ TEST_F(Dhcp6ParserTest, sharedNetworksDerive) {
     SharedNetwork6Ptr net = nets->at(0);
     ASSERT_TRUE(net);
 
+    // The first shared network has two subnets.
     const Subnet6SimpleCollection* subs = net->getAllSubnets();
     ASSERT_TRUE(subs);
     EXPECT_EQ(2, subs->size());
@@ -6944,6 +7434,7 @@ TEST_F(Dhcp6ParserTest, sharedNetworksDerive) {
     EXPECT_EQ(1, subs->size());
 
     // This subnet should derive its renew-timer from global scope.
+    // All other parameters should have default values.
     s = checkSubnet(*subs, "2001:db3::/48", 1, 2, 3, 4, 2, 4, 3, 5);
     EXPECT_FALSE(s->getInterfaceId());
     EXPECT_FALSE(s->hasRelays());
@@ -7081,18 +7572,25 @@ TEST_F(Dhcp6ParserTest, sharedNetworksInterfacesMixed) {
 // This test checks if client-class is derived properly.
 TEST_F(Dhcp6ParserTest, sharedNetworksDeriveClientClass) {
 
+    // This config is structured in a way that the first shared network has
+    // client-class defined. This should in general be inherited by subnets, but
+    // it's also possible to override the values on subnet level.
     string config = "{\n"
+        "\"renew-timer\": 1, \n" // global values here
+        "\"rebind-timer\": 2, \n"
+        "\"preferred-lifetime\": 3,\n"
+        "\"valid-lifetime\": 4, \n"
         "\"shared-networks\": [ {\n"
-        "    \"name\": \"foo\"\n,"
+        "    \"name\": \"foo\"\n," // shared network values here
         "    \"client-class\": \"alpha\",\n"
         "    \"subnet6\": [\n"
         "    { \n"
-        "        \"id\": 1, \n"
+        "        \"id\": 1,\n"
         "        \"subnet\": \"2001:db1::/48\",\n"
         "        \"pools\": [ { \"pool\": \"2001:db1::/64\" } ]\n"
         "    },\n"
         "    { \n"
-        "        \"id\": 2, \n"
+        "        \"id\": 2,\n"
         "        \"subnet\": \"2001:db2::/48\",\n"
         "        \"pools\": [ { \"pool\": \"2001:db2::/64\" } ],\n"
         "        \"client-class\": \"beta\"\n"
@@ -7103,12 +7601,12 @@ TEST_F(Dhcp6ParserTest, sharedNetworksDeriveClientClass) {
         "    \"name\": \"bar\",\n"
         "    \"subnet6\": [\n"
         "    {\n"
-        "        \"id\": 3, \n"
+        "        \"id\": 3,\n"
         "        \"subnet\": \"2001:db3::/48\",\n"
         "        \"pools\": [ { \"pool\": \"2001:db3::/64\" } ]\n"
         "    }\n"
         "    ]\n"
-        "} ]\n"
+        " } ]\n"
         "} \n";
 
     configure(config, CONTROL_RESULT_SUCCESS, "");
@@ -7126,21 +7624,23 @@ TEST_F(Dhcp6ParserTest, sharedNetworksDeriveClientClass) {
     // Let's check the first one.
     SharedNetwork6Ptr net = nets->at(0);
     ASSERT_TRUE(net);
+
     EXPECT_EQ("alpha", net->getClientClass().get());
 
+    // The first shared network has two subnets.
     const Subnet6SimpleCollection* subs = net->getAllSubnets();
     ASSERT_TRUE(subs);
     EXPECT_EQ(2, subs->size());
 
     // For the first subnet, the client-class should be inherited from
     // shared-network level.
-    Subnet6Ptr s = checkSubnet(*subs, "2001:db1::/48", 0, 0, 0, 7200);
+    Subnet6Ptr s = checkSubnet(*subs, "2001:db1::/48", 1, 2, 3, 4);
     ASSERT_TRUE(s);
     EXPECT_EQ("alpha", s->getClientClass().get());
 
     // For the second subnet, the values are overridden on subnet level.
     // The value should not be inherited.
-    s = checkSubnet(*subs, "2001:db2::/48", 0, 0, 0, 7200);
+    s = checkSubnet(*subs, "2001:db2::/48", 1, 2, 3, 4);
     ASSERT_TRUE(s);
     EXPECT_EQ("beta", s->getClientClass().get()); // beta defined on subnet level
 
@@ -7155,7 +7655,7 @@ TEST_F(Dhcp6ParserTest, sharedNetworksDeriveClientClass) {
     EXPECT_EQ(1, subs->size());
 
     // This subnet should derive its renew-timer from global scope.
-    s = checkSubnet(*subs, "2001:db3::/48", 0, 0, 0, 7200);
+    s = checkSubnet(*subs, "2001:db3::/48", 1, 2, 3, 4);
     EXPECT_TRUE(s->getClientClass().empty());
 }
 
@@ -7473,6 +7973,8 @@ TEST_F(Dhcp6ParserTest, comments) {
     ASSERT_EQ(1, subs->size());
     Subnet6Ptr sub = *subs->begin();
     ASSERT_TRUE(sub);
+    EXPECT_EQ(100, sub->getID());
+    EXPECT_EQ("2001:db1::/48", sub->toText());
 
     // Check subnet user context.
     ConstElementPtr ctx_sub = sub->getContext();
@@ -7480,8 +7982,6 @@ TEST_F(Dhcp6ParserTest, comments) {
     ASSERT_EQ(1, ctx_sub->size());
     ASSERT_TRUE(ctx_sub->get("comment"));
     EXPECT_EQ("\"A subnet\"", ctx_sub->get("comment")->str());
-    EXPECT_EQ(100, sub->getID());
-    EXPECT_EQ("2001:db1::/48", sub->toText());
 
     // The subnet has a pool.
     const PoolCollection& pools = sub->getPools(Lease::TYPE_NA);
@@ -7621,7 +8121,6 @@ TEST_F(Dhcp6ParserTest, globalReservations) {
         "\"valid-lifetime\": 4000 }\n";
 
     ConstElementPtr json;
-    (json = parseDHCP6(config));
     ASSERT_NO_THROW(json = parseDHCP6(config));
     extractConfig(config);
 
@@ -7647,6 +8146,7 @@ TEST_F(Dhcp6ParserTest, globalReservations) {
     for (unsigned int i = 1; i < 7; ++i) {
         hwaddr.push_back(static_cast<uint8_t>(i));
     }
+
     // Retrieve the reservation and sanity check the address reserved.
     ConstHostPtr host = hosts_cfg->get6(SUBNET_ID_GLOBAL, Host::IDENT_HWADDR,
                                         &hwaddr[0], hwaddr.size());
@@ -7656,10 +8156,12 @@ TEST_F(Dhcp6ParserTest, globalReservations) {
     EXPECT_TRUE(reservationExists(IPv6Resrv(IPv6Resrv::TYPE_NA,
                                             IOAddress("2001:db8:2::abcd")),
                                   resrv));
+
     // This reservation should be solely assigned to the subnet 234,
     // and not to other two.
     EXPECT_FALSE(hosts_cfg->get6(123, Host::IDENT_HWADDR,
                                  &hwaddr[0], hwaddr.size()));
+
     EXPECT_FALSE(hosts_cfg->get6(542, Host::IDENT_HWADDR,
                                  &hwaddr[0], hwaddr.size()));
     // Check that options are assigned correctly.
@@ -7679,6 +8181,8 @@ TEST_F(Dhcp6ParserTest, globalReservations) {
     for (unsigned int i = 1; i < 0xb; ++i) {
         duid.push_back(static_cast<uint8_t>(i));
     }
+
+    // Retrieve the global reservation and sanity check the  hostname reserved.
     host = hosts_cfg->get6(SUBNET_ID_GLOBAL, Host::IDENT_DUID, &duid[0], duid.size());
     ASSERT_TRUE(host);
     resrv = host->getIPv6Reservations(IPv6Resrv::TYPE_NA);
@@ -7686,8 +8190,7 @@ TEST_F(Dhcp6ParserTest, globalReservations) {
     EXPECT_TRUE(reservationExists(IPv6Resrv(IPv6Resrv::TYPE_NA,
                                             IOAddress("2001:db8:2::1234")),
                                   resrv));
-    EXPECT_FALSE(hosts_cfg->get6(123, Host::IDENT_DUID, &duid[0], duid.size()));
-    EXPECT_FALSE(hosts_cfg->get6(542, Host::IDENT_DUID, &duid[0], duid.size()));
+
     // Check that options are assigned correctly.
     opt_dns = retrieveOption<Option6AddrLstPtr>(*host, D6O_NAME_SERVERS);
     ASSERT_TRUE(opt_dns);
@@ -7697,6 +8200,11 @@ TEST_F(Dhcp6ParserTest, globalReservations) {
     opt_prf = retrieveOption<OptionUint8Ptr>(*host, D6O_PREFERENCE);
     ASSERT_TRUE(opt_prf);
     EXPECT_EQ(11, static_cast<int>(opt_prf->getValue()));
+
+    // This reservation should be global solely and not assigned to
+    // either subnet
+    EXPECT_FALSE(hosts_cfg->get6(123, Host::IDENT_DUID, &duid[0], duid.size()));
+    EXPECT_FALSE(hosts_cfg->get6(542, Host::IDENT_DUID, &duid[0], duid.size()));
 }
 
 // Rather than disable these tests they are compiled out.  This avoids them
@@ -7754,18 +8262,18 @@ TEST_F(Dhcp6ParserTest, configControlInfo) {
 // Check whether it is possible to configure server-tag
 TEST_F(Dhcp6ParserTest, serverTag) {
     // Config without server-tag
-    string config_no_tag = "{ " + genIfaceConfig() + "," +
+    string config_no_tag = "{ " + genIfaceConfig() + ","
         "\"subnet6\": [  ] "
         "}";
 
     // Config with server-tag
-    string config_tag = "{ " + genIfaceConfig() + "," +
+    string config_tag = "{ " + genIfaceConfig() + ","
         "\"server-tag\": \"boo\", "
         "\"subnet6\": [  ] "
         "}";
 
     // Config with an invalid server-tag
-    string bad_tag = "{ " + genIfaceConfig() + "," +
+    string bad_tag = "{ " + genIfaceConfig() + ","
         "\"server-tag\": 777, "
         "\"subnet6\": [  ] "
         "}";
@@ -7795,6 +8303,7 @@ TEST_F(Dhcp6ParserTest, dhcpQueueControl) {
         std::string json_;
         std::string mt_json_;
     };
+
     std::vector<Scenario> scenarios = {
         {
         "no entry",
@@ -7980,87 +8489,175 @@ TEST_F(Dhcp6ParserTest, dhcpQueueControlInvalid) {
     }
 }
 
-// Verifies the value of store-extended-info for subnets when there
-// is a global value defined.
-TEST_F(Dhcp6ParserTest, storeExtendedInfoGlobal) {
+// Checks inheritence of calculate-tee-times, t1-percent, t2-percent
+TEST_F(Dhcp6ParserTest, calculateTeeTimesInheritence) {
+    // Configure the server. This should succeed.
+    string config =
+        "{ \n"
+        "    \"interfaces-config\": { \n"
+        "        \"interfaces\": [\"*\" ] \n"
+        "    }, \n"
+        "    \"valid-lifetime\": 4000, \n"
+        "    \"preferred-lifetime\": 3000,"
+        "    \"shared-networks\": [ { \n"
+        "        \"name\": \"foo\", \n"
+        "       \"calculate-tee-times\": true, \n"
+        "       \"t1-percent\": .4, \n"
+        "       \"t2-percent\": .75,\n"
+        "        \"subnet6\": ["
+        "        { "
+        "            \"id\": 100,"
+        "            \"subnet\": \"2001:db8:1::/64\", \n"
+        "            \"pools\": [ { \"pool\": \"2001:db8:1::/80\" } ], \n"
+        "            \"calculate-tee-times\": false,\n"
+        "            \"t1-percent\": .45, \n"
+        "            \"t2-percent\": .65 \n"
+        "        }, \n"
+        "        {  \n"
+        "            \"id\": 200, \n"
+        "            \"subnet\": \"2001:db8:2::/64\", \n"
+        "            \"pools\": [ { \"pool\": \"2001:db8:2::/80\" } ] \n"
+        "        } \n"
+        "        ] \n"
+        "     } ], \n"
+        "    \"subnet6\": [ { \n"
+        "        \"id\": 300, \n"
+        "        \"subnet\":\"2001:db8:3::/64\", \n"
+        "        \"pools\": [ { \"pool\": \"2001:db8:3::/80\" } ]\n"
+        "     } ] \n"
+        "} \n";
+
+    extractConfig(config);
+    configure(config, CONTROL_RESULT_SUCCESS, "");
+
+    CfgSubnets6Ptr subnets6 = CfgMgr::instance().getStagingCfg()->getCfgSubnets6();
+
+    // Subnet 100 should use its own explicit values.
+    ConstSubnet6Ptr subnet6 = subnets6->getBySubnetId(100);
+    ASSERT_TRUE(subnet6);
+    EXPECT_FALSE(subnet6->getCalculateTeeTimes());
+    EXPECT_TRUE(util::areDoublesEquivalent(0.45, subnet6->getT1Percent()));
+    EXPECT_TRUE(util::areDoublesEquivalent(0.65, subnet6->getT2Percent()));
+
+    // Subnet 200 should use the shared-network values.
+    subnet6 = subnets6->getBySubnetId(200);
+    ASSERT_TRUE(subnet6);
+    EXPECT_TRUE(subnet6->getCalculateTeeTimes());
+    EXPECT_TRUE(util::areDoublesEquivalent(0.4, subnet6->getT1Percent()));
+    EXPECT_TRUE(util::areDoublesEquivalent(0.75, subnet6->getT2Percent()));
+
+    // Subnet 300 should use the global values.
+    subnet6 = subnets6->getBySubnetId(300);
+    ASSERT_TRUE(subnet6);
+    EXPECT_TRUE(subnet6->getCalculateTeeTimes());
+    EXPECT_TRUE(util::areDoublesEquivalent(0.5, subnet6->getT1Percent()));
+    EXPECT_TRUE(util::areDoublesEquivalent(0.8, subnet6->getT2Percent()));
+}
+
+// This test checks that the global store-extended-info parameter is optional
+// and that values under the subnet are used.
+TEST_F(Dhcp6ParserTest, storeExtendedInfoNoGlobal) {
     const string config = "{ " + genIfaceConfig() + ","
         "\"preferred-lifetime\": 3000,"
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
-        "\"store-extended-info\": true,"
         "\"subnet6\": [ "
-        "{ "
-        "    \"id\": 1, "
+        "{"
+        "    \"id\": 1,"
         "    \"pools\": [ { \"pool\": \"2001:db8:1::1 - 2001:db8:1::ffff\" } ],"
-        "    \"subnet\": \"2001:db8:1::/64\","
-        "    \"store-extended-info\": false"
+        "    \"subnet\": \"2001:db8:1::/64\""
         "},"
         "{"
         "    \"id\": 2, "
+        "    \"store-extended-info\": true,"
         "    \"pools\": [ { \"pool\": \"2001:db8:2::1 - 2001:db8:2::ffff\" } ],"
-        "    \"subnet\": \"2001:db8:2::/64\" "
+        "    \"subnet\": \"2001:db8:2::/64\""
         "} ],"
         "\"valid-lifetime\": 4000 }";
 
-    ConstElementPtr json = parseJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
+    extractConfig(config);
+
     ConstElementPtr status;
-    EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json));
+    ASSERT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json));
     checkResult(status, 0);
 
-    // First subnet should override the global value.
+    // First subnet should use global default.
     CfgSubnets6Ptr cfg = CfgMgr::instance().getStagingCfg()->getCfgSubnets6();
     Subnet6Ptr subnet = cfg->selectSubnet(IOAddress("2001:db8:1::"));
     ASSERT_TRUE(subnet);
+    // Reset the fetch global function to staging (vs current) config.
+    subnet->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
+        return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
+    });
     EXPECT_FALSE(subnet->getStoreExtendedInfo());
 
-    // Second subnet should use the global value.
+    // Second subnet should use its own value.
     subnet = cfg->selectSubnet(IOAddress("2001:db8:2::"));
     ASSERT_TRUE(subnet);
+    // Reset the fetch global function to staging (vs current) config.
+    subnet->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
+        return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
+    });
     EXPECT_TRUE(subnet->getStoreExtendedInfo());
 }
 
-// Verifies the value of store-extended-info for subnets when there
-// is no global value defined.
-TEST_F(Dhcp6ParserTest, storeExtendedInfoNoGlobal) {
+// This test checks that the global store-extended-info parameter is used
+// when there is no such parameter under subnet and that the parameter
+// specified for a subnet overrides the global setting.
+TEST_F(Dhcp6ParserTest, storeExtendedInfoGlobal) {
     const string config = "{ " + genIfaceConfig() + ","
         "\"preferred-lifetime\": 3000,"
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
+        "\"store-extended-info\": true,"
         "\"subnet6\": [ "
         "{ "
-        "    \"id\": 1, "
+        "    \"id\": 1,"
+        "    \"store-extended-info\": false,"
         "    \"pools\": [ { \"pool\": \"2001:db8:1::1 - 2001:db8:1::ffff\" } ],"
         "    \"subnet\": \"2001:db8:1::/64\""
         "},"
         "{"
-        "    \"id\": 2, "
+        "    \"id\": 2,"
         "    \"pools\": [ { \"pool\": \"2001:db8:2::1 - 2001:db8:2::ffff\" } ],"
-        "    \"subnet\": \"2001:db8:2::/64\","
-        "    \"store-extended-info\": true"
+        "    \"subnet\": \"2001:db8:2::/64\" "
         "} ],"
         "\"valid-lifetime\": 4000 }";
 
-    ConstElementPtr json = parseJSON(config);
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
+    extractConfig(config);
+
     ConstElementPtr status;
-    EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json));
+    ASSERT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json));
     checkResult(status, 0);
 
-    // First subnet should use global default.
+    // First subnet should override the global value.
     CfgSubnets6Ptr cfg = CfgMgr::instance().getStagingCfg()->getCfgSubnets6();
-    Subnet6Ptr subnet = cfg->selectSubnet(IOAddress("2001:db8:1::"));
-    ASSERT_TRUE(subnet);
-    EXPECT_FALSE(subnet->getStoreExtendedInfo());
+    Subnet6Ptr subnet1 = cfg->selectSubnet(IOAddress("2001:db8:1::"));
+    ASSERT_TRUE(subnet1);
+    // Reset the fetch global function to staging (vs current) config.
+    subnet1->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
+        return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
+    });
+    EXPECT_FALSE(subnet1->getStoreExtendedInfo());
 
-    // Second subnet should use its own value.
-    subnet = cfg->selectSubnet(IOAddress("2001:db8:2::"));
-    ASSERT_TRUE(subnet);
-    EXPECT_TRUE(subnet->getStoreExtendedInfo());
+    // Second subnet should use the global value.
+    Subnet6Ptr subnet2 = cfg->selectSubnet(IOAddress("2001:db8:2::"));
+    ASSERT_TRUE(subnet2);
+    // Reset the fetch global function to staging (vs current) config.
+    subnet2->setFetchGlobalsFn([]() -> ConstCfgGlobalsPtr {
+        return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
+    });
+    EXPECT_TRUE(subnet2->getStoreExtendedInfo());
 }
 
 /// This test checks that the statistic-default-sample-count and age
 /// global parameters are committed to the stats manager as expected.
 TEST_F(Dhcp6ParserTest, statsDefaultLimits) {
-    std::string config = "{ " + genIfaceConfig() + "," +
+    std::string config = "{ " + genIfaceConfig() + ","
         "\"preferred-lifetime\": 3000,"
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
@@ -8086,7 +8683,7 @@ TEST_F(Dhcp6ParserTest, statsDefaultLimits) {
 
 // This test checks that using default multi threading settings works.
 TEST_F(Dhcp6ParserTest, multiThreadingDefaultSettings) {
-    std::string config = "{ " + genIfaceConfig() + "," +
+    std::string config = "{ " + genIfaceConfig() + ","
         "\"subnet6\": [  ]"
         "}";
 
@@ -8123,7 +8720,7 @@ TEST_F(Dhcp6ParserTest, multiThreadingSettings) {
         "    \"thread-pool-size\": 48,\n"
         "    \"packet-queue-size\": 1024\n"
         "}";
-    std::string config = "{ " + genIfaceConfig() + "," +
+    std::string config = "{ " + genIfaceConfig() + ","
         "\"subnet6\": [  ], "
         "\"multi-threading\": " + content_json + "}";
 
@@ -8146,10 +8743,52 @@ TEST_F(Dhcp6ParserTest, multiThreadingSettings) {
                 << "  actual: " << *(cfg) << std::endl;
 }
 
+// Verify that parsing for the global parameter, parked-packet-limit,
+// is correct.
+TEST_F(Dhcp6ParserTest, parkedPacketLimit) {
+    // Config without parked-packet-limit
+    string config_no_limit = "{ " + genIfaceConfig() + ","
+        "\"subnet6\": [  ] "
+        "}";
+
+    // Config with parked-packet-limit
+    string config_limit = "{ " + genIfaceConfig() + ","
+        "\"parked-packet-limit\": 777, "
+        "\"subnet6\": [  ] "
+        "}";
+
+    // Config with an invalid parked-packet-limit
+    string bad_limit = "{ " + genIfaceConfig() + ","
+        "\"parked-packet-limit\": \"boo\", "
+        "\"subnet6\": [  ] "
+        "}";
+
+    // Should not exist after construction.
+    ASSERT_FALSE(CfgMgr::instance().getStagingCfg()->getConfiguredGlobal("parked-packet-limit"));
+
+    // Configuration with no limit should default to 256.
+    configure(config_no_limit, CONTROL_RESULT_SUCCESS, "");
+    ConstElementPtr ppl;
+    ASSERT_TRUE(ppl = CfgMgr::instance().getStagingCfg()->getConfiguredGlobal("parked-packet-limit"));
+    EXPECT_EQ(256, ppl->intValue());
+
+    // Clear the config
+    CfgMgr::instance().clear();
+
+    // Configuration with the limit should have the limit value.
+    configure(config_limit, CONTROL_RESULT_SUCCESS, "");
+
+    ASSERT_TRUE(ppl = CfgMgr::instance().getStagingCfg()->getConfiguredGlobal("parked-packet-limit"));
+    EXPECT_EQ(777, ppl->intValue());
+
+    // Make sure an invalid limit fails to parse.
+    ASSERT_THROW(parseDHCP6(bad_limit), std::exception);
+}
+
 // Verifies that client class definitions may specify
 // valid and preferred lifetime triplets.
 TEST_F(Dhcp6ParserTest, clientClassValidPreferredLifetime) {
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"client-classes\" : [ \n"
         "   { \n"
         "       \"name\": \"one\", \n"
@@ -8212,7 +8851,7 @@ TEST_F(Dhcp6ParserTest, clientClassValidPreferredLifetime) {
 // Verifies that template client class definitions may specify
 // valid and preferred lifetime triplets.
 TEST_F(Dhcp6ParserTest, templateClientClassValidPreferredLifetime) {
-    string config = "{ " + genIfaceConfig() + "," +
+    string config = "{ " + genIfaceConfig() + ","
         "\"client-classes\" : [ \n"
         "   { \n"
         "       \"name\": \"one\", \n"
@@ -8279,17 +8918,17 @@ TEST_F(Dhcp6ParserTest, templateClientClassValidPreferredLifetime) {
 // This test checks that ddns-conflict-resolution-mode value can be specified at
 // global and subnet levels.
 TEST_F(Dhcp6ParserTest, storeDdnsConflictResolutionMode) {
-    std::string config = "{ " + genIfaceConfig() + "," +
+    std::string config = "{ " + genIfaceConfig() + ","
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"subnet6\": [ "
-        "{ "
+        "{"
         "    \"id\": 1,"
         "    \"pools\": [ { \"pool\": \"2001:db8:1::1 - 2001:db8:1::ffff\" } ],"
         "    \"ddns-conflict-resolution-mode\": \"check-with-dhcid\","
         "    \"subnet\": \"2001:db8:1::/64\""
         "},"
-        "{ "
+        "{"
         "    \"id\": 2,"
         "    \"pools\": [ { \"pool\": \"2001:db8:2::1 - 2001:db8:2::ffff\" } ],"
         "    \"ddns-conflict-resolution-mode\": \"check-exists-with-dhcid\","
index 84350f1ab7d556cf0d0e57dbac7aa0ba63086895..642c032244928cee0f77b3018e1720c4055468f2 100644 (file)
@@ -75,13 +75,53 @@ const char* EXTRACTED_CONFIGS[] = {
 "            \"interfaces\": [ \"*\" ],\n"
 "            \"re-detect\": false\n"
 "        },\n"
+"        \"rebind-timer\": 2000,\n"
+"        \"subnet6\": [\n"
+"            {\n"
+"                \"id\": 1,\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"pool\": \"2001:db8::/64\"\n"
+"                    }\n"
+"                ],\n"
+"                \"subnet\": \"2001:db8::/32\"\n"
+"            }\n"
+"        ],\n"
+"        \"valid-lifetime\": 4000\n"
+"    }\n",
+    // CONFIGURATION 1
+"{\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"renew-timer\": 1000,\n"
+"        \"subnet6\": [\n"
+"            {\n"
+"                \"id\": 1,\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"pool\": \"2001:db8::/64\"\n"
+"                    }\n"
+"                ],\n"
+"                \"subnet\": \"2001:db8::/32\"\n"
+"            }\n"
+"        ],\n"
+"        \"valid-lifetime\": 4000\n"
+"    }\n",
+    // CONFIGURATION 2
+"{\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
 "        \"preferred-lifetime\": 3000,\n"
 "        \"rebind-timer\": 2000,\n"
 "        \"renew-timer\": 1000,\n"
 "        \"subnet6\": [ ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 1
+    // CONFIGURATION 3
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -107,7 +147,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 2
+    // CONFIGURATION 4
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -156,7 +196,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 3
+    // CONFIGURATION 5
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -205,7 +245,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 4
+    // CONFIGURATION 6
 "{\n"
 "        \"compatibility\": {\n"
 "            \"lenient-option-parsing\": true\n"
@@ -230,7 +270,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 5
+    // CONFIGURATION 7
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -264,7 +304,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 6
+    // CONFIGURATION 8
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -287,7 +327,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 7
+    // CONFIGURATION 9
 "{\n"
 "        \"preferred-lifetime\": 3000,\n"
 "        \"rebind-timer\": 2000,\n"
@@ -306,7 +346,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 8
+    // CONFIGURATION 10
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -343,7 +383,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 9
+    // CONFIGURATION 11
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -365,7 +405,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 10
+    // CONFIGURATION 12
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -389,7 +429,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "            }\n"
 "        ]\n"
 "    }\n",
-    // CONFIGURATION 11
+    // CONFIGURATION 13
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -415,7 +455,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "            }\n"
 "        ]\n"
 "    }\n",
-    // CONFIGURATION 12
+    // CONFIGURATION 14
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -454,7 +494,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "            }\n"
 "        ]\n"
 "    }\n",
-    // CONFIGURATION 13
+    // CONFIGURATION 15
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -478,7 +518,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "            }\n"
 "        ]\n"
 "    }\n",
-    // CONFIGURATION 14
+    // CONFIGURATION 16
 "{\n"
 "        \"option-def\": [\n"
 "            {\n"
@@ -489,7 +529,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "            }\n"
 "        ]\n"
 "    }\n",
-    // CONFIGURATION 15
+    // CONFIGURATION 17
 "{\n"
 "        \"option-def\": [\n"
 "            {\n"
@@ -501,7 +541,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "            }\n"
 "        ]\n"
 "    }\n",
-    // CONFIGURATION 16
+    // CONFIGURATION 18
 "{\n"
 "        \"option-def\": [\n"
 "            {\n"
@@ -518,7 +558,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "            }\n"
 "        ]\n"
 "    }\n",
-    // CONFIGURATION 17
+    // CONFIGURATION 19
 "{\n"
 "        \"option-def\": [\n"
 "            {\n"
@@ -530,7 +570,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "            }\n"
 "        ]\n"
 "    }\n",
-    // CONFIGURATION 18
+    // CONFIGURATION 20
 "{\n"
 "        \"option-def\": [\n"
 "            {\n"
@@ -542,7 +582,29 @@ const char* EXTRACTED_CONFIGS[] = {
 "            }\n"
 "        ]\n"
 "    }\n",
-    // CONFIGURATION 19
+    // CONFIGURATION 21
+"{\n"
+"        \"option-def\": [\n"
+"            {\n"
+"                \"code\": 100,\n"
+"                \"name\": \"foo\",\n"
+"                \"space\": \"dhcp6\",\n"
+"                \"type\": \"string\"\n"
+"            }\n"
+"        ]\n"
+"    }\n",
+    // CONFIGURATION 22
+"{\n"
+"        \"option-def\": [\n"
+"            {\n"
+"                \"code\": 63,\n"
+"                \"name\": \"geolocation\",\n"
+"                \"space\": \"dhcp6\",\n"
+"                \"type\": \"string\"\n"
+"            }\n"
+"        ]\n"
+"    }\n",
+    // CONFIGURATION 23
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -575,7 +637,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 20
+    // CONFIGURATION 24
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -608,7 +670,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 21
+    // CONFIGURATION 25
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -650,7 +712,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 22
+    // CONFIGURATION 26
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -687,7 +749,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        \"renew-timer\": 1000,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 23
+    // CONFIGURATION 27
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -746,7 +808,48 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 24
+    // CONFIGURATION 28
+"{\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"option-data\": [\n"
+"            {\n"
+"                \"csv-format\": false,\n"
+"                \"data\": \"AB\",\n"
+"                \"name\": \"subscriber-id\"\n"
+"            }\n"
+"        ],\n"
+"        \"preferred-lifetime\": 3000,\n"
+"        \"rebind-timer\": 2000,\n"
+"        \"renew-timer\": 1000,\n"
+"        \"subnet6\": [\n"
+"            {\n"
+"                \"id\": 1,\n"
+"                \"option-data\": [\n"
+"                    {\n"
+"                        \"csv-format\": false,\n"
+"                        \"data\": \"ABCDEF0105\",\n"
+"                        \"name\": \"subscriber-id\"\n"
+"                    },\n"
+"                    {\n"
+"                        \"csv-format\": false,\n"
+"                        \"data\": \"FFFEFDFCFB\",\n"
+"                        \"name\": \"user-class\"\n"
+"                    }\n"
+"                ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"pool\": \"2001:db8:1::/80\"\n"
+"                    }\n"
+"                ],\n"
+"                \"subnet\": \"2001:db8:1::/64\"\n"
+"            }\n"
+"        ],\n"
+"        \"valid-lifetime\": 4000\n"
+"    }\n",
+    // CONFIGURATION 29
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -791,7 +894,41 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 25
+    // CONFIGURATION 30
+"{\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"preferred-lifetime\": 3000,\n"
+"        \"rebind-timer\": 2000,\n"
+"        \"renew-timer\": 1000,\n"
+"        \"subnet6\": [\n"
+"            {\n"
+"                \"id\": 1,\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [\n"
+"                            {\n"
+"                                \"csv-format\": false,\n"
+"                                \"data\": \"0102030405060708090A\",\n"
+"                                \"name\": \"subscriber-id\"\n"
+"                            },\n"
+"                            {\n"
+"                                \"csv-format\": false,\n"
+"                                \"data\": \"FFFEFDFCFB\",\n"
+"                                \"name\": \"user-class\"\n"
+"                            }\n"
+"                        ],\n"
+"                        \"pool\": \"2001:db8:1::10 - 2001:db8:1::100\"\n"
+"                    }\n"
+"                ],\n"
+"                \"subnet\": \"2001:db8:1::/64\"\n"
+"            }\n"
+"        ],\n"
+"        \"valid-lifetime\": 4000\n"
+"    }\n",
+    // CONFIGURATION 31
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -856,7 +993,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 26
+    // CONFIGURATION 32
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -894,7 +1031,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 27
+    // CONFIGURATION 33
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -932,7 +1069,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 28
+    // CONFIGURATION 34
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"eth0\" ],\n"
@@ -943,7 +1080,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        \"renew-timer\": 1000,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 29
+    // CONFIGURATION 35
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"eth0\", \"eth1\", \"*\" ],\n"
@@ -954,7 +1091,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        \"renew-timer\": 1000,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 30
+    // CONFIGURATION 36
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -971,15 +1108,18 @@ const char* EXTRACTED_CONFIGS[] = {
 "                        \"pool\": \"2001:db8:1::1 - 2001:db8:1::ffff\"\n"
 "                    }\n"
 "                ],\n"
+"                \"rebind-timer\": 2,\n"
 "                \"relay\": {\n"
 "                    \"ip-addresses\": [ \"2001:db8:1::abcd\" ]\n"
 "                },\n"
-"                \"subnet\": \"2001:db8:1::/64\"\n"
+"                \"renew-timer\": 1,\n"
+"                \"subnet\": \"2001:db8:1::/64\",\n"
+"                \"valid-lifetime\": 4\n"
 "            }\n"
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 31
+    // CONFIGURATION 37
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -996,15 +1136,18 @@ const char* EXTRACTED_CONFIGS[] = {
 "                        \"pool\": \"2001:db8:1::1 - 2001:db8:1::ffff\"\n"
 "                    }\n"
 "                ],\n"
+"                \"rebind-timer\": 2,\n"
 "                \"relay\": {\n"
 "                    \"ip-addresses\": [ \"2001:db9::abcd\", \"2001:db9::abce\" ]\n"
 "                },\n"
-"                \"subnet\": \"2001:db8:1::/64\"\n"
+"                \"renew-timer\": 1,\n"
+"                \"subnet\": \"2001:db8:1::/64\",\n"
+"                \"valid-lifetime\": 4\n"
 "            }\n"
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 32
+    // CONFIGURATION 38
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1056,7 +1199,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 33
+    // CONFIGURATION 39
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1090,7 +1233,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 34
+    // CONFIGURATION 40
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1132,7 +1275,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 35
+    // CONFIGURATION 41
 "{\n"
 "        \"dhcp-ddns\": {\n"
 "            \"enable-updates\": true,\n"
@@ -1164,7 +1307,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 36
+    // CONFIGURATION 42
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1251,7 +1394,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 37
+    // CONFIGURATION 43
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1291,7 +1434,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 38
+    // CONFIGURATION 44
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1304,7 +1447,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        \"subnet6\": [ ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 39
+    // CONFIGURATION 45
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1317,7 +1460,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        \"subnet6\": [ ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 40
+    // CONFIGURATION 46
 "{\n"
 "        \"preferred-lifetime\": 3000,\n"
 "        \"rebind-timer\": 2000,\n"
@@ -1405,7 +1548,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 41
+    // CONFIGURATION 47
 "{\n"
 "        \"preferred-lifetime\": 3000,\n"
 "        \"rebind-timer\": 2000,\n"
@@ -1438,28 +1581,28 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 42
+    // CONFIGURATION 48
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
 "            \"re-detect\": false\n"
 "        },\n"
-"        \"preferred-lifetime\": 3000,\n"
-"        \"rebind-timer\": 2000,\n"
-"        \"relay-supplied-options\": [ \"dns-servers\", \"remote-id\" ],\n"
-"        \"renew-timer\": 1000,\n"
-"        \"subnet6\": [ ],\n"
-"        \"valid-lifetime\": 4000\n"
+"        \"subnet6\": [ ]\n"
 "    }\n",
-    // CONFIGURATION 43
+    // CONFIGURATION 49
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
 "            \"re-detect\": false\n"
 "        },\n"
-"        \"subnet6\": [ ]\n"
+"        \"preferred-lifetime\": 3000,\n"
+"        \"rebind-timer\": 2000,\n"
+"        \"relay-supplied-options\": [ \"dns-servers\", \"remote-id\" ],\n"
+"        \"renew-timer\": 1000,\n"
+"        \"subnet6\": [ ],\n"
+"        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 44
+    // CONFIGURATION 50
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1467,7 +1610,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        },\n"
 "        \"subnet6\": [ ]\n"
 "    }\n",
-    // CONFIGURATION 45
+    // CONFIGURATION 51
 "{\n"
 "        \"decline-probation-period\": 12345,\n"
 "        \"interfaces-config\": {\n"
@@ -1476,7 +1619,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        },\n"
 "        \"subnet6\": [ ]\n"
 "    }\n",
-    // CONFIGURATION 46
+    // CONFIGURATION 52
 "{\n"
 "        \"expired-leases-processing\": {\n"
 "            \"flush-reclaimed-timer-wait-time\": 35,\n"
@@ -1492,7 +1635,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        },\n"
 "        \"subnet6\": [ ]\n"
 "    }\n",
-    // CONFIGURATION 47
+    // CONFIGURATION 53
 "{\n"
 "        \"client-classes\": [\n"
 "            {\n"
@@ -1525,10 +1668,70 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 48
+    // CONFIGURATION 54
 "{\n"
-"        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ],\n"
+"        \"client-classes\": [\n"
+"            {\n"
+"                \"max-valid-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 1000,\n"
+"                \"name\": \"one\",\n"
+"                \"valid-lifetime\": 2000\n"
+"            },\n"
+"            {\n"
+"                \"name\": \"two\"\n"
+"            }\n"
+"        ],\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"subnet6\": [\n"
+"            {\n"
+"                \"id\": 1,\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"pool\": \"2001:db8::1 - 2001:db8::ffff\"\n"
+"                    }\n"
+"                ],\n"
+"                \"subnet\": \"2001:db8::/64\"\n"
+"            }\n"
+"        ]\n"
+"    }\n",
+    // CONFIGURATION 55
+"{\n"
+"        \"client-classes\": [\n"
+"            {\n"
+"                \"max-valid-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 1000,\n"
+"                \"name\": \"one\",\n"
+"                \"template-test\": \"''\",\n"
+"                \"valid-lifetime\": 2000\n"
+"            },\n"
+"            {\n"
+"                \"name\": \"two\",\n"
+"                \"template-test\": \"''\"\n"
+"            }\n"
+"        ],\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"subnet6\": [\n"
+"            {\n"
+"                \"id\": 1,\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"pool\": \"2001:db8::1 - 2001:db8::ffff\"\n"
+"                    }\n"
+"                ],\n"
+"                \"subnet\": \"2001:db8::/64\"\n"
+"            }\n"
+"        ]\n"
+"    }\n",
+    // CONFIGURATION 56
+"{\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
 "            \"re-detect\": false\n"
 "        },\n"
 "        \"preferred-lifetime\": 3000,\n"
@@ -1547,7 +1750,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 49
+    // CONFIGURATION 57
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1570,7 +1773,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 50
+    // CONFIGURATION 58
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1598,7 +1801,35 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 51
+    // CONFIGURATION 59
+"{\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"preferred-lifetime\": 3000,\n"
+"        \"rebind-timer\": 2000,\n"
+"        \"renew-timer\": 1000,\n"
+"        \"subnet6\": [\n"
+"            {\n"
+"                \"id\": 1,\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"pool\": \"2001:db8::/64\",\n"
+"                        \"user-context\": {\n"
+"                            \"lw4over6-bind-prefix-len\": 56,\n"
+"                            \"lw4over6-sharing-ratio\": 64,\n"
+"                            \"lw4over6-sysports-exclude\": true,\n"
+"                            \"lw4over6-v4-pool\": \"192.0.2.0/24\"\n"
+"                        }\n"
+"                    }\n"
+"                ],\n"
+"                \"subnet\": \"2001:db8::/32\"\n"
+"            }\n"
+"        ],\n"
+"        \"valid-lifetime\": 4000\n"
+"    }\n",
+    // CONFIGURATION 60
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1626,7 +1857,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 52
+    // CONFIGURATION 61
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1650,7 +1881,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 53
+    // CONFIGURATION 62
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1675,7 +1906,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 54
+    // CONFIGURATION 63
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1705,7 +1936,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 55
+    // CONFIGURATION 64
 "{\n"
 "        \"hosts-databases\": [\n"
 "            {\n"
@@ -1731,7 +1962,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        \"renew-timer\": 1000,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 56
+    // CONFIGURATION 65
 "{\n"
 "        \"client-classes\": [\n"
 "            {\n"
@@ -1881,7 +2112,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "            \"comment\": \"A DHCPv6 server\"\n"
 "        }\n"
 "    }\n",
-    // CONFIGURATION 57
+    // CONFIGURATION 66
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1946,7 +2177,123 @@ const char* EXTRACTED_CONFIGS[] = {
 "        ],\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 58
+    // CONFIGURATION 67
+"{\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"preferred-lifetime\": 3000,\n"
+"        \"shared-networks\": [\n"
+"            {\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"name\": \"foo\",\n"
+"                \"subnet6\": [\n"
+"                    {\n"
+"                        \"calculate-tee-times\": false,\n"
+"                        \"id\": 100,\n"
+"                        \"pools\": [\n"
+"                            {\n"
+"                                \"pool\": \"2001:db8:1::/80\"\n"
+"                            }\n"
+"                        ],\n"
+"                        \"subnet\": \"2001:db8:1::/64\",\n"
+"                        \"t1-percent\": 0.45,\n"
+"                        \"t2-percent\": 0.65\n"
+"                    },\n"
+"                    {\n"
+"                        \"id\": 200,\n"
+"                        \"pools\": [\n"
+"                            {\n"
+"                                \"pool\": \"2001:db8:2::/80\"\n"
+"                            }\n"
+"                        ],\n"
+"                        \"subnet\": \"2001:db8:2::/64\"\n"
+"                    }\n"
+"                ],\n"
+"                \"t1-percent\": 0.4,\n"
+"                \"t2-percent\": 0.75\n"
+"            }\n"
+"        ],\n"
+"        \"subnet6\": [\n"
+"            {\n"
+"                \"id\": 300,\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"pool\": \"2001:db8:3::/80\"\n"
+"                    }\n"
+"                ],\n"
+"                \"subnet\": \"2001:db8:3::/64\"\n"
+"            }\n"
+"        ],\n"
+"        \"valid-lifetime\": 4000\n"
+"    }\n",
+    // CONFIGURATION 68
+"{\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"preferred-lifetime\": 3000,\n"
+"        \"rebind-timer\": 2000,\n"
+"        \"renew-timer\": 1000,\n"
+"        \"subnet6\": [\n"
+"            {\n"
+"                \"id\": 1,\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"pool\": \"2001:db8:1::1 - 2001:db8:1::ffff\"\n"
+"                    }\n"
+"                ],\n"
+"                \"subnet\": \"2001:db8:1::/64\"\n"
+"            },\n"
+"            {\n"
+"                \"id\": 2,\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"pool\": \"2001:db8:2::1 - 2001:db8:2::ffff\"\n"
+"                    }\n"
+"                ],\n"
+"                \"store-extended-info\": true,\n"
+"                \"subnet\": \"2001:db8:2::/64\"\n"
+"            }\n"
+"        ],\n"
+"        \"valid-lifetime\": 4000\n"
+"    }\n",
+    // CONFIGURATION 69
+"{\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"preferred-lifetime\": 3000,\n"
+"        \"rebind-timer\": 2000,\n"
+"        \"renew-timer\": 1000,\n"
+"        \"store-extended-info\": true,\n"
+"        \"subnet6\": [\n"
+"            {\n"
+"                \"id\": 1,\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"pool\": \"2001:db8:1::1 - 2001:db8:1::ffff\"\n"
+"                    }\n"
+"                ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8:1::/64\"\n"
+"            },\n"
+"            {\n"
+"                \"id\": 2,\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"pool\": \"2001:db8:2::1 - 2001:db8:2::ffff\"\n"
+"                    }\n"
+"                ],\n"
+"                \"subnet\": \"2001:db8:2::/64\"\n"
+"            }\n"
+"        ],\n"
+"        \"valid-lifetime\": 4000\n"
+"    }\n",
+    // CONFIGURATION 70
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1959,7 +2306,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        \"statistic-default-sample-count\": 10,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 59
+    // CONFIGURATION 71
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1967,7 +2314,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        },\n"
 "        \"subnet6\": [ ]\n"
 "    }\n",
-    // CONFIGURATION 60
+    // CONFIGURATION 72
 "{\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
@@ -1980,7 +2327,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "        },\n"
 "        \"subnet6\": [ ]\n"
 "    }\n",
-    // CONFIGURATION 61
+    // CONFIGURATION 73
 "{\n"
 "        \"client-classes\": [\n"
 "            {\n"
@@ -2012,7 +2359,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "            }\n"
 "        ]\n"
 "    }\n",
-    // CONFIGURATION 62
+    // CONFIGURATION 74
 "{\n"
 "        \"client-classes\": [\n"
 "            {\n"
@@ -2046,7 +2393,7 @@ const char* EXTRACTED_CONFIGS[] = {
 "            }\n"
 "        ]\n"
 "    }\n",
-    // CONFIGURATION 63
+    // CONFIGURATION 75
 "{\n"
 "        \"ddns-conflict-resolution-mode\": \"no-check-with-dhcid\",\n"
 "        \"interfaces-config\": {\n"
@@ -2172,10 +2519,8 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"option-def\": [ ],\n"
 "        \"parked-packet-limit\": 256,\n"
 "        \"pd-allocator\": \"iterative\",\n"
-"        \"preferred-lifetime\": 3000,\n"
 "        \"rebind-timer\": 2000,\n"
 "        \"relay-supplied-options\": [ \"65\" ],\n"
-"        \"renew-timer\": 1000,\n"
 "        \"reservations-global\": false,\n"
 "        \"reservations-in-subnet\": true,\n"
 "        \"reservations-lookup-first\": false,\n"
@@ -2197,7 +2542,35 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"statistic-default-sample-age\": 0,\n"
 "        \"statistic-default-sample-count\": 20,\n"
 "        \"store-extended-info\": false,\n"
-"        \"subnet6\": [ ],\n"
+"        \"subnet6\": [\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"id\": 1,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8::/64\"\n"
+"                    }\n"
+"                ],\n"
+"                \"rapid-commit\": false,\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8::/32\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 4000\n"
+"            }\n"
+"        ],\n"
 "        \"t1-percent\": 0.5,\n"
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
@@ -2253,10 +2626,6 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"type\": \"memfile\"\n"
 "        },\n"
 "        \"mac-sources\": [ \"any\" ],\n"
-"        \"max-preferred-lifetime\": 4000,\n"
-"        \"max-valid-lifetime\": 5000,\n"
-"        \"min-preferred-lifetime\": 2000,\n"
-"        \"min-valid-lifetime\": 3000,\n"
 "        \"multi-threading\": {\n"
 "            \"enable-multi-threading\": true,\n"
 "            \"packet-queue-size\": 64,\n"
@@ -2266,8 +2635,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"option-def\": [ ],\n"
 "        \"parked-packet-limit\": 256,\n"
 "        \"pd-allocator\": \"iterative\",\n"
-"        \"preferred-lifetime\": 3000,\n"
-"        \"rebind-timer\": 2000,\n"
 "        \"relay-supplied-options\": [ \"65\" ],\n"
 "        \"renew-timer\": 1000,\n"
 "        \"reservations-global\": false,\n"
@@ -2296,20 +2663,232 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"allocator\": \"iterative\",\n"
 "                \"calculate-tee-times\": true,\n"
 "                \"id\": 1,\n"
-"                \"max-preferred-lifetime\": 4000,\n"
-"                \"max-valid-lifetime\": 5000,\n"
-"                \"min-preferred-lifetime\": 2000,\n"
-"                \"min-valid-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-allocator\": \"iterative\",\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
 "                    {\n"
 "                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8:1::1-2001:db8:1::ffff\"\n"
+"                        \"pool\": \"2001:db8::/64\"\n"
 "                    }\n"
 "                ],\n"
-"                \"preferred-lifetime\": 3000,\n"
+"                \"rapid-commit\": false,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8::/32\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 4000\n"
+"            }\n"
+"        ],\n"
+"        \"t1-percent\": 0.5,\n"
+"        \"t2-percent\": 0.8,\n"
+"        \"valid-lifetime\": 4000\n"
+"    }\n",
+    // CONFIGURATION 2
+"{\n"
+"        \"allocator\": \"iterative\",\n"
+"        \"calculate-tee-times\": true,\n"
+"        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
+"        \"ddns-generated-prefix\": \"myhost\",\n"
+"        \"ddns-override-client-update\": false,\n"
+"        \"ddns-override-no-update\": false,\n"
+"        \"ddns-qualifying-suffix\": \"\",\n"
+"        \"ddns-replace-client-name\": \"never\",\n"
+"        \"ddns-send-updates\": true,\n"
+"        \"ddns-update-on-renew\": false,\n"
+"        \"decline-probation-period\": 86400,\n"
+"        \"dhcp-ddns\": {\n"
+"            \"enable-updates\": false,\n"
+"            \"max-queue-size\": 1024,\n"
+"            \"ncr-format\": \"JSON\",\n"
+"            \"ncr-protocol\": \"UDP\",\n"
+"            \"sender-ip\": \"0.0.0.0\",\n"
+"            \"sender-port\": 0,\n"
+"            \"server-ip\": \"127.0.0.1\",\n"
+"            \"server-port\": 53001\n"
+"        },\n"
+"        \"dhcp-queue-control\": {\n"
+"            \"capacity\": 64,\n"
+"            \"enable-queue\": false,\n"
+"            \"queue-type\": \"kea-ring6\"\n"
+"        },\n"
+"        \"dhcp4o6-port\": 0,\n"
+"        \"early-global-reservations-lookup\": false,\n"
+"        \"expired-leases-processing\": {\n"
+"            \"flush-reclaimed-timer-wait-time\": 25,\n"
+"            \"hold-reclaimed-time\": 3600,\n"
+"            \"max-reclaim-leases\": 100,\n"
+"            \"max-reclaim-time\": 250,\n"
+"            \"reclaim-timer-wait-time\": 10,\n"
+"            \"unwarned-reclaim-cycles\": 5\n"
+"        },\n"
+"        \"hooks-libraries\": [ ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
+"        \"hostname-char-replacement\": \"\",\n"
+"        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"ip-reservations-unique\": true,\n"
+"        \"lease-database\": {\n"
+"            \"type\": \"memfile\"\n"
+"        },\n"
+"        \"mac-sources\": [ \"any\" ],\n"
+"        \"multi-threading\": {\n"
+"            \"enable-multi-threading\": true,\n"
+"            \"packet-queue-size\": 64,\n"
+"            \"thread-pool-size\": 0\n"
+"        },\n"
+"        \"option-data\": [ ],\n"
+"        \"option-def\": [ ],\n"
+"        \"parked-packet-limit\": 256,\n"
+"        \"pd-allocator\": \"iterative\",\n"
+"        \"preferred-lifetime\": 3000,\n"
+"        \"rebind-timer\": 2000,\n"
+"        \"relay-supplied-options\": [ \"65\" ],\n"
+"        \"renew-timer\": 1000,\n"
+"        \"reservations-global\": false,\n"
+"        \"reservations-in-subnet\": true,\n"
+"        \"reservations-lookup-first\": false,\n"
+"        \"reservations-out-of-pool\": false,\n"
+"        \"sanity-checks\": {\n"
+"            \"extended-info-checks\": \"fix\",\n"
+"            \"lease-checks\": \"warn\"\n"
+"        },\n"
+"        \"server-id\": {\n"
+"            \"enterprise-id\": 0,\n"
+"            \"htype\": 0,\n"
+"            \"identifier\": \"\",\n"
+"            \"persist\": true,\n"
+"            \"time\": 0,\n"
+"            \"type\": \"LLT\"\n"
+"        },\n"
+"        \"server-tag\": \"\",\n"
+"        \"shared-networks\": [ ],\n"
+"        \"statistic-default-sample-age\": 0,\n"
+"        \"statistic-default-sample-count\": 20,\n"
+"        \"store-extended-info\": false,\n"
+"        \"subnet6\": [ ],\n"
+"        \"t1-percent\": 0.5,\n"
+"        \"t2-percent\": 0.8,\n"
+"        \"valid-lifetime\": 4000\n"
+"    }\n",
+    // CONFIGURATION 3
+"{\n"
+"        \"allocator\": \"iterative\",\n"
+"        \"calculate-tee-times\": true,\n"
+"        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
+"        \"ddns-generated-prefix\": \"myhost\",\n"
+"        \"ddns-override-client-update\": false,\n"
+"        \"ddns-override-no-update\": false,\n"
+"        \"ddns-qualifying-suffix\": \"\",\n"
+"        \"ddns-replace-client-name\": \"never\",\n"
+"        \"ddns-send-updates\": true,\n"
+"        \"ddns-update-on-renew\": false,\n"
+"        \"decline-probation-period\": 86400,\n"
+"        \"dhcp-ddns\": {\n"
+"            \"enable-updates\": false,\n"
+"            \"max-queue-size\": 1024,\n"
+"            \"ncr-format\": \"JSON\",\n"
+"            \"ncr-protocol\": \"UDP\",\n"
+"            \"sender-ip\": \"0.0.0.0\",\n"
+"            \"sender-port\": 0,\n"
+"            \"server-ip\": \"127.0.0.1\",\n"
+"            \"server-port\": 53001\n"
+"        },\n"
+"        \"dhcp-queue-control\": {\n"
+"            \"capacity\": 64,\n"
+"            \"enable-queue\": false,\n"
+"            \"queue-type\": \"kea-ring6\"\n"
+"        },\n"
+"        \"dhcp4o6-port\": 0,\n"
+"        \"early-global-reservations-lookup\": false,\n"
+"        \"expired-leases-processing\": {\n"
+"            \"flush-reclaimed-timer-wait-time\": 25,\n"
+"            \"hold-reclaimed-time\": 3600,\n"
+"            \"max-reclaim-leases\": 100,\n"
+"            \"max-reclaim-time\": 250,\n"
+"            \"reclaim-timer-wait-time\": 10,\n"
+"            \"unwarned-reclaim-cycles\": 5\n"
+"        },\n"
+"        \"hooks-libraries\": [ ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
+"        \"hostname-char-replacement\": \"\",\n"
+"        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"ip-reservations-unique\": true,\n"
+"        \"lease-database\": {\n"
+"            \"type\": \"memfile\"\n"
+"        },\n"
+"        \"mac-sources\": [ \"any\" ],\n"
+"        \"max-preferred-lifetime\": 4000,\n"
+"        \"max-valid-lifetime\": 5000,\n"
+"        \"min-preferred-lifetime\": 2000,\n"
+"        \"min-valid-lifetime\": 3000,\n"
+"        \"multi-threading\": {\n"
+"            \"enable-multi-threading\": true,\n"
+"            \"packet-queue-size\": 64,\n"
+"            \"thread-pool-size\": 0\n"
+"        },\n"
+"        \"option-data\": [ ],\n"
+"        \"option-def\": [ ],\n"
+"        \"parked-packet-limit\": 256,\n"
+"        \"pd-allocator\": \"iterative\",\n"
+"        \"preferred-lifetime\": 3000,\n"
+"        \"rebind-timer\": 2000,\n"
+"        \"relay-supplied-options\": [ \"65\" ],\n"
+"        \"renew-timer\": 1000,\n"
+"        \"reservations-global\": false,\n"
+"        \"reservations-in-subnet\": true,\n"
+"        \"reservations-lookup-first\": false,\n"
+"        \"reservations-out-of-pool\": false,\n"
+"        \"sanity-checks\": {\n"
+"            \"extended-info-checks\": \"fix\",\n"
+"            \"lease-checks\": \"warn\"\n"
+"        },\n"
+"        \"server-id\": {\n"
+"            \"enterprise-id\": 0,\n"
+"            \"htype\": 0,\n"
+"            \"identifier\": \"\",\n"
+"            \"persist\": true,\n"
+"            \"time\": 0,\n"
+"            \"type\": \"LLT\"\n"
+"        },\n"
+"        \"server-tag\": \"\",\n"
+"        \"shared-networks\": [ ],\n"
+"        \"statistic-default-sample-age\": 0,\n"
+"        \"statistic-default-sample-count\": 20,\n"
+"        \"store-extended-info\": false,\n"
+"        \"subnet6\": [\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"id\": 1,\n"
+"                \"max-preferred-lifetime\": 4000,\n"
+"                \"max-valid-lifetime\": 5000,\n"
+"                \"min-preferred-lifetime\": 2000,\n"
+"                \"min-valid-lifetime\": 3000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8:1::1-2001:db8:1::ffff\"\n"
+"                    }\n"
+"                ],\n"
+"                \"preferred-lifetime\": 3000,\n"
 "                \"rapid-commit\": false,\n"
 "                \"rebind-timer\": 2000,\n"
 "                \"relay\": {\n"
@@ -2328,7 +2907,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 2
+    // CONFIGURATION 4
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -2543,7 +3122,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 3
+    // CONFIGURATION 5
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -2758,7 +3337,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 4
+    // CONFIGURATION 6
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -2883,7 +3462,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 5
+    // CONFIGURATION 7
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -3009,7 +3588,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 6
+    // CONFIGURATION 8
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -3132,7 +3711,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 7
+    // CONFIGURATION 9
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -3255,7 +3834,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 8
+    // CONFIGURATION 10
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -3416,7 +3995,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 9
+    // CONFIGURATION 11
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -3538,7 +4117,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 10
+    // CONFIGURATION 12
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -3662,7 +4241,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 11
+    // CONFIGURATION 13
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -3788,7 +4367,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 12
+    // CONFIGURATION 14
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -3929,7 +4508,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 13
+    // CONFIGURATION 15
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -4053,7 +4632,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 14
+    // CONFIGURATION 16
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -4150,7 +4729,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 15
+    // CONFIGURATION 17
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -4247,7 +4826,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 16
+    // CONFIGURATION 18
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -4353,7 +4932,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 17
+    // CONFIGURATION 19
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -4450,7 +5029,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 18
+    // CONFIGURATION 20
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -4547,7 +5126,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 19
+    // CONFIGURATION 21
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -4590,7 +5169,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hostname-char-replacement\": \"\",\n"
 "        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ],\n"
+"            \"interfaces\": [ ],\n"
 "            \"re-detect\": false\n"
 "        },\n"
 "        \"ip-reservations-unique\": true,\n"
@@ -4603,7 +5182,201 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"packet-queue-size\": 64,\n"
 "            \"thread-pool-size\": 0\n"
 "        },\n"
-"        \"option-data\": [\n"
+"        \"option-data\": [ ],\n"
+"        \"option-def\": [\n"
+"            {\n"
+"                \"array\": false,\n"
+"                \"code\": 100,\n"
+"                \"encapsulate\": \"\",\n"
+"                \"name\": \"foo\",\n"
+"                \"record-types\": \"\",\n"
+"                \"space\": \"dhcp6\",\n"
+"                \"type\": \"string\"\n"
+"            }\n"
+"        ],\n"
+"        \"parked-packet-limit\": 256,\n"
+"        \"pd-allocator\": \"iterative\",\n"
+"        \"relay-supplied-options\": [ \"65\" ],\n"
+"        \"reservations-global\": false,\n"
+"        \"reservations-in-subnet\": true,\n"
+"        \"reservations-lookup-first\": false,\n"
+"        \"reservations-out-of-pool\": false,\n"
+"        \"sanity-checks\": {\n"
+"            \"extended-info-checks\": \"fix\",\n"
+"            \"lease-checks\": \"warn\"\n"
+"        },\n"
+"        \"server-id\": {\n"
+"            \"enterprise-id\": 0,\n"
+"            \"htype\": 0,\n"
+"            \"identifier\": \"\",\n"
+"            \"persist\": true,\n"
+"            \"time\": 0,\n"
+"            \"type\": \"LLT\"\n"
+"        },\n"
+"        \"server-tag\": \"\",\n"
+"        \"shared-networks\": [ ],\n"
+"        \"statistic-default-sample-age\": 0,\n"
+"        \"statistic-default-sample-count\": 20,\n"
+"        \"store-extended-info\": false,\n"
+"        \"subnet6\": [ ],\n"
+"        \"t1-percent\": 0.5,\n"
+"        \"t2-percent\": 0.8,\n"
+"        \"valid-lifetime\": 7200\n"
+"    }\n",
+    // CONFIGURATION 22
+"{\n"
+"        \"allocator\": \"iterative\",\n"
+"        \"calculate-tee-times\": true,\n"
+"        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
+"        \"ddns-generated-prefix\": \"myhost\",\n"
+"        \"ddns-override-client-update\": false,\n"
+"        \"ddns-override-no-update\": false,\n"
+"        \"ddns-qualifying-suffix\": \"\",\n"
+"        \"ddns-replace-client-name\": \"never\",\n"
+"        \"ddns-send-updates\": true,\n"
+"        \"ddns-update-on-renew\": false,\n"
+"        \"decline-probation-period\": 86400,\n"
+"        \"dhcp-ddns\": {\n"
+"            \"enable-updates\": false,\n"
+"            \"max-queue-size\": 1024,\n"
+"            \"ncr-format\": \"JSON\",\n"
+"            \"ncr-protocol\": \"UDP\",\n"
+"            \"sender-ip\": \"0.0.0.0\",\n"
+"            \"sender-port\": 0,\n"
+"            \"server-ip\": \"127.0.0.1\",\n"
+"            \"server-port\": 53001\n"
+"        },\n"
+"        \"dhcp-queue-control\": {\n"
+"            \"capacity\": 64,\n"
+"            \"enable-queue\": false,\n"
+"            \"queue-type\": \"kea-ring6\"\n"
+"        },\n"
+"        \"dhcp4o6-port\": 0,\n"
+"        \"early-global-reservations-lookup\": false,\n"
+"        \"expired-leases-processing\": {\n"
+"            \"flush-reclaimed-timer-wait-time\": 25,\n"
+"            \"hold-reclaimed-time\": 3600,\n"
+"            \"max-reclaim-leases\": 100,\n"
+"            \"max-reclaim-time\": 250,\n"
+"            \"reclaim-timer-wait-time\": 10,\n"
+"            \"unwarned-reclaim-cycles\": 5\n"
+"        },\n"
+"        \"hooks-libraries\": [ ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
+"        \"hostname-char-replacement\": \"\",\n"
+"        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"ip-reservations-unique\": true,\n"
+"        \"lease-database\": {\n"
+"            \"type\": \"memfile\"\n"
+"        },\n"
+"        \"mac-sources\": [ \"any\" ],\n"
+"        \"multi-threading\": {\n"
+"            \"enable-multi-threading\": true,\n"
+"            \"packet-queue-size\": 64,\n"
+"            \"thread-pool-size\": 0\n"
+"        },\n"
+"        \"option-data\": [ ],\n"
+"        \"option-def\": [\n"
+"            {\n"
+"                \"array\": false,\n"
+"                \"code\": 63,\n"
+"                \"encapsulate\": \"\",\n"
+"                \"name\": \"geolocation\",\n"
+"                \"record-types\": \"\",\n"
+"                \"space\": \"dhcp6\",\n"
+"                \"type\": \"string\"\n"
+"            }\n"
+"        ],\n"
+"        \"parked-packet-limit\": 256,\n"
+"        \"pd-allocator\": \"iterative\",\n"
+"        \"relay-supplied-options\": [ \"65\" ],\n"
+"        \"reservations-global\": false,\n"
+"        \"reservations-in-subnet\": true,\n"
+"        \"reservations-lookup-first\": false,\n"
+"        \"reservations-out-of-pool\": false,\n"
+"        \"sanity-checks\": {\n"
+"            \"extended-info-checks\": \"fix\",\n"
+"            \"lease-checks\": \"warn\"\n"
+"        },\n"
+"        \"server-id\": {\n"
+"            \"enterprise-id\": 0,\n"
+"            \"htype\": 0,\n"
+"            \"identifier\": \"\",\n"
+"            \"persist\": true,\n"
+"            \"time\": 0,\n"
+"            \"type\": \"LLT\"\n"
+"        },\n"
+"        \"server-tag\": \"\",\n"
+"        \"shared-networks\": [ ],\n"
+"        \"statistic-default-sample-age\": 0,\n"
+"        \"statistic-default-sample-count\": 20,\n"
+"        \"store-extended-info\": false,\n"
+"        \"subnet6\": [ ],\n"
+"        \"t1-percent\": 0.5,\n"
+"        \"t2-percent\": 0.8,\n"
+"        \"valid-lifetime\": 7200\n"
+"    }\n",
+    // CONFIGURATION 23
+"{\n"
+"        \"allocator\": \"iterative\",\n"
+"        \"calculate-tee-times\": true,\n"
+"        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
+"        \"ddns-generated-prefix\": \"myhost\",\n"
+"        \"ddns-override-client-update\": false,\n"
+"        \"ddns-override-no-update\": false,\n"
+"        \"ddns-qualifying-suffix\": \"\",\n"
+"        \"ddns-replace-client-name\": \"never\",\n"
+"        \"ddns-send-updates\": true,\n"
+"        \"ddns-update-on-renew\": false,\n"
+"        \"decline-probation-period\": 86400,\n"
+"        \"dhcp-ddns\": {\n"
+"            \"enable-updates\": false,\n"
+"            \"max-queue-size\": 1024,\n"
+"            \"ncr-format\": \"JSON\",\n"
+"            \"ncr-protocol\": \"UDP\",\n"
+"            \"sender-ip\": \"0.0.0.0\",\n"
+"            \"sender-port\": 0,\n"
+"            \"server-ip\": \"127.0.0.1\",\n"
+"            \"server-port\": 53001\n"
+"        },\n"
+"        \"dhcp-queue-control\": {\n"
+"            \"capacity\": 64,\n"
+"            \"enable-queue\": false,\n"
+"            \"queue-type\": \"kea-ring6\"\n"
+"        },\n"
+"        \"dhcp4o6-port\": 0,\n"
+"        \"early-global-reservations-lookup\": false,\n"
+"        \"expired-leases-processing\": {\n"
+"            \"flush-reclaimed-timer-wait-time\": 25,\n"
+"            \"hold-reclaimed-time\": 3600,\n"
+"            \"max-reclaim-leases\": 100,\n"
+"            \"max-reclaim-time\": 250,\n"
+"            \"reclaim-timer-wait-time\": 10,\n"
+"            \"unwarned-reclaim-cycles\": 5\n"
+"        },\n"
+"        \"hooks-libraries\": [ ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
+"        \"hostname-char-replacement\": \"\",\n"
+"        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"ip-reservations-unique\": true,\n"
+"        \"lease-database\": {\n"
+"            \"type\": \"memfile\"\n"
+"        },\n"
+"        \"mac-sources\": [ \"any\" ],\n"
+"        \"multi-threading\": {\n"
+"            \"enable-multi-threading\": true,\n"
+"            \"packet-queue-size\": 64,\n"
+"            \"thread-pool-size\": 0\n"
+"        },\n"
+"        \"option-data\": [\n"
 "            {\n"
 "                \"always-send\": false,\n"
 "                \"code\": 38,\n"
@@ -4688,7 +5461,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 20
+    // CONFIGURATION 24
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -4829,7 +5602,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 21
+    // CONFIGURATION 25
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -4980,7 +5753,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 22
+    // CONFIGURATION 26
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -5108,7 +5881,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 23
+    // CONFIGURATION 27
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -5286,7 +6059,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 24
+    // CONFIGURATION 28
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -5342,7 +6115,17 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"packet-queue-size\": 64,\n"
 "            \"thread-pool-size\": 0\n"
 "        },\n"
-"        \"option-data\": [ ],\n"
+"        \"option-data\": [\n"
+"            {\n"
+"                \"always-send\": false,\n"
+"                \"code\": 38,\n"
+"                \"csv-format\": false,\n"
+"                \"data\": \"AB\",\n"
+"                \"name\": \"subscriber-id\",\n"
+"                \"never-send\": false,\n"
+"                \"space\": \"dhcp6\"\n"
+"            }\n"
+"        ],\n"
 "        \"option-def\": [ ],\n"
 "        \"parked-packet-limit\": 256,\n"
 "        \"pd-allocator\": \"iterative\",\n"
@@ -5385,43 +6168,11 @@ const char* UNPARSED_CONFIGS[] = {
 "                        \"always-send\": false,\n"
 "                        \"code\": 38,\n"
 "                        \"csv-format\": false,\n"
-"                        \"data\": \"0102030405060708090A\",\n"
+"                        \"data\": \"ABCDEF0105\",\n"
 "                        \"name\": \"subscriber-id\",\n"
 "                        \"never-send\": false,\n"
 "                        \"space\": \"dhcp6\"\n"
-"                    }\n"
-"                ],\n"
-"                \"pd-allocator\": \"iterative\",\n"
-"                \"pd-pools\": [ ],\n"
-"                \"pools\": [\n"
-"                    {\n"
-"                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8:1::/80\"\n"
-"                    }\n"
-"                ],\n"
-"                \"preferred-lifetime\": 3000,\n"
-"                \"rapid-commit\": false,\n"
-"                \"rebind-timer\": 2000,\n"
-"                \"relay\": {\n"
-"                    \"ip-addresses\": [ ]\n"
-"                },\n"
-"                \"renew-timer\": 1000,\n"
-"                \"reservations\": [ ],\n"
-"                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8:1::/64\",\n"
-"                \"t1-percent\": 0.5,\n"
-"                \"t2-percent\": 0.8,\n"
-"                \"valid-lifetime\": 4000\n"
-"            },\n"
-"            {\n"
-"                \"allocator\": \"iterative\",\n"
-"                \"calculate-tee-times\": true,\n"
-"                \"id\": 2,\n"
-"                \"max-preferred-lifetime\": 3000,\n"
-"                \"max-valid-lifetime\": 4000,\n"
-"                \"min-preferred-lifetime\": 3000,\n"
-"                \"min-valid-lifetime\": 4000,\n"
-"                \"option-data\": [\n"
+"                    },\n"
 "                    {\n"
 "                        \"always-send\": false,\n"
 "                        \"code\": 15,\n"
@@ -5437,7 +6188,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"pools\": [\n"
 "                    {\n"
 "                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8:2::/80\"\n"
+"                        \"pool\": \"2001:db8:1::/80\"\n"
 "                    }\n"
 "                ],\n"
 "                \"preferred-lifetime\": 3000,\n"
@@ -5449,7 +6200,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"reservations\": [ ],\n"
 "                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8:2::/64\",\n"
+"                \"subnet\": \"2001:db8:1::/64\",\n"
 "                \"t1-percent\": 0.5,\n"
 "                \"t2-percent\": 0.8,\n"
 "                \"valid-lifetime\": 4000\n"
@@ -5459,7 +6210,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 25
+    // CONFIGURATION 29
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -5553,70 +6304,23 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"max-valid-lifetime\": 4000,\n"
 "                \"min-preferred-lifetime\": 3000,\n"
 "                \"min-valid-lifetime\": 4000,\n"
-"                \"option-data\": [ ],\n"
-"                \"pd-allocator\": \"iterative\",\n"
-"                \"pd-pools\": [\n"
-"                    {\n"
-"                        \"delegated-len\": 64,\n"
-"                        \"option-data\": [\n"
-"                            {\n"
-"                                \"always-send\": false,\n"
-"                                \"code\": 38,\n"
-"                                \"csv-format\": false,\n"
-"                                \"data\": \"112233445566\",\n"
-"                                \"name\": \"subscriber-id\",\n"
-"                                \"never-send\": false,\n"
-"                                \"space\": \"dhcp6\"\n"
-"                            }\n"
-"                        ],\n"
-"                        \"prefix\": \"3000::\",\n"
-"                        \"prefix-len\": 48\n"
-"                    },\n"
+"                \"option-data\": [\n"
 "                    {\n"
-"                        \"delegated-len\": 64,\n"
-"                        \"option-data\": [\n"
-"                            {\n"
-"                                \"always-send\": false,\n"
-"                                \"code\": 15,\n"
-"                                \"csv-format\": false,\n"
-"                                \"data\": \"AABBCCDDEE\",\n"
-"                                \"name\": \"user-class\",\n"
-"                                \"never-send\": false,\n"
-"                                \"space\": \"dhcp6\"\n"
-"                            }\n"
-"                        ],\n"
-"                        \"prefix\": \"3001::\",\n"
-"                        \"prefix-len\": 48\n"
+"                        \"always-send\": false,\n"
+"                        \"code\": 38,\n"
+"                        \"csv-format\": false,\n"
+"                        \"data\": \"0102030405060708090A\",\n"
+"                        \"name\": \"subscriber-id\",\n"
+"                        \"never-send\": false,\n"
+"                        \"space\": \"dhcp6\"\n"
 "                    }\n"
 "                ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
 "                    {\n"
-"                        \"option-data\": [\n"
-"                            {\n"
-"                                \"always-send\": false,\n"
-"                                \"code\": 38,\n"
-"                                \"csv-format\": false,\n"
-"                                \"data\": \"0102030405060708090A\",\n"
-"                                \"name\": \"subscriber-id\",\n"
-"                                \"never-send\": false,\n"
-"                                \"space\": \"dhcp6\"\n"
-"                            }\n"
-"                        ],\n"
-"                        \"pool\": \"2001:db8:1::10-2001:db8:1::100\"\n"
-"                    },\n"
-"                    {\n"
-"                        \"option-data\": [\n"
-"                            {\n"
-"                                \"always-send\": false,\n"
-"                                \"code\": 15,\n"
-"                                \"csv-format\": false,\n"
-"                                \"data\": \"FFFEFDFCFB\",\n"
-"                                \"name\": \"user-class\",\n"
-"                                \"never-send\": false,\n"
-"                                \"space\": \"dhcp6\"\n"
-"                            }\n"
-"                        ],\n"
-"                        \"pool\": \"2001:db8:1::300-2001:db8:1::400\"\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8:1::/80\"\n"
 "                    }\n"
 "                ],\n"
 "                \"preferred-lifetime\": 3000,\n"
@@ -5632,13 +6336,54 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"t1-percent\": 0.5,\n"
 "                \"t2-percent\": 0.8,\n"
 "                \"valid-lifetime\": 4000\n"
+"            },\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"id\": 2,\n"
+"                \"max-preferred-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-preferred-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [\n"
+"                    {\n"
+"                        \"always-send\": false,\n"
+"                        \"code\": 15,\n"
+"                        \"csv-format\": false,\n"
+"                        \"data\": \"FFFEFDFCFB\",\n"
+"                        \"name\": \"user-class\",\n"
+"                        \"never-send\": false,\n"
+"                        \"space\": \"dhcp6\"\n"
+"                    }\n"
+"                ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8:2::/80\"\n"
+"                    }\n"
+"                ],\n"
+"                \"preferred-lifetime\": 3000,\n"
+"                \"rapid-commit\": false,\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8:2::/64\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 4000\n"
 "            }\n"
 "        ],\n"
 "        \"t1-percent\": 0.5,\n"
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 26
+    // CONFIGURATION 30
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -5694,24 +6439,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"packet-queue-size\": 64,\n"
 "            \"thread-pool-size\": 0\n"
 "        },\n"
-"        \"option-data\": [\n"
-"            {\n"
-"                \"always-send\": false,\n"
-"                \"code\": 100,\n"
-"                \"csv-format\": false,\n"
-"                \"data\": \"1234\",\n"
-"                \"never-send\": false,\n"
-"                \"space\": \"vendor-1234\"\n"
-"            },\n"
-"            {\n"
-"                \"always-send\": false,\n"
-"                \"code\": 100,\n"
-"                \"csv-format\": false,\n"
-"                \"data\": \"ABCDEF0105\",\n"
-"                \"never-send\": false,\n"
-"                \"space\": \"vendor-4491\"\n"
-"            }\n"
-"        ],\n"
+"        \"option-data\": [ ],\n"
 "        \"option-def\": [ ],\n"
 "        \"parked-packet-limit\": 256,\n"
 "        \"pd-allocator\": \"iterative\",\n"
@@ -5754,8 +6482,27 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
 "                    {\n"
-"                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8:1::/80\"\n"
+"                        \"option-data\": [\n"
+"                            {\n"
+"                                \"always-send\": false,\n"
+"                                \"code\": 38,\n"
+"                                \"csv-format\": false,\n"
+"                                \"data\": \"0102030405060708090A\",\n"
+"                                \"name\": \"subscriber-id\",\n"
+"                                \"never-send\": false,\n"
+"                                \"space\": \"dhcp6\"\n"
+"                            },\n"
+"                            {\n"
+"                                \"always-send\": false,\n"
+"                                \"code\": 15,\n"
+"                                \"csv-format\": false,\n"
+"                                \"data\": \"FFFEFDFCFB\",\n"
+"                                \"name\": \"user-class\",\n"
+"                                \"never-send\": false,\n"
+"                                \"space\": \"dhcp6\"\n"
+"                            }\n"
+"                        ],\n"
+"                        \"pool\": \"2001:db8:1::10-2001:db8:1::100\"\n"
 "                    }\n"
 "                ],\n"
 "                \"preferred-lifetime\": 3000,\n"
@@ -5777,7 +6524,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 27
+    // CONFIGURATION 31
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -5833,28 +6580,8 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"packet-queue-size\": 64,\n"
 "            \"thread-pool-size\": 0\n"
 "        },\n"
-"        \"option-data\": [\n"
-"            {\n"
-"                \"always-send\": false,\n"
-"                \"code\": 100,\n"
-"                \"csv-format\": true,\n"
-"                \"data\": \"this is a string vendor-opt\",\n"
-"                \"name\": \"foo\",\n"
-"                \"never-send\": false,\n"
-"                \"space\": \"vendor-4491\"\n"
-"            }\n"
-"        ],\n"
-"        \"option-def\": [\n"
-"            {\n"
-"                \"array\": false,\n"
-"                \"code\": 100,\n"
-"                \"encapsulate\": \"\",\n"
-"                \"name\": \"foo\",\n"
-"                \"record-types\": \"\",\n"
-"                \"space\": \"vendor-4491\",\n"
-"                \"type\": \"string\"\n"
-"            }\n"
-"        ],\n"
+"        \"option-data\": [ ],\n"
+"        \"option-def\": [ ],\n"
 "        \"parked-packet-limit\": 256,\n"
 "        \"pd-allocator\": \"iterative\",\n"
 "        \"preferred-lifetime\": 3000,\n"
@@ -5893,11 +6620,68 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"min-valid-lifetime\": 4000,\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-allocator\": \"iterative\",\n"
-"                \"pd-pools\": [ ],\n"
+"                \"pd-pools\": [\n"
+"                    {\n"
+"                        \"delegated-len\": 64,\n"
+"                        \"option-data\": [\n"
+"                            {\n"
+"                                \"always-send\": false,\n"
+"                                \"code\": 38,\n"
+"                                \"csv-format\": false,\n"
+"                                \"data\": \"112233445566\",\n"
+"                                \"name\": \"subscriber-id\",\n"
+"                                \"never-send\": false,\n"
+"                                \"space\": \"dhcp6\"\n"
+"                            }\n"
+"                        ],\n"
+"                        \"prefix\": \"3000::\",\n"
+"                        \"prefix-len\": 48\n"
+"                    },\n"
+"                    {\n"
+"                        \"delegated-len\": 64,\n"
+"                        \"option-data\": [\n"
+"                            {\n"
+"                                \"always-send\": false,\n"
+"                                \"code\": 15,\n"
+"                                \"csv-format\": false,\n"
+"                                \"data\": \"AABBCCDDEE\",\n"
+"                                \"name\": \"user-class\",\n"
+"                                \"never-send\": false,\n"
+"                                \"space\": \"dhcp6\"\n"
+"                            }\n"
+"                        ],\n"
+"                        \"prefix\": \"3001::\",\n"
+"                        \"prefix-len\": 48\n"
+"                    }\n"
+"                ],\n"
 "                \"pools\": [\n"
 "                    {\n"
-"                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8:1::/80\"\n"
+"                        \"option-data\": [\n"
+"                            {\n"
+"                                \"always-send\": false,\n"
+"                                \"code\": 38,\n"
+"                                \"csv-format\": false,\n"
+"                                \"data\": \"0102030405060708090A\",\n"
+"                                \"name\": \"subscriber-id\",\n"
+"                                \"never-send\": false,\n"
+"                                \"space\": \"dhcp6\"\n"
+"                            }\n"
+"                        ],\n"
+"                        \"pool\": \"2001:db8:1::10-2001:db8:1::100\"\n"
+"                    },\n"
+"                    {\n"
+"                        \"option-data\": [\n"
+"                            {\n"
+"                                \"always-send\": false,\n"
+"                                \"code\": 15,\n"
+"                                \"csv-format\": false,\n"
+"                                \"data\": \"FFFEFDFCFB\",\n"
+"                                \"name\": \"user-class\",\n"
+"                                \"never-send\": false,\n"
+"                                \"space\": \"dhcp6\"\n"
+"                            }\n"
+"                        ],\n"
+"                        \"pool\": \"2001:db8:1::300-2001:db8:1::400\"\n"
 "                    }\n"
 "                ],\n"
 "                \"preferred-lifetime\": 3000,\n"
@@ -5919,7 +6703,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 28
+    // CONFIGURATION 32
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -5962,7 +6746,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hostname-char-replacement\": \"\",\n"
 "        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"eth0\" ],\n"
+"            \"interfaces\": [ \"*\" ],\n"
 "            \"re-detect\": false\n"
 "        },\n"
 "        \"ip-reservations-unique\": true,\n"
@@ -5975,15 +6759,32 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"packet-queue-size\": 64,\n"
 "            \"thread-pool-size\": 0\n"
 "        },\n"
-"        \"option-data\": [ ],\n"
-"        \"option-def\": [ ],\n"
-"        \"parked-packet-limit\": 256,\n"
-"        \"pd-allocator\": \"iterative\",\n"
-"        \"preferred-lifetime\": 3000,\n"
-"        \"rebind-timer\": 2000,\n"
-"        \"relay-supplied-options\": [ \"65\" ],\n"
-"        \"renew-timer\": 1000,\n"
-"        \"reservations-global\": false,\n"
+"        \"option-data\": [\n"
+"            {\n"
+"                \"always-send\": false,\n"
+"                \"code\": 100,\n"
+"                \"csv-format\": false,\n"
+"                \"data\": \"1234\",\n"
+"                \"never-send\": false,\n"
+"                \"space\": \"vendor-1234\"\n"
+"            },\n"
+"            {\n"
+"                \"always-send\": false,\n"
+"                \"code\": 100,\n"
+"                \"csv-format\": false,\n"
+"                \"data\": \"ABCDEF0105\",\n"
+"                \"never-send\": false,\n"
+"                \"space\": \"vendor-4491\"\n"
+"            }\n"
+"        ],\n"
+"        \"option-def\": [ ],\n"
+"        \"parked-packet-limit\": 256,\n"
+"        \"pd-allocator\": \"iterative\",\n"
+"        \"preferred-lifetime\": 3000,\n"
+"        \"rebind-timer\": 2000,\n"
+"        \"relay-supplied-options\": [ \"65\" ],\n"
+"        \"renew-timer\": 1000,\n"
+"        \"reservations-global\": false,\n"
 "        \"reservations-in-subnet\": true,\n"
 "        \"reservations-lookup-first\": false,\n"
 "        \"reservations-out-of-pool\": false,\n"
@@ -6004,12 +6805,44 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"statistic-default-sample-age\": 0,\n"
 "        \"statistic-default-sample-count\": 20,\n"
 "        \"store-extended-info\": false,\n"
-"        \"subnet6\": [ ],\n"
+"        \"subnet6\": [\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"id\": 1,\n"
+"                \"max-preferred-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-preferred-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8:1::/80\"\n"
+"                    }\n"
+"                ],\n"
+"                \"preferred-lifetime\": 3000,\n"
+"                \"rapid-commit\": false,\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8:1::/64\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 4000\n"
+"            }\n"
+"        ],\n"
 "        \"t1-percent\": 0.5,\n"
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 29
+    // CONFIGURATION 33
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -6052,7 +6885,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hostname-char-replacement\": \"\",\n"
 "        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\", \"eth0\", \"eth1\" ],\n"
+"            \"interfaces\": [ \"*\" ],\n"
 "            \"re-detect\": false\n"
 "        },\n"
 "        \"ip-reservations-unique\": true,\n"
@@ -6065,8 +6898,28 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"packet-queue-size\": 64,\n"
 "            \"thread-pool-size\": 0\n"
 "        },\n"
-"        \"option-data\": [ ],\n"
-"        \"option-def\": [ ],\n"
+"        \"option-data\": [\n"
+"            {\n"
+"                \"always-send\": false,\n"
+"                \"code\": 100,\n"
+"                \"csv-format\": true,\n"
+"                \"data\": \"this is a string vendor-opt\",\n"
+"                \"name\": \"foo\",\n"
+"                \"never-send\": false,\n"
+"                \"space\": \"vendor-4491\"\n"
+"            }\n"
+"        ],\n"
+"        \"option-def\": [\n"
+"            {\n"
+"                \"array\": false,\n"
+"                \"code\": 100,\n"
+"                \"encapsulate\": \"\",\n"
+"                \"name\": \"foo\",\n"
+"                \"record-types\": \"\",\n"
+"                \"space\": \"vendor-4491\",\n"
+"                \"type\": \"string\"\n"
+"            }\n"
+"        ],\n"
 "        \"parked-packet-limit\": 256,\n"
 "        \"pd-allocator\": \"iterative\",\n"
 "        \"preferred-lifetime\": 3000,\n"
@@ -6094,12 +6947,44 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"statistic-default-sample-age\": 0,\n"
 "        \"statistic-default-sample-count\": 20,\n"
 "        \"store-extended-info\": false,\n"
-"        \"subnet6\": [ ],\n"
+"        \"subnet6\": [\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"id\": 1,\n"
+"                \"max-preferred-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-preferred-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8:1::/80\"\n"
+"                    }\n"
+"                ],\n"
+"                \"preferred-lifetime\": 3000,\n"
+"                \"rapid-commit\": false,\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8:1::/64\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 4000\n"
+"            }\n"
+"        ],\n"
 "        \"t1-percent\": 0.5,\n"
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 30
+    // CONFIGURATION 34
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -6142,7 +7027,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hostname-char-replacement\": \"\",\n"
 "        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ],\n"
+"            \"interfaces\": [ \"eth0\" ],\n"
 "            \"re-detect\": false\n"
 "        },\n"
 "        \"ip-reservations-unique\": true,\n"
@@ -6184,44 +7069,12 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"statistic-default-sample-age\": 0,\n"
 "        \"statistic-default-sample-count\": 20,\n"
 "        \"store-extended-info\": false,\n"
-"        \"subnet6\": [\n"
-"            {\n"
-"                \"allocator\": \"iterative\",\n"
-"                \"calculate-tee-times\": true,\n"
-"                \"id\": 1,\n"
-"                \"max-preferred-lifetime\": 3000,\n"
-"                \"max-valid-lifetime\": 4000,\n"
-"                \"min-preferred-lifetime\": 3000,\n"
-"                \"min-valid-lifetime\": 4000,\n"
-"                \"option-data\": [ ],\n"
-"                \"pd-allocator\": \"iterative\",\n"
-"                \"pd-pools\": [ ],\n"
-"                \"pools\": [\n"
-"                    {\n"
-"                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8:1::1-2001:db8:1::ffff\"\n"
-"                    }\n"
-"                ],\n"
-"                \"preferred-lifetime\": 3000,\n"
-"                \"rapid-commit\": false,\n"
-"                \"rebind-timer\": 2000,\n"
-"                \"relay\": {\n"
-"                    \"ip-addresses\": [ \"2001:db8:1::abcd\" ]\n"
-"                },\n"
-"                \"renew-timer\": 1000,\n"
-"                \"reservations\": [ ],\n"
-"                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8:1::/64\",\n"
-"                \"t1-percent\": 0.5,\n"
-"                \"t2-percent\": 0.8,\n"
-"                \"valid-lifetime\": 4000\n"
-"            }\n"
-"        ],\n"
+"        \"subnet6\": [ ],\n"
 "        \"t1-percent\": 0.5,\n"
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 31
+    // CONFIGURATION 35
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -6264,7 +7117,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hostname-char-replacement\": \"\",\n"
 "        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ],\n"
+"            \"interfaces\": [ \"*\", \"eth0\", \"eth1\" ],\n"
 "            \"re-detect\": false\n"
 "        },\n"
 "        \"ip-reservations-unique\": true,\n"
@@ -6306,44 +7159,12 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"statistic-default-sample-age\": 0,\n"
 "        \"statistic-default-sample-count\": 20,\n"
 "        \"store-extended-info\": false,\n"
-"        \"subnet6\": [\n"
-"            {\n"
-"                \"allocator\": \"iterative\",\n"
-"                \"calculate-tee-times\": true,\n"
-"                \"id\": 1,\n"
-"                \"max-preferred-lifetime\": 3000,\n"
-"                \"max-valid-lifetime\": 4000,\n"
-"                \"min-preferred-lifetime\": 3000,\n"
-"                \"min-valid-lifetime\": 4000,\n"
-"                \"option-data\": [ ],\n"
-"                \"pd-allocator\": \"iterative\",\n"
-"                \"pd-pools\": [ ],\n"
-"                \"pools\": [\n"
-"                    {\n"
-"                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8:1::1-2001:db8:1::ffff\"\n"
-"                    }\n"
-"                ],\n"
-"                \"preferred-lifetime\": 3000,\n"
-"                \"rapid-commit\": false,\n"
-"                \"rebind-timer\": 2000,\n"
-"                \"relay\": {\n"
-"                    \"ip-addresses\": [ \"2001:db9::abcd\", \"2001:db9::abce\" ]\n"
-"                },\n"
-"                \"renew-timer\": 1000,\n"
-"                \"reservations\": [ ],\n"
-"                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8:1::/64\",\n"
-"                \"t1-percent\": 0.5,\n"
-"                \"t2-percent\": 0.8,\n"
-"                \"valid-lifetime\": 4000\n"
-"            }\n"
-"        ],\n"
+"        \"subnet6\": [ ],\n"
 "        \"t1-percent\": 0.5,\n"
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 32
+    // CONFIGURATION 36
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -6432,136 +7253,40 @@ const char* UNPARSED_CONFIGS[] = {
 "            {\n"
 "                \"allocator\": \"iterative\",\n"
 "                \"calculate-tee-times\": true,\n"
-"                \"client-class\": \"alpha\",\n"
 "                \"id\": 1,\n"
 "                \"max-preferred-lifetime\": 3000,\n"
-"                \"max-valid-lifetime\": 4000,\n"
+"                \"max-valid-lifetime\": 4,\n"
 "                \"min-preferred-lifetime\": 3000,\n"
-"                \"min-valid-lifetime\": 4000,\n"
+"                \"min-valid-lifetime\": 4,\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-allocator\": \"iterative\",\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
 "                    {\n"
 "                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8:1::/80\"\n"
+"                        \"pool\": \"2001:db8:1::1-2001:db8:1::ffff\"\n"
 "                    }\n"
 "                ],\n"
 "                \"preferred-lifetime\": 3000,\n"
 "                \"rapid-commit\": false,\n"
-"                \"rebind-timer\": 2000,\n"
+"                \"rebind-timer\": 2,\n"
 "                \"relay\": {\n"
-"                    \"ip-addresses\": [ ]\n"
+"                    \"ip-addresses\": [ \"2001:db8:1::abcd\" ]\n"
 "                },\n"
-"                \"renew-timer\": 1000,\n"
+"                \"renew-timer\": 1,\n"
 "                \"reservations\": [ ],\n"
 "                \"store-extended-info\": false,\n"
 "                \"subnet\": \"2001:db8:1::/64\",\n"
 "                \"t1-percent\": 0.5,\n"
 "                \"t2-percent\": 0.8,\n"
-"                \"valid-lifetime\": 4000\n"
-"            },\n"
-"            {\n"
-"                \"allocator\": \"iterative\",\n"
-"                \"calculate-tee-times\": true,\n"
-"                \"client-class\": \"beta\",\n"
-"                \"id\": 2,\n"
-"                \"max-preferred-lifetime\": 3000,\n"
-"                \"max-valid-lifetime\": 4000,\n"
-"                \"min-preferred-lifetime\": 3000,\n"
-"                \"min-valid-lifetime\": 4000,\n"
-"                \"option-data\": [ ],\n"
-"                \"pd-allocator\": \"iterative\",\n"
-"                \"pd-pools\": [ ],\n"
-"                \"pools\": [\n"
-"                    {\n"
-"                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8:2::/80\"\n"
-"                    }\n"
-"                ],\n"
-"                \"preferred-lifetime\": 3000,\n"
-"                \"rapid-commit\": false,\n"
-"                \"rebind-timer\": 2000,\n"
-"                \"relay\": {\n"
-"                    \"ip-addresses\": [ ]\n"
-"                },\n"
-"                \"renew-timer\": 1000,\n"
-"                \"reservations\": [ ],\n"
-"                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8:2::/64\",\n"
-"                \"t1-percent\": 0.5,\n"
-"                \"t2-percent\": 0.8,\n"
-"                \"valid-lifetime\": 4000\n"
-"            },\n"
-"            {\n"
-"                \"allocator\": \"iterative\",\n"
-"                \"calculate-tee-times\": true,\n"
-"                \"client-class\": \"gamma\",\n"
-"                \"id\": 3,\n"
-"                \"max-preferred-lifetime\": 3000,\n"
-"                \"max-valid-lifetime\": 4000,\n"
-"                \"min-preferred-lifetime\": 3000,\n"
-"                \"min-valid-lifetime\": 4000,\n"
-"                \"option-data\": [ ],\n"
-"                \"pd-allocator\": \"iterative\",\n"
-"                \"pd-pools\": [ ],\n"
-"                \"pools\": [\n"
-"                    {\n"
-"                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8:3::/80\"\n"
-"                    }\n"
-"                ],\n"
-"                \"preferred-lifetime\": 3000,\n"
-"                \"rapid-commit\": false,\n"
-"                \"rebind-timer\": 2000,\n"
-"                \"relay\": {\n"
-"                    \"ip-addresses\": [ ]\n"
-"                },\n"
-"                \"renew-timer\": 1000,\n"
-"                \"reservations\": [ ],\n"
-"                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8:3::/64\",\n"
-"                \"t1-percent\": 0.5,\n"
-"                \"t2-percent\": 0.8,\n"
-"                \"valid-lifetime\": 4000\n"
-"            },\n"
-"            {\n"
-"                \"allocator\": \"iterative\",\n"
-"                \"calculate-tee-times\": true,\n"
-"                \"id\": 4,\n"
-"                \"max-preferred-lifetime\": 3000,\n"
-"                \"max-valid-lifetime\": 4000,\n"
-"                \"min-preferred-lifetime\": 3000,\n"
-"                \"min-valid-lifetime\": 4000,\n"
-"                \"option-data\": [ ],\n"
-"                \"pd-allocator\": \"iterative\",\n"
-"                \"pd-pools\": [ ],\n"
-"                \"pools\": [\n"
-"                    {\n"
-"                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8:4::/80\"\n"
-"                    }\n"
-"                ],\n"
-"                \"preferred-lifetime\": 3000,\n"
-"                \"rapid-commit\": false,\n"
-"                \"rebind-timer\": 2000,\n"
-"                \"relay\": {\n"
-"                    \"ip-addresses\": [ ]\n"
-"                },\n"
-"                \"renew-timer\": 1000,\n"
-"                \"reservations\": [ ],\n"
-"                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8:4::/64\",\n"
-"                \"t1-percent\": 0.5,\n"
-"                \"t2-percent\": 0.8,\n"
-"                \"valid-lifetime\": 4000\n"
+"                \"valid-lifetime\": 4\n"
 "            }\n"
 "        ],\n"
 "        \"t1-percent\": 0.5,\n"
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 33
+    // CONFIGURATION 37
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -6652,53 +7377,38 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"calculate-tee-times\": true,\n"
 "                \"id\": 1,\n"
 "                \"max-preferred-lifetime\": 3000,\n"
-"                \"max-valid-lifetime\": 4000,\n"
+"                \"max-valid-lifetime\": 4,\n"
 "                \"min-preferred-lifetime\": 3000,\n"
-"                \"min-valid-lifetime\": 4000,\n"
+"                \"min-valid-lifetime\": 4,\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-allocator\": \"iterative\",\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
 "                    {\n"
-"                        \"client-class\": \"alpha\",\n"
-"                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8:1::/80\"\n"
-"                    },\n"
-"                    {\n"
-"                        \"client-class\": \"beta\",\n"
-"                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8:2::/80\"\n"
-"                    },\n"
-"                    {\n"
-"                        \"client-class\": \"gamma\",\n"
-"                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8:3::/80\"\n"
-"                    },\n"
-"                    {\n"
 "                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8:4::/80\"\n"
+"                        \"pool\": \"2001:db8:1::1-2001:db8:1::ffff\"\n"
 "                    }\n"
 "                ],\n"
 "                \"preferred-lifetime\": 3000,\n"
 "                \"rapid-commit\": false,\n"
-"                \"rebind-timer\": 2000,\n"
+"                \"rebind-timer\": 2,\n"
 "                \"relay\": {\n"
-"                    \"ip-addresses\": [ ]\n"
+"                    \"ip-addresses\": [ \"2001:db9::abcd\", \"2001:db9::abce\" ]\n"
 "                },\n"
-"                \"renew-timer\": 1000,\n"
+"                \"renew-timer\": 1,\n"
 "                \"reservations\": [ ],\n"
 "                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8::/40\",\n"
+"                \"subnet\": \"2001:db8:1::/64\",\n"
 "                \"t1-percent\": 0.5,\n"
 "                \"t2-percent\": 0.8,\n"
-"                \"valid-lifetime\": 4000\n"
+"                \"valid-lifetime\": 4\n"
 "            }\n"
 "        ],\n"
 "        \"t1-percent\": 0.5,\n"
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 34
+    // CONFIGURATION 38
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -6787,6 +7497,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            {\n"
 "                \"allocator\": \"iterative\",\n"
 "                \"calculate-tee-times\": true,\n"
+"                \"client-class\": \"alpha\",\n"
 "                \"id\": 1,\n"
 "                \"max-preferred-lifetime\": 3000,\n"
 "                \"max-valid-lifetime\": 4000,\n"
@@ -6794,36 +7505,108 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"min-valid-lifetime\": 4000,\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-allocator\": \"iterative\",\n"
-"                \"pd-pools\": [\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
 "                    {\n"
-"                        \"client-class\": \"alpha\",\n"
-"                        \"delegated-len\": 64,\n"
 "                        \"option-data\": [ ],\n"
-"                        \"prefix\": \"2001:db8:1::\",\n"
-"                        \"prefix-len\": 48\n"
-"                    },\n"
+"                        \"pool\": \"2001:db8:1::/80\"\n"
+"                    }\n"
+"                ],\n"
+"                \"preferred-lifetime\": 3000,\n"
+"                \"rapid-commit\": false,\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8:1::/64\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 4000\n"
+"            },\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"client-class\": \"beta\",\n"
+"                \"id\": 2,\n"
+"                \"max-preferred-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-preferred-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
 "                    {\n"
-"                        \"client-class\": \"beta\",\n"
-"                        \"delegated-len\": 64,\n"
 "                        \"option-data\": [ ],\n"
-"                        \"prefix\": \"2001:db8:2::\",\n"
-"                        \"prefix-len\": 48\n"
-"                    },\n"
+"                        \"pool\": \"2001:db8:2::/80\"\n"
+"                    }\n"
+"                ],\n"
+"                \"preferred-lifetime\": 3000,\n"
+"                \"rapid-commit\": false,\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8:2::/64\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 4000\n"
+"            },\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"client-class\": \"gamma\",\n"
+"                \"id\": 3,\n"
+"                \"max-preferred-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-preferred-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
 "                    {\n"
-"                        \"client-class\": \"gamma\",\n"
-"                        \"delegated-len\": 64,\n"
 "                        \"option-data\": [ ],\n"
-"                        \"prefix\": \"2001:db8:3::\",\n"
-"                        \"prefix-len\": 48\n"
-"                    },\n"
+"                        \"pool\": \"2001:db8:3::/80\"\n"
+"                    }\n"
+"                ],\n"
+"                \"preferred-lifetime\": 3000,\n"
+"                \"rapid-commit\": false,\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8:3::/64\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 4000\n"
+"            },\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"id\": 4,\n"
+"                \"max-preferred-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-preferred-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
 "                    {\n"
-"                        \"delegated-len\": 64,\n"
 "                        \"option-data\": [ ],\n"
-"                        \"prefix\": \"2001:db8:4::\",\n"
-"                        \"prefix-len\": 48\n"
+"                        \"pool\": \"2001:db8:4::/80\"\n"
 "                    }\n"
 "                ],\n"
-"                \"pools\": [ ],\n"
 "                \"preferred-lifetime\": 3000,\n"
 "                \"rapid-commit\": false,\n"
 "                \"rebind-timer\": 2000,\n"
@@ -6833,7 +7616,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"reservations\": [ ],\n"
 "                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8::/64\",\n"
+"                \"subnet\": \"2001:db8:4::/64\",\n"
 "                \"t1-percent\": 0.5,\n"
 "                \"t2-percent\": 0.8,\n"
 "                \"valid-lifetime\": 4000\n"
@@ -6843,7 +7626,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 35
+    // CONFIGURATION 39
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -6857,14 +7640,14 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"ddns-update-on-renew\": false,\n"
 "        \"decline-probation-period\": 86400,\n"
 "        \"dhcp-ddns\": {\n"
-"            \"enable-updates\": true,\n"
-"            \"max-queue-size\": 2048,\n"
+"            \"enable-updates\": false,\n"
+"            \"max-queue-size\": 1024,\n"
 "            \"ncr-format\": \"JSON\",\n"
 "            \"ncr-protocol\": \"UDP\",\n"
-"            \"sender-ip\": \"3001::2\",\n"
-"            \"sender-port\": 778,\n"
-"            \"server-ip\": \"3001::1\",\n"
-"            \"server-port\": 777\n"
+"            \"sender-ip\": \"0.0.0.0\",\n"
+"            \"sender-port\": 0,\n"
+"            \"server-ip\": \"127.0.0.1\",\n"
+"            \"server-port\": 53001\n"
 "        },\n"
 "        \"dhcp-queue-control\": {\n"
 "            \"capacity\": 64,\n"
@@ -6942,8 +7725,23 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"
 "                    {\n"
+"                        \"client-class\": \"alpha\",\n"
 "                        \"option-data\": [ ],\n"
 "                        \"pool\": \"2001:db8:1::/80\"\n"
+"                    },\n"
+"                    {\n"
+"                        \"client-class\": \"beta\",\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8:2::/80\"\n"
+"                    },\n"
+"                    {\n"
+"                        \"client-class\": \"gamma\",\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8:3::/80\"\n"
+"                    },\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8:4::/80\"\n"
 "                    }\n"
 "                ],\n"
 "                \"preferred-lifetime\": 3000,\n"
@@ -6955,7 +7753,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"reservations\": [ ],\n"
 "                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8:1::/64\",\n"
+"                \"subnet\": \"2001:db8::/40\",\n"
 "                \"t1-percent\": 0.5,\n"
 "                \"t2-percent\": 0.8,\n"
 "                \"valid-lifetime\": 4000\n"
@@ -6965,7 +7763,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 36
+    // CONFIGURATION 40
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -7054,126 +7852,42 @@ const char* UNPARSED_CONFIGS[] = {
 "            {\n"
 "                \"allocator\": \"iterative\",\n"
 "                \"calculate-tee-times\": true,\n"
-"                \"id\": 123,\n"
+"                \"id\": 1,\n"
 "                \"max-preferred-lifetime\": 3000,\n"
 "                \"max-valid-lifetime\": 4000,\n"
 "                \"min-preferred-lifetime\": 3000,\n"
 "                \"min-valid-lifetime\": 4000,\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-allocator\": \"iterative\",\n"
-"                \"pd-pools\": [ ],\n"
-"                \"pools\": [\n"
+"                \"pd-pools\": [\n"
 "                    {\n"
+"                        \"client-class\": \"alpha\",\n"
+"                        \"delegated-len\": 64,\n"
 "                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8:1::/80\"\n"
-"                    }\n"
-"                ],\n"
-"                \"preferred-lifetime\": 3000,\n"
-"                \"rapid-commit\": false,\n"
-"                \"rebind-timer\": 2000,\n"
-"                \"relay\": {\n"
-"                    \"ip-addresses\": [ ]\n"
-"                },\n"
-"                \"renew-timer\": 1000,\n"
-"                \"reservations\": [ ],\n"
-"                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8:1::/64\",\n"
-"                \"t1-percent\": 0.5,\n"
-"                \"t2-percent\": 0.8,\n"
-"                \"valid-lifetime\": 4000\n"
-"            },\n"
-"            {\n"
-"                \"allocator\": \"iterative\",\n"
-"                \"calculate-tee-times\": true,\n"
-"                \"id\": 234,\n"
-"                \"max-preferred-lifetime\": 3000,\n"
-"                \"max-valid-lifetime\": 4000,\n"
-"                \"min-preferred-lifetime\": 3000,\n"
-"                \"min-valid-lifetime\": 4000,\n"
-"                \"option-data\": [ ],\n"
-"                \"pd-allocator\": \"iterative\",\n"
-"                \"pd-pools\": [ ],\n"
-"                \"pools\": [ ],\n"
-"                \"preferred-lifetime\": 3000,\n"
-"                \"rapid-commit\": false,\n"
-"                \"rebind-timer\": 2000,\n"
-"                \"relay\": {\n"
-"                    \"ip-addresses\": [ ]\n"
-"                },\n"
-"                \"renew-timer\": 1000,\n"
-"                \"reservations\": [\n"
+"                        \"prefix\": \"2001:db8:1::\",\n"
+"                        \"prefix-len\": 48\n"
+"                    },\n"
 "                    {\n"
-"                        \"client-classes\": [ ],\n"
-"                        \"hostname\": \"\",\n"
-"                        \"hw-address\": \"01:02:03:04:05:06\",\n"
-"                        \"ip-addresses\": [ \"2001:db8:2::abcd\" ],\n"
-"                        \"option-data\": [\n"
-"                            {\n"
-"                                \"always-send\": false,\n"
-"                                \"code\": 23,\n"
-"                                \"csv-format\": true,\n"
-"                                \"data\": \"2001:db8:2::abbc\",\n"
-"                                \"name\": \"dns-servers\",\n"
-"                                \"never-send\": false,\n"
-"                                \"space\": \"dhcp6\"\n"
-"                            },\n"
-"                            {\n"
-"                                \"always-send\": false,\n"
-"                                \"code\": 7,\n"
-"                                \"csv-format\": true,\n"
-"                                \"data\": \"25\",\n"
-"                                \"name\": \"preference\",\n"
-"                                \"never-send\": false,\n"
-"                                \"space\": \"dhcp6\"\n"
-"                            }\n"
-"                        ],\n"
-"                        \"prefixes\": [ ]\n"
+"                        \"client-class\": \"beta\",\n"
+"                        \"delegated-len\": 64,\n"
+"                        \"option-data\": [ ],\n"
+"                        \"prefix\": \"2001:db8:2::\",\n"
+"                        \"prefix-len\": 48\n"
 "                    },\n"
 "                    {\n"
-"                        \"client-classes\": [ ],\n"
-"                        \"duid\": \"01:02:03:04:05:06:07:08:09:0a\",\n"
-"                        \"hostname\": \"\",\n"
-"                        \"ip-addresses\": [ \"2001:db8:2::1234\" ],\n"
-"                        \"option-data\": [\n"
-"                            {\n"
-"                                \"always-send\": false,\n"
-"                                \"code\": 23,\n"
-"                                \"csv-format\": true,\n"
-"                                \"data\": \"2001:db8:2::1111\",\n"
-"                                \"name\": \"dns-servers\",\n"
-"                                \"never-send\": false,\n"
-"                                \"space\": \"dhcp6\"\n"
-"                            },\n"
-"                            {\n"
-"                                \"always-send\": false,\n"
-"                                \"code\": 7,\n"
-"                                \"csv-format\": true,\n"
-"                                \"data\": \"11\",\n"
-"                                \"name\": \"preference\",\n"
-"                                \"never-send\": false,\n"
-"                                \"space\": \"dhcp6\"\n"
-"                            }\n"
-"                        ],\n"
-"                        \"prefixes\": [ ]\n"
+"                        \"client-class\": \"gamma\",\n"
+"                        \"delegated-len\": 64,\n"
+"                        \"option-data\": [ ],\n"
+"                        \"prefix\": \"2001:db8:3::\",\n"
+"                        \"prefix-len\": 48\n"
+"                    },\n"
+"                    {\n"
+"                        \"delegated-len\": 64,\n"
+"                        \"option-data\": [ ],\n"
+"                        \"prefix\": \"2001:db8:4::\",\n"
+"                        \"prefix-len\": 48\n"
 "                    }\n"
 "                ],\n"
-"                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8:2::/64\",\n"
-"                \"t1-percent\": 0.5,\n"
-"                \"t2-percent\": 0.8,\n"
-"                \"valid-lifetime\": 4000\n"
-"            },\n"
-"            {\n"
-"                \"allocator\": \"iterative\",\n"
-"                \"calculate-tee-times\": true,\n"
-"                \"id\": 542,\n"
-"                \"max-preferred-lifetime\": 3000,\n"
-"                \"max-valid-lifetime\": 4000,\n"
-"                \"min-preferred-lifetime\": 3000,\n"
-"                \"min-valid-lifetime\": 4000,\n"
-"                \"option-data\": [ ],\n"
-"                \"pd-allocator\": \"iterative\",\n"
-"                \"pd-pools\": [ ],\n"
 "                \"pools\": [ ],\n"
 "                \"preferred-lifetime\": 3000,\n"
 "                \"rapid-commit\": false,\n"
@@ -7182,45 +7896,9 @@ const char* UNPARSED_CONFIGS[] = {
 "                    \"ip-addresses\": [ ]\n"
 "                },\n"
 "                \"renew-timer\": 1000,\n"
-"                \"reservations\": [\n"
-"                    {\n"
-"                        \"client-classes\": [ ],\n"
-"                        \"hostname\": \"\",\n"
-"                        \"hw-address\": \"06:05:04:03:02:01\",\n"
-"                        \"ip-addresses\": [ ],\n"
-"                        \"option-data\": [ ],\n"
-"                        \"prefixes\": [ \"2001:db8:3:1::/96\" ]\n"
-"                    },\n"
-"                    {\n"
-"                        \"client-classes\": [ ],\n"
-"                        \"duid\": \"0a:09:08:07:06:05:04:03:02:01\",\n"
-"                        \"hostname\": \"\",\n"
-"                        \"ip-addresses\": [ ],\n"
-"                        \"option-data\": [\n"
-"                            {\n"
-"                                \"always-send\": false,\n"
-"                                \"code\": 23,\n"
-"                                \"csv-format\": true,\n"
-"                                \"data\": \"2001:db8:3::3333\",\n"
-"                                \"name\": \"dns-servers\",\n"
-"                                \"never-send\": false,\n"
-"                                \"space\": \"dhcp6\"\n"
-"                            },\n"
-"                            {\n"
-"                                \"always-send\": false,\n"
-"                                \"code\": 7,\n"
-"                                \"csv-format\": true,\n"
-"                                \"data\": \"33\",\n"
-"                                \"name\": \"preference\",\n"
-"                                \"never-send\": false,\n"
-"                                \"space\": \"dhcp6\"\n"
-"                            }\n"
-"                        ],\n"
-"                        \"prefixes\": [ \"2001:db8:3:2::/96\" ]\n"
-"                    }\n"
-"                ],\n"
+"                \"reservations\": [ ],\n"
 "                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8:3::/64\",\n"
+"                \"subnet\": \"2001:db8::/64\",\n"
 "                \"t1-percent\": 0.5,\n"
 "                \"t2-percent\": 0.8,\n"
 "                \"valid-lifetime\": 4000\n"
@@ -7230,7 +7908,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 37
+    // CONFIGURATION 41
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -7244,14 +7922,14 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"ddns-update-on-renew\": false,\n"
 "        \"decline-probation-period\": 86400,\n"
 "        \"dhcp-ddns\": {\n"
-"            \"enable-updates\": false,\n"
-"            \"max-queue-size\": 1024,\n"
+"            \"enable-updates\": true,\n"
+"            \"max-queue-size\": 2048,\n"
 "            \"ncr-format\": \"JSON\",\n"
 "            \"ncr-protocol\": \"UDP\",\n"
-"            \"sender-ip\": \"0.0.0.0\",\n"
-"            \"sender-port\": 0,\n"
-"            \"server-ip\": \"127.0.0.1\",\n"
-"            \"server-port\": 53001\n"
+"            \"sender-ip\": \"3001::2\",\n"
+"            \"sender-port\": 778,\n"
+"            \"server-ip\": \"3001::1\",\n"
+"            \"server-port\": 777\n"
 "        },\n"
 "        \"dhcp-queue-control\": {\n"
 "            \"capacity\": 64,\n"
@@ -7287,17 +7965,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"thread-pool-size\": 0\n"
 "        },\n"
 "        \"option-data\": [ ],\n"
-"        \"option-def\": [\n"
-"            {\n"
-"                \"array\": false,\n"
-"                \"code\": 100,\n"
-"                \"encapsulate\": \"\",\n"
-"                \"name\": \"foo\",\n"
-"                \"record-types\": \"\",\n"
-"                \"space\": \"isc\",\n"
-"                \"type\": \"uint32\"\n"
-"            }\n"
-"        ],\n"
+"        \"option-def\": [ ],\n"
 "        \"parked-packet-limit\": 256,\n"
 "        \"pd-allocator\": \"iterative\",\n"
 "        \"preferred-lifetime\": 3000,\n"
@@ -7329,7 +7997,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            {\n"
 "                \"allocator\": \"iterative\",\n"
 "                \"calculate-tee-times\": true,\n"
-"                \"id\": 234,\n"
+"                \"id\": 1,\n"
 "                \"max-preferred-lifetime\": 3000,\n"
 "                \"max-valid-lifetime\": 4000,\n"
 "                \"min-preferred-lifetime\": 3000,\n"
@@ -7337,7 +8005,12 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"option-data\": [ ],\n"
 "                \"pd-allocator\": \"iterative\",\n"
 "                \"pd-pools\": [ ],\n"
-"                \"pools\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8:1::/80\"\n"
+"                    }\n"
+"                ],\n"
 "                \"preferred-lifetime\": 3000,\n"
 "                \"rapid-commit\": false,\n"
 "                \"rebind-timer\": 2000,\n"
@@ -7345,28 +8018,9 @@ const char* UNPARSED_CONFIGS[] = {
 "                    \"ip-addresses\": [ ]\n"
 "                },\n"
 "                \"renew-timer\": 1000,\n"
-"                \"reservations\": [\n"
-"                    {\n"
-"                        \"client-classes\": [ ],\n"
-"                        \"duid\": \"01:02:03:04:05:06:07:08:09:0a\",\n"
-"                        \"hostname\": \"\",\n"
-"                        \"ip-addresses\": [ \"2001:db8:2::1234\" ],\n"
-"                        \"option-data\": [\n"
-"                            {\n"
-"                                \"always-send\": false,\n"
-"                                \"code\": 100,\n"
-"                                \"csv-format\": true,\n"
-"                                \"data\": \"11\",\n"
-"                                \"name\": \"foo\",\n"
-"                                \"never-send\": false,\n"
-"                                \"space\": \"isc\"\n"
-"                            }\n"
-"                        ],\n"
-"                        \"prefixes\": [ ]\n"
-"                    }\n"
-"                ],\n"
+"                \"reservations\": [ ],\n"
 "                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8:2::/64\",\n"
+"                \"subnet\": \"2001:db8:1::/64\",\n"
 "                \"t1-percent\": 0.5,\n"
 "                \"t2-percent\": 0.8,\n"
 "                \"valid-lifetime\": 4000\n"
@@ -7376,7 +8030,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 38
+    // CONFIGURATION 42
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -7426,7 +8080,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"lease-database\": {\n"
 "            \"type\": \"memfile\"\n"
 "        },\n"
-"        \"mac-sources\": [ \"client-link-addr-option\", \"remote-id\", \"subscriber-id\" ],\n"
+"        \"mac-sources\": [ \"any\" ],\n"
 "        \"multi-threading\": {\n"
 "            \"enable-multi-threading\": true,\n"
 "            \"packet-queue-size\": 64,\n"
@@ -7461,102 +8115,187 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"statistic-default-sample-age\": 0,\n"
 "        \"statistic-default-sample-count\": 20,\n"
 "        \"store-extended-info\": false,\n"
-"        \"subnet6\": [ ],\n"
-"        \"t1-percent\": 0.5,\n"
-"        \"t2-percent\": 0.8,\n"
-"        \"valid-lifetime\": 4000\n"
-"    }\n",
-    // CONFIGURATION 39
-"{\n"
-"        \"allocator\": \"iterative\",\n"
-"        \"calculate-tee-times\": true,\n"
-"        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
-"        \"ddns-generated-prefix\": \"myhost\",\n"
-"        \"ddns-override-client-update\": false,\n"
-"        \"ddns-override-no-update\": false,\n"
-"        \"ddns-qualifying-suffix\": \"\",\n"
-"        \"ddns-replace-client-name\": \"never\",\n"
-"        \"ddns-send-updates\": true,\n"
-"        \"ddns-update-on-renew\": false,\n"
-"        \"decline-probation-period\": 86400,\n"
-"        \"dhcp-ddns\": {\n"
-"            \"enable-updates\": false,\n"
-"            \"max-queue-size\": 1024,\n"
-"            \"ncr-format\": \"JSON\",\n"
-"            \"ncr-protocol\": \"UDP\",\n"
-"            \"sender-ip\": \"0.0.0.0\",\n"
-"            \"sender-port\": 0,\n"
-"            \"server-ip\": \"127.0.0.1\",\n"
-"            \"server-port\": 53001\n"
-"        },\n"
-"        \"dhcp-queue-control\": {\n"
-"            \"capacity\": 64,\n"
-"            \"enable-queue\": false,\n"
-"            \"queue-type\": \"kea-ring6\"\n"
-"        },\n"
-"        \"dhcp4o6-port\": 0,\n"
-"        \"early-global-reservations-lookup\": false,\n"
-"        \"expired-leases-processing\": {\n"
-"            \"flush-reclaimed-timer-wait-time\": 25,\n"
-"            \"hold-reclaimed-time\": 3600,\n"
-"            \"max-reclaim-leases\": 100,\n"
-"            \"max-reclaim-time\": 250,\n"
-"            \"reclaim-timer-wait-time\": 10,\n"
-"            \"unwarned-reclaim-cycles\": 5\n"
-"        },\n"
-"        \"hooks-libraries\": [ ],\n"
-"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
-"        \"hostname-char-replacement\": \"\",\n"
-"        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
-"        \"interfaces-config\": {\n"
-"            \"interfaces\": [ \"*\" ],\n"
-"            \"re-detect\": false\n"
-"        },\n"
-"        \"ip-reservations-unique\": true,\n"
-"        \"lease-database\": {\n"
-"            \"type\": \"memfile\"\n"
-"        },\n"
-"        \"mac-sources\": [ \"client-link-addr-option\", \"remote-id\", \"subscriber-id\" ],\n"
-"        \"multi-threading\": {\n"
-"            \"enable-multi-threading\": true,\n"
-"            \"packet-queue-size\": 64,\n"
-"            \"thread-pool-size\": 0\n"
-"        },\n"
-"        \"option-data\": [ ],\n"
-"        \"option-def\": [ ],\n"
-"        \"parked-packet-limit\": 256,\n"
-"        \"pd-allocator\": \"iterative\",\n"
-"        \"preferred-lifetime\": 3000,\n"
-"        \"rebind-timer\": 2000,\n"
-"        \"relay-supplied-options\": [ \"65\" ],\n"
-"        \"renew-timer\": 1000,\n"
-"        \"reservations-global\": false,\n"
-"        \"reservations-in-subnet\": true,\n"
-"        \"reservations-lookup-first\": false,\n"
-"        \"reservations-out-of-pool\": false,\n"
-"        \"sanity-checks\": {\n"
-"            \"extended-info-checks\": \"fix\",\n"
-"            \"lease-checks\": \"warn\"\n"
-"        },\n"
-"        \"server-id\": {\n"
-"            \"enterprise-id\": 0,\n"
-"            \"htype\": 0,\n"
-"            \"identifier\": \"\",\n"
-"            \"persist\": true,\n"
-"            \"time\": 0,\n"
-"            \"type\": \"LLT\"\n"
-"        },\n"
-"        \"server-tag\": \"\",\n"
-"        \"shared-networks\": [ ],\n"
-"        \"statistic-default-sample-age\": 0,\n"
-"        \"statistic-default-sample-count\": 20,\n"
-"        \"store-extended-info\": false,\n"
-"        \"subnet6\": [ ],\n"
+"        \"subnet6\": [\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"id\": 123,\n"
+"                \"max-preferred-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-preferred-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8:1::/80\"\n"
+"                    }\n"
+"                ],\n"
+"                \"preferred-lifetime\": 3000,\n"
+"                \"rapid-commit\": false,\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8:1::/64\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 4000\n"
+"            },\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"id\": 234,\n"
+"                \"max-preferred-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-preferred-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [ ],\n"
+"                \"preferred-lifetime\": 3000,\n"
+"                \"rapid-commit\": false,\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [\n"
+"                    {\n"
+"                        \"client-classes\": [ ],\n"
+"                        \"hostname\": \"\",\n"
+"                        \"hw-address\": \"01:02:03:04:05:06\",\n"
+"                        \"ip-addresses\": [ \"2001:db8:2::abcd\" ],\n"
+"                        \"option-data\": [\n"
+"                            {\n"
+"                                \"always-send\": false,\n"
+"                                \"code\": 23,\n"
+"                                \"csv-format\": true,\n"
+"                                \"data\": \"2001:db8:2::abbc\",\n"
+"                                \"name\": \"dns-servers\",\n"
+"                                \"never-send\": false,\n"
+"                                \"space\": \"dhcp6\"\n"
+"                            },\n"
+"                            {\n"
+"                                \"always-send\": false,\n"
+"                                \"code\": 7,\n"
+"                                \"csv-format\": true,\n"
+"                                \"data\": \"25\",\n"
+"                                \"name\": \"preference\",\n"
+"                                \"never-send\": false,\n"
+"                                \"space\": \"dhcp6\"\n"
+"                            }\n"
+"                        ],\n"
+"                        \"prefixes\": [ ]\n"
+"                    },\n"
+"                    {\n"
+"                        \"client-classes\": [ ],\n"
+"                        \"duid\": \"01:02:03:04:05:06:07:08:09:0a\",\n"
+"                        \"hostname\": \"\",\n"
+"                        \"ip-addresses\": [ \"2001:db8:2::1234\" ],\n"
+"                        \"option-data\": [\n"
+"                            {\n"
+"                                \"always-send\": false,\n"
+"                                \"code\": 23,\n"
+"                                \"csv-format\": true,\n"
+"                                \"data\": \"2001:db8:2::1111\",\n"
+"                                \"name\": \"dns-servers\",\n"
+"                                \"never-send\": false,\n"
+"                                \"space\": \"dhcp6\"\n"
+"                            },\n"
+"                            {\n"
+"                                \"always-send\": false,\n"
+"                                \"code\": 7,\n"
+"                                \"csv-format\": true,\n"
+"                                \"data\": \"11\",\n"
+"                                \"name\": \"preference\",\n"
+"                                \"never-send\": false,\n"
+"                                \"space\": \"dhcp6\"\n"
+"                            }\n"
+"                        ],\n"
+"                        \"prefixes\": [ ]\n"
+"                    }\n"
+"                ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8:2::/64\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 4000\n"
+"            },\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"id\": 542,\n"
+"                \"max-preferred-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-preferred-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [ ],\n"
+"                \"preferred-lifetime\": 3000,\n"
+"                \"rapid-commit\": false,\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [\n"
+"                    {\n"
+"                        \"client-classes\": [ ],\n"
+"                        \"hostname\": \"\",\n"
+"                        \"hw-address\": \"06:05:04:03:02:01\",\n"
+"                        \"ip-addresses\": [ ],\n"
+"                        \"option-data\": [ ],\n"
+"                        \"prefixes\": [ \"2001:db8:3:1::/96\" ]\n"
+"                    },\n"
+"                    {\n"
+"                        \"client-classes\": [ ],\n"
+"                        \"duid\": \"0a:09:08:07:06:05:04:03:02:01\",\n"
+"                        \"hostname\": \"\",\n"
+"                        \"ip-addresses\": [ ],\n"
+"                        \"option-data\": [\n"
+"                            {\n"
+"                                \"always-send\": false,\n"
+"                                \"code\": 23,\n"
+"                                \"csv-format\": true,\n"
+"                                \"data\": \"2001:db8:3::3333\",\n"
+"                                \"name\": \"dns-servers\",\n"
+"                                \"never-send\": false,\n"
+"                                \"space\": \"dhcp6\"\n"
+"                            },\n"
+"                            {\n"
+"                                \"always-send\": false,\n"
+"                                \"code\": 7,\n"
+"                                \"csv-format\": true,\n"
+"                                \"data\": \"33\",\n"
+"                                \"name\": \"preference\",\n"
+"                                \"never-send\": false,\n"
+"                                \"space\": \"dhcp6\"\n"
+"                            }\n"
+"                        ],\n"
+"                        \"prefixes\": [ \"2001:db8:3:2::/96\" ]\n"
+"                    }\n"
+"                ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8:3::/64\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 4000\n"
+"            }\n"
+"        ],\n"
 "        \"t1-percent\": 0.5,\n"
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 40
+    // CONFIGURATION 43
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -7599,7 +8338,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hostname-char-replacement\": \"\",\n"
 "        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ ],\n"
+"            \"interfaces\": [ \"*\" ],\n"
 "            \"re-detect\": false\n"
 "        },\n"
 "        \"ip-reservations-unique\": true,\n"
@@ -7613,7 +8352,17 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"thread-pool-size\": 0\n"
 "        },\n"
 "        \"option-data\": [ ],\n"
-"        \"option-def\": [ ],\n"
+"        \"option-def\": [\n"
+"            {\n"
+"                \"array\": false,\n"
+"                \"code\": 100,\n"
+"                \"encapsulate\": \"\",\n"
+"                \"name\": \"foo\",\n"
+"                \"record-types\": \"\",\n"
+"                \"space\": \"isc\",\n"
+"                \"type\": \"uint32\"\n"
+"            }\n"
+"        ],\n"
 "        \"parked-packet-limit\": 256,\n"
 "        \"pd-allocator\": \"iterative\",\n"
 "        \"preferred-lifetime\": 3000,\n"
@@ -7645,7 +8394,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            {\n"
 "                \"allocator\": \"iterative\",\n"
 "                \"calculate-tee-times\": true,\n"
-"                \"id\": 1,\n"
+"                \"id\": 234,\n"
 "                \"max-preferred-lifetime\": 3000,\n"
 "                \"max-valid-lifetime\": 4000,\n"
 "                \"min-preferred-lifetime\": 3000,\n"
@@ -7653,12 +8402,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"option-data\": [ ],\n"
 "                \"pd-allocator\": \"iterative\",\n"
 "                \"pd-pools\": [ ],\n"
-"                \"pools\": [\n"
-"                    {\n"
-"                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8:1::/64\"\n"
-"                    }\n"
-"                ],\n"
+"                \"pools\": [ ],\n"
 "                \"preferred-lifetime\": 3000,\n"
 "                \"rapid-commit\": false,\n"
 "                \"rebind-timer\": 2000,\n"
@@ -7666,211 +8410,28 @@ const char* UNPARSED_CONFIGS[] = {
 "                    \"ip-addresses\": [ ]\n"
 "                },\n"
 "                \"renew-timer\": 1000,\n"
-"                \"reservations\": [ ],\n"
-"                \"reservations-global\": false,\n"
-"                \"reservations-in-subnet\": true,\n"
-"                \"reservations-out-of-pool\": false,\n"
-"                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8:1::/48\",\n"
-"                \"t1-percent\": 0.5,\n"
-"                \"t2-percent\": 0.8,\n"
-"                \"valid-lifetime\": 4000\n"
-"            },\n"
-"            {\n"
-"                \"allocator\": \"iterative\",\n"
-"                \"calculate-tee-times\": true,\n"
-"                \"id\": 2,\n"
-"                \"max-preferred-lifetime\": 3000,\n"
-"                \"max-valid-lifetime\": 4000,\n"
-"                \"min-preferred-lifetime\": 3000,\n"
-"                \"min-valid-lifetime\": 4000,\n"
-"                \"option-data\": [ ],\n"
-"                \"pd-allocator\": \"iterative\",\n"
-"                \"pd-pools\": [ ],\n"
-"                \"pools\": [\n"
-"                    {\n"
-"                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8:2::/64\"\n"
-"                    }\n"
-"                ],\n"
-"                \"preferred-lifetime\": 3000,\n"
-"                \"rapid-commit\": false,\n"
-"                \"rebind-timer\": 2000,\n"
-"                \"relay\": {\n"
-"                    \"ip-addresses\": [ ]\n"
-"                },\n"
-"                \"renew-timer\": 1000,\n"
-"                \"reservations\": [ ],\n"
-"                \"reservations-global\": false,\n"
-"                \"reservations-in-subnet\": true,\n"
-"                \"reservations-out-of-pool\": true,\n"
-"                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8:2::/48\",\n"
-"                \"t1-percent\": 0.5,\n"
-"                \"t2-percent\": 0.8,\n"
-"                \"valid-lifetime\": 4000\n"
-"            },\n"
-"            {\n"
-"                \"allocator\": \"iterative\",\n"
-"                \"calculate-tee-times\": true,\n"
-"                \"id\": 3,\n"
-"                \"max-preferred-lifetime\": 3000,\n"
-"                \"max-valid-lifetime\": 4000,\n"
-"                \"min-preferred-lifetime\": 3000,\n"
-"                \"min-valid-lifetime\": 4000,\n"
-"                \"option-data\": [ ],\n"
-"                \"pd-allocator\": \"iterative\",\n"
-"                \"pd-pools\": [ ],\n"
-"                \"pools\": [\n"
-"                    {\n"
-"                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8:3::/64\"\n"
-"                    }\n"
-"                ],\n"
-"                \"preferred-lifetime\": 3000,\n"
-"                \"rapid-commit\": false,\n"
-"                \"rebind-timer\": 2000,\n"
-"                \"relay\": {\n"
-"                    \"ip-addresses\": [ ]\n"
-"                },\n"
-"                \"renew-timer\": 1000,\n"
-"                \"reservations\": [ ],\n"
-"                \"reservations-global\": false,\n"
-"                \"reservations-in-subnet\": false,\n"
-"                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8:3::/48\",\n"
-"                \"t1-percent\": 0.5,\n"
-"                \"t2-percent\": 0.8,\n"
-"                \"valid-lifetime\": 4000\n"
-"            },\n"
-"            {\n"
-"                \"allocator\": \"iterative\",\n"
-"                \"calculate-tee-times\": true,\n"
-"                \"id\": 4,\n"
-"                \"max-preferred-lifetime\": 3000,\n"
-"                \"max-valid-lifetime\": 4000,\n"
-"                \"min-preferred-lifetime\": 3000,\n"
-"                \"min-valid-lifetime\": 4000,\n"
-"                \"option-data\": [ ],\n"
-"                \"pd-allocator\": \"iterative\",\n"
-"                \"pd-pools\": [ ],\n"
-"                \"pools\": [\n"
-"                    {\n"
-"                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8:4::/64\"\n"
-"                    }\n"
-"                ],\n"
-"                \"preferred-lifetime\": 3000,\n"
-"                \"rapid-commit\": false,\n"
-"                \"rebind-timer\": 2000,\n"
-"                \"relay\": {\n"
-"                    \"ip-addresses\": [ ]\n"
-"                },\n"
-"                \"renew-timer\": 1000,\n"
-"                \"reservations\": [ ],\n"
-"                \"reservations-global\": true,\n"
-"                \"reservations-in-subnet\": false,\n"
-"                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8:4::/48\",\n"
-"                \"t1-percent\": 0.5,\n"
-"                \"t2-percent\": 0.8,\n"
-"                \"valid-lifetime\": 4000\n"
-"            },\n"
-"            {\n"
-"                \"allocator\": \"iterative\",\n"
-"                \"calculate-tee-times\": true,\n"
-"                \"id\": 5,\n"
-"                \"max-preferred-lifetime\": 3000,\n"
-"                \"max-valid-lifetime\": 4000,\n"
-"                \"min-preferred-lifetime\": 3000,\n"
-"                \"min-valid-lifetime\": 4000,\n"
-"                \"option-data\": [ ],\n"
-"                \"pd-allocator\": \"iterative\",\n"
-"                \"pd-pools\": [ ],\n"
-"                \"pools\": [\n"
-"                    {\n"
-"                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8:5::/64\"\n"
-"                    }\n"
-"                ],\n"
-"                \"preferred-lifetime\": 3000,\n"
-"                \"rapid-commit\": false,\n"
-"                \"rebind-timer\": 2000,\n"
-"                \"relay\": {\n"
-"                    \"ip-addresses\": [ ]\n"
-"                },\n"
-"                \"renew-timer\": 1000,\n"
-"                \"reservations\": [ ],\n"
-"                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8:5::/48\",\n"
-"                \"t1-percent\": 0.5,\n"
-"                \"t2-percent\": 0.8,\n"
-"                \"valid-lifetime\": 4000\n"
-"            },\n"
-"            {\n"
-"                \"allocator\": \"iterative\",\n"
-"                \"calculate-tee-times\": true,\n"
-"                \"id\": 6,\n"
-"                \"max-preferred-lifetime\": 3000,\n"
-"                \"max-valid-lifetime\": 4000,\n"
-"                \"min-preferred-lifetime\": 3000,\n"
-"                \"min-valid-lifetime\": 4000,\n"
-"                \"option-data\": [ ],\n"
-"                \"pd-allocator\": \"iterative\",\n"
-"                \"pd-pools\": [ ],\n"
-"                \"pools\": [\n"
-"                    {\n"
-"                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8:6::/64\"\n"
-"                    }\n"
-"                ],\n"
-"                \"preferred-lifetime\": 3000,\n"
-"                \"rapid-commit\": false,\n"
-"                \"rebind-timer\": 2000,\n"
-"                \"relay\": {\n"
-"                    \"ip-addresses\": [ ]\n"
-"                },\n"
-"                \"renew-timer\": 1000,\n"
-"                \"reservations\": [ ],\n"
-"                \"reservations-global\": true,\n"
-"                \"reservations-in-subnet\": true,\n"
-"                \"reservations-out-of-pool\": false,\n"
-"                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8:6::/48\",\n"
-"                \"t1-percent\": 0.5,\n"
-"                \"t2-percent\": 0.8,\n"
-"                \"valid-lifetime\": 4000\n"
-"            },\n"
-"            {\n"
-"                \"allocator\": \"iterative\",\n"
-"                \"calculate-tee-times\": true,\n"
-"                \"id\": 7,\n"
-"                \"max-preferred-lifetime\": 3000,\n"
-"                \"max-valid-lifetime\": 4000,\n"
-"                \"min-preferred-lifetime\": 3000,\n"
-"                \"min-valid-lifetime\": 4000,\n"
-"                \"option-data\": [ ],\n"
-"                \"pd-allocator\": \"iterative\",\n"
-"                \"pd-pools\": [ ],\n"
-"                \"pools\": [\n"
+"                \"reservations\": [\n"
 "                    {\n"
-"                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8:7::/64\"\n"
+"                        \"client-classes\": [ ],\n"
+"                        \"duid\": \"01:02:03:04:05:06:07:08:09:0a\",\n"
+"                        \"hostname\": \"\",\n"
+"                        \"ip-addresses\": [ \"2001:db8:2::1234\" ],\n"
+"                        \"option-data\": [\n"
+"                            {\n"
+"                                \"always-send\": false,\n"
+"                                \"code\": 100,\n"
+"                                \"csv-format\": true,\n"
+"                                \"data\": \"11\",\n"
+"                                \"name\": \"foo\",\n"
+"                                \"never-send\": false,\n"
+"                                \"space\": \"isc\"\n"
+"                            }\n"
+"                        ],\n"
+"                        \"prefixes\": [ ]\n"
 "                    }\n"
 "                ],\n"
-"                \"preferred-lifetime\": 3000,\n"
-"                \"rapid-commit\": false,\n"
-"                \"rebind-timer\": 2000,\n"
-"                \"relay\": {\n"
-"                    \"ip-addresses\": [ ]\n"
-"                },\n"
-"                \"renew-timer\": 1000,\n"
-"                \"reservations\": [ ],\n"
-"                \"reservations-global\": true,\n"
-"                \"reservations-in-subnet\": true,\n"
-"                \"reservations-out-of-pool\": true,\n"
 "                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8:7::/48\",\n"
+"                \"subnet\": \"2001:db8:2::/64\",\n"
 "                \"t1-percent\": 0.5,\n"
 "                \"t2-percent\": 0.8,\n"
 "                \"valid-lifetime\": 4000\n"
@@ -7878,12 +8439,1124 @@ const char* UNPARSED_CONFIGS[] = {
 "        ],\n"
 "        \"t1-percent\": 0.5,\n"
 "        \"t2-percent\": 0.8,\n"
-"        \"valid-lifetime\": 4000\n"
+"        \"valid-lifetime\": 4000\n"
+"    }\n",
+    // CONFIGURATION 44
+"{\n"
+"        \"allocator\": \"iterative\",\n"
+"        \"calculate-tee-times\": true,\n"
+"        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
+"        \"ddns-generated-prefix\": \"myhost\",\n"
+"        \"ddns-override-client-update\": false,\n"
+"        \"ddns-override-no-update\": false,\n"
+"        \"ddns-qualifying-suffix\": \"\",\n"
+"        \"ddns-replace-client-name\": \"never\",\n"
+"        \"ddns-send-updates\": true,\n"
+"        \"ddns-update-on-renew\": false,\n"
+"        \"decline-probation-period\": 86400,\n"
+"        \"dhcp-ddns\": {\n"
+"            \"enable-updates\": false,\n"
+"            \"max-queue-size\": 1024,\n"
+"            \"ncr-format\": \"JSON\",\n"
+"            \"ncr-protocol\": \"UDP\",\n"
+"            \"sender-ip\": \"0.0.0.0\",\n"
+"            \"sender-port\": 0,\n"
+"            \"server-ip\": \"127.0.0.1\",\n"
+"            \"server-port\": 53001\n"
+"        },\n"
+"        \"dhcp-queue-control\": {\n"
+"            \"capacity\": 64,\n"
+"            \"enable-queue\": false,\n"
+"            \"queue-type\": \"kea-ring6\"\n"
+"        },\n"
+"        \"dhcp4o6-port\": 0,\n"
+"        \"early-global-reservations-lookup\": false,\n"
+"        \"expired-leases-processing\": {\n"
+"            \"flush-reclaimed-timer-wait-time\": 25,\n"
+"            \"hold-reclaimed-time\": 3600,\n"
+"            \"max-reclaim-leases\": 100,\n"
+"            \"max-reclaim-time\": 250,\n"
+"            \"reclaim-timer-wait-time\": 10,\n"
+"            \"unwarned-reclaim-cycles\": 5\n"
+"        },\n"
+"        \"hooks-libraries\": [ ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
+"        \"hostname-char-replacement\": \"\",\n"
+"        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"ip-reservations-unique\": true,\n"
+"        \"lease-database\": {\n"
+"            \"type\": \"memfile\"\n"
+"        },\n"
+"        \"mac-sources\": [ \"client-link-addr-option\", \"remote-id\", \"subscriber-id\" ],\n"
+"        \"multi-threading\": {\n"
+"            \"enable-multi-threading\": true,\n"
+"            \"packet-queue-size\": 64,\n"
+"            \"thread-pool-size\": 0\n"
+"        },\n"
+"        \"option-data\": [ ],\n"
+"        \"option-def\": [ ],\n"
+"        \"parked-packet-limit\": 256,\n"
+"        \"pd-allocator\": \"iterative\",\n"
+"        \"preferred-lifetime\": 3000,\n"
+"        \"rebind-timer\": 2000,\n"
+"        \"relay-supplied-options\": [ \"65\" ],\n"
+"        \"renew-timer\": 1000,\n"
+"        \"reservations-global\": false,\n"
+"        \"reservations-in-subnet\": true,\n"
+"        \"reservations-lookup-first\": false,\n"
+"        \"reservations-out-of-pool\": false,\n"
+"        \"sanity-checks\": {\n"
+"            \"extended-info-checks\": \"fix\",\n"
+"            \"lease-checks\": \"warn\"\n"
+"        },\n"
+"        \"server-id\": {\n"
+"            \"enterprise-id\": 0,\n"
+"            \"htype\": 0,\n"
+"            \"identifier\": \"\",\n"
+"            \"persist\": true,\n"
+"            \"time\": 0,\n"
+"            \"type\": \"LLT\"\n"
+"        },\n"
+"        \"server-tag\": \"\",\n"
+"        \"shared-networks\": [ ],\n"
+"        \"statistic-default-sample-age\": 0,\n"
+"        \"statistic-default-sample-count\": 20,\n"
+"        \"store-extended-info\": false,\n"
+"        \"subnet6\": [ ],\n"
+"        \"t1-percent\": 0.5,\n"
+"        \"t2-percent\": 0.8,\n"
+"        \"valid-lifetime\": 4000\n"
+"    }\n",
+    // CONFIGURATION 45
+"{\n"
+"        \"allocator\": \"iterative\",\n"
+"        \"calculate-tee-times\": true,\n"
+"        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
+"        \"ddns-generated-prefix\": \"myhost\",\n"
+"        \"ddns-override-client-update\": false,\n"
+"        \"ddns-override-no-update\": false,\n"
+"        \"ddns-qualifying-suffix\": \"\",\n"
+"        \"ddns-replace-client-name\": \"never\",\n"
+"        \"ddns-send-updates\": true,\n"
+"        \"ddns-update-on-renew\": false,\n"
+"        \"decline-probation-period\": 86400,\n"
+"        \"dhcp-ddns\": {\n"
+"            \"enable-updates\": false,\n"
+"            \"max-queue-size\": 1024,\n"
+"            \"ncr-format\": \"JSON\",\n"
+"            \"ncr-protocol\": \"UDP\",\n"
+"            \"sender-ip\": \"0.0.0.0\",\n"
+"            \"sender-port\": 0,\n"
+"            \"server-ip\": \"127.0.0.1\",\n"
+"            \"server-port\": 53001\n"
+"        },\n"
+"        \"dhcp-queue-control\": {\n"
+"            \"capacity\": 64,\n"
+"            \"enable-queue\": false,\n"
+"            \"queue-type\": \"kea-ring6\"\n"
+"        },\n"
+"        \"dhcp4o6-port\": 0,\n"
+"        \"early-global-reservations-lookup\": false,\n"
+"        \"expired-leases-processing\": {\n"
+"            \"flush-reclaimed-timer-wait-time\": 25,\n"
+"            \"hold-reclaimed-time\": 3600,\n"
+"            \"max-reclaim-leases\": 100,\n"
+"            \"max-reclaim-time\": 250,\n"
+"            \"reclaim-timer-wait-time\": 10,\n"
+"            \"unwarned-reclaim-cycles\": 5\n"
+"        },\n"
+"        \"hooks-libraries\": [ ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
+"        \"hostname-char-replacement\": \"\",\n"
+"        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"ip-reservations-unique\": true,\n"
+"        \"lease-database\": {\n"
+"            \"type\": \"memfile\"\n"
+"        },\n"
+"        \"mac-sources\": [ \"client-link-addr-option\", \"remote-id\", \"subscriber-id\" ],\n"
+"        \"multi-threading\": {\n"
+"            \"enable-multi-threading\": true,\n"
+"            \"packet-queue-size\": 64,\n"
+"            \"thread-pool-size\": 0\n"
+"        },\n"
+"        \"option-data\": [ ],\n"
+"        \"option-def\": [ ],\n"
+"        \"parked-packet-limit\": 256,\n"
+"        \"pd-allocator\": \"iterative\",\n"
+"        \"preferred-lifetime\": 3000,\n"
+"        \"rebind-timer\": 2000,\n"
+"        \"relay-supplied-options\": [ \"65\" ],\n"
+"        \"renew-timer\": 1000,\n"
+"        \"reservations-global\": false,\n"
+"        \"reservations-in-subnet\": true,\n"
+"        \"reservations-lookup-first\": false,\n"
+"        \"reservations-out-of-pool\": false,\n"
+"        \"sanity-checks\": {\n"
+"            \"extended-info-checks\": \"fix\",\n"
+"            \"lease-checks\": \"warn\"\n"
+"        },\n"
+"        \"server-id\": {\n"
+"            \"enterprise-id\": 0,\n"
+"            \"htype\": 0,\n"
+"            \"identifier\": \"\",\n"
+"            \"persist\": true,\n"
+"            \"time\": 0,\n"
+"            \"type\": \"LLT\"\n"
+"        },\n"
+"        \"server-tag\": \"\",\n"
+"        \"shared-networks\": [ ],\n"
+"        \"statistic-default-sample-age\": 0,\n"
+"        \"statistic-default-sample-count\": 20,\n"
+"        \"store-extended-info\": false,\n"
+"        \"subnet6\": [ ],\n"
+"        \"t1-percent\": 0.5,\n"
+"        \"t2-percent\": 0.8,\n"
+"        \"valid-lifetime\": 4000\n"
+"    }\n",
+    // CONFIGURATION 46
+"{\n"
+"        \"allocator\": \"iterative\",\n"
+"        \"calculate-tee-times\": true,\n"
+"        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
+"        \"ddns-generated-prefix\": \"myhost\",\n"
+"        \"ddns-override-client-update\": false,\n"
+"        \"ddns-override-no-update\": false,\n"
+"        \"ddns-qualifying-suffix\": \"\",\n"
+"        \"ddns-replace-client-name\": \"never\",\n"
+"        \"ddns-send-updates\": true,\n"
+"        \"ddns-update-on-renew\": false,\n"
+"        \"decline-probation-period\": 86400,\n"
+"        \"dhcp-ddns\": {\n"
+"            \"enable-updates\": false,\n"
+"            \"max-queue-size\": 1024,\n"
+"            \"ncr-format\": \"JSON\",\n"
+"            \"ncr-protocol\": \"UDP\",\n"
+"            \"sender-ip\": \"0.0.0.0\",\n"
+"            \"sender-port\": 0,\n"
+"            \"server-ip\": \"127.0.0.1\",\n"
+"            \"server-port\": 53001\n"
+"        },\n"
+"        \"dhcp-queue-control\": {\n"
+"            \"capacity\": 64,\n"
+"            \"enable-queue\": false,\n"
+"            \"queue-type\": \"kea-ring6\"\n"
+"        },\n"
+"        \"dhcp4o6-port\": 0,\n"
+"        \"early-global-reservations-lookup\": false,\n"
+"        \"expired-leases-processing\": {\n"
+"            \"flush-reclaimed-timer-wait-time\": 25,\n"
+"            \"hold-reclaimed-time\": 3600,\n"
+"            \"max-reclaim-leases\": 100,\n"
+"            \"max-reclaim-time\": 250,\n"
+"            \"reclaim-timer-wait-time\": 10,\n"
+"            \"unwarned-reclaim-cycles\": 5\n"
+"        },\n"
+"        \"hooks-libraries\": [ ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
+"        \"hostname-char-replacement\": \"\",\n"
+"        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"ip-reservations-unique\": true,\n"
+"        \"lease-database\": {\n"
+"            \"type\": \"memfile\"\n"
+"        },\n"
+"        \"mac-sources\": [ \"any\" ],\n"
+"        \"multi-threading\": {\n"
+"            \"enable-multi-threading\": true,\n"
+"            \"packet-queue-size\": 64,\n"
+"            \"thread-pool-size\": 0\n"
+"        },\n"
+"        \"option-data\": [ ],\n"
+"        \"option-def\": [ ],\n"
+"        \"parked-packet-limit\": 256,\n"
+"        \"pd-allocator\": \"iterative\",\n"
+"        \"preferred-lifetime\": 3000,\n"
+"        \"rebind-timer\": 2000,\n"
+"        \"relay-supplied-options\": [ \"65\" ],\n"
+"        \"renew-timer\": 1000,\n"
+"        \"reservations-global\": false,\n"
+"        \"reservations-in-subnet\": true,\n"
+"        \"reservations-lookup-first\": false,\n"
+"        \"reservations-out-of-pool\": false,\n"
+"        \"sanity-checks\": {\n"
+"            \"extended-info-checks\": \"fix\",\n"
+"            \"lease-checks\": \"warn\"\n"
+"        },\n"
+"        \"server-id\": {\n"
+"            \"enterprise-id\": 0,\n"
+"            \"htype\": 0,\n"
+"            \"identifier\": \"\",\n"
+"            \"persist\": true,\n"
+"            \"time\": 0,\n"
+"            \"type\": \"LLT\"\n"
+"        },\n"
+"        \"server-tag\": \"\",\n"
+"        \"shared-networks\": [ ],\n"
+"        \"statistic-default-sample-age\": 0,\n"
+"        \"statistic-default-sample-count\": 20,\n"
+"        \"store-extended-info\": false,\n"
+"        \"subnet6\": [\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"id\": 1,\n"
+"                \"max-preferred-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-preferred-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8:1::/64\"\n"
+"                    }\n"
+"                ],\n"
+"                \"preferred-lifetime\": 3000,\n"
+"                \"rapid-commit\": false,\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"reservations-global\": false,\n"
+"                \"reservations-in-subnet\": true,\n"
+"                \"reservations-out-of-pool\": false,\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8:1::/48\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 4000\n"
+"            },\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"id\": 2,\n"
+"                \"max-preferred-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-preferred-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8:2::/64\"\n"
+"                    }\n"
+"                ],\n"
+"                \"preferred-lifetime\": 3000,\n"
+"                \"rapid-commit\": false,\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"reservations-global\": false,\n"
+"                \"reservations-in-subnet\": true,\n"
+"                \"reservations-out-of-pool\": true,\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8:2::/48\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 4000\n"
+"            },\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"id\": 3,\n"
+"                \"max-preferred-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-preferred-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8:3::/64\"\n"
+"                    }\n"
+"                ],\n"
+"                \"preferred-lifetime\": 3000,\n"
+"                \"rapid-commit\": false,\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"reservations-global\": false,\n"
+"                \"reservations-in-subnet\": false,\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8:3::/48\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 4000\n"
+"            },\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"id\": 4,\n"
+"                \"max-preferred-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-preferred-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8:4::/64\"\n"
+"                    }\n"
+"                ],\n"
+"                \"preferred-lifetime\": 3000,\n"
+"                \"rapid-commit\": false,\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"reservations-global\": true,\n"
+"                \"reservations-in-subnet\": false,\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8:4::/48\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 4000\n"
+"            },\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"id\": 5,\n"
+"                \"max-preferred-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-preferred-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8:5::/64\"\n"
+"                    }\n"
+"                ],\n"
+"                \"preferred-lifetime\": 3000,\n"
+"                \"rapid-commit\": false,\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8:5::/48\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 4000\n"
+"            },\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"id\": 6,\n"
+"                \"max-preferred-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-preferred-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8:6::/64\"\n"
+"                    }\n"
+"                ],\n"
+"                \"preferred-lifetime\": 3000,\n"
+"                \"rapid-commit\": false,\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"reservations-global\": true,\n"
+"                \"reservations-in-subnet\": true,\n"
+"                \"reservations-out-of-pool\": false,\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8:6::/48\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 4000\n"
+"            },\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"id\": 7,\n"
+"                \"max-preferred-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-preferred-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8:7::/64\"\n"
+"                    }\n"
+"                ],\n"
+"                \"preferred-lifetime\": 3000,\n"
+"                \"rapid-commit\": false,\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"reservations-global\": true,\n"
+"                \"reservations-in-subnet\": true,\n"
+"                \"reservations-out-of-pool\": true,\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8:7::/48\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 4000\n"
+"            }\n"
+"        ],\n"
+"        \"t1-percent\": 0.5,\n"
+"        \"t2-percent\": 0.8,\n"
+"        \"valid-lifetime\": 4000\n"
+"    }\n",
+    // CONFIGURATION 47
+"{\n"
+"        \"allocator\": \"iterative\",\n"
+"        \"calculate-tee-times\": true,\n"
+"        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
+"        \"ddns-generated-prefix\": \"myhost\",\n"
+"        \"ddns-override-client-update\": false,\n"
+"        \"ddns-override-no-update\": false,\n"
+"        \"ddns-qualifying-suffix\": \"\",\n"
+"        \"ddns-replace-client-name\": \"never\",\n"
+"        \"ddns-send-updates\": true,\n"
+"        \"ddns-update-on-renew\": false,\n"
+"        \"decline-probation-period\": 86400,\n"
+"        \"dhcp-ddns\": {\n"
+"            \"enable-updates\": false,\n"
+"            \"max-queue-size\": 1024,\n"
+"            \"ncr-format\": \"JSON\",\n"
+"            \"ncr-protocol\": \"UDP\",\n"
+"            \"sender-ip\": \"0.0.0.0\",\n"
+"            \"sender-port\": 0,\n"
+"            \"server-ip\": \"127.0.0.1\",\n"
+"            \"server-port\": 53001\n"
+"        },\n"
+"        \"dhcp-queue-control\": {\n"
+"            \"capacity\": 64,\n"
+"            \"enable-queue\": false,\n"
+"            \"queue-type\": \"kea-ring6\"\n"
+"        },\n"
+"        \"dhcp4o6-port\": 0,\n"
+"        \"early-global-reservations-lookup\": false,\n"
+"        \"expired-leases-processing\": {\n"
+"            \"flush-reclaimed-timer-wait-time\": 25,\n"
+"            \"hold-reclaimed-time\": 3600,\n"
+"            \"max-reclaim-leases\": 100,\n"
+"            \"max-reclaim-time\": 250,\n"
+"            \"reclaim-timer-wait-time\": 10,\n"
+"            \"unwarned-reclaim-cycles\": 5\n"
+"        },\n"
+"        \"hooks-libraries\": [ ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
+"        \"hostname-char-replacement\": \"\",\n"
+"        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"ip-reservations-unique\": true,\n"
+"        \"lease-database\": {\n"
+"            \"type\": \"memfile\"\n"
+"        },\n"
+"        \"mac-sources\": [ \"any\" ],\n"
+"        \"multi-threading\": {\n"
+"            \"enable-multi-threading\": true,\n"
+"            \"packet-queue-size\": 64,\n"
+"            \"thread-pool-size\": 0\n"
+"        },\n"
+"        \"option-data\": [ ],\n"
+"        \"option-def\": [ ],\n"
+"        \"parked-packet-limit\": 256,\n"
+"        \"pd-allocator\": \"iterative\",\n"
+"        \"preferred-lifetime\": 3000,\n"
+"        \"rebind-timer\": 2000,\n"
+"        \"relay-supplied-options\": [ \"65\" ],\n"
+"        \"renew-timer\": 1000,\n"
+"        \"reservations-global\": false,\n"
+"        \"reservations-in-subnet\": true,\n"
+"        \"reservations-lookup-first\": false,\n"
+"        \"reservations-out-of-pool\": true,\n"
+"        \"sanity-checks\": {\n"
+"            \"extended-info-checks\": \"fix\",\n"
+"            \"lease-checks\": \"warn\"\n"
+"        },\n"
+"        \"server-id\": {\n"
+"            \"enterprise-id\": 0,\n"
+"            \"htype\": 0,\n"
+"            \"identifier\": \"\",\n"
+"            \"persist\": true,\n"
+"            \"time\": 0,\n"
+"            \"type\": \"LLT\"\n"
+"        },\n"
+"        \"server-tag\": \"\",\n"
+"        \"shared-networks\": [ ],\n"
+"        \"statistic-default-sample-age\": 0,\n"
+"        \"statistic-default-sample-count\": 20,\n"
+"        \"store-extended-info\": false,\n"
+"        \"subnet6\": [\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"id\": 1,\n"
+"                \"max-preferred-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-preferred-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8:1::/64\"\n"
+"                    }\n"
+"                ],\n"
+"                \"preferred-lifetime\": 3000,\n"
+"                \"rapid-commit\": false,\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"reservations-global\": false,\n"
+"                \"reservations-in-subnet\": true,\n"
+"                \"reservations-out-of-pool\": false,\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8:1::/48\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 4000\n"
+"            },\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"id\": 2,\n"
+"                \"max-preferred-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-preferred-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8:2::/64\"\n"
+"                    }\n"
+"                ],\n"
+"                \"preferred-lifetime\": 3000,\n"
+"                \"rapid-commit\": false,\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8:2::/48\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 4000\n"
+"            }\n"
+"        ],\n"
+"        \"t1-percent\": 0.5,\n"
+"        \"t2-percent\": 0.8,\n"
+"        \"valid-lifetime\": 4000\n"
+"    }\n",
+    // CONFIGURATION 48
+"{\n"
+"        \"allocator\": \"iterative\",\n"
+"        \"calculate-tee-times\": true,\n"
+"        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
+"        \"ddns-generated-prefix\": \"myhost\",\n"
+"        \"ddns-override-client-update\": false,\n"
+"        \"ddns-override-no-update\": false,\n"
+"        \"ddns-qualifying-suffix\": \"\",\n"
+"        \"ddns-replace-client-name\": \"never\",\n"
+"        \"ddns-send-updates\": true,\n"
+"        \"ddns-update-on-renew\": false,\n"
+"        \"decline-probation-period\": 86400,\n"
+"        \"dhcp-ddns\": {\n"
+"            \"enable-updates\": false,\n"
+"            \"max-queue-size\": 1024,\n"
+"            \"ncr-format\": \"JSON\",\n"
+"            \"ncr-protocol\": \"UDP\",\n"
+"            \"sender-ip\": \"0.0.0.0\",\n"
+"            \"sender-port\": 0,\n"
+"            \"server-ip\": \"127.0.0.1\",\n"
+"            \"server-port\": 53001\n"
+"        },\n"
+"        \"dhcp-queue-control\": {\n"
+"            \"capacity\": 64,\n"
+"            \"enable-queue\": false,\n"
+"            \"queue-type\": \"kea-ring6\"\n"
+"        },\n"
+"        \"dhcp4o6-port\": 0,\n"
+"        \"early-global-reservations-lookup\": false,\n"
+"        \"expired-leases-processing\": {\n"
+"            \"flush-reclaimed-timer-wait-time\": 25,\n"
+"            \"hold-reclaimed-time\": 3600,\n"
+"            \"max-reclaim-leases\": 100,\n"
+"            \"max-reclaim-time\": 250,\n"
+"            \"reclaim-timer-wait-time\": 10,\n"
+"            \"unwarned-reclaim-cycles\": 5\n"
+"        },\n"
+"        \"hooks-libraries\": [ ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
+"        \"hostname-char-replacement\": \"\",\n"
+"        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"ip-reservations-unique\": true,\n"
+"        \"lease-database\": {\n"
+"            \"type\": \"memfile\"\n"
+"        },\n"
+"        \"mac-sources\": [ \"any\" ],\n"
+"        \"multi-threading\": {\n"
+"            \"enable-multi-threading\": true,\n"
+"            \"packet-queue-size\": 64,\n"
+"            \"thread-pool-size\": 0\n"
+"        },\n"
+"        \"option-data\": [ ],\n"
+"        \"option-def\": [ ],\n"
+"        \"parked-packet-limit\": 256,\n"
+"        \"pd-allocator\": \"iterative\",\n"
+"        \"relay-supplied-options\": [ \"65\" ],\n"
+"        \"reservations-global\": false,\n"
+"        \"reservations-in-subnet\": true,\n"
+"        \"reservations-lookup-first\": false,\n"
+"        \"reservations-out-of-pool\": false,\n"
+"        \"sanity-checks\": {\n"
+"            \"extended-info-checks\": \"fix\",\n"
+"            \"lease-checks\": \"warn\"\n"
+"        },\n"
+"        \"server-id\": {\n"
+"            \"enterprise-id\": 0,\n"
+"            \"htype\": 0,\n"
+"            \"identifier\": \"\",\n"
+"            \"persist\": true,\n"
+"            \"time\": 0,\n"
+"            \"type\": \"LLT\"\n"
+"        },\n"
+"        \"server-tag\": \"\",\n"
+"        \"shared-networks\": [ ],\n"
+"        \"statistic-default-sample-age\": 0,\n"
+"        \"statistic-default-sample-count\": 20,\n"
+"        \"store-extended-info\": false,\n"
+"        \"subnet6\": [ ],\n"
+"        \"t1-percent\": 0.5,\n"
+"        \"t2-percent\": 0.8,\n"
+"        \"valid-lifetime\": 7200\n"
+"    }\n",
+    // CONFIGURATION 49
+"{\n"
+"        \"allocator\": \"iterative\",\n"
+"        \"calculate-tee-times\": true,\n"
+"        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
+"        \"ddns-generated-prefix\": \"myhost\",\n"
+"        \"ddns-override-client-update\": false,\n"
+"        \"ddns-override-no-update\": false,\n"
+"        \"ddns-qualifying-suffix\": \"\",\n"
+"        \"ddns-replace-client-name\": \"never\",\n"
+"        \"ddns-send-updates\": true,\n"
+"        \"ddns-update-on-renew\": false,\n"
+"        \"decline-probation-period\": 86400,\n"
+"        \"dhcp-ddns\": {\n"
+"            \"enable-updates\": false,\n"
+"            \"max-queue-size\": 1024,\n"
+"            \"ncr-format\": \"JSON\",\n"
+"            \"ncr-protocol\": \"UDP\",\n"
+"            \"sender-ip\": \"0.0.0.0\",\n"
+"            \"sender-port\": 0,\n"
+"            \"server-ip\": \"127.0.0.1\",\n"
+"            \"server-port\": 53001\n"
+"        },\n"
+"        \"dhcp-queue-control\": {\n"
+"            \"capacity\": 64,\n"
+"            \"enable-queue\": false,\n"
+"            \"queue-type\": \"kea-ring6\"\n"
+"        },\n"
+"        \"dhcp4o6-port\": 0,\n"
+"        \"early-global-reservations-lookup\": false,\n"
+"        \"expired-leases-processing\": {\n"
+"            \"flush-reclaimed-timer-wait-time\": 25,\n"
+"            \"hold-reclaimed-time\": 3600,\n"
+"            \"max-reclaim-leases\": 100,\n"
+"            \"max-reclaim-time\": 250,\n"
+"            \"reclaim-timer-wait-time\": 10,\n"
+"            \"unwarned-reclaim-cycles\": 5\n"
+"        },\n"
+"        \"hooks-libraries\": [ ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
+"        \"hostname-char-replacement\": \"\",\n"
+"        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"ip-reservations-unique\": true,\n"
+"        \"lease-database\": {\n"
+"            \"type\": \"memfile\"\n"
+"        },\n"
+"        \"mac-sources\": [ \"any\" ],\n"
+"        \"multi-threading\": {\n"
+"            \"enable-multi-threading\": true,\n"
+"            \"packet-queue-size\": 64,\n"
+"            \"thread-pool-size\": 0\n"
+"        },\n"
+"        \"option-data\": [ ],\n"
+"        \"option-def\": [ ],\n"
+"        \"parked-packet-limit\": 256,\n"
+"        \"pd-allocator\": \"iterative\",\n"
+"        \"preferred-lifetime\": 3000,\n"
+"        \"rebind-timer\": 2000,\n"
+"        \"relay-supplied-options\": [ \"23\", \"37\", \"65\" ],\n"
+"        \"renew-timer\": 1000,\n"
+"        \"reservations-global\": false,\n"
+"        \"reservations-in-subnet\": true,\n"
+"        \"reservations-lookup-first\": false,\n"
+"        \"reservations-out-of-pool\": false,\n"
+"        \"sanity-checks\": {\n"
+"            \"extended-info-checks\": \"fix\",\n"
+"            \"lease-checks\": \"warn\"\n"
+"        },\n"
+"        \"server-id\": {\n"
+"            \"enterprise-id\": 0,\n"
+"            \"htype\": 0,\n"
+"            \"identifier\": \"\",\n"
+"            \"persist\": true,\n"
+"            \"time\": 0,\n"
+"            \"type\": \"LLT\"\n"
+"        },\n"
+"        \"server-tag\": \"\",\n"
+"        \"shared-networks\": [ ],\n"
+"        \"statistic-default-sample-age\": 0,\n"
+"        \"statistic-default-sample-count\": 20,\n"
+"        \"store-extended-info\": false,\n"
+"        \"subnet6\": [ ],\n"
+"        \"t1-percent\": 0.5,\n"
+"        \"t2-percent\": 0.8,\n"
+"        \"valid-lifetime\": 4000\n"
+"    }\n",
+    // CONFIGURATION 50
+"{\n"
+"        \"allocator\": \"iterative\",\n"
+"        \"calculate-tee-times\": true,\n"
+"        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
+"        \"ddns-generated-prefix\": \"myhost\",\n"
+"        \"ddns-override-client-update\": false,\n"
+"        \"ddns-override-no-update\": false,\n"
+"        \"ddns-qualifying-suffix\": \"\",\n"
+"        \"ddns-replace-client-name\": \"never\",\n"
+"        \"ddns-send-updates\": true,\n"
+"        \"ddns-update-on-renew\": false,\n"
+"        \"decline-probation-period\": 86400,\n"
+"        \"dhcp-ddns\": {\n"
+"            \"enable-updates\": false,\n"
+"            \"max-queue-size\": 1024,\n"
+"            \"ncr-format\": \"JSON\",\n"
+"            \"ncr-protocol\": \"UDP\",\n"
+"            \"sender-ip\": \"0.0.0.0\",\n"
+"            \"sender-port\": 0,\n"
+"            \"server-ip\": \"127.0.0.1\",\n"
+"            \"server-port\": 53001\n"
+"        },\n"
+"        \"dhcp-queue-control\": {\n"
+"            \"capacity\": 64,\n"
+"            \"enable-queue\": false,\n"
+"            \"queue-type\": \"kea-ring6\"\n"
+"        },\n"
+"        \"dhcp4o6-port\": 0,\n"
+"        \"early-global-reservations-lookup\": false,\n"
+"        \"expired-leases-processing\": {\n"
+"            \"flush-reclaimed-timer-wait-time\": 25,\n"
+"            \"hold-reclaimed-time\": 3600,\n"
+"            \"max-reclaim-leases\": 100,\n"
+"            \"max-reclaim-time\": 250,\n"
+"            \"reclaim-timer-wait-time\": 10,\n"
+"            \"unwarned-reclaim-cycles\": 5\n"
+"        },\n"
+"        \"hooks-libraries\": [ ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
+"        \"hostname-char-replacement\": \"\",\n"
+"        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"ip-reservations-unique\": true,\n"
+"        \"lease-database\": {\n"
+"            \"type\": \"memfile\"\n"
+"        },\n"
+"        \"mac-sources\": [ \"any\" ],\n"
+"        \"multi-threading\": {\n"
+"            \"enable-multi-threading\": true,\n"
+"            \"packet-queue-size\": 64,\n"
+"            \"thread-pool-size\": 0\n"
+"        },\n"
+"        \"option-data\": [ ],\n"
+"        \"option-def\": [ ],\n"
+"        \"parked-packet-limit\": 256,\n"
+"        \"pd-allocator\": \"iterative\",\n"
+"        \"relay-supplied-options\": [ \"65\" ],\n"
+"        \"reservations-global\": false,\n"
+"        \"reservations-in-subnet\": true,\n"
+"        \"reservations-lookup-first\": false,\n"
+"        \"reservations-out-of-pool\": false,\n"
+"        \"sanity-checks\": {\n"
+"            \"extended-info-checks\": \"fix\",\n"
+"            \"lease-checks\": \"warn\"\n"
+"        },\n"
+"        \"server-id\": {\n"
+"            \"enterprise-id\": 0,\n"
+"            \"htype\": 0,\n"
+"            \"identifier\": \"\",\n"
+"            \"persist\": true,\n"
+"            \"time\": 0,\n"
+"            \"type\": \"LLT\"\n"
+"        },\n"
+"        \"server-tag\": \"\",\n"
+"        \"shared-networks\": [ ],\n"
+"        \"statistic-default-sample-age\": 0,\n"
+"        \"statistic-default-sample-count\": 20,\n"
+"        \"store-extended-info\": false,\n"
+"        \"subnet6\": [ ],\n"
+"        \"t1-percent\": 0.5,\n"
+"        \"t2-percent\": 0.8,\n"
+"        \"valid-lifetime\": 7200\n"
+"    }\n",
+    // CONFIGURATION 51
+"{\n"
+"        \"allocator\": \"iterative\",\n"
+"        \"calculate-tee-times\": true,\n"
+"        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
+"        \"ddns-generated-prefix\": \"myhost\",\n"
+"        \"ddns-override-client-update\": false,\n"
+"        \"ddns-override-no-update\": false,\n"
+"        \"ddns-qualifying-suffix\": \"\",\n"
+"        \"ddns-replace-client-name\": \"never\",\n"
+"        \"ddns-send-updates\": true,\n"
+"        \"ddns-update-on-renew\": false,\n"
+"        \"decline-probation-period\": 12345,\n"
+"        \"dhcp-ddns\": {\n"
+"            \"enable-updates\": false,\n"
+"            \"max-queue-size\": 1024,\n"
+"            \"ncr-format\": \"JSON\",\n"
+"            \"ncr-protocol\": \"UDP\",\n"
+"            \"sender-ip\": \"0.0.0.0\",\n"
+"            \"sender-port\": 0,\n"
+"            \"server-ip\": \"127.0.0.1\",\n"
+"            \"server-port\": 53001\n"
+"        },\n"
+"        \"dhcp-queue-control\": {\n"
+"            \"capacity\": 64,\n"
+"            \"enable-queue\": false,\n"
+"            \"queue-type\": \"kea-ring6\"\n"
+"        },\n"
+"        \"dhcp4o6-port\": 0,\n"
+"        \"early-global-reservations-lookup\": false,\n"
+"        \"expired-leases-processing\": {\n"
+"            \"flush-reclaimed-timer-wait-time\": 25,\n"
+"            \"hold-reclaimed-time\": 3600,\n"
+"            \"max-reclaim-leases\": 100,\n"
+"            \"max-reclaim-time\": 250,\n"
+"            \"reclaim-timer-wait-time\": 10,\n"
+"            \"unwarned-reclaim-cycles\": 5\n"
+"        },\n"
+"        \"hooks-libraries\": [ ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
+"        \"hostname-char-replacement\": \"\",\n"
+"        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"ip-reservations-unique\": true,\n"
+"        \"lease-database\": {\n"
+"            \"type\": \"memfile\"\n"
+"        },\n"
+"        \"mac-sources\": [ \"any\" ],\n"
+"        \"multi-threading\": {\n"
+"            \"enable-multi-threading\": true,\n"
+"            \"packet-queue-size\": 64,\n"
+"            \"thread-pool-size\": 0\n"
+"        },\n"
+"        \"option-data\": [ ],\n"
+"        \"option-def\": [ ],\n"
+"        \"parked-packet-limit\": 256,\n"
+"        \"pd-allocator\": \"iterative\",\n"
+"        \"relay-supplied-options\": [ \"65\" ],\n"
+"        \"reservations-global\": false,\n"
+"        \"reservations-in-subnet\": true,\n"
+"        \"reservations-lookup-first\": false,\n"
+"        \"reservations-out-of-pool\": false,\n"
+"        \"sanity-checks\": {\n"
+"            \"extended-info-checks\": \"fix\",\n"
+"            \"lease-checks\": \"warn\"\n"
+"        },\n"
+"        \"server-id\": {\n"
+"            \"enterprise-id\": 0,\n"
+"            \"htype\": 0,\n"
+"            \"identifier\": \"\",\n"
+"            \"persist\": true,\n"
+"            \"time\": 0,\n"
+"            \"type\": \"LLT\"\n"
+"        },\n"
+"        \"server-tag\": \"\",\n"
+"        \"shared-networks\": [ ],\n"
+"        \"statistic-default-sample-age\": 0,\n"
+"        \"statistic-default-sample-count\": 20,\n"
+"        \"store-extended-info\": false,\n"
+"        \"subnet6\": [ ],\n"
+"        \"t1-percent\": 0.5,\n"
+"        \"t2-percent\": 0.8,\n"
+"        \"valid-lifetime\": 7200\n"
+"    }\n",
+    // CONFIGURATION 52
+"{\n"
+"        \"allocator\": \"iterative\",\n"
+"        \"calculate-tee-times\": true,\n"
+"        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
+"        \"ddns-generated-prefix\": \"myhost\",\n"
+"        \"ddns-override-client-update\": false,\n"
+"        \"ddns-override-no-update\": false,\n"
+"        \"ddns-qualifying-suffix\": \"\",\n"
+"        \"ddns-replace-client-name\": \"never\",\n"
+"        \"ddns-send-updates\": true,\n"
+"        \"ddns-update-on-renew\": false,\n"
+"        \"decline-probation-period\": 86400,\n"
+"        \"dhcp-ddns\": {\n"
+"            \"enable-updates\": false,\n"
+"            \"max-queue-size\": 1024,\n"
+"            \"ncr-format\": \"JSON\",\n"
+"            \"ncr-protocol\": \"UDP\",\n"
+"            \"sender-ip\": \"0.0.0.0\",\n"
+"            \"sender-port\": 0,\n"
+"            \"server-ip\": \"127.0.0.1\",\n"
+"            \"server-port\": 53001\n"
+"        },\n"
+"        \"dhcp-queue-control\": {\n"
+"            \"capacity\": 64,\n"
+"            \"enable-queue\": false,\n"
+"            \"queue-type\": \"kea-ring6\"\n"
+"        },\n"
+"        \"dhcp4o6-port\": 0,\n"
+"        \"early-global-reservations-lookup\": false,\n"
+"        \"expired-leases-processing\": {\n"
+"            \"flush-reclaimed-timer-wait-time\": 35,\n"
+"            \"hold-reclaimed-time\": 1800,\n"
+"            \"max-reclaim-leases\": 50,\n"
+"            \"max-reclaim-time\": 100,\n"
+"            \"reclaim-timer-wait-time\": 20,\n"
+"            \"unwarned-reclaim-cycles\": 10\n"
+"        },\n"
+"        \"hooks-libraries\": [ ],\n"
+"        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
+"        \"hostname-char-replacement\": \"\",\n"
+"        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
+"        \"interfaces-config\": {\n"
+"            \"interfaces\": [ \"*\" ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"ip-reservations-unique\": true,\n"
+"        \"lease-database\": {\n"
+"            \"type\": \"memfile\"\n"
+"        },\n"
+"        \"mac-sources\": [ \"any\" ],\n"
+"        \"multi-threading\": {\n"
+"            \"enable-multi-threading\": true,\n"
+"            \"packet-queue-size\": 64,\n"
+"            \"thread-pool-size\": 0\n"
+"        },\n"
+"        \"option-data\": [ ],\n"
+"        \"option-def\": [ ],\n"
+"        \"parked-packet-limit\": 256,\n"
+"        \"pd-allocator\": \"iterative\",\n"
+"        \"relay-supplied-options\": [ \"65\" ],\n"
+"        \"reservations-global\": false,\n"
+"        \"reservations-in-subnet\": true,\n"
+"        \"reservations-lookup-first\": false,\n"
+"        \"reservations-out-of-pool\": false,\n"
+"        \"sanity-checks\": {\n"
+"            \"extended-info-checks\": \"fix\",\n"
+"            \"lease-checks\": \"warn\"\n"
+"        },\n"
+"        \"server-id\": {\n"
+"            \"enterprise-id\": 0,\n"
+"            \"htype\": 0,\n"
+"            \"identifier\": \"\",\n"
+"            \"persist\": true,\n"
+"            \"time\": 0,\n"
+"            \"type\": \"LLT\"\n"
+"        },\n"
+"        \"server-tag\": \"\",\n"
+"        \"shared-networks\": [ ],\n"
+"        \"statistic-default-sample-age\": 0,\n"
+"        \"statistic-default-sample-count\": 20,\n"
+"        \"store-extended-info\": false,\n"
+"        \"subnet6\": [ ],\n"
+"        \"t1-percent\": 0.5,\n"
+"        \"t2-percent\": 0.8,\n"
+"        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 41
+    // CONFIGURATION 53
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
+"        \"client-classes\": [\n"
+"            {\n"
+"                \"name\": \"one\",\n"
+"                \"option-data\": [ ]\n"
+"            },\n"
+"            {\n"
+"                \"name\": \"two\",\n"
+"                \"option-data\": [ ]\n"
+"            },\n"
+"            {\n"
+"                \"name\": \"three\",\n"
+"                \"option-data\": [ ]\n"
+"            }\n"
+"        ],\n"
 "        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
 "        \"ddns-generated-prefix\": \"myhost\",\n"
 "        \"ddns-override-client-update\": false,\n"
@@ -7923,7 +9596,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hostname-char-replacement\": \"\",\n"
 "        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
 "        \"interfaces-config\": {\n"
-"            \"interfaces\": [ ],\n"
+"            \"interfaces\": [ \"*\" ],\n"
 "            \"re-detect\": false\n"
 "        },\n"
 "        \"ip-reservations-unique\": true,\n"
@@ -7947,7 +9620,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"reservations-global\": false,\n"
 "        \"reservations-in-subnet\": true,\n"
 "        \"reservations-lookup-first\": false,\n"
-"        \"reservations-out-of-pool\": true,\n"
+"        \"reservations-out-of-pool\": false,\n"
 "        \"sanity-checks\": {\n"
 "            \"extended-info-checks\": \"fix\",\n"
 "            \"lease-checks\": \"warn\"\n"
@@ -7980,41 +9653,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"pools\": [\n"
 "                    {\n"
 "                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8:1::/64\"\n"
-"                    }\n"
-"                ],\n"
-"                \"preferred-lifetime\": 3000,\n"
-"                \"rapid-commit\": false,\n"
-"                \"rebind-timer\": 2000,\n"
-"                \"relay\": {\n"
-"                    \"ip-addresses\": [ ]\n"
-"                },\n"
-"                \"renew-timer\": 1000,\n"
-"                \"reservations\": [ ],\n"
-"                \"reservations-global\": false,\n"
-"                \"reservations-in-subnet\": true,\n"
-"                \"reservations-out-of-pool\": false,\n"
-"                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8:1::/48\",\n"
-"                \"t1-percent\": 0.5,\n"
-"                \"t2-percent\": 0.8,\n"
-"                \"valid-lifetime\": 4000\n"
-"            },\n"
-"            {\n"
-"                \"allocator\": \"iterative\",\n"
-"                \"calculate-tee-times\": true,\n"
-"                \"id\": 2,\n"
-"                \"max-preferred-lifetime\": 3000,\n"
-"                \"max-valid-lifetime\": 4000,\n"
-"                \"min-preferred-lifetime\": 3000,\n"
-"                \"min-valid-lifetime\": 4000,\n"
-"                \"option-data\": [ ],\n"
-"                \"pd-allocator\": \"iterative\",\n"
-"                \"pd-pools\": [ ],\n"
-"                \"pools\": [\n"
-"                    {\n"
-"                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8:2::/64\"\n"
+"                        \"pool\": \"2001:db8:1::1-2001:db8:1::ffff\"\n"
 "                    }\n"
 "                ],\n"
 "                \"preferred-lifetime\": 3000,\n"
@@ -8026,7 +9665,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"reservations\": [ ],\n"
 "                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8:2::/48\",\n"
+"                \"subnet\": \"2001:db8:1::/64\",\n"
 "                \"t1-percent\": 0.5,\n"
 "                \"t2-percent\": 0.8,\n"
 "                \"valid-lifetime\": 4000\n"
@@ -8036,10 +9675,23 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 42
+    // CONFIGURATION 54
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
+"        \"client-classes\": [\n"
+"            {\n"
+"                \"max-valid-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 1000,\n"
+"                \"name\": \"one\",\n"
+"                \"option-data\": [ ],\n"
+"                \"valid-lifetime\": 2000\n"
+"            },\n"
+"            {\n"
+"                \"name\": \"two\",\n"
+"                \"option-data\": [ ]\n"
+"            }\n"
+"        ],\n"
 "        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
 "        \"ddns-generated-prefix\": \"myhost\",\n"
 "        \"ddns-override-client-update\": false,\n"
@@ -8096,10 +9748,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"option-def\": [ ],\n"
 "        \"parked-packet-limit\": 256,\n"
 "        \"pd-allocator\": \"iterative\",\n"
-"        \"preferred-lifetime\": 3000,\n"
-"        \"rebind-timer\": 2000,\n"
-"        \"relay-supplied-options\": [ \"23\", \"37\", \"65\" ],\n"
-"        \"renew-timer\": 1000,\n"
+"        \"relay-supplied-options\": [ \"65\" ],\n"
 "        \"reservations-global\": false,\n"
 "        \"reservations-in-subnet\": true,\n"
 "        \"reservations-lookup-first\": false,\n"
@@ -8121,15 +9770,57 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"statistic-default-sample-age\": 0,\n"
 "        \"statistic-default-sample-count\": 20,\n"
 "        \"store-extended-info\": false,\n"
-"        \"subnet6\": [ ],\n"
+"        \"subnet6\": [\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"id\": 1,\n"
+"                \"max-valid-lifetime\": 7200,\n"
+"                \"min-valid-lifetime\": 7200,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8::1-2001:db8::ffff\"\n"
+"                    }\n"
+"                ],\n"
+"                \"rapid-commit\": false,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8::/64\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 7200\n"
+"            }\n"
+"        ],\n"
 "        \"t1-percent\": 0.5,\n"
 "        \"t2-percent\": 0.8,\n"
-"        \"valid-lifetime\": 4000\n"
+"        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 43
+    // CONFIGURATION 55
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
+"        \"client-classes\": [\n"
+"            {\n"
+"                \"max-valid-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 1000,\n"
+"                \"name\": \"one\",\n"
+"                \"option-data\": [ ],\n"
+"                \"template-test\": \"''\",\n"
+"                \"valid-lifetime\": 2000\n"
+"            },\n"
+"            {\n"
+"                \"name\": \"two\",\n"
+"                \"option-data\": [ ],\n"
+"                \"template-test\": \"''\"\n"
+"            }\n"
+"        ],\n"
 "        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
 "        \"ddns-generated-prefix\": \"myhost\",\n"
 "        \"ddns-override-client-update\": false,\n"
@@ -8208,12 +9899,39 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"statistic-default-sample-age\": 0,\n"
 "        \"statistic-default-sample-count\": 20,\n"
 "        \"store-extended-info\": false,\n"
-"        \"subnet6\": [ ],\n"
+"        \"subnet6\": [\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"id\": 1,\n"
+"                \"max-valid-lifetime\": 7200,\n"
+"                \"min-valid-lifetime\": 7200,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8::1-2001:db8::ffff\"\n"
+"                    }\n"
+"                ],\n"
+"                \"rapid-commit\": false,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8::/64\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 7200\n"
+"            }\n"
+"        ],\n"
 "        \"t1-percent\": 0.5,\n"
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 44
+    // CONFIGURATION 56
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -8273,7 +9991,10 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"option-def\": [ ],\n"
 "        \"parked-packet-limit\": 256,\n"
 "        \"pd-allocator\": \"iterative\",\n"
+"        \"preferred-lifetime\": 3000,\n"
+"        \"rebind-timer\": 2000,\n"
 "        \"relay-supplied-options\": [ \"65\" ],\n"
+"        \"renew-timer\": 1000,\n"
 "        \"reservations-global\": false,\n"
 "        \"reservations-in-subnet\": true,\n"
 "        \"reservations-lookup-first\": false,\n"
@@ -8295,12 +10016,44 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"statistic-default-sample-age\": 0,\n"
 "        \"statistic-default-sample-count\": 20,\n"
 "        \"store-extended-info\": false,\n"
-"        \"subnet6\": [ ],\n"
+"        \"subnet6\": [\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"id\": 1,\n"
+"                \"max-preferred-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-preferred-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8::/64\"\n"
+"                    }\n"
+"                ],\n"
+"                \"preferred-lifetime\": 3000,\n"
+"                \"rapid-commit\": false,\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8::/32\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 4000\n"
+"            }\n"
+"        ],\n"
 "        \"t1-percent\": 0.5,\n"
 "        \"t2-percent\": 0.8,\n"
-"        \"valid-lifetime\": 7200\n"
+"        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 45
+    // CONFIGURATION 57
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -8312,7 +10065,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"ddns-replace-client-name\": \"never\",\n"
 "        \"ddns-send-updates\": true,\n"
 "        \"ddns-update-on-renew\": false,\n"
-"        \"decline-probation-period\": 12345,\n"
+"        \"decline-probation-period\": 86400,\n"
 "        \"dhcp-ddns\": {\n"
 "            \"enable-updates\": false,\n"
 "            \"max-queue-size\": 1024,\n"
@@ -8360,7 +10113,10 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"option-def\": [ ],\n"
 "        \"parked-packet-limit\": 256,\n"
 "        \"pd-allocator\": \"iterative\",\n"
+"        \"preferred-lifetime\": 3000,\n"
+"        \"rebind-timer\": 2000,\n"
 "        \"relay-supplied-options\": [ \"65\" ],\n"
+"        \"renew-timer\": 1000,\n"
 "        \"reservations-global\": false,\n"
 "        \"reservations-in-subnet\": true,\n"
 "        \"reservations-lookup-first\": false,\n"
@@ -8382,12 +10138,45 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"statistic-default-sample-age\": 0,\n"
 "        \"statistic-default-sample-count\": 20,\n"
 "        \"store-extended-info\": false,\n"
-"        \"subnet6\": [ ],\n"
+"        \"subnet6\": [\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"id\": 1,\n"
+"                \"max-preferred-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-preferred-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8::/64\",\n"
+"                        \"user-context\": { }\n"
+"                    }\n"
+"                ],\n"
+"                \"preferred-lifetime\": 3000,\n"
+"                \"rapid-commit\": false,\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8::/32\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 4000\n"
+"            }\n"
+"        ],\n"
 "        \"t1-percent\": 0.5,\n"
 "        \"t2-percent\": 0.8,\n"
-"        \"valid-lifetime\": 7200\n"
+"        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 46
+    // CONFIGURATION 58
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -8418,12 +10207,12 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"dhcp4o6-port\": 0,\n"
 "        \"early-global-reservations-lookup\": false,\n"
 "        \"expired-leases-processing\": {\n"
-"            \"flush-reclaimed-timer-wait-time\": 35,\n"
-"            \"hold-reclaimed-time\": 1800,\n"
-"            \"max-reclaim-leases\": 50,\n"
-"            \"max-reclaim-time\": 100,\n"
-"            \"reclaim-timer-wait-time\": 20,\n"
-"            \"unwarned-reclaim-cycles\": 10\n"
+"            \"flush-reclaimed-timer-wait-time\": 25,\n"
+"            \"hold-reclaimed-time\": 3600,\n"
+"            \"max-reclaim-leases\": 100,\n"
+"            \"max-reclaim-time\": 250,\n"
+"            \"reclaim-timer-wait-time\": 10,\n"
+"            \"unwarned-reclaim-cycles\": 5\n"
 "        },\n"
 "        \"hooks-libraries\": [ ],\n"
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
@@ -8447,7 +10236,10 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"option-def\": [ ],\n"
 "        \"parked-packet-limit\": 256,\n"
 "        \"pd-allocator\": \"iterative\",\n"
+"        \"preferred-lifetime\": 3000,\n"
+"        \"rebind-timer\": 2000,\n"
 "        \"relay-supplied-options\": [ \"65\" ],\n"
+"        \"renew-timer\": 1000,\n"
 "        \"reservations-global\": false,\n"
 "        \"reservations-in-subnet\": true,\n"
 "        \"reservations-lookup-first\": false,\n"
@@ -8469,29 +10261,53 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"statistic-default-sample-age\": 0,\n"
 "        \"statistic-default-sample-count\": 20,\n"
 "        \"store-extended-info\": false,\n"
-"        \"subnet6\": [ ],\n"
+"        \"subnet6\": [\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"id\": 1,\n"
+"                \"max-preferred-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-preferred-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8::/64\",\n"
+"                        \"user-context\": {\n"
+"                            \"lw4over6-bind-prefix-len\": 56,\n"
+"                            \"lw4over6-sharing-ratio\": 64,\n"
+"                            \"lw4over6-sysports-exclude\": true,\n"
+"                            \"lw4over6-v4-pool\": \"192.0.2.0/24\"\n"
+"                        }\n"
+"                    }\n"
+"                ],\n"
+"                \"preferred-lifetime\": 3000,\n"
+"                \"rapid-commit\": false,\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8::/32\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 4000\n"
+"            }\n"
+"        ],\n"
 "        \"t1-percent\": 0.5,\n"
 "        \"t2-percent\": 0.8,\n"
-"        \"valid-lifetime\": 7200\n"
+"        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 47
+    // CONFIGURATION 59
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
-"        \"client-classes\": [\n"
-"            {\n"
-"                \"name\": \"one\",\n"
-"                \"option-data\": [ ]\n"
-"            },\n"
-"            {\n"
-"                \"name\": \"two\",\n"
-"                \"option-data\": [ ]\n"
-"            },\n"
-"            {\n"
-"                \"name\": \"three\",\n"
-"                \"option-data\": [ ]\n"
-"            }\n"
-"        ],\n"
 "        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
 "        \"ddns-generated-prefix\": \"myhost\",\n"
 "        \"ddns-override-client-update\": false,\n"
@@ -8588,7 +10404,13 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"pools\": [\n"
 "                    {\n"
 "                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8:1::1-2001:db8:1::ffff\"\n"
+"                        \"pool\": \"2001:db8::/64\",\n"
+"                        \"user-context\": {\n"
+"                            \"lw4over6-bind-prefix-len\": 56,\n"
+"                            \"lw4over6-sharing-ratio\": 64,\n"
+"                            \"lw4over6-sysports-exclude\": true,\n"
+"                            \"lw4over6-v4-pool\": \"192.0.2.0/24\"\n"
+"                        }\n"
 "                    }\n"
 "                ],\n"
 "                \"preferred-lifetime\": 3000,\n"
@@ -8600,7 +10422,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"reservations\": [ ],\n"
 "                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8:1::/64\",\n"
+"                \"subnet\": \"2001:db8::/32\",\n"
 "                \"t1-percent\": 0.5,\n"
 "                \"t2-percent\": 0.8,\n"
 "                \"valid-lifetime\": 4000\n"
@@ -8610,7 +10432,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 48
+    // CONFIGURATION 60
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -8710,7 +10532,13 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"pools\": [\n"
 "                    {\n"
 "                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8::/64\"\n"
+"                        \"pool\": \"2001:db8::/64\",\n"
+"                        \"user-context\": {\n"
+"                            \"lw4over6-bind-prefix-len\": 56,\n"
+"                            \"lw4over6-sharing-ratio\": 64,\n"
+"                            \"lw4over6-sysports-exclude\": true,\n"
+"                            \"lw4over6-v4-pool\": \"192.0.2.0/24\"\n"
+"                        }\n"
 "                    }\n"
 "                ],\n"
 "                \"preferred-lifetime\": 3000,\n"
@@ -8732,7 +10560,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 49
+    // CONFIGURATION 61
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -8828,14 +10656,15 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"min-valid-lifetime\": 4000,\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-allocator\": \"iterative\",\n"
-"                \"pd-pools\": [ ],\n"
-"                \"pools\": [\n"
+"                \"pd-pools\": [\n"
 "                    {\n"
+"                        \"delegated-len\": 64,\n"
 "                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8::/64\",\n"
-"                        \"user-context\": { }\n"
+"                        \"prefix\": \"2001:db8::\",\n"
+"                        \"prefix-len\": 56\n"
 "                    }\n"
 "                ],\n"
+"                \"pools\": [ ],\n"
 "                \"preferred-lifetime\": 3000,\n"
 "                \"rapid-commit\": false,\n"
 "                \"rebind-timer\": 2000,\n"
@@ -8855,7 +10684,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 50
+    // CONFIGURATION 62
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -8951,19 +10780,16 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"min-valid-lifetime\": 4000,\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-allocator\": \"iterative\",\n"
-"                \"pd-pools\": [ ],\n"
-"                \"pools\": [\n"
+"                \"pd-pools\": [\n"
 "                    {\n"
+"                        \"delegated-len\": 64,\n"
 "                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8::/64\",\n"
-"                        \"user-context\": {\n"
-"                            \"lw4over6-bind-prefix-len\": 56,\n"
-"                            \"lw4over6-sharing-ratio\": 64,\n"
-"                            \"lw4over6-sysports-exclude\": true,\n"
-"                            \"lw4over6-v4-pool\": \"192.0.2.0/24\"\n"
-"                        }\n"
+"                        \"prefix\": \"2001:db8::\",\n"
+"                        \"prefix-len\": 56,\n"
+"                        \"user-context\": { }\n"
 "                    }\n"
 "                ],\n"
+"                \"pools\": [ ],\n"
 "                \"preferred-lifetime\": 3000,\n"
 "                \"rapid-commit\": false,\n"
 "                \"rebind-timer\": 2000,\n"
@@ -8983,7 +10809,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 51
+    // CONFIGURATION 63
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -9079,11 +10905,12 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"min-valid-lifetime\": 4000,\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-allocator\": \"iterative\",\n"
-"                \"pd-pools\": [ ],\n"
-"                \"pools\": [\n"
+"                \"pd-pools\": [\n"
 "                    {\n"
+"                        \"delegated-len\": 64,\n"
 "                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8::/64\",\n"
+"                        \"prefix\": \"2001:db8::\",\n"
+"                        \"prefix-len\": 56,\n"
 "                        \"user-context\": {\n"
 "                            \"lw4over6-bind-prefix-len\": 56,\n"
 "                            \"lw4over6-sharing-ratio\": 64,\n"
@@ -9092,6 +10919,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                        }\n"
 "                    }\n"
 "                ],\n"
+"                \"pools\": [ ],\n"
 "                \"preferred-lifetime\": 3000,\n"
 "                \"rapid-commit\": false,\n"
 "                \"rebind-timer\": 2000,\n"
@@ -9111,7 +10939,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 52
+    // CONFIGURATION 64
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -9153,6 +10981,21 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"hostname-char-replacement\": \"\",\n"
 "        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
+"        \"hosts-databases\": [\n"
+"            {\n"
+"                \"name\": \"keatest1\",\n"
+"                \"password\": \"keatest\",\n"
+"                \"type\": \"mysql\",\n"
+"                \"user\": \"keatest\"\n"
+"            },\n"
+"            {\n"
+"                \"name\": \"keatest2\",\n"
+"                \"password\": \"keatest\",\n"
+"                \"retry-on-startup\": true,\n"
+"                \"type\": \"mysql\",\n"
+"                \"user\": \"keatest\"\n"
+"            }\n"
+"        ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
 "            \"re-detect\": false\n"
@@ -9196,49 +11039,71 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"statistic-default-sample-age\": 0,\n"
 "        \"statistic-default-sample-count\": 20,\n"
 "        \"store-extended-info\": false,\n"
-"        \"subnet6\": [\n"
+"        \"subnet6\": [ ],\n"
+"        \"t1-percent\": 0.5,\n"
+"        \"t2-percent\": 0.8,\n"
+"        \"valid-lifetime\": 4000\n"
+"    }\n",
+    // CONFIGURATION 65
+"{\n"
+"        \"allocator\": \"iterative\",\n"
+"        \"calculate-tee-times\": true,\n"
+"        \"client-classes\": [\n"
 "            {\n"
-"                \"allocator\": \"iterative\",\n"
-"                \"calculate-tee-times\": true,\n"
-"                \"id\": 1,\n"
-"                \"max-preferred-lifetime\": 3000,\n"
-"                \"max-valid-lifetime\": 4000,\n"
-"                \"min-preferred-lifetime\": 3000,\n"
-"                \"min-valid-lifetime\": 4000,\n"
+"                \"name\": \"all\",\n"
 "                \"option-data\": [ ],\n"
-"                \"pd-allocator\": \"iterative\",\n"
-"                \"pd-pools\": [\n"
-"                    {\n"
-"                        \"delegated-len\": 64,\n"
-"                        \"option-data\": [ ],\n"
-"                        \"prefix\": \"2001:db8::\",\n"
-"                        \"prefix-len\": 56\n"
+"                \"test\": \"'' == ''\",\n"
+"                \"user-context\": {\n"
+"                    \"comment\": \"match all\"\n"
+"                }\n"
+"            },\n"
+"            {\n"
+"                \"name\": \"none\",\n"
+"                \"option-data\": [ ]\n"
+"            },\n"
+"            {\n"
+"                \"name\": \"both\",\n"
+"                \"option-data\": [ ],\n"
+"                \"user-context\": {\n"
+"                    \"comment\": \"a comment\",\n"
+"                    \"version\": 1\n"
+"                }\n"
+"            }\n"
+"        ],\n"
+"        \"control-sockets\": [\n"
+"            {\n"
+"                \"socket-name\": \"/tmp/kea6-ctrl-socket\",\n"
+"                \"socket-type\": \"unix\",\n"
+"                \"user-context\": {\n"
+"                    \"comment\": \"Indirect comment\"\n"
+"                }\n"
+"            },\n"
+"            {\n"
+"                \"authentication\": {\n"
+"                    \"clients\": [\n"
+"                        {\n"
+"                            \"password\": \"1234\",\n"
+"                            \"user\": \"admin\",\n"
+"                            \"user-context\": {\n"
+"                                \"comment\": \"admin is authorized\"\n"
+"                            }\n"
+"                        }\n"
+"                    ],\n"
+"                    \"directory\": \"\",\n"
+"                    \"realm\": \"kea-dhcpv6-server\",\n"
+"                    \"type\": \"basic\",\n"
+"                    \"user-context\": {\n"
+"                        \"comment\": \"basic HTTP authentication\"\n"
 "                    }\n"
-"                ],\n"
-"                \"pools\": [ ],\n"
-"                \"preferred-lifetime\": 3000,\n"
-"                \"rapid-commit\": false,\n"
-"                \"rebind-timer\": 2000,\n"
-"                \"relay\": {\n"
-"                    \"ip-addresses\": [ ]\n"
 "                },\n"
-"                \"renew-timer\": 1000,\n"
-"                \"reservations\": [ ],\n"
-"                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8::/32\",\n"
-"                \"t1-percent\": 0.5,\n"
-"                \"t2-percent\": 0.8,\n"
-"                \"valid-lifetime\": 4000\n"
+"                \"socket-address\": \"127.0.0.1\",\n"
+"                \"socket-port\": 8000,\n"
+"                \"socket-type\": \"http\",\n"
+"                \"user-context\": {\n"
+"                    \"comment\": \"HTTP control socket\"\n"
+"                }\n"
 "            }\n"
 "        ],\n"
-"        \"t1-percent\": 0.5,\n"
-"        \"t2-percent\": 0.8,\n"
-"        \"valid-lifetime\": 4000\n"
-"    }\n",
-    // CONFIGURATION 53
-"{\n"
-"        \"allocator\": \"iterative\",\n"
-"        \"calculate-tee-times\": true,\n"
 "        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
 "        \"ddns-generated-prefix\": \"myhost\",\n"
 "        \"ddns-override-client-update\": false,\n"
@@ -9256,7 +11121,10 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"sender-ip\": \"0.0.0.0\",\n"
 "            \"sender-port\": 0,\n"
 "            \"server-ip\": \"127.0.0.1\",\n"
-"            \"server-port\": 53001\n"
+"            \"server-port\": 53001,\n"
+"            \"user-context\": {\n"
+"                \"comment\": \"No dynamic DNS\"\n"
+"            }\n"
 "        },\n"
 "        \"dhcp-queue-control\": {\n"
 "            \"capacity\": 64,\n"
@@ -9279,7 +11147,10 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
-"            \"re-detect\": false\n"
+"            \"re-detect\": false,\n"
+"            \"user-context\": {\n"
+"                \"comment\": \"Use wildcard\"\n"
+"            }\n"
 "        },\n"
 "        \"ip-reservations-unique\": true,\n"
 "        \"lease-database\": {\n"
@@ -9291,14 +11162,37 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"packet-queue-size\": 64,\n"
 "            \"thread-pool-size\": 0\n"
 "        },\n"
-"        \"option-data\": [ ],\n"
-"        \"option-def\": [ ],\n"
+"        \"option-data\": [\n"
+"            {\n"
+"                \"always-send\": false,\n"
+"                \"code\": 38,\n"
+"                \"csv-format\": false,\n"
+"                \"data\": \"ABCDEF0105\",\n"
+"                \"name\": \"subscriber-id\",\n"
+"                \"never-send\": false,\n"
+"                \"space\": \"dhcp6\",\n"
+"                \"user-context\": {\n"
+"                    \"comment\": \"Set option value\"\n"
+"                }\n"
+"            }\n"
+"        ],\n"
+"        \"option-def\": [\n"
+"            {\n"
+"                \"array\": false,\n"
+"                \"code\": 100,\n"
+"                \"encapsulate\": \"\",\n"
+"                \"name\": \"foo\",\n"
+"                \"record-types\": \"\",\n"
+"                \"space\": \"isc\",\n"
+"                \"type\": \"ipv6-address\",\n"
+"                \"user-context\": {\n"
+"                    \"comment\": \"An option definition\"\n"
+"                }\n"
+"            }\n"
+"        ],\n"
 "        \"parked-packet-limit\": 256,\n"
 "        \"pd-allocator\": \"iterative\",\n"
-"        \"preferred-lifetime\": 3000,\n"
-"        \"rebind-timer\": 2000,\n"
 "        \"relay-supplied-options\": [ \"65\" ],\n"
-"        \"renew-timer\": 1000,\n"
 "        \"reservations-global\": false,\n"
 "        \"reservations-in-subnet\": true,\n"
 "        \"reservations-lookup-first\": false,\n"
@@ -9313,54 +11207,114 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"identifier\": \"\",\n"
 "            \"persist\": true,\n"
 "            \"time\": 0,\n"
-"            \"type\": \"LLT\"\n"
+"            \"type\": \"LL\",\n"
+"            \"user-context\": {\n"
+"                \"comment\": \"DHCPv6 specific\"\n"
+"            }\n"
 "        },\n"
 "        \"server-tag\": \"\",\n"
-"        \"shared-networks\": [ ],\n"
-"        \"statistic-default-sample-age\": 0,\n"
-"        \"statistic-default-sample-count\": 20,\n"
-"        \"store-extended-info\": false,\n"
-"        \"subnet6\": [\n"
+"        \"shared-networks\": [\n"
 "            {\n"
 "                \"allocator\": \"iterative\",\n"
 "                \"calculate-tee-times\": true,\n"
-"                \"id\": 1,\n"
-"                \"max-preferred-lifetime\": 3000,\n"
-"                \"max-valid-lifetime\": 4000,\n"
-"                \"min-preferred-lifetime\": 3000,\n"
-"                \"min-valid-lifetime\": 4000,\n"
+"                \"max-valid-lifetime\": 7200,\n"
+"                \"min-valid-lifetime\": 7200,\n"
+"                \"name\": \"foo\",\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-allocator\": \"iterative\",\n"
-"                \"pd-pools\": [\n"
-"                    {\n"
-"                        \"delegated-len\": 64,\n"
-"                        \"option-data\": [ ],\n"
-"                        \"prefix\": \"2001:db8::\",\n"
-"                        \"prefix-len\": 56,\n"
-"                        \"user-context\": { }\n"
-"                    }\n"
-"                ],\n"
-"                \"pools\": [ ],\n"
-"                \"preferred-lifetime\": 3000,\n"
 "                \"rapid-commit\": false,\n"
-"                \"rebind-timer\": 2000,\n"
 "                \"relay\": {\n"
 "                    \"ip-addresses\": [ ]\n"
 "                },\n"
-"                \"renew-timer\": 1000,\n"
-"                \"reservations\": [ ],\n"
 "                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8::/32\",\n"
+"                \"subnet6\": [\n"
+"                    {\n"
+"                        \"allocator\": \"iterative\",\n"
+"                        \"calculate-tee-times\": true,\n"
+"                        \"id\": 100,\n"
+"                        \"max-valid-lifetime\": 7200,\n"
+"                        \"min-valid-lifetime\": 7200,\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pd-allocator\": \"iterative\",\n"
+"                        \"pd-pools\": [\n"
+"                            {\n"
+"                                \"delegated-len\": 64,\n"
+"                                \"option-data\": [ ],\n"
+"                                \"prefix\": \"2001:db2::\",\n"
+"                                \"prefix-len\": 48,\n"
+"                                \"user-context\": {\n"
+"                                    \"comment\": \"A prefix pool\"\n"
+"                                }\n"
+"                            }\n"
+"                        ],\n"
+"                        \"pools\": [\n"
+"                            {\n"
+"                                \"option-data\": [ ],\n"
+"                                \"pool\": \"2001:db1::/64\",\n"
+"                                \"user-context\": {\n"
+"                                    \"comment\": \"A pool\"\n"
+"                                }\n"
+"                            }\n"
+"                        ],\n"
+"                        \"relay\": {\n"
+"                            \"ip-addresses\": [ ]\n"
+"                        },\n"
+"                        \"reservations\": [\n"
+"                            {\n"
+"                                \"client-classes\": [ ],\n"
+"                                \"hostname\": \"foo.example.com\",\n"
+"                                \"hw-address\": \"aa:bb:cc:dd:ee:ff\",\n"
+"                                \"ip-addresses\": [ ],\n"
+"                                \"option-data\": [\n"
+"                                    {\n"
+"                                        \"always-send\": false,\n"
+"                                        \"code\": 24,\n"
+"                                        \"csv-format\": true,\n"
+"                                        \"data\": \"example.com\",\n"
+"                                        \"name\": \"domain-search\",\n"
+"                                        \"never-send\": false,\n"
+"                                        \"space\": \"dhcp6\",\n"
+"                                        \"user-context\": {\n"
+"                                            \"comment\": \"An option in a reservation\"\n"
+"                                        }\n"
+"                                    }\n"
+"                                ],\n"
+"                                \"prefixes\": [ ],\n"
+"                                \"user-context\": {\n"
+"                                    \"comment\": \"A host reservation\"\n"
+"                                }\n"
+"                            }\n"
+"                        ],\n"
+"                        \"store-extended-info\": false,\n"
+"                        \"subnet\": \"2001:db1::/48\",\n"
+"                        \"t1-percent\": 0.5,\n"
+"                        \"t2-percent\": 0.8,\n"
+"                        \"user-context\": {\n"
+"                            \"comment\": \"A subnet\"\n"
+"                        },\n"
+"                        \"valid-lifetime\": 7200\n"
+"                    }\n"
+"                ],\n"
 "                \"t1-percent\": 0.5,\n"
 "                \"t2-percent\": 0.8,\n"
-"                \"valid-lifetime\": 4000\n"
+"                \"user-context\": {\n"
+"                    \"comment\": \"A shared network\"\n"
+"                },\n"
+"                \"valid-lifetime\": 7200\n"
 "            }\n"
 "        ],\n"
+"        \"statistic-default-sample-age\": 0,\n"
+"        \"statistic-default-sample-count\": 20,\n"
+"        \"store-extended-info\": false,\n"
+"        \"subnet6\": [ ],\n"
 "        \"t1-percent\": 0.5,\n"
 "        \"t2-percent\": 0.8,\n"
-"        \"valid-lifetime\": 4000\n"
+"        \"user-context\": {\n"
+"            \"comment\": \"A DHCPv6 server\"\n"
+"        },\n"
+"        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 54
+    // CONFIGURATION 66
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -9424,6 +11378,62 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"rebind-timer\": 2000,\n"
 "        \"relay-supplied-options\": [ \"65\" ],\n"
 "        \"renew-timer\": 1000,\n"
+"        \"reservations\": [\n"
+"            {\n"
+"                \"client-classes\": [ ],\n"
+"                \"hostname\": \"\",\n"
+"                \"hw-address\": \"01:02:03:04:05:06\",\n"
+"                \"ip-addresses\": [ \"2001:db8:2::abcd\" ],\n"
+"                \"option-data\": [\n"
+"                    {\n"
+"                        \"always-send\": false,\n"
+"                        \"code\": 23,\n"
+"                        \"csv-format\": true,\n"
+"                        \"data\": \"2001:db8:2::abbc\",\n"
+"                        \"name\": \"dns-servers\",\n"
+"                        \"never-send\": false,\n"
+"                        \"space\": \"dhcp6\"\n"
+"                    },\n"
+"                    {\n"
+"                        \"always-send\": false,\n"
+"                        \"code\": 7,\n"
+"                        \"csv-format\": true,\n"
+"                        \"data\": \"25\",\n"
+"                        \"name\": \"preference\",\n"
+"                        \"never-send\": false,\n"
+"                        \"space\": \"dhcp6\"\n"
+"                    }\n"
+"                ],\n"
+"                \"prefixes\": [ ]\n"
+"            },\n"
+"            {\n"
+"                \"client-classes\": [ ],\n"
+"                \"duid\": \"01:02:03:04:05:06:07:08:09:0a\",\n"
+"                \"hostname\": \"\",\n"
+"                \"ip-addresses\": [ \"2001:db8:2::1234\" ],\n"
+"                \"option-data\": [\n"
+"                    {\n"
+"                        \"always-send\": false,\n"
+"                        \"code\": 23,\n"
+"                        \"csv-format\": true,\n"
+"                        \"data\": \"2001:db8:2::1111\",\n"
+"                        \"name\": \"dns-servers\",\n"
+"                        \"never-send\": false,\n"
+"                        \"space\": \"dhcp6\"\n"
+"                    },\n"
+"                    {\n"
+"                        \"always-send\": false,\n"
+"                        \"code\": 7,\n"
+"                        \"csv-format\": true,\n"
+"                        \"data\": \"11\",\n"
+"                        \"name\": \"preference\",\n"
+"                        \"never-send\": false,\n"
+"                        \"space\": \"dhcp6\"\n"
+"                    }\n"
+"                ],\n"
+"                \"prefixes\": [ ]\n"
+"            }\n"
+"        ],\n"
 "        \"reservations-global\": false,\n"
 "        \"reservations-in-subnet\": true,\n"
 "        \"reservations-lookup-first\": false,\n"
@@ -9449,27 +11459,45 @@ const char* UNPARSED_CONFIGS[] = {
 "            {\n"
 "                \"allocator\": \"iterative\",\n"
 "                \"calculate-tee-times\": true,\n"
-"                \"id\": 1,\n"
+"                \"id\": 123,\n"
+"                \"max-preferred-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-preferred-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8:1::/80\"\n"
+"                    }\n"
+"                ],\n"
+"                \"preferred-lifetime\": 3000,\n"
+"                \"rapid-commit\": false,\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8:1::/64\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 4000\n"
+"            },\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"id\": 234,\n"
 "                \"max-preferred-lifetime\": 3000,\n"
 "                \"max-valid-lifetime\": 4000,\n"
 "                \"min-preferred-lifetime\": 3000,\n"
 "                \"min-valid-lifetime\": 4000,\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-allocator\": \"iterative\",\n"
-"                \"pd-pools\": [\n"
-"                    {\n"
-"                        \"delegated-len\": 64,\n"
-"                        \"option-data\": [ ],\n"
-"                        \"prefix\": \"2001:db8::\",\n"
-"                        \"prefix-len\": 56,\n"
-"                        \"user-context\": {\n"
-"                            \"lw4over6-bind-prefix-len\": 56,\n"
-"                            \"lw4over6-sharing-ratio\": 64,\n"
-"                            \"lw4over6-sysports-exclude\": true,\n"
-"                            \"lw4over6-v4-pool\": \"192.0.2.0/24\"\n"
-"                        }\n"
-"                    }\n"
-"                ],\n"
+"                \"pd-pools\": [ ],\n"
 "                \"pools\": [ ],\n"
 "                \"preferred-lifetime\": 3000,\n"
 "                \"rapid-commit\": false,\n"
@@ -9480,7 +11508,33 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"renew-timer\": 1000,\n"
 "                \"reservations\": [ ],\n"
 "                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8::/32\",\n"
+"                \"subnet\": \"2001:db8:2::/64\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 4000\n"
+"            },\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"id\": 542,\n"
+"                \"max-preferred-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-preferred-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [ ],\n"
+"                \"preferred-lifetime\": 3000,\n"
+"                \"rapid-commit\": false,\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8:3::/64\",\n"
 "                \"t1-percent\": 0.5,\n"
 "                \"t2-percent\": 0.8,\n"
 "                \"valid-lifetime\": 4000\n"
@@ -9490,7 +11544,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 55
+    // CONFIGURATION 67
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -9532,21 +11586,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"host-reservation-identifiers\": [ \"hw-address\", \"duid\" ],\n"
 "        \"hostname-char-replacement\": \"\",\n"
 "        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
-"        \"hosts-databases\": [\n"
-"            {\n"
-"                \"name\": \"keatest1\",\n"
-"                \"password\": \"keatest\",\n"
-"                \"type\": \"mysql\",\n"
-"                \"user\": \"keatest\"\n"
-"            },\n"
-"            {\n"
-"                \"name\": \"keatest2\",\n"
-"                \"password\": \"keatest\",\n"
-"                \"retry-on-startup\": true,\n"
-"                \"type\": \"mysql\",\n"
-"                \"user\": \"keatest\"\n"
-"            }\n"
-"        ],\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
 "            \"re-detect\": false\n"
@@ -9566,9 +11605,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"parked-packet-limit\": 256,\n"
 "        \"pd-allocator\": \"iterative\",\n"
 "        \"preferred-lifetime\": 3000,\n"
-"        \"rebind-timer\": 2000,\n"
 "        \"relay-supplied-options\": [ \"65\" ],\n"
-"        \"renew-timer\": 1000,\n"
 "        \"reservations-global\": false,\n"
 "        \"reservations-in-subnet\": true,\n"
 "        \"reservations-lookup-first\": false,\n"
@@ -9586,75 +11623,128 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"type\": \"LLT\"\n"
 "        },\n"
 "        \"server-tag\": \"\",\n"
-"        \"shared-networks\": [ ],\n"
+"        \"shared-networks\": [\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"max-preferred-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-preferred-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"name\": \"foo\",\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"preferred-lifetime\": 3000,\n"
+"                \"rapid-commit\": false,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet6\": [\n"
+"                    {\n"
+"                        \"allocator\": \"iterative\",\n"
+"                        \"calculate-tee-times\": false,\n"
+"                        \"id\": 100,\n"
+"                        \"max-preferred-lifetime\": 3000,\n"
+"                        \"max-valid-lifetime\": 4000,\n"
+"                        \"min-preferred-lifetime\": 3000,\n"
+"                        \"min-valid-lifetime\": 4000,\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pd-allocator\": \"iterative\",\n"
+"                        \"pd-pools\": [ ],\n"
+"                        \"pools\": [\n"
+"                            {\n"
+"                                \"option-data\": [ ],\n"
+"                                \"pool\": \"2001:db8:1::/80\"\n"
+"                            }\n"
+"                        ],\n"
+"                        \"preferred-lifetime\": 3000,\n"
+"                        \"relay\": {\n"
+"                            \"ip-addresses\": [ ]\n"
+"                        },\n"
+"                        \"reservations\": [ ],\n"
+"                        \"store-extended-info\": false,\n"
+"                        \"subnet\": \"2001:db8:1::/64\",\n"
+"                        \"t1-percent\": 0.45,\n"
+"                        \"t2-percent\": 0.65,\n"
+"                        \"valid-lifetime\": 4000\n"
+"                    },\n"
+"                    {\n"
+"                        \"allocator\": \"iterative\",\n"
+"                        \"calculate-tee-times\": true,\n"
+"                        \"id\": 200,\n"
+"                        \"max-preferred-lifetime\": 3000,\n"
+"                        \"max-valid-lifetime\": 4000,\n"
+"                        \"min-preferred-lifetime\": 3000,\n"
+"                        \"min-valid-lifetime\": 4000,\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pd-allocator\": \"iterative\",\n"
+"                        \"pd-pools\": [ ],\n"
+"                        \"pools\": [\n"
+"                            {\n"
+"                                \"option-data\": [ ],\n"
+"                                \"pool\": \"2001:db8:2::/80\"\n"
+"                            }\n"
+"                        ],\n"
+"                        \"preferred-lifetime\": 3000,\n"
+"                        \"relay\": {\n"
+"                            \"ip-addresses\": [ ]\n"
+"                        },\n"
+"                        \"reservations\": [ ],\n"
+"                        \"store-extended-info\": false,\n"
+"                        \"subnet\": \"2001:db8:2::/64\",\n"
+"                        \"t1-percent\": 0.4,\n"
+"                        \"t2-percent\": 0.75,\n"
+"                        \"valid-lifetime\": 4000\n"
+"                    }\n"
+"                ],\n"
+"                \"t1-percent\": 0.4,\n"
+"                \"t2-percent\": 0.75,\n"
+"                \"valid-lifetime\": 4000\n"
+"            }\n"
+"        ],\n"
 "        \"statistic-default-sample-age\": 0,\n"
 "        \"statistic-default-sample-count\": 20,\n"
 "        \"store-extended-info\": false,\n"
-"        \"subnet6\": [ ],\n"
+"        \"subnet6\": [\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"id\": 300,\n"
+"                \"max-preferred-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-preferred-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8:3::/80\"\n"
+"                    }\n"
+"                ],\n"
+"                \"preferred-lifetime\": 3000,\n"
+"                \"rapid-commit\": false,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": false,\n"
+"                \"subnet\": \"2001:db8:3::/64\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 4000\n"
+"            }\n"
+"        ],\n"
 "        \"t1-percent\": 0.5,\n"
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 56
+    // CONFIGURATION 68
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
-"        \"client-classes\": [\n"
-"            {\n"
-"                \"name\": \"all\",\n"
-"                \"option-data\": [ ],\n"
-"                \"test\": \"'' == ''\",\n"
-"                \"user-context\": {\n"
-"                    \"comment\": \"match all\"\n"
-"                }\n"
-"            },\n"
-"            {\n"
-"                \"name\": \"none\",\n"
-"                \"option-data\": [ ]\n"
-"            },\n"
-"            {\n"
-"                \"name\": \"both\",\n"
-"                \"option-data\": [ ],\n"
-"                \"user-context\": {\n"
-"                    \"comment\": \"a comment\",\n"
-"                    \"version\": 1\n"
-"                }\n"
-"            }\n"
-"        ],\n"
-"        \"control-sockets\": [\n"
-"            {\n"
-"                \"socket-name\": \"/tmp/kea6-ctrl-socket\",\n"
-"                \"socket-type\": \"unix\",\n"
-"                \"user-context\": {\n"
-"                    \"comment\": \"Indirect comment\"\n"
-"                }\n"
-"            },\n"
-"            {\n"
-"                \"authentication\": {\n"
-"                    \"clients\": [\n"
-"                        {\n"
-"                            \"password\": \"1234\",\n"
-"                            \"user\": \"admin\",\n"
-"                            \"user-context\": {\n"
-"                                \"comment\": \"admin is authorized\"\n"
-"                            }\n"
-"                        }\n"
-"                    ],\n"
-"                    \"directory\": \"\",\n"
-"                    \"realm\": \"kea-dhcpv6-server\",\n"
-"                    \"type\": \"basic\",\n"
-"                    \"user-context\": {\n"
-"                        \"comment\": \"basic HTTP authentication\"\n"
-"                    }\n"
-"                },\n"
-"                \"socket-address\": \"127.0.0.1\",\n"
-"                \"socket-port\": 8000,\n"
-"                \"socket-type\": \"http\",\n"
-"                \"user-context\": {\n"
-"                    \"comment\": \"HTTP control socket\"\n"
-"                }\n"
-"            }\n"
-"        ],\n"
 "        \"ddns-conflict-resolution-mode\": \"check-with-dhcid\",\n"
 "        \"ddns-generated-prefix\": \"myhost\",\n"
 "        \"ddns-override-client-update\": false,\n"
@@ -9672,10 +11762,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"sender-ip\": \"0.0.0.0\",\n"
 "            \"sender-port\": 0,\n"
 "            \"server-ip\": \"127.0.0.1\",\n"
-"            \"server-port\": 53001,\n"
-"            \"user-context\": {\n"
-"                \"comment\": \"No dynamic DNS\"\n"
-"            }\n"
+"            \"server-port\": 53001\n"
 "        },\n"
 "        \"dhcp-queue-control\": {\n"
 "            \"capacity\": 64,\n"
@@ -9698,52 +11785,26 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n"
 "        \"interfaces-config\": {\n"
 "            \"interfaces\": [ \"*\" ],\n"
-"            \"re-detect\": false,\n"
-"            \"user-context\": {\n"
-"                \"comment\": \"Use wildcard\"\n"
-"            }\n"
-"        },\n"
-"        \"ip-reservations-unique\": true,\n"
-"        \"lease-database\": {\n"
-"            \"type\": \"memfile\"\n"
-"        },\n"
-"        \"mac-sources\": [ \"any\" ],\n"
-"        \"multi-threading\": {\n"
-"            \"enable-multi-threading\": true,\n"
-"            \"packet-queue-size\": 64,\n"
-"            \"thread-pool-size\": 0\n"
-"        },\n"
-"        \"option-data\": [\n"
-"            {\n"
-"                \"always-send\": false,\n"
-"                \"code\": 38,\n"
-"                \"csv-format\": false,\n"
-"                \"data\": \"ABCDEF0105\",\n"
-"                \"name\": \"subscriber-id\",\n"
-"                \"never-send\": false,\n"
-"                \"space\": \"dhcp6\",\n"
-"                \"user-context\": {\n"
-"                    \"comment\": \"Set option value\"\n"
-"                }\n"
-"            }\n"
-"        ],\n"
-"        \"option-def\": [\n"
-"            {\n"
-"                \"array\": false,\n"
-"                \"code\": 100,\n"
-"                \"encapsulate\": \"\",\n"
-"                \"name\": \"foo\",\n"
-"                \"record-types\": \"\",\n"
-"                \"space\": \"isc\",\n"
-"                \"type\": \"ipv6-address\",\n"
-"                \"user-context\": {\n"
-"                    \"comment\": \"An option definition\"\n"
-"                }\n"
-"            }\n"
-"        ],\n"
+"            \"re-detect\": false\n"
+"        },\n"
+"        \"ip-reservations-unique\": true,\n"
+"        \"lease-database\": {\n"
+"            \"type\": \"memfile\"\n"
+"        },\n"
+"        \"mac-sources\": [ \"any\" ],\n"
+"        \"multi-threading\": {\n"
+"            \"enable-multi-threading\": true,\n"
+"            \"packet-queue-size\": 64,\n"
+"            \"thread-pool-size\": 0\n"
+"        },\n"
+"        \"option-data\": [ ],\n"
+"        \"option-def\": [ ],\n"
 "        \"parked-packet-limit\": 256,\n"
 "        \"pd-allocator\": \"iterative\",\n"
+"        \"preferred-lifetime\": 3000,\n"
+"        \"rebind-timer\": 2000,\n"
 "        \"relay-supplied-options\": [ \"65\" ],\n"
+"        \"renew-timer\": 1000,\n"
 "        \"reservations-global\": false,\n"
 "        \"reservations-in-subnet\": true,\n"
 "        \"reservations-lookup-first\": false,\n"
@@ -9758,114 +11819,82 @@ const char* UNPARSED_CONFIGS[] = {
 "            \"identifier\": \"\",\n"
 "            \"persist\": true,\n"
 "            \"time\": 0,\n"
-"            \"type\": \"LL\",\n"
-"            \"user-context\": {\n"
-"                \"comment\": \"DHCPv6 specific\"\n"
-"            }\n"
+"            \"type\": \"LLT\"\n"
 "        },\n"
 "        \"server-tag\": \"\",\n"
-"        \"shared-networks\": [\n"
+"        \"shared-networks\": [ ],\n"
+"        \"statistic-default-sample-age\": 0,\n"
+"        \"statistic-default-sample-count\": 20,\n"
+"        \"store-extended-info\": false,\n"
+"        \"subnet6\": [\n"
 "            {\n"
 "                \"allocator\": \"iterative\",\n"
 "                \"calculate-tee-times\": true,\n"
-"                \"max-valid-lifetime\": 7200,\n"
-"                \"min-valid-lifetime\": 7200,\n"
-"                \"name\": \"foo\",\n"
+"                \"id\": 1,\n"
+"                \"max-preferred-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-preferred-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8:1::1-2001:db8:1::ffff\"\n"
+"                    }\n"
+"                ],\n"
+"                \"preferred-lifetime\": 3000,\n"
 "                \"rapid-commit\": false,\n"
+"                \"rebind-timer\": 2000,\n"
 "                \"relay\": {\n"
 "                    \"ip-addresses\": [ ]\n"
 "                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
 "                \"store-extended-info\": false,\n"
-"                \"subnet6\": [\n"
+"                \"subnet\": \"2001:db8:1::/64\",\n"
+"                \"t1-percent\": 0.5,\n"
+"                \"t2-percent\": 0.8,\n"
+"                \"valid-lifetime\": 4000\n"
+"            },\n"
+"            {\n"
+"                \"allocator\": \"iterative\",\n"
+"                \"calculate-tee-times\": true,\n"
+"                \"id\": 2,\n"
+"                \"max-preferred-lifetime\": 3000,\n"
+"                \"max-valid-lifetime\": 4000,\n"
+"                \"min-preferred-lifetime\": 3000,\n"
+"                \"min-valid-lifetime\": 4000,\n"
+"                \"option-data\": [ ],\n"
+"                \"pd-allocator\": \"iterative\",\n"
+"                \"pd-pools\": [ ],\n"
+"                \"pools\": [\n"
 "                    {\n"
-"                        \"allocator\": \"iterative\",\n"
-"                        \"calculate-tee-times\": true,\n"
-"                        \"id\": 100,\n"
-"                        \"max-valid-lifetime\": 7200,\n"
-"                        \"min-valid-lifetime\": 7200,\n"
 "                        \"option-data\": [ ],\n"
-"                        \"pd-allocator\": \"iterative\",\n"
-"                        \"pd-pools\": [\n"
-"                            {\n"
-"                                \"delegated-len\": 64,\n"
-"                                \"option-data\": [ ],\n"
-"                                \"prefix\": \"2001:db2::\",\n"
-"                                \"prefix-len\": 48,\n"
-"                                \"user-context\": {\n"
-"                                    \"comment\": \"A prefix pool\"\n"
-"                                }\n"
-"                            }\n"
-"                        ],\n"
-"                        \"pools\": [\n"
-"                            {\n"
-"                                \"option-data\": [ ],\n"
-"                                \"pool\": \"2001:db1::/64\",\n"
-"                                \"user-context\": {\n"
-"                                    \"comment\": \"A pool\"\n"
-"                                }\n"
-"                            }\n"
-"                        ],\n"
-"                        \"relay\": {\n"
-"                            \"ip-addresses\": [ ]\n"
-"                        },\n"
-"                        \"reservations\": [\n"
-"                            {\n"
-"                                \"client-classes\": [ ],\n"
-"                                \"hostname\": \"foo.example.com\",\n"
-"                                \"hw-address\": \"aa:bb:cc:dd:ee:ff\",\n"
-"                                \"ip-addresses\": [ ],\n"
-"                                \"option-data\": [\n"
-"                                    {\n"
-"                                        \"always-send\": false,\n"
-"                                        \"code\": 24,\n"
-"                                        \"csv-format\": true,\n"
-"                                        \"data\": \"example.com\",\n"
-"                                        \"name\": \"domain-search\",\n"
-"                                        \"never-send\": false,\n"
-"                                        \"space\": \"dhcp6\",\n"
-"                                        \"user-context\": {\n"
-"                                            \"comment\": \"An option in a reservation\"\n"
-"                                        }\n"
-"                                    }\n"
-"                                ],\n"
-"                                \"prefixes\": [ ],\n"
-"                                \"user-context\": {\n"
-"                                    \"comment\": \"A host reservation\"\n"
-"                                }\n"
-"                            }\n"
-"                        ],\n"
-"                        \"store-extended-info\": false,\n"
-"                        \"subnet\": \"2001:db1::/48\",\n"
-"                        \"t1-percent\": 0.5,\n"
-"                        \"t2-percent\": 0.8,\n"
-"                        \"user-context\": {\n"
-"                            \"comment\": \"A subnet\"\n"
-"                        },\n"
-"                        \"valid-lifetime\": 7200\n"
+"                        \"pool\": \"2001:db8:2::1-2001:db8:2::ffff\"\n"
 "                    }\n"
 "                ],\n"
+"                \"preferred-lifetime\": 3000,\n"
+"                \"rapid-commit\": false,\n"
+"                \"rebind-timer\": 2000,\n"
+"                \"relay\": {\n"
+"                    \"ip-addresses\": [ ]\n"
+"                },\n"
+"                \"renew-timer\": 1000,\n"
+"                \"reservations\": [ ],\n"
+"                \"store-extended-info\": true,\n"
+"                \"subnet\": \"2001:db8:2::/64\",\n"
 "                \"t1-percent\": 0.5,\n"
 "                \"t2-percent\": 0.8,\n"
-"                \"user-context\": {\n"
-"                    \"comment\": \"A shared network\"\n"
-"                },\n"
-"                \"valid-lifetime\": 7200\n"
+"                \"valid-lifetime\": 4000\n"
 "            }\n"
 "        ],\n"
-"        \"statistic-default-sample-age\": 0,\n"
-"        \"statistic-default-sample-count\": 20,\n"
-"        \"store-extended-info\": false,\n"
-"        \"subnet6\": [ ],\n"
 "        \"t1-percent\": 0.5,\n"
 "        \"t2-percent\": 0.8,\n"
-"        \"user-context\": {\n"
-"            \"comment\": \"A DHCPv6 server\"\n"
-"        },\n"
-"        \"valid-lifetime\": 7200\n"
+"        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 57
+    // CONFIGURATION 69
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -9929,62 +11958,6 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"rebind-timer\": 2000,\n"
 "        \"relay-supplied-options\": [ \"65\" ],\n"
 "        \"renew-timer\": 1000,\n"
-"        \"reservations\": [\n"
-"            {\n"
-"                \"client-classes\": [ ],\n"
-"                \"hostname\": \"\",\n"
-"                \"hw-address\": \"01:02:03:04:05:06\",\n"
-"                \"ip-addresses\": [ \"2001:db8:2::abcd\" ],\n"
-"                \"option-data\": [\n"
-"                    {\n"
-"                        \"always-send\": false,\n"
-"                        \"code\": 23,\n"
-"                        \"csv-format\": true,\n"
-"                        \"data\": \"2001:db8:2::abbc\",\n"
-"                        \"name\": \"dns-servers\",\n"
-"                        \"never-send\": false,\n"
-"                        \"space\": \"dhcp6\"\n"
-"                    },\n"
-"                    {\n"
-"                        \"always-send\": false,\n"
-"                        \"code\": 7,\n"
-"                        \"csv-format\": true,\n"
-"                        \"data\": \"25\",\n"
-"                        \"name\": \"preference\",\n"
-"                        \"never-send\": false,\n"
-"                        \"space\": \"dhcp6\"\n"
-"                    }\n"
-"                ],\n"
-"                \"prefixes\": [ ]\n"
-"            },\n"
-"            {\n"
-"                \"client-classes\": [ ],\n"
-"                \"duid\": \"01:02:03:04:05:06:07:08:09:0a\",\n"
-"                \"hostname\": \"\",\n"
-"                \"ip-addresses\": [ \"2001:db8:2::1234\" ],\n"
-"                \"option-data\": [\n"
-"                    {\n"
-"                        \"always-send\": false,\n"
-"                        \"code\": 23,\n"
-"                        \"csv-format\": true,\n"
-"                        \"data\": \"2001:db8:2::1111\",\n"
-"                        \"name\": \"dns-servers\",\n"
-"                        \"never-send\": false,\n"
-"                        \"space\": \"dhcp6\"\n"
-"                    },\n"
-"                    {\n"
-"                        \"always-send\": false,\n"
-"                        \"code\": 7,\n"
-"                        \"csv-format\": true,\n"
-"                        \"data\": \"11\",\n"
-"                        \"name\": \"preference\",\n"
-"                        \"never-send\": false,\n"
-"                        \"space\": \"dhcp6\"\n"
-"                    }\n"
-"                ],\n"
-"                \"prefixes\": [ ]\n"
-"            }\n"
-"        ],\n"
 "        \"reservations-global\": false,\n"
 "        \"reservations-in-subnet\": true,\n"
 "        \"reservations-lookup-first\": false,\n"
@@ -10005,12 +11978,12 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"shared-networks\": [ ],\n"
 "        \"statistic-default-sample-age\": 0,\n"
 "        \"statistic-default-sample-count\": 20,\n"
-"        \"store-extended-info\": false,\n"
+"        \"store-extended-info\": true,\n"
 "        \"subnet6\": [\n"
 "            {\n"
 "                \"allocator\": \"iterative\",\n"
 "                \"calculate-tee-times\": true,\n"
-"                \"id\": 123,\n"
+"                \"id\": 1,\n"
 "                \"max-preferred-lifetime\": 3000,\n"
 "                \"max-valid-lifetime\": 4000,\n"
 "                \"min-preferred-lifetime\": 3000,\n"
@@ -10021,7 +11994,7 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"pools\": [\n"
 "                    {\n"
 "                        \"option-data\": [ ],\n"
-"                        \"pool\": \"2001:db8:1::/80\"\n"
+"                        \"pool\": \"2001:db8:1::1-2001:db8:1::ffff\"\n"
 "                    }\n"
 "                ],\n"
 "                \"preferred-lifetime\": 3000,\n"
@@ -10041,7 +12014,7 @@ const char* UNPARSED_CONFIGS[] = {
 "            {\n"
 "                \"allocator\": \"iterative\",\n"
 "                \"calculate-tee-times\": true,\n"
-"                \"id\": 234,\n"
+"                \"id\": 2,\n"
 "                \"max-preferred-lifetime\": 3000,\n"
 "                \"max-valid-lifetime\": 4000,\n"
 "                \"min-preferred-lifetime\": 3000,\n"
@@ -10049,7 +12022,12 @@ const char* UNPARSED_CONFIGS[] = {
 "                \"option-data\": [ ],\n"
 "                \"pd-allocator\": \"iterative\",\n"
 "                \"pd-pools\": [ ],\n"
-"                \"pools\": [ ],\n"
+"                \"pools\": [\n"
+"                    {\n"
+"                        \"option-data\": [ ],\n"
+"                        \"pool\": \"2001:db8:2::1-2001:db8:2::ffff\"\n"
+"                    }\n"
+"                ],\n"
 "                \"preferred-lifetime\": 3000,\n"
 "                \"rapid-commit\": false,\n"
 "                \"rebind-timer\": 2000,\n"
@@ -10058,44 +12036,18 @@ const char* UNPARSED_CONFIGS[] = {
 "                },\n"
 "                \"renew-timer\": 1000,\n"
 "                \"reservations\": [ ],\n"
-"                \"store-extended-info\": false,\n"
+"                \"store-extended-info\": true,\n"
 "                \"subnet\": \"2001:db8:2::/64\",\n"
 "                \"t1-percent\": 0.5,\n"
 "                \"t2-percent\": 0.8,\n"
 "                \"valid-lifetime\": 4000\n"
-"            },\n"
-"            {\n"
-"                \"allocator\": \"iterative\",\n"
-"                \"calculate-tee-times\": true,\n"
-"                \"id\": 542,\n"
-"                \"max-preferred-lifetime\": 3000,\n"
-"                \"max-valid-lifetime\": 4000,\n"
-"                \"min-preferred-lifetime\": 3000,\n"
-"                \"min-valid-lifetime\": 4000,\n"
-"                \"option-data\": [ ],\n"
-"                \"pd-allocator\": \"iterative\",\n"
-"                \"pd-pools\": [ ],\n"
-"                \"pools\": [ ],\n"
-"                \"preferred-lifetime\": 3000,\n"
-"                \"rapid-commit\": false,\n"
-"                \"rebind-timer\": 2000,\n"
-"                \"relay\": {\n"
-"                    \"ip-addresses\": [ ]\n"
-"                },\n"
-"                \"renew-timer\": 1000,\n"
-"                \"reservations\": [ ],\n"
-"                \"store-extended-info\": false,\n"
-"                \"subnet\": \"2001:db8:3::/64\",\n"
-"                \"t1-percent\": 0.5,\n"
-"                \"t2-percent\": 0.8,\n"
-"                \"valid-lifetime\": 4000\n"
 "            }\n"
 "        ],\n"
 "        \"t1-percent\": 0.5,\n"
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 58
+    // CONFIGURATION 70
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -10185,7 +12137,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 4000\n"
 "    }\n",
-    // CONFIGURATION 59
+    // CONFIGURATION 71
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -10272,7 +12224,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 60
+    // CONFIGURATION 72
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -10359,7 +12311,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 61
+    // CONFIGURATION 73
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -10489,7 +12441,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 62
+    // CONFIGURATION 74
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"
@@ -10621,7 +12573,7 @@ const char* UNPARSED_CONFIGS[] = {
 "        \"t2-percent\": 0.8,\n"
 "        \"valid-lifetime\": 7200\n"
 "    }\n",
-    // CONFIGURATION 63
+    // CONFIGURATION 75
 "{\n"
 "        \"allocator\": \"iterative\",\n"
 "        \"calculate-tee-times\": true,\n"