dhcp6.dox 18.2 KB
Newer Older
1
// Copyright (C) 2012-2014 Internet Systems Consortium, Inc. ("ISC")
2
3
4
5
6
7
8
9
10
11
12
13
14
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.

15
/**
16
 @page dhcp6 DHCPv6 Server Component
17

18
 Kea offers DHCPv6 server implementation. It is implemented as
19
 kea-dhcp6 component. Its primary code is located in
20
21
22
23
24
25
26
27
28
29
30
 isc::dhcp::Dhcpv6Srv class. It uses \ref libdhcp extensively,
 especially lib::dhcp::Pkt6, isc::dhcp::Option and
 isc::dhcp::IfaceMgr classes. Currently this code offers skeleton
 functionality, i.e. it is able to receive and process incoming
 requests and trasmit responses. However, it does not have database
 management, so it returns only one, hardcoded lease to whoever asks
 for it.

 DHCPv6 server component does not support relayed traffic yet, as
 support for relay decapsulation is not implemented yet.

31
 @section dhcpv6Session Bundy message queue integration
32

33
34
DHCPv4 server now has two configuration backends: JSON and Bundy. The
following section applies only to the Bundy backend.
35

36
 DHCPv6 server component is now integrated with Bundy/BIND10 message queue.
37
38
39
 It follows the same principle as DHCPv4. See \ref dhcpv4Session for
 details.

40
 @section dhcpv6ConfigParser Configuration Parser in DHCPv6
41

42
 kea-dhcp6 compiled with Bundy backend uses Bundy cfgmgr for commands and
43
 configuration. During initial configuration (See \ref
44
45
 isc::dhcp::ControlledDhcpv6Srv::init() in bundy_controller.cc), the configuration handler
 callback is installed (see bundyConfigHandler().
46
47
48
49
 It is called every time there is a new configuration. In particular, it is
 called every time during daemon start process. It contains a
 isc::data::ConstElementPtr to a new configuration.  This simple handler calls
 \ref isc::dhcp::configureDhcp6Server() method that processes received configuration.
50

51
52
 This method iterates over list of received configuration elements and creates a
 list of parsers for each received entry. Parser is an object that is derived
53
 from a DhcpConfigParser class. Once a parser is created
54
 (constructor), its value is set (using build() method). Once all parsers are
55
 build, the configuration is then applied ("committed") and commit() method is
56
 called.
57

58
59
60
61
62
63
 \note With the implementation of the Kea ticket #3534 we're moving away from
 the concept of commit being called for individual parsers. When this ticket
 and a couple of followup tickets are implemented, the commit will be a
 single operation executed for the whole configuration received from many
 parsers.

64
 All parsers are defined in src/bin/dhcp6/config_parser.cc file. Some of them
65
66
67
68
69
70
71
 are generic (e.g. Uint32Parser that is able to handle any
 unsigned 32 bit integer), but some are very specialized (e.g.
 Subnets6ListConfigParser parses definitions of Subnet6 lists). In some cases,
 e.g. subnet6 definitions, the configuration entry is not a simple value, but
 a map or a list itself. In such case, the parser iterates over all elements
 and creates parsers for a given scope. This process may be repeated (sort of)
 recursively.
72

73
 @section dhcpv6ConfigInherit DHCPv6 Configuration Inheritance
74

75
 One notable useful feature of DHCP configuration is its parameter inheritance.
76
77
78
 For example, renew-timer value may be specified at a global scope and it then
 applies to all subnets. However, some subnets may have it overwritten with more
 specific values that takes precedence over global values that are considered
79
80
81
82
83
84
85
 defaults. Some parsers (e.g. Uint32Parser and StringParser) implement that
 inheritance. By default, they store values in global uint32_defaults and
 string_defaults storages. However, it is possible to instruct them to store
 parsed values in more specific storages. That capability is used, e.g. in
 Subnet6ConfigParser that has its own storage that is unique for each subnet.
 Finally, during commit phase (commit() method), appropriate parsers can use
 apply parameter inheritance.
86
87

 Debugging configuration parser may be confusing. Therefore there is a special
88
 class called DebugParser. It does not configure anything, but just
89
90
 accepts any parameter of any type. If requested to commit configuration, it will
 print out received parameter name and its value. This class is not currently used,
91
92
93
94
95
96
97
98
99
 but it is convenient to have it every time a new parameter is added to DHCP
 configuration. For that purpose it should be left in the code.

 Parameter inheritance is done during reconfiguration phase, as reconfigurations
 are rare, so extra logic here is not a problem. On the other hand, values of
 those parameters may be used thousands times per second, so its use must be as
 simple as possible. In fact, currently the code has to call Subnet6->getT1() and
 do not implement any fancy inheritance logic.

100
101
102
@section dhcpv6DDNSIntegration DHCPv6 Server Support for the Dynamic DNS Updates

The DHCPv6 server supports processing of the DHCPv6 Client FQDN Option described in
103
the RFC4704. This Option is sent by the DHCPv6 client to instruct the server to
104
105
106
107
108
update the DNS mappings for the acquired lease. A client may send its fully
qualified domain name, a partial name or it may choose that server will generate
the name. In the last case, the client sends an empty domain-name field in the
DHCPv6 Client FQDN Option.

109
As described in RFC4704, client may choose that the server delegates the forward
110
111
112
113
DNS update to the client and that the server performs the reverse update only. Current
version of the DHCPv6 server does not support delegation of the forward update
to the client. The implementation of this feature is planned for the future releases.

114
115
The kea-dhcp-ddns process is responsible for the actual communication with the DNS
server, i.e. to send DNS Update messages. The kea-dhcp6 module is responsible
116
for generating so called @ref isc::dhcp_ddns::NameChangeRequest and sending it to the
117
kea-dhcp-ddns module. The @ref isc::dhcp_ddns::NameChangeRequest object represents changes to the
118
DNS bindings, related to acquisition, renewal or release of the lease. The kea-dhcp6
119
120
121
122
123
124
125
module implements the simple FIFO queue of the NameChangeRequest objects. The module
logic, which processes the incoming DHCPv6 Client FQDN Options puts these requests
into the FIFO queue.

@todo Currently the FIFO queue is not processed after the NameChangeRequests are
generated and added to it. In the future implementation steps it is planned to create
a code which will check if there are any outstanding requests in the queue and
126
send them to the kea-dhcp-ddns module when server is idle waiting for DHCP messages.
127

128
In the simplest case, when client gets one address from the server, a DHCPv6 server
129
may generate 0, 1 or 2 NameChangeRequests during single message processing.
130
131
Server generates no NameChangeRequests if it is not configured to update DNS
 or it rejects the DNS update for any other reason.
132

133
Server may generate 1 NameChangeRequest in a situation when a client acquires a
134
new lease or it releases an existing lease. In the former case, the NameChangeRequest
135
type is CHG_ADD, which indicates that the kea-dhcp-ddns module should add a new DNS
136
137
binding for the client, and it is assumed that there is no DNS binding for this
client already. In the latter case, the NameChangeRequest type is CHG_REMOVE to
138
indicate to the kea-dhcp-ddns module that the existing DNS binding should be removed
139
140
from the DNS. The binding consists of the forward and reverse mapping.
A server may only remove the mapping which it had added. Therefore, the lease database
141
142
143
144
holds an information which updates (no update, reverse only update, forward only update,
both reverse and forward update) have been performed when the lease was acquired.
Server checks this information to make a decision which mapping it is supposed to
remove when a lease is released.
145
146
147
148
149

Server may generate 2 NameChangeRequests in case the client is renewing a lease and
it already has a DNS binding for that lease. Note, that renewal may be triggered
as a result of sending a RENEW message as well as the REQUEST message. In both cases
DHCPv6 server will check if there is an existing lease for the client which has sent
150
a message, and it will check in the lease database if the DNS Updates had
151
152
153
154
155
156
157
been performed for this client. If the notion of client's FQDN changes comparing to
the information stored in the lease database, the DHCPv6 has to remove an existing
binding from the DNS and then add a new binding according to the new FQDN information
received from the client. If the FQDN sent in the message which triggered a renewal
doesn't change (comparing to the information in the lease database) the NameChangeRequest
is not generated.

158
159
160
161
In the more complex scenarios, when server sends multiple IA_NA options, each holding
multiple IAADDR options, server will generate more NameChangeRequests for a single
message being processed. That is 0, 1, 2 for the individual IA_NA. Generation of
the distinct NameChangeRequests for each IADDR is not supported yet.
162

163
The DHCPv6 Client FQDN Option comprises "NOS" flags which communicate to the
164
server what updates (if any) client expects the server to perform. Server
165
166
167
168
169
170
171
172
173
174
may be configured to obey client's preference or do FQDN processing in a
different way. If the server overrides client's preference it will communicate it
by sending the DHCPv6 Client FQDN Option in its responses to a client, with
appropriate flags set.

@todo Note, that current implementation doesn't allow configuration of the server's behaviour
with respect to DNS Updates. This is planned for the future. The default behaviour is
constituted by the set of constants defined in the (upper part of) dhcp6_srv.cc file.
Once the configuration is implemented, these constants will be removed.

175
176
 @todo Add section about setting up options and their definitions with bindctl.

177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
@section dhcpv6OptionsParse Custom functions to parse message options

The DHCPv6 server implementation provides a generic support to define option
formats and set option values. A number of options formats have been defined
for standard options in libdhcp++. However, the formats for vendor specific
options are dynamically configured by the server's administrator and thus can't
be stored in libdhcp++. Such option formats are stored in the
@c isc::dhcp::CfgMgr. The libdhcp++ provides functions for recursive parsing
of options which may be encapsulated by other options up to the any level of
encapsulation but these functions are unaware of the option formats defined
in the @c isc::dhcp::CfgMgr because they belong to a different library.
Therefore, the generic functions @c isc::dhcp::LibDHCP::unpackOptions4 and
@c isc::dhcp::LibDHCP::unpackOptions6 are only useful to parse standard
options which definitions are provided in the libdhcp++. In order to overcome
this problem a callback mechanism has been implemented in @c Option and @c Pkt6
classes. By installing a callback function on the instance of the @c Pkt6 the
server may provide a custom implementation of the options parsing algorithm.
This callback function will take precedence over the @c LibDHCP::unpackOptions6
and @c LibDHCP::unpackOptions4 functions. With this approach, the callback is
implemented within the context of the server and it has access to all objects
which define its configuration (including dynamically created option
definitions).

200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
@section dhcpv6Classifier DHCPv6 Client Classification

Kea DHCPv6 server currently supports simplified client classification. It is called
"simplified", because the incoming packets are classified based on the content
of the vendor class (16) option. More flexible classification is planned, but there
are no specific development dates agreed.

For each incoming packet, @ref isc::dhcp::Dhcpv6Srv::classifyPacket() method is
called.  It attempts to extract content of the vendor class option and interprets
as a name of the class. Although the RFC3315 says that the vendor class may
contain more than one chunk of data, the existing code handles only one data
block, because that is what actual devices use. For now, the code has been
tested with two classes used in cable modem networks: eRouter1.0 and docsis3.0,
but any other content of the vendor class option will be interpreted as a class
name.

In principle any given packet can belong to zero or more classes. As the current
classifier is very modest, there's only one way to assign a class (based on vendor class
option), the ability to assign more than one class to a packet is not yet exercised.
Neverthless, there is such a possibility and it will be used in a near future. To
check whether a packet belongs to given class, isc::dhcp::Pkt6::inClass method should
be used.

Currently there is no class behaviour coded in DHCPv6, hence no v6 equivalent of
@ref isc::dhcp::Dhcpv4Srv::classSpecificProcessing. Should any need for such a code arise,
it will be conducted in an external hooks library.

227
It is possible to define class restrictions in subnet, so a given subnet is only
Tomek Mrugalski's avatar
Tomek Mrugalski committed
228
229
accessible to clients that belong to a given class. That is implemented as isc::dhcp::Pkt6::classes_
being passed in isc::dhcp::Dhcpv6Srv::selectSubnet() to isc::dhcp::CfgMgr::getSubnet6().
230
231
232
Currently this capability is usable, but the number of scenarios it supports is
limited.

233
234
235
 @section dhcpv6ConfigBackend Configuration backend for DHCPv6

There are many theoretical ways in which server configuration can be stored. Kea 0.8 and
236
earlier versions used Bundy/BIND10 framework and its internal storage for DHCPv6 server configuration.
237
238
239
240
241
The legacy ISC-DHCP implementation uses flat files. Configuration stored in JSON files is
becoming more and more popular among various projects. There are unofficial patches for
ISC-DHCP that keep parts of the configuration in LDAP. It was also suggested that in some
cases it would be convenient to keep configuration in XML files.

242
Kea 0.9 has introduced configuration backends that are switchable during compilation phase.
243
There is a new parameter for configure script: --with-kea-config. It currently supports
244
two values: BUNDY and JSON.
245

246
BUNDY (which is the default value as of April 2014) means that Kea6 is linked with the
247
Bundy (former BIND10) configuration backend that connects to the Bundy/BIND10 framework and in general works
248
exactly the same as Kea 0.8 and earlier versions. The benefits of that backend are uniform
249
250
251
integration with Bundy/BIND10 framework, easy on-line reconfiguration using bindctl, available
RESTful API. On the other hand, it requires the whole heavy Bundy framework that requires
Python3 to be present. That framework is going away with the release of Kea 0.9.
252
253
254
255

JSON is a new configuration backend that causes Kea to read JSON configuration file from
disk. It does not require any framework and thus is considered more lightweight. It will
allow dynamic on-line reconfiguration, but will lack remote capabilities (i.e. no RESTful
256
257
API). This configuration backend is expected to be the default for upcoming Kea 0.9. It
requires <tt> -c config-file </tt> command-line option.
258
259

Internally, configuration backends are implemented as different implementations of the
260
isc::dhcp::ControlledDhcpv6Srv class, stored in {kea,bundy}_controller.cc files. Depending on
261
the choice made by ./configure script, only one of those files is compiled and linked.
262
There are backend specific tests in src/bin/dhcp6/tests/{kea,bundy}_controller_unittest.cc.
263
264
265
266
267
268
269
270
271
272
Only tests specific to selected backend are linked and executed during make distcheck.

While it is unlikely that ISC will support more than one backend at any given time, there
are several aspects that make that approach appealing in the long term. First, having
two backends is essential during transition time, where both old and new backend is used.
Second, there are external organizations that develop and presumably maintain LDAP backend
for ISC-DHCP. Is at least possible that similar will happen for Kea. Finally, if we ever
extend the isc::dhcp::CfgMgr with configuration export, this approach could be used as
a migration tool.

273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
@section dhcpv6SignalBasedReconfiguration Reconfiguring DHCPv6 server with SIGHUP signal

Online reconfiguration (reconfiguration without a need to restart the server) is an
important feature which is supported by all modern DHCP servers. When using the JSON
configuration backend, a configuration file name is specified with a command line
option of the DHCP server binary. The configuration file is used to configure the
server at startup. If the initial configuration fails, the server will fail to start.
If the server starts and configures successfully it will use the initial configuration
until it is reconfigured.

The reconfiguration request can be triggered externally (from other process) by editing
a configuration file and sending a SIGHUP signal to DHCP server process. After receiving
the SIGHUP signal, the server will re-read the configuration file specified at startup.
If the reconfiguration fails, the server will continue to run and use the last good
configuration.

289
The signal handler for SIGHUP (also for SIGTERM and SIGINT) are installed in the
290
kea_controller.cc using the @c isc::util::SignalSet class. The
291
292
293
294
295
296
297
298
299
300
301
302
@c isc::dhcp::Dhcp6Srv calls @c isc::dhcp::Daemon::handleSignal on each pass
through the main loop. This method fetches the last received signal and calls
a handler function defined in the kea_controller.cc. The handler function
calls a static function @c configure defined in the kea_controller.cc.

In order for the signal handler to know the location of the configuration file
(specified at process startup), the location of this file needs to be stored
in a static variable so as it may be directly accessed by the signal handler.
This static variable is stored in the @c dhcp::Daemon class and all Kea processes
can use it (all processes derive from this class). The configuration file
location is initialized when the @c Daemon::init method is called. Therefore,
derived classes should call it in their implementations of the @c init method.
303

304
305
306
307
 @section dhcpv6Other Other DHCPv6 topics

 For hooks API support in DHCPv6, see @ref dhcpv6Hooks.

308
 */