.. note::
- Since Kea 2.7.1, a reserved (so delegated) prefix can be associated
- with a single prefix to exclude as for prefix delegation pools
- :ref:`pd-exclude-option`. The host reservation syntax is extended
- by a new entry ``excluded-prefixes`` which when is present must have
- the same size as the ``prefixes`` entry: both contains strings
- representing IPv6 prefixes (e.g. ``2001:db8::/48``). Each element of
- the ``excluded-prefixes`` must be either the empty string or match
- the prefix at the same position in the ``prefixes`` list, e.g.
- ``2001:db8:0:1::/64`` matches / can be associated with ``2001:db8::/48``.
- An empty ``excluded-prefixes`` list or a list with only empty strings
- can be omitted (and will be omitted when produced by Kea).
+ Beginning with Kea 2.7.3, the host reservation syntax supports
+ a new entry, ``excluded-prefixes``. It can be used to specify
+ prefixes the client should exclude from delegated prefixes.
+ When present it must have the same number of elements as the
+ ``prefixes`` entry. Both entries contain strings representing IPv6
+ prefixes. Each element of the ``excluded-prefixes`` must be either
+ an empty string or match the prefix at the same position in
+ ``prefixes``. An empty ``excluded-prefixes`` list or a list with
+ only empty strings can be omitted. An example which excludes
+ ``2001:db8:0:1::/64`` from ``2001:db8::/48`` is shown below:
::
.. note::
- Host reservations have precedence over prefix pools so when a reserved
- prefix without an excluded prefix is assigned no pd-exclude option
- is added to the prefix option even the prefix is in a configured
- prefix pool with an excluded prefix (different from previous behavior).
+ Since host reservations have precedence over prefix pools, a reserved
+ prefix without an excluded prefix will not add a pd-exclude option
+ to the prefix option even if the delegated prefix is in a configured
+ prefix pool that does specify an excluded prefix (different from
+ previous behavior).
.. _reservation6-conflict:
/// @brief This test verifies that it is possible to specify an excluded
/// prefix (RFC 6603) and send it back to the client requesting prefix
/// delegation using a pool.
- void directClientExcludedPrefixPool();
+ ///
+ /// @param request_pdx request pd exclude option.
+ void directClientExcludedPrefixPool(bool request_pdx);
/// @brief This test verifies that it is possible to specify an excluded
/// prefix (RFC 6603) and send it back to the client requesting prefix
/// delegation using a reservation.
- void directClientExcludedPrefixHost();
+ ///
+ /// @param request_pdx request pd exclude option.
+ void directClientExcludedPrefixHost(bool request_pdx);
/// @brief Check that when the client includes the Rapid Commit option in
/// its Solicit, the server responds with Reply and commits the lease.
}
void
-SARRTest::directClientExcludedPrefixPool() {
+SARRTest::directClientExcludedPrefixPool(bool request_pdx) {
Dhcp6Client client;
// Configure client to request IA_PD.
client.requestPrefix();
- client.requestOption(D6O_PD_EXCLUDE);
+ // Request pd exclude option when wanted.
+ if (request_pdx) {
+ client.requestOption(D6O_PD_EXCLUDE);
+ }
configure(CONFIGS[3], *client.getServer());
// Make sure we ended-up having expected number of subnets configured.
const Subnet6Collection* subnets = CfgMgr::instance().getCurrentCfg()->
Option6IAPrefixPtr pd_option = boost::dynamic_pointer_cast<Option6IAPrefix>(option);
ASSERT_TRUE(pd_option);
option = pd_option->getOption(D6O_PD_EXCLUDE);
+ if (!request_pdx) {
+ EXPECT_FALSE(option);
+ return;
+ }
ASSERT_TRUE(option);
Option6PDExcludePtr pd_exclude = boost::dynamic_pointer_cast<Option6PDExclude>(option);
ASSERT_TRUE(pd_exclude);
TEST_F(SARRTest, directClientExcludedPrefixPool) {
Dhcpv6SrvMTTestGuard guard(*this, false);
- directClientExcludedPrefixPool();
+ directClientExcludedPrefixPool(true);
}
TEST_F(SARRTest, directClientExcludedPrefixPoolMultiThreading) {
Dhcpv6SrvMTTestGuard guard(*this, true);
- directClientExcludedPrefixPool();
+ directClientExcludedPrefixPool(true);
+}
+
+TEST_F(SARRTest, directClientExcludedPrefixPoolNoOro) {
+ Dhcpv6SrvMTTestGuard guard(*this, false);
+ directClientExcludedPrefixPool(false);
+}
+
+TEST_F(SARRTest, directClientExcludedPrefixPoolNoOroMultiThreading) {
+ Dhcpv6SrvMTTestGuard guard(*this, true);
+ directClientExcludedPrefixPool(false);
}
void
-SARRTest::directClientExcludedPrefixHost() {
+SARRTest::directClientExcludedPrefixHost(bool request_pdx) {
Dhcp6Client client;
// Set DUID matching the one used to create host reservations.
client.setDUID("01:02:03:05");
// Configure client to request IA_PD.
client.requestPrefix();
- client.requestOption(D6O_PD_EXCLUDE);
+ // Request pd exclude option when wanted.
+ if (request_pdx) {
+ client.requestOption(D6O_PD_EXCLUDE);
+ }
configure(CONFIGS[8], *client.getServer());
// Make sure we ended-up having expected number of subnets configured.
const Subnet6Collection* subnets = CfgMgr::instance().getCurrentCfg()->
Option6IAPrefixPtr pd_option = boost::dynamic_pointer_cast<Option6IAPrefix>(option);
ASSERT_TRUE(pd_option);
option = pd_option->getOption(D6O_PD_EXCLUDE);
+ if (!request_pdx) {
+ EXPECT_FALSE(option);
+ return;
+ }
ASSERT_TRUE(option);
Option6PDExcludePtr pd_exclude = boost::dynamic_pointer_cast<Option6PDExclude>(option);
ASSERT_TRUE(pd_exclude);
TEST_F(SARRTest, directClientExcludedPrefixHost) {
Dhcpv6SrvMTTestGuard guard(*this, false);
- directClientExcludedPrefixHost();
+ directClientExcludedPrefixHost(true);
}
TEST_F(SARRTest, directClientExcludedPrefixHostMultiThreading) {
Dhcpv6SrvMTTestGuard guard(*this, true);
- directClientExcludedPrefixHost();
+ directClientExcludedPrefixHost(true);
+}
+
+TEST_F(SARRTest, directClientExcludedPrefixHostNoOro) {
+ Dhcpv6SrvMTTestGuard guard(*this, false);
+ directClientExcludedPrefixHost(false);
+}
+
+TEST_F(SARRTest, directClientExcludedPrefixHostNoOroMultiThreading) {
+ Dhcpv6SrvMTTestGuard guard(*this, true);
+ directClientExcludedPrefixHost(false);
}
void
testInvalidConfig<HostReservationParser6>(config);
}
+// This test verifies that the configuration parser throws an exception
+// when the excluded prefix is invalid (prefixes do not match).
+TEST_F(HostReservationParserTest, dhcp6ExcludedPrefixNotMatch) {
+ std::string config = "{ \"duid\": \"01:02:03:04:05:06:07:08:09:0A\","
+ "\"prefixes\": [ \"2001:db8::/48\" ],"
+ "\"excluded-prefixes\": [ \"2001:db9:0:1::/64\" ] }";
+ testInvalidConfig<HostReservationParser6>(config);
+}
+
+// This test verifies that the configuration parser throws an exception
+// when the excluded prefix is invalid (bad length).
+TEST_F(HostReservationParserTest, dhcp6ExcludedPrefixBadLength) {
+ std::string config = "{ \"duid\": \"01:02:03:04:05:06:07:08:09:0A\","
+ "\"prefixes\": [ \"2001:db8::/48\" ],"
+ "\"excluded-prefixes\": [ \"2001:db8::/48\" ] }";
+ testInvalidConfig<HostReservationParser6>(config);
+}
+
// This test verifies that the configuration parser throws an exception
// when invalid prefix length type is specified.
TEST_F(HostReservationParserTest, dhcp6InvalidPrefixLengthType) {