diff --git a/doc/guide/dhcp4-srv.xml b/doc/guide/dhcp4-srv.xml index b17cd80b86..b32566c63f 100644 --- a/doc/guide/dhcp4-srv.xml +++ b/doc/guide/dhcp4-srv.xml @@ -219,16 +219,20 @@ file. Moving onto the DHCPv4 configuration elements, the first few elements define some global parameters. valid-lifetime -defines for how long the addresses (leases) given out by the +defines how long the addresses (leases) given out by the server are valid. If nothing changes, a client that got an address is allowed to use it for 4000 seconds. (Note that integer numbers are specified as is, without any quotes around them.) renew-timer and rebind-timer are values (also in seconds) that define T1 and T2 timers that govern when the client will begin the renewal and -rebind procedures. Note that renew-timer and -rebind-timer are optional. If they are not specified the -client will select values for T1 and T2 timers according to the -RFC 2131. +rebind procedures. Both renew-timer and +rebind-timer are optional. The server will only send +rebind-timer to the client, via DHPv4 option code 59, if it is less than +valid-lifetime; and it will only send renew-timer, via DHCPv4 option code 58, +if it is less than rebind-timer (or valid-lifetime if rebind-timer was not +specified). In their absence, the client should select values for T1 and T2 +timers according to the RFC 2131. The interfaces-config map specifies the server configuration concerning the network interfaces, on which the server should @@ -4322,15 +4326,15 @@ autogenerated IDs are not stable across configuration changes. If "relay" is specified, the "ip-addresses" parameter within it is mandatory. - - + + - As of Kea 1.4, the "ip-address" parameter has been deprecated in favor - of "ip-addresses" which supports specifying a list of addresses. + As of Kea 1.4, the "ip-address" parameter has been deprecated in favor + of "ip-addresses" which supports specifying a list of addresses. Configuration parsing, will honor the singular form for now but users are encouraged to migrate. - + diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc index 6b8f365e97..72f49d4055 100644 --- a/src/bin/dhcp4/dhcp4_srv.cc +++ b/src/bin/dhcp4/dhcp4_srv.cc @@ -2137,21 +2137,32 @@ Dhcpv4Srv::assignLease(Dhcpv4Exchange& ex) { // Subnet mask (type 1) resp->addOption(getNetmaskOption(subnet)); - // renewal-timer (type 58) - if (!subnet->getT1().unspecified()) { + // rebind timer (type 59) - if specified then send it only it if + // it is lease than lease life time. Note we "sanity" check T1 + // and T2 against lease lifetime here in event the lifetime has + // been altered somewhere along the line. + uint32_t timer_ceiling = lease->valid_lft_; + if ((!subnet->getT2().unspecified()) && + (subnet->getT2() < timer_ceiling)) { + OptionUint32Ptr t2(new OptionUint32(Option::V4, + DHO_DHCP_REBINDING_TIME, + subnet->getT2())); + resp->addOption(t2); + + // If T2 is specified, then it becomes the ceiling for T1 + timer_ceiling = subnet->getT2(); + } + + // renewal-timer (type 58) - if specified then send it only if + // it is less than the ceiling (T2 if given, lease life time if not) + if ((!subnet->getT1().unspecified()) && + (subnet->getT1() < timer_ceiling)) { OptionUint32Ptr t1(new OptionUint32(Option::V4, DHO_DHCP_RENEWAL_TIME, subnet->getT1())); resp->addOption(t1); } - // rebind timer (type 59) - if (!subnet->getT2().unspecified()) { - OptionUint32Ptr t2(new OptionUint32(Option::V4, - DHO_DHCP_REBINDING_TIME, - subnet->getT2())); - resp->addOption(t2); - } // Create NameChangeRequests if DDNS is enabled and this is a // real allocation. diff --git a/src/bin/dhcp4/tests/config_parser_unittest.cc b/src/bin/dhcp4/tests/config_parser_unittest.cc index e1e291e815..1b02bfb8b8 100644 --- a/src/bin/dhcp4/tests/config_parser_unittest.cc +++ b/src/bin/dhcp4/tests/config_parser_unittest.cc @@ -826,15 +826,14 @@ TEST_F(Dhcp4ParserTest, unspecifiedRenewTimer) { Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()-> getCfgSubnets4()->selectSubnet(IOAddress("192.0.2.200")); ASSERT_TRUE(subnet); - EXPECT_FALSE(subnet->getT1().unspecified()); + + EXPECT_TRUE(subnet->getT1().unspecified()); EXPECT_FALSE(subnet->getT2().unspecified()); - EXPECT_EQ(900, subnet->getT1()); // that's the default value EXPECT_EQ(2000, subnet->getT2()); EXPECT_EQ(4000, subnet->getValid()); // Check that subnet-id is 1 EXPECT_EQ(1, subnet->getID()); - } /// Check that the rebind-timer doesn't have to be specified, in which case @@ -863,8 +862,7 @@ TEST_F(Dhcp4ParserTest, unspecifiedRebindTimer) { ASSERT_TRUE(subnet); EXPECT_FALSE(subnet->getT1().unspecified()); EXPECT_EQ(1000, subnet->getT1()); - EXPECT_FALSE(subnet->getT2().unspecified()); - EXPECT_EQ(1800, subnet->getT2()); // that's the default value + EXPECT_TRUE(subnet->getT2().unspecified()); EXPECT_EQ(4000, subnet->getValid()); // Check that subnet-id is 1 diff --git a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc index 324bd0f74c..b31d605d9b 100644 --- a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc +++ b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc @@ -760,25 +760,24 @@ TEST_F(Dhcpv4SrvTest, DiscoverBasic) { checkClientId(offer, clientid); } -// Check that option 58 and 59 are not included if they are not specified. -TEST_F(Dhcpv4SrvTest, DiscoverNoTimers) { +// Check that option 58 and 59 are only included if they were specified +// and T2 is less than valid lft; T1 is less than T2 (if given) or valid +// lft if T2 is not given. +TEST_F(Dhcpv4SrvTest, DiscoverTimers) { IfaceMgrTestConfig test_config(true); IfaceMgr::instance().openSockets4(); boost::scoped_ptr srv; ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0))); - Pkt4Ptr dis = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234)); - dis->setRemoteAddr(IOAddress("192.0.2.1")); - OptionPtr clientid = generateClientId(); - dis->addOption(clientid); - dis->setIface("eth1"); - - // Recreate a subnet but set T1 and T2 to "unspecified". + // Recreate subnet + Triplet unspecified; + Triplet valid_lft(1000); subnet_.reset(new Subnet4(IOAddress("192.0.2.0"), 24, - Triplet(), - Triplet(), - 3000)); + unspecified, + unspecified, + valid_lft)); + pool_ = Pool4Ptr(new Pool4(IOAddress("192.0.2.100"), IOAddress("192.0.2.110"))); subnet_->addPool(pool_); @@ -786,20 +785,131 @@ TEST_F(Dhcpv4SrvTest, DiscoverNoTimers) { CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->add(subnet_); CfgMgr::instance().commit(); - // Pass it to the server and get an offer - Pkt4Ptr offer = srv->processDiscover(dis); + // Struct for describing an individual timer test scenario + struct TimerTest { + // logged test description + std::string description_; + // configured value for subnet's T1 + Triplet cfg_t1_; + // configured value for subnet's T1 + Triplet cfg_t2_; + // True if Offer should contain Subnet's T1 value + bool exp_t1_; + // True if Offer should contain Subnet's T2 value + bool exp_t2_; + }; - // Check if we get response at all - checkResponse(offer, DHCPOFFER, 1234); + // Convenience constants + bool T1 = true; + bool T2 = true; - // T1 and T2 timers must not be present. - checkAddressParams(offer, subnet_, false, false); + // Test scenarios + std::vector tests = { + { + "T1:unspecified, T2:unspecified", + unspecified, unspecified, + // Client should neither. + !T1, !T2 + }, + { + "T1 unspecified, T2 < VALID", + unspecified, valid_lft - 1, + // Client should only get T2. + !T1, T2 + }, + { + "T1:unspecified, T2 = VALID", + unspecified, valid_lft, + // Client should get neither. + !T1, !T2 + }, + { + "T1:unspecified, T2 > VALID", + unspecified, valid_lft + 1, + // Client should get neither. + !T1, !T2 + }, + + { + "T1 < VALID, T2:unspecified", + valid_lft - 1, unspecified, + // Client should only get T1. + T1, !T2 + }, + { + "T1 = VALID, T2:unspecified", + valid_lft, unspecified, + // Client should get neither. + !T1, !T2 + }, + { + "T1 > VALID, T2:unspecified", + valid_lft + 1, unspecified, + // Client should get neither. + !T1, !T2 + }, + { + "T1 < T2 < VALID", + valid_lft - 2, valid_lft - 1, + // Client should get both. + T1, T2 + }, + { + "T1 = T2 < VALID", + valid_lft - 1, valid_lft - 1, + // Client should only get T2. + !T1, T2 + }, + { + "T1 > T2 < VALID", + valid_lft - 1, valid_lft - 2, + // Client should only get T2. + !T1, T2 + }, + { + "T1 = T2 = VALID", + valid_lft, valid_lft, + // Client should get neither. + !T1, !T2 + }, + { + "T1 > VALID < T2, T2 > VALID", + valid_lft + 1, valid_lft + 2, + // Client should get neither. + !T1, !T2 + } + }; + + // Create a discover packet to use + Pkt4Ptr dis = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234)); + dis->setRemoteAddr(IOAddress("192.0.2.1")); + OptionPtr clientid = generateClientId(); + dis->addOption(clientid); + dis->setIface("eth1"); + + // Iterate over the test scenarios. + for (auto test = tests.begin(); test != tests.end(); ++test) { + { + SCOPED_TRACE((*test).description_); + // Configure sunbet's timer values + subnet_->setT1((*test).cfg_t1_); + subnet_->setT2((*test).cfg_t2_); + + // Discover/Offer exchange with the server + Pkt4Ptr offer = srv->processDiscover(dis); + + // Verify we have an offer + checkResponse(offer, DHCPOFFER, 1234); + + // Verify the timers are as expected. + checkAddressParams(offer, subnet_, + (*test).exp_t1_, (*test).exp_t2_); + } + } - // Check identifiers - checkServerId(offer, srv->getServerID()); - checkClientId(offer, clientid); } + // This test verifies that incoming DISCOVER can be handled properly, that an // OFFER is generated, that the response has an address and that address // really belongs to the configured pool. @@ -4298,7 +4408,6 @@ TEST_F(Dhcpv4SrvTest, truncatedVIVSOOption) { ASSERT_TRUE(offer); } - /// @todo: Implement proper tests for MySQL lease/host database, /// see ticket #4214. diff --git a/src/bin/dhcp4/tests/get_config_unittest.cc b/src/bin/dhcp4/tests/get_config_unittest.cc index 064d61909d..40006fe256 100644 --- a/src/bin/dhcp4/tests/get_config_unittest.cc +++ b/src/bin/dhcp4/tests/get_config_unittest.cc @@ -1960,7 +1960,6 @@ const char* UNPARSED_CONFIGS[] = { " \"relay\": {\n" " \"ip-addresses\": [ ]\n" " },\n" -" \"renew-timer\": 900,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [ ],\n" " \"server-hostname\": \"\",\n" @@ -2026,7 +2025,6 @@ const char* UNPARSED_CONFIGS[] = { " \"pool\": \"192.0.2.1-192.0.2.100\"\n" " }\n" " ],\n" -" \"rebind-timer\": 1800,\n" " \"relay\": {\n" " \"ip-addresses\": [ ]\n" " },\n" @@ -6965,11 +6963,9 @@ const char* UNPARSED_CONFIGS[] = { " \"match-client-id\": true,\n" " \"name\": \"foo\",\n" " \"option-data\": [ ],\n" -" \"rebind-timer\": 0,\n" " \"relay\": {\n" " \"ip-addresses\": [ ]\n" " },\n" -" \"renew-timer\": 0,\n" " \"reservation-mode\": \"all\",\n" " \"subnet4\": [\n" " {\n" @@ -6989,11 +6985,9 @@ const char* UNPARSED_CONFIGS[] = { " \"pool\": \"192.0.1.1-192.0.1.10\"\n" " }\n" " ],\n" -" \"rebind-timer\": 1800,\n" " \"relay\": {\n" " \"ip-addresses\": [ ]\n" " },\n" -" \"renew-timer\": 900,\n" " \"reservation-mode\": \"all\",\n" " \"reservations\": [\n" " {\n" @@ -7021,8 +7015,7 @@ const char* UNPARSED_CONFIGS[] = { " \"subnet\": \"192.0.1.0/24\",\n" " \"valid-lifetime\": 7200\n" " }\n" -" ],\n" -" \"valid-lifetime\": 0\n" +" ]\n" " }\n" " ],\n" " \"subnet4\": [ ]\n" diff --git a/src/bin/dhcp4/tests/simple_parser4_unittest.cc b/src/bin/dhcp4/tests/simple_parser4_unittest.cc index f56fdb7440..395b6f37a2 100644 --- a/src/bin/dhcp4/tests/simple_parser4_unittest.cc +++ b/src/bin/dhcp4/tests/simple_parser4_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2016-2018 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 @@ -95,12 +95,14 @@ TEST_F(SimpleParser4Test, globalDefaults4) { EXPECT_NO_THROW(num = SimpleParser4::setAllDefaults(empty)); - // We expect at least 3 parameters to be inserted. - EXPECT_TRUE(num >= 3); + // We expect at least 1 parameter to be inserted. + EXPECT_TRUE(num >= 1); checkIntegerValue(empty, "valid-lifetime", 7200); - checkIntegerValue(empty, "rebind-timer", 1800); - checkIntegerValue(empty, "renew-timer", 900); + + // Timers are optional and by default are not present + EXPECT_FALSE(empty->contains("rebind-timer")); + EXPECT_FALSE(empty->contains("renew-timer")); // Make sure that preferred-lifetime is not set for v4 (it's v6 only // parameter) diff --git a/src/bin/dhcp6/tests/get_config_unittest.cc b/src/bin/dhcp6/tests/get_config_unittest.cc index 46db37bf34..55cfc62390 100644 --- a/src/bin/dhcp6/tests/get_config_unittest.cc +++ b/src/bin/dhcp6/tests/get_config_unittest.cc @@ -6534,11 +6534,9 @@ const char* UNPARSED_CONFIGS[] = { " \"option-data\": [ ],\n" " \"preferred-lifetime\": 0,\n" " \"rapid-commit\": false,\n" -" \"rebind-timer\": 0,\n" " \"relay\": {\n" " \"ip-addresses\": [ ]\n" " },\n" -" \"renew-timer\": 0,\n" " \"reservation-mode\": \"all\",\n" " \"subnet6\": [\n" " {\n" @@ -6593,8 +6591,7 @@ const char* UNPARSED_CONFIGS[] = { " \"subnet\": \"2001:db1::/48\",\n" " \"valid-lifetime\": 7200\n" " }\n" -" ],\n" -" \"valid-lifetime\": 0\n" +" ]\n" " }\n" " ],\n" " \"subnet6\": [ ]\n" diff --git a/src/lib/dhcpsrv/network.cc b/src/lib/dhcpsrv/network.cc index fbd7d35539..aab0552056 100644 --- a/src/lib/dhcpsrv/network.cc +++ b/src/lib/dhcpsrv/network.cc @@ -136,18 +136,26 @@ Network::toElement() const { map->set("require-client-classes", class_list); } - // Set renew-timer - map->set("renew-timer", - Element::create(static_cast - (getT1().get()))); + // T1, T2, and Valid are optional for SharedNetworks, and + // T1 and T2 are optional for Subnet4 thus we will only + // output them if they are marked as specified. + if (!getT1().unspecified()) { + map->set("renew-timer", + Element::create(static_cast(getT1().get()))); + } + // Set rebind-timer - map->set("rebind-timer", - Element::create(static_cast - (getT2().get()))); + if (!getT2().unspecified()) { + map->set("rebind-timer", + Element::create(static_cast(getT2().get()))); + } + // Set valid-lifetime - map->set("valid-lifetime", - Element::create(static_cast + if (!getValid().unspecified()) { + map->set("valid-lifetime", + Element::create(static_cast (getValid().get()))); + } // Set reservation mode Network::HRMode hrmode = getHostReservationMode(); diff --git a/src/lib/dhcpsrv/network.h b/src/lib/dhcpsrv/network.h index 161afedc45..5b51732b4b 100644 --- a/src/lib/dhcpsrv/network.h +++ b/src/lib/dhcpsrv/network.h @@ -109,7 +109,7 @@ public: /// @brief Constructor. Network() - : iface_name_(), client_class_(""), t1_(0), t2_(0), valid_(0), + : iface_name_(), client_class_(""), t1_(), t2_(), valid_(), host_reservation_mode_(HR_ALL), cfg_option_(new CfgOption()) { } diff --git a/src/lib/dhcpsrv/parsers/dhcp_parsers.cc b/src/lib/dhcpsrv/parsers/dhcp_parsers.cc index aec0ed2645..71cd832f1b 100644 --- a/src/lib/dhcpsrv/parsers/dhcp_parsers.cc +++ b/src/lib/dhcpsrv/parsers/dhcp_parsers.cc @@ -652,9 +652,16 @@ Subnet4ConfigParser::initSubnet(data::ConstElementPtr params, asiolink::IOAddress addr, uint8_t len) { // The renew-timer and rebind-timer are optional. If not set, the // option 58 and 59 will not be sent to a client. In this case the - // client will use default values based on the valid-lifetime. - Triplet t1 = getInteger(params, "renew-timer"); - Triplet t2 = getInteger(params, "rebind-timer"); + // client should formulate default values based on the valid-lifetime. + Triplet t1; + if (params->contains("renew-timer")) { + t1 = getInteger(params, "renew-timer"); + } + + Triplet t2; + if (params->contains("rebind-timer")) { + t2 = getInteger(params, "rebind-timer"); + } // The valid-lifetime is mandatory. It may be specified for a // particular subnet. If not, the global value should be present. diff --git a/src/lib/dhcpsrv/parsers/simple_parser4.cc b/src/lib/dhcpsrv/parsers/simple_parser4.cc index e766e96323..d91d3fd045 100644 --- a/src/lib/dhcpsrv/parsers/simple_parser4.cc +++ b/src/lib/dhcpsrv/parsers/simple_parser4.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2016-2018 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 @@ -56,8 +56,6 @@ const SimpleDefaults SimpleParser4::OPTION4_DEFAULTS = { /// in Dhcp4) are optional. If not defined, the following values will be /// used. const SimpleDefaults SimpleParser4::GLOBAL4_DEFAULTS = { - { "renew-timer", Element::integer, "900" }, - { "rebind-timer", Element::integer, "1800" }, { "valid-lifetime", Element::integer, "7200" }, { "decline-probation-period", Element::integer, "86400" }, // 24h { "dhcp4o6-port", Element::integer, "0" }, diff --git a/src/lib/dhcpsrv/tests/cfg_shared_networks4_unittest.cc b/src/lib/dhcpsrv/tests/cfg_shared_networks4_unittest.cc index 80896223ec..eb72937a42 100644 --- a/src/lib/dhcpsrv/tests/cfg_shared_networks4_unittest.cc +++ b/src/lib/dhcpsrv/tests/cfg_shared_networks4_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2017-2018 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 @@ -109,12 +109,14 @@ TEST(CfgSharedNetworks4Test, duplicateName) { TEST(CfgSharedNetworks4Test, unparse) { SharedNetwork4Ptr network1(new SharedNetwork4("frog")); SharedNetwork4Ptr network2(new SharedNetwork4("dog")); - network1->setIface("eth0"); network1->addRelayAddress(IOAddress("198.16.1.1")); network1->addRelayAddress(IOAddress("198.16.1.2")); network2->setIface("eth1"); + network2->setT1(Triplet(100)); + network2->setT2(Triplet(200)); + network2->setValid(Triplet(300)); CfgSharedNetworks4 cfg; ASSERT_NO_THROW(cfg.add(network1)); @@ -126,25 +128,22 @@ TEST(CfgSharedNetworks4Test, unparse) { " \"interface\": \"eth1\",\n" " \"match-client-id\": true,\n" " \"name\": \"dog\",\n" + " \"rebind-timer\": 200,\n" " \"option-data\": [ ],\n" - " \"rebind-timer\": 0,\n" + " \"renew-timer\": 100,\n" " \"relay\": { \"ip-addresses\": [ ] },\n" - " \"renew-timer\": 0,\n" " \"reservation-mode\": \"all\"," " \"subnet4\": [ ],\n" - " \"valid-lifetime\": 0\n" + " \"valid-lifetime\": 300\n" " },\n" " {\n" " \"interface\": \"eth0\",\n" " \"match-client-id\": true,\n" " \"name\": \"frog\",\n" " \"option-data\": [ ],\n" - " \"rebind-timer\": 0,\n" " \"relay\": { \"ip-addresses\": [ \"198.16.1.1\", \"198.16.1.2\" ] },\n" - " \"renew-timer\": 0,\n" " \"reservation-mode\": \"all\"," - " \"subnet4\": [ ],\n" - " \"valid-lifetime\": 0\n" + " \"subnet4\": [ ]\n" " }\n" "]\n"; diff --git a/src/lib/dhcpsrv/tests/cfg_shared_networks6_unittest.cc b/src/lib/dhcpsrv/tests/cfg_shared_networks6_unittest.cc index f24069c744..d71670c1d8 100644 --- a/src/lib/dhcpsrv/tests/cfg_shared_networks6_unittest.cc +++ b/src/lib/dhcpsrv/tests/cfg_shared_networks6_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2017-2018 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 @@ -113,7 +113,11 @@ TEST(CfgSharedNetworks6Test, unparse) { network1->setIface("eth0"); network1->addRelayAddress(IOAddress("2001:db8:1::1")); network1->addRelayAddress(IOAddress("2001:db8:1::2")); + network2->setIface("eth1"); + network2->setT1(Triplet(100)); + network2->setT2(Triplet(200)); + network2->setValid(Triplet(300)); CfgSharedNetworks6 cfg; ASSERT_NO_THROW(cfg.add(network1)); @@ -127,12 +131,12 @@ TEST(CfgSharedNetworks6Test, unparse) { " \"option-data\": [ ],\n" " \"preferred-lifetime\": 0,\n" " \"rapid-commit\": false,\n" - " \"rebind-timer\": 0,\n" + " \"rebind-timer\": 200,\n" " \"relay\": { \"ip-addresses\": [ ] },\n" - " \"renew-timer\": 0,\n" + " \"renew-timer\": 100,\n" " \"reservation-mode\": \"all\"," " \"subnet6\": [ ],\n" - " \"valid-lifetime\": 0\n" + " \"valid-lifetime\": 300\n" " },\n" " {\n" " \"interface\": \"eth0\",\n" @@ -140,12 +144,9 @@ TEST(CfgSharedNetworks6Test, unparse) { " \"option-data\": [ ],\n" " \"preferred-lifetime\": 0,\n" " \"rapid-commit\": false,\n" - " \"rebind-timer\": 0,\n" " \"relay\": { \"ip-addresses\": [ \"2001:db8:1::1\", \"2001:db8:1::2\" ] },\n" - " \"renew-timer\": 0,\n" " \"reservation-mode\": \"all\"," - " \"subnet6\": [ ],\n" - " \"valid-lifetime\": 0\n" + " \"subnet6\": [ ]\n" " }\n" "]\n";