2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-29 13:07:50 +00:00

added missing tables, columns and values in cql schema, ordered declarations and definitions in lease and host managers

This commit is contained in:
Razvan Becheriu 2018-02-13 18:28:40 +02:00
parent 63ea348578
commit e409c164a6
19 changed files with 571 additions and 517 deletions

View File

@ -74,6 +74,58 @@ public:
/// @brief Default destructor implementation. /// @brief Default destructor implementation.
virtual ~BaseHostDataSource() { } virtual ~BaseHostDataSource() { }
/// @brief Adds a new host to the collection.
///
/// The implementations of this method should guard against duplicate
/// reservations for the same host, where possible. For example, when the
/// reservation for the same HW address and subnet id is added twice, the
/// implementation should throw an exception. Note, that usually it is
/// impossible to guard against adding duplicated host, where one instance
/// is identified by HW address, another one by DUID.
///
/// @param host Pointer to the new @c Host object being added.
virtual void add(const HostPtr& host) = 0;
/// @brief Attempts to delete a host by (subnet-id, address)
///
/// This method supports both v4 and v6.
///
/// @param subnet_id subnet identifier.
/// @param addr specified address.
/// @return true if deletion was successful, false if the host was not there.
/// @throw various exceptions in case of errors
virtual bool del(const SubnetID& subnet_id, const asiolink::IOAddress& addr) = 0;
/// @brief Attempts to delete a host by (subnet-id4, identifier, identifier-type)
///
/// This method supports both v4 hosts only.
///
/// @param subnet_id IPv4 Subnet identifier.
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
/// @return true if deletion was successful, false if the host was not there.
/// @throw various exceptions in case of errors
virtual bool del4(const SubnetID& subnet_id,
const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin, const size_t identifier_len) = 0;
/// @brief Attempts to delete a host by (subnet-id6, identifier, identifier-type)
///
/// This method supports both v6 hosts only.
///
/// @param subnet_id IPv6 Subnet identifier.
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
/// @return true if deletion was successful, false if the host was not there.
/// @throw various exceptions in case of errors
virtual bool del6(const SubnetID& subnet_id,
const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin, const size_t identifier_len) = 0;
/// @brief Return all hosts for the specified HW address or DUID. /// @brief Return all hosts for the specified HW address or DUID.
/// ///
/// This method returns all @c Host objects which represent reservations /// This method returns all @c Host objects which represent reservations
@ -235,58 +287,6 @@ public:
virtual ConstHostPtr virtual ConstHostPtr
get6(const SubnetID& subnet_id, const asiolink::IOAddress& address) const = 0; get6(const SubnetID& subnet_id, const asiolink::IOAddress& address) const = 0;
/// @brief Adds a new host to the collection.
///
/// The implementations of this method should guard against duplicate
/// reservations for the same host, where possible. For example, when the
/// reservation for the same HW address and subnet id is added twice, the
/// implementation should throw an exception. Note, that usually it is
/// impossible to guard against adding duplicated host, where one instance
/// is identified by HW address, another one by DUID.
///
/// @param host Pointer to the new @c Host object being added.
virtual void add(const HostPtr& host) = 0;
/// @brief Attempts to delete a host by (subnet-id, address)
///
/// This method supports both v4 and v6.
///
/// @param subnet_id subnet identifier.
/// @param addr specified address.
/// @return true if deletion was successful, false if the host was not there.
/// @throw various exceptions in case of errors
virtual bool del(const SubnetID& subnet_id, const asiolink::IOAddress& addr) = 0;
/// @brief Attempts to delete a host by (subnet-id4, identifier, identifier-type)
///
/// This method supports both v4 hosts only.
///
/// @param subnet_id IPv4 Subnet identifier.
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
/// @return true if deletion was successful, false if the host was not there.
/// @throw various exceptions in case of errors
virtual bool del4(const SubnetID& subnet_id,
const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin, const size_t identifier_len) = 0;
/// @brief Attempts to delete a host by (subnet-id6, identifier, identifier-type)
///
/// This method supports both v6 hosts only.
///
/// @param subnet_id IPv6 Subnet identifier.
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
/// @return true if deletion was successful, false if the host was not there.
/// @throw various exceptions in case of errors
virtual bool del6(const SubnetID& subnet_id,
const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin, const size_t identifier_len) = 0;
/// @brief Return backend type /// @brief Return backend type
/// ///
/// Returns the type of the backend (e.g. "mysql", "memfile" etc.) /// Returns the type of the backend (e.g. "mysql", "memfile" etc.)

View File

@ -1401,7 +1401,6 @@ CqlHostDataSourceImpl::get4(const SubnetID& subnet_id, const asiolink::IOAddress
where_values.add(&host_ipv4_subnet_id); where_values.add(&host_ipv4_subnet_id);
where_values.add(&host_ipv4_address); where_values.add(&host_ipv4_address);
// Run statement. // Run statement.
ConstHostPtr result = getHost(CqlHostExchange::GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS, ConstHostPtr result = getHost(CqlHostExchange::GET_HOST_BY_IPV4_SUBNET_ID_AND_ADDRESS,
where_values); where_values);
@ -1781,7 +1780,6 @@ CqlHostDataSourceImpl::insertHost(const HostPtr& host,
host, subnet_id, reservation, option_space, option_descriptor, host, subnet_id, reservation, option_space, option_descriptor,
CqlHostExchange::INSERT_HOST, assigned_values); CqlHostExchange::INSERT_HOST, assigned_values);
host_exchange->executeMutation(dbconn_, assigned_values, host_exchange->executeMutation(dbconn_, assigned_values,
CqlHostExchange::INSERT_HOST); CqlHostExchange::INSERT_HOST);
} catch (const StatementNotApplied& exception) { } catch (const StatementNotApplied& exception) {
@ -1827,6 +1825,23 @@ CqlHostDataSource::add(const HostPtr& host) {
impl_->add(host); impl_->add(host);
} }
bool
CqlHostDataSource::del(const SubnetID& /*subnet_id*/, const asiolink::IOAddress& /*addr*/) {
isc_throw(NotImplemented, "CqlHostDataSource::del NotImplemented");
}
bool
CqlHostDataSource::del4(const SubnetID& /*subnet_id*/, const Host::IdentifierType& /*type*/,
const uint8_t* /*identifier_begin*/, const size_t /*identifier_len*/) {
isc_throw(NotImplemented, "CqlHostDataSource::del4 NotImplemented");
}
bool
CqlHostDataSource::del6(const SubnetID& /*subnet_id*/, const Host::IdentifierType& /*type*/,
const uint8_t* /*identifier_begin*/, const size_t /*identifier_len*/) {
isc_throw(NotImplemented, "CqlHostDataSource::del6 NotImplemented");
}
ConstHostCollection ConstHostCollection
CqlHostDataSource::getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid) const { CqlHostDataSource::getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_HOST_GET_ALL); LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_HOST_GET_ALL);
@ -1913,23 +1928,6 @@ CqlHostDataSource::get6(const SubnetID& subnet_id,
return (impl_->get6(subnet_id, address)); return (impl_->get6(subnet_id, address));
} }
bool
CqlHostDataSource::del(const SubnetID& /*subnet_id*/, const asiolink::IOAddress& /*addr*/) {
isc_throw(NotImplemented, "CqlHostDataSource::del NotImplemented");
}
bool
CqlHostDataSource::del4(const SubnetID& /*subnet_id*/, const Host::IdentifierType& /*type*/,
const uint8_t* /*identifier_begin*/, const size_t /*identifier_len*/) {
isc_throw(NotImplemented, "CqlHostDataSource::del4 NotImplemented");
}
bool
CqlHostDataSource::del6(const SubnetID& /*subnet_id*/, const Host::IdentifierType& /*type*/,
const uint8_t* /*identifier_begin*/, const size_t /*identifier_len*/) {
isc_throw(NotImplemented, "CqlHostDataSource::del6 NotImplemented");
}
std::string std::string
CqlHostDataSource::getType() const { CqlHostDataSource::getType() const {
return std::string("cql"); return std::string("cql");

View File

@ -100,6 +100,109 @@ public:
/// @param host pointer to the new @ref Host being added. /// @param host pointer to the new @ref Host being added.
virtual void add(const HostPtr& host) override; virtual void add(const HostPtr& host) override;
/// @brief Attempts to delete a host by (subnet-id, address)
///
/// This method supports both v4 and v6.
///
/// @param subnet_id subnet identfier.
/// @param addr specified address.
/// @return true if deletion was successful, false if the host was not
/// there.
/// @throw various exceptions in case of errors
virtual bool del(const SubnetID& subnet_id,
const asiolink::IOAddress& addr);
/// @brief Attempts to delete a host by (subnet-id4, identifier-type,
/// identifier).
///
/// This method supports v4 hosts only.
///
/// @param subnet_id IPv4 Subnet identifier.
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
/// @return true if deletion was successful, false if the host was not
/// there.
/// @throw various exceptions in case of errors
virtual bool del4(const SubnetID& subnet_id,
const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin,
const size_t identifier_len);
/// @brief Attempts to delete a host by (subnet-id6, identifier-type,
/// identifier).
///
/// This method supports v6 hosts only.
///
/// @param subnet_id IPv6 Subnet identifier.
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
/// @return true if deletion was successful, false if the host was not
/// there.
/// @throw various exceptions in case of errors
virtual bool del6(const SubnetID& subnet_id,
const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin,
const size_t identifier_len);
/// @brief Return all @ref Host objects for the specified @ref HWAddr or
/// @ref DUID.
///
/// Returns all @ref Host objects which represent reservations
/// for the specified HW address or DUID. Note, that this method may
/// return multiple reservations because a particular client may have
/// reservations in multiple subnets and the same client may be identified
/// by HW address or DUID. The server is unable to verify that the specific
/// DUID and HW address belong to the same client, until the client sends
/// a DHCP message.
///
/// Specifying both @ref HWAddr and @ref DUID is allowed for this method
/// and results in returning all objects that are associated with hardware
/// address OR duid. For example: if one @ref Host is associated with the
/// specified @ref HWAddr and another @ref Host is associated with the
/// specified @ref DUID, two hosts will be returned.
///
/// @param hwaddr HW address of the client or NULL if no HW address
/// available.
/// @param duid client id or NULL if not available, e.g. DHCPv4 client case.
///
/// @return collection of const @ref Host objects.
virtual ConstHostCollection
getAll(const HWAddrPtr& hwaddr,
const DuidPtr& duid = DuidPtr()) const override;
/// @brief Return all hosts connected to any subnet for which reservations
/// have been made using a specified identifier.
///
/// This method returns all @ref Host objects which represent reservations
/// for a specified identifier. This method may return multiple hosts
/// because a particular client may have reservations in multiple subnets.
///
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
///
/// @return Collection of const @ref Host objects.
virtual ConstHostCollection
getAll(const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin,
const size_t identifier_len) const override;
/// @brief Returns a collection of hosts using the specified IPv4 address.
///
/// This method may return multiple @ref Host objects if they are connected
/// to different subnets.
///
/// @param address IPv4 address for which the @ref Host object is searched.
///
/// @return Collection of const @ref Host objects.
virtual ConstHostCollection
getAll4(const asiolink::IOAddress& address) const override;
/// @brief Retrieves a single @ref Host connected to an IPv4 subnet. /// @brief Retrieves a single @ref Host connected to an IPv4 subnet.
/// ///
/// Implementations of this method should guard against the case when /// Implementations of this method should guard against the case when
@ -209,109 +312,6 @@ public:
get6(const SubnetID& subnet_id, get6(const SubnetID& subnet_id,
const asiolink::IOAddress& address) const override; const asiolink::IOAddress& address) const override;
/// @brief Return all @ref Host objects for the specified @ref HWAddr or
/// @ref DUID.
///
/// Returns all @ref Host objects which represent reservations
/// for the specified HW address or DUID. Note, that this method may
/// return multiple reservations because a particular client may have
/// reservations in multiple subnets and the same client may be identified
/// by HW address or DUID. The server is unable to verify that the specific
/// DUID and HW address belong to the same client, until the client sends
/// a DHCP message.
///
/// Specifying both @ref HWAddr and @ref DUID is allowed for this method
/// and results in returning all objects that are associated with hardware
/// address OR duid. For example: if one @ref Host is associated with the
/// specified @ref HWAddr and another @ref Host is associated with the
/// specified @ref DUID, two hosts will be returned.
///
/// @param hwaddr HW address of the client or NULL if no HW address
/// available.
/// @param duid client id or NULL if not available, e.g. DHCPv4 client case.
///
/// @return collection of const @ref Host objects.
virtual ConstHostCollection
getAll(const HWAddrPtr& hwaddr,
const DuidPtr& duid = DuidPtr()) const override;
/// @brief Return all hosts connected to any subnet for which reservations
/// have been made using a specified identifier.
///
/// This method returns all @ref Host objects which represent reservations
/// for a specified identifier. This method may return multiple hosts
/// because a particular client may have reservations in multiple subnets.
///
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
///
/// @return Collection of const @ref Host objects.
virtual ConstHostCollection
getAll(const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin,
const size_t identifier_len) const override;
/// @brief Returns a collection of hosts using the specified IPv4 address.
///
/// This method may return multiple @ref Host objects if they are connected
/// to different subnets.
///
/// @param address IPv4 address for which the @ref Host object is searched.
///
/// @return Collection of const @ref Host objects.
virtual ConstHostCollection
getAll4(const asiolink::IOAddress& address) const override;
/// @brief Attempts to delete a host by (subnet-id, address)
///
/// This method supports both v4 and v6.
///
/// @param subnet_id subnet identfier.
/// @param addr specified address.
/// @return true if deletion was successful, false if the host was not
/// there.
/// @throw various exceptions in case of errors
virtual bool del(const SubnetID& subnet_id,
const asiolink::IOAddress& addr);
/// @brief Attempts to delete a host by (subnet-id4, identifier-type,
/// identifier).
///
/// This method supports v4 hosts only.
///
/// @param subnet_id IPv4 Subnet identifier.
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
/// @return true if deletion was successful, false if the host was not
/// there.
/// @throw various exceptions in case of errors
virtual bool del4(const SubnetID& subnet_id,
const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin,
const size_t identifier_len);
/// @brief Attempts to delete a host by (subnet-id6, identifier-type,
/// identifier).
///
/// This method supports v6 hosts only.
///
/// @param subnet_id IPv6 Subnet identifier.
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
/// @return true if deletion was successful, false if the host was not
/// there.
/// @throw various exceptions in case of errors
virtual bool del6(const SubnetID& subnet_id,
const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin,
const size_t identifier_len);
/// @brief Returns textual description of the backend. /// @brief Returns textual description of the backend.
/// ///
/// @return Description of the backend. /// @return Description of the backend.

View File

@ -267,18 +267,6 @@ public:
const DUID& duid, const DUID& duid,
uint32_t iaid, uint32_t iaid,
SubnetID subnet_id) const override; SubnetID subnet_id) const override;
/// @brief Returns a collection of expired DHCPv6 leases.
///
/// This method returns at most @c max_leases expired leases. The leases
/// returned haven't been reclaimed, i.e. the database query must exclude
/// reclaimed leases from the results returned.
///
/// @param [out] expired_leases A container to which expired leases returned
/// by the database backend are added.
/// @param max_leases A maximum number of leases to be returned. If this
/// value is set to 0, all expired (but not reclaimed) leases are returned.
virtual void getExpiredLeases6(Lease6Collection& expired_leases,
const size_t max_leases) const override;
/// @brief Returns a collection of expired DHCPv4 leases. /// @brief Returns a collection of expired DHCPv4 leases.
/// ///
@ -293,6 +281,18 @@ public:
virtual void getExpiredLeases4(Lease4Collection& expired_leases, virtual void getExpiredLeases4(Lease4Collection& expired_leases,
const size_t max_leases) const override; const size_t max_leases) const override;
/// @brief Returns a collection of expired DHCPv6 leases.
///
/// This method returns at most @c max_leases expired leases. The leases
/// returned haven't been reclaimed, i.e. the database query must exclude
/// reclaimed leases from the results returned.
///
/// @param [out] expired_leases A container to which expired leases returned
/// by the database backend are added.
/// @param max_leases A maximum number of leases to be returned. If this
/// value is set to 0, all expired (but not reclaimed) leases are returned.
virtual void getExpiredLeases6(Lease6Collection& expired_leases,
const size_t max_leases) const override;
/// @} /// @}
/// @brief Updates IPv4 lease. /// @brief Updates IPv4 lease.

View File

@ -341,20 +341,6 @@ public:
Lease6Ptr getLease6(Lease::Type type, const DUID& duid, Lease6Ptr getLease6(Lease::Type type, const DUID& duid,
uint32_t iaid, SubnetID subnet_id) const; uint32_t iaid, SubnetID subnet_id) const;
/// @brief Returns a collection of expired DHCPv6 leases.
///
/// This method returns at most @c max_leases expired leases. The leases
/// returned haven't been reclaimed, i.e. the database query must exclude
/// reclaimed leases from the results returned.
///
/// @param [out] expired_leases A container to which expired leases returned
/// by the database backend are added.
/// @param max_leases A maximum number of leases to be returned. If this
/// value is set to 0, all expired (but not reclaimed) leases are returned.
virtual void getExpiredLeases6(Lease6Collection& expired_leases,
const size_t max_leases) const = 0;
/// @brief Returns a collection of expired DHCPv4 leases. /// @brief Returns a collection of expired DHCPv4 leases.
/// ///
/// This method returns at most @c max_leases expired leases. The leases /// This method returns at most @c max_leases expired leases. The leases
@ -368,6 +354,19 @@ public:
virtual void getExpiredLeases4(Lease4Collection& expired_leases, virtual void getExpiredLeases4(Lease4Collection& expired_leases,
const size_t max_leases) const = 0; const size_t max_leases) const = 0;
/// @brief Returns a collection of expired DHCPv6 leases.
///
/// This method returns at most @c max_leases expired leases. The leases
/// returned haven't been reclaimed, i.e. the database query must exclude
/// reclaimed leases from the results returned.
///
/// @param [out] expired_leases A container to which expired leases returned
/// by the database backend are added.
/// @param max_leases A maximum number of leases to be returned. If this
/// value is set to 0, all expired (but not reclaimed) leases are returned.
virtual void getExpiredLeases6(Lease6Collection& expired_leases,
const size_t max_leases) const = 0;
/// @brief Updates IPv4 lease. /// @brief Updates IPv4 lease.
/// ///
/// @param lease4 The lease to be updated. /// @param lease4 The lease to be updated.

View File

@ -831,31 +831,6 @@ Memfile_LeaseMgr::getLeases6(Lease::Type type,
return (collection); return (collection);
} }
void
Memfile_LeaseMgr::getExpiredLeases6(Lease6Collection& expired_leases,
const size_t max_leases) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MEMFILE_GET_EXPIRED6)
.arg(max_leases);
// Obtain the index which segragates leases by state and time.
const Lease6StorageExpirationIndex& index = storage6_.get<ExpirationIndexTag>();
// Retrieve leases which are not reclaimed and which haven't expired. The
// 'less-than' operator will be used for both components of the index. So,
// for the 'state' 'false' is less than 'true'. Also the leases with
// expiration time lower than current time will be returned.
Lease6StorageExpirationIndex::const_iterator ub =
index.upper_bound(boost::make_tuple(false, time(NULL)));
// Copy only the number of leases indicated by the max_leases parameter.
for (Lease6StorageExpirationIndex::const_iterator lease = index.begin();
(lease != ub) && ((max_leases == 0) || (std::distance(index.begin(), lease) <
max_leases));
++lease) {
expired_leases.push_back(Lease6Ptr(new Lease6(**lease)));
}
}
void void
Memfile_LeaseMgr::getExpiredLeases4(Lease4Collection& expired_leases, Memfile_LeaseMgr::getExpiredLeases4(Lease4Collection& expired_leases,
const size_t max_leases) const { const size_t max_leases) const {
@ -881,6 +856,31 @@ Memfile_LeaseMgr::getExpiredLeases4(Lease4Collection& expired_leases,
} }
} }
void
Memfile_LeaseMgr::getExpiredLeases6(Lease6Collection& expired_leases,
const size_t max_leases) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MEMFILE_GET_EXPIRED6)
.arg(max_leases);
// Obtain the index which segragates leases by state and time.
const Lease6StorageExpirationIndex& index = storage6_.get<ExpirationIndexTag>();
// Retrieve leases which are not reclaimed and which haven't expired. The
// 'less-than' operator will be used for both components of the index. So,
// for the 'state' 'false' is less than 'true'. Also the leases with
// expiration time lower than current time will be returned.
Lease6StorageExpirationIndex::const_iterator ub =
index.upper_bound(boost::make_tuple(false, time(NULL)));
// Copy only the number of leases indicated by the max_leases parameter.
for (Lease6StorageExpirationIndex::const_iterator lease = index.begin();
(lease != ub) && ((max_leases == 0) || (std::distance(index.begin(), lease) <
max_leases));
++lease) {
expired_leases.push_back(Lease6Ptr(new Lease6(**lease)));
}
}
void void
Memfile_LeaseMgr::updateLease4(const Lease4Ptr& lease) { Memfile_LeaseMgr::updateLease4(const Lease4Ptr& lease) {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,

View File

@ -271,20 +271,6 @@ public:
uint32_t iaid, uint32_t iaid,
SubnetID subnet_id) const; SubnetID subnet_id) const;
/// @brief Returns a collection of expired DHCPv6 leases.
///
/// This method returns at most @c max_leases expired leases. The leases
/// returned haven't been reclaimed, i.e. the database query must exclude
/// reclaimed leases from the results returned.
///
/// @param [out] expired_leases A container to which expired leases returned
/// by the database backend are added.
/// @param max_leases A maximum number of leases to be returned. If this
/// value is set to 0, all expired (but not reclaimed) leases are returned.
virtual void getExpiredLeases6(Lease6Collection& expired_leases,
const size_t max_leases) const;
/// @brief Returns a collection of expired DHCPv4 leases. /// @brief Returns a collection of expired DHCPv4 leases.
/// ///
/// This method returns at most @c max_leases expired leases. The leases /// This method returns at most @c max_leases expired leases. The leases
@ -298,6 +284,19 @@ public:
virtual void getExpiredLeases4(Lease4Collection& expired_leases, virtual void getExpiredLeases4(Lease4Collection& expired_leases,
const size_t max_leases) const; const size_t max_leases) const;
/// @brief Returns a collection of expired DHCPv6 leases.
///
/// This method returns at most @c max_leases expired leases. The leases
/// returned haven't been reclaimed, i.e. the database query must exclude
/// reclaimed leases from the results returned.
///
/// @param [out] expired_leases A container to which expired leases returned
/// by the database backend are added.
/// @param max_leases A maximum number of leases to be returned. If this
/// value is set to 0, all expired (but not reclaimed) leases are returned.
virtual void getExpiredLeases6(Lease6Collection& expired_leases,
const size_t max_leases) const;
/// @brief Updates IPv4 lease. /// @brief Updates IPv4 lease.
/// ///
/// @warning This function does not validate the pointer to the lease. /// @warning This function does not validate the pointer to the lease.

View File

@ -802,7 +802,6 @@ private:
my_bool dhcp4_boot_file_name_null_; my_bool dhcp4_boot_file_name_null_;
//@} //@}
}; };
/// @brief Extends base exchange class with ability to retrieve DHCP options /// @brief Extends base exchange class with ability to retrieve DHCP options
@ -1541,7 +1540,6 @@ private:
/// @brief Reservation id for last processed row. /// @brief Reservation id for last processed row.
uint32_t most_recent_reservation_id_; uint32_t most_recent_reservation_id_;
}; };
/// @brief This class is used for storing IPv6 reservations in a MySQL database. /// @brief This class is used for storing IPv6 reservations in a MySQL database.
@ -2078,7 +2076,6 @@ public:
bool is_readonly_; bool is_readonly_;
}; };
/// @brief Array of tagged statements. /// @brief Array of tagged statements.
typedef boost::array<TaggedStatement, MySqlHostDataSourceImpl::NUM_STATEMENTS> typedef boost::array<TaggedStatement, MySqlHostDataSourceImpl::NUM_STATEMENTS>
TaggedStatementArray; TaggedStatementArray;
@ -2552,7 +2549,6 @@ MySqlHostDataSourceImpl::checkReadOnly() const {
} }
} }
MySqlHostDataSource:: MySqlHostDataSource::
MySqlHostDataSource(const MySqlConnection::ParameterMap& parameters) MySqlHostDataSource(const MySqlConnection::ParameterMap& parameters)
: impl_(new MySqlHostDataSourceImpl(parameters)) { : impl_(new MySqlHostDataSourceImpl(parameters)) {
@ -2909,13 +2905,11 @@ MySqlHostDataSource::get6(const asiolink::IOAddress& prefix,
inbind[0].length = &addr6_length; inbind[0].length = &addr6_length;
inbind[0].buffer_length = addr6_length; inbind[0].buffer_length = addr6_length;
uint8_t tmp = prefix_len; uint8_t tmp = prefix_len;
inbind[1].buffer_type = MYSQL_TYPE_TINY; inbind[1].buffer_type = MYSQL_TYPE_TINY;
inbind[1].buffer = reinterpret_cast<char*>(&tmp); inbind[1].buffer = reinterpret_cast<char*>(&tmp);
inbind[1].is_unsigned = MLM_TRUE; inbind[1].is_unsigned = MLM_TRUE;
ConstHostCollection collection; ConstHostCollection collection;
impl_->getHostCollection(MySqlHostDataSourceImpl::GET_HOST_PREFIX, impl_->getHostCollection(MySqlHostDataSourceImpl::GET_HOST_PREFIX,
inbind, impl_->host_ipv6_exchange_, inbind, impl_->host_ipv6_exchange_,
@ -2965,7 +2959,6 @@ MySqlHostDataSource::get6(const SubnetID& subnet_id,
return (result); return (result);
} }
// Miscellaneous database methods. // Miscellaneous database methods.
std::string MySqlHostDataSource::getName() const { std::string MySqlHostDataSource::getName() const {
@ -3041,7 +3034,6 @@ MySqlHostDataSource::commit() {
impl_->conn_.commit(); impl_->conn_.commit();
} }
void void
MySqlHostDataSource::rollback() { MySqlHostDataSource::rollback() {
// If operating in read-only mode, throw exception. // If operating in read-only mode, throw exception.
@ -3049,6 +3041,5 @@ MySqlHostDataSource::rollback() {
impl_->conn_.rollback(); impl_->conn_.rollback();
} }
}; // end of isc::dhcp namespace }; // end of isc::dhcp namespace
}; // end of isc namespace }; // end of isc namespace

View File

@ -59,6 +59,60 @@ public:
/// Releases prepared MySQL statements used by the backend. /// Releases prepared MySQL statements used by the backend.
virtual ~MySqlHostDataSource(); virtual ~MySqlHostDataSource();
/// @brief Adds a new host to the collection.
///
/// The implementations of this method should guard against duplicate
/// reservations for the same host, where possible. For example, when the
/// reservation for the same HW address and subnet id is added twice, the
/// addHost method should throw an DuplicateEntry exception. Note, that
/// usually it is impossible to guard against adding duplicated host, where
/// one instance is identified by HW address, another one by DUID.
///
/// @param host Pointer to the new @c Host object being added.
virtual void add(const HostPtr& host);
/// @brief Attempts to delete a host by (subnet-id, address)
///
/// This method supports both v4 and v6.
///
/// @param subnet_id subnet identifier.
/// @param addr specified address.
/// @return true if deletion was successful, false if the host was not there.
/// @throw various exceptions in case of errors
virtual bool del(const SubnetID& subnet_id, const asiolink::IOAddress& addr);
/// @brief Attempts to delete a host by (subnet4-id, identifier type, identifier)
///
/// This method supports v4 hosts only.
///
/// @param subnet_id subnet identifier.
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
///
/// @return true if deletion was successful, false if the host was not there.
/// @throw various exceptions in case of errors
virtual bool del4(const SubnetID& subnet_id,
const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin, const size_t identifier_len);
/// @brief Attempts to delete a host by (subnet6-id, identifier type, identifier)
///
/// This method supports v6 hosts only.
///
/// @param subnet_id subnet identifier.
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
///
/// @return true if deletion was successful, false if the host was not there.
/// @throw various exceptions in case of errors
virtual bool del6(const SubnetID& subnet_id,
const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin, const size_t identifier_len);
/// @brief Return all hosts for the specified HW address or DUID. /// @brief Return all hosts for the specified HW address or DUID.
/// ///
/// This method returns all @c Host objects which represent reservations /// This method returns all @c Host objects which represent reservations
@ -213,60 +267,6 @@ public:
virtual ConstHostPtr virtual ConstHostPtr
get6(const SubnetID& subnet_id, const asiolink::IOAddress& address) const; get6(const SubnetID& subnet_id, const asiolink::IOAddress& address) const;
/// @brief Adds a new host to the collection.
///
/// The implementations of this method should guard against duplicate
/// reservations for the same host, where possible. For example, when the
/// reservation for the same HW address and subnet id is added twice, the
/// addHost method should throw an DuplicateEntry exception. Note, that
/// usually it is impossible to guard against adding duplicated host, where
/// one instance is identified by HW address, another one by DUID.
///
/// @param host Pointer to the new @c Host object being added.
virtual void add(const HostPtr& host);
/// @brief Attempts to delete a host by (subnet-id, address)
///
/// This method supports both v4 and v6.
///
/// @param subnet_id subnet identifier.
/// @param addr specified address.
/// @return true if deletion was successful, false if the host was not there.
/// @throw various exceptions in case of errors
virtual bool del(const SubnetID& subnet_id, const asiolink::IOAddress& addr);
/// @brief Attempts to delete a host by (subnet4-id, identifier type, identifier)
///
/// This method supports v4 hosts only.
///
/// @param subnet_id subnet identifier.
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
///
/// @return true if deletion was successful, false if the host was not there.
/// @throw various exceptions in case of errors
virtual bool del4(const SubnetID& subnet_id,
const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin, const size_t identifier_len);
/// @brief Attempts to delete a host by (subnet6-id, identifier type, identifier)
///
/// This method supports v6 hosts only.
///
/// @param subnet_id subnet identifier.
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
///
/// @return true if deletion was successful, false if the host was not there.
/// @throw various exceptions in case of errors
virtual bool del6(const SubnetID& subnet_id,
const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin, const size_t identifier_len);
/// @brief Return backend type /// @brief Return backend type
/// ///
/// Returns the type of the backend (e.g. "mysql", "memfile" etc.) /// Returns the type of the backend (e.g. "mysql", "memfile" etc.)
@ -319,4 +319,3 @@ private:
} }
#endif // MYSQL_HOST_DATA_SOURCE_H #endif // MYSQL_HOST_DATA_SOURCE_H

View File

@ -1909,14 +1909,6 @@ MySqlLeaseMgr::getLeases6(Lease::Type lease_type,
return (result); return (result);
} }
void
MySqlLeaseMgr::getExpiredLeases6(Lease6Collection& expired_leases,
const size_t max_leases) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MYSQL_GET_EXPIRED6)
.arg(max_leases);
getExpiredLeasesCommon(expired_leases, max_leases, GET_LEASE6_EXPIRE);
}
void void
MySqlLeaseMgr::getExpiredLeases4(Lease4Collection& expired_leases, MySqlLeaseMgr::getExpiredLeases4(Lease4Collection& expired_leases,
const size_t max_leases) const { const size_t max_leases) const {
@ -1925,6 +1917,14 @@ MySqlLeaseMgr::getExpiredLeases4(Lease4Collection& expired_leases,
getExpiredLeasesCommon(expired_leases, max_leases, GET_LEASE4_EXPIRE); getExpiredLeasesCommon(expired_leases, max_leases, GET_LEASE4_EXPIRE);
} }
void
MySqlLeaseMgr::getExpiredLeases6(Lease6Collection& expired_leases,
const size_t max_leases) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MYSQL_GET_EXPIRED6)
.arg(max_leases);
getExpiredLeasesCommon(expired_leases, max_leases, GET_LEASE6_EXPIRE);
}
template<typename LeaseCollection> template<typename LeaseCollection>
void void
MySqlLeaseMgr::getExpiredLeasesCommon(LeaseCollection& expired_leases, MySqlLeaseMgr::getExpiredLeasesCommon(LeaseCollection& expired_leases,
@ -2147,6 +2147,24 @@ MySqlLeaseMgr::deleteExpiredReclaimedLeasesCommon(const uint32_t secs,
return (deleted_leases); return (deleted_leases);
} }
LeaseStatsQueryPtr
MySqlLeaseMgr::startLeaseStatsQuery4() {
LeaseStatsQueryPtr query(new MySqlLeaseStatsQuery(conn_,
RECOUNT_LEASE4_STATS,
false));
query->start();
return(query);
}
LeaseStatsQueryPtr
MySqlLeaseMgr::startLeaseStatsQuery6() {
LeaseStatsQueryPtr query(new MySqlLeaseStatsQuery(conn_,
RECOUNT_LEASE6_STATS,
true));
query->start();
return(query);
}
size_t size_t
MySqlLeaseMgr::wipeLeases4(const SubnetID& /*subnet_id*/) { MySqlLeaseMgr::wipeLeases4(const SubnetID& /*subnet_id*/) {
isc_throw(NotImplemented, "wipeLeases4 is not implemented for MySQL backend"); isc_throw(NotImplemented, "wipeLeases4 is not implemented for MySQL backend");
@ -2227,24 +2245,6 @@ MySqlLeaseMgr::getVersion() const {
return (std::make_pair(major, minor)); return (std::make_pair(major, minor));
} }
LeaseStatsQueryPtr
MySqlLeaseMgr::startLeaseStatsQuery4() {
LeaseStatsQueryPtr query(new MySqlLeaseStatsQuery(conn_,
RECOUNT_LEASE4_STATS,
false));
query->start();
return(query);
}
LeaseStatsQueryPtr
MySqlLeaseMgr::startLeaseStatsQuery6() {
LeaseStatsQueryPtr query(new MySqlLeaseStatsQuery(conn_,
RECOUNT_LEASE6_STATS,
true));
query->start();
return(query);
}
void void
MySqlLeaseMgr::commit() { MySqlLeaseMgr::commit() {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MYSQL_COMMIT); LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MYSQL_COMMIT);

View File

@ -268,20 +268,6 @@ public:
virtual Lease6Collection getLeases6(Lease::Type type, const DUID& duid, virtual Lease6Collection getLeases6(Lease::Type type, const DUID& duid,
uint32_t iaid, SubnetID subnet_id) const; uint32_t iaid, SubnetID subnet_id) const;
/// @brief Returns a collection of expired DHCPv6 leases.
///
/// This method returns at most @c max_leases expired leases. The leases
/// returned haven't been reclaimed, i.e. the database query must exclude
/// reclaimed leases from the results returned.
///
/// @param [out] expired_leases A container to which expired leases returned
/// by the database backend are added.
/// @param max_leases A maximum number of leases to be returned. If this
/// value is set to 0, all expired (but not reclaimed) leases are returned.
virtual void getExpiredLeases6(Lease6Collection& expired_leases,
const size_t max_leases) const;
/// @brief Returns a collection of expired DHCPv4 leases. /// @brief Returns a collection of expired DHCPv4 leases.
/// ///
/// This method returns at most @c max_leases expired leases. The leases /// This method returns at most @c max_leases expired leases. The leases
@ -295,6 +281,19 @@ public:
virtual void getExpiredLeases4(Lease4Collection& expired_leases, virtual void getExpiredLeases4(Lease4Collection& expired_leases,
const size_t max_leases) const; const size_t max_leases) const;
/// @brief Returns a collection of expired DHCPv6 leases.
///
/// This method returns at most @c max_leases expired leases. The leases
/// returned haven't been reclaimed, i.e. the database query must exclude
/// reclaimed leases from the results returned.
///
/// @param [out] expired_leases A container to which expired leases returned
/// by the database backend are added.
/// @param max_leases A maximum number of leases to be returned. If this
/// value is set to 0, all expired (but not reclaimed) leases are returned.
virtual void getExpiredLeases6(Lease6Collection& expired_leases,
const size_t max_leases) const;
/// @brief Updates IPv4 lease. /// @brief Updates IPv4 lease.
/// ///
/// Updates the record of the lease in the database (as identified by the /// Updates the record of the lease in the database (as identified by the
@ -341,6 +340,35 @@ public:
/// @return Number of leases deleted. /// @return Number of leases deleted.
virtual uint64_t deleteExpiredReclaimedLeases4(const uint32_t secs); virtual uint64_t deleteExpiredReclaimedLeases4(const uint32_t secs);
/// @brief Deletes all expired-reclaimed DHCPv6 leases.
///
/// @param secs Number of seconds since expiration of leases before
/// they can be removed. Leases which have expired later than this
/// time will not be deleted.
///
/// @return Number of leases deleted.
virtual uint64_t deleteExpiredReclaimedLeases6(const uint32_t secs);
/// @brief Creates and runs the IPv4 lease stats query
///
/// It creates an instance of a MySqlLeaseStatsQuery4 and then
/// invokes its start method, which fetches its statistical data
/// result set by executing the RECOUNT_LEASE_STATS4 query.
/// The query object is then returned.
///
/// @return The populated query as a pointer to an LeaseStatsQuery
virtual LeaseStatsQueryPtr startLeaseStatsQuery4();
/// @brief Creates and runs the IPv6 lease stats query
///
/// It creates an instance of a MySqlLeaseStatsQuery6 and then
/// invokes its start method, which fetches its statistical data
/// result set by executing the RECOUNT_LEASE_STATS6 query.
/// The query object is then returned.
///
/// @return The populated query as a pointer to an LeaseStatsQuery
virtual LeaseStatsQueryPtr startLeaseStatsQuery6();
/// @brief Removes specified IPv4 leases. /// @brief Removes specified IPv4 leases.
/// ///
/// This rather dangerous method is able to remove all leases from specified /// This rather dangerous method is able to remove all leases from specified
@ -363,15 +391,6 @@ public:
/// @return number of leases removed. /// @return number of leases removed.
virtual size_t wipeLeases6(const SubnetID& subnet_id); virtual size_t wipeLeases6(const SubnetID& subnet_id);
/// @brief Deletes all expired-reclaimed DHCPv6 leases.
///
/// @param secs Number of seconds since expiration of leases before
/// they can be removed. Leases which have expired later than this
/// time will not be deleted.
///
/// @return Number of leases deleted.
virtual uint64_t deleteExpiredReclaimedLeases6(const uint32_t secs);
/// @brief Return backend type /// @brief Return backend type
/// ///
/// Returns the type of the backend (e.g. "mysql", "memfile" etc.) /// Returns the type of the backend (e.g. "mysql", "memfile" etc.)
@ -627,26 +646,6 @@ private:
uint64_t deleteExpiredReclaimedLeasesCommon(const uint32_t secs, uint64_t deleteExpiredReclaimedLeasesCommon(const uint32_t secs,
StatementIndex statement_index); StatementIndex statement_index);
/// @brief Creates and runs the IPv4 lease stats query
///
/// It creates an instance of a MySqlLeaseStatsQuery4 and then
/// invokes its start method, which fetches its statistical data
/// result set by executing the RECOUNT_LEASE_STATS4 query.
/// The query object is then returned.
///
/// @return The populated query as a pointer to an LeaseStatsQuery
virtual LeaseStatsQueryPtr startLeaseStatsQuery4();
/// @brief Creates and runs the IPv6 lease stats query
///
/// It creates an instance of a MySqlLeaseStatsQuery6 and then
/// invokes its start method, which fetches its statistical data
/// result set by executing the RECOUNT_LEASE_STATS6 query.
/// The query object is then returned.
///
/// @return The populated query as a pointer to an LeaseStatsQuery
virtual LeaseStatsQueryPtr startLeaseStatsQuery6();
/// @brief Check Error and Throw Exception /// @brief Check Error and Throw Exception
/// ///
/// This method invokes @ref MySqlConnection::checkError. /// This method invokes @ref MySqlConnection::checkError.

View File

@ -418,7 +418,6 @@ protected:
HostPtr host_; HostPtr host_;
}; };
/// @brief Extends base exchange class with ability to retrieve DHCP options /// @brief Extends base exchange class with ability to retrieve DHCP options
/// from the 'dhcp4_options' and 'dhcp6_options' tables. /// from the 'dhcp4_options' and 'dhcp6_options' tables.
/// ///
@ -1009,7 +1008,6 @@ private:
/// @brief Reservation id for last processed row. /// @brief Reservation id for last processed row.
uint64_t most_recent_reservation_id_; uint64_t most_recent_reservation_id_;
}; };
/// @brief This class is used for storing IPv6 reservations in a PgSQL database. /// @brief This class is used for storing IPv6 reservations in a PgSQL database.
@ -1240,7 +1238,6 @@ private:
} // end of anonymous namespace } // end of anonymous namespace
namespace isc { namespace isc {
namespace dhcp { namespace dhcp {
@ -1762,7 +1759,6 @@ PgSqlHostDataSourceImpl::addStatement(StatementIndex stindex,
} }
return (last_id); return (last_id);
} }
bool bool
@ -1921,10 +1917,8 @@ PgSqlHostDataSourceImpl::checkReadOnly() const {
} }
} }
/*********** PgSqlHostDataSource *********************/ /*********** PgSqlHostDataSource *********************/
PgSqlHostDataSource:: PgSqlHostDataSource::
PgSqlHostDataSource(const PgSqlConnection::ParameterMap& parameters) PgSqlHostDataSource(const PgSqlConnection::ParameterMap& parameters)
: impl_(new PgSqlHostDataSourceImpl(parameters)) { : impl_(new PgSqlHostDataSourceImpl(parameters)) {
@ -2020,7 +2014,6 @@ PgSqlHostDataSource::del4(const SubnetID& subnet_id,
return (impl_->delStatement(PgSqlHostDataSourceImpl::DEL_HOST_SUBID4_ID, return (impl_->delStatement(PgSqlHostDataSourceImpl::DEL_HOST_SUBID4_ID,
bind_array)); bind_array));
} }
bool bool
@ -2041,7 +2034,6 @@ PgSqlHostDataSource::del6(const SubnetID& subnet_id,
return (impl_->delStatement(PgSqlHostDataSourceImpl::DEL_HOST_SUBID6_ID, return (impl_->delStatement(PgSqlHostDataSourceImpl::DEL_HOST_SUBID6_ID,
bind_array)); bind_array));
} }
ConstHostCollection ConstHostCollection
@ -2287,7 +2279,6 @@ PgSqlHostDataSource::commit() {
impl_->conn_.commit(); impl_->conn_.commit();
} }
void void
PgSqlHostDataSource::rollback() { PgSqlHostDataSource::rollback() {
// If operating in read-only mode, throw exception. // If operating in read-only mode, throw exception.

View File

@ -64,6 +64,83 @@ public:
/// the destruction of member impl_. /// the destruction of member impl_.
virtual ~PgSqlHostDataSource(); virtual ~PgSqlHostDataSource();
/// @brief Adds a new host to the collection.
///
/// The method will insert the given host and all of its children (v4
/// options, v6 options, and v6 reservations) into the database. It
/// relies on constraints defined as part of the PostgreSQL schema to
/// defend against duplicate entries and to ensure referential
/// integrity.
///
/// Violation of any of these constraints for a host will result in a
/// DuplicateEntry exception:
///
/// -# IPV4_ADDRESS and DHCP4_SUBNET_ID combination must be unique
/// -# IPV6 ADDRESS and PREFIX_LEN combination must be unique
/// -# DHCP ID, DHCP ID TYPE, and DHCP4_SUBNET_ID combination must be unique
/// -# DHCP ID, DHCP ID TYPE, and DHCP6_SUBNET_ID combination must be unique
///
/// In addition, violating the following referential constraints will
/// a DbOperationError exception:
///
/// -# DHCP ID TYPE must be defined in the HOST_IDENTIFIER_TYPE table
/// -# For DHCP4 Options:
/// -# HOST_ID must exist with HOSTS
/// -# SCOPE_ID must be defined in DHCP_OPTION_SCOPE
/// -# For DHCP6 Options:
/// -# HOST_ID must exist with HOSTS
/// -# SCOPE_ID must be defined in DHCP_OPTION_SCOPE
/// -# For IPV6 Reservations:
/// -# HOST_ID must exist with HOSTS
/// -# Address and Prefix Length must be unique (DuplicateEntry)
///
/// @param host Pointer to the new @c Host object being added.
/// @throw DuplicateEntry or DbOperationError dependent on the constraint
/// violation
virtual void add(const HostPtr& host);
/// @brief Attempts to delete a host by (subnet-id, address)
///
/// This method supports both v4 and v6.
///
/// @param subnet_id subnet identifier.
/// @param addr specified address.
/// @return true if deletion was successful, false if the host was not there.
/// @throw various exceptions in case of errors
virtual bool del(const SubnetID& subnet_id, const asiolink::IOAddress& addr);
/// @brief Attempts to delete a host by (subnet4-id, identifier type, identifier)
///
/// This method supports v4 hosts only.
///
/// @param subnet_id subnet identifier.
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
///
/// @return true if deletion was successful, false if the host was not there.
/// @throw various exceptions in case of errors
virtual bool del4(const SubnetID& subnet_id,
const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin, const size_t identifier_len);
/// @brief Attempts to delete a host by (subnet6-id, identifier type, identifier)
///
/// This method supports v6 hosts only.
///
/// @param subnet_id subnet identifier.
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
///
/// @return true if deletion was successful, false if the host was not there.
/// @throw various exceptions in case of errors
virtual bool del6(const SubnetID& subnet_id,
const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin, const size_t identifier_len);
/// @brief Return all hosts for the specified HW address or DUID. /// @brief Return all hosts for the specified HW address or DUID.
/// ///
/// This method returns all @c Host objects which represent reservations /// This method returns all @c Host objects which represent reservations
@ -216,83 +293,6 @@ public:
virtual ConstHostPtr virtual ConstHostPtr
get6(const SubnetID& subnet_id, const asiolink::IOAddress& address) const; get6(const SubnetID& subnet_id, const asiolink::IOAddress& address) const;
/// @brief Adds a new host to the collection.
///
/// The method will insert the given host and all of its children (v4
/// options, v6 options, and v6 reservations) into the database. It
/// relies on constraints defined as part of the PostgreSQL schema to
/// defend against duplicate entries and to ensure referential
/// integrity.
///
/// Violation of any of these constraints for a host will result in a
/// DuplicateEntry exception:
///
/// -# IPV4_ADDRESS and DHCP4_SUBNET_ID combination must be unique
/// -# IPV6 ADDRESS and PREFIX_LEN combination must be unique
/// -# DHCP ID, DHCP ID TYPE, and DHCP4_SUBNET_ID combination must be unique
/// -# DHCP ID, DHCP ID TYPE, and DHCP6_SUBNET_ID combination must be unique
///
/// In addition, violating the following referential constraints will
/// a DbOperationError exception:
///
/// -# DHCP ID TYPE must be defined in the HOST_IDENTIFIER_TYPE table
/// -# For DHCP4 Options:
/// -# HOST_ID must exist with HOSTS
/// -# SCOPE_ID must be defined in DHCP_OPTION_SCOPE
/// -# For DHCP6 Options:
/// -# HOST_ID must exist with HOSTS
/// -# SCOPE_ID must be defined in DHCP_OPTION_SCOPE
/// -# For IPV6 Reservations:
/// -# HOST_ID must exist with HOSTS
/// -# Address and Prefix Length must be unique (DuplicateEntry)
///
/// @param host Pointer to the new @c Host object being added.
/// @throw DuplicateEntry or DbOperationError dependent on the constraint
/// violation
virtual void add(const HostPtr& host);
/// @brief Attempts to delete a host by (subnet-id, address)
///
/// This method supports both v4 and v6.
///
/// @param subnet_id subnet identifier.
/// @param addr specified address.
/// @return true if deletion was successful, false if the host was not there.
/// @throw various exceptions in case of errors
virtual bool del(const SubnetID& subnet_id, const asiolink::IOAddress& addr);
/// @brief Attempts to delete a host by (subnet4-id, identifier type, identifier)
///
/// This method supports v4 hosts only.
///
/// @param subnet_id subnet identifier.
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
///
/// @return true if deletion was successful, false if the host was not there.
/// @throw various exceptions in case of errors
virtual bool del4(const SubnetID& subnet_id,
const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin, const size_t identifier_len);
/// @brief Attempts to delete a host by (subnet6-id, identifier type, identifier)
///
/// This method supports v6 hosts only.
///
/// @param subnet_id subnet identifier.
/// @param identifier_type Identifier type.
/// @param identifier_begin Pointer to a beginning of a buffer containing
/// an identifier.
/// @param identifier_len Identifier length.
///
/// @return true if deletion was successful, false if the host was not there.
/// @throw various exceptions in case of errors
virtual bool del6(const SubnetID& subnet_id,
const Host::IdentifierType& identifier_type,
const uint8_t* identifier_begin, const size_t identifier_len);
/// @brief Return backend type /// @brief Return backend type
/// ///
/// Returns the type of database as the string "postgresql". This is /// Returns the type of database as the string "postgresql". This is
@ -336,7 +336,6 @@ public:
virtual void rollback(); virtual void rollback();
private: private:
/// @brief Pointer to the implementation of the @ref PgSqlHostDataSource. /// @brief Pointer to the implementation of the @ref PgSqlHostDataSource.
PgSqlHostDataSourceImpl* impl_; PgSqlHostDataSourceImpl* impl_;
}; };

View File

@ -26,7 +26,7 @@ using namespace std;
namespace { namespace {
/// @todo TKM lease6 needs to accommodate hwaddr,hwtype, and hwaddr source /// @todo TKM lease6 needs to accommodate hwaddr, hwtype, and hwaddr source
/// columns. This is covered by tickets #3557, #4530, and PR#9. /// columns. This is covered by tickets #3557, #4530, and PR#9.
/// @brief Catalog of all the SQL statements currently supported. Note /// @brief Catalog of all the SQL statements currently supported. Note
@ -1056,6 +1056,16 @@ PgSqlLeaseMgr::getLease4(const ClientId& clientid) const {
return (result); return (result);
} }
Lease4Ptr
PgSqlLeaseMgr::getLease4(const ClientId&, const HWAddr&, SubnetID) const {
/// This function is currently not implemented because allocation engine
/// searches for the lease using HW address or client identifier.
/// It never uses both parameters in the same time. We need to
/// consider if this function is needed at all.
isc_throw(NotImplemented, "The PgSqlLeaseMgr::getLease4 function was"
" called, but it is not implemented");
}
Lease4Ptr Lease4Ptr
PgSqlLeaseMgr::getLease4(const ClientId& clientid, SubnetID subnet_id) const { PgSqlLeaseMgr::getLease4(const ClientId& clientid, SubnetID subnet_id) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
@ -1079,16 +1089,6 @@ PgSqlLeaseMgr::getLease4(const ClientId& clientid, SubnetID subnet_id) const {
return (result); return (result);
} }
Lease4Ptr
PgSqlLeaseMgr::getLease4(const ClientId&, const HWAddr&, SubnetID) const {
/// This function is currently not implemented because allocation engine
/// searches for the lease using HW address or client identifier.
/// It never uses both parameters in the same time. We need to
/// consider if this function is needed at all.
isc_throw(NotImplemented, "The PgSqlLeaseMgr::getLease4 function was"
" called, but it is not implemented");
}
Lease4Collection Lease4Collection
PgSqlLeaseMgr::getLeases4(SubnetID subnet_id) const { PgSqlLeaseMgr::getLeases4(SubnetID subnet_id) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_PGSQL_GET_SUBID4) LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_PGSQL_GET_SUBID4)
@ -1205,14 +1205,6 @@ PgSqlLeaseMgr::getLeases6(Lease::Type lease_type, const DUID& duid,
return (result); return (result);
} }
void
PgSqlLeaseMgr::getExpiredLeases6(Lease6Collection& expired_leases,
const size_t max_leases) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_PGSQL_GET_EXPIRED6)
.arg(max_leases);
getExpiredLeasesCommon(expired_leases, max_leases, GET_LEASE6_EXPIRE);
}
void void
PgSqlLeaseMgr::getExpiredLeases4(Lease4Collection& expired_leases, PgSqlLeaseMgr::getExpiredLeases4(Lease4Collection& expired_leases,
const size_t max_leases) const { const size_t max_leases) const {
@ -1221,6 +1213,14 @@ PgSqlLeaseMgr::getExpiredLeases4(Lease4Collection& expired_leases,
getExpiredLeasesCommon(expired_leases, max_leases, GET_LEASE4_EXPIRE); getExpiredLeasesCommon(expired_leases, max_leases, GET_LEASE4_EXPIRE);
} }
void
PgSqlLeaseMgr::getExpiredLeases6(Lease6Collection& expired_leases,
const size_t max_leases) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_PGSQL_GET_EXPIRED6)
.arg(max_leases);
getExpiredLeasesCommon(expired_leases, max_leases, GET_LEASE6_EXPIRE);
}
template<typename LeaseCollection> template<typename LeaseCollection>
void void
PgSqlLeaseMgr::getExpiredLeasesCommon(LeaseCollection& expired_leases, PgSqlLeaseMgr::getExpiredLeasesCommon(LeaseCollection& expired_leases,

View File

@ -161,18 +161,6 @@ public:
virtual Lease4Ptr getLease4(const ClientId& client_id, const HWAddr& hwaddr, virtual Lease4Ptr getLease4(const ClientId& client_id, const HWAddr& hwaddr,
SubnetID subnet_id) const; SubnetID subnet_id) const;
/// @brief Returns all IPv4 leases for the particular subnet identifier.
///
/// @param subnet_id subnet identifier.
///
/// @return Lease collection (may be empty if no IPv4 lease found).
virtual Lease4Collection getLeases4(SubnetID subnet_id) const;
/// @brief Returns all IPv4 leases.
///
/// @return Lease collection (may be empty if no IPv4 lease found).
virtual Lease4Collection getLeases4() const;
/// @brief Returns existing IPv4 lease for specified client-id /// @brief Returns existing IPv4 lease for specified client-id
/// ///
/// There can be at most one lease for a given HW address in a single /// There can be at most one lease for a given HW address in a single
@ -188,6 +176,18 @@ public:
virtual Lease4Ptr getLease4(const ClientId& clientid, virtual Lease4Ptr getLease4(const ClientId& clientid,
SubnetID subnet_id) const; SubnetID subnet_id) const;
/// @brief Returns all IPv4 leases for the particular subnet identifier.
///
/// @param subnet_id subnet identifier.
///
/// @return Lease collection (may be empty if no IPv4 lease found).
virtual Lease4Collection getLeases4(SubnetID subnet_id) const;
/// @brief Returns all IPv4 leases.
///
/// @return Lease collection (may be empty if no IPv4 lease found).
virtual Lease4Collection getLeases4() const;
/// @brief Returns existing IPv6 lease for a given IPv6 address. /// @brief Returns existing IPv6 lease for a given IPv6 address.
/// ///
/// For a given address, we assume that there will be only one lease. /// For a given address, we assume that there will be only one lease.
@ -242,20 +242,6 @@ public:
virtual Lease6Collection getLeases6(Lease::Type type, const DUID& duid, virtual Lease6Collection getLeases6(Lease::Type type, const DUID& duid,
uint32_t iaid, SubnetID subnet_id) const; uint32_t iaid, SubnetID subnet_id) const;
/// @brief Returns a collection of expired DHCPv6 leases.
///
/// This method returns at most @c max_leases expired leases. The leases
/// returned haven't been reclaimed, i.e. the database query must exclude
/// reclaimed leases from the results returned.
///
/// @param [out] expired_leases A container to which expired leases returned
/// by the database backend are added.
/// @param max_leases A maximum number of leases to be returned. If this
/// value is set to 0, all expired (but not reclaimed) leases are returned.
virtual void getExpiredLeases6(Lease6Collection& expired_leases,
const size_t max_leases) const;
/// @brief Returns a collection of expired DHCPv4 leases. /// @brief Returns a collection of expired DHCPv4 leases.
/// ///
/// This method returns at most @c max_leases expired leases. The leases /// This method returns at most @c max_leases expired leases. The leases
@ -269,6 +255,19 @@ public:
virtual void getExpiredLeases4(Lease4Collection& expired_leases, virtual void getExpiredLeases4(Lease4Collection& expired_leases,
const size_t max_leases) const; const size_t max_leases) const;
/// @brief Returns a collection of expired DHCPv6 leases.
///
/// This method returns at most @c max_leases expired leases. The leases
/// returned haven't been reclaimed, i.e. the database query must exclude
/// reclaimed leases from the results returned.
///
/// @param [out] expired_leases A container to which expired leases returned
/// by the database backend are added.
/// @param max_leases A maximum number of leases to be returned. If this
/// value is set to 0, all expired (but not reclaimed) leases are returned.
virtual void getExpiredLeases6(Lease6Collection& expired_leases,
const size_t max_leases) const;
/// @brief Updates IPv4 lease. /// @brief Updates IPv4 lease.
/// ///
/// Updates the record of the lease in the database (as identified by the /// Updates the record of the lease in the database (as identified by the

View File

@ -131,6 +131,8 @@ CREATE TABLE IF NOT EXISTS lease_hwaddr_source (
PRIMARY KEY ((hwaddr_source)) PRIMARY KEY ((hwaddr_source))
); );
INSERT INTO lease_hwaddr_source (hwaddr_source, name) VALUES (0, 'HWADDR_SOURCE_UNKNOWN');
-- Hardware address obtained from raw sockets -- Hardware address obtained from raw sockets
INSERT INTO lease_hwaddr_source (hwaddr_source, name) VALUES (1, 'HWADDR_SOURCE_RAW'); INSERT INTO lease_hwaddr_source (hwaddr_source, name) VALUES (1, 'HWADDR_SOURCE_RAW');
@ -194,12 +196,17 @@ INSERT INTO schema_version (version, minor) VALUES (1, 0);
-- Table `host_reservations` -- Table `host_reservations`
-- ----------------------------------------------------- -- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS host_reservations ( CREATE TABLE IF NOT EXISTS host_reservations (
id bigint,
host_identifier blob, host_identifier blob,
host_identifier_type int, host_identifier_type int,
host_ipv4_subnet_id int, host_ipv4_subnet_id int,
host_ipv6_subnet_id int, host_ipv6_subnet_id int,
host_ipv4_address int, host_ipv4_address int,
host_ipv4_next_server int,
host_ipv4_server_hostname text,
host_ipv4_boot_file_name text,
hostname text, hostname text,
user_context text,
host_ipv4_client_classes text, host_ipv4_client_classes text,
host_ipv6_client_classes text, host_ipv6_client_classes text,
-- reservation -- reservation
@ -216,7 +223,8 @@ CREATE TABLE IF NOT EXISTS host_reservations (
option_is_persistent boolean, option_is_persistent boolean,
option_client_class text, option_client_class text,
option_subnet_id int, option_subnet_id int,
id bigint, option_user_context text,
option_scope_id int,
PRIMARY KEY ((id)) PRIMARY KEY ((id))
); );
@ -228,8 +236,39 @@ CREATE INDEX IF NOT EXISTS host_reservationsindex5 ON host_reservations (host_ip
CREATE INDEX IF NOT EXISTS host_reservationsindex6 ON host_reservations (reserved_ipv6_prefix_address); CREATE INDEX IF NOT EXISTS host_reservationsindex6 ON host_reservations (reserved_ipv6_prefix_address);
CREATE INDEX IF NOT EXISTS host_reservationsindex7 ON host_reservations (reserved_ipv6_prefix_length); CREATE INDEX IF NOT EXISTS host_reservationsindex7 ON host_reservations (reserved_ipv6_prefix_length);
TRUNCATE SCHEMA_VERSION; --
-- Table structure for table host_identifier_type.
--
CREATE TABLE IF NOT EXISTS host_identifier_type (
type int,
name varchar,
PRIMARY KEY ((type))
);
-- Insert currently defined type names.
INSERT INTO host_identifier_type (type, name) VALUES (0, 'hw-address');
INSERT INTO host_identifier_type (type, name) VALUES (1, 'duid');
INSERT INTO host_identifier_type (type, name) VALUES (2, 'circuit-id');
INSERT INTO host_identifier_type (type, name) VALUES (3, 'client-id');
INSERT INTO host_identifier_type (type, name) VALUES (4, 'flex-id');
--
-- Table structure for table dhcp_option_scope.
--
CREATE TABLE IF NOT EXISTS dhcp_option_scope (
scope_id int,
scope_name varchar,
PRIMARY KEY ((scope_name))
);
INSERT INTO dhcp_option_scope (scope_id, scope_name) VALUES (0, 'global');
INSERT INTO dhcp_option_scope (scope_id, scope_name) VALUES (1, 'subnet');
INSERT INTO dhcp_option_scope (scope_id, scope_name) VALUES (2, 'client-class');
INSERT INTO dhcp_option_scope (scope_id, scope_name) VALUES (3, 'host');
DELETE FROM schema_version WHERE version=1;
INSERT INTO schema_version (version, minor) VALUES(2, 0); INSERT INTO schema_version (version, minor) VALUES(2, 0);
-- This line concludes database upgrade to version 2.0 -- This line concludes database upgrade to version 2.0

View File

@ -22,20 +22,26 @@ cqlsh "$@" <<EOF
-- ----------------------------------------------------- -- -----------------------------------------------------
-- Table \`host_reservations\` -- Table \`host_reservations\`
-- ----------------------------------------------------- -- -----------------------------------------------------
CREATE TABLE host_reservations ( CREATE TABLE IF NOT EXISTS host_reservations (
id bigint, id bigint,
host_identifier blob, host_identifier blob,
host_identifier_type int, host_identifier_type int,
host_ipv4_subnet_id int, host_ipv4_subnet_id int,
host_ipv6_subnet_id int, host_ipv6_subnet_id int,
host_ipv4_address int, host_ipv4_address int,
host_ipv4_next_server int,
host_ipv4_server_hostname text,
host_ipv4_boot_file_name text,
hostname text, hostname text,
user_context text,
host_ipv4_client_classes text, host_ipv4_client_classes text,
host_ipv6_client_classes text, host_ipv6_client_classes text,
-- reservation
reserved_ipv6_prefix_address text, reserved_ipv6_prefix_address text,
reserved_ipv6_prefix_length int, reserved_ipv6_prefix_length int,
reserved_ipv6_prefix_address_type int, reserved_ipv6_prefix_address_type int,
iaid int, iaid int,
-- option
option_universe int, option_universe int,
option_code int, option_code int,
option_value blob, option_value blob,
@ -44,8 +50,11 @@ CREATE TABLE host_reservations (
option_is_persistent boolean, option_is_persistent boolean,
option_client_class text, option_client_class text,
option_subnet_id int, option_subnet_id int,
PRIMARY KEY (id) option_user_context text,
option_scope_id int,
PRIMARY KEY ((id))
); );
CREATE INDEX IF NOT EXISTS host_reservationsindex1 ON host_reservations (host_identifier); CREATE INDEX IF NOT EXISTS host_reservationsindex1 ON host_reservations (host_identifier);
CREATE INDEX IF NOT EXISTS host_reservationsindex2 ON host_reservations (host_identifier_type); CREATE INDEX IF NOT EXISTS host_reservationsindex2 ON host_reservations (host_identifier_type);
CREATE INDEX IF NOT EXISTS host_reservationsindex3 ON host_reservations (host_ipv4_subnet_id); CREATE INDEX IF NOT EXISTS host_reservationsindex3 ON host_reservations (host_ipv4_subnet_id);
@ -54,6 +63,38 @@ CREATE INDEX IF NOT EXISTS host_reservationsindex5 ON host_reservations (host_ip
CREATE INDEX IF NOT EXISTS host_reservationsindex6 ON host_reservations (reserved_ipv6_prefix_address); CREATE INDEX IF NOT EXISTS host_reservationsindex6 ON host_reservations (reserved_ipv6_prefix_address);
CREATE INDEX IF NOT EXISTS host_reservationsindex7 ON host_reservations (reserved_ipv6_prefix_length); CREATE INDEX IF NOT EXISTS host_reservationsindex7 ON host_reservations (reserved_ipv6_prefix_length);
--
-- Table structure for table host_identifier_type.
--
CREATE TABLE IF NOT EXISTS host_identifier_type (
type int,
name varchar,
PRIMARY KEY ((type))
);
-- Insert currently defined type names.
INSERT INTO host_identifier_type (type, name) VALUES (0, 'hw-address');
INSERT INTO host_identifier_type (type, name) VALUES (1, 'duid');
INSERT INTO host_identifier_type (type, name) VALUES (2, 'circuit-id');
INSERT INTO host_identifier_type (type, name) VALUES (3, 'client-id');
INSERT INTO host_identifier_type (type, name) VALUES (4, 'flex-id');
--
-- Table structure for table dhcp_option_scope.
--
CREATE TABLE IF NOT EXISTS dhcp_option_scope (
scope_id int,
scope_name varchar,
PRIMARY KEY ((scope_name))
);
INSERT INTO dhcp_option_scope (scope_id, scope_name) VALUES (0, 'global');
INSERT INTO dhcp_option_scope (scope_id, scope_name) VALUES (1, 'subnet');
INSERT INTO dhcp_option_scope (scope_id, scope_name) VALUES (2, 'client-class');
INSERT INTO dhcp_option_scope (scope_id, scope_name) VALUES (3, 'host');
DELETE FROM schema_version WHERE version=1; DELETE FROM schema_version WHERE version=1;
INSERT INTO schema_version (version, minor) VALUES(2, 0); INSERT INTO schema_version (version, minor) VALUES(2, 0);

View File

@ -352,6 +352,10 @@ CREATE TABLE lease_hwaddr_source (
name VARCHAR(40) DEFAULT NULL name VARCHAR(40) DEFAULT NULL
); );
-- In the event hardware address cannot be determined, we need to satisfy
-- foreign key constraint between lease6 and lease_hardware_source.
INSERT INTO lease_hwaddr_source VALUES (0, 'HWADDR_SOURCE_UNKNOWN');
-- Hardware address obtained from raw sockets. -- Hardware address obtained from raw sockets.
INSERT INTO lease_hwaddr_source VALUES (1, 'HWADDR_SOURCE_RAW'); INSERT INTO lease_hwaddr_source VALUES (1, 'HWADDR_SOURCE_RAW');
@ -375,10 +379,6 @@ INSERT INTO lease_hwaddr_source VALUES (64, 'HWADDR_SOURCE_DOCSIS_CMTS');
INSERT INTO lease_hwaddr_source VALUES (128, 'HWADDR_SOURCE_DOCSIS_MODEM'); INSERT INTO lease_hwaddr_source VALUES (128, 'HWADDR_SOURCE_DOCSIS_MODEM');
-- In the event hardware address cannot be determined, we need to satisfy
-- foreign key constraint between lease6 and lease_hardware_source.
INSERT INTO lease_hwaddr_source VALUES (0, 'HWADDR_SOURCE_UNKNOWN');
-- Adding ORDER BY clause to sort by lease address. -- Adding ORDER BY clause to sort by lease address.
-- --
-- FUNCTION that returns a result set containing the data for lease4 dumps. -- FUNCTION that returns a result set containing the data for lease4 dumps.

View File

@ -138,6 +138,10 @@ CREATE TABLE lease_hwaddr_source (
name VARCHAR(40) DEFAULT NULL name VARCHAR(40) DEFAULT NULL
); );
-- In the event hardware address cannot be determined, we need to satisfy
-- foreign key constraint between lease6 and lease_hardware_source
INSERT INTO lease_hwaddr_source VALUES (0, 'HWADDR_SOURCE_UNKNOWN');
-- Hardware address obtained from raw sockets -- Hardware address obtained from raw sockets
INSERT INTO lease_hwaddr_source VALUES (1, 'HWADDR_SOURCE_RAW'); INSERT INTO lease_hwaddr_source VALUES (1, 'HWADDR_SOURCE_RAW');
@ -161,10 +165,6 @@ INSERT INTO lease_hwaddr_source VALUES (64, 'HWADDR_SOURCE_DOCSIS_CMTS');
INSERT INTO lease_hwaddr_source VALUES (128, 'HWADDR_SOURCE_DOCSIS_MODEM'); INSERT INTO lease_hwaddr_source VALUES (128, 'HWADDR_SOURCE_DOCSIS_MODEM');
-- In the event hardware address cannot be determined, we need to satisfy
-- foreign key constraint between lease6 and lease_hardware_source
INSERT INTO lease_hwaddr_source VALUES (0, 'HWADDR_SOURCE_UNKNOWN');
-- Adding ORDER BY clause to sort by lease address -- Adding ORDER BY clause to sort by lease address
-- --
-- FUNCTION that returns a result set containing the data for lease4 dumps -- FUNCTION that returns a result set containing the data for lease4 dumps