]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[295-min-max-lease-time-configuration-options] Finished DHCPv6 server unit tests
authorFrancis Dupont <fdupont@isc.org>
Tue, 21 May 2019 08:56:52 +0000 (10:56 +0200)
committerFrancis Dupont <fdupont@isc.org>
Sat, 22 Jun 2019 14:05:23 +0000 (10:05 -0400)
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
src/bin/dhcp6/tests/dhcp6_test_utils.cc
src/bin/dhcp6/tests/dhcp6_test_utils.h
src/bin/dhcp6/tests/get_config_unittest.cc

index 4eb3fcd85846721351980c0b3fc67f98d34d64af..8aa5d0e11b47abe8a75d7b93476383c0fbb91257 100644 (file)
@@ -1269,16 +1269,16 @@ TEST_F(Dhcpv6SrvTest, RenewSomeoneElesesLease) {
 TEST_F(Dhcpv6SrvTest, defaultLifetimeRenew) {
     // Defaults are 3000 and 4000.
     testRenewBasic(Lease::TYPE_NA, "2001:db8:1:1::cafe:babe",
-                   "2001:db8:1:1::cafe:babe", 128, true,
-                   0, 0, 3000, 4000);
+                   "2001:db8:1:1::cafe:babe", 128,
+                   true, false, 0, 0, 3000, 4000);
 }
 
 // This test verifies that a renewal returns specified lifetimes when
-// the client adds an IAADDR sub option with in-bound lifetime hints.
+// the client adds an IAPREFIX sub option with in-bound lifetime hints.
 TEST_F(Dhcpv6SrvTest, hintLifetimeRenew) {
     testRenewBasic(Lease::TYPE_PD, "2001:db8:1:2::",
-                   "2001:db8:1:2::", pd_pool_->getLength(), true,
-                   2999, 4001, 2999, 4001);
+                   "2001:db8:1:2::", pd_pool_->getLength(),
+                   true, false, 2999, 4001, 2999, 4001);
 }
 
 // This test verifies that a renewal returns min lifetimes when
@@ -1286,17 +1286,62 @@ TEST_F(Dhcpv6SrvTest, hintLifetimeRenew) {
 TEST_F(Dhcpv6SrvTest, minLifetimeRenew) {
     // Min values are 2000 and 3000.
     testRenewBasic(Lease::TYPE_NA, "2001:db8:1:1::cafe:babe",
-                   "2001:db8:1:1::cafe:babe", 128, true,
-                   1000, 2000, 2000, 3000);
+                   "2001:db8:1:1::cafe:babe", 128,
+                   true, false, 1000, 2000, 2000, 3000);
 }
 
 // This test verifies that a renewal returns max ifetimes when
-// the client adds an IAADDR sub option with too large lifetime hints.
+// the client adds an IAPREFIX sub option with too large lifetime hints.
 TEST_F(Dhcpv6SrvTest, maxLifetimeRenew) {
     // Max  values are 4000 and 5000.
     testRenewBasic(Lease::TYPE_PD, "2001:db8:1:2::",
-                   "2001:db8:1:2::", pd_pool_->getLength(), true,
-                   5000, 6000, 4000, 5000);
+                   "2001:db8:1:2::", pd_pool_->getLength(),
+                   true, false, 5000, 6000, 4000, 5000);
+}
+
+// This test is a mixed of FqdnDhcpv6SrvTest.processRequestReuseExpiredLease
+// and testRenewBasic. The idea is to force the reuse of an expired lease
+// so the allocation engine reuseExpiredLease routine is called instead
+// of the two other routines computing lease lifetimes createLease6
+// and extendLease6.
+TEST_F(Dhcpv6SrvTest, reuseExpiredBasic) {
+    testRenewBasic(Lease::TYPE_NA, "2001:db8:1:1::cafe:babe",
+                   "2001:db8:1:1::cafe:babe", 128, true, true);
+}
+
+// This test verifies that an expired reuse returns default lifetimes when
+// the client adds an IAADDR sub option with zero lifetime hints.
+TEST_F(Dhcpv6SrvTest, defaultLifetimeReuseExpired) {
+    // Defaults are 3000 and 4000.
+    testRenewBasic(Lease::TYPE_NA, "2001:db8:1:1::cafe:babe",
+                   "2001:db8:1:1::cafe:babe", 128,
+                   true, true, 0, 0, 3000, 4000);
+}
+
+// This test verifies that an expired reuse returns specified lifetimes when
+// the client adds an IAADDR sub option with in-bound lifetime hints.
+TEST_F(Dhcpv6SrvTest, hintLifetimeReuseExpired) {
+    testRenewBasic(Lease::TYPE_NA, "2001:db8:1:1::cafe:babe",
+                   "2001:db8:1:1::cafe:babe", 128,
+                   true, true, 2999, 4001, 2999, 4001);
+}
+
+// This test verifies that an expired reuse returns min lifetimes when
+// the client adds an IAADDR sub option with too small lifetime hints.
+TEST_F(Dhcpv6SrvTest, minLifetimeReuseExpired) {
+    // Min values are 2000 and 3000.
+    testRenewBasic(Lease::TYPE_NA, "2001:db8:1:1::cafe:babe",
+                   "2001:db8:1:1::cafe:babe", 128,
+                   true, true, 1000, 2000, 2000, 3000);
+}
+
+// This test verifies that an expired reuse returns max lifetimes when
+// the client adds an IAADDR sub option with too large lifetime hints.
+TEST_F(Dhcpv6SrvTest, maxLifetimeReuseExpired) {
+    // Max  values are 4000 and 5000.
+    testRenewBasic(Lease::TYPE_NA, "2001:db8:1:1::cafe:babe",
+                   "2001:db8:1:1::cafe:babe", 128,
+                   true, true, 5000, 6000, 4000, 5000);
 }
 
 // This test verifies that incoming (positive) RELEASE with address can be
index fc754cb95330898aff74abc8bd9f37ba9170e431..9ff1706544977e381ae3caeb2bbfcc48819c9788 100644 (file)
@@ -247,22 +247,38 @@ Dhcpv6SrvTest::testRenewBasic(Lease::Type type,
                               const std::string& renew_addr,
                               const uint8_t prefix_len,
                               bool insert_before_renew,
+                              bool expire_before_renew,
                               uint32_t hint_pref,
                               uint32_t hint_valid,
                               uint32_t expected_pref,
                               uint32_t expected_valid) {
     NakedDhcpv6Srv srv(0);
 
+    const IOAddress existing(existing_addr);
+    const IOAddress renew(renew_addr);
+    const uint32_t iaid = 234;
+
+    // To reuse an expired lease we need a subnet with a pool that
+    // consists of exactly one address. This address will get expired
+    // and then be reused.
+    if (expire_before_renew) {
+        CfgMgr::instance().clear();
+        subnet_.reset(new Subnet6(IOAddress("2001:db8:1:1::"),
+                                  48, 1000, 2000, 3000, 4000));
+        subnet_->setIface("eth0");
+        pool_.reset(new Pool6(Lease::TYPE_NA, existing, existing));
+        subnet_->addPool(pool_);
+        CfgMgr::instance().setFamily(AF_INET6);
+        CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet_);
+        CfgMgr::instance().commit();
+    }
+
     // Use intervals for lifetimes for lifetime tests.
     if (hint_pref != 300 || hint_valid != 500) {
         subnet_->setPreferred(Triplet<uint32_t>(2000, 3000, 4000));
         subnet_->setValid(Triplet<uint32_t>(3000, 4000, 5000));
     }
 
-    const IOAddress existing(existing_addr);
-    const IOAddress renew(renew_addr);
-    const uint32_t iaid = 234;
-
     // Generate client-id also duid_
     OptionPtr clientid = generateClientId();
 
@@ -289,14 +305,37 @@ Dhcpv6SrvTest::testRenewBasic(Lease::Type type,
         EXPECT_NE(l->cltt_, time(NULL));
     }
 
+    if (expire_before_renew) {
+        // The lease must exist.
+        ASSERT_TRUE(l);
+
+        // Change the subnet identifier to make the allocation engine to
+        // not treat the lease as being renewed by the same client,
+        // but to treat it as expired lease to be reused.
+        ++l->subnet_id_;
+
+        // Move the cllt back in time and make sure that the lease got expired.
+        l->cltt_ = time(NULL) - 10;
+        l->valid_lft_ = 5;
+        ASSERT_TRUE(l->expired());
+        // Update the lease in the lease database.
+        LeaseMgrFactory::instance().updateLease6(l);
+    }
+
     Pkt6Ptr req;
+    uint8_t message_type = DHCPV6_RENEW;
+    // Use a request vs a renew for getting an expired lease without
+    // extending it. i.e. not call extendLease6 after reuseExpiredLease.
+    if (expire_before_renew) {
+        message_type = DHCPV6_REQUEST;
+    }
 
     if (hint_pref == 300 && hint_valid == 500) {
-        req = createMessage(DHCPV6_RENEW, type, IOAddress(renew_addr),
+        req = createMessage(message_type, type, IOAddress(renew_addr),
                             prefix_len, iaid);
     } else {
         // from createMessage
-        req.reset(new Pkt6(DHCPV6_RENEW, 1234));
+        req.reset(new Pkt6(message_type, 1234));
         req->setRemoteAddr(IOAddress("fe80::abcd"));
         req->setIface("eth0");
 
@@ -329,7 +368,12 @@ Dhcpv6SrvTest::testRenewBasic(Lease::Type type,
     req->addOption(srv.getServerID());
 
     // Pass it to the server and hope for a REPLY
-    Pkt6Ptr reply = srv.processRenew(req);
+    Pkt6Ptr reply;
+    if (!expire_before_renew) {
+        reply = srv.processRenew(req);
+    } else {
+        reply = srv.processRequest(req);
+    }
 
     // Check if we get response at all
     checkResponse(reply, DHCPV6_REPLY, 1234);
index 7eb960a715147657d670377933f82dc1e193e64f..471a2a97de7231a5732d4186539052a5f98e63ce 100644 (file)
@@ -692,6 +692,8 @@ public:
     /// @param prefix_len length of the prefix (128 for addresses)
     /// @param insert_before_renew should the lease be inserted into the database
     ///        before we try renewal?
+    /// @param expire_before_renew should the lease be expired before we try
+    ///        renewal?
     /// @param hint_pref preferred lifetime hint (default is 300)
     /// @param hint_valid valid lifetime hint (default is 500)
     /// @param expected_pref expected preferred lifetime (zero means not check)
@@ -701,6 +703,7 @@ public:
                    const std::string& existing_addr,
                    const std::string& renew_addr, const uint8_t prefix_len,
                    bool insert_before_renew = true,
+                   bool expire_before_renew = false,
                    uint32_t hint_pref = 300, uint32_t hint_valid = 500,
                    uint32_t expected_pref = 0, uint32_t expected_valid = 0);
 
index 042a5256214c32f5f6c705d014d8e415b05d7902..1420529705da3db96a475bfe0329c3bb296f3b0f 100644 (file)
@@ -87,6 +87,10 @@ const char* EXTRACTED_CONFIGS[] = {
 "            \"interfaces\": [ \"*\" ],\n"
 "            \"re-detect\": false\n"
 "        },\n"
+"        \"max-preferred-lifetime\": 4000,\n"
+"        \"max-valid-lifetime\": 5000,\n"
+"        \"min-preferred-lifetime\": 2000,\n"
+"        \"min-valid-lifetime\": 3000,\n"
 "        \"preferred-lifetime\": 3000,\n"
 "        \"rebind-timer\": 2000,\n"
 "        \"renew-timer\": 1000,\n"
@@ -252,11 +256,19 @@ const char* EXTRACTED_CONFIGS[] = {
 "            \"interfaces\": [ \"*\" ],\n"
 "            \"re-detect\": false\n"
 "        },\n"
+"        \"max-preferred-lifetime\": 4000,\n"
+"        \"max-valid-lifetime\": 5000,\n"
+"        \"min-preferred-lifetime\": 2000,\n"
+"        \"min-valid-lifetime\": 3000,\n"
 "        \"preferred-lifetime\": 3000,\n"
 "        \"rebind-timer\": 2000,\n"
 "        \"renew-timer\": 1000,\n"
 "        \"subnet6\": [\n"
 "            {\n"
+"                \"max-preferred-lifetime\": 4,\n"
+"                \"max-valid-lifetime\": 5,\n"
+"                \"min-preferred-lifetime\": 2,\n"
+"                \"min-valid-lifetime\": 3,\n"
 "                \"pools\": [\n"
 "                    {\n"
 "                        \"pool\": \"2001:db8:1::1 - 2001:db8:1::ffff\"\n"
@@ -1955,6 +1967,10 @@ 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"
 "        \"option-data\": [ ],\n"
 "        \"option-def\": [ ],\n"
 "        \"preferred-lifetime\": 3000,\n"
@@ -2047,6 +2063,10 @@ const char* UNPARSED_CONFIGS[] = {
 "            {\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-pools\": [ ],\n"
 "                \"pools\": [\n"
@@ -2624,6 +2644,10 @@ 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"
 "        \"option-data\": [ ],\n"
 "        \"option-def\": [ ],\n"
 "        \"preferred-lifetime\": 3000,\n"
@@ -2648,6 +2672,10 @@ const char* UNPARSED_CONFIGS[] = {
 "            {\n"
 "                \"calculate-tee-times\": true,\n"
 "                \"id\": 1,\n"
+"                \"max-preferred-lifetime\": 4,\n"
+"                \"max-valid-lifetime\": 5,\n"
+"                \"min-preferred-lifetime\": 2,\n"
+"                \"min-valid-lifetime\": 3,\n"
 "                \"option-data\": [ ],\n"
 "                \"pd-pools\": [ ],\n"
 "                \"pools\": [\n"