2
0
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:
Francis Dupont
2024-08-29 17:44:16 +02:00
parent 8476fd1a21
commit dde7aa86ee
5 changed files with 112 additions and 4 deletions

View File

@@ -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.

View File

@@ -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)

View File

@@ -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 =

View File

@@ -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();

View File

@@ -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