From 13a8becc1b8cc6751a43fbae75a37c61f4988b3f Mon Sep 17 00:00:00 2001 From: Francis Dupont Date: Mon, 20 Nov 2017 23:27:07 +0100 Subject: [PATCH] [5425] Added final (?) tests --- src/bin/dhcp4/tests/config_parser_unittest.cc | 28 +- src/bin/dhcp4/tests/dhcp4_srv_unittest.cc | 51 +++ src/bin/dhcp4/tests/get_config_unittest.cc | 381 ++++++++++++++++-- src/bin/dhcp6/dhcp6_lexer.cc | 1 + src/bin/dhcp6/dhcp6_lexer.ll | 1 + src/bin/dhcp6/tests/classify_unittests.cc | 87 ++++ src/bin/dhcp6/tests/config_parser_unittest.cc | 84 +++- src/bin/dhcp6/tests/get_config_unittest.cc | 8 + src/lib/dhcpsrv/tests/subnet_unittest.cc | 93 ++++- 9 files changed, 678 insertions(+), 56 deletions(-) diff --git a/src/bin/dhcp4/tests/config_parser_unittest.cc b/src/bin/dhcp4/tests/config_parser_unittest.cc index c2cdcbbe5c..cb4088ab07 100644 --- a/src/bin/dhcp4/tests/config_parser_unittest.cc +++ b/src/bin/dhcp4/tests/config_parser_unittest.cc @@ -4112,11 +4112,13 @@ TEST_F(Dhcp4ParserTest, classifyPools) { " }," " {" " \"pool\": \"192.0.3.101 - 192.0.3.150\", " - " \"client-class\": \"beta\" " + " \"client-class\": \"beta\", " + " \"known-clients\": \"never\" " " }," " {" " \"pool\": \"192.0.4.101 - 192.0.4.150\", " - " \"client-class\": \"gamma\" " + " \"client-class\": \"gamma\", " + " \"known-clients\": \"only\" " " }," " {" " \"pool\": \"192.0.5.101 - 192.0.5.150\" " @@ -4145,9 +4147,13 @@ TEST_F(Dhcp4ParserTest, classifyPools) { ClientClasses classes; classes.insert("alpha"); EXPECT_TRUE(pools.at(0)->clientSupported(classes, false)); + EXPECT_TRUE(pools.at(0)->clientSupported(classes, true)); EXPECT_FALSE(pools.at(1)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(1)->clientSupported(classes, true)); EXPECT_FALSE(pools.at(2)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(2)->clientSupported(classes, true)); EXPECT_TRUE(pools.at(3)->clientSupported(classes, false)); + EXPECT_TRUE(pools.at(3)->clientSupported(classes, true)); // Let's check if client belonging to beta class is supported in pool[1] // and not supported in any other pool (except pools[3], which allows @@ -4155,9 +4161,13 @@ TEST_F(Dhcp4ParserTest, classifyPools) { classes.clear(); classes.insert("beta"); EXPECT_FALSE(pools.at(0)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(0)->clientSupported(classes, true)); EXPECT_TRUE(pools.at(1)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(1)->clientSupported(classes, true)); EXPECT_FALSE(pools.at(2)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(2)->clientSupported(classes, true)); EXPECT_TRUE(pools.at(3)->clientSupported(classes, false)); + EXPECT_TRUE(pools.at(3)->clientSupported(classes, true)); // Let's check if client belonging to gamma class is supported in pool[2] // and not supported in any other pool (except pool[3], which allows @@ -4165,26 +4175,38 @@ TEST_F(Dhcp4ParserTest, classifyPools) { classes.clear(); classes.insert("gamma"); EXPECT_FALSE(pools.at(0)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(0)->clientSupported(classes, true)); EXPECT_FALSE(pools.at(1)->clientSupported(classes, false)); - EXPECT_TRUE(pools.at(2)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(1)->clientSupported(classes, true)); + EXPECT_FALSE(pools.at(2)->clientSupported(classes, false)); + EXPECT_TRUE(pools.at(2)->clientSupported(classes, true)); EXPECT_TRUE(pools.at(3)->clientSupported(classes, false)); + EXPECT_TRUE(pools.at(3)->clientSupported(classes, true)); // Let's check if client belonging to some other class (not mentioned in // the config) is supported only in pool[3], which allows everyone. classes.clear(); classes.insert("delta"); EXPECT_FALSE(pools.at(0)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(0)->clientSupported(classes, true)); EXPECT_FALSE(pools.at(1)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(1)->clientSupported(classes, true)); EXPECT_FALSE(pools.at(2)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(2)->clientSupported(classes, true)); EXPECT_TRUE(pools.at(3)->clientSupported(classes, false)); + EXPECT_TRUE(pools.at(3)->clientSupported(classes, true)); // Finally, let's check class-less client. He should be allowed only in // the last pool, which does not have any class restrictions. classes.clear(); EXPECT_FALSE(pools.at(0)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(0)->clientSupported(classes, true)); EXPECT_FALSE(pools.at(1)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(1)->clientSupported(classes, true)); EXPECT_FALSE(pools.at(2)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(2)->clientSupported(classes, true)); EXPECT_TRUE(pools.at(3)->clientSupported(classes, false)); + EXPECT_TRUE(pools.at(3)->clientSupported(classes, true)); } // This test verifies that the host reservations can be specified for diff --git a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc index f650d33867..d2cd09f099 100644 --- a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc +++ b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc @@ -2387,6 +2387,57 @@ TEST_F(Dhcpv4SrvTest, clientPoolClassify) { EXPECT_FALSE(offer->getYiaddr().isV4Zero()); } +// Checks if the known-clients field is indeed used for pool selection. +TEST_F(Dhcpv4SrvTest, clientPoolKnown) { + IfaceMgrTestConfig test_config(true); + IfaceMgr::instance().openSockets4(); + + NakedDhcpv4Srv srv(0); + + // This test configures 2 pools. + string config = "{ \"interfaces-config\": {" + " \"interfaces\": [ \"*\" ]" + "}," + "\"rebind-timer\": 2000, " + "\"renew-timer\": 1000, " + "\"subnet4\": [ " + "{ \"pools\": [ { " + " \"pool\": \"192.0.2.1 - 192.0.2.100\", " + " \"known-clients\": \"only\" }, " + " { \"pool\": \"192.0.3.1 - 192.0.3.100\", " + " \"known-clients\": \"never\" } ], " + " \"subnet\": \"192.0.0.0/16\" } " + "]," + "\"valid-lifetime\": 4000 }"; + + ConstElementPtr json; + ASSERT_NO_THROW(json = parseDHCP4(config, true)); + + ConstElementPtr status; + EXPECT_NO_THROW(status = configureDhcp4Server(srv, json)); + + CfgMgr::instance().commit(); + + // check if returned status is OK + ASSERT_TRUE(status); + comment_ = config::parseAnswer(rcode_, status); + ASSERT_EQ(0, rcode_); + + // Create a simple packet + Pkt4Ptr dis = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234)); + dis->setRemoteAddr(IOAddress("192.0.2.1")); + dis->setCiaddr(IOAddress("192.0.2.1")); + dis->setIface("eth0"); + OptionPtr clientid = generateClientId(); + dis->addOption(clientid); + + // First pool requires reservation so the second will be used + Pkt4Ptr offer = srv.processDiscover(dis); + ASSERT_TRUE(offer); + EXPECT_EQ(DHCPOFFER, offer->getType()); + EXPECT_EQ("192.0.3.1", offer->getYiaddr().toText()); +} + // Verifies last resort option 43 is backward compatible TEST_F(Dhcpv4SrvTest, option43LastResort) { IfaceMgrTestConfig test_config(true); diff --git a/src/bin/dhcp4/tests/get_config_unittest.cc b/src/bin/dhcp4/tests/get_config_unittest.cc index 5ee6aca358..95e2c00464 100644 --- a/src/bin/dhcp4/tests/get_config_unittest.cc +++ b/src/bin/dhcp4/tests/get_config_unittest.cc @@ -1158,6 +1158,85 @@ const char* EXTRACTED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"subnet4\": [\n" " {\n" +" \"client-class\": \"alpha\",\n" +" \"pools\": [\n" +" {\n" +" \"pool\": \"192.0.2.1 - 192.0.2.100\"\n" +" }\n" +" ],\n" +" \"subnet\": \"192.0.2.0/24\"\n" +" },\n" +" {\n" +" \"client-class\": \"beta\",\n" +" \"pools\": [\n" +" {\n" +" \"pool\": \"192.0.3.101 - 192.0.3.150\"\n" +" }\n" +" ],\n" +" \"subnet\": \"192.0.3.0/24\"\n" +" },\n" +" {\n" +" \"client-class\": \"gamma\",\n" +" \"pools\": [\n" +" {\n" +" \"pool\": \"192.0.4.101 - 192.0.4.150\"\n" +" }\n" +" ],\n" +" \"subnet\": \"192.0.4.0/24\"\n" +" },\n" +" {\n" +" \"pools\": [\n" +" {\n" +" \"pool\": \"192.0.5.101 - 192.0.5.150\"\n" +" }\n" +" ],\n" +" \"subnet\": \"192.0.5.0/24\"\n" +" }\n" +" ],\n" +" \"valid-lifetime\": 4000\n" +" }\n", + // CONFIGURATION 42 +"{\n" +" \"interfaces-config\": {\n" +" \"interfaces\": [ \"*\" ]\n" +" },\n" +" \"rebind-timer\": 2000,\n" +" \"renew-timer\": 1000,\n" +" \"subnet4\": [\n" +" {\n" +" \"pools\": [\n" +" {\n" +" \"client-class\": \"alpha\",\n" +" \"pool\": \"192.0.2.1 - 192.0.2.100\"\n" +" },\n" +" {\n" +" \"client-class\": \"beta\",\n" +" \"known-clients\": \"never\",\n" +" \"pool\": \"192.0.3.101 - 192.0.3.150\"\n" +" },\n" +" {\n" +" \"client-class\": \"gamma\",\n" +" \"known-clients\": \"only\",\n" +" \"pool\": \"192.0.4.101 - 192.0.4.150\"\n" +" },\n" +" {\n" +" \"pool\": \"192.0.5.101 - 192.0.5.150\"\n" +" }\n" +" ],\n" +" \"subnet\": \"192.0.0.0/16\"\n" +" }\n" +" ],\n" +" \"valid-lifetime\": 4000\n" +" }\n", + // CONFIGURATION 43 +"{\n" +" \"interfaces-config\": {\n" +" \"interfaces\": [ \"*\" ]\n" +" },\n" +" \"rebind-timer\": 2000,\n" +" \"renew-timer\": 1000,\n" +" \"subnet4\": [\n" +" {\n" " \"id\": 123,\n" " \"pools\": [\n" " {\n" @@ -1247,7 +1326,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 42 + // CONFIGURATION 44 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ]\n" @@ -1288,7 +1367,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 43 + // CONFIGURATION 45 "{\n" " \"rebind-timer\": 2000,\n" " \"renew-timer\": 1000,\n" @@ -1331,21 +1410,21 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 44 + // CONFIGURATION 46 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ]\n" " },\n" " \"subnet4\": [ ]\n" " }\n", - // CONFIGURATION 45 + // CONFIGURATION 47 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ]\n" " },\n" " \"subnet4\": [ ]\n" " }\n", - // CONFIGURATION 46 + // CONFIGURATION 48 "{\n" " \"decline-probation-period\": 12345,\n" " \"interfaces-config\": {\n" @@ -1353,7 +1432,7 @@ const char* EXTRACTED_CONFIGS[] = { " },\n" " \"subnet4\": [ ]\n" " }\n", - // CONFIGURATION 47 + // CONFIGURATION 49 "{\n" " \"expired-leases-processing\": {\n" " \"flush-reclaimed-timer-wait-time\": 35,\n" @@ -1368,7 +1447,7 @@ const char* EXTRACTED_CONFIGS[] = { " },\n" " \"subnet4\": [ ]\n" " }\n", - // CONFIGURATION 48 + // CONFIGURATION 50 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ]\n" @@ -1387,7 +1466,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 49 + // CONFIGURATION 51 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ]\n" @@ -1407,7 +1486,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 50 + // CONFIGURATION 52 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ]\n" @@ -1427,7 +1506,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 51 + // CONFIGURATION 53 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ]\n" @@ -1448,7 +1527,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 52 + // CONFIGURATION 54 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ]\n" @@ -1468,7 +1547,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 53 + // CONFIGURATION 55 "{\n" " \"client-classes\": [\n" " {\n" @@ -1498,7 +1577,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 54 + // CONFIGURATION 56 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ]\n" @@ -1517,7 +1596,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 55 + // CONFIGURATION 57 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ]\n" @@ -1537,7 +1616,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 56 + // CONFIGURATION 58 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ]\n" @@ -1561,7 +1640,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 57 + // CONFIGURATION 59 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ]\n" @@ -4893,6 +4972,244 @@ const char* UNPARSED_CONFIGS[] = { " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" " \"boot-file-name\": \"\",\n" +" \"client-class\": \"alpha\",\n" +" \"id\": 1,\n" +" \"match-client-id\": true,\n" +" \"next-server\": \"0.0.0.0\",\n" +" \"option-data\": [ ],\n" +" \"pools\": [\n" +" {\n" +" \"option-data\": [ ],\n" +" \"pool\": \"192.0.2.1-192.0.2.100\"\n" +" }\n" +" ],\n" +" \"rebind-timer\": 2000,\n" +" \"relay\": {\n" +" \"ip-address\": \"0.0.0.0\"\n" +" },\n" +" \"renew-timer\": 1000,\n" +" \"reservation-mode\": \"all\",\n" +" \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" +" \"subnet\": \"192.0.2.0/24\",\n" +" \"valid-lifetime\": 4000\n" +" },\n" +" {\n" +" \"4o6-interface\": \"\",\n" +" \"4o6-interface-id\": \"\",\n" +" \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" +" \"client-class\": \"beta\",\n" +" \"id\": 2,\n" +" \"match-client-id\": true,\n" +" \"next-server\": \"0.0.0.0\",\n" +" \"option-data\": [ ],\n" +" \"pools\": [\n" +" {\n" +" \"option-data\": [ ],\n" +" \"pool\": \"192.0.3.101-192.0.3.150\"\n" +" }\n" +" ],\n" +" \"rebind-timer\": 2000,\n" +" \"relay\": {\n" +" \"ip-address\": \"0.0.0.0\"\n" +" },\n" +" \"renew-timer\": 1000,\n" +" \"reservation-mode\": \"all\",\n" +" \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" +" \"subnet\": \"192.0.3.0/24\",\n" +" \"valid-lifetime\": 4000\n" +" },\n" +" {\n" +" \"4o6-interface\": \"\",\n" +" \"4o6-interface-id\": \"\",\n" +" \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" +" \"client-class\": \"gamma\",\n" +" \"id\": 3,\n" +" \"match-client-id\": true,\n" +" \"next-server\": \"0.0.0.0\",\n" +" \"option-data\": [ ],\n" +" \"pools\": [\n" +" {\n" +" \"option-data\": [ ],\n" +" \"pool\": \"192.0.4.101-192.0.4.150\"\n" +" }\n" +" ],\n" +" \"rebind-timer\": 2000,\n" +" \"relay\": {\n" +" \"ip-address\": \"0.0.0.0\"\n" +" },\n" +" \"renew-timer\": 1000,\n" +" \"reservation-mode\": \"all\",\n" +" \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" +" \"subnet\": \"192.0.4.0/24\",\n" +" \"valid-lifetime\": 4000\n" +" },\n" +" {\n" +" \"4o6-interface\": \"\",\n" +" \"4o6-interface-id\": \"\",\n" +" \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" +" \"id\": 4,\n" +" \"match-client-id\": true,\n" +" \"next-server\": \"0.0.0.0\",\n" +" \"option-data\": [ ],\n" +" \"pools\": [\n" +" {\n" +" \"option-data\": [ ],\n" +" \"pool\": \"192.0.5.101-192.0.5.150\"\n" +" }\n" +" ],\n" +" \"rebind-timer\": 2000,\n" +" \"relay\": {\n" +" \"ip-address\": \"0.0.0.0\"\n" +" },\n" +" \"renew-timer\": 1000,\n" +" \"reservation-mode\": \"all\",\n" +" \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" +" \"subnet\": \"192.0.5.0/24\",\n" +" \"valid-lifetime\": 4000\n" +" }\n" +" ]\n" +" }\n", + // CONFIGURATION 42 +"{\n" +" \"decline-probation-period\": 86400,\n" +" \"dhcp-ddns\": {\n" +" \"always-include-fqdn\": false,\n" +" \"enable-updates\": false,\n" +" \"generated-prefix\": \"myhost\",\n" +" \"max-queue-size\": 1024,\n" +" \"ncr-format\": \"JSON\",\n" +" \"ncr-protocol\": \"UDP\",\n" +" \"override-client-update\": false,\n" +" \"override-no-update\": false,\n" +" \"qualifying-suffix\": \"\",\n" +" \"replace-client-name\": \"never\",\n" +" \"sender-ip\": \"0.0.0.0\",\n" +" \"sender-port\": 0,\n" +" \"server-ip\": \"127.0.0.1\",\n" +" \"server-port\": 53001\n" +" },\n" +" \"dhcp4o6-port\": 0,\n" +" \"echo-client-id\": true,\n" +" \"expired-leases-processing\": {\n" +" \"flush-reclaimed-timer-wait-time\": 25,\n" +" \"hold-reclaimed-time\": 3600,\n" +" \"max-reclaim-leases\": 100,\n" +" \"max-reclaim-time\": 250,\n" +" \"reclaim-timer-wait-time\": 10,\n" +" \"unwarned-reclaim-cycles\": 5\n" +" },\n" +" \"hooks-libraries\": [ ],\n" +" \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n" +" \"interfaces-config\": {\n" +" \"interfaces\": [ \"*\" ],\n" +" \"re-detect\": false\n" +" },\n" +" \"lease-database\": {\n" +" \"type\": \"memfile\"\n" +" },\n" +" \"option-data\": [ ],\n" +" \"option-def\": [ ],\n" +" \"shared-networks\": [ ],\n" +" \"subnet4\": [\n" +" {\n" +" \"4o6-interface\": \"\",\n" +" \"4o6-interface-id\": \"\",\n" +" \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" +" \"id\": 1,\n" +" \"match-client-id\": true,\n" +" \"next-server\": \"0.0.0.0\",\n" +" \"option-data\": [ ],\n" +" \"pools\": [\n" +" {\n" +" \"client-class\": \"alpha\",\n" +" \"option-data\": [ ],\n" +" \"pool\": \"192.0.2.1-192.0.2.100\"\n" +" },\n" +" {\n" +" \"client-class\": \"beta\",\n" +" \"known-clients\": \"never\",\n" +" \"option-data\": [ ],\n" +" \"pool\": \"192.0.3.101-192.0.3.150\"\n" +" },\n" +" {\n" +" \"client-class\": \"gamma\",\n" +" \"known-clients\": \"only\",\n" +" \"option-data\": [ ],\n" +" \"pool\": \"192.0.4.101-192.0.4.150\"\n" +" },\n" +" {\n" +" \"option-data\": [ ],\n" +" \"pool\": \"192.0.5.101-192.0.5.150\"\n" +" }\n" +" ],\n" +" \"rebind-timer\": 2000,\n" +" \"relay\": {\n" +" \"ip-address\": \"0.0.0.0\"\n" +" },\n" +" \"renew-timer\": 1000,\n" +" \"reservation-mode\": \"all\",\n" +" \"reservations\": [ ],\n" +" \"server-hostname\": \"\",\n" +" \"subnet\": \"192.0.0.0/16\",\n" +" \"valid-lifetime\": 4000\n" +" }\n" +" ]\n" +" }\n", + // CONFIGURATION 43 +"{\n" +" \"decline-probation-period\": 86400,\n" +" \"dhcp-ddns\": {\n" +" \"always-include-fqdn\": false,\n" +" \"enable-updates\": false,\n" +" \"generated-prefix\": \"myhost\",\n" +" \"max-queue-size\": 1024,\n" +" \"ncr-format\": \"JSON\",\n" +" \"ncr-protocol\": \"UDP\",\n" +" \"override-client-update\": false,\n" +" \"override-no-update\": false,\n" +" \"qualifying-suffix\": \"\",\n" +" \"replace-client-name\": \"never\",\n" +" \"sender-ip\": \"0.0.0.0\",\n" +" \"sender-port\": 0,\n" +" \"server-ip\": \"127.0.0.1\",\n" +" \"server-port\": 53001\n" +" },\n" +" \"dhcp4o6-port\": 0,\n" +" \"echo-client-id\": true,\n" +" \"expired-leases-processing\": {\n" +" \"flush-reclaimed-timer-wait-time\": 25,\n" +" \"hold-reclaimed-time\": 3600,\n" +" \"max-reclaim-leases\": 100,\n" +" \"max-reclaim-time\": 250,\n" +" \"reclaim-timer-wait-time\": 10,\n" +" \"unwarned-reclaim-cycles\": 5\n" +" },\n" +" \"hooks-libraries\": [ ],\n" +" \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n" +" \"interfaces-config\": {\n" +" \"interfaces\": [ \"*\" ],\n" +" \"re-detect\": false\n" +" },\n" +" \"lease-database\": {\n" +" \"type\": \"memfile\"\n" +" },\n" +" \"option-data\": [ ],\n" +" \"option-def\": [ ],\n" +" \"shared-networks\": [ ],\n" +" \"subnet4\": [\n" +" {\n" +" \"4o6-interface\": \"\",\n" +" \"4o6-interface-id\": \"\",\n" +" \"4o6-subnet\": \"\",\n" +" \"boot-file-name\": \"\",\n" " \"id\": 123,\n" " \"match-client-id\": true,\n" " \"next-server\": \"0.0.0.0\",\n" @@ -5071,7 +5388,7 @@ const char* UNPARSED_CONFIGS[] = { " }\n" " ]\n" " }\n", - // CONFIGURATION 42 + // CONFIGURATION 44 "{\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" @@ -5171,7 +5488,7 @@ const char* UNPARSED_CONFIGS[] = { " }\n" " ]\n" " }\n", - // CONFIGURATION 43 + // CONFIGURATION 45 "{\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" @@ -5319,7 +5636,7 @@ const char* UNPARSED_CONFIGS[] = { " }\n" " ]\n" " }\n", - // CONFIGURATION 44 + // CONFIGURATION 46 "{\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" @@ -5362,7 +5679,7 @@ const char* UNPARSED_CONFIGS[] = { " \"shared-networks\": [ ],\n" " \"subnet4\": [ ]\n" " }\n", - // CONFIGURATION 45 + // CONFIGURATION 47 "{\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" @@ -5405,7 +5722,7 @@ const char* UNPARSED_CONFIGS[] = { " \"shared-networks\": [ ],\n" " \"subnet4\": [ ]\n" " }\n", - // CONFIGURATION 46 + // CONFIGURATION 48 "{\n" " \"decline-probation-period\": 12345,\n" " \"dhcp-ddns\": {\n" @@ -5448,7 +5765,7 @@ const char* UNPARSED_CONFIGS[] = { " \"shared-networks\": [ ],\n" " \"subnet4\": [ ]\n" " }\n", - // CONFIGURATION 47 + // CONFIGURATION 49 "{\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" @@ -5491,7 +5808,7 @@ const char* UNPARSED_CONFIGS[] = { " \"shared-networks\": [ ],\n" " \"subnet4\": [ ]\n" " }\n", - // CONFIGURATION 48 + // CONFIGURATION 50 "{\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" @@ -5561,7 +5878,7 @@ const char* UNPARSED_CONFIGS[] = { " }\n" " ]\n" " }\n", - // CONFIGURATION 49 + // CONFIGURATION 51 "{\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" @@ -5631,7 +5948,7 @@ const char* UNPARSED_CONFIGS[] = { " }\n" " ]\n" " }\n", - // CONFIGURATION 50 + // CONFIGURATION 52 "{\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" @@ -5701,7 +6018,7 @@ const char* UNPARSED_CONFIGS[] = { " }\n" " ]\n" " }\n", - // CONFIGURATION 51 + // CONFIGURATION 53 "{\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" @@ -5771,7 +6088,7 @@ const char* UNPARSED_CONFIGS[] = { " }\n" " ]\n" " }\n", - // CONFIGURATION 52 + // CONFIGURATION 54 "{\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" @@ -5841,7 +6158,7 @@ const char* UNPARSED_CONFIGS[] = { " }\n" " ]\n" " }\n", - // CONFIGURATION 53 + // CONFIGURATION 55 "{\n" " \"client-classes\": [\n" " {\n" @@ -5937,7 +6254,7 @@ const char* UNPARSED_CONFIGS[] = { " }\n" " ]\n" " }\n", - // CONFIGURATION 54 + // CONFIGURATION 56 "{\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" @@ -6007,7 +6324,7 @@ const char* UNPARSED_CONFIGS[] = { " }\n" " ]\n" " }\n", - // CONFIGURATION 55 + // CONFIGURATION 57 "{\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" @@ -6078,7 +6395,7 @@ const char* UNPARSED_CONFIGS[] = { " }\n" " ]\n" " }\n", - // CONFIGURATION 56 + // CONFIGURATION 58 "{\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" @@ -6153,7 +6470,7 @@ const char* UNPARSED_CONFIGS[] = { " }\n" " ]\n" " }\n", - // CONFIGURATION 57 + // CONFIGURATION 59 "{\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" diff --git a/src/bin/dhcp6/dhcp6_lexer.cc b/src/bin/dhcp6/dhcp6_lexer.cc index cd5397d241..52b3cc4701 100644 --- a/src/bin/dhcp6/dhcp6_lexer.cc +++ b/src/bin/dhcp6/dhcp6_lexer.cc @@ -3014,6 +3014,7 @@ YY_RULE_SETUP { switch(driver.ctx_) { case isc::dhcp::Parser6Context::POOLS: + case isc::dhcp::Parser6Context::PD_POOLS: return isc::dhcp::Dhcp6Parser::make_KNOWN_CLIENTS(driver.loc_); default: return isc::dhcp::Dhcp6Parser::make_STRING("known-clients", driver.loc_); diff --git a/src/bin/dhcp6/dhcp6_lexer.ll b/src/bin/dhcp6/dhcp6_lexer.ll index 4808abeb27..fba59d48e0 100644 --- a/src/bin/dhcp6/dhcp6_lexer.ll +++ b/src/bin/dhcp6/dhcp6_lexer.ll @@ -830,6 +830,7 @@ ControlCharacterFill [^"\\]|\\{JSONEscapeSequence} \"known-clients\" { switch(driver.ctx_) { case isc::dhcp::Parser6Context::POOLS: + case isc::dhcp::Parser6Context::PD_POOLS: return isc::dhcp::Dhcp6Parser::make_KNOWN_CLIENTS(driver.loc_); default: return isc::dhcp::Dhcp6Parser::make_STRING("known-clients", driver.loc_); diff --git a/src/bin/dhcp6/tests/classify_unittests.cc b/src/bin/dhcp6/tests/classify_unittests.cc index 7a81310f92..d8967e8ffe 100644 --- a/src/bin/dhcp6/tests/classify_unittests.cc +++ b/src/bin/dhcp6/tests/classify_unittests.cc @@ -735,6 +735,93 @@ TEST_F(ClassifyTest, clientClassifyPool) { EXPECT_TRUE(ia_na3->getOption(D6O_IAADDR)); } +// Checks if the known-clients field is indeed used for pool selection. +TEST_F(ClassifyTest, clientKnownPool) { + IfaceMgrTestConfig test_config(true); + + NakedDhcpv6Srv srv(0); + + // This test configures 2 pools. + std::string config = "{ \"interfaces-config\": {" + " \"interfaces\": [ \"*\" ]" + "}," + "\"preferred-lifetime\": 3000," + "\"rebind-timer\": 2000, " + "\"renew-timer\": 1000, " + "\"client-classes\": [ " + " { " + " \"name\": \"foo\" " + " }, " + " { " + " \"name\": \"bar\" " + " } " + "], " + "\"subnet6\": [ " + " { \"pools\": [ " + " { " + " \"pool\": \"2001:db8:1::/64\", " + " \"known-clients\": \"only\" " + " }, " + " { " + " \"pool\": \"2001:db8:2::/64\", " + " \"known-clients\": \"never\" " + " } " + " ], " + " \"subnet\": \"2001:db8:2::/40\", " + " \"reservations\": [ " + " { \"duid\": \"01:02:03:04\", \"hostname\": \"foo\" } ] " + " } " + "], " + "\"valid-lifetime\": 4000 }"; + + ASSERT_NO_THROW(configure(config)); + + OptionPtr clientid1 = generateClientId(); + Pkt6Ptr query1 = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234)); + query1->setRemoteAddr(IOAddress("2001:db8:1::3")); + query1->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000)); + query1->addOption(clientid1); + query1->setIface("eth1"); + + // First pool requires reservation so the second will be used + srv.classifyPacket(query1); + Pkt6Ptr response1 = srv.processSolicit(query1); + ASSERT_TRUE(response1); + OptionPtr ia_na1 = response1->getOption(D6O_IA_NA); + ASSERT_TRUE(ia_na1); + EXPECT_FALSE(ia_na1->getOption(D6O_STATUS_CODE)); + OptionPtr iaaddr1 = ia_na1->getOption(D6O_IAADDR); + ASSERT_TRUE(iaaddr1); + boost::shared_ptr addr1 = + boost::dynamic_pointer_cast(iaaddr1); + ASSERT_TRUE(addr1); + EXPECT_EQ("2001:db8:2::", addr1->getAddress().toText()); + + // Try with DUID 01:02:03:04 + uint8_t duid[] = { 0x01, 0x02, 0x03, 0x04 }; + OptionBuffer buf(duid, duid + sizeof(duid)); + OptionPtr clientid2(new Option(Option::V6, D6O_CLIENTID, buf)); + Pkt6Ptr query2 = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 2345)); + query2->setRemoteAddr(IOAddress("2001:db8:1::3")); + query2->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000)); + query2->addOption(clientid2); + query2->setIface("eth1"); + + // Now the first pool will be used + srv.classifyPacket(query2); + Pkt6Ptr response2 = srv.processSolicit(query2); + ASSERT_TRUE(response2); + OptionPtr ia_na2 = response2->getOption(D6O_IA_NA); + ASSERT_TRUE(ia_na2); + EXPECT_FALSE(ia_na2->getOption(D6O_STATUS_CODE)); + OptionPtr iaaddr2 = ia_na2->getOption(D6O_IAADDR); + ASSERT_TRUE(iaaddr2); + boost::shared_ptr addr2 = + boost::dynamic_pointer_cast(iaaddr2); + ASSERT_TRUE(addr2); + EXPECT_EQ("2001:db8:1::", addr2->getAddress().toText()); +} + // Tests whether a packet with custom vendor-class (not erouter or docsis) // is classified properly. TEST_F(ClassifyTest, vendorClientClassification2) { diff --git a/src/bin/dhcp6/tests/config_parser_unittest.cc b/src/bin/dhcp6/tests/config_parser_unittest.cc index 27f4edc129..21c209604b 100644 --- a/src/bin/dhcp6/tests/config_parser_unittest.cc +++ b/src/bin/dhcp6/tests/config_parser_unittest.cc @@ -4149,11 +4149,13 @@ TEST_F(Dhcp6ParserTest, classifyPools) { " }," " {" " \"pool\": \"2001:db8:2::/80\", " - " \"client-class\": \"beta\" " + " \"client-class\": \"beta\", " + " \"known-clients\": \"never\" " " }," " {" " \"pool\": \"2001:db8:3::/80\", " - " \"client-class\": \"gamma\" " + " \"client-class\": \"gamma\", " + " \"known-clients\": \"only\" " " }," " {" " \"pool\": \"2001:db8:4::/80\" " @@ -4181,10 +4183,14 @@ TEST_F(Dhcp6ParserTest, classifyPools) { // everyone). ClientClasses classes; classes.insert("alpha"); - EXPECT_TRUE (pools.at(0)->clientSupported(classes, false)); + EXPECT_TRUE(pools.at(0)->clientSupported(classes, false)); + EXPECT_TRUE(pools.at(0)->clientSupported(classes, true)); EXPECT_FALSE(pools.at(1)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(1)->clientSupported(classes, true)); EXPECT_FALSE(pools.at(2)->clientSupported(classes, false)); - EXPECT_TRUE (pools.at(3)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(2)->clientSupported(classes, true)); + EXPECT_TRUE(pools.at(3)->clientSupported(classes, false)); + EXPECT_TRUE(pools.at(3)->clientSupported(classes, true)); // Let's check if client belonging to beta class is supported in pool[1] // and not supported in any other pool (except pool[3], which allows @@ -4192,9 +4198,13 @@ TEST_F(Dhcp6ParserTest, classifyPools) { classes.clear(); classes.insert("beta"); EXPECT_FALSE(pools.at(0)->clientSupported(classes, false)); - EXPECT_TRUE (pools.at(1)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(0)->clientSupported(classes, true)); + EXPECT_TRUE(pools.at(1)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(1)->clientSupported(classes, true)); EXPECT_FALSE(pools.at(2)->clientSupported(classes, false)); - EXPECT_TRUE (pools.at(3)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(2)->clientSupported(classes, true)); + EXPECT_TRUE(pools.at(3)->clientSupported(classes, false)); + EXPECT_TRUE(pools.at(3)->clientSupported(classes, true)); // Let's check if client belonging to gamma class is supported in pool[2] // and not supported in any other pool (except pool[3], which allows @@ -4202,26 +4212,38 @@ TEST_F(Dhcp6ParserTest, classifyPools) { classes.clear(); classes.insert("gamma"); EXPECT_FALSE(pools.at(0)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(0)->clientSupported(classes, true)); EXPECT_FALSE(pools.at(1)->clientSupported(classes, false)); - EXPECT_TRUE (pools.at(2)->clientSupported(classes, false)); - EXPECT_TRUE (pools.at(3)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(1)->clientSupported(classes, true)); + EXPECT_FALSE(pools.at(2)->clientSupported(classes, false)); + EXPECT_TRUE(pools.at(2)->clientSupported(classes, true)); + EXPECT_TRUE(pools.at(3)->clientSupported(classes, false)); + EXPECT_TRUE(pools.at(3)->clientSupported(classes, true)); // Let's check if client belonging to some other class (not mentioned in // the config) is supported only in pool[3], which allows everyone. classes.clear(); classes.insert("delta"); EXPECT_FALSE(pools.at(0)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(0)->clientSupported(classes, true)); EXPECT_FALSE(pools.at(1)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(1)->clientSupported(classes, true)); EXPECT_FALSE(pools.at(2)->clientSupported(classes, false)); - EXPECT_TRUE (pools.at(3)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(2)->clientSupported(classes, true)); + EXPECT_TRUE(pools.at(3)->clientSupported(classes, false)); + EXPECT_TRUE(pools.at(3)->clientSupported(classes, true)); // Finally, let's check class-less client. He should be allowed only in // the last pool, which does not have any class restrictions. classes.clear(); EXPECT_FALSE(pools.at(0)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(0)->clientSupported(classes, true)); EXPECT_FALSE(pools.at(1)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(1)->clientSupported(classes, true)); EXPECT_FALSE(pools.at(2)->clientSupported(classes, false)); - EXPECT_TRUE (pools.at(3)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(2)->clientSupported(classes, true)); + EXPECT_TRUE(pools.at(3)->clientSupported(classes, false)); + EXPECT_TRUE(pools.at(3)->clientSupported(classes, true)); } // Goal of this test is to verify that multiple pdpools can be configured @@ -4243,13 +4265,15 @@ TEST_F(Dhcp6ParserTest, classifyPdPools) { " \"prefix-len\": 48, " " \"delegated-len\": 64, " " \"prefix\": \"2001:db8:2::\", " - " \"client-class\": \"beta\" " + " \"client-class\": \"beta\", " + " \"known-clients\": \"never\" " " }," " {" " \"prefix-len\": 48, " " \"delegated-len\": 64, " " \"prefix\": \"2001:db8:3::\", " - " \"client-class\": \"gamma\" " + " \"client-class\": \"gamma\", " + " \"known-clients\": \"only\" " " }," " {" " \"prefix-len\": 48, " @@ -4279,10 +4303,14 @@ TEST_F(Dhcp6ParserTest, classifyPdPools) { // everyone). ClientClasses classes; classes.insert("alpha"); - EXPECT_TRUE (pools.at(0)->clientSupported(classes, false)); + EXPECT_TRUE(pools.at(0)->clientSupported(classes, false)); + EXPECT_TRUE(pools.at(0)->clientSupported(classes, true)); EXPECT_FALSE(pools.at(1)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(1)->clientSupported(classes, true)); EXPECT_FALSE(pools.at(2)->clientSupported(classes, false)); - EXPECT_TRUE (pools.at(3)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(2)->clientSupported(classes, true)); + EXPECT_TRUE(pools.at(3)->clientSupported(classes, false)); + EXPECT_TRUE(pools.at(3)->clientSupported(classes, true)); // Let's check if client belonging to beta class is supported in pool[1] // and not supported in any other pool (except pool[3], which allows @@ -4290,9 +4318,13 @@ TEST_F(Dhcp6ParserTest, classifyPdPools) { classes.clear(); classes.insert("beta"); EXPECT_FALSE(pools.at(0)->clientSupported(classes, false)); - EXPECT_TRUE (pools.at(1)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(0)->clientSupported(classes, true)); + EXPECT_TRUE(pools.at(1)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(1)->clientSupported(classes, true)); EXPECT_FALSE(pools.at(2)->clientSupported(classes, false)); - EXPECT_TRUE (pools.at(3)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(2)->clientSupported(classes, true)); + EXPECT_TRUE(pools.at(3)->clientSupported(classes, false)); + EXPECT_TRUE(pools.at(3)->clientSupported(classes, true)); // Let's check if client belonging to gamma class is supported in pool[2] // and not supported in any other pool (except pool[3], which allows @@ -4300,26 +4332,38 @@ TEST_F(Dhcp6ParserTest, classifyPdPools) { classes.clear(); classes.insert("gamma"); EXPECT_FALSE(pools.at(0)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(0)->clientSupported(classes, true)); EXPECT_FALSE(pools.at(1)->clientSupported(classes, false)); - EXPECT_TRUE (pools.at(2)->clientSupported(classes, false)); - EXPECT_TRUE (pools.at(3)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(1)->clientSupported(classes, true)); + EXPECT_FALSE(pools.at(2)->clientSupported(classes, false)); + EXPECT_TRUE(pools.at(2)->clientSupported(classes, true)); + EXPECT_TRUE(pools.at(3)->clientSupported(classes, false)); + EXPECT_TRUE(pools.at(3)->clientSupported(classes, true)); // Let's check if client belonging to some other class (not mentioned in // the config) is supported only in pool[3], which allows everyone. classes.clear(); classes.insert("delta"); EXPECT_FALSE(pools.at(0)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(0)->clientSupported(classes, true)); EXPECT_FALSE(pools.at(1)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(1)->clientSupported(classes, true)); EXPECT_FALSE(pools.at(2)->clientSupported(classes, false)); - EXPECT_TRUE (pools.at(3)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(2)->clientSupported(classes, true)); + EXPECT_TRUE(pools.at(3)->clientSupported(classes, false)); + EXPECT_TRUE(pools.at(3)->clientSupported(classes, true)); // Finally, let's check class-less client. He should be allowed only in // the last pool, which does not have any class restrictions. classes.clear(); EXPECT_FALSE(pools.at(0)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(0)->clientSupported(classes, true)); EXPECT_FALSE(pools.at(1)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(1)->clientSupported(classes, true)); EXPECT_FALSE(pools.at(2)->clientSupported(classes, false)); - EXPECT_TRUE (pools.at(3)->clientSupported(classes, false)); + EXPECT_FALSE(pools.at(2)->clientSupported(classes, true)); + EXPECT_TRUE(pools.at(3)->clientSupported(classes, false)); + EXPECT_TRUE(pools.at(3)->clientSupported(classes, true)); } // This test checks the ability of the server to parse a configuration diff --git a/src/bin/dhcp6/tests/get_config_unittest.cc b/src/bin/dhcp6/tests/get_config_unittest.cc index 22f8b4d971..05996adee3 100644 --- a/src/bin/dhcp6/tests/get_config_unittest.cc +++ b/src/bin/dhcp6/tests/get_config_unittest.cc @@ -1002,10 +1002,12 @@ const char* EXTRACTED_CONFIGS[] = { " },\n" " {\n" " \"client-class\": \"beta\",\n" +" \"known-clients\": \"never\",\n" " \"pool\": \"2001:db8:2::/80\"\n" " },\n" " {\n" " \"client-class\": \"gamma\",\n" +" \"known-clients\": \"only\",\n" " \"pool\": \"2001:db8:3::/80\"\n" " },\n" " {\n" @@ -1037,12 +1039,14 @@ const char* EXTRACTED_CONFIGS[] = { " {\n" " \"client-class\": \"beta\",\n" " \"delegated-len\": 64,\n" +" \"known-clients\": \"never\",\n" " \"prefix\": \"2001:db8:2::\",\n" " \"prefix-len\": 48\n" " },\n" " {\n" " \"client-class\": \"gamma\",\n" " \"delegated-len\": 64,\n" +" \"known-clients\": \"only\",\n" " \"prefix\": \"2001:db8:3::\",\n" " \"prefix-len\": 48\n" " },\n" @@ -4454,11 +4458,13 @@ const char* UNPARSED_CONFIGS[] = { " },\n" " {\n" " \"client-class\": \"beta\",\n" +" \"known-clients\": \"never\",\n" " \"option-data\": [ ],\n" " \"pool\": \"2001:db8:2::/80\"\n" " },\n" " {\n" " \"client-class\": \"gamma\",\n" +" \"known-clients\": \"only\",\n" " \"option-data\": [ ],\n" " \"pool\": \"2001:db8:3::/80\"\n" " },\n" @@ -4546,6 +4552,7 @@ const char* UNPARSED_CONFIGS[] = { " {\n" " \"client-class\": \"beta\",\n" " \"delegated-len\": 64,\n" +" \"known-clients\": \"never\",\n" " \"option-data\": [ ],\n" " \"prefix\": \"2001:db8:2::\",\n" " \"prefix-len\": 48\n" @@ -4553,6 +4560,7 @@ const char* UNPARSED_CONFIGS[] = { " {\n" " \"client-class\": \"gamma\",\n" " \"delegated-len\": 64,\n" +" \"known-clients\": \"only\",\n" " \"option-data\": [ ],\n" " \"prefix\": \"2001:db8:3::\",\n" " \"prefix-len\": 48\n" diff --git a/src/lib/dhcpsrv/tests/subnet_unittest.cc b/src/lib/dhcpsrv/tests/subnet_unittest.cc index 8da02897ae..272600088d 100644 --- a/src/lib/dhcpsrv/tests/subnet_unittest.cc +++ b/src/lib/dhcpsrv/tests/subnet_unittest.cc @@ -265,6 +265,44 @@ TEST(Subnet4Test, pool4InSubnet4) { ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, three_classes, false, IOAddress("192.1.2.195"))); EXPECT_EQ(mypool, pool3); + + // And now known clients + EXPECT_EQ(Pool::SERVE_BOTH, pool1->getKnownClients()); + pool2->setKnownClients(Pool::SERVE_KNOWN); + pool3->setKnownClients(Pool::SERVE_UNKNOWN); + pool4->setKnownClients(Pool::SERVE_UNKNOWN); + + ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class, false, + IOAddress("192.1.2.64"))); + EXPECT_EQ(mypool, pool1); + ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class, true, + IOAddress("192.1.2.64"))); + EXPECT_EQ(mypool, pool1); + ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class, false, + IOAddress("192.1.2.129"))); + EXPECT_FALSE(mypool); + ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class, true, + IOAddress("192.1.2.129"))); + + EXPECT_EQ(mypool, pool2); + ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class, false, + IOAddress("192.1.2.195"))); + EXPECT_FALSE(mypool); + ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class, true, + IOAddress("192.1.2.195"))); + EXPECT_FALSE(mypool); + ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, bar_class, false, + IOAddress("192.1.2.195"))); + EXPECT_EQ(mypool, pool3); + ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, bar_class, true, + IOAddress("192.1.2.195"))); + EXPECT_FALSE(mypool); + ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class, false, + IOAddress("192.1.2.201"))); + EXPECT_EQ(mypool, pool4); + ASSERT_NO_THROW(mypool = subnet->getPool(Lease::TYPE_V4, no_class, true, + IOAddress("192.1.2.201"))); + EXPECT_FALSE(mypool); } // Check if it's possible to get specified number of possible leases for @@ -323,6 +361,16 @@ TEST(Subnet4Test, getCapacity) { EXPECT_EQ(196, subnet->getPoolCapacity(Lease::TYPE_V4, foo_class, false)); EXPECT_EQ(200, subnet->getPoolCapacity(Lease::TYPE_V4, bar_class, false)); EXPECT_EQ(200, subnet->getPoolCapacity(Lease::TYPE_V4, three_classes, false)); + + // And now known clients + EXPECT_EQ(Pool::SERVE_BOTH, pool1->getKnownClients()); + pool2->setKnownClients(Pool::SERVE_KNOWN); + pool3->setKnownClients(Pool::SERVE_UNKNOWN); + + EXPECT_EQ(132, subnet->getPoolCapacity(Lease::TYPE_V4, no_class, false)); + EXPECT_EQ(196, subnet->getPoolCapacity(Lease::TYPE_V4, no_class, true)); + EXPECT_EQ(136, subnet->getPoolCapacity(Lease::TYPE_V4, bar_class, false)); + EXPECT_EQ(196, subnet->getPoolCapacity(Lease::TYPE_V4, bar_class, true)); } // Checks that it is not allowed to add invalid pools. @@ -559,6 +607,11 @@ TEST(Subnet4Test, inRangeinPool) { three_classes.insert("bar"); three_classes.insert("baz"); EXPECT_TRUE(subnet->inPool(Lease::TYPE_V4, IOAddress("192.2.3.4"), three_classes, false)); + + // Add known clients + pool1->setKnownClients(Pool::SERVE_UNKNOWN); + EXPECT_TRUE(subnet->inPool(Lease::TYPE_V4, IOAddress("192.2.3.4"), three_classes, false)); + EXPECT_FALSE(subnet->inPool(Lease::TYPE_V4, IOAddress("192.2.3.4"), three_classes, true)); } // This test checks if the toText() method returns text representation @@ -789,6 +842,13 @@ TEST(Subnet6Test, Pool6getCapacity) { EXPECT_EQ(uint64_t(4294967296ull + 4294967296ull + 65536), subnet->getPoolCapacity(Lease::TYPE_NA, three_classes, false)); + // Add known clients + pool2->setKnownClients(Pool::SERVE_KNOWN); + EXPECT_EQ(uint64_t(65536), + subnet->getPoolCapacity(Lease::TYPE_NA, no_class, false)); + EXPECT_EQ(uint64_t(4294967296ull + 65536), + subnet->getPoolCapacity(Lease::TYPE_NA, no_class, true)); + // This is 2^64 prefixes. We're overflown uint64_t. PoolPtr pool4(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:4::"), 64)); subnet->addPool(pool4); @@ -799,7 +859,6 @@ TEST(Subnet6Test, Pool6getCapacity) { subnet->addPool(pool5); EXPECT_EQ(std::numeric_limits::max(), subnet->getPoolCapacity(Lease::TYPE_NA)); - } // Test checks whether the number of prefixes available in the pools are @@ -903,6 +962,33 @@ TEST(Subnet6Test, Pool6InSubnet6) { mypool = subnet->getPool(Lease::TYPE_NA, three_classes, false, IOAddress("2001:db8:1:3::dead:beef")); EXPECT_EQ(mypool, pool3); + + // Add know cients + pool3->setKnownClients(Pool::SERVE_UNKNOWN); + mypool = subnet->getPool(Lease::TYPE_NA, no_class, false, + IOAddress("2001:db8:1:3::dead:beef")); + EXPECT_FALSE(mypool); + mypool = subnet->getPool(Lease::TYPE_NA, no_class, true, + IOAddress("2001:db8:1:3::dead:beef")); + EXPECT_FALSE(mypool); + mypool = subnet->getPool(Lease::TYPE_NA, foo_class, false, + IOAddress("2001:db8:1:3::dead:beef")); + EXPECT_FALSE(mypool); + mypool = subnet->getPool(Lease::TYPE_NA, foo_class, true, + IOAddress("2001:db8:1:3::dead:beef")); + EXPECT_FALSE(mypool); + mypool = subnet->getPool(Lease::TYPE_NA, bar_class, false, + IOAddress("2001:db8:1:3::dead:beef")); + EXPECT_EQ(mypool, pool3); + mypool = subnet->getPool(Lease::TYPE_NA, bar_class, true, + IOAddress("2001:db8:1:3::dead:beef")); + EXPECT_FALSE(mypool); + mypool = subnet->getPool(Lease::TYPE_NA, three_classes, false, + IOAddress("2001:db8:1:3::dead:beef")); + EXPECT_EQ(mypool, pool3); + mypool = subnet->getPool(Lease::TYPE_NA, three_classes, true, + IOAddress("2001:db8:1:3::dead:beef")); + EXPECT_FALSE(mypool); } // Check if Subnet6 supports different types of pools properly. @@ -1414,6 +1500,11 @@ TEST(Subnet6Test, inRangeinPool) { three_classes.insert("bar"); three_classes.insert("baz"); EXPECT_TRUE(subnet->inPool(Lease::TYPE_NA, IOAddress("2001:db8::18"), three_classes, false)); + + // Add known clients + pool1->setKnownClients(Pool::SERVE_KNOWN); + EXPECT_FALSE(subnet->inPool(Lease::TYPE_NA, IOAddress("2001:db8::18"), three_classes, false)); + EXPECT_TRUE(subnet->inPool(Lease::TYPE_NA, IOAddress("2001:db8::18"), three_classes, true)); } // This test verifies that inRange() and inPool() methods work properly -- 2.47.2