19 #include <boost/foreach.hpp> 44 << expression_cfg->str() <<
"] must be a string, at (" 45 << expression_cfg->getPosition() <<
")");
51 expression_cfg->getValue(value);
53 EvalContext eval_ctx(family == AF_INET ? Option::V4 : Option::V6,
58 }
catch (
const std::exception& ex) {
61 "expression: [" << value
62 <<
"] error: " << ex.
what() <<
" at (" 63 << expression_cfg->getPosition() <<
")");
73 bool append_error_position,
74 bool check_dependencies) {
76 std::string name = getString(class_def_cfg,
"name");
79 "not empty parameter 'name' is required " 80 << getPosition(
"name", class_def_cfg) <<
")");
87 bool depend_on_known =
false;
91 [&class_dictionary, &depend_on_known, check_dependencies]
97 parser.
parse(match_expr, test_cfg, family, check_defined);
98 test = test_cfg->stringValue();
108 SimpleParser4::OPTION4_DEF_DEFAULTS :
109 SimpleParser6::OPTION6_DEF_DEFAULTS);
117 if (!LibDHCP::shouldDeferOptionUnpack(def->getOptionSpaceName(),
120 "Not allowed option definition for code '" 121 << def->getCode() <<
"' in space '" 122 << def->getOptionSpaceName() <<
"' at (" 123 << option_def->getPosition() <<
")");
127 }
catch (
const std::exception& ex) {
130 << option_def->getPosition() <<
")");
139 auto opts_parser = createOptionDataListParser(family, defs);
140 opts_parser->parse(options, option_data);
148 << user_context->getPosition() <<
")");
153 bool required =
false;
154 if (class_def_cfg->contains(
"only-if-required")) {
155 required = getBoolean(class_def_cfg,
"only-if-required");
160 if (class_def_cfg->contains(
"next-server")) {
161 std::string next_server_txt = getString(class_def_cfg,
"next-server");
163 next_server =
IOAddress(next_server_txt);
166 "Invalid next-server value specified: '" 167 << next_server_txt <<
"' (" 168 << getPosition(
"next-server", class_def_cfg) <<
")");
171 if (next_server.
getFamily() != AF_INET) {
173 << next_server_txt <<
"', must be IPv4 address (" 174 << getPosition(
"next-server", class_def_cfg) <<
")");
179 << next_server_txt <<
"', must not be a broadcast (" 180 << getPosition(
"next-server", class_def_cfg) <<
")");
186 if (class_def_cfg->contains(
"server-hostname")) {
187 sname = getString(class_def_cfg,
"server-hostname");
189 if (sname.length() >= Pkt4::MAX_SNAME_LEN) {
191 << Pkt4::MAX_SNAME_LEN - 1 <<
" bytes long, it is " 192 << sname.length() <<
" (" 193 << getPosition(
"server-hostname", class_def_cfg) <<
")");
198 std::string filename;
199 if (class_def_cfg->contains(
"boot-file-name")) {
200 filename = getString(class_def_cfg,
"boot-file-name");
202 if (filename.length() > Pkt4::MAX_FILE_LEN) {
204 << Pkt4::MAX_FILE_LEN - 1 <<
" bytes long, it is " 205 << filename.length() <<
" (" 206 << getPosition(
"boot-file-name", class_def_cfg) <<
")");
215 if (family != AF_INET) {
217 preferred_lft = parseIntTriplet(class_def_cfg,
"preferred-lifetime");
225 <<
"' only-if-required flag must be false");
229 <<
"' test expression must be empty");
235 if (name ==
"DROP") {
238 <<
"' only-if-required flag must be false");
245 class_dictionary->addClass(name, match_expr, test, required,
246 depend_on_known, options, defs,
247 user_context, next_server, sname, filename,
248 valid_lft, preferred_lft);
249 }
catch (
const std::exception& ex) {
250 std::ostringstream s;
251 s <<
"Can't add class: " << ex.what();
253 if (append_error_position) {
254 s <<
" (" << class_def_cfg->getPosition() <<
")";
262 const uint16_t family) {
264 if (!class_def_cfg || (class_def_cfg->getType() !=
Element::map)) {
269 static std::set<std::string> supported_params = {
"name",
275 "min-valid-lifetime",
276 "max-valid-lifetime" };
280 static std::set<std::string> supported_params_v4 = {
"option-def",
286 static std::set<std::string> supported_params_v6 = {
"preferred-lifetime",
287 "min-preferred-lifetime",
288 "max-preferred-lifetime" };
291 for (
auto name_value_pair : class_def_cfg->mapValue()) {
292 if ((supported_params.count(name_value_pair.first) > 0) ||
293 ((family == AF_INET) && (supported_params_v4.count(name_value_pair.first) > 0)) ||
294 ((family != AF_INET) && (supported_params_v6.count(name_value_pair.first) > 0))) {
298 << name_value_pair.first <<
"'");
303 boost::shared_ptr<OptionDataListParser>
304 ClientClassDefParser::createOptionDataListParser(
const uint16_t address_family,
306 auto parser = boost::make_shared<OptionDataListParser>(address_family, cfg_option_def);
314 uint16_t family,
bool check_dependencies) {
317 client_class_def_list->listValue()) {
319 parser.
parse(dictionary, client_class_def, family,
true, check_dependencies);
Parser for a single client class definition.
boost::shared_ptr< CfgOption > CfgOptionPtr
Non-const pointer.
isc::dhcp::Expression expression
Parsed expression (output tokens are stored here)
boost::shared_ptr< CfgOptionDef > CfgOptionDefPtr
Non-const pointer.
OptionDefinitionPtr parse(isc::data::ConstElementPtr option_def)
Parses an entry that describes single option definition.
void parse(ExpressionPtr &expression, isc::data::ConstElementPtr expression_cfg, uint16_t family, isc::eval::EvalContext::CheckDefined check_defined=isc::eval::EvalContext::acceptAll)
Parses an expression configuration element into an Expression.
Maintains a list of ClientClassDef's.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
bool isClientClassDefined(ClientClassDictionaryPtr &class_dictionary, bool &depend_on_known, const ClientClass &client_class)
Check if a client class name is already defined, i.e.
Parser for a logical expression.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Represents option data configuration for the DHCP server.
Parsers for client class definitions.
To be removed. Please use ConfigError instead.
bool isV4Bcast() const
Convenience function to check if it is an IPv4 broadcast address.
Parser for a single option definition.
boost::shared_ptr< ClientClassDictionary > ClientClassDictionaryPtr
Defines a pointer to a ClientClassDictionary.
Evaluation context, an interface to the expression evaluation.
boost::shared_ptr< const Element > ConstElementPtr
Represents option definitions used by the DHCP server.
std::list< std::string > builtinNames
List of classes for which test expressions cannot be defined.
static size_t setListDefaults(isc::data::ConstElementPtr list, const SimpleDefaults &default_values)
Sets the default values for all entries in a list.
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.
void parse(ClientClassDictionaryPtr &class_dictionary, isc::data::ConstElementPtr client_class_def, uint16_t family, bool append_error_position=true, bool check_dependencies=true)
Parses an entry that describes single client class definition.
An exception that is thrown if an error occurs within the IO module.
boost::shared_ptr< OptionDefinition > OptionDefinitionPtr
Pointer to option definition object.
std::string ClientClass
Defines a single class name.
The IOAddress class represents an IP addresses (version agnostic)
std::function< bool(const ClientClass &)> CheckDefined
Type of the check defined function.
Defines classes for storing client class definitions.
boost::shared_ptr< Expression > ExpressionPtr
bool parseString(const std::string &str, ParserType type=PARSER_BOOL)
Run the parser on the string specified.
short getFamily() const
Returns the address family.