1-- Copyright (C) 2018-2019 Internet Systems Consortium, Inc. ("ISC")
2-- Copyright (C) 2015-2018 Deutsche Telekom AG.
3
4-- Author: Razvan Becheriu <razvan.becheriu@qualitance.com>
5
6-- Licensed under the Apache License, Version 2.0 (the "License");
7-- you may not use this file except in compliance with the License.
8-- You may obtain a copy of the License at
9
10--           http://www.apache.org/licenses/LICENSE-2.0
11
12-- Unless required by applicable law or agreed to in writing, software
13-- distributed under the License is distributed on an "AS IS" BASIS,
14-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15-- See the License for the specific language governing permissions and
16-- limitations under the License.
17
18-- This is the Kea schema specification for Cassandra CQL.
19
20-- The schema is reasonably portable (with the exception of the engine
21-- specification, which is Cassandra CQL-specific).  Minor changes might be needed for
22-- other databases.
23
24-- To create the schema, either type the command:
25
26-- cqlsh -u <user> -p <password> -k <database> -f dhcpdb_create.cql
27
28-- ... at the command prompt, or log in to the CQL database and at the "cqlsh>"
29-- prompt, issue the command:
30
31-- SOURCE dhcpdb_create.cql
32
33-- This script is also called from kea-admin, see kea-admin db-init cql
34
35-- Over time, Kea database schema will evolve. Each version is marked with
36-- major.minor version. This file is organized sequentially, i.e. database
37-- is initialized to 1.0, then upgraded to 2.0 etc. This may be somewhat
38-- sub-optimal, but it ensues consistency with upgrade scripts. (It is much
39-- easier to maintain init and upgrade scripts if they look the same).
40-- Since initialization is done only once, it's performance is not an issue.
41
42-- This line starts database initialization to 1.0.
43
44-- Holds the IPv4 leases.
45-- -----------------------------------------------------
46-- Table `lease4`
47-- -----------------------------------------------------
48CREATE TABLE IF NOT EXISTS lease4 (
49    address INT,
50    hwaddr BLOB,
51    client_id BLOB,
52    valid_lifetime BIGINT,
53    expire BIGINT,
54    subnet_id INT,
55    fqdn_fwd BOOLEAN,
56    fqdn_rev BOOLEAN,
57    hostname VARCHAR,
58    state INT,
59    PRIMARY KEY ((address))
60);
61
62-- Create search indexes for lease4 table
63CREATE INDEX IF NOT EXISTS lease4index1 ON lease4 (client_id);
64CREATE INDEX IF NOT EXISTS lease4index2 ON lease4 (subnet_id);
65CREATE INDEX IF NOT EXISTS lease4index3 ON lease4 (hwaddr);
66CREATE INDEX IF NOT EXISTS lease4index4 ON lease4 (expire);
67CREATE INDEX IF NOT EXISTS lease4index5 ON lease4 (state);
68
69-- Holds the IPv6 leases.
70-- N.B. The use of a VARCHAR for the address is temporary for development:
71-- it will eventually be replaced by BINARY(16).
72-- -----------------------------------------------------
73-- Table `lease6`
74-- -----------------------------------------------------
75CREATE TABLE IF NOT EXISTS lease6 (
76    address VARCHAR,
77    valid_lifetime BIGINT,
78    expire BIGINT,
79    subnet_id INT,
80    pref_lifetime BIGINT,
81    duid BLOB,
82    iaid INT,
83    lease_type INT,
84    prefix_len INT,
85    fqdn_fwd BOOLEAN,
86    fqdn_rev BOOLEAN,
87    hostname VARCHAR,
88    hwaddr BLOB,
89    hwtype INT,
90    hwaddr_source INT,
91    state INT,
92    PRIMARY KEY ((address))
93);
94
95-- Create search indexes for lease6 table
96CREATE INDEX IF NOT EXISTS lease6index1 ON lease6 (duid);
97CREATE INDEX IF NOT EXISTS lease6index2 ON lease6 (iaid);
98CREATE INDEX IF NOT EXISTS lease6index3 ON lease6 (lease_type);
99CREATE INDEX IF NOT EXISTS lease6index4 ON lease6 (subnet_id);
100CREATE INDEX IF NOT EXISTS lease6index5 ON lease6 (expire);
101CREATE INDEX IF NOT EXISTS lease6index6 ON lease6 (state);
102
103-- ... and a definition of lease6 types.  This table is a convenience for
104-- users of the database - if they want to view the lease table and use the
105-- type names, they can join this table with the lease6 table.
106-- Make sure those values match Lease6::LeaseType enum (see src/bin/dhcpsrv/
107-- lease_mgr.h)
108-- -----------------------------------------------------
109-- Table `lease6_types`
110-- -----------------------------------------------------
111CREATE TABLE IF NOT EXISTS lease6_types (
112    lease_type INT,                             -- Lease type code.
113    name VARCHAR,                               -- Name of the lease type
114    PRIMARY KEY ((lease_type))
115);
116INSERT INTO lease6_types (lease_type, name) VALUES (0, 'IA_NA');   -- Non-temporary v6 addresses
117INSERT INTO lease6_types (lease_type, name) VALUES (1, 'IA_TA');   -- Temporary v6 addresses
118INSERT INTO lease6_types (lease_type, name) VALUES (2, 'IA_PD');   -- Prefix delegations
119
120-- Kea keeps track of the hardware/MAC address source, i.e. how the address
121-- was obtained. Depending on the technique and your network topology, it may
122-- be more or less trustworthy. This table is a convenience for
123-- users of the database - if they want to view the lease table and use the
124-- type names, they can join this table with the lease6 table. For details,
125-- see constants defined in src/lib/dhcp/dhcp/pkt.h for detailed explanation.
126-- -----------------------------------------------------
127-- Table `lease_hwaddr_source`
128-- -----------------------------------------------------
129CREATE TABLE IF NOT EXISTS lease_hwaddr_source (
130    hwaddr_source INT,
131    name VARCHAR,
132    PRIMARY KEY ((hwaddr_source))
133);
134
135INSERT INTO lease_hwaddr_source (hwaddr_source, name) VALUES (0, 'HWADDR_SOURCE_UNKNOWN');
136
137-- Hardware address obtained from raw sockets
138INSERT INTO lease_hwaddr_source (hwaddr_source, name) VALUES (1, 'HWADDR_SOURCE_RAW');
139
140-- Hardware address converted from IPv6 link-local address with EUI-64
141INSERT INTO lease_hwaddr_source (hwaddr_source, name) VALUES (2, 'HWADDR_SOURCE_IPV6_LINK_LOCAL');
142
143-- Hardware address extracted from client-id (duid)
144INSERT INTO lease_hwaddr_source (hwaddr_source, name) VALUES (4, 'HWADDR_SOURCE_DUID');
145
146-- Hardware address extracted from client address relay option (RFC6939)
147INSERT INTO lease_hwaddr_source (hwaddr_source, name) VALUES (8, 'HWADDR_SOURCE_CLIENT_ADDR_RELAY_OPTION');
148
149-- Hardware address extracted from remote-id option (RFC4649)
150INSERT INTO lease_hwaddr_source (hwaddr_source, name) VALUES (16, 'HWADDR_SOURCE_REMOTE_ID');
151
152-- Hardware address extracted from subscriber-id option (RFC4580)
153INSERT INTO lease_hwaddr_source (hwaddr_source, name) VALUES (32, 'HWADDR_SOURCE_SUBSCRIBER_ID');
154
155-- Hardware address extracted from docsis options
156INSERT INTO lease_hwaddr_source (hwaddr_source, name) VALUES (64, 'HWADDR_SOURCE_DOCSIS_CMTS');
157
158INSERT INTO lease_hwaddr_source (hwaddr_source, name) VALUES (128, 'HWADDR_SOURCE_DOCSIS_MODEM');
159
160-- Create table holding mapping of the lease states to their names.
161-- This is not used in queries from the DHCP server but rather in
162-- direct queries from the lease database management tools.
163-- -----------------------------------------------------
164-- Table `lease_state`
165-- -----------------------------------------------------
166CREATE TABLE IF NOT EXISTS lease_state (
167    state INT,
168    name VARCHAR,
169    PRIMARY KEY ((state))
170);
171
172-- Insert currently defined state names.
173INSERT INTO lease_state (state, name) VALUES (0, 'default');
174INSERT INTO lease_state (state, name) VALUES (1, 'declined');
175INSERT INTO lease_state (state, name) VALUES (2, 'expired-reclaimed');
176
177-- Finally, the version of the schema.  We start at 1.0 during development.
178-- This table is only modified during schema upgrades.  For historical reasons
179-- (related to the names of the columns in the BIND 10 DNS database file), the
180-- first column is called "version" and not "major".
181-- -----------------------------------------------------
182-- Table `schema_version`
183-- -----------------------------------------------------
184CREATE TABLE IF NOT EXISTS schema_version (
185    version INT,
186    minor INT,
187    PRIMARY KEY ((version))
188);
189
190INSERT INTO schema_version (version, minor) VALUES (1, 0);
191
192-- This line concludes database initialization to version 1.0.
193
194-- This line starts database upgrade to version 2.0
195
196-- -----------------------------------------------------
197-- Table `host_reservations`
198-- -----------------------------------------------------
199CREATE TABLE IF NOT EXISTS host_reservations (
200    id BIGINT,
201    host_identifier BLOB,
202    host_identifier_type INT,
203    host_ipv4_subnet_id INT,
204    host_ipv6_subnet_id INT,
205    host_ipv4_address INT,
206    host_ipv4_next_server INT,
207    host_ipv4_server_hostname VARCHAR,
208    host_ipv4_boot_file_name VARCHAR,
209    hostname VARCHAR,
210    user_context VARCHAR,
211    host_ipv4_client_classes VARCHAR,
212    host_ipv6_client_classes VARCHAR,
213    -- reservation
214    reserved_ipv6_prefix_address VARCHAR,
215    reserved_ipv6_prefix_length INT,
216    reserved_ipv6_prefix_address_type INT,
217    iaid INT,
218    -- option
219    option_universe INT,
220    option_code INT,
221    option_value BLOB,
222    option_formatted_value VARCHAR,
223    option_space VARCHAR,
224    option_is_persistent BOOLEAN,
225    option_client_class VARCHAR,
226    option_subnet_id INT,
227    option_user_context VARCHAR,
228    option_scope_id INT,
229    PRIMARY KEY ((id))
230);
231
232CREATE INDEX IF NOT EXISTS host_reservationsindex1 ON host_reservations (host_identifier);
233CREATE INDEX IF NOT EXISTS host_reservationsindex2 ON host_reservations (host_identifier_type);
234CREATE INDEX IF NOT EXISTS host_reservationsindex3 ON host_reservations (host_ipv4_subnet_id);
235CREATE INDEX IF NOT EXISTS host_reservationsindex4 ON host_reservations (host_ipv6_subnet_id);
236CREATE INDEX IF NOT EXISTS host_reservationsindex5 ON host_reservations (host_ipv4_address);
237CREATE INDEX IF NOT EXISTS host_reservationsindex6 ON host_reservations (reserved_ipv6_prefix_address);
238CREATE INDEX IF NOT EXISTS host_reservationsindex7 ON host_reservations (reserved_ipv6_prefix_length);
239
240-- -----------------------------------------------------
241-- Table `host_identifier_type`
242-- -----------------------------------------------------
243
244CREATE TABLE IF NOT EXISTS host_identifier_type (
245    type INT,
246    name VARCHAR,
247    PRIMARY KEY ((type))
248);
249
250-- Insert currently defined type names.
251INSERT INTO host_identifier_type (type, name) VALUES (0, 'hw-address');
252INSERT INTO host_identifier_type (type, name) VALUES (1, 'duid');
253INSERT INTO host_identifier_type (type, name) VALUES (2, 'circuit-id');
254INSERT INTO host_identifier_type (type, name) VALUES (3, 'client-id');
255INSERT INTO host_identifier_type (type, name) VALUES (4, 'flex-id');
256
257-- -----------------------------------------------------
258-- Table `dhcp_option_scope`
259-- -----------------------------------------------------
260
261CREATE TABLE IF NOT EXISTS dhcp_option_scope (
262    scope_id INT,
263    scope_name VARCHAR,
264    PRIMARY KEY ((scope_id))
265);
266
267INSERT INTO dhcp_option_scope (scope_id, scope_name) VALUES (0, 'global');
268INSERT INTO dhcp_option_scope (scope_id, scope_name) VALUES (1, 'subnet');
269INSERT INTO dhcp_option_scope (scope_id, scope_name) VALUES (2, 'client-class');
270INSERT INTO dhcp_option_scope (scope_id, scope_name) VALUES (3, 'host');
271
272DELETE FROM schema_version WHERE version=1;
273INSERT INTO schema_version (version, minor) VALUES(2, 0);
274
275-- This line concludes database upgrade to version 2.0
276
277-- This line starts database upgrade to version 3.0
278
279-- Add a column holding leases for user context.
280ALTER TABLE lease4 ADD user_context VARCHAR;
281ALTER TABLE lease6 ADD user_context VARCHAR;
282
283-- -----------------------------------------------------
284-- Table `logs` (logs table is used by forensic logging hook library)
285-- -----------------------------------------------------
286CREATE TABLE IF NOT EXISTS logs (
287    timeuuid TIMEUUID,  -- creation timeuuid, use dateOf() to get timestamp
288    address VARCHAR,    -- address or prefix
289    log VARCHAR,        -- the log itself
290    PRIMARY KEY ((timeuuid))
291);
292
293-- Create search index for logs table
294CREATE INDEX IF NOT EXISTS logsindex ON logs (address);
295
296-- This line adds auth_key column into host reservation table
297ALTER TABLE host_reservations ADD auth_key VARCHAR;
298
299-- Cql requires primary keys in the WHERE here.
300DELETE FROM schema_version WHERE version=2;
301INSERT INTO schema_version (version, minor) VALUES(3, 0);
302
303-- This line concludes database upgrade to version 3.0
304
305-- This line starts database upgrade to version 4.0
306
307-- -----------------------------------------------------
308-- Table `hosts`
309-- -----------------------------------------------------
310CREATE TABLE IF NOT EXISTS hosts (
311    key BIGINT,
312    id BIGINT,
313    host_identifier BLOB,
314    host_identifier_type INT,
315    host_ipv4_subnet_id INT,
316    host_ipv6_subnet_id INT,
317    host_ipv4_address INT,
318    host_ipv4_next_server INT,
319    host_ipv4_server_hostname VARCHAR,
320    host_ipv4_boot_file_name VARCHAR,
321    hostname VARCHAR,
322    auth_key VARCHAR,
323    user_context VARCHAR,
324    host_ipv4_client_classes VARCHAR,
325    host_ipv6_client_classes VARCHAR,
326    -- reservation
327    reserved_ipv6_prefix_address VARCHAR,
328    reserved_ipv6_prefix_length INT,
329    reserved_ipv6_prefix_address_type INT,
330    iaid INT,
331    -- option
332    option_universe INT,
333    option_code INT,
334    option_value BLOB,
335    option_formatted_value VARCHAR,
336    option_space VARCHAR,
337    option_is_persistent BOOLEAN,
338    option_client_class VARCHAR,
339    option_subnet_id INT,
340    option_user_context VARCHAR,
341    option_scope_id INT,
342    PRIMARY KEY ((key), id)
343);
344
345CREATE INDEX IF NOT EXISTS hostsindex1 ON hosts (host_identifier);
346CREATE INDEX IF NOT EXISTS hostsindex2 ON hosts (host_identifier_type);
347CREATE INDEX IF NOT EXISTS hostsindex3 ON hosts (host_ipv4_subnet_id);
348CREATE INDEX IF NOT EXISTS hostsindex4 ON hosts (host_ipv6_subnet_id);
349CREATE INDEX IF NOT EXISTS hostsindex5 ON hosts (host_ipv4_address);
350CREATE INDEX IF NOT EXISTS hostsindex6 ON hosts (reserved_ipv6_prefix_address);
351CREATE INDEX IF NOT EXISTS hostsindex7 ON hosts (reserved_ipv6_prefix_length);
352
353DROP TABLE IF EXISTS host_reservations;
354
355DROP INDEX IF EXISTS host_reservationsindex1;
356DROP INDEX IF EXISTS host_reservationsindex2;
357DROP INDEX IF EXISTS host_reservationsindex3;
358DROP INDEX IF EXISTS host_reservationsindex4;
359DROP INDEX IF EXISTS host_reservationsindex5;
360DROP INDEX IF EXISTS host_reservationsindex6;
361DROP INDEX IF EXISTS host_reservationsindex7;
362
363-- Cql requires primary keys in the WHERE here.
364DELETE FROM schema_version WHERE version=3;
365INSERT INTO schema_version (version, minor) VALUES(4, 0);
366
367-- This line concludes database upgrade to version 4.0
368
369-- This line starts database upgrade to version 5.0
370
371-- Add the lower case hostname column to reservations.
372ALTER TABLE hosts ADD lower_case_hostname VARCHAR;
373
374-- Make the lower case hostname an index.
375CREATE INDEX IF NOT EXISTS hostsindex8 ON hosts (lower_case_hostname);
376
377-- Create a new hostname index on lease4.
378CREATE INDEX IF NOT EXISTS lease4index6 ON lease4 (hostname);
379
380-- Create a new hostname index on lease6.
381CREATE INDEX IF NOT EXISTS lease6index7 ON lease6 (hostname);
382
383DELETE FROM schema_version WHERE version=4;
384INSERT INTO schema_version (version, minor) VALUES(5, 0);
385
386-- This line concludes database upgrade to version 5.0
387