| Kea 3.0.2-git

network_state.cc
Go to the documentation of this file.
1// Copyright (C) 2017-2025 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
9#include <exceptions/exceptions.h>
10#include <dhcpsrv/network_state.h>
11#include <dhcpsrv/timer_mgr.h>
12#include <util/multi_threading_mgr.h>
13#include <boost/enable_shared_from_this.hpp>
14#include <functional>
15#include <sstream>
16#include <string>
17#include <unordered_set>
18
19 using namespace isc::data;
20 using namespace isc::util;
21
22 namespace isc {
23 namespace dhcp {
24
26 class NetworkStateImpl : public boost::enable_shared_from_this<NetworkStateImpl>,
27 public CfgToElement {
28 public:
29
31 NetworkStateImpl() : globally_disabled_(false), disabled_subnets_(),
32 disabled_networks_(), timer_mgr_(TimerMgr::instance()),
33 disabled_by_origin_() {
34 }
35
37 ~NetworkStateImpl() {
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 disabled_by_origin_.insert(origin);
60 } else {
61 disabled_by_origin_.erase(origin);
62 // Enable the service only if all flags have been cleared.
63 if (disabled_by_origin_.empty()) {
64 globally_disabled_ = false;
65 }
66 }
67 }
68
72 void resetForDbConnection() {
73 auto disabled_by_origin = disabled_by_origin_;
74 for (auto const& origin : disabled_by_origin) {
75 if (origin >= NetworkState::DB_CONNECTION) {
76 disabled_by_origin_.erase(origin);
77 }
78 }
79 if (disabled_by_origin_.empty()) {
80 globally_disabled_ = false;
81 }
82 }
83
87 void resetForLocalCommands() {
88 auto disabled_by_origin = disabled_by_origin_;
89 for (auto const& origin : disabled_by_origin) {
90 if (origin >= NetworkState::HA_LOCAL_COMMAND &&
91 origin < NetworkState::HA_REMOTE_COMMAND) {
92 disabled_by_origin_.erase(origin);
93 }
94 }
95 if (disabled_by_origin_.empty()) {
96 globally_disabled_ = false;
97 }
98 }
99
103 void resetForRemoteCommands() {
104 auto disabled_by_origin = disabled_by_origin_;
105 for (auto const& origin : disabled_by_origin) {
106 if (origin >= NetworkState::HA_REMOTE_COMMAND &&
107 origin < NetworkState::DB_CONNECTION) {
108 disabled_by_origin_.erase(origin);
109 }
110 }
111 if (disabled_by_origin_.empty()) {
112 globally_disabled_ = false;
113 }
114 }
115
121 void delayedEnable(unsigned int origin) {
122 setDisableService(false, origin);
123 destroyTimer(origin);
124 }
125
135 void createTimer(const unsigned int seconds, unsigned int origin) {
136 destroyTimer(origin);
137 if (origin >= NetworkState::DB_CONNECTION) {
138 isc_throw(BadValue, "DB connection does not support delayed enable");
139 }
140 auto timer_name = getTimerName(origin);
141 timer_mgr_->registerTimer(timer_name,
142 std::bind(&NetworkStateImpl::delayedEnable,
143 shared_from_this(), origin),
144 seconds * 1000,
145 asiolink::IntervalTimer::ONE_SHOT);
146 timer_mgr_->setup(timer_name);
147 }
148
152 void destroyTimer(unsigned int origin) {
153 if (origin >= NetworkState::DB_CONNECTION) {
154 return;
155 }
156 auto timer_name = getTimerName(origin);
157 if (timer_mgr_->isTimerRegistered(timer_name)) {
158 timer_mgr_->unregisterTimer(timer_name);
159 }
160 }
161
166 std::string getTimerName(unsigned int origin) const {
167 std::ostringstream timer_name;
168 timer_name << "network-state-timer-" << origin;
169 return (timer_name.str());
170 }
171
175 virtual ElementPtr toElement() const {
176 ElementPtr result = Element::createMap();
177 result->set("globally-disabled", Element::create(globally_disabled_));
178 bool disabled_by_user = false;
179 ElementPtr local_origin = Element::createList();
180 ElementPtr remote_origin = Element::createList();
181 ElementPtr db_origin = Element::createList();
182 std::set<unsigned int> ordered(disabled_by_origin_.begin(), disabled_by_origin_.end());
183 for (auto const& origin : ordered) {
184 if (origin == NetworkState::USER_COMMAND) {
185 disabled_by_user = true;
186 }
187 if (origin >= NetworkState::HA_LOCAL_COMMAND && origin < NetworkState::HA_REMOTE_COMMAND) {
188 local_origin->add(Element::create(origin));
189 }
190 if (origin >= NetworkState::HA_REMOTE_COMMAND && origin < NetworkState::DB_CONNECTION) {
191 remote_origin->add(Element::create(origin));
192 }
193 if (origin >= NetworkState::DB_CONNECTION) {
194 db_origin->add(Element::create(origin));
195 }
196 }
197 result->set("disabled-by-user", Element::create(disabled_by_user));
198 result->set("disabled-by-local-command", local_origin);
199 result->set("disabled-by-remote-command", remote_origin);
200 result->set("disabled-by-db-connection", db_origin);
201
202 return (result);
203 }
204
206 bool globally_disabled_;
207
209 NetworkState::Subnets disabled_subnets_;
210
212 NetworkState::Networks disabled_networks_;
213
218 TimerMgrPtr timer_mgr_;
219
221 std::unordered_set<unsigned int> disabled_by_origin_;
222};
223
224 NetworkState::NetworkState()
225 : impl_(new NetworkStateImpl()), mutex_(new std::mutex()) {
226}
227
228 void
229 NetworkState::disableService(unsigned int origin) {
230 MultiThreadingLock lock(*mutex_);
231 impl_->setDisableService(true, origin);
232}
233
234 void
235 NetworkState::enableService(unsigned int origin) {
236 MultiThreadingLock lock(*mutex_);
237 impl_->delayedEnable(origin);
238}
239
240 void
241 NetworkState::resetForDbConnection() {
242 MultiThreadingLock lock(*mutex_);
243 impl_->resetForDbConnection();
244}
245
246 void
247 NetworkState::resetForLocalCommands() {
248 MultiThreadingLock lock(*mutex_);
249 impl_->resetForLocalCommands();
250}
251
252 void
253 NetworkState::resetForRemoteCommands() {
254 MultiThreadingLock lock(*mutex_);
255 impl_->resetForRemoteCommands();
256}
257
258 void
259 NetworkState::delayedEnableService(const unsigned int seconds, unsigned int origin) {
260 MultiThreadingLock lock(*mutex_);
261 impl_->createTimer(seconds, origin);
262}
263
264 bool
265 NetworkState::isServiceEnabled() const {
266 MultiThreadingLock lock(*mutex_);
267 return (!impl_->globally_disabled_);
268}
269
270 bool
271 NetworkState::isDelayedEnableService() const {
272 for (auto const& origin : impl_->disabled_by_origin_) {
273 if (TimerMgr::instance()->isTimerRegistered(impl_->getTimerName(origin))) {
274 return (true);
275 }
276 }
277 return (false);
278}
279
280 void
281 NetworkState::selectiveDisable(const NetworkState::Subnets&) {
282 isc_throw(NotImplemented, "selectiveDisableService is not implemented");
283}
284
285 void
286 NetworkState::selectiveDisable(const NetworkState::Networks&) {
287 isc_throw(NotImplemented, "selectiveDisableService is not implemented");
288}
289
290 void
291 NetworkState::selectiveEnable(const NetworkState::Subnets&) {
292 isc_throw(NotImplemented, "selectiveEnableService is not implemented");
293}
294
295 void
296 NetworkState::selectiveEnable(const NetworkState::Networks&) {
297 isc_throw(NotImplemented, "selectiveEnableService is not implemented");
298}
299
300 ElementPtr NetworkState::toElement() const {
301 MultiThreadingLock lock(*mutex_);
302 return (impl_->toElement());
303}
304
305} // end of namespace isc::dhcp
306} // end of namespace isc
isc::BadValue
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
Definition exceptions/exceptions.h:132
isc::NotImplemented
A generic exception that is thrown when a function is not implemented.
Definition exceptions/exceptions.h:166
isc::asiolink::IntervalTimer::ONE_SHOT
@ ONE_SHOT
Definition interval_timer.h:63
isc::data::Element::create
static ElementPtr create(const Position &pos=ZERO_POSITION())
Definition data.cc:249
isc::data::Element::createMap
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition data.cc:304
isc::data::Element::createList
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
Definition data.cc:299
isc::dhcp::NetworkStateImpl
Implementation of the NetworkState class.
Definition network_state.cc:27
isc::dhcp::NetworkStateImpl::resetForDbConnection
void resetForDbConnection()
Reset internal counters for a database connection origin.
Definition network_state.cc:72
isc::dhcp::NetworkStateImpl::getTimerName
std::string getTimerName(unsigned int origin) const
Creates a unique timer name from the origin.
Definition network_state.cc:166
isc::dhcp::NetworkStateImpl::setDisableService
void setDisableService(const bool disable, unsigned int origin)
Sets appropriate disabled or enabled DHCP service state for the respective origin.
Definition network_state.cc:55
isc::dhcp::NetworkStateImpl::disabled_subnets_
NetworkState::Subnets disabled_subnets_
A list of subnets for which the DHCP service has been disabled.
Definition network_state.cc:209
isc::dhcp::NetworkStateImpl::toElement
virtual ElementPtr toElement() const
The network state as Element.
Definition network_state.cc:175
isc::dhcp::NetworkStateImpl::resetForRemoteCommands
void resetForRemoteCommands()
Reset origin for remote commands.
Definition network_state.cc:103
isc::dhcp::NetworkStateImpl::globally_disabled_
bool globally_disabled_
A flag indicating if DHCP service is globally disabled.
Definition network_state.cc:206
isc::dhcp::NetworkStateImpl::timer_mgr_
TimerMgrPtr timer_mgr_
A pointer to the common timer manager.
Definition network_state.cc:218
isc::dhcp::NetworkStateImpl::delayedEnable
void delayedEnable(unsigned int origin)
Enables DHCP service for an origin.
Definition network_state.cc:121
isc::dhcp::NetworkStateImpl::NetworkStateImpl
NetworkStateImpl()
Constructor.
Definition network_state.cc:31
isc::dhcp::NetworkStateImpl::disabled_by_origin_
std::unordered_set< unsigned int > disabled_by_origin_
A set of requests to disable the service by origin.
Definition network_state.cc:221
isc::dhcp::NetworkStateImpl::disabled_networks_
NetworkState::Networks disabled_networks_
A list of networks for which the DHCP service has been disabled.
Definition network_state.cc:212
isc::dhcp::NetworkStateImpl::createTimer
void createTimer(const unsigned int seconds, unsigned int origin)
Creates a timer counting the time when delayedEnable should be automatically called.
Definition network_state.cc:135
isc::dhcp::NetworkStateImpl::~NetworkStateImpl
~NetworkStateImpl()
Destructor.
Definition network_state.cc:37
isc::dhcp::NetworkStateImpl::destroyTimer
void destroyTimer(unsigned int origin)
Destroys a timer if present.
Definition network_state.cc:152
isc::dhcp::NetworkStateImpl::resetForLocalCommands
void resetForLocalCommands()
Reset origin for local commands.
Definition network_state.cc:87
isc::dhcp::NetworkState::DB_CONNECTION
static const unsigned int DB_CONNECTION
The network state is being altered by the DB connection recovery mechanics.
Definition network_state.h:99
isc::dhcp::NetworkState::selectiveDisable
void selectiveDisable(const NetworkState::Subnets &subnets)
Disable DHCP service for selected subnets.
Definition network_state.cc:281
isc::dhcp::NetworkState::Subnets
std::set< SubnetID > Subnets
Type of the container holding collection of subnet identifiers.
Definition network_state.h:102
isc::dhcp::NetworkState::NetworkState
NetworkState()
Constructor.
Definition network_state.cc:224
isc::dhcp::NetworkState::toElement
virtual isc::data::ElementPtr toElement() const
The network state as Element.
Definition network_state.cc:300
isc::dhcp::NetworkState::USER_COMMAND
static const unsigned int USER_COMMAND
Origin of the network state transition.
Definition network_state.h:82
isc::dhcp::NetworkState::Networks
std::set< std::string > Networks
Type of the container holding collection of shared network names.
Definition network_state.h:105
isc::dhcp::NetworkState::HA_LOCAL_COMMAND
static const unsigned int HA_LOCAL_COMMAND
The network state is being altered by an HA internal command.
Definition network_state.h:88
isc::dhcp::NetworkState::isDelayedEnableService
bool isDelayedEnableService() const
Checks if delayed enabling of DHCP services is scheduled.
Definition network_state.cc:271
isc::dhcp::NetworkState::HA_REMOTE_COMMAND
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.
Definition network_state.h:95
isc::dhcp::NetworkState::resetForDbConnection
void resetForDbConnection()
Reset internal counters for database connection.
Definition network_state.cc:241
isc::dhcp::NetworkState::resetForLocalCommands
void resetForLocalCommands()
Reset origins for local commands.
Definition network_state.cc:247
isc::dhcp::NetworkState::selectiveEnable
void selectiveEnable(const NetworkState::Subnets &subnets)
Enable DHCP service for selected subnets.
Definition network_state.cc:291
isc::dhcp::NetworkState::enableService
void enableService(unsigned int origin)
Enable the DHCP service state for respective transition origin.
Definition network_state.cc:235
isc::dhcp::NetworkState::disableService
void disableService(unsigned int origin)
Disable the DHCP service state for respective transition origin.
Definition network_state.cc:229
isc::dhcp::NetworkState::isServiceEnabled
bool isServiceEnabled() const
Checks if the DHCP service is globally enabled.
Definition network_state.cc:265
isc::dhcp::NetworkState::delayedEnableService
void delayedEnableService(const unsigned int seconds, unsigned int origin)
Schedules enabling DHCP service in the future.
Definition network_state.cc:259
isc::dhcp::NetworkState::resetForRemoteCommands
void resetForRemoteCommands()
Reset origins for remote commands.
Definition network_state.cc:253
isc::dhcp::TimerMgr
Manages a pool of asynchronous interval timers.
Definition timer_mgr.h:62
isc::dhcp::TimerMgr::instance
static const TimerMgrPtr & instance()
Returns pointer to the sole instance of the TimerMgr.
Definition timer_mgr.cc:446
exceptions.h
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition exceptions/exceptions.h:210
multi_threading_mgr.h
isc::data
Definition base_stamped_element.cc:12
isc::data::ElementPtr
boost::shared_ptr< Element > ElementPtr
Definition data.h:28
isc::dhcp
Definition dhcp4/client_handler.cc:20
isc::dhcp::TimerMgrPtr
boost::shared_ptr< TimerMgr > TimerMgrPtr
Type definition of the shared pointer to TimerMgr.
Definition timer_mgr.h:27
isc::util
Definition time_utils.cc:43
isc
Defines the logger used by the top-level component of kea-lfc.
Definition agent_parser.cc:148
network_state.h
isc::data::CfgToElement
Abstract class for configuration Cfg_* classes.
Definition cfg_to_element.h:29
isc::util::MultiThreadingLock
RAII lock object to protect the code in the same scope with a mutex.
Definition multi_threading_mgr.h:349
timer_mgr.h