// 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;
}
subnet.reset();
} else {
- subnet = network->getNextSubnet(original_subnet, subnet);
+ subnet = subnet->getNextSubnet(original_subnet);
}
}
}
}
}
- 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);
// 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;
}
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();
}
}
template<typename SubnetPtrType, typename SubnetCollectionType>
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()) {
// subnet must exist in this container, thus we throw if the iterator
// is not found.
const auto& index = subnets.template get<SubnetSubnetIdIndexTag>();
- 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");
}
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));
}
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));
}
/// @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.
/// @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.
///
/// @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.
/// @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.
///
#include <asiolink/io_address.h>
#include <dhcp/option_space.h>
#include <dhcpsrv/addr_utilities.h>
+#include <dhcpsrv/shared_network.h>
#include <dhcpsrv/subnet.h>
#include <algorithm>
#include <sstream>
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;
}
}
+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;
typedef boost::shared_ptr<Subnet> SubnetPtr;
+class Subnet4;
+
+/// @brief A const pointer to a @c Subnet4 object.
+typedef boost::shared_ptr<const Subnet4> ConstSubnet4Ptr;
+
+/// @brief A pointer to a @c Subnet4 object.
+typedef boost::shared_ptr<Subnet4> Subnet4Ptr;
+
/// @brief A configuration holder for IPv4 subnet.
///
/// This class represents an IPv4 subnet.
const Triplet<uint32_t>& 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.
///
Cfg4o6 dhcp4o6_;
};
-/// @brief A const pointer to a @c Subnet4 object.
-typedef boost::shared_ptr<const Subnet4> ConstSubnet4Ptr;
+class Subnet6;
-/// @brief A pointer to a @c Subnet4 object.
-typedef boost::shared_ptr<Subnet4> Subnet4Ptr;
+/// @brief A const pointer to a @c Subnet6 object.
+typedef boost::shared_ptr<const Subnet6> ConstSubnet6Ptr;
+/// @brief A pointer to a Subnet6 object
+typedef boost::shared_ptr<Subnet6> Subnet6Ptr;
/// @brief A configuration holder for IPv6 subnet.
///
const Triplet<uint32_t>& 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.
///
};
-/// @brief A const pointer to a @c Subnet6 object.
-typedef boost::shared_ptr<const Subnet6> ConstSubnet6Ptr;
-
-/// @brief A pointer to a Subnet6 object
-typedef boost::shared_ptr<Subnet6> Subnet6Ptr;
-
/// @name Definition of the multi index container holding subnet information
///
//@{
// 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.
// 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.