2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-09-01 14:35:29 +00:00

[268-reservation-mode-is-not-global] Updated code for global reservation mode

This commit is contained in:
Francis Dupont
2018-11-16 23:09:31 +01:00
parent 5c009f91d0
commit fae9245a36
12 changed files with 133 additions and 17 deletions

View File

@@ -766,6 +766,7 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
\"reservation-mode\" {
switch(driver.ctx_) {
case isc::dhcp::Parser4Context::DHCP4:
case isc::dhcp::Parser4Context::SUBNET4:
case isc::dhcp::Parser4Context::SHARED_NETWORK:
return isc::dhcp::Dhcp4Parser::make_RESERVATION_MODE(driver.loc_);

View File

@@ -464,6 +464,7 @@ global_param: valid_lifetime
| reservations
| config_control
| server_tag
| reservation_mode
| unknown_map_entry
;

View File

@@ -545,7 +545,8 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
(config_pair.first == "next-server") ||
(config_pair.first == "server-hostname") ||
(config_pair.first == "boot-file-name") ||
(config_pair.first == "server-tag")) {
(config_pair.first == "server-tag") ||
(config_pair.first == "reservation-mode")) {
continue;
}

View File

@@ -244,7 +244,7 @@ public:
/// Used while parsing shared-networks structures.
SHARED_NETWORK,
/// Used while parsing Dhcp4/Subnet4/reservation-mode.
/// Used while parsing Dhcp4/reservation-mode.
RESERVATION_MODE,
/// Used while parsing Dhcp4/option-def structures.

View File

@@ -4929,6 +4929,60 @@ TEST_F(Dhcp4ParserTest, hostReservationPerSubnet) {
EXPECT_EQ(Network::HR_ALL, subnet->getHostReservationMode());
}
/// The goal of this test is to verify that Host Reservation modes can be
/// specified globally.
TEST_F(Dhcp4ParserTest, hostReservationGlobal) {
/// - Configuration:
/// - only addresses (no prefixes)
/// - 2 subnets with :
/// - 192.0.2.0/24 (all reservations enabled)
/// - 192.0.3.0/24 (reservations not specified)
const char* hr_config =
"{ "
"\"rebind-timer\": 2000, "
"\"renew-timer\": 1000, "
"\"reservation-mode\": \"out-of-pool\", "
"\"subnet4\": [ { "
" \"pools\": [ { \"pool\": \"192.0.2.0/24\" } ],"
" \"subnet\": \"192.0.2.0/24\", "
" \"reservation-mode\": \"all\""
" },"
" {"
" \"pools\": [ { \"pool\": \"192.0.3.0/24\" } ],"
" \"subnet\": \"192.0.3.0/24\""
" } ],"
"\"valid-lifetime\": 4000 }";
ConstElementPtr json;
ASSERT_NO_THROW(json = parseDHCP4(hr_config));
extractConfig(hr_config);
ConstElementPtr result;
EXPECT_NO_THROW(result = configureDhcp4Server(*srv_, json));
// returned value should be 0 (success)
checkResult(result, 0);
// Let's get all subnets and check that there are 4 of them.
ConstCfgSubnets4Ptr subnets = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
ASSERT_TRUE(subnets);
const Subnet4Collection* subnet_col = subnets->getAll();
ASSERT_EQ(2, subnet_col->size()); // We expect 2 subnets
// Let's check if the parsed subnets have correct HR modes.
// Subnet 1
Subnet4Ptr subnet;
subnet = subnets->selectSubnet(IOAddress("192.0.2.1"));
ASSERT_TRUE(subnet);
EXPECT_EQ(Network::HR_ALL, subnet->getHostReservationMode());
// Subnet 2
subnet = subnets->selectSubnet(IOAddress("192.0.3.1"));
ASSERT_TRUE(subnet);
EXPECT_EQ(Network::HR_OUT_OF_POOL, subnet->getHostReservationMode());
}
/// Check that the decline-probation-period has a default value when not
/// specified.
TEST_F(Dhcp4ParserTest, declineTimerDefault) {

View File

@@ -1039,6 +1039,7 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence}
\"reservation-mode\" {
switch(driver.ctx_) {
case isc::dhcp::Parser6Context::DHCP6:
case isc::dhcp::Parser6Context::SUBNET6:
case isc::dhcp::Parser6Context::SHARED_NETWORK:
return isc::dhcp::Dhcp6Parser::make_RESERVATION_MODE(driver.loc_);

View File

@@ -465,6 +465,7 @@ global_param: preferred_lifetime
| reservations
| config_control
| server_tag
| reservation_mode
| unknown_map_entry
;

View File

@@ -637,7 +637,8 @@ configureDhcp6Server(Dhcpv6Srv& server, isc::data::ConstElementPtr config_set,
(config_pair.first == "decline-probation-period") ||
(config_pair.first == "dhcp4o6-port") ||
(config_pair.first == "user-context") ||
(config_pair.first == "server-tag")) {
(config_pair.first == "server-tag") ||
(config_pair.first == "reservation-mode")) {
continue;
}

View File

@@ -245,7 +245,7 @@ public:
/// Used while parsing shared-networks structures.
SHARED_NETWORK,
/// Used while parsing Dhcp6/Subnet6/reservation-mode.
/// Used while parsing Dhcp6/reservation-mode.
RESERVATION_MODE,
/// Used while parsing Dhcp6/option-def structures.

View File

@@ -5184,11 +5184,12 @@ TEST_F(Dhcp6ParserTest, hostReservationPerSubnet) {
/// - Configuration:
/// - only addresses (no prefixes)
/// - 4 subnets with:
/// - 5 subnets with:
/// - 2001:db8:1::/64 (all reservations enabled)
/// - 2001:db8:2::/64 (out-of-pool reservations)
/// - 2001:db8:3::/64 (reservations disabled)
/// - 2001:db8:3::/64 (reservations not specified)
/// - 2001:db8:4::/64 (global reservations)
/// - 2001:db8:5::/64 (reservations not specified)
const char* HR_CONFIG =
"{"
"\"preferred-lifetime\": 3000,"
@@ -5231,11 +5232,11 @@ TEST_F(Dhcp6ParserTest, hostReservationPerSubnet) {
checkResult(status, 0);
CfgMgr::instance().commit();
// Let's get all subnets and check that there are 4 of them.
// Let's get all subnets and check that there are 5 of them.
ConstCfgSubnets6Ptr subnets = CfgMgr::instance().getCurrentCfg()->getCfgSubnets6();
ASSERT_TRUE(subnets);
const Subnet6Collection* subnet_col = subnets->getAll();
ASSERT_EQ(5, subnet_col->size()); // We expect 4 subnets
ASSERT_EQ(5, subnet_col->size()); // We expect 5 subnets
// Let's check if the parsed subnets have correct HR modes.
@@ -5266,6 +5267,63 @@ TEST_F(Dhcp6ParserTest, hostReservationPerSubnet) {
EXPECT_EQ(Network::HR_ALL, subnet->getHostReservationMode());
}
/// The goal of this test is to verify that Host Reservation modes can be
/// specified globally.
TEST_F(Dhcp6ParserTest, hostReservationGlobal) {
/// - Configuration:
/// - only addresses (no prefixes)
/// - 2 subnets with:
/// - 2001:db8:1::/64 (all reservations enabled)
/// - 2001:db8:2::/64 (reservations not specified)
const char* HR_CONFIG =
"{"
"\"preferred-lifetime\": 3000,"
"\"rebind-timer\": 2000, "
"\"renew-timer\": 1000, "
"\"reservation-mode\": \"out-of-pool\", "
"\"subnet6\": [ { "
" \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ],"
" \"subnet\": \"2001:db8:1::/48\", "
" \"reservation-mode\": \"all\""
" },"
" {"
" \"pools\": [ { \"pool\": \"2001:db8:2::/64\" } ],"
" \"subnet\": \"2001:db8:2::/48\" "
" } ],"
"\"valid-lifetime\": 4000 }";
ConstElementPtr json;
ASSERT_NO_THROW(json = parseDHCP6(HR_CONFIG));
extractConfig(HR_CONFIG);
ConstElementPtr status;
EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
// returned value should be 0 (success)
checkResult(status, 0);
CfgMgr::instance().commit();
// Let's get all subnets and check that there are 2 of them.
ConstCfgSubnets6Ptr subnets = CfgMgr::instance().getCurrentCfg()->getCfgSubnets6();
ASSERT_TRUE(subnets);
const Subnet6Collection* subnet_col = subnets->getAll();
ASSERT_EQ(2, subnet_col->size()); // We expect 2 subnets
// Let's check if the parsed subnets have correct HR modes.
// Subnet 1
Subnet6Ptr subnet;
subnet = subnets->selectSubnet(IOAddress("2001:db8:1::1"));
ASSERT_TRUE(subnet);
EXPECT_EQ(Network::HR_ALL, subnet->getHostReservationMode());
// Subnet 2
subnet = subnets->selectSubnet(IOAddress("2001:db8:2::1"));
ASSERT_TRUE(subnet);
EXPECT_EQ(Network::HR_OUT_OF_POOL, subnet->getHostReservationMode());
}
/// The goal of this test is to verify that configuration can include
/// Relay Supplied options (specified as numbers).
TEST_F(Dhcp6ParserTest, rsooNumbers) {

View File

@@ -67,7 +67,8 @@ const SimpleDefaults SimpleParser4::GLOBAL4_DEFAULTS = {
{ "next-server", Element::string, "0.0.0.0" },
{ "server-hostname", Element::string, "" },
{ "boot-file-name", Element::string, "" },
{ "server-tag", Element::string, "" }
{ "server-tag", Element::string, "" },
{ "reservation-mode", Element::string, "all" }
};
/// @brief This table defines default values for each IPv4 subnet.
@@ -81,7 +82,6 @@ const SimpleDefaults SimpleParser4::SUBNET4_DEFAULTS = {
{ "id", Element::integer, "0" }, // 0 means autogenerate
{ "interface", Element::string, "" },
{ "client-class", Element::string, "" },
{ "reservation-mode", Element::string, "all" },
{ "4o6-interface", Element::string, "" },
{ "4o6-interface-id", Element::string, "" },
{ "4o6-subnet", Element::string, "" },
@@ -103,8 +103,7 @@ const SimpleDefaults SimpleParser4::SHARED_SUBNET4_DEFAULTS = {
/// @brief This table defines default values for each IPv4 shared network.
const SimpleDefaults SimpleParser4::SHARED_NETWORK4_DEFAULTS = {
{ "client-class", Element::string, "" },
{ "interface", Element::string, "" },
{ "reservation-mode", Element::string, "all" }
{ "interface", Element::string, "" }
};
/// @brief This table defines default values for interfaces for DHCPv4.

View File

@@ -63,7 +63,8 @@ const SimpleDefaults SimpleParser6::GLOBAL6_DEFAULTS = {
{ "valid-lifetime", Element::integer, "7200" },
{ "decline-probation-period", Element::integer, "86400" }, // 24h
{ "dhcp4o6-port", Element::integer, "0" },
{ "server-tag", Element::string, "" }
{ "server-tag", Element::string, "" },
{ "reservation-mode", Element::string, "all" }
};
/// @brief This table defines default values for each IPv6 subnet.
@@ -71,9 +72,8 @@ const SimpleDefaults SimpleParser6::SUBNET6_DEFAULTS = {
{ "id", Element::integer, "0" }, // 0 means autogenerate
{ "interface", Element::string, "" },
{ "client-class", Element::string, "" },
{ "reservation-mode", Element::string, "all" },
{ "rapid-commit", Element::boolean, "false" }, // rapid-commit disabled by default
{ "interface-id", Element::string, "" },
{ "interface-id", Element::string, "" }
};
/// @brief This table defines default values for each IPv6 subnet.
@@ -86,7 +86,6 @@ const SimpleDefaults SimpleParser6::SHARED_NETWORK6_DEFAULTS = {
{ "client-class", Element::string, "" },
{ "interface", Element::string, "" },
{ "interface-id", Element::string, "" },
{ "reservation-mode", Element::string, "all" },
{ "rapid-commit", Element::boolean, "false" } // rapid-commit disabled by default
};