From e21656d5594ef0e63e26757546ca3d945df73107 Mon Sep 17 00:00:00 2001 From: Razvan Becheriu Date: Wed, 10 Jul 2024 18:31:59 +0300 Subject: [#3446] add dhcp state to get-status --- src/bin/dhcp4/ctrl_dhcp4_srv.cc | 5 ++- src/bin/dhcp6/ctrl_dhcp6_srv.cc | 4 +++ src/lib/dhcpsrv/network_state.cc | 78 ++++++++++++++++++++++++++++++++++++++++ src/lib/dhcpsrv/network_state.h | 17 +++++++++ 4 files changed, 103 insertions(+), 1 deletion(-) diff --git a/src/bin/dhcp4/ctrl_dhcp4_srv.cc b/src/bin/dhcp4/ctrl_dhcp4_srv.cc index d0483a3584..3863e8fdb9 100644 --- a/src/bin/dhcp4/ctrl_dhcp4_srv.cc +++ b/src/bin/dhcp4/ctrl_dhcp4_srv.cc @@ -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())); diff --git a/src/bin/dhcp6/ctrl_dhcp6_srv.cc b/src/bin/dhcp6/ctrl_dhcp6_srv.cc index 457eeb46a1..6bcfb3f254 100644 --- a/src/bin/dhcp6/ctrl_dhcp6_srv.cc +++ b/src/bin/dhcp6/ctrl_dhcp6_srv.cc @@ -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())); diff --git a/src/lib/dhcpsrv/network_state.cc b/src/lib/dhcpsrv/network_state.cc index 97e84dba50..57b5671714 100644 --- a/src/lib/dhcpsrv/network_state.cc +++ b/src/lib/dhcpsrv/network_state.cc @@ -16,6 +16,7 @@ #include #include +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 diff --git a/src/lib/dhcpsrv/network_state.h b/src/lib/dhcpsrv/network_state.h index 861d1a78cb..ab20f67cae 100644 --- a/src/lib/dhcpsrv/network_state.h +++ b/src/lib/dhcpsrv/network_state.h @@ -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: -- cgit v1.2.3