Commit 6418fa8a authored by Francis Dupont's avatar Francis Dupont
Browse files

[5374] Checkpoint for regen before tests

parent c78317c0
......@@ -2970,6 +2970,9 @@ void Dhcpv4Srv::classifyByVendor(const Pkt4Ptr& pkt) {
}
void Dhcpv4Srv::classifyPacket(const Pkt4Ptr& pkt) {
// All packets belongs to ALL.
pkt->addClass("ALL");
// First phase: built-in vendor class processing
classifyByVendor(pkt);
......
......@@ -3084,7 +3084,9 @@ void Dhcpv6Srv::classifyByVendor(const Pkt6Ptr& pkt, std::string& classes) {
}
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);
......
......@@ -292,6 +292,11 @@ ClientClassDictionary::toElement() const {
return (result);
}
std::list<std::string>
builtinNames = {
"ALL", "KNOWN"
};
std::list<std::string>
builtinPrefixes = {
"VENDOR_CLASS_", "AFTER_", "EXTERNAL_"
......@@ -299,6 +304,13 @@ builtinPrefixes = {
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()) {
......@@ -314,9 +326,9 @@ isClientClassBuiltIn(const ClientClass& client_class) {
}
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);
}
......@@ -327,7 +339,7 @@ isClientClassKnown(ClientClassDictionaryPtr& class_dictionary,
return (true);
}
// Unknown...
// Not defined...
return (false);
}
......
......@@ -340,6 +340,10 @@ private:
/// @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;
......@@ -351,14 +355,14 @@ 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
......
......@@ -37,7 +37,7 @@ void
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 ("
......@@ -50,7 +50,7 @@ ExpressionParser::parse(ExpressionPtr& expression,
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;
......@@ -84,8 +84,9 @@ ClientClassDefParser::parse(ClientClassDictionaryPtr& class_dictionary,
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
......@@ -67,13 +67,13 @@ public:
/// @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);
};
......
......@@ -24,7 +24,7 @@
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
......@@ -17,9 +17,9 @@
#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)
{
}
......@@ -190,8 +190,8 @@ EvalContext::fromUint32(const uint32_t integer) {
}
bool
EvalContext::isClientClassKnown(const ClientClass& client_class) {
return (check_known_(client_class));
EvalContext::isClientClassDefined(const ClientClass& client_class) {
return (check_defined_(client_class));
}
void
......
......@@ -41,19 +41,19 @@ public:
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();
......@@ -181,11 +181,11 @@ public:
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.
......@@ -200,8 +200,8 @@ public:
/// 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_;
};
......
......@@ -873,11 +873,11 @@ namespace isc { namespace eval {
//
// 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
......@@ -219,11 +219,11 @@ bool_expr : "(" bool_expr ")"
//
// 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
......@@ -409,14 +409,14 @@ public:
/// 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 {
......@@ -1119,23 +1119,23 @@ TEST_F(EvalContextTest, relay6FieldError) {
"<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_);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment