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
|
and shared network, i.e. in the same order from the way in which
|
||||||
``option-data`` is processed.
|
``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::
|
.. note::
|
||||||
|
|
||||||
Vendor-Identifying Vendor Options are a special case: for all other
|
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
|
(pd-)pool, subnet, and shared network, i.e. in the same order from the
|
||||||
way in which ``option-data`` is processed.
|
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:
|
.. _dhcp6-ddns-config:
|
||||||
|
|
||||||
DDNS for DHCPv6
|
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_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_ASSIGNED = "DHCP4_CLASS_ASSIGNED";
|
||||||
extern const isc::log::MessageID DHCP4_CLASS_UNCONFIGURED = "DHCP4_CLASS_UNCONFIGURED";
|
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_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_DATA = "DHCP4_CLIENT_FQDN_DATA";
|
||||||
extern const isc::log::MessageID DHCP4_CLIENT_FQDN_PROCESS = "DHCP4_CLIENT_FQDN_PROCESS";
|
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_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_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_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_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_RESERVED_HOSTNAME_ASSIGNED = "DHCP4_RESERVED_HOSTNAME_ASSIGNED";
|
||||||
extern const isc::log::MessageID DHCP4_RESPONSE_DATA = "DHCP4_RESPONSE_DATA";
|
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_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_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_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_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_DATA", "%1: Client sent FQDN option: %2",
|
||||||
"DHCP4_CLIENT_FQDN_PROCESS", "%1: processing Client FQDN option",
|
"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_REQUEST", "%1: server is processing DHCPREQUEST with hint=%2",
|
||||||
"DHCP4_REQUIRED_CLASS_EVAL_ERROR", "%1: Expression '%2' evaluated to %3",
|
"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_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_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_RESERVED_HOSTNAME_ASSIGNED", "%1: server assigned reserved hostname %2",
|
||||||
"DHCP4_RESPONSE_DATA", "%1: responding with packet %2 (type %3), packet details: %4",
|
"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_CLASSES_ASSIGNED_AFTER_SUBNET_SELECTION;
|
||||||
extern const isc::log::MessageID DHCP4_CLASS_ASSIGNED;
|
extern const isc::log::MessageID DHCP4_CLASS_ASSIGNED;
|
||||||
extern const isc::log::MessageID DHCP4_CLASS_UNCONFIGURED;
|
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_CLIENTID_IGNORED_FOR_LEASES;
|
||||||
extern const isc::log::MessageID DHCP4_CLIENT_FQDN_DATA;
|
extern const isc::log::MessageID DHCP4_CLIENT_FQDN_DATA;
|
||||||
extern const isc::log::MessageID DHCP4_CLIENT_FQDN_PROCESS;
|
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_REQUEST;
|
||||||
extern const isc::log::MessageID DHCP4_REQUIRED_CLASS_EVAL_ERROR;
|
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_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_RESERVATIONS_LOOKUP_FIRST_ENABLED;
|
||||||
extern const isc::log::MessageID DHCP4_RESERVED_HOSTNAME_ASSIGNED;
|
extern const isc::log::MessageID DHCP4_RESERVED_HOSTNAME_ASSIGNED;
|
||||||
extern const isc::log::MessageID DHCP4_RESPONSE_DATA;
|
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
|
before the classification was added to Kea is used, or class naming is
|
||||||
inconsistent.
|
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
|
% DHCP4_CLIENTID_IGNORED_FOR_LEASES %1: not using client identifier for lease allocation for subnet %2
|
||||||
Logged at debug log level 50.
|
Logged at debug log level 50.
|
||||||
This debug message is issued when the server is processing the DHCPv4 message
|
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
|
been successfully evaluated. The client class name and the result value of the
|
||||||
evaluation are printed.
|
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.
|
% 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
|
This is a message informing that host reservations lookup is performed before
|
||||||
lease lookup when multi-threading is enabled overwriting configured value.
|
lease lookup when multi-threading is enabled overwriting configured value.
|
||||||
|
@ -4866,15 +4866,19 @@ void Dhcpv4Srv::requiredClassify(Dhcpv4Exchange& ex) {
|
|||||||
for (auto const& cclass : classes) {
|
for (auto const& cclass : classes) {
|
||||||
const ClientClassDefPtr class_def = dict->findClass(cclass);
|
const ClientClassDefPtr class_def = dict->findClass(cclass);
|
||||||
if (!class_def) {
|
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);
|
.arg(cclass);
|
||||||
|
// Ignore it as it can't have an attached action
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const ExpressionPtr& expr_ptr = class_def->getMatchExpr();
|
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) {
|
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);
|
.arg(cclass);
|
||||||
|
query->addClass(cclass);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Evaluate the expression which can return false (no match),
|
// 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());
|
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.
|
// This test checks the handling for the DROP special class.
|
||||||
TEST_F(ClassifyTest, dropClass) {
|
TEST_F(ClassifyTest, dropClass) {
|
||||||
Dhcp4Client client(Dhcp4Client::SELECTING);
|
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_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_ASSIGNED = "DHCP6_CLASS_ASSIGNED";
|
||||||
extern const isc::log::MessageID DHCP6_CLASS_UNCONFIGURED = "DHCP6_CLASS_UNCONFIGURED";
|
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_COMPLETE = "DHCP6_CONFIG_COMPLETE";
|
||||||
extern const isc::log::MessageID DHCP6_CONFIG_LOAD_FAIL = "DHCP6_CONFIG_LOAD_FAIL";
|
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";
|
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_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_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_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_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_RESERVATIONS_LOOKUP_FIRST_ENABLED = "DHCP6_RESERVATIONS_LOOKUP_FIRST_ENABLED";
|
||||||
extern const isc::log::MessageID DHCP6_RESPONSE_DATA = "DHCP6_RESPONSE_DATA";
|
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_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_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_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_COMPLETE", "DHCPv6 server has completed configuration: %1",
|
||||||
"DHCP6_CONFIG_LOAD_FAIL", "configuration error using file: %1, reason: %2",
|
"DHCP6_CONFIG_LOAD_FAIL", "configuration error using file: %1, reason: %2",
|
||||||
"DHCP6_CONFIG_PACKET_QUEUE", "DHCPv6 packet queue info after configuration: %1",
|
"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_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_ERROR", "%1: Expression '%2' evaluated to %3",
|
||||||
"DHCP6_REQUIRED_CLASS_EVAL_RESULT", "%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_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_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",
|
"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_CLASSES_ASSIGNED_AFTER_SUBNET_SELECTION;
|
||||||
extern const isc::log::MessageID DHCP6_CLASS_ASSIGNED;
|
extern const isc::log::MessageID DHCP6_CLASS_ASSIGNED;
|
||||||
extern const isc::log::MessageID DHCP6_CLASS_UNCONFIGURED;
|
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_COMPLETE;
|
||||||
extern const isc::log::MessageID DHCP6_CONFIG_LOAD_FAIL;
|
extern const isc::log::MessageID DHCP6_CONFIG_LOAD_FAIL;
|
||||||
extern const isc::log::MessageID DHCP6_CONFIG_PACKET_QUEUE;
|
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_RELEASE_PD_FAIL_WRONG_IAID;
|
||||||
extern const isc::log::MessageID DHCP6_REQUIRED_CLASS_EVAL_ERROR;
|
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_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_REQUIRED_OPTIONS_CHECK_FAIL;
|
||||||
extern const isc::log::MessageID DHCP6_RESERVATIONS_LOOKUP_FIRST_ENABLED;
|
extern const isc::log::MessageID DHCP6_RESERVATIONS_LOOKUP_FIRST_ENABLED;
|
||||||
extern const isc::log::MessageID DHCP6_RESPONSE_DATA;
|
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
|
before the classification was added to Kea is used, or class naming is
|
||||||
inconsistent.
|
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
|
% DHCP6_CONFIG_COMPLETE DHCPv6 server has completed configuration: %1
|
||||||
This is an informational message announcing the successful processing of a
|
This is an informational message announcing the successful processing of a
|
||||||
new configuration. it is output during server startup, and when an updated
|
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
|
been successfully evaluated. The client class name and the result value of the
|
||||||
evaluation are printed.
|
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
|
% DHCP6_REQUIRED_OPTIONS_CHECK_FAIL %1: %2 message received from %3 failed the following check: %4
|
||||||
Logged at debug log level 40.
|
Logged at debug log level 40.
|
||||||
This message indicates that received DHCPv6 packet is invalid. This may be due
|
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) {
|
for (auto const& cclass : classes) {
|
||||||
const ClientClassDefPtr class_def = dict->findClass(cclass);
|
const ClientClassDefPtr class_def = dict->findClass(cclass);
|
||||||
if (!class_def) {
|
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);
|
.arg(cclass);
|
||||||
|
// Ignore it as it can't have an attached action
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const ExpressionPtr& expr_ptr = class_def->getMatchExpr();
|
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) {
|
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);
|
.arg(cclass);
|
||||||
|
pkt->addClass(cclass);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Evaluate the expression which can return false (no match),
|
// 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());
|
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.
|
// This test checks the complex membership from HA with server1 telephone.
|
||||||
TEST_F(ClassifyTest, server1Telephone) {
|
TEST_F(ClassifyTest, server1Telephone) {
|
||||||
// Create a client.
|
// Create a client.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user