Kea 1.5.0
srv_config.cc
Go to the documentation of this file.
1// Copyright (C) 2014-2018 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8#include <dhcpsrv/cfgmgr.h>
13#include <log/logger_manager.h>
15#include <dhcp/pkt.h> // Needed for HWADDR_SOURCE_*
16#include <list>
17#include <sstream>
18
19using namespace isc::log;
20using namespace isc::data;
21using namespace isc::process;
22
23namespace isc {
24namespace dhcp {
25
27 : sequence_(0), cfg_iface_(new CfgIface()),
28 cfg_option_def_(new CfgOptionDef()), cfg_option_(new CfgOption()),
29 cfg_subnets4_(new CfgSubnets4()), cfg_subnets6_(new CfgSubnets6()),
30 cfg_shared_networks4_(new CfgSharedNetworks4()),
31 cfg_shared_networks6_(new CfgSharedNetworks6()),
32 cfg_hosts_(new CfgHosts()), cfg_rsoo_(new CfgRSOO()),
33 cfg_expiration_(new CfgExpiration()), cfg_duid_(new CfgDUID()),
34 cfg_db_access_(new CfgDbAccess()),
35 cfg_host_operations4_(CfgHostOperations::createConfig4()),
36 cfg_host_operations6_(CfgHostOperations::createConfig6()),
37 class_dictionary_(new ClientClassDictionary()),
38 decline_timer_(0), echo_v4_client_id_(true), dhcp4o6_port_(0),
39 d2_client_config_(new D2ClientConfig()),
40 configured_globals_(Element::createMap()),
41 cfg_consist_(new CfgConsistency()),
42 server_tag_("") {
43}
44
45SrvConfig::SrvConfig(const uint32_t sequence)
46 : sequence_(sequence), cfg_iface_(new CfgIface()),
47 cfg_option_def_(new CfgOptionDef()), cfg_option_(new CfgOption()),
48 cfg_subnets4_(new CfgSubnets4()), cfg_subnets6_(new CfgSubnets6()),
49 cfg_shared_networks4_(new CfgSharedNetworks4()),
50 cfg_shared_networks6_(new CfgSharedNetworks6()),
51 cfg_hosts_(new CfgHosts()), cfg_rsoo_(new CfgRSOO()),
52 cfg_expiration_(new CfgExpiration()), cfg_duid_(new CfgDUID()),
53 cfg_db_access_(new CfgDbAccess()),
54 cfg_host_operations4_(CfgHostOperations::createConfig4()),
55 cfg_host_operations6_(CfgHostOperations::createConfig6()),
56 class_dictionary_(new ClientClassDictionary()),
57 decline_timer_(0), echo_v4_client_id_(true), dhcp4o6_port_(0),
58 d2_client_config_(new D2ClientConfig()),
59 configured_globals_(Element::createMap()),
60 cfg_consist_(new CfgConsistency()),
61 server_tag_("") {
62}
63
64std::string
65SrvConfig::getConfigSummary(const uint32_t selection) const {
66 std::ostringstream s;
67 size_t subnets_num;
68 if ((selection & CFGSEL_SUBNET4) == CFGSEL_SUBNET4) {
69 subnets_num = getCfgSubnets4()->getAll()->size();
70 if (subnets_num > 0) {
71 s << "added IPv4 subnets: " << subnets_num;
72 } else {
73 s << "no IPv4 subnets!";
74 }
75 s << "; ";
76 }
77
78 if ((selection & CFGSEL_SUBNET6) == CFGSEL_SUBNET6) {
79 subnets_num = getCfgSubnets6()->getAll()->size();
80 if (subnets_num > 0) {
81 s << "added IPv6 subnets: " << subnets_num;
82 } else {
83 s << "no IPv6 subnets!";
84 }
85 s << "; ";
86 }
87
88 if ((selection & CFGSEL_DDNS) == CFGSEL_DDNS) {
89 bool ddns_enabled = getD2ClientConfig()->getEnableUpdates();
90 s << "DDNS: " << (ddns_enabled ? "enabled" : "disabled") << "; ";
91 }
92
93 if (s.tellp() == static_cast<std::streampos>(0)) {
94 s << "no config details available";
95 }
96
97 std::string summary = s.str();
98 size_t last_separator_pos = summary.find_last_of(";");
99 if (last_separator_pos == summary.length() - 2) {
100 summary.erase(last_separator_pos);
101 }
102 return (summary);
103}
104
105bool
107 return (getSequence() == other.getSequence());
108}
109
110void
111SrvConfig::copy(SrvConfig& new_config) const {
112 ConfigBase::copy(new_config);
113
114 // Replace interface configuration.
115 new_config.cfg_iface_.reset(new CfgIface(*cfg_iface_));
116 // Replace option definitions.
117 cfg_option_def_->copyTo(*new_config.cfg_option_def_);
118 cfg_option_->copyTo(*new_config.cfg_option_);
119 // Replace the client class dictionary
120 new_config.class_dictionary_.reset(new ClientClassDictionary(*class_dictionary_));
121 // Replace the D2 client configuration
123 // Replace configured hooks libraries.
124 new_config.hooks_config_.clear();
125 using namespace isc::hooks;
126 for (HookLibsCollection::const_iterator it =
127 hooks_config_.get().begin();
128 it != hooks_config_.get().end(); ++it) {
129 new_config.hooks_config_.add(it->first, it->second);
130 }
131}
132
133bool
134SrvConfig::equals(const SrvConfig& other) const {
135
136 // Checks common elements: logging & config control
137 if (!ConfigBase::equals(other)) {
138 return (false);
139 }
140
141 // Common information is equal between objects, so check other values.
142 if ((*cfg_iface_ != *other.cfg_iface_) ||
143 (*cfg_option_def_ != *other.cfg_option_def_) ||
144 (*cfg_option_ != *other.cfg_option_) ||
145 (*class_dictionary_ != *other.class_dictionary_) ||
146 (*d2_client_config_ != *other.d2_client_config_)) {
147 return (false);
148 }
149 // Now only configured hooks libraries can differ.
150 // If number of configured hooks libraries are different, then
151 // configurations aren't equal.
152 if (hooks_config_.get().size() != other.hooks_config_.get().size()) {
153 return (false);
154 }
155 // Pass through all configured hooks libraries.
156 return (hooks_config_.equal(other.hooks_config_));
157}
158
159void
161
162 // Removes statistics for v4 and v6 subnets
163 getCfgSubnets4()->removeStatistics();
164
165 getCfgSubnets6()->removeStatistics();
166}
167
168void
170 // Updating subnet statistics involves updating lease statistics, which
171 // is done by the LeaseMgr. Since servers with subnets, must have a
172 // LeaseMgr, we do not bother updating subnet stats for servers without
173 // a lease manager, such as D2. @todo We should probably examine why
174 // "SrvConfig" is being used by D2.
176 // Updates statistics for v4 and v6 subnets
177 getCfgSubnets4()->updateStatistics();
178
179 getCfgSubnets6()->updateStatistics();
180 }
181}
182
183void
185 if (config->getType() != Element::map) {
186 isc_throw(BadValue, "extractConfiguredGlobals must be given a map element");
187 }
188
189 const std::map<std::string, ConstElementPtr>& values = config->mapValue();
190 for (auto value = values.begin(); value != values.end(); ++value) {
191 if (value->second->getType() != Element::list &&
192 value->second->getType() != Element::map) {
193 addConfiguredGlobal(value->first, value->second);
194 }
195 }
196}
197
200 // Toplevel map
202
203 // Get family for the configuration manager
204 uint16_t family = CfgMgr::instance().getFamily();
205 // DhcpX global map
207
208 // Add in explicitly configured globals.
209 dhcp->setValue(configured_globals_->mapValue());
210
211 // Set user-context
212 contextToElement(dhcp);
213
214 // Set decline-probation-period
215 dhcp->set("decline-probation-period",
216 Element::create(static_cast<long long>(decline_timer_)));
217 // Set echo-client-id (DHCPv4)
218 if (family == AF_INET) {
219 dhcp->set("echo-client-id", Element::create(echo_v4_client_id_));
220 }
221 // Set dhcp4o6-port
222 dhcp->set("dhcp4o6-port",
223 Element::create(static_cast<int>(dhcp4o6_port_)));
224
225 // Set dhcp-ddns
226 dhcp->set("dhcp-ddns", d2_client_config_->toElement());
227 // Set interfaces-config
228 dhcp->set("interfaces-config", cfg_iface_->toElement());
229 // Set option-def
230 dhcp->set("option-def", cfg_option_def_->toElement());
231 // Set option-data
232 dhcp->set("option-data", cfg_option_->toElement());
233
234 // Set subnets and shared networks.
235
236 // We have two problems to solve:
237 // - a subnet is unparsed once:
238 // * if it is a plain subnet in the global subnet list
239 // * if it is a member of a shared network in the shared network
240 // subnet list
241 // - unparsed subnets must be kept to add host reservations in them.
242 // Of course this can be done only when subnets are unparsed.
243
244 // The list of all unparsed subnets
245 std::vector<ElementPtr> sn_list;
246
247 if (family == AF_INET) {
248 // Get plain subnets
249 ElementPtr plain_subnets = Element::createList();
250 const Subnet4Collection* subnets = cfg_subnets4_->getAll();
251 for (Subnet4Collection::const_iterator subnet = subnets->cbegin();
252 subnet != subnets->cend(); ++subnet) {
253 // Skip subnets which are in a shared-network
254 SharedNetwork4Ptr network;
255 (*subnet)->getSharedNetwork(network);
256 if (network) {
257 continue;
258 }
259 ElementPtr subnet_cfg = (*subnet)->toElement();
260 sn_list.push_back(subnet_cfg);
261 plain_subnets->add(subnet_cfg);
262 }
263 dhcp->set("subnet4", plain_subnets);
264
265 // Get shared networks
266 ElementPtr shared_networks = cfg_shared_networks4_->toElement();
267 dhcp->set("shared-networks", shared_networks);
268
269 // Get subnets in shared network subnet lists
270 const std::vector<ElementPtr> networks = shared_networks->listValue();
271 for (auto network = networks.cbegin();
272 network != networks.cend(); ++network) {
273 const std::vector<ElementPtr> sh_list =
274 (*network)->get("subnet4")->listValue();
275 for (auto subnet = sh_list.cbegin();
276 subnet != sh_list.cend(); ++subnet) {
277 sn_list.push_back(*subnet);
278 }
279 }
280
281 } else {
282 // Get plain subnets
283 ElementPtr plain_subnets = Element::createList();
284 const Subnet6Collection* subnets = cfg_subnets6_->getAll();
285 for (Subnet6Collection::const_iterator subnet = subnets->cbegin();
286 subnet != subnets->cend(); ++subnet) {
287 // Skip subnets which are in a shared-network
288 SharedNetwork6Ptr network;
289 (*subnet)->getSharedNetwork(network);
290 if (network) {
291 continue;
292 }
293 ElementPtr subnet_cfg = (*subnet)->toElement();
294 sn_list.push_back(subnet_cfg);
295 plain_subnets->add(subnet_cfg);
296 }
297 dhcp->set("subnet6", plain_subnets);
298
299 // Get shared networks
300 ElementPtr shared_networks = cfg_shared_networks6_->toElement();
301 dhcp->set("shared-networks", shared_networks);
302
303 // Get subnets in shared network subnet lists
304 const std::vector<ElementPtr> networks = shared_networks->listValue();
305 for (auto network = networks.cbegin();
306 network != networks.cend(); ++network) {
307 const std::vector<ElementPtr> sh_list =
308 (*network)->get("subnet6")->listValue();
309 for (auto subnet = sh_list.cbegin();
310 subnet != sh_list.cend(); ++subnet) {
311 sn_list.push_back(*subnet);
312 }
313 }
314 }
315
316 // Host reservations
317 CfgHostsList resv_list;
318 resv_list.internalize(cfg_hosts_->toElement());
319
320 // Insert global reservations
321 ConstElementPtr global_resvs = resv_list.get(SUBNET_ID_GLOBAL);
322 if (global_resvs->size() > 0) {
323 dhcp->set("reservations", global_resvs);
324 }
325
326 // Insert subnet reservations
327 for (std::vector<ElementPtr>::const_iterator subnet = sn_list.cbegin();
328 subnet != sn_list.cend(); ++subnet) {
329 ConstElementPtr id = (*subnet)->get("id");
330 if (isNull(id)) {
331 isc_throw(ToElementError, "subnet has no id");
332 }
333 SubnetID subnet_id = id->intValue();
334 ConstElementPtr resvs = resv_list.get(subnet_id);
335 (*subnet)->set("reservations", resvs);
336 }
337
338 // Set expired-leases-processing
339 ConstElementPtr expired = cfg_expiration_->toElement();
340 dhcp->set("expired-leases-processing", expired);
341 if (family == AF_INET6) {
342 // Set server-id (DHCPv6)
343 dhcp->set("server-id", cfg_duid_->toElement());
344
345 // Set relay-supplied-options (DHCPv6)
346 dhcp->set("relay-supplied-options", cfg_rsoo_->toElement());
347 }
348 // Set lease-database
349 CfgLeaseDbAccess lease_db(*cfg_db_access_);
350 dhcp->set("lease-database", lease_db.toElement());
351 // Set hosts-databases
352 CfgHostDbAccess host_db(*cfg_db_access_);
353 ConstElementPtr hosts_databases = host_db.toElement();
354 if (hosts_databases->size() > 0) {
355 dhcp->set("hosts-databases", hosts_databases);
356 }
357 // Set host-reservation-identifiers
358 ConstElementPtr host_ids;
359 if (family == AF_INET) {
360 host_ids = cfg_host_operations4_->toElement();
361 } else {
362 host_ids = cfg_host_operations6_->toElement();
363 }
364 dhcp->set("host-reservation-identifiers", host_ids);
365 // Set mac-sources (DHCPv6)
366 if (family == AF_INET6) {
367 dhcp->set("mac-sources", cfg_mac_source_.toElement());
368 }
369 // Set control-socket (skip if null as empty is not legal)
370 if (!isNull(control_socket_)) {
371 dhcp->set("control-socket", UserContext::toElement(control_socket_));
372 }
373 // Set client-classes
374 ConstElementPtr client_classes = class_dictionary_->toElement();
375 // @todo accept empty list
376 if (!client_classes->empty()) {
377 dhcp->set("client-classes", client_classes);
378 }
379 // Set hooks-libraries
380 ConstElementPtr hooks_libs = hooks_config_.toElement();
381 dhcp->set("hooks-libraries", hooks_libs);
382 // Set DhcpX
383 result->set(family == AF_INET ? "Dhcp4" : "Dhcp6", dhcp);
384
385 ConstElementPtr cfg_consist = cfg_consist_->toElement();
386 dhcp->set("sanity-checks", cfg_consist);
387
388 // Set config-control (if it exists)
390 if (info) {
391 ConstElementPtr info_elem = info->toElement();
392 dhcp->set("config-control", info_elem);
393 }
394
395 // Set dhcp-packet-control (if it exists)
396 data::ConstElementPtr dhcp_queue_control = getDHCPQueueControl();
397 if (dhcp_queue_control) {
398 dhcp->set("dhcp-queue-control", dhcp_queue_control);
399 }
400
401 return (result);
402}
403
404}
405}
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
Cannot unparse error.
The Element class represents a piece of data, used by the command channel and configuration parts.
Definition: data.h:66
static ElementPtr create(const Position &pos=ZERO_POSITION())
Definition: data.cc:223
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition: data.cc:268
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
Definition: data.cc:263
Parameters for various consistency checks.
Holds manual configuration of the server identifier (DUID).
Definition: cfg_duid.h:30
Holds access parameters and the configuration of the lease and hosts database connection.
Definition: cfg_db_access.h:25
Holds configuration parameters pertaining to lease expiration and lease affinity.
Represents global configuration for host reservations.
Utility class to represent host reservation configurations internally as a map keyed by subnet IDs,...
isc::data::ConstElementPtr get(SubnetID id) const
Return the host reservations for a subnet ID.
void internalize(isc::data::ConstElementPtr list)
Internalize a list Element.
Represents the host reservations specified in the configuration file.
Definition: cfg_hosts.h:38
Represents selection of interfaces for DHCP server.
Definition: cfg_iface.h:130
virtual isc::data::ElementPtr toElement() const
Unparse a configuration object.
uint16_t getFamily() const
Returns address family.
Definition: cfgmgr.h:242
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition: cfgmgr.cc:25
Represents option definitions used by the DHCP server.
Represents option data configuration for the DHCP server.
Definition: cfg_option.h:248
Represents configuration of the RSOO options for the DHCP server.
Definition: cfg_rsoo.h:25
Represents configuration of IPv4 shared networks.
Represents configuration of IPv6 shared networks.
Holds subnets configured for the DHCPv4 server.
Definition: cfg_subnets4.h:32
Holds subnets configured for the DHCPv6 server.
Definition: cfg_subnets6.h:33
Maintains a list of ClientClassDef's.
Acts as a storage vault for D2 client configuration.
Definition: d2_client_cfg.h:53
static bool haveInstance()
Indicates if the lease manager has been instantiated.
Specifies current DHCP configuration.
Definition: srv_config.h:44
static const uint32_t CFGSEL_SUBNET4
Number of IPv4 subnets.
Definition: srv_config.h:52
void addConfiguredGlobal(const std::string &name, isc::data::ConstElementPtr value)
Adds a parameter to the collection configured globals.
Definition: srv_config.h:570
void extractConfiguredGlobals(isc::data::ConstElementPtr config)
Saves scalar elements from the global scope of a configuration.
Definition: srv_config.cc:184
void setD2ClientConfig(const D2ClientConfigPtr &d2_client_config)
Sets the D2 client configuration.
Definition: srv_config.h:555
bool sequenceEquals(const SrvConfig &other)
Compares configuration sequence with other sequence.
Definition: srv_config.cc:106
CfgSubnets4Ptr getCfgSubnets4()
Returns pointer to non-const object holding subnets configuration for DHCPv4.
Definition: srv_config.h:188
CfgSubnets6Ptr getCfgSubnets6()
Returns pointer to non-const object holding subnets configuration for DHCPv6.
Definition: srv_config.h:222
D2ClientConfigPtr getD2ClientConfig()
Returns pointer to the D2 client configuration.
Definition: srv_config.h:544
std::string getConfigSummary(const uint32_t selection) const
Returns summary of the configuration in the textual format.
Definition: srv_config.cc:65
const isc::data::ConstElementPtr getDHCPQueueControl() const
Returns DHCP queue control information.
Definition: srv_config.h:365
bool equals(const SrvConfig &other) const
Compares two objects for equality.
Definition: srv_config.cc:134
uint32_t getSequence() const
Returns configuration sequence number.
Definition: srv_config.h:106
static const uint32_t CFGSEL_DDNS
DDNS enabled/disabled.
Definition: srv_config.h:60
void removeStatistics()
Removes statistics.
Definition: srv_config.cc:160
virtual isc::data::ElementPtr toElement() const
Unparse a configuration object.
Definition: srv_config.cc:199
static const uint32_t CFGSEL_SUBNET6
Number of IPv6 subnets.
Definition: srv_config.h:54
void updateStatistics()
Updates statistics.
Definition: srv_config.cc:169
void copy(SrvConfig &new_config) const
Copies the current configuration to a new configuration.
Definition: srv_config.cc:111
SrvConfig()
Default constructor.
Definition: srv_config.cc:26
void clear()
Removes all configured hooks libraries.
Definition: hooks_config.h:59
bool equal(const HooksConfig &other) const
Compares two Hooks Config classes for equality.
Definition: hooks_config.cc:67
const isc::hooks::HookLibsCollection & get() const
Provides access to the configured hooks libraries.
Definition: hooks_config.h:54
isc::data::ElementPtr toElement() const
Unparse a configuration object.
void add(std::string libname, isc::data::ConstElementPtr parameters)
Adds additional hooks libraries.
Definition: hooks_config.h:46
virtual isc::data::ElementPtr toElement() const
Converts to Element representation.
Definition: config_base.cc:86
process::ConstConfigControlInfoPtr getConfigControlInfo() const
Fetches a read-only copy of the configuration control information.
Definition: config_base.h:82
void copy(ConfigBase &new_config) const
Copies the current configuration to a new configuration.
Definition: config_base.cc:69
bool equals(const ConfigBase &other) const
Compares two configuration.
Definition: config_base.cc:31
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:23
bool isNull(ConstElementPtr p)
Checks whether the given ElementPtr is a NULL pointer.
Definition: data.cc:1043
boost::shared_ptr< Element > ElementPtr
Definition: data.h:22
boost::multi_index_container< Subnet6Ptr, boost::multi_index::indexed_by< boost::multi_index::random_access< boost::multi_index::tag< SubnetRandomAccessIndexTag > >, boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetSubnetIdIndexTag >, boost::multi_index::const_mem_fun< Subnet, SubnetID, &Subnet::getID > >, boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetPrefixIndexTag >, boost::multi_index::const_mem_fun< Subnet, std::string, &Subnet::toText > > > > Subnet6Collection
A collection of Subnet6 objects.
Definition: subnet.h:843
boost::shared_ptr< SharedNetwork6 > SharedNetwork6Ptr
Pointer to SharedNetwork6 object.
uint32_t SubnetID
Unique identifier for a subnet (both v4 and v6)
Definition: lease.h:24
boost::multi_index_container< Subnet4Ptr, boost::multi_index::indexed_by< boost::multi_index::random_access< boost::multi_index::tag< SubnetRandomAccessIndexTag > >, boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetSubnetIdIndexTag >, boost::multi_index::const_mem_fun< Subnet, SubnetID, &Subnet::getID > >, boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetPrefixIndexTag >, boost::multi_index::const_mem_fun< Subnet, std::string, &Subnet::toText > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< SubnetServerIdIndexTag >, boost::multi_index::const_mem_fun< Network4, asiolink::IOAddress, &Network4::getServerId > > > > Subnet4Collection
A collection of Subnet4 objects.
Definition: subnet.h:798
boost::shared_ptr< SharedNetwork4 > SharedNetwork4Ptr
Pointer to SharedNetwork4 object.
boost::shared_ptr< const ConfigControlInfo > ConstConfigControlInfoPtr
Defines a pointer to a const ConfigControlInfo.
Defines the logger used by the top-level component of kea-dhcp-ddns.
void contextToElement(data::ElementPtr map) const
Merge unparse a user_context object.
Definition: user_context.cc:15
static data::ElementPtr toElement(data::ConstElementPtr map)
Copy extracting comments an Element map.
Definition: user_context.cc:34
virtual isc::data::ElementPtr toElement() const
Unparse.
utility class for unparsing
virtual isc::data::ElementPtr toElement() const
Unparse.