Kea  2.1.7-git
network_state.cc
Go to the documentation of this file.
1 // Copyright (C) 2017-2021 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 
10 #include <dhcpsrv/network_state.h>
11 #include <dhcpsrv/timer_mgr.h>
13 #include <boost/enable_shared_from_this.hpp>
14 #include <functional>
15 #include <string>
16 
17 using namespace isc::util;
18 
19 namespace {
20 
22 const std::string NETWORK_STATE_TIMER_NAME_USER_CMD = "network-state-timer-user-cmd";
23 const std::string NETWORK_STATE_TIMER_NAME_HA_CMD = "network-state-timer-ha-cmd";
24 
25 } // end of anonymous namespace
26 
27 namespace isc {
28 namespace dhcp {
29 
31 class NetworkStateImpl : public boost::enable_shared_from_this<NetworkStateImpl> {
32 public:
33 
36  : server_type_(server_type), globally_disabled_(false),
37  disabled_subnets_(), disabled_networks_(),
38  timer_mgr_(TimerMgr::instance()), disabled_by_user_command_(false),
39  disabled_by_ha_command_(false), disabled_by_db_connection_(0) {
40  }
41 
44  destroyTimer(NetworkState::Origin::USER_COMMAND);
45  destroyTimer(NetworkState::Origin::HA_COMMAND);
46  }
47 
60  void setDisableService(const bool disable,
61  const NetworkState::Origin& origin) {
62  if (disable) {
63  // Disable the service for any flag.
64  globally_disabled_ = true;
65  switch (origin) {
66  case NetworkState::Origin::USER_COMMAND:
67  disabled_by_user_command_ = true;
68  break;
69  case NetworkState::Origin::HA_COMMAND:
70  disabled_by_ha_command_ = true;
71  break;
72  case NetworkState::Origin::DB_CONNECTION:
73  ++disabled_by_db_connection_;
74  break;
75  default:
76  isc_throw(NotImplemented, "origin value not handled when "
77  "disabling the network state");
78  break;
79  }
80  } else {
81  switch (origin) {
82  case NetworkState::Origin::USER_COMMAND:
83  disabled_by_user_command_ = false;
84  break;
85  case NetworkState::Origin::HA_COMMAND:
86  disabled_by_ha_command_ = false;
87  break;
88  case NetworkState::Origin::DB_CONNECTION:
89  // Never go below 0 (using unsigned type).
90  // This should never happen anyway.
91  if (disabled_by_db_connection_) {
92  --disabled_by_db_connection_;
93  }
94  break;
95  default:
96  isc_throw(NotImplemented, "origin value not handled when "
97  "enabling the network state");
98  break;
99  }
100  // Enable the service only if all flags have been cleared.
101  if (!disabled_by_user_command_ && !disabled_by_ha_command_ &&
102  disabled_by_db_connection_ == 0) {
103  globally_disabled_ = false;
104  }
105  }
106  }
107 
113  void reset(const NetworkState::Origin& origin) {
114  switch (origin) {
115  case NetworkState::Origin::USER_COMMAND:
116  disabled_by_user_command_ = false;
117  break;
118  case NetworkState::Origin::HA_COMMAND:
119  disabled_by_ha_command_ = false;
120  break;
121  case NetworkState::Origin::DB_CONNECTION:
122  disabled_by_db_connection_ = 0;
123  break;
124  default:
125  isc_throw(NotImplemented, "origin value not handled when "
126  "resetting the network state");
127  break;
128  }
129  // Enable the service only if all flags have been cleared.
130  if (!disabled_by_user_command_ && !disabled_by_ha_command_ &&
131  disabled_by_db_connection_ == 0) {
132  globally_disabled_ = false;
133  }
134  }
135 
141  void enableAll(const NetworkState::Origin& origin) {
142  setDisableService(false, origin);
143 
145 
146  destroyTimer(origin);
147  }
148 
158  void createTimer(const unsigned int seconds,
159  const NetworkState::Origin& origin) {
160  destroyTimer(origin);
161  std::string timer_name = NETWORK_STATE_TIMER_NAME_USER_CMD;
162  switch (origin) {
163  case NetworkState::Origin::USER_COMMAND:
164  timer_name = NETWORK_STATE_TIMER_NAME_USER_CMD;
165  break;
166  case NetworkState::Origin::HA_COMMAND:
167  timer_name = NETWORK_STATE_TIMER_NAME_HA_CMD;
168  break;
169  case NetworkState::Origin::DB_CONNECTION:
170  isc_throw(BadValue, "DB connection does not support delayed enable");
171  break;
172  default:
173  isc_throw(NotImplemented, "origin value not handled when creating "
174  "a timer for delayed enable");
175  break;
176  }
177  timer_mgr_->registerTimer(timer_name,
178  std::bind(&NetworkStateImpl::enableAll,
179  shared_from_this(), origin),
180  seconds * 1000,
182  timer_mgr_->setup(timer_name);
183  }
184 
188  void destroyTimer(const NetworkState::Origin& origin) {
189  std::string timer_name = NETWORK_STATE_TIMER_NAME_USER_CMD;
190  switch (origin) {
191  case NetworkState::Origin::USER_COMMAND:
192  timer_name = NETWORK_STATE_TIMER_NAME_USER_CMD;
193  break;
194  case NetworkState::Origin::HA_COMMAND:
195  timer_name = NETWORK_STATE_TIMER_NAME_HA_CMD;
196  break;
197  case NetworkState::Origin::DB_CONNECTION:
198  return;
199  default:
200  isc_throw(NotImplemented, "origin value not handled when creating "
201  "a timer for delayed enable");
202  break;
203  }
204  if (timer_mgr_->isTimerRegistered(timer_name)) {
205  timer_mgr_->unregisterTimer(timer_name);
206  }
207  }
208 
211 
214 
217 
220 
226 
230 
234 
238 };
239 
240 NetworkState::NetworkState(const NetworkState::ServerType& server_type)
241  : impl_(new NetworkStateImpl(server_type)), mutex_(new std::mutex()) {
242 }
243 
244 void
246  if (MultiThreadingMgr::instance().getMode()) {
247  std::lock_guard<std::mutex> lk(*mutex_);
248  impl_->setDisableService(true, origin);
249  } else {
250  impl_->setDisableService(true, origin);
251  }
252 }
253 
254 void
256  if (MultiThreadingMgr::instance().getMode()) {
257  std::lock_guard<std::mutex> lk(*mutex_);
258  impl_->setDisableService(false, origin);
259  } else {
260  impl_->setDisableService(false, origin);
261  }
262 }
263 
264 void
266  if (MultiThreadingMgr::instance().getMode()) {
267  std::lock_guard<std::mutex> lk(*mutex_);
268  impl_->reset(origin);
269  } else {
270  impl_->reset(origin);
271  }
272 }
273 
274 void
276  if (MultiThreadingMgr::instance().getMode()) {
277  std::lock_guard<std::mutex> lk(*mutex_);
278  impl_->enableAll(origin);
279  } else {
280  impl_->enableAll(origin);
281  }
282 }
283 
284 void
285 NetworkState::delayedEnableAll(const unsigned int seconds,
286  const NetworkState::Origin& origin) {
287  if (MultiThreadingMgr::instance().getMode()) {
288  std::lock_guard<std::mutex> lk(*mutex_);
289  impl_->createTimer(seconds, origin);
290  } else {
291  impl_->createTimer(seconds, origin);
292  }
293 }
294 
295 bool
297  if (MultiThreadingMgr::instance().getMode()) {
298  std::lock_guard<std::mutex> lk(*mutex_);
299  return (!impl_->globally_disabled_);
300  } else {
301  return (!impl_->globally_disabled_);
302  }
303 }
304 
305 bool
307  return (TimerMgr::instance()->isTimerRegistered(NETWORK_STATE_TIMER_NAME_USER_CMD) ||
308  TimerMgr::instance()->isTimerRegistered(NETWORK_STATE_TIMER_NAME_HA_CMD));
309 }
310 
311 void
313  isc_throw(NotImplemented, "selectiveDisableService is not implemented");
314 }
315 
316 void
318  isc_throw(NotImplemented, "selectiveDisableService is not implemented");
319 }
320 
321 void
323  isc_throw(NotImplemented, "selectiveEnableService is not implemented");
324 }
325 
326 void
328  isc_throw(NotImplemented, "selectiveEnableService is not implemented");
329 }
330 
331 } // end of namespace isc::dhcp
332 } // end of namespace isc
boost::shared_ptr< TimerMgr > TimerMgrPtr
Type definition of the shared pointer to TimerMgr.
Definition: timer_mgr.h:24
NetworkState::ServerType server_type_
Server type.
A generic exception that is thrown when a function is not implemented.
std::set< std::string > Networks
Type of the container holding collection of shared network names.
Definition: network_state.h:98
bool globally_disabled_
A flag indicating if DHCP service is globally disabled.
void setDisableService(const bool disable, const NetworkState::Origin &origin)
Sets appropriate disabled or enabled DHCP service state for the respective origin.
void enableAll(const NetworkState::Origin &origin)
Enables DHCP service globally and per scopes.
void enableService(const NetworkState::Origin &origin)
Enable the DHCP service state for respective transition origin.
ServerType
DHCP server type.
Definition: network_state.h:74
Manages a pool of asynchronous interval timers.
Definition: timer_mgr.h:62
void delayedEnableAll(const unsigned int seconds, const NetworkState::Origin &origin)
Schedules enabling DHCP service in the future.
void reset(const NetworkState::Origin &type)
Reset internal counters.
STL namespace.
std::set< SubnetID > Subnets
Type of the container holding collection of subnet identifiers.
Definition: network_state.h:95
void selectiveEnable(const NetworkState::Subnets &subnets)
Enable DHCP service for selected subnets.
void enableAll(const NetworkState::Origin &origin)
Enables DHCP service globally and for scopes which have been disabled as a result of control command...
bool disabled_by_ha_command_
Flag which indicates the state has been disabled by the HA command.
Origin
Origin of the network state transition.
Definition: network_state.h:84
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
Definition: edns.h:19
Implementation of the NetworkState class.
NetworkState::Networks disabled_networks_
A list of networks for which the DHCP service has been disabled.
NetworkStateImpl(const NetworkState::ServerType &server_type)
Constructor.
void destroyTimer(const NetworkState::Origin &origin)
Destroys a timer if present.
void selectiveDisable(const NetworkState::Subnets &subnets)
Disable DHCP service for selected subnets.
Defines the logger used by the top-level component of kea-lfc.
bool isServiceEnabled() const
Checks if the DHCP service is globally enabled.
void disableService(const NetworkState::Origin &origin)
Disable the DHCP service state for respective transition origin.
uint32_t disabled_by_db_connection_
Flag which indicates the state has been disabled by a DB connection loss.
NetworkState::Subnets disabled_subnets_
A list of subnets for which the DHCP service has been disabled.
static const TimerMgrPtr & instance()
Returns pointer to the sole instance of the TimerMgr.
Definition: timer_mgr.cc:449
void createTimer(const unsigned int seconds, const NetworkState::Origin &origin)
Creates a timer counting the time when enableAll should be automatically called.
void reset(const NetworkState::Origin &origin)
Reset internal counters for a specific origin.
bool isDelayedEnableAll() const
Checks if delayed enabling of DHCP services is scheduled.
bool disabled_by_user_command_
Flag which indicates the state has been disabled by an user command.
TimerMgrPtr timer_mgr_
A pointer to the common timer manager.