2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-23 02:17:33 +00:00
kea/src/lib/dhcpsrv/parsers/base_network_parser.cc

257 lines
9.5 KiB
C++
Raw Normal View History

// Copyright (C) 2019-2025 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/.
#include <config.h>
#include <util/triplet.h>
#include <dhcpsrv/dhcpsrv_log.h>
#include <dhcpsrv/parsers/base_network_parser.h>
#include <util/optional.h>
#include <util/str.h>
using namespace isc::data;
using namespace isc::util;
namespace isc {
namespace dhcp {
void
BaseNetworkParser::parseCommon(const ConstElementPtr& network_data,
NetworkPtr& network) {
bool has_renew = network_data->contains("renew-timer");
bool has_rebind = network_data->contains("rebind-timer");
int64_t renew = -1;
int64_t rebind = -1;
if (has_renew) {
renew = getInteger(network_data, "renew-timer");
if (renew < 0) {
isc_throw(DhcpConfigError, "the value of renew-timer ("
<< renew << ") must be a positive number");
}
network->setT1(renew);
}
if (has_rebind) {
rebind = getInteger(network_data, "rebind-timer");
if (rebind < 0) {
isc_throw(DhcpConfigError, "the value of rebind-timer ("
<< rebind << ") must be a positive number");
}
network->setT2(rebind);
}
if (has_renew && has_rebind && (renew > rebind)) {
// The renew-timer value is too large and server logic
// later on will end up not sending it. Warn the user but
// allow the configuration to pass.
LOG_WARN(dhcpsrv_logger, DHCPSRV_CFGMGR_RENEW_GTR_REBIND)
.arg(network->getLabel())
.arg(renew)
.arg(rebind);
}
network->setValid(parseIntTriplet(network_data, "valid-lifetime"));
if (network_data->contains("store-extended-info")) {
network->setStoreExtendedInfo(getBoolean(network_data,
"store-extended-info"));
}
2020-11-11 19:06:06 +02:00
if (network_data->contains("reservations-global")) {
network->setReservationsGlobal(getBoolean(network_data,
"reservations-global"));
}
if (network_data->contains("reservations-in-subnet")) {
network->setReservationsInSubnet(getBoolean(network_data,
"reservations-in-subnet"));
}
if (network_data->contains("reservations-out-of-pool")) {
network->setReservationsOutOfPool(getBoolean(network_data,
"reservations-out-of-pool"));
}
}
void
BaseNetworkParser::parseTeePercents(const ConstElementPtr& network_data,
NetworkPtr& network) {
bool calculate_tee_times = network->getCalculateTeeTimes();
if (network_data->contains("calculate-tee-times")) {
calculate_tee_times = getBoolean(network_data, "calculate-tee-times");
network->setCalculateTeeTimes(calculate_tee_times);
}
Optional<double> t2_percent;
if (network_data->contains("t2-percent")) {
t2_percent = getDouble(network_data, "t2-percent");
}
Optional<double> t1_percent;
if (network_data->contains("t1-percent")) {
t1_percent = getDouble(network_data, "t1-percent");
}
if (calculate_tee_times) {
if (!t2_percent.unspecified() && ((t2_percent.get() <= 0.0) ||
(t2_percent.get() >= 1.0))) {
isc_throw(DhcpConfigError, "t2-percent: " << t2_percent.get()
<< " is invalid, it must be greater than 0.0 and less than 1.0");
}
if (!t1_percent.unspecified() && ((t1_percent.get() <= 0.0) ||
(t1_percent.get() >= 1.0))) {
isc_throw(DhcpConfigError, "t1-percent: " << t1_percent.get()
<< " is invalid it must be greater than 0.0 and less than 1.0");
}
if (!t1_percent.unspecified() && !t2_percent.unspecified() &&
(t1_percent.get() >= t2_percent.get())) {
isc_throw(DhcpConfigError, "t1-percent: " << t1_percent.get()
<< " is invalid, it must be less than t2-percent: "
<< t2_percent.get());
}
}
network->setT2Percent(t2_percent);
network->setT1Percent(t1_percent);
}
void
BaseNetworkParser::parseCacheParams(const ConstElementPtr& network_data,
NetworkPtr& network) {
if (network_data->contains("cache-threshold")) {
double cache_threshold = getDouble(network_data, "cache-threshold");
if ((cache_threshold < 0.0) || (cache_threshold >= 1.0)) {
isc_throw(DhcpConfigError, "cache-threshold: " << cache_threshold
<< " is invalid, it must be greater than or equal to 0.0 and less than 1.0");
}
network->setCacheThreshold(cache_threshold);
}
2020-10-02 17:10:31 +02:00
if (network_data->contains("cache-max-age")) {
network->setCacheMaxAge(getInteger(network_data, "cache-max-age"));
}
}
[#35,!517] Added DDDNS parameters to networks,subnets, and their parsers src/lib/dhcpsrv/network.* Network - added DDNS parameters: Optional members, getters, setters Network::toElement() - added DDNS parameters src/lib/dhcpsrv/parsers/base_network_parser.* BaseNetworkParser::parseDdnsParams() - new method to parse DDNS parameters BaseNetworkParser::parseLifetime() - fixed unitialized variables warning src/lib/dhcpsrv/parsers/dhcp_parsers.cc Subnet4ConfigParser::initSubnet() Subnet6ConfigParser::initSubnet() - added call to parseDdnsParms(). src/lib/dhcpsrv/parsers/shared_network_parser.cc SharedNetwork4Parser::parse() SharedNetwork6Parser::parse() - added call to parseDdnsParms(). src/lib/dhcpsrv/parsers/simple_parser4.cc SimpleParser4::GLOBAL4_PARAMETERS SimpleParser4::GLOBAL4_DEFAULTS SimpleParser4::SUBNET4_PARAMETERS SimpleParser4::INHERIT_TO_SUBNET4 SimpleParser4::SHARED_NETWORK4_PARAMETERS - added DDNS parameters src/lib/dhcpsrv/parsers/simple_parser6.cc SimpleParser6::GLOBAL6_PARAMETERS SimpleParser6::GLOBAL6_DEFAULTS SimpleParser6::SUBNET6_PARAMETERS SimpleParser6::INHERIT_TO_SUBNET6 SimpleParser6::SHARED_NETWORK6_PARAMETERS - added DDNS parameters src/lib/dhcpsrv/tests/cfg_shared_networks4_unittest.cc src/lib/dhcpsrv/tests/cfg_shared_networks6_unittest.cc src/lib/dhcpsrv/tests/dhcp_parsers_unittest.cc src/lib/dhcpsrv/tests/network_unittest.cc src/lib/dhcpsrv/tests/shared_network_parser_unittest.cc src/lib/dhcpsrv/tests/shared_network_unittest.cc src/lib/dhcpsrv/tests/subnet_unittest.cc Updated tests.
2019-09-26 08:33:41 -04:00
void
BaseNetworkParser::parseDdnsParams(const data::ConstElementPtr& network_data,
NetworkPtr& network) {
parseDdnsParameters(network_data, network);
[#35,!517] Added DDDNS parameters to networks,subnets, and their parsers src/lib/dhcpsrv/network.* Network - added DDNS parameters: Optional members, getters, setters Network::toElement() - added DDNS parameters src/lib/dhcpsrv/parsers/base_network_parser.* BaseNetworkParser::parseDdnsParams() - new method to parse DDNS parameters BaseNetworkParser::parseLifetime() - fixed unitialized variables warning src/lib/dhcpsrv/parsers/dhcp_parsers.cc Subnet4ConfigParser::initSubnet() Subnet6ConfigParser::initSubnet() - added call to parseDdnsParms(). src/lib/dhcpsrv/parsers/shared_network_parser.cc SharedNetwork4Parser::parse() SharedNetwork6Parser::parse() - added call to parseDdnsParms(). src/lib/dhcpsrv/parsers/simple_parser4.cc SimpleParser4::GLOBAL4_PARAMETERS SimpleParser4::GLOBAL4_DEFAULTS SimpleParser4::SUBNET4_PARAMETERS SimpleParser4::INHERIT_TO_SUBNET4 SimpleParser4::SHARED_NETWORK4_PARAMETERS - added DDNS parameters src/lib/dhcpsrv/parsers/simple_parser6.cc SimpleParser6::GLOBAL6_PARAMETERS SimpleParser6::GLOBAL6_DEFAULTS SimpleParser6::SUBNET6_PARAMETERS SimpleParser6::INHERIT_TO_SUBNET6 SimpleParser6::SHARED_NETWORK6_PARAMETERS - added DDNS parameters src/lib/dhcpsrv/tests/cfg_shared_networks4_unittest.cc src/lib/dhcpsrv/tests/cfg_shared_networks6_unittest.cc src/lib/dhcpsrv/tests/dhcp_parsers_unittest.cc src/lib/dhcpsrv/tests/network_unittest.cc src/lib/dhcpsrv/tests/shared_network_parser_unittest.cc src/lib/dhcpsrv/tests/shared_network_unittest.cc src/lib/dhcpsrv/tests/subnet_unittest.cc Updated tests.
2019-09-26 08:33:41 -04:00
}
2022-11-21 17:30:31 +01:00
void
BaseNetworkParser::parseAllocatorParams(const data::ConstElementPtr& network_data,
NetworkPtr& network) {
if (network_data->contains("allocator")) {
auto allocator_type = getString(network_data, "allocator");
2023-03-16 19:09:05 +01:00
if ((allocator_type != "iterative") && (allocator_type != "random") &&
(allocator_type != "flq")) {
2022-11-21 17:30:31 +01:00
// Unsupported allocator type used.
2023-03-16 19:09:05 +01:00
isc_throw(DhcpConfigError, "supported allocators are: iterative, random and flq");
2022-11-21 17:30:31 +01:00
}
network->setAllocatorType(allocator_type);
}
}
void
BaseNetworkParser::parsePdAllocatorParams(const data::ConstElementPtr& network_data,
Network6Ptr& network) {
if (network_data->contains("pd-allocator")) {
auto allocator_type = getString(network_data, "pd-allocator");
2023-03-16 19:09:05 +01:00
if ((allocator_type != "iterative") && (allocator_type != "random") &&
(allocator_type != "flq")) {
2022-11-21 17:30:31 +01:00
// Unsupported allocator type used.
2023-03-16 19:09:05 +01:00
isc_throw(DhcpConfigError, "supported allocators are: iterative, random and flq");
2022-11-21 17:30:31 +01:00
}
network->setPdAllocatorType(allocator_type);
}
}
void
BaseNetworkParser::parseOfferLft(const data::ConstElementPtr& network_data,
Network4Ptr& network) {
if (network_data->contains("offer-lifetime")) {
auto value = getInteger(network_data, "offer-lifetime");
if (value < 0) {
isc_throw(DhcpConfigError, "the value of offer-lifetime '"
<< value << "' must be a positive number ("
<< getPosition("offer-lifetime", network_data) << ")");
}
network->setOfferLft(value);
}
}
void
BaseNetworkParser::getAdditionalClassesElem(ConstElementPtr params,
ClassAdderFunc adder_func) {
2024-10-25 21:58:16 +03:00
// Try setting up additional client classes.
ConstElementPtr req_class_list = params->get("require-client-classes");
ConstElementPtr class_list = params->get("evaluate-additional-classes");
if (req_class_list) {
if (!class_list) {
LOG_WARN(dhcpsrv_logger, DHCPSRV_REQUIRE_CLIENT_CLASSES_DEPRECATED);
class_list = req_class_list;
} else {
isc_throw(isc::dhcp::DhcpConfigError,
"cannot specify both 'require-client-classes' and "
"'evaluate-additional-classes'. Use only the latter.");
}
}
if (class_list) {
const std::vector<data::ElementPtr>& classes = class_list->listValue();
for (auto const& cclass : classes) {
if ((cclass->getType() != Element::string) ||
cclass->stringValue().empty()) {
isc_throw(DhcpConfigError, "invalid class name (" << cclass->getPosition() << ")");
}
(adder_func)(cclass->stringValue());
}
}
}
[#3592] modified in lib dhcp and dhcpsrv src/lib/dhcp/classify.* ClientClasses:intersects() - new function src/lib/dhcp/tests/classify_unittest.cc TEST(ClassifyTest, ClientClassesIntersects) - new test src/lib/dhcpsrv/cfg_option.cc OptionDescriptor::allowedForClientClasses() use inet intersects() function src/lib/dhcpsrv/dhcpsrv_messages.mes DHCPSRV_CLIENT_CLASS_DEPRECATED - new message src/lib/dhcpsrv/network.* Network - replaced client_class_ string with client_classes_ container Network::clientSupported() - uses new intersects() function Network::allowClientClass() - modified to insert Network::toElement() - updated src/lib/dhcpsrv/parsers/base_network_parser.* BaseNetworkParser::getClientClassesElem() - new function src/lib/dhcpsrv/parsers/dhcp_parsers.cc src/lib/dhcpsrv/parsers/shared_network_parser.cc Updated parsers to use BaseNetworkParser::getClientClassesElem() src/lib/dhcpsrv/parsers/simple_parser4.cc src/lib/dhcpsrv/parsers/simple_parser6.cc Added client-classes src/lib/dhcpsrv/pool.* replaced client_class_ string with client_classes_ container Pool::clientSupported()- use new intersects() function src/lib/dhcpsrv/shared_network.cc ShareNetwork::getPreferredSubnet() - updated src/lib/dhcpsrv/tests/cfg_subnets4_unittest.cc src/lib/dhcpsrv/tests/cfg_subnets6_unittest.cc Updated tests src/lib/dhcpsrv/tests/dhcp_parsers_unittest.cc TEST_F(DhcpParserTest, deprecatedClientClassSubnet4) TEST_F(DhcpParserTest, deprecatedClientClassSubnet6) { TEST_F(DhcpParserTest, deprecatedClientClassPool4) { TEST_F(DhcpParserTest, deprecatedClientClassPool6) { src/lib/dhcpsrv/tests/network_unittest.cc Removed inheritance support check src/lib/dhcpsrv/tests/pool_unittest.cc Updated tests src/lib/dhcpsrv/tests/shared_network_parser_unittest.cc TEST_F(SharedNetwork4ParserTest, deprecatedClientClass) TEST_F(SharedNetwork6ParserTest, deprecatedClientClass) src/lib/dhcpsrv/tests/shared_network_unittest.cc src/lib/dhcpsrv/tests/subnet_unittest.cc Updated tests src/lib/dhcpsrv/testutils/generic_cb_dhcp4_unittest.cc src/lib/dhcpsrv/testutils/generic_cb_dhcp6_unittest.cc Updated tests
2024-10-30 14:31:18 -04:00
void
BaseNetworkParser::getClientClassesElem(ConstElementPtr params,
ClassAdderFunc adder_func) {
// Try setting up client client classes.
ConstElementPtr class_elem = params->get("client-class");
ConstElementPtr class_list = params->get("client-classes");
if (class_elem) {
if (!class_list) {
LOG_WARN(dhcpsrv_logger, DHCPSRV_CLIENT_CLASS_DEPRECATED);
if (class_elem->getType() != Element::string) {
isc_throw(DhcpConfigError, "invalid class name (" << class_elem->getPosition() << ")");
}
if (!class_elem->stringValue().empty()) {
(adder_func)(class_elem->stringValue());
}
} else {
isc_throw(isc::dhcp::DhcpConfigError,
"cannot specify both 'client-class' and "
"'client-classes'. Use only the latter.");
}
}
if (class_list) {
for (auto const& cclass : class_list->listValue()) {
[#3592] modified in lib dhcp and dhcpsrv src/lib/dhcp/classify.* ClientClasses:intersects() - new function src/lib/dhcp/tests/classify_unittest.cc TEST(ClassifyTest, ClientClassesIntersects) - new test src/lib/dhcpsrv/cfg_option.cc OptionDescriptor::allowedForClientClasses() use inet intersects() function src/lib/dhcpsrv/dhcpsrv_messages.mes DHCPSRV_CLIENT_CLASS_DEPRECATED - new message src/lib/dhcpsrv/network.* Network - replaced client_class_ string with client_classes_ container Network::clientSupported() - uses new intersects() function Network::allowClientClass() - modified to insert Network::toElement() - updated src/lib/dhcpsrv/parsers/base_network_parser.* BaseNetworkParser::getClientClassesElem() - new function src/lib/dhcpsrv/parsers/dhcp_parsers.cc src/lib/dhcpsrv/parsers/shared_network_parser.cc Updated parsers to use BaseNetworkParser::getClientClassesElem() src/lib/dhcpsrv/parsers/simple_parser4.cc src/lib/dhcpsrv/parsers/simple_parser6.cc Added client-classes src/lib/dhcpsrv/pool.* replaced client_class_ string with client_classes_ container Pool::clientSupported()- use new intersects() function src/lib/dhcpsrv/shared_network.cc ShareNetwork::getPreferredSubnet() - updated src/lib/dhcpsrv/tests/cfg_subnets4_unittest.cc src/lib/dhcpsrv/tests/cfg_subnets6_unittest.cc Updated tests src/lib/dhcpsrv/tests/dhcp_parsers_unittest.cc TEST_F(DhcpParserTest, deprecatedClientClassSubnet4) TEST_F(DhcpParserTest, deprecatedClientClassSubnet6) { TEST_F(DhcpParserTest, deprecatedClientClassPool4) { TEST_F(DhcpParserTest, deprecatedClientClassPool6) { src/lib/dhcpsrv/tests/network_unittest.cc Removed inheritance support check src/lib/dhcpsrv/tests/pool_unittest.cc Updated tests src/lib/dhcpsrv/tests/shared_network_parser_unittest.cc TEST_F(SharedNetwork4ParserTest, deprecatedClientClass) TEST_F(SharedNetwork6ParserTest, deprecatedClientClass) src/lib/dhcpsrv/tests/shared_network_unittest.cc src/lib/dhcpsrv/tests/subnet_unittest.cc Updated tests src/lib/dhcpsrv/testutils/generic_cb_dhcp4_unittest.cc src/lib/dhcpsrv/testutils/generic_cb_dhcp6_unittest.cc Updated tests
2024-10-30 14:31:18 -04:00
if ((cclass->getType() != Element::string) ||
cclass->stringValue().empty()) {
isc_throw(DhcpConfigError, "invalid class name (" << cclass->getPosition() << ")");
}
(adder_func)(cclass->stringValue());
}
}
}
} // end of namespace isc::dhcp
} // end of namespace isc