]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#4163] Fixed manyPdPoolsPreferHigher and MT
authorFrancis Dupont <fdupont@isc.org>
Sun, 12 Oct 2025 11:47:46 +0000 (13:47 +0200)
committerFrancis Dupont <fdupont@isc.org>
Fri, 24 Oct 2025 16:20:06 +0000 (18:20 +0200)
src/lib/dhcpsrv/allocator.cc
src/lib/dhcpsrv/allocator.h
src/lib/dhcpsrv/flq_allocator.cc
src/lib/dhcpsrv/flq_allocator.h
src/lib/dhcpsrv/tests/flq_allocator_unittest.cc

index 3ae7ba1721c0a31dc3769ddf736f0cee208c8fce..b250bf57c691ebf82db1137da8263946510d0428 100644 (file)
@@ -80,14 +80,14 @@ Allocator::initAfterConfigure() {
 
 double
 Allocator::getOccupancyRate(const asiolink::IOAddress&,
-                            const ClientClasses&) const {
+                            const ClientClasses&) {
     return (0.);
 }
 
 double
 Allocator::getOccupancyRate(const asiolink::IOAddress&,
                             const uint8_t,
-                            const ClientClasses&) const {
+                            const ClientClasses&) {
     return (0.);
 }
 
index d9cf620e6b5eb9bcb904057df97281a4be73b4ef..43d05efea22770225f373c3cc0a8595e7625e15a 100644 (file)
@@ -152,7 +152,7 @@ public:
     /// @param client_classes list of classes client belongs to.
     virtual double
     getOccupancyRate(const asiolink::IOAddress& addr,
-                     const ClientClasses& client_classes) const;
+                     const ClientClasses& client_classes);
 
     /// @brief Returns the occupancy rate (v6 prefixes).
     ///
@@ -168,7 +168,7 @@ public:
     virtual double
     getOccupancyRate(const asiolink::IOAddress& pref,
                      const uint8_t plen,
-                     const ClientClasses& client_classes) const;
+                     const ClientClasses& client_classes);
 
     /// @brief Check if the pool matches the selection criteria relative to the
     /// provided hint prefix length.
index e560f108d6de17a50322ecdb692f648c80fa2ee6..edf573e0f4f41b92cfdca6cb01fdce6286d34857 100644 (file)
@@ -137,7 +137,14 @@ FreeLeaseQueueAllocator::pickPrefixInternal(const ClientClasses& client_classes,
 
 double
 FreeLeaseQueueAllocator::getOccupancyRate(const IOAddress& addr,
-                                          const ClientClasses& client_classes) const {
+                                          const ClientClasses& client_classes) {
+    MultiThreadingLock lock(mutex_);
+    return (getOccupancyRateInternal(addr, client_classes));
+}
+
+double
+FreeLeaseQueueAllocator::getOccupancyRateInternal(const IOAddress& addr,
+                                                  const ClientClasses& client_classes) {
     // Sanity.
     if (!addr.isV4()) {
         return (0.);
@@ -185,7 +192,15 @@ FreeLeaseQueueAllocator::getOccupancyRate(const IOAddress& addr,
 double
 FreeLeaseQueueAllocator::getOccupancyRate(const IOAddress& pref,
                                           const uint8_t plen,
-                                          const ClientClasses& client_classes) const {
+                                          const ClientClasses& client_classes) {
+    MultiThreadingLock lock(mutex_);
+    return (getOccupancyRateInternal(pref, plen, client_classes));
+}
+
+double
+FreeLeaseQueueAllocator::getOccupancyRateInternal(const IOAddress& pref,
+                                                  const uint8_t plen,
+                                                  const ClientClasses& client_classes) {
     // Sanity.
     if (!pref.isV6()) {
         return (0.);
index 78e503722b2390cd97f498c03f94169c7d5bd28a..168e754afe3ce2e2d8d63c2519cc367a67677a1e 100644 (file)
@@ -63,7 +63,7 @@ public:
     /// @param client_classes list of classes client belongs to.
     virtual double
     getOccupancyRate(const asiolink::IOAddress& addr,
-                     const ClientClasses& client_classes) const;
+                     const ClientClasses& client_classes);
 
     /// @brief Returns the occupancy rate (v6 prefixes).
     ///
@@ -79,7 +79,7 @@ public:
     virtual double
     getOccupancyRate(const asiolink::IOAddress& pref,
                      const uint8_t plen,
-                     const ClientClasses& client_classes) const;
+                     const ClientClasses& client_classes);
 
 private:
 
@@ -148,6 +148,40 @@ private:
                        const isc::asiolink::IOAddress& hint,
                        uint8_t hint_prefix_length);
 
+    /// @brief Returns the occupancy rate (v4 addresses).
+    ///
+    /// Internal thread-unsafe implementation.
+    ///
+    /// The method counts the total number and the number of not free
+    /// addresses in the suitable pools of the subnet, and returns the
+    /// occupancy rate. If the total number of addresses is over UMAX64
+    /// or the address is not from one of these pools, or by default
+    /// the 0. rate is returned.
+    ///
+    /// @param addr the address.
+    /// @param client_classes list of classes client belongs to.
+    virtual double
+    getOccupancyRateInternal(const asiolink::IOAddress& addr,
+                             const ClientClasses& client_classes);
+
+    /// @brief Returns the occupancy rate (v6 prefixes).
+    ///
+    /// Internal thread-unsafe implementation.
+    ///
+    /// The method counts the total number and the number of not free
+    /// prefixes in the suitable pools of the subnet, and returns the
+    /// occupancy rate. If the total number of prefixes is over UMAX64
+    /// or the prefix is not from one of these pools, or by default
+    /// the 0. rate is returned.
+    ///
+    /// @param pref the prefix.
+    /// @param plen the prefix length.
+    /// @param client_classes list of classes client belongs to.
+    virtual double
+    getOccupancyRateInternal(const asiolink::IOAddress& pref,
+                             const uint8_t plen,
+                             const ClientClasses& client_classes);
+
     /// @brief Convenience function returning pool allocation state instance.
     ///
     /// It creates a new pool state instance and assigns it to the pool
index bed7284b0dca048e5fb33340b267a66e3e4d66a9..daade94f39e0128c2a9a65fecb37514ec456c268 100644 (file)
@@ -1042,6 +1042,7 @@ TEST_F(FreeLeaseQueueAllocatorTest6, manyPdPoolsPreferHigher) {
     Pool6Ptr pool;
 
     std::set<IOAddress> prefixes;
+    bool assigned = false;
     for (size_t i = 0; i < total; ++i) {
         IOAddress candidate = alloc.pickPrefix(cc_, pool, duid_, Allocator::PREFIX_LEN_HIGHER, IOAddress("::"), 64);
         EXPECT_FALSE(candidate.isV6Zero());
@@ -1049,11 +1050,15 @@ TEST_F(FreeLeaseQueueAllocatorTest6, manyPdPoolsPreferHigher) {
         prefixes.insert(candidate);
         EXPECT_TRUE(subnet_->inPool(Lease::TYPE_PD, candidate));
         EXPECT_TRUE(subnet_->inPool(Lease::TYPE_PD, candidate, cc_));
+        if (candidate == IOAddress("3001::")) {
+            assigned = true;
+        }
     }
     // Make sure that unique prefixes have been returned.
     EXPECT_EQ(total, prefixes.size());
     double r = alloc.getOccupancyRate(IOAddress("3001::"), 128, cc_);
-    EXPECT_EQ(2560. / 68096., r);
+    // getOccupancyRate argument is always considered as not free.
+    EXPECT_EQ((assigned ? 2560. : 2561.) / 68096., r);
 }
 
 // Test that the allocator respects client class guards.