From: Thomas Markwalder Date: Thu, 28 Mar 2019 15:03:07 +0000 (-0400) Subject: [#413,!288] - kea-dhcp6 now uses globals from config back end X-Git-Tag: Kea-1.6.0-beta~270^2~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c416c968f81f54c9e69d92ff7ea4ced4d681c1d9;p=thirdparty%2Fkea.git [#413,!288] - kea-dhcp6 now uses globals from config back end src/bin/dhcp6/tests/config_backend_unittest.cc TEST_F(Dhcp6CBTest, mergeGlobals) - enabled test src/lib/dhcpsrv/srv_config.* SrvConfig::merge(ConfigBase& other) - invoke merge6() SrvConfig::mergeGlobals4() renamed to mergeGlobals() SrvConfig::merge6(SrvConfig& other) - new method src/lib/dhcpsrv/tests/srv_config_unittest.cc TEST_F(SrvConfigTest, mergeGlobals6) - new test --- diff --git a/src/bin/dhcp6/tests/config_backend_unittest.cc b/src/bin/dhcp6/tests/config_backend_unittest.cc index fe995168fe..0d4d50ffb6 100644 --- a/src/bin/dhcp6/tests/config_backend_unittest.cc +++ b/src/bin/dhcp6/tests/config_backend_unittest.cc @@ -162,7 +162,7 @@ public: // This test verifies that externally configured globals are // merged correctly into staging configuration. -TEST_F(Dhcp6CBTest, DISABLED_mergeGlobals) { +TEST_F(Dhcp6CBTest, mergeGlobals) { string base_config = "{ \n" " \"interfaces-config\": { \n" diff --git a/src/lib/dhcpsrv/srv_config.cc b/src/lib/dhcpsrv/srv_config.cc index c7b42b87be..0aea3b208d 100644 --- a/src/lib/dhcpsrv/srv_config.cc +++ b/src/lib/dhcpsrv/srv_config.cc @@ -164,7 +164,7 @@ SrvConfig::merge(ConfigBase& other) { if (CfgMgr::instance().getFamily() == AF_INET) { merge4(other_srv_config); } else { - /// @todo merge6(); + merge6(other_srv_config); } } catch (const std::bad_cast&) { isc_throw(InvalidOperation, "internal server error: must use derivation" @@ -178,7 +178,7 @@ SrvConfig::merge4(SrvConfig& other) { // We merge objects in order of dependency (real or theoretical). // Merge globals. - mergeGlobals4(other); + mergeGlobals(other); // Merge option defs. We need to do this next so we // pass these into subsequent merges so option instances @@ -186,28 +186,56 @@ SrvConfig::merge4(SrvConfig& other) { // definitions. cfg_option_def_->merge((*other.getCfgOptionDef())); - // Merge options. + // Merge options. cfg_option_->merge(cfg_option_def_, (*other.getCfgOption())); // Merge shared networks. cfg_shared_networks4_->merge(cfg_option_def_, *(other.getCfgSharedNetworks4())); // Merge subnets. - cfg_subnets4_->merge(cfg_option_def_, getCfgSharedNetworks4(), + cfg_subnets4_->merge(cfg_option_def_, getCfgSharedNetworks4(), *(other.getCfgSubnets4())); /// @todo merge other parts of the configuration here. } void -SrvConfig::mergeGlobals4(SrvConfig& other) { +SrvConfig::merge6(SrvConfig& other) { + // We merge objects in order of dependency (real or theoretical). + + // Merge globals. + mergeGlobals(other); + +#if 0 + // Merge option defs. We need to do this next so we + // pass these into subsequent merges so option instances + // at each level can be created based on the merged + // definitions. + cfg_option_def_->merge((*other.getCfgOptionDef())); + + // Merge options. + cfg_option_->merge(cfg_option_def_, (*other.getCfgOption())); + + // Merge shared networks. + cfg_shared_networks6_->merge(cfg_option_def_, *(other.getCfgSharedNetworks6())); + + // Merge subnets. + cfg_subnets6_->merge(cfg_option_def_, getCfgSharedNetworks4(), + *(other.getCfgSubnets6())); +#endif + + /// @todo merge other parts of the configuration here. +} + +void +SrvConfig::mergeGlobals(SrvConfig& other) { // Iterate over the "other" globals, adding/overwriting them into // this config's list of globals. for (auto other_global : other.getConfiguredGlobals()->mapValue()) { addConfiguredGlobal(other_global.first, other_global.second); } - // A handful of values are stored as members in SrvConfig. So we'll + // A handful of values are stored as members in SrvConfig. So we'll // iterate over the merged globals, setting approprate members. for (auto merged_global : getConfiguredGlobals()->mapValue()) { std::string name = merged_global.first; @@ -217,6 +245,8 @@ SrvConfig::mergeGlobals4(SrvConfig& other) { setDeclinePeriod(element->intValue()); } else if (name == "echo-client-id") { + // echo-client-id is v4 only, but we'll let upstream + // worry about that. setEchoClientId(element->boolValue()); } else if (name == "dhcp4o6port") { @@ -232,6 +262,7 @@ SrvConfig::mergeGlobals4(SrvConfig& other) { } } + void SrvConfig::removeStatistics() { diff --git a/src/lib/dhcpsrv/srv_config.h b/src/lib/dhcpsrv/srv_config.h index 12abefdd37..71636c8270 100644 --- a/src/lib/dhcpsrv/srv_config.h +++ b/src/lib/dhcpsrv/srv_config.h @@ -652,8 +652,34 @@ private: /// into this configuration. void merge4(SrvConfig& other); + /// @brief Merges the DHCPv6 configuration specified as a parameter into + /// this configuration. + /// + /// The general rule is that the configuration data from the @c other + /// object replaces configuration data held in this object instance. + /// The data that do not overlap between the two objects is simply + /// inserted into this configuration. + /// + /// @warning The call to @c merge may modify the data in the @c other + /// object. Therefore, the caller must not rely on the data held + /// in the @c other object after the call to @c merge. Also, the + /// data held in @c other must not be modified after the call to + /// @c merge because it may affect the merged configuration. + /// + /// The @c other parameter must be a @c SrvConfig or its derivation. + /// + /// Currently, the following parts of the v6 configuration are merged: + /// - globals + /// - shared-networks + /// - subnets + /// + /// @todo Add support for merging other configuration elements. + /// + /// @param other An object holding the configuration to be merged + /// into this configuration. + void merge6(SrvConfig& other); - /// @brief Merges the DHCPv4 globals specified in the given configuration + /// @brief Merges the globals specified in the given configuration /// into this configuration. /// /// Configurable global values may be specified either via JSON @@ -675,7 +701,7 @@ private: /// /// @param other An object holding the configuration to be merged /// into this configuration. - void mergeGlobals4(SrvConfig& other); + void mergeGlobals(SrvConfig& other); /// @brief Sequence number identifying the configuration. uint32_t sequence_; diff --git a/src/lib/dhcpsrv/tests/srv_config_unittest.cc b/src/lib/dhcpsrv/tests/srv_config_unittest.cc index 89a3dcdd23..b1a0a09f28 100644 --- a/src/lib/dhcpsrv/tests/srv_config_unittest.cc +++ b/src/lib/dhcpsrv/tests/srv_config_unittest.cc @@ -985,7 +985,7 @@ TEST_F(SrvConfigTest, mergeGlobals4) { // Let's create the "existing" config we will merge into. SrvConfig cfg_to; - // Set some explicit values. + // Set some explicit values. cfg_to.setDeclinePeriod(100); cfg_to.setEchoClientId(false); cfg_to.setDhcp4o6Port(777); @@ -1025,7 +1025,73 @@ TEST_F(SrvConfigTest, mergeGlobals4) { // server-tag port should be the "from" configured value. EXPECT_EQ("use_this_server", cfg_to.getServerTag().get()); - // Next we check the explicitly "configured" globals. + // Next we check the explicitly "configured" globals. + // The list should be all of the "to" + "from", with the + // latter overwriting the former. + std::string exp_globals = + "{ \n" + " \"decline-probation-period\": 300, \n" + " \"dhcp4o6port\": 999, \n" + " \"server-tag\": \"use_this_server\" \n" + "} \n"; + + ConstElementPtr expected_globals; + ASSERT_NO_THROW(expected_globals = Element::fromJSON(exp_globals)) + << "exp_globals didn't parse, test is broken"; + + EXPECT_TRUE(isEquivalent(expected_globals, cfg_to.getConfiguredGlobals())); + +} + +// This test verifies that globals from one SrvConfig +// can be merged into another. It verifies that values +// in the from-config override those in to-config which +// override those in GLOBAL4_DEFAULTS. +TEST_F(SrvConfigTest, mergeGlobals6) { + // Set the family we're working with. + CfgMgr::instance().setFamily(AF_INET6); + + // Let's create the "existing" config we will merge into. + SrvConfig cfg_to; + + // Set some explicit values. + cfg_to.setDeclinePeriod(100); + cfg_to.setEchoClientId(false); + cfg_to.setDhcp4o6Port(777); + cfg_to.setServerTag("not_this_server"); + + // Add some configured globals + cfg_to.addConfiguredGlobal("decline-probation-period", Element::create(300)); + cfg_to.addConfiguredGlobal("dhcp4o6port", Element::create(888)); + + // Now we'll create the config we'll merge from. + SrvConfig cfg_from; + + // Set some explicit values. None of these should be preserved. + cfg_from.setDeclinePeriod(200); + cfg_from.setEchoClientId(true); + cfg_from.setDhcp4o6Port(888); + cfg_from.setServerTag("nor_this_server"); + + // Add some configured globals: + cfg_to.addConfiguredGlobal("dhcp4o6port", Element::create(999)); + cfg_to.addConfiguredGlobal("server-tag", Element::create("use_this_server")); + + // Now let's merge. + ASSERT_NO_THROW(cfg_to.merge(cfg_from)); + + // Make sure the explicit values are set correctly. + + // decline-probation-period should be the "to" configured value. + EXPECT_EQ(300, cfg_to.getDeclinePeriod()); + + // dhcp4o6port should be the "from" configured value. + EXPECT_EQ(999, cfg_to.getDhcp4o6Port()); + + // server-tag port should be the "from" configured value. + EXPECT_EQ("use_this_server", cfg_to.getServerTag().get()); + + // Next we check the explicitly "configured" globals. // The list should be all of the "to" + "from", with the // latter overwriting the former. std::string exp_globals =