mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-29 04:57:52 +00:00
[#3588] Modified no test required classes
This commit is contained in:
parent
8263915af3
commit
dc8af16a6e
6
changelog_unreleased/3588-required-no-test
Normal file
6
changelog_unreleased/3588-required-no-test
Normal file
@ -0,0 +1,6 @@
|
||||
[func]* fdupont
|
||||
Modified the behavior of required client classes
|
||||
configured without a test expression: they are now
|
||||
unconditionally added as they always evaluate to
|
||||
true (vs false previously).
|
||||
(Gitlab #3388)
|
@ -3423,6 +3423,10 @@ The order in which required classes are considered is: pool, subnet,
|
||||
and shared network, i.e. in the same order from the way in which
|
||||
``option-data`` is processed.
|
||||
|
||||
Since Kea version 2.7.4 required client classes configured without
|
||||
a test expression are unconditionally added, i.e. they are considered
|
||||
to always be evaluated to ``true``.
|
||||
|
||||
.. note::
|
||||
|
||||
Vendor-Identifying Vendor Options are a special case: for all other
|
||||
|
@ -3201,6 +3201,10 @@ levels. The order in which required classes are considered is:
|
||||
(pd-)pool, subnet, and shared network, i.e. in the same order from the
|
||||
way in which ``option-data`` is processed.
|
||||
|
||||
Since Kea version 2.7.4 required client classes configured without
|
||||
a test expression are unconditionally added, i.e. they are considered
|
||||
to always be evaluated to ``true``.
|
||||
|
||||
.. _dhcp6-ddns-config:
|
||||
|
||||
DDNS for DHCPv6
|
||||
|
@ -19,8 +19,6 @@ extern const isc::log::MessageID DHCP4_CLASSES_ASSIGNED = "DHCP4_CLASSES_ASSIGNE
|
||||
extern const isc::log::MessageID DHCP4_CLASSES_ASSIGNED_AFTER_SUBNET_SELECTION = "DHCP4_CLASSES_ASSIGNED_AFTER_SUBNET_SELECTION";
|
||||
extern const isc::log::MessageID DHCP4_CLASS_ASSIGNED = "DHCP4_CLASS_ASSIGNED";
|
||||
extern const isc::log::MessageID DHCP4_CLASS_UNCONFIGURED = "DHCP4_CLASS_UNCONFIGURED";
|
||||
extern const isc::log::MessageID DHCP4_CLASS_UNDEFINED = "DHCP4_CLASS_UNDEFINED";
|
||||
extern const isc::log::MessageID DHCP4_CLASS_UNTESTABLE = "DHCP4_CLASS_UNTESTABLE";
|
||||
extern const isc::log::MessageID DHCP4_CLIENTID_IGNORED_FOR_LEASES = "DHCP4_CLIENTID_IGNORED_FOR_LEASES";
|
||||
extern const isc::log::MessageID DHCP4_CLIENT_FQDN_DATA = "DHCP4_CLIENT_FQDN_DATA";
|
||||
extern const isc::log::MessageID DHCP4_CLIENT_FQDN_PROCESS = "DHCP4_CLIENT_FQDN_PROCESS";
|
||||
@ -150,6 +148,8 @@ extern const isc::log::MessageID DHCP4_RELEASE_FAIL_WRONG_CLIENT = "DHCP4_RELEAS
|
||||
extern const isc::log::MessageID DHCP4_REQUEST = "DHCP4_REQUEST";
|
||||
extern const isc::log::MessageID DHCP4_REQUIRED_CLASS_EVAL_ERROR = "DHCP4_REQUIRED_CLASS_EVAL_ERROR";
|
||||
extern const isc::log::MessageID DHCP4_REQUIRED_CLASS_EVAL_RESULT = "DHCP4_REQUIRED_CLASS_EVAL_RESULT";
|
||||
extern const isc::log::MessageID DHCP4_REQUIRED_CLASS_UNDEFINED = "DHCP4_REQUIRED_CLASS_UNDEFINED";
|
||||
extern const isc::log::MessageID DHCP4_REQUIRED_CLASS_UNTESTABLE = "DHCP4_REQUIRED_CLASS_UNTESTABLE";
|
||||
extern const isc::log::MessageID DHCP4_RESERVATIONS_LOOKUP_FIRST_ENABLED = "DHCP4_RESERVATIONS_LOOKUP_FIRST_ENABLED";
|
||||
extern const isc::log::MessageID DHCP4_RESERVED_HOSTNAME_ASSIGNED = "DHCP4_RESERVED_HOSTNAME_ASSIGNED";
|
||||
extern const isc::log::MessageID DHCP4_RESPONSE_DATA = "DHCP4_RESPONSE_DATA";
|
||||
@ -197,8 +197,6 @@ const char* values[] = {
|
||||
"DHCP4_CLASSES_ASSIGNED_AFTER_SUBNET_SELECTION", "%1: client packet has been assigned to the following classes: %2",
|
||||
"DHCP4_CLASS_ASSIGNED", "%1: client packet has been assigned to the following class: %2",
|
||||
"DHCP4_CLASS_UNCONFIGURED", "%1: client packet belongs to an unconfigured class: %2",
|
||||
"DHCP4_CLASS_UNDEFINED", "required class %1 has no definition",
|
||||
"DHCP4_CLASS_UNTESTABLE", "required class %1 has no test expression",
|
||||
"DHCP4_CLIENTID_IGNORED_FOR_LEASES", "%1: not using client identifier for lease allocation for subnet %2",
|
||||
"DHCP4_CLIENT_FQDN_DATA", "%1: Client sent FQDN option: %2",
|
||||
"DHCP4_CLIENT_FQDN_PROCESS", "%1: processing Client FQDN option",
|
||||
@ -328,6 +326,8 @@ const char* values[] = {
|
||||
"DHCP4_REQUEST", "%1: server is processing DHCPREQUEST with hint=%2",
|
||||
"DHCP4_REQUIRED_CLASS_EVAL_ERROR", "%1: Expression '%2' evaluated to %3",
|
||||
"DHCP4_REQUIRED_CLASS_EVAL_RESULT", "%1: Expression '%2' evaluated to %3",
|
||||
"DHCP4_REQUIRED_CLASS_UNDEFINED", "required class %1 has no definition",
|
||||
"DHCP4_REQUIRED_CLASS_UNTESTABLE", "required class %1 has no test expression",
|
||||
"DHCP4_RESERVATIONS_LOOKUP_FIRST_ENABLED", "Multi-threading is enabled and host reservations lookup is always performed first.",
|
||||
"DHCP4_RESERVED_HOSTNAME_ASSIGNED", "%1: server assigned reserved hostname %2",
|
||||
"DHCP4_RESPONSE_DATA", "%1: responding with packet %2 (type %3), packet details: %4",
|
||||
|
@ -20,8 +20,6 @@ extern const isc::log::MessageID DHCP4_CLASSES_ASSIGNED;
|
||||
extern const isc::log::MessageID DHCP4_CLASSES_ASSIGNED_AFTER_SUBNET_SELECTION;
|
||||
extern const isc::log::MessageID DHCP4_CLASS_ASSIGNED;
|
||||
extern const isc::log::MessageID DHCP4_CLASS_UNCONFIGURED;
|
||||
extern const isc::log::MessageID DHCP4_CLASS_UNDEFINED;
|
||||
extern const isc::log::MessageID DHCP4_CLASS_UNTESTABLE;
|
||||
extern const isc::log::MessageID DHCP4_CLIENTID_IGNORED_FOR_LEASES;
|
||||
extern const isc::log::MessageID DHCP4_CLIENT_FQDN_DATA;
|
||||
extern const isc::log::MessageID DHCP4_CLIENT_FQDN_PROCESS;
|
||||
@ -151,6 +149,8 @@ extern const isc::log::MessageID DHCP4_RELEASE_FAIL_WRONG_CLIENT;
|
||||
extern const isc::log::MessageID DHCP4_REQUEST;
|
||||
extern const isc::log::MessageID DHCP4_REQUIRED_CLASS_EVAL_ERROR;
|
||||
extern const isc::log::MessageID DHCP4_REQUIRED_CLASS_EVAL_RESULT;
|
||||
extern const isc::log::MessageID DHCP4_REQUIRED_CLASS_UNDEFINED;
|
||||
extern const isc::log::MessageID DHCP4_REQUIRED_CLASS_UNTESTABLE;
|
||||
extern const isc::log::MessageID DHCP4_RESERVATIONS_LOOKUP_FIRST_ENABLED;
|
||||
extern const isc::log::MessageID DHCP4_RESERVED_HOSTNAME_ASSIGNED;
|
||||
extern const isc::log::MessageID DHCP4_RESPONSE_DATA;
|
||||
|
@ -94,16 +94,6 @@ which cannot be found in the configuration. Either a hook written
|
||||
before the classification was added to Kea is used, or class naming is
|
||||
inconsistent.
|
||||
|
||||
% DHCP4_CLASS_UNDEFINED required class %1 has no definition
|
||||
Logged at debug log level 40.
|
||||
This debug message informs that a class is listed for required evaluation but
|
||||
has no definition.
|
||||
|
||||
% DHCP4_CLASS_UNTESTABLE required class %1 has no test expression
|
||||
Logged at debug log level 40.
|
||||
This debug message informs that a class was listed for required evaluation but
|
||||
its definition does not include a test expression to evaluate.
|
||||
|
||||
% DHCP4_CLIENTID_IGNORED_FOR_LEASES %1: not using client identifier for lease allocation for subnet %2
|
||||
Logged at debug log level 50.
|
||||
This debug message is issued when the server is processing the DHCPv4 message
|
||||
@ -989,6 +979,17 @@ This debug message indicates that the expression of a required client class has
|
||||
been successfully evaluated. The client class name and the result value of the
|
||||
evaluation are printed.
|
||||
|
||||
% DHCP4_REQUIRED_CLASS_UNDEFINED required class %1 has no definition
|
||||
Logged at debug log level 40.
|
||||
This debug message informs that a class is listed for required evaluation but
|
||||
has no definition. The class is ignored.
|
||||
|
||||
% DHCP4_REQUIRED_CLASS_UNTESTABLE required class %1 has no test expression
|
||||
Logged at debug log level 40.
|
||||
This debug message informs that a class was listed for required evaluation but
|
||||
its definition does not include a test expression to evaluate. The class is
|
||||
unconditionally added to the query.
|
||||
|
||||
% DHCP4_RESERVATIONS_LOOKUP_FIRST_ENABLED Multi-threading is enabled and host reservations lookup is always performed first.
|
||||
This is a message informing that host reservations lookup is performed before
|
||||
lease lookup when multi-threading is enabled overwriting configured value.
|
||||
|
@ -4866,15 +4866,19 @@ void Dhcpv4Srv::requiredClassify(Dhcpv4Exchange& ex) {
|
||||
for (auto const& cclass : classes) {
|
||||
const ClientClassDefPtr class_def = dict->findClass(cclass);
|
||||
if (!class_def) {
|
||||
LOG_DEBUG(dhcp4_logger, DBG_DHCP4_BASIC, DHCP4_CLASS_UNDEFINED)
|
||||
LOG_DEBUG(dhcp4_logger, DBG_DHCP4_BASIC,
|
||||
DHCP4_REQUIRED_CLASS_UNDEFINED)
|
||||
.arg(cclass);
|
||||
// Ignore it as it can't have an attached action
|
||||
continue;
|
||||
}
|
||||
const ExpressionPtr& expr_ptr = class_def->getMatchExpr();
|
||||
// Nothing to do without an expression to evaluate
|
||||
// Add a class without an expression to evaluate
|
||||
if (!expr_ptr) {
|
||||
LOG_DEBUG(dhcp4_logger, DBG_DHCP4_BASIC, DHCP4_CLASS_UNTESTABLE)
|
||||
LOG_DEBUG(dhcp4_logger, DBG_DHCP4_BASIC,
|
||||
DHCP4_REQUIRED_CLASS_UNTESTABLE)
|
||||
.arg(cclass);
|
||||
query->addClass(cclass);
|
||||
continue;
|
||||
}
|
||||
// Evaluate the expression which can return false (no match),
|
||||
|
@ -1238,6 +1238,100 @@ TEST_F(ClassifyTest, precedenceNetwork) {
|
||||
EXPECT_EQ("10.0.0.3", addrs[0].toText());
|
||||
}
|
||||
|
||||
// This test checks a required class without a test entry can be
|
||||
// unconditionally added.
|
||||
TEST_F(ClassifyTest, requiredNoTest) {
|
||||
std::string config =
|
||||
"{"
|
||||
"\"interfaces-config\": {"
|
||||
" \"interfaces\": [ \"*\" ]"
|
||||
"},"
|
||||
"\"valid-lifetime\": 600,"
|
||||
"\"client-classes\": ["
|
||||
" {"
|
||||
" \"name\": \"for-network\","
|
||||
" \"option-data\": [ {"
|
||||
" \"name\": \"domain-name-servers\","
|
||||
" \"data\": \"10.0.0.3\""
|
||||
" } ]"
|
||||
" }"
|
||||
"],"
|
||||
"\"shared-networks\": [ {"
|
||||
" \"name\": \"frog\","
|
||||
" \"require-client-classes\": [ \"for-network\" ],"
|
||||
" \"subnet4\": [ { "
|
||||
" \"subnet\": \"10.0.0.0/24\","
|
||||
" \"id\": 1,"
|
||||
" \"pools\": [ { "
|
||||
" \"pool\": \"10.0.0.10-10.0.0.100\""
|
||||
" } ]"
|
||||
" } ]"
|
||||
"} ]"
|
||||
"}";
|
||||
|
||||
// Create a client requesting domain-name-servers option
|
||||
Dhcp4Client client(Dhcp4Client::SELECTING);
|
||||
client.requestOptions(DHO_DOMAIN_NAME_SERVERS);
|
||||
|
||||
// Load the config and perform a DORA
|
||||
configure(config, *client.getServer());
|
||||
ASSERT_NO_THROW(client.doDORA());
|
||||
|
||||
// Check response
|
||||
Pkt4Ptr resp = client.getContext().response_;
|
||||
ASSERT_TRUE(resp);
|
||||
EXPECT_EQ("10.0.0.10", resp->getYiaddr().toText());
|
||||
|
||||
// Check domain-name-servers option
|
||||
OptionPtr opt = resp->getOption(DHO_DOMAIN_NAME_SERVERS);
|
||||
ASSERT_TRUE(opt);
|
||||
Option4AddrLstPtr servers =
|
||||
boost::dynamic_pointer_cast<Option4AddrLst>(opt);
|
||||
ASSERT_TRUE(servers);
|
||||
auto addrs = servers->getAddresses();
|
||||
ASSERT_EQ(1, addrs.size());
|
||||
EXPECT_EQ("10.0.0.3", addrs[0].toText());
|
||||
}
|
||||
|
||||
// This test checks a required class which is not defined is ignored.
|
||||
TEST_F(ClassifyTest, requiredNoDefined) {
|
||||
std::string config =
|
||||
"{"
|
||||
"\"interfaces-config\": {"
|
||||
" \"interfaces\": [ \"*\" ]"
|
||||
"},"
|
||||
"\"valid-lifetime\": 600,"
|
||||
"\"shared-networks\": [ {"
|
||||
" \"name\": \"frog\","
|
||||
" \"require-client-classes\": [ \"for-network\" ],"
|
||||
" \"subnet4\": [ { "
|
||||
" \"subnet\": \"10.0.0.0/24\","
|
||||
" \"id\": 1,"
|
||||
" \"pools\": [ { "
|
||||
" \"pool\": \"10.0.0.10-10.0.0.100\""
|
||||
" } ]"
|
||||
" } ]"
|
||||
"} ]"
|
||||
"}";
|
||||
|
||||
// Create a client requesting domain-name-servers option
|
||||
Dhcp4Client client(Dhcp4Client::SELECTING);
|
||||
client.requestOptions(DHO_DOMAIN_NAME_SERVERS);
|
||||
|
||||
// Load the config and perform a DORA
|
||||
configure(config, *client.getServer());
|
||||
ASSERT_NO_THROW(client.doDORA());
|
||||
|
||||
// Check response
|
||||
Pkt4Ptr resp = client.getContext().response_;
|
||||
ASSERT_TRUE(resp);
|
||||
EXPECT_EQ("10.0.0.10", resp->getYiaddr().toText());
|
||||
|
||||
// Check domain-name-servers option
|
||||
OptionPtr opt = resp->getOption(DHO_DOMAIN_NAME_SERVERS);
|
||||
EXPECT_FALSE(opt);
|
||||
}
|
||||
|
||||
// This test checks the handling for the DROP special class.
|
||||
TEST_F(ClassifyTest, dropClass) {
|
||||
Dhcp4Client client(Dhcp4Client::SELECTING);
|
||||
|
@ -21,8 +21,6 @@ extern const isc::log::MessageID DHCP6_CLASSES_ASSIGNED = "DHCP6_CLASSES_ASSIGNE
|
||||
extern const isc::log::MessageID DHCP6_CLASSES_ASSIGNED_AFTER_SUBNET_SELECTION = "DHCP6_CLASSES_ASSIGNED_AFTER_SUBNET_SELECTION";
|
||||
extern const isc::log::MessageID DHCP6_CLASS_ASSIGNED = "DHCP6_CLASS_ASSIGNED";
|
||||
extern const isc::log::MessageID DHCP6_CLASS_UNCONFIGURED = "DHCP6_CLASS_UNCONFIGURED";
|
||||
extern const isc::log::MessageID DHCP6_CLASS_UNDEFINED = "DHCP6_CLASS_UNDEFINED";
|
||||
extern const isc::log::MessageID DHCP6_CLASS_UNTESTABLE = "DHCP6_CLASS_UNTESTABLE";
|
||||
extern const isc::log::MessageID DHCP6_CONFIG_COMPLETE = "DHCP6_CONFIG_COMPLETE";
|
||||
extern const isc::log::MessageID DHCP6_CONFIG_LOAD_FAIL = "DHCP6_CONFIG_LOAD_FAIL";
|
||||
extern const isc::log::MessageID DHCP6_CONFIG_PACKET_QUEUE = "DHCP6_CONFIG_PACKET_QUEUE";
|
||||
@ -149,6 +147,8 @@ extern const isc::log::MessageID DHCP6_RELEASE_PD_FAIL_WRONG_DUID = "DHCP6_RELEA
|
||||
extern const isc::log::MessageID DHCP6_RELEASE_PD_FAIL_WRONG_IAID = "DHCP6_RELEASE_PD_FAIL_WRONG_IAID";
|
||||
extern const isc::log::MessageID DHCP6_REQUIRED_CLASS_EVAL_ERROR = "DHCP6_REQUIRED_CLASS_EVAL_ERROR";
|
||||
extern const isc::log::MessageID DHCP6_REQUIRED_CLASS_EVAL_RESULT = "DHCP6_REQUIRED_CLASS_EVAL_RESULT";
|
||||
extern const isc::log::MessageID DHCP6_REQUIRED_CLASS_UNDEFINED = "DHCP6_REQUIRED_CLASS_UNDEFINED";
|
||||
extern const isc::log::MessageID DHCP6_REQUIRED_CLASS_UNTESTABLE = "DHCP6_REQUIRED_CLASS_UNTESTABLE";
|
||||
extern const isc::log::MessageID DHCP6_REQUIRED_OPTIONS_CHECK_FAIL = "DHCP6_REQUIRED_OPTIONS_CHECK_FAIL";
|
||||
extern const isc::log::MessageID DHCP6_RESERVATIONS_LOOKUP_FIRST_ENABLED = "DHCP6_RESERVATIONS_LOOKUP_FIRST_ENABLED";
|
||||
extern const isc::log::MessageID DHCP6_RESPONSE_DATA = "DHCP6_RESPONSE_DATA";
|
||||
@ -188,8 +188,6 @@ const char* values[] = {
|
||||
"DHCP6_CLASSES_ASSIGNED_AFTER_SUBNET_SELECTION", "%1: client packet has been assigned to the following classes: %2",
|
||||
"DHCP6_CLASS_ASSIGNED", "%1: client packet has been assigned to the following class: %2",
|
||||
"DHCP6_CLASS_UNCONFIGURED", "%1: client packet belongs to an unconfigured class: %2",
|
||||
"DHCP6_CLASS_UNDEFINED", "required class %1 has no definition",
|
||||
"DHCP6_CLASS_UNTESTABLE", "required class %1 has no test expression",
|
||||
"DHCP6_CONFIG_COMPLETE", "DHCPv6 server has completed configuration: %1",
|
||||
"DHCP6_CONFIG_LOAD_FAIL", "configuration error using file: %1, reason: %2",
|
||||
"DHCP6_CONFIG_PACKET_QUEUE", "DHCPv6 packet queue info after configuration: %1",
|
||||
@ -316,6 +314,8 @@ const char* values[] = {
|
||||
"DHCP6_RELEASE_PD_FAIL_WRONG_IAID", "%1: client tried to release prefix %2/%3, but it used wrong IAID (expected %4, but got %5)",
|
||||
"DHCP6_REQUIRED_CLASS_EVAL_ERROR", "%1: Expression '%2' evaluated to %3",
|
||||
"DHCP6_REQUIRED_CLASS_EVAL_RESULT", "%1: Expression '%2' evaluated to %3",
|
||||
"DHCP6_REQUIRED_CLASS_UNDEFINED", "required class %1 has no definition",
|
||||
"DHCP6_REQUIRED_CLASS_UNTESTABLE", "required class %1 has no test expression",
|
||||
"DHCP6_REQUIRED_OPTIONS_CHECK_FAIL", "%1: %2 message received from %3 failed the following check: %4",
|
||||
"DHCP6_RESERVATIONS_LOOKUP_FIRST_ENABLED", "Multi-threading is enabled and host reservations lookup is always performed first.",
|
||||
"DHCP6_RESPONSE_DATA", "%1: responding with packet %2 (type %3), packet details: %4",
|
||||
|
@ -22,8 +22,6 @@ extern const isc::log::MessageID DHCP6_CLASSES_ASSIGNED;
|
||||
extern const isc::log::MessageID DHCP6_CLASSES_ASSIGNED_AFTER_SUBNET_SELECTION;
|
||||
extern const isc::log::MessageID DHCP6_CLASS_ASSIGNED;
|
||||
extern const isc::log::MessageID DHCP6_CLASS_UNCONFIGURED;
|
||||
extern const isc::log::MessageID DHCP6_CLASS_UNDEFINED;
|
||||
extern const isc::log::MessageID DHCP6_CLASS_UNTESTABLE;
|
||||
extern const isc::log::MessageID DHCP6_CONFIG_COMPLETE;
|
||||
extern const isc::log::MessageID DHCP6_CONFIG_LOAD_FAIL;
|
||||
extern const isc::log::MessageID DHCP6_CONFIG_PACKET_QUEUE;
|
||||
@ -150,6 +148,8 @@ extern const isc::log::MessageID DHCP6_RELEASE_PD_FAIL_WRONG_DUID;
|
||||
extern const isc::log::MessageID DHCP6_RELEASE_PD_FAIL_WRONG_IAID;
|
||||
extern const isc::log::MessageID DHCP6_REQUIRED_CLASS_EVAL_ERROR;
|
||||
extern const isc::log::MessageID DHCP6_REQUIRED_CLASS_EVAL_RESULT;
|
||||
extern const isc::log::MessageID DHCP6_REQUIRED_CLASS_UNDEFINED;
|
||||
extern const isc::log::MessageID DHCP6_REQUIRED_CLASS_UNTESTABLE;
|
||||
extern const isc::log::MessageID DHCP6_REQUIRED_OPTIONS_CHECK_FAIL;
|
||||
extern const isc::log::MessageID DHCP6_RESERVATIONS_LOOKUP_FIRST_ENABLED;
|
||||
extern const isc::log::MessageID DHCP6_RESPONSE_DATA;
|
||||
|
@ -112,16 +112,6 @@ which cannot be found in the configuration. Either a hook written
|
||||
before the classification was added to Kea is used, or class naming is
|
||||
inconsistent.
|
||||
|
||||
% DHCP6_CLASS_UNDEFINED required class %1 has no definition
|
||||
Logged at debug log level 40.
|
||||
This debug message informs that a class is listed for required evaluation but
|
||||
has no definition.
|
||||
|
||||
% DHCP6_CLASS_UNTESTABLE required class %1 has no test expression
|
||||
Logged at debug log level 40.
|
||||
This debug message informs that a class was listed for required evaluation but
|
||||
its definition does not include a test expression to evaluate.
|
||||
|
||||
% DHCP6_CONFIG_COMPLETE DHCPv6 server has completed configuration: %1
|
||||
This is an informational message announcing the successful processing of a
|
||||
new configuration. it is output during server startup, and when an updated
|
||||
@ -994,6 +984,17 @@ This debug message indicates that the expression of a required client class has
|
||||
been successfully evaluated. The client class name and the result value of the
|
||||
evaluation are printed.
|
||||
|
||||
% DHCP6_REQUIRED_CLASS_UNDEFINED required class %1 has no definition
|
||||
Logged at debug log level 40.
|
||||
This debug message informs that a class is listed for required evaluation but
|
||||
has no definition. The class is ignored.
|
||||
|
||||
% DHCP6_REQUIRED_CLASS_UNTESTABLE required class %1 has no test expression
|
||||
Logged at debug log level 40.
|
||||
This debug message informs that a class was listed for required evaluation but
|
||||
its definition does not include a test expression to evaluate. The class is
|
||||
unconditionally added to the query.
|
||||
|
||||
% DHCP6_REQUIRED_OPTIONS_CHECK_FAIL %1: %2 message received from %3 failed the following check: %4
|
||||
Logged at debug log level 40.
|
||||
This message indicates that received DHCPv6 packet is invalid. This may be due
|
||||
|
@ -4495,15 +4495,19 @@ Dhcpv6Srv::requiredClassify(const Pkt6Ptr& pkt, AllocEngine::ClientContext6& ctx
|
||||
for (auto const& cclass : classes) {
|
||||
const ClientClassDefPtr class_def = dict->findClass(cclass);
|
||||
if (!class_def) {
|
||||
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_BASIC, DHCP6_CLASS_UNDEFINED)
|
||||
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_BASIC,
|
||||
DHCP6_REQUIRED_CLASS_UNDEFINED)
|
||||
.arg(cclass);
|
||||
// Ignore it as it can't have an attached action
|
||||
continue;
|
||||
}
|
||||
const ExpressionPtr& expr_ptr = class_def->getMatchExpr();
|
||||
// Nothing to do without an expression to evaluate
|
||||
// Add a class without an expression to evaluate
|
||||
if (!expr_ptr) {
|
||||
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_BASIC, DHCP6_CLASS_UNTESTABLE)
|
||||
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_BASIC,
|
||||
DHCP6_REQUIRED_CLASS_UNTESTABLE)
|
||||
.arg(cclass);
|
||||
pkt->addClass(cclass);
|
||||
continue;
|
||||
}
|
||||
// Evaluate the expression which can return false (no match),
|
||||
|
@ -2268,6 +2268,106 @@ TEST_F(ClassifyTest, precedenceNetwork) {
|
||||
EXPECT_EQ("2001:db8:1::3", addrs[0].toText());
|
||||
}
|
||||
|
||||
// This test checks a required class without a test entry can be
|
||||
// unconditionally added.
|
||||
TEST_F(ClassifyTest, requiredNoTest) {
|
||||
std::string config =
|
||||
"{"
|
||||
"\"interfaces-config\": {"
|
||||
" \"interfaces\": [ \"*\" ]"
|
||||
"},"
|
||||
"\"client-classes\": ["
|
||||
" {"
|
||||
" \"name\": \"for-network\","
|
||||
" \"option-data\": [ {"
|
||||
" \"name\": \"dns-servers\","
|
||||
" \"data\": \"2001:db8:1::3\""
|
||||
" } ]"
|
||||
" }"
|
||||
"],"
|
||||
"\"shared-networks\": [ {"
|
||||
" \"name\": \"frog\","
|
||||
" \"interface\": \"eth1\","
|
||||
" \"require-client-classes\": [ \"for-network\" ],"
|
||||
" \"subnet6\": [ { "
|
||||
" \"subnet\": \"2001:db8:1::/64\","
|
||||
" \"id\": 1,"
|
||||
" \"pools\": [ { "
|
||||
" \"pool\": \"2001:db8:1::1 - 2001:db8:1::64\""
|
||||
" } ]"
|
||||
" } ]"
|
||||
"} ],"
|
||||
"\"valid-lifetime\": 600"
|
||||
"}";
|
||||
|
||||
// Create a client requesting dns-servers option
|
||||
Dhcp6Client client;
|
||||
client.setInterface("eth1");
|
||||
client.requestAddress(0xabca, IOAddress("2001:db8:1::28"));
|
||||
client.requestOption(D6O_NAME_SERVERS);
|
||||
|
||||
// Load the config and perform a SARR
|
||||
configure(config, *client.getServer());
|
||||
ASSERT_NO_THROW(client.doSARR());
|
||||
|
||||
// Check response
|
||||
EXPECT_EQ(1, client.getLeaseNum());
|
||||
Pkt6Ptr resp = client.getContext().response_;
|
||||
ASSERT_TRUE(resp);
|
||||
|
||||
// Check dns-servers option
|
||||
OptionPtr opt = resp->getOption(D6O_NAME_SERVERS);
|
||||
ASSERT_TRUE(opt);
|
||||
Option6AddrLstPtr servers =
|
||||
boost::dynamic_pointer_cast<Option6AddrLst>(opt);
|
||||
ASSERT_TRUE(servers);
|
||||
auto addrs = servers->getAddresses();
|
||||
ASSERT_EQ(1, addrs.size());
|
||||
EXPECT_EQ("2001:db8:1::3", addrs[0].toText());
|
||||
}
|
||||
|
||||
// This test checks a required class which is not defined is ignored.
|
||||
TEST_F(ClassifyTest, requiredNoDefined) {
|
||||
std::string config =
|
||||
"{"
|
||||
"\"interfaces-config\": {"
|
||||
" \"interfaces\": [ \"*\" ]"
|
||||
"},"
|
||||
"\"shared-networks\": [ {"
|
||||
" \"name\": \"frog\","
|
||||
" \"interface\": \"eth1\","
|
||||
" \"require-client-classes\": [ \"for-network\" ],"
|
||||
" \"subnet6\": [ { "
|
||||
" \"subnet\": \"2001:db8:1::/64\","
|
||||
" \"id\": 1,"
|
||||
" \"pools\": [ { "
|
||||
" \"pool\": \"2001:db8:1::1 - 2001:db8:1::64\""
|
||||
" } ]"
|
||||
" } ]"
|
||||
"} ],"
|
||||
"\"valid-lifetime\": 600"
|
||||
"}";
|
||||
|
||||
// Create a client requesting dns-servers option
|
||||
Dhcp6Client client;
|
||||
client.setInterface("eth1");
|
||||
client.requestAddress(0xabca, IOAddress("2001:db8:1::28"));
|
||||
client.requestOption(D6O_NAME_SERVERS);
|
||||
|
||||
// Load the config and perform a SARR
|
||||
configure(config, *client.getServer());
|
||||
ASSERT_NO_THROW(client.doSARR());
|
||||
|
||||
// Check response
|
||||
EXPECT_EQ(1, client.getLeaseNum());
|
||||
Pkt6Ptr resp = client.getContext().response_;
|
||||
ASSERT_TRUE(resp);
|
||||
|
||||
// Check dns-servers option
|
||||
OptionPtr opt = resp->getOption(D6O_NAME_SERVERS);
|
||||
EXPECT_FALSE(opt);
|
||||
}
|
||||
|
||||
// This test checks the complex membership from HA with server1 telephone.
|
||||
TEST_F(ClassifyTest, server1Telephone) {
|
||||
// Create a client.
|
||||
|
Loading…
x
Reference in New Issue
Block a user