summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcin Siodelski <marcin@isc.org>2016-05-19 19:45:46 +0200
committerMarcin Siodelski <marcin@isc.org>2016-06-03 12:41:21 +0200
commit2987c3d82fb6586c81f5c82246bfd1a9c0a0381d (patch)
treeb012d80600f7108260c1c027756774f9d88d8a0a
parent[master] Merge branch 'trac4318' (diff)
downloadkea-2987c3d82fb6586c81f5c82246bfd1a9c0a0381d.tar.xz
kea-2987c3d82fb6586c81f5c82246bfd1a9c0a0381d.zip
[4317] Added client-id as supported host identifier.
-rw-r--r--src/lib/dhcpsrv/host.cc9
-rw-r--r--src/lib/dhcpsrv/host.h16
-rw-r--r--src/lib/dhcpsrv/parsers/host_reservation_parser.cc1
-rw-r--r--src/lib/dhcpsrv/tests/host_reservation_parser_unittest.cc35
-rw-r--r--src/lib/dhcpsrv/tests/host_unittest.cc3
5 files changed, 57 insertions, 7 deletions
diff --git a/src/lib/dhcpsrv/host.cc b/src/lib/dhcpsrv/host.cc
index ac5b9f7660..3c54e188b2 100644
--- a/src/lib/dhcpsrv/host.cc
+++ b/src/lib/dhcpsrv/host.cc
@@ -136,6 +136,9 @@ Host::getIdentifierType(const std::string& identifier_name) {
} else if (identifier_name == "circuit-id") {
return (IDENT_CIRCUIT_ID);
+ } else if (identifier_name == "client-id") {
+ return (IDENT_CLIENT_ID);
+
} else {
isc_throw(isc::BadValue, "invalid client identifier type '"
<< identifier_name << "'");
@@ -176,6 +179,9 @@ Host::getIdentifierAsText(const IdentifierType& type, const uint8_t* value,
case IDENT_CIRCUIT_ID:
s << "circuit-id";
break;
+ case IDENT_CLIENT_ID:
+ s << "client-id";
+ break;
default:
// This should never happen actually, unless we add new identifier
// and forget to add a case for it above.
@@ -198,6 +204,9 @@ Host::getIdentifierName(const IdentifierType& type) {
case Host::IDENT_CIRCUIT_ID:
return ("circuit-id");
+ case Host::IDENT_CLIENT_ID:
+ return ("client-id");
+
default:
;
}
diff --git a/src/lib/dhcpsrv/host.h b/src/lib/dhcpsrv/host.h
index 01435bf279..433ac3dad6 100644
--- a/src/lib/dhcpsrv/host.h
+++ b/src/lib/dhcpsrv/host.h
@@ -175,17 +175,21 @@ public:
/// @brief Type of the host identifier.
///
- /// Currently hardware address assigned to an interface and the
- /// DHCPv6 client's DUID are supported.
+ /// Currently supported identifiers are:
+ /// - hardware address (DHCPv4 and DHCPv6),
+ /// - DUID (DHCPv4 and DHCPv6),
+ /// - circuit identifier (DHCPv4),
+ /// - client identifier (DHCPv4).
enum IdentifierType {
IDENT_HWADDR,
IDENT_DUID,
- IDENT_CIRCUIT_ID
+ IDENT_CIRCUIT_ID,
+ IDENT_CLIENT_ID
};
/// @brief Constant pointing to the last identifier of the
/// @ref IdentifierType enumeration.
- static const IdentifierType LAST_IDENTIFIER_TYPE = IDENT_CIRCUIT_ID;
+ static const IdentifierType LAST_IDENTIFIER_TYPE = IDENT_CLIENT_ID;
/// @brief Constructor.
///
@@ -240,7 +244,7 @@ public:
///
/// @param identifier Identifier in the textual format. The expected formats
/// for the hardware address and other identifiers are provided above.
- /// @param identifier_name One of "hw-address", "duid", "circuit-id".
+ /// @param identifier_name One of "hw-address", "duid", "circuit-id", "client-id".
/// @param ipv4_subnet_id Identifier of the IPv4 subnet to which the host
/// is connected.
/// @param ipv6_subnet_id Identifier of the IPv6 subnet to which the host
@@ -282,7 +286,7 @@ public:
/// This method is called by the @c Host constructor.
///
/// @param identifier Reference to a new identifier in the textual format.
- /// @param name One of "hw-address", "duid", "circuit-id".
+ /// @param name One of "hw-address", "duid", "circuit-id", "client-id".
///
/// @throw BadValue if the identifier is invalid.
void setIdentifier(const std::string& identifier, const std::string& name);
diff --git a/src/lib/dhcpsrv/parsers/host_reservation_parser.cc b/src/lib/dhcpsrv/parsers/host_reservation_parser.cc
index 35dafd359a..491abfa495 100644
--- a/src/lib/dhcpsrv/parsers/host_reservation_parser.cc
+++ b/src/lib/dhcpsrv/parsers/host_reservation_parser.cc
@@ -41,6 +41,7 @@ getSupportedParams4(const bool identifiers_only = false) {
identifiers_set.insert("hw-address");
identifiers_set.insert("duid");
identifiers_set.insert("circuit-id");
+ identifiers_set.insert("client-id");
}
// Copy identifiers and add all other parameters.
if (params_set.empty()) {
diff --git a/src/lib/dhcpsrv/tests/host_reservation_parser_unittest.cc b/src/lib/dhcpsrv/tests/host_reservation_parser_unittest.cc
index 88d879b912..ebcadf0113 100644
--- a/src/lib/dhcpsrv/tests/host_reservation_parser_unittest.cc
+++ b/src/lib/dhcpsrv/tests/host_reservation_parser_unittest.cc
@@ -182,6 +182,9 @@ protected:
/// @brief Vector holding circuit id used by tests.
std::vector<uint8_t> circuit_id_;
+
+ /// @brief Vector holding client id used by tests.
+ std::vector<uint8_t> client_id_;
};
void
@@ -199,6 +202,11 @@ HostReservationParserTest::SetUp() {
const std::string circuit_id_str = "howdy";
circuit_id_.assign(circuit_id_str.begin(), circuit_id_str.end());
+
+ client_id_.push_back(0x01); // Client identifier type.
+ // Often client id comprises HW address.
+ client_id_.insert(client_id_.end(), hwaddr_->hwaddr_.begin(),
+ hwaddr_->hwaddr_.end());
}
void
@@ -252,6 +260,22 @@ TEST_F(HostReservationParserTest, dhcp4CircuitIdHexWithPrefix) {
circuit_id_);
}
+// This test verifies that the parser can parse a reservation entry for
+// which client-id is an identifier. The client-id is specified in
+// hexadecimal format.
+TEST_F(HostReservationParserTest, dhcp4ClientIdHex) {
+ testIdentifier4("client-id", "01010203040506", Host::IDENT_CLIENT_ID,
+ client_id_);
+}
+
+// This test verifies that the parser can parse a reservation entry for
+// which client-id is an identifier. The client-id is specified in
+// hexadecimal format with a '0x' prefix.
+TEST_F(HostReservationParserTest, dhcp4ClientIdHexWithPrefix) {
+ testIdentifier4("client-id", "0x01010203040506", Host::IDENT_CLIENT_ID,
+ client_id_);
+}
+
// This test verifies that the parser can parse the reservation entry
// when IPv4 address is specified, but hostname is not.
TEST_F(HostReservationParserTest, dhcp4NoHostname) {
@@ -465,6 +489,17 @@ TEST_F(HostReservationParserTest, dhcp6CircuitId) {
testInvalidConfig<HostReservationParser6>(config);
}
+// This test verifies that host reservation parser for DHCPv6 rejects
+// "client-id" as a host identifier.
+TEST_F(HostReservationParserTest, dhcp6ClientId) {
+ // Use DHCPv4 specific identifier 'circuit-id' with DHCPv6 parser.
+ std::string config = "{ \"client-id\": \"01010203040506\","
+ "\"ip-addresses\": [ \"2001:db8:1::100\", \"2001:db8:1::200\" ],"
+ "\"prefixes\": [ ],"
+ "\"hostname\": \"foo.example.com\" }";
+ testInvalidConfig<HostReservationParser6>(config);
+}
+
// This test verfies that the parser can parse the IPv6 reservation entry
// which lacks hostname parameter.
TEST_F(HostReservationParserTest, dhcp6NoHostname) {
diff --git a/src/lib/dhcpsrv/tests/host_unittest.cc b/src/lib/dhcpsrv/tests/host_unittest.cc
index ee389158fd..535d861ef4 100644
--- a/src/lib/dhcpsrv/tests/host_unittest.cc
+++ b/src/lib/dhcpsrv/tests/host_unittest.cc
@@ -23,7 +23,7 @@ namespace {
/// @brief Holds a type of the last identifier in @c IdentifierType enum.
///
/// This value must be updated when new identifiers are added to the enum.
-const Host::IdentifierType LAST_IDENTIFIER_TYPE = Host::IDENT_CIRCUIT_ID;
+const Host::IdentifierType LAST_IDENTIFIER_TYPE = Host::IDENT_CLIENT_ID;
// This test verifies that it is possible to create IPv6 address
// reservation.
@@ -180,6 +180,7 @@ TEST_F(HostTest, getIdentifier) {
EXPECT_EQ(Host::IDENT_HWADDR, Host::getIdentifierType("hw-address"));
EXPECT_EQ(Host::IDENT_DUID, Host::getIdentifierType("duid"));
EXPECT_EQ(Host::IDENT_CIRCUIT_ID, Host::getIdentifierType("circuit-id"));
+ EXPECT_EQ(Host::IDENT_CLIENT_ID, Host::getIdentifierType("client-id"));
EXPECT_THROW(Host::getIdentifierType("unuspported"), isc::BadValue);
}