Browse Source

[3322] Changes after review:

 - Unit-tests for DHCPv4 now use configure() method.
 - Typo fixed in DHCPv6 unit-tests.
 - Removed, updated comments in cfgmgr
 - Guide updated
Tomek Mrugalski 11 years ago
parent
commit
8174421f66

+ 9 - 9
doc/guide/bind10-guide.xml

@@ -5545,17 +5545,17 @@ should include options from the isc option space:
           The DHCPv6 server may receive requests from local (connected to the
           The DHCPv6 server may receive requests from local (connected to the
           same subnet as the server) and remote (connecting via relays) clients.
           same subnet as the server) and remote (connecting via relays) clients.
           As server may have many subnet configurations defined, it must select
           As server may have many subnet configurations defined, it must select
-          appropriate subnet for a given request. To do this, the server first
+          appropriate subnet for a given request.
-          checks if there is only one subnet defined and source of the packet is
-          link-local. If this is the case, the server assumes that the only
-          subnet defined is local and client is indeed connected to it. This
-          check simplifies small deployments.
           </para>
           </para>
           <para>
           <para>
-          If there are two or more subnets defined, the server can not assume
+          The server can not assume which of configured subnets are local. It is
-          which of those (if any) subnets are local. Therefore an optional
+          possible in IPv4, where there is reasonable expectation that the
-          "interface" parameter is available within a subnet definition to
+          server will have a (global) IPv4 address configured on the interface,
-          designate that a given subnet is local, i.e. reachable directly over
+          and can use that information to detect whether a subnet is local or
+          not. That assumption is not true in IPv6, as the DHCPv6 must be able
+          to operate with having link-local addresses only. Therefore an optional
+          &quot;interface&quot; parameter is available within a subnet definition
+          to designate that a given subnet is local, i.e. reachable directly over
           specified interface. For example the server that is intended to serve
           specified interface. For example the server that is intended to serve
           a local subnet over eth0 may be configured as follows:
           a local subnet over eth0 may be configured as follows:
 <screen>
 <screen>

+ 15 - 40
src/bin/dhcp4/tests/dhcp4_srv_unittest.cc

@@ -3314,10 +3314,6 @@ TEST_F(Dhcpv4SrvTest, clientClassification) {
 // .clientClassification above.
 // .clientClassification above.
 TEST_F(Dhcpv4SrvTest, clientClassify2) {
 TEST_F(Dhcpv4SrvTest, clientClassify2) {
 
 
-    NakedDhcpv4Srv srv(0);
-
-    ConstElementPtr status;
-
     // This test configures 2 subnets. We actually only need the
     // This test configures 2 subnets. We actually only need the
     // first one, but since there's still this ugly hack that picks
     // 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
     // the pool if there is only one, we must use more than one
@@ -3340,15 +3336,9 @@ TEST_F(Dhcpv4SrvTest, clientClassify2) {
         "],"
         "],"
         "\"valid-lifetime\": 4000 }";
         "\"valid-lifetime\": 4000 }";
 
 
-    ElementPtr json = Element::fromJSON(config);
+    ASSERT_NO_THROW(configure(config));
-
-    EXPECT_NO_THROW(status = configureDhcp4Server(srv, json));
-
-    // 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));
     Pkt4Ptr dis = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234));
     dis->setRemoteAddr(IOAddress("192.0.2.1"));
     dis->setRemoteAddr(IOAddress("192.0.2.1"));
     dis->setCiaddr(IOAddress("192.0.2.1"));
     dis->setCiaddr(IOAddress("192.0.2.1"));
@@ -3358,27 +3348,25 @@ TEST_F(Dhcpv4SrvTest, clientClassify2) {
 
 
     // This discover does not belong to foo class, so it will not
     // This discover does not belong to foo class, so it will not
     // be serviced
     // be serviced
-    EXPECT_FALSE(srv.selectSubnet(dis));
+    EXPECT_FALSE(srv_.selectSubnet(dis));
 
 
     // Let's add the packet to bar class and try again.
     // Let's add the packet to bar class and try again.
     dis->addClass("bar");
     dis->addClass("bar");
 
 
     // Still not supported, because it belongs to wrong class.
     // Still not supported, because it belongs to wrong class.
-    EXPECT_FALSE(srv.selectSubnet(dis));
+    EXPECT_FALSE(srv_.selectSubnet(dis));
 
 
     // Let's add it to maching class.
     // Let's add it to maching class.
     dis->addClass("foo");
     dis->addClass("foo");
 
 
     // This time it should work
     // This time it should work
-    EXPECT_TRUE(srv.selectSubnet(dis));
+    EXPECT_TRUE(srv_.selectSubnet(dis));
 }
 }
 
 
 // Checks if relay IP address specified in the relay-info structure in
 // Checks if relay IP address specified in the relay-info structure in
 // subnet4 is being used properly.
 // subnet4 is being used properly.
 TEST_F(Dhcpv4SrvTest, relayOverride) {
 TEST_F(Dhcpv4SrvTest, relayOverride) {
 
 
-    NakedDhcpv4Srv srv(0);
-
     // We have 2 subnets defined. Note that both have a relay address
     // We have 2 subnets defined. Note that both have a relay address
     // defined. Both are not belonging to the subnets. That is
     // defined. Both are not belonging to the subnets. That is
     // important, because if the relay belongs to the subnet, there's
     // important, because if the relay belongs to the subnet, there's
@@ -3401,12 +3389,7 @@ TEST_F(Dhcpv4SrvTest, relayOverride) {
         "\"valid-lifetime\": 4000 }";
         "\"valid-lifetime\": 4000 }";
 
 
     // Use this config to set up the server
     // Use this config to set up the server
-    ElementPtr json = Element::fromJSON(config);
+    ASSERT_NO_THROW(configure(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
     // Let's get the subnet configuration objects
     const Subnet4Collection* subnets = CfgMgr::instance().getSubnets4();
     const Subnet4Collection* subnets = CfgMgr::instance().getSubnets4();
@@ -3429,41 +3412,37 @@ TEST_F(Dhcpv4SrvTest, relayOverride) {
     // This is just a sanity check, we're using regular method: ciaddr 192.0.2.1
     // 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
     // belongs to the first subnet, so it is selected
     dis->setGiaddr(IOAddress("192.0.2.1"));
     dis->setGiaddr(IOAddress("192.0.2.1"));
-    EXPECT_TRUE(subnet1 == srv.selectSubnet(dis));
+    EXPECT_TRUE(subnet1 == srv_.selectSubnet(dis));
 
 
     // Relay belongs to the second subnet, so it  should be selected.
     // Relay belongs to the second subnet, so it  should be selected.
     dis->setGiaddr(IOAddress("192.0.3.1"));
     dis->setGiaddr(IOAddress("192.0.3.1"));
-    EXPECT_TRUE(subnet2 == srv.selectSubnet(dis));
+    EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis));
 
 
     // Now let's check if the relay override for the first subnets works
     // Now let's check if the relay override for the first subnets works
     dis->setGiaddr(IOAddress("192.0.5.1"));
     dis->setGiaddr(IOAddress("192.0.5.1"));
-    EXPECT_TRUE(subnet1 == srv.selectSubnet(dis));
+    EXPECT_TRUE(subnet1 == srv_.selectSubnet(dis));
 
 
     // The same check for the second subnet...
     // The same check for the second subnet...
     dis->setGiaddr(IOAddress("192.0.5.2"));
     dis->setGiaddr(IOAddress("192.0.5.2"));
-    EXPECT_TRUE(subnet2 == srv.selectSubnet(dis));
+    EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis));
 
 
     // And finally, let's check if mis-matched relay address will end up
     // And finally, let's check if mis-matched relay address will end up
     // in not selecting a subnet at all
     // in not selecting a subnet at all
     dis->setGiaddr(IOAddress("192.0.5.3"));
     dis->setGiaddr(IOAddress("192.0.5.3"));
-    EXPECT_FALSE(srv.selectSubnet(dis));
+    EXPECT_FALSE(srv_.selectSubnet(dis));
 
 
     // Finally, check that the relay override works only with relay address
     // Finally, check that the relay override works only with relay address
     // (GIADDR) and does not affect client address (CIADDR)
     // (GIADDR) and does not affect client address (CIADDR)
     dis->setGiaddr(IOAddress("0.0.0.0"));
     dis->setGiaddr(IOAddress("0.0.0.0"));
     dis->setHops(0);
     dis->setHops(0);
     dis->setCiaddr(IOAddress("192.0.5.1"));
     dis->setCiaddr(IOAddress("192.0.5.1"));
-    EXPECT_FALSE(srv.selectSubnet(dis));
+    EXPECT_FALSE(srv_.selectSubnet(dis));
 }
 }
 
 
 // Checks if relay IP address specified in the relay-info structure can be
 // Checks if relay IP address specified in the relay-info structure can be
 // used together with client-classification.
 // used together with client-classification.
 TEST_F(Dhcpv4SrvTest, relayOverrideAndClientClass) {
 TEST_F(Dhcpv4SrvTest, relayOverrideAndClientClass) {
 
 
-    NakedDhcpv4Srv srv(0);
-
-    ConstElementPtr status;
-
     // This test configures 2 subnets. They both are on the same link, so they
     // 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
     // have the same relay-ip address. Furthermore, the first subnet is
     // reserved for clients that belong to class "foo".
     // reserved for clients that belong to class "foo".
@@ -3486,11 +3465,7 @@ TEST_F(Dhcpv4SrvTest, relayOverrideAndClientClass) {
         "\"valid-lifetime\": 4000 }";
         "\"valid-lifetime\": 4000 }";
 
 
     // Use this config to set up the server
     // Use this config to set up the server
-    ElementPtr json = Element::fromJSON(config);
+    ASSERT_NO_THROW(configure(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();
     const Subnet4Collection* subnets = CfgMgr::instance().getSubnets4();
     ASSERT_EQ(2, subnets->size());
     ASSERT_EQ(2, subnets->size());
@@ -3514,12 +3489,12 @@ TEST_F(Dhcpv4SrvTest, relayOverrideAndClientClass) {
     // subnet[0], even though the relay-ip matches. It should be accepted 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
     // subnet[1], because the subnet matches and there are no class
     // requirements.
     // requirements.
-    EXPECT_TRUE(subnet2 == srv.selectSubnet(dis));
+    EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis));
 
 
     // Now let's add this packet to class foo and recheck. This time it should
     // 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.
     // be accepted in the first subnet, because both class and relay-ip match.
     dis->addClass("foo");
     dis->addClass("foo");
-    EXPECT_TRUE(subnet1 == srv.selectSubnet(dis));
+    EXPECT_TRUE(subnet1 == srv_.selectSubnet(dis));
 }
 }
 
 
 // This test verifies that the direct message is dropped when it has been
 // This test verifies that the direct message is dropped when it has been

+ 1 - 1
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc

@@ -1807,7 +1807,7 @@ TEST_F(Dhcpv6SrvTest, clientClassify2) {
 }
 }
 
 
 // Checks if relay IP address specified in the relay-info structure in
 // Checks if relay IP address specified in the relay-info structure in
-// subnet4 is being used properly.
+// subnet6 is being used properly.
 TEST_F(Dhcpv6SrvTest, relayOverride) {
 TEST_F(Dhcpv6SrvTest, relayOverride) {
 
 
     NakedDhcpv6Srv srv(0);
     NakedDhcpv6Srv srv(0);

+ 2 - 2
src/lib/dhcpsrv/cfgmgr.cc

@@ -155,7 +155,7 @@ CfgMgr::getSubnet6(const std::string& iface,
 Subnet6Ptr
 Subnet6Ptr
 CfgMgr::getSubnet6(const isc::asiolink::IOAddress& hint,
 CfgMgr::getSubnet6(const isc::asiolink::IOAddress& hint,
                    const isc::dhcp::ClientClasses& classes,
                    const isc::dhcp::ClientClasses& classes,
-                   bool relay) {
+                   const bool relay) {
 
 
     // If there's only one subnet configured, let's just use it
     // If there's only one subnet configured, let's just use it
     // The idea is to keep small deployments easy. In a small network - one
     // The idea is to keep small deployments easy. In a small network - one
@@ -240,7 +240,7 @@ void CfgMgr::addSubnet6(const Subnet6Ptr& subnet) {
 Subnet4Ptr
 Subnet4Ptr
 CfgMgr::getSubnet4(const isc::asiolink::IOAddress& hint,
 CfgMgr::getSubnet4(const isc::asiolink::IOAddress& hint,
                    const isc::dhcp::ClientClasses& classes,
                    const isc::dhcp::ClientClasses& classes,
-                   bool relay /* = false */) const {
+                   bool relay) const {
     // Iterate over existing subnets to find a suitable one for the
     // Iterate over existing subnets to find a suitable one for the
     // given address.
     // given address.
     for (Subnet4Collection::const_iterator subnet = subnets4_.begin();
     for (Subnet4Collection::const_iterator subnet = subnets4_.begin();

+ 8 - 4
src/lib/dhcpsrv/cfgmgr.h

@@ -169,10 +169,14 @@ public:
     /// If there are any classes specified in a subnet, that subnet
     /// If there are any classes specified in a subnet, that subnet
     /// will be selected only if the client belongs to appropriate class.
     /// will be selected only if the client belongs to appropriate class.
     ///
     ///
+    /// @note The client classification is checked before any relay
+    /// information checks are conducted.
+    ///
     /// If relay is true then relay info overrides (i.e. value the sysadmin
     /// If relay is true then relay info overrides (i.e. value the sysadmin
-    /// can configure in Dhcp4/subnet6[X]/relay/ip-address) can be used.
+    /// can configure in Dhcp6/subnet6[X]/relay/ip-address) can be used.
-    /// That is true only for relays. Those overrides must not be used
+    /// That is applicable only for relays. Those overrides must not be used
-    /// for client address or for client hints. They are for giaddr only.
+    /// for client address or for client hints. They are for link-addr field
+    /// in the RELAY_FORW message only.
     ///
     ///
     /// @param hint an address that belongs to a searched subnet
     /// @param hint an address that belongs to a searched subnet
     /// @param classes classes the client belongs to
     /// @param classes classes the client belongs to
@@ -181,7 +185,7 @@ public:
     /// @return a subnet object (or NULL if no suitable match was fount)
     /// @return a subnet object (or NULL if no suitable match was fount)
     Subnet6Ptr getSubnet6(const isc::asiolink::IOAddress& hint,
     Subnet6Ptr getSubnet6(const isc::asiolink::IOAddress& hint,
                           const isc::dhcp::ClientClasses& classes,
                           const isc::dhcp::ClientClasses& classes,
-                          bool relay = false);
+                          const bool relay = false);
 
 
     /// @brief get IPv6 subnet by interface name
     /// @brief get IPv6 subnet by interface name
     ///
     ///