mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-30 21:45:37 +00:00
[#3390] Checkpoint: doc and split
This commit is contained in:
@@ -1736,6 +1736,8 @@ types are given in :ref:`dhcp-types`.
|
||||
+--------------------------+-----------------+-----------------+-----------------+
|
||||
| relay-id | 53 | binary | false |
|
||||
+--------------------------+-----------------+-----------------+-----------------+
|
||||
| ntp-server | 56 | empty | false |
|
||||
+--------------------------+-----------------+-----------------+-----------------+
|
||||
| v6-access-domain | 57 | fqdn | false |
|
||||
+--------------------------+-----------------+-----------------+-----------------+
|
||||
| sip-ua-cs-list | 58 | fqdn | true |
|
||||
@@ -2190,6 +2192,15 @@ Further examples are provided in Kea sources in the ``all-options.json`` file
|
||||
in the ``doc/examples/kea6`` directory. The DHCPv4 option is nearly identical, and is described
|
||||
in :ref:`dnr4-options`.
|
||||
|
||||
.. _ntp-server-suboptions:
|
||||
|
||||
NTP Server Suboptions
|
||||
---------------------
|
||||
|
||||
NTP server option is a contaier of suboptions: ntp-server-address (1), ntp-server-multicast (2)
|
||||
carrying an IPv6 address, and ntp-server-fqdn (3) carrying a FQDN in wire format defined
|
||||
in the "v6-ntp-server-suboptions" option space. Each option instance carries one and only one
|
||||
suboption as required by `RFC 5908 <https://tools.ietf.org/html/rfc5908>`__.
|
||||
|
||||
.. _dhcp6-custom-options:
|
||||
|
||||
@@ -7751,6 +7762,10 @@ The following standards are currently supported in Kea:
|
||||
query types) is supported. This requires the leasequery hook. See
|
||||
:ref:`hooks-lease-query` for details.
|
||||
|
||||
- *Network Time Protocol (NTP) Server Option for DHCPv6*:
|
||||
`RFC 5908 <https://tools.ietf.org/html/rfc5908>`__: The NTP server option and its
|
||||
suboptions are supported. See :ref:`ntp-server-suboptions` for details.
|
||||
|
||||
- *DHCPv6 Options for Network Boot*: `RFC 5970 <https://tools.ietf.org/html/rfc5970>`__:
|
||||
The network boot options are supported.
|
||||
|
||||
|
@@ -1384,6 +1384,7 @@ Dhcpv6Srv::processPacketPktSend(hooks::CalloutHandlePtr& callout_handle,
|
||||
|
||||
if (!skip_pack) {
|
||||
try {
|
||||
LibDHCP::splitNtpServerOptions6(rsp->options_);
|
||||
rsp->pack();
|
||||
} catch (const std::exception& e) {
|
||||
LOG_ERROR(options6_logger, DHCP6_PACK_FAIL)
|
||||
|
@@ -16,6 +16,7 @@
|
||||
#include <dhcp/option_definition.h>
|
||||
#include <dhcp/option_int_array.h>
|
||||
#include <dhcp/option_vendor_class.h>
|
||||
#include <dhcp/option_custom.h>
|
||||
#include <dhcp/std_option_defs.h>
|
||||
#include <dhcp/docsis3_option_defs.h>
|
||||
#include <exceptions/exceptions.h>
|
||||
@@ -1251,6 +1252,25 @@ LibDHCP::packOptions6(OutputBuffer& buf, const OptionCollection& options) {
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LibDHCP::splitNtpServerOptions6(OptionCollection& options) {
|
||||
pair<OptionCollection::const_iterator, OptionCollection::const_iterator>
|
||||
range = options.equal_range(D6O_NTP_SERVER);
|
||||
if (range.first == range.second) {
|
||||
return;
|
||||
}
|
||||
auto ntp_servers = OptionCollection(range.first, range.second);
|
||||
static_cast<void>(options.erase(range.first, range.second));
|
||||
auto def = D6O_NTP_SERVER_DEF();
|
||||
for (auto opt : ntp_servers) {
|
||||
for (auto sub : opt.second->getOptions()) {
|
||||
auto new_option(new OptionCustom(def, Option::V6));
|
||||
new_option->addOption(sub.second);
|
||||
options.insert(make_pair(D6O_NTP_SERVER, new_option));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LibDHCP::OptionFactoryRegister(Option::Universe u, uint16_t opt_type,
|
||||
Option::Factory* factory) {
|
||||
@@ -1311,6 +1331,7 @@ LibDHCP::initOptionDefs() {
|
||||
static_cast<void>(LibDHCP::D6O_LQ_QUERY_DEF());
|
||||
static_cast<void>(LibDHCP::D6O_CLIENT_DATA_DEF());
|
||||
static_cast<void>(LibDHCP::D6O_LQ_RELAY_DATA_DEF());
|
||||
static_cast<void>(LibDHCP::D6O_NTP_SERVER_DEF());
|
||||
static_cast<void>(LibDHCP::D6O_BOOTFILE_URL_DEF());
|
||||
static_cast<void>(LibDHCP::D6O_RSOO_DEF());
|
||||
|
||||
@@ -1587,6 +1608,24 @@ LibDHCP::D6O_LQ_RELAY_DATA_DEF() {
|
||||
return (*def);
|
||||
}
|
||||
|
||||
const OptionDefinition&
|
||||
LibDHCP::D6O_NTP_SERVER_DEF() {
|
||||
static OptionDefinitionPtr def =
|
||||
LibDHCP::getOptionDef(DHCP6_OPTION_SPACE, D6O_NTP_SERVER);
|
||||
static bool check_once(true);
|
||||
if (check_once) {
|
||||
isc_throw_assert(def);
|
||||
isc_throw_assert(def->getName() == "ntp-server");
|
||||
isc_throw_assert(def->getCode() == D6O_NTP_SERVER);
|
||||
isc_throw_assert(def->getType() == OPT_EMPTY_TYPE);
|
||||
isc_throw_assert(!def->getArrayType());
|
||||
isc_throw_assert(def->getEncapsulatedSpace() == V6_NTP_SERVER_SPACE);
|
||||
isc_throw_assert(def->getOptionSpaceName() == DHCP6_OPTION_SPACE);
|
||||
check_once = false;
|
||||
}
|
||||
return (*def);
|
||||
}
|
||||
|
||||
const OptionDefinition&
|
||||
LibDHCP::D6O_BOOTFILE_URL_DEF() {
|
||||
static OptionDefinitionPtr def =
|
||||
|
@@ -256,6 +256,13 @@ public:
|
||||
static void packOptions6(isc::util::OutputBuffer& buf,
|
||||
const isc::dhcp::OptionCollection& options);
|
||||
|
||||
/// @brief Split NTP server option to one suboption per instance.
|
||||
///
|
||||
/// See RFC 5908 for the requirement.
|
||||
/// @param options The option container which needs to be updated with split
|
||||
/// options.
|
||||
static void splitNtpServerOptions6(isc::dhcp::OptionCollection& options);
|
||||
|
||||
/// @brief Parses provided buffer as DHCPv6 options and creates
|
||||
/// Option objects.
|
||||
///
|
||||
@@ -448,6 +455,9 @@ public:
|
||||
/// @brief Get definition of D6O_LQ_RELAY_DATA option.
|
||||
static const OptionDefinition& D6O_LQ_RELAY_DATA_DEF();
|
||||
|
||||
/// @brief Get definition of D6O_NTP_SERVER option.
|
||||
static const OptionDefinition& D6O_NTP_SERVER_DEF();
|
||||
|
||||
/// @brief Get definition of D6O_BOOTFILE_URL option.
|
||||
static const OptionDefinition& D6O_BOOTFILE_URL_DEF();
|
||||
|
||||
|
@@ -3797,10 +3797,8 @@ TEST_F(LibDhcpTest, v6NtpServer) {
|
||||
fqdn->toText());
|
||||
|
||||
// Build back the NTP server option.
|
||||
OptionDefinitionPtr opt_def =
|
||||
LibDHCP::getOptionDef(DHCP6_OPTION_SPACE, D6O_NTP_SERVER);
|
||||
ASSERT_TRUE(opt_def);
|
||||
ASSERT_NO_THROW(option.reset(new OptionCustom(*opt_def, Option::V6)));
|
||||
auto opt_def = LibDHCP::D6O_NTP_SERVER_DEF();
|
||||
ASSERT_NO_THROW(option.reset(new OptionCustom(opt_def, Option::V6)));
|
||||
ASSERT_TRUE(option);
|
||||
|
||||
// Add address.
|
||||
@@ -3849,4 +3847,49 @@ TEST_F(LibDhcpTest, v6NtpServer) {
|
||||
EXPECT_TRUE(memcmp(&bin[0], outbuf.getData(), bin.size()) == 0);
|
||||
}
|
||||
|
||||
// Check splitNtpServerOptions6.
|
||||
TEST_F(LibDhcpTest, splitNtpServerOptions6) {
|
||||
OptionCollection col;
|
||||
auto def = LibDHCP::D6O_NTP_SERVER_DEF();
|
||||
OptionCustomPtr opt1(new OptionCustom(def, Option::V6));
|
||||
OptionCustomPtr opt2(new OptionCustom(def, Option::V6));
|
||||
OptionCustomPtr opt3(new OptionCustom(def, Option::V6));
|
||||
|
||||
// Fill first option with three addresses.
|
||||
OptionDefinitionPtr addr_def =
|
||||
LibDHCP::getOptionDef(V6_NTP_SERVER_SPACE, NTP_SUBOPTION_SRV_ADDR);
|
||||
ASSERT_TRUE(addr_def);
|
||||
OptionCustomPtr addr1(new OptionCustom(*addr_def, Option::V6));
|
||||
OptionCustomPtr addr2(new OptionCustom(*addr_def, Option::V6));
|
||||
OptionCustomPtr addr3(new OptionCustom(*addr_def, Option::V6));
|
||||
EXPECT_NO_THROW(addr1->writeAddress(IOAddress("2001:db8::abcd")));
|
||||
opt1->addOption(addr1);
|
||||
EXPECT_NO_THROW(addr2->writeAddress(IOAddress("2001:db8::bcde")));
|
||||
opt1->addOption(addr2);
|
||||
EXPECT_NO_THROW(addr3->writeAddress(IOAddress("2001:db8::cdef")));
|
||||
opt1->addOption(addr3);
|
||||
col.insert(make_pair(D6O_NTP_SERVER, opt1));
|
||||
|
||||
// Leave second option empty.
|
||||
col.insert(make_pair(D6O_NTP_SERVER, opt2));
|
||||
|
||||
// Fill third option with a FQDN.
|
||||
OptionDefinitionPtr fqdn_def =
|
||||
LibDHCP::getOptionDef(V6_NTP_SERVER_SPACE, NTP_SUBOPTION_SRV_FQDN);
|
||||
ASSERT_TRUE(fqdn_def);
|
||||
OptionCustomPtr fqdn(new OptionCustom(*fqdn_def, Option::V6));
|
||||
EXPECT_NO_THROW(fqdn->writeFqdn("foo.bar."));
|
||||
opt3->addOption(fqdn);
|
||||
col.insert(make_pair(D6O_NTP_SERVER, opt3));
|
||||
|
||||
// Insert another option.
|
||||
OptionPtr opts(new OptionString(Option::V6, D6O_BOOTFILE_URL, "foobar"));
|
||||
col.insert(make_pair(D6O_BOOTFILE_URL, opts));
|
||||
|
||||
// Split them: expect 5 options (opt1 -> 3, opt2 -> 0, opt3 -> 1 and opts).
|
||||
ASSERT_EQ(4, col.size());
|
||||
ASSERT_NO_THROW(LibDHCP::splitNtpServerOptions6(col));
|
||||
EXPECT_EQ(5, col.size());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
Reference in New Issue
Block a user