mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-22 18:08:16 +00:00
[#1387] Checkpoint: server code
This commit is contained in:
parent
9e208d0248
commit
3cb38f1943
@ -1152,6 +1152,9 @@
|
||||
// List of reserved IPv6 prefixes.
|
||||
"prefixes": [ "2001:db8:2:abcd::/64" ],
|
||||
|
||||
// List of excluded IPv6 prefixes.
|
||||
"excluded-prefixes": [ "2001:db8:2:abcd:1::/80" ],
|
||||
|
||||
// Reserved hostname.
|
||||
"hostname": "foo.example.com",
|
||||
|
||||
|
@ -4285,8 +4285,26 @@ another.
|
||||
An empty ``excluded-prefixes`` list or a list with only empty strings
|
||||
can be omitted (and will be omitted when produced by Kea).
|
||||
|
||||
todo: add something about adding the pd-exclude option to returned
|
||||
prefixes as done for prefix delegation pools.
|
||||
::
|
||||
|
||||
"reservations": [
|
||||
{
|
||||
"duid": "01:02:03:04:05:06:07:08:09:0A",
|
||||
"ip-addresses": [ "2001:db8:1::103" ],
|
||||
"prefixes": [ "2001:db8::/48 ],
|
||||
"excluded-prefixes": [ "2001:db8:0:1::/64 ],
|
||||
"hostname": "foo.example.com"
|
||||
}
|
||||
],
|
||||
...
|
||||
|
||||
|
||||
.. 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).
|
||||
|
||||
.. _reservation6-conflict:
|
||||
|
||||
|
@ -1720,6 +1720,15 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu]
|
||||
}
|
||||
}
|
||||
|
||||
\"excluded-prefixes\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser6Context::RESERVATIONS:
|
||||
return isc::dhcp::Dhcp6Parser::make_EXCLUDED_PREFIXES(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp6Parser::make_STRING("excluded-prefixes", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"duid\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser6Context::MAC_SOURCES:
|
||||
|
@ -189,6 +189,7 @@ using namespace std;
|
||||
RESERVATIONS "reservations"
|
||||
IP_ADDRESSES "ip-addresses"
|
||||
PREFIXES "prefixes"
|
||||
EXCLUDED_PREFIXES "excluded-prefixes"
|
||||
DUID "duid"
|
||||
HW_ADDRESS "hw-address"
|
||||
HOSTNAME "hostname"
|
||||
@ -2377,6 +2378,7 @@ reservation_param: duid
|
||||
| reservation_client_classes
|
||||
| ip_addresses
|
||||
| prefixes
|
||||
| excluded_prefixes
|
||||
| hw_address
|
||||
| hostname
|
||||
| flex_id_value
|
||||
@ -2408,6 +2410,17 @@ prefixes: PREFIXES {
|
||||
ctx.leave();
|
||||
};
|
||||
|
||||
excluded_prefixes: EXCLUDED_PREFIXES {
|
||||
ctx.unique("excluded-prefixes", ctx.loc2pos(@1));
|
||||
ElementPtr l(new ListElement(ctx.loc2pos(@1)));
|
||||
ctx.stack_.back()->set("excluded-prefixes", l);
|
||||
ctx.stack_.push_back(l);
|
||||
ctx.enter(ctx.NO_KEYWORD);
|
||||
} COLON list_strings {
|
||||
ctx.stack_.pop_back();
|
||||
ctx.leave();
|
||||
};
|
||||
|
||||
duid: DUID {
|
||||
ctx.unique("duid", ctx.loc2pos(@1));
|
||||
ctx.enter(ctx.NO_KEYWORD);
|
||||
|
@ -2462,6 +2462,32 @@ Dhcpv6Srv::getMAC(const Pkt6Ptr& pkt) {
|
||||
return (hwaddr);
|
||||
}
|
||||
|
||||
OptionPtr
|
||||
Dhcpv6Srv::getPDExclude(const AllocEngine::ClientContext6& ctx,
|
||||
const Lease6Ptr& lease) {
|
||||
|
||||
// Search the reservation the prefix is from.
|
||||
ConstHostPtr host = ctx.currentHost();
|
||||
if (host) {
|
||||
IPv6ResrvRange resvs = host->getIPv6Reservations(IPv6Resrv::TYPE_PD);
|
||||
BOOST_FOREACH(auto const& resv, resvs) {
|
||||
if ((resv.second.getPrefix() == lease->addr_) &&
|
||||
(resv.second.getPrefixLen() == lease->prefixlen_)) {
|
||||
return (resv.second.getPDExclude());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Search the pool the address is from.
|
||||
const Subnet6Ptr& subnet = ctx.subnet_;
|
||||
Pool6Ptr pool = boost::dynamic_pointer_cast<Pool6>(
|
||||
subnet->getPool(Lease::TYPE_PD, lease->addr_));
|
||||
if (pool) {
|
||||
return (pool->getPrefixExcludeOption());
|
||||
}
|
||||
return (OptionPtr());
|
||||
}
|
||||
|
||||
OptionPtr
|
||||
Dhcpv6Srv::assignIA_NA(const Pkt6Ptr& query,
|
||||
AllocEngine::ClientContext6& ctx,
|
||||
@ -2718,15 +2744,9 @@ Dhcpv6Srv::assignIA_PD(const Pkt6Ptr& query,
|
||||
ia_rsp->addOption(addr);
|
||||
|
||||
if (pd_exclude_requested) {
|
||||
// PD exclude option has been requested via ORO, thus we need to
|
||||
// include it if the pool configuration specifies this option.
|
||||
Pool6Ptr pool = boost::dynamic_pointer_cast<
|
||||
Pool6>(subnet->getPool(Lease::TYPE_PD, l->addr_));
|
||||
if (pool) {
|
||||
Option6PDExcludePtr pd_exclude_option = pool->getPrefixExcludeOption();
|
||||
if (pd_exclude_option) {
|
||||
addr->addOption(pd_exclude_option);
|
||||
}
|
||||
OptionPtr pd_exclude_option = getPDExclude(ctx, l);
|
||||
if (pd_exclude_option) {
|
||||
addr->addOption(pd_exclude_option);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3049,16 +3069,9 @@ Dhcpv6Srv::extendIA_PD(const Pkt6Ptr& query,
|
||||
ia_rsp->addOption(prf);
|
||||
|
||||
if (pd_exclude_requested) {
|
||||
// PD exclude option has been requested via ORO, thus we need to
|
||||
// include it if the pool configuration specifies this option.
|
||||
Pool6Ptr pool = boost::dynamic_pointer_cast<
|
||||
Pool6>(subnet->getPool(Lease::TYPE_PD, l->addr_));
|
||||
|
||||
if (pool) {
|
||||
Option6PDExcludePtr pd_exclude_option = pool->getPrefixExcludeOption();
|
||||
if (pd_exclude_option) {
|
||||
prf->addOption(pd_exclude_option);
|
||||
}
|
||||
OptionPtr pd_exclude_option = getPDExclude(ctx, l);
|
||||
if (pd_exclude_option) {
|
||||
prf->addOption(pd_exclude_option);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1059,6 +1059,14 @@ protected:
|
||||
void checkDynamicSubnetChange(const Pkt6Ptr& question, Pkt6Ptr& answer,
|
||||
AllocEngine::ClientContext6& ctx,
|
||||
const Subnet6Ptr orig_subnet);
|
||||
|
||||
/// @brief Return the PD exclude option to include.
|
||||
///
|
||||
/// @param ctx client context (contains subnet and hosts).
|
||||
/// @param lease lease (contains address/prefix and prefix length).
|
||||
OptionPtr getPDExclude(const AllocEngine::ClientContext6& ctx,
|
||||
const Lease6Ptr& lease);
|
||||
|
||||
public:
|
||||
|
||||
/// Used for DHCPv4-over-DHCPv6 too.
|
||||
|
@ -4050,7 +4050,7 @@ TEST_F(Dhcpv6SrvTest, generateFqdnUpdate) {
|
||||
EXPECT_EQ("myhost-2001-db8-1--1.example.com.", l->hostname_);
|
||||
|
||||
// Should see follow log message ids in the log file.
|
||||
EXPECT_EQ(1, countFile("DHCP6_DDNS_FQDN_GENERATED"));
|
||||
EXPECT_EQ(1, countFile("DHCP6_DDNS_FQDN_GENERATED"));
|
||||
EXPECT_EQ(0, countFile("DHCP6_DDNS_GENERATED_FQDN_UPDATE_FAIL"));
|
||||
}
|
||||
|
||||
@ -4104,7 +4104,7 @@ TEST_F(Dhcpv6SrvTest, generateFqdnNoUpdate) {
|
||||
|
||||
// Check that an IA_NA with an iaaddr was returned for the requested
|
||||
// address with lifetimes of 0.
|
||||
boost::shared_ptr<Option6IAAddr> iaaddr = checkIA_NA(reply, 234, 0, 0);
|
||||
boost::shared_ptr<Option6IAAddr> iaaddr = checkIA_NA(reply, 234, 0, 0);
|
||||
ASSERT_TRUE(iaaddr);
|
||||
EXPECT_EQ(addr, iaaddr->getAddress());
|
||||
EXPECT_EQ(0, iaaddr->getPreferred());
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2015-2023 Internet Systems Consortium, Inc. ("ISC")
|
||||
// Copyright (C) 2015-2024 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
|
||||
@ -61,6 +61,22 @@ namespace {
|
||||
/// - prefix pool: 3000::/72
|
||||
/// - excluded prefix 3000::1000/120 in a prefix pool.
|
||||
///
|
||||
/// - Configuration 6:
|
||||
/// - addresses and prefixes
|
||||
/// - 1 subnet with one address pool and one prefix pool
|
||||
/// - address pool: 2001:db8:1::/64
|
||||
/// - prefix pool: 3000::/72
|
||||
/// - excluded prefix 3000::1000/120 in a prefix pool.
|
||||
/// - reservation for 3000::/80 (has precedence over the prefix pool).
|
||||
///
|
||||
/// - Configuration 7:
|
||||
/// - addresses and prefixes
|
||||
/// - 1 subnet with one address pool and one prefix pool
|
||||
/// - address pool: 2001:db8:1::/64
|
||||
/// - prefix pool: 3000::/72
|
||||
/// - excluded prefix 3000::1000/120 in a prefix pool.
|
||||
/// - reservation for 3000::/80 with 3000::2000/120 excluded prefix.
|
||||
///
|
||||
const char* RENEW_CONFIGS[] = {
|
||||
// Configuration 0
|
||||
"{ \"interfaces-config\": {"
|
||||
@ -224,7 +240,67 @@ const char* RENEW_CONFIGS[] = {
|
||||
" \"interface-id\": \"\","
|
||||
" \"interface\": \"eth0\""
|
||||
" } ],"
|
||||
"\"valid-lifetime\": 4000 }"
|
||||
"\"valid-lifetime\": 4000"
|
||||
"}",
|
||||
|
||||
// Configuration 6
|
||||
"{ \"interfaces-config\": {"
|
||||
" \"interfaces\": [ \"*\" ]"
|
||||
"},"
|
||||
"\"preferred-lifetime\": 3000,"
|
||||
"\"rebind-timer\": 2000, "
|
||||
"\"renew-timer\": 1000, "
|
||||
"\"subnet6\": [ { "
|
||||
" \"id\": 1, "
|
||||
" \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ],"
|
||||
" \"pd-pools\": ["
|
||||
" { \"prefix\": \"3000::\", "
|
||||
" \"prefix-len\": 72, "
|
||||
" \"delegated-len\": 80,"
|
||||
" \"excluded-prefix\": \"3000::1000\","
|
||||
" \"excluded-prefix-len\": 120"
|
||||
" } ],"
|
||||
" \"subnet\": \"2001:db8:1::/48\", "
|
||||
" \"reservations\": ["
|
||||
" {"
|
||||
" \"duid\": \"01:02:03:05\","
|
||||
" \"prefixes\": [ \"3000::/80\" ]"
|
||||
" } ],"
|
||||
" \"interface-id\": \"\","
|
||||
" \"interface\": \"eth0\""
|
||||
" } ],"
|
||||
"\"valid-lifetime\": 4000"
|
||||
"}",
|
||||
|
||||
// Configuration 7
|
||||
"{ \"interfaces-config\": {"
|
||||
" \"interfaces\": [ \"*\" ]"
|
||||
"},"
|
||||
"\"preferred-lifetime\": 3000,"
|
||||
"\"rebind-timer\": 2000, "
|
||||
"\"renew-timer\": 1000, "
|
||||
"\"subnet6\": [ { "
|
||||
" \"id\": 1, "
|
||||
" \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ],"
|
||||
" \"pd-pools\": ["
|
||||
" { \"prefix\": \"3000::\", "
|
||||
" \"prefix-len\": 72, "
|
||||
" \"delegated-len\": 80,"
|
||||
" \"excluded-prefix\": \"3000::1000\","
|
||||
" \"excluded-prefix-len\": 120"
|
||||
" } ],"
|
||||
" \"subnet\": \"2001:db8:1::/48\", "
|
||||
" \"reservations\": ["
|
||||
" {"
|
||||
" \"duid\": \"01:02:03:05\","
|
||||
" \"prefixes\": [ \"3000::/80\" ],"
|
||||
" \"excluded-prefixes\": [ \"3000::2000/120\" ]"
|
||||
" } ],"
|
||||
" \"interface-id\": \"\","
|
||||
" \"interface\": \"eth0\""
|
||||
" } ],"
|
||||
"\"valid-lifetime\": 4000"
|
||||
"}"
|
||||
};
|
||||
|
||||
/// @brief Test fixture class for testing Renew.
|
||||
@ -314,8 +390,8 @@ TEST_F(RenewTest, requestPrefixInRenew) {
|
||||
}
|
||||
|
||||
// Test that it is possible to renew a prefix lease with a Prefix Exclude
|
||||
// option being included during renew.
|
||||
TEST_F(RenewTest, renewWithExcludedPrefix) {
|
||||
// option from PD pool being included during renew.
|
||||
TEST_F(RenewTest, renewWithExcludedPrefixPool) {
|
||||
Dhcp6Client client;
|
||||
|
||||
// Configure client to request IA_NA and IA_PD.
|
||||
@ -325,7 +401,7 @@ TEST_F(RenewTest, renewWithExcludedPrefix) {
|
||||
// Request Prefix Exclude option.
|
||||
client.requestOption(D6O_PD_EXCLUDE);
|
||||
|
||||
// Configure the server with NA pools only.
|
||||
// Configure the server with NA and PD pools but without excluded prefix.
|
||||
ASSERT_NO_THROW(configure(RENEW_CONFIGS[2], *client.getServer()));
|
||||
|
||||
// Perform 4-way exchange.
|
||||
@ -399,6 +475,95 @@ TEST_F(RenewTest, renewWithExcludedPrefix) {
|
||||
EXPECT_EQ(120, static_cast<unsigned>(pd_exclude->getExcludedPrefixLength()));
|
||||
}
|
||||
|
||||
// Test that it is possible to renew a prefix lease with a Prefix Exclude
|
||||
// option from host reservation being included during renew.
|
||||
TEST_F(RenewTest, renewWithExcludedPrefixHost) {
|
||||
Dhcp6Client client;
|
||||
|
||||
// Set DUID matching the one used to create host reservations.
|
||||
client.setDUID("01:02:03:05");
|
||||
|
||||
// Configure client to request IA_NA and IA_PD.
|
||||
client.requestAddress(na_iaid_);
|
||||
client.requestPrefix(pd_iaid_);
|
||||
|
||||
// Request Prefix Exclude option.
|
||||
client.requestOption(D6O_PD_EXCLUDE);
|
||||
|
||||
// Configure the server with a reservation but without excluded prefix.
|
||||
ASSERT_NO_THROW(configure(RENEW_CONFIGS[6], *client.getServer()));
|
||||
|
||||
// Perform 4-way exchange.
|
||||
ASSERT_NO_THROW(client.doSARR());
|
||||
|
||||
// Simulate aging of leases.
|
||||
client.fastFwdTime(1000);
|
||||
|
||||
// Make sure that the client has acquired NA lease.
|
||||
std::vector<Lease6> leases_client_na = client.getLeasesByType(Lease::TYPE_NA);
|
||||
ASSERT_EQ(1, leases_client_na.size());
|
||||
EXPECT_EQ(STATUS_Success, client.getStatusCode(na_iaid_));
|
||||
|
||||
// The client should also acquire a PD lease.
|
||||
std::vector<Lease6> leases_client_pd = client.getLeasesByType(Lease::TYPE_PD);
|
||||
ASSERT_EQ(1, leases_client_pd.size());
|
||||
ASSERT_EQ(STATUS_Success, client.getStatusCode(pd_iaid_));
|
||||
|
||||
// Send Renew message to the server, including IA_NA and IA_PD.
|
||||
ASSERT_NO_THROW(client.doRenew());
|
||||
|
||||
std::vector<Lease6> leases_client_na_renewed =
|
||||
client.getLeasesByType(Lease::TYPE_NA);
|
||||
ASSERT_EQ(1, leases_client_na_renewed.size());
|
||||
EXPECT_EQ(STATUS_Success, client.getStatusCode(na_iaid_));
|
||||
|
||||
std::vector<Lease6> leases_client_pd_renewed =
|
||||
client.getLeasesByType(Lease::TYPE_PD);
|
||||
ASSERT_EQ(1, leases_client_pd_renewed.size());
|
||||
EXPECT_EQ(STATUS_Success, client.getStatusCode(pd_iaid_));
|
||||
|
||||
// Make sure that Prefix Exclude option hasn't been included.
|
||||
OptionPtr option = client.getContext().response_->getOption(D6O_IA_PD);
|
||||
ASSERT_TRUE(option);
|
||||
option = option->getOption(D6O_IAPREFIX);
|
||||
ASSERT_TRUE(option);
|
||||
option = option->getOption(D6O_PD_EXCLUDE);
|
||||
ASSERT_FALSE(option);
|
||||
|
||||
// Reconfigure the server to use the reservation with excluded prefix.
|
||||
configure(RENEW_CONFIGS[7], *client.getServer());
|
||||
|
||||
// Send Renew message to the server, including IA_NA and IA_PD.
|
||||
ASSERT_NO_THROW(client.doRenew());
|
||||
|
||||
// Make sure that the client has acquired NA lease.
|
||||
leases_client_na_renewed = client.getLeasesByType(Lease::TYPE_NA);
|
||||
ASSERT_EQ(1, leases_client_na_renewed.size());
|
||||
EXPECT_EQ(STATUS_Success, client.getStatusCode(na_iaid_));
|
||||
|
||||
// Make sure that the client has acquired PD lease.
|
||||
leases_client_pd_renewed = client.getLeasesByType(Lease::TYPE_PD);
|
||||
ASSERT_EQ(1, leases_client_pd_renewed.size());
|
||||
EXPECT_EQ(STATUS_Success, client.getStatusCode(pd_iaid_));
|
||||
|
||||
// The leases should have been renewed.
|
||||
EXPECT_GE(leases_client_na_renewed[0].cltt_ - leases_client_na[0].cltt_, 1000);
|
||||
EXPECT_GE(leases_client_pd_renewed[0].cltt_ - leases_client_pd[0].cltt_, 1000);
|
||||
|
||||
// This time, the Prefix Exclude option should be included.
|
||||
option = client.getContext().response_->getOption(D6O_IA_PD);
|
||||
ASSERT_TRUE(option);
|
||||
option = option->getOption(D6O_IAPREFIX);
|
||||
ASSERT_TRUE(option);
|
||||
option = option->getOption(D6O_PD_EXCLUDE);
|
||||
ASSERT_TRUE(option);
|
||||
Option6PDExcludePtr pd_exclude = boost::dynamic_pointer_cast<Option6PDExclude>(option);
|
||||
ASSERT_TRUE(pd_exclude);
|
||||
EXPECT_EQ("3000::2000", pd_exclude->getExcludedPrefix(IOAddress("3000::"),
|
||||
80).toText());
|
||||
EXPECT_EQ(120, static_cast<unsigned>(pd_exclude->getExcludedPrefixLength()));
|
||||
}
|
||||
|
||||
// This test verifies that the client can request a prefix delegation
|
||||
// with a hint, while it is renewing an address lease.
|
||||
TEST_F(RenewTest, requestPrefixInRenewUseHint) {
|
||||
|
@ -74,6 +74,16 @@ namespace {
|
||||
/// - One subnet with three distinct pools.
|
||||
/// - Random allocator enabled globally for delegated prefixes.
|
||||
/// - Iterative allocator for address allocation.
|
||||
///
|
||||
/// - Configation 7:
|
||||
/// - Cache max age and threshold.
|
||||
///
|
||||
/// - Configuration 8 (derived from 3):
|
||||
/// - one subnet 3000::/32 used on eth0 interface
|
||||
/// - prefixes of length 64, delegated from the pool: 2001:db8:3::/48
|
||||
/// - Excluded Prefix specified (RFC 6603).
|
||||
/// - Reservation (which has precedence over the pool) with excluded prefix.
|
||||
///
|
||||
const char* CONFIGS[] = {
|
||||
// Configuration 0
|
||||
"{ \"interfaces-config\": {"
|
||||
@ -328,6 +338,35 @@ const char* CONFIGS[] = {
|
||||
],
|
||||
"valid-lifetime": 600
|
||||
})",
|
||||
|
||||
// Configuration 8
|
||||
"{ \"interfaces-config\": {"
|
||||
" \"interfaces\": [ \"*\" ]"
|
||||
"},"
|
||||
"\"preferred-lifetime\": 3000,"
|
||||
"\"rebind-timer\": 2000, "
|
||||
"\"renew-timer\": 1000, "
|
||||
"\"subnet6\": [ { "
|
||||
" \"id\": 1, "
|
||||
" \"pd-pools\": ["
|
||||
" { \"prefix\": \"2001:db8:3::\", "
|
||||
" \"prefix-len\": 48, "
|
||||
" \"delegated-len\": 64,"
|
||||
" \"excluded-prefix\": \"2001:db8:3::1000\","
|
||||
" \"excluded-prefix-len\": 120"
|
||||
" } ],"
|
||||
" \"subnet\": \"3000::/32\", "
|
||||
" \"reservations\": ["
|
||||
" {"
|
||||
" \"duid\": \"01:02:03:05\","
|
||||
" \"prefixes\": [ \"2001:db8:3::/64\" ],"
|
||||
" \"excluded-prefixes\": [ \"2001:db8:3::2000/120\" ]"
|
||||
" } ],"
|
||||
" \"interface-id\": \"\","
|
||||
" \"interface\": \"eth0\""
|
||||
" } ],"
|
||||
"\"valid-lifetime\": 4000"
|
||||
"}",
|
||||
};
|
||||
|
||||
/// @brief Test fixture class for testing 4-way exchange: Solicit-Advertise,
|
||||
@ -379,8 +418,13 @@ public:
|
||||
|
||||
/// @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.
|
||||
void directClientExcludedPrefix();
|
||||
/// delegation using a pool.
|
||||
void directClientExcludedPrefixPool();
|
||||
|
||||
/// @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();
|
||||
|
||||
/// @brief Check that when the client includes the Rapid Commit option in
|
||||
/// its Solicit, the server responds with Reply and commits the lease.
|
||||
@ -638,7 +682,7 @@ TEST_F(SARRTest, optionsInheritanceMultiThreading) {
|
||||
}
|
||||
|
||||
void
|
||||
SARRTest::directClientExcludedPrefix() {
|
||||
SARRTest::directClientExcludedPrefixPool() {
|
||||
Dhcp6Client client;
|
||||
// Configure client to request IA_PD.
|
||||
client.requestPrefix();
|
||||
@ -677,14 +721,66 @@ SARRTest::directClientExcludedPrefix() {
|
||||
EXPECT_EQ(120, static_cast<unsigned>(pd_exclude->getExcludedPrefixLength()));
|
||||
}
|
||||
|
||||
TEST_F(SARRTest, directClientExcludedPrefix) {
|
||||
TEST_F(SARRTest, directClientExcludedPrefixPool) {
|
||||
Dhcpv6SrvMTTestGuard guard(*this, false);
|
||||
directClientExcludedPrefix();
|
||||
directClientExcludedPrefixPool();
|
||||
}
|
||||
|
||||
TEST_F(SARRTest, directClientExcludedPrefixMultiThreading) {
|
||||
TEST_F(SARRTest, directClientExcludedPrefixPoolMultiThreading) {
|
||||
Dhcpv6SrvMTTestGuard guard(*this, true);
|
||||
directClientExcludedPrefix();
|
||||
directClientExcludedPrefixPool();
|
||||
}
|
||||
|
||||
void
|
||||
SARRTest::directClientExcludedPrefixHost() {
|
||||
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);
|
||||
configure(CONFIGS[8], *client.getServer());
|
||||
// Make sure we ended-up having expected number of subnets configured.
|
||||
const Subnet6Collection* subnets = CfgMgr::instance().getCurrentCfg()->
|
||||
getCfgSubnets6()->getAll();
|
||||
ASSERT_EQ(1, subnets->size());
|
||||
// Perform 4-way exchange.
|
||||
ASSERT_NO_THROW(client.doSARR());
|
||||
// Server should have assigned a prefix.
|
||||
ASSERT_EQ(1, client.getLeaseNum());
|
||||
Lease6 lease_client = client.getLease(0);
|
||||
EXPECT_EQ(64, lease_client.prefixlen_);
|
||||
EXPECT_EQ(3000, lease_client.preferred_lft_);
|
||||
EXPECT_EQ(4000, lease_client.valid_lft_);
|
||||
Lease6Ptr lease_server = checkLease(lease_client);
|
||||
// Check that the server recorded the lease.
|
||||
ASSERT_TRUE(lease_server);
|
||||
|
||||
OptionPtr option = client.getContext().response_->getOption(D6O_IA_PD);
|
||||
ASSERT_TRUE(option);
|
||||
Option6IAPtr ia = boost::dynamic_pointer_cast<Option6IA>(option);
|
||||
ASSERT_TRUE(ia);
|
||||
option = ia->getOption(D6O_IAPREFIX);
|
||||
ASSERT_TRUE(option);
|
||||
Option6IAPrefixPtr pd_option = boost::dynamic_pointer_cast<Option6IAPrefix>(option);
|
||||
ASSERT_TRUE(pd_option);
|
||||
option = pd_option->getOption(D6O_PD_EXCLUDE);
|
||||
ASSERT_TRUE(option);
|
||||
Option6PDExcludePtr pd_exclude = boost::dynamic_pointer_cast<Option6PDExclude>(option);
|
||||
ASSERT_TRUE(pd_exclude);
|
||||
EXPECT_EQ("2001:db8:3::2000", pd_exclude->getExcludedPrefix(IOAddress("2001:db8:3::"),
|
||||
64).toText());
|
||||
EXPECT_EQ(120, static_cast<unsigned>(pd_exclude->getExcludedPrefixLength()));
|
||||
}
|
||||
|
||||
TEST_F(SARRTest, directClientExcludedPrefixHost) {
|
||||
Dhcpv6SrvMTTestGuard guard(*this, false);
|
||||
directClientExcludedPrefixHost();
|
||||
}
|
||||
|
||||
TEST_F(SARRTest, directClientExcludedPrefixHostMultiThreading) {
|
||||
Dhcpv6SrvMTTestGuard guard(*this, true);
|
||||
directClientExcludedPrefixHost();
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
x
Reference in New Issue
Block a user