From: Piotrek Zadroga Date: Tue, 20 Jun 2023 08:54:38 +0000 (+0200) Subject: [#2795] extend impl of BaseHostDataSource::getAll6 X-Git-Tag: Kea-2.4.0~96 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d00b966b6b3beca4104f08ee8ea0d45c3b7f6b0b;p=thirdparty%2Fkea.git [#2795] extend impl of BaseHostDataSource::getAll6 --- diff --git a/src/lib/dhcpsrv/mysql_host_data_source.cc b/src/lib/dhcpsrv/mysql_host_data_source.cc index d18a0a6a1c..bf5c541c9c 100644 --- a/src/lib/dhcpsrv/mysql_host_data_source.cc +++ b/src/lib/dhcpsrv/mysql_host_data_source.cc @@ -2078,6 +2078,7 @@ public: GET_HOST_SUBID_ADDR, // Gets host by IPv4 SubnetID and IPv4 address GET_HOST_PREFIX, // Gets host by IPv6 prefix GET_HOST_SUBID6_ADDR, // Gets host by IPv6 SubnetID and IPv6 prefix + GET_HOST_ADDR6, // Gets host by IPv6 prefix GET_HOST_SUBID4, // Gets hosts by IPv4 SubnetID GET_HOST_SUBID6, // Gets hosts by IPv6 SubnetID GET_HOST_HOSTNAME, // Gets hosts by hostname @@ -2486,6 +2487,31 @@ TaggedStatementArray tagged_statements = { { "WHERE address = ?) " "ORDER BY h.host_id, o.option_id, r.reservation_id"}, + // Retrieves host information, IPv6 reservations and DHCPv6 options + // associated with a host using IPv6 prefix. This query + // returns host information for a single host. However, multiple rows + // are returned due to left joining IPv6 reservations and DHCPv6 options. + // The number of rows returned is multiplication of number of existing + // IPv6 reservations and DHCPv6 options. + {MySqlHostDataSourceImpl::GET_HOST_ADDR6, + "SELECT h.host_id, h.dhcp_identifier, " + "h.dhcp_identifier_type, h.dhcp4_subnet_id, " + "h.dhcp6_subnet_id, h.ipv4_address, h.hostname, " + "h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, " + "h.dhcp4_next_server, h.dhcp4_server_hostname, " + "h.dhcp4_boot_file_name, h.auth_key, " + "o.option_id, o.code, o.value, o.formatted_value, o.space, " + "o.persistent, o.cancelled, o.user_context, " + "r.reservation_id, r.address, r.prefix_len, r.type, " + "r.dhcp6_iaid " + "FROM hosts AS h " + "LEFT JOIN dhcp6_options AS o " + "ON h.host_id = o.host_id " + "LEFT JOIN ipv6_reservations AS r " + "ON h.host_id = r.host_id " + "WHERE r.address = ? " + "ORDER BY h.host_id, o.option_id, r.reservation_id"}, + // Retrieves host information along with the DHCPv4 options associated with // it. Left joining the dhcp4_options table results in multiple rows being // returned for the same host. Hosts are retrieved by IPv4 subnet id. @@ -3970,6 +3996,36 @@ MySqlHostDataSource::getAll6(const SubnetID& subnet_id, return (collection); } +ConstHostCollection +MySqlHostDataSource::getAll6(const IOAddress& address) const { + if (!address.isV6()) { + isc_throw(BadValue, "MySqlHostDataSource::getAll6(address): " + "wrong address type, address supplied is an IPv4 address"); + } + + // Get a context + MySqlHostContextAlloc get_context(*impl_); + MySqlHostContextPtr ctx = get_context.ctx_; + + // Set up the WHERE clause value + MYSQL_BIND inbind[1]; + memset(inbind, 0, sizeof(inbind)); + + std::string addr6 = address.toText(); + unsigned long addr6_length = addr6.size(); + + inbind[0].buffer_type = MYSQL_TYPE_BLOB; + inbind[0].buffer = reinterpret_cast + (const_cast(addr6.c_str())); + inbind[0].length = &addr6_length; + inbind[0].buffer_length = addr6_length; + + ConstHostCollection collection; + impl_->getHostCollection(ctx, MySqlHostDataSourceImpl::GET_HOST_ADDR6, inbind, + ctx->host_ipv6_exchange_, collection, false); + return (collection); +} + void MySqlHostDataSource::update(HostPtr const& host) { // Get a context. diff --git a/src/lib/dhcpsrv/mysql_host_data_source.h b/src/lib/dhcpsrv/mysql_host_data_source.h index d5e1b48744..bf99472a99 100644 --- a/src/lib/dhcpsrv/mysql_host_data_source.h +++ b/src/lib/dhcpsrv/mysql_host_data_source.h @@ -403,6 +403,29 @@ public: getAll6(const SubnetID& subnet_id, const asiolink::IOAddress& address) const; + /// @brief Returns all hosts having a reservation for a specified + /// address or delegated prefix (lease) in all subnets. + /// + /// In most cases it is desired that there is at most one reservation + /// for a given IPv6 lease within a subnet. In a default configuration, + /// the backend does not allow for inserting more than one host with + /// the same IPv6 address or prefix. + /// + /// If the backend is configured to allow multiple hosts with reservations + /// for the same IPv6 lease in the given subnet, this method can return + /// more than one host per subnet. + /// + /// The typical use case when a single IPv6 lease is reserved for multiple + /// hosts is when these hosts represent different interfaces of the same + /// machine and each interface comes with a different MAC address. In that + /// case, the same IPv6 lease is assigned regardless of which interface is + /// used by the DHCP client to communicate with the server. + /// + /// @param address reserved IPv6 address/prefix. + /// + /// @return Collection of const @c Host objects. + virtual ConstHostCollection getAll6(const asiolink::IOAddress& address) const; + /// @brief Implements @ref BaseHostDataSource::update() for MySQL. /// /// Attempts to update an existing host entry. diff --git a/src/lib/dhcpsrv/pgsql_host_data_source.cc b/src/lib/dhcpsrv/pgsql_host_data_source.cc index 2222672a65..d8d636acce 100644 --- a/src/lib/dhcpsrv/pgsql_host_data_source.cc +++ b/src/lib/dhcpsrv/pgsql_host_data_source.cc @@ -1401,6 +1401,7 @@ public: GET_HOST_SUBID_ADDR, // Gets host by IPv4 SubnetID and IPv4 address GET_HOST_PREFIX, // Gets host by IPv6 prefix GET_HOST_SUBID6_ADDR, // Gets host by IPv6 SubnetID and IPv6 prefix + GET_HOST_ADDR6, // Gets host by IPv6 prefix GET_HOST_SUBID4, // Gets hosts by IPv4 SubnetID GET_HOST_SUBID6, // Gets hosts by IPv6 SubnetID GET_HOST_HOSTNAME, // Gets hosts by hostname @@ -1813,6 +1814,33 @@ TaggedStatementArray tagged_statements = { { "ORDER BY h.host_id, o.option_id, r.reservation_id" }, + // PgSqlHostDataSourceImpl::GET_HOST_ADDR6 + // Retrieves host information, IPv6 reservations and DHCPv6 options + // associated with a host using IPv6 prefix. This query + // returns host information for a single host. However, multiple rows + // are returned due to left joining IPv6 reservations and DHCPv6 options. + // The number of rows returned is multiplication of number of existing + // IPv6 reservations and DHCPv6 options. + {1, + { OID_VARCHAR }, + "get_host_addr6", + "SELECT h.host_id, h.dhcp_identifier, " + " h.dhcp_identifier_type, h.dhcp4_subnet_id, " + " h.dhcp6_subnet_id, h.ipv4_address, h.hostname, " + " h.dhcp4_client_classes, h.dhcp6_client_classes, h.user_context, " + " h.dhcp4_next_server, h.dhcp4_server_hostname, " + " h.dhcp4_boot_file_name, h.auth_key, " + " o.option_id, o.code, o.value, o.formatted_value, o.space, " + " o.persistent, o.cancelled, o.user_context, " + " r.reservation_id, r.address, r.prefix_len, r.type, " + " r.dhcp6_iaid " + "FROM hosts AS h " + "LEFT JOIN dhcp6_options AS o ON h.host_id = o.host_id " + "LEFT JOIN ipv6_reservations AS r ON h.host_id = r.host_id " + "WHERE r.address = $1 " + "ORDER BY h.host_id, o.option_id, r.reservation_id" + }, + // PgSqlHostDataSourceImpl::GET_HOST_SUBID4 // // Retrieves host information for all hosts in a subnet, along with the @@ -3189,6 +3217,29 @@ PgSqlHostDataSource::getAll6(const SubnetID& subnet_id, return (collection); } +ConstHostCollection +PgSqlHostDataSource::getAll6(const IOAddress& address) const { + if (!address.isV6()) { + isc_throw(BadValue, "PgSqlHostDataSource::get6(address): " + "wrong address type, address supplied is an IPv4 address"); + } + + // Get a context + PgSqlHostContextAlloc get_context(*impl_); + PgSqlHostContextPtr ctx = get_context.ctx_; + + // Set up the WHERE clause value + PsqlBindArrayPtr bind_array(new PsqlBindArray()); + + // Add the prefix + bind_array->add(address); + + ConstHostCollection collection; + impl_->getHostCollection(ctx, PgSqlHostDataSourceImpl::GET_HOST_ADDR6, + bind_array, ctx->host_ipv6_exchange_, collection, false); + return (collection); +} + void PgSqlHostDataSource::update(HostPtr const& host) { // Get a context. diff --git a/src/lib/dhcpsrv/pgsql_host_data_source.h b/src/lib/dhcpsrv/pgsql_host_data_source.h index a8a5f22105..9496736c75 100644 --- a/src/lib/dhcpsrv/pgsql_host_data_source.h +++ b/src/lib/dhcpsrv/pgsql_host_data_source.h @@ -451,6 +451,8 @@ public: getAll6(const SubnetID& subnet_id, const asiolink::IOAddress& address) const; + virtual ConstHostCollection getAll6(const asiolink::IOAddress& address) const; + /// @brief Implements @ref BaseHostDataSource::update() for PostgreSQL. /// /// Attempts to update an existing host entry.