Parcourir la source

subnet4: Add support for "client prefix length" parameter

This allows to set the prefix length advertised to clients.  By default,
this is simply the prefix length of the subnet, but in some situations it
is useful to override it.

For instance, for a subnet of 203.0.113.0/24 and a client prefix length
of 32, a client would configure itself with an address like 203.0.113.66/32.
Baptiste Jonglez il y a 7 ans
Parent
commit
fa88154512

+ 4 - 2
src/lib/dhcpsrv/parsers/dhcp_parsers.cc

@@ -602,11 +602,13 @@ Subnet4ConfigParser::initSubnet(data::ConstElementPtr params,
     if (!t2.unspecified()) {
         s << "t2=" << t2 << ", ";
     }
-    s <<"valid-lifetime=" << valid;
+    s << "valid-lifetime=" << valid << ", ";
+    s << "client-prefix-length=" << static_cast<int>(client_prefix_len);
 
     LOG_INFO(dhcpsrv_logger, DHCPSRV_CFGMGR_NEW_SUBNET4).arg(s.str());
 
-    Subnet4Ptr subnet4(new Subnet4(addr, len, t1, t2, valid, subnet_id));
+    Subnet4Ptr subnet4(new Subnet4(addr, len, client_prefix_len, t1, t2,
+                                   valid, subnet_id));
     subnet_ = subnet4;
 
     // Set the match-client-id value for the subnet. It is always present.

+ 5 - 3
src/lib/dhcpsrv/subnet.cc

@@ -51,9 +51,10 @@ namespace dhcp {
 SubnetID Subnet::static_id_ = 1;
 
 Subnet::Subnet(const isc::asiolink::IOAddress& prefix, uint8_t len,
-               const SubnetID id)
+               const SubnetID id, uint8_t client_prefix_len)
     : id_(id == 0 ? generateNextID() : id), prefix_(prefix),
       prefix_len_(len),
+      client_prefix_len_(client_prefix_len),
       last_allocated_ia_(lastAddrInPrefix(prefix, len)),
       last_allocated_ta_(lastAddrInPrefix(prefix, len)),
       last_allocated_pd_(lastAddrInPrefix(prefix, len)) {
@@ -159,11 +160,12 @@ void Subnet4::checkType(Lease::Type type) const {
 }
 
 Subnet4::Subnet4(const isc::asiolink::IOAddress& prefix, uint8_t length,
+                 uint8_t client_prefix_len,
                  const Triplet<uint32_t>& t1,
                  const Triplet<uint32_t>& t2,
                  const Triplet<uint32_t>& valid_lifetime,
                  const SubnetID id)
-    : Subnet(prefix, length, id), Network4(),
+    : Subnet(prefix, length, client_prefix_len, id), Network4(),
       siaddr_(IOAddress("0.0.0.0")) {
     if (!prefix.isV4()) {
         isc_throw(BadValue, "Non IPv4 prefix " << prefix.toText()
@@ -481,7 +483,7 @@ Subnet6::Subnet6(const isc::asiolink::IOAddress& prefix, uint8_t length,
                  const Triplet<uint32_t>& preferred_lifetime,
                  const Triplet<uint32_t>& valid_lifetime,
                  const SubnetID id)
-    : Subnet(prefix, length, id), Network6() {
+    : Subnet(prefix, length, -1, id), Network6() {
     if (!prefix.isV6()) {
         isc_throw(BadValue, "Non IPv6 prefix " << prefix
                   << " specified in subnet6");

+ 20 - 1
src/lib/dhcpsrv/subnet.h

@@ -91,6 +91,13 @@ public:
         return (std::make_pair(prefix_, prefix_len_));
     }
 
+    /// @brief Returns the prefix length advertised to clients
+    ///
+    /// @return client prefix length
+    uint8_t getClientPrefixLength() const {
+        return (client_prefix_len_);
+    }
+
     /// @brief Adds a new pool for the subnet.
     ///
     /// This method checks that the address range represented by the pool
@@ -255,8 +262,9 @@ protected:
     /// @param len prefix length for the subnet
     /// @param id arbitrary subnet id, value of 0 triggers autogeneration
     /// of subnet id
+    /// @param client_prefix_len prefix length advertised to clients
     Subnet(const isc::asiolink::IOAddress& prefix, uint8_t len,
-           const SubnetID id);
+           const SubnetID id, uint8_t client_prefix_len);
 
     /// @brief virtual destructor
     ///
@@ -336,6 +344,15 @@ protected:
     /// @brief a prefix length of the subnet
     uint8_t prefix_len_;
 
+    /// @brief the prefix length advertised to clients
+    ///
+    /// In some cases, it may be useful to have clients with a prefix
+    /// length that is either smaller or larger than the actual prefix
+    /// configured in the server subnet.  For instance, a server may be
+    /// configured with a /24 subnet but hand out addresses as /32
+    /// prefixes, using option 121.
+    uint8_t client_prefix_len_;
+
     /// @brief last allocated address
     ///
     /// This is the last allocated address that was previously allocated from
@@ -391,12 +408,14 @@ public:
     ///
     /// @param prefix Subnet4 prefix
     /// @param length prefix length
+    /// @param client_prefix_len prefix length advertised to clients
     /// @param t1 renewal timer (in seconds)
     /// @param t2 rebind timer (in seconds)
     /// @param valid_lifetime preferred lifetime of leases (in seconds)
     /// @param id arbitrary subnet id, default value of 0 triggers
     /// autogeneration of subnet id
     Subnet4(const isc::asiolink::IOAddress& prefix, uint8_t length,
+            uint8_t client_prefix_len,
             const Triplet<uint32_t>& t1,
             const Triplet<uint32_t>& t2,
             const Triplet<uint32_t>& valid_lifetime,