Browse Source

[3150] Checks for different pool types implemented.

Tomek Mrugalski 11 years ago
parent
commit
c37f3b910e

+ 2 - 1
src/bin/dhcp4/dhcp4_srv.cc

@@ -135,7 +135,8 @@ Dhcpv4Srv::Dhcpv4Srv(uint16_t port, const char* dbconfig, const bool use_bcast,
             .arg(LeaseMgrFactory::instance().getName());
 
         // Instantiate allocation engine
-        alloc_engine_.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100));
+        alloc_engine_.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100,
+                                            false /* false = IPv4 */));
 
         // Register hook points
         hook_index_pkt4_receive_   = Hooks.hook_index_pkt4_receive_;

+ 13 - 2
src/lib/dhcpsrv/subnet.cc

@@ -89,6 +89,9 @@ Subnet::getOptionDescriptor(const std::string& option_space,
 }
 
 isc::asiolink::IOAddress Subnet::getLastAllocated(Pool::PoolType type) const {
+    // check if the type is valid (and throw if it isn't)
+    checkType(type);
+
     switch (type) {
     case Pool::TYPE_V4:
     case Pool::TYPE_IA:
@@ -131,7 +134,7 @@ Subnet::toText() const {
     return (tmp.str());
 }
 
-void Subnet4::checkType(Pool::PoolType type) {
+void Subnet4::checkType(Pool::PoolType type) const {
     if (type != Pool::TYPE_V4) {
         isc_throw(BadValue, "Only TYPE_V4 is allowed for Subnet4");
     }
@@ -149,6 +152,9 @@ Subnet4::Subnet4(const isc::asiolink::IOAddress& prefix, uint8_t length,
 }
 
 const PoolCollection& Subnet::getPools(Pool::PoolType type) const {
+    // check if the type is valid (and throw if it isn't)
+    checkType(type);
+
     switch (type) {
     case Pool::TYPE_V4:
     case Pool::TYPE_IA:
@@ -163,6 +169,8 @@ const PoolCollection& Subnet::getPools(Pool::PoolType type) const {
 }
 
 PoolPtr Subnet::getPool(Pool::PoolType type, isc::asiolink::IOAddress hint) {
+    // check if the type is valid (and throw if it isn't)
+    checkType(type);
 
     PoolCollection* pools = NULL;
 
@@ -214,6 +222,9 @@ Subnet::addPool(const PoolPtr& pool) {
 
     /// @todo: Check that pools do not overlap
 
+    // check if the type is valid (and throw if it isn't)
+    checkType(pool->getType());
+
     switch (pool->getType()) {
     case Pool::TYPE_V4:
     case Pool::TYPE_IA:
@@ -283,7 +294,7 @@ Subnet6::Subnet6(const isc::asiolink::IOAddress& prefix, uint8_t length,
     }
 }
 
-void Subnet6::checkType(Pool::PoolType type) {
+void Subnet6::checkType(Pool::PoolType type) const {
     if ( (type != Pool::TYPE_IA) && (type != Pool::TYPE_TA) &&
          (type != Pool::TYPE_PD)) {
         isc_throw(BadValue, "Invalid Pool type: " << static_cast<int>(type)

+ 3 - 3
src/lib/dhcpsrv/subnet.h

@@ -352,7 +352,7 @@ protected:
     ///
     /// @param type type to be checked
     /// @throw BadValue if invalid value is used
-    virtual void checkType(Pool::PoolType type) = 0;
+    virtual void checkType(Pool::PoolType type) const = 0;
 
     /// @brief Check if option is valid and can be added to a subnet.
     ///
@@ -464,7 +464,7 @@ protected:
     ///
     /// @param type type to be checked
     /// @throw BadValue if invalid value is used
-    virtual void checkType(Pool::PoolType type);
+    virtual void checkType(Pool::PoolType type) const;
 };
 
 /// @brief A pointer to a Subnet4 object
@@ -535,7 +535,7 @@ protected:
     ///
     /// @param type type to be checked
     /// @throw BadValue if invalid value is used
-    virtual void checkType(Pool::PoolType type);
+    virtual void checkType(Pool::PoolType type) const;
 
     /// @brief specifies optional interface-id
     OptionPtr interface_id_;

+ 117 - 1
src/lib/dhcpsrv/tests/subnet_unittest.cc

@@ -197,6 +197,52 @@ TEST(Subnet4Test, lastAllocated) {
     EXPECT_THROW(subnet->setLastAllocated(Pool::TYPE_PD, addr), BadValue);
 }
 
+// Checks if the V4 is the only allowed type for Pool4 and if getPool()
+// is working properly.
+TEST(Subnet4Test, PoolType) {
+
+    Subnet4Ptr subnet(new Subnet4(IOAddress("192.2.0.0"), 16, 1, 2, 3));
+
+    PoolPtr pool1(new Pool4(IOAddress("192.2.1.0"), 24));
+    PoolPtr pool2(new Pool4(IOAddress("192.2.2.0"), 24));
+    PoolPtr pool3(new Pool6(Pool6::TYPE_IA, IOAddress("2001:db8:1:3::"), 64));
+    PoolPtr pool4(new Pool6(Pool6::TYPE_TA, IOAddress("2001:db8:1:4::"), 64));
+    PoolPtr pool5(new Pool6(Pool6::TYPE_PD, IOAddress("2001:db8:1:1::"), 64));
+
+    // There should be no pools of any type by default
+    EXPECT_EQ(PoolPtr(), subnet->getAnyPool(Pool::TYPE_V4));
+
+    // It should not be possible to ask for V6 pools in Subnet4
+    EXPECT_THROW(subnet->getAnyPool(Pool::TYPE_IA), BadValue);
+    EXPECT_THROW(subnet->getAnyPool(Pool::TYPE_TA), BadValue);
+    EXPECT_THROW(subnet->getAnyPool(Pool::TYPE_PD), BadValue);
+
+    // Let's add a single V4 pool and check that it can be retrieved
+    subnet->addPool(pool1);
+
+    // If there's only one IA pool, get that pool (without and with hint)
+    EXPECT_EQ(pool1, subnet->getAnyPool(Pool::TYPE_V4));
+    EXPECT_EQ(pool1, subnet->getPool(Pool::TYPE_V4, IOAddress("192.0.1.167")));
+
+    // Let's add additional V4 pool
+    subnet->addPool(pool2);
+
+    // Try without hints
+    EXPECT_EQ(pool1, subnet->getAnyPool(Pool::TYPE_V4));
+
+    // Try with valid hints
+    EXPECT_EQ(pool1, subnet->getPool(Pool::TYPE_V4, IOAddress("192.2.1.5")));
+    EXPECT_EQ(pool2, subnet->getPool(Pool::TYPE_V4, IOAddress("192.2.2.254")));
+
+    // Try with bogus hints (hints should be ingored)
+    EXPECT_EQ(pool1, subnet->getPool(Pool::TYPE_V4, IOAddress("10.1.1.1")));
+
+    // Trying to add Pool6 to Subnet4 is a big no,no!
+    EXPECT_THROW(subnet->addPool(pool3), BadValue);
+    EXPECT_THROW(subnet->addPool(pool4), BadValue);
+    EXPECT_THROW(subnet->addPool(pool5), BadValue);
+}
+
 // Tests for Subnet6
 
 TEST(Subnet6Test, constructor) {
@@ -240,7 +286,6 @@ TEST(Subnet6Test, Pool6InSubnet6) {
     PoolPtr mypool = subnet->getAnyPool(Pool::TYPE_IA);
     EXPECT_EQ(mypool, pool1);
 
-
     subnet->addPool(pool2);
     subnet->addPool(pool3);
 
@@ -256,6 +301,77 @@ TEST(Subnet6Test, Pool6InSubnet6) {
     EXPECT_EQ(mypool, pool3);
 }
 
+// Check if Subnet6 supports different types of pools properly.
+TEST(Subnet6Test, PoolTypes) {
+
+    Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));
+
+    PoolPtr pool1(new Pool6(Pool6::TYPE_IA, IOAddress("2001:db8:1:1::"), 64));
+    PoolPtr pool2(new Pool6(Pool6::TYPE_TA, IOAddress("2001:db8:1:2::"), 64));
+    PoolPtr pool3(new Pool6(Pool6::TYPE_PD, IOAddress("2001:db8:1:3::"), 64));
+    PoolPtr pool4(new Pool6(Pool6::TYPE_PD, IOAddress("2001:db8:1:4::"), 64));
+
+    PoolPtr pool5(new Pool4(IOAddress("192.0.2.0"), 24));
+
+    // There should be no pools of any type by default
+    EXPECT_EQ(PoolPtr(), subnet->getAnyPool(Pool::TYPE_IA));
+    EXPECT_EQ(PoolPtr(), subnet->getAnyPool(Pool::TYPE_TA));
+    EXPECT_EQ(PoolPtr(), subnet->getAnyPool(Pool::TYPE_PD));
+
+    // Trying to get IPv4 pool from Subnet6 is not allowed
+    EXPECT_THROW(subnet->getAnyPool(Pool::TYPE_V4), BadValue);
+
+    // Let's add a single IA pool and check that it can be retrieved
+    subnet->addPool(pool1);
+
+    // If there's only one IA pool, get that pool
+    EXPECT_EQ(pool1, subnet->getAnyPool(Pool::TYPE_IA));
+    EXPECT_EQ(pool1, subnet->getPool(Pool::TYPE_IA, IOAddress("2001:db8:1:1::1")));
+
+    // Check if pools of different type are not returned
+    EXPECT_EQ(PoolPtr(), subnet->getAnyPool(Pool::TYPE_TA));
+    EXPECT_EQ(PoolPtr(), subnet->getAnyPool(Pool::TYPE_PD));
+
+    // We ask with good hints, but wrong types, should return nothing
+    EXPECT_EQ(PoolPtr(), subnet->getPool(Pool::TYPE_PD, IOAddress("2001:db8:1:2::1")));
+    EXPECT_EQ(PoolPtr(), subnet->getPool(Pool::TYPE_TA, IOAddress("2001:db8:1:3::1")));
+
+    // Let's add TA and PD pools
+    subnet->addPool(pool2);
+    subnet->addPool(pool3);
+
+    // Try without hints
+    EXPECT_EQ(pool1, subnet->getAnyPool(Pool::TYPE_IA));
+    EXPECT_EQ(pool2, subnet->getAnyPool(Pool::TYPE_TA));
+    EXPECT_EQ(pool3, subnet->getAnyPool(Pool::TYPE_PD));
+
+    // Try with valid hints
+    EXPECT_EQ(pool1, subnet->getPool(Pool::TYPE_IA, IOAddress("2001:db8:1:1::1")));
+    EXPECT_EQ(pool2, subnet->getPool(Pool::TYPE_TA, IOAddress("2001:db8:1:2::1")));
+    EXPECT_EQ(pool3, subnet->getPool(Pool::TYPE_PD, IOAddress("2001:db8:1:3::1")));
+
+    // Try with bogus hints (hints should be ingored)
+    EXPECT_EQ(pool1, subnet->getPool(Pool::TYPE_IA, IOAddress("2001:db8:1:7::1")));
+    EXPECT_EQ(pool2, subnet->getPool(Pool::TYPE_TA, IOAddress("2001:db8:1:7::1")));
+    EXPECT_EQ(pool3, subnet->getPool(Pool::TYPE_PD, IOAddress("2001:db8:1:7::1")));
+
+    // Let's add a second PD pool
+    subnet->addPool(pool4);
+
+    // Without hints, it should return the first pool
+    EXPECT_EQ(pool3, subnet->getAnyPool(Pool::TYPE_PD));
+
+    // With valid hint, it should return that hint
+    EXPECT_EQ(pool3, subnet->getPool(Pool::TYPE_PD, IOAddress("2001:db8:1:3::1")));
+    EXPECT_EQ(pool4, subnet->getPool(Pool::TYPE_PD, IOAddress("2001:db8:1:4::1")));
+
+    // With invalid hint, it should return the first pool
+    EXPECT_EQ(pool3, subnet->getPool(Pool::TYPE_PD, IOAddress("2001:db8::123")));
+
+    // Adding Pool4 to Subnet6 is a big no, no!
+    EXPECT_THROW(subnet->addPool(pool5), BadValue);
+}
+
 TEST(Subnet6Test, Subnet6_Pool6_checks) {
 
     Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));