Kea 2.7.5
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), additional_(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_), additional_(rhs.additional_),
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
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 (additional_);
106}
107
108void
110 additional_ = additional;
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);
150 .arg(pkt->getLabel())
151 .arg(getName())
152 .arg(status ? "true" : "false");
153 if (status) {
154 // Matching: add the class
155 pkt->addClass(getName());
156 }
157 } catch (const Exception& ex) {
159 .arg(pkt->getLabel())
160 .arg(getName())
161 .arg(ex.what());
162 }
163}
164
165const std::string TemplateClientClassDef::SPAWN_CLASS_PREFIX("SPAWN_");
166
168 const ExpressionPtr& match_expr,
169 const CfgOptionPtr& options) :
170 ClientClassDef(name, match_expr, options) {
171}
172
173void
175 // Evaluate the expression which can return false (no match),
176 // true (match) or raise an exception (error)
177 try {
178 std::string subclass = evaluateString(*expr_ptr, *pkt);
179 if (!subclass.empty()) {
181 .arg(pkt->getLabel())
182 .arg(getName())
183 .arg(subclass);
184 // Matching: add the subclass
186 value += getName();
187 value += "_";
188 value += subclass;
189 pkt->addSubClass(getName(), value);
190 }
191 } catch (const Exception& ex) {
193 .arg(pkt->getLabel())
194 .arg(getName())
195 .arg(ex.what());
196 }
197}
198
199bool
200ClientClassDef::dependOnClass(const std::string& name) const {
201 return (isc::dhcp::dependOnClass(match_expr_, name));
202}
203
204bool
206 return ((name_ == other.name_) &&
207 ((!match_expr_ && !other.match_expr_) ||
208 (match_expr_ && other.match_expr_ &&
209 (*match_expr_ == *other.match_expr_))) &&
210 ((!cfg_option_ && !other.cfg_option_) ||
211 (cfg_option_ && other.cfg_option_ &&
212 (*cfg_option_ == *other.cfg_option_))) &&
213 ((!cfg_option_def_ && !other.cfg_option_def_) ||
214 (cfg_option_def_ && other.cfg_option_def_ &&
215 (*cfg_option_def_ == *other.cfg_option_def_))) &&
216 (additional_ == other.additional_) &&
217 (depend_on_known_ == other.depend_on_known_) &&
218 (next_server_ == other.next_server_) &&
219 (sname_ == other.sname_) &&
220 (filename_ == other.filename_));
221}
222
225 uint16_t family = CfgMgr::instance().getFamily();
227 // Set user-context
228 contextToElement(result);
229 // Set name
230 result->set("name", Element::create(name_));
231 // Set original match expression (empty string won't parse)
232 if (!test_.empty()) {
233 result->set("test", Element::create(test_));
234 }
235 // Set only-in-additional-list
236 if (additional_) {
237 result->set("only-in-additional-list", Element::create(additional_));
238 }
239 // Set option-def (used only by DHCPv4)
240 if (cfg_option_def_ && (family == AF_INET)) {
241 result->set("option-def", cfg_option_def_->toElement());
242 result->set("option-data", cfg_option_->toElement(cfg_option_def_));
243 } else {
244 // Set option-data
245 result->set("option-data", cfg_option_->toElement());
246 }
247
248 if (family == AF_INET) {
249 // V4 only
250 // Set next-server
251 result->set("next-server", Element::create(next_server_.toText()));
252 // Set server-hostname
253 result->set("server-hostname", Element::create(sname_));
254 // Set boot-file-name
255 result->set("boot-file-name", Element::create(filename_));
256
257 // Set offer-lifetime
258 if (!offer_lft_.unspecified()) {
259 result->set("offer-lifetime",
260 Element::create(static_cast<long long>(offer_lft_.get())));
261 }
262 } else {
263 // V6 only
264 // Set preferred-lifetime
265 if (!preferred_.unspecified()) {
266 result->set("preferred-lifetime",
267 Element::create(static_cast<long long>(preferred_.get())));
268 }
269
270 if (preferred_.getMin() < preferred_.get()) {
271 result->set("min-preferred-lifetime",
272 Element::create(static_cast<long long>(preferred_.getMin())));
273 }
274
275 if (preferred_.getMax() > preferred_.get()) {
276 result->set("max-preferred-lifetime",
277 Element::create(static_cast<long long>(preferred_.getMax())));
278 }
279 }
280
281 // Set valid-lifetime
282 if (!valid_.unspecified()) {
283 result->set("valid-lifetime",
284 Element::create(static_cast<long long>(valid_.get())));
285
286 if (valid_.getMin() < valid_.get()) {
287 result->set("min-valid-lifetime",
288 Element::create(static_cast<long long>(valid_.getMin())));
289 }
290
291 if (valid_.getMax() > valid_.get()) {
292 result->set("max-valid-lifetime",
293 Element::create(static_cast<long long>(valid_.getMax())));
294 }
295 }
296
297 return (result);
298}
299
302 auto const& result = ClientClassDef::toElement();
303 auto const& test = result->get("test");
304 if (test) {
305 result->set("template-test", test);
306 result->remove("test");
307 } else {
308 result->set("template-test", Element::create(""));
309 }
310 return (result);
311}
312
313std::ostream& operator<<(std::ostream& os, const ClientClassDef& x) {
314 os << "ClientClassDef:" << x.getName();
315 return (os);
316}
317
318//********** ClientClassDictionary ******************//
319
323
325 : map_(new ClientClassDefMap()), list_(new ClientClassDefList()) {
326 for (auto const& cclass : *rhs.list_) {
328 addClass(copy);
329 }
330}
331
334
335void
336ClientClassDictionary::addClass(const std::string& name,
337 const ExpressionPtr& match_expr,
338 const std::string& test,
339 bool additional,
340 bool depend_on_known,
341 const CfgOptionPtr& cfg_option,
342 CfgOptionDefPtr cfg_option_def,
343 ConstElementPtr user_context,
344 asiolink::IOAddress next_server,
345 const std::string& sname,
346 const std::string& filename,
347 const util::Triplet<uint32_t>& valid,
348 const util::Triplet<uint32_t>& preferred,
349 bool is_template,
350 const util::Optional<uint32_t>& offer_lft) {
351 ClientClassDefPtr cclass;
352 if (is_template) {
353 cclass.reset(new TemplateClientClassDef(name, match_expr, cfg_option));
354 } else {
355 cclass.reset(new ClientClassDef(name, match_expr, cfg_option));
356 }
357 cclass->setTest(test);
358 cclass->setAdditional(additional);
359 cclass->setDependOnKnown(depend_on_known);
360 cclass->setCfgOptionDef(cfg_option_def);
361 cclass->setContext(user_context),
362 cclass->setNextServer(next_server);
363 cclass->setSname(sname);
364 cclass->setFilename(filename);
365 cclass->setValid(valid);
366 cclass->setPreferred(preferred);
367 cclass->setOfferLft(offer_lft);
368 addClass(cclass);
369}
370
371void
373 if (!class_def) {
374 isc_throw(BadValue, "ClientClassDictionary::addClass "
375 " - class definition cannot be null");
376 }
377
378 if (findClass(class_def->getName())) {
379 isc_throw(DuplicateClientClassDef, "Client Class: "
380 << class_def->getName() << " has already been defined");
381 }
382
383 list_->push_back(class_def);
384 (*map_)[class_def->getName()] = class_def;
385}
386
388ClientClassDictionary::findClass(const std::string& name) const {
389 ClientClassDefMap::iterator it = map_->find(name);
390 if (it != map_->end()) {
391 return (*it).second;
392 }
393
394 return (ClientClassDefPtr());
395}
396
397void
398ClientClassDictionary::removeClass(const std::string& name) {
399 for (ClientClassDefList::iterator this_class = list_->begin();
400 this_class != list_->end(); ++this_class) {
401 if ((*this_class)->getName() == name) {
402 list_->erase(this_class);
403 break;
404 }
405 }
406 map_->erase(name);
407}
408
409void
411 // Class id equal to 0 means it wasn't set.
412 if (id == 0) {
413 return;
414 }
415 for (ClientClassDefList::iterator this_class = list_->begin();
416 this_class != list_->end(); ++this_class) {
417 if ((*this_class)->getId() == id) {
418 map_->erase((*this_class)->getName());
419 list_->erase(this_class);
420 break;
421 }
422 }
423}
424
427 return (list_);
428}
429
430bool
432 return (list_->empty());
433}
434
435bool
437 std::string& dependent_class) const {
438 // Skip previous classes as they should not depend on name.
439 bool found = false;
440 for (auto const& this_class : *list_) {
441 if (found) {
442 if (this_class->dependOnClass(name)) {
443 dependent_class = this_class->getName();
444 return (true);
445 }
446 } else {
447 if (this_class->getName() == name) {
448 found = true;
449 }
450 }
451 }
452 return (false);
453}
454
455bool
457 if (list_->size() != other.list_->size()) {
458 return (false);
459 }
460
461 ClientClassDefList::const_iterator this_class = list_->cbegin();
462 ClientClassDefList::const_iterator other_class = other.list_->cbegin();
463 while (this_class != list_->cend() &&
464 other_class != other.list_->cend()) {
465 if (!*this_class || !*other_class ||
466 **this_class != **other_class) {
467 return false;
468 }
469
470 ++this_class;
471 ++other_class;
472 }
473
474 return (true);
475}
476
477void
479 std::queue<ExpressionPtr> expressions;
480 for (auto const& c : *list_) {
481 if (!c->getTest().empty()) {
482 ExpressionPtr match_expr = boost::make_shared<Expression>();
483 ExpressionParser parser;
485 if (dynamic_cast<TemplateClientClassDef*>(c.get())) {
486 parser_type = EvalContext::PARSER_STRING;
487 }
488 parser.parse(match_expr, Element::create(c->getTest()), family,
489 EvalContext::acceptAll, parser_type);
490 expressions.push(match_expr);
491 }
492 }
493 // All expressions successfully initialized. Let's set them for the
494 // client classes in the dictionary.
495 for (auto const& c : *list_) {
496 if (!c->getTest().empty()) {
497 c->setMatchExpr(expressions.front());
498 expressions.pop();
499 }
500 }
501}
502
503void
505 for (auto const& c : *list_) {
506 // If the class has no options, skip it.
507 CfgOptionPtr class_options = c->getCfgOption();
508 if (!class_options || class_options->empty()) {
509 continue;
510 }
511
512 // If the class has no option definitions, use the set
513 // of definitions we were given as is to create its
514 // options.
515 if (!c->getCfgOptionDef()) {
516 class_options->createOptions(external_defs);
517 } else {
518 // Class has its own option definitions, we need a
519 // composite set of definitions to recreate its options.
520 // We make copies of both sets of definitions, then merge
521 // the external defs copy into the class defs copy.
522 // We do this because merging actually effects both sets
523 // of definitions and we cannot alter either set.
524 // Seed the composite set with the class's definitions.
525 CfgOptionDefPtr composite_defs(new CfgOptionDef());
526 c->getCfgOptionDef()->copyTo(*composite_defs);
527
528 // Make a copy of the external definitions and
529 // merge those into the composite set. This should give
530 // us a set of options with class definitions taking
531 // precedence.
532 CfgOptionDefPtr external_defs_copy(new CfgOptionDef());
533 external_defs->copyTo(*external_defs_copy);
534 composite_defs->merge(*external_defs_copy);
535
536 // Now create the class options using the composite
537 // set of definitions.
538 class_options->createOptions(composite_defs);
539 }
540 }
541}
542
543void
545 for (auto const& c : *list_) {
546 CfgOptionPtr class_options = c->getCfgOption();
547 if (class_options) {
548 class_options->encapsulate();
549 }
550 }
551}
552
556 // Iterate on the map
557 for (auto const& this_class : *list_) {
558 result->add(this_class->toElement());
559 }
560 return (result);
561}
562
565 if (this != &rhs) {
566 list_->clear();
567 map_->clear();
568 for (auto const& cclass : *rhs.list_) {
570 addClass(copy);
571 }
572 }
573 return (*this);
574}
575
577std::list<std::string>
579 // DROP is not in this list because it is special but not built-in.
580 // In fact DROP is set from an expression as callouts can drop
581 // directly the incoming packet. The expression must not depend on
582 // KNOWN/UNKNOWN which are set far after the drop point.
583 // SKIP_DDNS, used by DDNS-tuning is also omitted from this list
584 // so users may assign it a test expression.
585 "ALL", "KNOWN", "UNKNOWN", "BOOTP"
586};
587
594std::list<std::string>
596 "VENDOR_CLASS_", "HA_", "AFTER_", "EXTERNAL_"
597};
598
599bool
600isClientClassBuiltIn(const ClientClass& client_class) {
601 for (auto const& bn : builtinNames) {
602 if (client_class == bn) {
603 return true;
604 }
605 }
606
607 for (auto const& bt : builtinPrefixes) {
608 if (client_class.size() <= bt.size()) {
609 continue;
610 }
611 auto mis = std::mismatch(bt.cbegin(), bt.cend(), client_class.cbegin());
612 if (mis.first == bt.cend()) {
613 return true;
614 }
615 }
616
617 return false;
618}
619
620bool
622 bool& depend_on_known,
623 const ClientClass& client_class) {
624 // First check built-in classes
625 if (isClientClassBuiltIn(client_class)) {
626 // Check direct dependency on [UN]KNOWN
627 if ((client_class == "KNOWN") || (client_class == "UNKNOWN")) {
628 depend_on_known = true;
629 }
630 return (true);
631 }
632
633 // Second check already defined, i.e. in the dictionary
634 ClientClassDefPtr def = class_dictionary->findClass(client_class);
635 if (def) {
636 // Check indirect dependency on [UN]KNOWN
637 if (def->getDependOnKnown()) {
638 depend_on_known = true;
639 }
640 return (true);
641 }
642
643 // Not defined...
644 return (false);
645}
646
647} // namespace isc::dhcp
648} // 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.
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,...
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:372
Embodies a single client class definition.
void setAdditional(bool additional)
Sets the only if additional flag.
bool equals(const ClientClassDef &other) const
Compares two ClientClassDef objects for equality.
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.
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.
bool getAdditional() const
Fetches the only if additional flag.
void setDependOnKnown(bool depend_on_known)
Sets the depend on known flag aka use host flag.
Maintains a list of ClientClassDef's.
void addClass(const std::string &name, const ExpressionPtr &match_expr, const std::string &test, bool additional, 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.
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 encapsulateOptions() const
Iterates over the classes in the dictionary and encapsulates suboptions.
void createOptions(const CfgOptionDefPtr &cfg_option_def)
Iterates over the classes in the dictionary and recreates the options.
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.
@ PARSER_BOOL
expression is expected to evaluate to bool
@ PARSER_STRING
expression is expected to evaluate to string
static bool acceptAll(const ClientClass &client_class)
Accept all client class names.
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_
#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_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:998
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:832
const isc::log::MessageID DHCPSRV_EVAL_ERROR
boost::shared_ptr< CfgOptionDef > CfgOptionDefPtr
Non-const pointer.
const isc::log::MessageID DHCPSRV_TEMPLATE_EVAL_RESULT
boost::shared_ptr< ClientClassDef > ClientClassDefPtr
a pointer to an ClientClassDef
std::string evaluateString(const Expression &expr, Pkt &pkt)
Evaluate a RPN expression for a v4 or v6 packet and return a string value.
Definition evaluate.cc:45
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
const isc::log::MessageID DHCPSRV_TEMPLATE_EVAL_ERROR
boost::shared_ptr< Expression > ExpressionPtr
Definition token.h:31
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:34
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:29
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.
const isc::log::MessageID DHCPSRV_EVAL_RESULT
Defines the logger used by the top-level component of kea-lfc.
Abstract class for configuration Cfg_* classes.
Base class for user context.
void contextToElement(data::ElementPtr map) const
Merge unparse a user_context object.