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 #ifndef NETWORK_H
8 #define NETWORK_H
9
10 #include <cc/cfg_to_element.h>
11 #include <cc/data.h>
12 #include <cc/element_value.h>
13 #include <cc/stamped_element.h>
14 #include <cc/user_context.h>
15 #include <dhcp/classify.h>
16 #include <dhcp/option.h>
17 #include <dhcpsrv/cfg_option.h>
18 #include <dhcpsrv/cfg_4o6.h>
19 #include <dhcpsrv/d2_client_cfg.h>
20 #include <dhcpsrv/triplet.h>
21 #include <util/optional.h>
22 #include <boost/shared_ptr.hpp>
23 #include <boost/weak_ptr.hpp>
24 #include <cstdint>
25 #include <functional>
26 #include <string>
27
28 /// @brief Template to ignore unused arguments.
29 namespace {
30 template <typename... Args>
unused(Args const &...)31 inline void unused(Args const& ...) {}
32 } // end of anonymous namespace
33
34 namespace isc {
35 namespace dhcp {
36
37 /// List of IOAddresses
38 typedef std::vector<isc::asiolink::IOAddress> IOAddressList;
39
40 class Network;
41
42 /// @brief Pointer to the @ref Network object.
43 typedef boost::shared_ptr<Network> NetworkPtr;
44
45 /// @brief Weak pointer to the @ref Network object.
46 typedef boost::weak_ptr<Network> WeakNetworkPtr;
47
48 /// @brief Callback function for @c Network that retrieves globally
49 /// configured parameters.
50 typedef std::function<data::ConstElementPtr()> FetchNetworkGlobalsFn;
51
52 /// @brief Common interface representing a network to which the DHCP clients
53 /// are connected.
54 ///
55 /// The most common type of network, in Kea's terminology, is a subnet. The
56 /// @ref Subnet derives from this class. Another types of objects implementing
57 /// this interface are @ref SharedNetwork4 and @ref SharedNetwork6 objects.
58 /// They group multiple subnets together to provide means for
59 /// extending available address pools (a single client may obtain IP
60 /// address from any of the pools belonging to subnets in the shared
61 /// network), or for selecting a subnet on a given link, depending on the
62 /// class of the client (e.g. cable network case: different subnet is
63 /// selected for cable modems, different one for routers).
64 ///
65 /// The subnets and shared networks share many data structures, e.g. DHCP
66 /// options, local interface name, address manipulation methods. Both subnets
67 /// and shared networks derive from this class to provide the common
68 /// functionality.
69 ///
70 /// The DHCP server configuration is complex because many parameters may
71 /// be specified at different levels of hierarchy. The lower level values,
72 /// e.g. subnet specific values, take precedence over upper level values,
73 /// e.g. shared network specific ones. For historical reasons, the DHCP
74 /// servers expect that the appropriate values are inherited from the
75 /// upper configuration levels to the lower configuration levels upon
76 /// the reconfiguration. For example: if a user didn't specify
77 /// valid-lifetime for a subnet, calling @c Subnet4::getValid() should
78 /// result in returning a global value of valid-lifetime. In the early
79 /// Kea days it was achieved by the configuration parsers which would
80 /// explicitly assign the global valid lifetime to the @c Subnet4
81 /// instances for which the subnet specific value was not provided. This
82 /// approach has a major benefit that it is fast. However, it makes
83 /// the subnets tightly dependent on the global values (and shared
84 /// network specific values). Modification of the global value must
85 /// result in modification of this value in all subnets for which
86 /// there is no explicit value provided. This issue became a serious
87 /// road block during the implementation of the Configuration Backend.
88 ///
89 /// The @c Network object has been modified to address the problem of
90 /// inheritance of global, shared network specific and subnet specific
91 /// parameters in a generic way, at the same time minimizing the need to
92 /// change the existing server logic.
93 ///
94 /// The @c Network object now holds the pointer to the "parent" @c Network
95 /// object. Thus subnets which belong to a shared network will have
96 /// that shared network as its parent. Stand-alone subnets, will have
97 /// no parent.
98 ///
99 /// The general idea is that the accessor functions of the network
100 /// will first check if the accessed value is specified or not (that
101 /// is handled by @c util::Optional object). If the value is specified
102 /// it is returned. Otherwise, the object will check if there is a
103 /// parent object it belongs to and will call the appropriate method
104 /// of that object. If the value is present it is returned. Otherwise
105 /// the global value is returned.
106 ///
107 /// Accessing global values from the @c Network object is troublesome.
108 /// There is no uniform way to access those values. For example, the
109 /// given network may be in a staging or current configuration and
110 /// it really has no means to know in which of the two it belongs.
111 /// In fact, an attempt to pass the pointer to the @c SrvConfig object
112 /// would cause a circular dependency between the @c Network and the
113 /// @c SrvConfig. Even if it was possible and the @c Network had
114 /// access to the specific @c SrvConfig instance, it doesn't handle
115 /// the cases when the @c SrvConfig instance was modified.
116 ///
117 /// To deal with the problem of accessing the global parameters in a
118 /// flexible manner, we elected to use an optional callback function
119 /// which can be associated with the @c Network object. This callback
120 /// implements the logic to retrieve global parameters and return them
121 /// in a well known form, so as the @c Network accessors can use them.
122 class Network : public virtual isc::data::StampedElement,
123 public virtual isc::data::UserContext,
124 public isc::data::CfgToElement {
125 public:
126 /// @brief Holds optional information about relay.
127 ///
128 /// In some cases it is beneficial to have additional information about
129 /// a relay configured in the subnet. For now, the structure holds only
130 /// IP addresses, but there may potentially be additional parameters added
131 /// later, e.g. relay interface-id or relay-id.
132 class RelayInfo {
133 public:
134
135 /// @brief Adds an address to the list of addresses
136 ///
137 /// @param addr address to add
138 /// @throw BadValue if the address is already in the list
139 void addAddress(const asiolink::IOAddress& addr);
140
141 /// @brief Returns const reference to the list of addresses
142 ///
143 /// @return const reference to the list of addresses
144 const IOAddressList& getAddresses() const;
145
146 /// @brief Indicates whether or not the address list has entries
147 ///
148 /// @return True if the address list is not empty
149 bool hasAddresses() const;
150
151 /// @brief Checks the address list for the given address
152 ///
153 /// @return True if the address is found in the address list
154 bool containsAddress(const asiolink::IOAddress& addr) const;
155
156 private:
157 /// @brief List of relay IP addresses
158 IOAddressList addresses_;
159 };
160
161 /// @brief Inheritance "mode" used when fetching an optional @c Network
162 /// parameter.
163 ///
164 /// The following modes are currently supported:
165 /// - NONE: no inheritance is used, the network specific value is returned
166 /// regardless if it is specified or not.
167 /// - PARENT_NETWORK: parent network specific value is returned or unspecified
168 /// if the parent network doesn't exist.
169 /// - GLOBAL: global specific value is returned.
170 /// - ALL: inheritance is used on all levels: network specific value takes
171 /// precedence over parent specific value over the global value.
172 enum class Inheritance {
173 NONE,
174 PARENT_NETWORK,
175 GLOBAL,
176 ALL
177 };
178
179 /// Pointer to the RelayInfo structure
180 typedef boost::shared_ptr<Network::RelayInfo> RelayInfoPtr;
181
182 /// @brief Constructor.
Network()183 Network()
184 : iface_name_(), client_class_(), t1_(), t2_(), valid_(),
185 reservations_global_(false, true), reservations_in_subnet_(true, true),
186 reservations_out_of_pool_(false, true), cfg_option_(new CfgOption()),
187 calculate_tee_times_(), t1_percent_(), t2_percent_(),
188 ddns_send_updates_(), ddns_override_no_update_(), ddns_override_client_update_(),
189 ddns_replace_client_name_mode_(), ddns_generated_prefix_(), ddns_qualifying_suffix_(),
190 hostname_char_set_(), hostname_char_replacement_(), store_extended_info_(),
191 cache_threshold_(), cache_max_age_(), ddns_update_on_renew_(),
192 ddns_use_conflict_resolution_() {
193 }
194
195 /// @brief Virtual destructor.
196 ///
197 /// Does nothing at the moment.
~Network()198 virtual ~Network() { };
199
200 /// @brief Sets the optional callback function used to fetch globally
201 /// configured parameters.
202 ///
203 /// @param fetch_globals_fn Pointer to the function.
setFetchGlobalsFn(FetchNetworkGlobalsFn fetch_globals_fn)204 void setFetchGlobalsFn(FetchNetworkGlobalsFn fetch_globals_fn) {
205 fetch_globals_fn_ = fetch_globals_fn;
206 }
207
208 /// @brief Checks if the network is associated with a function used to
209 /// fetch globally configured parameters.
210 ///
211 /// @return true if it is associated, false otherwise.
hasFetchGlobalsFn()212 bool hasFetchGlobalsFn() const {
213 return (static_cast<bool>(fetch_globals_fn_));
214 }
215
216 /// @brief Sets local name of the interface for which this network is
217 /// selected.
218 ///
219 /// If the interface is specified, the server will use the network
220 /// associated with this local interface to allocate IP addresses and
221 /// other resources to a client.
222 ///
223 /// @param iface_name Interface name.
setIface(const util::Optional<std::string> & iface_name)224 void setIface(const util::Optional<std::string>& iface_name) {
225 iface_name_ = iface_name;
226 }
227
228 /// @brief Returns name of the local interface for which this network is
229 /// selected.
230 ///
231 /// @param inheritance inheritance mode to be used.
232 /// @return Interface name as text.
233 util::Optional<std::string>
234 getIface(const Inheritance& inheritance = Inheritance::ALL) const {
235 return (getProperty<Network>(&Network::getIface, iface_name_,
236 inheritance));
237 };
238
239 /// @brief Sets information about relay
240 ///
241 /// In some situations where there are shared subnets (i.e. two different
242 /// subnets are available on the same physical link), there is only one
243 /// relay that handles incoming requests from clients. In such a case,
244 /// the usual subnet selection criteria based on relay belonging to the
245 /// subnet being selected are no longer sufficient and we need to explicitly
246 /// specify a relay. One notable example of such uncommon, but valid
247 /// scenario is a cable network, where there is only one CMTS (one relay),
248 /// but there are 2 distinct subnets behind it: one for cable modems
249 /// and another one for CPEs and other user equipment behind modems.
250 /// From manageability perspective, it is essential that modems get addresses
251 /// from different subnet, so users won't tinker with their modems.
252 ///
253 /// Setting this parameter is not needed in most deployments.
254 /// This structure holds IP address only for now, but it is expected to
255 /// be extended in the future.
256 ///
257 /// @param relay structure that contains relay information
setRelayInfo(const RelayInfo & relay)258 void setRelayInfo(const RelayInfo& relay) {
259 relay_ = relay;
260 }
261
262 /// @brief Returns const reference to relay information
263 ///
264 /// @note The returned reference is only valid as long as the object
265 /// returned it is valid.
266 ///
267 /// @return const reference to the relay information
getRelayInfo()268 const RelayInfo& getRelayInfo() const {
269 return (relay_);
270 }
271
272 /// @brief Adds an address to the list addresses in the network's relay info
273 ///
274 /// @param addr address of the relay
275 /// @throw BadValue if the address is already in the list
276 void addRelayAddress(const asiolink::IOAddress& addr);
277
278 /// @brief Returns the list of relay addresses from the network's relay info
279 ///
280 /// @return const reference to the list of addresses
281 const IOAddressList& getRelayAddresses() const;
282
283 /// @brief Indicates if network's relay info has relay addresses
284 ///
285 /// @return True the relay list is not empty, false otherwise
286 bool hasRelays() const;
287
288 /// @brief Tests if the network's relay info contains the given address
289 ///
290 /// @param address address to search for in the relay list
291 /// @return True if a relay with the given address is found, false otherwise
292 bool hasRelayAddress(const asiolink::IOAddress& address) const;
293
294 /// @brief Checks whether this network supports client that belongs to
295 /// specified classes.
296 ///
297 /// This method checks whether a client that belongs to given classes can
298 /// use this network. For example, if this class is reserved for client
299 /// class "foo" and the client belongs to classes "foo", "bar" and "baz",
300 /// it is supported. On the other hand, client belonging to classes
301 /// "foobar" and "zyxxy" is not supported.
302 ///
303 /// @note: changed the planned white and black lists idea to a simple
304 /// client class name.
305 ///
306 /// @param client_classes list of all classes the client belongs to
307 /// @return true if client can be supported, false otherwise
308 virtual bool
309 clientSupported(const isc::dhcp::ClientClasses& client_classes) const;
310
311 /// @brief Sets the supported class to class class_name
312 ///
313 /// @param class_name client class to be supported by this network
314 void allowClientClass(const isc::dhcp::ClientClass& class_name);
315
316 /// @brief Adds class class_name to classes required to be evaluated.
317 ///
318 /// @param class_name client class required to be evaluated
319 void requireClientClass(const isc::dhcp::ClientClass& class_name);
320
321 /// @brief Returns classes which are required to be evaluated
322 const ClientClasses& getRequiredClasses() const;
323
324 /// @brief returns the client class
325 ///
326 /// @note The returned reference is only valid as long as the object
327 /// returned it is valid.
328 ///
329 /// @param inheritance inheritance mode to be used.
330 /// @return client class @ref client_class_
331 util::Optional<ClientClass>
332 getClientClass(const Inheritance& inheritance = Inheritance::ALL) const {
333 return (getProperty<Network>(&Network::getClientClass, client_class_,
334 inheritance));
335 }
336
337 /// @brief Return valid-lifetime for addresses in that prefix
338 ///
339 /// @param inheritance inheritance mode to be used.
340 Triplet<uint32_t> getValid(const Inheritance& inheritance = Inheritance::ALL) const {
341 return (getProperty<Network>(&Network::getValid, valid_, inheritance,
342 "valid-lifetime", "min-valid-lifetime",
343 "max-valid-lifetime"));
344 }
345
346 /// @brief Sets new valid lifetime for a network.
347 ///
348 /// @param valid New valid lifetime in seconds.
setValid(const Triplet<uint32_t> & valid)349 void setValid(const Triplet<uint32_t>& valid) {
350 valid_ = valid;
351 }
352
353 /// @brief Returns T1 (renew timer), expressed in seconds
354 ///
355 /// @param inheritance inheritance mode to be used.
356 Triplet<uint32_t> getT1(const Inheritance& inheritance = Inheritance::ALL) const {
357 return (getProperty<Network>(&Network::getT1, t1_, inheritance, "renew-timer"));
358 }
359
360 /// @brief Sets new renew timer for a network.
361 ///
362 /// @param t1 New renew timer value in seconds.
setT1(const Triplet<uint32_t> & t1)363 void setT1(const Triplet<uint32_t>& t1) {
364 t1_ = t1;
365 }
366
367 /// @brief Returns T2 (rebind timer), expressed in seconds
368 ///
369 /// @param inheritance inheritance mode to be used.
370 Triplet<uint32_t> getT2(const Inheritance& inheritance = Inheritance::ALL) const {
371 return (getProperty<Network>(&Network::getT2, t2_, inheritance, "rebind-timer"));
372 }
373
374 /// @brief Sets new rebind timer for a network.
375 ///
376 /// @param t2 New rebind timer value in seconds.
setT2(const Triplet<uint32_t> & t2)377 void setT2(const Triplet<uint32_t>& t2) {
378 t2_ = t2;
379 }
380
381 /// @brief Returns whether global reservations should be fetched.
382 ///
383 /// @param inheritance inheritance mode to be used.
384 util::Optional<bool>
385 getReservationsGlobal(const Inheritance& inheritance = Inheritance::ALL) const {
386 return (getProperty<Network>(&Network::getReservationsGlobal,
387 reservations_global_,
388 inheritance,
389 "reservations-global"));
390 }
391
392 /// @brief Sets whether global reservations should be fetched.
393 ///
394 /// @param reservations_global new value of enabled/disabled.
setReservationsGlobal(const util::Optional<bool> & reservations_global)395 void setReservationsGlobal(const util::Optional<bool>& reservations_global) {
396 reservations_global_ = reservations_global;
397 }
398
399 /// @brief Returns whether subnet reservations should be fetched.
400 ///
401 /// @param inheritance inheritance mode to be used.
402 util::Optional<bool>
403 getReservationsInSubnet(const Inheritance& inheritance = Inheritance::ALL) const {
404 return (getProperty<Network>(&Network::getReservationsInSubnet,
405 reservations_in_subnet_,
406 inheritance,
407 "reservations-in-subnet"));
408 }
409
410 /// @brief Sets whether subnet reservations should be fetched.
411 ///
412 /// @param reservations_in_subnet new value of enabled/disabled.
setReservationsInSubnet(const util::Optional<bool> & reservations_in_subnet)413 void setReservationsInSubnet(const util::Optional<bool>& reservations_in_subnet) {
414 reservations_in_subnet_ = reservations_in_subnet;
415 }
416
417 /// @brief Returns whether only out-of-pool reservations are allowed.
418 ///
419 /// @param inheritance inheritance mode to be used.
420 util::Optional<bool>
421 getReservationsOutOfPool(const Inheritance& inheritance = Inheritance::ALL) const {
422 return (getProperty<Network>(&Network::getReservationsOutOfPool,
423 reservations_out_of_pool_,
424 inheritance,
425 "reservations-out-of-pool"));
426 }
427
428 /// @brief Sets whether only out-of-pool reservations are allowed.
429 ///
430 /// @param reservations_out_of_pool new value of enabled/disabled.
setReservationsOutOfPool(const util::Optional<bool> & reservations_out_of_pool)431 void setReservationsOutOfPool(const util::Optional<bool>& reservations_out_of_pool) {
432 reservations_out_of_pool_ = reservations_out_of_pool;
433 }
434
435 /// @brief Returns pointer to the option data configuration for this network.
getCfgOption()436 CfgOptionPtr getCfgOption() {
437 return (cfg_option_);
438 }
439
440 /// @brief Returns const pointer to the option data configuration for this
441 /// network.
getCfgOption()442 ConstCfgOptionPtr getCfgOption() const {
443 return (cfg_option_);
444 }
445
446 /// @brief Returns whether or not T1/T2 calculation is enabled.
447 ///
448 /// @param inheritance inheritance mode to be used.
449 util::Optional<bool>
450 getCalculateTeeTimes(const Inheritance& inheritance = Inheritance::ALL) const {
451 return (getProperty<Network>(&Network::getCalculateTeeTimes,
452 calculate_tee_times_,
453 inheritance,
454 "calculate-tee-times"));
455 }
456
457 /// @brief Sets whether or not T1/T2 calculation is enabled.
458 ///
459 /// @param calculate_tee_times new value of enabled/disabled.
setCalculateTeeTimes(const util::Optional<bool> & calculate_tee_times)460 void setCalculateTeeTimes(const util::Optional<bool>& calculate_tee_times) {
461 calculate_tee_times_ = calculate_tee_times;
462 }
463
464 /// @brief Returns percentage to use when calculating the T1 (renew timer).
465 ///
466 /// @param inheritance inheritance mode to be used.
467 util::Optional<double>
468 getT1Percent(const Inheritance& inheritance = Inheritance::ALL) const {
469 return (getProperty<Network>(&Network::getT1Percent, t1_percent_,
470 inheritance, "t1-percent"));
471 }
472
473 /// @brief Sets new percentage for calculating T1 (renew timer).
474 ///
475 /// @param t1_percent New percentage to use.
setT1Percent(const util::Optional<double> & t1_percent)476 void setT1Percent(const util::Optional<double>& t1_percent) {
477 t1_percent_ = t1_percent;
478 }
479
480 /// @brief Returns percentage to use when calculating the T2 (rebind timer).
481 ///
482 /// @param inheritance inheritance mode to be used.
483 util::Optional<double>
484 getT2Percent(const Inheritance& inheritance = Inheritance::ALL) const {
485 return (getProperty<Network>(&Network::getT2Percent, t2_percent_,
486 inheritance, "t2-percent"));
487 }
488
489 /// @brief Sets new percentage for calculating T2 (rebind timer).
490 ///
491 /// @param t2_percent New percentage to use.
setT2Percent(const util::Optional<double> & t2_percent)492 void setT2Percent(const util::Optional<double>& t2_percent) {
493 t2_percent_ = t2_percent;
494 }
495
496 /// @brief Returns ddns-send-updates
497 ///
498 /// @param inheritance inheritance mode to be used.
499 util::Optional<bool>
500 getDdnsSendUpdates(const Inheritance& inheritance = Inheritance::ALL) const {
501 return (getProperty<Network>(&Network::getDdnsSendUpdates, ddns_send_updates_,
502 inheritance, "ddns-send-updates"));
503 }
504
505 /// @brief Sets new ddns-send-updates
506 ///
507 /// @param ddns_send_updates New value to use.
setDdnsSendUpdates(const util::Optional<bool> & ddns_send_updates)508 void setDdnsSendUpdates(const util::Optional<bool>& ddns_send_updates) {
509 ddns_send_updates_ = ddns_send_updates;
510 }
511
512 /// @brief Returns ddns-override-no-update
513 ///
514 /// @param inheritance inheritance mode to be used.
515 util::Optional<bool>
516 getDdnsOverrideNoUpdate(const Inheritance& inheritance = Inheritance::ALL) const {
517 return (getProperty<Network>(&Network::getDdnsOverrideNoUpdate,
518 ddns_override_no_update_,
519 inheritance, "ddns-override-no-update"));
520 }
521
522 /// @brief Sets new ddns-override-no-update
523 ///
524 /// @param ddns_override_no_update New value to use.
setDdnsOverrideNoUpdate(const util::Optional<bool> & ddns_override_no_update)525 void setDdnsOverrideNoUpdate(const util::Optional<bool>& ddns_override_no_update) {
526 ddns_override_no_update_ = ddns_override_no_update;
527 }
528
529 /// @brief Returns ddns-override-client-update
530 ///
531 /// @param inheritance inheritance mode to be used.
532 util::Optional<bool>
533 getDdnsOverrideClientUpdate(const Inheritance& inheritance = Inheritance::ALL) const {
534 return (getProperty<Network>(&Network::getDdnsOverrideClientUpdate,
535 ddns_override_client_update_,
536 inheritance, "ddns-override-client-update"));
537 }
538
539 /// @brief Sets new ddns-override-client-update
540 ///
541 /// @param ddns_override_client_update New value to use.
setDdnsOverrideClientUpdate(const util::Optional<bool> & ddns_override_client_update)542 void setDdnsOverrideClientUpdate(const util::Optional<bool>&
543 ddns_override_client_update) {
544 ddns_override_client_update_ = ddns_override_client_update;
545 }
546
547 /// @brief Returns ddns-replace-client-name-mode
548 ///
549 /// @param inheritance inheritance mode to be used.
550 util::Optional<D2ClientConfig::ReplaceClientNameMode>
551 getDdnsReplaceClientNameMode(const Inheritance& inheritance = Inheritance::ALL) const {
552 // Inheritance for ddns-replace-client-name is a little different than for other
553 // parameters. The value at the global level is given as a string.
554 // Thus we call getProperty here without a global name to check if it
555 // is specified on network level only.
556 const util::Optional<D2ClientConfig::ReplaceClientNameMode>& mode =
557 getProperty<Network>(&Network::getDdnsReplaceClientNameMode,
558 ddns_replace_client_name_mode_, inheritance);
559
560 // If it is not specified at network level we need this special
561 // case code to convert the global string value to an enum.
562 if (mode.unspecified() && (inheritance != Inheritance::NONE) &&
563 (inheritance != Inheritance::PARENT_NETWORK)) {
564 // Get global mode.
565 util::Optional<std::string> mode_label;
566 mode_label = getGlobalProperty(mode_label, "ddns-replace-client-name");
567 if (!mode_label.unspecified()) {
568 try {
569 // If the mode is globally configured, convert it to an enum.
570 return (D2ClientConfig::stringToReplaceClientNameMode(mode_label.get()));
catch(...)571 } catch (...) {
572 // This should not really happen because the configuration
573 // parser should have already verified the globally configured
574 // mode. However, we want to be 100% sure that this
575 // method doesn't throw. Let's just return unspecified.
576 return (mode);
577 }
578 }
579 }
580 return (mode);
581 }
582
583 /// @brief Sets new ddns-replace-client-name-mode
584 ///
585 /// @param ddns_replace_client_name_mode New value to use.
586 void
setDdnsReplaceClientNameMode(const util::Optional<D2ClientConfig::ReplaceClientNameMode> & ddns_replace_client_name_mode)587 setDdnsReplaceClientNameMode(const util::Optional<D2ClientConfig::ReplaceClientNameMode>&
588 ddns_replace_client_name_mode) {
589 ddns_replace_client_name_mode_ = ddns_replace_client_name_mode;
590 }
591
592 /// @brief Returns ddns-generated-prefix
593 ///
594 /// @param inheritance inheritance mode to be used.
595 util::Optional<std::string>
596 getDdnsGeneratedPrefix(const Inheritance& inheritance = Inheritance::ALL) const {
597 return (getProperty<Network>(&Network::getDdnsGeneratedPrefix,
598 ddns_generated_prefix_,
599 inheritance, "ddns-generated-prefix"));
600 }
601
602 /// @brief Sets new ddns-generated-prefix
603 ///
604 /// @param ddns_generated_prefix New value to use.
setDdnsGeneratedPrefix(const util::Optional<std::string> & ddns_generated_prefix)605 void setDdnsGeneratedPrefix(const util::Optional<std::string>& ddns_generated_prefix) {
606 ddns_generated_prefix_ = ddns_generated_prefix;
607 }
608
609 /// @brief Returns ddns-qualifying-suffix
610 ///
611 /// @param inheritance inheritance mode to be used.
612 util::Optional<std::string>
613 getDdnsQualifyingSuffix(const Inheritance& inheritance = Inheritance::ALL) const {
614 return (getProperty<Network>(&Network::getDdnsQualifyingSuffix,
615 ddns_qualifying_suffix_,
616 inheritance, "ddns-qualifying-suffix"));
617 }
618
619 /// @brief Sets new ddns-qualifying-suffix
620 ///
621 /// @param ddns_qualifying_suffix New value to use.
setDdnsQualifyingSuffix(const util::Optional<std::string> & ddns_qualifying_suffix)622 void setDdnsQualifyingSuffix(const util::Optional<std::string>& ddns_qualifying_suffix) {
623 ddns_qualifying_suffix_ = ddns_qualifying_suffix;
624 }
625
626 /// @brief Return the char set regexp used to sanitize client hostnames.
627 util::Optional<std::string>
628 getHostnameCharSet(const Inheritance& inheritance = Inheritance::ALL) const {
629 return (getProperty<Network>(&Network::getHostnameCharSet, hostname_char_set_,
630 inheritance, "hostname-char-set"));
631 }
632
633 /// @brief Sets new hostname-char-set
634 ///
635 /// @param hostname_char_set New value to use.
setHostnameCharSet(const util::Optional<std::string> & hostname_char_set)636 void setHostnameCharSet(const util::Optional<std::string>& hostname_char_set) {
637 hostname_char_set_ = hostname_char_set;
638 }
639
640 /// @brief Return the invalid char replacement used to sanitize client hostnames.
641 util::Optional<std::string>
642 getHostnameCharReplacement(const Inheritance& inheritance = Inheritance::ALL) const {
643 return (getProperty<Network>(&Network::getHostnameCharReplacement,
644 hostname_char_replacement_,
645 inheritance, "hostname-char-replacement"));
646 }
647
648 /// @brief Sets new hostname-char-replacement
649 ///
650 /// @param hostname_char_replacement New value to use.
setHostnameCharReplacement(const util::Optional<std::string> & hostname_char_replacement)651 void setHostnameCharReplacement(const util::Optional<std::string>&
652 hostname_char_replacement) {
653 hostname_char_replacement_ = hostname_char_replacement;
654 }
655
656 /// @brief Returns store-extended-info
657 ///
658 /// @param inheritance inheritance mode to be used.
659 util::Optional<bool>
660 getStoreExtendedInfo(const Inheritance& inheritance = Inheritance::ALL) const {
661 return (getProperty<Network>(&Network::getStoreExtendedInfo,
662 store_extended_info_,
663 inheritance, "store-extended-info"));
664 }
665
666 /// @brief Sets new store-extended-info
667 ///
668 /// @param store_extended_info New value to use.
setStoreExtendedInfo(const util::Optional<bool> & store_extended_info)669 void setStoreExtendedInfo(const util::Optional<bool>& store_extended_info) {
670 store_extended_info_ = store_extended_info;
671 }
672
673 /// @brief Returns percentage to use as cache threshold.
674 ///
675 /// @param inheritance inheritance mode to be used.
676 util::Optional<double>
677 getCacheThreshold(const Inheritance& inheritance = Inheritance::ALL) const {
678 return (getProperty<Network>(&Network::getCacheThreshold,
679 cache_threshold_,
680 inheritance, "cache-threshold"));
681 }
682
683 /// @brief Sets cache threshold for a network.
684 ///
685 /// @param cache_threshold New cache threshold percentage to use.
setCacheThreshold(const util::Optional<double> & cache_threshold)686 void setCacheThreshold(const util::Optional<double>& cache_threshold) {
687 cache_threshold_ = cache_threshold;
688 }
689
690 /// @brief Returns value in seconds to use as cache maximum age.
691 ///
692 /// @param inheritance inheritance mode to be used.
693 util::Optional<uint32_t>
694 getCacheMaxAge(const Inheritance& inheritance = Inheritance::ALL) const {
695 return (getProperty<Network>(&Network::getCacheMaxAge, cache_max_age_,
696 inheritance, "cache-max-age"));
697 }
698
699 /// @brief Sets cache max for a network.
700 ///
701 /// @param cache_max_age New cache maximum value in seconds to use.
setCacheMaxAge(const util::Optional<uint32_t> & cache_max_age)702 void setCacheMaxAge(const util::Optional<uint32_t>& cache_max_age) {
703 cache_max_age_ = cache_max_age;
704 }
705
706 /// @brief Returns ddns-update-on-renew
707 ///
708 /// @param inheritance inheritance mode to be used.
709 util::Optional<bool>
710 getDdnsUpdateOnRenew(const Inheritance& inheritance = Inheritance::ALL) const {
711 return (getProperty<Network>(&Network::getDdnsUpdateOnRenew,
712 ddns_update_on_renew_,
713 inheritance, "ddns-update-on-renew"));
714 }
715
716 /// @brief Sets new ddns-update-on-renew
717 ///
718 /// @param ddns_update_on_renew New value to use.
setDdnsUpdateOnRenew(const util::Optional<bool> & ddns_update_on_renew)719 void setDdnsUpdateOnRenew(const util::Optional<bool>& ddns_update_on_renew) {
720 ddns_update_on_renew_ = ddns_update_on_renew;
721 }
722
723 /// @brief Returns ddns-use-conflict-resolution
724 ///
725 /// @param inheritance inheritance mode to be used.
726 util::Optional<bool>
727 getDdnsUseConflictResolution(const Inheritance& inheritance = Inheritance::ALL) const {
728 return (getProperty<Network>(&Network::getDdnsUseConflictResolution,
729 ddns_use_conflict_resolution_,
730 inheritance, "ddns-use-conflict-resolution"));
731 }
732
733 /// @brief Sets new ddns-use-conflict-resolution
734 ///
735 /// @param ddns_use_conflict_resolution New value to use.
setDdnsUseConflictResolution(const util::Optional<bool> & ddns_use_conflict_resolution)736 void setDdnsUseConflictResolution(const util::Optional<bool>& ddns_use_conflict_resolution) {
737 ddns_use_conflict_resolution_ = ddns_use_conflict_resolution;
738 }
739
740 /// @brief Unparses network object.
741 ///
742 /// @return A pointer to unparsed network configuration.
743 virtual data::ElementPtr toElement() const;
744
745 protected:
746
747 /// @brief Gets the optional callback function used to fetch globally
748 /// configured parameters.
749 ///
750 /// @return Pointer to the function.
getFetchGlobalsFn()751 FetchNetworkGlobalsFn getFetchGlobalsFn() const {
752 return (fetch_globals_fn_);
753 }
754
755 /// @brief Returns a value of global configuration parameter with
756 /// a given name.
757 ///
758 /// If the @c ferch_globals_fn_ function is non-null, this method will
759 /// invoke this function to retrieve a global value having the given
760 /// name. Typically, this method is invoked by @c getProperty when
761 /// network specific value of the parameter is not found. In some cases
762 /// it may be called by other methods. One such example is the
763 /// @c getDdnsReplaceClientNameMode which needs to call @c getGlobalProperty
764 /// explicitly to convert the global replace client name mode value from
765 /// a string to an enum.
766 ///
767 /// @tparam ReturnType Type of the returned value, e.g.
768 /// @c Optional<std::string>.
769 ///
770 /// @param property Value to be returned when it is specified or when
771 /// no global value is found.
772 /// @param global_name Name of the global parameter which value should
773 /// be returned
774 /// @param min_name Name of the min global parameter which value should
775 /// be returned for triplets
776 /// @param max_name Name of the max global parameter which value should
777 /// be returned for triplets
778 ///
779 /// @return Optional value fetched from the global level or the value
780 /// of @c property.
781 template<typename ReturnType>
782 ReturnType getGlobalProperty(ReturnType property,
783 const std::string& global_name,
784 const std::string& min_name = "",
785 const std::string& max_name = "") const {
786 unused(min_name, max_name);
787 if (!global_name.empty() && fetch_globals_fn_) {
788 data::ConstElementPtr globals = fetch_globals_fn_();
789 if (globals && (globals->getType() == data::Element::map)) {
790 data::ConstElementPtr global_param = globals->get(global_name);
791 if (global_param) {
792 // If there is a global parameter, convert it to the
793 // optional value of the given type and return.
794 return (data::ElementValue<typename ReturnType::ValueType>()(global_param));
795 }
796 }
797 }
798 return (property);
799 }
800
801 /// @brief The @c getGlobalProperty specialization for Triplet<T>.
802 ///
803 /// @note: use overloading vs specialization because full specialization
804 /// is not allowed in this scope.
805 ///
806 /// @tparam NumType Type of the encapsulated value(s).
807 ///
808 /// @param property Value to be returned when it is specified or when
809 /// no global value is found.
810 /// @param global_name Name of the global parameter which value should
811 /// be returned
812 /// @param min_name Name of the min global parameter which value should
813 /// be returned for triplets
814 /// @param max_name Name of the max global parameter which value should
815 /// be returned for triplets
816 ///
817 /// @return Optional value fetched from the global level or the value
818 /// of @c property.
819 template<typename NumType>
820 Triplet<NumType> getGlobalProperty(Triplet<NumType> property,
821 const std::string& global_name,
822 const std::string& min_name = "",
823 const std::string& max_name = "") const {
824
825 if (!global_name.empty() && fetch_globals_fn_) {
826 data::ConstElementPtr globals = fetch_globals_fn_();
827 if (globals && (globals->getType() == data::Element::map)) {
828 data::ConstElementPtr param = globals->get(global_name);
829 if (param) {
830 NumType def_value = static_cast<NumType>(param->intValue());
831 if (min_name.empty() || max_name.empty()) {
832 return (def_value);
833 } else {
834 NumType min_value = def_value;
835 NumType max_value = def_value;
836 data::ConstElementPtr min_param = globals->get(min_name);
837 if (min_param) {
838 min_value = static_cast<NumType>(min_param->intValue());
839 }
840 data::ConstElementPtr max_param = globals->get(max_name);
841 if (max_param) {
842 max_value = static_cast<NumType>(max_param->intValue());
843 }
844 return (Triplet<NumType>(min_value, def_value, max_value));
845 }
846 }
847 }
848 }
849 return (property);
850 }
851
852 /// @brief The @c getGlobalProperty specialization for Optional<IOAddress>.
853 ///
854 /// This does two things:
855 /// - uses the string value of the parameter
856 /// - falls back when the value is empty
857 ///
858 /// @note: use overloading vs specialization because full specialization
859 /// is not allowed in this scope.
860 ///
861 /// @param property Value to be returned when it is specified or when
862 /// no global value is found.
863 /// @param global_name Name of the global parameter which value should
864 /// be returned
865 /// @param min_name Name of the min global parameter which value should
866 /// be returned for triplets
867 /// @param max_name Name of the max global parameter which value should
868 /// be returned for triplets
869 ///
870 /// @return Optional value fetched from the global level or the value
871 /// of @c property.
872 util::Optional<asiolink::IOAddress>
873 getGlobalProperty(util::Optional<asiolink::IOAddress> property,
874 const std::string& global_name,
875 const std::string& min_name = "",
876 const std::string& max_name = "") const;
877
878 /// @brief Returns a value associated with a network using inheritance.
879 ///
880 /// This template method provides a generic mechanism to retrieve a
881 /// network parameter using inheritance. It is called from public
882 /// accessor methods which return an @c OptionalValue or @c Triplet.
883 ///
884 /// @tparam BaseType Type of this instance, e.g. @c Network, @c Network4
885 /// etc, which exposes a method to be called.
886 /// @tparam ReturnType Type of the returned value, e.g.
887 /// @c Optional<std::string>.
888 ///
889 /// @param MethodPointer Pointer to the method of the base class which
890 /// should be called on the parent network instance (typically on
891 /// @c SharedNetwork4 or @c SharedNetwork6) to fetch the parent specific
892 /// value if the value is unspecified for this instance.
893 /// @param property Value to be returned when it is specified or when
894 /// no explicit value is specified on upper inheritance levels.
895 /// @param inheritance inheritance mode to be used.
896 /// @param global_name Optional name of the global parameter which value
897 /// should be returned if the given parameter is not specified on network
898 /// level. This value is empty by default, which indicates that the
899 /// global value for the given parameter is not supported and shouldn't
900 /// be fetched.
901 /// @param min_name Name of the min global parameter which value should
902 /// be returned for triplets
903 /// @param max_name Name of the max global parameter which value should
904 /// be returned for triplets
905 ///
906 /// @return Optional value fetched from this instance level, parent
907 /// network level or global level
908 template<typename BaseType, typename ReturnType>
ReturnType(BaseType::* MethodPointer)909 ReturnType getProperty(ReturnType(BaseType::*MethodPointer)(const Inheritance&) const,
910 ReturnType property,
911 const Inheritance& inheritance,
912 const std::string& global_name = "",
913 const std::string& min_name = "",
914 const std::string& max_name = "") const {
915
916 // If no inheritance is to be used, return the value for this
917 // network regardless if it is specified or not.
918 if (inheritance == Inheritance::NONE) {
919 return (property);
920
921 } else if (inheritance == Inheritance::PARENT_NETWORK) {
922 ReturnType parent_property;
923
924 // Check if this instance has a parent network.
925 auto parent = boost::dynamic_pointer_cast<BaseType>(parent_network_.lock());
926 if (parent) {
927 parent_property = ((*parent).*MethodPointer)(Network::Inheritance::NONE);
928 }
929 return (parent_property);
930
931 // If global value requested, return it.
932 } else if (inheritance == Inheritance::GLOBAL) {
933 return (getGlobalProperty(ReturnType(), global_name, min_name, max_name));
934 }
935
936 // We use inheritance and the value is not specified on the network level.
937 // Hence, we need to get the parent network specific value or global value.
938 if (property.unspecified()) {
939 // Check if this instance has a parent network.
940 auto parent = boost::dynamic_pointer_cast<BaseType>(parent_network_.lock());
941 // If the parent network exists, let's fetch the parent specific
942 // value.
943 if (parent) {
944 // We're using inheritance so ask for the parent specific network
945 // and return it only if it is specified.
946 auto parent_property = ((*parent).*MethodPointer)(inheritance);
947 if (!parent_property.unspecified()) {
948 return (parent_property);
949 }
950 }
951
952 // The value is not specified on network level. If the value
953 // can be specified on global level and there is a callback
954 // that returns the global values, try to find this parameter
955 // at the global scope.
956 return (getGlobalProperty(property, global_name, min_name, max_name));
957 }
958
959 // We haven't found the value at any level, so return the unspecified.
960 return (property);
961 }
962
963 /// @brief Returns option pointer associated with a network using inheritance.
964 ///
965 /// This template method provides a generic mechanism to retrieve a
966 /// network parameter using inheritance. It is called from public
967 /// accessor methods which return an @c OptionPtr.
968 ///
969 /// @tparam BaseType Type of this instance, e.g. @c Network, @c Network4
970 /// etc, which exposes a method to be called.
971 ///
972 /// @param MethodPointer Pointer to the method of the base class which
973 /// should be called on the parent network instance (typically on
974 /// @c SharedNetwork4 or @c SharedNetwork6) to fetch the parent specific
975 /// value if the value is unspecified for this instance.
976 /// @param property the value to return when inheritance mode is NONE, or
977 /// when the mode is PARENT_NETWORK and the property has not been specified
978 /// by a parent network.
979 /// @param inheritance inheritance mode to be used.
980 ///
981 /// @return Option pointer fetched from this instance level or parent
982 /// network level.
983 template<typename BaseType>
984 OptionPtr
getOptionProperty(OptionPtr (BaseType::* MethodPointer)(const Inheritance & inheritance)const,OptionPtr property,const Inheritance & inheritance)985 getOptionProperty(OptionPtr(BaseType::*MethodPointer)(const Inheritance& inheritance) const,
986 OptionPtr property,
987 const Inheritance& inheritance) const {
988 if (inheritance == Network::Inheritance::NONE) {
989 return (property);
990
991 } else if (inheritance == Network::Inheritance::PARENT_NETWORK) {
992 OptionPtr parent_property;
993 // Check if this instance has a parent network.
994 auto parent = boost::dynamic_pointer_cast<BaseType>(parent_network_.lock());
995 // If the parent network exists, let's fetch the parent specific
996 // value.
997 if (parent) {
998 parent_property = ((*parent).*MethodPointer)(Network::Inheritance::NONE);
999 }
1000 return (parent_property);
1001
1002 } else if (inheritance == Network::Inheritance::GLOBAL) {
1003 return (OptionPtr());
1004 }
1005
1006 // We use inheritance and the value is not specified on the network level.
1007 // Hence, we need to get the parent network specific value.
1008 if (!property) {
1009 // Check if this instance has a parent network.
1010 auto parent = boost::dynamic_pointer_cast<BaseType>(parent_network_.lock());
1011 if (parent) {
1012 // We're using inheritance so ask for the parent specific network
1013 // and return it only if it is specified.
1014 OptionPtr parent_property = (((*parent).*MethodPointer)(inheritance));
1015 if (parent_property) {
1016 return (parent_property);
1017 }
1018 }
1019 }
1020
1021 // We haven't found the value at any level, so return the unspecified.
1022 return (property);
1023 }
1024
1025 /// @brief Holds interface name for which this network is selected.
1026 util::Optional<std::string> iface_name_;
1027
1028 /// @brief Relay information
1029 ///
1030 /// See @ref RelayInfo for detailed description.
1031 RelayInfo relay_;
1032
1033 /// @brief Optional definition of a client class
1034 ///
1035 /// If defined, only clients belonging to that class will be allowed to use
1036 /// this particular network. The default value for this is an empty string,
1037 /// which means that any client is allowed, regardless of its class.
1038 util::Optional<ClientClass> client_class_;
1039
1040 /// @brief Required classes
1041 ///
1042 /// If the network is selected these classes will be added to the
1043 /// incoming packet and their evaluation will be required.
1044 ClientClasses required_classes_;
1045
1046 /// @brief a Triplet (min/default/max) holding allowed renew timer values
1047 Triplet<uint32_t> t1_;
1048
1049 /// @brief a Triplet (min/default/max) holding allowed rebind timer values
1050 Triplet<uint32_t> t2_;
1051
1052 /// @brief a Triplet (min/default/max) holding allowed valid lifetime values
1053 Triplet<uint32_t> valid_;
1054
1055 /// @brief Enables global reservations.
1056 util::Optional<bool> reservations_global_;
1057
1058 /// @brief Enables subnet reservations.
1059 util::Optional<bool> reservations_in_subnet_;
1060
1061 /// @brief Enables out-of-pool reservations optimization.
1062 ///
1063 /// When true only out-of-pool reservations are allowed. This allows
1064 /// AllocEngine to skip reservation checks when dealing with addresses
1065 /// that are in pool.
1066 util::Optional<bool> reservations_out_of_pool_;
1067
1068 /// @brief Pointer to the option data configuration for this subnet.
1069 CfgOptionPtr cfg_option_;
1070
1071 /// @brief Enables calculation of T1 and T2 timers
1072 util::Optional<bool> calculate_tee_times_;
1073
1074 /// @brief Percentage of the lease lifetime to use when calculating T1 timer
1075 util::Optional<double> t1_percent_;
1076
1077 /// @brief Percentage of the lease lifetime to use when calculating T2 timer
1078 util::Optional<double> t2_percent_;
1079
1080 /// @brief Should Kea perform DNS updates. Used to provide scoped enabling
1081 /// and disabling of updates.
1082 util::Optional<bool> ddns_send_updates_;
1083
1084 /// @brief Should Kea perform updates, even if client requested no updates.
1085 /// Overrides the client request for no updates via the N flag.
1086 util::Optional<bool> ddns_override_no_update_;
1087
1088 /// @brief Should Kea perform updates, even if client requested delegation.
1089 util::Optional<bool> ddns_override_client_update_;
1090
1091 /// @brief How Kea should handle the domain-name supplied by the client.
1092 util::Optional<D2ClientConfig::ReplaceClientNameMode> ddns_replace_client_name_mode_;
1093
1094 /// @brief Prefix Kea should use when generating domain-names.
1095 util::Optional<std::string> ddns_generated_prefix_;
1096
1097 /// @brief Suffix Kea should use when to qualify partial domain-names.
1098 util::Optional<std::string> ddns_qualifying_suffix_;
1099
1100 /// @brief Regular expression describing invalid characters for client
1101 /// hostnames.
1102 util::Optional<std::string> hostname_char_set_;
1103
1104 /// @brief A string to replace invalid characters when scrubbing hostnames.
1105 /// Meaningful only if hostname_char_set_ is not empty.
1106 util::Optional<std::string> hostname_char_replacement_;
1107
1108 /// @brief Should Kea store additional client query data (e.g. relay-agent-info)
1109 /// on the lease.
1110 util::Optional<bool> store_extended_info_;
1111
1112 /// @brief Percentage of the lease lifetime to use as cache threshold.
1113 util::Optional<double> cache_threshold_;
1114
1115 /// @brief Value in seconds to use as cache maximal age.
1116 util::Optional<uint32_t> cache_max_age_;
1117
1118 /// @brief Should Kea perform updates when leases are extended
1119 util::Optional<bool> ddns_update_on_renew_;
1120
1121 /// @brief Used to to tell kea-dhcp-ddns whether or not to use conflict resolution.
1122 util::Optional<bool> ddns_use_conflict_resolution_;
1123
1124 /// @brief Pointer to another network that this network belongs to.
1125 ///
1126 /// The most common case is that this instance is a subnet which belongs
1127 /// to a shared network and the @c parent_network_ points to the shared
1128 /// network object. If the network instance (subnet) doesn't belong to
1129 /// a shared network this pointer is null.
1130 WeakNetworkPtr parent_network_;
1131
1132 /// @brief Pointer to the optional callback used to fetch globally
1133 /// configured parameters inherited to the @c Network object.
1134 FetchNetworkGlobalsFn fetch_globals_fn_;
1135 };
1136
1137 /// @brief Specialization of the @ref Network object for DHCPv4 case.
1138 class Network4 : public virtual Network {
1139 public:
1140
1141 /// @brief Constructor.
Network4()1142 Network4()
1143 : Network(), match_client_id_(true, true), authoritative_(),
1144 siaddr_(), sname_(), filename_() {
1145 }
1146
1147 /// @brief Returns the flag indicating if the client identifiers should
1148 /// be used to identify the client's lease.
1149 ///
1150 /// @param inheritance inheritance mode to be used.
1151 /// @return true if client identifiers should be used, false otherwise.
1152 util::Optional<bool>
1153 getMatchClientId(const Inheritance& inheritance = Inheritance::ALL) const {
1154 return (getProperty<Network4>(&Network4::getMatchClientId,
1155 match_client_id_,
1156 inheritance,
1157 "match-client-id"));
1158 }
1159
1160 /// @brief Sets the flag indicating if the client identifier should be
1161 /// used to identify the client's lease.
1162 ///
1163 /// @param match If this value is true, the client identifiers are not
1164 /// used for lease lookup.
setMatchClientId(const util::Optional<bool> & match)1165 void setMatchClientId(const util::Optional<bool>& match) {
1166 match_client_id_ = match;
1167 }
1168
1169 /// @brief Returns the flag indicating if requests for unknown IP addresses
1170 /// should be rejected with DHCPNAK instead of ignored.
1171 ///
1172 /// @param inheritance inheritance mode to be used.w
1173 /// @return true if requests for unknown IP addresses should be rejected,
1174 /// false otherwise.
1175 util::Optional<bool>
1176 getAuthoritative(const Inheritance& inheritance = Inheritance::ALL) const {
1177 return (getProperty<Network4>(&Network4::getAuthoritative, authoritative_,
1178 inheritance, "authoritative"));
1179 }
1180
1181 /// @brief Sets the flag indicating if requests for unknown IP addresses
1182 /// should be rejected with DHCPNAK instead of ignored.
1183 ///
1184 /// @param authoritative If this value is true, the requests for unknown IP
1185 /// addresses will be rejected with DHCPNAK messages
setAuthoritative(const util::Optional<bool> & authoritative)1186 void setAuthoritative(const util::Optional<bool>& authoritative) {
1187 authoritative_ = authoritative;
1188 }
1189
1190 /// @brief Sets siaddr for the network.
1191 ///
1192 /// Will be used for siaddr field (the next server) that typically is used
1193 /// as TFTP server. If not specified, the default value of 0.0.0.0 is
1194 /// used.
1195 void setSiaddr(const util::Optional<asiolink::IOAddress>& siaddr);
1196
1197 /// @brief Returns siaddr for this network.
1198 ///
1199 /// @return siaddr value
1200 util::Optional<asiolink::IOAddress>
1201 getSiaddr(const Inheritance& inheritance = Inheritance::ALL) const {
1202 return (getProperty<Network4>(&Network4::getSiaddr, siaddr_,
1203 inheritance, "next-server"));
1204 }
1205
1206 /// @brief Sets server hostname for the network.
1207 ///
1208 /// Will be used for server hostname field (may be empty if not defined)
1209 void setSname(const util::Optional<std::string>& sname);
1210
1211 /// @brief Returns server hostname for this network.
1212 ///
1213 /// @param inheritance inheritance mode to be used.
1214 /// @return server hostname value
1215 util::Optional<std::string>
1216 getSname(const Inheritance& inheritance = Inheritance::ALL) const {
1217 return (getProperty<Network4>(&Network4::getSname, sname_,
1218 inheritance, "server-hostname"));
1219 }
1220
1221 /// @brief Sets boot file name for the network.
1222 ///
1223 /// Will be used for boot file name (may be empty if not defined)
1224 void setFilename(const util::Optional<std::string>& filename);
1225
1226 /// @brief Returns boot file name for this subnet
1227 ///
1228 /// @param inheritance inheritance mode to be used.
1229 /// @return boot file name value
1230 util::Optional<std::string>
1231 getFilename(const Inheritance& inheritance = Inheritance::ALL) const {
1232 return (getProperty<Network4>(&Network4::getFilename, filename_,
1233 inheritance, "boot-file-name"));
1234 }
1235
1236 /// @brief Unparses network object.
1237 ///
1238 /// @return A pointer to unparsed network configuration.
1239 virtual data::ElementPtr toElement() const;
1240
1241 /// @brief Returns binary representation of the dhcp-server-identifier option (54).
1242 ///
1243 /// @return Server identifier option as IPv4 address. Zero IPv4 address
1244 /// indicates that server identifier hasn't been specified.
1245 virtual asiolink::IOAddress getServerId() const;
1246
1247 private:
1248
1249 /// @brief Should server use client identifiers for client lease
1250 /// lookup.
1251 util::Optional<bool> match_client_id_;
1252
1253 /// @brief Should requests for unknown IP addresses be rejected.
1254 util::Optional<bool> authoritative_;
1255
1256 /// @brief siaddr value for this subnet
1257 util::Optional<asiolink::IOAddress> siaddr_;
1258
1259 /// @brief server hostname for this subnet
1260 util::Optional<std::string> sname_;
1261
1262 /// @brief boot file name for this subnet
1263 util::Optional<std::string> filename_;
1264 };
1265
1266 /// @brief Specialization of the @ref Network object for DHCPv6 case.
1267 class Network6 : public virtual Network {
1268 public:
1269
1270 /// @brief Constructor.
Network6()1271 Network6()
1272 : Network(), preferred_(), interface_id_(), rapid_commit_() {
1273 }
1274
1275 /// @brief Returns preferred lifetime (in seconds)
1276 ///
1277 /// @param inheritance inheritance mode to be used.
1278 /// @return a triplet with preferred lifetime
1279 Triplet<uint32_t>
1280 getPreferred(const Inheritance& inheritance = Inheritance::ALL) const {
1281 return (getProperty<Network6>(&Network6::getPreferred, preferred_,
1282 inheritance, "preferred-lifetime",
1283 "min-preferred-lifetime",
1284 "max-preferred-lifetime"));
1285 }
1286
1287 /// @brief Sets new preferred lifetime for a network.
1288 ///
1289 /// @param preferred New preferred lifetime in seconds.
setPreferred(const Triplet<uint32_t> & preferred)1290 void setPreferred(const Triplet<uint32_t>& preferred) {
1291 preferred_ = preferred;
1292 }
1293
1294 /// @brief Returns interface-id value (if specified)
1295 ///
1296 /// @param inheritance inheritance mode to be used.
1297 /// @return interface-id option (if defined)
1298 OptionPtr getInterfaceId(const Inheritance& inheritance = Inheritance::ALL) const {
1299 return (getOptionProperty<Network6>(&Network6::getInterfaceId, interface_id_,
1300 inheritance));
1301 }
1302
1303 /// @brief sets interface-id option (if defined)
1304 ///
1305 /// @param ifaceid pointer to interface-id option
setInterfaceId(const OptionPtr & ifaceid)1306 void setInterfaceId(const OptionPtr& ifaceid) {
1307 interface_id_ = ifaceid;
1308 }
1309
1310 /// @brief Returns boolean value indicating that the Rapid Commit option
1311 /// is supported or unsupported for the subnet.
1312 ///
1313 /// @param inheritance inheritance mode to be used.
1314 /// @return true if the Rapid Commit option is supported, false otherwise.
1315 util::Optional<bool>
1316 getRapidCommit(const Inheritance& inheritance = Inheritance::ALL) const {
1317
1318 return (getProperty<Network6>(&Network6::getRapidCommit, rapid_commit_,
1319 inheritance, "rapid-commit"));
1320 }
1321
1322 /// @brief Enables or disables Rapid Commit option support for the subnet.
1323 ///
1324 /// @param rapid_commit A boolean value indicating that the Rapid Commit
1325 /// option support is enabled (if true), or disabled (if false).
setRapidCommit(const util::Optional<bool> & rapid_commit)1326 void setRapidCommit(const util::Optional<bool>& rapid_commit) {
1327 rapid_commit_ = rapid_commit;
1328 };
1329
1330 /// @brief Unparses network object.
1331 ///
1332 /// @return A pointer to unparsed network configuration.
1333 virtual data::ElementPtr toElement() const;
1334
1335 private:
1336
1337 /// @brief a triplet with preferred lifetime (in seconds)
1338 Triplet<uint32_t> preferred_;
1339
1340 /// @brief specifies optional interface-id
1341 OptionPtr interface_id_;
1342
1343 /// @brief A flag indicating if Rapid Commit option is supported
1344 /// for this network.
1345 ///
1346 /// It's default value is false, which indicates that the Rapid
1347 /// Commit is disabled for the subnet.
1348 util::Optional<bool> rapid_commit_;
1349 };
1350
1351 } // end of namespace isc::dhcp
1352 } // end of namespace isc
1353
1354 #endif // NETWORK_H
1355