mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-31 14:05:33 +00:00
[3336] renew-timer and rebind-timer are optional parameters in Kea4.
This commit is contained in:
@@ -281,24 +281,32 @@ protected:
|
|||||||
/// @param addr is IPv4 address of the subnet.
|
/// @param addr is IPv4 address of the subnet.
|
||||||
/// @param len is the prefix length
|
/// @param len is the prefix length
|
||||||
void initSubnet(isc::asiolink::IOAddress addr, uint8_t len) {
|
void initSubnet(isc::asiolink::IOAddress addr, uint8_t len) {
|
||||||
// Get all 'time' parameters using inheritance.
|
// The renew-timer and rebind-timer are optional. If not set, the
|
||||||
// If the subnet-specific value is defined then use it, else
|
// option 58 and 59 will not be sent to a client. In this case the
|
||||||
// use the global value. The global value must always be
|
// client will use default values based on the valid-lifetime.
|
||||||
// present. If it is not, it is an internal error and exception
|
Triplet<uint32_t> t1 = getOptionalParam("renew-timer");
|
||||||
// is thrown.
|
Triplet<uint32_t> t2 = getOptionalParam("rebind-timer");
|
||||||
Triplet<uint32_t> t1 = getParam("renew-timer");
|
// The valid-lifetime is mandatory. It may be specified for a
|
||||||
Triplet<uint32_t> t2 = getParam("rebind-timer");
|
// particular subnet. If not, the global value should be present.
|
||||||
|
// If there is no global value, exception is thrown.
|
||||||
Triplet<uint32_t> valid = getParam("valid-lifetime");
|
Triplet<uint32_t> valid = getParam("valid-lifetime");
|
||||||
// Subnet ID is optional. If it is not supplied the value of 0 is used,
|
// Subnet ID is optional. If it is not supplied the value of 0 is used,
|
||||||
// which means autogenerate.
|
// which means autogenerate.
|
||||||
SubnetID subnet_id =
|
SubnetID subnet_id =
|
||||||
static_cast<SubnetID>(uint32_values_->getOptionalParam("id", 0));
|
static_cast<SubnetID>(uint32_values_->getOptionalParam("id", 0));
|
||||||
|
|
||||||
stringstream tmp;
|
stringstream s;
|
||||||
tmp << addr << "/" << (int)len
|
s << addr << "/" << static_cast<int>(len) << " with params: ";
|
||||||
<< " with params t1=" << t1 << ", t2=" << t2 << ", valid=" << valid;
|
// t1 and t2 are optional may be not specified.
|
||||||
|
if (!t1.unspecified()) {
|
||||||
|
s << "t1=" << t1 << ", ";
|
||||||
|
}
|
||||||
|
if (!t2.unspecified()) {
|
||||||
|
s << "t2=" << t2 << ", ";
|
||||||
|
}
|
||||||
|
s <<"valid-lifetime=" << valid;
|
||||||
|
|
||||||
LOG_INFO(dhcp4_logger, DHCP4_CONFIG_NEW_SUBNET).arg(tmp.str());
|
LOG_INFO(dhcp4_logger, DHCP4_CONFIG_NEW_SUBNET).arg(s.str());
|
||||||
|
|
||||||
Subnet4Ptr subnet4(new Subnet4(addr, len, t1, t2, valid, subnet_id));
|
Subnet4Ptr subnet4(new Subnet4(addr, len, t1, t2, valid, subnet_id));
|
||||||
subnet_ = subnet4;
|
subnet_ = subnet4;
|
||||||
|
@@ -79,6 +79,8 @@ public:
|
|||||||
// is sane.
|
// is sane.
|
||||||
srv_.reset(new Dhcpv4Srv(0));
|
srv_.reset(new Dhcpv4Srv(0));
|
||||||
CfgMgr::instance().deleteActiveIfaces();
|
CfgMgr::instance().deleteActiveIfaces();
|
||||||
|
// Create fresh context.
|
||||||
|
globalContext()->copyContext(ParserContext(Option::V4));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that no hooks libraries are loaded. This is a pre-condition for
|
// Check that no hooks libraries are loaded. This is a pre-condition for
|
||||||
@@ -510,6 +512,73 @@ TEST_F(Dhcp4ParserTest, emptySubnet) {
|
|||||||
checkGlobalUint32("valid-lifetime", 4000);
|
checkGlobalUint32("valid-lifetime", 4000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check that the renew-timer doesn't have to be specified, in which case
|
||||||
|
/// it is marked unspecified in the Subnet.
|
||||||
|
TEST_F(Dhcp4ParserTest, unspecifiedRenewTimer) {
|
||||||
|
ConstElementPtr status;
|
||||||
|
|
||||||
|
string config = "{ \"interfaces\": [ \"*\" ],"
|
||||||
|
"\"rebind-timer\": 2000, "
|
||||||
|
"\"subnet4\": [ { "
|
||||||
|
" \"pool\": [ \"192.0.2.1 - 192.0.2.100\" ],"
|
||||||
|
" \"subnet\": \"192.0.2.0/24\" } ],"
|
||||||
|
"\"valid-lifetime\": 4000 }";
|
||||||
|
|
||||||
|
ElementPtr json = Element::fromJSON(config);
|
||||||
|
|
||||||
|
EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, json));
|
||||||
|
|
||||||
|
// returned value should be 0 (success)
|
||||||
|
checkResult(status, 0);
|
||||||
|
checkGlobalUint32("rebind-timer", 2000);
|
||||||
|
checkGlobalUint32("valid-lifetime", 4000);
|
||||||
|
|
||||||
|
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.200"),
|
||||||
|
classify_);
|
||||||
|
ASSERT_TRUE(subnet);
|
||||||
|
EXPECT_TRUE(subnet->getT1().unspecified());
|
||||||
|
EXPECT_FALSE(subnet->getT2().unspecified());
|
||||||
|
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
|
||||||
|
/// it is marked unspecified in the Subnet.
|
||||||
|
TEST_F(Dhcp4ParserTest, unspecifiedRebindTimer) {
|
||||||
|
ConstElementPtr status;
|
||||||
|
|
||||||
|
string config = "{ \"interfaces\": [ \"*\" ],"
|
||||||
|
"\"renew-timer\": 1000, "
|
||||||
|
"\"subnet4\": [ { "
|
||||||
|
" \"pool\": [ \"192.0.2.1 - 192.0.2.100\" ],"
|
||||||
|
" \"subnet\": \"192.0.2.0/24\" } ],"
|
||||||
|
"\"valid-lifetime\": 4000 }";
|
||||||
|
|
||||||
|
ElementPtr json = Element::fromJSON(config);
|
||||||
|
|
||||||
|
EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, json));
|
||||||
|
|
||||||
|
// returned value should be 0 (success)
|
||||||
|
checkResult(status, 0);
|
||||||
|
checkGlobalUint32("renew-timer", 1000);
|
||||||
|
checkGlobalUint32("valid-lifetime", 4000);
|
||||||
|
|
||||||
|
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.200"),
|
||||||
|
classify_);
|
||||||
|
ASSERT_TRUE(subnet);
|
||||||
|
EXPECT_FALSE(subnet->getT1().unspecified());
|
||||||
|
EXPECT_EQ(1000, subnet->getT1());
|
||||||
|
EXPECT_TRUE(subnet->getT2().unspecified());
|
||||||
|
EXPECT_EQ(4000, subnet->getValid());
|
||||||
|
|
||||||
|
// Check that subnet-id is 1
|
||||||
|
EXPECT_EQ(1, subnet->getID());
|
||||||
|
}
|
||||||
|
|
||||||
/// The goal of this test is to verify if defined subnet uses global
|
/// The goal of this test is to verify if defined subnet uses global
|
||||||
/// parameter timer definitions.
|
/// parameter timer definitions.
|
||||||
TEST_F(Dhcp4ParserTest, subnetGlobalDefaults) {
|
TEST_F(Dhcp4ParserTest, subnetGlobalDefaults) {
|
||||||
@@ -1700,6 +1769,7 @@ TEST_F(Dhcp4ParserTest, optionDataTwoSpaces) {
|
|||||||
// belongs to the 'dhcp4' option space as it is the
|
// belongs to the 'dhcp4' option space as it is the
|
||||||
// standard option.
|
// standard option.
|
||||||
string config = "{ \"interfaces\": [ \"*\" ],"
|
string config = "{ \"interfaces\": [ \"*\" ],"
|
||||||
|
"\"valid-lifetime\": 4000,"
|
||||||
"\"rebind-timer\": 2000,"
|
"\"rebind-timer\": 2000,"
|
||||||
"\"renew-timer\": 1000,"
|
"\"renew-timer\": 1000,"
|
||||||
"\"option-data\": [ {"
|
"\"option-data\": [ {"
|
||||||
@@ -1779,6 +1849,7 @@ TEST_F(Dhcp4ParserTest, optionDataEncapsulate) {
|
|||||||
|
|
||||||
// Starting stage 1. Configure sub-options and their definitions.
|
// Starting stage 1. Configure sub-options and their definitions.
|
||||||
string config = "{ \"interfaces\": [ \"*\" ],"
|
string config = "{ \"interfaces\": [ \"*\" ],"
|
||||||
|
"\"valid-lifetime\": 4000,"
|
||||||
"\"rebind-timer\": 2000,"
|
"\"rebind-timer\": 2000,"
|
||||||
"\"renew-timer\": 1000,"
|
"\"renew-timer\": 1000,"
|
||||||
"\"option-data\": [ {"
|
"\"option-data\": [ {"
|
||||||
@@ -2352,6 +2423,7 @@ TEST_F(Dhcp4ParserTest, stdOptionDataEncapsulate) {
|
|||||||
// that we will add to the base option.
|
// that we will add to the base option.
|
||||||
// Let's create some dummy options: foo and foo2.
|
// Let's create some dummy options: foo and foo2.
|
||||||
string config = "{ \"interfaces\": [ \"*\" ],"
|
string config = "{ \"interfaces\": [ \"*\" ],"
|
||||||
|
"\"valid-lifetime\": 4000,"
|
||||||
"\"rebind-timer\": 2000,"
|
"\"rebind-timer\": 2000,"
|
||||||
"\"renew-timer\": 1000,"
|
"\"renew-timer\": 1000,"
|
||||||
"\"option-data\": [ {"
|
"\"option-data\": [ {"
|
||||||
@@ -2512,6 +2584,7 @@ TEST_F(Dhcp4ParserTest, vendorOptionsHex) {
|
|||||||
// sharing the code 1 and belonging to the different vendor spaces.
|
// sharing the code 1 and belonging to the different vendor spaces.
|
||||||
// (different vendor-id values).
|
// (different vendor-id values).
|
||||||
string config = "{ \"interfaces\": [ \"*\" ],"
|
string config = "{ \"interfaces\": [ \"*\" ],"
|
||||||
|
"\"valid-lifetime\": 4000,"
|
||||||
"\"rebind-timer\": 2000,"
|
"\"rebind-timer\": 2000,"
|
||||||
"\"renew-timer\": 1000,"
|
"\"renew-timer\": 1000,"
|
||||||
"\"option-data\": [ {"
|
"\"option-data\": [ {"
|
||||||
@@ -2570,6 +2643,7 @@ TEST_F(Dhcp4ParserTest, vendorOptionsCsv) {
|
|||||||
// sharing the code 1 and belonging to the different vendor spaces.
|
// sharing the code 1 and belonging to the different vendor spaces.
|
||||||
// (different vendor-id values).
|
// (different vendor-id values).
|
||||||
string config = "{ \"interfaces\": [ \"*\" ],"
|
string config = "{ \"interfaces\": [ \"*\" ],"
|
||||||
|
"\"valid-lifetime\": 4000,"
|
||||||
"\"rebind-timer\": 2000,"
|
"\"rebind-timer\": 2000,"
|
||||||
"\"renew-timer\": 1000,"
|
"\"renew-timer\": 1000,"
|
||||||
"\"option-data\": [ {"
|
"\"option-data\": [ {"
|
||||||
@@ -2646,6 +2720,7 @@ buildHooksLibrariesConfig(const std::vector<std::string>& libraries) {
|
|||||||
// Append the remainder of the configuration.
|
// Append the remainder of the configuration.
|
||||||
config += string(
|
config += string(
|
||||||
"],"
|
"],"
|
||||||
|
"\"valid-lifetime\": 4000,"
|
||||||
"\"rebind-timer\": 2000,"
|
"\"rebind-timer\": 2000,"
|
||||||
"\"renew-timer\": 1000,"
|
"\"renew-timer\": 1000,"
|
||||||
"\"option-data\": [ {"
|
"\"option-data\": [ {"
|
||||||
|
@@ -1336,6 +1336,16 @@ SubnetConfigParser::getParam(const std::string& name) {
|
|||||||
return (Triplet<uint32_t>(value));
|
return (Triplet<uint32_t>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isc::dhcp::Triplet<uint32_t>
|
||||||
|
SubnetConfigParser::getOptionalParam(const std::string& name) {
|
||||||
|
try {
|
||||||
|
return (getParam(name));
|
||||||
|
} catch (const DhcpConfigError &) {
|
||||||
|
// No error. We will return an unspecified value.
|
||||||
|
}
|
||||||
|
return (Triplet<uint32_t>());
|
||||||
|
}
|
||||||
|
|
||||||
//**************************** D2ClientConfigParser **********************
|
//**************************** D2ClientConfigParser **********************
|
||||||
D2ClientConfigParser::D2ClientConfigParser(const std::string& entry_name)
|
D2ClientConfigParser::D2ClientConfigParser(const std::string& entry_name)
|
||||||
: entry_name_(entry_name), boolean_values_(new BooleanStorage()),
|
: entry_name_(entry_name), boolean_values_(new BooleanStorage()),
|
||||||
|
@@ -993,6 +993,18 @@ protected:
|
|||||||
/// @throw DhcpConfigError when requested parameter is not present
|
/// @throw DhcpConfigError when requested parameter is not present
|
||||||
isc::dhcp::Triplet<uint32_t> getParam(const std::string& name);
|
isc::dhcp::Triplet<uint32_t> getParam(const std::string& name);
|
||||||
|
|
||||||
|
/// @brief Returns optional value for a given parameter.
|
||||||
|
///
|
||||||
|
/// This method checks if an optional parameter has been specified for
|
||||||
|
/// a subnet. If not, it will try to use a global value. If the global
|
||||||
|
/// value is not specified it will return an object representing an
|
||||||
|
/// unspecified value.
|
||||||
|
///
|
||||||
|
/// @param name name of the configuration parameter.
|
||||||
|
/// @return An optional value or a @c Triplet object representing
|
||||||
|
/// unspecified value.
|
||||||
|
isc::dhcp::Triplet<uint32_t> getOptionalParam(const std::string& name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/// @brief Append sub-options to an option.
|
/// @brief Append sub-options to an option.
|
||||||
|
Reference in New Issue
Block a user