Browse Source

[5305] Introduced Network4/Network6.

Marcin Siodelski 7 years ago
parent
commit
3f860fb8cf

+ 4 - 1
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

+ 6 - 5
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<typename SharedNetworkPtrType>
+template<typename SharedNetworkPtrType, typename SharedNetworkCollection>
 class CfgSharedNetworks : public data::CfgToElement {
 public:
 
@@ -99,12 +99,12 @@ public:
 protected:
 
     /// @brief Multi index container holding shared networks.
-    SharedNetworkCollection<typename SharedNetworkPtrType::element_type>
-    networks_;
+    SharedNetworkCollection networks_;
 };
 
 /// @brief Represents configuration of IPv4 shared networks.
-class CfgSharedNetworks4 : public CfgSharedNetworks<SharedNetwork4Ptr> {
+class CfgSharedNetworks4 : public CfgSharedNetworks<SharedNetwork4Ptr,
+                                                    SharedNetwork4Collection> {
 public:
 
     /// @brief Returns pointer to all configured shared networks.
@@ -118,7 +118,8 @@ public:
 typedef boost::shared_ptr<CfgSharedNetworks4> CfgSharedNetworks4Ptr;
 
 /// @brief Represents configuration of IPv6 shared networks.
-class CfgSharedNetworks6 : public CfgSharedNetworks<SharedNetwork6Ptr> {
+class CfgSharedNetworks6 : public CfgSharedNetworks<SharedNetwork6Ptr,
+                                                    SharedNetwork6Collection> {
 public:
 
     /// @brief Returns pointer to all configured shared networks.

+ 8 - 0
src/lib/dhcpsrv/network.h

@@ -99,6 +99,14 @@ typedef boost::shared_ptr<Network> NetworkPtr;
 /// @brief Weak pointer to the @ref Network object.
 typedef boost::weak_ptr<Network> WeakNetworkPtr;
 
+class Network4 : public Network {
+public:
+};
+
+class Network6 : public Network {
+public:
+};
+
 } // end of namespace isc::dhcp
 } // end of namespace isc
 

+ 222 - 21
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 <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() {
@@ -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<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) {
@@ -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<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) {

+ 84 - 276
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<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.
@@ -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<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.
@@ -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<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