From: Francis Dupont Date: Sun, 5 Nov 2017 16:57:49 +0000 (+0100) Subject: [5425] Completed pool tests (with bug to fix) and cloned to plain subnets X-Git-Tag: trac5374_base~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=57cd314b47a154e6573fb8727f1cf31cbbd9dd6e;p=thirdparty%2Fkea.git [5425] Completed pool tests (with bug to fix) and cloned to plain subnets --- diff --git a/src/bin/dhcp4/tests/shared_network_unittest.cc b/src/bin/dhcp4/tests/shared_network_unittest.cc index bc50de5486..9e564d551e 100644 --- a/src/bin/dhcp4/tests/shared_network_unittest.cc +++ b/src/bin/dhcp4/tests/shared_network_unittest.cc @@ -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 diff --git a/src/bin/dhcp6/tests/shared_network_unittest.cc b/src/bin/dhcp6/tests/shared_network_unittest.cc index adeab7ed7e..2e869443d9 100644 --- a/src/bin/dhcp6/tests/shared_network_unittest.cc +++ b/src/bin/dhcp6/tests/shared_network_unittest.cc @@ -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