Kea  2.3.8
client_class_def.cc
Go to the documentation of this file.
1 // Copyright (C) 2015-2023 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 #include <boost/foreach.hpp>
17 
18 #include <queue>
19 
20 using namespace isc::data;
21 
22 namespace isc {
23 namespace dhcp {
24 
25 //********** ClientClassDef ******************//
26 
27 ClientClassDef::ClientClassDef(const std::string& name,
28  const ExpressionPtr& match_expr,
29  const CfgOptionPtr& cfg_option)
31  match_expr_(match_expr), required_(false), depend_on_known_(false),
32  cfg_option_(cfg_option), next_server_(asiolink::IOAddress::IPV4_ZERO_ADDRESS()),
33  valid_(), preferred_() {
34 
35  // Name can't be blank
36  if (name_.empty()) {
37  isc_throw(BadValue, "Client Class name cannot be blank");
38  }
39 
40  // We permit an empty expression for now. This will likely be useful
41  // for automatic classes such as vendor class.
42  // For classes without options, make sure we have an empty collection
43  if (!cfg_option_) {
44  cfg_option_.reset(new CfgOption());
45  }
46 }
47 
49  : UserContext(rhs), CfgToElement(rhs), StampedElement(rhs), name_(rhs.name_),
50  match_expr_(ExpressionPtr()), test_(rhs.test_), required_(rhs.required_),
51  depend_on_known_(rhs.depend_on_known_), cfg_option_(new CfgOption()),
52  next_server_(rhs.next_server_), sname_(rhs.sname_),
53  filename_(rhs.filename_), valid_(rhs.valid_), preferred_(rhs.preferred_),
54  offer_lft_(rhs.offer_lft_) {
55 
56  if (rhs.match_expr_) {
57  match_expr_.reset(new Expression());
58  *match_expr_ = *(rhs.match_expr_);
59  }
60 
61  if (rhs.cfg_option_def_) {
62  cfg_option_def_.reset(new CfgOptionDef());
63  rhs.cfg_option_def_->copyTo(*cfg_option_def_);
64  }
65 
66  if (rhs.cfg_option_) {
67  rhs.cfg_option_->copyTo(*cfg_option_);
68  }
69 }
70 
72 }
73 
74 std::string
76  return (name_);
77 }
78 
79 void
80 ClientClassDef::setName(const std::string& name) {
81  name_ = name;
82 }
83 
84 const ExpressionPtr&
86  return (match_expr_);
87 }
88 
89 void
91  match_expr_ = match_expr;
92 }
93 
94 std::string
96  return (test_);
97 }
98 
99 void
100 ClientClassDef::setTest(const std::string& test) {
101  test_ = test;
102 }
103 
104 bool
106  return (required_);
107 }
108 
109 void
111  required_ = required;
112 }
113 
114 bool
116  return (depend_on_known_);
117 }
118 
119 void
120 ClientClassDef::setDependOnKnown(bool depend_on_known) {
121  depend_on_known_ = depend_on_known;
122 }
123 
124 const CfgOptionDefPtr&
126  return (cfg_option_def_);
127 }
128 
129 void
131  cfg_option_def_ = cfg_option_def;
132 }
133 
134 const CfgOptionPtr&
136  return (cfg_option_);
137 }
138 
139 void
141  cfg_option_ = cfg_option;
142 }
143 
144 void
146  // Evaluate the expression which can return false (no match),
147  // true (match) or raise an exception (error)
148  try {
149  bool status = evaluateBool(*expr_ptr, *pkt);
150  if (status) {
152  .arg(getName())
153  .arg(status);
154  // Matching: add the class
155  pkt->addClass(getName());
156  } else {
158  .arg(getName())
159  .arg(status);
160  }
161  } catch (const Exception& ex) {
163  .arg(getName())
164  .arg(ex.what());
165  } catch (...) {
167  .arg(getName())
168  .arg("get exception?");
169  }
170 }
171 
172 const std::string TemplateClientClassDef::SPAWN_CLASS_PREFIX("SPAWN_");
173 
175  const ExpressionPtr& match_expr,
176  const CfgOptionPtr& options) :
177  ClientClassDef(name, match_expr, options) {
178 }
179 
180 void
182  // Evaluate the expression which can return false (no match),
183  // true (match) or raise an exception (error)
184  try {
185  std::string subclass = evaluateString(*expr_ptr, *pkt);
186  if (!subclass.empty()) {
188  .arg(getName())
189  .arg(subclass);
190  // Matching: add the subclass
192  value += getName();
193  value += "_";
194  value += subclass;
195  pkt->addSubClass(getName(), value);
196  }
197  } catch (const Exception& ex) {
199  .arg(getName())
200  .arg(ex.what());
201  } catch (...) {
203  .arg(getName())
204  .arg("get exception?");
205  }
206 }
207 
208 bool
209 ClientClassDef::dependOnClass(const std::string& name) const {
210  return (isc::dhcp::dependOnClass(match_expr_, name));
211 }
212 
213 bool
215  return ((name_ == other.name_) &&
216  ((!match_expr_ && !other.match_expr_) ||
217  (match_expr_ && other.match_expr_ &&
218  (*match_expr_ == *(other.match_expr_)))) &&
219  ((!cfg_option_ && !other.cfg_option_) ||
220  (cfg_option_ && other.cfg_option_ &&
221  (*cfg_option_ == *other.cfg_option_))) &&
222  ((!cfg_option_def_ && !other.cfg_option_def_) ||
223  (cfg_option_def_ && other.cfg_option_def_ &&
224  (*cfg_option_def_ == *other.cfg_option_def_))) &&
225  (required_ == other.required_) &&
226  (depend_on_known_ == other.depend_on_known_) &&
227  (next_server_ == other.next_server_) &&
228  (sname_ == other.sname_) &&
229  (filename_ == other.filename_));
230 }
231 
234  uint16_t family = CfgMgr::instance().getFamily();
235  ElementPtr result = Element::createMap();
236  // Set user-context
237  contextToElement(result);
238  // Set name
239  result->set("name", Element::create(name_));
240  // Set original match expression (empty string won't parse)
241  if (!test_.empty()) {
242  result->set("test", Element::create(test_));
243  }
244  // Set only-if-required
245  if (required_) {
246  result->set("only-if-required", Element::create(required_));
247  }
248  // Set option-def (used only by DHCPv4)
249  if (cfg_option_def_ && (family == AF_INET)) {
250  result->set("option-def", cfg_option_def_->toElement());
251  }
252  // Set option-data
253  result->set("option-data", cfg_option_->toElement());
254 
255  if (family == AF_INET) {
256  // V4 only
257  // Set next-server
258  result->set("next-server", Element::create(next_server_.toText()));
259  // Set server-hostname
260  result->set("server-hostname", Element::create(sname_));
261  // Set boot-file-name
262  result->set("boot-file-name", Element::create(filename_));
263 
264  // Set offer-lifetime
265  if (!offer_lft_.unspecified()) {
266  result->set("offer-lifetime",
267  Element::create(static_cast<long long>(offer_lft_.get())));
268  }
269  } else {
270  // V6 only
271  // Set preferred-lifetime
272  if (!preferred_.unspecified()) {
273  result->set("preferred-lifetime",
274  Element::create(static_cast<long long>(preferred_.get())));
275  }
276 
277  if (preferred_.getMin() < preferred_.get()) {
278  result->set("min-preferred-lifetime",
279  Element::create(static_cast<long long>(preferred_.getMin())));
280  }
281 
282  if (preferred_.getMax() > preferred_.get()) {
283  result->set("max-preferred-lifetime",
284  Element::create(static_cast<long long>(preferred_.getMax())));
285  }
286  }
287 
288  // Set valid-lifetime
289  if (!valid_.unspecified()) {
290  result->set("valid-lifetime",
291  Element::create(static_cast<long long>(valid_.get())));
292 
293  if (valid_.getMin() < valid_.get()) {
294  result->set("min-valid-lifetime",
295  Element::create(static_cast<long long>(valid_.getMin())));
296  }
297 
298  if (valid_.getMax() > valid_.get()) {
299  result->set("max-valid-lifetime",
300  Element::create(static_cast<long long>(valid_.getMax())));
301  }
302  }
303 
304  return (result);
305 }
306 
309  auto const& result = ClientClassDef::toElement();
310  auto const& test = result->get("test");
311  if (test) {
312  result->set("template-test", test);
313  result->remove("test");
314  } else {
315  result->set("template-test", Element::create(""));
316  }
317  return (result);
318 }
319 
320 std::ostream& operator<<(std::ostream& os, const ClientClassDef& x) {
321  os << "ClientClassDef:" << x.getName();
322  return (os);
323 }
324 
325 //********** ClientClassDictionary ******************//
326 
328  : map_(new ClientClassDefMap()), list_(new ClientClassDefList()) {
329 }
330 
332  : map_(new ClientClassDefMap()), list_(new ClientClassDefList()) {
333  BOOST_FOREACH(ClientClassDefPtr cclass, *(rhs.list_)) {
334  ClientClassDefPtr copy(new ClientClassDef(*cclass));
335  addClass(copy);
336  }
337 }
338 
340 }
341 
342 void
343 ClientClassDictionary::addClass(const std::string& name,
344  const ExpressionPtr& match_expr,
345  const std::string& test,
346  bool required,
347  bool depend_on_known,
348  const CfgOptionPtr& cfg_option,
349  CfgOptionDefPtr cfg_option_def,
350  ConstElementPtr user_context,
351  asiolink::IOAddress next_server,
352  const std::string& sname,
353  const std::string& filename,
354  const util::Triplet<uint32_t>& valid,
355  const util::Triplet<uint32_t>& preferred,
356  bool is_template,
357  const util::Optional<uint32_t>& offer_lft) {
358  ClientClassDefPtr cclass;
359  if (is_template) {
360  cclass.reset(new TemplateClientClassDef(name, match_expr, cfg_option));
361  } else {
362  cclass.reset(new ClientClassDef(name, match_expr, cfg_option));
363  }
364  cclass->setTest(test);
365  cclass->setRequired(required);
366  cclass->setDependOnKnown(depend_on_known);
367  cclass->setCfgOptionDef(cfg_option_def);
368  cclass->setContext(user_context),
369  cclass->setNextServer(next_server);
370  cclass->setSname(sname);
371  cclass->setFilename(filename);
372  cclass->setValid(valid);
373  cclass->setPreferred(preferred);
374  cclass->setOfferLft(offer_lft);
375  addClass(cclass);
376 }
377 
378 void
380  if (!class_def) {
381  isc_throw(BadValue, "ClientClassDictionary::addClass "
382  " - class definition cannot be null");
383  }
384 
385  if (findClass(class_def->getName())) {
386  isc_throw(DuplicateClientClassDef, "Client Class: "
387  << class_def->getName() << " has already been defined");
388  }
389 
390  list_->push_back(class_def);
391  (*map_)[class_def->getName()] = class_def;
392 }
393 
395 ClientClassDictionary::findClass(const std::string& name) const {
396  ClientClassDefMap::iterator it = map_->find(name);
397  if (it != map_->end()) {
398  return (*it).second;
399  }
400 
401  return (ClientClassDefPtr());
402 }
403 
404 void
405 ClientClassDictionary::removeClass(const std::string& name) {
406  for (ClientClassDefList::iterator this_class = list_->begin();
407  this_class != list_->end(); ++this_class) {
408  if ((*this_class)->getName() == name) {
409  list_->erase(this_class);
410  break;
411  }
412  }
413  map_->erase(name);
414 }
415 
416 void
418  // Class id equal to 0 means it wasn't set.
419  if (id == 0) {
420  return;
421  }
422  for (ClientClassDefList::iterator this_class = list_->begin();
423  this_class != list_->end(); ++this_class) {
424  if ((*this_class)->getId() == id) {
425  map_->erase((*this_class)->getName());
426  list_->erase(this_class);
427  break;
428  }
429  }
430 }
431 
434  return (list_);
435 }
436 
437 bool
439  return (list_->empty());
440 }
441 
442 bool
443 ClientClassDictionary::dependOnClass(const std::string& name,
444  std::string& dependent_class) const {
445  // Skip previous classes as they should not depend on name.
446  bool found = false;
447  for (ClientClassDefList::iterator this_class = list_->begin();
448  this_class != list_->end(); ++this_class) {
449  if (found) {
450  if ((*this_class)->dependOnClass(name)) {
451  dependent_class = (*this_class)->getName();
452  return (true);
453  }
454  } else {
455  if ((*this_class)->getName() == name) {
456  found = true;
457  }
458  }
459  }
460  return (false);
461 }
462 
463 bool
465  if (list_->size() != other.list_->size()) {
466  return (false);
467  }
468 
469  ClientClassDefList::const_iterator this_class = list_->cbegin();
470  ClientClassDefList::const_iterator other_class = other.list_->cbegin();
471  while (this_class != list_->cend() &&
472  other_class != other.list_->cend()) {
473  if (!*this_class || !*other_class ||
474  **this_class != **other_class) {
475  return false;
476  }
477 
478  ++this_class;
479  ++other_class;
480  }
481 
482  return (true);
483 }
484 
485 void
487  std::queue<ExpressionPtr> expressions;
488  for (auto c : *list_) {
489  if (!c->getTest().empty()) {
490  ExpressionPtr match_expr = boost::make_shared<Expression>();
491  ExpressionParser parser;
492  EvalContext::ParserType parser_type = EvalContext::PARSER_BOOL;
493  if (dynamic_cast<TemplateClientClassDef*>(c.get())) {
494  parser_type = EvalContext::PARSER_STRING;
495  }
496  parser.parse(match_expr, Element::create(c->getTest()), family,
497  EvalContext::acceptAll, parser_type);
498  expressions.push(match_expr);
499  }
500  }
501  // All expressions successfully initialized. Let's set them for the
502  // client classes in the dictionary.
503  for (auto c : *list_) {
504  if (!c->getTest().empty()) {
505  c->setMatchExpr(expressions.front());
506  expressions.pop();
507  }
508  }
509 }
510 
511 void
513  for (auto c : *list_) {
514  // If the class has no options, skip it.
515  CfgOptionPtr class_options = c->getCfgOption();
516  if (!class_options || class_options->empty()) {
517  continue;
518  }
519 
520  // If the class has no option definitions, use the set
521  // of definitions we were given as is to create its
522  // options.
523  if (!c->getCfgOptionDef()) {
524  class_options->createOptions(external_defs);
525  } else {
526  // Class has its own option definitions, we need a
527  // composite set of definitions to recreate its options.
528  // We make copies of both sets of definitions, then merge
529  // the external defs copy into the class defs copy.
530  // We do this because merging actually effects both sets
531  // of definitions and we cannot alter either set.
532  // Seed the composite set with the class's definitions.
533  CfgOptionDefPtr composite_defs(new CfgOptionDef());
534  c->getCfgOptionDef()->copyTo(*composite_defs);
535 
536  // Make a copy of the external definitions and
537  // merge those into the composite set. This should give
538  // us a set of options with class definitions taking
539  // precedence.
540  CfgOptionDefPtr external_defs_copy(new CfgOptionDef());
541  external_defs->copyTo(*external_defs_copy);
542  composite_defs->merge(*external_defs_copy);
543 
544  // Now create the class options using the composite
545  // set of definitions.
546  class_options->createOptions(composite_defs);
547  }
548  }
549 }
550 
553  ElementPtr result = Element::createList();
554  // Iterate on the map
555  for (ClientClassDefList::const_iterator this_class = list_->begin();
556  this_class != list_->cend(); ++this_class) {
557  result->add((*this_class)->toElement());
558  }
559  return (result);
560 }
561 
564  if (this != &rhs) {
565  list_->clear();
566  map_->clear();
567  for (auto cclass : *(rhs.list_)) {
568  ClientClassDefPtr copy(new ClientClassDef(*cclass));
569  addClass(copy);
570  }
571  }
572  return (*this);
573 }
574 
576 std::list<std::string>
578  // DROP is not in this list because it is special but not built-in.
579  // In fact DROP is set from an expression as callouts can drop
580  // directly the incoming packet. The expression must not depend on
581  // KNOWN/UNKNOWN which are set far after the drop point.
582  // SKIP_DDNS, used by DDNS-tuning is also omitted from this list
583  // so users may assign it a test expression.
584  "ALL", "KNOWN", "UNKNOWN", "BOOTP"
585 };
586 
593 std::list<std::string>
595  "VENDOR_CLASS_", "HA_", "AFTER_", "EXTERNAL_"
596 };
597 
598 bool
599 isClientClassBuiltIn(const ClientClass& client_class) {
600  for (std::list<std::string>::const_iterator bn = builtinNames.cbegin();
601  bn != builtinNames.cend(); ++bn) {
602  if (client_class == *bn) {
603  return true;
604  }
605  }
606 
607  for (std::list<std::string>::const_iterator bt = builtinPrefixes.cbegin();
608  bt != builtinPrefixes.cend(); ++bt) {
609  if (client_class.size() <= bt->size()) {
610  continue;
611  }
612  auto mis = std::mismatch(bt->cbegin(), bt->cend(), client_class.cbegin());
613  if (mis.first == bt->cend()) {
614  return true;
615  }
616  }
617 
618  return false;
619 }
620 
621 bool
623  bool& depend_on_known,
624  const ClientClass& client_class) {
625  // First check built-in classes
626  if (isClientClassBuiltIn(client_class)) {
627  // Check direct dependency on [UN]KNOWN
628  if ((client_class == "KNOWN") || (client_class == "UNKNOWN")) {
629  depend_on_known = true;
630  }
631  return (true);
632  }
633 
634  // Second check already defined, i.e. in the dictionary
635  ClientClassDefPtr def = class_dictionary->findClass(client_class);
636  if (def) {
637  // Check indirect dependency on [UN]KNOWN
638  if (def->getDependOnKnown()) {
639  depend_on_known = true;
640  }
641  return (true);
642  }
643 
644  // Not defined...
645  return (false);
646 }
647 
648 } // namespace isc::dhcp
649 } // 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:246
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition: data.cc:301
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
Definition: data.cc:296
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:351
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
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
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:693
#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:1395
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:29
boost::shared_ptr< Element > ElementPtr
Definition: data.h:26
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:859
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:780
const isc::log::MessageID EVAL_RESULT
Definition: eval_messages.h:55
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:28
std::list< std::string > builtinPrefixes
The prefixes used to check if a class is BuiltIn class.
std::ostream & operator<<(std::ostream &os, const OpaqueDataTuple &tuple)
Inserts the OpaqueDataTuple as a string into stream.
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