mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-09-05 08:25:16 +00:00
[5016] Update server code and tests to properly use exclude option.
This commit is contained in:
@@ -893,26 +893,7 @@ Dhcpv6Srv::appendRequestedOptions(const Pkt6Ptr& question, Pkt6Ptr& answer,
|
||||
// Get the list of options that client requested.
|
||||
const std::vector<uint16_t>& requested_opts = option_oro->getValues();
|
||||
|
||||
if (co_list.empty()) {
|
||||
// If there are no options configured, we at least have to check if
|
||||
// the client has requested PD exclude, which is configured as
|
||||
// part of the pool configuration.
|
||||
ctx.pd_exclude_requested_ = (std::find(requested_opts.begin(),
|
||||
requested_opts.end(),
|
||||
D6O_PD_EXCLUDE) !=
|
||||
requested_opts.end());
|
||||
return;
|
||||
}
|
||||
|
||||
BOOST_FOREACH(uint16_t opt, requested_opts) {
|
||||
// Prefix Exclude option requires special handling, as it can
|
||||
// be configured as part of the pool configuration.
|
||||
if (opt == D6O_PD_EXCLUDE) {
|
||||
ctx.pd_exclude_requested_ = true;
|
||||
// Prefix Exclude can only be included in the IA Prefix option
|
||||
// of IA_PD. Thus there is nothing more to do here.
|
||||
continue;
|
||||
}
|
||||
// Iterate on the configured option list
|
||||
for (CfgOptionList::const_iterator copts = co_list.begin();
|
||||
copts != co_list.end(); ++copts) {
|
||||
@@ -1576,6 +1557,8 @@ Dhcpv6Srv::assignIA_PD(const Pkt6Ptr& query, const Pkt6Ptr& answer,
|
||||
ia_rsp->setT1(subnet->getT1());
|
||||
ia_rsp->setT2(subnet->getT2());
|
||||
|
||||
const bool pd_exclude_requested = requestedInORO(query, D6O_PD_EXCLUDE);
|
||||
|
||||
for (Lease6Collection::iterator l = leases.begin();
|
||||
l != leases.end(); ++l) {
|
||||
|
||||
@@ -1594,14 +1577,12 @@ Dhcpv6Srv::assignIA_PD(const Pkt6Ptr& query, const Pkt6Ptr& answer,
|
||||
(*l)->valid_lft_));
|
||||
ia_rsp->addOption(addr);
|
||||
|
||||
if (ctx.pd_exclude_requested_) {
|
||||
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 && pool->getExcludedPrefixLength() > 0) {
|
||||
std::cout << pool->getExcludedPrefix() << "/"
|
||||
<< (unsigned)pool->getExcludedPrefixLength() << std::endl;
|
||||
OptionPtr opt(new Option6PDExclude((*l)->addr_,
|
||||
(*l)->prefixlen_,
|
||||
pool->getExcludedPrefix(),
|
||||
@@ -1877,6 +1858,8 @@ Dhcpv6Srv::extendIA_PD(const Pkt6Ptr& query,
|
||||
// into temporary container.
|
||||
AllocEngine::HintContainer hints = ctx.currentIA().hints_;
|
||||
|
||||
const bool pd_exclude_requested = requestedInORO(query, D6O_PD_EXCLUDE);
|
||||
|
||||
// For all the leases we have now, add the IAPPREFIX with non-zero lifetimes
|
||||
for (Lease6Collection::const_iterator l = leases.begin(); l != leases.end(); ++l) {
|
||||
|
||||
@@ -1885,7 +1868,8 @@ Dhcpv6Srv::extendIA_PD(const Pkt6Ptr& query,
|
||||
(*l)->preferred_lft_, (*l)->valid_lft_));
|
||||
ia_rsp->addOption(prf);
|
||||
|
||||
if (ctx.pd_exclude_requested_) {
|
||||
|
||||
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<
|
||||
@@ -3288,5 +3272,19 @@ int Dhcpv6Srv::getHookIndexBuffer6Send() {
|
||||
return (Hooks.hook_index_buffer6_send_);
|
||||
}
|
||||
|
||||
bool
|
||||
Dhcpv6Srv::requestedInORO(const Pkt6Ptr& query, const uint16_t code) const {
|
||||
OptionUint16ArrayPtr oro =
|
||||
boost::dynamic_pointer_cast<OptionUint16Array>(query->getOption(D6O_ORO));
|
||||
|
||||
if (oro) {
|
||||
const std::vector<uint16_t>& codes = oro->getValues();
|
||||
return (std::find(codes.begin(), codes.end(), code) != codes.end());
|
||||
}
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
};
|
||||
|
@@ -805,6 +805,15 @@ private:
|
||||
/// @param query packet received
|
||||
static void processStatsReceived(const Pkt6Ptr& query);
|
||||
|
||||
/// @brief Checks if the specified option code has been requested using
|
||||
/// the Option Request option.
|
||||
///
|
||||
/// @param query Pointer to the client's query.
|
||||
/// @parma code Option code.
|
||||
///
|
||||
/// @return true if option has been requested in the ORO.
|
||||
bool requestedInORO(const Pkt6Ptr& query, const uint16_t code) const;
|
||||
|
||||
/// UDP port number on which server listens.
|
||||
uint16_t port_;
|
||||
|
||||
|
@@ -218,7 +218,7 @@ const char* RENEW_CONFIGS[] = {
|
||||
" \"interface-id\": \"\","
|
||||
" \"interface\": \"eth0\""
|
||||
" } ],"
|
||||
"\"valid-lifetime\": 4000 }
|
||||
"\"valid-lifetime\": 4000 }"
|
||||
};
|
||||
|
||||
/// @brief Test fixture class for testing Renew.
|
||||
@@ -352,7 +352,7 @@ TEST_F(RenewTest, renewWithExcludedPrefix) {
|
||||
ASSERT_FALSE(option);
|
||||
|
||||
// Reconfigure the server to use the prefix pool with excluded prefix.
|
||||
configure(RENEW_CONFIGS[4], *client.getServer());
|
||||
configure(RENEW_CONFIGS[5], *client.getServer());
|
||||
|
||||
// Send Renew message to the server, including IA_NA and IA_PD.
|
||||
ASSERT_NO_THROW(client.doRenew());
|
||||
|
@@ -339,7 +339,7 @@ TEST_F(SARRTest, directClientExcludedPrefix) {
|
||||
// Configure client to request IA_PD.
|
||||
client.requestPrefix();
|
||||
client.requestOption(D6O_PD_EXCLUDE);
|
||||
configure(CONFIGS[2], *client.getServer());
|
||||
configure(CONFIGS[3], *client.getServer());
|
||||
// Make sure we ended-up having expected number of subnets configured.
|
||||
const Subnet6Collection* subnets = CfgMgr::instance().getCurrentCfg()->
|
||||
getCfgSubnets6()->getAll();
|
||||
|
@@ -350,7 +350,7 @@ AllocEngine::ClientContext6::ClientContext6(const Subnet6Ptr& subnet,
|
||||
duid_(duid), hwaddr_(), host_identifiers_(), host_(),
|
||||
fwd_dns_update_(fwd_dns), rev_dns_update_(rev_dns),
|
||||
hostname_(hostname), callout_handle_(callout_handle),
|
||||
allocated_resources_(), ias_(), pd_exclude_requested_(false) {
|
||||
allocated_resources_(), ias_() {
|
||||
|
||||
// Initialize host identifiers.
|
||||
if (duid) {
|
||||
|
@@ -397,10 +397,6 @@ public:
|
||||
/// @brief Container holding IA specific contexts.
|
||||
std::vector<IAContext> ias_;
|
||||
|
||||
/// @brief Indicates if PD exclude option has been requested by a
|
||||
/// client.
|
||||
bool pd_exclude_requested_;
|
||||
|
||||
/// @brief Convenience method adding allocated prefix or address.
|
||||
///
|
||||
/// @param prefix Prefix or address.
|
||||
|
@@ -71,7 +71,7 @@ int Dhcp4o6IpcBase::open(uint16_t port, EndpointType endpoint_type) {
|
||||
}
|
||||
// We'll connect to the loopback address so bind to it too.
|
||||
local6.sin6_addr.s6_addr[15] = 1;
|
||||
if (bind(sock, (struct sockaddr *)&local6, sizeof(local6)) < 0) {
|
||||
if (::bind(sock, (struct sockaddr *)&local6, sizeof(local6)) < 0) {
|
||||
::close(sock);
|
||||
isc_throw(Dhcp4o6IpcError, "Failed to bind DHCP4o6 socket.");
|
||||
}
|
||||
|
@@ -525,11 +525,7 @@ private:
|
||||
// If the option space is a standard DHCPv4 or DHCPv6 option space,
|
||||
// this is most likely a standard option, for which we have a
|
||||
// definition created within libdhcp++.
|
||||
OptionDefinitionPtr def;
|
||||
if ((space == DHCP4_OPTION_SPACE) ||
|
||||
(space == DHCP6_OPTION_SPACE)) {
|
||||
def = LibDHCP::getOptionDef(universe_, code);
|
||||
}
|
||||
OptionDefinitionPtr def = LibDHCP::getOptionDef(space, code);
|
||||
|
||||
// Otherwise, we may check if this an option encapsulated within the
|
||||
// vendor space.
|
||||
|
Reference in New Issue
Block a user