Kea 2.2.0
base_network_parser.cc
Go to the documentation of this file.
1// Copyright (C) 2019-2022 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 <util/triplet.h>
10#include <util/optional.h>
11#include <util/strutil.h>
12
13using namespace isc::data;
14using namespace isc::util;
15
16namespace isc {
17namespace dhcp {
18
19void
21 if (!config->contains("reservation-mode")) {
22 return;
23 }
24 if (config->contains("reservations-global") ||
25 config->contains("reservations-in-subnet") ||
26 config->contains("reservations-out-of-pool")) {
27 isc_throw(DhcpConfigError, "invalid use of both 'reservation-mode'"
28 " and one of 'reservations-global', 'reservations-in-subnet'"
29 " or 'reservations-out-of-pool' parameters");
30 }
31 std::string hr_mode = getString(config, "reservation-mode");
32 if ((hr_mode == "disabled") || (hr_mode == "off")) {
33 config->set("reservations-global", Element::create(false));
34 config->set("reservations-in-subnet", Element::create(false));
35 } else if (hr_mode == "out-of-pool") {
36 config->set("reservations-global", Element::create(false));
37 config->set("reservations-in-subnet", Element::create(true));
38 config->set("reservations-out-of-pool", Element::create(true));
39 } else if (hr_mode == "global") {
40 config->set("reservations-global", Element::create(true));
41 config->set("reservations-in-subnet", Element::create(false));
42 } else if (hr_mode == "all") {
43 config->set("reservations-global", Element::create(false));
44 config->set("reservations-in-subnet", Element::create(true));
45 config->set("reservations-out-of-pool", Element::create(false));
46 } else {
47 isc_throw(DhcpConfigError, "invalid reservation-mode parameter: '"
48 << hr_mode << "' ("
49 << getPosition("reservation-mode", config) << ")");
50 }
51 config->remove("reservation-mode");
52}
53
54void
56 if (!config->get(CfgGlobals::RESERVATION_MODE)) {
57 return;
58 }
59 if (config->get(CfgGlobals::RESERVATIONS_GLOBAL) ||
62 isc_throw(DhcpConfigError, "invalid use of both 'reservation-mode'"
63 " and one of 'reservations-global', 'reservations-in-subnet'"
64 " or 'reservations-out-of-pool' parameters");
65 }
66 std::string hr_mode = config->get(CfgGlobals::RESERVATION_MODE)->stringValue();
67 if ((hr_mode == "disabled") || (hr_mode == "off")) {
70 } else if (hr_mode == "out-of-pool") {
74 } else if (hr_mode == "global") {
77 } else if (hr_mode == "all") {
80 config->set("reservations-out-of-pool", Element::create(false));
81 } else {
82 isc_throw(DhcpConfigError, "invalid reservation-mode parameter: '"
83 << hr_mode << "' ("
84 << config->get(CfgGlobals::RESERVATION_MODE)->getPosition()
85 << ")");
86 }
88}
89
90void
92 NetworkPtr& network) {
93 bool has_renew = network_data->contains("renew-timer");
94 bool has_rebind = network_data->contains("rebind-timer");
95 int64_t renew = -1;
96 int64_t rebind = -1;
97
98 if (has_renew) {
99 renew = getInteger(network_data, "renew-timer");
100 if (renew < 0) {
101 isc_throw(DhcpConfigError, "the value of renew-timer ("
102 << renew << ") must be a positive number");
103 }
104 network->setT1(renew);
105 }
106
107 if (has_rebind) {
108 rebind = getInteger(network_data, "rebind-timer");
109 if (rebind < 0) {
110 isc_throw(DhcpConfigError, "the value of rebind-timer ("
111 << rebind << ") must be a positive number");
112 }
113 network->setT2(rebind);
114 }
115
116 if (has_renew && has_rebind && (renew > rebind)) {
117 isc_throw(DhcpConfigError, "the value of renew-timer (" << renew
118 << ") is greater than the value of rebind-timer ("
119 << rebind << ")");
120 }
121
122 network->setValid(parseIntTriplet(network_data, "valid-lifetime"));
123
124 if (network_data->contains("store-extended-info")) {
125 network->setStoreExtendedInfo(getBoolean(network_data,
126 "store-extended-info"));
127 }
128
129 if (network_data->contains("reservations-global")) {
130 network->setReservationsGlobal(getBoolean(network_data,
131 "reservations-global"));
132 }
133
134 if (network_data->contains("reservations-in-subnet")) {
135 network->setReservationsInSubnet(getBoolean(network_data,
136 "reservations-in-subnet"));
137 }
138
139 if (network_data->contains("reservations-out-of-pool")) {
140 network->setReservationsOutOfPool(getBoolean(network_data,
141 "reservations-out-of-pool"));
142 }
143}
144
145void
147 NetworkPtr& network) {
148 bool calculate_tee_times = network->getCalculateTeeTimes();
149 if (network_data->contains("calculate-tee-times")) {
150 calculate_tee_times = getBoolean(network_data, "calculate-tee-times");
151 network->setCalculateTeeTimes(calculate_tee_times);
152 }
153
154 Optional<double> t2_percent;
155 if (network_data->contains("t2-percent")) {
156 t2_percent = getDouble(network_data, "t2-percent");
157 }
158
159 Optional<double> t1_percent;
160 if (network_data->contains("t1-percent")) {
161 t1_percent = getDouble(network_data, "t1-percent");
162 }
163 if (calculate_tee_times) {
164 if (!t2_percent.unspecified() && ((t2_percent.get() <= 0.0) ||
165 (t2_percent.get() >= 1.0))) {
166 isc_throw(DhcpConfigError, "t2-percent: " << t2_percent.get()
167 << " is invalid, it must be greater than 0.0 and less than 1.0");
168 }
169
170 if (!t1_percent.unspecified() && ((t1_percent.get() <= 0.0) ||
171 (t1_percent.get() >= 1.0))) {
172 isc_throw(DhcpConfigError, "t1-percent: " << t1_percent.get()
173 << " is invalid it must be greater than 0.0 and less than 1.0");
174 }
175
176 if (!t1_percent.unspecified() && !t2_percent.unspecified() &&
177 (t1_percent.get() >= t2_percent.get())) {
178 isc_throw(DhcpConfigError, "t1-percent: " << t1_percent.get()
179 << " is invalid, it must be less than t2-percent: "
180 << t2_percent.get());
181 }
182 }
183
184 network->setT2Percent(t2_percent);
185 network->setT1Percent(t1_percent);
186}
187
188void
190 NetworkPtr& network) {
191 if (network_data->contains("cache-threshold")) {
192 double cache_threshold = getDouble(network_data, "cache-threshold");
193 if ((cache_threshold <= 0.0) || (cache_threshold >= 1.0)) {
194 isc_throw(DhcpConfigError, "cache-threshold: " << cache_threshold
195 << " is invalid, it must be greater than 0.0 and less than 1.0");
196 }
197 network->setCacheThreshold(cache_threshold);
198 }
199
200 if (network_data->contains("cache-max-age")) {
201 network->setCacheMaxAge(getInteger(network_data, "cache-max-age"));
202 }
203}
204
205void
207 NetworkPtr& network) {
208
209 if (network_data->contains("ddns-send-updates")) {
210 network->setDdnsSendUpdates(getBoolean(network_data, "ddns-send-updates"));
211 }
212
213 if (network_data->contains("ddns-override-no-update")) {
214 network->setDdnsOverrideNoUpdate(getBoolean(network_data, "ddns-override-no-update"));
215 }
216
217 if (network_data->contains("ddns-override-client-update")) {
218 network->setDdnsOverrideClientUpdate(getBoolean(network_data, "ddns-override-client-update"));
219 }
220
221 if (network_data->contains("ddns-replace-client-name")) {
222 network->setDdnsReplaceClientNameMode(getAndConvert<D2ClientConfig::ReplaceClientNameMode,
224 (network_data, "ddns-replace-client-name",
225 "ReplaceClientName mode"));
226 }
227
228 if (network_data->contains("ddns-generated-prefix")) {
229 network->setDdnsGeneratedPrefix(getString(network_data, "ddns-generated-prefix"));
230 }
231
232 if (network_data->contains("ddns-qualifying-suffix")) {
233 network->setDdnsQualifyingSuffix(getString(network_data, "ddns-qualifying-suffix"));
234 }
235
236 std::string hostname_char_set;
237 if (network_data->contains("hostname-char-set")) {
238 hostname_char_set = getString(network_data, "hostname-char-set");
239 network->setHostnameCharSet(hostname_char_set);
240 }
241
242 std::string hostname_char_replacement;
243 if (network_data->contains("hostname-char-replacement")) {
244 hostname_char_replacement = getString(network_data, "hostname-char-replacement");
245 network->setHostnameCharReplacement(hostname_char_replacement);
246 }
247
248 // We need to validate sanitizer values here so we can detect problems and
249 // cause a configuration. We don't retain the compilation because it's not
250 // something we can inherit.
251 if (!hostname_char_set.empty()) {
252 try {
253 str::StringSanitizerPtr sanitizer(new str::StringSanitizer(hostname_char_set,
254 hostname_char_replacement));
255 } catch (const std::exception& ex) {
256 isc_throw(BadValue, "hostname-char-set '" << hostname_char_set
257 << "' is not a valid regular expression");
258 }
259 }
260
261 if (network_data->contains("ddns-update-on-renew")) {
262 network->setDdnsUpdateOnRenew(getBoolean(network_data, "ddns-update-on-renew"));
263 }
264
265 if (network_data->contains("ddns-use-conflict-resolution")) {
266 network->setDdnsUseConflictResolution(getBoolean(network_data, "ddns-use-conflict-resolution"));
267 }
268}
269
270} // end of namespace isc::dhcp
271} // end of namespace isc
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
static ElementPtr create(const Position &pos=ZERO_POSITION())
Definition: data.cc:241
target_type getAndConvert(isc::data::ConstElementPtr scope, const std::string &name, const std::string &type_name)
Returns a converted value from a scope.
static const data::Element::Position & getPosition(const std::string &name, const data::ConstElementPtr parent)
Utility method that returns position of an element.
static double getDouble(const ConstElementPtr &scope, const std::string &name)
Returns a floating point parameter from a scope.
static std::string getString(isc::data::ConstElementPtr scope, const std::string &name)
Returns a string parameter from a scope.
const isc::util::Triplet< uint32_t > parseIntTriplet(const data::ConstElementPtr &scope, const std::string &name)
Parses an integer triplet.
static bool getBoolean(isc::data::ConstElementPtr scope, const std::string &name)
Returns a boolean parameter from a scope.
static int64_t getInteger(isc::data::ConstElementPtr scope, const std::string &name)
Returns an integer parameter from a scope.
void parseCacheParams(const data::ConstElementPtr &network_data, NetworkPtr &network)
Parses parameters related to lease cache settings.
void parseDdnsParams(const data::ConstElementPtr &network_data, NetworkPtr &network)
Parses parameters pertaining to DDNS behavior.
void parseCommon(const data::ConstElementPtr &network_data, NetworkPtr &network)
Parses common parameters.
static void moveReservationMode(isc::data::ElementPtr config)
Moves deprecated reservation-mode parameter to new reservations flags.
void parseTeePercents(const data::ConstElementPtr &network_data, NetworkPtr &network)
Parses parameters related to "percent" timers settings.
static ReplaceClientNameMode stringToReplaceClientNameMode(const std::string &mode_str)
Converts labels to ReplaceClientNameMode enum values.
ReplaceClientNameMode
Defines the client name replacement modes.
Definition: d2_client_cfg.h:76
To be removed. Please use ConfigError instead.
T get() const
Retrieves the encapsulated value.
Definition: optional.h:114
void unspecified(bool unspecified)
Modifies the flag that indicates whether the value is specified or unspecified.
Definition: optional.h:136
Implements a regular expression based string scrubber.
Definition: strutil.h:310
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:27
boost::shared_ptr< Element > ElementPtr
Definition: data.h:24
boost::shared_ptr< CfgGlobals > CfgGlobalsPtr
Non-const shared pointer to a CfgGlobals instance.
Definition: cfg_globals.h:156
boost::shared_ptr< Network > NetworkPtr
Pointer to the Network object.
Definition: network.h:41
boost::shared_ptr< StringSanitizer > StringSanitizerPtr
Type representing the pointer to the StringSanitizer.
Definition: strutil.h:358
Definition: edns.h:19
Defines the logger used by the top-level component of kea-lfc.