Commit 9d434f28 authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[master] Merge branch 'trac3571'

parents 77c820a3 1f0c2a12
// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2014-2016 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
......@@ -78,7 +78,8 @@ Host::Host(const uint8_t* identifier, const size_t identifier_len,
ipv6_subnet_id_(ipv6_subnet_id),
ipv4_reservation_(asiolink::IOAddress::IPV4_ZERO_ADDRESS()),
hostname_(hostname), dhcp4_client_classes_(dhcp4_client_classes),
dhcp6_client_classes_(dhcp6_client_classes) {
dhcp6_client_classes_(dhcp6_client_classes),
cfg_option4_(), cfg_option6_() {
// Initialize HWAddr or DUID
setIdentifier(identifier, identifier_len, identifier_type);
......@@ -99,7 +100,8 @@ Host::Host(const std::string& identifier, const std::string& identifier_name,
ipv6_subnet_id_(ipv6_subnet_id),
ipv4_reservation_(asiolink::IOAddress::IPV4_ZERO_ADDRESS()),
hostname_(hostname), dhcp4_client_classes_(dhcp4_client_classes),
dhcp6_client_classes_(dhcp6_client_classes) {
dhcp6_client_classes_(dhcp6_client_classes),
cfg_option4_(new CfgOption()), cfg_option6_(new CfgOption()) {
// Initialize HWAddr or DUID
setIdentifier(identifier, identifier_name);
......
// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2014-2016 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
......@@ -11,6 +11,7 @@
#include <dhcp/classify.h>
#include <dhcp/duid.h>
#include <dhcp/hwaddr.h>
#include <dhcpsrv/cfg_option.h>
#include <dhcpsrv/subnet_id.h>
#include <boost/shared_ptr.hpp>
#include <list>
......@@ -154,9 +155,13 @@ typedef std::pair<IPv6ResrvIterator, IPv6ResrvIterator> IPv6ResrvRange;
/// DHCPv6 server and vice versa. Also, this approach allows for reserving
/// common resources such as host name for DHCPv4 and DHCPv6 clients.
///
/// This class also holds pointers to specific DHCP options reserved
/// for a host. Options instances are held in @c CfgOption objects.
/// There are two @c CfgOption objects in this class, one holding
/// DHCPv4 options, another one holding DHCPv6 options.
///
/// @todo This class offers basic functionality for storing host information.
/// It will need to be extended to allow for the following operations:
/// - store DHCPv4 and DHCPv6 options for the host,
/// - remove and replace IPv6 reservations
/// - remove and replace client classes
/// - disable IPv4 reservation without a need to set it to the 0.0.0.0 address
......@@ -409,6 +414,36 @@ public:
return (dhcp6_client_classes_);
}
/// @brief Returns pointer to the DHCPv4 option data configuration for
/// this host.
///
/// Returned pointer can be used to add, remove and udate options
/// reserved for a host.
CfgOptionPtr getCfgOption4() {
return (cfg_option4_);
}
/// @brief Returns const pointer to the DHCPv4 option data configuration for
/// this host.
ConstCfgOptionPtr getCfgOption4() const {
return (cfg_option4_);
}
/// @brief Returns pointer to the DHCPv6 option data configuration for
/// this host.
///
/// Returned pointer can be used to add, remove and udate options
/// reserved for a host.
CfgOptionPtr getCfgOption6() {
return (cfg_option6_);
}
/// @brief Returns const pointer to the DHCPv6 option data configuration for
/// this host.
ConstCfgOptionPtr getCfgOption6() const {
return (cfg_option6_);
}
/// @brief Returns information about the host in the textual format.
std::string toText() const;
......@@ -447,6 +482,10 @@ private:
ClientClasses dhcp4_client_classes_;
/// @brief Collection of classes associated with a DHCPv6 client.
ClientClasses dhcp6_client_classes_;
/// @brief Pointer to the DHCPv4 option data configuration for this host.
CfgOptionPtr cfg_option4_;
/// @brief Pointer to the DHCPv6 option data configuration for this host.
CfgOptionPtr cfg_option6_;
};
/// @brief Pointer to the @c Host object.
......
// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2014-2016 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
......@@ -503,6 +503,134 @@ TEST(HostTest, addClientClasses) {
EXPECT_TRUE(host->getClientClasses6().contains("bar"));
}
// This test checks that it is possible to add DHCPv4 options for a host.
TEST(HostTest, addOptions4) {
Host host("01:02:03:04:05:06", "hw-address", SubnetID(1), SubnetID(2),
IOAddress("192.0.2.3"));
// Differentiate options by their codes (100-109)
for (uint16_t code = 100; code < 110; ++code) {
OptionPtr option(new Option(Option::V4, code, OptionBuffer(10, 0xFF)));
ASSERT_NO_THROW(host.getCfgOption4()->add(option, false, "dhcp4"));
}
// Add 7 options to another option space. The option codes partially overlap
// with option codes that we have added to dhcp4 option space.
for (uint16_t code = 105; code < 112; ++code) {
OptionPtr option(new Option(Option::V4, code, OptionBuffer(10, 0xFF)));
ASSERT_NO_THROW(host.getCfgOption4()->add(option, false, "isc"));
}
// Get options from the Subnet and check if all 10 are there.
OptionContainerPtr options = host.getCfgOption4()->getAll("dhcp4");
ASSERT_TRUE(options);
ASSERT_EQ(10, options->size());
// It should be possible to retrieve DHCPv6 options but the container
// should be empty.
OptionContainerPtr options6 = host.getCfgOption6()->getAll("dhcp6");
ASSERT_TRUE(options6);
EXPECT_TRUE(options6->empty());
// Also make sure that for dhcp4 option space no DHCPv6 options are
// returned. This is to check that containers for DHCPv4 and DHCPv6
// options do not share information.
options6 = host.getCfgOption6()->getAll("dhcp4");
ASSERT_TRUE(options6);
EXPECT_TRUE(options6->empty());
// Validate codes of options added to dhcp4 option space.
uint16_t expected_code = 100;
for (OptionContainer::const_iterator option_desc = options->begin();
option_desc != options->end(); ++option_desc) {
ASSERT_TRUE(option_desc->option_);
EXPECT_EQ(expected_code, option_desc->option_->getType());
++expected_code;
}
options = host.getCfgOption4()->getAll("isc");
ASSERT_TRUE(options);
ASSERT_EQ(7, options->size());
// Validate codes of options added to isc option space.
expected_code = 105;
for (OptionContainer::const_iterator option_desc = options->begin();
option_desc != options->end(); ++option_desc) {
ASSERT_TRUE(option_desc->option_);
EXPECT_EQ(expected_code, option_desc->option_->getType());
++expected_code;
}
// Try to get options from a non-existing option space.
options = host.getCfgOption4()->getAll("abcd");
ASSERT_TRUE(options);
EXPECT_TRUE(options->empty());
}
// This test checks that it is possible to add DHCPv6 options for a host.
TEST(HostTest, addOptions6) {
Host host("01:02:03:04:05:06", "hw-address", SubnetID(1), SubnetID(2),
IOAddress("192.0.2.3"));
// Differentiate options by their codes (100-109)
for (uint16_t code = 100; code < 110; ++code) {
OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
ASSERT_NO_THROW(host.getCfgOption6()->add(option, false, "dhcp6"));
}
// Add 7 options to another option space. The option codes partially overlap
// with option codes that we have added to dhcp6 option space.
for (uint16_t code = 105; code < 112; ++code) {
OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
ASSERT_NO_THROW(host.getCfgOption6()->add(option, false, "isc"));
}
// Get options from the Subnet and check if all 10 are there.
OptionContainerPtr options = host.getCfgOption6()->getAll("dhcp6");
ASSERT_TRUE(options);
ASSERT_EQ(10, options->size());
// It should be possible to retrieve DHCPv4 options but the container
// should be empty.
OptionContainerPtr options4 = host.getCfgOption4()->getAll("dhcp4");
ASSERT_TRUE(options4);
EXPECT_TRUE(options4->empty());
// Also make sure that for dhcp6 option space no DHCPv4 options are
// returned. This is to check that containers for DHCPv4 and DHCPv6
// options do not share information.
options4 = host.getCfgOption4()->getAll("dhcp6");
ASSERT_TRUE(options4);
EXPECT_TRUE(options4->empty());
// Validate codes of options added to dhcp6 option space.
uint16_t expected_code = 100;
for (OptionContainer::const_iterator option_desc = options->begin();
option_desc != options->end(); ++option_desc) {
ASSERT_TRUE(option_desc->option_);
EXPECT_EQ(expected_code, option_desc->option_->getType());
++expected_code;
}
options = host.getCfgOption6()->getAll("isc");
ASSERT_TRUE(options);
ASSERT_EQ(7, options->size());
// Validate codes of options added to isc option space.
expected_code = 105;
for (OptionContainer::const_iterator option_desc = options->begin();
option_desc != options->end(); ++option_desc) {
ASSERT_TRUE(option_desc->option_);
EXPECT_EQ(expected_code, option_desc->option_->getType());
++expected_code;
}
// Try to get options from a non-existing option space.
options = host.getCfgOption6()->getAll("abcd");
ASSERT_TRUE(options);
EXPECT_TRUE(options->empty());
}
TEST(HostTest, getIdentifierAsText) {
Host host1("01:02:03:04:05:06", "hw-address",
SubnetID(1), SubnetID(2),
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment