]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#365,!296] kea-dhcp6 calculates tee times
authorThomas Markwalder <tmark@isc.org>
Thu, 4 Apr 2019 14:38:42 +0000 (10:38 -0400)
committerThomas Markwalder <tmark@isc.org>
Fri, 26 Apr 2019 14:45:03 +0000 (10:45 -0400)
Server calcultates T1 & T2 when enabled.  Does not
include parser support for calculate-tee-times,
t1-percent, or t2-percent

src/bin/dhcp6/dhcp6_srv.*
    Dhcpv6Srv::setTeeTimes() - new method to
    calcualte T1 and T2

    Dhcpv6Srv::assignIA_NA()
    Dhcpv6Srv::extendIA_NA()
    Dhcpv6Srv::assignIA_PD()
    Dhcpv6Srv::extendIA_NA() - modified to call setTeeTimes()

src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
    TEST_F(Dhcpv6SrvTest, calculateTeeTimers)  - new test

src/bin/dhcp6/tests/hooks_unittest.cc
    Removed overriding of Lease::t1_ and t2_ from tests

src/bin/dhcp6/dhcp6_srv.cc
src/bin/dhcp6/dhcp6_srv.h
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
src/bin/dhcp6/tests/hooks_unittest.cc

index fba6cfbbe51604b2c0d609a98103d9682e971e84..3a02ac87b63fb12e4028a88ba7b89a992c37334f 100644 (file)
@@ -1832,8 +1832,8 @@ Dhcpv6Srv::assignIA_NA(const Pkt6Ptr& query, const Pkt6Ptr& answer,
             .arg(ia->getIAID())
             .arg(lease->toText());
 
-        ia_rsp->setT1(subnet->getT1());
-        ia_rsp->setT2(subnet->getT2());
+        // Set the values for T1 and T2.
+        setTeeTimes(lease->valid_lft_, subnet, ia_rsp);
 
         Option6IAAddrPtr addr(new Option6IAAddr(D6O_IAADDR, lease->addr_,
                                                 lease->preferred_lft_,
@@ -1917,14 +1917,19 @@ Dhcpv6Srv::assignIA_PD(const Pkt6Ptr& query, const Pkt6Ptr& /*answer*/,
 
     if (!leases.empty()) {
 
-        ia_rsp->setT1(subnet->getT1());
-        ia_rsp->setT2(subnet->getT2());
+        // Need to retain the shortest valid lease time to use
+        // for calculating T1 and T2.
+        uint32_t min_valid_lft = (*leases.begin())->valid_lft_;
 
         const bool pd_exclude_requested = requestedInORO(query, D6O_PD_EXCLUDE);
-
         for (Lease6Collection::iterator l = leases.begin();
              l != leases.end(); ++l) {
 
+            // Check for new minimum lease time
+            if (min_valid_lft > (*l)->valid_lft_) {
+                min_valid_lft = (*l)->valid_lft_;
+            }
+
             // We have a lease! Let's wrap its content into IA_PD option
             // with IAADDR suboption.
             LOG_INFO(lease6_logger, ctx.fake_allocation_ ?
@@ -1954,6 +1959,9 @@ Dhcpv6Srv::assignIA_PD(const Pkt6Ptr& query, const Pkt6Ptr& /*answer*/,
             }
         }
 
+        // Set T1 and T2, using the shortest valid lifetime among the leases.
+        setTeeTimes(min_valid_lft, subnet, ia_rsp);
+
         // It would be possible to insert status code=0(success) as well,
         // but this is considered waste of bandwidth as absence of status
         // code is considered a success.
@@ -2006,10 +2014,6 @@ Dhcpv6Srv::extendIA_NA(const Pkt6Ptr& query, const Pkt6Ptr& answer,
         return (ia_rsp);
     }
 
-    // Set up T1, T2 timers
-    ia_rsp->setT1(subnet->getT1());
-    ia_rsp->setT2(subnet->getT2());
-
     // Get DDNS update directions
     bool do_fwd = false;
     bool do_rev = false;
@@ -2062,18 +2066,29 @@ Dhcpv6Srv::extendIA_NA(const Pkt6Ptr& query, const Pkt6Ptr& answer,
     // into temporary container.
     AllocEngine::HintContainer hints = ctx.currentIA().hints_;
 
+    // Retains the shortest valid lease time to use
+    // for calculating T1 and T2.
+    uint32_t min_valid_lft = std::numeric_limits<uint32_t>::max();
+
     // For all leases we have now, add the IAADDR with non-zero lifetimes.
     for (Lease6Collection::const_iterator l = leases.begin(); l != leases.end(); ++l) {
         Option6IAAddrPtr iaaddr(new Option6IAAddr(D6O_IAADDR,
                                 (*l)->addr_, (*l)->preferred_lft_, (*l)->valid_lft_));
         ia_rsp->addOption(iaaddr);
-        LOG_INFO(lease6_logger, DHCP6_LEASE_RENEW)
+
+        // Check for new minimum lease time
+        if ((*l)->valid_lft_ < min_valid_lft) {
+            min_valid_lft = (*l)->valid_lft_;
+        }
+
+        LOG_INFO(lease6_logger, DHCP6_PD_LEASE_RENEW)
             .arg(query->getLabel())
             .arg((*l)->addr_.toText())
-            .arg(ia_rsp->getIAID());
+            .arg(static_cast<int>((*l)->prefixlen_))
+            .arg(ia->getIAID());
 
-        // Now remove this address from the hints list.
-        AllocEngine::ResourceType hint_type((*l)->addr_, 128);
+        // Now remove this prefix from the hints list.
+        AllocEngine::ResourceType hint_type((*l)->addr_, (*l)->prefixlen_);
         hints.erase(std::remove(hints.begin(), hints.end(), hint_type),
                     hints.end());
     }
@@ -2120,9 +2135,10 @@ Dhcpv6Srv::extendIA_NA(const Pkt6Ptr& query, const Pkt6Ptr& answer,
         ia_rsp->addOption(iaaddr);
     }
 
-    // All is left is to insert the status code.
-    if (leases.empty()) {
-
+    if (!leases.empty()) {
+        // We allocated leases so we need to update T1 and T2.
+        setTeeTimes(min_valid_lft, subnet, ia_rsp);
+    } else {
         // The server wasn't able allocate new lease and renew an existing
         // lease. In that case, the server sends NoAddrsAvail per RFC 8415.
         ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
@@ -2185,10 +2201,6 @@ Dhcpv6Srv::extendIA_PD(const Pkt6Ptr& query,
         }
     }
 
-    // Set up T1, T2 timers
-    ia_rsp->setT1(subnet->getT1());
-    ia_rsp->setT2(subnet->getT2());
-
     // Set per-IA context values.
     ctx.createIAContext();
     ctx.currentIA().iaid_ = ia->getIAID();
@@ -2234,7 +2246,10 @@ Dhcpv6Srv::extendIA_PD(const Pkt6Ptr& query,
 
     const bool pd_exclude_requested = requestedInORO(query, D6O_PD_EXCLUDE);
 
-    // For all the leases we have now, add the IAPREFIX with non-zero lifetimes
+    // Retains the shortest valid lease time to use
+    // for calculating T1 and T2.
+    uint32_t min_valid_lft = std::numeric_limits<uint32_t>::max();
+
     for (Lease6Collection::const_iterator l = leases.begin(); l != leases.end(); ++l) {
 
         Option6IAPrefixPtr prf(new Option6IAPrefix(D6O_IAPREFIX,
@@ -2257,6 +2272,10 @@ Dhcpv6Srv::extendIA_PD(const Pkt6Ptr& query,
             }
         }
 
+        // Check for new minimum lease time
+        if ((*l)->valid_lft_ < min_valid_lft) {
+            min_valid_lft = (*l)->valid_lft_;
+        }
 
         LOG_INFO(lease6_logger, DHCP6_PD_LEASE_RENEW)
             .arg(query->getLabel())
@@ -2303,9 +2322,11 @@ Dhcpv6Srv::extendIA_PD(const Pkt6Ptr& query,
         }
     }
 
-    // All is left is to insert the status code.
-    if (leases.empty()) {
-
+    if (!leases.empty()) {
+        // We allocated leases so we need to update T1 and T2.
+        setTeeTimes(min_valid_lft, subnet, ia_rsp);
+    } else {
+        // All is left is to insert the status code.
         // The server wasn't able allocate new lease and renew an existing
         // lease. In that case, the server sends NoPrefixAvail per RFC 8415.
         ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
@@ -3869,5 +3890,47 @@ void Dhcpv6Srv::discardPackets() {
     HooksManager::clearParkingLots();
 }
 
+void
+Dhcpv6Srv::setTeeTimes(uint32_t valid_lft, const Subnet6Ptr& subnet, Option6IAPtr& resp) {
+    uint32_t t2_time = 0;
+    // If T2 is explicitly configured we'll use try value.
+    if (!subnet->getT2().unspecified()) {
+        t2_time = subnet->getT2();
+    } else if (subnet->getCalculateTeeTimes()) {
+        // Calculating tee times is enabled, so calculated it.
+        t2_time = static_cast<uint32_t>(subnet->getT2Percent() * valid_lft);
+    }
+
+    // Send the T2 candidate value only if it's sane: to be sane it must be less than
+    // the valid life time.
+    uint32_t timer_ceiling = valid_lft;
+    if (t2_time > 0 && t2_time < timer_ceiling) {
+        resp->setT2(t2_time);
+        // When we send T2, timer ceiling for T1 becomes T2.
+        timer_ceiling = t2_time;
+    } else {
+        // It's either explicitly 0 or insane, leave it to the client
+        resp->setT2(0);
+    }
+
+    uint32_t t1_time = 0;
+    // If T1 is explicitly configured we'll use try value.
+    if (!subnet->getT1().unspecified()) {
+        t1_time = subnet->getT1();
+    } else if (subnet->getCalculateTeeTimes()) {
+        // Calculating tee times is enabled, so calculate it.
+        t1_time = static_cast<uint32_t>(subnet->getT1Percent() * valid_lft);
+    }
+
+    // Send T1 if it's sane: If we sent T2, T1 must be less than that.  If not it must be
+    // less than the valid life time.
+    if (t1_time > 0 && t1_time < timer_ceiling) {
+        resp->setT1(t1_time);
+    } else {
+        // It's either explicitly 0 or insane, leave it to the client
+        resp->setT1(0);
+    }
+}
+
 };
 };
index 1e0670cc6ec2390df59894e3de0c47d44f514b51..20bb91a1c59fc223ae62be7da8842ac3e0b36d02 100644 (file)
@@ -679,6 +679,37 @@ protected:
     void extendLeases(const Pkt6Ptr& query, Pkt6Ptr& reply,
                       AllocEngine::ClientContext6& ctx);
 
+    /// @brief Sets the T1 and T2 timers in the outbound IA
+    ///
+    /// This method determines the values for both the T1 and T2
+    /// timers for the given IA. It is influenced by the
+    /// lease's subnet's values for renew-timer, rebind-timer,
+    /// calculate-tee-times, t1-percent, and t2-percent as follows:
+    ///
+    /// T2:
+    ///
+    /// The candidate value for T2 defaults to zero. If the rebind-timer value
+    /// is specified then use it.  If not and calculate-tee-times is true, then
+    /// use the value given by: valid lease time * t2-percent.
+    ///
+    /// If the T2 candidate is less than the valid lease time use it,
+    /// otherwise set T2 to zero.
+    ///
+    /// T1:
+    ///
+    /// The candidate value for T1 defaults to zero. If the renew-timer value
+    /// is specified then use it. If not and calculate-tee-times is true, then
+    /// use the value given by: valid lease time * t1-percent.
+    ///
+    /// The T1 candidate will be used provided it less than the T2 when T2 is
+    /// is greater than zero. When T2 is zero then the T1 candidate must be
+    /// less than the valid lease time, otherwise T1 will be set to zero.
+    ///
+    /// @param lease lease being assigned to the client
+    /// @param subnet the subnet to which the lease belongs
+    /// @param resp outbound IA option in which the timers are set.
+    void setTeeTimes(uint32_t valid_lft, const Subnet6Ptr& subnet, Option6IAPtr& resp);
+
     /// @brief Attempts to release received addresses
     ///
     /// It iterates through received IA_NA options and attempts to release
index b8fe023e2e0875031e679bb746a09f74b11a471c..c2d80a85ec68c57fafd1a2d4e8468475dcb7ff5c 100644 (file)
@@ -2452,6 +2452,148 @@ TEST_F(Dhcpv6SrvTest, truncatedVIVSO) {
     ASSERT_TRUE(adv);
 }
 
+// Check that T1 and T2 values are set correctly.
+TEST_F(Dhcpv6SrvTest, calculateTeeTimers) {
+    NakedDhcpv6Srv srv(0);
+
+    // Struct for describing an individual timer test scenario
+    struct TimerTest {
+        // logged test description
+        std::string description_;
+        // configured value for subnet's T1
+        Triplet<uint32_t> cfg_t1_;
+        // configured value for subnet's T1
+        Triplet<uint32_t> cfg_t2_;
+        // whether or not calculation is enabled
+        bool calculate_tee_times;
+        // configured value for sunbet's t1_percent.
+        double t1_percent_;
+        // configured value for sunbet's t2_percent.
+        double t2_percent_;
+        // expected value for T1 in server response.
+        // A value of 0 means server should not have sent T1.
+        uint32_t t1_exp_value_;
+        // expected value for T2 in server response.
+        // A value of 0 means server should not have sent T2.
+        uint32_t t2_exp_value_;
+    };
+
+    // Handy constants
+    Triplet<uint32_t> unspecified;
+    Triplet<uint32_t> valid_lft(1000);
+    bool calculate_enabled = true;
+
+    // Test scenarios
+    std::vector<TimerTest> tests = {
+    // Tests with calculation disabled
+    {
+        "T1 and T2 calculated",
+        unspecified, unspecified,
+        calculate_enabled,
+        0.4, 0.8,
+        400, 800
+    },
+    {
+        "T1 and T2 specified insane",
+        valid_lft + 1,  valid_lft + 2,
+        calculate_enabled,
+        0.4, 0.8,
+        0, 0
+    },
+    {
+        "T1 should be calculated, T2 specified",
+        unspecified, valid_lft - 1,
+        calculate_enabled,
+        0.4, 0.8,
+        400, valid_lft - 1
+    },
+    {
+        "T1 specified, T2 should be calculated",
+        299, unspecified,
+        calculate_enabled,
+        0.4, 0.8,
+        299, 800
+    },
+    {
+        "T1 specified insane (> T2), T2 should be calculated",
+        valid_lft - 1, unspecified,
+        calculate_enabled,
+        0.4, 0.8,
+        0, 800
+    },
+    // Tests with calculation disabled
+    {
+        "T1 and T2 unspecified, (no calculation)",
+        unspecified, unspecified,
+        !calculate_enabled,
+        0.4, 0.8,
+        0, 0
+    },
+    {
+        "T1 specified, T2 unspecified (no calculation)",
+        valid_lft - 1, unspecified,
+        !calculate_enabled,
+        0.4, 0.8,
+        valid_lft - 1, 0
+    },
+    {
+        "both T1 and T2 specified (no calculation)",
+        valid_lft - 2, valid_lft - 1,
+        !calculate_enabled,
+        0.4, 0.8,
+        valid_lft - 2, valid_lft - 1
+    },
+    {
+        "T1 specified insane (>= lease T2), T2 specified (no calculation)",
+        valid_lft - 1, valid_lft - 1,
+        !calculate_enabled,
+        0.4, 0.8,
+        0, valid_lft - 1
+    },
+    {
+        "T1 specified insane (>= lease time), T2 not specified (no calculation)",
+        valid_lft, unspecified,
+        !calculate_enabled,
+        0.4, 0.8,
+        0, 0
+    }
+    };
+
+    // Calculation is enabled for all the scenarios.
+    subnet_->setValid(valid_lft);
+
+    // Create a discover packet to use
+    Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
+    sol->setRemoteAddr(IOAddress("fe80::abcd"));
+    sol->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
+    OptionPtr clientid = generateClientId();
+    sol->addOption(clientid);
+    sol->setIface("eth0");
+
+    // Iterate over the test scenarios.
+    for (auto test = tests.begin(); test != tests.end(); ++test) {
+        {
+            SCOPED_TRACE((*test).description_);
+            // Configure sunbet for the scenario
+            subnet_->setT1((*test).cfg_t1_);
+            subnet_->setT2((*test).cfg_t2_);
+            subnet_->setCalculateTeeTimes((*test).calculate_tee_times);
+            subnet_->setT1Percent((*test).t1_percent_);
+            subnet_->setT2Percent((*test).t2_percent_);
+            AllocEngine::ClientContext6 ctx;
+            bool drop = false;
+            srv.initContext(sol, ctx, drop);
+            ASSERT_FALSE(drop);
+            Pkt6Ptr reply = srv.processSolicit(ctx);
+
+            // check if we get response at all
+            checkResponse(reply, DHCPV6_ADVERTISE, 1234);
+
+            // check that IA_NA was returned and T1 and T2 are correct.
+            checkIA_NA(reply, 234, (*test).t1_exp_value_, (*test).t2_exp_value_);
+        }
+    }
+}
 
 /// @todo: Add more negative tests for processX(), e.g. extend sanityCheck() test
 /// to call processX() methods.
index 67e88fa597ac8d51d5194ac32569ea49df9ce8cd..33ec8e4444300fcf82806510aad82beabec13b4d 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2013-2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2019 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
@@ -566,8 +566,6 @@ public:
     /// The following values are used by the callout to override
     /// renewed lease parameters
     static const uint32_t override_iaid_;
-    static const uint32_t override_t1_;
-    static const uint32_t override_t2_;
     static const uint32_t override_preferred_;
     static const uint32_t override_valid_;
 
@@ -587,8 +585,6 @@ public:
         EXPECT_TRUE(callback_lease6_);
         // Let's override some values in the lease
         callback_lease6_->iaid_          = override_iaid_;
-        callback_lease6_->t1_            = override_t1_;
-        callback_lease6_->t2_            = override_t2_;
         callback_lease6_->preferred_lft_ = override_preferred_;
         callback_lease6_->valid_lft_     = override_valid_;
 
@@ -596,8 +592,6 @@ public:
         EXPECT_TRUE(callback_ia_na_);
         // Override the values to be sent to the client as well
         callback_ia_na_->setIAID(override_iaid_);
-        callback_ia_na_->setT1(override_t1_);
-        callback_ia_na_->setT2(override_t2_);
 
         callback_argument_names_ = callout_handle.getArgumentNames();
         return (0);
@@ -651,8 +645,6 @@ public:
         EXPECT_TRUE(callback_lease6_);
         // Let's override some values in the lease
         callback_lease6_->iaid_          = override_iaid_;
-        callback_lease6_->t1_            = override_t1_;
-        callback_lease6_->t2_            = override_t2_;
         callback_lease6_->preferred_lft_ = override_preferred_;
         callback_lease6_->valid_lft_     = override_valid_;
 
@@ -660,8 +652,6 @@ public:
         EXPECT_TRUE(callback_ia_na_);
         // Override the values to be sent to the client as well
         callback_ia_na_->setIAID(override_iaid_);
-        callback_ia_na_->setT1(override_t1_);
-        callback_ia_na_->setT2(override_t2_);
 
         callback_argument_names_ = callout_handle.getArgumentNames();
         return (0);
@@ -949,8 +939,6 @@ public:
 // The following parameters are used by callouts to override
 // renewed lease parameters
 const uint32_t HooksDhcpv6SrvTest::override_iaid_ = 1000;
-const uint32_t HooksDhcpv6SrvTest::override_t1_ = 1001;
-const uint32_t HooksDhcpv6SrvTest::override_t2_ = 1002;
 const uint32_t HooksDhcpv6SrvTest::override_preferred_ = 1003;
 const uint32_t HooksDhcpv6SrvTest::override_valid_ = 1004;
 
@@ -2704,10 +2692,8 @@ TEST_F(HooksDhcpv6SrvTest, basicLease6Renew) {
                                                         addr);
     ASSERT_TRUE(l);
 
-    // Check that T1, T2, preferred, valid and cltt really set and not using
+    // Check that preferred, valid and cltt really set and not using
     // previous (500, 501, etc.) values
-    EXPECT_NE(l->t1_, subnet_->getT1());
-    EXPECT_NE(l->t2_, subnet_->getT2());
     EXPECT_NE(l->preferred_lft_, subnet_->getPreferred());
     EXPECT_NE(l->valid_lft_, subnet_->getValid());
     EXPECT_NE(l->cltt_, time(NULL));
@@ -2808,10 +2794,8 @@ TEST_F(HooksDhcpv6SrvTest, leaseUpdateLease6Renew) {
                                                         addr);
     ASSERT_TRUE(l);
 
-    // Check that T1, T2, preferred, valid and cltt really set and not using
+    // Check that preferred, valid and cltt really set and not using
     // previous (500, 501, etc.) values
-    EXPECT_NE(l->t1_, subnet_->getT1());
-    EXPECT_NE(l->t2_, subnet_->getT2());
     EXPECT_NE(l->preferred_lft_, subnet_->getPreferred());
     EXPECT_NE(l->valid_lft_, subnet_->getValid());
     EXPECT_NE(l->cltt_, time(NULL));
@@ -2830,6 +2814,15 @@ TEST_F(HooksDhcpv6SrvTest, leaseUpdateLease6Renew) {
     // Server-id is mandatory in RENEW
     req->addOption(srv.getServerID());
 
+    // Turn on tee time calculation so we can see the effect of overriding
+    // the lease life time.
+    subnet_->setCalculateTeeTimes(true);
+    Triplet<uint32_t> unspecified;
+    subnet_->setT1(unspecified);
+    subnet_->setT2(unspecified);
+    subnet_->setT1Percent(0.60);
+    subnet_->setT2Percent(0.80);
+
     // Pass it to the server and hope for a REPLY
     Pkt6Ptr reply = srv.processRenew(req);
     ASSERT_TRUE(reply);
@@ -2841,7 +2834,7 @@ TEST_F(HooksDhcpv6SrvTest, leaseUpdateLease6Renew) {
     ASSERT_TRUE(tmp);
 
     // Check that IA_NA was returned and that there's an address included
-    boost::shared_ptr<Option6IAAddr> addr_opt = checkIA_NA(reply, 1000, 1001, 1002);
+    boost::shared_ptr<Option6IAAddr> addr_opt = checkIA_NA(reply, 1000, 602, 803);
 
     ASSERT_TRUE(addr_opt);
     // Check that the lease is really in the database
@@ -2849,14 +2842,10 @@ TEST_F(HooksDhcpv6SrvTest, leaseUpdateLease6Renew) {
     ASSERT_TRUE(l);
 
     // Check that we chose the distinct override values
-    ASSERT_NE(override_t1_,        subnet_->getT1());
-    ASSERT_NE(override_t2_,        subnet_->getT2());
     ASSERT_NE(override_preferred_, subnet_->getPreferred());
     EXPECT_NE(override_valid_,     subnet_->getValid());
 
-    // Check that T1, T2, preferred, valid were overridden the the callout
-    EXPECT_EQ(override_t1_, l->t1_);
-    EXPECT_EQ(override_t2_, l->t2_);
+    // Check that preferred, valid were overridden the the callout
     EXPECT_EQ(override_preferred_, l->preferred_lft_);
     EXPECT_EQ(override_valid_, l->valid_lft_);
 
@@ -2904,10 +2893,8 @@ TEST_F(HooksDhcpv6SrvTest, skipLease6Renew) {
                                                         addr);
     ASSERT_TRUE(l);
 
-    // Check that T1, T2, preferred, valid and cltt really set and not using
+    // Check that preferred, valid and cltt are really set and not using
     // previous (500, 501, etc.) values
-    EXPECT_NE(l->t1_, subnet_->getT1());
-    EXPECT_NE(l->t2_, subnet_->getT2());
     EXPECT_NE(l->preferred_lft_, subnet_->getPreferred());
     EXPECT_NE(l->valid_lft_, subnet_->getValid());
     EXPECT_NE(l->cltt_, time(NULL));
@@ -2937,8 +2924,6 @@ TEST_F(HooksDhcpv6SrvTest, skipLease6Renew) {
 
     // Check that the old values are still there and they were not
     // updated by the renewal
-    EXPECT_NE(l->t1_, subnet_->getT1());
-    EXPECT_NE(l->t2_, subnet_->getT2());
     EXPECT_NE(l->preferred_lft_, subnet_->getPreferred());
     EXPECT_NE(l->valid_lft_, subnet_->getValid());
     EXPECT_NE(l->cltt_, time(NULL));
@@ -3831,10 +3816,8 @@ TEST_F(HooksDhcpv6SrvTest, basicLease6Rebind) {
                                                         addr);
     ASSERT_TRUE(l);
 
-    // Check that T1, T2, preferred, valid and cltt really set and not using
+    // Check that preferred, valid and cltt really set and not using
     // previous (500, 501, etc.) values
-    EXPECT_NE(l->t1_, subnet_->getT1());
-    EXPECT_NE(l->t2_, subnet_->getT2());
     EXPECT_NE(l->preferred_lft_, subnet_->getPreferred());
     EXPECT_NE(l->valid_lft_, subnet_->getValid());
     EXPECT_NE(l->cltt_, time(NULL));
@@ -3932,8 +3915,6 @@ TEST_F(HooksDhcpv6SrvTest, leaseUpdateLease6Rebind) {
 
     // Check that T1, T2, preferred, valid and cltt really set and not using
     // previous (500, 501, etc.) values
-    EXPECT_NE(l->t1_, subnet_->getT1());
-    EXPECT_NE(l->t2_, subnet_->getT2());
     EXPECT_NE(l->preferred_lft_, subnet_->getPreferred());
     EXPECT_NE(l->valid_lft_, subnet_->getValid());
     EXPECT_NE(l->cltt_, time(NULL));
@@ -3949,6 +3930,15 @@ TEST_F(HooksDhcpv6SrvTest, leaseUpdateLease6Rebind) {
     req->addOption(ia);
     req->addOption(clientid);
 
+    // Turn on tee time calculation so we can see the effect of overriding
+    // the lease life time.
+    subnet_->setCalculateTeeTimes(true);
+    Triplet<uint32_t> unspecified;
+    subnet_->setT1(unspecified);
+    subnet_->setT2(unspecified);
+    subnet_->setT1Percent(0.60);
+    subnet_->setT2Percent(0.80);
+
     // Pass it to the server and hope for a REPLY
     Pkt6Ptr reply = srv.processRebind(req);
     ASSERT_TRUE(reply);
@@ -3960,7 +3950,8 @@ TEST_F(HooksDhcpv6SrvTest, leaseUpdateLease6Rebind) {
     ASSERT_TRUE(tmp);
 
     // Check that IA_NA was returned and that there's an address included
-    boost::shared_ptr<Option6IAAddr> addr_opt = checkIA_NA(reply, 1000, 1001, 1002);
+    // Note we also verify that T1 and T2 were calculated correctly.
+    boost::shared_ptr<Option6IAAddr> addr_opt = checkIA_NA(reply, 1000, 602, 803);
 
     ASSERT_TRUE(addr_opt);
     // Check that the lease is really in the database
@@ -3968,14 +3959,10 @@ TEST_F(HooksDhcpv6SrvTest, leaseUpdateLease6Rebind) {
     ASSERT_TRUE(l);
 
     // Check that we chose the distinct override values
-    ASSERT_NE(override_t1_,        subnet_->getT1());
-    ASSERT_NE(override_t2_,        subnet_->getT2());
     ASSERT_NE(override_preferred_, subnet_->getPreferred());
     EXPECT_NE(override_valid_,     subnet_->getValid());
 
-    // Check that T1, T2, preferred, valid were overridden the the callout
-    EXPECT_EQ(override_t1_, l->t1_);
-    EXPECT_EQ(override_t2_, l->t2_);
+    // Check that preferred and  valid were overridden in the callout
     EXPECT_EQ(override_preferred_, l->preferred_lft_);
     EXPECT_EQ(override_valid_, l->valid_lft_);
 
@@ -4023,10 +4010,8 @@ TEST_F(HooksDhcpv6SrvTest, skipLease6Rebind) {
                                                         addr);
     ASSERT_TRUE(l);
 
-    // Check that T1, T2, preferred, valid and cltt really set and not using
+    // Check that preferred, valid and cltt really set and not using
     // previous (500, 501, etc.) values
-    EXPECT_NE(l->t1_, subnet_->getT1());
-    EXPECT_NE(l->t2_, subnet_->getT2());
     EXPECT_NE(l->preferred_lft_, subnet_->getPreferred());
     EXPECT_NE(l->valid_lft_, subnet_->getValid());
     EXPECT_NE(l->cltt_, time(NULL));
@@ -4053,8 +4038,6 @@ TEST_F(HooksDhcpv6SrvTest, skipLease6Rebind) {
 
     // Check that the old values are still there and they were not
     // updated by the rebinding
-    EXPECT_NE(l->t1_, subnet_->getT1());
-    EXPECT_NE(l->t2_, subnet_->getT2());
     EXPECT_NE(l->preferred_lft_, subnet_->getPreferred());
     EXPECT_NE(l->valid_lft_, subnet_->getValid());
     EXPECT_NE(l->cltt_, time(NULL));