Commit 17282104 authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[3281] Config manager checks for subnet id duplications.

parent 9ecdae6c
......@@ -219,6 +219,11 @@ 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 the same as ID of an existing"
" subnet");
}
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE, DHCPSRV_CFGMGR_ADD_SUBNET6)
.arg(subnet->toText());
subnets6_.push_back(subnet);
......@@ -282,6 +287,11 @@ CfgMgr::getSubnet4(const std::string& iface_name,
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 the same as ID of an existing"
" subnet");
}
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE, DHCPSRV_CFGMGR_ADD_SUBNET4)
.arg(subnet->toText());
subnets4_.push_back(subnet);
......@@ -377,6 +387,29 @@ CfgMgr::isIfaceListedActive(const std::string& iface) const {
return (false);
}
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();
subnet_it != subnets6_.end(); ++subnet_it) {
if ((*subnet_it)->getID() == subnet.getID()) {
return (true);
}
}
return (false);
}
const isc::asiolink::IOAddress*
CfgMgr::getUnicast(const std::string& iface) const {
UnicastIfacesCollection::const_iterator addr = unicast_addrs_.find(iface);
......
......@@ -47,6 +47,13 @@ public:
isc::Exception(file, line, what) { };
};
/// @brief Exception thrown upon attempt to add subnet with an ID that belongs
/// to the subnet that already exists.
class DuplicateSubnetID : public Exception {
public:
DuplicateSubnetID(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) { };
};
/// @brief Configuration Manager
///
......@@ -458,6 +465,20 @@ private:
/// @c CfgMgr::active_ifaces_.
bool isIfaceListedActive(const std::string& iface) const;
/// @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
/// subnet with equal id already exists.
/// @return true if the duplicate subnet exists.
bool isDuplicate(const Subnet6& subnet) const;
/// @brief A collection of option definitions.
///
/// A collection of option definitions that can be accessed
......
......@@ -1053,6 +1053,41 @@ TEST_F(CfgMgrTest, getSubnet4ForInterface) {
}
// 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.
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);
}
/// @todo Add unit-tests for testing:
/// - addActiveIface() with invalid interface name
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment