From: Tomek Mrugalski Date: Thu, 13 Feb 2014 17:41:22 +0000 (+0100) Subject: [3322] Unit-tests for relay-ip override implemented. X-Git-Tag: bind10-1.2.0beta1-release~27^2~11 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6a6d055a324242f2b6986848474c1dfc27bf5a0f;p=thirdparty%2Fkea.git [3322] Unit-tests for relay-ip override implemented. --- diff --git a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc index ba787aa4d6..91698a8cbc 100644 --- a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc +++ b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc @@ -3373,6 +3373,161 @@ TEST_F(Dhcpv4SrvTest, clientClassify2) { EXPECT_TRUE(srv.selectSubnet(dis)); } +// Checks if relay IP address specified in the relay-info structure in +// subnet4 is being used properly. +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 + // no need to specify relay override. + string config = "{ \"interfaces\": [ \"*\" ]," + "\"rebind-timer\": 2000, " + "\"renew-timer\": 1000, " + "\"subnet4\": [ " + "{ \"pool\": [ \"192.0.2.2 - 192.0.2.100\" ]," + " \"relay\": { " + " \"ip-address\": \"192.0.5.1\"" + " }," + " \"subnet\": \"192.0.2.0/24\" }, " + "{ \"pool\": [ \"192.0.3.1 - 192.0.3.100\" ]," + " \"relay\": { " + " \"ip-address\": \"192.0.5.2\"" + " }," + " \"subnet\": \"192.0.3.0/24\" } " + "]," + "\"valid-lifetime\": 4000 }"; + + // Use this config to set up the server + ElementPtr json = Element::fromJSON(config); + EXPECT_NO_THROW(status = configureDhcp4Server(srv, json)); + ASSERT_TRUE(status); + comment_ = config::parseAnswer(rcode_, status); + ASSERT_EQ(0, rcode_); + + const Subnet4Collection* subnets = CfgMgr::instance().getSubnets4(); + ASSERT_EQ(2, subnets->size()); + + // Let's get them for easy reference + Subnet4Ptr subnet1 = (*subnets)[0]; + Subnet4Ptr subnet2 = (*subnets)[1]; + ASSERT_TRUE(subnet1); + ASSERT_TRUE(subnet2); + + // Let's create a packet. + Pkt4Ptr dis = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234)); + dis->setRemoteAddr(IOAddress("192.0.2.1")); + dis->setIface("eth0"); + dis->setHops(1); + OptionPtr clientid = generateClientId(); + dis->addOption(clientid); + + // This is just a sanity check, we're using regular method: ciaddr 192.0.2.1 + // belongs to the first subnet, so it is selected + dis->setGiaddr(IOAddress("192.0.2.1")); + EXPECT_TRUE(subnet1 == srv.selectSubnet(dis)); + + // Relay belongs to the second subnet, so it should be selected. + dis->setGiaddr(IOAddress("192.0.3.1")); + EXPECT_TRUE(subnet2 == srv.selectSubnet(dis)); + + // Now let's check if the relay override for the first subnets works + dis->setGiaddr(IOAddress("192.0.5.1")); + EXPECT_TRUE(subnet1 == srv.selectSubnet(dis)); + + // The same check for the second subnet... + dis->setGiaddr(IOAddress("192.0.5.2")); + EXPECT_TRUE(subnet2 == srv.selectSubnet(dis)); + + // And finally, let's check if mis-matched relay address will end up + // in not selecting a subnet at all + dis->setGiaddr(IOAddress("192.0.5.3")); + EXPECT_FALSE(srv.selectSubnet(dis)); + + // Finally, check that the relay override works only with relay address + // (GIADDR) and does not affect client address (CIADDR) + dis->setGiaddr(IOAddress("0.0.0.0")); + dis->setHops(0); + dis->setCiaddr(IOAddress("192.0.5.1")); + EXPECT_FALSE(srv.selectSubnet(dis)); +} + +// Checks if relay IP address specified in the relay-info structure can be +// used together with client-classification. +TEST_F(Dhcpv4SrvTest, relayOverrideAndClientClass) { + + NakedDhcpv4Srv srv(0); + + ConstElementPtr status; + + // 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\": [ \"*\" ]," + "\"rebind-timer\": 2000, " + "\"renew-timer\": 1000, " + "\"subnet4\": [ " + "{ \"pool\": [ \"192.0.2.2 - 192.0.2.100\" ]," + " \"client-class\": \"foo\", " + " \"relay\": { " + " \"ip-address\": \"192.0.5.1\"" + " }," + " \"subnet\": \"192.0.2.0/24\" }, " + "{ \"pool\": [ \"192.0.3.1 - 192.0.3.100\" ]," + " \"relay\": { " + " \"ip-address\": \"192.0.5.1\"" + " }," + " \"subnet\": \"192.0.3.0/24\" } " + "]," + "\"valid-lifetime\": 4000 }"; + + // Use this config to set up the server + ElementPtr json = Element::fromJSON(config); + EXPECT_NO_THROW(status = configureDhcp4Server(srv, json)); + ASSERT_TRUE(status); + comment_ = config::parseAnswer(rcode_, status); + ASSERT_EQ(0, rcode_); + + const Subnet4Collection* subnets = CfgMgr::instance().getSubnets4(); + ASSERT_EQ(2, subnets->size()); + + // Let's get them for easy reference + Subnet4Ptr subnet1 = (*subnets)[0]; + Subnet4Ptr subnet2 = (*subnets)[1]; + ASSERT_TRUE(subnet1); + ASSERT_TRUE(subnet2); + + // Let's create a packet. + Pkt4Ptr dis = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234)); + dis->setRemoteAddr(IOAddress("192.0.2.1")); + dis->setIface("eth0"); + dis->setHops(1); + dis->setGiaddr(IOAddress("192.0.5.1")); + OptionPtr clientid = generateClientId(); + dis->addOption(clientid); + + // 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(dis)); + + // 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. + dis->addClass("foo"); + EXPECT_TRUE(subnet1 == srv.selectSubnet(dis)); +} + // This test verifies that the direct message is dropped when it has been // received by the server via an interface for which there is no subnet // configured. It also checks that the message is not dropped (is processed)