Browse Source

[3322] Relay address used in relay-info can now be used in getSubnet{4,6}

Tomek Mrugalski 11 years ago
parent
commit
349644e019
4 changed files with 35 additions and 6 deletions
  1. 2 1
      src/bin/dhcp4/dhcp4_srv.cc
  2. 1 1
      src/bin/dhcp6/dhcp6_srv.cc
  3. 16 2
      src/lib/dhcpsrv/cfgmgr.cc
  4. 16 2
      src/lib/dhcpsrv/cfgmgr.h

+ 2 - 1
src/bin/dhcp4/dhcp4_srv.cc

@@ -1415,7 +1415,8 @@ Dhcpv4Srv::selectSubnet(const Pkt4Ptr& question) const {
     // level functions.
     if (question->isRelayed()) {
         subnet = CfgMgr::instance().getSubnet4(question->getGiaddr(),
-                                               question->classes_);
+                                               question->classes_,
+                                               true);
 
     // The message is not relayed so it is sent directly by a client. But
     // the client may be renewing its lease and in such case it unicasts

+ 1 - 1
src/bin/dhcp6/dhcp6_srv.cc

@@ -885,7 +885,7 @@ Dhcpv6Srv::selectSubnet(const Pkt6Ptr& question) {
             // if relay filled in link_addr field, then let's use it
             if (link_addr != IOAddress("::")) {
                 subnet = CfgMgr::instance().getSubnet6(link_addr,
-                                                       question->classes_);
+                                                       question->classes_, true);
             }
         }
     }

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

@@ -154,7 +154,8 @@ CfgMgr::getSubnet6(const std::string& iface,
 
 Subnet6Ptr
 CfgMgr::getSubnet6(const isc::asiolink::IOAddress& hint,
-                   const isc::dhcp::ClientClasses& classes) {
+                   const isc::dhcp::ClientClasses& classes,
+                   bool relay) {
 
     // 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
@@ -180,6 +181,12 @@ CfgMgr::getSubnet6(const isc::asiolink::IOAddress& hint,
             continue;
         }
 
+        // If the hint is a relay address, and there is relay info specified
+        // for this subnet and those two match, then use this subnet.
+        if (relay && ((*subnet)->getRelayInfo().addr_ == hint) ) {
+            return (*subnet);
+        }
+
         if ((*subnet)->inRange(hint)) {
             LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE,
                       DHCPSRV_CFGMGR_SUBNET6)
@@ -232,7 +239,8 @@ void CfgMgr::addSubnet6(const Subnet6Ptr& subnet) {
 
 Subnet4Ptr
 CfgMgr::getSubnet4(const isc::asiolink::IOAddress& hint,
-                   const isc::dhcp::ClientClasses& classes) const {
+                   const isc::dhcp::ClientClasses& classes,
+                   bool relay /* = false */) const {
     // Iterate over existing subnets to find a suitable one for the
     // given address.
     for (Subnet4Collection::const_iterator subnet = subnets4_.begin();
@@ -243,6 +251,12 @@ CfgMgr::getSubnet4(const isc::asiolink::IOAddress& hint,
             continue;
         }
 
+        // If the hint is a relay address, and there is relay info specified
+        // for this subnet and those two match, then use this subnet.
+        if (relay && ((*subnet)->getRelayInfo().addr_ == hint) ) {
+            return (*subnet);
+        }
+
         // Let's check if the client belongs to the given subnet
         if ((*subnet)->inRange(hint)) {
             LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE,

+ 16 - 2
src/lib/dhcpsrv/cfgmgr.h

@@ -169,12 +169,19 @@ public:
     /// If there are any classes specified in a subnet, that subnet
     /// will be selected only if the client belongs to appropriate class.
     ///
+    /// 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.
+    /// That is true only for relays. Those overrides must not be used
+    /// for client address or for client hints. They are for giaddr only.
+    ///
     /// @param hint an address that belongs to a searched subnet
     /// @param classes classes the client belongs to
+    /// @param relay true if address specified in hint is a relay
     ///
     /// @return a subnet object (or NULL if no suitable match was fount)
     Subnet6Ptr getSubnet6(const isc::asiolink::IOAddress& hint,
-                          const isc::dhcp::ClientClasses& classes);
+                          const isc::dhcp::ClientClasses& classes,
+                          bool relay = false);
 
     /// @brief get IPv6 subnet by interface name
     ///
@@ -262,12 +269,19 @@ public:
     /// If there are any classes specified in a subnet, that subnet
     /// will be selected only if the client belongs to appropriate class.
     ///
+    /// If relay is true then relay info overrides (i.e. value the sysadmin
+    /// can configure in Dhcp4/subnet4[X]/relay/ip-address) can be used.
+    /// That is true only for relays. Those overrides must not be used
+    /// for client address or for client hints. They are for giaddr only.
+    ///
     /// @param hint an address that belongs to a searched subnet
     /// @param classes classes the client belongs to
+    /// @param relay true if address specified in hint is a relay
     ///
     /// @return a subnet object
     Subnet4Ptr getSubnet4(const isc::asiolink::IOAddress& hint,
-                          const isc::dhcp::ClientClasses& classes) const;
+                          const isc::dhcp::ClientClasses& classes,
+                          bool relay = false) const;
 
     /// @brief Returns a subnet for the specified local interface.
     ///