mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-09-02 23:15:20 +00:00
[3628] Host reservation parser is now connected to the subnet parsers.
This commit is contained in:
@@ -22,6 +22,8 @@
|
|||||||
#include <dhcpsrv/option_space_container.h>
|
#include <dhcpsrv/option_space_container.h>
|
||||||
#include <dhcpsrv/parsers/dbaccess_parser.h>
|
#include <dhcpsrv/parsers/dbaccess_parser.h>
|
||||||
#include <dhcpsrv/parsers/dhcp_parsers.h>
|
#include <dhcpsrv/parsers/dhcp_parsers.h>
|
||||||
|
#include <dhcpsrv/parsers/host_reservation_parser.h>
|
||||||
|
#include <dhcpsrv/parsers/host_reservations_list_parser.h>
|
||||||
#include <util/encode/hex.h>
|
#include <util/encode/hex.h>
|
||||||
#include <util/strutil.h>
|
#include <util/strutil.h>
|
||||||
|
|
||||||
@@ -144,6 +146,14 @@ public:
|
|||||||
<< subnet->getPosition() << ")");
|
<< subnet->getPosition() << ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse Host Reservations for this subnet if any.
|
||||||
|
ConstElementPtr reservations = subnet->get("reservations");
|
||||||
|
if (reservations) {
|
||||||
|
ParserPtr parser(new HostReservationsListParser<
|
||||||
|
HostReservationParser4>(subnet_->getID()));
|
||||||
|
parser->build(reservations);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Commits subnet configuration.
|
/// @brief Commits subnet configuration.
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#include <dhcp/tests/iface_mgr_test_config.h>
|
#include <dhcp/tests/iface_mgr_test_config.h>
|
||||||
#include <dhcpsrv/subnet.h>
|
#include <dhcpsrv/subnet.h>
|
||||||
#include <dhcpsrv/cfgmgr.h>
|
#include <dhcpsrv/cfgmgr.h>
|
||||||
|
#include <dhcpsrv/cfg_hosts.h>
|
||||||
#include <dhcpsrv/cfg_subnets4.h>
|
#include <dhcpsrv/cfg_subnets4.h>
|
||||||
#include <dhcpsrv/testutils/config_result_check.h>
|
#include <dhcpsrv/testutils/config_result_check.h>
|
||||||
#include <hooks/hooks_manager.h>
|
#include <hooks/hooks_manager.h>
|
||||||
@@ -3237,4 +3238,150 @@ TEST_F(Dhcp4ParserTest, classifySubnets) {
|
|||||||
EXPECT_TRUE (subnets->at(3)->clientSupported(classes));
|
EXPECT_TRUE (subnets->at(3)->clientSupported(classes));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This test verifies that the host reservations can be specified for
|
||||||
|
// respective IPv4 subnets.
|
||||||
|
TEST_F(Dhcp4ParserTest, reservations) {
|
||||||
|
ConstElementPtr x;
|
||||||
|
string config = "{ \"interfaces\": [ \"*\" ],"
|
||||||
|
"\"rebind-timer\": 2000, "
|
||||||
|
"\"renew-timer\": 1000, "
|
||||||
|
"\"subnet4\": [ { "
|
||||||
|
" \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
|
||||||
|
" \"subnet\": \"192.0.2.0/24\", "
|
||||||
|
" \"id\": 123,"
|
||||||
|
" \"reservations\": ["
|
||||||
|
" ]"
|
||||||
|
" },"
|
||||||
|
" {"
|
||||||
|
" \"reservations\": ["
|
||||||
|
" {"
|
||||||
|
" \"duid\": \"01:02:03:04:05:06:07:08:09:0A\","
|
||||||
|
" \"ip-address\": \"192.0.3.112\","
|
||||||
|
" \"hostname\": \"\""
|
||||||
|
" },"
|
||||||
|
" {"
|
||||||
|
" \"hw-address\": \"01:02:03:04:05:06\","
|
||||||
|
" \"ip-address\": \"192.0.3.120\","
|
||||||
|
" \"hostname\": \"\""
|
||||||
|
" }"
|
||||||
|
" ],"
|
||||||
|
" \"pools\": [ { \"pool\": \"192.0.3.101 - 192.0.3.150\" } ],"
|
||||||
|
" \"subnet\": \"192.0.3.0/24\", "
|
||||||
|
" \"id\": 234"
|
||||||
|
" },"
|
||||||
|
" {"
|
||||||
|
" \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],"
|
||||||
|
" \"subnet\": \"192.0.4.0/24\","
|
||||||
|
" \"id\": 542,"
|
||||||
|
" \"reservations\": ["
|
||||||
|
" {"
|
||||||
|
" \"duid\": \"0A:09:08:07:06:05:04:03:02:01\","
|
||||||
|
" \"ip-address\": \"192.0.4.101\","
|
||||||
|
" \"hostname\": \"\""
|
||||||
|
" },"
|
||||||
|
" {"
|
||||||
|
" \"hw-address\": \"06:05:04:03:02:01\","
|
||||||
|
" \"ip-address\": \"192.0.4.102\","
|
||||||
|
" \"hostname\": \"\""
|
||||||
|
" }"
|
||||||
|
" ]"
|
||||||
|
" } ],"
|
||||||
|
"\"valid-lifetime\": 4000 }";
|
||||||
|
|
||||||
|
ElementPtr json = Element::fromJSON(config);
|
||||||
|
|
||||||
|
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
|
||||||
|
checkResult(x, 0);
|
||||||
|
|
||||||
|
// Make sure all subnets have been successfully configured. There is no
|
||||||
|
// need to sanity check the subnet properties because it should have
|
||||||
|
// been already tested by other tests.
|
||||||
|
const Subnet4Collection* subnets =
|
||||||
|
CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->getAll();
|
||||||
|
ASSERT_TRUE(subnets);
|
||||||
|
ASSERT_EQ(3, subnets->size());
|
||||||
|
|
||||||
|
// Hosts configuration must be available.
|
||||||
|
CfgHostsPtr hosts_cfg = CfgMgr::instance().getStagingCfg()->getCfgHosts();
|
||||||
|
ASSERT_TRUE(hosts_cfg);
|
||||||
|
|
||||||
|
// Let's create an object holding hardware address of the host having
|
||||||
|
// a reservation in the subnet having id of 234. For simlicity the
|
||||||
|
// address is a collection of numbers from 1 to 6.
|
||||||
|
std::vector<uint8_t> hwaddr_vec;
|
||||||
|
for (int i = 1; i < 7; ++i) {
|
||||||
|
hwaddr_vec.push_back(static_cast<uint8_t>(i));
|
||||||
|
}
|
||||||
|
HWAddrPtr hwaddr(new HWAddr(hwaddr_vec, HTYPE_ETHER));
|
||||||
|
// Retrieve the reservation and sanity check the address reserved.
|
||||||
|
ConstHostPtr host = hosts_cfg->get4(234, hwaddr);
|
||||||
|
ASSERT_TRUE(host);
|
||||||
|
EXPECT_EQ("192.0.3.120", host->getIPv4Reservation().toText());
|
||||||
|
// This reservation should be solely assigned to the subnet 234,
|
||||||
|
// and not to other two.
|
||||||
|
EXPECT_FALSE(hosts_cfg->get4(123, hwaddr));
|
||||||
|
EXPECT_FALSE(hosts_cfg->get4(542, hwaddr));
|
||||||
|
|
||||||
|
// Do the same test for the DUID based reservation.
|
||||||
|
std::vector<uint8_t> duid_vec;
|
||||||
|
for (int i = 1; i < 0xb; ++i) {
|
||||||
|
duid_vec.push_back(static_cast<uint8_t>(i));
|
||||||
|
}
|
||||||
|
DuidPtr duid(new DUID(duid_vec));
|
||||||
|
host = hosts_cfg->get4(234, HWAddrPtr(), duid);
|
||||||
|
ASSERT_TRUE(host);
|
||||||
|
EXPECT_EQ("192.0.3.112", host->getIPv4Reservation().toText());
|
||||||
|
EXPECT_FALSE(hosts_cfg->get4(123, HWAddrPtr(), duid));
|
||||||
|
EXPECT_FALSE(hosts_cfg->get4(542, HWAddrPtr(), duid));
|
||||||
|
|
||||||
|
// The HW address used for one of the reservations in the subnet 542
|
||||||
|
// consists of numbers from 6 to 1. So, let's just reverse the order
|
||||||
|
// of the address from the previous test.
|
||||||
|
hwaddr->hwaddr_.assign(hwaddr_vec.rbegin(), hwaddr_vec.rend());
|
||||||
|
host = hosts_cfg->get4(542, hwaddr);
|
||||||
|
EXPECT_TRUE(host);
|
||||||
|
EXPECT_EQ("192.0.4.102", host->getIPv4Reservation().toText());
|
||||||
|
// This reservation must not belong to other subnets.
|
||||||
|
EXPECT_FALSE(hosts_cfg->get4(123, hwaddr));
|
||||||
|
EXPECT_FALSE(hosts_cfg->get4(234, hwaddr));
|
||||||
|
|
||||||
|
// Repeat the test for the DUID based reservation in this subnet.
|
||||||
|
duid.reset(new DUID(std::vector<uint8_t>(duid_vec.rbegin(),
|
||||||
|
duid_vec.rend())));
|
||||||
|
host = hosts_cfg->get4(542, HWAddrPtr(), duid);
|
||||||
|
ASSERT_TRUE(host);
|
||||||
|
EXPECT_EQ("192.0.4.101", host->getIPv4Reservation().toText());
|
||||||
|
EXPECT_FALSE(hosts_cfg->get4(123, HWAddrPtr(), duid));
|
||||||
|
EXPECT_FALSE(hosts_cfg->get4(234, HWAddrPtr(), duid));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// This test verfies that the bogus host reservation would trigger a
|
||||||
|
// server configuration error. In this case the "hw-address" parameter in the
|
||||||
|
// reservation is misspelled.
|
||||||
|
TEST_F(Dhcp4ParserTest, reservationBogus) {
|
||||||
|
ConstElementPtr x;
|
||||||
|
string config = "{ \"interfaces\": [ \"*\" ],"
|
||||||
|
"\"rebind-timer\": 2000, "
|
||||||
|
"\"renew-timer\": 1000, "
|
||||||
|
"\"subnet4\": [ { "
|
||||||
|
" \"pools\": [ { \"pool\": \"192.0.4.101 - 192.0.4.150\" } ],"
|
||||||
|
" \"subnet\": \"192.0.4.0/24\","
|
||||||
|
" \"id\": 542,"
|
||||||
|
" \"reservations\": ["
|
||||||
|
" {"
|
||||||
|
" \"hw-addre\": \"06:05:04:03:02:01\","
|
||||||
|
" \"ip-address\": \"192.0.4.102\","
|
||||||
|
" \"hostname\": \"\""
|
||||||
|
" }"
|
||||||
|
" ]"
|
||||||
|
" } ],"
|
||||||
|
"\"valid-lifetime\": 4000 }";
|
||||||
|
|
||||||
|
ElementPtr json = Element::fromJSON(config);
|
||||||
|
|
||||||
|
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
|
||||||
|
checkResult(x, 1);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -27,6 +27,8 @@
|
|||||||
#include <dhcpsrv/parsers/dbaccess_parser.h>
|
#include <dhcpsrv/parsers/dbaccess_parser.h>
|
||||||
#include <dhcpsrv/parsers/dhcp_config_parser.h>
|
#include <dhcpsrv/parsers/dhcp_config_parser.h>
|
||||||
#include <dhcpsrv/parsers/dhcp_parsers.h>
|
#include <dhcpsrv/parsers/dhcp_parsers.h>
|
||||||
|
#include <dhcpsrv/parsers/host_reservation_parser.h>
|
||||||
|
#include <dhcpsrv/parsers/host_reservations_list_parser.h>
|
||||||
#include <log/logger_support.h>
|
#include <log/logger_support.h>
|
||||||
#include <util/encode/hex.h>
|
#include <util/encode/hex.h>
|
||||||
#include <util/strutil.h>
|
#include <util/strutil.h>
|
||||||
@@ -350,6 +352,13 @@ public:
|
|||||||
<< subnet->getPosition() << ")");
|
<< subnet->getPosition() << ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse Host Reservations for this subnet if any.
|
||||||
|
ConstElementPtr reservations = subnet->get("reservations");
|
||||||
|
if (reservations) {
|
||||||
|
ParserPtr parser(new HostReservationsListParser<
|
||||||
|
HostReservationParser6>(subnet_->getID()));
|
||||||
|
parser->build(reservations);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
#include <dhcp6/dhcp6_srv.h>
|
#include <dhcp6/dhcp6_srv.h>
|
||||||
#include <dhcpsrv/addr_utilities.h>
|
#include <dhcpsrv/addr_utilities.h>
|
||||||
#include <dhcpsrv/cfgmgr.h>
|
#include <dhcpsrv/cfgmgr.h>
|
||||||
|
#include <dhcpsrv/cfg_hosts.h>
|
||||||
#include <dhcpsrv/subnet.h>
|
#include <dhcpsrv/subnet.h>
|
||||||
#include <dhcpsrv/subnet_selector.h>
|
#include <dhcpsrv/subnet_selector.h>
|
||||||
#include <dhcpsrv/testutils/config_result_check.h>
|
#include <dhcpsrv/testutils/config_result_check.h>
|
||||||
@@ -3384,4 +3385,184 @@ TEST_F(Dhcp6ParserTest, invalidD2ClientConfig) {
|
|||||||
ASSERT_FALSE(CfgMgr::instance().ddnsEnabled());
|
ASSERT_FALSE(CfgMgr::instance().ddnsEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief Checks if the reservation is in the range of reservations.
|
||||||
|
///
|
||||||
|
/// @param resrv Reservation to be searched for.
|
||||||
|
/// @param range Range of reservations returned by the @c Host object
|
||||||
|
/// in which the reservation will be searched.
|
||||||
|
bool reservationExists(const IPv6Resrv& resrv, const IPv6ResrvRange& range) {
|
||||||
|
for (IPv6ResrvIterator it = range.first; it != range.second;
|
||||||
|
++it) {
|
||||||
|
if (resrv == it->second) {
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This test verifies that the host reservations can be specified for
|
||||||
|
// respective IPv6 subnets.
|
||||||
|
TEST_F(Dhcp6ParserTest, reservations) {
|
||||||
|
ConstElementPtr x;
|
||||||
|
string config = "{ \"interfaces\": [ \"*\" ],"
|
||||||
|
"\"rebind-timer\": 2000, "
|
||||||
|
"\"renew-timer\": 1000, "
|
||||||
|
"\"subnet6\": [ { "
|
||||||
|
" \"pools\": [ { \"pool\": \"2001:db8:1::/80\" } ],"
|
||||||
|
" \"subnet\": \"2001:db8:1::/64\", "
|
||||||
|
" \"id\": 123,"
|
||||||
|
" \"reservations\": ["
|
||||||
|
" ]"
|
||||||
|
" },"
|
||||||
|
" {"
|
||||||
|
" \"reservations\": ["
|
||||||
|
" {"
|
||||||
|
" \"duid\": \"01:02:03:04:05:06:07:08:09:0A\","
|
||||||
|
" \"ip-addresses\": [ \"2001:db8:2::1234\" ],"
|
||||||
|
" \"hostname\": \"\""
|
||||||
|
" },"
|
||||||
|
" {"
|
||||||
|
" \"hw-address\": \"01:02:03:04:05:06\","
|
||||||
|
" \"ip-addresses\": [ \"2001:db8:2::abcd\" ],"
|
||||||
|
" \"hostname\": \"\""
|
||||||
|
" }"
|
||||||
|
" ],"
|
||||||
|
" \"pools\": [ ],"
|
||||||
|
" \"subnet\": \"2001:db8:2::/64\", "
|
||||||
|
" \"id\": 234"
|
||||||
|
" },"
|
||||||
|
" {"
|
||||||
|
" \"pools\": [ ],"
|
||||||
|
" \"subnet\": \"2001:db8:3::/64\", "
|
||||||
|
" \"id\": 542,"
|
||||||
|
" \"reservations\": ["
|
||||||
|
" {"
|
||||||
|
" \"duid\": \"0A:09:08:07:06:05:04:03:02:01\","
|
||||||
|
" \"prefixes\": [ \"2001:db8:3:2::/96\" ],"
|
||||||
|
" \"hostname\": \"\""
|
||||||
|
" },"
|
||||||
|
" {"
|
||||||
|
" \"hw-address\": \"06:05:04:03:02:01\","
|
||||||
|
" \"prefixes\": [ \"2001:db8:3:1::/96\" ],"
|
||||||
|
" \"hostname\": \"\""
|
||||||
|
" }"
|
||||||
|
" ]"
|
||||||
|
" } ],"
|
||||||
|
"\"preferred-lifetime\": 3000,"
|
||||||
|
"\"valid-lifetime\": 4000 }";
|
||||||
|
|
||||||
|
ElementPtr json = Element::fromJSON(config);
|
||||||
|
|
||||||
|
EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
|
||||||
|
checkResult(x, 0);
|
||||||
|
|
||||||
|
// Make sure all subnets have been successfully configured. There is no
|
||||||
|
// need to sanity check the subnet properties because it should have
|
||||||
|
// been already tested by other tests.
|
||||||
|
const Subnet6Collection* subnets =
|
||||||
|
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->getAll();
|
||||||
|
ASSERT_TRUE(subnets);
|
||||||
|
ASSERT_EQ(3, subnets->size());
|
||||||
|
|
||||||
|
// Hosts configuration must be available.
|
||||||
|
CfgHostsPtr hosts_cfg = CfgMgr::instance().getStagingCfg()->getCfgHosts();
|
||||||
|
ASSERT_TRUE(hosts_cfg);
|
||||||
|
|
||||||
|
// Let's create an object holding hardware address of the host having
|
||||||
|
// a reservation in the subnet having id of 234. For simlicity the
|
||||||
|
// address is a collection of numbers from 1 to 6.
|
||||||
|
std::vector<uint8_t> hwaddr_vec;
|
||||||
|
for (int i = 1; i < 7; ++i) {
|
||||||
|
hwaddr_vec.push_back(static_cast<uint8_t>(i));
|
||||||
|
}
|
||||||
|
HWAddrPtr hwaddr(new HWAddr(hwaddr_vec, HTYPE_ETHER));
|
||||||
|
// Retrieve the reservation and sanity check the address reserved.
|
||||||
|
ConstHostPtr host = hosts_cfg->get6(234, DuidPtr(), hwaddr);
|
||||||
|
ASSERT_TRUE(host);
|
||||||
|
IPv6ResrvRange resrv = host->getIPv6Reservations(IPv6Resrv::TYPE_NA);
|
||||||
|
ASSERT_EQ(1, std::distance(resrv.first, resrv.second));
|
||||||
|
EXPECT_TRUE(reservationExists(IPv6Resrv(IPv6Resrv::TYPE_NA,
|
||||||
|
IOAddress("2001:db8:2::abcd")),
|
||||||
|
resrv));
|
||||||
|
// This reservation should be solely assigned to the subnet 234,
|
||||||
|
// and not to other two.
|
||||||
|
EXPECT_FALSE(hosts_cfg->get6(123, DuidPtr(), hwaddr));
|
||||||
|
EXPECT_FALSE(hosts_cfg->get6(542, DuidPtr(), hwaddr));
|
||||||
|
|
||||||
|
// Do the same test for the DUID based reservation.
|
||||||
|
std::vector<uint8_t> duid_vec;
|
||||||
|
for (int i = 1; i < 0xb; ++i) {
|
||||||
|
duid_vec.push_back(static_cast<uint8_t>(i));
|
||||||
|
}
|
||||||
|
DuidPtr duid(new DUID(duid_vec));
|
||||||
|
host = hosts_cfg->get6(234, duid);
|
||||||
|
ASSERT_TRUE(host);
|
||||||
|
resrv = host->getIPv6Reservations(IPv6Resrv::TYPE_NA);
|
||||||
|
ASSERT_EQ(1, std::distance(resrv.first, resrv.second));
|
||||||
|
EXPECT_TRUE(reservationExists(IPv6Resrv(IPv6Resrv::TYPE_NA,
|
||||||
|
IOAddress("2001:db8:2::1234")),
|
||||||
|
resrv));
|
||||||
|
EXPECT_FALSE(hosts_cfg->get6(123, duid));
|
||||||
|
EXPECT_FALSE(hosts_cfg->get6(542, duid));
|
||||||
|
|
||||||
|
// The HW address used for one of the reservations in the subnet 542
|
||||||
|
// consists of numbers from 6 to 1. So, let's just reverse the order
|
||||||
|
// of the address from the previous test.
|
||||||
|
hwaddr->hwaddr_.assign(hwaddr_vec.rbegin(), hwaddr_vec.rend());
|
||||||
|
host = hosts_cfg->get6(542, DuidPtr(), hwaddr);
|
||||||
|
EXPECT_TRUE(host);
|
||||||
|
resrv = host->getIPv6Reservations(IPv6Resrv::TYPE_PD);
|
||||||
|
ASSERT_EQ(1, std::distance(resrv.first, resrv.second));
|
||||||
|
EXPECT_TRUE(reservationExists(IPv6Resrv(IPv6Resrv::TYPE_PD,
|
||||||
|
IOAddress("2001:db8:3:1::"),
|
||||||
|
96), resrv));
|
||||||
|
|
||||||
|
// This reservation must not belong to other subnets.
|
||||||
|
EXPECT_FALSE(hosts_cfg->get6(123, DuidPtr(), hwaddr));
|
||||||
|
EXPECT_FALSE(hosts_cfg->get6(234, DuidPtr(), hwaddr));
|
||||||
|
|
||||||
|
// Repeat the test for the DUID based reservation in this subnet.
|
||||||
|
duid.reset(new DUID(std::vector<uint8_t>(duid_vec.rbegin(),
|
||||||
|
duid_vec.rend())));
|
||||||
|
host = hosts_cfg->get6(542, duid);
|
||||||
|
ASSERT_TRUE(host);
|
||||||
|
resrv = host->getIPv6Reservations(IPv6Resrv::TYPE_PD);
|
||||||
|
ASSERT_EQ(1, std::distance(resrv.first, resrv.second));
|
||||||
|
EXPECT_TRUE(reservationExists(IPv6Resrv(IPv6Resrv::TYPE_PD,
|
||||||
|
IOAddress("2001:db8:3:2::"),
|
||||||
|
96), resrv));
|
||||||
|
|
||||||
|
EXPECT_FALSE(hosts_cfg->get6(123, duid));
|
||||||
|
EXPECT_FALSE(hosts_cfg->get6(234, duid));
|
||||||
|
}
|
||||||
|
|
||||||
|
// This test verfies that the bogus host reservation would trigger a
|
||||||
|
// server configuration error. In this case the "duid" parameter in the
|
||||||
|
// reservation is misspelled.
|
||||||
|
TEST_F(Dhcp6ParserTest, reservationBogus) {
|
||||||
|
ConstElementPtr x;
|
||||||
|
string config = "{ \"interfaces\": [ \"*\" ],"
|
||||||
|
"\"rebind-timer\": 2000, "
|
||||||
|
"\"renew-timer\": 1000, "
|
||||||
|
"\"subnet6\": [ { "
|
||||||
|
" \"pools\": [ ],"
|
||||||
|
" \"subnet\": \"2001:db8:3::/64\", "
|
||||||
|
" \"id\": 542,"
|
||||||
|
" \"reservations\": ["
|
||||||
|
" {"
|
||||||
|
" \"dui\": \"0A:09:08:07:06:05:04:03:02:01\","
|
||||||
|
" \"prefixes\": [ \"2001:db8:3:2::/96\" ],"
|
||||||
|
" \"hostname\": \"\""
|
||||||
|
" }"
|
||||||
|
" ]"
|
||||||
|
" } ],"
|
||||||
|
"\"preferred-lifetime\": 3000,"
|
||||||
|
"\"valid-lifetime\": 4000 }";
|
||||||
|
|
||||||
|
ElementPtr json = Element::fromJSON(config);
|
||||||
|
|
||||||
|
EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
|
||||||
|
checkResult(x, 1);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@@ -965,12 +965,18 @@ SubnetConfigParser::SubnetConfigParser(const std::string&,
|
|||||||
void
|
void
|
||||||
SubnetConfigParser::build(ConstElementPtr subnet) {
|
SubnetConfigParser::build(ConstElementPtr subnet) {
|
||||||
BOOST_FOREACH(ConfigPair param, subnet->mapValue()) {
|
BOOST_FOREACH(ConfigPair param, subnet->mapValue()) {
|
||||||
|
// Host reservations must be parsed after subnet specific parameters.
|
||||||
|
if (param.first == "reservations") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
ParserPtr parser;
|
ParserPtr parser;
|
||||||
// When unsupported parameter is specified, the function called
|
// When unsupported parameter is specified, the function called
|
||||||
// below will thrown an exception. We have to catch this exception
|
// below will thrown an exception. We have to catch this exception
|
||||||
// to append the line number where the parameter is.
|
// to append the line number where the parameter is.
|
||||||
try {
|
try {
|
||||||
parser.reset(createSubnetConfigParser(param.first));
|
parser.reset(createSubnetConfigParser(param.first));
|
||||||
|
|
||||||
} catch (const std::exception& ex) {
|
} catch (const std::exception& ex) {
|
||||||
isc_throw(DhcpConfigError, ex.what() << " ("
|
isc_throw(DhcpConfigError, ex.what() << " ("
|
||||||
<< param.second->getPosition() << ")");
|
<< param.second->getPosition() << ")");
|
||||||
|
@@ -61,7 +61,7 @@ HostReservationParser::build(isc::data::ConstElementPtr reservation_data) {
|
|||||||
try {
|
try {
|
||||||
// hw-address or duid is a must.
|
// hw-address or duid is a must.
|
||||||
if (identifier_name.empty()) {
|
if (identifier_name.empty()) {
|
||||||
isc_throw(DhcpConfigError, "'hw-address' or 'duid' is a requirement"
|
isc_throw(DhcpConfigError, "'hw-address' or 'duid' is a required"
|
||||||
" parameter for host reservation");
|
" parameter for host reservation");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
#ifndef HOST_RESERVATIONS_LIST_PARSER_H
|
#ifndef HOST_RESERVATIONS_LIST_PARSER_H
|
||||||
#define HOST_RESERVATIONS_LIST_PARSER_H
|
#define HOST_RESERVATIONS_LIST_PARSER_H
|
||||||
|
|
||||||
|
#include <cc/data.h>
|
||||||
#include <dhcpsrv/subnet_id.h>
|
#include <dhcpsrv/subnet_id.h>
|
||||||
#include <dhcpsrv/parsers/dhcp_config_parser.h>
|
#include <dhcpsrv/parsers/dhcp_config_parser.h>
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
@@ -23,6 +24,11 @@ namespace isc {
|
|||||||
namespace dhcp {
|
namespace dhcp {
|
||||||
|
|
||||||
/// @brief Parser for a list of host reservations for a subnet.
|
/// @brief Parser for a list of host reservations for a subnet.
|
||||||
|
///
|
||||||
|
/// @tparam HostReservationParserType Host reservation parser to be used to
|
||||||
|
/// parse individual reservations: @c HostReservationParser4 or
|
||||||
|
/// @c HostReservationParser6.
|
||||||
|
template<typename HostReservationParserType>
|
||||||
class HostReservationsListParser : public DhcpConfigParser {
|
class HostReservationsListParser : public DhcpConfigParser {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -41,9 +47,8 @@ public:
|
|||||||
///
|
///
|
||||||
/// @throw DhcpConfigError If the configuration if any of the reservations
|
/// @throw DhcpConfigError If the configuration if any of the reservations
|
||||||
/// is invalid.
|
/// is invalid.
|
||||||
template<typename HostReservationParserType>
|
|
||||||
virtual void build(isc::data::ConstElementPtr hr_list) {
|
virtual void build(isc::data::ConstElementPtr hr_list) {
|
||||||
BOOST_FOREACH(ConstElementPtr reservation, hr_list->listValue()) {
|
BOOST_FOREACH(data::ConstElementPtr reservation, hr_list->listValue()) {
|
||||||
ParserPtr parser(new HostReservationParserType(subnet_id_));
|
ParserPtr parser(new HostReservationParserType(subnet_id_));
|
||||||
parser->build(reservation);
|
parser->build(reservation);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user