Kea 3.1.1
base_network_parser.cc
Go to the documentation of this file.
1// Copyright (C) 2019-2025 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>
11#include <util/optional.h>
12#include <util/str.h>
13
14using namespace isc::data;
15using namespace isc::util;
16
17namespace isc {
18namespace dhcp {
19
20void
22 NetworkPtr& network) {
23 bool has_renew = network_data->contains("renew-timer");
24 bool has_rebind = network_data->contains("rebind-timer");
25 int64_t renew = -1;
26 int64_t rebind = -1;
27
28 if (has_renew) {
29 renew = getInteger(network_data, "renew-timer");
30 if (renew < 0) {
31 isc_throw(DhcpConfigError, "the value of renew-timer ("
32 << renew << ") must be a positive number");
33 }
34 network->setT1(renew);
35 }
36
37 if (has_rebind) {
38 rebind = getInteger(network_data, "rebind-timer");
39 if (rebind < 0) {
40 isc_throw(DhcpConfigError, "the value of rebind-timer ("
41 << rebind << ") must be a positive number");
42 }
43 network->setT2(rebind);
44 }
45
46 if (has_renew && has_rebind && (renew > rebind)) {
47 // The renew-timer value is too large and server logic
48 // later on will end up not sending it. Warn the user but
49 // allow the configuration to pass.
51 .arg(network->getLabel())
52 .arg(renew)
53 .arg(rebind);
54 }
55
56 network->setValid(parseIntTriplet(network_data, "valid-lifetime"));
57
58 if (network_data->contains("store-extended-info")) {
59 network->setStoreExtendedInfo(getBoolean(network_data,
60 "store-extended-info"));
61 }
62
63 if (network_data->contains("reservations-global")) {
64 network->setReservationsGlobal(getBoolean(network_data,
65 "reservations-global"));
66 }
67
68 if (network_data->contains("reservations-in-subnet")) {
69 network->setReservationsInSubnet(getBoolean(network_data,
70 "reservations-in-subnet"));
71 }
72
73 if (network_data->contains("reservations-out-of-pool")) {
74 network->setReservationsOutOfPool(getBoolean(network_data,
75 "reservations-out-of-pool"));
76 }
77}
78
79void
81 NetworkPtr& network) {
82 bool calculate_tee_times = network->getCalculateTeeTimes();
83 if (network_data->contains("calculate-tee-times")) {
84 calculate_tee_times = getBoolean(network_data, "calculate-tee-times");
85 network->setCalculateTeeTimes(calculate_tee_times);
86 }
87
88 Optional<double> t2_percent;
89 if (network_data->contains("t2-percent")) {
90 t2_percent = getDouble(network_data, "t2-percent");
91 }
92
93 Optional<double> t1_percent;
94 if (network_data->contains("t1-percent")) {
95 t1_percent = getDouble(network_data, "t1-percent");
96 }
97 if (calculate_tee_times) {
98 if (!t2_percent.unspecified() && ((t2_percent.get() <= 0.0) ||
99 (t2_percent.get() >= 1.0))) {
100 isc_throw(DhcpConfigError, "t2-percent: " << t2_percent.get()
101 << " is invalid, it must be greater than 0.0 and less than 1.0");
102 }
103
104 if (!t1_percent.unspecified() && ((t1_percent.get() <= 0.0) ||
105 (t1_percent.get() >= 1.0))) {
106 isc_throw(DhcpConfigError, "t1-percent: " << t1_percent.get()
107 << " is invalid it must be greater than 0.0 and less than 1.0");
108 }
109
110 if (!t1_percent.unspecified() && !t2_percent.unspecified() &&
111 (t1_percent.get() >= t2_percent.get())) {
112 isc_throw(DhcpConfigError, "t1-percent: " << t1_percent.get()
113 << " is invalid, it must be less than t2-percent: "
114 << t2_percent.get());
115 }
116 }
117
118 network->setT2Percent(t2_percent);
119 network->setT1Percent(t1_percent);
120}
121
122void
124 NetworkPtr& network) {
125 if (network_data->contains("cache-threshold")) {
126 double cache_threshold = getDouble(network_data, "cache-threshold");
127 if ((cache_threshold < 0.0) || (cache_threshold >= 1.0)) {
128 isc_throw(DhcpConfigError, "cache-threshold: " << cache_threshold
129 << " is invalid, it must be greater than or equal to 0.0 and less than 1.0");
130 }
131 network->setCacheThreshold(cache_threshold);
132 }
133
134 if (network_data->contains("cache-max-age")) {
135 network->setCacheMaxAge(getInteger(network_data, "cache-max-age"));
136 }
137}
138
139void
141 NetworkPtr& network) {
142 parseDdnsParameters(network_data, network);
143}
144
145void
147 NetworkPtr& network) {
148 if (network_data->contains("allocator")) {
149 auto allocator_type = getString(network_data, "allocator");
150 if ((allocator_type != "iterative") && (allocator_type != "random") &&
151 (allocator_type != "flq")) {
152 // Unsupported allocator type used.
153 isc_throw(DhcpConfigError, "supported allocators are: iterative, random and flq");
154 }
155 network->setAllocatorType(allocator_type);
156 }
157}
158
159void
161 Network6Ptr& network) {
162 if (network_data->contains("pd-allocator")) {
163 auto allocator_type = getString(network_data, "pd-allocator");
164 if ((allocator_type != "iterative") && (allocator_type != "random") &&
165 (allocator_type != "flq")) {
166 // Unsupported allocator type used.
167 isc_throw(DhcpConfigError, "supported allocators are: iterative, random and flq");
168 }
169 network->setPdAllocatorType(allocator_type);
170 }
171}
172
173void
175 NetworkPtr& network) {
176 if (network_data->contains("adaptive-lease-time-threshold")) {
177 double adaptive_lease_time_threshold =
178 getDouble(network_data, "adaptive-lease-time-threshold");
179 if ((adaptive_lease_time_threshold <= 0.0) ||
180 (adaptive_lease_time_threshold > 1.0)) {
182 "adaptive-lease-time-threshold: "
183 << adaptive_lease_time_threshold
184 << " is invalid, it must be greater than 0.0 "
185 << "and less than or equal to 1.0");
186 }
187 network->setAdaptiveLeaseTimeThreshold(adaptive_lease_time_threshold);
188 }
189}
190
191void
193 Network4Ptr& network) {
194 if (network_data->contains("offer-lifetime")) {
195 auto value = getInteger(network_data, "offer-lifetime");
196 if (value < 0) {
197 isc_throw(DhcpConfigError, "the value of offer-lifetime '"
198 << value << "' must be a positive number ("
199 << getPosition("offer-lifetime", network_data) << ")");
200 }
201
202 network->setOfferLft(value);
203 }
204}
205
206void
208 ClassAdderFunc adder_func) {
209 // Try setting up additional client classes.
210 ConstElementPtr req_class_list = params->get("require-client-classes");
211 ConstElementPtr class_list = params->get("evaluate-additional-classes");
212 if (req_class_list) {
213 if (!class_list) {
215 class_list = req_class_list;
216 } else {
218 "cannot specify both 'require-client-classes' and "
219 "'evaluate-additional-classes'. Use only the latter.");
220 }
221 }
222
223 if (class_list) {
224 const std::vector<data::ElementPtr>& classes = class_list->listValue();
225 for (auto const& cclass : classes) {
226 if ((cclass->getType() != Element::string) ||
227 cclass->stringValue().empty()) {
228 isc_throw(DhcpConfigError, "invalid class name (" << cclass->getPosition() << ")");
229 }
230
231 (adder_func)(cclass->stringValue());
232 }
233 }
234}
235
236void
238 ClassAdderFunc adder_func) {
239 // Try setting up client client classes.
240 ConstElementPtr class_elem = params->get("client-class");
241 ConstElementPtr class_list = params->get("client-classes");
242 if (class_elem) {
243 if (!class_list) {
245 if (class_elem->getType() != Element::string) {
246 isc_throw(DhcpConfigError, "invalid class name (" << class_elem->getPosition() << ")");
247 }
248
249 if (!class_elem->stringValue().empty()) {
250 (adder_func)(class_elem->stringValue());
251 }
252 } else {
254 "cannot specify both 'client-class' and "
255 "'client-classes'. Use only the latter.");
256 }
257 }
258
259 if (class_list) {
260 for (auto const& cclass : class_list->listValue()) {
261 if ((cclass->getType() != Element::string) ||
262 cclass->stringValue().empty()) {
263 isc_throw(DhcpConfigError, "invalid class name (" << cclass->getPosition() << ")");
264 }
265
266 (adder_func)(cclass->stringValue());
267 }
268 }
269}
270
271} // end of namespace isc::dhcp
272} // end of namespace isc
int class_list(CalloutHandle &handle)
This is a command callout for 'class-list' command.
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 parseAllocatorParams(const data::ConstElementPtr &network_data, NetworkPtr &network)
Parses parameters pertaining to allocator selection.
static void getClientClassesElem(data::ConstElementPtr params, ClassAdderFunc adder_func)
Fetches the element for either 'client-classes' or deprecated 'client-class'.
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.
void parseAdaptiveLeaseTimeParam(const data::ConstElementPtr &network_data, NetworkPtr &network)
Parses parameter related to adaptive lease time.
std::function< void(const isc::dhcp::ClientClass &)> ClassAdderFunc
void parseDdnsParameters(const data::ConstElementPtr &config, DdnsOwnerTypePtr owner)
Parses parameters pertaining to DDNS behavior.
static void getAdditionalClassesElem(data::ConstElementPtr params, ClassAdderFunc adder_func)
Fetches the element for either 'evaluate-additional-classes' or deprecated 'require-client-classes'.
void parseTeePercents(const data::ConstElementPtr &network_data, NetworkPtr &network)
Parses parameters related to "percent" timers settings.
void parsePdAllocatorParams(const data::ConstElementPtr &network_data, Network6Ptr &network)
Parses parameters pertaining to prefix delegation allocator selection.
void parseOfferLft(const data::ConstElementPtr &network_data, Network4Ptr &network)
Parses offer-lifetime parameter (v4 only)
To be removed. Please use ConfigError instead.
A template representing an optional value.
Definition optional.h:36
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
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
Definition macros.h:26
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:29
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
Definition dhcpsrv_log.h:56
boost::shared_ptr< Network4 > Network4Ptr
Pointer to the Network4 object.
Definition network.h:1503
const isc::log::MessageID DHCPSRV_CFGMGR_RENEW_GTR_REBIND
boost::shared_ptr< Network6 > Network6Ptr
Pointer to the Network6 object.
Definition network.h:1508
const isc::log::MessageID DHCPSRV_CLIENT_CLASS_DEPRECATED
const isc::log::MessageID DHCPSRV_REQUIRE_CLIENT_CLASSES_DEPRECATED
boost::shared_ptr< Network > NetworkPtr
Pointer to the Network object.
Definition network.h:73
Defines the logger used by the top-level component of kea-lfc.