]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#2795] extend impl of BaseHostDataSource::getAll6
authorPiotrek Zadroga <piotrek@isc.org>
Tue, 20 Jun 2023 08:54:38 +0000 (10:54 +0200)
committerPiotrek Zadroga <piotrek@isc.org>
Mon, 26 Jun 2023 15:30:59 +0000 (15:30 +0000)
src/lib/dhcpsrv/mysql_host_data_source.cc
src/lib/dhcpsrv/mysql_host_data_source.h
src/lib/dhcpsrv/pgsql_host_data_source.cc
src/lib/dhcpsrv/pgsql_host_data_source.h

index d18a0a6a1cfe4ac615feba32c8bb87185c2ec156..bf5c541c9c53bd903a9e652051e5741edcba1e17 100644 (file)
@@ -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<char*>
+        (const_cast<char*>(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.
index d5e1b487441b13b407a660b5cb12b872e0a21271..bf99472a99c6908d9ccdd18aa2cabb08f936dc08 100644 (file)
@@ -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.
index 2222672a6547d65aa0ee8f94f3dfd3eaa7d1cd05..d8d636accec8eaab2e5558badca0ec7ce73d90a0 100644 (file)
@@ -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.
index a8a5f221058343ef5d7b032948687037bba2d4ee..9496736c7549439164e60f6ef7954586b6506719 100644 (file)
@@ -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.