diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 12:15:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 12:15:43 +0000 |
commit | f5f56e1a1c4d9e9496fcb9d81131066a964ccd23 (patch) | |
tree | 49e44c6f87febed37efb953ab5485aa49f6481a7 /src/bin/dhcp6/dhcp6.dox | |
parent | Initial commit. (diff) | |
download | isc-kea-upstream.tar.xz isc-kea-upstream.zip |
Adding upstream version 2.4.1.upstream/2.4.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/bin/dhcp6/dhcp6.dox')
-rw-r--r-- | src/bin/dhcp6/dhcp6.dox | 609 |
1 files changed, 609 insertions, 0 deletions
diff --git a/src/bin/dhcp6/dhcp6.dox b/src/bin/dhcp6/dhcp6.dox new file mode 100644 index 0000000..d575228 --- /dev/null +++ b/src/bin/dhcp6/dhcp6.dox @@ -0,0 +1,609 @@ +// Copyright (C) 2012-2023 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +/** + @page dhcp6 DHCPv6 Server Component + +Kea includes the "kea-dhcp6" component, which is the DHCPv6 server +implementation. This component is built around the +@ref isc::dhcp::Dhcpv6Srv class which controls all major operations +performed by the server such as: DHCP messages processing, callouts +execution for many hook points, FQDN processing and interactions with the +"kea-dhcp-ddns" component, lease allocation, system signals handling etc. + +The "kea-dhcp6" component requires linking with many different libraries +to obtain access to common functions like: interfaces and sockets +management, configuration parsing, leases management and allocation, +hooks infrastructure, statistics management etc. + +The following sections walk through some of the details of the "kea-dhcp6" +component implementation. + +@section dhcpv6ConfigParser Configuration Parsers in DHCPv6 + +This is a three minutes overview. If you are here only to learn absolute minimum about +the new parser, here's how you use it: + +@code + // The following code: + json = isc::data::Element::fromJSONFile(file_name, true); + + // can be replaced with this: + Parser6Context parser; + json = parser.parseFile(file_name, Parser6Context::PARSER_DHCP6); +@endcode + +Note: parsers are currently being migrated to @ref isc::data::SimpleParser. See +@ref ccSimpleParser page for details. + +For more detailed background information about flex and bison, see @ref parser. + +The common configuration parsers for the DHCP servers are located in the +src/lib/dhcpsrv/parsers/ directory. Parsers specific to the DHCPv6 component +are located in the src/bin/dhcp6/json_config_parser.cc. These parsers derive +from the common configuration parsers and customize their behavior. For +example: the @c Subnet6ConfigParser is used to parse parameters +describing a single subnet. It derives from the @c +isc::dhcp::SubnetConfigParser, which implements the common base for both +DHCPv4 and DHCPv6 subnets. The @ref Subnet6ConfigParser +implements the @c initSubnet abstract method, which creates an instance of +the DHCPv6 subnet. This method is invoked by the parent class. + +Some parsers for the DHCPv6 server derive from the isc::dhcp::DhcpConfigParser +class directly. This is an abstract class, defining a basic interface for +all configuration parsers. All DHCPv6 parsers deriving from this class +directly have their entire implementation in the +src/bin/dhcp6/json_config_parser.cc. + +@section dhcpv6ConfigParserBison Configuration Parser for DHCPv6 (bison) + +During the 1.2 milestone it was decided to significantly refactor the +parsers as their old implementation became unsustainable. In +general, the following issues of the existing code were noted: + +-# parsers are overwhelmingly complex. Even though each parser is relatively + simple class, the complexity comes from too large number of interacting parsers. +-# the code is disorganized, i.e. spread out between multiple directories + (src/bin/dhcp6 and src/lib/dhcpsrv/parsers). +-# The split into build/commit never worked well. In particular, it is not + trivial to revert configuration change. This split originates from BIND10 + days and was inherited from DNS auth that did receive only changes in + the configuration, rather than the full configuration. As a result, + the split was abused and many of the parsers have commit() being a + no-op operation. +-# There is no way to generate a list of all directives. We do have .spec files, + but they're not actually used by the code. The code has the directives + spread out in multiple places in multiple files in multiple directories. + Answering a simple question ("can I do X in the scope Y?") requires + a short session of reverse engineering. What's worse, we have the .spec + files that are kinda kept up to date. This is actually more damaging that + way, because there's no strict correlation between the code and .spec file. + So there may be parameters that are supported, but are not in .spec files. + The opposite is also true - .spec files can be buggy and have different + parameters. This is particularly true for default values. +-# It's exceedingly complex to add comments that don't start at the first + column or span several lines. Both Tomek and Marcin tried to implement + it, but failed miserably. The same is true for including files (have + include statement in the config that includes other files) +-# The current parsers don't handle the default values, i.e. if there's no + directive, the parser is not created at all. We have kludgy workarounds + for that, but the code for it is in different place than the parser, + which leads to the logic being spread out in different places. +-# syntax checking is poor. The existing JSON parser allowed things like + empty option-data entries: + @code + "option-data": [ {} ] + @endcode + having trailing commas: + @code + "option-data": [ + { + "code": 12, + "data": "2001:db8:1:0:ff00::1" + }, + ] + @endcode + or having incorrect types, e.g. specifying timer values as strings. + +To solve those issues a two phase approach was proposed: + +PHASE 1: replace isc::data::fromJSON with bison-based parser. This will allow + to have a single file that defines the actual syntax, much better syntax + checking, and provide more flexibility, like various comment types and + file inclusions. As a result, the parser still returns JSON structures that + are guaranteed to be correct from the grammar perspective. Sticking with + the JSON structures also allows us to continue using existing parsers. + Furthermore, it is possible to implement default values at this level + as simply inserting extra JSON structures in places that are necessary. + This part is covered by ticket 5036. + +PHASE 2: simplify existing parsers by getting rid of the build/commit split. + Get rid of the inheritance contexts. Essentially the parser should + take JSON structure as a parameter and return the configuration structure. + For example, for options this should essentially look like this: + @code + CfgOptionPtr parse(ConstElementPtr options) + @endcode + The whole complexity behind inheriting contexts should be removed + from the existing parsers and implemented in the bison parser. + It should return extra JSON elements. The details are TBD, but there is + one example for setting up an renew-timer value on the subnet level that + is inherited from the global ("Dhcp6") level. This phase is covered by + ticket 5039. + +The code change for 5036 introduces flex/bison based parser. It is +essentially defined in two files: dhcp6_lexer.ll, which defines +regular expressions that are used on the input (be it a file or a +string in memory). In essence, this code is being called repeatedly +and each time it returns a token. This repeats until either the +parsing is complete or syntax error is encountered. For example, for +the following text: + +@code +{ + "Dhcp6": + { + "renew-timer": 100 + } +} +@endcode +this code would return the following sentence of tokens: LCURLY_BRACKET, +DHCP6, COLON, LCURLY_BRACKET, RENEW_TIMER, COLON, INTEGER +(a token with a value of 100), RCURLY_BRACKET, RCURLY_BRACKET, END + +This stream of tokens is being consumed by the parser that is defined +in dhcp6_parser.yy. This file defines a grammar. Here's very simplified +version of the Dhcp6 grammar: + +@code +dhcp6_object: DHCP6 COLON LCURLY_BRACKET global_params RCURLY_BRACKET; + +global_params: global_param + | global_params COMMA global_param + ; + +// These are the parameters that are allowed in the top-level for +// Dhcp6. +global_param: preferred_lifetime + | valid_lifetime + | renew_timer + | rebind_timer + | subnet6_list + | interfaces_config + | lease_database + | hosts_database + | mac_sources + | relay_supplied_options + | host_reservation_identifiers + | client_classes + | option_data_list + | hooks_libraries + | expired_leases_processing + | server_id + | dhcp4o6_port + ; + +renew_timer: RENEW_TIMER COLON INTEGER; +@endcode + +This may be slightly difficult to read at the beginning, but after getting used +to the notation, it's very powerful and easy to extend. The first line defines +that dhcp6_object consists of certain tokens (DHCP6, COLON and LCURLY_BRACKET) +followed by 'global_params' expression, followed by RCURLY_BRACKET. + +The 'global_params' is defined recursively. It can either be a single +'global_param' expression, or (a shorter) global_params followed by a +comma and global_param. Bison will apply this and will be able to +parse comma separated lists of arbitrary lengths. + +A single parameter is defined by 'global_param' expression. This +represents any parameter that may appear in the global scope of Dhcp6 +object. The complete definition for all of them is complex, but the +example above includes renew_timer definition. It is defined as a +series of RENEW_TIMER, COLON, INTEGER tokens. + +The above is a simplified version of the actual grammar. If used in the version +above, it would parse the whole file, but would do nothing with that information. +To build actual structures, bison allows to inject C++ code at any phase of +the parsing. For example, when the parser detects Dhcp6 object, it wants to +create a new MapElement. When the whole object is parsed, we can perform +some sanity checks, inject defaults for parameters that were not defined, +log and do other stuff. + +@code +dhcp6_object: DHCP6 COLON LCURLY_BRACKET { + // This code is executed when we're about to start parsing + // the content of the map + ElementPtr m(new MapElement()); + ctx.stack_.back()->set("Dhcp6", m); + ctx.stack_.push_back(m); +} global_params RCURLY_BRACKET { + // Whole Dhcp6 parsing completed. If we ever want to do any wrap up + // (maybe some sanity checking, insert defaults if not specified), + // this would be the best place for it. + ctx.stack_.pop_back(); +}; +@endcode + +The above will do the following in order: consume DHCP6 token, consume COLON token, +consume LCURLY_BRACKET, execute the code in first { ... }, parse global_params +and do whatever the code for it tells, parser RCURLY_BRACKET, execute the code +in the second { ... }. + +There is a simple stack defined in ctx.stack_, which is isc::dhcp::Parser6Context +defined in src/bin/dhcp6/parser_context.h. When walking through the config file, each +new context (e.g. entering into Dhcp6, Subnet6, Pool), a new Element is added +to the end of the stack. Once the parsing of a given context is complete, it +is removed from the stack. At the end of parsing, there should be a single +element on the stack as the top-level parsing (syntax_map) only inserts the +MapElement object, but does not remove it. + +@section dhcpv6ConfigSubParser Parsing Partial Configuration in DHCPv6 + +For more generic description of the solution, see @ref parserSubgrammar. + +One another important capability required is the ability to parse not only the +whole configuration, but a subset of it. This is done by introducing artificial +tokens (e.g. TOPLEVEL_JSON and TOPLEVEL_DHCP6). For complete list of available +starting contexts, see @ref isc::dhcp::Parser6Context::ParserType. The +Parse6Context::parse() method takes one parameter that specifies, whether the +data to be parsed is expected to have a generic JSON or the whole configuration +(DHCP6). This feature is currently mostly used by unit-tests (which often skip +the '{ "Dhcp6": {' preamble), but it is expected to be soon used for parsing +subnets only, host reservations only, options or basically any other elements. +For example, to add the ability to parse only pools, the following could be added: + +@code +start: TOPLEVEL_GENERIC_JSON sub_json + | TOPLEVEL_DHCP6 sub_dhcp6 + | TOPLEVEL_POOL6 sub_pool6 + ; +@endcode + +The parser code contains the code definition and the Kea-dhcp6 updated +to use that new parser. That parser is able to to load all examples +from doc/example/kea6. It is also able to parser # comments (bash +style, starting at the beginning or middle of the line), // comments +(C++ style, can start anywhere) or / * * / comments (C style, can span +multiple lines). + +This parser is currently used in production code. See configure() +method in kea_controller.cc. + +There are several new unit-tests written, but the code mostly reuses existing +one to verify that existing functionality was not compromised. There are +several new interesting ones, though. ParserTest.file loads all the +config file examples we have in doc/examples/kea6. This ensures that the +parser is able to load them and also checks that our examples are sane. + +@section dhcp6ParserIncludes Configuration Files Inclusion + +The new parser provides an ability to include files. The syntax was chosen +to look similar to how Apache includes PHP scripts in HTML code. This +particular syntax was chosen to emphasize that the inclusion directive +is an additional feature and not really a part of JSON syntax. + +To include one file from another, user the following syntax: + +@code +{ + "Dhcp6": { + "interfaces-config": { + "interfaces": [ "*" ]}, + "preferred-lifetime": 3000, + "rebind-timer": 2000, + "renew-timer": 1000, + <?include "subnets.json"?> + "valid-lifetime": 4000 + } +} +@endcode + +The inclusion is implemented as a stack of files. Typically, when a +single file is parsed, the files_ (a vector of strings) and sfiles_ (a +vector of FILE*) both contain a single entry. However, when lexer +detects <?include "filename.json?>, it calls +@ref isc::dhcp::Parser6Context::includeFile method. Up to ten nesting +levels are supported. This arbitrarily chosen limit is a protection +against recursive inclusions. + +@section dhcp6ParserConflicts Avoiding syntactical conflicts in parsers + +Syntactic parser has a powerful ability to not only parse the string and +check if it's a valid JSON syntax, but also check that the resulting structures +match expected syntax (if subnet6 are really an array, not a map, if +timers are expressed as integers, not as strings etc.). + +However, there are times when we need to parse a string as arbitrary +JSON. For example, if we're in Dhcp6 and the config contains entries +for DhcpDdns or Dhcp4. If we were to use naive approach, the lexer +would go through that content and most likely find some tokens that +are also used in Dhcp6. for example 'renew-timer' would be detected +and the parser would complain that it was not expected. To avoid this +problem, syntactic context was introduced. When the syntactic parser +expects certain type of content, it calls @ref +isc::dhcp::Parser6Context::enter() method to indicate what type of +content is expected. For example, when Dhcp6 parser discovers +uninteresting content like Dhcp4, it enters NO_KEYWORD mode. In this +mode, everything is parsed as generic maps, lists, integers, booleans +or strings. This results in generic JSON structures without any syntax +checking. A corresponding/balanced @ref +isc::dhcp::Parser6Context::leave() call is required before leaving the +context to come back to the previous context. + +Entering a new syntactic context is useful in several ways. First, it allows +the parser to avoid conflicts. Second, it allows the lexer to return different +tokens depending on context (e.g. if "renew-timer" string is detected, the lexer +will return STRING token if in JSON mode or RENEW_TIMER if in DHCP6 +mode). Finally, the syntactic context allows the error message to be more +descriptive if the input string does not parse properly. + +Details of the refactor of the classes derived from DhcpConfigParser are +documented in https://gitlab.isc.org/isc-projects/kea/wikis/designs/simple-parser-design. + +For a generic description of the conflict avoidance, see @ref parserFlex. + +@section dhcpv6ConfigInherit DHCPv6 Configuration Inheritance + +One notable useful feature of DHCP configuration is its parameter inheritance. +For example, the "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 subnet +specific values that takes precedence over global values that are considered +defaults. The parameters inheritance is implemented by means of the "global +context". The global context is represented by the isc::dhcp::ParserContext +class and it holds pointers to storages of different kind, e.g. text parameters, +numeric parameters etc. When the server is parsing the top level configuration +parameters it passes pointers to the storages of the appropriate kind, to the +parsers being invoked to parse the global values. Parsers will store the +parsed values into these storages. Once the global parameters are stored in the +global context, the parsers for the nested configuration parameters are invoked. +These parsers check the presence of the parameters overriding the values of +the global parameters. If a value is not present, the value from the global +context is used. + +A good example of inheritance is the implementation of the @ref +isc::dhcp::SubnetConfigParser. The @c getParam method is used throughout the +class to obtain values of the parameters defining a subnet. It first checks +if the specific value is present in the local values storage. If it is not +present, it uses the value from the global context. + +@code +isc::dhcp::Triplet<uint32_t> +SubnetConfigParser::getParam(const std::string& name) { + uint32_t value = 0; + try { + // look for local value + value = uint32_values_->getParam(name); + } catch (const DhcpConfigError &) { + try { + // no local, use global value + value = global_context_->uint32_values_->getParam(name); + } catch (const DhcpConfigError &) { + isc_throw(DhcpConfigError, "Mandatory parameter " << name + << " missing (no global default and no subnet-" + << "specific value)"); + } + } + + return (Triplet<uint32_t>(value)); +} +@endcode + +Note that if the value is neither present in the local storage nor in the global +context, an error is signaled. + +Parameter inheritance is done once, during the reconfiguration phase. +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 +access to these parameters must be as efficient as possible. In fact, +currently the code has to only call @c Subnet6::getT1(), regardless if the +"renew-timer" has been specified as a global or subnet specific value. + +Debugging a configuration parser may be confusing. Therefore there is a special +class called DebugParser. It does not configure anything, but just +accepts any parameter of any type. If requested to commit a configuration, it will +print out received parameter name and its value. This class is not currently used, +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. + +@section dhcpv6DDNSIntegration DHCPv6 Server Support for the Dynamic DNS Updates + +The DHCPv6 server supports processing of the DHCPv6 Client FQDN Option described in +the RFC4704. This Option is sent by the DHCPv6 client to instruct the server to +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. + +As described in RFC4704, client may choose that the server delegates the forward +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. + +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 +for generating so called @ref isc::dhcp_ddns::NameChangeRequest and sending it to the +kea-dhcp-ddns module. The @ref isc::dhcp_ddns::NameChangeRequest object represents changes to the +DNS bindings, related to acquisition, renewal or release of the lease. The kea-dhcp6 +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 +send them to the kea-dhcp-ddns module when server is idle waiting for DHCP messages. + +In the simplest case, when client gets one address from the server, a DHCPv6 server +may generate 0, 1 or 2 NameChangeRequests during single message processing. +The server generates no NameChangeRequests if it is not configured to update DNS + or it rejects the DNS update for any other reason. + +The server may generate one NameChangeRequest in a situation when a client acquires a +new lease or it releases an existing lease. In the former case, the NameChangeRequest +type is CHG_ADD, which indicates that the kea-dhcp-ddns module should add a new DNS +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 +indicate to the kea-dhcp-ddns module that the existing DNS binding should be removed +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 +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. + +The server may generate two 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 +a message, and it will check in the lease database if the DNS Updates had +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. + +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. + +The DHCPv6 Client FQDN Option comprises "NOS" flags which communicate to the +server what updates (if any) client expects the server to perform. Server +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. + +@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 +@ref 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 @ref isc::dhcp::CfgMgr because they belong to a different library. +Therefore, the generic functions @ref isc::dhcp::LibDHCP::unpackOptions4 and +@ref isc::dhcp::LibDHCP::unpackOptions6 are only useful to parse standard +options whose 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). + +@section dhcpv6Classifier DHCPv6 Client Classification + +The Kea DHCPv6 currently supports two classification modes: simplified client +classification (that was an early implementation that used values of vendor class option) +and full client classification. + +@subsection dhcpv6ClassifierSimple Simple Client Classification in DHCPv6 + +The Kea DHCPv6 server 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 was added in 1.0 +and is described in @ref dhcpv6ClassifierFull. + +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 RFC 8415 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. +Nevertheless, 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. + +The code sometimes refers to this classification as "simple" or 'built-in", because +it does not require any configuration and thus is built into the server logic. + +@subsection dhcpv6ClassifierFull Full Client Classification in DHCPv6 + +Kea 1.0 introduced full client classification. Each client class consists of a name +and an expression that can be evaluated on an incoming packet. If it evaluates to +true, this packet is considered a member of said class. Class definitions are stored +in isc::dhcp::ClientClassDef objects that are kept in isc::dhcp::ClientClassDictionary +and can be retrieved from CfgMgr using isc::dhcp::SrvConfig::getClientClassDictionary(). +This is convenient as there are often multiple classes associated with a given scope. + +Client classification is done in isc::dhcp::Dhcpv6Srv::classifyPacket. First, the old +"built-in" (see @ref dhcpv6ClassifierSimple) classification is called (see @ref +isc::dhcp::Dhcpv6Srv::classifyByVendor). Then the code iterates over all class definitions +and for each class definition it calls isc::dhcp::evaluate, which is implemented in libeval +(see @ref libeval). If the evaluation is successful, the class name is added to the packet +(by calling isc::dhcp::pkt::addClass). + +If packet belongs to at least one class, this fact is logged. If there are any +exceptions raised during class evaluation, an error is logged and the code attempts +to evaluate the next class. + +@subsection dhcpv6ClassifierUsage How client classification information is used in DHCPv6 + +It is possible to define class restrictions in subnet, so a given subnet is only +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(). +Currently this capability is usable, but the number of scenarios it supports is +limited. + +Finally, it is possible to define client class-specific options, so clients belonging +to a class foo, will get options associated with class foo. This is implemented in +isc::dhcp::Dhcpv6Srv::buildCfgOptionList. + +@section dhcpv6ConfigBackend Configuration backend for DHCPv6 + +Earlier Kea versions had a concept of backends, which were implementations of +different ways how configuration could be delivered to Kea. It seems that the +concept of backends didn't get much enthusiasm from users and having multiple +backends was cumbersome to maintain, so it was removed in 1.0. + +@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. + +The signal handler for SIGHUP (also for SIGTERM and SIGINT) are installed in the +kea_controller.cc using the @c isc::util::SignalSet class. The +@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. + +The signal handler reconfigures the server using the configuration file +specified at server startup. The location of this file is held in the +@c Daemon class. + +@section dhcpv6Other Other DHCPv6 topics + +For hooks API support in DHCPv6, see @ref dhcpv6Hooks. + +For a description of how DHCPv4-over-DHCPv6 is implemented, see @subpage dhcpv4o6Dhcp6 + + */ |