]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#2815] Add a new parameter to HostMgr
authorSlawek Figiel <slawek@isc.org>
Fri, 31 Mar 2023 17:10:36 +0000 (19:10 +0200)
committerSlawek Figiel <slawek@isc.org>
Thu, 25 May 2023 11:29:28 +0000 (13:29 +0200)
src/lib/dhcpsrv/host_mgr.cc
src/lib/dhcpsrv/host_mgr.h

index 6282caf33299c81d1bed35a23a7d0b3c2f760479..55f077c1e32c1fb941f3c73a7edf65f1bb325a4b 100644 (file)
 
 namespace {
 
+/// @brief Convenience function returning a pointer to the hosts configuration
+/// for editing.
+///
+/// This function is called by the @c HostMgr methods requiring access to the
+/// host reservations specified in the DHCP server configuration.
+///
+/// @return A pointer to the non-const hosts reservation configuration.
+isc::dhcp::CfgHostsPtr getCfgHostsForEdit() {
+    return (isc::dhcp::CfgMgr::instance().getCurrentCfg()->getCfgHosts());
+}
+
 /// @brief Convenience function returning a pointer to the hosts configuration.
 ///
 /// This function is called by the @c HostMgr methods requiring access to the
@@ -20,7 +31,7 @@ namespace {
 ///
 /// @return A pointer to the const hosts reservation configuration.
 isc::dhcp::ConstCfgHostsPtr getCfgHosts() {
-    return (isc::dhcp::CfgMgr::instance().getCurrentCfg()->getCfgHosts());
+    return (getCfgHostsForEdit());
 }
 
 } // end of anonymous namespace
@@ -113,71 +124,102 @@ HostMgr::instance() {
 ConstHostCollection
 HostMgr::getAll(const Host::IdentifierType& identifier_type,
                 const uint8_t* identifier_begin,
-                const size_t identifier_len) const {
-    ConstHostCollection hosts = getCfgHosts()->getAll(identifier_type,
-                                                      identifier_begin,
-                                                      identifier_len);
-    for (auto source : alternate_sources_) {
-        ConstHostCollection hosts_plus =
-            source->getAll(identifier_type, identifier_begin, identifier_len);
-        hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
+                const size_t identifier_len,
+                const HostMgrOperationTarget target) const {
+    ConstHostCollection hosts;
+    if (target & HostMgrOperationTarget::PRIMARY_SOURCE) {
+        hosts = getCfgHosts()->getAll(identifier_type,
+                                                        identifier_begin,
+                                                        identifier_len);
+    }
+    if (target & HostMgrOperationTarget::ALTERNATE_SOURCES) {
+        for (auto source : alternate_sources_) {
+            ConstHostCollection hosts_plus =
+                source->getAll(identifier_type, identifier_begin, identifier_len);
+            hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
+        }
     }
     return (hosts);
 }
 
 ConstHostCollection
-HostMgr::getAll4(const SubnetID& subnet_id) const {
-    ConstHostCollection hosts = getCfgHosts()->getAll4(subnet_id);
-    for (auto source : alternate_sources_) {
-        ConstHostCollection hosts_plus = source->getAll4(subnet_id);
-        hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
+HostMgr::getAll4(const SubnetID& subnet_id, const HostMgrOperationTarget target) const {
+    ConstHostCollection hosts;
+    if (target & HostMgrOperationTarget::PRIMARY_SOURCE) {
+        hosts = getCfgHosts()->getAll4(subnet_id);
+    }
+    if (target & HostMgrOperationTarget::ALTERNATE_SOURCES) {
+        for (auto source : alternate_sources_) {
+            ConstHostCollection hosts_plus = source->getAll4(subnet_id);
+            hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
+        }
     }
     return (hosts);
 }
 
 
 ConstHostCollection
-HostMgr::getAll6(const SubnetID& subnet_id) const {
-    ConstHostCollection hosts = getCfgHosts()->getAll6(subnet_id);
-    for (auto source : alternate_sources_) {
-        ConstHostCollection hosts_plus = source->getAll6(subnet_id);
-        hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
+HostMgr::getAll6(const SubnetID& subnet_id, const HostMgrOperationTarget target) const {
+    ConstHostCollection hosts;
+    if (target & HostMgrOperationTarget::PRIMARY_SOURCE) {
+        hosts = getCfgHosts()->getAll6(subnet_id);
+    }
+    if (target & HostMgrOperationTarget::ALTERNATE_SOURCES) {
+        for (auto source : alternate_sources_) {
+            ConstHostCollection hosts_plus = source->getAll6(subnet_id);
+            hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
+        }
     }
     return (hosts);
 }
 
 ConstHostCollection
-HostMgr::getAllbyHostname(const std::string& hostname) const {
-    ConstHostCollection hosts = getCfgHosts()->getAllbyHostname(hostname);
-    for (auto source : alternate_sources_) {
-        ConstHostCollection hosts_plus = source->getAllbyHostname(hostname);
-        hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
+HostMgr::getAllbyHostname(const std::string& hostname, const HostMgrOperationTarget target) const {
+    ConstHostCollection hosts;
+    if (target & HostMgrOperationTarget::PRIMARY_SOURCE) {
+        hosts = getCfgHosts()->getAllbyHostname(hostname);
+    }
+    if (target & HostMgrOperationTarget::ALTERNATE_SOURCES) {
+        for (auto source : alternate_sources_) {
+            ConstHostCollection hosts_plus = source->getAllbyHostname(hostname);
+            hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
+        }
     }
     return (hosts);
 }
 
 ConstHostCollection
 HostMgr::getAllbyHostname4(const std::string& hostname,
-                           const SubnetID& subnet_id) const {
-    ConstHostCollection hosts = getCfgHosts()->getAllbyHostname4(hostname,
-                                                                 subnet_id);
-    for (auto source : alternate_sources_) {
-        ConstHostCollection hosts_plus = source->getAllbyHostname4(hostname,
-                                                                   subnet_id);
-        hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
+                           const SubnetID& subnet_id,
+                           const HostMgrOperationTarget target) const {
+    ConstHostCollection hosts;
+    if (target & HostMgrOperationTarget::PRIMARY_SOURCE) {
+        hosts = getCfgHosts()->getAllbyHostname4(hostname, subnet_id);
+    }
+    if (target & HostMgrOperationTarget::ALTERNATE_SOURCES) {
+        for (auto source : alternate_sources_) {
+            ConstHostCollection hosts_plus = source->getAllbyHostname4(hostname,
+                                                                    subnet_id);
+            hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
+        }
     }
     return (hosts);
 }
 
 ConstHostCollection
 HostMgr::getAllbyHostname6(const std::string& hostname,
-                           const SubnetID& subnet_id) const {
-    ConstHostCollection hosts = getCfgHosts()->getAllbyHostname6(hostname,
-                                                                 subnet_id);
-    for (auto source : alternate_sources_) {
-        ConstHostCollection hosts_plus = source->getAllbyHostname6(hostname,
-                                                                   subnet_id);
-        hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
+                           const SubnetID& subnet_id,
+                           const HostMgrOperationTarget target) const {
+    ConstHostCollection hosts;
+    if (target & HostMgrOperationTarget::PRIMARY_SOURCE) {
+        hosts = getCfgHosts()->getAllbyHostname6(hostname, subnet_id);
+    }
+    if (target & HostMgrOperationTarget::ALTERNATE_SOURCES) {
+        for (auto source : alternate_sources_) {
+            ConstHostCollection hosts_plus = source->getAllbyHostname6(hostname,
+                                                                    subnet_id);
+            hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
+        }
     }
     return (hosts);
 }
@@ -305,11 +347,16 @@ HostMgr::getPage6(size_t& source_index,
 }
 
 ConstHostCollection
-HostMgr::getAll4(const IOAddress& address) const {
-    ConstHostCollection hosts = getCfgHosts()->getAll4(address);
-    for (auto source : alternate_sources_) {
-        ConstHostCollection hosts_plus = source->getAll4(address);
-        hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
+HostMgr::getAll4(const IOAddress& address, const HostMgrOperationTarget target) const {
+    ConstHostCollection hosts;
+    if (target & HostMgrOperationTarget::PRIMARY_SOURCE) {
+        hosts = getCfgHosts()->getAll4(address);
+    }
+    if (target & HostMgrOperationTarget::ALTERNATE_SOURCES) {
+        for (auto source : alternate_sources_) {
+            ConstHostCollection hosts_plus = source->getAll4(address);
+            hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
+        }
     }
     return (hosts);
 }
@@ -318,13 +365,18 @@ ConstHostPtr
 HostMgr::get4Any(const SubnetID& subnet_id,
                  const Host::IdentifierType& identifier_type,
                  const uint8_t* identifier_begin,
-                 const size_t identifier_len) const {
-    ConstHostPtr host = getCfgHosts()->get4(subnet_id, identifier_type,
-                                            identifier_begin, identifier_len);
+                 const size_t identifier_len,
+                 const HostMgrOperationTarget target) const {
+    ConstHostPtr host;
+    if (target & HostMgrOperationTarget::PRIMARY_SOURCE) {
+        host = getCfgHosts()->get4(subnet_id, identifier_type,
+                                   identifier_begin, identifier_len);
+    }
 
-    // Found it in the config file or there are no backends configured?
+    // Found it in the config file, there are no backends configured, or
+    // querying them is disabled?
     // Then we're done here.
-    if (host || alternate_sources_.empty()) {
+    if (host || alternate_sources_.empty() || !(target & HostMgrOperationTarget::ALTERNATE_SOURCES)) {
         return (host);
     }
 
@@ -368,9 +420,10 @@ ConstHostPtr
 HostMgr::get4(const SubnetID& subnet_id,
               const Host::IdentifierType& identifier_type,
               const uint8_t* identifier_begin,
-              const size_t identifier_len) const {
+              const size_t identifier_len,
+              const HostMgrOperationTarget target) const {
     ConstHostPtr host = get4Any(subnet_id, identifier_type,
-                                identifier_begin, identifier_len);
+                                identifier_begin, identifier_len, target);
     if (host && host->getNegative()) {
         return (ConstHostPtr());
     } else if (!host && negative_caching_) {
@@ -382,9 +435,14 @@ HostMgr::get4(const SubnetID& subnet_id,
 
 ConstHostPtr
 HostMgr::get4(const SubnetID& subnet_id,
-              const asiolink::IOAddress& address) const {
-    ConstHostPtr host = getCfgHosts()->get4(subnet_id, address);
-    if (host || alternate_sources_.empty()) {
+              const asiolink::IOAddress& address,
+              const HostMgrOperationTarget target) const {
+    ConstHostPtr host;
+    if (target & HostMgrOperationTarget::PRIMARY_SOURCE) {
+        host = getCfgHosts()->get4(subnet_id, address);
+    }
+
+    if (host || alternate_sources_.empty() || !(target & HostMgrOperationTarget::ALTERNATE_SOURCES)) {
         return (host);
     }
     LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE,
@@ -408,25 +466,35 @@ HostMgr::get4(const SubnetID& subnet_id,
 
 ConstHostCollection
 HostMgr::getAll4(const SubnetID& subnet_id,
-                 const asiolink::IOAddress& address) const {
-    auto hosts = getCfgHosts()->getAll4(subnet_id, address);
+                 const asiolink::IOAddress& address,
+                 const HostMgrOperationTarget target) const {
+    ConstHostCollection hosts;
+    if (target & HostMgrOperationTarget::PRIMARY_SOURCE) {
+        hosts = getCfgHosts()->getAll4(subnet_id, address);
+    }
 
-    LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE,
-              HOSTS_MGR_ALTERNATE_GET_ALL_SUBNET_ID_ADDRESS4)
-        .arg(subnet_id)
-        .arg(address.toText());
+    if (target & HostMgrOperationTarget::ALTERNATE_SOURCES) {
+        LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE,
+                HOSTS_MGR_ALTERNATE_GET_ALL_SUBNET_ID_ADDRESS4)
+            .arg(subnet_id)
+            .arg(address.toText());
 
-    for (auto source : alternate_sources_) {
-        auto hosts_plus = source->getAll4(subnet_id, address);
-        hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
+        for (auto source : alternate_sources_) {
+            auto hosts_plus = source->getAll4(subnet_id, address);
+            hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
+        }
     }
     return (hosts);
 }
 
 ConstHostPtr
-HostMgr::get6(const IOAddress& prefix, const uint8_t prefix_len) const {
-    ConstHostPtr host = getCfgHosts()->get6(prefix, prefix_len);
-    if (host || alternate_sources_.empty()) {
+HostMgr::get6(const IOAddress& prefix, const uint8_t prefix_len,
+              const HostMgrOperationTarget target) const {
+    ConstHostPtr host;
+    if (target & HostMgrOperationTarget::PRIMARY_SOURCE) {
+        host = getCfgHosts()->get6(prefix, prefix_len);
+    }
+    if (host || alternate_sources_.empty() || !(target & HostMgrOperationTarget::ALTERNATE_SOURCES)) {
         return (host);
     }
     LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE, HOSTS_MGR_ALTERNATE_GET6_PREFIX)
@@ -451,10 +519,14 @@ ConstHostPtr
 HostMgr::get6Any(const SubnetID& subnet_id,
                  const Host::IdentifierType& identifier_type,
                  const uint8_t* identifier_begin,
-                 const size_t identifier_len) const {
-    ConstHostPtr host = getCfgHosts()->get6(subnet_id, identifier_type,
-                                            identifier_begin, identifier_len);
-    if (host || alternate_sources_.empty()) {
+                 const size_t identifier_len,
+                 const HostMgrOperationTarget target) const {
+    ConstHostPtr host;
+    if (target & HostMgrOperationTarget::PRIMARY_SOURCE) {
+        host = getCfgHosts()->get6(subnet_id, identifier_type,
+                                   identifier_begin, identifier_len);
+    }
+    if (host || alternate_sources_.empty() || !(target & HostMgrOperationTarget::ALTERNATE_SOURCES)) {
         return (host);
     }
 
@@ -498,9 +570,10 @@ ConstHostPtr
 HostMgr::get6(const SubnetID& subnet_id,
               const Host::IdentifierType& identifier_type,
               const uint8_t* identifier_begin,
-              const size_t identifier_len) const {
+              const size_t identifier_len,
+              const HostMgrOperationTarget target) const {
     ConstHostPtr host = get6Any(subnet_id, identifier_type,
-                                identifier_begin, identifier_len);
+                                identifier_begin, identifier_len, target);
     if (host && host->getNegative()) {
         return (ConstHostPtr());
     } else if (!host && negative_caching_) {
@@ -512,9 +585,13 @@ HostMgr::get6(const SubnetID& subnet_id,
 
 ConstHostPtr
 HostMgr::get6(const SubnetID& subnet_id,
-              const asiolink::IOAddress& addr) const {
-    ConstHostPtr host = getCfgHosts()->get6(subnet_id, addr);
-    if (host || alternate_sources_.empty()) {
+              const asiolink::IOAddress& addr,
+              const HostMgrOperationTarget target) const {
+    ConstHostPtr host;
+    if (target & HostMgrOperationTarget::PRIMARY_SOURCE) {
+        host = getCfgHosts()->get6(subnet_id, addr);
+    }
+    if (host || alternate_sources_.empty() || !(target & HostMgrOperationTarget::ALTERNATE_SOURCES)) {
         return (host);
     }
     LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE,
@@ -538,30 +615,47 @@ HostMgr::get6(const SubnetID& subnet_id,
 
 ConstHostCollection
 HostMgr::getAll6(const SubnetID& subnet_id,
-                 const asiolink::IOAddress& address) const {
-    auto hosts = getCfgHosts()->getAll6(subnet_id, address);
+                 const asiolink::IOAddress& address,
+                 const HostMgrOperationTarget target) const {
+    ConstHostCollection hosts;
 
-    LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE,
-              HOSTS_MGR_ALTERNATE_GET_ALL_SUBNET_ID_ADDRESS6)
-        .arg(subnet_id)
-        .arg(address.toText());
+    if (target & HostMgrOperationTarget::PRIMARY_SOURCE) {
+        hosts = getCfgHosts()->getAll6(subnet_id, address);
+    }
 
-    for (auto source : alternate_sources_) {
-        auto hosts_plus = source->getAll6(subnet_id, address);
-        hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
+    if (target & HostMgrOperationTarget::ALTERNATE_SOURCES) {
+        LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE,
+                HOSTS_MGR_ALTERNATE_GET_ALL_SUBNET_ID_ADDRESS6)
+            .arg(subnet_id)
+            .arg(address.toText());
+
+        for (auto source : alternate_sources_) {
+            auto hosts_plus = source->getAll6(subnet_id, address);
+            hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
+        }
     }
     return (hosts);
 }
 
 void
-HostMgr::add(const HostPtr& host) {
-    if (alternate_sources_.empty()) {
-        isc_throw(NoHostDataSourceManager, "Unable to add new host because there is "
-                  "no hosts-database configured.");
+HostMgr::add(const HostPtr& host, const HostMgrOperationTarget target) {
+    if (target & HostMgrOperationTarget::PRIMARY_SOURCE) {
+        getCfgHostsForEdit()->add(host);
     }
-    for (auto source : alternate_sources_) {
-        source->add(host);
+
+    if (target & HostMgrOperationTarget::ALTERNATE_SOURCES) {
+        // Don't throw if all targets were selected.
+        if (alternate_sources_.empty() && !(target & HostMgrOperationTarget::ALL_SOURCES)) {
+            isc_throw(NoHostDataSourceManager, "Unable to add new host because there is "
+                    "no hosts-database configured.");
+            
+        }
+
+        for (auto source : alternate_sources_) {
+            source->add(host);
+        }
     }
+
     // If no backend throws the host should be cached.
     if (cache_ptr_) {
         cache(host);
@@ -569,32 +663,54 @@ HostMgr::add(const HostPtr& host) {
 }
 
 bool
-HostMgr::del(const SubnetID& subnet_id, const asiolink::IOAddress& addr) {
-    if (alternate_sources_.empty()) {
-        isc_throw(NoHostDataSourceManager, "Unable to delete a host because there is "
-                  "no hosts-database configured.");
+HostMgr::del(const SubnetID& subnet_id, const asiolink::IOAddress& addr,
+             const HostMgrOperationTarget target) {
+    if (target & HostMgrOperationTarget::PRIMARY_SOURCE) {
+        if (getCfgHostsForEdit()->del(subnet_id, addr)) {
+            return (true);
+        }
     }
 
-    for (auto source : alternate_sources_) {
-        if (source->del(subnet_id, addr)) {
-            return (true);
+    if (target & HostMgrOperationTarget::ALTERNATE_SOURCES) {
+        // Don't throw if all targets were selected.
+        if (alternate_sources_.empty() && !(target & HostMgrOperationTarget::ALL_SOURCES)) {
+            isc_throw(NoHostDataSourceManager, "Unable to delete a host because there is "
+                    "no hosts-database configured.");
+        }
+
+        for (auto source : alternate_sources_) {
+            if (source->del(subnet_id, addr)) {
+                return (true);
+            }
         }
     }
+
     return (false);
 }
 
 bool
 HostMgr::del4(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
-              const uint8_t* identifier_begin, const size_t identifier_len) {
-    if (alternate_sources_.empty()) {
-        isc_throw(NoHostDataSourceManager, "Unable to delete a host because there is "
-                  "no hosts-database configured.");
+              const uint8_t* identifier_begin, const size_t identifier_len,
+              const HostMgrOperationTarget target) {
+    if (target & HostMgrOperationTarget::PRIMARY_SOURCE) {
+        if (getCfgHostsForEdit()->del4(subnet_id, identifier_type,
+                                       identifier_begin, identifier_len)) {
+            return (true);
+        }
     }
 
-    for (auto source : alternate_sources_) {
-        if (source->del4(subnet_id, identifier_type,
-                         identifier_begin, identifier_len)) {
-            return (true);
+    if (target & HostMgrOperationTarget::ALTERNATE_SOURCES) {
+        // Don't throw if all targets were selected.
+        if (alternate_sources_.empty() && !(target & HostMgrOperationTarget::ALL_SOURCES)) {
+            isc_throw(NoHostDataSourceManager, "Unable to delete a host because there is "
+                    "no hosts-database configured.");
+        }
+
+        for (auto source : alternate_sources_) {
+            if (source->del4(subnet_id, identifier_type,
+                             identifier_begin, identifier_len)) {
+                return (true);
+            }
         }
     }
     return (false);
@@ -602,16 +718,27 @@ HostMgr::del4(const SubnetID& subnet_id, const Host::IdentifierType& identifier_
 
 bool
 HostMgr::del6(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
-              const uint8_t* identifier_begin, const size_t identifier_len) {
-    if (alternate_sources_.empty()) {
-        isc_throw(NoHostDataSourceManager, "unable to delete a host because there is "
-                  "no alternate host data source present");
+              const uint8_t* identifier_begin, const size_t identifier_len,
+              const HostMgrOperationTarget target) {
+    if (target & HostMgrOperationTarget::PRIMARY_SOURCE) {
+        if (getCfgHostsForEdit()->del6(subnet_id, identifier_type,
+                                       identifier_begin, identifier_len)) {
+            return (true);
+        }
     }
 
-    for (auto source : alternate_sources_) {
-        if (source->del6(subnet_id, identifier_type,
-                         identifier_begin, identifier_len)) {
-            return (true);
+    if (target & HostMgrOperationTarget::ALTERNATE_SOURCES) {
+        // Don't throw if all targets were selected.
+        if (alternate_sources_.empty() && !(target & HostMgrOperationTarget::ALL_SOURCES)) {
+            isc_throw(NoHostDataSourceManager, "Unable to delete a host because there is "
+                    "no hosts-database configured.");
+        }
+
+        for (auto source : alternate_sources_) {
+            if (source->del6(subnet_id, identifier_type,
+                             identifier_begin, identifier_len)) {
+                return (true);
+            }
         }
     }
     return (false);
index fffbc7d4fdf375cd71521283f5851e21a1c9cee2..671433e999675d59a428714e856e57638e9859e3 100644 (file)
@@ -22,14 +22,13 @@ namespace isc {
 namespace dhcp {
 
 // Enum flags to define a target of the host manager functions.
-enum class HostMgrOperationTarget : uint8_t {
-    NONE = 0, // 1 << 0
+enum HostMgrOperationTarget {
     // Consider only the CfgHosts instance.
-    CONFIG_HOSTS = 1, // 1 << 1
+    PRIMARY_SOURCE = 1, // 1 << 1
     // Consider only the alternate sources.
     ALTERNATE_SOURCES = 2, // 1 << 2
     // Consider both CfgInstance and alternate sources.
-    ALL = 3  // CONFIG_HOSTS & ALTERNATE_SOURCES
+    ALL_SOURCES = 3  // PRIMARY_SOURCE & ALTERNATE_SOURCES
 };
 
 /// @brief Host Manager.
@@ -144,12 +143,14 @@ public:
     /// @param identifier_begin Pointer to a beginning of a buffer containing
     /// an identifier.
     /// @param identifier_len Identifier length.
+    /// @param target The host data source being a target of the operation.
     ///
     /// @return Collection of const @c Host objects.
     ConstHostCollection
     getAll(const Host::IdentifierType& identifier_type,
            const uint8_t* identifier_begin,
-           const size_t identifier_len) const;
+           const size_t identifier_len,
+           const HostMgrOperationTarget target=HostMgrOperationTarget::ALL_SOURCES) const;
 
     /// @brief Return all hosts in a DHCPv4 subnet.
     ///
@@ -164,10 +165,11 @@ public:
     /// reservations from the alternate source.
     ///
     /// @param subnet_id Subnet identifier.
+    /// @param target The host data source being a target of the operation.
     ///
     /// @return Collection of const @c Host objects.
     ConstHostCollection
-    getAll4(const SubnetID& subnet_id) const;
+    getAll4(const SubnetID& subnet_id, const HostMgrOperationTarget target) const;
 
     /// @brief Return all hosts in a DHCPv6 subnet.
     ///
@@ -182,10 +184,12 @@ public:
     /// reservations from the alternate source.
     ///
     /// @param subnet_id Subnet identifier.
+    /// @param target The host data source being a target of the operation.
     ///
     /// @return Collection of const @c Host objects.
     ConstHostCollection
-    getAll6(const SubnetID& subnet_id) const;
+    getAll6(const SubnetID& subnet_id,
+            const HostMgrOperationTarget target=HostMgrOperationTarget::ALL_SOURCES) const;
 
     /// @brief Return all hosts with a hostname.
     ///
@@ -193,10 +197,12 @@ public:
     /// using a specified hostname.
     ///
     /// @param hostname The lower case hostname.
+    /// @param target The host data source being a target of the operation.
     ///
     /// @return Collection of const @c Host objects.
     ConstHostCollection
-    getAllbyHostname(const std::string& hostname) const;
+    getAllbyHostname(const std::string& hostname,
+                     const HostMgrOperationTarget target=HostMgrOperationTarget::ALL_SOURCES) const;
 
     /// @brief Return all hosts with a hostname in a DHCPv4 subnet.
     ///
@@ -205,10 +211,12 @@ public:
     ///
     /// @param hostname The lower case hostname.
     /// @param subnet_id Subnet identifier.
+    /// @param target The host data source being a target of the operation.
     ///
     /// @return Collection of const @c Host objects.
     ConstHostCollection
-    getAllbyHostname4(const std::string& hostname, const SubnetID& subnet_id) const;
+    getAllbyHostname4(const std::string& hostname, const SubnetID& subnet_id,
+                      const HostMgrOperationTarget target=HostMgrOperationTarget::ALL_SOURCES) const;
 
     /// @brief Return all hosts with a hostname in a DHCPv6 subnet.
     ///
@@ -217,10 +225,12 @@ public:
     ///
     /// @param hostname The lower case hostname.
     /// @param subnet_id Subnet identifier.
+    /// @param target The host data source being a target of the operation.
     ///
     /// @return Collection of const @c Host objects.
     ConstHostCollection
-    getAllbyHostname6(const std::string& hostname, const SubnetID& subnet_id) const;
+    getAllbyHostname6(const std::string& hostname, const SubnetID& subnet_id,
+                      const HostMgrOperationTarget target=HostMgrOperationTarget::ALL_SOURCES) const;
 
     /// @brief Returns range of hosts in a DHCPv4 subnet.
     ///
@@ -347,10 +357,12 @@ public:
     /// alternate source.
     ///
     /// @param address IPv4 address for which the @c Host object is searched.
+    /// @param target The host data source being a target of the operation.
     ///
     /// @return Collection of const @c Host objects.
     ConstHostCollection
-    getAll4(const asiolink::IOAddress& address) const;
+    getAll4(const asiolink::IOAddress& address,
+            const HostMgrOperationTarget target=HostMgrOperationTarget::ALL_SOURCES) const;
 
     /// @brief Returns any host connected to the IPv4 subnet.
     ///
@@ -364,6 +376,7 @@ public:
     /// @param identifier_begin Pointer to a beginning of a buffer containing
     /// an identifier.
     /// @param identifier_len Identifier length.
+    /// @param target The host data source being a target of the operation.
     ///
     /// @return Const @c Host object for which reservation has been made using
     /// the specified identifier.
@@ -371,7 +384,8 @@ public:
     get4Any(const SubnetID& subnet_id,
             const Host::IdentifierType& identifier_type,
             const uint8_t* identifier_begin,
-            const size_t identifier_len) const;
+            const size_t identifier_len,
+            const HostMgrOperationTarget target=HostMgrOperationTarget::ALL_SOURCES) const;
 
     /// @brief Returns a host connected to the IPv4 subnet.
     ///
@@ -383,12 +397,14 @@ public:
     /// @param identifier_begin Pointer to a beginning of a buffer containing
     /// an identifier.
     /// @param identifier_len Identifier length.
+    /// @param target The host data source being a target of the operation.
     ///
     /// @return Const @c Host object for which reservation has been made using
     /// the specified identifier.
     ConstHostPtr
     get4(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
-         const uint8_t* identifier_begin, const size_t identifier_len) const;
+         const uint8_t* identifier_begin, const size_t identifier_len,
+         const HostMgrOperationTarget target=HostMgrOperationTarget::ALL_SOURCES) const;
 
     /// @brief Returns a host connected to the IPv4 subnet and having
     /// a reservation for a specified IPv4 address.
@@ -399,10 +415,12 @@ public:
     ///
     /// @param subnet_id Subnet identifier.
     /// @param address reserved IPv4 address.
+    /// @param target The host data source being a target of the operation.
     ///
     /// @return Const @c Host object using a specified IPv4 address.
     ConstHostPtr
-    get4(const SubnetID& subnet_id, const asiolink::IOAddress& address) const;
+    get4(const SubnetID& subnet_id, const asiolink::IOAddress& address,
+         const HostMgrOperationTarget target=HostMgrOperationTarget::ALL_SOURCES) const;
 
     /// @brief Returns all hosts connected to the IPv4 subnet and having
     /// a reservation for a specified address.
@@ -425,11 +443,13 @@ public:
     ///
     /// @param subnet_id Subnet identifier.
     /// @param address reserved IPv4 address.
+    /// @param target The host data source being a target of the operation.
     ///
     /// @return Collection of const @c Host objects.
     ConstHostCollection
     getAll4(const SubnetID& subnet_id,
-            const asiolink::IOAddress& address) const;
+            const asiolink::IOAddress& address,
+            const HostMgrOperationTarget target=HostMgrOperationTarget::ALL_SOURCES) const;
 
     /// @brief Returns any host connected to the IPv6 subnet.
     ///
@@ -443,6 +463,7 @@ public:
     /// @param identifier_begin Pointer to a beginning of a buffer containing
     /// an identifier.
     /// @param identifier_len Identifier length.
+    /// @param target The host data source being a target of the operation.
     ///
     /// @return Const @c Host object for which reservation has been made using
     /// the specified identifier.
@@ -450,7 +471,8 @@ public:
     get6Any(const SubnetID& subnet_id,
             const Host::IdentifierType& identifier_type,
             const uint8_t* identifier_begin,
-            const size_t identifier_len) const;
+            const size_t identifier_len,
+            const HostMgrOperationTarget target=HostMgrOperationTarget::ALL_SOURCES) const;
 
     /// @brief Returns a host connected to the IPv6 subnet.
     ///
@@ -462,12 +484,14 @@ public:
     /// @param identifier_begin Pointer to a beginning of a buffer containing
     /// an identifier.
     /// @param identifier_len Identifier length.
+    /// @param target The host data source being a target of the operation.
     ///
     /// @return Const @c Host object for which reservation has been made using
     /// the specified identifier.
     ConstHostPtr
     get6(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
-         const uint8_t* identifier_begin, const size_t identifier_len) const;
+         const uint8_t* identifier_begin, const size_t identifier_len,
+         const HostMgrOperationTarget target=HostMgrOperationTarget::ALL_SOURCES) const;
 
     /// @brief Returns a host using the specified IPv6 prefix.
     ///
@@ -476,19 +500,23 @@ public:
     ///
     /// @param prefix IPv6 prefix for which the @c Host object is searched.
     /// @param prefix_len IPv6 prefix length.
+    /// @param target The host data source being a target of the operation.
     ///
     /// @return Const @c Host object using a specified IPv6 prefix.
     ConstHostPtr
-    get6(const asiolink::IOAddress& prefix, const uint8_t prefix_len) const;
+    get6(const asiolink::IOAddress& prefix, const uint8_t prefix_len,
+         const HostMgrOperationTarget target=HostMgrOperationTarget::ALL_SOURCES) const;
 
     /// @brief Returns a host from specific subnet and reserved address.
     ///
     /// @param subnet_id subnet identifier.
     /// @param addr specified address.
+    /// @param target The host data source being a target of the operation.
     ///
     /// @return Const @c host object that has a reservation for specified address.
     ConstHostPtr
-    get6(const SubnetID& subnet_id, const asiolink::IOAddress& addr) const;
+    get6(const SubnetID& subnet_id, const asiolink::IOAddress& addr,
+         const HostMgrOperationTarget target=HostMgrOperationTarget::ALL_SOURCES) const;
 
     /// @brief Returns all hosts connected to the IPv6 subnet and having
     /// a reservation for a specified address or delegated prefix (lease).
@@ -511,11 +539,13 @@ public:
     ///
     /// @param subnet_id Subnet identifier.
     /// @param address reserved IPv6 address/prefix.
+    /// @param target The host data source being a target of the operation.
     ///
     /// @return Collection of const @c Host objects.
     ConstHostCollection
     getAll6(const SubnetID& subnet_id,
-            const asiolink::IOAddress& address) const;
+            const asiolink::IOAddress& address,
+            const HostMgrOperationTarget target=HostMgrOperationTarget::ALL_SOURCES) const;
 
     /// @brief Adds a new host to the alternate data source.
     ///
@@ -523,7 +553,9 @@ public:
     /// in use.
     ///
     /// @param host Pointer to the new @c Host object being added.
-    void add(const HostPtr& host);
+    /// @param target The host data source being a target of the operation.
+    void add(const HostPtr& host,
+             const HostMgrOperationTarget target=HostMgrOperationTarget::ALTERNATE_SOURCES);
 
     /// @brief Attempts to delete hosts by address.
     ///
@@ -536,8 +568,10 @@ public:
     ///
     /// @param subnet_id subnet identifier.
     /// @param addr specified address.
+    /// @param target The host data source being a target of the operation.
     /// @return true if deletion was successful, false otherwise.
-    bool del(const SubnetID& subnet_id, const asiolink::IOAddress& addr);
+    bool del(const SubnetID& subnet_id, const asiolink::IOAddress& addr,
+             const HostMgrOperationTarget target=HostMgrOperationTarget::ALTERNATE_SOURCES);
 
     /// @brief Attempts to delete a host by (subnet4-id, identifier, identifier-type)
     ///
@@ -548,10 +582,12 @@ public:
     /// @param identifier_begin Pointer to a beginning of a buffer containing
     /// an identifier.
     /// @param identifier_len Identifier length.
+    /// @param target The host data source being a target of the operation.
     /// @return true if deletion was successful, false otherwise.
     bool
     del4(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
-         const uint8_t* identifier_begin, const size_t identifier_len);
+         const uint8_t* identifier_begin, const size_t identifier_len,
+         const HostMgrOperationTarget target=HostMgrOperationTarget::ALTERNATE_SOURCES);
 
     /// @brief Attempts to delete a host by (subnet6-id, identifier, identifier-type)
     ///
@@ -562,10 +598,12 @@ public:
     /// @param identifier_begin Pointer to a beginning of a buffer containing
     /// an identifier.
     /// @param identifier_len Identifier length.
+    /// @param target The host data source being a target of the operation.
     /// @return true if deletion was successful, false otherwise.
     bool
     del6(const SubnetID& subnet_id, const Host::IdentifierType& identifier_type,
-         const uint8_t* identifier_begin, const size_t identifier_len);
+         const uint8_t* identifier_begin, const size_t identifier_len,
+         const HostMgrOperationTarget target=HostMgrOperationTarget::ALTERNATE_SOURCES);
 
     /// @brief Implements @ref BaseHostDataSource::update() for alternate sources.
     ///