From: Marcin Siodelski Date: Fri, 31 Jan 2014 13:10:44 +0000 (+0100) Subject: [3242] Implement function which returns subnet for the interface. X-Git-Tag: bind10-1.2.0beta1-release~63^2~14 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f4548b2768162c8748665d190e288bc87327dde1;p=thirdparty%2Fkea.git [3242] Implement function which returns subnet for the interface. This function replaces the one that checked whether there is a subnet for an interface and returns boolean value. --- diff --git a/src/lib/dhcpsrv/cfgmgr.cc b/src/lib/dhcpsrv/cfgmgr.cc index 60d02e577b..b8e36296a0 100644 --- a/src/lib/dhcpsrv/cfgmgr.cc +++ b/src/lib/dhcpsrv/cfgmgr.cc @@ -208,9 +208,9 @@ void CfgMgr::addSubnet6(const Subnet6Ptr& subnet) { } Subnet4Ptr -CfgMgr::getSubnet4(const isc::asiolink::IOAddress& hint) { +CfgMgr::getSubnet4(const isc::asiolink::IOAddress& hint) const { - // If there's only one subnet configured, let's just use it + /* // If there's only one subnet configured, let's just use it // The idea is to keep small deployments easy. In a small network - one // router that also runs DHCPv6 server. Users specifies a single pool and // expects it to just work. Without this, the server would complain that it @@ -223,10 +223,10 @@ CfgMgr::getSubnet4(const isc::asiolink::IOAddress& hint) { DHCPSRV_CFGMGR_ONLY_SUBNET4) .arg(subnets4_[0]->toText()).arg(hint.toText()); return (subnets4_[0]); - } + }*/ // If there is more than one, we need to choose the proper one - for (Subnet4Collection::iterator subnet = subnets4_.begin(); + for (Subnet4Collection::const_iterator subnet = subnets4_.begin(); subnet != subnets4_.end(); ++subnet) { if ((*subnet)->inRange(hint)) { LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE, @@ -242,22 +242,20 @@ CfgMgr::getSubnet4(const isc::asiolink::IOAddress& hint) { return (Subnet4Ptr()); } -bool -CfgMgr::belongsToSubnet4(const std::string& iface_name) const { +Subnet4Ptr +CfgMgr::getSubnet4(const std::string& iface_name) 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"); + 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("::1"); - if (iface->getAddress4(addr)) { - for (Subnet4Collection::const_iterator subnet = subnets4_.begin(); - subnet != subnets4_.end(); ++subnet) { - if ((*subnet)->inRange(addr)) { - return (true); - } - } - } - return (false); + // 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) : Subnet4Ptr()); } void CfgMgr::addSubnet4(const Subnet4Ptr& subnet) { diff --git a/src/lib/dhcpsrv/cfgmgr.h b/src/lib/dhcpsrv/cfgmgr.h index f22a994441..610e4b14c4 100644 --- a/src/lib/dhcpsrv/cfgmgr.h +++ b/src/lib/dhcpsrv/cfgmgr.h @@ -219,7 +219,7 @@ public: /// 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 Subnet4Collection* getSubnets4() { + const Subnet4Collection* getSubnets4() const { return (&subnets4_); } @@ -244,19 +244,19 @@ public: /// @param hint an address that belongs to a searched subnet /// /// @return a subnet object - Subnet4Ptr getSubnet4(const isc::asiolink::IOAddress& hint); + Subnet4Ptr getSubnet4(const isc::asiolink::IOAddress& hint) const; - /// @brief Checks that the IP address assigned to an interface belongs to - /// any subnet. + /// @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. + /// interface belongs to any IPv4 subnet configured, and returns this + /// subnet. /// /// @param iface Short name of the interface which is being checked. /// - /// @return Boolean value which indicates that the IP address belons to any - /// subnet (if true), false otherwise. - bool belongsToSubnet4(const std::string& iface) const; + /// @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; /// @brief adds a subnet4 void addSubnet4(const Subnet4Ptr& subnet); diff --git a/src/lib/dhcpsrv/tests/cfgmgr_unittest.cc b/src/lib/dhcpsrv/tests/cfgmgr_unittest.cc index ac34f2e423..a6223f767a 100644 --- a/src/lib/dhcpsrv/tests/cfgmgr_unittest.cc +++ b/src/lib/dhcpsrv/tests/cfgmgr_unittest.cc @@ -713,23 +713,42 @@ TEST_F(CfgMgrTest, d2ClientConfig) { // This test verfies that CfgMgr correctly determines that the address of the // interface belongs to existing IPv4 subnet. -TEST_F(CfgMgrTest, belongsToSubnet4) { +TEST_F(CfgMgrTest, getSubnet4ForInterface) { IfaceMgrTestConfig config(true); - ASSERT_FALSE(CfgMgr::instance().belongsToSubnet4("eth0")); - ASSERT_FALSE(CfgMgr::instance().belongsToSubnet4("eth1")); + // Initially, there are no subnets configured, so none of the IPv4 + // addresses assigned to eth0 and eth1 can match with any subnet. + ASSERT_FALSE(CfgMgr::instance().getSubnet4("eth0")); + ASSERT_FALSE(CfgMgr::instance().getSubnet4("eth1")); + // 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); - EXPECT_TRUE(CfgMgr::instance().belongsToSubnet4("eth0")); - EXPECT_FALSE(CfgMgr::instance().belongsToSubnet4("eth1")); + // The address on eth0 should match the existing subnet. + Subnet4Ptr subnet1_ret; + subnet1_ret = CfgMgr::instance().getSubnet4("eth0"); + 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")); + // Configure a second subnet. Subnet4Ptr subnet2(new Subnet4(IOAddress("192.0.2.1"), 24, 1, 2, 3)); CfgMgr::instance().addSubnet4(subnet2); - EXPECT_TRUE(CfgMgr::instance().belongsToSubnet4("eth0")); - EXPECT_TRUE(CfgMgr::instance().belongsToSubnet4("eth1")); + // There should be match between eth0 and subnet1 and between eth1 and + // subnet 2. + subnet1_ret = CfgMgr::instance().getSubnet4("eth0"); + ASSERT_TRUE(subnet1_ret); + EXPECT_EQ(subnet1->get().first, subnet1_ret->get().first); + Subnet4Ptr subnet2_ret = CfgMgr::instance().getSubnet4("eth1"); + 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"), + isc::BadValue); }