Kea 3.3.1
cfg_option.h
Go to the documentation of this file.
1// Copyright (C) 2014-2026 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 <set>
30#include <string>
31#include <vector>
32
33namespace isc {
34namespace dhcp {
35
37
39typedef boost::shared_ptr<OptionDescriptor> OptionDescriptorPtr;
40
42typedef std::vector<OptionDescriptor> OptionDescriptorList;
43
51public:
54
60
68
82 std::string formatted_value_;
83
93 std::string space_name_;
94
98
106 OptionDescriptor(const OptionPtr& opt, bool persist, bool cancel,
107 const std::string& formatted_value = "",
109 : data::StampedElement(), option_(opt), persistent_(persist),
110 cancelled_(cancel), formatted_value_(formatted_value),
111 space_name_() {
112 setContext(user_context);
113 }
114
119 OptionDescriptor(bool persist, bool cancel)
122
136
141 if (this != &other) {
142 // Not self-assignment.
143 data::StampedElement::operator=(other);
144 option_ = other.option_;
145 persistent_ = other.persistent_;
146 cancelled_ = other.cancelled_;
148 space_name_ = other.space_name_;
150 setContext(other.getContext());
151 }
152 return (*this);
153 }
154
164 static OptionDescriptorPtr create(const OptionPtr& opt,
165 bool persist,
166 bool cancel,
167 const std::string& formatted_value = "",
168 data::ConstElementPtr user_context =
170
177 static OptionDescriptorPtr create(bool persist, bool cancel);
178
184 static OptionDescriptorPtr create(const OptionDescriptor& desc);
185
191 bool equals(const OptionDescriptor& other) const;
192
198 bool operator==(const OptionDescriptor& other) const {
199 return (equals(other));
200 }
201
207 bool operator!=(const OptionDescriptor& other) const {
208 return (!equals(other));
209 }
210
214 void addClientClass(const std::string& class_name);
215
222 bool allowedForClientClasses(const ClientClasses& cclasses) const;
223
228};
229
259typedef boost::multi_index_container<
260 // Container comprises elements of OptionDescriptor type.
261 OptionDescriptor,
262 // Here we start enumerating various indexes.
263 boost::multi_index::indexed_by<
264 // Sequenced index allows accessing elements in the same way
265 // as elements in std::list.
266 // Sequenced is an index #0.
267 boost::multi_index::sequenced<>,
268 // Start definition of index #1.
269 boost::multi_index::hashed_non_unique<
270 // KeyFromKeyExtractor is the index key extractor that allows
271 // accessing option type being held by the OptionPtr through
272 // OptionDescriptor structure.
273 KeyFromKeyExtractor<
274 // Use option type as the index key. The type is held
275 // in OptionPtr object so we have to call Option::getType
276 // to retrieve this key for each element.
277 boost::multi_index::const_mem_fun<
278 Option,
279 uint16_t,
281 >,
282 // Indicate that OptionPtr is a member of
283 // OptionDescriptor structure.
284 boost::multi_index::member<
285 OptionDescriptor,
286 OptionPtr,
288 >
289 >
290 >,
291 // Start definition of index #2.
292 // Use 'persistent' struct member as a key.
293 boost::multi_index::hashed_non_unique<
294 boost::multi_index::member<
295 OptionDescriptor,
296 bool,
298 >
299 >,
300 // Start definition of index #3.
301 // Use BaseStampedElement::getModificationTime as a key.
302 boost::multi_index::ordered_non_unique<
303 boost::multi_index::const_mem_fun<
305 boost::posix_time::ptime,
307 >
308 >,
309
310 // Start definition of index #4.
311 // Use BaseStampedElement::getId as a key.
312 boost::multi_index::hashed_non_unique<
313 boost::multi_index::tag<OptionIdIndexTag>,
314 boost::multi_index::const_mem_fun<data::BaseStampedElement, uint64_t,
316 >,
317 // Start definition of index #5.
318 // Use 'cancelled' struct member as a key.
319 boost::multi_index::hashed_non_unique<
320 boost::multi_index::member<
321 OptionDescriptor,
322 bool,
324 >
325 >,
326 // Start definition of index #6.
327 boost::multi_index::hashed_non_unique<
328 boost::multi_index::composite_key<
329 OptionDescriptor,
330 KeyFromKeyExtractor<
331 boost::multi_index::const_mem_fun<
332 Option,
333 uint16_t,
335 >,
336 boost::multi_index::member<
337 OptionDescriptor,
338 OptionPtr,
340 >
341 >,
342 boost::multi_index::member<OptionDescriptor,
343 ClientClasses,
345 >
346 >
347 >
349
351typedef boost::shared_ptr<OptionContainer> OptionContainerPtr;
353typedef OptionContainer::nth_index<1>::type OptionContainerTypeIndex;
357typedef std::pair<OptionContainerTypeIndex::const_iterator,
358 OptionContainerTypeIndex::const_iterator> OptionContainerTypeRange;
360typedef OptionContainer::nth_index<2>::type OptionContainerPersistIndex;
364typedef std::pair<OptionContainerPersistIndex::const_iterator,
365 OptionContainerPersistIndex::const_iterator> OptionContainerPersistRange;
367typedef OptionContainer::nth_index<5>::type OptionContainerCancelIndex;
371typedef std::pair<OptionContainerCancelIndex::const_iterator,
372 OptionContainerCancelIndex::const_iterator> OptionContainerCancelRange;
373
375typedef OptionContainer::nth_index<6>::type OptionContainerTypeClassesIndex;
376typedef std::pair<OptionContainerTypeClassesIndex::const_iterator,
377 OptionContainerTypeClassesIndex::const_iterator> OptionContainerTypeClassesRange;
378
406public:
407
409 CfgOption();
410
414 bool empty() const;
415
418
419
424 bool equals(const CfgOption& other) const;
425
431 bool operator==(const CfgOption& other) const {
432 return (equals(other));
433 }
434
440 bool operator!=(const CfgOption& other) const {
441 return (!equals(other));
442 }
443
445
471 void add(const OptionPtr& option, const bool persistent,
472 const bool cancelled, const std::string& option_space,
473 const uint64_t id = 0);
474
483 void add(const OptionDescriptor& desc, const std::string& option_space);
484
498 void replace(const OptionDescriptor& desc, const std::string& option_space);
499
519 void merge(CfgOptionDefPtr cfg_def, CfgOption& other);
520
530 void createOptions(CfgOptionDefPtr cfg_def);
531
572 static bool createDescriptorOption(CfgOptionDefPtr cfg_def, const std::string& space,
573 OptionDescriptor& opt_desc);
574
583 void mergeTo(CfgOption& other) const;
584
590 void copyTo(CfgOption& other) const;
591
598 void encapsulate();
599
603 bool isEncapsulated() const {
604 return (encapsulated_);
605 }
606
609 static std::set<std::string> multiple_encapsulating_spaces_;
610
621 OptionContainerPtr getAll(const std::string& option_space) const;
622
629 OptionContainerPtr getAll(const uint32_t vendor_id) const;
630
642 OptionContainerPtr getAllCombined(const std::string& option_space) const;
643
661 template<typename Selector>
662 OptionDescriptor get(const Selector& key,
663 const uint16_t option_code) const {
664
665 // Check for presence of options.
666 OptionContainerPtr options = getAll(key);
667 if (!options || options->empty()) {
668 return (OptionDescriptor(false, false));
669 }
670
671 // Some options present, locate the one we are interested in.
672 const OptionContainerTypeIndex& idx = options->get<1>();
673 OptionContainerTypeIndex::const_iterator od_itr = idx.find(option_code);
674 if (od_itr == idx.end()) {
675 return (OptionDescriptor(false, false));
676 }
677
678 return (*od_itr);
679 }
680
692 template<typename Selector>
693 OptionDescriptorList getList(const Selector& key,
694 const uint16_t option_code) const {
695
697 // Check for presence of options.
698 OptionContainerPtr options = getAll(key);
699 if (!options || options->empty()) {
700 return (list);
701 }
702
703 // Some options present, locate the one we are interested in.
704 const OptionContainerTypeIndex& idx = options->get<1>();
705 OptionContainerTypeRange range = idx.equal_range(option_code);
706 // This code copies descriptors and can be optimized not doing this.
707 BOOST_FOREACH(auto const& od_itr, range) {
708 list.push_back(od_itr);
709 }
710
711 return (list);
712 }
713
727 template<typename Selector>
728 OptionDescriptor get(const Selector& key,
729 const uint16_t option_code,
730 const ClientClasses& client_classes) const {
731
732 // Check for presence of options.
733 OptionContainerPtr options = getAll(key);
734 if (!options || options->empty()) {
735 return (OptionDescriptor(false, false));
736 }
737
738 // Some options present, locate the one we are interested in
739 // using code + client_classes index.
740 auto& idx6 = options->get<6>();
741 auto const& od_itr6 = idx6.find(boost::make_tuple(option_code, client_classes));
742 if (od_itr6 == idx6.end()) {
743 return (OptionDescriptor(false, false));
744 }
745
746 return (*od_itr6);
747 }
748
759 template<typename Selector>
761 const uint16_t option_code,
762 const ClientClasses& cclasses) const {
763 // Check for presence of options.
764 OptionContainerPtr options = getAll(key);
765 if (!options || options->empty()) {
766 return (OptionDescriptor(false, false));
767 }
768
769 // We treat the empty client-classes case (if present) as a default.
770 // If we encounter it before we reach the end of the list of options
771 // remember it but keep checking the list for an actual match. We do
772 // it this way to avoid expecting the entries in any particular order.
773 auto & index = options->get<1>();
774 auto range = index.equal_range(option_code);
775 switch (std::distance(range.first, range.second)) {
776 case 0:
777 break;
778 case 1:
779 if ((*range.first).allowedForClientClasses(cclasses)) {
780 return (*range.first);
781 }
782 break;
783 default:
784 {
785 auto default_opt = index.end();
786 auto otr = range.first;
787 while (otr != range.second) {
788 if ((*otr).allowedForClientClasses(cclasses)) {
789 if (!(*otr).client_classes_.empty()) {
790 return (*otr);
791 }
792
793 default_opt = otr;
794 }
795
796 ++otr;
797 }
798
799 // If we have a default return it.
800 if (default_opt != index.end()) {
801 return (*default_opt);
802 }
803 }}
804
805 // None allowed.
806 return (OptionDescriptor(false, false));
807 }
808
819 size_t del(const std::string& option_space, const uint16_t option_code);
820
832 size_t del(const std::string& option_space, const uint16_t option_code,
833 const ClientClasses& client_classes);
834
841 size_t del(const uint32_t vendor_id, const uint16_t option_code);
842
864 size_t del(const uint64_t id);
865
873 std::list<std::string> getOptionSpaceNames() const {
874 return (options_.getOptionSpaceNames());
875 }
876
878 std::list<uint32_t> getVendorIds() const {
879 return (vendor_options_.getOptionSpaceNames());
880 }
881
889 std::list<std::string> getVendorIdsSpaceNames() const;
890
894 virtual isc::data::ElementPtr toElement() const;
895
900 virtual isc::data::ElementPtr toElement(CfgOptionDefPtr cfg_option_def) const;
901
911 toElementWithMetadata(const bool include_metadata,
912 CfgOptionDefPtr cfg_option_def = CfgOptionDefPtr()) const;
913
914private:
915
927 void encapsulateInternal(const std::string& option_space);
928
937 void encapsulateInternal(const OptionPtr& option);
938
942 void decapsulateInternal(const OptionPtr& option);
943
957 template <typename Selector>
958 void mergeInternal(const OptionSpaceContainer<OptionContainer,
959 OptionDescriptor, Selector>& src_container,
961 OptionDescriptor, Selector>& dest_container) const;
962
964 bool encapsulated_;
965
968 std::string> OptionSpaceCollection;
970 OptionSpaceCollection options_;
971
974 uint32_t> VendorOptionSpaceCollection;
976 VendorOptionSpaceCollection vendor_options_;
977};
978
980
981
983typedef boost::shared_ptr<CfgOption> CfgOptionPtr;
984
986typedef boost::shared_ptr<const CfgOption> ConstCfgOptionPtr;
987
989typedef std::list<ConstCfgOptionPtr> CfgOptionList;
990
992
993}
994}
995
996#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:405
bool isEncapsulated() const
Checks if options have been encapsulated.
Definition cfg_option.h:603
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:760
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.
static std::set< std::string > multiple_encapsulating_spaces_
Option spaces which can encapsulate multiple sub-options of the same type.
Definition cfg_option.h:609
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:662
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:693
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:873
bool empty() const
Indicates the object is empty.
Definition cfg_option.cc:89
bool operator==(const CfgOption &other) const
Equality operator.
Definition cfg_option.h:431
bool operator!=(const CfgOption &other) const
Inequality operator.
Definition cfg_option.h:440
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:728
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:84
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:94
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.
std::list< uint32_t > getVendorIds() const
Returns a list of all configured vendor identifiers.
Definition cfg_option.h:878
Container for storing client class names.
Definition classify.h:111
Option descriptor.
Definition cfg_option.h:50
OptionPtr option_
Option instance.
Definition cfg_option.h:53
bool operator!=(const OptionDescriptor &other) const
Inequality operator.
Definition cfg_option.h:207
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:93
OptionDescriptor & operator=(const OptionDescriptor &other)
Assignment operator.
Definition cfg_option.h:140
OptionDescriptor(const OptionPtr &opt, bool persist, bool cancel, const std::string &formatted_value="", data::ConstElementPtr user_context=data::ConstElementPtr())
Constructor.
Definition cfg_option.h:106
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:67
std::string formatted_value_
Option value in textual (CSV) format.
Definition cfg_option.h:82
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:97
OptionDescriptor(bool persist, bool cancel)
Constructor.
Definition cfg_option.h:119
bool operator==(const OptionDescriptor &other) const
Equality operator.
Definition cfg_option.h:198
OptionDescriptor(const OptionDescriptor &desc)
Copy constructor.
Definition cfg_option.h:126
bool persistent_
Persistence flag.
Definition cfg_option.h:59
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:30
boost::shared_ptr< Element > ElementPtr
Definition data.h:29
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:348
boost::shared_ptr< CfgOption > CfgOptionPtr
Non-const pointer.
Definition cfg_option.h:983
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:358
OptionContainer::nth_index< 1 >::type OptionContainerTypeIndex
Type of the index #1 - option type.
Definition cfg_option.h:353
std::pair< OptionContainerTypeClassesIndex::const_iterator, OptionContainerTypeClassesIndex::const_iterator > OptionContainerTypeClassesRange
Definition cfg_option.h:377
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:304
std::vector< OptionDescriptor > OptionDescriptorList
A list of option descriptors.
Definition cfg_option.h:42
OptionContainer::nth_index< 5 >::type OptionContainerCancelIndex
Type of the index #5 - option cancellation flag.
Definition cfg_option.h:367
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:365
boost::shared_ptr< OptionDescriptor > OptionDescriptorPtr
A pointer to option descriptor.
Definition cfg_option.h:39
OptionContainer::nth_index< 6 >::type OptionContainerTypeClassesIndex
Type of the index #6 - option type + client_classes.
Definition cfg_option.h:375
boost::shared_ptr< OptionContainer > OptionContainerPtr
Pointer to the OptionContainer object.
Definition cfg_option.h:351
OptionContainer::nth_index< 2 >::type OptionContainerPersistIndex
Type of the index #2 - option persistency flag.
Definition cfg_option.h:360
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:372
boost::shared_ptr< Option > OptionPtr
Definition option.h:37
std::list< ConstCfgOptionPtr > CfgOptionList
Const pointer list.
Definition cfg_option.h:989
boost::shared_ptr< const CfgOption > ConstCfgOptionPtr
Const pointer.
Definition cfg_option.h:986
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.