Kea 2.7.6
network_state.cc
Go to the documentation of this file.
1// Copyright (C) 2017-2024 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8
11#include <dhcpsrv/timer_mgr.h>
13#include <boost/enable_shared_from_this.hpp>
14#include <functional>
15#include <sstream>
16#include <string>
17#include <unordered_set>
18
19using namespace isc::data;
20using namespace isc::util;
21
22namespace isc {
23namespace dhcp {
24
26class NetworkStateImpl : public boost::enable_shared_from_this<NetworkStateImpl>,
27 public CfgToElement {
28public:
29
35
38 for (auto const& origin : disabled_by_origin_) {
39 destroyTimer(origin);
40 }
41 }
42
55 void setDisableService(const bool disable, unsigned int origin) {
56 if (disable) {
57 // Disable the service for any flag.
58 globally_disabled_ = true;
59 if (origin == NetworkState::DB_CONNECTION) {
61 } else {
62 disabled_by_origin_.insert(origin);
63 }
64 } else {
65 if (origin == NetworkState::DB_CONNECTION) {
66 // Never go below 0 (using unsigned type).
67 // This should never happen anyway.
70 }
71 } else {
72 disabled_by_origin_.erase(origin);
73 }
74 // Enable the service only if all flags have been cleared.
76 globally_disabled_ = false;
77 }
78 }
79 }
80
86 if (disabled_by_origin_.empty()) {
87 globally_disabled_ = false;
88 }
89 }
90
95 auto disabled_by_origin = disabled_by_origin_;
96 for (auto const& origin : disabled_by_origin) {
97 if (origin >= NetworkState::HA_LOCAL_COMMAND &&
99 disabled_by_origin_.erase(origin);
100 }
101 }
103 globally_disabled_ = false;
104 }
105 }
106
111 auto disabled_by_origin = disabled_by_origin_;
112 for (auto const& origin : disabled_by_origin) {
113 if (origin >= NetworkState::HA_REMOTE_COMMAND &&
115 disabled_by_origin_.erase(origin);
116 }
117 }
119 globally_disabled_ = false;
120 }
121 }
122
128 void delayedEnable(unsigned int origin) {
129 setDisableService(false, origin);
130 destroyTimer(origin);
131 }
132
142 void createTimer(const unsigned int seconds, unsigned int origin) {
143 destroyTimer(origin);
144 if (origin == NetworkState::DB_CONNECTION) {
145 isc_throw(BadValue, "DB connection does not support delayed enable");
146 }
147 auto timer_name = getTimerName(origin);
148 timer_mgr_->registerTimer(timer_name,
150 shared_from_this(), origin),
151 seconds * 1000,
153 timer_mgr_->setup(timer_name);
154 }
155
159 void destroyTimer(unsigned int origin) {
160 if (origin == NetworkState::DB_CONNECTION) {
161 return;
162 }
163 auto timer_name = getTimerName(origin);
164 if (timer_mgr_->isTimerRegistered(timer_name)) {
165 timer_mgr_->unregisterTimer(timer_name);
166 }
167 }
168
173 std::string getTimerName(unsigned int origin) const {
174 std::ostringstream timer_name;
175 timer_name << "network-state-timer-" << origin;
176 return (timer_name.str());
177 }
178
182 virtual ElementPtr toElement() const {
184 result->set("globally-disabled", Element::create(globally_disabled_));
185 result->set("disabled-by-db-connection", Element::create(disabled_by_db_connection_ != 0));
186 bool disabled_by_user = false;
187 ElementPtr local_origin = Element::createList();
188 ElementPtr remote_origin = Element::createList();
189 std::set<unsigned int> ordered(disabled_by_origin_.begin(), disabled_by_origin_.end());
190 for (auto const& origin : ordered) {
191 if (origin == NetworkState::USER_COMMAND) {
192 disabled_by_user = true;
193 }
195 local_origin->add(Element::create(origin));
196 }
198 remote_origin->add(Element::create(origin));
199 }
200 }
201 result->set("disabled-by-user", Element::create(disabled_by_user));
202 result->set("disabled-by-local-command", local_origin);
203 result->set("disabled-by-remote-command", remote_origin);
204
205 return (result);
206 }
207
210
213
216
222
224 std::unordered_set<unsigned int> disabled_by_origin_;
225
229};
230
232 : impl_(new NetworkStateImpl()), mutex_(new std::mutex()) {
233}
234
235void
236NetworkState::disableService(unsigned int origin) {
237 MultiThreadingLock lock(*mutex_);
238 impl_->setDisableService(true, origin);
239}
240
241void
242NetworkState::enableService(unsigned int origin) {
243 MultiThreadingLock lock(*mutex_);
244 impl_->delayedEnable(origin);
245}
246
247void
249 MultiThreadingLock lock(*mutex_);
250 impl_->resetForDbConnection();
251}
252
253void
255 MultiThreadingLock lock(*mutex_);
256 impl_->resetForLocalCommands();
257}
258
259void
261 MultiThreadingLock lock(*mutex_);
262 impl_->resetForRemoteCommands();
263}
264
265void
266NetworkState::delayedEnableService(const unsigned int seconds, unsigned int origin) {
267 MultiThreadingLock lock(*mutex_);
268 impl_->createTimer(seconds, origin);
269}
270
271bool
273 MultiThreadingLock lock(*mutex_);
274 return (!impl_->globally_disabled_);
275}
276
277bool
279 for (auto const& origin : impl_->disabled_by_origin_) {
280 if (TimerMgr::instance()->isTimerRegistered(impl_->getTimerName(origin))) {
281 return (true);
282 }
283 }
284 return (false);
285}
286
287void
289 isc_throw(NotImplemented, "selectiveDisableService is not implemented");
290}
291
292void
294 isc_throw(NotImplemented, "selectiveDisableService is not implemented");
295}
296
297void
299 isc_throw(NotImplemented, "selectiveEnableService is not implemented");
300}
301
302void
304 isc_throw(NotImplemented, "selectiveEnableService is not implemented");
305}
306
308 MultiThreadingLock lock(*mutex_);
309 return (impl_->toElement());
310}
311
312} // end of namespace isc::dhcp
313} // end of namespace isc
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
A generic exception that is thrown when a function is not implemented.
static ElementPtr create(const Position &pos=ZERO_POSITION())
Definition data.cc:249
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition data.cc:304
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
Definition data.cc:299
Implementation of the NetworkState class.
void resetForDbConnection()
Reset internal counters for a database connection origin.
std::string getTimerName(unsigned int origin) const
Creates a unique timer name from the origin.
void setDisableService(const bool disable, unsigned int origin)
Sets appropriate disabled or enabled DHCP service state for the respective origin.
NetworkState::Subnets disabled_subnets_
A list of subnets for which the DHCP service has been disabled.
virtual ElementPtr toElement() const
The network state as Element.
void resetForRemoteCommands()
Reset origin for remote commands.
bool globally_disabled_
A flag indicating if DHCP service is globally disabled.
TimerMgrPtr timer_mgr_
A pointer to the common timer manager.
void delayedEnable(unsigned int origin)
Enables DHCP service for an origin.
uint32_t disabled_by_db_connection_
Flag which indicates the state has been disabled by a DB connection loss.
std::unordered_set< unsigned int > disabled_by_origin_
A set of requests to disable the service by origin.
NetworkState::Networks disabled_networks_
A list of networks for which the DHCP service has been disabled.
void createTimer(const unsigned int seconds, unsigned int origin)
Creates a timer counting the time when delayedEnable should be automatically called.
void destroyTimer(unsigned int origin)
Destroys a timer if present.
void resetForLocalCommands()
Reset origin for local commands.
static const unsigned int DB_CONNECTION
The network state is being altered by the DB connection recovery mechanics.
void selectiveDisable(const NetworkState::Subnets &subnets)
Disable DHCP service for selected subnets.
virtual isc::data::ElementPtr toElement() const
The network state as Element.
static const unsigned int USER_COMMAND
Origin of the network state transition.
std::set< SubnetID > Subnets
Type of the container holding collection of subnet identifiers.
std::set< std::string > Networks
Type of the container holding collection of shared network names.
static const unsigned int HA_LOCAL_COMMAND
The network state is being altered by an HA internal command.
bool isDelayedEnableService() const
Checks if delayed enabling of DHCP services is scheduled.
static const unsigned int HA_REMOTE_COMMAND
The network state is being altered by a "dhcp-disable" or "dhcp-enable" command sent by a HA partner.
void resetForDbConnection()
Reset internal counters for database connection.
void resetForLocalCommands()
Reset origins for local commands.
void selectiveEnable(const NetworkState::Subnets &subnets)
Enable DHCP service for selected subnets.
void enableService(unsigned int origin)
Enable the DHCP service state for respective transition origin.
void disableService(unsigned int origin)
Disable the DHCP service state for respective transition origin.
bool isServiceEnabled() const
Checks if the DHCP service is globally enabled.
void delayedEnableService(const unsigned int seconds, unsigned int origin)
Schedules enabling DHCP service in the future.
void resetForRemoteCommands()
Reset origins for remote commands.
Manages a pool of asynchronous interval timers.
Definition timer_mgr.h:62
static const TimerMgrPtr & instance()
Returns pointer to the sole instance of the TimerMgr.
Definition timer_mgr.cc:446
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< Element > ElementPtr
Definition data.h:28
boost::shared_ptr< TimerMgr > TimerMgrPtr
Type definition of the shared pointer to TimerMgr.
Definition timer_mgr.h:27
Defines the logger used by the top-level component of kea-lfc.
Abstract class for configuration Cfg_* classes.
RAII lock object to protect the code in the same scope with a mutex.