]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[master] Merged trac5425a (class in pools)
authorFrancis Dupont <fdupont@isc.org>
Mon, 29 Jan 2018 17:37:53 +0000 (18:37 +0100)
committerFrancis Dupont <fdupont@isc.org>
Mon, 29 Jan 2018 17:37:53 +0000 (18:37 +0100)
1  2 
src/bin/dhcp4/tests/dhcp4_srv_unittest.cc
src/bin/dhcp6/dhcp6_messages.mes
src/bin/dhcp6/tests/classify_unittests.cc
src/lib/dhcpsrv/alloc_engine.cc
src/lib/dhcpsrv/pool.cc

index bd9238f7fc319b7e45aebe710ad3d971b21a997a,f650d33867f0acbfe3779d4ac5ae2d42c55d0fde..25b540c1ffe9d60539988c4b8fd35f45c0d68028
@@@ -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);
Simple merge
index 3ab0a9c2cfbcedd4350212d9ddffa65d1cc58796,e09ad8ea6fd28cf7e9cb689f157fa053a7f7f8da..b63a297c5438327a3256001265b01f9d7ceb3609
@@@ -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) {
Simple merge
Simple merge