summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcin Siodelski <marcin@isc.org>2016-08-22 11:40:01 +0200
committerMarcin Siodelski <marcin@isc.org>2016-08-23 12:09:36 +0200
commit7ca1d779673f6704d81fb39a71d37620fa2d9042 (patch)
tree0d13f3c56c4a01ea73eb3fb25eae06ae57b906aa
parent[4552] Updated Host object with DHCPv4 specific message fields. (diff)
downloadkea-7ca1d779673f6704d81fb39a71d37620fa2d9042.tar.xz
kea-7ca1d779673f6704d81fb39a71d37620fa2d9042.zip
[4552] Added support for DHCPv4 message fields into config parser.
-rw-r--r--src/bin/dhcp4/dhcp4.spec18
-rw-r--r--src/lib/dhcpsrv/cfg_hosts.cc7
-rw-r--r--src/lib/dhcpsrv/parsers/host_reservation_parser.cc13
-rw-r--r--src/lib/dhcpsrv/tests/host_reservation_parser_unittest.cc52
4 files changed, 87 insertions, 3 deletions
diff --git a/src/bin/dhcp4/dhcp4.spec b/src/bin/dhcp4/dhcp4.spec
index 8e24e6992e..24cb0d6020 100644
--- a/src/bin/dhcp4/dhcp4.spec
+++ b/src/bin/dhcp4/dhcp4.spec
@@ -507,6 +507,24 @@
"item_type": "string",
"item_optional": false,
"item_default": "0.0.0.0"
+ },
+ {
+ "item_name": "next-server",
+ "item_type": "string",
+ "item_optional": true,
+ "item_default": "0.0.0.0"
+ },
+ {
+ "item_name": "server-name",
+ "item_type": "string",
+ "item_optional": true,
+ "item_default": ""
+ },
+ {
+ "item_name": "boot-file-name",
+ "item_type": "string",
+ "item_optional": true,
+ "item_default": ""
} ]
}
},
diff --git a/src/lib/dhcpsrv/cfg_hosts.cc b/src/lib/dhcpsrv/cfg_hosts.cc
index 2f4a0d1785..748fd4d273 100644
--- a/src/lib/dhcpsrv/cfg_hosts.cc
+++ b/src/lib/dhcpsrv/cfg_hosts.cc
@@ -572,10 +572,13 @@ CfgHosts::add4(const HostPtr& host) {
DuidPtr duid = host->getDuid();
// There should be at least one resource reserved: hostname, IPv4
- // address, IPv6 address or prefix.
+ // address, siaddr, sname, file or IPv6 address or prefix.
if (host->getHostname().empty() &&
(host->getIPv4Reservation().isV4Zero()) &&
- (!host->hasIPv6Reservation()) &&
+ !host->hasIPv6Reservation() &&
+ host->getNextServer().isV4Zero() &&
+ host->getServerHostname().empty() &&
+ host->getBootFileName().empty() &&
host->getCfgOption4()->empty() &&
host->getCfgOption6()->empty()) {
std::ostringstream s;
diff --git a/src/lib/dhcpsrv/parsers/host_reservation_parser.cc b/src/lib/dhcpsrv/parsers/host_reservation_parser.cc
index 491abfa495..5bf627b3d1 100644
--- a/src/lib/dhcpsrv/parsers/host_reservation_parser.cc
+++ b/src/lib/dhcpsrv/parsers/host_reservation_parser.cc
@@ -49,6 +49,9 @@ getSupportedParams4(const bool identifiers_only = false) {
params_set.insert("hostname");
params_set.insert("ip-address");
params_set.insert("option-data");
+ params_set.insert("next-server");
+ params_set.insert("server-name");
+ params_set.insert("boot-file-name");
}
return (identifiers_only ? identifiers_set : params_set);
}
@@ -120,7 +123,6 @@ HostReservationParser::build(isc::data::ConstElementPtr reservation_data) {
} else if (element.first == "hostname") {
hostname = element.second->stringValue();
-
}
} catch (const std::exception& ex) {
// Append line number where the error occurred.
@@ -207,7 +209,16 @@ HostReservationParser4::build(isc::data::ConstElementPtr reservation_data) {
if (element.first == "ip-address") {
host_->setIPv4Reservation(IOAddress(element.second->
stringValue()));
+ } else if (element.first == "next-server") {
+ host_->setNextServer(IOAddress(element.second->stringValue()));
+
+ } else if (element.first == "server-name") {
+ host_->setServerHostname(element.second->stringValue());
+
+ } else if (element.first == "boot-file-name") {
+ host_->setBootFileName(element.second->stringValue());
}
+
} catch (const std::exception& ex) {
// Append line number where the error occurred.
isc_throw(DhcpConfigError, ex.what() << " ("
diff --git a/src/lib/dhcpsrv/tests/host_reservation_parser_unittest.cc b/src/lib/dhcpsrv/tests/host_reservation_parser_unittest.cc
index 11ed6afe23..ea634b6b7b 100644
--- a/src/lib/dhcpsrv/tests/host_reservation_parser_unittest.cc
+++ b/src/lib/dhcpsrv/tests/host_reservation_parser_unittest.cc
@@ -299,6 +299,34 @@ TEST_F(HostReservationParserTest, dhcp4NoHostname) {
EXPECT_TRUE(hosts[0]->getHostname().empty());
}
+// This test verifies that the parser can parse reservation entry
+// containing next-server, server-name and boot-file-name values for
+// DHCPv4 message fields.
+TEST_F(HostReservationParserTest, dhcp4MessageFields) {
+ std::string config = "{ \"hw-address\": \"1:2:3:4:5:6\","
+ "\"next-server\": \"192.0.2.11\","
+ "\"server-name\": \"some-name.example.org\","
+ "\"boot-file-name\": \"/tmp/some-file.efi\" }";
+
+ ElementPtr config_element = Element::fromJSON(config);
+
+ HostReservationParser4 parser(SubnetID(10));
+ ASSERT_NO_THROW(parser.build(config_element));
+
+ CfgHostsPtr cfg_hosts = CfgMgr::instance().getStagingCfg()->getCfgHosts();
+ HostCollection hosts;
+ ASSERT_NO_THROW(hosts = cfg_hosts->getAll(Host::IDENT_HWADDR,
+ &hwaddr_->hwaddr_[0],
+ hwaddr_->hwaddr_.size()));
+
+ ASSERT_EQ(1, hosts.size());
+
+ EXPECT_EQ(10, hosts[0]->getIPv4SubnetID());
+ EXPECT_EQ("192.0.2.11", hosts[0]->getNextServer().toText());
+ EXPECT_EQ("some-name.example.org", hosts[0]->getServerHostname());
+ EXPECT_EQ("/tmp/some-file.efi", hosts[0]->getBootFileName());
+}
+
// This test verifies that the configuration parser for host reservations
// throws an exception when IPv6 address is specified for IPv4 address
@@ -381,6 +409,30 @@ TEST_F(HostReservationParserTest, bcastAddress) {
}
// This test verifies that the configuration parser for host reservations
+// throws an exception when invalid next server address is specified.
+TEST_F(HostReservationParserTest, malformedNextServer) {
+ std::string config = "{ \"hw-address\": \"01:02:03:04:05:06\","
+ "\"next-server\": \"192.0.2.bogus\" }";
+ testInvalidConfig<HostReservationParser4>(config);
+}
+
+// This test verifies that the configuration parser for host reservations
+// throws an exception when zero next server address is specified.
+TEST_F(HostReservationParserTest, zeroNextServer) {
+ std::string config = "{ \"hw-address\": \"01:02:03:04:05:06\","
+ "\"next-server\": \"0.0.0.0\" }";
+ testInvalidConfig<HostReservationParser4>(config);
+}
+
+// This test verifies that the configuration parser for host reservations
+// throws an exception when broadcast next server address is specified.
+TEST_F(HostReservationParserTest, bcastNextServer) {
+ std::string config = "{ \"hw-address\": \"01:02:03:04:05:06\","
+ "\"next-server\": \"255.255.255.255\" }";
+ testInvalidConfig<HostReservationParser4>(config);
+}
+
+// This test verifies that the configuration parser for host reservations
// throws an exception when unsupported parameter is specified.
TEST_F(HostReservationParserTest, invalidParameterName) {
// The "ip-addresses" parameter name is incorrect for the DHCPv4