Commit ac390543 authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[3688] Implemented AllocEngine::findReservation for DHCPv4.

parent bfce8a98
......@@ -1300,6 +1300,26 @@ AllocEngine::allocateLease4(ClientContext4& ctx) {
return (new_lease);
}
void
AllocEngine::findReservation(ClientContext4& ctx) const {
ctx.host_.reset();
// We can only search for the reservation if a subnet has been selected.
if (ctx.subnet_) {
// Check which host reservation mode is supported in this subnet.
Subnet::HRMode hr_mode = ctx.subnet_->getHostReservationMode();
// Check if there is a host reseravtion for this client. Attempt to
// get host information
if (hr_mode != Subnet::HR_DISABLED) {
// This method should handle the case when there is neither hwaddr
// nor clientid_ available and simply return NULL.
ctx.host_ = HostMgr::instance().get4(ctx.subnet_->getID(), ctx.hwaddr_,
ctx.clientid_);
}
}
}
Lease4Ptr
AllocEngine::discoverLease4(AllocEngine::ClientContext4& ctx) {
// Obtain the sole instance of the LeaseMgr.
......
......@@ -874,6 +874,16 @@ public:
/// @return Allocated IPv4 lease (or NULL if allocation failed).
Lease4Ptr allocateLease4(ClientContext4& ctx);
/// @brief Attempts to find the host reservation for the client.
///
/// This method attempts to find the host reservation for the client. If
/// found, it is set in the @c ctx.host_. If the host reservations are
/// disabled for the particular subnet or the reservation is not found
/// for the client, the @ctx.host_ is set to NULL.
///
/// @param ctx Client context holding various information about the client.
void findReservation(ClientContext4& ctx) const;
private:
/// @brief Offers the lease.
......
......@@ -1292,6 +1292,80 @@ TEST_F(AllocEngine4Test, reservedAddressShortPool) {
EXPECT_EQ("192.0.2.100", allocated_lease->addr_.toText());
}
// This test checks that the AllocEngine::findReservation method finds
// and returns host reservation for the DHCPv4 client using the data from
// the client context. If the host reservation can't be found, it sets
// the value of NULL in the host_ field of the client context.
TEST_F(AllocEngine4Test, findReservation) {
// Create the instance of the allocation engine.
AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 100, false);
// Context is required to call the AllocEngine::findReservation.
AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
IOAddress("0.0.0.0"), false, false,
"", false);
// There is no reservation in the database so no host should be
// retruned.
ASSERT_NO_THROW(engine.findReservation(ctx));
EXPECT_FALSE(ctx.host_);
// Create a reservation for the client.
HostPtr host(new Host(&hwaddr_->hwaddr_[0], hwaddr_->hwaddr_.size(),
Host::IDENT_HWADDR, subnet_->getID(),
SubnetID(0), IOAddress("192.0.2.100")));
CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
CfgMgr::instance().commit();
// This time the reservation should be returned.
ASSERT_NO_THROW(engine.findReservation(ctx));
EXPECT_TRUE(ctx.host_);
EXPECT_EQ(ctx.host_->getIPv4Reservation(), host->getIPv4Reservation());
// If the host reservation mode for the subnet is disabled, the
// host should not be returned, even though it exists in the
// host database.
subnet_->setHostReservationMode(Subnet::HR_DISABLED);
ASSERT_NO_THROW(engine.findReservation(ctx));
EXPECT_FALSE(ctx.host_);
// Check the third possible reservation mode.
subnet_->setHostReservationMode(Subnet::HR_OUT_OF_POOL);
ASSERT_NO_THROW(engine.findReservation(ctx));
EXPECT_TRUE(ctx.host_);
EXPECT_EQ(ctx.host_->getIPv4Reservation(), host->getIPv4Reservation());
// This time use the client identifier to search for the host.
host.reset(new Host(&clientid_->getClientId()[0],
clientid_->getClientId().size(),
Host::IDENT_DUID, subnet_->getID(),
SubnetID(0), IOAddress("192.0.2.101")));
CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
CfgMgr::instance().commit();
ASSERT_NO_THROW(engine.findReservation(ctx));
EXPECT_TRUE(ctx.host_);
EXPECT_EQ(ctx.host_->getIPv4Reservation(), host->getIPv4Reservation());
// Remove the subnet. Subnet id is required to find host reservations, so
// if it is set to NULL, no reservation should be returned
ctx.subnet_.reset();
ASSERT_NO_THROW(engine.findReservation(ctx));
EXPECT_FALSE(ctx.host_);
// The same if there is a mismatch of the subnet id between the reservation
// and the context.
ctx.subnet_ = subnet_;
host.reset(new Host(&hwaddr_->hwaddr_[0], hwaddr_->hwaddr_.size(),
Host::IDENT_HWADDR, subnet_->getID() + 1,
SubnetID(0), IOAddress("192.0.2.100")));
CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
CfgMgr::instance().commit();
ASSERT_NO_THROW(engine.findReservation(ctx));
EXPECT_FALSE(ctx.host_);
}
}; // namespace test
}; // namespace dhcp
}; // namespace isc
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment