}
// First check for reservation when it is the choice.
- if (check_reservation_first && (hr_mode & Network::HR_IN_SUBNET)) {
+ if (check_reservation_first && ((hr_mode & Network::HR_IN_SUBNET) &&
+ !(hr_mode & Network::HR_OUT_OF_POOL))) {
auto hosts = getIPv6Resrv(subnet->getID(), candidate);
if (!hosts.empty()) {
// Don't allocate.
/// In-pool reservations: Check if this address is reserved for someone
/// else. There is no need to check for whom it is reserved, because if
/// it has been reserved for us we would have already allocated a lease.
- if (!check_reservation_first && (hr_mode & Network::HR_IN_SUBNET)) {
+ if (!check_reservation_first && (hr_mode & Network::HR_IN_SUBNET) &&
+ !(hr_mode & Network::HR_OUT_OF_POOL)) {
auto hosts = getIPv6Resrv(subnet->getID(), candidate);
if (!hosts.empty()) {
// Don't allocate.
// allocation attempts.
} else if (existing->expired()) {
// Make sure it's not reserved.
- if (!check_reservation_first && (hr_mode & Network::HR_IN_SUBNET)) {
+ if (!check_reservation_first && (hr_mode & Network::HR_IN_SUBNET) &&
+ !(hr_mode & Network::HR_OUT_OF_POOL)) {
auto hosts = getIPv6Resrv(subnet->getID(), candidate);
if (!hosts.empty()) {
// Don't allocate.
/// @return true if the address is reserved for another client.
bool
addressReserved(const IOAddress& address, const AllocEngine::ClientContext4& ctx) {
- if (ctx.subnet_ &&
- ((ctx.subnet_->getHostReservationMode() & Network::HR_IN_SUBNET) ||
- ((ctx.subnet_->getHostReservationMode() & Network::HR_OUT_OF_POOL) &&
- (!ctx.subnet_->inPool(Lease::TYPE_V4, address))))) {
+ bool in_subnet = (ctx.subnet_->getHostReservationMode() & Network::HR_IN_SUBNET);
+ bool out_of_pool = (ctx.subnet_->getHostReservationMode() & Network::HR_OUT_OF_POOL);
+ if (ctx.subnet_ && ((in_subnet && !out_of_pool) ||
+ (out_of_pool && (!ctx.subnet_->inPool(Lease::TYPE_V4, address))))) {
// The global parameter ip-reservations-unique controls whether it is allowed
// to specify multiple reservations for the same IP address or delegated prefix
// or IP reservations must be unique. Some host backends do not support the
}
auto host = ctx.hosts_.find(subnet->getID());
- if ((host != ctx.hosts_.end()) &&
- !(host->second->getIPv4Reservation().isV4Zero()) &&
- ((subnet->getHostReservationMode() & Network::HR_IN_SUBNET) ||
- ((subnet->getHostReservationMode() & Network::HR_OUT_OF_POOL) &&
- (!subnet->inPool(Lease::TYPE_V4, host->second->getIPv4Reservation()))))) {
+ bool in_subnet = (subnet->getHostReservationMode() & Network::HR_IN_SUBNET);
+ bool out_of_pool = (subnet->getHostReservationMode() & Network::HR_OUT_OF_POOL);
+ auto reservation = host->second->getIPv4Reservation();
+ if ((host != ctx.hosts_.end()) && !reservation.isV4Zero() &&
+ ((in_subnet && !out_of_pool) ||
+ (out_of_pool && !subnet->inPool(Lease::TYPE_V4, reservation)))) {
ctx.subnet_ = subnet;
return (true);
}
ConstElementPtr elem;
uint8_t flags = 0;
+ bool force_true = false;
try {
- elem = config_elem->get("reservations-global");
+ elem = config_elem->get("reservations-out-of-pool");
if (elem) {
bool value = elem->boolValue();
if (value) {
- flags |= Network::HR_GLOBAL;
+ flags |= Network::HR_IN_SUBNET | Network::HR_OUT_OF_POOL;
+ force_true = true;
}
}
bool value = elem->boolValue();
if (value) {
flags |= Network::HR_IN_SUBNET;
+ } else if (force_true) {
+ isc_throw(DhcpConfigError, "invalid use of disabled 'reservations-in-subnet'"
+ " when enabled 'reservations-out-of-pool'");
}
}
- elem = config_elem->get("reservations-out-of-pool");
+ elem = config_elem->get("reservations-global");
if (elem) {
bool value = elem->boolValue();
if (value) {
- flags |= Network::HR_IN_SUBNET | Network::HR_OUT_OF_POOL;
+ flags |= Network::HR_GLOBAL;
}
}
} catch (const Exception& ex) {