Kea 3.1.1
cfg_option.h
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#ifndef CFG_OPTION_H
8#define CFG_OPTION_H
9
10#include <dhcp/option.h>
11#include <dhcp/classify.h>
13#include <cc/cfg_to_element.h>
14#include <cc/stamped_element.h>
15#include <cc/user_context.h>
18#include <boost/foreach.hpp>
19#include <boost/multi_index_container.hpp>
20#include <boost/multi_index/hashed_index.hpp>
21#include <boost/multi_index/ordered_index.hpp>
22#include <boost/multi_index/sequenced_index.hpp>
23#include <boost/multi_index/mem_fun.hpp>
24#include <boost/multi_index/member.hpp>
25#include <boost/multi_index/composite_key.hpp>
26#include <boost/shared_ptr.hpp>
27#include <stdint.h>
28#include <list>
29#include <string>
30#include <vector>
31
32namespace isc {
33namespace dhcp {
34
36
38typedef boost::shared_ptr<OptionDescriptor> OptionDescriptorPtr;
39
41typedef std::vector<OptionDescriptor> OptionDescriptorList;
42
50public:
53
59
67
81 std::string formatted_value_;
82
92 std::string space_name_;
93
97
105 OptionDescriptor(const OptionPtr& opt, bool persist, bool cancel,
106 const std::string& formatted_value = "",
108 : data::StampedElement(), option_(opt), persistent_(persist),
109 cancelled_(cancel), formatted_value_(formatted_value),
110 space_name_() {
111 setContext(user_context);
112 }
113
118 OptionDescriptor(bool persist, bool cancel)
121
135
140 if (this != &other) {
141 // Not self-assignment.
142 data::StampedElement::operator=(other);
143 option_ = other.option_;
144 persistent_ = other.persistent_;
145 cancelled_ = other.cancelled_;
147 space_name_ = other.space_name_;
149 setContext(other.getContext());
150 }
151 return (*this);
152 }
153
163 static OptionDescriptorPtr create(const OptionPtr& opt,
164 bool persist,
165 bool cancel,
166 const std::string& formatted_value = "",
167 data::ConstElementPtr user_context =
169
176 static OptionDescriptorPtr create(bool persist, bool cancel);
177
183 static OptionDescriptorPtr create(const OptionDescriptor& desc);
184
190 bool equals(const OptionDescriptor& other) const;
191
197 bool operator==(const OptionDescriptor& other) const {
198 return (equals(other));
199 }
200
206 bool operator!=(const OptionDescriptor& other) const {
207 return (!equals(other));
208 }
209
213 void addClientClass(const std::string& class_name);
214
221 bool allowedForClientClasses(const ClientClasses& cclasses) const;
222
227};
228
258typedef boost::multi_index_container<
259 // Container comprises elements of OptionDescriptor type.
260 OptionDescriptor,
261 // Here we start enumerating various indexes.
262 boost::multi_index::indexed_by<
263 // Sequenced index allows accessing elements in the same way
264 // as elements in std::list.
265 // Sequenced is an index #0.
266 boost::multi_index::sequenced<>,
267 // Start definition of index #1.
268 boost::multi_index::hashed_non_unique<
269 // KeyFromKeyExtractor is the index key extractor that allows
270 // accessing option type being held by the OptionPtr through
271 // OptionDescriptor structure.
272 KeyFromKeyExtractor<
273 // Use option type as the index key. The type is held
274 // in OptionPtr object so we have to call Option::getType
275 // to retrieve this key for each element.
276 boost::multi_index::const_mem_fun<
277 Option,
278 uint16_t,
280 >,
281 // Indicate that OptionPtr is a member of
282 // OptionDescriptor structure.
283 boost::multi_index::member<
284 OptionDescriptor,
285 OptionPtr,
287 >
288 >
289 >,
290 // Start definition of index #2.
291 // Use 'persistent' struct member as a key.
292 boost::multi_index::hashed_non_unique<
293 boost::multi_index::member<
294 OptionDescriptor,
295 bool,
297 >
298 >,
299 // Start definition of index #3.
300 // Use BaseStampedElement::getModificationTime as a key.
301 boost::multi_index::ordered_non_unique<
302 boost::multi_index::const_mem_fun<
304 boost::posix_time::ptime,
306 >
307 >,
308
309 // Start definition of index #4.
310 // Use BaseStampedElement::getId as a key.
311 boost::multi_index::hashed_non_unique<
312 boost::multi_index::tag<OptionIdIndexTag>,
313 boost::multi_index::const_mem_fun<data::BaseStampedElement, uint64_t,
315 >,
316 // Start definition of index #5.
317 // Use 'cancelled' struct member as a key.
318 boost::multi_index::hashed_non_unique<
319 boost::multi_index::member<
320 OptionDescriptor,
321 bool,
323 >
324 >,
325 // Start definition of index #6.
326 boost::multi_index::hashed_non_unique<
327 boost::multi_index::composite_key<
328 OptionDescriptor,
329 KeyFromKeyExtractor<
330 boost::multi_index::const_mem_fun<
331 Option,
332 uint16_t,
334 >,
335 boost::multi_index::member<
336 OptionDescriptor,
337 OptionPtr,
339 >
340 >,
341 boost::multi_index::member<OptionDescriptor,
342 ClientClasses,
344 >
345 >
346 >
348
350typedef boost::shared_ptr<OptionContainer> OptionContainerPtr;
352typedef OptionContainer::nth_index<1>::type OptionContainerTypeIndex;
356typedef std::pair<OptionContainerTypeIndex::const_iterator,
357 OptionContainerTypeIndex::const_iterator> OptionContainerTypeRange;
359typedef OptionContainer::nth_index<2>::type OptionContainerPersistIndex;
363typedef std::pair<OptionContainerPersistIndex::const_iterator,
364 OptionContainerPersistIndex::const_iterator> OptionContainerPersistRange;
366typedef OptionContainer::nth_index<5>::type OptionContainerCancelIndex;
370typedef std::pair<OptionContainerCancelIndex::const_iterator,
371 OptionContainerCancelIndex::const_iterator> OptionContainerCancelRange;
372
374typedef OptionContainer::nth_index<6>::type OptionContainerTypeClassesIndex;
375typedef std::pair<OptionContainerTypeClassesIndex::const_iterator,
376 OptionContainerTypeClassesIndex::const_iterator> OptionContainerTypeClassesRange;
377
405public:
406
408 CfgOption();
409
413 bool empty() const;
414
417
418
423 bool equals(const CfgOption& other) const;
424
430 bool operator==(const CfgOption& other) const {
431 return (equals(other));
432 }
433
439 bool operator!=(const CfgOption& other) const {
440 return (!equals(other));
441 }
442
444
470 void add(const OptionPtr& option, const bool persistent,
471 const bool cancelled, const std::string& option_space,
472 const uint64_t id = 0);
473
482 void add(const OptionDescriptor& desc, const std::string& option_space);
483
497 void replace(const OptionDescriptor& desc, const std::string& option_space);
498
518 void merge(CfgOptionDefPtr cfg_def, CfgOption& other);
519
529 void createOptions(CfgOptionDefPtr cfg_def);
530
571 static bool createDescriptorOption(CfgOptionDefPtr cfg_def, const std::string& space,
572 OptionDescriptor& opt_desc);
573
582 void mergeTo(CfgOption& other) const;
583
589 void copyTo(CfgOption& other) const;
590
597 void encapsulate();
598
602 bool isEncapsulated() const {
603 return (encapsulated_);
604 }
605
616 OptionContainerPtr getAll(const std::string& option_space) const;
617
624 OptionContainerPtr getAll(const uint32_t vendor_id) const;
625
637 OptionContainerPtr getAllCombined(const std::string& option_space) const;
638
656 template<typename Selector>
657 OptionDescriptor get(const Selector& key,
658 const uint16_t option_code) const {
659
660 // Check for presence of options.
661 OptionContainerPtr options = getAll(key);
662 if (!options || options->empty()) {
663 return (OptionDescriptor(false, false));
664 }
665
666 // Some options present, locate the one we are interested in.
667 const OptionContainerTypeIndex& idx = options->get<1>();
668 OptionContainerTypeIndex::const_iterator od_itr = idx.find(option_code);
669 if (od_itr == idx.end()) {
670 return (OptionDescriptor(false, false));
671 }
672
673 return (*od_itr);
674 }
675
687 template<typename Selector>
688 OptionDescriptorList getList(const Selector& key,
689 const uint16_t option_code) const {
690
692 // Check for presence of options.
693 OptionContainerPtr options = getAll(key);
694 if (!options || options->empty()) {
695 return (list);
696 }
697
698 // Some options present, locate the one we are interested in.
699 const OptionContainerTypeIndex& idx = options->get<1>();
700 OptionContainerTypeRange range = idx.equal_range(option_code);
701 // This code copies descriptors and can be optimized not doing this.
702 BOOST_FOREACH(auto const& od_itr, range) {
703 list.push_back(od_itr);
704 }
705
706 return (list);
707 }
708
722 template<typename Selector>
723 OptionDescriptor get(const Selector& key,
724 const uint16_t option_code,
725 const ClientClasses& client_classes) const {
726
727 // Check for presence of options.
728 OptionContainerPtr options = getAll(key);
729 if (!options || options->empty()) {
730 return (OptionDescriptor(false, false));
731 }
732
733 // Some options present, locate the one we are interested in
734 // using code + client_classes index.
735 auto& idx6 = options->get<6>();
736 auto const& od_itr6 = idx6.find(boost::make_tuple(option_code, client_classes));
737 if (od_itr6 == idx6.end()) {
738 return (OptionDescriptor(false, false));
739 }
740
741 return (*od_itr6);
742 }
743
754 template<typename Selector>
756 const uint16_t option_code,
757 const ClientClasses& cclasses) const {
758 // Check for presence of options.
759 OptionContainerPtr options = getAll(key);
760 if (!options || options->empty()) {
761 return (OptionDescriptor(false, false));
762 }
763
764 // We treat the empty client-classes case (if present) as a default.
765 // If we encounter it before we reach the end of the list of options
766 // remember it but keep checking the list for an actual match. We do
767 // it this way to avoid expecting the entries in any particular order.
768 auto & index = options->get<1>();
769 auto range = index.equal_range(option_code);
770 switch (std::distance(range.first, range.second)) {
771 case 0:
772 break;
773 case 1:
774 if ((*range.first).allowedForClientClasses(cclasses)) {
775 return (*range.first);
776 }
777 break;
778 default:
779 {
780 auto default_opt = index.end();
781 auto otr = range.first;
782 while (otr != range.second) {
783 if ((*otr).allowedForClientClasses(cclasses)) {
784 if (!(*otr).client_classes_.empty()) {
785 return (*otr);
786 }
787
788 default_opt = otr;
789 }
790
791 ++otr;
792 }
793
794 // If we have a default return it.
795 if (default_opt != index.end()) {
796 return (*default_opt);
797 }
798 }}
799
800 // None allowed.
801 return (OptionDescriptor(false, false));
802 }
803
814 size_t del(const std::string& option_space, const uint16_t option_code);
815
827 size_t del(const std::string& option_space, const uint16_t option_code,
828 const ClientClasses& client_classes);
829
836 size_t del(const uint32_t vendor_id, const uint16_t option_code);
837
859 size_t del(const uint64_t id);
860
868 std::list<std::string> getOptionSpaceNames() const {
869 return (options_.getOptionSpaceNames());
870 }
871
873 std::list<uint32_t> getVendorIds() const {
874 return (vendor_options_.getOptionSpaceNames());
875 }
876
884 std::list<std::string> getVendorIdsSpaceNames() const;
885
889 virtual isc::data::ElementPtr toElement() const;
890
895 virtual isc::data::ElementPtr toElement(CfgOptionDefPtr cfg_option_def) const;
896
906 toElementWithMetadata(const bool include_metadata,
907 CfgOptionDefPtr cfg_option_def = CfgOptionDefPtr()) const;
908
909private:
910
922 void encapsulateInternal(const std::string& option_space);
923
932 void encapsulateInternal(const OptionPtr& option);
933
947 template <typename Selector>
948 void mergeInternal(const OptionSpaceContainer<OptionContainer,
949 OptionDescriptor, Selector>& src_container,
951 OptionDescriptor, Selector>& dest_container) const;
952
954 bool encapsulated_;
955
958 std::string> OptionSpaceCollection;
960 OptionSpaceCollection options_;
961
964 uint32_t> VendorOptionSpaceCollection;
966 VendorOptionSpaceCollection vendor_options_;
967};
968
970
971
973typedef boost::shared_ptr<CfgOption> CfgOptionPtr;
974
976typedef boost::shared_ptr<const CfgOption> ConstCfgOptionPtr;
977
979typedef std::list<ConstCfgOptionPtr> CfgOptionList;
980
982
983}
984}
985
986#endif // CFG_OPTION_H
boost::shared_ptr< Option > OptionPtr
Definition option.h:37
Defines elements for storing the names of client classes.
This class represents configuration element which is associated with database identifier and the modi...
boost::posix_time::ptime getModificationTime() const
Returns timestamp.
uint64_t getId() const
Returns element's database identifier.
This class represents configuration element which is associated with database identifier,...
Represents option data configuration for the DHCP server.
Definition cfg_option.h:404
bool isEncapsulated() const
Checks if options have been encapsulated.
Definition cfg_option.h:602
OptionDescriptor allowedForClientClasses(const Selector &key, const uint16_t option_code, const ClientClasses &cclasses) const
Fetches an option for a given code if it is allowed for the given list of client classes.
Definition cfg_option.h:755
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.
OptionDescriptor get(const Selector &key, const uint16_t option_code) const
Returns option for the specified key and option code.
Definition cfg_option.h:657
isc::data::ElementPtr toElementWithMetadata(const bool include_metadata, CfgOptionDefPtr cfg_option_def=CfgOptionDefPtr()) const
Unparse a configuration object with optionally including the metadata.
OptionDescriptorList getList(const Selector &key, const uint16_t option_code) const
Returns options for the specified key and option code.
Definition cfg_option.h:688
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:83
bool operator==(const CfgOption &other) const
Equality operator.
Definition cfg_option.h:430
bool operator!=(const CfgOption &other) const
Inequality operator.
Definition cfg_option.h:439
OptionDescriptor get(const Selector &key, const uint16_t option_code, const ClientClasses &client_classes) const
Returns option for the specified key, option code and client classes tag.
Definition cfg_option.h:723
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:78
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:88
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:94
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
Option descriptor.
Definition cfg_option.h:49
OptionPtr option_
Option instance.
Definition cfg_option.h:52
bool operator!=(const OptionDescriptor &other) const
Inequality operator.
Definition cfg_option.h:206
void addClientClass(const std::string &class_name)
Adds new client class for which the option is allowed.
Definition cfg_option.cc:57
std::string space_name_
Option space name.
Definition cfg_option.h:92
OptionDescriptor & operator=(const OptionDescriptor &other)
Assignment operator.
Definition cfg_option.h:139
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:46
bool allowedForClientClasses(const ClientClasses &cclasses) const
Validates an OptionDescriptor's client-classes against a list of classes.
Definition cfg_option.cc:70
ClientClassesPtr copyClientClasses() const
Get a copy of client classes.
Definition cfg_option.cc:65
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:27
ClientClasses client_classes_
Collection of classes for the which option is allowed.
Definition cfg_option.h:96
OptionDescriptor(bool persist, bool cancel)
Constructor.
Definition cfg_option.h:118
bool operator==(const OptionDescriptor &other) const
Equality operator.
Definition cfg_option.h:197
OptionDescriptor(const OptionDescriptor &desc)
Copy constructor.
Definition cfg_option.h:125
bool persistent_
Persistence flag.
Definition cfg_option.h:58
Simple container for option spaces holding various items.
uint16_t getType() const
Returns option type (0-255 for DHCPv4, 0-65535 for DHCPv6)
Definition option.h:300
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:29
boost::shared_ptr< Element > ElementPtr
Definition data.h:28
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
boost::shared_ptr< CfgOption > CfgOptionPtr
Non-const pointer.
Definition cfg_option.h:973
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
std::pair< OptionContainerTypeClassesIndex::const_iterator, OptionContainerTypeClassesIndex::const_iterator > OptionContainerTypeClassesRange
Definition cfg_option.h:376
std::map< std::string, OptionSpacePtr > OptionSpaceCollection
A collection of option spaces.
boost::shared_ptr< CfgOptionDef > CfgOptionDefPtr
Non-const pointer.
boost::shared_ptr< ClientClasses > ClientClassesPtr
Smart pointer to ClientClasses object.
Definition classify.h:281
std::vector< OptionDescriptor > OptionDescriptorList
A list of option descriptors.
Definition cfg_option.h:41
OptionContainer::nth_index< 5 >::type OptionContainerCancelIndex
Type of the index #5 - option cancellation flag.
Definition cfg_option.h:366
std::pair< OptionContainerPersistIndex::const_iterator, OptionContainerPersistIndex::const_iterator > OptionContainerPersistRange
Pair of iterators to represent the range of options having the same persistency flag.
Definition cfg_option.h:364
boost::shared_ptr< OptionDescriptor > OptionDescriptorPtr
A pointer to option descriptor.
Definition cfg_option.h:38
OptionContainer::nth_index< 6 >::type OptionContainerTypeClassesIndex
Type of the index #6 - option type + client_classes.
Definition cfg_option.h:374
boost::shared_ptr< OptionContainer > OptionContainerPtr
Pointer to the OptionContainer object.
Definition cfg_option.h:350
OptionContainer::nth_index< 2 >::type OptionContainerPersistIndex
Type of the index #2 - option persistency flag.
Definition cfg_option.h:359
std::pair< OptionContainerCancelIndex::const_iterator, OptionContainerCancelIndex::const_iterator > OptionContainerCancelRange
Pair of iterators to represent the range of options having the same cancellation flag.
Definition cfg_option.h:371
boost::shared_ptr< Option > OptionPtr
Definition option.h:37
std::list< ConstCfgOptionPtr > CfgOptionList
Const pointer list.
Definition cfg_option.h:979
boost::shared_ptr< const CfgOption > ConstCfgOptionPtr
Const pointer.
Definition cfg_option.h:976
Defines the logger used by the top-level component of kea-lfc.
Abstract class for configuration Cfg_* classes.
Base class for user context.
data::ConstElementPtr getContext() const
Returns const pointer to the user context.
void setContext(const data::ConstElementPtr &ctx)
Sets user context.