From: Marcin Siodelski Date: Fri, 8 Sep 2017 18:29:59 +0000 (+0200) Subject: [5306] Implemented getNextSubnet() function for subnets. X-Git-Tag: trac5363_base~21^2~13 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c76416e5d4c07b0dcb2ea97a2b9fa94a6b17516e;p=thirdparty%2Fkea.git [5306] Implemented getNextSubnet() function for subnets. --- diff --git a/src/lib/dhcpsrv/alloc_engine.cc b/src/lib/dhcpsrv/alloc_engine.cc index fdd5fdc68e..7b6f48fb8d 100644 --- a/src/lib/dhcpsrv/alloc_engine.cc +++ b/src/lib/dhcpsrv/alloc_engine.cc @@ -2192,9 +2192,7 @@ void findClientLease(AllocEngine::ClientContext4& ctx, Lease4Ptr& client_lease) // Some of the subnets within a shared network may not be allowed // for the client if classification restrictions have been applied. if (!subnet->clientSupported(ctx.query_->getClasses())) { - if (network) { - subnet = network->getNextSubnet(original_subnet, subnet); - } + subnet = subnet->getNextSubnet(original_subnet); continue; } @@ -2235,7 +2233,7 @@ void findClientLease(AllocEngine::ClientContext4& ctx, Lease4Ptr& client_lease) subnet.reset(); } else { - subnet = network->getNextSubnet(original_subnet, subnet); + subnet = subnet->getNextSubnet(original_subnet); } } } @@ -2271,15 +2269,7 @@ inAllowedPool(AllocEngine::ClientContext4& ctx, const IOAddress& address) { } } - if (network) { - // Address is not within pools or client class not supported, so - // let's proceed to the next subnet. - current_subnet = network->getNextSubnet(ctx.subnet_, current_subnet); - - } else { - // No shared network, so there are no more subnets to try. - current_subnet.reset(); - } + current_subnet = current_subnet->getNextSubnet(ctx.subnet_); } return (false); @@ -2966,9 +2956,7 @@ AllocEngine::allocateUnreservedLease4(ClientContext4& ctx) { // Some of the subnets within a shared network may not be allowed // for the client if classification restrictions have been applied. if (!subnet->clientSupported(ctx.query_->getClasses())) { - if (network) { - subnet = network->getNextSubnet(original_subnet, subnet); - } + subnet = subnet->getNextSubnet(original_subnet); continue; } @@ -2993,23 +2981,16 @@ AllocEngine::allocateUnreservedLease4(ClientContext4& ctx) { break; } } + ++total_attempts; } - total_attempts += max_attempts; - - // If our current subnet belongs to a shared network, let's try other - // subnets in the same shared network. - if (network) { - subnet = network->getNextSubnet(original_subnet, subnet); + // This pointer may be set to NULL if hooks set SKIP status. + if (subnet) { + subnet = subnet->getNextSubnet(original_subnet); if (subnet) { ctx.subnet_ = subnet; } - - } else { - // Subnet doesn't belong to a shared network so we have no more - // subnets/address pools to try. The client won't get the lease. - subnet.reset(); } } diff --git a/src/lib/dhcpsrv/shared_network.cc b/src/lib/dhcpsrv/shared_network.cc index 5a38e0356a..fba654a8c3 100644 --- a/src/lib/dhcpsrv/shared_network.cc +++ b/src/lib/dhcpsrv/shared_network.cc @@ -157,16 +157,7 @@ public: template static SubnetPtrType getNextSubnet(const SubnetCollectionType& subnets, const SubnetPtrType& first_subnet, - const SubnetPtrType& current_subnet) { - // Current subnet must not be null. The caller must explicitly set it - // to one of the pointers that belong to this shared network, typically - // to a selected subnet. - if (!current_subnet) { - isc_throw(BadValue, "null subnet specified for a shared" - " network while searching for next subnet is this" - " network"); - } - + const SubnetID& current_subnet) { // It is ok to have a shared network without any subnets, but in this // case there is nothing else we can return but null pointer. if (subnets.empty()) { @@ -177,9 +168,9 @@ public: // subnet must exist in this container, thus we throw if the iterator // is not found. const auto& index = subnets.template get(); - auto subnet_id_it = index.find(current_subnet->getID()); + auto subnet_id_it = index.find(current_subnet); if (subnet_id_it == index.cend()) { - isc_throw(BadValue, "no such subnet " << current_subnet->getID() + isc_throw(BadValue, "no such subnet " << current_subnet << " within shared network"); } @@ -235,7 +226,7 @@ SharedNetwork4::getSubnet(const SubnetID& subnet_id) const { Subnet4Ptr SharedNetwork4::getNextSubnet(const Subnet4Ptr& first_subnet, - const Subnet4Ptr& current_subnet) const { + const SubnetID& current_subnet) const { return (Impl::getNextSubnet(subnets_, first_subnet, current_subnet)); } @@ -283,7 +274,7 @@ SharedNetwork6::getSubnet(const SubnetID& subnet_id) const { Subnet6Ptr SharedNetwork6::getNextSubnet(const Subnet6Ptr& first_subnet, - const Subnet6Ptr& current_subnet) const { + const SubnetID& current_subnet) const { return (Impl::getNextSubnet(subnets_, first_subnet, current_subnet)); } diff --git a/src/lib/dhcpsrv/shared_network.h b/src/lib/dhcpsrv/shared_network.h index 474bbf4d4a..3d3e38ba51 100644 --- a/src/lib/dhcpsrv/shared_network.h +++ b/src/lib/dhcpsrv/shared_network.h @@ -103,7 +103,7 @@ public: /// @param first_subnet Pointer to a subnet from which the caller is /// iterating over subnets within shared network. This is typically a /// subnet selected during "subnet selection" step. - /// @param current_subnet Pointer to a subnet for which next subnet is + /// @param current_subnet Identifier of a subnet for which next subnet is /// to be found. /// /// @return Pointer to next subnet or null pointer if no more subnets found. @@ -111,7 +111,7 @@ public: /// @throw isc::BadValue if invalid arguments specified, e.g. unable to /// find first or current subnet within shared network. Subnet4Ptr getNextSubnet(const Subnet4Ptr& first_subnet, - const Subnet4Ptr& current_subnet) const; + const SubnetID& current_subnet) const; /// @brief Unparses shared network object. /// @@ -226,7 +226,7 @@ public: /// @param first_subnet Pointer to a subnet from which the caller is /// iterating over subnets within shared network. This is typically a /// subnet selected during "subnet selection" step. - /// @param current_subnet Pointer to a subnet for which next subnet is + /// @param current_subnet Identifier of a subnet for which next subnet is /// to be found. /// /// @return Pointer to next subnet or null pointer if no more subnets found. @@ -234,7 +234,7 @@ public: /// @throw isc::BadValue if invalid arguments specified, e.g. unable to /// find first or current subnet within shared network. Subnet6Ptr getNextSubnet(const Subnet6Ptr& first_subnet, - const Subnet6Ptr& current_subnet) const; + const SubnetID& current_subnet) const; /// @brief Unparses shared network object. /// diff --git a/src/lib/dhcpsrv/subnet.cc b/src/lib/dhcpsrv/subnet.cc index 69ba8f0739..955085f51d 100644 --- a/src/lib/dhcpsrv/subnet.cc +++ b/src/lib/dhcpsrv/subnet.cc @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -176,6 +177,17 @@ Subnet4::Subnet4(const isc::asiolink::IOAddress& prefix, uint8_t length, setValid(valid_lifetime); } +Subnet4Ptr +Subnet4::getNextSubnet(const Subnet4Ptr& first_subnet) const { + SharedNetwork4Ptr network; + getSharedNetwork(network); + if (network) { + return (network->getNextSubnet(first_subnet, getID())); + } + + return (Subnet4Ptr()); +} + bool Subnet4::clientSupported(const isc::dhcp::ClientClasses& client_classes) const { NetworkPtr network; @@ -450,6 +462,17 @@ void Subnet6::checkType(Lease::Type type) const { } } +Subnet6Ptr +Subnet6::getNextSubnet(const Subnet6Ptr& first_subnet) const { + SharedNetwork6Ptr network; + getSharedNetwork(network); + if (network) { + return (network->getNextSubnet(first_subnet, getID())); + } + + return (Subnet6Ptr()); +} + bool Subnet6::clientSupported(const isc::dhcp::ClientClasses& client_classes) const { NetworkPtr network; diff --git a/src/lib/dhcpsrv/subnet.h b/src/lib/dhcpsrv/subnet.h index 991ec503b9..ba230db589 100644 --- a/src/lib/dhcpsrv/subnet.h +++ b/src/lib/dhcpsrv/subnet.h @@ -371,6 +371,14 @@ protected: typedef boost::shared_ptr SubnetPtr; +class Subnet4; + +/// @brief A const pointer to a @c Subnet4 object. +typedef boost::shared_ptr ConstSubnet4Ptr; + +/// @brief A pointer to a @c Subnet4 object. +typedef boost::shared_ptr Subnet4Ptr; + /// @brief A configuration holder for IPv4 subnet. /// /// This class represents an IPv4 subnet. @@ -394,6 +402,20 @@ public: const Triplet& valid_lifetime, const SubnetID id = 0); + /// @brief Returns next subnet within shared network. + /// + /// If the current subnet doesn't belong to any shared network or if + /// the next subnet is the same as first subnet (specified in the + /// arguments) a NULL pointer is returned. + /// + /// @param first_subnet Pointer to the subnet from which iterations have + /// started. + /// + /// @return Pointer to the next subnet or NULL pointer if the next subnet + /// is the first subnet or if the current subnet doesn't belong to a + /// shared network. + Subnet4Ptr getNextSubnet(const Subnet4Ptr& first_subnet) const; + /// @brief Checks whether this subnet and parent shared network supports /// the client that belongs to specified classes. /// @@ -464,12 +486,13 @@ private: Cfg4o6 dhcp4o6_; }; -/// @brief A const pointer to a @c Subnet4 object. -typedef boost::shared_ptr ConstSubnet4Ptr; +class Subnet6; -/// @brief A pointer to a @c Subnet4 object. -typedef boost::shared_ptr Subnet4Ptr; +/// @brief A const pointer to a @c Subnet6 object. +typedef boost::shared_ptr ConstSubnet6Ptr; +/// @brief A pointer to a Subnet6 object +typedef boost::shared_ptr Subnet6Ptr; /// @brief A configuration holder for IPv6 subnet. /// @@ -496,6 +519,20 @@ public: const Triplet& valid_lifetime, const SubnetID id = 0); + /// @brief Returns next subnet within shared network. + /// + /// If the current subnet doesn't belong to any shared network or if + /// the next subnet is the same as first subnet (specified in the + /// arguments) a NULL pointer is returned. + /// + /// @param first_subnet Pointer to the subnet from which iterations have + /// started. + /// + /// @return Pointer to the next subnet or NULL pointer if the next subnet + /// is the first subnet or if the current subnet doesn't belong to a + /// shared network. + Subnet6Ptr getNextSubnet(const Subnet6Ptr& first_subnet) const; + /// @brief Checks whether this subnet and parent shared network supports /// the client that belongs to specified classes. /// @@ -533,12 +570,6 @@ private: }; -/// @brief A const pointer to a @c Subnet6 object. -typedef boost::shared_ptr ConstSubnet6Ptr; - -/// @brief A pointer to a Subnet6 object -typedef boost::shared_ptr Subnet6Ptr; - /// @name Definition of the multi index container holding subnet information /// //@{ diff --git a/src/lib/dhcpsrv/tests/shared_network_unittest.cc b/src/lib/dhcpsrv/tests/shared_network_unittest.cc index 7a342ff892..e9bcc7c6c4 100644 --- a/src/lib/dhcpsrv/tests/shared_network_unittest.cc +++ b/src/lib/dhcpsrv/tests/shared_network_unittest.cc @@ -164,7 +164,7 @@ TEST(SharedNetwork4Test, getNextSubnet) { // Iterate over the subnets starting from the subnet with index i. for (auto j = 0; j < subnets.size(); ++j) { // Get next subnet (following the one currently in s). - s = networks[0]->getNextSubnet(subnets[i], s); + s = networks[0]->getNextSubnet(subnets[i], s->getID()); // The last iteration should return empty pointer to indicate end of // the subnets within shared network. If we're not at last iteration // check that the subnet identifier of the returned subnet is valid. @@ -426,7 +426,7 @@ TEST(SharedNetwork6Test, getNextSubnet) { // Iterate over the subnets starting from the subnet with index i. for (auto j = 0; j < subnets.size(); ++j) { // Get next subnet (following the one currently in s). - s = networks[0]->getNextSubnet(subnets[i], s); + s = networks[0]->getNextSubnet(subnets[i], s->getID()); // The last iteration should return empty pointer to indicate end of // the subnets within shared network. If we're not at last iteration // check that the subnet identifier of the returned subnet is valid.