]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#3017] fix interface redetection
authorAndrei Pavel <andrei@isc.org>
Wed, 11 Oct 2023 17:42:09 +0000 (20:42 +0300)
committerAndrei Pavel <andrei@isc.org>
Tue, 17 Oct 2023 09:35:40 +0000 (12:35 +0300)
There is no unit test added, because that would require interface
changes which need root access.

src/bin/dhcp4/json_config_parser.cc
src/bin/dhcp6/json_config_parser.cc

index bb31ab4357ad263ef9edc95eeef8b6e8ac31dadc..20cb04df51a93546cd779b767b0b41b6e3a18eaa 100644 (file)
@@ -322,8 +322,15 @@ void configureCommandChannel() {
     }
 }
 
+/// @brief Process a DHCPv4 confguration and return an answer stating if the
+/// configuration is valid, or specifying details about the error otherwise.
+///
+/// @param config_set the configuration being processed
+/// @param check_only whether the processing is only for testing the
+///     configuration, in which case some configuration elements, such as
+///     interfaces, might be left uncommitted or unprocessed
 isc::data::ConstElementPtr
-processDhcp4Config(isc::data::ConstElementPtr config_set) {
+processDhcp4Config(isc::data::ConstElementPtr config_set, bool const check_only) {
     // Before starting any subnet operations, let's reset the subnet-id counter,
     // so newly recreated configuration starts with first subnet-id equal 1.
     Subnet::resetSubnetID();
@@ -444,10 +451,16 @@ processDhcp4Config(isc::data::ConstElementPtr config_set) {
             parser.parse(hr_identifiers);
         }
 
+        // Interfaces are parsed one more time with test_mode=false in the
+        // caller context. Presumably, this would make it possible to create
+        // IfacesConfigParser with test_mode=false here, since if the result of
+        // processDhcp4Config is a success, the interfaces get applied there.
+        // However test_mode influences redetection which can influence the
+        // result of processDhcp4Config, so let's keep test_mode=check_only.
         ConstElementPtr ifaces_config = mutable_cfg->get("interfaces-config");
         if (ifaces_config) {
             parameter_name = "interfaces-config";
-            IfacesConfigParser parser(AF_INET, true);
+            IfacesConfigParser parser(AF_INET, check_only);
             CfgIfacePtr cfg_iface = srv_config->getCfgIface();
             parser.parse(cfg_iface, ifaces_config);
         }
@@ -763,7 +776,7 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
     LOG_DEBUG(dhcp4_logger, DBG_DHCP4_COMMAND, DHCP4_CONFIG_START)
         .arg(server.redactConfig(config_set)->str());
 
-    auto answer = processDhcp4Config(config_set);
+    auto answer = processDhcp4Config(config_set, check_only);
 
     int status_code = CONTROL_RESULT_SUCCESS;
     isc::config::parseAnswer(status_code, answer);
index c1c1bf94618435eae0145b99c2e6cdbf059de0d5..0b897e4ae565827b3753533c45024d1e01db5f54 100644 (file)
@@ -425,8 +425,15 @@ void configureCommandChannel() {
     }
 }
 
+/// @brief Process a DHCPv6 confguration and return an answer stating if the
+/// configuration is valid, or specifying details about the error otherwise.
+///
+/// @param config_set the configuration being processed
+/// @param check_only whether the processing is only for testing the
+///     configuration, in which case some configuration elements, such as
+///     interfaces, might be left uncommitted or unprocessed
 isc::data::ConstElementPtr
-processDhcp6Config(isc::data::ConstElementPtr config_set) {
+processDhcp6Config(isc::data::ConstElementPtr config_set, bool const check_only) {
     // Before starting any subnet operations, let's reset the subnet-id counter,
     // so newly recreated configuration starts with first subnet-id equal 1.
     Subnet::resetSubnetID();
@@ -570,10 +577,16 @@ processDhcp6Config(isc::data::ConstElementPtr config_set) {
             parser.parse(cfg, server_id);
         }
 
+        // Interfaces are parsed one more time with test_mode=false in the
+        // caller context. Presumably, this would make it possible to create
+        // IfacesConfigParser with test_mode=false here, since if the result of
+        // processDhcp6Config is a success, the interfaces get applied there.
+        // However test_mode influences redetection which can influence the
+        // result of processDhcp6Config, so let's keep test_mode=check_only.
         ConstElementPtr ifaces_config = mutable_cfg->get("interfaces-config");
         if (ifaces_config) {
             parameter_name = "interfaces-config";
-            IfacesConfigParser parser(AF_INET6, true);
+            IfacesConfigParser parser(AF_INET6, check_only);
             CfgIfacePtr cfg_iface = srv_config->getCfgIface();
             parser.parse(cfg_iface, ifaces_config);
         }
@@ -888,7 +901,7 @@ configureDhcp6Server(Dhcpv6Srv& server, isc::data::ConstElementPtr config_set,
     LOG_DEBUG(dhcp6_logger, DBG_DHCP6_COMMAND, DHCP6_CONFIG_START)
         .arg(server.redactConfig(config_set)->str());
 
-    auto answer = processDhcp6Config(config_set);
+    auto answer = processDhcp6Config(config_set, check_only);
 
     int status_code = CONTROL_RESULT_SUCCESS;
     isc::config::parseAnswer(status_code, answer);