]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#3446] add dhcp state to get-status
authorRazvan Becheriu <razvan@isc.org>
Wed, 10 Jul 2024 15:31:59 +0000 (18:31 +0300)
committerRazvan Becheriu <razvan@isc.org>
Tue, 16 Jul 2024 12:43:21 +0000 (12:43 +0000)
src/bin/dhcp4/ctrl_dhcp4_srv.cc
src/bin/dhcp6/ctrl_dhcp6_srv.cc
src/lib/dhcpsrv/network_state.cc
src/lib/dhcpsrv/network_state.h

index d0483a3584a2e13a11e3cb27a61c68728b1ef5e5..3863e8fdb9018b9ddf9114bda644671ead0e6efb 100644 (file)
@@ -799,6 +799,8 @@ ControlledDhcpv4Srv::commandStatusGetHandler(const string&,
     }
     status->set("sockets", sockets);
 
+    status->set("dhcp-state": network_state_->toElement());
+
     return (createAnswer(CONTROL_RESULT_SUCCESS, status));
 }
 
@@ -878,7 +880,8 @@ ControlledDhcpv4Srv::processConfig(isc::data::ConstElementPtr config) {
         cfg_db->createManagers();
         // Reset counters related to connections as all managers have been recreated.
         srv->getNetworkState()->resetForDbConnection();
-
+        srv->getNetworkState()->resetForLocalCommands();
+        srv->getNetworkState()->resetForRemoteCommands();
     } catch (const std::exception& ex) {
         err << "Unable to open database: " << ex.what();
         return (isc::config::createAnswer(CONTROL_RESULT_ERROR, err.str()));
index 457eeb46a1cb78469eef708851cfa4b6d3eb7506..6bcfb3f2540a8285f65cbc50bcc1d5465eb1f887 100644 (file)
@@ -804,6 +804,8 @@ ControlledDhcpv6Srv::commandStatusGetHandler(const string&,
     }
     status->set("sockets", sockets);
 
+    status->set("dhcp-state": network_state_->toElement());
+
     return (createAnswer(CONTROL_RESULT_SUCCESS, status));
 }
 
@@ -886,6 +888,8 @@ ControlledDhcpv6Srv::processConfig(isc::data::ConstElementPtr config) {
         cfg_db->createManagers();
         // Reset counters related to connections as all managers have been recreated.
         srv->getNetworkState()->resetForDbConnection();
+        srv->getNetworkState()->resetForLocalCommands();
+        srv->getNetworkState()->resetForRemoteCommands();
     } catch (const std::exception& ex) {
         err << "Unable to open database: " << ex.what();
         return (isc::config::createAnswer(CONTROL_RESULT_ERROR, err.str()));
index 97e84dba50abfa341146d3707604fd137a2e3754..57b567171420b12377d93d1f175277be04bbf24d 100644 (file)
@@ -16,6 +16,7 @@
 #include <string>
 #include <unordered_set>
 
+using namespace isc::data;
 using namespace isc::util;
 
 namespace isc {
@@ -88,6 +89,36 @@ public:
         }
     }
 
+    /// @brief Reset origin for local commands.
+    ///
+    /// @note The dhcp service will remain disabled until all flags are cleared.
+    void resetForLocalCommands() {
+        auto disabled_by_origin = disabled_by_origin_;
+        for (auto const& origin : disabled_by_origin) {
+            if (origin >= NetworkState::HA_LOCAL_COMMAND && origin < NetworkState::HA_REMOTE_COMMAND) {
+                disabled_by_origin_.erase(origin);
+            }
+        }
+        if (disabled_by_origin_.empty()) {
+            globally_disabled_ = false;
+        }
+    }
+
+    /// @brief Reset origin for remote commands.
+    ///
+    /// @note The dhcp service will remain disabled until all flags are cleared.
+    void resetForRemoteCommands() {
+        auto disabled_by_origin = disabled_by_origin_;
+        for (auto const& origin : disabled_by_origin) {
+            if (origin >= NetworkState::HA_REMOTE_COMMAND && origin < NetworkState::DB_CONNECTION) {
+                disabled_by_origin_.erase(origin);
+            }
+        }
+        if (disabled_by_origin_.empty()) {
+            globally_disabled_ = false;
+        }
+    }
+
     /// @brief Enables DHCP service for an origin.
     ///
     /// If delayed enabling DHCP service has been scheduled, it cancels it.
@@ -144,6 +175,36 @@ public:
         return (timer_name.str());
     }
 
+    /// @brief The network state as Element.
+    ///
+    /// @return The network state as Element.
+    ConstElementPtr toElement() {
+        ElementPtr result = Element::createMap();
+        result->set("globally-disabled", Element::create(globally_disabled_));
+        result->set("disabled-by-db-connection", Element::create(disabled_by_db_connection_ != 0));
+        bool disabled_by_user = false;
+        ElementPtr local_origin = Element::createList();
+        uint16_t local_count = 0;
+        ElementPtr remote_origin = Element::createList();
+        uint16_t remote_count = 0;
+        for (auto const& origin : disabled_by_origin_) {
+            if (origin == NetworkState::USER_COMMAND) {
+                disabled_by_user = true;
+            }
+            if (origin >= NetworkState::HA_LOCAL_COMMAND && origin < NetworkState::HA_REMOTE_COMMAND) {
+                local_origin->set(local_count++, Element::create(origin - NetworkState::HA_LOCAL_COMMAND));
+            }
+            if (origin >= NetworkState::HA_REMOTE_COMMAND && origin < NetworkState::DB_CONNECTION) {
+                remote_origin->set(remote_count++, Element::create(origin - NetworkState::HA_REMOTE_COMMAND));
+            }
+        }
+        result->set("disabled-by-user", Element::create(disabled_by_user));
+        result->set("disabled-by-local-command", local_origin);
+        result->set("disabled-by-remote-command", remote_origin);
+
+        return (result);
+    }
+
     /// @brief Server type.
     NetworkState::ServerType server_type_;
 
@@ -192,6 +253,18 @@ NetworkState::resetForDbConnection() {
     impl_->resetForDbConnection();
 }
 
+void
+NetworkState::resetForLocalCommands() {
+    MultiThreadingLock lock(*mutex_);
+    impl_->resetForLocalCommands();
+}
+
+void
+NetworkState::resetForRemoteCommands() {
+    MultiThreadingLock lock(*mutex_);
+    impl_->resetForRemoteCommands();
+}
+
 void
 NetworkState::delayedEnableService(const unsigned int seconds, unsigned int origin) {
     MultiThreadingLock lock(*mutex_);
@@ -234,5 +307,10 @@ NetworkState::selectiveEnable(const NetworkState::Networks&) {
     isc_throw(NotImplemented, "selectiveEnableService is not implemented");
 }
 
+ConstElementPtr NetworkState::toElement() {
+    MultiThreadingLock lock(*mutex_);
+    return (impl_->toElement());
+}
+
 } // end of namespace isc::dhcp
 } // end of namespace isc
index 861d1a78cb33440e776fc5c863ac3a3e04436946..ab20f67caeca8871a6e0797184f5a9a2ad6a3fdf 100644 (file)
@@ -139,6 +139,18 @@ public:
     /// all other origins is enabled.
     void resetForDbConnection();
 
+    /// @brief Reset origins for local commands.
+    ///
+    /// It results in enabling the network service if network service for
+    /// all other origins is enabled.
+    void resetForLocalCommands();
+
+    /// @brief Reset origins for remote commands.
+    ///
+    /// It results in enabling the network service if network service for
+    /// all other origins is enabled.
+    void resetForRemoteCommands();
+
     /// @brief Schedules enabling DHCP service in the future.
     ///
     /// @param seconds Number of seconds after which the service should be enabled
@@ -196,6 +208,11 @@ public:
     /// @throw isc::NotImplemented
     void selectiveEnable(const NetworkState::Networks& networks);
 
+    /// @brief The network state as Element.
+    ///
+    /// @return The network state as Element.
+    isc::data::ConstElementPtr toElement();
+
     //@}
 
 private: