}
void Dhcpv4Srv::classifyPacket(const Pkt4Ptr& pkt) {
+ // All packets belongs to ALL.
+ pkt->addClass("ALL");
+
// First phase: built-in vendor class processing
classifyByVendor(pkt);
}
void Dhcpv6Srv::classifyPacket(const Pkt6Ptr& pkt) {
- string classes = "";
+ // All packets belongs to ALL
+ pkt->addClass("ALL");
+ string classes = "ALL ";
// First phase: built-in vendor class processing
classifyByVendor(pkt, classes);
return (result);
}
+std::list<std::string>
+builtinNames = {
+ "ALL", "KNOWN"
+};
+
std::list<std::string>
builtinPrefixes = {
"VENDOR_CLASS_", "AFTER_", "EXTERNAL_"
bool
isClientClassBuiltIn(const ClientClass& client_class) {
+ for (std::list<std::string>::const_iterator bn = builtinNames.cbegin();
+ bn != builtinNames.cend(); ++bn) {
+ if (client_class == *bn) {
+ return true;
+ }
+ }
+
for (std::list<std::string>::const_iterator bt = builtinPrefixes.cbegin();
bt != builtinPrefixes.cend(); ++bt) {
if (client_class.size() <= bt->size()) {
}
bool
-isClientClassKnown(ClientClassDictionaryPtr& class_dictionary,
- const ClientClass& client_class) {
- // First check built-in prefixes
+isClientClassDefined(ClientClassDictionaryPtr& class_dictionary,
+ const ClientClass& client_class) {
+ // First check built-in classes
if (isClientClassBuiltIn(client_class)) {
return (true);
}
return (true);
}
- // Unknown...
+ // Not defined...
return (false);
}
/// @brief Defines a pointer to a ClientClassDictionary
typedef boost::shared_ptr<ClientClassDictionary> ClientClassDictionaryPtr;
+/// @brief List of built-in client class names.
+/// i.e. ALL and KNOWN.
+extern std::list<std::string> builtinNames;
+
/// @brief List of built-in client class prefixes
/// i.e. VENDOR_CLASS_, AFTER_ and EXTERNAL_.
extern std::list<std::string> builtinPrefixes;
bool isClientClassBuiltIn(const ClientClass& client_class);
-/// @brief Check if a client class name is already known,
-/// i.e. beginning by a built-in prefix or in the dictionary,
+/// @brief Check if a client class name is already defined,
+/// i.e. is built-in or in the dictionary,
///
/// @param class_dictionary A class dictionary where to look for.
/// @param client_class A client class name to look for.
-/// @return true if known or built-in, false if not.
-bool isClientClassKnown(ClientClassDictionaryPtr& class_dictionary,
- const ClientClass& client_class);
+/// @return true if defined or built-in, false if not.
+bool isClientClassDefined(ClientClassDictionaryPtr& class_dictionary,
+ const ClientClass& client_class);
} // namespace isc::dhcp
} // namespace isc
ExpressionParser::parse(ExpressionPtr& expression,
ConstElementPtr expression_cfg,
uint16_t family,
- std::function<bool(const ClientClass&)> check_known) {
+ EvalContext::CheckDefined check_defined) {
if (expression_cfg->getType() != Element::string) {
isc_throw(DhcpConfigError, "expression ["
<< expression_cfg->str() << "] must be a string, at ("
expression_cfg->getValue(value);
try {
EvalContext eval_ctx(family == AF_INET ? Option::V4 : Option::V6,
- check_known);
+ check_defined);
eval_ctx.parseString(value);
expression.reset(new Expression());
*expression = eval_ctx.expression;
if (test_cfg) {
ExpressionParser parser;
using std::placeholders::_1;
- auto check_known = std::bind(isClientClassKnown, class_dictionary, _1);
- parser.parse(match_expr, test_cfg, family, check_known);
+ auto check_defined =
+ std::bind(isClientClassDefined, class_dictionary, _1);
+ parser.parse(match_expr, test_cfg, family, check_defined);
test = test_cfg->stringValue();
}
-// Copyright (C) 2015, 2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
/// @param expression variable in which to store the new expression
/// @param expression_cfg the configuration entry to be parsed.
/// @param family the address family of the expression.
- /// @param check_known a closure to check if a client class is known.
+ /// @param check_defined a closure to check if a client class is defined.
///
/// @throw DhcpConfigError if parsing was unsuccessful.
void parse(ExpressionPtr& expression,
isc::data::ConstElementPtr expression_cfg,
uint16_t family,
- std::function<bool(const ClientClass&)> check_known =
+ isc::eval::EvalContext::CheckDefined check_defined =
isc::eval::EvalContext::acceptAll);
};
Parameters to the @ref isc::eval::EvalContext class constructor are
the universe to choose between DHCPv4 and DHCPv6 for DHCP version
dependent expressions, and a function used
- by the parser to accept only already known or built-in client
+ by the parser to accept only already defined or built-in client
class names in client class membership expressions. This function defaults
to accept all client class names.
-// Copyright (C) 2015-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
#include <limits>
EvalContext::EvalContext(const Option::Universe& option_universe,
- std::function<bool(const ClientClass&)> check_known)
+ CheckDefined check_defined)
: trace_scanning_(false), trace_parsing_(false),
- option_universe_(option_universe), check_known_(check_known)
+ option_universe_(option_universe), check_defined_(check_defined)
{
}
}
bool
-EvalContext::isClientClassKnown(const ClientClass& client_class) {
- return (check_known_(client_class));
+EvalContext::isClientClassDefined(const ClientClass& client_class) {
+ return (check_defined_(client_class));
}
void
PARSER_STRING ///< expression is expected to evaluate to string
} ParserType;
- /// @brief Type of the check known function.
- typedef std::function<bool(const ClientClass&)> CheckKnown;
+ /// @brief Type of the check defined function.
+ typedef std::function<bool(const ClientClass&)> CheckDefined;
/// @brief Default constructor.
///
/// @param option_universe Option universe: DHCPv4 or DHCPv6. This is used
/// by the parser to determine which option definitions set should be used
/// to map option names to option codes.
- /// @param check_known A function called to check if a client class
- /// used for membership is already known. If it is not the parser
+ /// @param check_defined A function called to check if a client class
+ /// used for membership is already defined. If it is not the parser
/// will fail: only backward or built-in references are accepted.
EvalContext(const Option::Universe& option_universe,
- CheckKnown check_known = acceptAll);
+ CheckDefined check_defined = acceptAll);
/// @brief destructor
virtual ~EvalContext();
return (option_universe_);
}
- /// @brief Check if a client class is already known
+ /// @brief Check if a client class is already defined
///
/// @param client_class the client class name to check
- /// @return true if the client class is known, false if not
- bool isClientClassKnown(const ClientClass& client_class);
+ /// @return true if the client class is defined, false if not
+ bool isClientClassDefined(const ClientClass& client_class);
private:
/// @brief Flag determining scanner debugging.
/// set should be used to map option name to option code.
Option::Universe option_universe_;
- /// @brief Function to check if a client class is already known
- CheckKnown check_known_;
+ /// @brief Function to check if a client class is already defined.
+ CheckDefined check_defined_;
};
//
// This token will check if the packet is a member of
// the specified client class.
- // To avoid loops at evaluation only already known and
+ // To avoid loops at evaluation only already defined and
// built-in classes are allowed.
std::string cc = yystack_[1].value.as< std::string > ();
- if (!ctx.isClientClassKnown(cc)) {
- error(yystack_[1].location, "Unknown client class '" + cc + "'");
+ if (!ctx.isClientClassDefined(cc)) {
+ error(yystack_[1].location, "Not defined client class '" + cc + "'");
}
TokenPtr member(new TokenMember(cc));
ctx.expression.push_back(member);
-/* Copyright (C) 2015-2017 Internet Systems Consortium, Inc. ("ISC")
+/* Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC")
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
//
// This token will check if the packet is a member of
// the specified client class.
- // To avoid loops at evaluation only already known and
+ // To avoid loops at evaluation only already defined and
// built-in classes are allowed.
std::string cc = $3;
- if (!ctx.isClientClassKnown(cc)) {
- error(@3, "Unknown client class '" + cc + "'");
+ if (!ctx.isClientClassDefined(cc)) {
+ error(@3, "Not defined client class '" + cc + "'");
}
TokenPtr member(new TokenMember(cc));
ctx.expression.push_back(member);
-// Copyright (C) 2015-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
/// expected.
///
/// @param expr expression to be parsed
- /// @param check_known closure checking if the client class is known
+ /// @param check_defined closure checking if the client class is defined
/// @param exp_client_class expected client class name to be parsed
/// @param exp_tokens expected number of tokens
void testMember(const std::string& expr,
- std::function<bool(const ClientClass&)> check_known,
+ EvalContext::CheckDefined check_defined,
const std::string& exp_client_class,
int exp_tokens) {
- EvalContext eval(Option::V6, check_known);
+ EvalContext eval(Option::V6, check_defined);
// parse the expression
try {
"<string>:1.8: Nest level invalid for DHCPv4 packets");
}
-// Tests parsing of member with known class
+// Tests parsing of member with defined class
TEST_F(EvalContextTest, member) {
- auto check_known = [](const ClientClass& cc) { return (cc == "foo"); };
- testMember("member('foo')", check_known, "foo", 1);
+ auto check_defined = [](const ClientClass& cc) { return (cc == "foo"); };
+ testMember("member('foo')", check_defined, "foo", 1);
}
-// Test parsing of member with unknown class
+// Test parsing of member with not defined class
TEST_F(EvalContextTest, memberError) {
- auto check_known = [](const ClientClass& cc) { return (cc == "foo"); };
- EvalContext eval(Option::V6, check_known);
+ auto check_defined = [](const ClientClass& cc) { return (cc == "foo"); };
+ EvalContext eval(Option::V6, check_defined);
parsed_ = false;
try {
parsed_ = eval.parseString("member('bar')");
FAIL() << "Expected EvalParseError but nothing was raised";
}
catch (const EvalParseError& ex) {
- EXPECT_EQ("<string>:1.8-12: Unknown client class 'bar'",
+ EXPECT_EQ("<string>:1.8-12: Not defined client class 'bar'",
std::string(ex.what()));
EXPECT_FALSE(parsed_);
}