From: Marcin Siodelski Date: Tue, 5 Sep 2017 09:02:53 +0000 (+0200) Subject: [5305] Introduced Network4/Network6. X-Git-Tag: trac5073a_base~11^2~7 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=3f860fb8cfa44046e49fc81dd2c745d31ac854cb;p=thirdparty%2Fkea.git [5305] Introduced Network4/Network6. --- diff --git a/src/lib/dhcpsrv/assignable_network.h b/src/lib/dhcpsrv/assignable_network.h index 2b64d44ce2..ee1f208b57 100644 --- a/src/lib/dhcpsrv/assignable_network.h +++ b/src/lib/dhcpsrv/assignable_network.h @@ -20,9 +20,12 @@ namespace dhcp { /// private method. Association of a network with a subnet must be always /// conducted using this class. This prevents unwanted replacements of /// shared networks within subnets. -class AssignableNetwork : public Network { +class AssignableNetwork { protected: + /// @brief Virtual destructor. + virtual ~AssignableNetwork() { } + /// @brief Returns shared pointer to this object. /// /// This abstract method must be implemented by derived classes to diff --git a/src/lib/dhcpsrv/cfg_shared_networks.h b/src/lib/dhcpsrv/cfg_shared_networks.h index b3965f6d59..5d954850cd 100644 --- a/src/lib/dhcpsrv/cfg_shared_networks.h +++ b/src/lib/dhcpsrv/cfg_shared_networks.h @@ -29,7 +29,7 @@ namespace dhcp { /// /// @tparam Type of the pointer to a shared network, i.e. @ref SharedNetwork4Ptr /// or @ref SharedNetwork6Ptr. -template +template class CfgSharedNetworks : public data::CfgToElement { public: @@ -99,12 +99,12 @@ public: protected: /// @brief Multi index container holding shared networks. - SharedNetworkCollection - networks_; + SharedNetworkCollection networks_; }; /// @brief Represents configuration of IPv4 shared networks. -class CfgSharedNetworks4 : public CfgSharedNetworks { +class CfgSharedNetworks4 : public CfgSharedNetworks { public: /// @brief Returns pointer to all configured shared networks. @@ -118,7 +118,8 @@ public: typedef boost::shared_ptr CfgSharedNetworks4Ptr; /// @brief Represents configuration of IPv6 shared networks. -class CfgSharedNetworks6 : public CfgSharedNetworks { +class CfgSharedNetworks6 : public CfgSharedNetworks { public: /// @brief Returns pointer to all configured shared networks. diff --git a/src/lib/dhcpsrv/network.h b/src/lib/dhcpsrv/network.h index 3b8beaa63b..99e03e842d 100644 --- a/src/lib/dhcpsrv/network.h +++ b/src/lib/dhcpsrv/network.h @@ -99,6 +99,14 @@ typedef boost::shared_ptr NetworkPtr; /// @brief Weak pointer to the @ref Network object. typedef boost::weak_ptr WeakNetworkPtr; +class Network4 : public Network { +public: +}; + +class Network6 : public Network { +public: +}; + } // end of namespace isc::dhcp } // end of namespace isc diff --git a/src/lib/dhcpsrv/shared_network.cc b/src/lib/dhcpsrv/shared_network.cc index 9f7c9c43ea..17c9442829 100644 --- a/src/lib/dhcpsrv/shared_network.cc +++ b/src/lib/dhcpsrv/shared_network.cc @@ -4,25 +4,211 @@ // 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 #include +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 + 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(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 + static SubnetPtrType del(SubnetCollectionType& subnets, + const SubnetID& subnet_id) { + auto& index = subnets.template get(); + 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 + static SubnetPtrType getSubnet(const SubnetCollectionType& subnets, + const SubnetID& subnet_id) { + const auto& index = subnets.template get(); + 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 + 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(); + 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(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() { @@ -31,29 +217,36 @@ 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(subnets_, subnet_id); + clearSharedNetwork(subnet); } Subnet4Ptr SharedNetwork4::getSubnet(const SubnetID& subnet_id) const { - return (SharedNetwork::getSubnet(subnets_, subnet_id)); + return (Impl::getSubnet(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) { @@ -72,29 +265,37 @@ SharedNetwork6::sharedFromThis() { 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(subnets_, subnet_id); + clearSharedNetwork(subnet); } Subnet6Ptr SharedNetwork6::getSubnet(const SubnetID& subnet_id) const { - return (SharedNetwork::getSubnet(subnets_, subnet_id)); + return (Impl::getSubnet(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) { diff --git a/src/lib/dhcpsrv/shared_network.h b/src/lib/dhcpsrv/shared_network.h index 67fb3705a0..474bbf4d4a 100644 --- a/src/lib/dhcpsrv/shared_network.h +++ b/src/lib/dhcpsrv/shared_network.h @@ -24,288 +24,25 @@ namespace isc { namespace dhcp { -class SharedNetwork; - -/// @brief Pointer to the @ref SharedNetwork object. -typedef boost::shared_ptr 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 - 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(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 - void del(SubnetCollectionType& subnets, const SubnetID& subnet_id) { - auto& index = subnets.template get(); - 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 - SubnetPtrType getSubnet(const SubnetCollectionType& subnets, - const SubnetID& subnet_id) const { - const auto& index = subnets.template get(); - 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 - 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(); - 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(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 -using SharedNetworkCollection = boost::multi_index_container< - // Multi index container holds pointers to the shared networks. - boost::shared_ptr, - 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 - >, - // Second index allows for access by shared network's name. - boost::multi_index::ordered_unique< - boost::multi_index::tag, - boost::multi_index::const_mem_fun - > - > ->; - /// @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 { +/// Specialization of the @ref Network4 class for IPv4 shared networks. +class SharedNetwork4 : public Network4, + public boost::enable_shared_from_this, + 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. @@ -315,6 +52,18 @@ public: /// @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. @@ -371,6 +120,9 @@ public: private: + /// @brief Holds a name of a shared network. + std::string name_; + /// @brief Collection of IPv4 subnets within shared network. Subnet4Collection subnets_; }; @@ -378,21 +130,42 @@ private: /// @brief Pointer to @ref SharedNetwork4 object. typedef boost::shared_ptr SharedNetwork4Ptr; -/// @brief A collection of @ref SharedNetwork4 objects. -typedef SharedNetworkCollection 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 + >, + // Second index allows for access by shared network's name. + boost::multi_index::ordered_unique< + boost::multi_index::tag, + boost::multi_index::const_mem_fun + > + > +> 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 { +/// Specialization of the @ref Network6 class for IPv6 shared networks. +class SharedNetwork6 : public Network6, + public boost::enable_shared_from_this, + 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. @@ -402,6 +175,18 @@ public: /// @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. @@ -458,6 +243,9 @@ public: private: + /// @brief Holds a name of a shared network. + std::string name_; + /// @brief Collection of IPv6 subnets within shared network. Subnet6Collection subnets_; }; @@ -465,8 +253,28 @@ private: /// @brief Pointer to @ref SharedNetwork6 object. typedef boost::shared_ptr SharedNetwork6Ptr; -/// @brief A collection of @ref SharedNetwork6 objects. -typedef SharedNetworkCollection 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 + >, + // Second index allows for access by shared network's name. + boost::multi_index::ordered_unique< + boost::multi_index::tag, + boost::multi_index::const_mem_fun + > + > +> SharedNetwork6Collection; } // end of namespace isc::dhcp } // end of namespace isc