wiki:HostReservationsHowTo

Version 3 (modified by marcin, 3 years ago) (diff)

--

Tips about Host Reservations in Kea 1.1

Introduction

This document has been created while the Kea 1.1.0 was still under development. The Host Reservations appears to be one of the most desired features in Kea 1.1.0 and we continuously receive many questions pertaining to Host Reservations over mailing lists. This document is intended to address some of the most common questions, i.e. how to manage reservations in the SQL database and what SQL queries the server is using to retrieve reservations.

Host Reservations in MySQL Database

Host Reservations Data Structure in MySQL Database

The host reservation information is held in multiple tables within a database:

  • hosts - includes client identification information, subnet identifiers for both DHCPv4 and DHCPv6 client, hostname reserved for a client, IPv4 address reservation and client class names
  • ipv6_reservations - holds IPv6 address and prefix reservations for a client. It provides one-to-many relation with hosts table
  • dhcp4_options - holds DHCPv4 options reserved for a client (one-to-many with hosts table)
  • dhcp6_options - holds DHCPv6 options reserved for a client (one-to-many with hosts table)

In addition, the MySQL schema contains two tables mapping the numeric identifiers to the user friendly text representations:

  • host_identifier_type - contains the mapping of host identifiers to the host identifiers names,
  • dhcp_option_scope - contains the mapping of DHCP option scopes (e.g. global, subnet etc), used in dhcp4_options and dhcp6_options tables, into the scope names.

For any host reservation there must be an entry added into the hosts table. Adding entries into other tables is optional, e.g. if only IPv4 reservation is required for a client there is no entry added into the ipv6_reservations table. Similarly, if there are no client specific options assigned, there are no entries added into the dhcp4_options or dhcp6_options tables.

IPv4 only Reservation

In order to add an IPv4 address and hostname reservation for a client, identified by its MAC address the following MySQL INSERT statement can be used:

START TRANSACTION;
SET @ipv4_reservation='192.0.2.4';
SET @hostname = 'myhost.example.org';
SET @identifier_type='hw-address';
SET @identifier_value='10:20:30:40:50:60';
SET @dhcp4_subnet_id=1;

INSERT INTO hosts (dhcp_identifier,
                   dhcp_identifier_type,
		   dhcp4_subnet_id,
                   ipv4_address,
                   hostname)
VALUES (UNHEX(REPLACE(@identifier_value, ':', '')),
	(SELECT type FROM host_identifier_type WHERE name=@identifier_type),
        @dhcp4_subnet_id,
        INET_ATON(@ipv4_reservation),
        @hostname);

COMMIT;

The reservation will be made for an address of 192.0.2.4 and hostname of myhost.example.org. The identifier type hw-address indicates that the client is identified by its MAC address. The identifier_value specifies the MAC address of the client. The dhcp4_subnet_id must match the identifier of the subnet to which the client is connected. The subnet identifier can be explicitly specified as a parameter of a subnet declaration within the Kea configuration file. This identifier should be used here.

Different identifier types can also be used to create reservations. All supported identifier names can be retrieved from the dhcp_identifier_type table. Note however, that some of them may be specific to DHCPv4 or DHCPv6 only. For example: circuit-id and client-id' are specific to DHCPv4 and must not be used for DHCPv6 reservations.

In order to test that the reservation has been successfully added the following SELECT query can be used:

SELECT 
    HEX(h.dhcp_identifier) AS dhcp_identifier,
    i.name AS dhcp_identifier_name,
    h.dhcp4_subnet_id AS dhcp4_subnet_id,
    INET_NTOA(h.ipv4_address) AS ipv4_address,
    h.hostname AS hostname
FROM
    hosts AS h
        INNER JOIN
    host_identifier_type AS i ON h.dhcp_identifier_type = i.type;

IPv6 only Reservations

A DHCPv6 client can have multiple IPv6 reservations assigned. In this example we'll demonstrate how to make two reservations for a particular client.

The statement will insert a DHCPv6 host and two reservations into the database:

START TRANSACTION;
SET @ipv6_address_reservation='2001:db8:1::100';
SET @ipv6_prefix_reservation='3000:1::';
SET @ipv6_prefix_len_reservation=64;
SET @hostname = 'myhost.example.org';
SET @identifier_type='duid';
-- DUID-EN with ISC enterprise id (2495) --
SET @identifier_value='00:02:00:00:09:BF:10:20:03:04:05:06:07:08';
SET @dhcp6_subnet_id=1;
INSERT INTO hosts (dhcp_identifier,
                   dhcp_identifier_type,
		   dhcp6_subnet_id,
                   hostname)
VALUES (UNHEX(REPLACE(@identifier_value, ':', '')),
		(SELECT type FROM host_identifier_type WHERE name=@identifier_type),
        @dhcp6_subnet_id,
        @hostname);

-- Obtain host_id generated for a newly added host entry. It will be used to associate --
-- IPv6 reservations within the ipv6_reservations table with this host --
SET @inserted_host_id = (SELECT LAST_INSERT_ID());

-- Insert address reservation. Note that 0 indicates address reservation type. --
INSERT INTO ipv6_reservations(address, type, host_id)
VALUES (@ipv6_address_reservation, 0, @inserted_host_id);

-- Insert prefix reservation. The value of 1 indicates prefix reservation type. --
INSERT INTO ipv6_reservations(address, prefix_len, type, host_id)
VALUES (@ipv6_prefix_reservation, @ipv6_prefix_len_reservation, 1, @inserted_host_id);

COMMIT;

Note that it is possible to insert more than one address and prefix reservation for the client.

It is also important to use the correct format of the DUID. The expected format comprises the whole DUID carried in the Client Identifier option. In our example it comprises DUID type = DUID-EN (2 bytes) and the enterprise id (4 bytes), followed by a variable length value.

In order to test that reservations have been added correctly for this client, the following query can be used:

SELECT 
    r.address, r.prefix_len, r.type
FROM
    ipv6_reservations AS r
        INNER JOIN
    hosts AS h ON r.host_id = h.host_id
WHERE
    h.dhcp_identifier = UNHEX(REPLACE(@identifier_value, ':', ''));

DHCPv4 options

TBD