From: Francis Dupont Date: Mon, 29 Jan 2018 17:37:53 +0000 (+0100) Subject: [master] Merged trac5425a (class in pools) X-Git-Tag: trac5524_base~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3d6bb5b1d43ae84d09a733d282e50b9f2091190c;p=thirdparty%2Fkea.git [master] Merged trac5425a (class in pools) --- 3d6bb5b1d43ae84d09a733d282e50b9f2091190c diff --cc src/bin/dhcp4/tests/dhcp4_srv_unittest.cc index bd9238f7fc,f650d33867..25b540c1ff --- a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc +++ b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc @@@ -2318,10 -2315,78 +2318,79 @@@ TEST_F(Dhcpv4SrvTest, clientClassify) dis->addClass("foo"); // This time it should work - EXPECT_TRUE(srv_.selectSubnet(dis)); + EXPECT_TRUE(srv_.selectSubnet(dis, drop)); + EXPECT_FALSE(drop); } + // Checks if the client-class field is indeed used for pool selection. + TEST_F(Dhcpv4SrvTest, clientPoolClassify) { + IfaceMgrTestConfig test_config(true); + IfaceMgr::instance().openSockets4(); + + NakedDhcpv4Srv srv(0); + + // This test configures 2 pools. + // The second pool does not play any role here. The client's + // IP address belongs to the first pool, so only that first + // pool is being tested. + string config = "{ \"interfaces-config\": {" + " \"interfaces\": [ \"*\" ]" + "}," + "\"rebind-timer\": 2000, " + "\"renew-timer\": 1000, " + "\"subnet4\": [ " + "{ \"pools\": [ { " + " \"pool\": \"192.0.2.1 - 192.0.2.100\", " + " \"client-class\": \"foo\" }, " + " { \"pool\": \"192.0.3.1 - 192.0.3.100\", " + " \"client-class\": \"xyzzy\" } ], " + " \"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 that we'll use for classification + 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); + + // This discover does not belong to foo class, so it will not + // be serviced + Pkt4Ptr offer = srv.processDiscover(dis); + EXPECT_FALSE(offer); + + // Let's add the packet to bar class and try again. + dis->addClass("bar"); + + // Still not supported, because it belongs to wrong class. + offer = srv.processDiscover(dis); + EXPECT_FALSE(offer); + + // Let's add it to matching class. + dis->addClass("foo"); + + // This time it should work + offer = srv.processDiscover(dis); + ASSERT_TRUE(offer); + EXPECT_EQ(DHCPOFFER, offer->getType()); + EXPECT_FALSE(offer->getYiaddr().isV4Zero()); + } + // Verifies last resort option 43 is backward compatible TEST_F(Dhcpv4SrvTest, option43LastResort) { IfaceMgrTestConfig test_config(true); diff --cc src/bin/dhcp6/tests/classify_unittests.cc index 3ab0a9c2cf,e09ad8ea6f..b63a297c54 --- a/src/bin/dhcp6/tests/classify_unittests.cc +++ b/src/bin/dhcp6/tests/classify_unittests.cc @@@ -643,10 -614,88 +617,89 @@@ TEST_F(ClassifyTest, clientClassifySubn sol->addClass("foo"); // This time it should work - EXPECT_TRUE(srv_.selectSubnet(sol)); + EXPECT_TRUE(srv_.selectSubnet(sol, drop)); + EXPECT_FALSE(drop); } + // Checks if the client-class field is indeed used for pool selection. + TEST_F(ClassifyTest, clientClassifyPool) { + IfaceMgrTestConfig test_config(true); + + NakedDhcpv6Srv srv(0); + + // This test configures 2 pools. + // The second pool does not play any role here. The client's + // IP address belongs to the first pool, so only that first + // pool is being tested. + 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\", " + " \"client-class\": \"foo\" " + " }, " + " { " + " \"pool\": \"2001:db8:2::/64\", " + " \"client-class\": \"xyzzy\" " + " } " + " ], " + " \"subnet\": \"2001:db8:2::/40\" " + " } " + "], " + "\"valid-lifetime\": 4000 }"; + + ASSERT_NO_THROW(configure(config)); + + Pkt6Ptr query1 = createSolicit("2001:db8:1::3"); + Pkt6Ptr query2 = createSolicit("2001:db8:1::3"); + Pkt6Ptr query3 = createSolicit("2001:db8:1::3"); + + // This discover does not belong to foo class, so it will not + // be serviced + srv.classifyPacket(query1); + Pkt6Ptr response1 = srv.processSolicit(query1); + ASSERT_TRUE(response1); + OptionPtr ia_na1 = response1->getOption(D6O_IA_NA); + ASSERT_TRUE(ia_na1); + EXPECT_TRUE(ia_na1->getOption(D6O_STATUS_CODE)); + EXPECT_FALSE(ia_na1->getOption(D6O_IAADDR)); + + // Let's add the packet to bar class and try again. + query2->addClass("bar"); + // Still not supported, because it belongs to wrong class. + srv.classifyPacket(query2); + Pkt6Ptr response2 = srv.processSolicit(query2); + ASSERT_TRUE(response2); + OptionPtr ia_na2 = response2->getOption(D6O_IA_NA); + ASSERT_TRUE(ia_na2); + EXPECT_TRUE(ia_na2->getOption(D6O_STATUS_CODE)); + EXPECT_FALSE(ia_na2->getOption(D6O_IAADDR)); + + // Let's add it to matching class. + query3->addClass("foo"); + // This time it should work + srv.classifyPacket(query3); + Pkt6Ptr response3 = srv.processSolicit(query3); + ASSERT_TRUE(response3); + OptionPtr ia_na3 = response3->getOption(D6O_IA_NA); + ASSERT_TRUE(ia_na3); + EXPECT_FALSE(ia_na3->getOption(D6O_STATUS_CODE)); + EXPECT_TRUE(ia_na3->getOption(D6O_IAADDR)); + } + // Tests whether a packet with custom vendor-class (not erouter or docsis) // is classified properly. TEST_F(ClassifyTest, vendorClientClassification2) {