Kea 2.5.6
client_class_def.cc
Go to the documentation of this file.
1// Copyright (C) 2015-2024 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 <eval/dependency.h>
10#include <eval/evaluate.h>
11#include <eval/eval_log.h>
13#include <dhcpsrv/cfgmgr.h>
14#include <dhcpsrv/dhcpsrv_log.h>
16
17#include <queue>
18
19using namespace isc::data;
20
21namespace isc {
22namespace dhcp {
23
24//********** ClientClassDef ******************//
25
26ClientClassDef::ClientClassDef(const std::string& name,
27 const ExpressionPtr& match_expr,
28 const CfgOptionPtr& cfg_option)
30 match_expr_(match_expr), required_(false), depend_on_known_(false),
31 cfg_option_(cfg_option), next_server_(asiolink::IOAddress::IPV4_ZERO_ADDRESS()),
32 valid_(), preferred_() {
33
34 // Name can't be blank
35 if (name_.empty()) {
36 isc_throw(BadValue, "Client Class name cannot be blank");
37 }
38
39 // We permit an empty expression for now. This will likely be useful
40 // for automatic classes such as vendor class.
41 // For classes without options, make sure we have an empty collection
42 if (!cfg_option_) {
43 cfg_option_.reset(new CfgOption());
44 }
45}
46
48 : UserContext(rhs), CfgToElement(rhs), StampedElement(rhs), name_(rhs.name_),
49 match_expr_(ExpressionPtr()), test_(rhs.test_), required_(rhs.required_),
50 depend_on_known_(rhs.depend_on_known_), cfg_option_(new CfgOption()),
51 next_server_(rhs.next_server_), sname_(rhs.sname_),
52 filename_(rhs.filename_), valid_(rhs.valid_), preferred_(rhs.preferred_),
53 offer_lft_(rhs.offer_lft_) {
54
55 if (rhs.match_expr_) {
56 match_expr_.reset(new Expression());
57 *match_expr_ = *rhs.match_expr_;
58 }
59
60 if (rhs.cfg_option_def_) {
61 cfg_option_def_.reset(new CfgOptionDef());
62 rhs.cfg_option_def_->copyTo(*cfg_option_def_);
63 }
64
65 if (rhs.cfg_option_) {
66 rhs.cfg_option_->copyTo(*cfg_option_);
67 }
68}
69
71}
72
73std::string
75 return (name_);
76}
77
78void
79ClientClassDef::setName(const std::string& name) {
80 name_ = name;
81}
82
83const ExpressionPtr&
85 return (match_expr_);
86}
87
88void
90 match_expr_ = match_expr;
91}
92
93std::string
95 return (test_);
96}
97
98void
99ClientClassDef::setTest(const std::string& test) {
100 test_ = test;
101}
102
103bool
105 return (required_);
106}
107
108void
110 required_ = required;
111}
112
113bool
115 return (depend_on_known_);
116}
117
118void
119ClientClassDef::setDependOnKnown(bool depend_on_known) {
120 depend_on_known_ = depend_on_known;
121}
122
123const CfgOptionDefPtr&
125 return (cfg_option_def_);
126}
127
128void
130 cfg_option_def_ = cfg_option_def;
131}
132
133const CfgOptionPtr&
135 return (cfg_option_);
136}
137
138void
140 cfg_option_ = cfg_option;
141}
142
143void
145 // Evaluate the expression which can return false (no match),
146 // true (match) or raise an exception (error)
147 try {
148 bool status = evaluateBool(*expr_ptr, *pkt);
149 if (status) {
151 .arg(getName())
152 .arg("true");
153 // Matching: add the class
154 pkt->addClass(getName());
155 } else {
157 .arg(getName())
158 .arg("false");
159 }
160 } catch (const Exception& ex) {
162 .arg(getName())
163 .arg(ex.what());
164 } catch (...) {
166 .arg(getName())
167 .arg("get exception?");
168 }
169}
170
171const std::string TemplateClientClassDef::SPAWN_CLASS_PREFIX("SPAWN_");
172
174 const ExpressionPtr& match_expr,
175 const CfgOptionPtr& options) :
176 ClientClassDef(name, match_expr, options) {
177}
178
179void
181 // Evaluate the expression which can return false (no match),
182 // true (match) or raise an exception (error)
183 try {
184 std::string subclass = evaluateString(*expr_ptr, *pkt);
185 if (!subclass.empty()) {
187 .arg(getName())
188 .arg(subclass);
189 // Matching: add the subclass
191 value += getName();
192 value += "_";
193 value += subclass;
194 pkt->addSubClass(getName(), value);
195 }
196 } catch (const Exception& ex) {
198 .arg(getName())
199 .arg(ex.what());
200 } catch (...) {
202 .arg(getName())
203 .arg("get exception?");
204 }
205}
206
207bool
208ClientClassDef::dependOnClass(const std::string& name) const {
209 return (isc::dhcp::dependOnClass(match_expr_, name));
210}
211
212bool
214 return ((name_ == other.name_) &&
215 ((!match_expr_ && !other.match_expr_) ||
216 (match_expr_ && other.match_expr_ &&
217 (*match_expr_ == *other.match_expr_))) &&
218 ((!cfg_option_ && !other.cfg_option_) ||
219 (cfg_option_ && other.cfg_option_ &&
220 (*cfg_option_ == *other.cfg_option_))) &&
221 ((!cfg_option_def_ && !other.cfg_option_def_) ||
222 (cfg_option_def_ && other.cfg_option_def_ &&
223 (*cfg_option_def_ == *other.cfg_option_def_))) &&
224 (required_ == other.required_) &&
225 (depend_on_known_ == other.depend_on_known_) &&
226 (next_server_ == other.next_server_) &&
227 (sname_ == other.sname_) &&
228 (filename_ == other.filename_));
229}
230
233 uint16_t family = CfgMgr::instance().getFamily();
235 // Set user-context
236 contextToElement(result);
237 // Set name
238 result->set("name", Element::create(name_));
239 // Set original match expression (empty string won't parse)
240 if (!test_.empty()) {
241 result->set("test", Element::create(test_));
242 }
243 // Set only-if-required
244 if (required_) {
245 result->set("only-if-required", Element::create(required_));
246 }
247 // Set option-def (used only by DHCPv4)
248 if (cfg_option_def_ && (family == AF_INET)) {
249 result->set("option-def", cfg_option_def_->toElement());
250 }
251 // Set option-data
252 result->set("option-data", cfg_option_->toElement());
253
254 if (family == AF_INET) {
255 // V4 only
256 // Set next-server
257 result->set("next-server", Element::create(next_server_.toText()));
258 // Set server-hostname
259 result->set("server-hostname", Element::create(sname_));
260 // Set boot-file-name
261 result->set("boot-file-name", Element::create(filename_));
262
263 // Set offer-lifetime
264 if (!offer_lft_.unspecified()) {
265 result->set("offer-lifetime",
266 Element::create(static_cast<long long>(offer_lft_.get())));
267 }
268 } else {
269 // V6 only
270 // Set preferred-lifetime
271 if (!preferred_.unspecified()) {
272 result->set("preferred-lifetime",
273 Element::create(static_cast<long long>(preferred_.get())));
274 }
275
276 if (preferred_.getMin() < preferred_.get()) {
277 result->set("min-preferred-lifetime",
278 Element::create(static_cast<long long>(preferred_.getMin())));
279 }
280
281 if (preferred_.getMax() > preferred_.get()) {
282 result->set("max-preferred-lifetime",
283 Element::create(static_cast<long long>(preferred_.getMax())));
284 }
285 }
286
287 // Set valid-lifetime
288 if (!valid_.unspecified()) {
289 result->set("valid-lifetime",
290 Element::create(static_cast<long long>(valid_.get())));
291
292 if (valid_.getMin() < valid_.get()) {
293 result->set("min-valid-lifetime",
294 Element::create(static_cast<long long>(valid_.getMin())));
295 }
296
297 if (valid_.getMax() > valid_.get()) {
298 result->set("max-valid-lifetime",
299 Element::create(static_cast<long long>(valid_.getMax())));
300 }
301 }
302
303 return (result);
304}
305
308 auto const& result = ClientClassDef::toElement();
309 auto const& test = result->get("test");
310 if (test) {
311 result->set("template-test", test);
312 result->remove("test");
313 } else {
314 result->set("template-test", Element::create(""));
315 }
316 return (result);
317}
318
319std::ostream& operator<<(std::ostream& os, const ClientClassDef& x) {
320 os << "ClientClassDef:" << x.getName();
321 return (os);
322}
323
324//********** ClientClassDictionary ******************//
325
327 : map_(new ClientClassDefMap()), list_(new ClientClassDefList()) {
328}
329
331 : map_(new ClientClassDefMap()), list_(new ClientClassDefList()) {
332 for (auto const& cclass : *rhs.list_) {
334 addClass(copy);
335 }
336}
337
339}
340
341void
342ClientClassDictionary::addClass(const std::string& name,
343 const ExpressionPtr& match_expr,
344 const std::string& test,
345 bool required,
346 bool depend_on_known,
347 const CfgOptionPtr& cfg_option,
348 CfgOptionDefPtr cfg_option_def,
349 ConstElementPtr user_context,
350 asiolink::IOAddress next_server,
351 const std::string& sname,
352 const std::string& filename,
353 const util::Triplet<uint32_t>& valid,
354 const util::Triplet<uint32_t>& preferred,
355 bool is_template,
356 const util::Optional<uint32_t>& offer_lft) {
357 ClientClassDefPtr cclass;
358 if (is_template) {
359 cclass.reset(new TemplateClientClassDef(name, match_expr, cfg_option));
360 } else {
361 cclass.reset(new ClientClassDef(name, match_expr, cfg_option));
362 }
363 cclass->setTest(test);
364 cclass->setRequired(required);
365 cclass->setDependOnKnown(depend_on_known);
366 cclass->setCfgOptionDef(cfg_option_def);
367 cclass->setContext(user_context),
368 cclass->setNextServer(next_server);
369 cclass->setSname(sname);
370 cclass->setFilename(filename);
371 cclass->setValid(valid);
372 cclass->setPreferred(preferred);
373 cclass->setOfferLft(offer_lft);
374 addClass(cclass);
375}
376
377void
379 if (!class_def) {
380 isc_throw(BadValue, "ClientClassDictionary::addClass "
381 " - class definition cannot be null");
382 }
383
384 if (findClass(class_def->getName())) {
385 isc_throw(DuplicateClientClassDef, "Client Class: "
386 << class_def->getName() << " has already been defined");
387 }
388
389 list_->push_back(class_def);
390 (*map_)[class_def->getName()] = class_def;
391}
392
394ClientClassDictionary::findClass(const std::string& name) const {
395 ClientClassDefMap::iterator it = map_->find(name);
396 if (it != map_->end()) {
397 return (*it).second;
398 }
399
400 return (ClientClassDefPtr());
401}
402
403void
404ClientClassDictionary::removeClass(const std::string& name) {
405 for (ClientClassDefList::iterator this_class = list_->begin();
406 this_class != list_->end(); ++this_class) {
407 if ((*this_class)->getName() == name) {
408 list_->erase(this_class);
409 break;
410 }
411 }
412 map_->erase(name);
413}
414
415void
417 // Class id equal to 0 means it wasn't set.
418 if (id == 0) {
419 return;
420 }
421 for (ClientClassDefList::iterator this_class = list_->begin();
422 this_class != list_->end(); ++this_class) {
423 if ((*this_class)->getId() == id) {
424 map_->erase((*this_class)->getName());
425 list_->erase(this_class);
426 break;
427 }
428 }
429}
430
433 return (list_);
434}
435
436bool
438 return (list_->empty());
439}
440
441bool
443 std::string& dependent_class) const {
444 // Skip previous classes as they should not depend on name.
445 bool found = false;
446 for (auto const& this_class : *list_) {
447 if (found) {
448 if (this_class->dependOnClass(name)) {
449 dependent_class = this_class->getName();
450 return (true);
451 }
452 } else {
453 if (this_class->getName() == name) {
454 found = true;
455 }
456 }
457 }
458 return (false);
459}
460
461bool
463 if (list_->size() != other.list_->size()) {
464 return (false);
465 }
466
467 ClientClassDefList::const_iterator this_class = list_->cbegin();
468 ClientClassDefList::const_iterator other_class = other.list_->cbegin();
469 while (this_class != list_->cend() &&
470 other_class != other.list_->cend()) {
471 if (!*this_class || !*other_class ||
472 **this_class != **other_class) {
473 return false;
474 }
475
476 ++this_class;
477 ++other_class;
478 }
479
480 return (true);
481}
482
483void
485 std::queue<ExpressionPtr> expressions;
486 for (auto const& c : *list_) {
487 if (!c->getTest().empty()) {
488 ExpressionPtr match_expr = boost::make_shared<Expression>();
489 ExpressionParser parser;
491 if (dynamic_cast<TemplateClientClassDef*>(c.get())) {
492 parser_type = EvalContext::PARSER_STRING;
493 }
494 parser.parse(match_expr, Element::create(c->getTest()), family,
495 EvalContext::acceptAll, parser_type);
496 expressions.push(match_expr);
497 }
498 }
499 // All expressions successfully initialized. Let's set them for the
500 // client classes in the dictionary.
501 for (auto const& c : *list_) {
502 if (!c->getTest().empty()) {
503 c->setMatchExpr(expressions.front());
504 expressions.pop();
505 }
506 }
507}
508
509void
511 for (auto const& c : *list_) {
512 // If the class has no options, skip it.
513 CfgOptionPtr class_options = c->getCfgOption();
514 if (!class_options || class_options->empty()) {
515 continue;
516 }
517
518 // If the class has no option definitions, use the set
519 // of definitions we were given as is to create its
520 // options.
521 if (!c->getCfgOptionDef()) {
522 class_options->createOptions(external_defs);
523 } else {
524 // Class has its own option definitions, we need a
525 // composite set of definitions to recreate its options.
526 // We make copies of both sets of definitions, then merge
527 // the external defs copy into the class defs copy.
528 // We do this because merging actually effects both sets
529 // of definitions and we cannot alter either set.
530 // Seed the composite set with the class's definitions.
531 CfgOptionDefPtr composite_defs(new CfgOptionDef());
532 c->getCfgOptionDef()->copyTo(*composite_defs);
533
534 // Make a copy of the external definitions and
535 // merge those into the composite set. This should give
536 // us a set of options with class definitions taking
537 // precedence.
538 CfgOptionDefPtr external_defs_copy(new CfgOptionDef());
539 external_defs->copyTo(*external_defs_copy);
540 composite_defs->merge(*external_defs_copy);
541
542 // Now create the class options using the composite
543 // set of definitions.
544 class_options->createOptions(composite_defs);
545 }
546 }
547}
548
552 // Iterate on the map
553 for (auto const& this_class : *list_) {
554 result->add(this_class->toElement());
555 }
556 return (result);
557}
558
561 if (this != &rhs) {
562 list_->clear();
563 map_->clear();
564 for (auto const& cclass : *rhs.list_) {
566 addClass(copy);
567 }
568 }
569 return (*this);
570}
571
573std::list<std::string>
575 // DROP is not in this list because it is special but not built-in.
576 // In fact DROP is set from an expression as callouts can drop
577 // directly the incoming packet. The expression must not depend on
578 // KNOWN/UNKNOWN which are set far after the drop point.
579 // SKIP_DDNS, used by DDNS-tuning is also omitted from this list
580 // so users may assign it a test expression.
581 "ALL", "KNOWN", "UNKNOWN", "BOOTP"
582};
583
590std::list<std::string>
592 "VENDOR_CLASS_", "HA_", "AFTER_", "EXTERNAL_"
593};
594
595bool
596isClientClassBuiltIn(const ClientClass& client_class) {
597 for (auto const& bn : builtinNames) {
598 if (client_class == bn) {
599 return true;
600 }
601 }
602
603 for (auto const& bt : builtinPrefixes) {
604 if (client_class.size() <= bt.size()) {
605 continue;
606 }
607 auto mis = std::mismatch(bt.cbegin(), bt.cend(), client_class.cbegin());
608 if (mis.first == bt.cend()) {
609 return true;
610 }
611 }
612
613 return false;
614}
615
616bool
618 bool& depend_on_known,
619 const ClientClass& client_class) {
620 // First check built-in classes
621 if (isClientClassBuiltIn(client_class)) {
622 // Check direct dependency on [UN]KNOWN
623 if ((client_class == "KNOWN") || (client_class == "UNKNOWN")) {
624 depend_on_known = true;
625 }
626 return (true);
627 }
628
629 // Second check already defined, i.e. in the dictionary
630 ClientClassDefPtr def = class_dictionary->findClass(client_class);
631 if (def) {
632 // Check indirect dependency on [UN]KNOWN
633 if (def->getDependOnKnown()) {
634 depend_on_known = true;
635 }
636 return (true);
637 }
638
639 // Not defined...
640 return (false);
641}
642
643} // namespace isc::dhcp
644} // namespace isc
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
This is a base class for exceptions thrown from the DNS library module.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
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
This class represents configuration element which is associated with database identifier,...
uint16_t getFamily() const
Returns address family.
Definition: cfgmgr.h:280
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition: cfgmgr.cc:25
Represents option definitions used by the DHCP server.
Represents option data configuration for the DHCP server.
Definition: cfg_option.h:352
Embodies a single client class definition.
bool equals(const ClientClassDef &other) const
Compares two ClientClassDef objects for equality.
bool getRequired() const
Fetches the only if required flag.
void setCfgOption(const CfgOptionPtr &cfg_option)
Sets the class's option collection.
void setName(const std::string &name)
Sets the class's name.
bool dependOnClass(const std::string &name) const
Checks direct dependency.
bool getDependOnKnown() const
Fetches the depend on known flag aka use host flag.
void setRequired(bool required)
Sets the only if required flag.
virtual void test(PktPtr pkt, const ExpressionPtr &expr_ptr)
Test method which checks if the packet belongs to the class.
const CfgOptionDefPtr & getCfgOptionDef() const
Fetches the class's option definitions.
ClientClassDef(const std::string &name, const ExpressionPtr &match_expr, const CfgOptionPtr &options=CfgOptionPtr())
Constructor.
const ExpressionPtr & getMatchExpr() const
Fetches the class's match expression.
void setCfgOptionDef(const CfgOptionDefPtr &cfg_option_def)
Sets the class's option definition collection.
virtual ~ClientClassDef()
Destructor.
std::string getName() const
Fetches the class's name.
const CfgOptionPtr & getCfgOption() const
Fetches the class's option collection.
void setMatchExpr(const ExpressionPtr &match_expr)
Sets the class's match expression.
void setTest(const std::string &test)
Sets the class's original match expression.
virtual isc::data::ElementPtr toElement() const
Unparse a configuration object.
std::string getTest() const
Fetches the class's original match expression.
void setDependOnKnown(bool depend_on_known)
Sets the depend on known flag aka use host flag.
Maintains a list of ClientClassDef's.
ClientClassDefPtr findClass(const std::string &name) const
Fetches the class definition for a given class name.
bool equals(const ClientClassDictionary &other) const
Compares two ClientClassDictionary objects for equality.
void removeClass(const std::string &name)
Removes a given class definition from the dictionary.
bool empty() const
Checks if the class dictionary is empty.
bool dependOnClass(const std::string &name, std::string &dependent_class) const
Checks direct dependency.
const ClientClassDefListPtr & getClasses() const
Fetches the dictionary's list of classes.
ClientClassDictionary & operator=(const ClientClassDictionary &rhs)
Copy assignment operator.
void createOptions(const CfgOptionDefPtr &cfg_option_def)
Iterates over the classes in the dictionary and recreates the options.
void addClass(const std::string &name, const ExpressionPtr &match_expr, const std::string &test, bool required, bool depend_on_known, const CfgOptionPtr &options, CfgOptionDefPtr defs=CfgOptionDefPtr(), isc::data::ConstElementPtr user_context=isc::data::ConstElementPtr(), asiolink::IOAddress next_server=asiolink::IOAddress("0.0.0.0"), const std::string &sname=std::string(), const std::string &filename=std::string(), const util::Triplet< uint32_t > &valid=util::Triplet< uint32_t >(), const util::Triplet< uint32_t > &preferred=util::Triplet< uint32_t >(), bool is_template=false, const util::Optional< uint32_t > &offer_lft=util::Optional< uint32_t >())
Adds a new class to the list.
virtual isc::data::ElementPtr toElement() const
Unparse a configuration object.
void initMatchExpr(uint16_t family)
Iterates over the classes in the dictionary and ensures that that match expressions are initialized.
Error that occurs when an attempt is made to add a duplicate class to a class dictionary.
Parser for a logical expression.
void parse(ExpressionPtr &expression, isc::data::ConstElementPtr expression_cfg, uint16_t family, isc::eval::EvalContext::CheckDefined check_defined=isc::eval::EvalContext::acceptAll, isc::eval::EvalContext::ParserType parser_type=isc::eval::EvalContext::PARSER_BOOL)
Parses an expression configuration element into an Expression.
static const std::string SPAWN_CLASS_PREFIX
This is a prefix added to the spawned class name.
TemplateClientClassDef(const std::string &name, const ExpressionPtr &match_expr, const CfgOptionPtr &options=CfgOptionPtr())
Constructor.
virtual void test(PktPtr pkt, const ExpressionPtr &expr_ptr) override
Test method which checks if the packet belongs to the class.
virtual isc::data::ElementPtr toElement() const override
Unparse a configuration object.
ParserType
Specifies what type of expression the parser is expected to see.
Definition: eval_context.h:38
@ PARSER_BOOL
expression is expected to evaluate to bool
Definition: eval_context.h:39
@ PARSER_STRING
expression is expected to evaluate to string
Definition: eval_context.h:40
static bool acceptAll(const ClientClass &client_class)
Accept all client class names.
Definition: eval_context.cc:32
A template representing an optional value.
Definition: optional.h:36
T get() const
Retrieves the encapsulated value.
Definition: optional.h:114
void unspecified(bool unspecified)
Modifies the flag that indicates whether the value is specified or unspecified.
Definition: optional.h:136
This template specifies a parameter value.
Definition: triplet.h:37
T get(T hint) const
Returns value with a hint.
Definition: triplet.h:99
T getMax() const
Returns a maximum allowed value.
Definition: triplet.h:112
T getMin() const
Returns a minimum allowed value.
Definition: triplet.h:85
Defines classes for storing client class definitions.
Parsers for client class definitions.
const Name & name_
Definition: dns/message.cc:699
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition: macros.h:32
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition: macros.h:20
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition: macros.h:14
ElementPtr copy(ConstElementPtr from, int level)
Copy the data up to a nesting level.
Definition: data.cc:1420
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
boost::shared_ptr< isc::dhcp::Pkt > PktPtr
A pointer to either Pkt4 or Pkt6 packet.
Definition: pkt.h:967
std::string ClientClass
Defines a single class name.
Definition: classify.h:42
std::vector< ClientClassDefPtr > ClientClassDefList
Defines a list of ClientClassDefPtr's, using insert order.
boost::shared_ptr< CfgOption > CfgOptionPtr
Non-const pointer.
Definition: cfg_option.h:803
const isc::log::MessageID EVAL_RESULT
Definition: eval_messages.h:57
boost::shared_ptr< CfgOptionDef > CfgOptionDefPtr
Non-const pointer.
boost::shared_ptr< ClientClassDef > ClientClassDefPtr
a pointer to an ClientClassDef
std::string evaluateString(const Expression &expr, Pkt &pkt)
Definition: evaluate.cc:27
std::list< std::string > builtinPrefixes
The prefixes used to check if a class is BuiltIn class.
const int DHCPSRV_DBG_TRACE_DETAIL
Additional information.
Definition: dhcpsrv_log.h:38
boost::shared_ptr< Expression > ExpressionPtr
Definition: token.h:30
boost::shared_ptr< ClientClassDictionary > ClientClassDictionaryPtr
Defines a pointer to a ClientClassDictionary.
boost::shared_ptr< ClientClassDefList > ClientClassDefListPtr
Defines a pointer to a ClientClassDefList.
bool evaluateBool(const Expression &expr, Pkt &pkt)
Evaluate a RPN expression for a v4 or v6 packet and return a true or false decision.
Definition: evaluate.cc:14
bool isClientClassDefined(ClientClassDictionaryPtr &class_dictionary, bool &depend_on_known, const ClientClass &client_class)
Check if a client class name is already defined, i.e.
std::vector< TokenPtr > Expression
This is a structure that holds an expression converted to RPN.
Definition: token.h:28
bool isClientClassBuiltIn(const ClientClass &client_class)
Check if a client class name is builtin.
bool dependOnClass(const TokenPtr &token, const std::string &name)
Checks dependency on a token.
Definition: dependency.cc:15
std::list< std::string > builtinNames
List of classes for which test expressions cannot be defined.
std::unordered_map< std::string, ClientClassDefPtr > ClientClassDefMap
Defines a map of ClientClassDef's, keyed by the class name.
Defines the logger used by the top-level component of kea-lfc.
Abstract class for configuration Cfg_* classes.
Base class for user context.
Definition: user_context.h:22
void contextToElement(data::ElementPtr map) const
Merge unparse a user_context object.
Definition: user_context.cc:15