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
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
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();
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");
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);
/// @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)
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);
" \"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"
" \"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"
" \"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"
" {\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"
" \"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"
" {\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"