From 15925ccf96e9fe326a5d131325452485dd72ed21 Mon Sep 17 00:00:00 2001 From: Tomek Mrugalski Date: Fri, 6 Mar 2015 19:05:34 +0100 Subject: [PATCH] [3689] findReservation() implemented --- src/bin/dhcp6/dhcp6_srv.cc | 12 ++++-- src/lib/dhcpsrv/alloc_engine.cc | 69 +++++++++++++++++++++------------ src/lib/dhcpsrv/alloc_engine.h | 30 +++++++++++--- 3 files changed, 78 insertions(+), 33 deletions(-) diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc index 3483808e45..fe9f7099f5 100644 --- a/src/bin/dhcp6/dhcp6_srv.cc +++ b/src/bin/dhcp6/dhcp6_srv.cc @@ -1301,7 +1301,8 @@ Dhcpv6Srv::assignIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid, // It's ok if there response is NULL. Hardware address is optional in Lease6. ctx.hwaddr_ = getMAC(query); - Lease6Collection leases = alloc_engine_->allocateLeases6(ctx); + alloc_engine_->findReservation(ctx); + Lease6Collection leases = alloc_engine_->allocateLeases6(ctx, false); /// @todo: Handle more than one lease Lease6Ptr lease; @@ -1444,7 +1445,8 @@ Dhcpv6Srv::assignIA_PD(const Subnet6Ptr& subnet, const DuidPtr& duid, // It's ok if there response is NULL. Hardware address is optional in Lease6 ctx.hwaddr_ = getMAC(query); - Lease6Collection leases = alloc_engine_->allocateLeases6(ctx); + alloc_engine_->findReservation(ctx); + Lease6Collection leases = alloc_engine_->allocateLeases6(ctx, false); if (!leases.empty()) { @@ -1589,7 +1591,8 @@ Dhcpv6Srv::extendIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid, ctx.allow_new_leases_in_renewals_ = true; } - Lease6Collection leases = alloc_engine_->renewLeases6(ctx); + alloc_engine_->findReservation(ctx); + Lease6Collection leases = alloc_engine_->renewLeases6(ctx, false); // Ok, now we have the leases extended. We have: // - what the client tried to renew in ctx.hints_ @@ -1770,7 +1773,8 @@ Dhcpv6Srv::extendIA_PD(const Subnet6Ptr& subnet, const DuidPtr& duid, // - old_leases - leases that used to be, but are no longer valid // - changed_leases - leases that have FQDN changed (not really important // in PD context) - Lease6Collection leases = alloc_engine_->renewLeases6(ctx); + alloc_engine_->findReservation(ctx); + Lease6Collection leases = alloc_engine_->renewLeases6(ctx, false); // 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) { diff --git a/src/lib/dhcpsrv/alloc_engine.cc b/src/lib/dhcpsrv/alloc_engine.cc index 1b96d90a99..e9b74aa96b 100644 --- a/src/lib/dhcpsrv/alloc_engine.cc +++ b/src/lib/dhcpsrv/alloc_engine.cc @@ -318,9 +318,30 @@ AllocEngine::ClientContext6::ClientContext6(const Subnet6Ptr& subnet, const Duid } +void AllocEngine::findReservation(ClientContext6& ctx) const { + if (!ctx.subnet_) { + isc_throw(InvalidOperation, "Subnet is required for IPv6 lease allocation"); + } else if (!ctx.duid_) { + isc_throw(InvalidOperation, "DUID is mandatory for IPv6 lease allocation"); + } + + // Check which host reservation mode is supported in this subnet. + Subnet::HRMode hr_mode = ctx.subnet_->getHostReservationMode(); + + // Check if there's a host reservation for this client. Attempt to get + // host info only if reservations are not disabled. + if (hr_mode != Subnet::HR_DISABLED) { + + ctx.host_ = HostMgr::instance().get6(ctx.subnet_->getID(), ctx.duid_, + ctx.hwaddr_); + } else { + // Let's explicitly set it to NULL if reservations are disabled. + ctx.host_.reset(); + } +} Lease6Collection -AllocEngine::allocateLeases6(ClientContext6& ctx) { +AllocEngine::allocateLeases6(ClientContext6& ctx, bool find_reservation) { try { if (!ctx.subnet_) { @@ -330,18 +351,17 @@ AllocEngine::allocateLeases6(ClientContext6& ctx) { isc_throw(InvalidOperation, "DUID is mandatory for IPv6 lease allocation"); } - // Check which host reservation mode is supported in this subnet. - Subnet::HRMode hr_mode = ctx.subnet_->getHostReservationMode(); - - // Check if there's a host reservation for this client. Attempt to get - // host info only if reservations are not disabled. - if (hr_mode != Subnet::HR_DISABLED) { + if (find_reservation) { + findReservation(ctx); + } - ctx.host_ = HostMgr::instance().get6(ctx.subnet_->getID(), ctx.duid_, - ctx.hwaddr_); - } else { - // Let's explicitly set it to NULL if reservations are disabled. - ctx.host_.reset(); + // Let's check whether there's a hostname specified in the reservation + if (ctx.host_) { + std::string hostname = ctx.host_->getHostname(); + // If there is, let's use it + if (!hostname.empty()) { + ctx.hostname_ = hostname; + } } // Check if there are existing leases for that subnet/duid/iaid @@ -1001,7 +1021,7 @@ Lease6Ptr AllocEngine::createLease6(ClientContext6& ctx, } Lease6Collection -AllocEngine::renewLeases6(ClientContext6& ctx) { +AllocEngine::renewLeases6(ClientContext6& ctx, bool find_host) { try { if (!ctx.subnet_) { isc_throw(InvalidOperation, "Subnet is required for allocation"); @@ -1011,20 +1031,21 @@ AllocEngine::renewLeases6(ClientContext6& ctx) { isc_throw(InvalidOperation, "DUID is mandatory for allocation"); } - // Check which host reservation mode is supported in this subnet. - Subnet::HRMode hr_mode = ctx.subnet_->getHostReservationMode(); - - // Check if there's a host reservation for this client. Attempt to get - // host info only if reservations are not disabled. - if (hr_mode != Subnet::HR_DISABLED) { + // We can attempt to find appropriate reservation + if (find_host) { + findReservation(ctx); + } - ctx.host_ = HostMgr::instance().get6(ctx.subnet_->getID(), ctx.duid_, - ctx.hwaddr_); - } else { - // Host reservations disabled? Then explicitly set host to NULL - ctx.host_.reset(); + // Let's check whether there's a hostname specified in the reservation + if (ctx.host_) { + std::string hostname = ctx.host_->getHostname(); + // If there is, let's use it + if (!hostname.empty()) { + ctx.hostname_ = hostname; + } } + // Check if there are any leases for this client. Lease6Collection leases = LeaseMgrFactory::instance() .getLeases6(ctx.type_, *ctx.duid_, ctx.iaid_, ctx.subnet_->getID()); diff --git a/src/lib/dhcpsrv/alloc_engine.h b/src/lib/dhcpsrv/alloc_engine.h index a92a837aae..33363147b2 100644 --- a/src/lib/dhcpsrv/alloc_engine.h +++ b/src/lib/dhcpsrv/alloc_engine.h @@ -406,7 +406,8 @@ public: /// it into LeaseMgr (if this allocation is not fake, i.e. this is not a /// response to SOLICIT). /// - /// This method uses host reservation if appropriate. The host reservation + /// This method uses host reservation if ctx.host_ is set. The easy way to + /// set it is to call @ref AllocEngine::findReservation(ctx). The host reservation /// is convenient, but incurs performance penalty, so it can be tweaked on /// a per subnet basis. There are three possible modes: /// 1. disabled (no host reservation at all). This is the most performant one @@ -444,6 +445,12 @@ public: /// /// @param ctx client context that passes all necessary information. See /// @ref ClientContext6 for details. + /// @param find_resrv specifies whether the code should search for host + /// reservation. true means that the code will consult HostMgr, false means + /// to skip this check. That is easier to use, but is redundant if the + /// ctx.host_ field is already set. We can't use ctx.host_ == NULL as + /// check, because for cases whithout reservations, the reservation + /// search would be repeated. /// /// The following fields of ClientContext6 are used: /// @@ -477,8 +484,7 @@ public: /// /// @return Allocated IPv6 leases (may be empty if allocation failed) Lease6Collection - allocateLeases6(ClientContext6& ctx); - + allocateLeases6(ClientContext6& ctx, bool find_resrv = true); /// @brief Renews existing DHCPv6 leases for a given IA. /// @@ -498,9 +504,23 @@ public: /// prefixes the client had sent. @ref ClientContext6::old_leases_ will /// contain removed leases in this case. /// + /// @param find_resrv specifies whether the code should search for host + /// reservation. true means that the code will consult HostMgr, false means + /// to skip this check. That is easier to use, but is redundant if the + /// ctx.host_ field is already set. We can't use ctx.host_ == NULL as + /// check, because for cases whithout reservations, the reservation + /// search would be repeated. + /// + /// /// @return Returns renewed lease. - Lease6Collection - renewLeases6(ClientContext6& ctx); + Lease6Collection renewLeases6(ClientContext6& ctx, bool find_resrv = true); + + /// @brief Attempts to find appropriate host reservation. + /// + /// Attempts to find appropriate host reservation in HostMgr. If found, it + /// will be set in ctx.host_. + /// @param ctx Client context that contains all necessary information. + void findReservation(ClientContext6& ctx) const; private: -- 2.47.2