]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
Add UnregisterInterfaceCallback
authorBreuninger Matthias (ETAS-DAP/XPC-Fe3) <Matthias.Breuninger@etas.com>
Fri, 31 Jan 2025 12:09:27 +0000 (13:09 +0100)
committerVincent Bernat <vincent@bernat.ch>
Tue, 4 Feb 2025 08:22:21 +0000 (09:22 +0100)
src/lib/lldpctl.hpp

index c0cf3dc24e57bbf3d37ab705c801501ca92d543d..add03ca8ae420e9e3029d96d89cf420f9738fc9d 100644 (file)
@@ -494,6 +494,8 @@ template <typename X = void, typename Y = void> class LldpWatch {
        /**
         * @brief Register an interface specific callback on remote changes.
         *
+        * @note Only up to one callback can be registered per interface.
+        *
         * @param if_name       The local interface to monitor.
         * @param callback      Callback to trigger on remote changes.
         * @param ctx           Optional context passed to @p callback.
@@ -514,6 +516,12 @@ template <typename X = void, typename Y = void> class LldpWatch {
 
                std::scoped_lock lock { mutex_ };
 
+               if (interface_callbacks_.contains(if_name) ) {
+                       throw std::system_error(std::error_code(LLDPCTL_ERR_CANNOT_CREATE,
+                                                   LldpErrCategory()),
+                           "Callback already registered for interface '" + if_name + "'");
+               }
+
                /**
                 * Note:
                 * There's a race one way or the other - we decided to accept the one
@@ -532,6 +540,32 @@ template <typename X = void, typename Y = void> class LldpWatch {
                    std::make_pair(callback, const_cast<Y *>(ctx)));
        }
 
+       /**
+        * @brief Unregister a previously registered interface specific callback
+        * on remote changes.
+        *
+        * @param if_name       The local interface not to monitor anymore.
+        */
+       void UnregisterInterfaceCallback(const std::string &if_name)
+       {
+               const auto interface {
+                       LldpCtl().GetInterface(if_name)
+               };
+               if (!interface.has_value()) {
+                       throw std::system_error(std::error_code(LLDPCTL_ERR_NOT_EXIST,
+                                                   LldpErrCategory()),
+                           "Couldn't find interface '" + if_name + "'");
+               }
+
+               std::scoped_lock lock { mutex_ };
+
+               if (0 == interface_callbacks_.erase(if_name) ) {
+                       throw std::system_error(std::error_code(LLDPCTL_ERR_NOT_EXIST,
+                                                   LldpErrCategory()),
+                           "No callback registered for interface '" + if_name + "'");
+               }
+       }
+
     private:
        static void WatchCallback(lldpctl_change_t change, lldpctl_atom_t *interface,
            lldpctl_atom_t *neighbor, void *p)