2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-30 05:27:55 +00:00

[3625] Use CfgSubnets6 to obtain subnet information.

This commit is contained in:
Marcin Siodelski 2014-10-30 12:44:37 +01:00
parent 6c956ebafc
commit 4a5895b993
24 changed files with 222 additions and 723 deletions

View File

@ -38,6 +38,7 @@
#include <dhcpsrv/lease_mgr.h>
#include <dhcpsrv/lease_mgr_factory.h>
#include <dhcpsrv/subnet.h>
#include <dhcpsrv/subnet_selector.h>
#include <dhcpsrv/utils.h>
#include <exceptions/exceptions.h>
#include <hooks/callout_handle.h>
@ -868,43 +869,25 @@ Dhcpv6Srv::sanityCheck(const Pkt6Ptr& pkt, RequirementLevel clientid,
Subnet6Ptr
Dhcpv6Srv::selectSubnet(const Pkt6Ptr& question) {
// Initialize subnet selector with the values used to select the subnet.
SubnetSelector selector;
selector.iface_name_ = question->getIface();
selector.remote_address_ = question->getRemoteAddr();
selector.first_relay_linkaddr_ = IOAddress("::");
selector.client_classes_ = question->classes_;
Subnet6Ptr subnet;
if (question->relay_info_.empty()) {
// This is a direct (non-relayed) message
// Try to find a subnet if received packet from a directly connected client
subnet = CfgMgr::instance().getSubnet6(question->getIface(),
question->classes_);
if (!subnet) {
// If no subnet was found, try to find it based on remote address
subnet = CfgMgr::instance().getSubnet6(question->getRemoteAddr(),
question->classes_);
}
} else {
// This is a relayed message
OptionPtr interface_id = question->getAnyRelayOption(D6O_INTERFACE_ID,
Pkt6::RELAY_GET_FIRST);
if (interface_id) {
subnet = CfgMgr::instance().getSubnet6(interface_id,
question->classes_);
}
if (!subnet) {
// If no interface-id was specified (or not configured on server),
// let's try address matching
IOAddress link_addr = question->relay_info_.back().linkaddr_;
// if relay filled in link_addr field, then let's use it
if (link_addr != IOAddress("::")) {
subnet = CfgMgr::instance().getSubnet6(link_addr,
question->classes_, true);
}
}
// Initialize fields specific to relayed messages.
if (!question->relay_info_.empty()) {
selector.first_relay_linkaddr_ = question->relay_info_.back().linkaddr_;
selector.interface_id_ =
question->getAnyRelayOption(D6O_INTERFACE_ID,
Pkt6::RELAY_GET_FIRST);
}
Subnet6Ptr subnet = CfgMgr::instance().getCurrentCfg()->
getCfgSubnets6()->selectSubnet(selector);
// Let's execute all callouts registered for subnet6_receive
if (HooksManager::calloutsPresent(Hooks.hook_index_subnet6_select_)) {
CalloutHandlePtr callout_handle = getCalloutHandle(question);
@ -919,7 +902,9 @@ Dhcpv6Srv::selectSubnet(const Pkt6Ptr& question) {
// We pass pointer to const collection for performance reasons.
// Otherwise we would get a non-trivial performance penalty each
// time subnet6_select is called.
callout_handle->setArgument("subnet6collection", CfgMgr::instance().getSubnets6());
callout_handle->setArgument("subnet6collection",
CfgMgr::instance().getCurrentCfg()->
getCfgSubnets6()->getAll());
// Call user (and server-side) callouts
HooksManager::callCallouts(Hooks.hook_index_subnet6_select_, *callout_handle);

View File

@ -344,7 +344,7 @@ public:
// subnet id is invalid (duplicate). Thus, we catch exceptions
// here to append a position in the configuration string.
try {
isc::dhcp::CfgMgr::instance().addSubnet6(sub6ptr);
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(sub6ptr);
} catch (const std::exception& ex) {
isc_throw(DhcpConfigError, ex.what() << " ("
<< subnet->getPosition() << ")");
@ -534,12 +534,6 @@ public:
///
/// @param subnets_list pointer to a list of IPv6 subnets
void build(ConstElementPtr subnets_list) {
// @todo: Implement more subtle reconfiguration than toss
// the old one and replace with the new one.
// remove old subnets
isc::dhcp::CfgMgr::instance().deleteSubnets6();
BOOST_FOREACH(ConstElementPtr subnet, subnets_list->listValue()) {
ParserPtr parser(new Subnet6ConfigParser("subnet"));
parser->build(subnet);

View File

@ -26,6 +26,7 @@
#include <dhcpsrv/addr_utilities.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/subnet.h>
#include <dhcpsrv/subnet_selector.h>
#include <dhcpsrv/testutils/config_result_check.h>
#include <hooks/hooks_manager.h>
@ -247,13 +248,13 @@ public:
getOptionFromSubnet(const IOAddress& subnet_address,
const uint16_t option_code,
const uint16_t expected_options_count = 1) {
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(subnet_address,
classify_);
Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
selectSubnet(subnet_address, classify_);
if (!subnet) {
/// @todo replace toText() with the use of operator <<.
ADD_FAILURE() << "A subnet for the specified address "
<< subnet_address.toText()
<< "does not exist in Config Manager";
<< " does not exist in Config Manager";
}
OptionContainerPtr options =
subnet->getCfgOption()->getAll("dhcp6");
@ -469,6 +470,8 @@ public:
const uint16_t option_code,
const uint8_t* expected_data,
const size_t expected_data_len) {
CfgMgr::instance().clear();
std::string config = createConfigWithOption(params);
ASSERT_TRUE(executeConfiguration(config, "parse option configuration"));
@ -557,8 +560,8 @@ TEST_F(Dhcp6ParserTest, subnetGlobalDefaults) {
// Now check if the configuration was indeed handled and we have
// expected pool configured.
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"),
classify_);
Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
selectSubnet(IOAddress("2001:db8:1::5"), classify_);
ASSERT_TRUE(subnet);
EXPECT_EQ(1000, subnet->getT1());
EXPECT_EQ(2000, subnet->getT2());
@ -605,7 +608,10 @@ TEST_F(Dhcp6ParserTest, multipleSubnets) {
EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
checkResult(x, 0);
const Subnet6Collection* subnets = CfgMgr::instance().getSubnets6();
CfgMgr::instance().commit();
const Subnet6Collection* subnets =
CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getAll();
ASSERT_TRUE(subnets);
ASSERT_EQ(4, subnets->size()); // We expect 4 subnets
@ -660,7 +666,10 @@ TEST_F(Dhcp6ParserTest, multipleSubnetsExplicitIDs) {
EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
checkResult(x, 0);
const Subnet6Collection* subnets = CfgMgr::instance().getSubnets6();
CfgMgr::instance().commit();
const Subnet6Collection* subnets =
CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getAll();
ASSERT_TRUE(subnets);
ASSERT_EQ(4, subnets->size()); // We expect 4 subnets
@ -796,7 +805,10 @@ TEST_F(Dhcp6ParserTest, reconfigureRemoveSubnet) {
EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
checkResult(x, 0);
const Subnet6Collection* subnets = CfgMgr::instance().getSubnets6();
CfgMgr::instance().commit();
const Subnet6Collection* subnets =
CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getAll();
ASSERT_TRUE(subnets);
ASSERT_EQ(4, subnets->size()); // We expect 4 subnets
@ -805,7 +817,9 @@ TEST_F(Dhcp6ParserTest, reconfigureRemoveSubnet) {
EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
checkResult(x, 0);
subnets = CfgMgr::instance().getSubnets6();
CfgMgr::instance().commit();
subnets = CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getAll();
ASSERT_TRUE(subnets);
ASSERT_EQ(3, subnets->size()); // We expect 3 subnets now (4th is removed)
@ -820,12 +834,16 @@ TEST_F(Dhcp6ParserTest, reconfigureRemoveSubnet) {
EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
checkResult(x, 0);
CfgMgr::instance().commit();
// Do reconfiguration
json = Element::fromJSON(config_second_removed);
EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
checkResult(x, 0);
subnets = CfgMgr::instance().getSubnets6();
CfgMgr::instance().commit();
subnets = CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getAll();
ASSERT_TRUE(subnets);
ASSERT_EQ(3, subnets->size()); // We expect 4 subnets
@ -863,8 +881,8 @@ TEST_F(Dhcp6ParserTest, subnetLocal) {
// returned value should be 0 (configuration success)
checkResult(status, 0);
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"),
classify_);
Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
selectSubnet(IOAddress("2001:db8:1::5"), classify_);
ASSERT_TRUE(subnet);
EXPECT_EQ(1, subnet->getT1());
EXPECT_EQ(2, subnet->getT2());
@ -898,8 +916,8 @@ TEST_F(Dhcp6ParserTest, subnetInterface) {
// returned value should be 0 (configuration success)
checkResult(status, 0);
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"),
classify_);
Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
selectSubnet(IOAddress("2001:db8:1::5"), classify_);
ASSERT_TRUE(subnet);
EXPECT_EQ(valid_iface_, subnet->getIface());
}
@ -931,8 +949,8 @@ TEST_F(Dhcp6ParserTest, subnetInterfaceBogus) {
checkResult(status, 1);
EXPECT_TRUE(errorContainsPosition(status, "<string>"));
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"),
classify_);
Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
selectSubnet(IOAddress("2001:db8:1::5"), classify_);
EXPECT_FALSE(subnet);
}
@ -993,16 +1011,20 @@ TEST_F(Dhcp6ParserTest, subnetInterfaceId) {
// Try to get a subnet based on bogus interface-id option
OptionBuffer tmp(bogus_interface_id.begin(), bogus_interface_id.end());
OptionPtr ifaceid(new Option(Option::V6, D6O_INTERFACE_ID, tmp));
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(ifaceid, classify_);
SubnetSelector selector;
selector.first_relay_linkaddr_ = IOAddress("5000::1");
selector.interface_id_.reset(new Option(Option::V6, D6O_INTERFACE_ID, tmp));
Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
selectSubnet(selector);
EXPECT_FALSE(subnet);
// Now try to get subnet for valid interface-id value
tmp = OptionBuffer(valid_interface_id.begin(), valid_interface_id.end());
ifaceid.reset(new Option(Option::V6, D6O_INTERFACE_ID, tmp));
subnet = CfgMgr::instance().getSubnet6(ifaceid, classify_);
selector.interface_id_.reset(new Option(Option::V6, D6O_INTERFACE_ID, tmp));
subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
selectSubnet(selector);
ASSERT_TRUE(subnet);
EXPECT_TRUE(ifaceid->equals(subnet->getInterfaceId()));
EXPECT_TRUE(selector.interface_id_->equals(subnet->getInterfaceId()));
}
@ -1084,7 +1106,8 @@ TEST_F(Dhcp6ParserTest, multiplePools) {
ASSERT_NO_THROW(status = configureDhcp6Server(srv_, json));
checkResult(status, 0);
const Subnet6Collection* subnets = CfgMgr::instance().getSubnets6();
const Subnet6Collection* subnets =
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->getAll();
ASSERT_TRUE(subnets);
ASSERT_EQ(2, subnets->size()); // We expect 2 subnets
@ -1163,8 +1186,8 @@ TEST_F(Dhcp6ParserTest, poolPrefixLen) {
// returned value must be 1 (configuration parse error)
checkResult(x, 0);
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"),
classify_);
Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
selectSubnet(IOAddress("2001:db8:1::5"), classify_);
ASSERT_TRUE(subnet);
EXPECT_EQ(1000, subnet->getT1());
EXPECT_EQ(2000, subnet->getT2());
@ -1205,8 +1228,8 @@ TEST_F(Dhcp6ParserTest, pdPoolBasics) {
checkResult(x, 0);
// Test that we can retrieve the subnet.
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"),
classify_);
Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
selectSubnet(IOAddress("2001:db8:1::5"), classify_);
ASSERT_TRUE(subnet);
// Fetch the collection of PD pools. It should have 1 entry.
@ -1277,8 +1300,8 @@ TEST_F(Dhcp6ParserTest, pdPoolList) {
checkResult(x, 0);
// Test that we can retrieve the subnet.
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"),
classify_);
Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
selectSubnet(IOAddress("2001:db8:1::5"), classify_);
ASSERT_TRUE(subnet);
// Fetch the collection of NA pools. It should have 1 entry.
@ -1333,8 +1356,8 @@ TEST_F(Dhcp6ParserTest, subnetAndPrefixDelegated) {
checkResult(x, 0);
// Test that we can retrieve the subnet.
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"),
classify_);
Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
selectSubnet(IOAddress("2001:db8:1::5"), classify_);
ASSERT_TRUE(subnet);
@ -2027,8 +2050,8 @@ TEST_F(Dhcp6ParserTest, optionDataDefaults) {
EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
checkResult(x, 0);
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"),
classify_);
Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
selectSubnet(IOAddress("2001:db8:1::5"), classify_);
ASSERT_TRUE(subnet);
OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp6");
ASSERT_EQ(2, options->size());
@ -2122,8 +2145,8 @@ TEST_F(Dhcp6ParserTest, optionDataTwoSpaces) {
checkResult(status, 0);
// Options should be now available for the subnet.
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"),
classify_);
Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
selectSubnet(IOAddress("2001:db8:1::5"), classify_);
ASSERT_TRUE(subnet);
// Try to get the option from the space dhcp6.
OptionDescriptor desc1 = subnet->getCfgOption()->get("dhcp6", 38);
@ -2278,8 +2301,8 @@ TEST_F(Dhcp6ParserTest, optionDataEncapsulate) {
checkResult(status, 0);
// Get the subnet.
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"),
classify_);
Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
selectSubnet(IOAddress("2001:db8:1::5"), classify_);
ASSERT_TRUE(subnet);
// We should have one option available.
@ -2341,8 +2364,8 @@ TEST_F(Dhcp6ParserTest, optionDataInMultipleSubnets) {
EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
checkResult(x, 0);
Subnet6Ptr subnet1 = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"),
classify_);
Subnet6Ptr subnet1 = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
selectSubnet(IOAddress("2001:db8:1::5"), classify_);
ASSERT_TRUE(subnet1);
OptionContainerPtr options1 = subnet1->getCfgOption()->getAll("dhcp6");
ASSERT_EQ(1, options1->size());
@ -2367,8 +2390,8 @@ TEST_F(Dhcp6ParserTest, optionDataInMultipleSubnets) {
sizeof(subid_expected));
// Test another subnet in the same way.
Subnet6Ptr subnet2 = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:2::4"),
classify_);
Subnet6Ptr subnet2 = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
selectSubnet(IOAddress("2001:db8:2::4"), classify_);
ASSERT_TRUE(subnet2);
OptionContainerPtr options2 = subnet2->getCfgOption()->getAll("dhcp6");
ASSERT_EQ(1, options2->size());
@ -2402,8 +2425,6 @@ TEST_F(Dhcp6ParserTest, optionDataBoolean) {
ASSERT_TRUE(executeConfiguration(config, "parse configuration with a"
" boolean value"));
CfgMgr::instance().commit();
// The subnet should now hold one option with the code 1000.
OptionDescriptor desc =
getOptionFromSubnet(IOAddress("2001:db8:1::5"), 1000);
@ -2538,8 +2559,8 @@ TEST_F(Dhcp6ParserTest, optionDataLowerCase) {
EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
checkResult(x, 0);
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"),
classify_);
Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
selectSubnet(IOAddress("2001:db8:1::5"), classify_);
ASSERT_TRUE(subnet);
OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp6");
ASSERT_EQ(1, options->size());
@ -2581,8 +2602,8 @@ TEST_F(Dhcp6ParserTest, stdOptionData) {
EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
checkResult(x, 0);
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"),
classify_);
Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
selectSubnet(IOAddress("2001:db8:1::5"), classify_);
ASSERT_TRUE(subnet);
OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp6");
ASSERT_EQ(1, options->size());
@ -2659,8 +2680,8 @@ TEST_F(Dhcp6ParserTest, vendorOptionsHex) {
checkResult(status, 0);
// Options should be now available for the subnet.
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"),
classify_);
Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
selectSubnet(IOAddress("2001:db8:1::5"), classify_);
ASSERT_TRUE(subnet);
// Try to get the option from the vendor space 4491
@ -2721,8 +2742,8 @@ TEST_F(Dhcp6ParserTest, vendorOptionsCsv) {
checkResult(status, 0);
// Options should be now available for the subnet.
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"),
classify_);
Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
selectSubnet(IOAddress("2001:db8:1::5"), classify_);
ASSERT_TRUE(subnet);
// Try to get the option from the vendor space 4491
@ -2864,8 +2885,8 @@ TEST_F(Dhcp6ParserTest, DISABLED_stdOptionDataEncapsulate) {
checkResult(status, 0);
// Get the subnet.
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"),
classify_);
Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
selectSubnet(IOAddress("2001:db8:1::5"), classify_);
ASSERT_TRUE(subnet);
// We should have one option available.
@ -3151,8 +3172,8 @@ TEST_F(Dhcp6ParserTest, subnetRelayInfo) {
// returned value should be 0 (configuration success)
checkResult(status, 0);
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::1"),
classify_);
Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->
selectSubnet(IOAddress("2001:db8:1::1"), classify_);
ASSERT_TRUE(subnet);
EXPECT_EQ("2001:db8:1::abcd", subnet->getRelayInfo().addr_.toText());
}
@ -3191,7 +3212,8 @@ TEST_F(Dhcp6ParserTest, classifySubnets) {
EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
checkResult(x, 0);
const Subnet6Collection* subnets = CfgMgr::instance().getSubnets6();
const Subnet6Collection* subnets =
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->getAll();
ASSERT_TRUE(subnets);
ASSERT_EQ(4, subnets->size()); // We expect 4 subnets

View File

@ -233,7 +233,8 @@ TEST_F(ConfirmTest, relayedClientNoAddress) {
// Configure the server.
configure(CONFIRM_CONFIGS[1], *client.getServer());
// Make sure we ended-up having expected number of subnets configured.
const Subnet6Collection* subnets = CfgMgr::instance().getSubnets6();
const Subnet6Collection* subnets =
CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getAll();
ASSERT_EQ(2, subnets->size());
// Client to send relayed message.
client.useRelay();
@ -255,7 +256,7 @@ TEST_F(ConfirmTest, relayedClientNoSubnet) {
ASSERT_NO_FATAL_FAILURE(requestLease(CONFIRM_CONFIGS[1], 2, client));
// Now that the client has a lease, let's remove any subnets to check
// how the server would respond to the Confirm.
ASSERT_NO_THROW(CfgMgr::instance().deleteSubnets6());
ASSERT_NO_THROW(CfgMgr::instance().clear());
// Send Confirm message to the server.
ASSERT_NO_THROW(client.doConfirm());
// Client should have received a status code option and this option should

View File

@ -182,7 +182,7 @@ TEST_F(CtrlDhcpv6SrvTest, configReload) {
ElementPtr config = Element::fromJSON(config_txt);
// Make sure there are no subnets configured.
CfgMgr::instance().deleteSubnets6();
CfgMgr::instance().clear();
// Now send the command
int rcode = -1;
@ -192,11 +192,12 @@ TEST_F(CtrlDhcpv6SrvTest, configReload) {
EXPECT_EQ(0, rcode); // Expect success
// Check that the config was indeed applied.
const Subnet6Collection* subnets = CfgMgr::instance().getSubnets6();
const Subnet6Collection* subnets =
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->getAll();
EXPECT_EQ(3, subnets->size());
// Clean up after the test.
CfgMgr::instance().deleteSubnets6();
CfgMgr::instance().clear();
}
} // End of anonymous namespace

View File

@ -128,6 +128,7 @@ Dhcp6SrvD2Test::configureD2(bool enable_d2, const bool exp_result,
void
Dhcp6SrvD2Test::configure(const std::string& config, bool exp_result) {
CfgMgr::instance().clear();
ElementPtr json = Element::fromJSON(config);
ConstElementPtr status;

View File

@ -53,7 +53,8 @@ Dhcpv6MessageTest::requestLease(const std::string& config,
// Configure the server.
configure(config, *client.getServer());
// Make sure we ended-up having expected number of subnets configured.
const Subnet6Collection* subnets = CfgMgr::instance().getSubnets6();
const Subnet6Collection* subnets =
CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getAll();
ASSERT_EQ(subnets_num, subnets->size());
// Do the actual 4-way exchange.
ASSERT_NO_THROW(client.doSARR());
@ -63,8 +64,8 @@ Dhcpv6MessageTest::requestLease(const std::string& config,
// subnets.
ASSERT_EQ(1, client.getLeaseNum());
Lease6 lease_client = client.getLease(0);
ASSERT_TRUE(CfgMgr::instance().getSubnet6(lease_client.addr_,
ClientClasses()));
ASSERT_TRUE(CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->
selectSubnet(lease_client.addr_, ClientClasses()));
// Check that the client's lease matches the information on the server
// side.
Lease6Ptr lease_server = checkLease(lease_client);

View File

@ -1182,8 +1182,9 @@ TEST_F(Dhcpv6SrvTest, selectSubnetAddr) {
// CASE 1: We have only one subnet defined and we received local traffic.
// The only available subnet used to be picked, but not anymore
CfgMgr::instance().deleteSubnets6();
CfgMgr::instance().addSubnet6(subnet1); // just a single subnet
CfgMgr::instance().clear();
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet1); // just a single subnet
CfgMgr::instance().commit();
Pkt6Ptr pkt = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
pkt->setRemoteAddr(IOAddress("fe80::abcd"));
@ -1196,38 +1197,42 @@ TEST_F(Dhcpv6SrvTest, selectSubnetAddr) {
// We should NOT select it.
// Identical steps as in case 1, but repeated for clarity
CfgMgr::instance().deleteSubnets6();
CfgMgr::instance().addSubnet6(subnet1); // just a single subnet
CfgMgr::instance().clear();
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet1); // just a single subnet
CfgMgr::instance().commit();
pkt->setRemoteAddr(IOAddress("2001:db8:abcd::2345"));
Subnet6Ptr selected = srv.selectSubnet(pkt);
EXPECT_FALSE(selected);
// CASE 3: We have three subnets defined and we received local traffic.
// Nothing should be selected.
CfgMgr::instance().deleteSubnets6();
CfgMgr::instance().addSubnet6(subnet1);
CfgMgr::instance().addSubnet6(subnet2);
CfgMgr::instance().addSubnet6(subnet3);
CfgMgr::instance().clear();
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet1);
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet2);
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet3);
CfgMgr::instance().commit();
pkt->setRemoteAddr(IOAddress("fe80::abcd"));
selected = srv.selectSubnet(pkt);
EXPECT_FALSE(selected);
// CASE 4: We have three subnets defined and we received relayed traffic
// that came out of subnet 2. We should select subnet2 then
CfgMgr::instance().deleteSubnets6();
CfgMgr::instance().addSubnet6(subnet1);
CfgMgr::instance().addSubnet6(subnet2);
CfgMgr::instance().addSubnet6(subnet3);
CfgMgr::instance().clear();
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet1);
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet2);
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet3);
CfgMgr::instance().commit();
pkt->setRemoteAddr(IOAddress("2001:db8:2::baca"));
selected = srv.selectSubnet(pkt);
EXPECT_EQ(selected, subnet2);
// CASE 5: We have three subnets defined and we received relayed traffic
// that came out of undefined subnet. We should select nothing
CfgMgr::instance().deleteSubnets6();
CfgMgr::instance().addSubnet6(subnet1);
CfgMgr::instance().addSubnet6(subnet2);
CfgMgr::instance().addSubnet6(subnet3);
CfgMgr::instance().clear();
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet1);
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet2);
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet3);
CfgMgr::instance().commit();
pkt->setRemoteAddr(IOAddress("2001:db8:4::baca"));
EXPECT_FALSE(srv.selectSubnet(pkt));
}
@ -1246,8 +1251,9 @@ TEST_F(Dhcpv6SrvTest, selectSubnetIface) {
// CASE 1: We have only one subnet defined and it is available via eth0.
// Packet came from eth0. The only available subnet should be selected
CfgMgr::instance().deleteSubnets6();
CfgMgr::instance().addSubnet6(subnet1); // just a single subnet
CfgMgr::instance().clear();
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet1); // just a single subnet
CfgMgr::instance().commit();
Pkt6Ptr pkt = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
pkt->setIface("eth0");
@ -1257,8 +1263,9 @@ TEST_F(Dhcpv6SrvTest, selectSubnetIface) {
// CASE 2: We have only one subnet defined and it is available via eth0.
// Packet came from eth1. We should not select it
CfgMgr::instance().deleteSubnets6();
CfgMgr::instance().addSubnet6(subnet1); // just a single subnet
CfgMgr::instance().clear();
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet1); // just a single subnet
CfgMgr::instance().commit();
pkt->setIface("eth1");
@ -1268,10 +1275,11 @@ TEST_F(Dhcpv6SrvTest, selectSubnetIface) {
// CASE 3: We have only 3 subnets defined, one over eth0, one remote and
// one over wifi1.
// Packet came from eth1. We should not select it
CfgMgr::instance().deleteSubnets6();
CfgMgr::instance().addSubnet6(subnet1);
CfgMgr::instance().addSubnet6(subnet2);
CfgMgr::instance().addSubnet6(subnet3);
CfgMgr::instance().clear();
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet1);
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet2);
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet3);
CfgMgr::instance().commit();
pkt->setIface("eth0");
EXPECT_EQ(subnet1, srv.selectSubnet(pkt));
@ -1298,8 +1306,9 @@ TEST_F(Dhcpv6SrvTest, selectSubnetRelayLinkaddr) {
// CASE 1: We have only one subnet defined and we received relayed traffic.
// The only available subnet should NOT be selected.
CfgMgr::instance().deleteSubnets6();
CfgMgr::instance().addSubnet6(subnet1); // just a single subnet
CfgMgr::instance().clear();
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet1); // just a single subnet
CfgMgr::instance().commit();
Pkt6Ptr pkt = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
pkt->relay_info_.push_back(relay);
@ -1309,19 +1318,21 @@ TEST_F(Dhcpv6SrvTest, selectSubnetRelayLinkaddr) {
// CASE 2: We have three subnets defined and we received relayed traffic.
// Nothing should be selected.
CfgMgr::instance().deleteSubnets6();
CfgMgr::instance().addSubnet6(subnet1);
CfgMgr::instance().addSubnet6(subnet2);
CfgMgr::instance().addSubnet6(subnet3);
CfgMgr::instance().clear();
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet1);
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet2);
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet3);
CfgMgr::instance().commit();
selected = srv.selectSubnet(pkt);
EXPECT_EQ(selected, subnet2);
// CASE 3: We have three subnets defined and we received relayed traffic
// that came out of subnet 2. We should select subnet2 then
CfgMgr::instance().deleteSubnets6();
CfgMgr::instance().addSubnet6(subnet1);
CfgMgr::instance().addSubnet6(subnet2);
CfgMgr::instance().addSubnet6(subnet3);
CfgMgr::instance().clear();
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet1);
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet2);
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet3);
CfgMgr::instance().commit();
// Source of the packet should have no meaning. Selection is based
// on linkaddr field in the relay
@ -1331,10 +1342,11 @@ TEST_F(Dhcpv6SrvTest, selectSubnetRelayLinkaddr) {
// CASE 4: We have three subnets defined and we received relayed traffic
// that came out of undefined subnet. We should select nothing
CfgMgr::instance().deleteSubnets6();
CfgMgr::instance().addSubnet6(subnet1);
CfgMgr::instance().addSubnet6(subnet2);
CfgMgr::instance().addSubnet6(subnet3);
CfgMgr::instance().clear();
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet1);
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet2);
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet3);
CfgMgr::instance().commit();
pkt->relay_info_.clear();
relay.linkaddr_ = IOAddress("2001:db8:4::1234");
pkt->relay_info_.push_back(relay);
@ -1357,8 +1369,9 @@ TEST_F(Dhcpv6SrvTest, selectSubnetRelayInterfaceId) {
// CASE 1: We have only one subnet defined and it is for interface-id "relay1"
// Packet came with interface-id "relay2". We should not select subnet1
CfgMgr::instance().deleteSubnets6();
CfgMgr::instance().addSubnet6(subnet1); // just a single subnet
CfgMgr::instance().clear();
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet1); // just a single subnet
CfgMgr::instance().commit();
Pkt6Ptr pkt = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
Pkt6::RelayInfo relay;
@ -1374,18 +1387,20 @@ TEST_F(Dhcpv6SrvTest, selectSubnetRelayInterfaceId) {
// CASE 2: We have only one subnet defined and it is for interface-id "relay2"
// Packet came with interface-id "relay2". We should select it
CfgMgr::instance().deleteSubnets6();
CfgMgr::instance().addSubnet6(subnet2); // just a single subnet
CfgMgr::instance().clear();
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet2); // just a single subnet
CfgMgr::instance().commit();
selected = srv.selectSubnet(pkt);
EXPECT_EQ(selected, subnet2);
// CASE 3: We have only 3 subnets defined: one remote for interface-id "relay1",
// one remote for interface-id "relay2" and third local
// packet comes with interface-id "relay2". We should select subnet2
CfgMgr::instance().deleteSubnets6();
CfgMgr::instance().addSubnet6(subnet1);
CfgMgr::instance().addSubnet6(subnet2);
CfgMgr::instance().addSubnet6(subnet3);
CfgMgr::instance().clear();
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet1);
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet2);
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet3);
CfgMgr::instance().commit();
EXPECT_EQ(subnet2, srv.selectSubnet(pkt));
}
@ -1938,7 +1953,8 @@ TEST_F(Dhcpv6SrvTest, relayOverride) {
ASSERT_NO_THROW(configure(config));
// Let's get the subnet configuration objects
const Subnet6Collection* subnets = CfgMgr::instance().getSubnets6();
const Subnet6Collection* subnets =
CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getAll();
ASSERT_EQ(2, subnets->size());
// Let's get them for easy reference
@ -2014,7 +2030,8 @@ TEST_F(Dhcpv6SrvTest, relayOverrideAndClientClass) {
ASSERT_NO_THROW(configure(config));
// Let's get the subnet configuration objects
const Subnet6Collection* subnets = CfgMgr::instance().getSubnets6();
const Subnet6Collection* subnets =
CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getAll();
ASSERT_EQ(2, subnets->size());
// Let's get them for easy reference

View File

@ -36,8 +36,9 @@ Dhcpv6SrvTest::Dhcpv6SrvTest()
64));
subnet_->addPool(pool_);
isc::dhcp::CfgMgr::instance().deleteSubnets6();
isc::dhcp::CfgMgr::instance().addSubnet6(subnet_);
isc::dhcp::CfgMgr::instance().clear();
isc::dhcp::CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet_);
isc::dhcp::CfgMgr::instance().commit();
// configure PD pool
pd_pool_ = isc::dhcp::Pool6Ptr
@ -604,6 +605,8 @@ Dhcpv6SrvTest::configure(const std::string& config, NakedDhcpv6Srv& srv) {
int rcode;
ConstElementPtr comment = config::parseAnswer(rcode, status);
ASSERT_EQ(0, rcode);
CfgMgr::instance().commit();
}
// Generate IA_NA option with specified parameters

View File

@ -348,7 +348,7 @@ public:
///
/// Removes existing configuration.
~Dhcpv6SrvTest() {
isc::dhcp::CfgMgr::instance().deleteSubnets6();
isc::dhcp::CfgMgr::instance().clear();
};
/// @brief Runs DHCPv6 configuration from the JSON string.

View File

@ -974,13 +974,14 @@ TEST_F(FqdnDhcpv6SrvTest, processRequestReuseExpiredLease) {
// We are going to configure a subnet with a pool that consists of
// exactly one address. This address will be handed out to the
// client, will get expired and then be reused.
CfgMgr::instance().deleteSubnets6();
CfgMgr::instance().clear();
subnet_ = Subnet6Ptr(new Subnet6(IOAddress("2001:db8:1:1::"), 56, 1, 2,
3, 4));
subnet_->setIface("eth0");
pool_ = Pool6Ptr(new Pool6(Lease::TYPE_NA, addr, addr));
subnet_->addPool(pool_);
CfgMgr::instance().addSubnet6(subnet_);
CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->add(subnet_);
CfgMgr::instance().commit();
// Allocate a lease.
testProcessMessage(DHCPV6_REQUEST, "myhost.example.com",

View File

@ -922,6 +922,8 @@ TEST_F(HooksDhcpv6SrvTest, subnet6_select) {
comment_ = parseAnswer(rcode_, status);
ASSERT_EQ(0, rcode_);
CfgMgr::instance().commit();
// Prepare solicit packet. Server should select first subnet for it
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
sol->setRemoteAddr(IOAddress("fe80::abcd"));
@ -942,7 +944,8 @@ TEST_F(HooksDhcpv6SrvTest, subnet6_select) {
// Check that pkt6 argument passing was successful and returned proper value
EXPECT_TRUE(callback_pkt6_.get() == sol.get());
const Subnet6Collection* exp_subnets = CfgMgr::instance().getSubnets6();
const Subnet6Collection* exp_subnets =
CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getAll();
// The server is supposed to pick the first subnet, because of matching
// interface. Check that the value is reported properly.
@ -990,6 +993,8 @@ TEST_F(HooksDhcpv6SrvTest, subnet_select_change) {
comment_ = parseAnswer(rcode_, status);
ASSERT_EQ(0, rcode_);
CfgMgr::instance().commit();
// Prepare solicit packet. Server should select first subnet for it
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
sol->setRemoteAddr(IOAddress("fe80::abcd"));
@ -1016,7 +1021,8 @@ TEST_F(HooksDhcpv6SrvTest, subnet_select_change) {
ASSERT_TRUE(addr_opt);
// Get all subnets and use second subnet for verification
const Subnet6Collection* subnets = CfgMgr::instance().getSubnets6();
const Subnet6Collection* subnets =
CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getAll();
ASSERT_EQ(2, subnets->size());
// Advertised address must belong to the second pool (in subnet's range,

View File

@ -106,7 +106,8 @@ TEST_F(JSONFileBackendTest, jsonFile) {
EXPECT_NO_THROW(srv->init(TEST_FILE));
// Now check if the configuration has been applied correctly.
const Subnet6Collection* subnets = CfgMgr::instance().getSubnets6();
const Subnet6Collection* subnets =
CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getAll();
ASSERT_TRUE(subnets);
ASSERT_EQ(3, subnets->size()); // We expect 3 subnets.
@ -176,7 +177,8 @@ TEST_F(JSONFileBackendTest, comments) {
EXPECT_NO_THROW(srv->init(TEST_FILE));
// Now check if the configuration has been applied correctly.
const Subnet6Collection* subnets = CfgMgr::instance().getSubnets6();
const Subnet6Collection* subnets =
CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getAll();
ASSERT_TRUE(subnets);
ASSERT_EQ(1, subnets->size());

View File

@ -223,8 +223,8 @@ TEST_F(RebindTest, directClient) {
// subnets.
ASSERT_EQ(1, client.getLeaseNum());
Lease6 lease_client2 = client.getLease(0);
ASSERT_TRUE(CfgMgr::instance().getSubnet6(lease_client2.addr_,
ClientClasses()));
ASSERT_TRUE(CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->
selectSubnet(lease_client2.addr_, ClientClasses()));
// The client's lease should have been extended. The client will
// update the cltt to current time when the lease gets extended.
ASSERT_GE(lease_client2.cltt_ - lease_client.cltt_, 1000);
@ -337,8 +337,8 @@ TEST_F(RebindTest, relayedClient) {
// subnets.
ASSERT_EQ(1, client.getLeaseNum());
Lease6 lease_client2 = client.getLease(0);
ASSERT_TRUE(CfgMgr::instance().getSubnet6(lease_client2.addr_,
ClientClasses()));
ASSERT_TRUE(CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->
selectSubnet(lease_client2.addr_, ClientClasses()));
// The client's lease should have been extended. The client will
// update the cltt to current time when the lease gets extended.
ASSERT_GE(lease_client2.cltt_ - lease_client.cltt_, 1000);
@ -498,8 +498,8 @@ TEST_F(RebindTest, directClientPD) {
// subnets.
ASSERT_EQ(1, client.getLeaseNum());
Lease6 lease_client2 = client.getLease(0);
ASSERT_TRUE(CfgMgr::instance().getSubnet6(lease_client2.addr_,
ClientClasses()));
ASSERT_TRUE(CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->
selectSubnet(lease_client2.addr_, ClientClasses()));
// The client's lease should have been extended. The client will
// update the cltt to current time when the lease gets extended.
ASSERT_GE(lease_client2.cltt_ - lease_client.cltt_, 1000);
@ -675,8 +675,8 @@ TEST_F(RebindTest, relayedUnicast) {
// subnets.
ASSERT_EQ(1, client.getLeaseNum());
Lease6 lease_client2 = client.getLease(0);
ASSERT_TRUE(CfgMgr::instance().getSubnet6(lease_client2.addr_,
ClientClasses()));
ASSERT_TRUE(CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->
selectSubnet(lease_client2.addr_, ClientClasses()));
// The client's lease should have been extended. The client will
// update the cltt to current time when the lease gets extended.
ASSERT_GE(lease_client2.cltt_ - lease_client.cltt_, 1000);

View File

@ -76,7 +76,8 @@ TEST_F(SARRTest, directClientPrefixHint) {
client.usePD();
configure(CONFIGS[0], *client.getServer());
// Make sure we ended-up having expected number of subnets configured.
const Subnet6Collection* subnets = CfgMgr::instance().getSubnets6();
const Subnet6Collection* subnets = CfgMgr::instance().getCurrentCfg()->
getCfgSubnets6()->getAll();
ASSERT_EQ(1, subnets->size());
// Append IAPREFIX option to the client's message.
ASSERT_NO_THROW(client.useHint(100, 200, 64, "2001:db8:3:33::33"));

View File

@ -49,7 +49,7 @@ CfgSubnets6::selectSubnet(const SubnetSelector& selector) const {
}
// If interface name didn't match, try the client's address.
if (!subnet && selector.remote_address_.isSpecified()) {
if (!subnet && selector.remote_address_ != IOAddress("::")) {
subnet = selectSubnet(selector.remote_address_,
selector.client_classes_);
}

View File

@ -62,114 +62,6 @@ CfgMgr::addOptionSpace6(const OptionSpacePtr& space) {
spaces6_.insert(make_pair(space->getName(), space));
}
Subnet6Ptr
CfgMgr::getSubnet6(const std::string& iface,
const isc::dhcp::ClientClasses& classes) {
if (!iface.length()) {
return (Subnet6Ptr());
}
// If there is more than one, we need to choose the proper one
for (Subnet6Collection::iterator subnet = subnets6_.begin();
subnet != subnets6_.end(); ++subnet) {
// If client is rejected because of not meeting client class criteria...
if (!(*subnet)->clientSupported(classes)) {
continue;
}
if (iface == (*subnet)->getIface()) {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE,
DHCPSRV_CFGMGR_SUBNET6_IFACE)
.arg((*subnet)->toText()).arg(iface);
return (*subnet);
}
}
return (Subnet6Ptr());
}
Subnet6Ptr
CfgMgr::getSubnet6(const isc::asiolink::IOAddress& hint,
const isc::dhcp::ClientClasses& classes,
const bool relay) {
// If there is more than one, we need to choose the proper one
for (Subnet6Collection::iterator subnet = subnets6_.begin();
subnet != subnets6_.end(); ++subnet) {
// If client is rejected because of not meeting client class criteria...
if (!(*subnet)->clientSupported(classes)) {
continue;
}
// If the hint is a relay address, and there is relay info specified
// for this subnet and those two match, then use this subnet.
if (relay && ((*subnet)->getRelayInfo().addr_ == hint) ) {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE,
DHCPSRV_CFGMGR_SUBNET6_RELAY)
.arg((*subnet)->toText()).arg(hint.toText());
return (*subnet);
}
if ((*subnet)->inRange(hint)) {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE, DHCPSRV_CFGMGR_SUBNET6)
.arg((*subnet)->toText()).arg(hint.toText());
return (*subnet);
}
}
// sorry, we don't support that subnet
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE, DHCPSRV_CFGMGR_NO_SUBNET6)
.arg(hint.toText());
return (Subnet6Ptr());
}
Subnet6Ptr CfgMgr::getSubnet6(OptionPtr iface_id_option,
const isc::dhcp::ClientClasses& classes) {
if (!iface_id_option) {
return (Subnet6Ptr());
}
// Let's iterate over all subnets and for those that have interface-id
// defined, check if the interface-id is equal to what we are looking for
for (Subnet6Collection::iterator subnet = subnets6_.begin();
subnet != subnets6_.end(); ++subnet) {
// If client is rejected because of not meeting client class criteria...
if (!(*subnet)->clientSupported(classes)) {
continue;
}
if ( (*subnet)->getInterfaceId() &&
((*subnet)->getInterfaceId()->equals(iface_id_option))) {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE,
DHCPSRV_CFGMGR_SUBNET6_IFACE_ID)
.arg((*subnet)->toText());
return (*subnet);
}
}
return (Subnet6Ptr());
}
void CfgMgr::addSubnet6(const Subnet6Ptr& subnet) {
/// @todo: Check that this new subnet does not cross boundaries of any
/// other already defined subnet.
/// @todo: Check that there is no subnet with the same interface-id
if (isDuplicate(*subnet)) {
isc_throw(isc::dhcp::DuplicateSubnetID, "ID of the new IPv6 subnet '"
<< subnet->getID() << "' is already in use");
}
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE, DHCPSRV_CFGMGR_ADD_SUBNET6)
.arg(subnet->toText());
subnets6_.push_back(subnet);
}
void CfgMgr::deleteSubnets6() {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE, DHCPSRV_CFGMGR_DELETE_SUBNET6);
subnets6_.clear();
}
std::string CfgMgr::getDataDir() {
return (datadir_);

View File

@ -126,97 +126,6 @@ public:
return (spaces6_);
}
/// @brief get IPv6 subnet by address
///
/// Finds a matching subnet, based on an address. This can be used
/// in two cases: when trying to find an appropriate lease based on
/// a) relay link address (that must be the address that is on link)
/// b) our global address on the interface the message was received on
/// (for directly connected clients)
///
/// If there are any classes specified in a subnet, that subnet
/// will be selected only if the client belongs to appropriate class.
///
/// @note The client classification is checked before any relay
/// information checks are conducted.
///
/// If relay is true then relay info overrides (i.e. value the sysadmin
/// can configure in Dhcp6/subnet6[X]/relay/ip-address) can be used.
/// That is applicable only for relays. Those overrides must not be used
/// for client address or for client hints. They are for link-addr field
/// in the RELAY_FORW message only.
///
/// @param hint an address that belongs to a searched subnet
/// @param classes classes the client belongs to
/// @param relay true if address specified in hint is a relay
///
/// @return a subnet object (or NULL if no suitable match was fount)
Subnet6Ptr getSubnet6(const isc::asiolink::IOAddress& hint,
const isc::dhcp::ClientClasses& classes,
const bool relay = false);
/// @brief get IPv6 subnet by interface name
///
/// Finds a matching local subnet, based on interface name. This
/// is used for selecting subnets that were explicitly marked by the
/// user as reachable over specified network interface.
///
/// If there are any classes specified in a subnet, that subnet
/// will be selected only if the client belongs to appropriate class.
///
/// @param iface_name interface name
/// @param classes classes the client belongs to
///
/// @return a subnet object (or NULL if no suitable match was fount)
Subnet6Ptr getSubnet6(const std::string& iface_name,
const isc::dhcp::ClientClasses& classes);
/// @brief get IPv6 subnet by interface-id
///
/// Another possibility to find a subnet is based on interface-id.
///
/// If there are any classes specified in a subnet, that subnet
/// will be selected only if the client belongs to appropriate class.
///
/// @param interface_id content of interface-id option returned by a relay
/// @param classes classes the client belongs to
///
/// @return a subnet object
Subnet6Ptr getSubnet6(OptionPtr interface_id,
const isc::dhcp::ClientClasses& classes);
/// @brief adds an IPv6 subnet
///
/// @param subnet new subnet to be added.
void addSubnet6(const Subnet6Ptr& subnet);
/// @todo: Add subnet6 removal routines. Currently it is not possible
/// to remove subnets. The only case where subnet6 removal would be
/// needed is a dynamic server reconfiguration - a use case that is not
/// planned to be supported any time soon.
/// @brief removes all IPv6 subnets
///
/// This method removes all existing IPv6 subnets. It is used during
/// reconfiguration - old configuration is wiped and new definitions
/// are used to recreate subnets.
///
/// @todo Implement more intelligent approach. Note that comparison
/// between old and new configuration is tricky. For example: is
/// 2000::/64 and 2000::/48 the same subnet or is it something
/// completely new?
void deleteSubnets6();
/// @brief returns const reference to all subnets6
///
/// This is used in a hook (subnet6_select), where the hook is able
/// to choose a different subnet. Server code has to offer a list
/// of possible choices (i.e. all subnets).
/// @return a pointer to const Subnet6 collection
const Subnet6Collection* getSubnets6() {
return (&subnets6_);
}
/// @brief returns path do the data directory
///
/// This method returns a path to writeable directory that DHCP servers

View File

@ -51,7 +51,7 @@ SrvConfig::getConfigSummary(const uint32_t selection) const {
}
if ((selection & CFGSEL_SUBNET6) == CFGSEL_SUBNET6) {
subnets_num = CfgMgr::instance().getSubnets6()->size();
subnets_num = getCfgSubnets6()->getAll()->size();
if (subnets_num > 0) {
s << "added IPv6 subnets: " << subnets_num;
} else {

View File

@ -18,7 +18,6 @@
#include <asiolink/io_address.h>
#include <dhcp/classify.h>
#include <dhcp/option.h>
#include <util/optional_value.h>
#include <string>
namespace isc {
@ -47,9 +46,9 @@ struct SubnetSelector {
//@}
/// @brief Address on which the message was received.
util::OptionalValue<asiolink::IOAddress> local_address_;
asiolink::IOAddress local_address_;
/// @brief Source address of the message.
util::OptionalValue<asiolink::IOAddress> remote_address_;
asiolink::IOAddress remote_address_;
/// @brief Classes that the client belongs to.
ClientClasses client_classes_;
/// @brief Name of the interface on which the message was received.
@ -63,8 +62,8 @@ struct SubnetSelector {
giaddr_(asiolink::IOAddress("0.0.0.0")),
interface_id_(),
first_relay_linkaddr_(asiolink::IOAddress("::")),
local_address_(asiolink::IOAddress("0.0.0.0"), false),
remote_address_(asiolink::IOAddress("0.0.0.0"), false),
local_address_(asiolink::IOAddress("0.0.0.0")),
remote_address_(asiolink::IOAddress("0.0.0.0")),
client_classes_(), iface_name_(std::string()) {
}
};

View File

@ -91,6 +91,8 @@ public:
/// in many tests, initializes cfg_mgr configuration and creates
/// lease database.
AllocEngine6Test() {
CfgMgr::instance().clear();
duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
iaid_ = 42;
@ -115,7 +117,6 @@ public:
void initSubnet(const IOAddress& subnet, const IOAddress& pool_start,
const IOAddress& pool_end) {
CfgMgr& cfg_mgr = CfgMgr::instance();
cfg_mgr.deleteSubnets6();
subnet_ = Subnet6Ptr(new Subnet6(subnet, 56, 1, 2, 3, 4));
pool_ = Pool6Ptr(new Pool6(Lease::TYPE_NA, pool_start, pool_end));
@ -125,7 +126,8 @@ public:
pd_pool_ = Pool6Ptr(new Pool6(Lease::TYPE_PD, subnet, 56, 64));
subnet_->addPool(pd_pool_);
cfg_mgr.addSubnet6(subnet_);
cfg_mgr.getStagingCfg()->getCfgSubnets6()->add(subnet_);
cfg_mgr.commit();
}
@ -855,13 +857,13 @@ TEST_F(AllocEngine6Test, outOfAddresses6) {
IOAddress addr("2001:db8:1::ad");
CfgMgr& cfg_mgr = CfgMgr::instance();
cfg_mgr.deleteSubnets6(); // Get rid of the default test configuration
cfg_mgr.clear(); // Get rid of the default test configuration
// Create configuration similar to other tests, but with a single address pool
subnet_ = Subnet6Ptr(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));
pool_ = Pool6Ptr(new Pool6(Lease::TYPE_NA, addr, addr)); // just a single address
subnet_->addPool(pool_);
cfg_mgr.addSubnet6(subnet_);
cfg_mgr.getStagingCfg()->getCfgSubnets6()->add(subnet_);
// Just a different duid
DuidPtr other_duid = DuidPtr(new DUID(vector<uint8_t>(12, 0xff)));
@ -939,13 +941,14 @@ TEST_F(AllocEngine6Test, requestReuseExpiredLease6) {
IOAddress addr("2001:db8:1::ad");
CfgMgr& cfg_mgr = CfgMgr::instance();
cfg_mgr.deleteSubnets6(); // Get rid of the default test configuration
cfg_mgr.clear(); // Get rid of the default test configuration
// Create configuration similar to other tests, but with a single address pool
subnet_ = Subnet6Ptr(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));
pool_ = Pool6Ptr(new Pool6(Lease::TYPE_NA, addr, addr)); // just a single address
subnet_->addPool(pool_);
cfg_mgr.addSubnet6(subnet_);
cfg_mgr.getStagingCfg()->getCfgSubnets6()->add(subnet_);
cfg_mgr.commit();
// Let's create an expired lease
DuidPtr other_duid = DuidPtr(new DUID(vector<uint8_t>(12, 0xff)));

View File

@ -283,7 +283,6 @@ public:
void clear() {
CfgMgr::instance().setVerbose(false);
CfgMgr::instance().deleteSubnets6();
CfgMgr::instance().clear();
}
@ -304,307 +303,6 @@ TEST_F(CfgMgrTest, configuration) {
EXPECT_TRUE(configuration->getLoggingInfo().empty());
}
// This test verifies if the configuration manager is able to hold v6 subnets
// with their relay address information and return proper subnets, based on
// those addresses.
TEST_F(CfgMgrTest, subnet6RelayOverride) {
CfgMgr& cfg_mgr = CfgMgr::instance();
// Let's configure 3 subnets
Subnet6Ptr subnet1(new Subnet6(IOAddress("2001:db8:1::"), 48, 1, 2, 3, 4));
Subnet6Ptr subnet2(new Subnet6(IOAddress("2001:db8:2::"), 48, 1, 2, 3, 4));
Subnet6Ptr subnet3(new Subnet6(IOAddress("2001:db8:3::"), 48, 1, 2, 3, 4));
cfg_mgr.addSubnet6(subnet1);
cfg_mgr.addSubnet6(subnet2);
cfg_mgr.addSubnet6(subnet3);
// Check that without relay-info specified, subnets are not selected
EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("2001:db8:ff::1"), classify_, true));
EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("2001:db8:ff::2"), classify_, true));
EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("2001:db8:ff::3"), classify_, true));
// Now specify relay info
subnet1->setRelayInfo(IOAddress("2001:db8:ff::1"));
subnet2->setRelayInfo(IOAddress("2001:db8:ff::2"));
subnet3->setRelayInfo(IOAddress("2001:db8:ff::3"));
// And try again. This time relay-info is there and should match.
EXPECT_EQ(subnet1, cfg_mgr.getSubnet6(IOAddress("2001:db8:ff::1"), classify_, true));
EXPECT_EQ(subnet2, cfg_mgr.getSubnet6(IOAddress("2001:db8:ff::2"), classify_, true));
EXPECT_EQ(subnet3, cfg_mgr.getSubnet6(IOAddress("2001:db8:ff::3"), classify_, true));
// Finally, check that the relay works only if hint provided is relay address
EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("2001:db8:ff::1"), classify_, false));
EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("2001:db8:ff::2"), classify_, false));
EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("2001:db8:ff::3"), classify_, false));
}
// This test verifies if the configuration manager is able to hold and return
// valid leases
TEST_F(CfgMgrTest, classifySubnet6) {
CfgMgr& cfg_mgr = CfgMgr::instance();
// Let's configure 3 subnets
Subnet6Ptr subnet1(new Subnet6(IOAddress("2000::"), 48, 1, 2, 3, 4));
Subnet6Ptr subnet2(new Subnet6(IOAddress("3000::"), 48, 1, 2, 3, 4));
Subnet6Ptr subnet3(new Subnet6(IOAddress("4000::"), 48, 1, 2, 3, 4));
cfg_mgr.addSubnet6(subnet1);
cfg_mgr.addSubnet6(subnet2);
cfg_mgr.addSubnet6(subnet3);
// Let's sanity check that we can use that configuration.
EXPECT_EQ(subnet1, cfg_mgr.getSubnet6(IOAddress("2000::123"), classify_));
EXPECT_EQ(subnet2, cfg_mgr.getSubnet6(IOAddress("3000::345"), classify_));
EXPECT_EQ(subnet3, cfg_mgr.getSubnet6(IOAddress("4000::567"), classify_));
// Client now belongs to bar class.
classify_.insert("bar");
// There are no class restrictions defined, so everything should work
// as before
EXPECT_EQ(subnet1, cfg_mgr.getSubnet6(IOAddress("2000::123"), classify_));
EXPECT_EQ(subnet2, cfg_mgr.getSubnet6(IOAddress("3000::345"), classify_));
EXPECT_EQ(subnet3, cfg_mgr.getSubnet6(IOAddress("4000::567"), classify_));
// Now let's add client class restrictions.
subnet1->allowClientClass("foo"); // Serve here only clients from foo class
subnet2->allowClientClass("bar"); // Serve here only clients from bar class
subnet3->allowClientClass("baz"); // Serve here only clients from baz class
// The same check as above should result in client being served only in
// bar class, i.e. subnet2
EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("2000::123"), classify_));
EXPECT_EQ(subnet2, cfg_mgr.getSubnet6(IOAddress("3000::345"), classify_));
EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("4000::567"), classify_));
// Now let's check that client with wrong class is not supported
classify_.clear();
classify_.insert("some_other_class");
EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("2000::123"), classify_));
EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("3000::345"), classify_));
EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("4000::567"), classify_));
// Finally, let's check that client without any classes is not supported
classify_.clear();
EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("2000::123"), classify_));
EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("3000::345"), classify_));
EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("4000::567"), classify_));
}
// This test verifies if the configuration manager is able to hold, select
// and return valid subnets, based on interface names along with client
// classification.
TEST_F(CfgMgrTest, classifySubnet6Interface) {
CfgMgr& cfg_mgr = CfgMgr::instance();
// Let's have an odd configuration: 3 shared subnets available on the
// same direct link.
Subnet6Ptr subnet1(new Subnet6(IOAddress("2000::"), 48, 1, 2, 3, 4));
Subnet6Ptr subnet2(new Subnet6(IOAddress("3000::"), 48, 1, 2, 3, 4));
Subnet6Ptr subnet3(new Subnet6(IOAddress("4000::"), 48, 1, 2, 3, 4));
subnet1->setIface("foo");
subnet2->setIface("foo");
subnet3->setIface("foo");
cfg_mgr.addSubnet6(subnet1);
cfg_mgr.addSubnet6(subnet2);
cfg_mgr.addSubnet6(subnet3);
// Regular client should get the first subnet, because it meets all
// criteria (matching interface name, no class restrictions.
EXPECT_EQ(subnet1, cfg_mgr.getSubnet6("foo", classify_));
// Now let's add class requirements for subnet1
subnet1->allowClientClass("alpha");
// Client should now get the subnet2, because he no longer meets
// requirements for subnet1 (belongs to wrong class)
EXPECT_EQ(subnet2, cfg_mgr.getSubnet6("foo", classify_));
// Now let's add (not matching) classes to the other two subnets
subnet2->allowClientClass("beta");
subnet3->allowClientClass("gamma");
// No subnets are suitable, so nothing will be selected
EXPECT_FALSE(cfg_mgr.getSubnet6("foo", classify_));
// Ok, let's add the client to gamme class, so he'll get a subnet
classify_.insert("gamma");
EXPECT_EQ(subnet3, cfg_mgr.getSubnet6("foo", classify_));
}
// This test verifies if the configuration manager is able to hold, select
// and return valid subnets, based on interface-id option inserted by relay,
// along with client classification.
TEST_F(CfgMgrTest, classifySubnet6InterfaceId) {
CfgMgr& cfg_mgr = CfgMgr::instance();
// Let's have an odd configuration: 3 shared subnets available via the
// same remote relay with the same interface-id.
Subnet6Ptr subnet1(new Subnet6(IOAddress("2000::"), 48, 1, 2, 3, 4));
Subnet6Ptr subnet2(new Subnet6(IOAddress("3000::"), 48, 1, 2, 3, 4));
Subnet6Ptr subnet3(new Subnet6(IOAddress("4000::"), 48, 1, 2, 3, 4));
OptionPtr ifaceid = generateInterfaceId("relay1.eth0");
subnet1->setInterfaceId(ifaceid);
subnet2->setInterfaceId(ifaceid);
subnet3->setInterfaceId(ifaceid);
cfg_mgr.addSubnet6(subnet1);
cfg_mgr.addSubnet6(subnet2);
cfg_mgr.addSubnet6(subnet3);
// Regular client should get the first subnet, because it meets all
// criteria (matching interface name, no class restrictions.
EXPECT_EQ(subnet1, cfg_mgr.getSubnet6(ifaceid, classify_));
// Now let's add class requirements for subnet1
subnet1->allowClientClass("alpha");
// Client should now get the subnet2, because he no longer meets
// requirements for subnet1 (belongs to wrong class)
EXPECT_EQ(subnet2, cfg_mgr.getSubnet6(ifaceid, classify_));
// Now let's add (not matching) classes to the other two subnets
subnet2->allowClientClass("beta");
subnet3->allowClientClass("gamma");
// No subnets are suitable, so nothing will be selected
EXPECT_FALSE(cfg_mgr.getSubnet6(ifaceid, classify_));
// Ok, let's add the client to gamme class, so he'll get a subnet
classify_.insert("gamma");
EXPECT_EQ(subnet3, cfg_mgr.getSubnet6(ifaceid, classify_));
}
// This test verifies if the configuration manager is able to hold and return
// valid leases
TEST_F(CfgMgrTest, subnet6) {
CfgMgr& cfg_mgr = CfgMgr::instance();
Subnet6Ptr subnet1(new Subnet6(IOAddress("2000::"), 48, 1, 2, 3, 4));
Subnet6Ptr subnet2(new Subnet6(IOAddress("3000::"), 48, 1, 2, 3, 4));
Subnet6Ptr subnet3(new Subnet6(IOAddress("4000::"), 48, 1, 2, 3, 4));
// There shouldn't be any subnet configured at this stage
EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("2000::1"), classify_));
cfg_mgr.addSubnet6(subnet1);
// Now we have only one subnet, any request will be served from it
EXPECT_EQ(subnet1, cfg_mgr.getSubnet6(IOAddress("2000::1"), classify_));
// We used to allow getting a sole subnet if there was only one subnet
// configured. That is no longer true. The code should not return
// a subnet.
EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("fe80::dead:beef"), classify_));
cfg_mgr.addSubnet6(subnet2);
cfg_mgr.addSubnet6(subnet3);
EXPECT_EQ(subnet3, cfg_mgr.getSubnet6(IOAddress("4000::123"), classify_));
EXPECT_EQ(subnet2, cfg_mgr.getSubnet6(IOAddress("3000::dead:beef"),
classify_));
EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("5000::1"), classify_));
// Check that deletion of the subnets works.
cfg_mgr.deleteSubnets6();
EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("2000::123"), classify_));
EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("3000::123"), classify_));
EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("4000::123"), classify_));
}
// This test verifies if the configuration manager is able to hold, select
// and return valid subnets, based on interface names.
TEST_F(CfgMgrTest, subnet6Interface) {
CfgMgr& cfg_mgr = CfgMgr::instance();
Subnet6Ptr subnet1(new Subnet6(IOAddress("2000::"), 48, 1, 2, 3, 4));
Subnet6Ptr subnet2(new Subnet6(IOAddress("3000::"), 48, 1, 2, 3, 4));
Subnet6Ptr subnet3(new Subnet6(IOAddress("4000::"), 48, 1, 2, 3, 4));
subnet1->setIface("foo");
subnet2->setIface("bar");
subnet3->setIface("foobar");
// There shouldn't be any subnet configured at this stage
EXPECT_FALSE(cfg_mgr.getSubnet6("foo", classify_));
cfg_mgr.addSubnet6(subnet1);
// Now we have only one subnet, any request will be served from it
EXPECT_EQ(subnet1, cfg_mgr.getSubnet6("foo", classify_));
// Check that the interface name is checked even when there is
// only one subnet defined.
EXPECT_FALSE(cfg_mgr.getSubnet6("bar", classify_));
// We used to allow getting a sole subnet if there was only one subnet
// configured. That is no longer true. The code should not return
// a subnet.
EXPECT_FALSE(cfg_mgr.getSubnet6(IOAddress("fe80::dead:beef"), classify_));
cfg_mgr.addSubnet6(subnet2);
cfg_mgr.addSubnet6(subnet3);
EXPECT_EQ(subnet3, cfg_mgr.getSubnet6("foobar", classify_));
EXPECT_EQ(subnet2, cfg_mgr.getSubnet6("bar", classify_));
EXPECT_FALSE(cfg_mgr.getSubnet6("xyzzy", classify_)); // no such interface
// Check that deletion of the subnets works.
cfg_mgr.deleteSubnets6();
EXPECT_FALSE(cfg_mgr.getSubnet6("foo", classify_));
EXPECT_FALSE(cfg_mgr.getSubnet6("bar", classify_));
EXPECT_FALSE(cfg_mgr.getSubnet6("foobar", classify_));
}
// This test verifies if the configuration manager is able to hold, select
// and return valid leases, based on interface-id option values
TEST_F(CfgMgrTest, subnet6InterfaceId) {
CfgMgr& cfg_mgr = CfgMgr::instance();
Subnet6Ptr subnet1(new Subnet6(IOAddress("2000::"), 48, 1, 2, 3, 4));
Subnet6Ptr subnet2(new Subnet6(IOAddress("3000::"), 48, 1, 2, 3, 4));
Subnet6Ptr subnet3(new Subnet6(IOAddress("4000::"), 48, 1, 2, 3, 4));
// interface-id options used in subnets 1,2, and 3
OptionPtr ifaceid1 = generateInterfaceId("relay1.eth0");
OptionPtr ifaceid2 = generateInterfaceId("VL32");
// That's a strange interface-id, but this is a real life example
OptionPtr ifaceid3 = generateInterfaceId("ISAM144|299|ipv6|nt:vp:1:110");
// bogus interface-id
OptionPtr ifaceid_bogus = generateInterfaceId("non-existent");
subnet1->setInterfaceId(ifaceid1);
subnet2->setInterfaceId(ifaceid2);
subnet3->setInterfaceId(ifaceid3);
// There shouldn't be any subnet configured at this stage
EXPECT_FALSE(cfg_mgr.getSubnet6(ifaceid1, classify_));
cfg_mgr.addSubnet6(subnet1);
// If we have only a single subnet and the request came from a local
// address, let's use that subnet
EXPECT_EQ(subnet1, cfg_mgr.getSubnet6(ifaceid1, classify_));
EXPECT_FALSE(cfg_mgr.getSubnet6(ifaceid2, classify_));
cfg_mgr.addSubnet6(subnet2);
cfg_mgr.addSubnet6(subnet3);
EXPECT_EQ(subnet3, cfg_mgr.getSubnet6(ifaceid3, classify_));
EXPECT_EQ(subnet2, cfg_mgr.getSubnet6(ifaceid2, classify_));
EXPECT_FALSE(cfg_mgr.getSubnet6(ifaceid_bogus, classify_));
// Check that deletion of the subnets works.
cfg_mgr.deleteSubnets6();
EXPECT_FALSE(cfg_mgr.getSubnet6(ifaceid1, classify_));
EXPECT_FALSE(cfg_mgr.getSubnet6(ifaceid2, classify_));
EXPECT_FALSE(cfg_mgr.getSubnet6(ifaceid3, classify_));
}
// This test verifies that new DHCPv4 option spaces can be added to
// the configuration manager and that duplicated option space is
// rejected.
@ -731,26 +429,6 @@ TEST_F(CfgMgrTest, d2ClientConfig) {
EXPECT_NE(*original_config, *updated_config);
}
// Checks that detection of duplicated subnet IDs works as expected. It should
// not be possible to add two IPv6 subnets holding the same ID to the config
// manager.
TEST_F(CfgMgrTest, subnet6Duplication) {
CfgMgr& cfg_mgr = CfgMgr::instance();
Subnet6Ptr subnet1(new Subnet6(IOAddress("2001:db8:1::"), 64, 1, 2, 3,
4, 123));
Subnet6Ptr subnet2(new Subnet6(IOAddress("2001:db8:2::"), 64, 1, 2, 3,
4, 124));
Subnet6Ptr subnet3(new Subnet6(IOAddress("2001:db8:3::"), 64, 1, 2, 3,
4, 123));
ASSERT_NO_THROW(cfg_mgr.addSubnet6(subnet1));
EXPECT_NO_THROW(cfg_mgr.addSubnet6(subnet2));
// Subnet 3 has the same ID as subnet 1. It shouldn't be able to add it.
EXPECT_THROW(cfg_mgr.addSubnet6(subnet3), isc::dhcp::DuplicateSubnetID);
}
// This test verifies that the configuration staging, commit and rollback works
// as expected.
TEST_F(CfgMgrTest, staging) {

View File

@ -447,7 +447,6 @@ public:
void reset_context(){
// Note set context universe to V6 as it has to be something.
CfgMgr::instance().clear();
CfgMgr::instance().deleteSubnets6();
parser_context_.reset(new ParserContext(Option::V6));
// Ensure no hooks libraries are loaded.

View File

@ -41,8 +41,6 @@ public:
/// is @c TEST_SUBNETS_NUM for IPv4 and IPv6 each.
SrvConfigTest()
: iface_mgr_test_config_(true) {
// Remove any subnets dangling from previous unit tests.
clearSubnets();
// Disable DDNS.
enableDDNS(false);
@ -74,10 +72,7 @@ public:
}
/// @brief Destructor.
///
/// Removes any dangling configuration.
virtual ~SrvConfigTest() {
clearSubnets();
}
/// @brief Convenience function which adds IPv4 subnet to the configuration.
@ -108,12 +103,6 @@ public:
/// @c conf_ object.
void addSubnet6(const unsigned int index);
/// @brief Removes all subnets from the configuration.
///
/// @todo Modify this function once the subnet configuration is migrated
/// from @c CfgMgr to @c SrvConfig.
void clearSubnets();
/// @brief Enable/disable DDNS.
///
/// @param enable A boolean value indicating if the DDNS should be
@ -146,12 +135,7 @@ SrvConfigTest::addSubnet6(const unsigned int index) {
FAIL() << "Subnet index " << index << "out of range (0.."
<< TEST_SUBNETS_NUM << "): " << "unable to add IPv6 subnet";
}
CfgMgr::instance().addSubnet6(test_subnets6_[index]);
}
void
SrvConfigTest::clearSubnets() {
CfgMgr::instance().deleteSubnets6();
conf_.getCfgSubnets6()->add(test_subnets6_[index]);
}
void