From: Francis Dupont Date: Tue, 21 May 2019 08:56:52 +0000 (+0200) Subject: [295-min-max-lease-time-configuration-options] Finished DHCPv6 server unit tests X-Git-Tag: Kea-1.6.0-beta2~243 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8d0f10e6fd436d7dc06de8acfd406306b2824d70;p=thirdparty%2Fkea.git [295-min-max-lease-time-configuration-options] Finished DHCPv6 server unit tests --- diff --git a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc index 4eb3fcd858..8aa5d0e11b 100644 --- a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc +++ b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc @@ -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 diff --git a/src/bin/dhcp6/tests/dhcp6_test_utils.cc b/src/bin/dhcp6/tests/dhcp6_test_utils.cc index fc754cb953..9ff1706544 100644 --- a/src/bin/dhcp6/tests/dhcp6_test_utils.cc +++ b/src/bin/dhcp6/tests/dhcp6_test_utils.cc @@ -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(2000, 3000, 4000)); subnet_->setValid(Triplet(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); diff --git a/src/bin/dhcp6/tests/dhcp6_test_utils.h b/src/bin/dhcp6/tests/dhcp6_test_utils.h index 7eb960a715..471a2a97de 100644 --- a/src/bin/dhcp6/tests/dhcp6_test_utils.h +++ b/src/bin/dhcp6/tests/dhcp6_test_utils.h @@ -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); diff --git a/src/bin/dhcp6/tests/get_config_unittest.cc b/src/bin/dhcp6/tests/get_config_unittest.cc index 042a525621..1420529705 100644 --- a/src/bin/dhcp6/tests/get_config_unittest.cc +++ b/src/bin/dhcp6/tests/get_config_unittest.cc @@ -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"