From: Tomek Mrugalski Date: Thu, 13 Feb 2014 18:10:18 +0000 (+0100) Subject: [3322] Unit-tests for DHCPv4 implemented. X-Git-Tag: bind10-1.2.0beta1-release~27^2~10 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6975ad04e89daa261d03d2d8383a8b960fed3bae;p=thirdparty%2Fkea.git [3322] Unit-tests for DHCPv4 implemented. --- diff --git a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc index 91698a8cbc..cdc9e1fc44 100644 --- a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc +++ b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc @@ -3379,14 +3379,6 @@ TEST_F(Dhcpv4SrvTest, relayOverride) { NakedDhcpv4Srv srv(0); - ConstElementPtr status; - - // This test configures 2 subnets. We actually only need the - // first one, but since there's still this ugly hack that picks - // the pool if there is only one, we must use more than one - // subnet. That ugly hack will be removed in #3242, currently - // under review. - // We have 2 subnets defined. Note that both have a relay address // defined. Both are not belonging to the subnets. That is // important, because if the relay belongs to the subnet, there's @@ -3410,11 +3402,13 @@ TEST_F(Dhcpv4SrvTest, relayOverride) { // Use this config to set up the server ElementPtr json = Element::fromJSON(config); + ConstElementPtr status; EXPECT_NO_THROW(status = configureDhcp4Server(srv, json)); ASSERT_TRUE(status); comment_ = config::parseAnswer(rcode_, status); ASSERT_EQ(0, rcode_); + // Let's get the subnet configuration objects const Subnet4Collection* subnets = CfgMgr::instance().getSubnets4(); ASSERT_EQ(2, subnets->size()); diff --git a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc index ea3692e005..1a8e12b315 100644 --- a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc +++ b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc @@ -1806,6 +1806,161 @@ TEST_F(Dhcpv6SrvTest, clientClassify2) { EXPECT_TRUE(srv.selectSubnet(sol)); } +// Checks if relay IP address specified in the relay-info structure in +// subnet4 is being used properly. +TEST_F(Dhcpv6SrvTest, relayOverride) { + + NakedDhcpv6Srv srv(0); + + // We have 2 subnets defined. Note that both have a relay address + // defined. Both are not belonging to the subnets. That is + // important, because if the relay belongs to the subnet, there's + // no need to specify relay override. + string config = "{ \"interfaces\": [ \"*\" ]," + "\"preferred-lifetime\": 3000," + "\"rebind-timer\": 2000, " + "\"renew-timer\": 1000, " + "\"subnet6\": [ " + " { \"pool\": [ \"2001:db8:1::/64\" ]," + " \"subnet\": \"2001:db8:1::/48\", " + " \"relay\": { " + " \"ip-address\": \"2001:db8:3::1\"" + " }" + " }, " + " { \"pool\": [ \"2001:db8:2::/64\" ]," + " \"subnet\": \"2001:db8:2::/48\", " + " \"relay\": { " + " \"ip-address\": \"2001:db8:3::2\"" + " }" + " } " + "]," + "\"valid-lifetime\": 4000 }"; + + // Use this config to set up the server + ElementPtr json = Element::fromJSON(config); + ConstElementPtr status; + EXPECT_NO_THROW(status = configureDhcp6Server(srv, json)); + ASSERT_TRUE(status); + comment_ = config::parseAnswer(rcode_, status); + ASSERT_EQ(0, rcode_); + + // Let's get the subnet configuration objects + const Subnet6Collection* subnets = CfgMgr::instance().getSubnets6(); + ASSERT_EQ(2, subnets->size()); + + // Let's get them for easy reference + Subnet6Ptr subnet1 = (*subnets)[0]; + Subnet6Ptr subnet2 = (*subnets)[1]; + ASSERT_TRUE(subnet1); + ASSERT_TRUE(subnet2); + + Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234)); + sol->setRemoteAddr(IOAddress("2001:db8:1::3")); + sol->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000)); + OptionPtr clientid = generateClientId(); + sol->addOption(clientid); + + // Now pretend the packet came via one relay. + Pkt6::RelayInfo relay; + relay.linkaddr_ = IOAddress("2001:db8:1::1"); + relay.peeraddr_ = IOAddress("fe80::1"); + + sol->relay_info_.push_back(relay); + + // This is just a sanity check, we're using regular method: the relay + // belongs to the first (2001:db8:1::/64) subnet, so it's an easy decision. + EXPECT_TRUE(subnet1 == srv.selectSubnet(sol)); + + // Relay belongs to the second subnet, so it should be selected. + sol->relay_info_.back().linkaddr_ = IOAddress("2001:db8:2::1"); + EXPECT_TRUE(subnet2 == srv.selectSubnet(sol)); + + // Now let's check if the relay override for the first subnets works + sol->relay_info_.back().linkaddr_ = IOAddress("2001:db8:3::1"); + EXPECT_TRUE(subnet1 == srv.selectSubnet(sol)); + + // Now repeat that for relay matching the second subnet. + sol->relay_info_.back().linkaddr_ = IOAddress("2001:db8:3::2"); + EXPECT_TRUE(subnet2 == srv.selectSubnet(sol)); + + // Finally, let's check that completely mismatched relay will not get us + // anything + sol->relay_info_.back().linkaddr_ = IOAddress("2001:db8:1234::1"); + EXPECT_FALSE(srv.selectSubnet(sol)); +} + +// Checks if relay IP address specified in the relay-info structure can be +// used together with client-classification. +TEST_F(Dhcpv6SrvTest, relayOverrideAndClientClass) { + + NakedDhcpv6Srv srv(0); + + // This test configures 2 subnets. They both are on the same link, so they + // have the same relay-ip address. Furthermore, the first subnet is + // reserved for clients that belong to class "foo". + string config = "{ \"interfaces\": [ \"*\" ]," + "\"preferred-lifetime\": 3000," + "\"rebind-timer\": 2000, " + "\"renew-timer\": 1000, " + "\"subnet6\": [ " + " { \"pool\": [ \"2001:db8:1::/64\" ]," + " \"subnet\": \"2001:db8:1::/48\", " + " \"client-class\": \"foo\", " + " \"relay\": { " + " \"ip-address\": \"2001:db8:3::1\"" + " }" + " }, " + " { \"pool\": [ \"2001:db8:2::/64\" ]," + " \"subnet\": \"2001:db8:2::/48\", " + " \"relay\": { " + " \"ip-address\": \"2001:db8:3::1\"" + " }" + " } " + "]," + "\"valid-lifetime\": 4000 }"; + + // Use this config to set up the server + ElementPtr json = Element::fromJSON(config); + ConstElementPtr status; + EXPECT_NO_THROW(status = configureDhcp6Server(srv, json)); + ASSERT_TRUE(status); + comment_ = config::parseAnswer(rcode_, status); + ASSERT_EQ(0, rcode_); + + // Let's get the subnet configuration objects + const Subnet6Collection* subnets = CfgMgr::instance().getSubnets6(); + ASSERT_EQ(2, subnets->size()); + + // Let's get them for easy reference + Subnet6Ptr subnet1 = (*subnets)[0]; + Subnet6Ptr subnet2 = (*subnets)[1]; + ASSERT_TRUE(subnet1); + ASSERT_TRUE(subnet2); + + Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234)); + sol->setRemoteAddr(IOAddress("2001:db8:1::3")); + sol->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000)); + OptionPtr clientid = generateClientId(); + sol->addOption(clientid); + + // Now pretend the packet came via one relay. + Pkt6::RelayInfo relay; + relay.linkaddr_ = IOAddress("2001:db8:3::1"); + relay.peeraddr_ = IOAddress("fe80::1"); + + sol->relay_info_.push_back(relay); + + // This packet does not belong to class foo, so it should be rejected in + // subnet[0], even though the relay-ip matches. It should be accepted in + // subnet[1], because the subnet matches and there are no class + // requirements. + EXPECT_TRUE(subnet2 == srv.selectSubnet(sol)); + + // Now let's add this packet to class foo and recheck. This time it should + // be accepted in the first subnet, because both class and relay-ip match. + sol->addClass("foo"); + EXPECT_TRUE(subnet1 == srv.selectSubnet(sol)); +} /// @todo: Add more negative tests for processX(), e.g. extend sanityCheck() test /// to call processX() methods.