cfg->setServerTag(server_tag);
}
+ /// @brief Sets global parameters before other parameters are parsed.
+ ///
+ /// This method sets selected global parameters before other parameters
+ /// are parsed. This is important when the bahavior of the parsers
+ /// run later depends on these global paramters.
+ ///
+ /// Currently this method sets the following global parameters:
+ /// - ip-reservations-unique
+ ///
+ /// @param global global configuration scope
+ /// @param cfg Server configuration (parsed parameters will be stored here)
+ void parseEarly(const SrvConfigPtr& cfg, const ConstElementPtr& global) {
+ // Set ip-reservations-unique flag.
+ bool ip_reservations_unique = getBoolean(global, "ip-reservations-unique");
+ cfg->setIPReservationsUnique(ip_reservations_unique);
+ }
+
/// @brief Copies subnets from shared networks to regular subnets container
///
/// @param from pointer to shared networks container (copy from here)
// with the parser code debugability, so I decided to keep it as a
// series of independent ifs.
+ // This parser is used in several places.
+ Dhcp4ConfigParser global_parser;
+
+ // Apply global options in the staging config, e.g. ip-reservations-unique
+ global_parser.parseEarly(srv_cfg, mutable_cfg);
+
// We need definitions first
ConstElementPtr option_defs = mutable_cfg->get("option-def");
if (option_defs) {
}
}
- // This parser is used in several places.
- Dhcp4ConfigParser global_parser;
-
// Keep relative orders of shared networks and subnets.
ConstElementPtr shared_networks = mutable_cfg->get("shared-networks");
if (shared_networks) {
" \"interface\": \"eth0\"\n"
" }\n"
"]\n"
+ "}",
+
+ // Configuration 7 multiple reservations for the same IP address.
+ "{ \"interfaces-config\": {\n"
+ " \"interfaces\": [ \"*\" ]\n"
+ "},\n"
+ "\"valid-lifetime\": 600,\n"
+ "\"ip-reservations-unique\": false,\n"
+ "\"subnet4\": [\n"
+ " {\n"
+ " \"subnet\": \"10.0.0.0/24\",\n"
+ " \"id\": 10,\n"
+ " \"reservations\": [\n"
+ " { \n"
+ " \"hw-address\": \"aa:bb:cc:dd:ee:fe\",\n"
+ " \"ip-address\": \"10.0.0.123\"\n"
+ " },\n"
+ " { \n"
+ " \"hw-address\": \"aa:bb:cc:dd:ee:ff\",\n"
+ " \"ip-address\": \"10.0.0.123\"\n"
+ " }\n"
+ " ],\n"
+ " \"pools\": [\n"
+ " {\n"
+ " \"pool\": \"10.0.0.10-10.0.0.255\"\n"
+ " }\n"
+ " ],\n"
+ " \"interface\": \"eth0\"\n"
+ " }\n"
+ "]\n"
"}"
};
ASSERT_NO_FATAL_FAILURE(testGlobalClassSubnetPoolSelection(6, "10.0.0.10", "10.0.0.20"));
}
+// Verifies that if the server is configured to allow for specifying
+// multiple reservations for the same IP address the first client
+// matching the reservation will be given this address.
+TEST_F(HostTest, oneOfMultiple) {
+ Dhcp4Client client(Dhcp4Client::SELECTING);
+
+ // Hardware address matches all reservations
+ client.setHWAddress("aa:bb:cc:dd:ee:fe");
+
+ runDoraTest(CONFIGS[7], client, "", "10.0.0.123");
+}
+
} // end of anonymous namespace
srv_config->setServerTag(server_tag);
}
+ /// @brief Sets global parameters before other parameters are parsed.
+ ///
+ /// This method sets selected global parameters before other parameters
+ /// are parsed. This is important when the bahavior of the parsers
+ /// run later depends on these global paramters.
+ ///
+ /// Currently this method sets the following global parameters:
+ /// - ip-reservations-unique
+ ///
+ /// @param global global configuration scope
+ /// @param cfg Server configuration (parsed parameters will be stored here)
+ void parseEarly(const SrvConfigPtr& cfg, const ConstElementPtr& global) {
+ // Set ip-reservations-unique flag.
+ bool ip_reservations_unique = getBoolean(global, "ip-reservations-unique");
+ cfg->setIPReservationsUnique(ip_reservations_unique);
+ }
+
/// @brief Copies subnets from shared networks to regular subnets container
///
/// @param from pointer to shared networks container (copy from here)
// with the parser code debugability, so I decided to keep it as a
// series of independent ifs.
+ // This parser is used in several places.
+ Dhcp6ConfigParser global_parser;
+
+ // Apply global options in the staging config, e.g. ip-reservations-unique
+ global_parser.parseEarly(srv_config, mutable_cfg);
+
// Specific check for this global parameter.
ConstElementPtr data_directory = mutable_cfg->get("data-directory");
if (data_directory) {
}
}
- // This parser is used in several places.
- Dhcp6ConfigParser global_parser;
-
// Keep relative orders of shared networks and subnets.
ConstElementPtr shared_networks = mutable_cfg->get("shared-networks");
if (shared_networks) {
" \"interface\": \"eth0\"\n"
" }\n"
"]\n"
+ "}",
+
+ // Configuration 13 multiple reservations for the same IP address.
+ "{ \"interfaces-config\": {\n"
+ " \"interfaces\": [ \"*\" ]\n"
+ "},\n"
+ "\"valid-lifetime\": 4000,\n"
+ "\"ip-reservations-unique\": false,\n"
+ "\"subnet6\": [\n"
+ " {\n"
+ " \"subnet\": \"2001:db8:1::/64\",\n"
+ " \"id\": 10,"
+ " \"reservations\": [\n"
+ " {\n"
+ " \"duid\": \"01:02:03:04\",\n"
+ " \"ip-addresses\": [ \"2001:db8:1::15\" ]\n"
+ " },\n"
+ " {\n"
+ " \"duid\": \"01:02:03:05\",\n"
+ " \"ip-addresses\": [ \"2001:db8:1::15\" ]\n"
+ " }\n"
+ " ],\n"
+ " \"pools\": ["
+ " {\n"
+ " \"pool\": \"2001:db8:1::10-2001:db8:1::200\""
+ " }\n"
+ " ],\n"
+ " \"interface\": \"eth0\"\n"
+ " }\n"
+ "]\n"
"}"
};
"2001:db8:1::20"));
}
+// Verifies that if the server is configured to allow for specifying
+// multiple reservations for the same IP address the first client
+// matching the reservation will be given this address.
+TEST_F(HostTest, oneOfMultiple) {
+ Dhcp6Client client1;
+ client1.setDUID("01:02:03:04");
+
+ ASSERT_NO_THROW(configure(CONFIGS[13], *client1.getServer()));
+
+ // First client performs 4-way exchange and obtains an address and
+ // prefix indicated in hints.
+ requestIA(client1, Hint(IAID(1), "2001:db8:1::10"));
+
+ ASSERT_NO_THROW(client1.doSARR());
+
+ // Make sure the client has obtained requested leases.
+ ASSERT_TRUE(client1.hasLeaseForAddress(IOAddress("2001:db8:1::15"), IAID(1)));
+}
+
} // end of anonymous namespace
-// Copyright (C) 2016-2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-2020 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
/// specified with @ref CfgDbAccess::setAppendedParameters
std::list<std::string> getHostDbAccessStringList() const;
+ /// @brief Modifies the setting imposing whether the IP reservations
+ /// are unique or can be non-unique.
+ ///
+ /// This flag can be set to @c false when the server is explicitly
+ /// configured to allow multiple hosts to have the same IP reservation.
+ /// In that case, the @c createManagers function will attempt to use
+ /// this setting for @c HostMgr.
+ ///
+ /// Note that the @c HostMgr can reject the new setting if any of the
+ /// host backends used does not support specifying multipe hosts with
+ /// the same IP address.
+ ///
+ /// @param unique new setting to be used by @c HostMgr.
+ void setIPReservationsUnique(const bool unique) {
+ ip_reservations_unique_ = unique;
+ }
+
/// @brief Creates instance of lease manager and host data sources
/// according to the configuration specified.
void createManagers() const;
/// @brief Holds host database access strings.
std::list<std::string> host_db_access_;
+ /// @brief Holds the setting whether IP reservations should be unique
+ /// or can be non-unique.
+ bool ip_reservations_unique_;
};
/// @brief A pointer to the @c CfgDbAccess.
}
}
+void
+SrvConfig::setIPReservationsUnique(const bool unique) {
+ getCfgHosts()->setIPReservationsUnique(unique);
+ getCfgDbAccess()->setIPReservationsUnique(unique);
+}
+
bool
DdnsParams::getEnableUpdates() const {
if (!subnet_) {
/// @param srv_elem server top level map to alter
static void moveDdnsParams(isc::data::ElementPtr srv_elem);
+ /// @brief Configures the server to allow or disallow specifying multiple
+ /// hosts with the same IP address.
+ ///
+ /// This setting is applied in @c CfgDbAccess and @c CfgHosts. This function
+ /// should be called when the server is being configured using the configuration
+ /// file, config-set command or via the configuration backend.
+ ///
+ /// @param unique Boolean value indicating if it is allowed (when false)
+ /// or disallowed to specify multiple hosts with the same IP reservation.
+ void setIPReservationsUnique(const bool unique);
+
/// @brief Unparse a configuration object
///
/// @return a pointer to unparsed configuration