]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1082] Checkpoint: updated failing UTs
authorFrancis Dupont <fdupont@isc.org>
Fri, 26 Nov 2021 14:31:35 +0000 (15:31 +0100)
committerRazvan Becheriu <razvan@isc.org>
Thu, 6 Jan 2022 12:48:45 +0000 (14:48 +0200)
src/lib/dhcpsrv/cfg_globals.cc
src/lib/dhcpsrv/cfg_globals.h
src/lib/dhcpsrv/libdhcpsrv.dox
src/lib/dhcpsrv/network.h
src/lib/dhcpsrv/parsers/base_network_parser.cc
src/lib/dhcpsrv/parsers/base_network_parser.h
src/lib/dhcpsrv/srv_config.cc
src/lib/dhcpsrv/tests/cb_ctl_dhcp_unittest.cc
src/lib/dhcpsrv/tests/dhcp_parsers_unittest.cc
src/lib/dhcpsrv/tests/network_unittest.cc
src/lib/dhcpsrv/tests/srv_config_unittest.cc

index 2469744e7a42004072bacc56588ccf4c3244cde5..9b030f66a934f1a2424732e54ee667d7e621d669 100644 (file)
@@ -47,6 +47,7 @@ CfgGlobals::nameToIndex = {
     { "ip-reservations-unique", IP_RESERVATIONS_UNIQUE },
     { "ddns-update-on-renew", DDNS_UPDATE_ON_RENEW },
     { "ddns-use-conflict-resolution", DDNS_USE_CONFLICT_RESOLUTION },
+    { "parked-packet-limit", PARKED_PACKET_LIMIT },
 
     // DHCPv4 specific parameters.
     { "echo-client-id", ECHO_CLIENT_ID },
index dd60ddbf5891bbfca33fd592bf34099489c49520..fa051756a9ad9f504493ca74e48abf18b146df79 100644 (file)
@@ -70,6 +70,7 @@ public:
         IP_RESERVATIONS_UNIQUE,
         DDNS_UPDATE_ON_RENEW,
         DDNS_USE_CONFLICT_RESOLUTION,
+        PARKED_PACKET_LIMIT,
 
         // DHCPv4 specific parameters.
         ECHO_CLIENT_ID,
index fb22a76ad20bda3fc023a2f878ad14506d397e08..8435afccb4759bd5bf537f78dec3b0eb880c2ecb 100644 (file)
@@ -16,6 +16,7 @@ client, relay and other tools like perfdhcp) code, please see
 
 This library contains several crucial elements for the operation of the DHCP server:
 
+- isc::dhcp::CfgGlobals - global scalar (i.e. not list or map) parameters.
 - isc::dhcp::LeaseMgr - lease manager is the name for the database backend that stores
   leases.
 - isc::dhcp::CfgMgr - configuration manager that holds DHCP specific
@@ -29,6 +30,30 @@ This library contains several crucial elements for the operation of the DHCP ser
 - isc::dhcp::Dhcp4o6IpcBase - common part (base class) of DHCPv4-over-DHCPv6
   inter server communication (aka IPC).
 
+@section cfgglobals Global Parameters
+
+The global paramaters handle direct (vs using a search in a name to
+value table) access to global scalar (i.e. not list or map) parameter values.
+
+This is related to the procedure to add a new global scalar parameter to
+the DHCPv4 or DHCPv6 (DHCPvX below) server implementation:
+
+- update the src/bin/dhcpX/dhcpX_lexer.ll to add the new token
+- update the src/bin/dhcpX/dhcpX_parser.yy to add the new syntax
+- update the src/bin/dhcpX/json_config_parser.cc to add the new parameter
+  in the global parameter big if statement
+- update the src/lib/dhcpsrv/parsers/simple_parserX.cc file to add the new
+  parameter in the GLOBALX_PARAMETERS keyword list and eventually in the
+  GLOBALX_DEFAULTS list
+- update the cfg_globals.h and cfg_globals.cc files, note that specific to
+  v4 or v6 parameters are after no specific
+- if the parameter exists for shared networks, subnets, etc,
+  the corresponding tables must be updated in simple parser files
+
+Note there is nothing to update for a global parameter in the configuration
+backend: no new column in database schemas, no code in hooks. Of course
+this does not apply to parameters which exist at not global level too.
+
 @section leasemgr Lease Manager
 
 LeaseMgr provides a common, unified abstract API for all database backends. All
index 9c5b2c9b241212ffcfc65e46496d5b2ef0b4fdb0..470745e11ca6be44d7e18db91a0911fbd9826ed1 100644 (file)
@@ -1311,13 +1311,15 @@ public:
     /// @brief Returns boolean value indicating that the Rapid Commit option
     /// is supported or unsupported for the subnet.
     ///
+    /// @note This parameter does not exist at the global level.
+    ///
     /// @param inheritance inheritance mode to be used.
     /// @return true if the Rapid Commit option is supported, false otherwise.
     util::Optional<bool>
     getRapidCommit(const Inheritance& inheritance = Inheritance::ALL) const {
 
         return (getProperty<Network6>(&Network6::getRapidCommit, rapid_commit_,
-                                      inheritance, "rapid-commit"));
+                                      inheritance));
     }
 
     /// @brief Enables or disables Rapid Commit option support for the subnet.
index 21c6d7a3051eb25a98cc87fa490274a73e598cf0..6de34383d6083bfa1ccab126d1538846d0cd9161 100644 (file)
@@ -51,6 +51,41 @@ BaseNetworkParser::moveReservationMode(ElementPtr config) {
     config->remove("reservation-mode");
 }
 
+void
+BaseNetworkParser::moveReservationMode(CfgGlobalsPtr config) {
+    if (!config->get("reservation-mode")) {
+        return;
+    }
+    if (config->get("reservations-global") ||
+        config->get("reservations-in-subnet") ||
+        config->get("reservations-out-of-pool")) {
+        isc_throw(DhcpConfigError, "invalid use of both 'reservation-mode'"
+                  " and one of 'reservations-global', 'reservations-in-subnet'"
+                  " or 'reservations-out-of-pool' parameters");
+    }
+    std::string hr_mode = config->get("reservation-mode")->stringValue();
+    if ((hr_mode == "disabled") || (hr_mode == "off")) {
+        config->set("reservations-global", Element::create(false));
+        config->set("reservations-in-subnet", Element::create(false));
+    } else if (hr_mode == "out-of-pool") {
+        config->set("reservations-global", Element::create(false));
+        config->set("reservations-in-subnet", Element::create(true));
+        config->set("reservations-out-of-pool", Element::create(true));
+    } else if (hr_mode == "global") {
+        config->set("reservations-global", Element::create(true));
+        config->set("reservations-in-subnet", Element::create(false));
+    } else if (hr_mode == "all") {
+        config->set("reservations-global", Element::create(false));
+        config->set("reservations-in-subnet", Element::create(true));
+        config->set("reservations-out-of-pool", Element::create(false));
+    } else {
+        isc_throw(DhcpConfigError, "invalid reservation-mode parameter: '"
+                  << hr_mode << "' ("
+                  << config->get("reservation-mode")->getPosition() << ")");
+    }
+    config->set("reservation-mode", ConstElementPtr());
+}
+
 void
 BaseNetworkParser::parseCommon(const ConstElementPtr& network_data,
                                NetworkPtr& network) {
index b8b17580d360d0ed3676cfccb4318f823a36f0bc..311249c914aa0e143b1b8f130478915aa7782cf2 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <cc/data.h>
 #include <cc/simple_parser.h>
+#include <dhcpsrv/cfg_globals.h>
 #include <dhcpsrv/network.h>
 
 namespace isc {
@@ -27,6 +28,14 @@ public:
     /// and a flag are specified.
     static void moveReservationMode(isc::data::ElementPtr config);
 
+    /// @brief Moves deprecated reservation-mode parameter to
+    /// new reservations flags.
+    ///
+    /// @param config [in/out] global parameters to alter.
+    /// @throw DhcpConfigError on error e.g. when both reservation-mode
+    /// and a flag are specified.
+    static void moveReservationMode(CfgGlobalsPtr config);
+
 protected:
 
     /// @brief Parses common parameters
index b8fd09fa634d5a5dc83badc9b16e7b624e37e89b..9d759a4a05d5e3447e6e20a23aa2dfe4ad456ded 100644 (file)
@@ -233,13 +233,12 @@ SrvConfig::merge6(SrvConfig& other) {
 void
 SrvConfig::mergeGlobals(SrvConfig& other) {
     auto config_set = getConfiguredGlobals();
-    ElementPtr mutable_cfg = boost::const_pointer_cast<Element>(config_set);
     // If the deprecated reservation-mode is found in database, overwrite other
     // reservation flags so there is no conflict when merging to new flags.
-    if (other.getConfiguredGlobals()->find("reservation-mode")) {
-        mutable_cfg->remove("reservations-global");
-        mutable_cfg->remove("reservations-in-subnet");
-        mutable_cfg->remove("reservations-out-of-pool");
+    if (other.getConfiguredGlobal("reservation-mode")) {
+        config_set->set("reservations-global", ConstElementPtr());
+        config_set->set("reservations-in-subnet", ConstElementPtr());
+        config_set->set("reservations-out-of-pool", ConstElementPtr());
     }
     // Iterate over the "other" globals, adding/overwriting them into
     // this config's list of globals.
@@ -248,7 +247,7 @@ SrvConfig::mergeGlobals(SrvConfig& other) {
     }
 
     // Merge the reservation-mode to new reservation flags.
-    BaseNetworkParser::moveReservationMode(mutable_cfg);
+    BaseNetworkParser::moveReservationMode(config_set);
 
     // A handful of values are stored as members in SrvConfig. So we'll
     // iterate over the merged globals, setting approprate members.
index e6318b1336adfb904a481ed87a829e5df365bbfd..2e59f2da940c46a0874c28e1166a280e5cfa2c91 100644 (file)
@@ -307,13 +307,13 @@ public:
         auto& mgr = ConfigBackendDHCPv4Mgr::instance();
 
         // Insert global parameters into a database.
-        StampedValuePtr global_parameter = StampedValue::create("foo", "bar");
+        StampedValuePtr global_parameter = StampedValue::create("comment", "bar");
         global_parameter->setModificationTime(getTimestamp("dhcp4_global_parameter"));
         ASSERT_NO_THROW(mgr.getPool()->createUpdateGlobalParameter4(BackendSelector::UNSPEC(),
                                                                     ServerSelector::ALL(),
                                                                     global_parameter));
 
-        global_parameter = StampedValue::create("bar", "teta");
+        global_parameter = StampedValue::create("next-server", "teta");
         global_parameter->setModificationTime(getTimestamp("dhcp4_global_parameter"));
         ASSERT_NO_THROW(mgr.getPool()->createUpdateGlobalParameter4(BackendSelector::UNSPEC(),
                                                                     ServerSelector::ALL(),
@@ -526,11 +526,11 @@ public:
         // be merged.
         if (hasConfigElement("dhcp4_global_parameter") &&
             (getTimestamp("dhcp4_global_parameter") > lb_modification_time)) {
-            checkConfiguredGlobal(srv_cfg, "foo", Element::create("bar"));
+            checkConfiguredGlobal(srv_cfg, "comment", Element::create("bar"));
 
         } else {
             // Otherwise it shouldn't exist.
-            EXPECT_FALSE(srv_cfg->getConfiguredGlobals()->get("foo"));
+            EXPECT_FALSE(srv_cfg->getConfiguredGlobals()->get("comment"));
         }
 
         // If there is an audit entry for option definition and the definition
@@ -653,12 +653,12 @@ public:
         {
             SCOPED_TRACE("global parameters");
             // One of the global parameters should still be there.
-            EXPECT_TRUE(srv_cfg->getConfiguredGlobals()->get("bar"));
+            EXPECT_TRUE(srv_cfg->getConfiguredGlobals()->get("next-server"));
             if (deleteConfigElement("dhcp4_global_parameter", 1)) {
-                EXPECT_FALSE(srv_cfg->getConfiguredGlobals()->get("foo"));
+                EXPECT_FALSE(srv_cfg->getConfiguredGlobals()->get("comment"));
 
             } else {
-                EXPECT_TRUE(srv_cfg->getConfiguredGlobals()->get("foo"));
+                EXPECT_TRUE(srv_cfg->getConfiguredGlobals()->get("next-server"));
             }
         }
 
@@ -768,7 +768,7 @@ TEST_F(CBControlDHCPv4Test, databaseConfigApplyAll) {
 // deleted from the database.
 TEST_F(CBControlDHCPv4Test, databaseConfigApplyDeleteAll) {
     testDatabaseConfigApplyDelete(getTimestamp(-5), [this]() {
-        remoteDeleteGlobalParameter("foo", 1);
+        remoteDeleteGlobalParameter("comment", 1);
         remoteDeleteOptionDef(101, "isc");
         remoteDeleteOption(DHO_HOST_NAME, DHCP4_OPTION_SPACE);
         remoteDeleteSharedNetwork("one");
@@ -807,7 +807,7 @@ TEST_F(CBControlDHCPv4Test, databaseConfigApplyGlobal) {
 // database.
 TEST_F(CBControlDHCPv4Test, databaseConfigApplyDeleteGlobal) {
     testDatabaseConfigApplyDelete(getTimestamp(-5), [this]() {
-        remoteDeleteGlobalParameter("foo", 1);
+        remoteDeleteGlobalParameter("comment", 1);
     });
 }
 
@@ -1103,13 +1103,13 @@ public:
         auto& mgr = ConfigBackendDHCPv6Mgr::instance();
 
         // Insert global parameters into a database.
-        StampedValuePtr global_parameter = StampedValue::create("foo", "bar");
+        StampedValuePtr global_parameter = StampedValue::create("comment", "bar");
         global_parameter->setModificationTime(getTimestamp("dhcp6_global_parameter"));
         ASSERT_NO_THROW(mgr.getPool()->createUpdateGlobalParameter6(BackendSelector::UNSPEC(),
                                                                     ServerSelector::ALL(),
                                                                     global_parameter));
 
-        global_parameter = StampedValue::create("bar", "teta");
+        global_parameter = StampedValue::create("data-directory", "teta");
         global_parameter->setModificationTime(getTimestamp("dhcp6_global_parameter"));
         ASSERT_NO_THROW(mgr.getPool()->createUpdateGlobalParameter6(BackendSelector::UNSPEC(),
                                                                     ServerSelector::ALL(),
@@ -1322,11 +1322,11 @@ public:
         // be merged.
         if (hasConfigElement("dhcp6_global_parameter") &&
             (getTimestamp("dhcp6_global_parameter") > lb_modification_time)) {
-            checkConfiguredGlobal(srv_cfg, "foo", Element::create("bar"));
+            checkConfiguredGlobal(srv_cfg, "comment", Element::create("bar"));
 
         } else {
             // Otherwise it shouldn't exist.
-            EXPECT_FALSE(srv_cfg->getConfiguredGlobals()->get("foo"));
+            EXPECT_FALSE(srv_cfg->getConfiguredGlobals()->get("comment"));
         }
 
         // If there is an audit entry for option definition and the definition
@@ -1449,12 +1449,12 @@ public:
         {
             SCOPED_TRACE("global parameters");
             // One of the global parameters should still be there.
-            EXPECT_TRUE(srv_cfg->getConfiguredGlobals()->get("bar"));
+            EXPECT_TRUE(srv_cfg->getConfiguredGlobals()->get("data-directory"));
             if (deleteConfigElement("dhcp6_global_parameter", 1)) {
-                EXPECT_FALSE(srv_cfg->getConfiguredGlobals()->get("foo"));
+                EXPECT_FALSE(srv_cfg->getConfiguredGlobals()->get("comment"));
 
             } else {
-                EXPECT_TRUE(srv_cfg->getConfiguredGlobals()->get("foo"));
+                EXPECT_TRUE(srv_cfg->getConfiguredGlobals()->get("comment"));
             }
         }
 
@@ -1550,7 +1550,7 @@ TEST_F(CBControlDHCPv6Test, databaseConfigApplyAll) {
 // deleted from the database.
 TEST_F(CBControlDHCPv6Test, databaseConfigApplyDeleteAll) {
     testDatabaseConfigApplyDelete(getTimestamp(-5), [this]() {
-        remoteDeleteGlobalParameter("foo", 1);
+        remoteDeleteGlobalParameter("comment", 1);
         remoteDeleteOptionDef(101, "isc");
         remoteDeleteOption(D6O_BOOTFILE_URL, DHCP6_OPTION_SPACE);
         remoteDeleteSharedNetwork("one");
@@ -1587,7 +1587,7 @@ TEST_F(CBControlDHCPv6Test, databaseConfigApplyGlobal) {
 // database.
 TEST_F(CBControlDHCPv6Test, databaseConfigApplyDeleteGlobal) {
     testDatabaseConfigApplyDelete(getTimestamp(-5), [this]() {
-        remoteDeleteGlobalParameter("foo", 1);
+        remoteDeleteGlobalParameter("comment", 1);
     });
 }
 
index c08742e2c896074c8e7520f979e0e626e9e5d0c2..9bdb47530971d8078936936de7aa120a4e9ed1ad 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2012-2020 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2021 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
index 7c0612603fe11f49df6b1ad0b0822572badfc26c..c08f7d2b5f7cb5dd91995a85a1ed1a08b5d7e7c5 100644 (file)
@@ -358,7 +358,8 @@ TEST_F(NetworkTest, inheritanceSupport4) {
 TEST_F(NetworkTest, inheritanceSupport6) {
     // Set global values for each parameter.
     globals_->set("preferred-lifetime", Element::create(80));
-    globals_->set("rapid-commit", Element::create(false));
+    // Rapid commit is not a global parameter.
+    // globals_->set("rapid-commit", Element::create(false));
     globals_->set("ddns-send-updates", Element::create(true));
     globals_->set("ddns-override-no-update", Element::create(true));
     globals_->set("ddns-override-client-update", Element::create(true));
@@ -380,12 +381,6 @@ TEST_F(NetworkTest, inheritanceSupport6) {
                                              &Network6::setPreferred,
                                              60, 80);
     }
-    {
-        SCOPED_TRACE("rapid-commit");
-        testNetworkInheritance<TestNetwork6>(&Network6::getRapidCommit,
-                                             &Network6::setRapidCommit,
-                                             true, false);
-    }
     {
         SCOPED_TRACE("ddns-send-updates");
         testNetworkInheritance<TestNetwork6>(&Network6::getDdnsSendUpdates,
index 51dc377e8036bf93f4b7cda259d91b65f24ac892..e3c6a2d1451bd498644d773fd7707d5e819fac0f 100644 (file)
@@ -469,15 +469,16 @@ TEST_F(SrvConfigTest, configuredGlobals) {
 
     // Now let's create a configuration from which to extract global scalars.
     // Extraction (currently) has no business logic, so the elements we use
-    // can be arbitrary.
+    // can be arbitrary when not scalar.
     ConstElementPtr global_cfg;
     std::string global_cfg_str =
     "{\n"
-    " \"astring\": \"okay\",\n"
+    " \"comment\": \"okay\",\n" // a string
     " \"amap\": { \"not-this\":777, \"not-that\": \"poo\" },\n"
-    " \"anint\": 444,\n"
+    " \"valid-lifetime\": 444,\n" // an int
     " \"alist\": [ 1, 2, 3 ],\n"
-    " \"abool\": true\n"
+    " \"store-extended-info\": true,\n" // a bool
+    " \"t1-percent\": 1.234\n" // a real
     "}\n";
     ASSERT_NO_THROW(global_cfg = Element::fromJSON(global_cfg_str));
 
@@ -491,15 +492,18 @@ TEST_F(SrvConfigTest, configuredGlobals) {
     // Maps and lists should be excluded.
     auto globals = srv_globals->valuesMap();
     for (auto global = globals.begin(); global != globals.end(); ++global) {
-        if (global->first == "astring") {
+        if (global->first == "comment") {
             ASSERT_EQ(Element::string, global->second->getType());
             EXPECT_EQ("okay", global->second->stringValue());
-        } else if (global->first == "anint") {
+        } else if (global->first == "valid-lifetime") {
             ASSERT_EQ(Element::integer, global->second->getType());
             EXPECT_EQ(444, global->second->intValue());
-        } else if (global->first == "abool") {
+        } else if (global->first == "store-extended-info") {
             ASSERT_EQ(Element::boolean, global->second->getType());
             EXPECT_TRUE(global->second->boolValue());
+        } else if (global->first == "t1-percent") {
+            ASSERT_EQ(Element::real, global->second->getType());
+            EXPECT_EQ(1.234, global->second->doubleValue());
         } else {
             ADD_FAILURE() << "unexpected element found:" << global->first;
         }
@@ -508,16 +512,15 @@ TEST_F(SrvConfigTest, configuredGlobals) {
     // Verify that using getConfiguredGlobal() to fetch an individual
     // parameters works.
     ConstElementPtr global;
-    // We should find global "astring".
-    ASSERT_NO_THROW(global = conf.getConfiguredGlobal("astring"));
+    // We should find global "comment".
+    ASSERT_NO_THROW(global = conf.getConfiguredGlobal("comment"));
     ASSERT_TRUE(global);
     ASSERT_EQ(Element::string, global->getType());
     EXPECT_EQ("okay", global->stringValue());
 
-    // Not finding global "not-there" should return an empty pointer
+    // Not finding global "not-there" should throw.
     // without throwing.
-    ASSERT_NO_THROW(global = conf.getConfiguredGlobal("not-there"));
-    ASSERT_FALSE(global);
+    ASSERT_THROW(conf.getConfiguredGlobal("not-there"), isc::NotFound);
 }
 
 // Verifies that the toElement method works well (tests limited to
@@ -578,11 +581,11 @@ TEST_F(SrvConfigTest, unparse) {
     conf.setDhcp4o6Port(6767);
     // Add "configured globals"
     conf.addConfiguredGlobal("renew-timer", Element::create(777));
-    conf.addConfiguredGlobal("foo", Element::create("bar"));
+    conf.addConfiguredGlobal("comment", Element::create("bar"));
     params = "\"echo-client-id\": false,\n";
     params += "\"dhcp4o6-port\": 6767,\n";
     params += "\"renew-timer\": 777,\n";
-    params += "\"foo\": \"bar\"\n";
+    params += "\"comment\": \"bar\"\n";
     isc::test::runToElementTest<SrvConfig>
         (header4 + defaults + defaults4 + params + trailer, conf);
 
@@ -590,7 +593,7 @@ TEST_F(SrvConfigTest, unparse) {
     CfgMgr::instance().setFamily(AF_INET6);
     params = ",\"dhcp4o6-port\": 6767,\n";
     params += "\"renew-timer\": 777,\n";
-    params += "\"foo\": \"bar\"\n";
+    params += "\"comment\": \"bar\"\n";
     isc::test::runToElementTest<SrvConfig>
         (header6 + defaults + defaults6 + params + trailer, conf);
 }
@@ -1071,7 +1074,7 @@ TEST_F(SrvConfigTest, mergeGlobals4) {
                     << "exp_globals didn't parse, test is broken";
 
     EXPECT_TRUE(isEquivalent(expected_globals,
-                            cfg_to.getConfiguredGlobals()->toElement()));
+                             cfg_to.getConfiguredGlobals()->toElement()));
 }
 
 // This test verifies that globals from one SrvConfig
@@ -1144,7 +1147,7 @@ TEST_F(SrvConfigTest, mergeGlobals6) {
                     << "exp_globals didn't parse, test is broken";
 
     EXPECT_TRUE(isEquivalent(expected_globals,
-                            cfg_to.getConfiguredGlobals()->toElement()));
+                             cfg_to.getConfiguredGlobals()->toElement()));
 
 }
 
@@ -1680,42 +1683,55 @@ TEST_F(SrvConfigTest, sanityChecksLifetime) {
         SCOPED_TRACE("no lifetime");
 
         SrvConfig conf(32);
-        EXPECT_NO_THROW(conf.sanityChecksLifetime("lifetime"));
+        EXPECT_NO_THROW(conf.sanityChecksLifetime("valid-lifetime"));
+        EXPECT_NO_THROW(conf.sanityChecksLifetime("preferred-lifetime"));
     }
 
     {
         SCOPED_TRACE("lifetime only");
 
         SrvConfig conf(32);
-        conf.addConfiguredGlobal("lifetime", Element::create(1000));
-        EXPECT_NO_THROW(conf.sanityChecksLifetime("lifetime"));
+        conf.addConfiguredGlobal("valid-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("preferred-lifetime", Element::create(500));
+        EXPECT_NO_THROW(conf.sanityChecksLifetime("valid-lifetime"));
+        EXPECT_NO_THROW(conf.sanityChecksLifetime("preferred-lifetime"));
     }
 
     {
         SCOPED_TRACE("min-lifetime only");
 
         SrvConfig conf(32);
-        conf.addConfiguredGlobal("min-lifetime", Element::create(1000));
-        EXPECT_NO_THROW(conf.sanityChecksLifetime("lifetime"));
+        conf.addConfiguredGlobal("min-valid-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("min-preferred-lifetime", Element::create(500));
+        EXPECT_NO_THROW(conf.sanityChecksLifetime("valid-lifetime"));
+        EXPECT_NO_THROW(conf.sanityChecksLifetime("preferred-lifetime"));
     }
 
     {
         SCOPED_TRACE("max-lifetime only");
 
         SrvConfig conf(32);
-        conf.addConfiguredGlobal("max-lifetime", Element::create(1000));
-        EXPECT_NO_THROW(conf.sanityChecksLifetime("lifetime"));
+        conf.addConfiguredGlobal("max-valid-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("max-preferred-lifetime", Element::create(500));
+        EXPECT_NO_THROW(conf.sanityChecksLifetime("valid-lifetime"));
+        EXPECT_NO_THROW(conf.sanityChecksLifetime("preferred-lifetime"));
     }
 
     {
         SCOPED_TRACE("min-lifetime and max-lifetime but no lifetime");
 
         SrvConfig conf(32);
-        conf.addConfiguredGlobal("min-lifetime", Element::create(1000));
-        conf.addConfiguredGlobal("max-lifetime", Element::create(2000));
-        std::string msg = "have min-lifetime and max-lifetime but no ";
-        msg += "lifetime (default)";
-        EXPECT_THROW_MSG(conf.sanityChecksLifetime("lifetime"),
+        conf.addConfiguredGlobal("min-valid-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("min-preferred-lifetime", Element::create(500));
+        conf.addConfiguredGlobal("max-valid-lifetime", Element::create(2000));
+        conf.addConfiguredGlobal("max-preferred-lifetime", Element::create(1000));
+        std::string msg = "have min-valid-lifetime and max-valid-lifetime";
+        msg += " but no valid-lifetime (default)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime("valid-lifetime"),
+                         isc::BadValue, msg);
+        msg = "have min-preferred-lifetime and max-preferred-lifetime";
+        msg += " but no preferred-lifetime (default)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime("preferred-lifetime"),
                          isc::BadValue, msg);
     }
 
@@ -1723,22 +1739,33 @@ TEST_F(SrvConfigTest, sanityChecksLifetime) {
         SCOPED_TRACE("all lifetime parameters");
 
         SrvConfig conf(32);
-        conf.addConfiguredGlobal("min-lifetime", Element::create(1000));
-        conf.addConfiguredGlobal("lifetime", Element::create(2000));
-        conf.addConfiguredGlobal("max-lifetime", Element::create(3000));
-        EXPECT_NO_THROW(conf.sanityChecksLifetime("lifetime"));
+        conf.addConfiguredGlobal("min-valid-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("min-preferred-lifetime", Element::create(500));
+        conf.addConfiguredGlobal("valid-lifetime", Element::create(2000));
+        conf.addConfiguredGlobal("preferred-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("max-valid-lifetime", Element::create(3000));
+        conf.addConfiguredGlobal("max-preferred-lifetime", Element::create(1500));
+        EXPECT_NO_THROW(conf.sanityChecksLifetime("valid-lifetime"));
+        EXPECT_NO_THROW(conf.sanityChecksLifetime("preferred-lifetime"));
     }
 
     {
         SCOPED_TRACE("min-lifetime > max-lifetime");
 
         SrvConfig conf(32);
-        conf.addConfiguredGlobal("min-lifetime", Element::create(2000));
-        conf.addConfiguredGlobal("lifetime", Element::create(2000));
-        conf.addConfiguredGlobal("max-lifetime", Element::create(1000));
-        std::string msg = "the value of min-lifetime (2000) is not less ";
-        msg += "than max-lifetime (1000)";
-        EXPECT_THROW_MSG(conf.sanityChecksLifetime("lifetime"),
+        conf.addConfiguredGlobal("min-valid-lifetime", Element::create(2000));
+        conf.addConfiguredGlobal("min-preferred-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("valid-lifetime", Element::create(2000));
+        conf.addConfiguredGlobal("preferred-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("max-valid-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("max-preferred-lifetime", Element::create(500));
+        std::string msg = "the value of min-valid-lifetime (2000) is ";
+        msg += "not less than max-valid-lifetime (1000)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime("valid-lifetime"),
+                         isc::BadValue, msg);
+        msg = "the value of min-preferred-lifetime (1000) is ";
+        msg += "not less than max-preferred-lifetime (500)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime("preferred-lifetime"),
                          isc::BadValue, msg);
     }
 
@@ -1746,11 +1773,17 @@ TEST_F(SrvConfigTest, sanityChecksLifetime) {
         SCOPED_TRACE("min-lifetime > lifetime");
 
         SrvConfig conf(32);
-        conf.addConfiguredGlobal("min-lifetime", Element::create(2000));
-        conf.addConfiguredGlobal("lifetime", Element::create(1000));
-        std::string msg = "the value of min-lifetime (2000) is not less ";
-        msg += "than (default) lifetime (1000)";
-        EXPECT_THROW_MSG(conf.sanityChecksLifetime("lifetime"),
+        conf.addConfiguredGlobal("min-valid-lifetime", Element::create(2000));
+        conf.addConfiguredGlobal("min-preferred-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("valid-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("preferred-lifetime", Element::create(500));
+        std::string msg = "the value of min-valid-lifetime (2000) is ";
+        msg += "not less than (default) valid-lifetime (1000)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime("valid-lifetime"),
+                         isc::BadValue, msg);
+        msg = "the value of min-preferred-lifetime (1000) is ";
+        msg += "not less than (default) preferred-lifetime (500)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime("preferred-lifetime"),
                          isc::BadValue, msg);
     }
 
@@ -1758,11 +1791,17 @@ TEST_F(SrvConfigTest, sanityChecksLifetime) {
         SCOPED_TRACE("lifetime > max-lifetime");
 
         SrvConfig conf(32);
-        conf.addConfiguredGlobal("lifetime", Element::create(2000));
-        conf.addConfiguredGlobal("max-lifetime", Element::create(1000));
-        std::string msg = "the value of (default) lifetime (2000) is not ";
-        msg += "less than max-lifetime (1000)";
-        EXPECT_THROW_MSG(conf.sanityChecksLifetime("lifetime"),
+        conf.addConfiguredGlobal("valid-lifetime", Element::create(2000));
+        conf.addConfiguredGlobal("preferred-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("max-valid-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("max-preferred-lifetime", Element::create(500));
+        std::string msg = "the value of (default) valid-lifetime (2000) is";
+        msg += " not less than max-valid-lifetime (1000)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime("valid-lifetime"),
+                         isc::BadValue, msg);
+        msg = "the value of (default) preferred-lifetime (1000) is";
+        msg += " not less than max-preferred-lifetime (500)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime("preferred-lifetime"),
                          isc::BadValue, msg);
     }
 
@@ -1770,12 +1809,21 @@ TEST_F(SrvConfigTest, sanityChecksLifetime) {
         SCOPED_TRACE("lifetime not between min-lifetime and max-lifetime (too small)");
 
         SrvConfig conf(32);
-        conf.addConfiguredGlobal("min-lifetime", Element::create(1000));
-        conf.addConfiguredGlobal("lifetime", Element::create(500));
-        conf.addConfiguredGlobal("max-lifetime", Element::create(2000));
-        std::string msg = "the value of (default) lifetime (500) is not ";
-        msg += "between min-lifetime (1000) and max-lifetime (2000)";
-        EXPECT_THROW_MSG(conf.sanityChecksLifetime("lifetime"),
+        conf.addConfiguredGlobal("min-valid-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("min-preferred-lifetime", Element::create(500));
+        conf.addConfiguredGlobal("valid-lifetime", Element::create(500));
+        conf.addConfiguredGlobal("preferred-lifetime", Element::create(250));
+        conf.addConfiguredGlobal("max-valid-lifetime", Element::create(2000));
+        conf.addConfiguredGlobal("max-preferred-lifetime", Element::create(1000));
+        std::string msg = "the value of (default) valid-lifetime (500) is";
+        msg += " not between min-valid-lifetime (1000) and ";
+        msg += "max-valid-lifetime (2000)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime("valid-lifetime"),
+                         isc::BadValue, msg);
+        msg = "the value of (default) preferred-lifetime (250) is";
+        msg += " not between min-preferred-lifetime (500) and ";
+        msg += "max-preferred-lifetime (1000)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime("preferred-lifetime"),
                          isc::BadValue, msg);
     }
 
@@ -1783,12 +1831,21 @@ TEST_F(SrvConfigTest, sanityChecksLifetime) {
         SCOPED_TRACE("lifetime not between min-lifetime and max-lifetime (too large)");
 
         SrvConfig conf(32);
-        conf.addConfiguredGlobal("min-lifetime", Element::create(1000));
-        conf.addConfiguredGlobal("lifetime", Element::create(3000));
-        conf.addConfiguredGlobal("max-lifetime", Element::create(2000));
-        std::string msg = "the value of (default) lifetime (3000) is not ";
-        msg += "between min-lifetime (1000) and max-lifetime (2000)";
-        EXPECT_THROW_MSG(conf.sanityChecksLifetime("lifetime"),
+        conf.addConfiguredGlobal("min-valid-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("min-preferred-lifetime", Element::create(500));
+        conf.addConfiguredGlobal("valid-lifetime", Element::create(3000));
+        conf.addConfiguredGlobal("preferred-lifetime", Element::create(1500));
+        conf.addConfiguredGlobal("max-valid-lifetime", Element::create(2000));
+        conf.addConfiguredGlobal("max-preferred-lifetime", Element::create(1000));
+        std::string msg = "the value of (default) valid-lifetime (3000) is";
+        msg += " not between min-valid-lifetime (1000) and ";
+        msg += "max-valid-lifetime (2000)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime("valid-lifetime"),
+                         isc::BadValue, msg);
+        msg = "the value of (default) preferred-lifetime (1500) is";
+        msg += " not between min-preferred-lifetime (500) and ";
+        msg += "max-preferred-lifetime (1000)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime("preferred-lifetime"),
                          isc::BadValue, msg);
     }
 
@@ -1797,39 +1854,53 @@ TEST_F(SrvConfigTest, sanityChecksLifetime) {
     // when this overload is used, and this lowers the number of cases...
 
     SrvConfig target(10);
-    target.addConfiguredGlobal("min-lifetime", Element::create(1000));
-    target.addConfiguredGlobal("lifetime", Element::create(2000));
-    target.addConfiguredGlobal("max-lifetime", Element::create(3000));
+    target.addConfiguredGlobal("min-valid-lifetime", Element::create(1000));
+    target.addConfiguredGlobal("min-preferred-lifetime", Element::create(500));
+    target.addConfiguredGlobal("valid-lifetime", Element::create(2000));
+    target.addConfiguredGlobal("preferred-lifetime", Element::create(1000));
+    target.addConfiguredGlobal("max-valid-lifetime", Element::create(3000));
+    target.addConfiguredGlobal("max-preferred-lifetime", Element::create(1500));
 
     {
         SCOPED_TRACE("no lifetime");
 
         SrvConfig conf(32);
-        EXPECT_NO_THROW(conf.sanityChecksLifetime(target, "lifetime"));
+        EXPECT_NO_THROW(conf.sanityChecksLifetime(target, "valid-lifetime"));
+        EXPECT_NO_THROW(conf.sanityChecksLifetime(target,
+                                                  "preferred-lifetime"));
     }
 
     {
         SCOPED_TRACE("lifetime only");
 
         SrvConfig conf(32);
-        conf.addConfiguredGlobal("lifetime", Element::create(1000));
-        EXPECT_NO_THROW(conf.sanityChecksLifetime(target, "lifetime"));
+        conf.addConfiguredGlobal("valid-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("preferred-lifetime", Element::create(500));
+        EXPECT_NO_THROW(conf.sanityChecksLifetime(target, "valid-lifetime"));
+        EXPECT_NO_THROW(conf.sanityChecksLifetime(target,
+                                                  "preferred-lifetime"));
     }
 
     {
         SCOPED_TRACE("min-lifetime only");
 
         SrvConfig conf(32);
-        conf.addConfiguredGlobal("min-lifetime", Element::create(1000));
-        EXPECT_NO_THROW(conf.sanityChecksLifetime(target, "lifetime"));
+        conf.addConfiguredGlobal("min-valid-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("min-preferred-lifetime", Element::create(500));
+        EXPECT_NO_THROW(conf.sanityChecksLifetime(target, "valid-lifetime"));
+        EXPECT_NO_THROW(conf.sanityChecksLifetime(target,
+                                                  "preferred-lifetime"));
     }
 
     {
         SCOPED_TRACE("max-lifetime only");
 
         SrvConfig conf(32);
-        conf.addConfiguredGlobal("max-lifetime", Element::create(3000));
-        EXPECT_NO_THROW(conf.sanityChecksLifetime(target, "lifetime"));
+        conf.addConfiguredGlobal("max-valid-lifetime", Element::create(3000));
+        conf.addConfiguredGlobal("max-preferred-lifetime", Element::create(1500));
+        EXPECT_NO_THROW(conf.sanityChecksLifetime(target, "valid-lifetime"));
+        EXPECT_NO_THROW(conf.sanityChecksLifetime(target,
+                                                  "preferred-lifetime"));
     }
 
     {
@@ -1837,11 +1908,18 @@ TEST_F(SrvConfigTest, sanityChecksLifetime) {
 
         SrvConfig empty(10);
         SrvConfig conf(32);
-        conf.addConfiguredGlobal("min-lifetime", Element::create(1000));
-        conf.addConfiguredGlobal("max-lifetime", Element::create(3000));
-        std::string msg = "have min-lifetime and max-lifetime but no ";
-        msg += "lifetime (default)";
-        EXPECT_THROW_MSG(conf.sanityChecksLifetime(empty, "lifetime"),
+        conf.addConfiguredGlobal("min-valid-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("min-preferred-lifetime", Element::create(500));
+        conf.addConfiguredGlobal("max-valid-lifetime", Element::create(3000));
+        conf.addConfiguredGlobal("max-preferred-lifetime", Element::create(1500));
+        std::string msg = "have min-valid-lifetime and ";
+        msg += "max-valid-lifetime but no valid-lifetime (default)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(empty, "valid-lifetime"),
+                         isc::BadValue, msg);
+        msg = "have min-preferred-lifetime and ";
+        msg += "max-preferred-lifetime but no preferred-lifetime (default)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(empty,
+                                                   "preferred-lifetime"),
                          isc::BadValue, msg);
     }
 
@@ -1849,31 +1927,48 @@ TEST_F(SrvConfigTest, sanityChecksLifetime) {
         SCOPED_TRACE("all lifetime parameters");
 
         SrvConfig conf(32);
-        conf.addConfiguredGlobal("min-lifetime", Element::create(1000));
-        conf.addConfiguredGlobal("lifetime", Element::create(2000));
-        conf.addConfiguredGlobal("max-lifetime", Element::create(3000));
-        EXPECT_NO_THROW(conf.sanityChecksLifetime(target, "lifetime"));
+        conf.addConfiguredGlobal("min-valid-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("min-preferred-lifetime", Element::create(500));
+        conf.addConfiguredGlobal("valid-lifetime", Element::create(2000));
+        conf.addConfiguredGlobal("preferred-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("max-valid-lifetime", Element::create(3000));
+        conf.addConfiguredGlobal("max-preferred-lifetime", Element::create(1500));
+        EXPECT_NO_THROW(conf.sanityChecksLifetime(target, "valid-lifetime"));
+        EXPECT_NO_THROW(conf.sanityChecksLifetime(target,
+                                                  "preferred-lifetime"));
     }
 
     {
         SCOPED_TRACE("overwrite all lifetime parameters");
 
         SrvConfig conf(32);
-        conf.addConfiguredGlobal("min-lifetime", Element::create(100));
-        conf.addConfiguredGlobal("lifetime", Element::create(200));
-        conf.addConfiguredGlobal("max-lifetime", Element::create(300));
-        EXPECT_NO_THROW(conf.sanityChecksLifetime(target, "lifetime"));
+        conf.addConfiguredGlobal("min-valid-lifetime", Element::create(100));
+        conf.addConfiguredGlobal("min-preferred-lifetime", Element::create(50));
+        conf.addConfiguredGlobal("valid-lifetime", Element::create(200));
+        conf.addConfiguredGlobal("preferred-lifetime", Element::create(100));
+        conf.addConfiguredGlobal("max-valid-lifetime", Element::create(300));
+        conf.addConfiguredGlobal("max-preferred-lifetime", Element::create(150));
+        EXPECT_NO_THROW(conf.sanityChecksLifetime(target, "valid-lifetime"));
+        EXPECT_NO_THROW(conf.sanityChecksLifetime(target,
+                                                  "preferred-lifetime"));
     }
 
     {
         SCOPED_TRACE("min-lifetime > max-lifetime");
 
         SrvConfig conf(32);
-        conf.addConfiguredGlobal("min-lifetime", Element::create(2000));
-        conf.addConfiguredGlobal("max-lifetime", Element::create(1000));
-        std::string msg = "the value of new min-lifetime (2000) is not less ";
-        msg += "than new max-lifetime (1000)";
-        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target, "lifetime"),
+        conf.addConfiguredGlobal("min-valid-lifetime", Element::create(2000));
+        conf.addConfiguredGlobal("min-preferred-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("max-valid-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("max-preferred-lifetime", Element::create(500));
+        std::string msg = "the value of new min-valid-lifetime (2000) is";
+        msg += " not less than new max-valid-lifetime (1000)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target, "valid-lifetime"),
+                         isc::BadValue, msg);
+        msg = "the value of new min-preferred-lifetime (1000) is";
+        msg += " not less than new max-preferred-lifetime (500)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target,
+                                                   "preferred-lifetime"),
                          isc::BadValue, msg);
     }
 
@@ -1881,10 +1976,16 @@ TEST_F(SrvConfigTest, sanityChecksLifetime) {
         SCOPED_TRACE("target min-lifetime > max-lifetime");
 
         SrvConfig conf(32);
-        conf.addConfiguredGlobal("max-lifetime", Element::create(500));
-        std::string msg = "the value of previous min-lifetime (1000) is not ";
-        msg += "less than new max-lifetime (500)";
-        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target, "lifetime"),
+        conf.addConfiguredGlobal("max-valid-lifetime", Element::create(500));
+        conf.addConfiguredGlobal("max-preferred-lifetime", Element::create(250));
+        std::string msg = "the value of previous min-valid-lifetime (1000) is";
+        msg += " not less than new max-valid-lifetime (500)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target, "valid-lifetime"),
+                         isc::BadValue, msg);
+        msg = "the value of previous min-preferred-lifetime (500) is";
+        msg += " not less than new max-preferred-lifetime (250)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target,
+                                                   "preferred-lifetime"),
                          isc::BadValue, msg);
     }
 
@@ -1892,10 +1993,16 @@ TEST_F(SrvConfigTest, sanityChecksLifetime) {
         SCOPED_TRACE("min-lifetime > target max-lifetime");
 
         SrvConfig conf(32);
-        conf.addConfiguredGlobal("min-lifetime", Element::create(4000));
-        std::string msg = "the value of new min-lifetime (4000) is not less ";
-        msg += "than previous max-lifetime (3000)";
-        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target, "lifetime"),
+        conf.addConfiguredGlobal("min-valid-lifetime", Element::create(4000));
+        conf.addConfiguredGlobal("min-preferred-lifetime", Element::create(2000));
+        std::string msg = "the value of new min-valid-lifetime (4000) is";
+        msg += " not less than previous max-valid-lifetime (3000)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target, "valid-lifetime"),
+                         isc::BadValue, msg);
+        msg = "the value of new min-preferred-lifetime (2000) is";
+        msg += " not less than previous max-preferred-lifetime (1500)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target,
+                                                   "preferred-lifetime"),
                          isc::BadValue, msg);
     }
 
@@ -1904,11 +2011,18 @@ TEST_F(SrvConfigTest, sanityChecksLifetime) {
 
         SrvConfig empty(10);
         SrvConfig conf(32);
-        conf.addConfiguredGlobal("min-lifetime", Element::create(2000));
-        conf.addConfiguredGlobal("lifetime", Element::create(1000));
-        std::string msg = "the value of new min-lifetime (2000) is not less ";
-        msg += "than new (default) lifetime (1000)";
-        EXPECT_THROW_MSG(conf.sanityChecksLifetime(empty, "lifetime"),
+        conf.addConfiguredGlobal("min-valid-lifetime", Element::create(2000));
+        conf.addConfiguredGlobal("min-preferred-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("valid-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("preferred-lifetime", Element::create(500));
+        std::string msg = "the value of new min-valid-lifetime (2000) is";
+        msg += " not less than new (default) valid-lifetime (1000)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(empty, "valid-lifetime"),
+                         isc::BadValue, msg);
+        msg = "the value of new min-preferred-lifetime (1000) is";
+        msg += " not less than new (default) preferred-lifetime (500)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(empty,
+                                                   "preferred-lifetime"),
                          isc::BadValue, msg);
     }
 
@@ -1917,11 +2031,18 @@ TEST_F(SrvConfigTest, sanityChecksLifetime) {
 
         SrvConfig conf(32);
         SrvConfig target2(20);
-        conf.addConfiguredGlobal("lifetime", Element::create(1000));
-        target2.addConfiguredGlobal("min-lifetime", Element::create(2000));
-        std::string msg = "the value of previous min-lifetime (2000) is not ";
-        msg += "less than new (default) lifetime (1000)";
-        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target2, "lifetime"),
+        conf.addConfiguredGlobal("valid-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("preferred-lifetime", Element::create(500));
+        target2.addConfiguredGlobal("min-valid-lifetime", Element::create(2000));
+        target2.addConfiguredGlobal("min-preferred-lifetime", Element::create(1000));
+        std::string msg = "the value of previous min-valid-lifetime (2000)";
+        msg += " is not less than new (default) valid-lifetime (1000)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target2, "valid-lifetime"),
+                         isc::BadValue, msg);
+        msg = "the value of previous min-preferred-lifetime (1000) ";
+        msg += "is not less than new (default) preferred-lifetime (500)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target2,
+                                                   "preferred-lifetime"),
                          isc::BadValue, msg);
     }
 
@@ -1930,11 +2051,18 @@ TEST_F(SrvConfigTest, sanityChecksLifetime) {
 
         SrvConfig conf(32);
         SrvConfig target2(20);
-        conf.addConfiguredGlobal("min-lifetime", Element::create(2000));
-        target2.addConfiguredGlobal("lifetime", Element::create(1000));
-        std::string msg = "the value of new min-lifetime (2000) is not less ";
-        msg += "than previous (default) lifetime (1000)";
-        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target2, "lifetime"),
+        conf.addConfiguredGlobal("min-valid-lifetime", Element::create(2000));
+        conf.addConfiguredGlobal("min-preferred-lifetime", Element::create(1000));
+        target2.addConfiguredGlobal("valid-lifetime", Element::create(1000));
+        target2.addConfiguredGlobal("preferred-lifetime", Element::create(500));
+        std::string msg = "the value of new min-valid-lifetime (2000) is";
+        msg += " not less than previous (default) valid-lifetime (1000)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target2, "valid-lifetime"),
+                         isc::BadValue, msg);
+        msg = "the value of new min-preferred-lifetime (1000) is";
+        msg += " not less than previous (default) preferred-lifetime (500)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target2,
+                                                   "preferred-lifetime"),
                          isc::BadValue, msg);
     }
 
@@ -1943,11 +2071,18 @@ TEST_F(SrvConfigTest, sanityChecksLifetime) {
 
         SrvConfig empty(10);
         SrvConfig conf(32);
-        conf.addConfiguredGlobal("lifetime", Element::create(2000));
-        conf.addConfiguredGlobal("max-lifetime", Element::create(1000));
-        std::string msg = "the value of new (default) lifetime (2000) is not ";
-        msg += "less than new max-lifetime (1000)";
-        EXPECT_THROW_MSG(conf.sanityChecksLifetime(empty, "lifetime"),
+        conf.addConfiguredGlobal("valid-lifetime", Element::create(2000));
+        conf.addConfiguredGlobal("preferred-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("max-valid-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("max-preferred-lifetime", Element::create(500));
+        std::string msg = "the value of new (default) valid-lifetime (2000) ";
+        msg += "is not less than new max-valid-lifetime (1000)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(empty, "valid-lifetime"),
+                         isc::BadValue, msg);
+        msg = "the value of new (default) preferred-lifetime (1000) ";
+        msg += "is not less than new max-preferred-lifetime (500)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(empty,
+                                                   "preferred-lifetime"),
                          isc::BadValue, msg);
     }
 
@@ -1956,11 +2091,18 @@ TEST_F(SrvConfigTest, sanityChecksLifetime) {
 
         SrvConfig conf(32);
         SrvConfig target2(20);
-        conf.addConfiguredGlobal("max-lifetime", Element::create(1000));
-        target2.addConfiguredGlobal("lifetime", Element::create(2000));
-        std::string msg = "the value of previous (default) lifetime (2000) ";
-        msg += "is not less than new max-lifetime (1000)";
-        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target2, "lifetime"),
+        conf.addConfiguredGlobal("max-valid-lifetime", Element::create(1000));
+        conf.addConfiguredGlobal("max-preferred-lifetime", Element::create(500));
+        target2.addConfiguredGlobal("valid-lifetime", Element::create(2000));
+        target2.addConfiguredGlobal("preferred-lifetime", Element::create(1000));
+        std::string msg = "the value of previous (default) valid-lifetime ";
+        msg += "(2000) is not less than new max-valid-lifetime (1000)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target2, "valid-lifetime"),
+                         isc::BadValue, msg);
+        msg = "the value of previous (default) preferred-lifetime ";
+        msg += "(1000) is not less than new max-preferred-lifetime (500)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target2,
+                                                   "preferred-lifetime"),
                          isc::BadValue, msg);
     }
 
@@ -1969,11 +2111,18 @@ TEST_F(SrvConfigTest, sanityChecksLifetime) {
 
         SrvConfig conf(32);
         SrvConfig target2(20);
-        conf.addConfiguredGlobal("lifetime", Element::create(2000));
-        target2.addConfiguredGlobal("max-lifetime", Element::create(1000));
-        std::string msg = "the value of new (default) lifetime (2000) is not ";
-        msg += "less than previous max-lifetime (1000)";
-        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target2, "lifetime"),
+        conf.addConfiguredGlobal("valid-lifetime", Element::create(2000));
+        conf.addConfiguredGlobal("preferred-lifetime", Element::create(1000));
+        target2.addConfiguredGlobal("max-valid-lifetime", Element::create(1000));
+        target2.addConfiguredGlobal("max-preferred-lifetime", Element::create(500));
+        std::string msg = "the value of new (default) valid-lifetime (2000) ";
+        msg += "is not less than previous max-valid-lifetime (1000)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target2, "valid-lifetime"),
+                         isc::BadValue, msg);
+        msg = "the value of new (default) preferred-lifetime (1000) ";
+        msg += "is not less than previous max-preferred-lifetime (500)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target2,
+                                                   "preferred-lifetime"),
                          isc::BadValue, msg);
     }
 
@@ -1981,11 +2130,18 @@ TEST_F(SrvConfigTest, sanityChecksLifetime) {
         SCOPED_TRACE("lifetime not between min-lifetime and max-lifetime (too small)");
 
         SrvConfig conf(32);
-        conf.addConfiguredGlobal("lifetime", Element::create(500));
-        std::string msg = "the value of new (default) lifetime (500) is not ";
-        msg += "between previous min-lifetime (1000) and ";
-        msg += "previous max-lifetime (3000)";
-        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target, "lifetime"),
+        conf.addConfiguredGlobal("valid-lifetime", Element::create(500));
+        conf.addConfiguredGlobal("preferred-lifetime", Element::create(250));
+        std::string msg = "the value of new (default) valid-lifetime (500)";
+        msg += " is not between previous min-valid-lifetime (1000) and ";
+        msg += "previous max-valid-lifetime (3000)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target, "valid-lifetime"),
+                         isc::BadValue, msg);
+        msg = "the value of new (default) preferred-lifetime (250)";
+        msg += " is not between previous min-preferred-lifetime (500) and ";
+        msg += "previous max-preferred-lifetime (1500)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target,
+                                                   "preferred-lifetime"),
                          isc::BadValue, msg);
     }
 
@@ -1993,11 +2149,18 @@ TEST_F(SrvConfigTest, sanityChecksLifetime) {
         SCOPED_TRACE("lifetime not between min-lifetime and max-lifetime (too large)");
 
         SrvConfig conf(32);
-        conf.addConfiguredGlobal("lifetime", Element::create(4000));
-        std::string msg = "the value of new (default) lifetime (4000) is not ";
-        msg += "between previous min-lifetime (1000) and ";
-        msg += "previous max-lifetime (3000)";
-        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target, "lifetime"),
+        conf.addConfiguredGlobal("valid-lifetime", Element::create(4000));
+        conf.addConfiguredGlobal("preferred-lifetime", Element::create(2000));
+        std::string msg = "the value of new (default) valid-lifetime (4000)";
+        msg += " is not between previous min-valid-lifetime (1000) and ";
+        msg += "previous max-valid-lifetime (3000)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target, "valid-lifetime"),
+                         isc::BadValue, msg);
+        msg = "the value of new (default) preferred-lifetime (2000)";
+        msg += " is not between previous min-preferred-lifetime (500) and ";
+        msg += "previous max-preferred-lifetime (1500)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target,
+                                                   "preferred-lifetime"),
                          isc::BadValue, msg);
     }
 
@@ -2005,12 +2168,20 @@ TEST_F(SrvConfigTest, sanityChecksLifetime) {
         SCOPED_TRACE("lifetime not between min-lifetime and max-lifetime (too low)");
 
         SrvConfig conf(32);
-        conf.addConfiguredGlobal("min-lifetime", Element::create(100));
-        conf.addConfiguredGlobal("max-lifetime", Element::create(300));
-        std::string msg = "the value of previous (default) lifetime (2000) ";
-        msg += "is not between new min-lifetime (100) and ";
-        msg += "new max-lifetime (300)";
-        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target, "lifetime"),
+        conf.addConfiguredGlobal("min-valid-lifetime", Element::create(100));
+        conf.addConfiguredGlobal("min-preferred-lifetime", Element::create(50));
+        conf.addConfiguredGlobal("max-valid-lifetime", Element::create(300));
+        conf.addConfiguredGlobal("max-preferred-lifetime", Element::create(150));
+        std::string msg = "the value of previous (default) valid-lifetime";
+        msg += " (2000) is not between new min-valid-lifetime (100) and ";
+        msg += "new max-valid-lifetime (300)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target, "valid-lifetime"),
+                         isc::BadValue, msg);
+        msg = "the value of previous (default) preferred-lifetime";
+        msg += " (1000) is not between new min-preferred-lifetime (50) and ";
+        msg += "new max-preferred-lifetime (150)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target,
+                                                   "preferred-lifetime"),
                          isc::BadValue, msg);
     }
 
@@ -2018,12 +2189,20 @@ TEST_F(SrvConfigTest, sanityChecksLifetime) {
         SCOPED_TRACE("lifetime not between min-lifetime and max-lifetime (too high)");
 
         SrvConfig conf(32);
-        conf.addConfiguredGlobal("min-lifetime", Element::create(10000));
-        conf.addConfiguredGlobal("max-lifetime", Element::create(30000));
-        std::string msg = "the value of previous (default) lifetime (2000) ";
-        msg += "is not between new min-lifetime (10000) and ";
-        msg += "new max-lifetime (30000)";
-        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target, "lifetime"),
+        conf.addConfiguredGlobal("min-valid-lifetime", Element::create(10000));
+        conf.addConfiguredGlobal("min-preferred-lifetime", Element::create(5000));
+        conf.addConfiguredGlobal("max-valid-lifetime", Element::create(30000));
+        conf.addConfiguredGlobal("max-preferred-lifetime", Element::create(15000));
+        std::string msg = "the value of previous (default) valid-lifetime";
+        msg += " (2000) is not between new min-valid-lifetime (10000) and ";
+        msg += "new max-valid-lifetime (30000)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target, "valid-lifetime"),
+                         isc::BadValue, msg);
+        msg = "the value of previous (default) preferred-lifetime";
+        msg += " (1000) is not between new min-preferred-lifetime (5000) and ";
+        msg += "new max-preferred-lifetime (15000)";
+        EXPECT_THROW_MSG(conf.sanityChecksLifetime(target,
+                                                   "preferred-lifetime"),
                          isc::BadValue, msg);
     }
 }