From: Francis Dupont Date: Sun, 12 Oct 2025 11:47:46 +0000 (+0200) Subject: [#4163] Fixed manyPdPoolsPreferHigher and MT X-Git-Tag: Kea-3.1.3~26 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=25347fd9843ddb9dc67dac0d78bc0abdeedacbc4;p=thirdparty%2Fkea.git [#4163] Fixed manyPdPoolsPreferHigher and MT --- diff --git a/src/lib/dhcpsrv/allocator.cc b/src/lib/dhcpsrv/allocator.cc index 3ae7ba1721..b250bf57c6 100644 --- a/src/lib/dhcpsrv/allocator.cc +++ b/src/lib/dhcpsrv/allocator.cc @@ -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.); } diff --git a/src/lib/dhcpsrv/allocator.h b/src/lib/dhcpsrv/allocator.h index d9cf620e6b..43d05efea2 100644 --- a/src/lib/dhcpsrv/allocator.h +++ b/src/lib/dhcpsrv/allocator.h @@ -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. diff --git a/src/lib/dhcpsrv/flq_allocator.cc b/src/lib/dhcpsrv/flq_allocator.cc index e560f108d6..edf573e0f4 100644 --- a/src/lib/dhcpsrv/flq_allocator.cc +++ b/src/lib/dhcpsrv/flq_allocator.cc @@ -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.); diff --git a/src/lib/dhcpsrv/flq_allocator.h b/src/lib/dhcpsrv/flq_allocator.h index 78e503722b..168e754afe 100644 --- a/src/lib/dhcpsrv/flq_allocator.h +++ b/src/lib/dhcpsrv/flq_allocator.h @@ -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 diff --git a/src/lib/dhcpsrv/tests/flq_allocator_unittest.cc b/src/lib/dhcpsrv/tests/flq_allocator_unittest.cc index bed7284b0d..daade94f39 100644 --- a/src/lib/dhcpsrv/tests/flq_allocator_unittest.cc +++ b/src/lib/dhcpsrv/tests/flq_allocator_unittest.cc @@ -1042,6 +1042,7 @@ TEST_F(FreeLeaseQueueAllocatorTest6, manyPdPoolsPreferHigher) { Pool6Ptr pool; std::set 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.