mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-30 05:27:55 +00:00
[3587] Use CfgSubnets4 object to obtain information about subnets.
This commit is contained in:
parent
3e0307cc94
commit
feb21c04b9
@ -29,6 +29,7 @@
|
||||
#include <dhcpsrv/addr_utilities.h>
|
||||
#include <dhcpsrv/callout_handle_store.h>
|
||||
#include <dhcpsrv/cfgmgr.h>
|
||||
#include <dhcpsrv/cfg_subnets4.h>
|
||||
#include <dhcpsrv/lease_mgr.h>
|
||||
#include <dhcpsrv/lease_mgr_factory.h>
|
||||
#include <dhcpsrv/subnet.h>
|
||||
@ -1539,47 +1540,17 @@ Subnet4Ptr
|
||||
Dhcpv4Srv::selectSubnet(const Pkt4Ptr& question) const {
|
||||
|
||||
Subnet4Ptr subnet;
|
||||
static const IOAddress notset("0.0.0.0");
|
||||
static const IOAddress bcast("255.255.255.255");
|
||||
|
||||
// If a message is relayed, use the relay (giaddr) address to select subnet
|
||||
// for the client. Note that this may result in exception if the value
|
||||
// of hops does not correspond with the Giaddr. Such message is considered
|
||||
// to be malformed anyway and the message will be dropped by the higher
|
||||
// level functions.
|
||||
if (question->isRelayed()) {
|
||||
subnet = CfgMgr::instance().getSubnet4(question->getGiaddr(),
|
||||
question->classes_,
|
||||
true);
|
||||
CfgSubnets4::Selector selector;
|
||||
selector.ciaddr_ = question->getCiaddr();
|
||||
selector.giaddr_ = question->getGiaddr();
|
||||
selector.local_address_ = question->getLocalAddr();
|
||||
selector.remote_address_ = question->getRemoteAddr();
|
||||
selector.client_classes_ = question->classes_;
|
||||
selector.iface_name_ = question->getIface();
|
||||
|
||||
// The message is not relayed so it is sent directly by a client. But
|
||||
// the client may be renewing its lease and in such case it unicasts
|
||||
// its message to the server. Note that the unicast Request bypasses
|
||||
// relays and the client may be in a different network, so we can't
|
||||
// use IP address on the local interface to get the subnet. Instead,
|
||||
// we rely on the client's address to get the subnet.
|
||||
} else if ((question->getLocalAddr() != bcast) &&
|
||||
(question->getCiaddr() != notset)) {
|
||||
subnet = CfgMgr::instance().getSubnet4(question->getCiaddr(),
|
||||
question->classes_);
|
||||
|
||||
// Either renewing client or the client that sends DHCPINFORM
|
||||
// must set the ciaddr. But apparently some clients don't do it,
|
||||
// so if the client didn't include ciaddr we will use the source
|
||||
// address.
|
||||
} else if ((question->getLocalAddr() != bcast) &&
|
||||
(question->getRemoteAddr() != notset)) {
|
||||
subnet = CfgMgr::instance().getSubnet4(question->getRemoteAddr(),
|
||||
question->classes_);
|
||||
|
||||
// The message has been received from a directly connected client
|
||||
// and this client appears to have no address. The IPv4 address
|
||||
// assigned to the interface on which this message has been received,
|
||||
// will be used to determine the subnet suitable for the client.
|
||||
} else {
|
||||
subnet = CfgMgr::instance().getSubnet4(question->getIface(),
|
||||
question->classes_);
|
||||
}
|
||||
CfgMgr& cfgmgr = CfgMgr::instance();
|
||||
subnet = cfgmgr.getCurrentCfg()->getCfgSubnets4()->get(selector);
|
||||
|
||||
// Let's execute all callouts registered for subnet4_select
|
||||
if (HooksManager::calloutsPresent(hook_index_subnet4_select_)) {
|
||||
@ -1592,7 +1563,8 @@ Dhcpv4Srv::selectSubnet(const Pkt4Ptr& question) const {
|
||||
callout_handle->setArgument("query4", question);
|
||||
callout_handle->setArgument("subnet4", subnet);
|
||||
callout_handle->setArgument("subnet4collection",
|
||||
CfgMgr::instance().getSubnets4());
|
||||
cfgmgr.getCurrentCfg()->
|
||||
getCfgSubnets4()->getAll());
|
||||
|
||||
// Call user (and server-side) callouts
|
||||
HooksManager::callCallouts(hook_index_subnet4_select_,
|
||||
|
@ -138,7 +138,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().addSubnet4(sub4ptr);
|
||||
CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->add(sub4ptr);
|
||||
} catch (const std::exception& ex) {
|
||||
isc_throw(DhcpConfigError, ex.what() << " ("
|
||||
<< subnet->getPosition() << ")");
|
||||
@ -317,28 +317,16 @@ public:
|
||||
///
|
||||
/// @param subnets_list pointer to a list of IPv4 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
|
||||
CfgMgr::instance().deleteSubnets4();
|
||||
|
||||
BOOST_FOREACH(ConstElementPtr subnet, subnets_list->listValue()) {
|
||||
ParserPtr parser(new Subnet4ConfigParser("subnet"));
|
||||
parser->build(subnet);
|
||||
subnets_.push_back(parser);
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief commits subnets definitions.
|
||||
///
|
||||
/// Iterates over all Subnet4 parsers. Each parser contains definitions of
|
||||
/// a single subnet and its parameters and commits each subnet separately.
|
||||
/// Does nothing.
|
||||
void commit() {
|
||||
BOOST_FOREACH(ParserPtr subnet, subnets_) {
|
||||
subnet->commit();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// @brief Returns Subnet4ListConfigParser object
|
||||
@ -347,10 +335,6 @@ public:
|
||||
static DhcpConfigParser* factory(const std::string& param_name) {
|
||||
return (new Subnets4ListConfigParser(param_name));
|
||||
}
|
||||
|
||||
/// @brief collection of subnet parsers.
|
||||
ParserCollection subnets_;
|
||||
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
@ -545,10 +529,6 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
|
||||
// This operation should be exception safe but let's make sure.
|
||||
if (!rollback) {
|
||||
try {
|
||||
if (subnet_parser) {
|
||||
subnet_parser->commit();
|
||||
}
|
||||
|
||||
// No need to commit interface names as this is handled by the
|
||||
// CfgMgr::commit() function.
|
||||
|
||||
@ -582,7 +562,7 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
|
||||
}
|
||||
|
||||
LOG_INFO(dhcp4_logger, DHCP4_CONFIG_COMPLETE)
|
||||
.arg(CfgMgr::instance().getCurrentCfg()->
|
||||
.arg(CfgMgr::instance().getStagingCfg()->
|
||||
getConfigSummary(SrvConfig::CFGSEL_ALL4));
|
||||
|
||||
// Everything was fine. Configuration is successful.
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <dhcp/tests/iface_mgr_test_config.h>
|
||||
#include <dhcpsrv/subnet.h>
|
||||
#include <dhcpsrv/cfgmgr.h>
|
||||
#include <dhcpsrv/cfg_subnets4.h>
|
||||
#include <dhcpsrv/testutils/config_result_check.h>
|
||||
#include <hooks/hooks_manager.h>
|
||||
|
||||
@ -235,8 +236,8 @@ public:
|
||||
getOptionFromSubnet(const IOAddress& subnet_address,
|
||||
const uint16_t option_code,
|
||||
const uint16_t expected_options_count = 1) {
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(subnet_address,
|
||||
classify_);
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
|
||||
getCfgSubnets4()->get(subnet_address);
|
||||
if (!subnet) {
|
||||
/// @todo replace toText() with the use of operator <<.
|
||||
ADD_FAILURE() << "A subnet for the specified address "
|
||||
@ -397,6 +398,7 @@ public:
|
||||
/// latter case, a failure will have been added to the current test.
|
||||
bool
|
||||
executeConfiguration(const std::string& config, const char* operation) {
|
||||
CfgMgr::instance().clear();
|
||||
ConstElementPtr status;
|
||||
try {
|
||||
ElementPtr json = Element::fromJSON(config);
|
||||
@ -532,8 +534,8 @@ TEST_F(Dhcp4ParserTest, unspecifiedRenewTimer) {
|
||||
checkGlobalUint32("rebind-timer", 2000);
|
||||
checkGlobalUint32("valid-lifetime", 4000);
|
||||
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.200"),
|
||||
classify_);
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
|
||||
getCfgSubnets4()->get(IOAddress("192.0.2.200"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_TRUE(subnet->getT1().unspecified());
|
||||
EXPECT_FALSE(subnet->getT2().unspecified());
|
||||
@ -566,8 +568,8 @@ TEST_F(Dhcp4ParserTest, unspecifiedRebindTimer) {
|
||||
checkGlobalUint32("renew-timer", 1000);
|
||||
checkGlobalUint32("valid-lifetime", 4000);
|
||||
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.200"),
|
||||
classify_);
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
|
||||
getCfgSubnets4()->get(IOAddress("192.0.2.200"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_FALSE(subnet->getT1().unspecified());
|
||||
EXPECT_EQ(1000, subnet->getT1());
|
||||
@ -601,8 +603,8 @@ TEST_F(Dhcp4ParserTest, subnetGlobalDefaults) {
|
||||
|
||||
// Now check if the configuration was indeed handled and we have
|
||||
// expected pool configured.
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.200"),
|
||||
classify_);
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
|
||||
getCfgSubnets4()->get(IOAddress("192.0.2.200"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(1000, subnet->getT1());
|
||||
EXPECT_EQ(2000, subnet->getT2());
|
||||
@ -649,7 +651,10 @@ TEST_F(Dhcp4ParserTest, multipleSubnets) {
|
||||
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
|
||||
checkResult(x, 0);
|
||||
|
||||
const Subnet4Collection* subnets = CfgMgr::instance().getSubnets4();
|
||||
CfgMgr::instance().commit();
|
||||
|
||||
const Subnet4Collection* subnets =
|
||||
CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getAll();
|
||||
ASSERT_TRUE(subnets);
|
||||
ASSERT_EQ(4, subnets->size()); // We expect 4 subnets
|
||||
|
||||
@ -702,7 +707,10 @@ TEST_F(Dhcp4ParserTest, multipleSubnetsExplicitIDs) {
|
||||
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
|
||||
checkResult(x, 0);
|
||||
|
||||
const Subnet4Collection* subnets = CfgMgr::instance().getSubnets4();
|
||||
CfgMgr::instance().commit();
|
||||
|
||||
const Subnet4Collection* subnets =
|
||||
CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getAll();
|
||||
ASSERT_TRUE(subnets);
|
||||
ASSERT_EQ(4, subnets->size()); // We expect 4 subnets
|
||||
|
||||
@ -833,16 +841,19 @@ TEST_F(Dhcp4ParserTest, reconfigureRemoveSubnet) {
|
||||
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
|
||||
checkResult(x, 0);
|
||||
|
||||
const Subnet4Collection* subnets = CfgMgr::instance().getSubnets4();
|
||||
const Subnet4Collection* subnets =
|
||||
CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->getAll();
|
||||
ASSERT_TRUE(subnets);
|
||||
ASSERT_EQ(4, subnets->size()); // We expect 4 subnets
|
||||
|
||||
CfgMgr::instance().clear();
|
||||
|
||||
// Do the reconfiguration (the last subnet is removed)
|
||||
json = Element::fromJSON(config_first3);
|
||||
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
|
||||
checkResult(x, 0);
|
||||
|
||||
subnets = CfgMgr::instance().getSubnets4();
|
||||
subnets = CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->getAll();
|
||||
ASSERT_TRUE(subnets);
|
||||
ASSERT_EQ(3, subnets->size()); // We expect 3 subnets now (4th is removed)
|
||||
|
||||
@ -851,6 +862,8 @@ TEST_F(Dhcp4ParserTest, reconfigureRemoveSubnet) {
|
||||
EXPECT_EQ(2, subnets->at(1)->getID());
|
||||
EXPECT_EQ(3, subnets->at(2)->getID());
|
||||
|
||||
CfgMgr::instance().clear();
|
||||
|
||||
/// CASE 2: Configure 4 subnets, then reconfigure and remove one
|
||||
/// from in between (not first, not last)
|
||||
|
||||
@ -859,12 +872,14 @@ TEST_F(Dhcp4ParserTest, reconfigureRemoveSubnet) {
|
||||
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
|
||||
checkResult(x, 0);
|
||||
|
||||
CfgMgr::instance().clear();
|
||||
|
||||
// Do reconfiguration
|
||||
json = Element::fromJSON(config_second_removed);
|
||||
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
|
||||
checkResult(x, 0);
|
||||
|
||||
subnets = CfgMgr::instance().getSubnets4();
|
||||
subnets = CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->getAll();
|
||||
ASSERT_TRUE(subnets);
|
||||
ASSERT_EQ(3, subnets->size()); // We expect 4 subnets
|
||||
|
||||
@ -901,8 +916,8 @@ TEST_F(Dhcp4ParserTest, nextServerGlobal) {
|
||||
|
||||
// Now check if the configuration was indeed handled and we have
|
||||
// expected pool configured.
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.200"),
|
||||
classify_);
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
|
||||
getCfgSubnets4()->get(IOAddress("192.0.2.200"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ("1.2.3.4", subnet->getSiaddr().toText());
|
||||
}
|
||||
@ -931,8 +946,8 @@ TEST_F(Dhcp4ParserTest, nextServerSubnet) {
|
||||
|
||||
// Now check if the configuration was indeed handled and we have
|
||||
// expected pool configured.
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.200"),
|
||||
classify_);
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
|
||||
getCfgSubnets4()->get(IOAddress("192.0.2.200"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ("1.2.3.4", subnet->getSiaddr().toText());
|
||||
}
|
||||
@ -1022,8 +1037,8 @@ TEST_F(Dhcp4ParserTest, nextServerOverride) {
|
||||
|
||||
// Now check if the configuration was indeed handled and we have
|
||||
// expected pool configured.
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.200"),
|
||||
classify_);
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
|
||||
getCfgSubnets4()->get(IOAddress("192.0.2.200"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ("1.2.3.4", subnet->getSiaddr().toText());
|
||||
}
|
||||
@ -1061,6 +1076,8 @@ TEST_F(Dhcp4ParserTest, echoClientId) {
|
||||
EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, json_false));
|
||||
ASSERT_FALSE(CfgMgr::instance().echoClientId());
|
||||
|
||||
CfgMgr::instance().clear();
|
||||
|
||||
// Now check that "true" configuration is really applied.
|
||||
EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, json_true));
|
||||
ASSERT_TRUE(CfgMgr::instance().echoClientId());
|
||||
@ -1093,8 +1110,8 @@ TEST_F(Dhcp4ParserTest, subnetLocal) {
|
||||
// returned value should be 0 (configuration success)
|
||||
checkResult(status, 0);
|
||||
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.200"),
|
||||
classify_);
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
|
||||
getCfgSubnets4()->get(IOAddress("192.0.2.200"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(1, subnet->getT1());
|
||||
EXPECT_EQ(2, subnet->getT2());
|
||||
@ -1131,7 +1148,8 @@ TEST_F(Dhcp4ParserTest, multiplePools) {
|
||||
ASSERT_NO_THROW(status = configureDhcp4Server(*srv_, json));
|
||||
checkResult(status, 0);
|
||||
|
||||
const Subnet4Collection* subnets = CfgMgr::instance().getSubnets4();
|
||||
const Subnet4Collection* subnets =
|
||||
CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->getAll();
|
||||
ASSERT_TRUE(subnets);
|
||||
ASSERT_EQ(2, subnets->size()); // We expect 2 subnets
|
||||
|
||||
@ -1204,8 +1222,8 @@ TEST_F(Dhcp4ParserTest, poolPrefixLen) {
|
||||
// returned value must be 0 (configuration accepted)
|
||||
checkResult(status, 0);
|
||||
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.200"),
|
||||
classify_);
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
|
||||
getCfgSubnets4()->get(IOAddress("192.0.2.200"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(1000, subnet->getT1());
|
||||
EXPECT_EQ(2000, subnet->getT2());
|
||||
@ -1794,8 +1812,8 @@ TEST_F(Dhcp4ParserTest, optionDataDefaults) {
|
||||
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
|
||||
checkResult(x, 0);
|
||||
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.200"),
|
||||
classify_);
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
|
||||
getCfgSubnets4()->get(IOAddress("192.0.2.200"));
|
||||
ASSERT_TRUE(subnet);
|
||||
OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp4");
|
||||
ASSERT_EQ(2, options->size());
|
||||
@ -1880,8 +1898,8 @@ TEST_F(Dhcp4ParserTest, optionDataTwoSpaces) {
|
||||
checkResult(status, 0);
|
||||
|
||||
// Options should be now available for the subnet.
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.200"),
|
||||
classify_);
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
|
||||
getCfgSubnets4()->get(IOAddress("192.0.2.200"));
|
||||
ASSERT_TRUE(subnet);
|
||||
// Try to get the option from the space dhcp4.
|
||||
OptionDescriptor desc1 = subnet->getCfgOption()->get("dhcp4", 56);
|
||||
@ -2034,8 +2052,8 @@ TEST_F(Dhcp4ParserTest, optionDataEncapsulate) {
|
||||
checkResult(status, 0);
|
||||
|
||||
// Get the subnet.
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.5"),
|
||||
classify_);
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
|
||||
getCfgSubnets4()->get(IOAddress("192.0.2.5"));
|
||||
ASSERT_TRUE(subnet);
|
||||
|
||||
// We should have one option available.
|
||||
@ -2101,8 +2119,8 @@ TEST_F(Dhcp4ParserTest, optionDataInSingleSubnet) {
|
||||
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
|
||||
checkResult(x, 0);
|
||||
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.24"),
|
||||
classify_);
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
|
||||
getCfgSubnets4()->get(IOAddress("192.0.2.24"));
|
||||
ASSERT_TRUE(subnet);
|
||||
OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp4");
|
||||
ASSERT_EQ(2, options->size());
|
||||
@ -2252,8 +2270,8 @@ TEST_F(Dhcp4ParserTest, optionDataInMultipleSubnets) {
|
||||
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
|
||||
checkResult(x, 0);
|
||||
|
||||
Subnet4Ptr subnet1 = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.100"),
|
||||
classify_);
|
||||
Subnet4Ptr subnet1 = CfgMgr::instance().getStagingCfg()->
|
||||
getCfgSubnets4()->get(IOAddress("192.0.2.100"));
|
||||
ASSERT_TRUE(subnet1);
|
||||
OptionContainerPtr options1 = subnet1->getCfgOption()->getAll("dhcp4");
|
||||
ASSERT_EQ(1, options1->size());
|
||||
@ -2277,8 +2295,8 @@ TEST_F(Dhcp4ParserTest, optionDataInMultipleSubnets) {
|
||||
testOption(*range1.first, 56, foo_expected, sizeof(foo_expected));
|
||||
|
||||
// Test another subnet in the same way.
|
||||
Subnet4Ptr subnet2 = CfgMgr::instance().getSubnet4(IOAddress("192.0.3.102"),
|
||||
classify_);
|
||||
Subnet4Ptr subnet2 = CfgMgr::instance().getStagingCfg()->
|
||||
getCfgSubnets4()->get(IOAddress("192.0.3.102"));
|
||||
ASSERT_TRUE(subnet2);
|
||||
OptionContainerPtr options2 = subnet2->getCfgOption()->getAll("dhcp4");
|
||||
ASSERT_EQ(1, options2->size());
|
||||
@ -2355,8 +2373,8 @@ TEST_F(Dhcp4ParserTest, optionDataLowerCase) {
|
||||
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
|
||||
checkResult(x, 0);
|
||||
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.5"),
|
||||
classify_);
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
|
||||
getCfgSubnets4()->get(IOAddress("192.0.2.5"));
|
||||
ASSERT_TRUE(subnet);
|
||||
OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp4");
|
||||
ASSERT_EQ(1, options->size());
|
||||
@ -2398,8 +2416,8 @@ TEST_F(Dhcp4ParserTest, stdOptionData) {
|
||||
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
|
||||
checkResult(x, 0);
|
||||
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.5"),
|
||||
classify_);
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
|
||||
getCfgSubnets4()->get(IOAddress("192.0.2.5"));
|
||||
ASSERT_TRUE(subnet);
|
||||
OptionContainerPtr options =
|
||||
subnet->getCfgOption()->getAll("dhcp4");
|
||||
@ -2606,8 +2624,8 @@ TEST_F(Dhcp4ParserTest, stdOptionDataEncapsulate) {
|
||||
checkResult(status, 0);
|
||||
|
||||
// Get the subnet.
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.5"),
|
||||
classify_);
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
|
||||
getCfgSubnets4()->get(IOAddress("192.0.2.5"));
|
||||
ASSERT_TRUE(subnet);
|
||||
|
||||
// We should have one option available.
|
||||
@ -2690,8 +2708,8 @@ TEST_F(Dhcp4ParserTest, vendorOptionsHex) {
|
||||
checkResult(status, 0);
|
||||
|
||||
// Options should be now available for the subnet.
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.5"),
|
||||
classify_);
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
|
||||
getCfgSubnets4()->get(IOAddress("192.0.2.5"));
|
||||
ASSERT_TRUE(subnet);
|
||||
|
||||
// Try to get the option from the vendor space 4491
|
||||
@ -2751,8 +2769,8 @@ TEST_F(Dhcp4ParserTest, vendorOptionsCsv) {
|
||||
checkResult(status, 0);
|
||||
|
||||
// Options should be now available for the subnet.
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.5"),
|
||||
classify_);
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
|
||||
getCfgSubnets4()->get(IOAddress("192.0.2.5"));
|
||||
ASSERT_TRUE(subnet);
|
||||
|
||||
// Try to get the option from the vendor space 4491
|
||||
@ -3127,8 +3145,8 @@ TEST_F(Dhcp4ParserTest, subnetRelayInfo) {
|
||||
// returned value should be 0 (configuration success)
|
||||
checkResult(status, 0);
|
||||
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.200"),
|
||||
classify_);
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->
|
||||
getCfgSubnets4()->get(IOAddress("192.0.2.200"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ("192.0.2.123", subnet->getRelayInfo().addr_.toText());
|
||||
}
|
||||
@ -3166,7 +3184,8 @@ TEST_F(Dhcp4ParserTest, classifySubnets) {
|
||||
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
|
||||
checkResult(x, 0);
|
||||
|
||||
const Subnet4Collection* subnets = CfgMgr::instance().getSubnets4();
|
||||
const Subnet4Collection* subnets =
|
||||
CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->getAll();
|
||||
ASSERT_TRUE(subnets);
|
||||
ASSERT_EQ(4, subnets->size()); // We expect 4 subnets
|
||||
|
||||
|
@ -127,6 +127,8 @@ Dhcp4SrvD2Test::configure(const std::string& config, bool exp_result) {
|
||||
ElementPtr json = Element::fromJSON(config);
|
||||
ConstElementPtr status;
|
||||
|
||||
CfgMgr::instance().clear();
|
||||
|
||||
// Configure the server and make sure the config is accepted
|
||||
EXPECT_NO_THROW(status = configureDhcp4Server(srv_, json));
|
||||
ASSERT_TRUE(status);
|
||||
|
@ -553,8 +553,9 @@ TEST_F(Dhcpv4SrvTest, DiscoverNoTimers) {
|
||||
pool_ = Pool4Ptr(new Pool4(IOAddress("192.0.2.100"),
|
||||
IOAddress("192.0.2.110")));
|
||||
subnet_->addPool(pool_);
|
||||
CfgMgr::instance().deleteSubnets4();
|
||||
CfgMgr::instance().addSubnet4(subnet_);
|
||||
CfgMgr::instance().clear();
|
||||
CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->add(subnet_);
|
||||
CfgMgr::instance().commit();
|
||||
|
||||
// Pass it to the server and get an offer
|
||||
Pkt4Ptr offer = srv->processDiscover(dis);
|
||||
@ -741,8 +742,9 @@ TEST_F(Dhcpv4SrvTest, RequestNoTimers) {
|
||||
pool_ = Pool4Ptr(new Pool4(IOAddress("192.0.2.100"),
|
||||
IOAddress("192.0.2.110")));
|
||||
subnet_->addPool(pool_);
|
||||
CfgMgr::instance().deleteSubnets4();
|
||||
CfgMgr::instance().addSubnet4(subnet_);
|
||||
CfgMgr::instance().clear();
|
||||
CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->add(subnet_);
|
||||
CfgMgr::instance().commit();
|
||||
|
||||
// Pass it to the server and get an ACK.
|
||||
Pkt4Ptr ack = srv->processRequest(req);
|
||||
@ -1207,6 +1209,8 @@ TEST_F(Dhcpv4SrvTest, vendorOptionsDocsis) {
|
||||
comment_ = config::parseAnswer(rcode_, status);
|
||||
ASSERT_EQ(0, rcode_);
|
||||
|
||||
CfgMgr::instance().commit();
|
||||
|
||||
// Let's create a relayed DISCOVER. This particular relayed DISCOVER has
|
||||
// added option 82 (relay agent info) with 3 suboptions. The server
|
||||
// is supposed to echo it back in its response.
|
||||
@ -1448,6 +1452,8 @@ TEST_F(Dhcpv4SrvTest, nextServerOverride) {
|
||||
|
||||
EXPECT_NO_THROW(status = configureDhcp4Server(srv, json));
|
||||
|
||||
CfgMgr::instance().commit();
|
||||
|
||||
// check if returned status is OK
|
||||
ASSERT_TRUE(status);
|
||||
comment_ = config::parseAnswer(rcode_, status);
|
||||
@ -1492,6 +1498,8 @@ TEST_F(Dhcpv4SrvTest, nextServerGlobal) {
|
||||
|
||||
EXPECT_NO_THROW(status = configureDhcp4Server(srv, json));
|
||||
|
||||
CfgMgr::instance().commit();
|
||||
|
||||
// check if returned status is OK
|
||||
ASSERT_TRUE(status);
|
||||
comment_ = config::parseAnswer(rcode_, status);
|
||||
@ -2513,7 +2521,8 @@ TEST_F(HooksDhcpv4SrvTest, subnet4SelectSimple) {
|
||||
// Check that pkt4 argument passing was successful and returned proper value
|
||||
EXPECT_TRUE(callback_pkt4_.get() == sol.get());
|
||||
|
||||
const Subnet4Collection* exp_subnets = CfgMgr::instance().getSubnets4();
|
||||
const Subnet4Collection* exp_subnets =
|
||||
CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getAll();
|
||||
|
||||
// The server is supposed to pick the first subnet, because of matching
|
||||
// interface. Check that the value is reported properly.
|
||||
@ -2562,6 +2571,8 @@ TEST_F(HooksDhcpv4SrvTest, subnet4SelectChange) {
|
||||
comment_ = config::parseAnswer(rcode_, status);
|
||||
ASSERT_EQ(0, rcode_);
|
||||
|
||||
CfgMgr::instance().commit();
|
||||
|
||||
// Prepare discover packet. Server should select first subnet for it
|
||||
Pkt4Ptr sol = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234));
|
||||
sol->setRemoteAddr(IOAddress("192.0.2.1"));
|
||||
@ -2580,7 +2591,8 @@ TEST_F(HooksDhcpv4SrvTest, subnet4SelectChange) {
|
||||
EXPECT_NE("0.0.0.0", addr.toText());
|
||||
|
||||
// Get all subnets and use second subnet for verification
|
||||
const Subnet4Collection* subnets = CfgMgr::instance().getSubnets4();
|
||||
const Subnet4Collection* subnets =
|
||||
CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getAll();
|
||||
ASSERT_EQ(2, subnets->size());
|
||||
|
||||
// Advertised address must belong to the second pool (in subnet's range,
|
||||
@ -2979,6 +2991,8 @@ TEST_F(Dhcpv4SrvTest, vendorOptionsORO) {
|
||||
comment_ = isc::config::parseAnswer(rcode_, x);
|
||||
ASSERT_EQ(0, rcode_);
|
||||
|
||||
CfgMgr::instance().commit();
|
||||
|
||||
boost::shared_ptr<Pkt4> dis(new Pkt4(DHCPDISCOVER, 1234));
|
||||
// Set the giaddr and hops to non-zero address as if it was relayed.
|
||||
dis->setGiaddr(IOAddress("192.0.2.1"));
|
||||
@ -3195,7 +3209,8 @@ TEST_F(Dhcpv4SrvTest, relayOverride) {
|
||||
ASSERT_NO_THROW(configure(config));
|
||||
|
||||
// Let's get the subnet configuration objects
|
||||
const Subnet4Collection* subnets = CfgMgr::instance().getSubnets4();
|
||||
const Subnet4Collection* subnets =
|
||||
CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getAll();
|
||||
ASSERT_EQ(2, subnets->size());
|
||||
|
||||
// Let's get them for easy reference
|
||||
@ -3270,7 +3285,8 @@ TEST_F(Dhcpv4SrvTest, relayOverrideAndClientClass) {
|
||||
// Use this config to set up the server
|
||||
ASSERT_NO_THROW(configure(config));
|
||||
|
||||
const Subnet4Collection* subnets = CfgMgr::instance().getSubnets4();
|
||||
const Subnet4Collection* subnets =
|
||||
CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getAll();
|
||||
ASSERT_EQ(2, subnets->size());
|
||||
|
||||
// Let's get them for easy reference
|
||||
|
@ -45,14 +45,14 @@ Dhcpv4SrvTest::Dhcpv4SrvTest()
|
||||
pool_ = Pool4Ptr(new Pool4(IOAddress("192.0.2.100"), IOAddress("192.0.2.110")));
|
||||
subnet_->addPool(pool_);
|
||||
|
||||
CfgMgr::instance().clear();
|
||||
CfgMgr::instance().deleteSubnets4();
|
||||
CfgMgr::instance().addSubnet4(subnet_);
|
||||
|
||||
// Add Router option.
|
||||
Option4AddrLstPtr opt_routers(new Option4AddrLst(DHO_ROUTERS));
|
||||
opt_routers->setAddress(IOAddress("192.0.2.2"));
|
||||
subnet_->getCfgOption()->add(opt_routers, false, "dhcp4");
|
||||
|
||||
CfgMgr::instance().clear();
|
||||
CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->add(subnet_);
|
||||
CfgMgr::instance().commit();
|
||||
}
|
||||
|
||||
Dhcpv4SrvTest::~Dhcpv4SrvTest() {
|
||||
@ -389,7 +389,7 @@ Dhcpv4SrvTest::createPacketFromBuffer(const Pkt4Ptr& src_pkt,
|
||||
|
||||
void Dhcpv4SrvTest::TearDown() {
|
||||
|
||||
CfgMgr::instance().deleteSubnets4();
|
||||
CfgMgr::instance().clear();
|
||||
|
||||
// Close all open sockets.
|
||||
IfaceMgr::instance().closeSockets();
|
||||
@ -578,6 +578,8 @@ Dhcpv4SrvTest::configure(const std::string& config, NakedDhcpv4Srv& srv) {
|
||||
int rcode;
|
||||
ConstElementPtr comment = config::parseAnswer(rcode, status);
|
||||
ASSERT_EQ(0, rcode);
|
||||
|
||||
CfgMgr::instance().commit();
|
||||
}
|
||||
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <dhcp/classify.h>
|
||||
#include <dhcp/tests/iface_mgr_test_config.h>
|
||||
#include <dhcpsrv/cfgmgr.h>
|
||||
#include <dhcpsrv/cfg_subnets4.h>
|
||||
#include <dhcpsrv/lease_mgr_factory.h>
|
||||
#include <dhcpsrv/subnet.h>
|
||||
#include <dhcp4/json_config_parser.h>
|
||||
@ -225,8 +226,8 @@ TEST_F(DirectClientTest, twoSubnets) {
|
||||
// Client should get an Offer (not a NAK).
|
||||
ASSERT_EQ(DHCPOFFER, response->getType());
|
||||
// Check that the offered address belongs to the suitable subnet.
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(response->getYiaddr(),
|
||||
classify_);
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getCurrentCfg()->
|
||||
getCfgSubnets4()->get(response->getYiaddr());
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ("10.0.0.0", subnet->get().first.toText());
|
||||
|
||||
@ -237,7 +238,8 @@ TEST_F(DirectClientTest, twoSubnets) {
|
||||
// Client should get an Ack (not a NAK).
|
||||
ASSERT_EQ(DHCPACK, response->getType());
|
||||
// Check that the offered address belongs to the suitable subnet.
|
||||
subnet = CfgMgr::instance().getSubnet4(response->getYiaddr(), classify_);
|
||||
subnet = CfgMgr::instance().getCurrentCfg()->
|
||||
getCfgSubnets4()->get(response->getYiaddr());
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ("192.0.2.0", subnet->get().first.toText());
|
||||
|
||||
@ -283,8 +285,8 @@ TEST_F(DirectClientTest, oneSubnet) {
|
||||
// an Offer message.
|
||||
ASSERT_EQ(DHCPOFFER, response->getType());
|
||||
// Check that the offered address belongs to the suitable subnet.
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(response->getYiaddr(),
|
||||
classify_);
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getCurrentCfg()->
|
||||
getCfgSubnets4()->get(response->getYiaddr());
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ("10.0.0.0", subnet->get().first.toText());
|
||||
|
||||
@ -302,8 +304,8 @@ TEST_F(DirectClientTest, renew) {
|
||||
ASSERT_NO_FATAL_FAILURE(configureSubnet("10.0.0.0"));
|
||||
// Make sure that the subnet has been really added. Also, the subnet
|
||||
// will be needed to create a lease for a client.
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("10.0.0.10"),
|
||||
classify_);
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getCurrentCfg()->
|
||||
getCfgSubnets4()->get(IOAddress("10.0.0.10"));
|
||||
// Create a lease for a client that we will later renewed. By explicitly
|
||||
// creating a lease we will get to know the lease parameters, such as
|
||||
// leased address etc.
|
||||
@ -339,7 +341,8 @@ TEST_F(DirectClientTest, renew) {
|
||||
|
||||
ASSERT_EQ(DHCPACK, response->getType());
|
||||
// Check that the offered address belongs to the suitable subnet.
|
||||
subnet = CfgMgr::instance().getSubnet4(response->getYiaddr(), classify_);
|
||||
subnet = CfgMgr::instance().getCurrentCfg()->
|
||||
getCfgSubnets4()->get(response->getYiaddr());
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ("10.0.0.0", subnet->get().first.toText());
|
||||
|
||||
@ -360,8 +363,8 @@ TEST_F(DirectClientTest, rebind) {
|
||||
ASSERT_NO_FATAL_FAILURE(configureSubnet("10.0.0.0"));
|
||||
// Make sure that the subnet has been really added. Also, the subnet
|
||||
// will be needed to create a lease for a client.
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("10.0.0.10"),
|
||||
classify_);
|
||||
Subnet4Ptr subnet = CfgMgr::instance().getCurrentCfg()->
|
||||
getCfgSubnets4()->get(IOAddress("10.0.0.10"));
|
||||
// Create a lease, which will be later renewed. By explicitly creating a
|
||||
// lease we will know the lease parameters, such as leased address etc.
|
||||
const uint8_t hwaddr[] = { 1, 2, 3, 4, 5, 6 };
|
||||
@ -373,9 +376,9 @@ TEST_F(DirectClientTest, rebind) {
|
||||
LeaseMgrFactory::instance().addLease(lease);
|
||||
|
||||
// Broadcast Request through an interface for which there is no subnet
|
||||
// configured. This messag should be discarded by the server.
|
||||
// configured. This message should be discarded by the server.
|
||||
Pkt4Ptr req = Pkt4Ptr(new Pkt4(DHCPREQUEST, 1234));
|
||||
req->setCiaddr(IOAddress("10.0.0.10"));
|
||||
req->setCiaddr(IOAddress("10.0.0.10"));
|
||||
req = createClientMessage(req, "eth1");
|
||||
req->setRemoteAddr(req->getCiaddr());
|
||||
|
||||
@ -404,7 +407,8 @@ TEST_F(DirectClientTest, rebind) {
|
||||
// (transmitted over eth0).
|
||||
EXPECT_EQ(5678, response->getTransid());
|
||||
// Check that the offered address belongs to the suitable subnet.
|
||||
subnet = CfgMgr::instance().getSubnet4(response->getYiaddr(), classify_);
|
||||
subnet = CfgMgr::instance().getCurrentCfg()->
|
||||
getCfgSubnets4()->get(response->getYiaddr());
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ("10.0.0.0", subnet->get().first.toText());
|
||||
|
||||
|
@ -118,7 +118,8 @@ TEST_F(JSONFileBackendTest, jsonFile) {
|
||||
EXPECT_NO_THROW(srv->init(TEST_FILE));
|
||||
|
||||
// Now check if the configuration has been applied correctly.
|
||||
const Subnet4Collection* subnets = CfgMgr::instance().getSubnets4();
|
||||
const Subnet4Collection* subnets =
|
||||
CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getAll();
|
||||
ASSERT_TRUE(subnets);
|
||||
ASSERT_EQ(3, subnets->size()); // We expect 3 subnets.
|
||||
|
||||
@ -187,7 +188,8 @@ TEST_F(JSONFileBackendTest, comments) {
|
||||
EXPECT_NO_THROW(srv->init(TEST_FILE));
|
||||
|
||||
// Now check if the configuration has been applied correctly.
|
||||
const Subnet4Collection* subnets = CfgMgr::instance().getSubnets4();
|
||||
const Subnet4Collection* subnets =
|
||||
CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getAll();
|
||||
ASSERT_TRUE(subnets);
|
||||
ASSERT_EQ(1, subnets->size());
|
||||
|
||||
|
@ -26,6 +26,12 @@ const IOAddress& ZERO_ADDRESS() {
|
||||
return (address);
|
||||
}
|
||||
|
||||
/// @brief Returns @c IOAddress object holding broadcast address.
|
||||
const IOAddress& BCAST_ADDRESS() {
|
||||
static IOAddress address("255.255.255.255");
|
||||
return (address);
|
||||
}
|
||||
|
||||
} // end of anonymous namespace
|
||||
|
||||
namespace isc {
|
||||
@ -57,7 +63,7 @@ CfgSubnets4::get(const Selector& selector) const {
|
||||
// address will not match with any of the relay addresses accross all
|
||||
// subnets, but we need to verify that for all subnets before we can try
|
||||
// to use the giaddr to match with the subnet prefix.
|
||||
if (selector.giaddr_.isSpecified() && selector.giaddr_ != ZERO_ADDRESS()) {
|
||||
if (selector.giaddr_ != ZERO_ADDRESS()) {
|
||||
for (Subnet4Collection::const_iterator subnet = subnets_.begin();
|
||||
subnet != subnets_.end(); ++subnet) {
|
||||
// Eliminate those subnets that do not meet client class criteria.
|
||||
@ -79,36 +85,31 @@ CfgSubnets4::get(const Selector& selector) const {
|
||||
|
||||
IOAddress address = ZERO_ADDRESS();
|
||||
// If there is a giaddr, use it for subnet selection.
|
||||
if (selector.giaddr_.isSpecified() &&
|
||||
(selector.giaddr_ != ZERO_ADDRESS())) {
|
||||
if (selector.giaddr_ != ZERO_ADDRESS()) {
|
||||
address = selector.giaddr_;
|
||||
|
||||
// If it is a Renew or Rebind, use the ciaddr.
|
||||
} else if (selector.ciaddr_.isSpecified() &&
|
||||
selector.ciaddr_ != ZERO_ADDRESS()) {
|
||||
} else if ((selector.ciaddr_ != ZERO_ADDRESS()) &&
|
||||
(selector.local_address_ != BCAST_ADDRESS())) {
|
||||
address = selector.ciaddr_;
|
||||
|
||||
// If ciaddr is not specified, use the source address.
|
||||
} else if (selector.remote_address_.isSpecified() &&
|
||||
selector.remote_address_ != ZERO_ADDRESS()) {
|
||||
} else if ((selector.remote_address_ != ZERO_ADDRESS()) &&
|
||||
(selector.local_address_ != BCAST_ADDRESS())) {
|
||||
address = selector.remote_address_;
|
||||
|
||||
// If local interface name is known, use the local address on this
|
||||
// interface.
|
||||
} else if (selector.iface_name_.isSpecified()) {
|
||||
} else if (!selector.iface_name_.empty()) {
|
||||
Iface* iface = IfaceMgr::instance().getIface(selector.iface_name_);
|
||||
// This should never happen in the real life. Hence we throw an
|
||||
// exception.
|
||||
if (iface == NULL) {
|
||||
isc_throw(isc::BadValue, "interface " << selector.iface_name_.get()
|
||||
isc_throw(isc::BadValue, "interface " << selector.iface_name_
|
||||
<< " doesn't exist and therefore it is impossible"
|
||||
" to find a suitable subnet for its IPv4 address");
|
||||
}
|
||||
iface->getAddress4(address);
|
||||
|
||||
} else {
|
||||
isc_throw(isc::BadValue, "subnet selector structure does not contain"
|
||||
" sufficient information");
|
||||
}
|
||||
|
||||
// Unable to find a suitable address to use for subnet selection.
|
||||
@ -117,11 +118,18 @@ CfgSubnets4::get(const Selector& selector) const {
|
||||
}
|
||||
|
||||
// We have identified an address in the client's packet that can be
|
||||
// used for subnet selection. Match this packet with the subnets.
|
||||
// used for subnet selection. Match this packet with the subnets.
|
||||
return (get(address, selector.client_classes_));
|
||||
}
|
||||
|
||||
Subnet4Ptr
|
||||
CfgSubnets4::get(const IOAddress& address,
|
||||
const ClientClasses& client_classes) const {
|
||||
for (Subnet4Collection::const_iterator subnet = subnets_.begin();
|
||||
subnet != subnets_.end(); ++subnet) {
|
||||
|
||||
// Eliminate those subnets that do not meet client class criteria.
|
||||
if (!(*subnet)->clientSupported(selector.client_classes_)) {
|
||||
if (!(*subnet)->clientSupported(client_classes)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -48,23 +48,20 @@ public:
|
||||
/// @brief Subnet selector used in @c CfgSubnets4::getSubnet4.
|
||||
///
|
||||
/// This structure holds various parameters extracted from a packet sent
|
||||
/// by a DHCP client used to select the subnet for the client. Note that
|
||||
/// data members are optional which means that they may be left unspecified
|
||||
/// by the caller, if the caller doesn't have access to the relevant
|
||||
/// information.
|
||||
/// by a DHCP client used to select the subnet for the client.
|
||||
struct Selector {
|
||||
/// @brief ciaddr from the client's message.
|
||||
util::OptionalValue<asiolink::IOAddress> ciaddr_;
|
||||
asiolink::IOAddress ciaddr_;
|
||||
/// @brief giaddr from the client's message.
|
||||
util::OptionalValue<asiolink::IOAddress> giaddr_;
|
||||
asiolink::IOAddress giaddr_;
|
||||
/// @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.
|
||||
util::OptionalValue<ClientClasses> client_classes_;
|
||||
ClientClasses client_classes_;
|
||||
/// @brief Name of the interface on which the message was received.
|
||||
util::OptionalValue<std::string> iface_name_;
|
||||
std::string iface_name_;
|
||||
|
||||
/// @brief Default constructor.
|
||||
///
|
||||
@ -129,6 +126,20 @@ public:
|
||||
/// or they are insufficient to select a subnet.
|
||||
Subnet4Ptr get(const Selector& selector) const;
|
||||
|
||||
/// @brief Returns pointer to a subnet if provided address is in its range.
|
||||
///
|
||||
/// This method returns a pointer to the subnet if the address passed in
|
||||
/// parameter is in range with this subnet. This is mainly used for unit
|
||||
/// testing. This method is also called by the @c get(Selector).
|
||||
///
|
||||
/// @param address Address for which the subnet is searched.
|
||||
/// @param client_classes Optional parameter specifying the classes that
|
||||
/// the client belongs to.
|
||||
///
|
||||
/// @return Pointer to the selected subnet or NULL if no subnet found.
|
||||
Subnet4Ptr get(const asiolink::IOAddress& address,
|
||||
const ClientClasses& client_classes = ClientClasses()) const;
|
||||
|
||||
private:
|
||||
|
||||
/// @brief Checks that the IPv4 subnet with the given id already exists.
|
||||
|
@ -164,78 +164,6 @@ void CfgMgr::addSubnet6(const Subnet6Ptr& subnet) {
|
||||
subnets6_.push_back(subnet);
|
||||
}
|
||||
|
||||
Subnet4Ptr
|
||||
CfgMgr::getSubnet4(const isc::asiolink::IOAddress& hint,
|
||||
const isc::dhcp::ClientClasses& classes,
|
||||
bool relay) const {
|
||||
// Iterate over existing subnets to find a suitable one for the
|
||||
// given address.
|
||||
for (Subnet4Collection::const_iterator subnet = subnets4_.begin();
|
||||
subnet != subnets4_.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_SUBNET4_RELAY)
|
||||
.arg((*subnet)->toText()).arg(hint.toText());
|
||||
return (*subnet);
|
||||
}
|
||||
|
||||
// Let's check if the client belongs to the given subnet
|
||||
if ((*subnet)->inRange(hint)) {
|
||||
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE,
|
||||
DHCPSRV_CFGMGR_SUBNET4)
|
||||
.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_SUBNET4)
|
||||
.arg(hint.toText());
|
||||
return (Subnet4Ptr());
|
||||
}
|
||||
|
||||
Subnet4Ptr
|
||||
CfgMgr::getSubnet4(const std::string& iface_name,
|
||||
const isc::dhcp::ClientClasses& classes) const {
|
||||
Iface* iface = IfaceMgr::instance().getIface(iface_name);
|
||||
// This should never happen in the real life. Hence we throw an exception.
|
||||
if (iface == NULL) {
|
||||
isc_throw(isc::BadValue, "interface " << iface_name <<
|
||||
" doesn't exist and therefore it is impossible"
|
||||
" to find a suitable subnet for its IPv4 address");
|
||||
}
|
||||
IOAddress addr("0.0.0.0");
|
||||
// If IPv4 address assigned to the interface exists, find a suitable
|
||||
// subnet for it, else return NULL pointer to indicate that no subnet
|
||||
// could be found.
|
||||
return (iface->getAddress4(addr) ? getSubnet4(addr, classes) : Subnet4Ptr());
|
||||
}
|
||||
|
||||
void CfgMgr::addSubnet4(const Subnet4Ptr& subnet) {
|
||||
/// @todo: Check that this new subnet does not cross boundaries of any
|
||||
/// other already defined subnet.
|
||||
if (isDuplicate(*subnet)) {
|
||||
isc_throw(isc::dhcp::DuplicateSubnetID, "ID of the new IPv4 subnet '"
|
||||
<< subnet->getID() << "' is already in use");
|
||||
}
|
||||
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE, DHCPSRV_CFGMGR_ADD_SUBNET4)
|
||||
.arg(subnet->toText());
|
||||
subnets4_.push_back(subnet);
|
||||
}
|
||||
|
||||
void CfgMgr::deleteSubnets4() {
|
||||
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE, DHCPSRV_CFGMGR_DELETE_SUBNET4);
|
||||
subnets4_.clear();
|
||||
}
|
||||
|
||||
void CfgMgr::deleteSubnets6() {
|
||||
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE, DHCPSRV_CFGMGR_DELETE_SUBNET6);
|
||||
subnets6_.clear();
|
||||
@ -246,17 +174,6 @@ std::string CfgMgr::getDataDir() {
|
||||
return (datadir_);
|
||||
}
|
||||
|
||||
bool
|
||||
CfgMgr::isDuplicate(const Subnet4& subnet) const {
|
||||
for (Subnet4Collection::const_iterator subnet_it = subnets4_.begin();
|
||||
subnet_it != subnets4_.end(); ++subnet_it) {
|
||||
if ((*subnet_it)->getID() == subnet.getID()) {
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
bool
|
||||
CfgMgr::isDuplicate(const Subnet6& subnet) const {
|
||||
for (Subnet6Collection::const_iterator subnet_it = subnets6_.begin();
|
||||
|
@ -215,16 +215,6 @@ public:
|
||||
/// completely new?
|
||||
void deleteSubnets6();
|
||||
|
||||
/// @brief Returns pointer to the collection of all IPv4 subnets.
|
||||
///
|
||||
/// This is used in a hook (subnet4_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 Subnet4 collection
|
||||
const Subnet4Collection* getSubnets4() const {
|
||||
return (&subnets4_);
|
||||
}
|
||||
|
||||
/// @brief returns const reference to all subnets6
|
||||
///
|
||||
/// This is used in a hook (subnet6_select), where the hook is able
|
||||
@ -235,63 +225,6 @@ public:
|
||||
return (&subnets6_);
|
||||
}
|
||||
|
||||
/// @brief get IPv4 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.
|
||||
///
|
||||
/// If relay is true then relay info overrides (i.e. value the sysadmin
|
||||
/// can configure in Dhcp4/subnet4[X]/relay/ip-address) can be used.
|
||||
/// That is true only for relays. Those overrides must not be used
|
||||
/// for client address or for client hints. They are for giaddr 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
|
||||
Subnet4Ptr getSubnet4(const isc::asiolink::IOAddress& hint,
|
||||
const isc::dhcp::ClientClasses& classes,
|
||||
bool relay = false) const;
|
||||
|
||||
/// @brief Returns a subnet for the specified local interface.
|
||||
///
|
||||
/// This function checks that the IP address assigned to the specified
|
||||
/// interface belongs to any IPv4 subnet configured, and returns this
|
||||
/// subnet.
|
||||
///
|
||||
/// @todo Implement classes support here.
|
||||
///
|
||||
/// @param iface Short name of the interface which is being checked.
|
||||
/// @param classes classes the client belongs to
|
||||
///
|
||||
/// @return Pointer to the subnet matching interface specified or NULL
|
||||
/// pointer if IPv4 address on the interface doesn't match any subnet.
|
||||
Subnet4Ptr getSubnet4(const std::string& iface,
|
||||
const isc::dhcp::ClientClasses& classes) const;
|
||||
|
||||
/// @brief adds a subnet4
|
||||
void addSubnet4(const Subnet4Ptr& subnet);
|
||||
|
||||
/// @brief removes all IPv4 subnets
|
||||
///
|
||||
/// This method removes all existing IPv4 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
|
||||
/// 192.0.2.0/23 and 192.0.2.0/24 the same subnet or is it something
|
||||
/// completely new?
|
||||
void deleteSubnets4();
|
||||
|
||||
|
||||
/// @brief returns path do the data directory
|
||||
///
|
||||
/// This method returns a path to writeable directory that DHCP servers
|
||||
@ -484,14 +417,6 @@ protected:
|
||||
/// a match is found.
|
||||
Subnet6Collection subnets6_;
|
||||
|
||||
/// @brief A container for IPv4 subnets.
|
||||
///
|
||||
/// That is a simple vector of pointers. It does not make much sense to
|
||||
/// optimize access time (e.g. using a map), because typical search
|
||||
/// pattern will use calling inRange() method on each subnet until
|
||||
/// a match is found.
|
||||
Subnet4Collection subnets4_;
|
||||
|
||||
private:
|
||||
|
||||
/// @brief Checks if current configuration is created and creates it if needed.
|
||||
@ -501,13 +426,6 @@ private:
|
||||
/// default current configuration.
|
||||
void ensureCurrentAllocated();
|
||||
|
||||
/// @brief Checks that the IPv4 subnet with the given id already exists.
|
||||
///
|
||||
/// @param subnet Subnet for which this function will check if the other
|
||||
/// subnet with equal id already exists.
|
||||
/// @return true if the duplicate subnet exists.
|
||||
bool isDuplicate(const Subnet4& subnet) const;
|
||||
|
||||
/// @brief Checks that the IPv6 subnet with the given id already exists.
|
||||
///
|
||||
/// @param subnet Subnet for which this function will check if the other
|
||||
|
@ -83,10 +83,6 @@ of active interfaces. This doesn't prevent the server from listening to
|
||||
the DHCP traffic through open sockets, but will rather be used by Interface
|
||||
Manager to select active interfaces when sockets are re-opened.
|
||||
|
||||
% DHCPSRV_CFGMGR_DELETE_SUBNET4 deleting all IPv4 subnets
|
||||
A debug message noting that the DHCP configuration manager has deleted all IPv4
|
||||
subnets in its database.
|
||||
|
||||
% DHCPSRV_CFGMGR_DELETE_SUBNET6 deleting all IPv6 subnets
|
||||
A debug message noting that the DHCP configuration manager has deleted all IPv6
|
||||
subnets in its database.
|
||||
|
@ -39,7 +39,7 @@ SrvConfig::getConfigSummary(const uint32_t selection) const {
|
||||
std::ostringstream s;
|
||||
size_t subnets_num;
|
||||
if ((selection & CFGSEL_SUBNET4) == CFGSEL_SUBNET4) {
|
||||
subnets_num = CfgMgr::instance().getSubnets4()->size();
|
||||
subnets_num = getCfgSubnets4()->getAll()->size();
|
||||
if (subnets_num > 0) {
|
||||
s << "added IPv4 subnets: " << subnets_num;
|
||||
} else {
|
||||
|
@ -422,7 +422,8 @@ public:
|
||||
pool_ = Pool4Ptr(new Pool4(IOAddress("192.0.2.100"),
|
||||
IOAddress("192.0.2.109")));
|
||||
subnet_->addPool(pool_);
|
||||
cfg_mgr.addSubnet4(subnet_);
|
||||
cfg_mgr.getStagingCfg()->getCfgSubnets4()->add(subnet_);
|
||||
cfg_mgr.commit();
|
||||
|
||||
factory_.create("type=memfile universe=4 persist=false");
|
||||
}
|
||||
@ -1319,13 +1320,15 @@ TEST_F(AllocEngine4Test, smallPool4) {
|
||||
|
||||
IOAddress addr("192.0.2.17");
|
||||
CfgMgr& cfg_mgr = CfgMgr::instance();
|
||||
cfg_mgr.deleteSubnets4(); // Get rid of the default test configuration
|
||||
|
||||
// Get rid of the default subnet configuration.
|
||||
cfg_mgr.clear();
|
||||
|
||||
// Create configuration similar to other tests, but with a single address pool
|
||||
subnet_ = Subnet4Ptr(new Subnet4(IOAddress("192.0.2.0"), 24, 1, 2, 3));
|
||||
pool_ = Pool4Ptr(new Pool4(addr, addr)); // just a single address
|
||||
subnet_->addPool(pool_);
|
||||
cfg_mgr.addSubnet4(subnet_);
|
||||
cfg_mgr.getStagingCfg()->getCfgSubnets4()->add(subnet_);
|
||||
|
||||
Lease4Ptr lease = engine->allocateLease4(subnet_, clientid_, hwaddr_,
|
||||
IOAddress("0.0.0.0"),
|
||||
@ -1362,13 +1365,14 @@ TEST_F(AllocEngine4Test, outOfAddresses4) {
|
||||
|
||||
IOAddress addr("192.0.2.17");
|
||||
CfgMgr& cfg_mgr = CfgMgr::instance();
|
||||
cfg_mgr.deleteSubnets4(); // Get rid of the default test configuration
|
||||
// Get rid of the default test configuration.
|
||||
cfg_mgr.clear();
|
||||
|
||||
// Create configuration similar to other tests, but with a single address pool
|
||||
subnet_ = Subnet4Ptr(new Subnet4(IOAddress("192.0.2.0"), 24, 1, 2, 3));
|
||||
pool_ = Pool4Ptr(new Pool4(addr, addr)); // just a single address
|
||||
subnet_->addPool(pool_);
|
||||
cfg_mgr.addSubnet4(subnet_);
|
||||
cfg_mgr.getStagingCfg()->getCfgSubnets4()->add(subnet_);
|
||||
|
||||
// Just a different hw/client-id for the second client
|
||||
uint8_t hwaddr2[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
|
||||
@ -1401,13 +1405,14 @@ TEST_F(AllocEngine4Test, discoverReuseExpiredLease4) {
|
||||
|
||||
IOAddress addr("192.0.2.15");
|
||||
CfgMgr& cfg_mgr = CfgMgr::instance();
|
||||
cfg_mgr.deleteSubnets4(); // Get rid of the default test configuration
|
||||
// Get rid of the default test configuration.
|
||||
cfg_mgr.clear();
|
||||
|
||||
// Create configuration similar to other tests, but with a single address pool
|
||||
subnet_ = Subnet4Ptr(new Subnet4(IOAddress("192.0.2.0"), 24, 1, 2, 3));
|
||||
pool_ = Pool4Ptr(new Pool4(addr, addr)); // just a single address
|
||||
subnet_->addPool(pool_);
|
||||
cfg_mgr.addSubnet4(subnet_);
|
||||
cfg_mgr.getStagingCfg()->getCfgSubnets4()->add(subnet_);
|
||||
|
||||
// Just a different hw/client-id for the second client
|
||||
uint8_t hwaddr2[] = { 0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe};
|
||||
|
@ -282,7 +282,6 @@ public:
|
||||
|
||||
void clear() {
|
||||
CfgMgr::instance().setVerbose(false);
|
||||
CfgMgr::instance().deleteSubnets4();
|
||||
CfgMgr::instance().deleteSubnets6();
|
||||
CfgMgr::instance().clear();
|
||||
}
|
||||
@ -304,133 +303,6 @@ TEST_F(CfgMgrTest, configuration) {
|
||||
EXPECT_TRUE(configuration->getLoggingInfo().empty());
|
||||
}
|
||||
|
||||
// This test verifies if the configuration manager is able to hold and return
|
||||
// valid subnets.
|
||||
TEST_F(CfgMgrTest, subnet4) {
|
||||
CfgMgr& cfg_mgr = CfgMgr::instance();
|
||||
|
||||
Subnet4Ptr subnet1(new Subnet4(IOAddress("192.0.2.0"), 26, 1, 2, 3));
|
||||
Subnet4Ptr subnet2(new Subnet4(IOAddress("192.0.2.64"), 26, 1, 2, 3));
|
||||
Subnet4Ptr subnet3(new Subnet4(IOAddress("192.0.2.128"), 26, 1, 2, 3));
|
||||
|
||||
// There shouldn't be any subnet configured at this stage
|
||||
EXPECT_FALSE(cfg_mgr.getSubnet4(IOAddress("192.0.2.0"), classify_));
|
||||
|
||||
cfg_mgr.addSubnet4(subnet1);
|
||||
|
||||
// Now we have only one subnet, any request will be served from it
|
||||
EXPECT_EQ(subnet1, cfg_mgr.getSubnet4(IOAddress("192.0.2.63"),
|
||||
classify_));
|
||||
|
||||
// Now we add more subnets and check that both old and new subnets
|
||||
// are accessible.
|
||||
cfg_mgr.addSubnet4(subnet2);
|
||||
cfg_mgr.addSubnet4(subnet3);
|
||||
|
||||
EXPECT_EQ(subnet3, cfg_mgr.getSubnet4(IOAddress("192.0.2.191"), classify_));
|
||||
EXPECT_EQ(subnet1, cfg_mgr.getSubnet4(IOAddress("192.0.2.15"), classify_));
|
||||
EXPECT_EQ(subnet2, cfg_mgr.getSubnet4(IOAddress("192.0.2.85"), classify_));
|
||||
|
||||
// Try to find an address that does not belong to any subnet
|
||||
EXPECT_FALSE(cfg_mgr.getSubnet4(IOAddress("192.0.2.192"), classify_));
|
||||
|
||||
// Check that deletion of the subnets works.
|
||||
cfg_mgr.deleteSubnets4();
|
||||
EXPECT_FALSE(cfg_mgr.getSubnet4(IOAddress("192.0.2.191"), classify_));
|
||||
EXPECT_FALSE(cfg_mgr.getSubnet4(IOAddress("192.0.2.15"), classify_));
|
||||
EXPECT_FALSE(cfg_mgr.getSubnet4(IOAddress("192.0.2.85"), classify_));
|
||||
}
|
||||
|
||||
// This test verifies if the configuration manager is able to hold subnets with
|
||||
// their classifier information and return proper subnets, based on those
|
||||
// classes.
|
||||
TEST_F(CfgMgrTest, classifySubnet4) {
|
||||
CfgMgr& cfg_mgr = CfgMgr::instance();
|
||||
|
||||
// Let's configure 3 subnets
|
||||
Subnet4Ptr subnet1(new Subnet4(IOAddress("192.0.2.0"), 26, 1, 2, 3));
|
||||
Subnet4Ptr subnet2(new Subnet4(IOAddress("192.0.2.64"), 26, 1, 2, 3));
|
||||
Subnet4Ptr subnet3(new Subnet4(IOAddress("192.0.2.128"), 26, 1, 2, 3));
|
||||
|
||||
cfg_mgr.addSubnet4(subnet1);
|
||||
cfg_mgr.addSubnet4(subnet2);
|
||||
cfg_mgr.addSubnet4(subnet3);
|
||||
|
||||
// Let's sanity check that we can use that configuration.
|
||||
EXPECT_EQ(subnet1, cfg_mgr.getSubnet4(IOAddress("192.0.2.5"), classify_));
|
||||
EXPECT_EQ(subnet2, cfg_mgr.getSubnet4(IOAddress("192.0.2.70"), classify_));
|
||||
EXPECT_EQ(subnet3, cfg_mgr.getSubnet4(IOAddress("192.0.2.130"), 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.getSubnet4(IOAddress("192.0.2.5"), classify_));
|
||||
EXPECT_EQ(subnet2, cfg_mgr.getSubnet4(IOAddress("192.0.2.70"), classify_));
|
||||
EXPECT_EQ(subnet3, cfg_mgr.getSubnet4(IOAddress("192.0.2.130"), 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.getSubnet4(IOAddress("192.0.2.5"), classify_));
|
||||
EXPECT_EQ(subnet2, cfg_mgr.getSubnet4(IOAddress("192.0.2.70"), classify_));
|
||||
EXPECT_FALSE(cfg_mgr.getSubnet4(IOAddress("192.0.2.130"), classify_));
|
||||
|
||||
// Now let's check that client with wrong class is not supported
|
||||
classify_.clear();
|
||||
classify_.insert("some_other_class");
|
||||
EXPECT_FALSE(cfg_mgr.getSubnet4(IOAddress("192.0.2.5"), classify_));
|
||||
EXPECT_FALSE(cfg_mgr.getSubnet4(IOAddress("192.0.2.70"), classify_));
|
||||
EXPECT_FALSE(cfg_mgr.getSubnet4(IOAddress("192.0.2.130"), classify_));
|
||||
|
||||
// Finally, let's check that client without any classes is not supported
|
||||
classify_.clear();
|
||||
EXPECT_FALSE(cfg_mgr.getSubnet4(IOAddress("192.0.2.5"), classify_));
|
||||
EXPECT_FALSE(cfg_mgr.getSubnet4(IOAddress("192.0.2.70"), classify_));
|
||||
EXPECT_FALSE(cfg_mgr.getSubnet4(IOAddress("192.0.2.130"), classify_));
|
||||
}
|
||||
|
||||
// This test verifies if the configuration manager is able to hold v4 subnets
|
||||
// with their relay address information and return proper subnets, based on
|
||||
// those addresses.
|
||||
TEST_F(CfgMgrTest, subnet4RelayOverride) {
|
||||
CfgMgr& cfg_mgr = CfgMgr::instance();
|
||||
|
||||
// Let's configure 3 subnets
|
||||
Subnet4Ptr subnet1(new Subnet4(IOAddress("192.0.2.0"), 26, 1, 2, 3));
|
||||
Subnet4Ptr subnet2(new Subnet4(IOAddress("192.0.2.64"), 26, 1, 2, 3));
|
||||
Subnet4Ptr subnet3(new Subnet4(IOAddress("192.0.2.128"), 26, 1, 2, 3));
|
||||
|
||||
cfg_mgr.addSubnet4(subnet1);
|
||||
cfg_mgr.addSubnet4(subnet2);
|
||||
cfg_mgr.addSubnet4(subnet3);
|
||||
|
||||
// Check that without relay-info specified, subnets are not selected
|
||||
EXPECT_FALSE(cfg_mgr.getSubnet4(IOAddress("10.0.0.1"), classify_, true));
|
||||
EXPECT_FALSE(cfg_mgr.getSubnet4(IOAddress("10.0.0.2"), classify_, true));
|
||||
EXPECT_FALSE(cfg_mgr.getSubnet4(IOAddress("10.0.0.3"), classify_, true));
|
||||
|
||||
// Now specify relay info
|
||||
subnet1->setRelayInfo(IOAddress("10.0.0.1"));
|
||||
subnet2->setRelayInfo(IOAddress("10.0.0.2"));
|
||||
subnet3->setRelayInfo(IOAddress("10.0.0.3"));
|
||||
|
||||
// And try again. This time relay-info is there and should match.
|
||||
EXPECT_EQ(subnet1, cfg_mgr.getSubnet4(IOAddress("10.0.0.1"), classify_, true));
|
||||
EXPECT_EQ(subnet2, cfg_mgr.getSubnet4(IOAddress("10.0.0.2"), classify_, true));
|
||||
EXPECT_EQ(subnet3, cfg_mgr.getSubnet4(IOAddress("10.0.0.3"), classify_, true));
|
||||
|
||||
// Finally, check that the relay works only if hint provided is relay address
|
||||
EXPECT_FALSE(cfg_mgr.getSubnet4(IOAddress("10.0.0.1"), classify_, false));
|
||||
EXPECT_FALSE(cfg_mgr.getSubnet4(IOAddress("10.0.0.2"), classify_, false));
|
||||
EXPECT_FALSE(cfg_mgr.getSubnet4(IOAddress("10.0.0.3"), classify_, false));
|
||||
}
|
||||
|
||||
// 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.
|
||||
@ -858,63 +730,6 @@ TEST_F(CfgMgrTest, d2ClientConfig) {
|
||||
EXPECT_NE(*original_config, *updated_config);
|
||||
}
|
||||
|
||||
// This test verfies that CfgMgr correctly determines that the address of the
|
||||
// interface belongs to existing IPv4 subnet.
|
||||
TEST_F(CfgMgrTest, getSubnet4ForInterface) {
|
||||
IfaceMgrTestConfig config(true);
|
||||
|
||||
// Initially, there are no subnets configured, so none of the IPv4
|
||||
// addresses assigned to eth0 and eth1 can match with any subnet.
|
||||
EXPECT_FALSE(CfgMgr::instance().getSubnet4("eth0", classify_));
|
||||
EXPECT_FALSE(CfgMgr::instance().getSubnet4("eth1", classify_));
|
||||
|
||||
// Configure first subnet which address on eth0 corresponds to.
|
||||
Subnet4Ptr subnet1(new Subnet4(IOAddress("10.0.0.1"), 24, 1, 2, 3));
|
||||
CfgMgr::instance().addSubnet4(subnet1);
|
||||
|
||||
// The address on eth0 should match the existing subnet.
|
||||
Subnet4Ptr subnet1_ret;
|
||||
subnet1_ret = CfgMgr::instance().getSubnet4("eth0", classify_);
|
||||
ASSERT_TRUE(subnet1_ret);
|
||||
EXPECT_EQ(subnet1->get().first, subnet1_ret->get().first);
|
||||
// There should still be no match for eth1.
|
||||
EXPECT_FALSE(CfgMgr::instance().getSubnet4("eth1", classify_));
|
||||
|
||||
// Configure a second subnet.
|
||||
Subnet4Ptr subnet2(new Subnet4(IOAddress("192.0.2.1"), 24, 1, 2, 3));
|
||||
CfgMgr::instance().addSubnet4(subnet2);
|
||||
|
||||
// There should be match between eth0 and subnet1 and between eth1 and
|
||||
// subnet 2.
|
||||
subnet1_ret = CfgMgr::instance().getSubnet4("eth0", classify_);
|
||||
ASSERT_TRUE(subnet1_ret);
|
||||
EXPECT_EQ(subnet1->get().first, subnet1_ret->get().first);
|
||||
Subnet4Ptr subnet2_ret = CfgMgr::instance().getSubnet4("eth1", classify_);
|
||||
ASSERT_TRUE(subnet2_ret);
|
||||
EXPECT_EQ(subnet2->get().first, subnet2_ret->get().first);
|
||||
|
||||
// This function throws an exception if the name of the interface is wrong.
|
||||
EXPECT_THROW(CfgMgr::instance().getSubnet4("bogus-interface", classify_),
|
||||
isc::BadValue);
|
||||
|
||||
}
|
||||
|
||||
// Checks that detection of duplicated subnet IDs works as expected. It should
|
||||
// not be possible to add two IPv4 subnets holding the same ID to the config
|
||||
// manager.
|
||||
TEST_F(CfgMgrTest, subnet4Duplication) {
|
||||
CfgMgr& cfg_mgr = CfgMgr::instance();
|
||||
|
||||
Subnet4Ptr subnet1(new Subnet4(IOAddress("192.0.2.0"), 26, 1, 2, 3, 123));
|
||||
Subnet4Ptr subnet2(new Subnet4(IOAddress("192.0.2.64"), 26, 1, 2, 3, 124));
|
||||
Subnet4Ptr subnet3(new Subnet4(IOAddress("192.0.2.128"), 26, 1, 2, 3, 123));
|
||||
|
||||
ASSERT_NO_THROW(cfg_mgr.addSubnet4(subnet1));
|
||||
EXPECT_NO_THROW(cfg_mgr.addSubnet4(subnet2));
|
||||
// Subnet 3 has the same ID as subnet 1. It shouldn't be able to add it.
|
||||
EXPECT_THROW(cfg_mgr.addSubnet4(subnet3), isc::dhcp::DuplicateSubnetID);
|
||||
}
|
||||
|
||||
// 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.
|
||||
|
@ -446,7 +446,7 @@ public:
|
||||
/// during a given test if needed.
|
||||
void reset_context(){
|
||||
// Note set context universe to V6 as it has to be something.
|
||||
CfgMgr::instance().deleteSubnets4();
|
||||
CfgMgr::instance().clear();
|
||||
CfgMgr::instance().deleteSubnets6();
|
||||
parser_context_.reset(new ParserContext(Option::V6));
|
||||
|
||||
|
@ -137,7 +137,7 @@ SrvConfigTest::addSubnet4(const unsigned int index) {
|
||||
FAIL() << "Subnet index " << index << "out of range (0.."
|
||||
<< TEST_SUBNETS_NUM << "): " << "unable to add IPv4 subnet";
|
||||
}
|
||||
CfgMgr::instance().addSubnet4(test_subnets4_[index]);
|
||||
conf_.getCfgSubnets4()->add(test_subnets4_[index]);
|
||||
}
|
||||
|
||||
void
|
||||
@ -151,7 +151,6 @@ SrvConfigTest::addSubnet6(const unsigned int index) {
|
||||
|
||||
void
|
||||
SrvConfigTest::clearSubnets() {
|
||||
CfgMgr::instance().deleteSubnets4();
|
||||
CfgMgr::instance().deleteSubnets6();
|
||||
}
|
||||
|
||||
@ -254,11 +253,6 @@ TEST_F(SrvConfigTest, summarySubnets) {
|
||||
EXPECT_EQ("added IPv4 subnets: 2; added IPv6 subnets: 2",
|
||||
conf_.getConfigSummary(SrvConfig::CFGSEL_SUBNET));
|
||||
|
||||
// Remove all subnets and make sure that there are no reported subnets
|
||||
// back again.
|
||||
clearSubnets();
|
||||
EXPECT_EQ("no IPv4 subnets!; no IPv6 subnets!",
|
||||
conf_.getConfigSummary(SrvConfig::CFGSEL_SUBNET));
|
||||
}
|
||||
|
||||
// This test checks if entire configuration can be copied and that the sequence
|
||||
|
Loading…
x
Reference in New Issue
Block a user