Parcourir la source

[3322] Unit-tests for relay-ip override implemented.

Tomek Mrugalski il y a 11 ans
Parent
commit
6a6d055a32
1 fichiers modifiés avec 155 ajouts et 0 suppressions
  1. 155 0
      src/bin/dhcp4/tests/dhcp4_srv_unittest.cc

+ 155 - 0
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)