From: Marcin Siodelski Date: Wed, 22 Feb 2023 15:42:18 +0000 (+0100) Subject: [#2764] LeaseMgr callbacks per lease type X-Git-Tag: Kea-2.3.6~85 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=182cca2b6d033cd40977de7830b7cb931288d8a2;p=thirdparty%2Fkea.git [#2764] LeaseMgr callbacks per lease type --- diff --git a/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc b/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc index 615677e5b7..58a98d0903 100644 --- a/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc +++ b/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc @@ -2953,10 +2953,11 @@ GenericLeaseMgrTest::logCallback(TrackingLeaseMgr::CallbackType type, SubnetID s } int -GenericLeaseMgrTest::countLogs(TrackingLeaseMgr::CallbackType type, SubnetID subnet_id) const { +GenericLeaseMgrTest::countLogs(TrackingLeaseMgr::CallbackType type, SubnetID subnet_id, + Lease::Type lease_type) const { int count = 0; for (auto log : logs_) { - if ((log.type == type) && (log.subnet_id == subnet_id)) { + if ((log.type == type) && (log.subnet_id == subnet_id) && (log.lease->getType() == lease_type)) { ++count; } } @@ -4162,7 +4163,8 @@ GenericLeaseMgrTest::testClassLeaseCount6(Lease::Type ltype) { void GenericLeaseMgrTest::testTrackAddLease4(bool expect_locked, bool expect_mt_safe) { // Register a callback for all subnets. - lmptr_->registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, 0, "flq", + lmptr_->registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, "flq", 0, + Lease::TYPE_V4, std::bind(&GenericLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_ADD_LEASE, @@ -4200,7 +4202,8 @@ GenericLeaseMgrTest::testTrackAddLease4(bool expect_locked, bool expect_mt_safe) void GenericLeaseMgrTest::testTrackAddLease6(bool expect_locked, bool expect_mt_safe) { // Register a callback for all subnets. - lmptr_->registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, 0, "flq", + lmptr_->registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, "flq", 0, + Lease::TYPE_NA, std::bind(&GenericLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_ADD_LEASE, @@ -4208,7 +4211,7 @@ GenericLeaseMgrTest::testTrackAddLease6(bool expect_locked, bool expect_mt_safe) ph::_1, ph::_2)); // Add a lease. It should trigger the callback. - Lease6Ptr lease = initializeLease6(straddress6_[1]); + Lease6Ptr lease = initializeLease6(straddress6_[0]); EXPECT_TRUE(lmptr_->addLease(lease)); // Make sure that the callback has been invoked. @@ -4238,7 +4241,8 @@ GenericLeaseMgrTest::testTrackAddLease6(bool expect_locked, bool expect_mt_safe) void GenericLeaseMgrTest::testTrackUpdateLease4(bool expect_locked, bool expect_mt_safe) { // Register a callback for all subnets. - lmptr_->registerCallback(TrackingLeaseMgr::TRACK_UPDATE_LEASE, 0, "flq", + lmptr_->registerCallback(TrackingLeaseMgr::TRACK_UPDATE_LEASE, "flq", 0, + Lease::TYPE_V4, std::bind(&GenericLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_UPDATE_LEASE, @@ -4279,7 +4283,8 @@ GenericLeaseMgrTest::testTrackUpdateLease4(bool expect_locked, bool expect_mt_sa void GenericLeaseMgrTest::testTrackUpdateLease6(bool expect_locked, bool expect_mt_safe) { // Register a callback for all subnets. - lmptr_->registerCallback(TrackingLeaseMgr::TRACK_UPDATE_LEASE, 0, "flq", + lmptr_->registerCallback(TrackingLeaseMgr::TRACK_UPDATE_LEASE, "flq", 0, + Lease::TYPE_NA, std::bind(&GenericLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_UPDATE_LEASE, @@ -4287,7 +4292,7 @@ GenericLeaseMgrTest::testTrackUpdateLease6(bool expect_locked, bool expect_mt_sa ph::_1, ph::_2)); // Add a lease. - Lease6Ptr lease = initializeLease6(straddress6_[1]); + Lease6Ptr lease = initializeLease6(straddress6_[0]); EXPECT_TRUE(lmptr_->addLease(lease)); EXPECT_TRUE(logs_.empty()); @@ -4320,7 +4325,8 @@ GenericLeaseMgrTest::testTrackUpdateLease6(bool expect_locked, bool expect_mt_sa void GenericLeaseMgrTest::testTrackDeleteLease4(bool expect_locked, bool expect_mt_safe) { // Register a callback for all subnets. - lmptr_->registerCallback(TrackingLeaseMgr::TRACK_DELETE_LEASE, 0, "flq", + lmptr_->registerCallback(TrackingLeaseMgr::TRACK_DELETE_LEASE, "flq", 0, + Lease::TYPE_V4, std::bind(&GenericLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_DELETE_LEASE, @@ -4361,7 +4367,8 @@ GenericLeaseMgrTest::testTrackDeleteLease4(bool expect_locked, bool expect_mt_sa void GenericLeaseMgrTest::testTrackDeleteLease6(bool expect_locked, bool expect_mt_safe) { // Register a callback for all subnets. - lmptr_->registerCallback(TrackingLeaseMgr::TRACK_DELETE_LEASE, 0, "flq", + lmptr_->registerCallback(TrackingLeaseMgr::TRACK_DELETE_LEASE, "flq", 0, + Lease::TYPE_NA, std::bind(&GenericLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_DELETE_LEASE, @@ -4369,7 +4376,7 @@ GenericLeaseMgrTest::testTrackDeleteLease6(bool expect_locked, bool expect_mt_sa ph::_1, ph::_2)); // Add a lease. - Lease6Ptr lease = initializeLease6(straddress6_[1]); + Lease6Ptr lease = initializeLease6(straddress6_[0]); EXPECT_TRUE(lmptr_->addLease(lease)); EXPECT_TRUE(logs_.empty()); @@ -4402,7 +4409,8 @@ GenericLeaseMgrTest::testTrackDeleteLease6(bool expect_locked, bool expect_mt_sa void GenericLeaseMgrTest::testRecreateWithCallbacks(const std::string& access) { // Register a callback. - lmptr_->registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, 0, "flq", + lmptr_->registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, "flq", 0, + Lease::TYPE_V4, std::bind(&GenericLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_ADD_LEASE, @@ -4425,7 +4433,8 @@ GenericLeaseMgrTest::testRecreateWithCallbacks(const std::string& access) { void GenericLeaseMgrTest::testRecreateWithoutCallbacks(const std::string& access) { // Register a callback. - lmptr_->registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, 0, "flq", + lmptr_->registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, "flq", 0, + Lease::TYPE_V4, std::bind(&GenericLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_ADD_LEASE, diff --git a/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.h b/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.h index bd5ac03be9..68545f9af5 100644 --- a/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.h +++ b/src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.h @@ -182,13 +182,15 @@ public: /// @brief Counts log entries. /// - /// It counts the logs associated with the specific callback type and subnet id. + /// It counts the logs associated with the specific callback type, subnet id + /// and lease type. /// /// @param type callback type. /// @param subnet_id subnet identifier. /// @return The number of callback logs associated with the specific type and /// the subnet id. - int countLogs(TrackingLeaseMgr::CallbackType type, SubnetID subnet_id) const; + int countLogs(TrackingLeaseMgr::CallbackType type, SubnetID subnet_id, + Lease::Type lease_type) const; /// @brief checks that addLease, getLease4(addr) and deleteLease() works void testBasicLease4(); diff --git a/src/lib/dhcpsrv/tests/tracking_lease_mgr_unittest.cc b/src/lib/dhcpsrv/tests/tracking_lease_mgr_unittest.cc index 769371e6e2..7c42606e5e 100644 --- a/src/lib/dhcpsrv/tests/tracking_lease_mgr_unittest.cc +++ b/src/lib/dhcpsrv/tests/tracking_lease_mgr_unittest.cc @@ -35,21 +35,36 @@ public: /// @brief Convenience function creating a lease instance. /// - /// We don't use the @c initializeLease4 and the initializeLease6 functions - /// here because they use tons of parameters we don't really need here. - /// We simply need the subnet id and the address. It improves the tests - /// readability. + /// We don't use the @c initializeLease4 function here because it uses + /// tons of parameters we don't really need here. We simply need the + /// subnet id and the address. /// /// @param subnet_id subnet identifier for the lease. /// @param address leased address. - /// @tparam LeaseType type of the lease: @c Lease4 or Lease6. - template - boost::shared_ptr initializeLease(int subnet_id, std::string address) const { - auto lease = boost::make_shared(); + Lease4Ptr initializeLease(int subnet_id, std::string address) const { + auto lease = boost::make_shared(); lease->subnet_id_ = SubnetID(subnet_id); lease->addr_ = IOAddress(address); return (lease); } + + /// @brief Convenience function creating a lease instance. + /// + /// We don't use the initializeLease6 function here because it uses + /// tons of parameters we don't really need here. We simply need the + /// subnet id, lease type and the address. + /// + /// @param subnet_id subnet identifier for the lease. + /// @param lease_type lease type. + /// @param address leased address. + Lease6Ptr initializeLease(int subnet_id, Lease::Type lease_type, std::string address) const { + auto lease = boost::make_shared(); + lease->subnet_id_ = SubnetID(subnet_id); + lease->addr_ = IOAddress(address); + lease->type_ = lease_type; + return (lease); + } + }; /// Tests that leases can be locked and unlocked. When a lease is locked @@ -59,24 +74,24 @@ TEST_F(TrackingLeaseMgrTest, tryLock) { ConcreteLeaseMgr mgr(pmap); // An attempt to lock an already locked lease should fail. - EXPECT_TRUE(mgr.tryLock(initializeLease(1, "192.0.2.1"))); - EXPECT_FALSE(mgr.tryLock(initializeLease(1, "192.0.2.1"))); - EXPECT_TRUE(mgr.isLocked(initializeLease(1, "192.0.2.1"))); + EXPECT_TRUE(mgr.tryLock(initializeLease(1, "192.0.2.1"))); + EXPECT_FALSE(mgr.tryLock(initializeLease(1, "192.0.2.1"))); + EXPECT_TRUE(mgr.isLocked(initializeLease(1, "192.0.2.1"))); // We can lock another lease but we cannot lock an already locked one. - EXPECT_TRUE(mgr.tryLock(initializeLease(1, "192.0.2.2"))); - EXPECT_FALSE(mgr.tryLock(initializeLease(1, "192.0.2.1"))); - EXPECT_FALSE(mgr.tryLock(initializeLease(2, "192.0.2.2"))); - EXPECT_TRUE(mgr.isLocked(initializeLease(1, "192.0.1.2"))); - EXPECT_TRUE(mgr.isLocked(initializeLease(2, "192.0.2.2"))); + EXPECT_TRUE(mgr.tryLock(initializeLease(1, "192.0.2.2"))); + EXPECT_FALSE(mgr.tryLock(initializeLease(1, "192.0.2.1"))); + EXPECT_FALSE(mgr.tryLock(initializeLease(2, "192.0.2.2"))); + EXPECT_TRUE(mgr.isLocked(initializeLease(1, "192.0.2.1"))); + EXPECT_TRUE(mgr.isLocked(initializeLease(2, "192.0.2.2"))); // If we unlock the lease, it can be locked again. However, unlocking // the lease should not affect other locks. - mgr.unlock(initializeLease(1, "192.0.2.1")); - EXPECT_FALSE(mgr.isLocked(initializeLease(1, "192.0.2.1"))); - EXPECT_TRUE(mgr.isLocked(initializeLease(2, "192.0.2.2"))); - EXPECT_FALSE(mgr.tryLock(initializeLease(2, "192.0.2.2"))); - EXPECT_TRUE(mgr.tryLock(initializeLease(1, "192.0.2.1"))); + mgr.unlock(initializeLease(1, "192.0.2.1")); + EXPECT_FALSE(mgr.isLocked(initializeLease(1, "192.0.2.1"))); + EXPECT_TRUE(mgr.isLocked(initializeLease(2, "192.0.2.2"))); + EXPECT_FALSE(mgr.tryLock(initializeLease(2, "192.0.2.2"))); + EXPECT_TRUE(mgr.tryLock(initializeLease(1, "192.0.2.1"))); } /// Tests registering the callbacks. @@ -85,35 +100,40 @@ TEST_F(TrackingLeaseMgrTest, registerCallbacks) { ConcreteLeaseMgr mgr(pmap); // Callback for lease add and subnet id 0. - EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, 0, "flq", + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, "flq", 0, + Lease::TYPE_V4, std::bind(&TrackingLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_ADD_LEASE, 0, ph::_1, ph::_2))); // Callback for lease add and subnet id 1. - EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, 1, "flq", + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, "flq", 1, + Lease::TYPE_V4, std::bind(&TrackingLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_ADD_LEASE, 1, ph::_1, ph::_2))); // Callback for lease add and subnet id 2. - EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, 2, "flq", + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, "flq", 2, + Lease::TYPE_V4, std::bind(&TrackingLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_ADD_LEASE, 1, ph::_1, ph::_2))); // Callback for lease update and subnet id 0. - EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_UPDATE_LEASE, 0, "flq", + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_UPDATE_LEASE, "flq", 0, + Lease::TYPE_V4, std::bind(&TrackingLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_UPDATE_LEASE, 0, ph::_1, ph::_2))); // Callback for lease delete and subnet id 0. - EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_DELETE_LEASE, 0, "flq", + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_DELETE_LEASE, "flq", 0, + Lease::TYPE_V4, std::bind(&TrackingLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_DELETE_LEASE, @@ -121,16 +141,16 @@ TEST_F(TrackingLeaseMgrTest, registerCallbacks) { ph::_1, ph::_2))); // This call should trigger the lease add callbacks for subnet id 0 and 1. - EXPECT_NO_THROW(mgr.trackAddLease(initializeLease(1, "192.0.2.1"), false)); + EXPECT_NO_THROW(mgr.trackAddLease(initializeLease(1, "192.0.2.1"), false)); EXPECT_EQ(2, logs_.size()); - EXPECT_EQ(1, countLogs(TrackingLeaseMgr::TRACK_ADD_LEASE, 0)); - EXPECT_EQ(1, countLogs(TrackingLeaseMgr::TRACK_ADD_LEASE, 1)); + EXPECT_EQ(1, countLogs(TrackingLeaseMgr::TRACK_ADD_LEASE, 0, Lease::TYPE_V4)); + EXPECT_EQ(1, countLogs(TrackingLeaseMgr::TRACK_ADD_LEASE, 1, Lease::TYPE_V4)); // This call should trigger the lease add callback for subnet id 0 only. That's // because we have no callback for the subnet id 3. - EXPECT_NO_THROW(mgr.trackAddLease(initializeLease(3, "192.0.2.1"), false)); + EXPECT_NO_THROW(mgr.trackAddLease(initializeLease(3, "192.0.2.1"), false)); EXPECT_EQ(3, logs_.size()); - EXPECT_EQ(2, countLogs(TrackingLeaseMgr::TRACK_ADD_LEASE, 0)); + EXPECT_EQ(2, countLogs(TrackingLeaseMgr::TRACK_ADD_LEASE, 0, Lease::TYPE_V4)); } /// Test that registering the callbacks of the same type, for the same subnet id by the @@ -140,7 +160,8 @@ TEST_F(TrackingLeaseMgrTest, registerCallbacksConflicts) { ConcreteLeaseMgr mgr(pmap); // Add the callback for lease add and subnet id 0. - EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, 0, "flq", + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, "flq", 0, + Lease::TYPE_NA, std::bind(&TrackingLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_ADD_LEASE, @@ -148,7 +169,8 @@ TEST_F(TrackingLeaseMgrTest, registerCallbacksConflicts) { ph::_1, ph::_2))); // Another attempt should fail. - EXPECT_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, 0, "flq", + EXPECT_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, "flq", 0, + Lease::TYPE_NA, std::bind(&TrackingLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_ADD_LEASE, @@ -157,7 +179,8 @@ TEST_F(TrackingLeaseMgrTest, registerCallbacksConflicts) { InvalidOperation); // It should succeed for a different owner. - EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, 0, "qlf", + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, "qlf", 0, + Lease::TYPE_NA, std::bind(&TrackingLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_ADD_LEASE, @@ -165,7 +188,8 @@ TEST_F(TrackingLeaseMgrTest, registerCallbacksConflicts) { ph::_1, ph::_2))); // It should also succeed for a different subnet id. - EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, 5, "qlf", + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, "qlf", 5, + Lease::TYPE_NA, std::bind(&TrackingLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_ADD_LEASE, @@ -173,13 +197,65 @@ TEST_F(TrackingLeaseMgrTest, registerCallbacksConflicts) { ph::_1, ph::_2))); // But, another attempt for the subnet id should fail. - EXPECT_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, 5, "qlf", + EXPECT_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, "qlf", 5, + Lease::TYPE_NA, std::bind(&TrackingLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_ADD_LEASE, 5, ph::_1, ph::_2)), InvalidOperation); + + // However, changing a lease type should make it succeed. + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, "qlf", 5, + Lease::TYPE_PD, + std::bind(&TrackingLeaseMgrTest::logCallback, + this, + TrackingLeaseMgr::TRACK_ADD_LEASE, + 5, + ph::_1, ph::_2))); +} + +/// Test invoking the registered lease add callbacks. +TEST_F(TrackingLeaseMgrTest, trackAddLeaseDifferentLeaseTypes) { + DatabaseConnection::ParameterMap pmap; + ConcreteLeaseMgr mgr(pmap); + + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, "flq", 0, + Lease::TYPE_V4, + std::bind(&TrackingLeaseMgrTest::logCallback, + this, + TrackingLeaseMgr::TRACK_ADD_LEASE, + 0, + ph::_1, ph::_2))); + + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, "flq", 0, + Lease::TYPE_NA, + std::bind(&TrackingLeaseMgrTest::logCallback, + this, + TrackingLeaseMgr::TRACK_ADD_LEASE, + 0, + ph::_1, ph::_2))); + + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, "flq", 0, + Lease::TYPE_PD, + std::bind(&TrackingLeaseMgrTest::logCallback, + this, + TrackingLeaseMgr::TRACK_ADD_LEASE, + 0, + ph::_1, ph::_2))); + + EXPECT_NO_THROW(mgr.trackAddLease(initializeLease(1, "192.0.2.1"), false)); + EXPECT_EQ(1, logs_.size()); + EXPECT_EQ(1, countLogs(TrackingLeaseMgr::TRACK_ADD_LEASE, 0, Lease::TYPE_V4)); + + EXPECT_NO_THROW(mgr.trackAddLease(initializeLease(1, Lease::TYPE_NA, "2001:db8:1::1"), false)); + EXPECT_EQ(2, logs_.size()); + EXPECT_EQ(1, countLogs(TrackingLeaseMgr::TRACK_ADD_LEASE, 0, Lease::TYPE_NA)); + + EXPECT_NO_THROW(mgr.trackAddLease(initializeLease(1, Lease::TYPE_PD, "3000::"), false)); + EXPECT_EQ(3, logs_.size()); + EXPECT_EQ(1, countLogs(TrackingLeaseMgr::TRACK_ADD_LEASE, 0, Lease::TYPE_PD)); } /// Test invoking the registered lease update callbacks. @@ -187,27 +263,30 @@ TEST_F(TrackingLeaseMgrTest, trackUpdateLease) { DatabaseConnection::ParameterMap pmap; ConcreteLeaseMgr mgr(pmap); - EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, 0, "flq", + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, "flq", 0, + Lease::TYPE_V4, std::bind(&TrackingLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_ADD_LEASE, 0, ph::_1, ph::_2))); - EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_UPDATE_LEASE, 0, "flq", + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_UPDATE_LEASE, "flq", 0, + Lease::TYPE_V4, std::bind(&TrackingLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_UPDATE_LEASE, 0, ph::_1, ph::_2))); - EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_DELETE_LEASE, 0, "flq", + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_DELETE_LEASE, "flq", 0, + Lease::TYPE_V4, std::bind(&TrackingLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_DELETE_LEASE, 0, ph::_1, ph::_2))); - EXPECT_NO_THROW(mgr.trackUpdateLease(initializeLease(1, "192.0.2.1"), false)); + EXPECT_NO_THROW(mgr.trackUpdateLease(initializeLease(1, "192.0.2.1"), false)); EXPECT_EQ(1, logs_.size()); - EXPECT_EQ(1, countLogs(TrackingLeaseMgr::TRACK_UPDATE_LEASE, 0)); + EXPECT_EQ(1, countLogs(TrackingLeaseMgr::TRACK_UPDATE_LEASE, 0, Lease::TYPE_V4)); } /// Test invoking the registered lease delete callbacks. @@ -215,27 +294,30 @@ TEST_F(TrackingLeaseMgrTest, trackDeleteLease) { DatabaseConnection::ParameterMap pmap; ConcreteLeaseMgr mgr(pmap); - EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, 0, "flq", + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, "flq", 0, + Lease::TYPE_V4, std::bind(&TrackingLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_ADD_LEASE, 0, ph::_1, ph::_2))); - EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_UPDATE_LEASE, 0, "flq", + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_UPDATE_LEASE, "flq", 0, + Lease::TYPE_V4, std::bind(&TrackingLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_UPDATE_LEASE, 0, ph::_1, ph::_2))); - EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_DELETE_LEASE, 0, "flq", + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_DELETE_LEASE, "flq", 0, + Lease::TYPE_V4, std::bind(&TrackingLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_DELETE_LEASE, 0, ph::_1, ph::_2))); - EXPECT_NO_THROW(mgr.trackDeleteLease(initializeLease(1, "192.0.2.1"), false)); + EXPECT_NO_THROW(mgr.trackDeleteLease(initializeLease(1, "192.0.2.1"), false)); EXPECT_EQ(1, logs_.size()); - EXPECT_EQ(1, countLogs(TrackingLeaseMgr::TRACK_DELETE_LEASE, 0)); + EXPECT_EQ(1, countLogs(TrackingLeaseMgr::TRACK_DELETE_LEASE, 0, Lease::TYPE_V4)); } // Test unregistering the callbacks by subnet id. @@ -244,43 +326,50 @@ TEST_F(TrackingLeaseMgrTest, unregisterCallbacksBySubnetID) { ConcreteLeaseMgr mgr(pmap); // Register different callback types for different subnet identifiers. - EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, 0, "flq", + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, "flq", 0, + Lease::TYPE_V4, std::bind(&TrackingLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_ADD_LEASE, 0, ph::_1, ph::_2))); - EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, 1, "flq", + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, "flq", 1, + Lease::TYPE_V4, std::bind(&TrackingLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_ADD_LEASE, 1, ph::_1, ph::_2))); - EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, 2, "flq", + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, "flq", 2, + Lease::TYPE_V4, std::bind(&TrackingLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_ADD_LEASE, 2, ph::_1, ph::_2))); - EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_UPDATE_LEASE, 1, "flq", + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_UPDATE_LEASE, "flq", 1, + Lease::TYPE_V4, std::bind(&TrackingLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_UPDATE_LEASE, 1, ph::_1, ph::_2))); - EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_UPDATE_LEASE, 2, "flq", + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_UPDATE_LEASE, "flq", 2, + Lease::TYPE_V4, std::bind(&TrackingLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_UPDATE_LEASE, 2, ph::_1, ph::_2))); - EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_DELETE_LEASE, 1, "flq", + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_DELETE_LEASE, "flq", 1, + Lease::TYPE_V4, std::bind(&TrackingLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_DELETE_LEASE, 1, ph::_1, ph::_2))); - EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_DELETE_LEASE, 2, "flq", + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_DELETE_LEASE, "flq", 2, + Lease::TYPE_V4, std::bind(&TrackingLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_DELETE_LEASE, @@ -288,27 +377,27 @@ TEST_F(TrackingLeaseMgrTest, unregisterCallbacksBySubnetID) { ph::_1, ph::_2))); // Unregister the callbacks for subnet id 1. - EXPECT_NO_THROW(mgr.unregisterCallbacks(SubnetID(1))); + EXPECT_NO_THROW(mgr.unregisterCallbacks(SubnetID(1), Lease::TYPE_V4)); // Invoke the remaining callbacksm for the subnet id 1. - EXPECT_NO_THROW(mgr.trackAddLease(initializeLease(1, "192.0.2.1"), false)); - EXPECT_NO_THROW(mgr.trackUpdateLease(initializeLease(1, "192.0.2.1"), false)); - EXPECT_NO_THROW(mgr.trackDeleteLease(initializeLease(1, "192.0.2.1"), false)); + EXPECT_NO_THROW(mgr.trackAddLease(initializeLease(1, "192.0.2.1"), false)); + EXPECT_NO_THROW(mgr.trackUpdateLease(initializeLease(1, "192.0.2.1"), false)); + EXPECT_NO_THROW(mgr.trackDeleteLease(initializeLease(1, "192.0.2.1"), false)); // It should only run the callback for the subnet id 0 that is still // registered. EXPECT_EQ(1, logs_.size()); - EXPECT_EQ(1, countLogs(TrackingLeaseMgr::TRACK_ADD_LEASE, 0)); + EXPECT_EQ(1, countLogs(TrackingLeaseMgr::TRACK_ADD_LEASE, 0, Lease::TYPE_V4)); // Unregister this callback. - EXPECT_NO_THROW(mgr.unregisterCallbacks(SubnetID(0))); + EXPECT_NO_THROW(mgr.unregisterCallbacks(SubnetID(0), Lease::TYPE_V4)); // Make sure it is no longer invoked. - EXPECT_NO_THROW(mgr.trackAddLease(initializeLease(1, "192.0.2.1"), false)); + EXPECT_NO_THROW(mgr.trackAddLease(initializeLease(1, "192.0.2.1"), false)); EXPECT_EQ(1, logs_.size()); // Unregistering it again should be no-op. - EXPECT_NO_THROW(mgr.unregisterCallbacks(SubnetID(0))); + EXPECT_NO_THROW(mgr.unregisterCallbacks(SubnetID(0), Lease::TYPE_V4)); } /// Test unregistering all callbacks. @@ -317,13 +406,15 @@ TEST_F(TrackingLeaseMgrTest, unregisterAllCallbacks) { ConcreteLeaseMgr mgr(pmap); // Register some callbacks. - EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, 0, "flq", + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, "flq", 0, + Lease::TYPE_V4, std::bind(&TrackingLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_ADD_LEASE, 0, ph::_1, ph::_2))); - EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_UPDATE_LEASE, 0, "flq", + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_UPDATE_LEASE, "flq", 0, + Lease::TYPE_V4, std::bind(&TrackingLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_UPDATE_LEASE, @@ -343,7 +434,8 @@ TEST_F(TrackingLeaseMgrTest, hasCallbacks) { ConcreteLeaseMgr mgr(pmap); EXPECT_FALSE(mgr.hasCallbacks()); - EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, 0, "flq", + EXPECT_NO_THROW(mgr.registerCallback(TrackingLeaseMgr::TRACK_ADD_LEASE, "flq", 0, + Lease::TYPE_V4, std::bind(&TrackingLeaseMgrTest::logCallback, this, TrackingLeaseMgr::TRACK_ADD_LEASE, diff --git a/src/lib/dhcpsrv/tracking_lease_mgr.cc b/src/lib/dhcpsrv/tracking_lease_mgr.cc index 2be6752435..c723d48ddb 100644 --- a/src/lib/dhcpsrv/tracking_lease_mgr.cc +++ b/src/lib/dhcpsrv/tracking_lease_mgr.cc @@ -57,12 +57,13 @@ TrackingLeaseMgr::trackDeleteLease(const LeasePtr& lease, bool mt_safe) { void TrackingLeaseMgr::registerCallback(TrackingLeaseMgr::CallbackType type, - SubnetID subnet_id, std::string owner, + SubnetID subnet_id, + Lease::Type lease_type, TrackingLeaseMgr::CallbackFn callback_fn) { // The first index filters the callbacks by type and subnet_id. auto& idx = callbacks_->get<0>(); - auto range = idx.equal_range(boost::make_tuple(type, subnet_id)); + auto range = idx.equal_range(boost::make_tuple(type, subnet_id, lease_type)); if (range.first != range.second) { // Make sure that the callback for this owner does not exist. if (std::find_if(range.first, range.second, @@ -71,25 +72,31 @@ TrackingLeaseMgr::registerCallback(TrackingLeaseMgr::CallbackType type, }) != range.second) { isc_throw(InvalidOperation, "the callback owned by the " << owner << ", for subnet ID " << subnet_id + << ", and lease type " << Lease::typeToText(lease_type) << " has already been registered in the lease manager"); } } - TrackingLeaseMgr::Callback callback{type, owner, subnet_id, callback_fn}; + TrackingLeaseMgr::Callback callback{type, owner, subnet_id, lease_type, callback_fn}; callbacks_->insert(callback); } void TrackingLeaseMgr::registerCallback(TrackingLeaseMgr::CallbackType type, std::string owner, + Lease::Type lease_type, TrackingLeaseMgr::CallbackFn callback_fn) { - registerCallback(type, 0, owner, callback_fn); + registerCallback(type, owner, 0, lease_type, callback_fn); } void -TrackingLeaseMgr::unregisterCallbacks(SubnetID subnet_id) { - // The second index filters the callbacks by the subnet identifier. +TrackingLeaseMgr::unregisterCallbacks(SubnetID subnet_id, Lease::Type lease_type) { + // The second index filters the callbacks by the subnet identifier and + // the lease type. auto& idx = callbacks_->get<1>(); - idx.erase(subnet_id); + auto range = idx.equal_range(boost::make_tuple(subnet_id, lease_type)); + if (range.first != range.second) { + idx.erase(range.first, range.second); + } } void @@ -127,8 +134,8 @@ void TrackingLeaseMgr::runCallbacksForSubnetID(CallbackType type, SubnetID subnet_id, const LeasePtr& lease, bool mt_safe) { // The first index filters by callback type and subnet_id. - auto& idx_by_type = callbacks_->get<0>(); - auto cbs = idx_by_type.equal_range(boost::make_tuple(type, subnet_id)); + auto& idx = callbacks_->get<0>(); + auto cbs = idx.equal_range(boost::make_tuple(type, subnet_id, lease->getType())); if (cbs.first == cbs.second) { return; } diff --git a/src/lib/dhcpsrv/tracking_lease_mgr.h b/src/lib/dhcpsrv/tracking_lease_mgr.h index 58ab059a25..88b2740d03 100644 --- a/src/lib/dhcpsrv/tracking_lease_mgr.h +++ b/src/lib/dhcpsrv/tracking_lease_mgr.h @@ -99,14 +99,21 @@ public: /// @brief A structure representing a registered callback. /// - /// It associates the callback with a type, its owner, and a subnet - /// identifier. The owner is a string specified by the registration - /// function caller. There must be at most one callback registered - /// for the particular owner and the subnet identifier. + /// It associates the callback with a type, its owner, subnet + /// identifier, and a lease type. The owner is a string specified + /// by the registration function caller. There must be at most one + /// callback registered for the particular owner, subnet identifier + /// and the lease type. typedef struct { + /// Callback type (i.e., lease add, update, delete). CallbackType type; + /// An entity owning callback registration (e.g., FLQ allocator). std::string owner; + /// Subnet identifier associated with the callback. SubnetID subnet_id; + /// Lease types for which the callback should be invoked. + Lease::Type lease_type; + /// Callback function. CallbackFn fn; } Callback; @@ -116,7 +123,8 @@ protected: /// /// The callbacks are accessible via two indexes. The first composite index /// filters the callbacks by the callback type (i.e., lease add, update or delete) - /// and the subnet id. The second index filters the callbacks by the subnet id. + /// and the subnet id. The second index filters the callbacks by the subnet id + /// and the lease type. typedef boost::multi_index_container< Callback, boost::multi_index::indexed_by< @@ -124,11 +132,16 @@ protected: boost::multi_index::composite_key< Callback, boost::multi_index::member, - boost::multi_index::member + boost::multi_index::member, + boost::multi_index::member > >, - boost::multi_index::hashed_non_unique< - boost::multi_index::member + boost::multi_index::ordered_non_unique< + boost::multi_index::composite_key< + Callback, + boost::multi_index::member, + boost::multi_index::member + > > > > CallbackContainer; @@ -217,27 +230,32 @@ public: /// @brief Registers a callback function for a subnet. /// /// @param type callback type. + /// @param owner callback owner identifier. /// @param subnet_id subnet identifier; it can be set to 0 if the callback should be /// called for subnets. - /// @param owner callback owner identifier. + /// @param lease_type a lease type. /// @param callback_fn callback function instance. /// @throw InvalidOperation when the callback has been already registered for the given owner and /// the subnet identifier. - void registerCallback(CallbackType type, SubnetID subnet_id, std::string owner, CallbackFn callback_fn); + void registerCallback(CallbackType type, std::string owner, SubnetID subnet_id, + Lease::Type lease_type, CallbackFn callback_fn); /// @brief Registers a callback function for all subnets. /// /// @param type callback type. /// @param owner callback owner identifier. + /// @param lease_type a lease type. /// @param callback_fn callback function instance. /// @throw InvalidOperation when the callback has been already registered for the given owner and /// all subnets. - void registerCallback(CallbackType type, std::string owner, CallbackFn callback_fn); + void registerCallback(CallbackType type, std::string owner, Lease::Type lease_type, + CallbackFn callback_fn); /// @brief Unregisters all callbacks for a given subnet identifier. /// - /// @param subnet_id subnet identifier. - void unregisterCallbacks(SubnetID subnet_id); + /// @param subnet_id a subnet identifier. + /// @param lease_type a lease type. + void unregisterCallbacks(SubnetID subnet_id, Lease::Type lease_type); /// @brief Unregisters all callbacks. void unregisterAllCallbacks();