// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#include <exceptions/exceptions.h>
#include <dhcpsrv/shared_network.h>
+using namespace isc;
using namespace isc::data;
using namespace isc::dhcp;
-namespace isc {
-namespace dhcp {
+namespace {
-ElementPtr
-SharedNetwork::toElement() const {
- ElementPtr map = Network::toElement();
+/// @brief Implements common functionality for SharedNetwork4 and
+/// SharedNetwork6 classes.
+///
+/// It provides mechanisms to add, remove and find subnets within shared
+/// networks. It also provides means to walk over the subnets within a
+/// shared network.
+class Impl {
+public:
- // Set shared network name.
- if (!name_.empty()) {
- map->set("name", Element::create(name_));
+ /// @brief Adds a subnet to a shared network.
+ ///
+ /// This is a generic method for adding a new subnet to a shared network.
+ ///
+ /// @param [out] subnets Container holding subnets for this shared network.
+ /// @param subnet Pointer to a subnet being added to this shared network.
+ ///
+ /// @tparam SubnetPtrType Type of a pointer to a subnet, i.e. Subnet4Ptr
+ /// or @ref Subnet6Ptr.
+ /// @tparam SubnetCollectionType Type of a container holding subnets, i.e.
+ /// @ref Subnet4Collection or @ref Subnet6Collection.
+ ///
+ /// @throw isc::BadValue if subnet is null.
+ /// @throw isc::DuplicateSubnetID if a subnet with the given subnet id
+ /// already exists in this shared network.
+ /// @throw InvalidOperation if a subnet is already associated with some
+ /// shared network.
+ template<typename SubnetPtrType, typename SubnetCollectionType>
+ static void add(SubnetCollectionType& subnets, const SubnetPtrType& subnet) {
+ // Subnet must be non-null.
+ if (!subnet) {
+ isc_throw(BadValue, "null pointer specified when adding a subnet"
+ " to a shared network");
+ }
+
+ // Check if a subnet with this id already exists.
+ if (getSubnet<SubnetPtrType>(subnets, subnet->getID())) {
+ isc_throw(DuplicateSubnetID, "attempted to add subnet with a"
+ " duplicated subnet identifier " << subnet->getID());
+ }
+
+ // Check if the subnet is already associated with some network.
+ NetworkPtr network;
+ subnet->getSharedNetwork(network);
+ if (network) {
+ isc_throw(InvalidOperation, "subnet " << subnet->getID()
+ << " being added to a shared network"
+ " already belongs to a shared network");
+ }
+
+ // Add a subnet to the collection of subnets for this shared network.
+ subnets.push_back(subnet);
}
- return (map);
-}
+ /// @brief Removes a subnet from the shared network.
+ ///
+ /// @param [out] subnets Container holding subnets for this shared network.
+ /// @param subnet_id Identifier of a subnet to be removed.
+ ///
+ /// @tparam SubnetCollectionType Type of a container holding subnets, i.e.
+ /// @ref Subnet4Collection or @ref Subnet6Collection.
+ ///
+ /// @return Erased subnet.
+ /// @throw BadValue if a subnet with specified identifier doesn't exist.
+ template<typename SubnetPtrType, typename SubnetCollectionType>
+ static SubnetPtrType del(SubnetCollectionType& subnets,
+ const SubnetID& subnet_id) {
+ auto& index = subnets.template get<SubnetSubnetIdIndexTag>();
+ auto subnet_it = index.find(subnet_id);
+ if (subnet_it == index.end()) {
+ isc_throw(BadValue, "unable to delete subnet " << subnet_id
+ << " from shared network. Subnet doesn't belong"
+ " to this shared network");
+ }
+ auto subnet = *subnet_it;
+ index.erase(subnet_it);
+ return (subnet);
+ }
+
+ /// @brief Returns a subnet belonging to this network for a given subnet id.
+ ///
+ /// @param subnets Container holding subnets for this shared network.
+ /// @param subnet_id Identifier of a subnet being retrieved.
+ ///
+ /// @tparam SubnetPtrType Type of a pointer to a subnet, i.e. Subnet4Ptr
+ /// or @ref Subnet6Ptr.
+ /// @tparam SubnetCollectionType Type of a container holding subnets, i.e.
+ /// @ref Subnet4Collection or @ref Subnet6Collection.
+ ///
+ /// @return Pointer to the subnet or null if the subnet doesn't exist.
+ template<typename SubnetPtrType, typename SubnetCollectionType>
+ static SubnetPtrType getSubnet(const SubnetCollectionType& subnets,
+ const SubnetID& subnet_id) {
+ const auto& index = subnets.template get<SubnetSubnetIdIndexTag>();
+ auto subnet_it = index.find(subnet_id);
+ if (subnet_it != index.cend()) {
+ return (*subnet_it);
+ }
+
+ // Subnet not found.
+ return (SubnetPtrType());
+ }
+
+ /// @brief Retrieves next available subnet within shared network.
+ ///
+ /// This method returns next available subnet within a shared network.
+ /// The subnets are ordered and retrieved using random access index
+ /// (first in/first out). The next subnet means next in turn after
+ /// the current subnet, which is specified as an argument. A caller
+ /// can iterate over all subnets starting from any of the subnets
+ /// belonging to a shared network. This subnet is called here as
+ /// a first subnet and is also specified as a method argument. When the
+ /// method detects that the next available subnet is a first subnet, it
+ /// returns a null pointer to indicate that there are no more subnets
+ /// available.
+ ///
+ /// The typical use case for this method is to allow DHCP server's
+ /// allocation engine to walk over the available subnets within a shared
+ /// network, starting from a subnet that has been selected during the
+ /// "subnet selection" processing step. In some cases the allocation
+ /// engine is unable to allocate resources from a selected subnet due
+ /// to client classification restrictions or address shortage within
+ /// its pools. It then uses this mechanism to move to another subnet
+ /// belonging to the same shared network.
+ ///
+ /// @param subnets Container holding subnets belonging to this shared
+ /// network.
+ /// @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
+ /// to be found.
+ ///
+ /// @tparam SubnetPtrType Type of the pointer to a subnet, i.e.
+ /// @ref Subnet4Ptr or @ref Subnet6Ptr.
+ /// @tparam SubnetCollectionType Type of the container holding subnets, i.e.
+ /// @ref Subnet4Collection or @ref Subnet6Collection.
+ ///
+ /// @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 the container.
+ 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");
+ }
+
+ // 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()) {
+ return (SubnetPtrType());
+ }
+
+ // Need to retrieve an iterator to the current subnet first. The
+ // 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());
+ if (subnet_id_it == index.cend()) {
+ isc_throw(BadValue, "no such subnet " << current_subnet->getID()
+ << " within shared network");
+ }
+
+ // We need to transform this iterator (by subnet id) to a random access
+ // index iterator. Multi index container has a nice way of doing it.
+ auto subnet_it = subnets.template project<SubnetRandomAccessIndexTag>(subnet_id_it);
+
+ // Step to a next subnet within random access index.
+ if (++subnet_it == subnets.cend()) {
+ // If we reached the end of the container, start over from the
+ // beginning.
+ subnet_it = subnets.cbegin();
+ }
+
+ // Check if we have made a full circle. If we did, return a null pointer
+ // to indicate that there are no more subnets.
+ if ((*subnet_it)->getID() == first_subnet->getID()) {
+ return (SubnetPtrType());
+ }
+
+ // Got the next subnet, so return it.
+ return (*subnet_it);
+ }
+};
+
+} // end of anonymous namespace
+
+namespace isc {
+namespace dhcp {
NetworkPtr
SharedNetwork4::sharedFromThis() {
void
SharedNetwork4::add(const Subnet4Ptr& subnet) {
- SharedNetwork::add(subnets_, subnet);
+ Impl::add(subnets_, subnet);
+ // Associate the subnet with this network.
+ setSharedNetwork(subnet);
}
void
SharedNetwork4::del(const SubnetID& subnet_id) {
- SharedNetwork::del(subnets_, subnet_id);
+ Subnet4Ptr subnet = Impl::del<Subnet4Ptr>(subnets_, subnet_id);
+ clearSharedNetwork(subnet);
}
Subnet4Ptr
SharedNetwork4::getSubnet(const SubnetID& subnet_id) const {
- return (SharedNetwork::getSubnet<Subnet4Ptr>(subnets_, subnet_id));
+ return (Impl::getSubnet<Subnet4Ptr>(subnets_, subnet_id));
}
Subnet4Ptr
SharedNetwork4::getNextSubnet(const Subnet4Ptr& first_subnet,
const Subnet4Ptr& current_subnet) const {
- return (SharedNetwork::getNextSubnet(subnets_, first_subnet,
- current_subnet));
+ return (Impl::getNextSubnet(subnets_, first_subnet, current_subnet));
}
ElementPtr
SharedNetwork4::toElement() const {
- ElementPtr map = SharedNetwork::toElement();
+ ElementPtr map = Network::toElement();
+
+ // Set shared network name.
+ if (!name_.empty()) {
+ map->set("name", Element::create(name_));
+ }
ElementPtr subnet4 = Element::createList();
for (auto subnet = subnets_.cbegin(); subnet != subnets_.cend(); ++subnet) {
void
SharedNetwork6::add(const Subnet6Ptr& subnet) {
- SharedNetwork::add(subnets_, subnet);
+ Impl::add(subnets_, subnet);
+ // Associate the subnet with this network.
+ setSharedNetwork(subnet);
}
void
SharedNetwork6::del(const SubnetID& subnet_id) {
- SharedNetwork::del(subnets_, subnet_id);
+ Subnet6Ptr subnet = Impl::del<Subnet6Ptr>(subnets_, subnet_id);
+ clearSharedNetwork(subnet);
}
Subnet6Ptr
SharedNetwork6::getSubnet(const SubnetID& subnet_id) const {
- return (SharedNetwork::getSubnet<Subnet6Ptr>(subnets_, subnet_id));
+ return (Impl::getSubnet<Subnet6Ptr>(subnets_, subnet_id));
}
Subnet6Ptr
SharedNetwork6::getNextSubnet(const Subnet6Ptr& first_subnet,
const Subnet6Ptr& current_subnet) const {
- return (SharedNetwork::getNextSubnet(subnets_, first_subnet,
+ return (Impl::getNextSubnet(subnets_, first_subnet,
current_subnet));
}
ElementPtr
SharedNetwork6::toElement() const {
- ElementPtr map = SharedNetwork::toElement();
+ ElementPtr map = Network::toElement();
+
+ // Set shared network name.
+ if (!name_.empty()) {
+ map->set("name", Element::create(name_));
+ }
ElementPtr subnet6 = Element::createList();
for (auto subnet = subnets_.cbegin(); subnet != subnets_.cend(); ++subnet) {
namespace isc {
namespace dhcp {
-class SharedNetwork;
-
-/// @brief Pointer to the @ref SharedNetwork object.
-typedef boost::shared_ptr<SharedNetwork> SharedNetworkPtr;
-
-/// @brief Represents shared network, which groups multiple subnets.
-///
-/// Shared networks provide means for grouping multiple subnets together.
-/// There are two major use cases for such grouping:
-///
-/// - Extending available address pools to be allocated for clients on
-/// a particular link without a need to renumber.
-/// - Fulfill requirement in cable networks whereby two classes of devices
-/// are connected on the same link: cable modems and routers. Such devices
-/// must be assign addresses/prefixes from different pools based on client
-/// classification.
-///
-/// Shared networks provide similar interface like subnets, thus they both
-/// derive from the @ref Network class.
-class SharedNetwork : public AssignableNetwork {
-protected:
-
- /// @brief Constructor.
- ///
- /// Sets name of the shared network.
- explicit SharedNetwork(const std::string& name)
- : name_(name) {
- }
-
-public:
-
- /// @brief Returns a name of the shared network.
- std::string getName() const {
- return (name_);
- }
-
- /// @brief Sets new name for the shared network.
- ///
- /// @param name New name for the shared network.
- void setName(const std::string& name) {
- name_ = name;
- }
-
-protected:
-
- /// @brief Adds a subnet to a shared network.
- ///
- /// This is a generic method for adding a new subnet to a shared network.
- ///
- /// @param [out] subnets Container holding subnets for this shared network.
- /// @param subnet Pointer to a subnet being added to this shared network.
- ///
- /// @tparam SubnetPtrType Type of a pointer to a subnet, i.e. Subnet4Ptr
- /// or @ref Subnet6Ptr.
- /// @tparam SubnetCollectionType Type of a container holding subnets, i.e.
- /// @ref Subnet4Collection or @ref Subnet6Collection.
- ///
- /// @throw isc::BadValue if subnet is null.
- /// @throw isc::DuplicateSubnetID if a subnet with the given subnet id
- /// already exists in this shared network.
- /// @throw InvalidOperation if a subnet is already associated with some
- /// shared network.
- template<typename SubnetPtrType, typename SubnetCollectionType>
- void add(SubnetCollectionType& subnets, const SubnetPtrType& subnet) {
- // Subnet must be non-null.
- if (!subnet) {
- isc_throw(BadValue, "null pointer specified when adding a subnet"
- " to a shared network");
- }
-
- // Check if a subnet with this id already exists.
- if (getSubnet<SubnetPtrType>(subnets, subnet->getID())) {
- isc_throw(DuplicateSubnetID, "attempted to add subnet with a"
- " duplicated subnet identifier " << subnet->getID());
- }
-
- // Check if the subnet is already associated with some network.
- SharedNetworkPtr network;
- subnet->getSharedNetwork(network);
- if (network) {
- isc_throw(InvalidOperation, "subnet " << subnet->getID()
- << " being added to a shared network"
- " already belongs to a shared network");
- }
-
- // Add a subnet to the collection of subnets for this shared network.
- subnets.push_back(subnet);
- // Associate the subnet with this network.
- setSharedNetwork(subnet);
- }
-
- /// @brief Removes a subnet from the shared network.
- ///
- /// @param [out] subnets Container holding subnets for this shared network.
- /// @param subnet_id Identifier of a subnet to be removed.
- ///
- /// @tparam SubnetCollectionType Type of a container holding subnets, i.e.
- /// @ref Subnet4Collection or @ref Subnet6Collection.
- ///
- /// @throw BadValue if a subnet with specified identifier doesn't exist.
- template<typename SubnetCollectionType>
- void del(SubnetCollectionType& subnets, const SubnetID& subnet_id) {
- auto& index = subnets.template get<SubnetSubnetIdIndexTag>();
- auto subnet_it = index.find(subnet_id);
- if (subnet_it == index.end()) {
- isc_throw(BadValue, "unable to delete subnet " << subnet_id
- << " from shared network. Subnet doesn't belong"
- " to this shared network");
- }
- auto subnet = *subnet_it;
- index.erase(subnet_it);
- clearSharedNetwork(subnet);
- }
-
- /// @brief Returns a subnet belonging to this network for a given subnet id.
- ///
- /// @param subnets Container holding subnets for this shared network.
- /// @param subnet_id Identifier of a subnet being retrieved.
- ///
- /// @tparam SubnetPtrType Type of a pointer to a subnet, i.e. Subnet4Ptr
- /// or @ref Subnet6Ptr.
- /// @tparam SubnetCollectionType Type of a container holding subnets, i.e.
- /// @ref Subnet4Collection or @ref Subnet6Collection.
- ///
- /// @return Pointer to the subnet or null if the subnet doesn't exist.
- template<typename SubnetPtrType, typename SubnetCollectionType>
- SubnetPtrType getSubnet(const SubnetCollectionType& subnets,
- const SubnetID& subnet_id) const {
- const auto& index = subnets.template get<SubnetSubnetIdIndexTag>();
- auto subnet_it = index.find(subnet_id);
- if (subnet_it != index.cend()) {
- return (*subnet_it);
- }
-
- // Subnet not found.
- return (SubnetPtrType());
- }
-
- /// @brief Retrieves next available subnet within shared network.
- ///
- /// This method returns next available subnet within a shared network.
- /// The subnets are ordered and retrieved using random access index
- /// (first in/first out). The next subnet means next in turn after
- /// the current subnet, which is specified as an argument. A caller
- /// can iterate over all subnets starting from any of the subnets
- /// belonging to a shared network. This subnet is called here as
- /// a first subnet and is also specified as a method argument. When the
- /// method detects that the next available subnet is a first subnet, it
- /// returns a null pointer to indicate that there are no more subnets
- /// available.
- ///
- /// The typical use case for this method is to allow DHCP server's
- /// allocation engine to walk over the available subnets within a shared
- /// network, starting from a subnet that has been selected during the
- /// "subnet selection" processing step. In some cases the allocation
- /// engine is unable to allocate resources from a selected subnet due
- /// to client classification restrictions or address shortage within
- /// its pools. It then uses this mechanism to move to another subnet
- /// belonging to the same shared network.
- ///
- /// @param subnets Container holding subnets belonging to this shared
- /// network.
- /// @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
- /// to be found.
- ///
- /// @tparam SubnetPtrType Type of the pointer to a subnet, i.e.
- /// @ref Subnet4Ptr or @ref Subnet6Ptr.
- /// @tparam SubnetCollectionType Type of the container holding subnets, i.e.
- /// @ref Subnet4Collection or @ref Subnet6Collection.
- ///
- /// @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 the container.
- template<typename SubnetPtrType, typename SubnetCollectionType>
- SubnetPtrType getNextSubnet(const SubnetCollectionType& subnets,
- const SubnetPtrType& first_subnet,
- const SubnetPtrType& current_subnet) const {
- // 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");
- }
-
- // 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()) {
- return (SubnetPtrType());
- }
-
- // Need to retrieve an iterator to the current subnet first. The
- // 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());
- if (subnet_id_it == index.cend()) {
- isc_throw(BadValue, "no such subnet " << current_subnet->getID()
- << " within shared network");
- }
-
- // We need to transform this iterator (by subnet id) to a random access
- // index iterator. Multi index container has a nice way of doing it.
- auto subnet_it = subnets.template project<SubnetRandomAccessIndexTag>(subnet_id_it);
-
- // Step to a next subnet within random access index.
- if (++subnet_it == subnets.cend()) {
- // If we reached the end of the container, start over from the
- // beginning.
- subnet_it = subnets.cbegin();
- }
-
- // Check if we have made a full circle. If we did, return a null pointer
- // to indicate that there are no more subnets.
- if ((*subnet_it)->getID() == first_subnet->getID()) {
- return (SubnetPtrType());
- }
-
- // Got the next subnet, so return it.
- return (*subnet_it);
- }
-
- /// @brief Unparses shared network object.
- ///
- /// @return A pointer to unparsed shared network configuration.
- virtual data::ElementPtr toElement() const;
-
- /// @brief Holds a name of a shared network.
- std::string name_;
-
-};
-
/// @brief A tag for accessing random access index.
struct SharedNetworkRandomAccessIndexTag { };
/// @brief A tag for accessing index by shared network name.
struct SharedNetworkNameIndexTag { };
-/// @brief Multi index container holding shared networks.
-///
-/// This is multi index container can hold pointers to @ref SharedNetwork4
-/// or @ref SharedNetwork6 objects. It provides indexes for shared network
-/// lookups using properties such as shared network's name.
-///
-/// @tparam SharedNetworkType Type of the shared network: @ref SharedNetwork4
-/// or @ref SharedNetwork6.
-template<typename SharedNetworkType>
-using SharedNetworkCollection = boost::multi_index_container<
- // Multi index container holds pointers to the shared networks.
- boost::shared_ptr<SharedNetworkType>,
- boost::multi_index::indexed_by<
- // First is the random access index allowing for accessing objects
- // just like we'd do with vector.
- boost::multi_index::random_access<
- boost::multi_index::tag<SharedNetworkRandomAccessIndexTag>
- >,
- // Second index allows for access by shared network's name.
- boost::multi_index::ordered_unique<
- boost::multi_index::tag<SharedNetworkNameIndexTag>,
- boost::multi_index::const_mem_fun<SharedNetwork, std::string,
- &SharedNetwork::getName>
- >
- >
->;
-
/// @brief Shared network holding IPv4 subnets.
///
-/// Specialization of the @ref SharedNetwork class for IPv4 subnets.
-class SharedNetwork4 : public SharedNetwork,
- public boost::enable_shared_from_this<SharedNetwork4> {
+/// Specialization of the @ref Network4 class for IPv4 shared networks.
+class SharedNetwork4 : public Network4,
+ public boost::enable_shared_from_this<SharedNetwork4>,
+ public AssignableNetwork {
public:
/// @brief Constructor.
///
/// Sets name of the shared network.
explicit SharedNetwork4(const std::string& name)
- : SharedNetwork(name) {
+ : name_(name), subnets_() {
}
/// @brief Returns shared pointer to this network.
/// @return Shared pointer to this object.
virtual NetworkPtr sharedFromThis();
+ /// @brief Returns a name of the shared network.
+ std::string getName() const {
+ return (name_);
+ }
+
+ /// @brief Sets new name for the shared network.
+ ///
+ /// @param name New name for the shared network.
+ void setName(const std::string& name) {
+ name_ = name;
+ }
+
/// @brief Adds IPv4 subnet to a shared network.
///
/// @param subnet Pointer to a subnet being added to this shared network.
private:
+ /// @brief Holds a name of a shared network.
+ std::string name_;
+
/// @brief Collection of IPv4 subnets within shared network.
Subnet4Collection subnets_;
};
/// @brief Pointer to @ref SharedNetwork4 object.
typedef boost::shared_ptr<SharedNetwork4> SharedNetwork4Ptr;
-/// @brief A collection of @ref SharedNetwork4 objects.
-typedef SharedNetworkCollection<SharedNetwork4> SharedNetwork4Collection;
+/// @brief Multi index container holding shared networks.
+///
+/// This is multi index container can hold pointers to @ref SharedNetwork4
+/// objects. It provides indexes for shared network lookups using properties
+/// such as shared network's name.
+typedef boost::multi_index_container<
+ // Multi index container holds pointers to the shared networks.
+ SharedNetwork4Ptr,
+ boost::multi_index::indexed_by<
+ // First is the random access index allowing for accessing objects
+ // just like we'd do with vector.
+ boost::multi_index::random_access<
+ boost::multi_index::tag<SharedNetworkRandomAccessIndexTag>
+ >,
+ // Second index allows for access by shared network's name.
+ boost::multi_index::ordered_unique<
+ boost::multi_index::tag<SharedNetworkNameIndexTag>,
+ boost::multi_index::const_mem_fun<SharedNetwork4, std::string,
+ &SharedNetwork4::getName>
+ >
+ >
+> SharedNetwork4Collection;
/// @brief Shared network holding IPv6 subnets.
///
-/// Specialization of the @ref SharedNetwork class for IPv6 subnets.
-class SharedNetwork6 : public SharedNetwork,
- public boost::enable_shared_from_this<SharedNetwork6> {
+/// Specialization of the @ref Network6 class for IPv6 shared networks.
+class SharedNetwork6 : public Network6,
+ public boost::enable_shared_from_this<SharedNetwork6>,
+ public AssignableNetwork {
public:
/// @brief Constructor.
///
/// Sets name of the shared network.
explicit SharedNetwork6(const std::string& name)
- : SharedNetwork(name) {
+ : name_(name), subnets_() {
}
/// @brief Returns shared pointer to this network.
/// @return Shared pointer to this object.
virtual NetworkPtr sharedFromThis();
+ /// @brief Returns a name of the shared network.
+ std::string getName() const {
+ return (name_);
+ }
+
+ /// @brief Sets new name for the shared network.
+ ///
+ /// @param name New name for the shared network.
+ void setName(const std::string& name) {
+ name_ = name;
+ }
+
/// @brief Adds IPv6 subnet to a shared network.
///
/// @param subnet Pointer to a subnet being added to this shared network.
private:
+ /// @brief Holds a name of a shared network.
+ std::string name_;
+
/// @brief Collection of IPv6 subnets within shared network.
Subnet6Collection subnets_;
};
/// @brief Pointer to @ref SharedNetwork6 object.
typedef boost::shared_ptr<SharedNetwork6> SharedNetwork6Ptr;
-/// @brief A collection of @ref SharedNetwork6 objects.
-typedef SharedNetworkCollection<SharedNetwork6> SharedNetwork6Collection;
+/// @brief Multi index container holding shared networks.
+///
+/// This is multi index container can hold pointers to @ref SharedNetwork6
+/// objects. It provides indexes for shared network lookups using properties
+/// such as shared network's name.
+typedef boost::multi_index_container<
+ // Multi index container holds pointers to the shared networks.
+ SharedNetwork6Ptr,
+ boost::multi_index::indexed_by<
+ // First is the random access index allowing for accessing objects
+ // just like we'd do with vector.
+ boost::multi_index::random_access<
+ boost::multi_index::tag<SharedNetworkRandomAccessIndexTag>
+ >,
+ // Second index allows for access by shared network's name.
+ boost::multi_index::ordered_unique<
+ boost::multi_index::tag<SharedNetworkNameIndexTag>,
+ boost::multi_index::const_mem_fun<SharedNetwork6, std::string,
+ &SharedNetwork6::getName>
+ >
+ >
+> SharedNetwork6Collection;
} // end of namespace isc::dhcp
} // end of namespace isc