]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[5425] Completed pool tests (with bug to fix) and cloned to plain subnets
authorFrancis Dupont <fdupont@isc.org>
Sun, 5 Nov 2017 16:57:49 +0000 (17:57 +0100)
committerFrancis Dupont <fdupont@isc.org>
Sun, 5 Nov 2017 16:57:49 +0000 (17:57 +0100)
src/bin/dhcp4/tests/shared_network_unittest.cc
src/bin/dhcp6/tests/shared_network_unittest.cc

index bc50de548659b1d41b43989355324cfaca753854..9e564d551e919e76e58e076b3841b06055e7b608 100644 (file)
@@ -862,7 +862,7 @@ const char* NETWORKS_CONFIG[] = {
     "}",
 
 // Configuration #16
-// - 1 shared network with 1 subnet and 2 pools and client class restriction
+// - 1 shared network with 1 subnet and 2 pools (first pool has class restriction)
     "{"
     "    \"interfaces-config\": {"
     "        \"interfaces\": [ \"*\" ]"
@@ -871,6 +871,10 @@ const char* NETWORKS_CONFIG[] = {
     "        {"
     "            \"name\": \"a-devices\","
     "            \"test\": \"option[93].hex == 0x0001\""
+    "        },"
+    "        {"
+    "            \"name\": \"b-devices\","
+    "            \"test\": \"option[93].hex == 0x0002\""
     "        }"
     "    ],"
     "    \"valid-lifetime\": 600,"
@@ -895,6 +899,118 @@ const char* NETWORKS_CONFIG[] = {
     "            ]"
     "        }"
     "    ]"
+    "}",
+
+// Configuration #17
+// - 1 shared network with 1 subnet and 2 pools (each with class restriction)
+    "{"
+    "    \"interfaces-config\": {"
+    "        \"interfaces\": [ \"*\" ]"
+    "    },"
+    "    \"client-classes\": ["
+    "        {"
+    "            \"name\": \"a-devices\","
+    "            \"test\": \"option[93].hex == 0x0001\""
+    "        },"
+    "        {"
+    "            \"name\": \"b-devices\","
+    "            \"test\": \"option[93].hex == 0x0002\""
+    "        }"
+    "    ],"
+    "    \"valid-lifetime\": 600,"
+    "    \"shared-networks\": ["
+    "        {"
+    "            \"name\": \"frog\","
+    "            \"interface\": \"eth1\","
+    "            \"subnet4\": ["
+    "                {"
+    "                    \"subnet\": \"192.0.2.0/24\","
+    "                    \"id\": 10,"
+    "                    \"pools\": ["
+    "                        {"
+    "                            \"pool\": \"192.0.2.1 - 192.0.2.63\","
+    "                            \"client-class\": \"a-devices\""
+    "                        },"
+    "                        {"
+    "                            \"pool\": \"192.0.2.100 - 192.0.2.100\","
+    "                            \"client-class\": \"b-devices\""
+    "                        }"
+    "                    ]"
+    "                }"
+    "            ]"
+    "        }"
+    "    ]"
+    "}",
+
+// Configuration #18
+// - plain subnet and 2 pools (first pool has class restriction)
+    "{"
+    "    \"interfaces-config\": {"
+    "        \"interfaces\": [ \"*\" ]"
+    "    },"
+    "    \"client-classes\": ["
+    "        {"
+    "            \"name\": \"a-devices\","
+    "            \"test\": \"option[93].hex == 0x0001\""
+    "        },"
+    "        {"
+    "            \"name\": \"b-devices\","
+    "            \"test\": \"option[93].hex == 0x0002\""
+    "        }"
+    "    ],"
+    "    \"valid-lifetime\": 600,"
+    "    \"subnet4\": ["
+    "        {"
+    "            \"subnet\": \"192.0.2.0/24\","
+    "            \"id\": 10,"
+    "            \"interface\": \"eth1\","
+    "            \"pools\": ["
+    "                {"
+    "                    \"pool\": \"192.0.2.1 - 192.0.2.63\","
+    "                    \"client-class\": \"a-devices\""
+    "                },"
+    "                {"
+    "                    \"pool\": \"192.0.2.100 - 192.0.2.100\""
+    "                }"
+    "            ]"
+    "        }"
+    "    ]"
+    "}",
+
+// Configuration #19
+// - plain subnet and 2 pools (each with class restriction)
+    "{"
+    "    \"interfaces-config\": {"
+    "        \"interfaces\": [ \"*\" ]"
+    "    },"
+    "    \"client-classes\": ["
+    "        {"
+    "            \"name\": \"a-devices\","
+    "            \"test\": \"option[93].hex == 0x0001\""
+    "        },"
+    "        {"
+    "            \"name\": \"b-devices\","
+    "            \"test\": \"option[93].hex == 0x0002\""
+    "        }"
+    "    ],"
+    "    \"valid-lifetime\": 600,"
+    "    \"subnet4\": ["
+    "        {"
+    "            \"subnet\": \"192.0.2.0/24\","
+    "            \"id\": 10,"
+    "            \"interface\": \"eth1\","
+    "            \"pools\": ["
+    "                {"
+    "                    \"pool\": \"192.0.2.1 - 192.0.2.63\","
+    "                    \"client-class\": \"a-devices\""
+    "                },"
+    "                {"
+    "                    \"pool\": \"192.0.2.100 - 192.0.2.100\","
+    "                    \"client-class\": \"b-devices\""
+    "                }"
+    "            ]"
+    "        }"
+    "    ]"
     "}"
 
 };
@@ -1854,6 +1970,84 @@ TEST_F(Dhcpv4SharedNetworkTest, poolInSharedNetworkSelectedByClass) {
     testAssigned([this, &client2] {
         doDORA(client2, "192.0.2.100");
     });
+
+    // Now, let's reconfigure the server to also apply restrictions on the
+    // pool to which client2 now belongs.
+    configure(NETWORKS_CONFIG[17], *client1.getServer());
+
+    // The client should be refused to renew the lease because it doesn't belong
+    // to "b-devices" class.
+    client2.setState(Dhcp4Client::RENEWING);
+    testAssigned([this, &client2] {
+        doRequest(client2, "");
+    });
+
+    // If we add option93 with a value matching this class, the lease should
+    // get renewed.
+    OptionPtr option93_bis(new OptionUint16(Option::V4, 93, 0x0002));
+    client2.addExtraOption(option93_bis);
+
+    testAssigned([this, &client2] {
+        doRequest(client2, "192.0.2.100");
+    });
 }
 
+// Access to a pool within plain subnet is restricted by client classification.
+TEST_F(Dhcpv4SharedNetworkTest, poolInSubnetSelectedByClass) {
+    // Create client #1
+    Dhcp4Client client1(Dhcp4Client::SELECTING);
+    client1.setIfaceName("eth1");
+
+    // Configure the server with one plain subnet including two pools.
+    // The access to one of the pools is restricted by client classification.
+    configure(NETWORKS_CONFIG[18], *client1.getServer());
+
+    // Client #1 requests an address in the restricted pool but can't be assigned
+    // this address because the client doesn't belong to a certain class.
+    testAssigned([this, &client1] {
+        doDORA(client1, "192.0.2.100", "192.0.2.63");
+    });
+
+    // Release the lease that the client has got, because we'll need this address
+    // further in the test.
+    testAssigned([this, &client1] {
+        ASSERT_NO_THROW(client1.doRelease());
+    });
+
+    // Add option93 which would cause the client to be classified as "a-devices".
+    OptionPtr option93(new OptionUint16(Option::V4, 93, 0x0001));
+    client1.addExtraOption(option93);
+
+    // This time, the allocation of the address provided as hint should be successful.
+    testAssigned([this, &client1] {
+        doDORA(client1, "192.0.2.63", "192.0.2.63");
+    });
+
+    // Client 2 should be assigned an address from the unrestricted pool.
+    Dhcp4Client client2(client1.getServer(), Dhcp4Client::SELECTING);
+    client2.setIfaceName("eth1");
+    testAssigned([this, &client2] {
+        doDORA(client2, "192.0.2.100");
+    });
+
+    // Now, let's reconfigure the server to also apply restrictions on the
+    // pool to which client2 now belongs.
+    configure(NETWORKS_CONFIG[19], *client1.getServer());
+
+    // The client should be refused to renew the lease because it doesn't belong
+    // to "b-devices" class.
+    client2.setState(Dhcp4Client::RENEWING);
+    testAssigned([this, &client2] {
+        doRequest(client2, "");
+    });
+
+    // If we add option93 with a value matching this class, the lease should
+    // get renewed.
+    OptionPtr option93_bis(new OptionUint16(Option::V4, 93, 0x0002));
+    client2.addExtraOption(option93_bis);
+
+    testAssigned([this, &client2] {
+        doRequest(client2, "192.0.2.100");
+    });
+}
 } // end of anonymous namespace
index adeab7ed7e5b5e95abb016fffbb5444e31946291..2e869443d909cf6c131759068e22f32b3cb61357 100644 (file)
@@ -957,13 +957,17 @@ const char* NETWORKS_CONFIG[] = {
     "}",
 
 // Configuration #19.
-// - one shared network with on subnet and two pools (the first has
+// - one shared network with one subnet and two pools (the first has
 //   class restrictions)
     "{"
     "    \"client-classes\": ["
     "        {"
     "            \"name\": \"a-devices\","
     "            \"test\": \"option[1234].hex == 0x0001\""
+    "        },"
+    "        {"
+    "            \"name\": \"b-devices\","
+    "            \"test\": \"option[1234].hex == 0x0002\""
     "        }"
     "    ],"
     "    \"shared-networks\": ["
@@ -989,6 +993,112 @@ const char* NETWORKS_CONFIG[] = {
     "    ]"
     "}",
 
+// Configuration #20.
+// - one shared network with one subnet and two pools (each with class
+//   restriction)
+    "{"
+    "    \"client-classes\": ["
+    "        {"
+    "            \"name\": \"a-devices\","
+    "            \"test\": \"option[1234].hex == 0x0001\""
+    "        },"
+    "        {"
+    "            \"name\": \"b-devices\","
+    "            \"test\": \"option[1234].hex == 0x0002\""
+    "        }"
+    "    ],"
+    "    \"shared-networks\": ["
+    "        {"
+    "            \"name\": \"frog\","
+    "            \"interface\": \"eth1\","
+    "            \"subnet6\": ["
+    "                {"
+    "                    \"subnet\": \"2001:db8:1::/64\","
+    "                    \"id\": 10,"
+    "                    \"pools\": ["
+    "                        {"
+    "                            \"pool\": \"2001:db8:1::20 - 2001:db8:1::20\","
+    "                            \"client-class\": \"a-devices\""
+    "                        },"
+    "                        {"
+    "                            \"pool\": \"2001:db8:1::50 - 2001:db8:1::50\","
+    "                            \"client-class\": \"b-devices\""
+    "                        }"
+    "                    ]"
+    "                }"
+    "            ]"
+    "        }"
+    "    ]"
+    "}",
+
+// Configuration #21.
+// - one plain subnet with two pools (the first has class restrictions)
+    "{"
+    "    \"client-classes\": ["
+    "        {"
+    "            \"name\": \"a-devices\","
+    "            \"test\": \"option[1234].hex == 0x0001\""
+    "        },"
+    "        {"
+    "            \"name\": \"b-devices\","
+    "            \"test\": \"option[1234].hex == 0x0002\""
+    "        }"
+    "    ],"
+    "    \"subnet6\": ["
+    "        {"
+    "            \"subnet\": \"2001:db8:1::/64\","
+    "            \"id\": 10,"
+    "            \"interface\": \"eth1\","
+    "            \"pools\": ["
+    "                {"
+    "                    \"pool\": \"2001:db8:1::20 - 2001:db8:1::20\","
+    "                    \"client-class\": \"a-devices\""
+    "                },"
+    "                {"
+    "                    \"pool\": \"2001:db8:1::50 - 2001:db8:1::50\""
+    "                }"
+    "            ]"
+    "        }"
+    "    ]"
+    "}",
+
+// Configuration #22.
+// - one plain subnet with two pools (each with class restriction)
+    "{"
+    "    \"client-classes\": ["
+    "        {"
+    "            \"name\": \"a-devices\","
+    "            \"test\": \"option[1234].hex == 0x0001\""
+    "        },"
+    "        {"
+    "            \"name\": \"b-devices\","
+    "            \"test\": \"option[1234].hex == 0x0002\""
+    "        }"
+    "    ],"
+    "    \"shared-networks\": ["
+    "        {"
+    "            \"name\": \"frog\","
+    "            \"interface\": \"eth1\","
+    "            \"subnet6\": ["
+    "                {"
+    "                    \"subnet\": \"2001:db8:1::/64\","
+    "                    \"id\": 10,"
+    "                    \"pools\": ["
+    "                        {"
+    "                            \"pool\": \"2001:db8:1::20 - 2001:db8:1::20\","
+    "                            \"client-class\": \"a-devices\""
+    "                        },"
+    "                        {"
+    "                            \"pool\": \"2001:db8:1::50 - 2001:db8:1::50\","
+    "                            \"client-class\": \"b-devices\""
+    "                        }"
+    "                    ]"
+    "                }"
+    "            ]"
+    "        }"
+    "    ]"
+    "}"
+
 };
 
 /// @Brief Test fixture class for DHCPv6 server using shared networks.
@@ -2230,7 +2340,71 @@ TEST_F(Dhcpv6SharedNetworkTest, poolInSharedNetworkSelectedByClass) {
     });
     ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:1::20")));
 
-    // Client 2 should be assigned an address from the unrestricted subnet.
+    // Client 2 should be assigned an address from the unrestricted pool.
+    Dhcp6Client client2(client1.getServer());
+    client2.setInterface("eth1");
+    ASSERT_NO_THROW(client2.requestAddress(0xabca0));
+    testAssigned([this, &client2] {
+        ASSERT_NO_THROW(client2.doSARR());
+    });
+    ASSERT_TRUE(hasLeaseForAddress(client2, IOAddress("2001:db8:1::50")));
+
+    // Now, let's reconfigure the server to also apply restrictions on the
+    // pool to which client2 now belongs.
+    ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[20], *client1.getServer()));
+
+    testAssigned([this, &client2] {
+        ASSERT_NO_THROW(client2.doRenew());
+    });
+#if 0
+    EXPECT_EQ(0, client2.getLeaseNum());
+#endif
+
+    // If we add option 1234 with a value matching this class, the lease should
+    // get renewed.
+    OptionPtr option1234_bis(new OptionUint16(Option::V6, 1234, 0x0002));
+    client2.addExtraOption(option1234_bis);
+    testAssigned([this, &client2] {
+        ASSERT_NO_THROW(client2.doRenew());
+    });
+    EXPECT_EQ(1, client2.getLeaseNum());
+}
+
+// Pool is selected based on the client class specified using a plain subnet.
+TEST_F(Dhcpv6SharedNetworkTest, poolInSubnetSelectedByClass) {
+    // Create client #1.
+    Dhcp6Client client1;
+    client1.setInterface("eth1");
+
+    // Configure the server with one plain subnet including two pools.
+    // The access to one of the pools is restricted by client classification.
+    ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[21], *client1.getServer()));
+
+    // Client #1 requests an address in the restricted pool but can't be assigned
+    // this address because the client doesn't belong to a certain class.
+    ASSERT_NO_THROW(client1.requestAddress(0xabca, IOAddress("2001:db8:1::20")));
+    testAssigned([this, &client1] {
+        ASSERT_NO_THROW(client1.doSARR());
+    });
+    ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:1::50")));
+
+    // Release the lease that the client has got, because we'll need this address
+    // further in the test.
+    testAssigned([this, &client1] {
+        ASSERT_NO_THROW(client1.doRelease());
+    });
+
+    // Add option 1234 which would cause the client to be classified as "a-devices".
+    OptionPtr option1234(new OptionUint16(Option::V6, 1234, 0x0001));
+    client1.addExtraOption(option1234);
+
+    // This time, the allocation of the address provided as hint should be successful.
+    testAssigned([this, &client1] {
+        ASSERT_NO_THROW(client1.doSARR());
+    });
+    ASSERT_TRUE(hasLeaseForAddress(client1, IOAddress("2001:db8:1::20")));
+
+    // Client 2 should be assigned an address from the unrestricted pool.
     Dhcp6Client client2(client1.getServer());
     client2.setInterface("eth1");
     ASSERT_NO_THROW(client2.requestAddress(0xabca0));
@@ -2238,6 +2412,26 @@ TEST_F(Dhcpv6SharedNetworkTest, poolInSharedNetworkSelectedByClass) {
         ASSERT_NO_THROW(client2.doSARR());
     });
     ASSERT_TRUE(hasLeaseForAddress(client2, IOAddress("2001:db8:1::50")));
+
+    // Now, let's reconfigure the server to also apply restrictions on the
+    // pool to which client2 now belongs.
+    ASSERT_NO_FATAL_FAILURE(configure(NETWORKS_CONFIG[22], *client1.getServer()));
+
+    testAssigned([this, &client2] {
+        ASSERT_NO_THROW(client2.doRenew());
+    });
+#if 0
+    EXPECT_EQ(0, client2.getLeaseNum());
+#endif
+
+    // If we add option 1234 with a value matching this class, the lease should
+    // get renewed.
+    OptionPtr option1234_bis(new OptionUint16(Option::V6, 1234, 0x0002));
+    client2.addExtraOption(option1234_bis);
+    testAssigned([this, &client2] {
+        ASSERT_NO_THROW(client2.doRenew());
+    });
+    EXPECT_EQ(1, client2.getLeaseNum());
 }
 
 } // end of anonymous namespace