2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-30 05:27:55 +00:00

[#1405] updated unittests

This commit is contained in:
Razvan Becheriu 2020-10-09 18:39:58 +03:00
parent 2832b1e91d
commit 234296cbce
9 changed files with 428 additions and 125 deletions

View File

@ -5286,29 +5286,35 @@ TEST_F(Dhcp4ParserTest, hostReservationPerSubnet) {
/// - Configuration:
/// - only addresses (no prefixes)
/// - 4 subnets with:
/// - 192.0.2.0/24 (all reservations enabled)
/// - 192.0.3.0/24 (out-of-pool reservations)
/// - 192.0.4.0/24 (reservations disabled)
/// - 5 subnets with:
/// - 192.0.1.0/24 (all reservations enabled)
/// - 192.0.2.0/24 (out-of-pool reservations)
/// - 192.0.3.0/24 (reservations disabled)
/// - 192.0.4.0/24 (global reservations)
/// - 192.0.5.0/24 (reservations not specified)
const char* hr_config =
"{ "
"\"rebind-timer\": 2000, "
"\"renew-timer\": 1000, "
"\"subnet4\": [ { "
" \"pools\": [ { \"pool\": \"192.0.2.0/24\" } ],"
" \"subnet\": \"192.0.2.0/24\", "
" \"pools\": [ { \"pool\": \"192.0.1.0/24\" } ],"
" \"subnet\": \"192.0.1.0/24\", "
" \"reservation-mode\": \"all\""
" },"
" {"
" \"pools\": [ { \"pool\": \"192.0.3.0/24\" } ],"
" \"subnet\": \"192.0.3.0/24\", "
" \"pools\": [ { \"pool\": \"192.0.2.0/24\" } ],"
" \"subnet\": \"192.0.2.0/24\", "
" \"reservation-mode\": \"out-of-pool\""
" },"
" {"
" \"pools\": [ { \"pool\": \"192.0.3.0/24\" } ],"
" \"subnet\": \"192.0.4.0/24\", "
" \"reservation-mode\": \"disabled\""
" },"
" {"
" \"pools\": [ { \"pool\": \"192.0.4.0/24\" } ],"
" \"subnet\": \"192.0.4.0/24\", "
" \"reservation-mode\": \"disabled\""
" \"reservation-mode\": \"global\""
" },"
" {"
" \"pools\": [ { \"pool\": \"192.0.5.0/24\" } ],"
@ -5325,36 +5331,153 @@ TEST_F(Dhcp4ParserTest, hostReservationPerSubnet) {
// returned value should be 0 (success)
checkResult(result, 0);
// 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.
ConstCfgSubnets4Ptr subnets = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
ASSERT_TRUE(subnets);
const Subnet4Collection* subnet_col = subnets->getAll();
ASSERT_EQ(4, 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.
// Subnet 1
Subnet4Ptr subnet;
subnet = subnets->selectSubnet(IOAddress("192.0.2.1"));
subnet = subnets->selectSubnet(IOAddress("192.0.1.1"));
ASSERT_TRUE(subnet);
EXPECT_EQ(Network::HR_ALL, subnet->getHostReservationMode());
// Subnet 2
subnet = subnets->selectSubnet(IOAddress("192.0.3.1"));
subnet = subnets->selectSubnet(IOAddress("192.0.2.1"));
ASSERT_TRUE(subnet);
EXPECT_EQ(Network::HR_OUT_OF_POOL, subnet->getHostReservationMode());
// Subnet 3
subnet = subnets->selectSubnet(IOAddress("192.0.4.1"));
subnet = subnets->selectSubnet(IOAddress("192.0.3.1"));
ASSERT_TRUE(subnet);
EXPECT_EQ(Network::HR_DISABLED, subnet->getHostReservationMode());
// Subnet 4
subnet = subnets->selectSubnet(IOAddress("192.0.4.1"));
ASSERT_TRUE(subnet);
EXPECT_EQ(Network::HR_GLOBAL, subnet->getHostReservationMode());
// Subnet 5
subnet = subnets->selectSubnet(IOAddress("192.0.5.1"));
ASSERT_TRUE(subnet);
EXPECT_EQ(Network::HR_ALL, subnet->getHostReservationMode());
}
/// The goal of this test is to verify that Host Reservation modes can be
/// specified on a per-subnet basis.
TEST_F(Dhcp4ParserTest, hostReservationModesPerSubnet) {
/// - Configuration:
/// - only addresses (no prefixes)
/// - 6 subnets with:
/// - 192.0.1.0/24 (all reservations enabled)
/// - 192.0.2.0/24 (out-of-pool reservations)
/// - 192.0.3.0/24 (reservations disabled)
/// - 192.0.4.0/24 (global reservations)
/// - 192.0.5.0/24 (reservations not specified)
/// - 192.0.6.0/24 (global + all enabled)
const char* hr_config =
"{ "
"\"rebind-timer\": 2000, "
"\"renew-timer\": 1000, "
"\"subnet4\": [ { "
" \"pools\": [ { \"pool\": \"192.0.1.0/24\" } ],"
" \"subnet\": \"192.0.1.0/24\", "
" \"reservation-modes\": {"
" \"in-subnet\": True,"
" \"out-of-pool\": True"
" }"
" },"
" {"
" \"pools\": [ { \"pool\": \"192.0.2.0/24\" } ],"
" \"subnet\": \"192.0.2.0/24\", "
" \"reservation-modes\": {"
" \"out-of-pool\": True"
" }"
" },"
" {"
" \"pools\": [ { \"pool\": \"192.0.3.0/24\" } ],"
" \"subnet\": \"192.0.4.0/24\", "
" \"reservation-modes\": {"
" \"in-subnet\": False,"
" \"out-of-pool\": False,"
" \"global\": False"
" }"
" },"
" {"
" \"pools\": [ { \"pool\": \"192.0.4.0/24\" } ],"
" \"subnet\": \"192.0.4.0/24\", "
" \"reservation-modes\": {"
" \"global\": True"
" }"
" },"
" {"
" \"pools\": [ { \"pool\": \"192.0.5.0/24\" } ],"
" \"subnet\": \"192.0.5.0/24\""
" },"
" {"
" \"pools\": [ { \"pool\": \"192.0.6.0/24\" } ],"
" \"subnet\": \"192.0.6.0/24\", "
" \"reservation-modes\": {"
" \"in-subnet\": True,"
" \"out-of-pool\": True,"
" \"global\": True"
" }"
" } ],"
"\"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 6 of them.
ConstCfgSubnets4Ptr subnets = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
ASSERT_TRUE(subnets);
const Subnet4Collection* subnet_col = subnets->getAll();
ASSERT_EQ(6, subnet_col->size()); // We expect 6 subnets
// Let's check if the parsed subnets have correct HR modes.
// Subnet 1
Subnet4Ptr subnet;
subnet = subnets->selectSubnet(IOAddress("192.0.1.1"));
ASSERT_TRUE(subnet);
EXPECT_EQ(Network::HR_ALL, subnet->getHostReservationMode());
// Subnet 2
subnet = subnets->selectSubnet(IOAddress("192.0.2.1"));
ASSERT_TRUE(subnet);
EXPECT_EQ(Network::HR_OUT_OF_POOL, subnet->getHostReservationMode());
// Subnet 3
subnet = subnets->selectSubnet(IOAddress("192.0.3.1"));
ASSERT_TRUE(subnet);
EXPECT_EQ(Network::HR_DISABLED, subnet->getHostReservationMode());
// Subnet 4
subnet = subnets->selectSubnet(IOAddress("192.0.4.1"));
ASSERT_TRUE(subnet);
EXPECT_EQ(Network::HR_GLOBAL, subnet->getHostReservationMode());
// Subnet 5
subnet = subnets->selectSubnet(IOAddress("192.0.5.1"));
ASSERT_TRUE(subnet);
EXPECT_EQ(Network::HR_ALL, subnet->getHostReservationMode());
// Subnet 6
subnet = subnets->selectSubnet(IOAddress("192.0.6.1"));
ASSERT_TRUE(subnet);
EXPECT_EQ(Network::HR_ALL|Network::HR_GLOBAL, subnet->getHostReservationMode());
}
/// The goal of this test is to verify that Host Reservation modes can be
/// specified globally.
TEST_F(Dhcp4ParserTest, hostReservationGlobal) {
@ -5417,6 +5540,73 @@ TEST_F(Dhcp4ParserTest, hostReservationGlobal) {
EXPECT_EQ(Network::HR_OUT_OF_POOL, subnet->getHostReservationMode());
}
/// The goal of this test is to verify that Host Reservation modes can be
/// specified globally.
TEST_F(Dhcp4ParserTest, hostReservationModesGlobal) {
/// - 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-modes\": {"
" \"out-of-pool\": True"
" },"
"\"subnet4\": [ { "
" \"pools\": [ { \"pool\": \"192.0.2.0/24\" } ],"
" \"subnet\": \"192.0.2.0/24\", "
" \"reservation-modes\": {"
" \"in-subnet\": True,"
" \"out-of-pool\": True"
" }"
" },"
" {"
" \"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);
// Reset the fetch global function to staging (vs current) config.
subnet->setFetchGlobalsFn([]() -> ConstElementPtr {
return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
});
EXPECT_EQ(Network::HR_ALL, subnet->getHostReservationMode());
// Subnet 2
subnet = subnets->selectSubnet(IOAddress("192.0.3.1"));
ASSERT_TRUE(subnet);
// Reset the fetch global function to staging (vs current) config.
subnet->setFetchGlobalsFn([]() -> ConstElementPtr {
return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
});
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) {
@ -6271,7 +6461,9 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDerive) {
" \"relay\": {\n"
" \"ip-address\": \"5.6.7.8\"\n"
" },\n"
" \"reservation-mode\": \"out-of-pool\",\n"
" \"reservation-modes\": {"
" \"out-of-pool\": True"
" },"
" \"renew-timer\": 10,\n"
" \"rebind-timer\": 20,\n"
" \"valid-lifetime\": 40,\n"
@ -6297,7 +6489,9 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDerive) {
" \"relay\": {\n"
" \"ip-address\": \"55.66.77.88\"\n"
" },\n"
" \"reservation-mode\": \"disabled\"\n"
" \"reservation-modes\": {"
" \"global\": False"
" }"
" }\n"
" ]\n"
" },\n"

View File

@ -5738,6 +5738,121 @@ 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 on a per-subnet basis.
TEST_F(Dhcp6ParserTest, hostReservationModesPerSubnet) {
/// - Configuration:
/// - only addresses (no prefixes)
/// - 6 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:4::/64 (global reservations)
/// - 2001:db8:5::/64 (reservations not specified)
/// - 2001:db8:5::/64 (global + all enabled)
const char* HR_CONFIG =
"{"
"\"preferred-lifetime\": 3000,"
"\"rebind-timer\": 2000, "
"\"renew-timer\": 1000, "
"\"subnet6\": [ { "
" \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ],"
" \"subnet\": \"2001:db8:1::/48\", "
" \"reservation-modes\": {"
" \"in-subnet\": True,"
" \"out-of-pool\": True"
" }"
" },"
" {"
" \"pools\": [ { \"pool\": \"2001:db8:2::/64\" } ],"
" \"subnet\": \"2001:db8:2::/48\", "
" \"reservation-modes\": {"
" \"out-of-pool\": True"
" }"
" },"
" {"
" \"pools\": [ { \"pool\": \"2001:db8:3::/64\" } ],"
" \"subnet\": \"2001:db8:3::/48\", "
" \"reservation-modes\": {"
" \"in-subnet\": False,"
" \"out-of-pool\": False,"
" \"global\": False"
" }"
" },"
" {"
" \"pools\": [ { \"pool\": \"2001:db8:4::/64\" } ],"
" \"subnet\": \"2001:db8:4::/48\", "
" \"reservation-modes\": {"
" \"global\": True"
" }"
" },"
" {"
" \"pools\": [ { \"pool\": \"2001:db8:5::/64\" } ],"
" \"subnet\": \"2001:db8:5::/48\" "
" },"
" {"
" \"pools\": [ { \"pool\": \"2001:db8:6::/64\" } ],"
" \"subnet\": \"2001:db8:6::/48\", "
" \"reservation-modes\": {"
" \"in-subnet\": True,"
" \"out-of-pool\": True,"
" \"global\": True"
" }"
" } ],"
"\"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 6 of them.
ConstCfgSubnets6Ptr subnets = CfgMgr::instance().getCurrentCfg()->getCfgSubnets6();
ASSERT_TRUE(subnets);
const Subnet6Collection* subnet_col = subnets->getAll();
ASSERT_EQ(6, subnet_col->size()); // We expect 6 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());
// Subnet 3
subnet = subnets->selectSubnet(IOAddress("2001:db8:3::1"));
ASSERT_TRUE(subnet);
EXPECT_EQ(Network::HR_DISABLED, subnet->getHostReservationMode());
// Subnet 4
subnet = subnets->selectSubnet(IOAddress("2001:db8:4::1"));
ASSERT_TRUE(subnet);
EXPECT_EQ(Network::HR_GLOBAL, subnet->getHostReservationMode());
// Subnet 5
subnet = subnets->selectSubnet(IOAddress("2001:db8:5::1"));
ASSERT_TRUE(subnet);
EXPECT_EQ(Network::HR_ALL, subnet->getHostReservationMode());
// Subnet 6
subnet = subnets->selectSubnet(IOAddress("2001:db8:6::1"));
ASSERT_TRUE(subnet);
EXPECT_EQ(Network::HR_ALL|Network::HR_GLOBAL, subnet->getHostReservationMode());
}
/// The goal of this test is to verify that Host Reservation modes can be
/// specified globally.
TEST_F(Dhcp6ParserTest, hostReservationGlobal) {
@ -5795,6 +5910,68 @@ TEST_F(Dhcp6ParserTest, hostReservationGlobal) {
EXPECT_EQ(Network::HR_OUT_OF_POOL, subnet->getHostReservationMode());
}
/// The goal of this test is to verify that Host Reservation modes can be
/// specified globally.
TEST_F(Dhcp6ParserTest, hostReservationModesGlobal) {
/// - 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-modes\": {"
" \"out-of-pool\": True"
" },"
"\"subnet6\": [ { "
" \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ],"
" \"subnet\": \"2001:db8:1::/48\", "
" \"reservation-modes\": {"
" \"in-subnet\": True,"
" \"out-of-pool\": True"
" }"
" },"
" {"
" \"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) {
@ -6714,7 +6891,9 @@ TEST_F(Dhcp6ParserTest, sharedNetworksDerive) {
" \"ip-address\": \"1111::1\"\n"
" },\n"
" \"rapid-commit\": true,\n"
" \"reservation-mode\": \"disabled\",\n"
" \"reservation-modes\": {"
" \"global\": False"
" }"
" \"subnet6\": [\n"
" { \n"
" \"subnet\": \"2001:db1::/48\",\n"
@ -6736,7 +6915,9 @@ TEST_F(Dhcp6ParserTest, sharedNetworksDerive) {
" \"max-valid-lifetime\": 500, \n"
" \"interface-id\": \"twotwo\",\n"
" \"rapid-commit\": true,\n"
" \"reservation-mode\": \"out-of-pool\"\n"
" \"reservation-modes\": {"
" \"out-of-pool\": True"
" }"
" }\n"
" ]\n"
" },\n"

View File

@ -536,7 +536,7 @@ ConstHostPtr
AllocEngine::ClientContext6::currentHost() const {
Subnet6Ptr subnet = host_subnet_ ? host_subnet_ : subnet_;
if (subnet) {
SubnetID id = (subnet_->getHostReservationMode() == Network::HR_GLOBAL ?
SubnetID id = (subnet_->getHostReservationMode() & Network::HR_GLOBAL ?
SUBNET_ID_GLOBAL : subnet->getID());
auto host = hosts_.find(id);
@ -551,7 +551,7 @@ AllocEngine::ClientContext6::currentHost() const {
ConstHostPtr
AllocEngine::ClientContext6::globalHost() const {
Subnet6Ptr subnet = host_subnet_ ? host_subnet_ : subnet_;
if (subnet && subnet_->getHostReservationMode() == Network::HR_GLOBAL) {
if (subnet && (subnet_->getHostReservationMode() & Network::HR_GLOBAL)) {
auto host = hosts_.find(SUBNET_ID_GLOBAL);
if (host != hosts_.cend()) {
return (host->second);
@ -599,14 +599,16 @@ void AllocEngine::findReservation(ClientContext6& ctx) {
SharedNetwork6Ptr network;
subnet->getSharedNetwork(network);
if (subnet->getHostReservationMode() == Network::HR_GLOBAL) {
if (subnet->getHostReservationMode() & Network::HR_GLOBAL) {
ConstHostPtr ghost = findGlobalReservation(ctx);
if (ghost) {
ctx.hosts_[SUBNET_ID_GLOBAL] = ghost;
// @todo In theory, to support global as part of HR_ALL,
// we would just keep going, instead of returning.
return;
if (subnet->getHostReservationMode() == Network::HR_GLOBAL) {
return;
}
}
}
@ -1072,7 +1074,7 @@ AllocEngine::allocateUnreservedLeases6(ClientContext6& ctx) {
}
// First check for reservation when it is the choice.
if (check_reservation_first && (hr_mode == Network::HR_ALL)) {
if (check_reservation_first && (hr_mode & Network::HR_IN_SUBNET)) {
auto hosts = getIPv6Resrv(subnet->getID(), candidate);
if (!hosts.empty()) {
// Don't allocate.
@ -1097,7 +1099,7 @@ AllocEngine::allocateUnreservedLeases6(ClientContext6& ctx) {
/// In-pool reservations: Check if this address is reserved for someone
/// else. There is no need to check for whom it is reserved, because if
/// it has been reserved for us we would have already allocated a lease.
if (!check_reservation_first && (hr_mode == Network::HR_ALL)) {
if (!check_reservation_first && (hr_mode & Network::HR_IN_SUBNET)) {
auto hosts = getIPv6Resrv(subnet->getID(), candidate);
if (!hosts.empty()) {
// Don't allocate.
@ -1129,7 +1131,7 @@ AllocEngine::allocateUnreservedLeases6(ClientContext6& ctx) {
// allocation attempts.
} else if (existing->expired()) {
// Make sure it's not reserved.
if (!check_reservation_first && (hr_mode == Network::HR_ALL)) {
if (!check_reservation_first && (hr_mode & Network::HR_IN_SUBNET)) {
auto hosts = getIPv6Resrv(subnet->getID(), candidate);
if (!hosts.empty()) {
// Don't allocate.
@ -3211,7 +3213,7 @@ AllocEngine::ClientContext4::ClientContext4(const Subnet4Ptr& subnet,
ConstHostPtr
AllocEngine::ClientContext4::currentHost() const {
if (subnet_) {
SubnetID id = (subnet_->getHostReservationMode() == Network::HR_GLOBAL ?
SubnetID id = (subnet_->getHostReservationMode() & Network::HR_GLOBAL ?
SUBNET_ID_GLOBAL : subnet_->getID());
auto host = hosts_.find(id);
@ -3224,7 +3226,7 @@ AllocEngine::ClientContext4::currentHost() const {
ConstHostPtr
AllocEngine::ClientContext4::globalHost() const {
if (subnet_ && subnet_->getHostReservationMode() == Network::HR_GLOBAL) {
if (subnet_ && (subnet_->getHostReservationMode() & Network::HR_GLOBAL)) {
auto host = hosts_.find(SUBNET_ID_GLOBAL);
if (host != hosts_.cend()) {
return (host->second);
@ -3311,7 +3313,7 @@ AllocEngine::findReservation(ClientContext4& ctx) {
SharedNetwork4Ptr network;
subnet->getSharedNetwork(network);
if (subnet->getHostReservationMode() == Network::HR_GLOBAL) {
if (subnet->getHostReservationMode() & Network::HR_GLOBAL) {
ConstHostPtr ghost = findGlobalReservation(ctx);
if (ghost) {
ctx.hosts_[SUBNET_ID_GLOBAL] = ghost;

View File

@ -451,19 +451,25 @@ public:
util::Optional<bool> hr_mode_global;
getGlobalProperty(hr_mode_global, "reservation-modes.global");
if (!hr_mode_global.unspecified()) {
flags |= Network::HR_GLOBAL;
if (hr_mode_global.get()) {
flags |= Network::HR_GLOBAL;
}
found = true;
}
util::Optional<bool> hr_mode_in_subnet;
getGlobalProperty(hr_mode_in_subnet, "reservation-modes.in-subnet");
if (!hr_mode_in_subnet.unspecified()) {
flags |= Network::HR_IN_SUBNET;
if (hr_mode_in_subnet.get()) {
flags |= Network::HR_IN_SUBNET;
}
found = true;
}
util::Optional<bool> hr_mode_out_of_pool;
getGlobalProperty(hr_mode_out_of_pool, "reservation-modes.out-of-pool");
if (!hr_mode_out_of_pool.unspecified()) {
flags |= Network::HR_OUT_OF_POOL;
if (hr_mode_out_of_pool.get()) {
flags |= Network::HR_OUT_OF_POOL;
}
found = true;
}
if (found) {

View File

@ -399,16 +399,6 @@ SharedNetwork4::subnetsIncludeMatchClientId(const Subnet4Ptr& first_subnet,
return (false);
}
Subnet4Ptr
SharedNetwork4::subnetsAllHRGlobal() const {
for (auto subnet : *getAllSubnets()) {
if (subnet->getHostReservationMode() != Network::HR_GLOBAL) {
return (subnet);
}
}
return (Subnet4Ptr());
}
ElementPtr
SharedNetwork4::toElement() const {
ElementPtr map = Network4::toElement();
@ -498,16 +488,6 @@ SharedNetwork6::getPreferredSubnet(const Subnet6Ptr& selected_subnet,
return (Impl::getPreferredSubnet(subnets_, selected_subnet, lease_type));
}
Subnet6Ptr
SharedNetwork6::subnetsAllHRGlobal() const {
for (auto subnet : *getAllSubnets()) {
if (subnet->getHostReservationMode() != Network::HR_GLOBAL) {
return (subnet);
}
}
return (Subnet6Ptr());
}
ElementPtr
SharedNetwork6::toElement() const {
ElementPtr map = Network6::toElement();

View File

@ -195,12 +195,6 @@ public:
bool subnetsIncludeMatchClientId(const Subnet4Ptr& first_subnet,
const ClientClasses& client_classes);
/// @brief Check if the shared network includes a subnet with
/// not global host reservation mode.
///
/// @return First subnet which has not a global host reservation mode.
Subnet4Ptr subnetsAllHRGlobal() const;
/// @brief Unparses shared network object.
///
/// @return A pointer to unparsed shared network configuration.
@ -399,12 +393,6 @@ public:
Subnet6Ptr getPreferredSubnet(const Subnet6Ptr& selected_subnet,
const Lease::Type& lease_type) const;
/// @brief Check if the shared network includes a subnet with
/// not global host reservation mode.
///
/// @return First subnet which has not a global host reservation mode.
Subnet6Ptr subnetsAllHRGlobal() const;
/// @brief Unparses shared network object.
///
/// @return A pointer to unparsed shared network configuration.

View File

@ -185,6 +185,11 @@ TEST_F(NetworkTest, inheritanceSupport4) {
globals_->set("cache-max-age", Element::create(20));
globals_->set("ddns-update-on-renew", Element::create(true));
globals_->set("ddns-use-conflict-resolution", Element::create(true));
auto reservation_modes = Element::createMap();
reservation_modes->set("global", Element::create(false));
reservation_modes->set("in-subnet", Element::create(false));
reservation_modes->set("out-of-pool", Element::create(false));
globals_->set("reservation-modes", reservation_modes);
// For each parameter for which inheritance is supported run
// the test that checks if the values are inherited properly.
@ -217,6 +222,13 @@ TEST_F(NetworkTest, inheritanceSupport4) {
Network::HR_OUT_OF_POOL,
Network::HR_DISABLED);
}
{
SCOPED_TRACE("reservation-modes");
testNetworkInheritance<TestNetwork>(&Network::getHostReservationMode,
&Network::setHostReservationMode,
Network::HR_OUT_OF_POOL,
Network::HR_DISABLED);
}
{
SCOPED_TRACE("calculate-tee-times");
testNetworkInheritance<TestNetwork>(&Network::getCalculateTeeTimes,

View File

@ -128,7 +128,7 @@ public:
" \"rebind-timer\": 199,"
" \"relay\": { \"ip-addresses\": [ \"10.1.1.1\" ] },"
" \"renew-timer\": 99,"
" \"reservation-mode\": \"out-of-pool\","
" \"reservation-modes\": {\"out-of-pool\": True},"
" \"server-hostname\": \"example.org\","
" \"require-client-classes\": [ \"runner\" ],"
" \"user-context\": { \"comment\": \"example\" },"
@ -549,7 +549,7 @@ public:
" \"relay\": { \"ip-addresses\": [ \"2001:db8:1::1\" ] },"
" \"renew-timer\": 99,"
" \"require-client-classes\": [ \"runner\" ],"
" \"reservation-mode\": \"out-of-pool\","
" \"reservation-modes\": {\"out-of-pool\": True},"
" \"user-context\": { },"
" \"valid-lifetime\": 399,"
" \"min-valid-lifetime\": 299,"

View File

@ -576,36 +576,6 @@ TEST(SharedNetwork4Test, subnetsIncludeMatchClientId) {
EXPECT_TRUE(SharedNetwork4::subnetsIncludeMatchClientId(subnet1, classes));
}
// This test verifies that subnetsAllHRGlobal() works as expected.
TEST(SharedNetwork4Test, subnetsAllHRGlobal) {
SharedNetwork4Ptr network(new SharedNetwork4("frog"));
Subnet4Ptr bad;
// Empty shared network is right.
ASSERT_NO_THROW(bad = network->subnetsAllHRGlobal());
EXPECT_FALSE(bad);
// Create a subnet and add it to the shared network.
Subnet4Ptr subnet(new Subnet4(IOAddress("10.0.0.0"), 8, 10, 20, 30,
SubnetID(1)));
ASSERT_NO_THROW(network->add(subnet));
// Default host reservation mode is ALL.
bad.reset();
ASSERT_NO_THROW(bad = network->subnetsAllHRGlobal());
ASSERT_TRUE(bad);
EXPECT_EQ(1, bad->getID());
EXPECT_EQ("10.0.0.0/8", bad->toText());
// Set the HR mode to global.
subnet->setHostReservationMode(Network::HR_GLOBAL);
// Now the shared network is all global.
bad.reset();
ASSERT_NO_THROW(bad = network->subnetsAllHRGlobal());
EXPECT_FALSE(bad);
}
// This test verifies operations on the network's relay list
TEST(SharedNetwork4Test, relayInfoList) {
SharedNetwork4Ptr network(new SharedNetwork4("frog"));
@ -1298,36 +1268,6 @@ TEST(SharedNetwork6Test, getPreferredSubnetMultiThreading) {
EXPECT_EQ(subnet3->getID(), preferred->getID());
}
// This test verifies that subnetsAllHRGlobal() works as expected.
TEST(SharedNetwork6Test, subnetsAllHRGlobal) {
SharedNetwork6Ptr network(new SharedNetwork6("frog"));
Subnet6Ptr bad;
// Empty shared network is right.
ASSERT_NO_THROW(bad = network->subnetsAllHRGlobal());
EXPECT_FALSE(bad);
// Create a subnet and add it to the shared network.
Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), 64, 10, 20, 30,
40, SubnetID(1)));
ASSERT_NO_THROW(network->add(subnet));
// Default host reservation mode is ALL.
bad.reset();
ASSERT_NO_THROW(bad = network->subnetsAllHRGlobal());
ASSERT_TRUE(bad);
EXPECT_EQ(1, bad->getID());
EXPECT_EQ("2001:db8:1::/64", bad->toText());
// Set the HR mode to global.
subnet->setHostReservationMode(Network::HR_GLOBAL);
// Now the shared network is all global.
bad.reset();
ASSERT_NO_THROW(bad = network->subnetsAllHRGlobal());
EXPECT_FALSE(bad);
}
// This test verifies operations on the network's relay list
TEST(SharedNetwork6Test, relayInfoList) {
SharedNetwork6Ptr network(new SharedNetwork6("frog"));