mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-31 14:05:33 +00:00
[#1550] check if reservation is in pool before assigning it to the client
This commit is contained in:
@@ -74,7 +74,7 @@ const char* CONFIGS[] = {
|
||||
" } ],"
|
||||
"\"valid-lifetime\": 4000 }",
|
||||
|
||||
// Configuration 1
|
||||
// Configuration 1
|
||||
"{ \"interfaces-config\": {"
|
||||
" \"interfaces\": [ \"*\" ]"
|
||||
"},"
|
||||
@@ -99,7 +99,7 @@ const char* CONFIGS[] = {
|
||||
" \"qualifying-suffix\" : \"example.com\" }"
|
||||
"}",
|
||||
|
||||
// Configuration 2
|
||||
// Configuration 2
|
||||
"{ \"interfaces-config\": {"
|
||||
" \"interfaces\": [ \"*\" ]"
|
||||
"},"
|
||||
@@ -180,7 +180,35 @@ const char* CONFIGS[] = {
|
||||
" \"interface-id\": \"\","
|
||||
" \"interface\": \"eth0\""
|
||||
" } ],"
|
||||
"\"valid-lifetime\": 4000 }"
|
||||
"\"valid-lifetime\": 4000"
|
||||
"}",
|
||||
|
||||
// Configuration 4
|
||||
"{ \"interfaces-config\": {"
|
||||
" \"interfaces\": [ \"*\" ]"
|
||||
"},"
|
||||
"\"preferred-lifetime\": 3000,"
|
||||
"\"rebind-timer\": 2000, "
|
||||
"\"renew-timer\": 1000, "
|
||||
"\"subnet6\": [ { "
|
||||
" \"pools\": [ { \"pool\": \"2001:db8:1::1 - 2001:db8:1::10\" } ],"
|
||||
" \"subnet\": \"2001:db8:1::/48\", "
|
||||
" \"interface\": \"eth0\", "
|
||||
" \"reservations-global\": false,"
|
||||
" \"reservations-in-subnet\": true,"
|
||||
" \"reservations-out-of-pool\": true,"
|
||||
" \"reservations\": [ "
|
||||
" {"
|
||||
" \"duid\": \"aa:bb:cc:dd:ee:ff\","
|
||||
" \"ip-addresses\": [\"2001:db8:1::20\"]"
|
||||
" },"
|
||||
" {"
|
||||
" \"duid\": \"11:22:33:44:55:66\","
|
||||
" \"ip-addresses\": [\"2001:db8:1::5\"]"
|
||||
" }"
|
||||
" ]"
|
||||
"} ]"
|
||||
"}"
|
||||
};
|
||||
|
||||
/// @brief Test fixture class for testing 4-way exchange: Solicit-Advertise,
|
||||
@@ -624,5 +652,62 @@ TEST_F(SARRTest, pkt6ReceiveDropStat3) {
|
||||
EXPECT_EQ(1, pkt6_recv_drop->getInteger().first);
|
||||
}
|
||||
|
||||
// This test verifies that in pool reservations are ignored when the
|
||||
// reservation mode is set to "out-of-pool".
|
||||
TEST_F(SARRTest, reservationModeOutOfPool) {
|
||||
// Create the first client for which we have a reservation out of the
|
||||
// dynamic pool.
|
||||
Dhcp6Client client;
|
||||
configure(CONFIGS[4], *client.getServer());
|
||||
client.setDUID("aa:bb:cc:dd:ee:ff");
|
||||
client.setInterface("eth0");
|
||||
client.requestAddress(1234, IOAddress("2001:db8:1::3"));
|
||||
|
||||
// Perform 4-way exchange.
|
||||
ASSERT_NO_THROW(client.doSARR());
|
||||
// Server should have assigned a prefix.
|
||||
ASSERT_EQ(1, client.getLeaseNum());
|
||||
|
||||
Lease6 lease = client.getLease(0);
|
||||
// Check that the server allocated the reserved address.
|
||||
ASSERT_EQ("2001:db8:1::20", lease.addr_.toText());
|
||||
|
||||
client.clearConfig();
|
||||
// Create another client which has a reservation within the pool.
|
||||
// The server should ignore this reservation in the current mode.
|
||||
client.setDUID("11:22:33:44:55:66");
|
||||
// This client is requesting a different address than reserved. The
|
||||
// server should allocate this address to the client.
|
||||
// Perform 4-way exchange.
|
||||
ASSERT_NO_THROW(client.doSARR());
|
||||
// Server should have assigned a prefix.
|
||||
ASSERT_EQ(1, client.getLeaseNum());
|
||||
|
||||
lease = client.getLease(0);
|
||||
// Check that the requested address was assigned.
|
||||
ASSERT_EQ("2001:db8:1::3", lease.addr_.toText());
|
||||
}
|
||||
|
||||
// This test verifies that the in-pool reservation can be assigned to
|
||||
// the client not owning this reservation when the reservation mode is
|
||||
// set to "out-of-pool".
|
||||
TEST_F(SARRTest, reservationIgnoredInOutOfPoolMode) {
|
||||
// Create the first client for which we have a reservation out of the
|
||||
// dynamic pool.
|
||||
Dhcp6Client client;
|
||||
configure(CONFIGS[4], *client.getServer());
|
||||
client.setDUID("12:34:56:78:9A:BC");
|
||||
client.setInterface("eth0");
|
||||
client.requestAddress(1234, IOAddress("2001:db8:1::5"));
|
||||
|
||||
// Perform 4-way exchange.
|
||||
ASSERT_NO_THROW(client.doSARR());
|
||||
// Server should have assigned a prefix.
|
||||
ASSERT_EQ(1, client.getLeaseNum());
|
||||
|
||||
Lease6 lease = client.getLease(0);
|
||||
// Check that the server allocated the reserved address.
|
||||
ASSERT_EQ("2001:db8:1::5", lease.addr_.toText());
|
||||
}
|
||||
|
||||
} // end of anonymous namespace
|
||||
|
@@ -928,7 +928,11 @@ AllocEngine::allocateUnreservedLeases6(ClientContext6& ctx) {
|
||||
// it has been reserved for us we would have already allocated a lease.
|
||||
|
||||
ConstHostCollection hosts;
|
||||
if (in_subnet) {
|
||||
// The out-of-pool flag indicates that no client should be assigned reservations
|
||||
// from within the dynamic pool, and for that reason we only look at reservations that
|
||||
// are outside the pools, hence the inPool check.
|
||||
if (in_subnet && (!subnet->getReservationsOutOfPool() ||
|
||||
!ctx.subnet_->inPool(ctx.currentIA().type_, hint))) {
|
||||
hosts = getIPv6Resrv(subnet->getID(), hint);
|
||||
}
|
||||
|
||||
@@ -962,7 +966,11 @@ AllocEngine::allocateUnreservedLeases6(ClientContext6& ctx) {
|
||||
|
||||
// If the lease is expired, we may likely reuse it, but...
|
||||
ConstHostCollection hosts;
|
||||
if (in_subnet) {
|
||||
// The out-of-pool flag indicates that no client should be assigned reservations
|
||||
// from within the dynamic pool, and for that reason we only look at reservations that
|
||||
// are outside the pools, hence the inPool check.
|
||||
if (in_subnet && (!subnet->getReservationsOutOfPool() ||
|
||||
!ctx.subnet_->inPool(ctx.currentIA().type_, hint))) {
|
||||
hosts = getIPv6Resrv(subnet->getID(), hint);
|
||||
}
|
||||
|
||||
@@ -1250,6 +1258,8 @@ AllocEngine::allocateReservedLeases6(ClientContext6& ctx,
|
||||
|
||||
ConstHostPtr host = ctx.hosts_[subnet_id];
|
||||
|
||||
bool in_subnet = subnet->getReservationsInSubnet();
|
||||
|
||||
// Get the IPv6 reservations of specified type.
|
||||
const IPv6ResrvRange& reservs = host->getIPv6Reservations(type);
|
||||
BOOST_FOREACH(IPv6ResrvTuple type_lease_tuple, reservs) {
|
||||
@@ -1263,6 +1273,15 @@ AllocEngine::allocateReservedLeases6(ClientContext6& ctx,
|
||||
continue;
|
||||
}
|
||||
|
||||
// The out-of-pool flag indicates that no client should be assigned reservations
|
||||
// from within the dynamic pool, and for that reason we only look at reservations that
|
||||
// are outside the pools, hence the inPool check.
|
||||
if (in_subnet && (!subnet->getReservationsOutOfPool() ||
|
||||
!subnet->inPool(ctx.currentIA().type_, addr))) {
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If there's a lease for this address, let's not create it.
|
||||
// It doesn't matter whether it is for this client or for someone else.
|
||||
if (!LeaseMgrFactory::instance().getLease6(ctx.currentIA().type_,
|
||||
@@ -2946,6 +2965,9 @@ namespace {
|
||||
/// @return true if the address is reserved for another client.
|
||||
bool
|
||||
addressReserved(const IOAddress& address, const AllocEngine::ClientContext4& ctx) {
|
||||
// The out-of-pool flag indicates that no client should be assigned reservations
|
||||
// from within the dynamic pool, and for that reason we only look at reservations that
|
||||
// are outside the pools, hence the inPool check.
|
||||
if (ctx.subnet_ && ctx.subnet_->getReservationsInSubnet() &&
|
||||
(!ctx.subnet_->getReservationsOutOfPool() ||
|
||||
!ctx.subnet_->inPool(Lease::TYPE_V4, address))) {
|
||||
|
Reference in New Issue
Block a user