16 #include <boost/foreach.hpp> 27 ClientClassDef::ClientClassDef(
const std::string& name,
31 match_expr_(match_expr), required_(false), depend_on_known_(false),
33 valid_(), preferred_() {
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_) {
55 if (rhs.match_expr_) {
57 *match_expr_ = *(rhs.match_expr_);
60 if (rhs.cfg_option_def_) {
62 rhs.cfg_option_def_->copyTo(*cfg_option_def_);
65 if (rhs.cfg_option_) {
66 rhs.cfg_option_->copyTo(*cfg_option_);
90 match_expr_ = match_expr;
110 required_ = required;
115 return (depend_on_known_);
120 depend_on_known_ = depend_on_known;
125 return (cfg_option_def_);
130 cfg_option_def_ = cfg_option_def;
135 return (cfg_option_);
140 cfg_option_ = cfg_option;
167 .arg(
"get exception?");
185 if (!subclass.empty()) {
190 std::string value(TemplateClientClassDef::SPAWN_CLASS_PREFIX);
194 pkt->addSubClass(
getName(), value);
203 .arg(
"get exception?");
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_));
240 if (!test_.empty()) {
248 if (cfg_option_def_ && (family == AF_INET)) {
249 result->set(
"option-def", cfg_option_def_->toElement());
252 result->set(
"option-data", cfg_option_->toElement());
254 if (family == AF_INET) {
265 if (!preferred_.unspecified()) {
266 result->set(
"preferred-lifetime",
270 if (preferred_.getMin() < preferred_.get()) {
271 result->set(
"min-preferred-lifetime",
275 if (preferred_.getMax() > preferred_.get()) {
276 result->set(
"max-preferred-lifetime",
282 if (!valid_.unspecified()) {
283 result->set(
"valid-lifetime",
286 if (valid_.getMin() < valid_.get()) {
287 result->set(
"min-valid-lifetime",
291 if (valid_.getMax() > valid_.get()) {
292 result->set(
"max-valid-lifetime",
303 auto const&
test = result->get(
"test");
305 result->set(
"template-test",
test);
306 result->remove(
"test");
314 os <<
"ClientClassDef:" << x.
getName();
338 const std::string& test,
340 bool depend_on_known,
345 const std::string& sname,
346 const std::string& filename,
356 cclass->setTest(test);
357 cclass->setRequired(required);
358 cclass->setDependOnKnown(depend_on_known);
359 cclass->setCfgOptionDef(cfg_option_def);
360 cclass->setContext(user_context),
361 cclass->setNextServer(next_server);
362 cclass->setSname(sname);
363 cclass->setFilename(filename);
364 cclass->setValid(valid);
365 cclass->setPreferred(preferred);
373 " - class definition cannot be null");
378 << class_def->getName() <<
" has already been defined");
381 list_->push_back(class_def);
382 (*map_)[class_def->getName()] = class_def;
387 ClientClassDefMap::iterator it = map_->find(name);
388 if (it != map_->end()) {
397 for (ClientClassDefList::iterator this_class = list_->begin();
398 this_class != list_->end(); ++this_class) {
399 if ((*this_class)->getName() == name) {
400 list_->erase(this_class);
413 for (ClientClassDefList::iterator this_class = list_->begin();
414 this_class != list_->end(); ++this_class) {
415 if ((*this_class)->getId() == id) {
416 map_->erase((*this_class)->getName());
417 list_->erase(this_class);
430 return (list_->empty());
435 std::string& dependent_class)
const {
438 for (ClientClassDefList::iterator this_class = list_->begin();
439 this_class != list_->end(); ++this_class) {
441 if ((*this_class)->dependOnClass(name)) {
442 dependent_class = (*this_class)->getName();
446 if ((*this_class)->getName() == name) {
456 if (list_->size() != other.list_->size()) {
460 ClientClassDefList::const_iterator this_class = list_->cbegin();
461 ClientClassDefList::const_iterator other_class = other.list_->cbegin();
462 while (this_class != list_->cend() &&
463 other_class != other.list_->cend()) {
464 if (!*this_class || !*other_class ||
465 **this_class != **other_class) {
478 std::queue<ExpressionPtr> expressions;
479 for (
auto c : *list_) {
480 if (!c->getTest().empty()) {
484 if (dynamic_cast<TemplateClientClassDef*>(c.get())) {
485 parser_type = EvalContext::PARSER_STRING;
488 EvalContext::acceptAll, parser_type);
489 expressions.push(match_expr);
494 for (
auto c : *list_) {
495 if (!c->getTest().empty()) {
496 c->setMatchExpr(expressions.front());
504 for (
auto c : *list_) {
507 if (!class_options || class_options->empty()) {
514 if (!c->getCfgOptionDef()) {
515 class_options->createOptions(external_defs);
525 c->getCfgOptionDef()->copyTo(*composite_defs);
532 external_defs->copyTo(*external_defs_copy);
533 composite_defs->merge(*external_defs_copy);
537 class_options->createOptions(composite_defs);
546 for (ClientClassDefList::const_iterator this_class = list_->begin();
547 this_class != list_->cend(); ++this_class) {
548 result->add((*this_class)->toElement());
558 for (
auto cclass : *(rhs.list_)) {
567 std::list<std::string>
575 "ALL",
"KNOWN",
"UNKNOWN",
"BOOTP" 584 std::list<std::string>
586 "VENDOR_CLASS_",
"HA_",
"AFTER_",
"EXTERNAL_" 591 for (std::list<std::string>::const_iterator bn =
builtinNames.cbegin();
593 if (client_class == *bn) {
598 for (std::list<std::string>::const_iterator bt =
builtinPrefixes.cbegin();
600 if (client_class.size() <= bt->size()) {
603 auto mis = std::mismatch(bt->cbegin(), bt->cend(), client_class.cbegin());
604 if (mis.first == bt->cend()) {
614 bool& depend_on_known,
619 if ((client_class ==
"KNOWN") || (client_class ==
"UNKNOWN")) {
620 depend_on_known =
true;
629 if (def->getDependOnKnown()) {
630 depend_on_known =
true;
void setMatchExpr(const ExpressionPtr &match_expr)
Sets the class's match expression.
~ClientClassDictionary()
Destructor.
bool dependOnClass(const std::string &name, std::string &dependent_class) const
Checks direct dependency.
This class represents configuration element which is associated with database identifier, modification timestamp and servers.
virtual isc::data::ElementPtr toElement() const
Unparse a configuration object.
boost::shared_ptr< CfgOption > CfgOptionPtr
Non-const pointer.
const CfgOptionDefPtr & getCfgOptionDef() const
Fetches the class's option definitions.
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.
void setDependOnKnown(bool depend_on_known)
Sets the depend on known flag aka use host flag.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
std::string evaluateString(const Expression &expr, Pkt &pkt)
bool dependOnClass(const std::string &name) const
Checks direct dependency.
ClientClassDefPtr findClass(const std::string &name) const
Fetches the class definition for a given class name.
Base class for user context.
void setRequired(bool required)
Sets the only if required flag.
static CfgMgr & instance()
returns a single instance of Configuration Manager
const ClientClassDefListPtr & getClasses() const
Fetches the dictionary's list of classes.
std::unordered_map< std::string, ClientClassDefPtr > ClientClassDefMap
Defines a map of ClientClassDef's, keyed by the class name.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
boost::shared_ptr< Element > ElementPtr
std::string getName() const
Fetches the class's name.
boost::shared_ptr< CfgOptionDef > CfgOptionDefPtr
Non-const pointer.
void setTest(const std::string &test)
Sets the class's original match expression.
bool equals(const ClientClassDef &other) const
Compares two ClientClassDef objects for equality.
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Maintains a list of ClientClassDef's.
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
ClientClassDictionary()
Constructor.
bool isClientClassDefined(ClientClassDictionaryPtr &class_dictionary, bool &depend_on_known, const ClientClass &client_class)
Check if a client class name is already defined, i.e.
ClientClassDictionary & operator=(const ClientClassDictionary &rhs)
Copy assignment operator.
const CfgOptionPtr & getCfgOption() const
Fetches the class's option collection.
Parser for a logical expression.
TemplateClientClassDef(const std::string &name, const ExpressionPtr &match_expr, const CfgOptionPtr &options=CfgOptionPtr())
Constructor.
bool empty() const
Checks if the class dictionary is empty.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
Represents option data configuration for the DHCP server.
Parsers for client class definitions.
ElementPtr copy(ConstElementPtr from, int level)
Copy the data up to a nesting level.
const int DHCPSRV_DBG_TRACE_DETAIL
Additional information.
Error that occurs when an attempt is made to add a duplicate class to a class dictionary.
Abstract class for configuration Cfg_* classes.
uint16_t getFamily() const
Returns address family.
boost::shared_ptr< ClientClassDictionary > ClientClassDictionaryPtr
Defines a pointer to a ClientClassDictionary.
Embodies a single client class definition.
boost::shared_ptr< const Element > ConstElementPtr
std::string getTest() const
Fetches the class's original match expression.
bool dependOnClass(const TokenPtr &token, const std::string &name)
Checks dependency on a token.
Represents option definitions used by the DHCP server.
void contextToElement(data::ElementPtr map) const
Merge unparse a user_context object.
void createOptions(const CfgOptionDefPtr &cfg_option_def)
Iterates over the classes in the dictionary and recreates the options.
std::list< std::string > builtinNames
List of classes for which test expressions cannot be defined.
std::list< std::string > builtinPrefixes
The prefixes used to check if a class is BuiltIn class.
boost::shared_ptr< isc::dhcp::Pkt > PktPtr
A pointer to either Pkt4 or Pkt6 packet.
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)
Adds a new class to the list.
boost::shared_ptr< ClientClassDef > ClientClassDefPtr
a pointer to an ClientClassDef
virtual isc::data::ElementPtr toElement() const
Unparse a configuration object.
bool evaluateBool(const Expression &expr, Pkt &pkt)
Evaluate a RPN expression for a v4 or v6 packet and return a true or false decision.
std::vector< ClientClassDefPtr > ClientClassDefList
Defines a list of ClientClassDefPtr's, using insert order.
This is a base class for exceptions thrown from the DNS library module.
Defines the logger used by the top-level component of kea-lfc.
std::vector< TokenPtr > Expression
This is a structure that holds an expression converted to RPN.
virtual ~ClientClassDef()
Destructor.
static const std::string SPAWN_CLASS_PREFIX
This is a prefix added to the spawned class name.
boost::shared_ptr< ClientClassDefList > ClientClassDefListPtr
Defines a pointer to a ClientClassDefList.
static ElementPtr create(const Position &pos=ZERO_POSITION())
A wrapper interface for the ASIO library.
void removeClass(const std::string &name)
Removes a given class definition from the dictionary.
virtual void test(PktPtr pkt, const ExpressionPtr &expr_ptr)
Test method which checks if the packet belongs to the class.
const ExpressionPtr & getMatchExpr() const
Fetches the class's match expression.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
ParserType
Specifies what type of expression the parser is expected to see.
bool getRequired() const
Fetches the only if required flag.
void setName(const std::string &name)
Sets the class's name.
void setCfgOption(const CfgOptionPtr &cfg_option)
Sets the class's option collection.
ClientClassDef(const std::string &name, const ExpressionPtr &match_expr, const CfgOptionPtr &options=CfgOptionPtr())
Constructor.
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
bool isClientClassBuiltIn(const ClientClass &client_class)
Check if a client class name is builtin.
void initMatchExpr(uint16_t family)
Iterates over the classes in the dictionary and ensures that that match expressions are initialized...
std::string ClientClass
Defines a single class name.
The IOAddress class represents an IP addresses (version agnostic)
const isc::log::MessageID EVAL_RESULT
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.
friend std::ostream & operator<<(std::ostream &os, const ClientClassDef &x)
Provides a convenient text representation of the class.
Defines classes for storing client class definitions.
bool getDependOnKnown() const
Fetches the depend on known flag aka use host flag.
boost::shared_ptr< Expression > ExpressionPtr
bool equals(const ClientClassDictionary &other) const
Compares two ClientClassDictionary objects for equality.
void setCfgOptionDef(const CfgOptionDefPtr &cfg_option_def)
Sets the class's option definition collection.