Kea 3.1.3
cfg_option.cc
Go to the documentation of this file.
1// Copyright (C) 2014-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 <dhcp/libdhcp++.h>
10#include <dhcpsrv/cfg_option.h>
11#include <dhcp/dhcp6.h>
12#include <dhcp/option_space.h>
13#include <dhcpsrv/dhcpsrv_log.h>
14#include <util/encode/encode.h>
15#include <boost/algorithm/string/split.hpp>
16#include <boost/algorithm/string/classification.hpp>
17#include <boost/make_shared.hpp>
18#include <string>
19#include <sstream>
20#include <vector>
21
22using namespace isc::data;
23using namespace isc::log;
24
25namespace isc {
26namespace dhcp {
27
29OptionDescriptor::create(const OptionPtr& opt, bool persist, bool cancel,
30 const std::string& formatted_value,
31 ConstElementPtr user_context) {
32 return (boost::make_shared<OptionDescriptor>(opt, persist, cancel,
33 formatted_value,
34 user_context));
35}
36
38OptionDescriptor::create(bool persist, bool cancel) {
39 return (boost::make_shared<OptionDescriptor>(persist, cancel));
40}
41
44 return (boost::make_shared<OptionDescriptor>(desc));
45}
46
47bool
49 return ((persistent_ == other.persistent_) &&
50 (cancelled_ == other.cancelled_) &&
52 (space_name_ == other.space_name_) &&
53 ((option_ && other.option_) &&
54 option_->equals(other.option_)) &&
56}
57
58void
59OptionDescriptor::addClientClass(const std::string& class_name) {
60 std::string trimmed = util::str::trim(class_name);
61 if (!trimmed.empty()) {
62 client_classes_.insert(ClientClass(trimmed));
63 }
64}
65
70
71bool
73 if (client_classes_.empty()) {
74 return (true);
75 }
76
77 return (client_classes_.intersects(cclasses));
78}
79
81 : encapsulated_(false) {
82}
83
84bool
86 return (options_.empty() && vendor_options_.empty());
87}
88
89bool
90CfgOption::equals(const CfgOption& other) const {
91 return (options_.equals(other.options_) &&
92 vendor_options_.equals(other.vendor_options_));
93}
94
95void
97 const bool persistent,
98 const bool cancelled,
99 const std::string& option_space,
100 const uint64_t id) {
101 OptionDescriptor desc(option, persistent, cancelled);
102 if (id > 0) {
103 desc.setId(id);
104 }
105 add(desc, option_space);
106}
107
108void
109CfgOption::add(const OptionDescriptor& desc, const std::string& option_space) {
110 if (!desc.option_) {
111 isc_throw(isc::BadValue, "option being configured must not be NULL");
112
113 } else if (!OptionSpace::validateName(option_space)) {
114 isc_throw(isc::BadValue, "invalid option space name: '"
115 << option_space << "'");
116 }
117
118 const uint32_t vendor_id = LibDHCP::optionSpaceToVendorId(option_space);
119 if (vendor_id) {
120 vendor_options_.addItem(desc, vendor_id);
121 } else {
122 options_.addItem(desc, option_space);
123 }
124}
125
126void
127CfgOption::replace(const OptionDescriptor& desc, const std::string& option_space) {
128 if (!desc.option_) {
129 isc_throw(isc::BadValue, "option being replaced must not be NULL");
130 }
131
132 // Check for presence of options.
133 OptionContainerPtr options = getAll(option_space);
134 if (!options) {
135 isc_throw(isc::BadValue, "option space " << option_space
136 << " does not exist");
137 }
138
139 // Find the option we want to replace.
140 auto& idx6 = options->get<6>();
141 auto const& od_itr = idx6.find(boost::make_tuple(desc.option_->getType(), desc.client_classes_));
142 if (od_itr == idx6.end()) {
143 isc_throw(isc::BadValue, "cannot replace option: "
144 << option_space << ":" << desc.option_->getType()
145 << ", client-classes: " << desc.client_classes_.toText()
146 << ", it does not exist");
147 }
148
149 idx6.replace(od_itr, desc);
150}
151
152std::list<std::string>
154 std::list<uint32_t> ids = getVendorIds();
155 std::list<std::string> names;
156 for (auto const& id : ids) {
157 std::ostringstream s;
158 // Vendor space name is constructed as "vendor-XYZ" where XYZ is an
159 // uint32_t value, without leading zeros.
160 s << "vendor-" << id;
161 names.push_back(s.str());
162 }
163 return (names);
164}
165
166void
168 // First we merge our options into other.
169 // This adds my options that are not
170 // in other, to other (i.e we skip over
171 // duplicates).
172 mergeTo(other);
173
174 // Create option instances based on the given definitions.
175 other.createOptions(cfg_def);
176
177 // Next we copy "other" on top of ourself.
178 other.copyTo(*this);
179
180 // If we copied new options we may need to populate the
181 // sub-options into the upper level options. The server
182 // expects that the top-level options have suitable
183 // suboptions appended.
184 encapsulate();
185}
186
187void
189 // Iterate over all the option descriptors in
190 // all the spaces and instantiate the options
191 // based on the given definitions.
192 for (auto const& space : getOptionSpaceNames()) {
193 for (auto opt_desc : *(getAll(space))) {
194 try {
195 if (createDescriptorOption(cfg_def, space, opt_desc)) {
196 // Option was recreated, let's replace the descriptor.
197 replace(opt_desc, space);
198 }
199 } catch (const InvalidOperation& ex) {
201 .arg(ex.what());
202 }
203 }
204 }
205}
206
207bool
208CfgOption::createDescriptorOption(CfgOptionDefPtr cfg_def, const std::string& space,
209 OptionDescriptor& opt_desc) {
210 if (!opt_desc.option_) {
212 "validateCreateOption: descriptor has no option instance");
213 }
214
215 Option::Universe universe = opt_desc.option_->getUniverse();
216 uint16_t code = opt_desc.option_->getType();
217
218 // Find the option's definition, if it has one.
219 // First, check for a standard definition.
221
222 // If there is no standard definition but the option is vendor specific,
223 // we should search the definition within the vendor option space.
224 if (!def && (space != DHCP4_OPTION_SPACE) && (space != DHCP6_OPTION_SPACE)) {
225 uint32_t vendor_id = LibDHCP::optionSpaceToVendorId(space);
226 if (vendor_id > 0) {
227 def = LibDHCP::getVendorOptionDef(universe, vendor_id, code);
228 }
229 }
230
231 // Still haven't found the definition, so look for custom
232 // definition in the given set of configured definitions
233 if (!def) {
234 def = cfg_def->get(space, code);
235 }
236
237 // Finish with a last resort option definition.
238 if (!def) {
239 def = LibDHCP::getLastResortOptionDef(space, code);
240 }
241
242 std::string& formatted_value = opt_desc.formatted_value_;
243 if (!def) {
244 if (!formatted_value.empty()) {
245 isc_throw(InvalidOperation, "option: " << space << "." << code
246 << " has a formatted value: '" << formatted_value
247 << "' but no option definition");
248 }
249
250 // If there's no definition and no formatted string, we'll
251 // settle for the generic option already in the descriptor.
252 // Indicate no-change by returning false.
253 return (false);
254 }
255
256 try {
257 // Definition found. Let's replace the generic option in
258 // the descriptor with one created based on definition's factory.
259 if (formatted_value.empty()) {
260 // No formatted value, use data stored in the generic option.
261 opt_desc.option_ = def->optionFactory(universe, code, opt_desc.option_->getData());
262 } else {
263 // Spit the value specified in comma separated values format.
264 std::vector<std::string> split_vec;
265 boost::split(split_vec, formatted_value, boost::is_any_of(","));
266 opt_desc.option_ = def->optionFactory(universe, code, split_vec);
267 }
268 } catch (const std::exception& ex) {
269 isc_throw(InvalidOperation, "could not create option: " << space << "." << code
270 << " from data specified, reason: " << ex.what());
271 }
272
273 // Indicate we replaced the definition.
274 return (true);
275}
276
277void
279 // Merge non-vendor options.
280 mergeInternal(options_, other.options_);
281 // Merge vendor options.
282 mergeInternal(vendor_options_, other.vendor_options_);
283}
284
285void
287 // Remove any existing data in the destination.
288 other.options_.clearItems();
289 other.vendor_options_.clearItems();
290 mergeTo(other);
291 other.encapsulated_ = isEncapsulated();
292}
293
294void
296 // Append sub-options to the top level "dhcp4" option space.
297 encapsulateInternal(DHCP4_OPTION_SPACE);
298 // Append sub-options to the top level "dhcp6" option space.
299 encapsulateInternal(DHCP6_OPTION_SPACE);
300 encapsulated_ = true;
301}
302
303void
304CfgOption::encapsulateInternal(const std::string& option_space) {
305 // Get all options for the particular option space.
306 OptionContainerPtr options = getAll(option_space);
307 // For each option in the option space we will append sub-options
308 // from the option spaces they encapsulate.
309 for (auto const& opt : *options) {
310 encapsulateInternal(opt.option_);
311 }
312
313 for (auto const& vendor : getVendorIds()) {
314 OptionContainerPtr vendor_options = getAll(vendor);
315 // For each option in the option space we will append sub-options
316 // from the option spaces they encapsulate.
317 for (auto const& opt : *vendor_options) {
318 encapsulateInternal(opt.option_);
319 }
320 }
321}
322
323void
324CfgOption::encapsulateInternal(const OptionPtr& option) {
325 // Get encapsulated option space for the option.
326 const std::string& encap_space = option->getEncapsulatedSpace();
327 // Empty value means that no option space is encapsulated.
328 if (!encap_space.empty()) {
329 if (encap_space == DHCP4_OPTION_SPACE || encap_space == DHCP6_OPTION_SPACE) {
330 return;
331 }
332 // Retrieve all options from the encapsulated option space.
333 OptionContainerPtr encap_options = getAll(encap_space);
334 for (auto const& encap_opt : *encap_options) {
335 if (option.get() == encap_opt.option_.get()) {
336 // Avoid recursion by not adding options to themselves.
337 continue;
338 }
339
340 // Add sub-option if there isn't one added already.
341 if (!option->getOption(encap_opt.option_->getType())) {
342 option->addOption(encap_opt.option_);
343 }
344 encapsulateInternal(encap_opt.option_);
345 }
346 }
347}
348
349template <typename Selector>
350void
351CfgOption::mergeInternal(const OptionSpaceContainer<OptionContainer,
352 OptionDescriptor, Selector>& src_container,
354 OptionDescriptor, Selector>& dest_container) const {
355 // Get all option spaces used in source container.
356 std::list<Selector> selectors = src_container.getOptionSpaceNames();
357
358 // For each space in the source container retrieve the actual options and
359 // match them with the options held in the destination container under
360 // the same space.
361 for (auto const& it : selectors) {
362 // Get all options in the destination container for the particular
363 // option space.
364 OptionContainerPtr dest_all = dest_container.getItems(it);
365 OptionContainerPtr src_all = src_container.getItems(it);
366 // For each option under this option space check if there is a
367 // corresponding option in the destination container. If not,
368 // add one.
369 for (auto const& src_opt : *src_all) {
370 const OptionContainerTypeIndex& idx = dest_all->get<1>();
371 const OptionContainerTypeRange& range =
372 idx.equal_range(src_opt.option_->getType());
373 // If there is no such option in the destination container,
374 // add one.
375 if (std::distance(range.first, range.second) == 0) {
376 dest_container.addItem(OptionDescriptor(src_opt), it);
377 }
378 }
379 }
380}
381
383CfgOption::getAll(const std::string& option_space) const {
384 return (options_.getItems(option_space));
385}
386
388CfgOption::getAll(const uint32_t vendor_id) const {
389 return (vendor_options_.getItems(vendor_id));
390}
391
393CfgOption::getAllCombined(const std::string& option_space) const {
394 auto vendor_id = LibDHCP::optionSpaceToVendorId(option_space);
395 if (vendor_id > 0) {
396 return (getAll(vendor_id));
397 }
398 return (getAll(option_space));
399}
400
401size_t
402CfgOption::del(const std::string& option_space, const uint16_t option_code) {
403 // Check for presence of options.
404 OptionContainerPtr options = getAll(option_space);
405 if (!options || options->empty()) {
406 // There are no options, so there is nothing to do.
407 return (0);
408 }
409
410 // If this is not top level option we may also need to delete the
411 // option instance from options encapsulating the particular option
412 // space.
413 if ((option_space != DHCP4_OPTION_SPACE) &&
414 (option_space != DHCP6_OPTION_SPACE)) {
415 // For each option space name iterate over the existing options.
416 auto option_space_names = getOptionSpaceNames();
417 for (auto const& option_space_from_list : option_space_names) {
418 // Get all options within the particular option space.
419 auto const& options_in_space = getAll(option_space_from_list);
420 for (auto const& option_it : *options_in_space) {
421
422 // Check if the option encapsulates our option space and
423 // it does, try to delete our option.
424 if (option_it.option_ &&
425 (option_it.option_->getEncapsulatedSpace() == option_space)) {
426 option_it.option_->delOption(option_code);
427 }
428 }
429 }
430 }
431
432 auto& idx = options->get<1>();
433 return (idx.erase(option_code));
434}
435
436size_t
437CfgOption::del(const std::string& option_space, const uint16_t option_code,
438 const ClientClasses& client_classes) {
439 // Check for presence of options.
440 OptionContainerPtr options = getAll(option_space);
441 if (!options || options->empty()) {
442 // There are no options, so there is nothing to do.
443 return (0);
444 }
445
446 // If this is not top level option we may also need to delete the
447 // option instance from options encapsulating the particular option
448 // space.
449 if ((option_space != DHCP4_OPTION_SPACE) &&
450 (option_space != DHCP6_OPTION_SPACE)) {
451 // For each option space name iterate over the existing options.
452 auto option_space_names = getOptionSpaceNames();
453 for (auto const& option_space_from_list : option_space_names) {
454 // Get all options within the particular option space.
455 auto const& options_in_space = getAll(option_space_from_list);
456 for (auto const& option_it : *options_in_space) {
457
458 // Check if the option encapsulates our option space and
459 // if it does, try to delete our option.
460 if (option_it.option_ &&
461 (option_it.option_->getEncapsulatedSpace() == option_space)) {
462 option_it.option_->delOption(option_code);
463 }
464 }
465 }
466 }
467
468 auto& idx6 = options->get<6>();
469 auto range = idx6.equal_range(boost::make_tuple(option_code, client_classes));
470 auto count = std::distance(range.first, range.second);
471 if (count) {
472 idx6.erase(range.first, range.second);
473 }
474
475 return (count);
476}
477
478size_t
479CfgOption::del(const uint32_t vendor_id, const uint16_t option_code) {
480 // Check for presence of options.
481 OptionContainerPtr vendor_options = getAll(vendor_id);
482 if (!vendor_options || vendor_options->empty()) {
483 // There are no options, so there is nothing to do.
484 return (0);
485 }
486
487 auto& idx = vendor_options->get<1>();
488 return (idx.erase(option_code));
489}
490
491size_t
492CfgOption::del(const uint64_t id) {
493 // Hierarchical nature of the options configuration requires that
494 // we go over all options and decapsulate them before removing
495 // any of them. Let's walk over the existing option spaces.
496 for (auto const& space_name : getOptionSpaceNames()) {
497 // Get all options for the option space.
498 auto const& options = getAll(space_name);
499 for (auto const& option_it : *options) {
500 if (!option_it.option_) {
501 continue;
502 }
503
504 // For each option within the option space we need to dereference
505 // any existing sub options.
506 auto sub_options = option_it.option_->getOptions();
507 for (auto const& sub : sub_options) {
508 // Dereference sub option.
509 option_it.option_->delOption(sub.second->getType());
510 }
511 }
512 }
513
514 // Now that we got rid of dependencies between the instances of the options
515 // we can delete all options having a specified id.
516 size_t num_deleted = options_.deleteItems(id) + vendor_options_.deleteItems(id);
517
518 // Let's encapsulate those options that remain in the configuration.
519 encapsulate();
520
521 // Return the number of deleted options.
522 return (num_deleted);
523}
524
527 return (toElementWithMetadata(false));
528}
529
532 return (toElementWithMetadata(false, cfg_option_def));
533}
534
536CfgOption::toElementWithMetadata(const bool include_metadata,
537 CfgOptionDefPtr cfg_option_def) const {
538 // option-data value is a list of maps
540 // Iterate first on options using space names
541 const std::list<std::string>& names = options_.getOptionSpaceNames();
542 for (auto const& name : names) {
543 OptionContainerPtr opts = getAll(name);
544 for (auto const& opt : *opts) {
545 // Get and fill the map for this option
547 // Set user context
548 opt.contextToElement(map);
549 // Set space from parent iterator
550 map->set("space", Element::create(name));
551 // Set the code
552 uint16_t code = opt.option_->getType();
553 map->set("code", Element::create(code));
554 // Set the name (always for standard options else when asked for)
556 if (cfg_option_def) {
557 def = cfg_option_def->get(name, code);
558 }
559 if (!def) {
560 def = LibDHCP::getOptionDef(name, code);
561 }
562 if (!def) {
563 def = LibDHCP::getRuntimeOptionDef(name, code);
564 }
565 if (!def) {
566 def = LibDHCP::getLastResortOptionDef(name, code);
567 }
568 if (def) {
569 map->set("name", Element::create(def->getName()));
570 }
571 // Set the data item
572 if (!opt.formatted_value_.empty()) {
573 map->set("csv-format", Element::create(true));
574 if (def && def->getType() == OPT_EMPTY_TYPE) {
575 map->set("data", Element::create(""));
576 } else {
577 map->set("data", Element::create(opt.formatted_value_));
578 }
579 } else {
580 std::vector<uint8_t> bin = opt.option_->toBinary();
581 if (!opt.cancelled_ || !bin.empty()) {
582 map->set("csv-format", Element::create(false));
583 if (def && def->getType() == OPT_EMPTY_TYPE) {
584 map->set("data", Element::create(""));
585 } else {
586 std::string repr = util::encode::encodeHex(bin);
587 map->set("data", Element::create(repr));
588 }
589 }
590 }
591 // Set the persistency flag
592 map->set("always-send", Element::create(opt.persistent_));
593 // Set the cancelled flag.
594 map->set("never-send", Element::create(opt.cancelled_));
595 // Include metadata if requested.
596 if (include_metadata) {
597 map->set("metadata", opt.getMetadata());
598 }
599
600 // Include client-classes if not empty.
601 if (!opt.client_classes_.empty()) {
602 map->set("client-classes", opt.client_classes_.toElement());
603 }
604
605 // Push on the list
606 result->add(map);
607 }
608 }
609 // Iterate first on vendor_options using vendor ids
610 const std::list<uint32_t>& ids = vendor_options_.getOptionSpaceNames();
611 for (auto const& id : ids) {
612 OptionContainerPtr opts = getAll(id);
613 for (auto const& opt : *opts) {
614 // Get and fill the map for this option
616 // Set user context
617 opt.contextToElement(map);
618 // Set space from parent iterator
619 std::ostringstream oss;
620 oss << "vendor-" << id;
621 map->set("space", Element::create(oss.str()));
622 // Set the code
623 uint16_t code = opt.option_->getType();
624 map->set("code", Element::create(code));
625 // Set the name
626 Option::Universe universe = opt.option_->getUniverse();
628 LibDHCP::getVendorOptionDef(universe, id, code);
629 if (!def) {
630 // vendor-XXX space is in oss
631 def = LibDHCP::getRuntimeOptionDef(oss.str(), code);
632 }
633 if (def) {
634 map->set("name", Element::create(def->getName()));
635 }
636 // Set the data item
637 if (!opt.formatted_value_.empty()) {
638 map->set("csv-format", Element::create(true));
639 if (def && def->getType() == OPT_EMPTY_TYPE) {
640 map->set("data", Element::create(""));
641 } else {
642 map->set("data", Element::create(opt.formatted_value_));
643 }
644 } else {
645 std::vector<uint8_t> bin = opt.option_->toBinary();
646 if (!opt.cancelled_ || !bin.empty()) {
647 map->set("csv-format", Element::create(false));
648 if (def && def->getType() == OPT_EMPTY_TYPE) {
649 map->set("data", Element::create(""));
650 } else {
651 std::string repr = util::encode::encodeHex(bin);
652 map->set("data", Element::create(repr));
653 }
654 }
655 }
656 // Set the persistency flag
657 map->set("always-send", Element::create(opt.persistent_));
658 // Set the cancellation flag
659 map->set("never-send", Element::create(opt.cancelled_));
660
661 // Include client-classes if not empty.
662 if (!opt.client_classes_.empty()) {
663 map->set("client-classes", opt.client_classes_.toElement());
664 }
665
666 // Push on the list
667 result->add(map);
668 }
669 }
670
671 return (result);
672}
673
674} // namespace dhcp
675} // namespace isc
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown if a function is called in a prohibited way.
void setId(const uint64_t id)
Sets element's database identifier.
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
bool isEncapsulated() const
Checks if options have been encapsulated.
Definition cfg_option.h:602
OptionContainerPtr getAllCombined(const std::string &option_space) const
Returns all non-vendor or vendor options for the specified option space.
void encapsulate()
Appends encapsulated options to top-level options.
void replace(const OptionDescriptor &desc, const std::string &option_space)
Replaces the instance of an option within this collection.
static bool createDescriptorOption(CfgOptionDefPtr cfg_def, const std::string &space, OptionDescriptor &opt_desc)
Creates an option descriptor's option based on a set of option defs.
virtual isc::data::ElementPtr toElement() const
Unparse a configuration object.
void createOptions(CfgOptionDefPtr cfg_def)
Re-create the option in each descriptor based on given definitions.
isc::data::ElementPtr toElementWithMetadata(const bool include_metadata, CfgOptionDefPtr cfg_option_def=CfgOptionDefPtr()) const
Unparse a configuration object with optionally including the metadata.
size_t del(const std::string &option_space, const uint16_t option_code)
Deletes option for the specified option space and option code.
std::list< std::string > getOptionSpaceNames() const
Returns a list of configured option space names.
Definition cfg_option.h:868
bool empty() const
Indicates the object is empty.
Definition cfg_option.cc:85
void mergeTo(CfgOption &other) const
Merges this configuration to another configuration.
void copyTo(CfgOption &other) const
Copies this configuration to another configuration.
CfgOption()
default constructor
Definition cfg_option.cc:80
std::list< std::string > getVendorIdsSpaceNames() const
Returns a list of option space names for configured vendor ids.
OptionContainerPtr getAll(const std::string &option_space) const
Returns all options for the specified option space.
void merge(CfgOptionDefPtr cfg_def, CfgOption &other)
Merges another option configuration into this one.
bool equals(const CfgOption &other) const
Check if configuration is equal to other configuration.
Definition cfg_option.cc:90
void add(const OptionPtr &option, const bool persistent, const bool cancelled, const std::string &option_space, const uint64_t id=0)
Adds instance of the option to the configuration.
Definition cfg_option.cc:96
std::list< uint32_t > getVendorIds() const
Returns a list of all configured vendor identifiers.
Definition cfg_option.h:873
Container for storing client class names.
Definition classify.h:110
std::string toText(const std::string &separator=", ") const
Returns all class names as text.
Definition classify.cc:80
static OptionDefinitionPtr getOptionDef(const std::string &space, const uint16_t code)
Return the first option definition matching a particular option code.
Definition libdhcp++.cc:132
static OptionDefinitionPtr getVendorOptionDef(const Option::Universe u, const uint32_t vendor_id, const uint16_t code)
Returns vendor option definition for a given vendor-id and code.
Definition libdhcp++.cc:174
static uint32_t optionSpaceToVendorId(const std::string &option_space)
Converts option space name to vendor id.
static OptionDefinitionPtr getRuntimeOptionDef(const std::string &space, const uint16_t code)
Returns runtime (non-standard) option definition by space and option code.
Definition libdhcp++.cc:195
static OptionDefinitionPtr getLastResortOptionDef(const std::string &space, const uint16_t code)
Returns last resort option definition by space and option code.
Definition libdhcp++.cc:253
Option descriptor.
Definition cfg_option.h:49
OptionPtr option_
Option instance.
Definition cfg_option.h:52
void addClientClass(const std::string &class_name)
Adds new client class for which the option is allowed.
Definition cfg_option.cc:59
std::string space_name_
Option space name.
Definition cfg_option.h:92
OptionDescriptor(const OptionPtr &opt, bool persist, bool cancel, const std::string &formatted_value="", data::ConstElementPtr user_context=data::ConstElementPtr())
Constructor.
Definition cfg_option.h:105
bool equals(const OptionDescriptor &other) const
Checks if the one descriptor is equal to another.
Definition cfg_option.cc:48
bool allowedForClientClasses(const ClientClasses &cclasses) const
Validates an OptionDescriptor's client-classes against a list of classes.
Definition cfg_option.cc:72
ClientClassesPtr copyClientClasses() const
Get a copy of client classes.
Definition cfg_option.cc:67
bool cancelled_
Cancelled flag.
Definition cfg_option.h:66
std::string formatted_value_
Option value in textual (CSV) format.
Definition cfg_option.h:81
static OptionDescriptorPtr create(const OptionPtr &opt, bool persist, bool cancel, const std::string &formatted_value="", data::ConstElementPtr user_context=data::ConstElementPtr())
Factory function creating an instance of the OptionDescriptor.
Definition cfg_option.cc:29
ClientClasses client_classes_
Collection of classes for the which option is allowed.
Definition cfg_option.h:96
bool persistent_
Persistence flag.
Definition cfg_option.h:58
Simple container for option spaces holding various items.
void clearItems()
Remove all items from the container.
static bool validateName(const std::string &name)
Checks that the provided option space name is valid.
Universe
defines option universe DHCPv4 or DHCPv6
Definition option.h:90
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
Definition macros.h:26
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:29
boost::shared_ptr< Element > ElementPtr
Definition data.h:28
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
Definition dhcpsrv_log.h:56
std::string ClientClass
Defines a single class name.
Definition classify.h:44
boost::multi_index_container< OptionDescriptor, boost::multi_index::indexed_by< boost::multi_index::sequenced<>, boost::multi_index::hashed_non_unique< KeyFromKeyExtractor< boost::multi_index::const_mem_fun< Option, uint16_t, &Option::getType >, boost::multi_index::member< OptionDescriptor, OptionPtr, &OptionDescriptor::option_ > > >, boost::multi_index::hashed_non_unique< boost::multi_index::member< OptionDescriptor, bool, &OptionDescriptor::persistent_ > >, boost::multi_index::ordered_non_unique< boost::multi_index::const_mem_fun< data::BaseStampedElement, boost::posix_time::ptime, &data::BaseStampedElement::getModificationTime > >, boost::multi_index::hashed_non_unique< boost::multi_index::tag< OptionIdIndexTag >, boost::multi_index::const_mem_fun< data::BaseStampedElement, uint64_t, &data::BaseStampedElement::getId > >, boost::multi_index::hashed_non_unique< boost::multi_index::member< OptionDescriptor, bool, &OptionDescriptor::cancelled_ > >, boost::multi_index::hashed_non_unique< boost::multi_index::composite_key< OptionDescriptor, KeyFromKeyExtractor< boost::multi_index::const_mem_fun< Option, uint16_t, &Option::getType >, boost::multi_index::member< OptionDescriptor, OptionPtr, &OptionDescriptor::option_ > >, boost::multi_index::member< OptionDescriptor, ClientClasses, &OptionDescriptor::client_classes_ > > > > > OptionContainer
Multi index container for DHCP option descriptors.
Definition cfg_option.h:347
std::pair< OptionContainerTypeIndex::const_iterator, OptionContainerTypeIndex::const_iterator > OptionContainerTypeRange
Pair of iterators to represent the range of options having the same option type value.
Definition cfg_option.h:357
OptionContainer::nth_index< 1 >::type OptionContainerTypeIndex
Type of the index #1 - option type.
Definition cfg_option.h:352
boost::shared_ptr< CfgOptionDef > CfgOptionDefPtr
Non-const pointer.
boost::shared_ptr< ClientClasses > ClientClassesPtr
Smart pointer to ClientClasses object.
Definition classify.h:281
boost::shared_ptr< OptionDefinition > OptionDefinitionPtr
Pointer to option definition object.
boost::shared_ptr< OptionDescriptor > OptionDescriptorPtr
A pointer to option descriptor.
Definition cfg_option.h:38
boost::shared_ptr< OptionContainer > OptionContainerPtr
Pointer to the OptionContainer object.
Definition cfg_option.h:350
const isc::log::MessageID DHCPSRV_CFGMGR_OPTION_DEFINITION_MISMATCH
boost::shared_ptr< Option > OptionPtr
Definition option.h:37
string encodeHex(const vector< uint8_t > &binary)
Encode binary data in the base16 format.
Definition encode.cc:361
string trim(const string &input)
Trim leading and trailing spaces.
Definition str.cc:32
Defines the logger used by the top-level component of kea-lfc.
#define DHCP4_OPTION_SPACE
global std option spaces
#define DHCP6_OPTION_SPACE