new file: changelog_unreleased/4011-kea-dhcp6-client-ip-reservation-inconsistently-assigned
modified: doc/sphinx/arm/hooks-flex-id.rst
modified: src/hooks/dhcp/flex_id/flex_id_messages.cc
modified: src/hooks/dhcp/flex_id/flex_id_messages.h
modified: src/hooks/dhcp/flex_id/flex_id_messages.mes
modified: src/hooks/dhcp/flex_id/libloadtests/load_unload_unittests.cc
modified: src/hooks/dhcp/flex_id/load_unload.cc
--- /dev/null
+[func] tmark
+ The flex-id hook library parameter, ``identifier-expression``,
+ is now optional. Prior to this, it was manadatory.
+ (Gitlab #4011)
identifier.
The library can be loaded similarly to other hook libraries. It
-takes a mandatory parameter ``identifier-expression`` and some optional boolean
-parameters like ``replace-client-id`` and ``ignore-iaid``:
+supports the following parameters: ``identifier-expression``, ``replace-client-id``,
+and ``ignore-iaid``:
::
This functionality breaks RFC compliance and should be enabled only if
required. When enabled, a warning message is issued at configure time.
+
+.. note::
+
+ The ``ignore-iaid`` parameter operates independently of the flexible identifier
+ feature and may be used wihtout specifying a value for ``identifier-expression``.
+ When ``identifier-expression`` is omitted or specified as an empty string, `""`,
+ the flexible identifier feature is disabled. Kea versions prior to 3.1.2 require
+ a value for ``indentifier-expression`` but accept the empty string value. As of
+ Kea 3.1.2, the parameter is optional.
#include <log/message_types.h>
#include <log/message_initializer.h>
-extern const isc::log::MessageID FLEX_ID_EXPRESSION_EMPTY = "FLEX_ID_EXPRESSION_EMPTY";
extern const isc::log::MessageID FLEX_ID_EXPRESSION_EVALUATED = "FLEX_ID_EXPRESSION_EVALUATED";
extern const isc::log::MessageID FLEX_ID_EXPRESSION_EVALUATED_NP = "FLEX_ID_EXPRESSION_EVALUATED_NP";
extern const isc::log::MessageID FLEX_ID_EXPRESSION_HEX = "FLEX_ID_EXPRESSION_HEX";
extern const isc::log::MessageID FLEX_ID_EXPRESSION_INVALID_JSON_TYPE = "FLEX_ID_EXPRESSION_INVALID_JSON_TYPE";
-extern const isc::log::MessageID FLEX_ID_EXPRESSION_NOT_DEFINED = "FLEX_ID_EXPRESSION_NOT_DEFINED";
extern const isc::log::MessageID FLEX_ID_EXPRESSION_PARSE_FAILED = "FLEX_ID_EXPRESSION_PARSE_FAILED";
extern const isc::log::MessageID FLEX_ID_IGNORE_IAID_APPLIED_ON_NA = "FLEX_ID_IGNORE_IAID_APPLIED_ON_NA";
extern const isc::log::MessageID FLEX_ID_IGNORE_IAID_APPLIED_ON_PD = "FLEX_ID_IGNORE_IAID_APPLIED_ON_PD";
extern const isc::log::MessageID FLEX_ID_IGNORE_IAID_NOT_APPLIED_ON_NA = "FLEX_ID_IGNORE_IAID_NOT_APPLIED_ON_NA";
extern const isc::log::MessageID FLEX_ID_IGNORE_IAID_NOT_APPLIED_ON_PD = "FLEX_ID_IGNORE_IAID_NOT_APPLIED_ON_PD";
extern const isc::log::MessageID FLEX_ID_LOAD_ERROR = "FLEX_ID_LOAD_ERROR";
+extern const isc::log::MessageID FLEX_ID_NO_IDENTIFIER_EXPRESSION = "FLEX_ID_NO_IDENTIFIER_EXPRESSION";
extern const isc::log::MessageID FLEX_ID_REPLACE_CLIENT_ID_JSON_TYPE = "FLEX_ID_REPLACE_CLIENT_ID_JSON_TYPE";
extern const isc::log::MessageID FLEX_ID_RESTORE_CLIENT_ID = "FLEX_ID_RESTORE_CLIENT_ID";
extern const isc::log::MessageID FLEX_ID_RESTORE_DUID = "FLEX_ID_RESTORE_DUID";
namespace {
const char* values[] = {
- "FLEX_ID_EXPRESSION_EMPTY", "Specified identifier-expression is empty",
"FLEX_ID_EXPRESSION_EVALUATED", "Expression evaluated for packet to \"%1\" (size: %2)",
"FLEX_ID_EXPRESSION_EVALUATED_NP", "Expression evaluated for packet to 0x%1 (size: %2)",
"FLEX_ID_EXPRESSION_HEX", "evaluated expression in hexadecimal form \"%1\"",
"FLEX_ID_EXPRESSION_INVALID_JSON_TYPE", "The identifier-expression is %1, but expected JSON string",
- "FLEX_ID_EXPRESSION_NOT_DEFINED", "Expression (identifier-expression) is not defined.",
"FLEX_ID_EXPRESSION_PARSE_FAILED", "The identifier-expression is [%1], but fails to parse with error: %2",
"FLEX_ID_IGNORE_IAID_APPLIED_ON_NA", "the ignore-iaid has changed IAID (%1) to 0 for the IA_NA option.",
"FLEX_ID_IGNORE_IAID_APPLIED_ON_PD", "the ignore-iaid has changed IAID (%1) to 0 for the IA_PD option.",
"FLEX_ID_IGNORE_IAID_NOT_APPLIED_ON_NA", "the ignore-iaid was not applied on the packet because it contains more than one IA_NA.",
"FLEX_ID_IGNORE_IAID_NOT_APPLIED_ON_PD", "the ignore-iaid was not applied on the packet because it contains more than one IA_PD.",
"FLEX_ID_LOAD_ERROR", "An error occurred loading the library %1",
+ "FLEX_ID_NO_IDENTIFIER_EXPRESSION", "identifier-expression is either not specified or empty",
"FLEX_ID_REPLACE_CLIENT_ID_JSON_TYPE", "the replace-client-id is %1 but expected boolean value",
"FLEX_ID_RESTORE_CLIENT_ID", "restoring original client identifier '%1' in the response",
"FLEX_ID_RESTORE_DUID", "restoring original DUID \"%1\" in the response",
#include <log/message_types.h>
-extern const isc::log::MessageID FLEX_ID_EXPRESSION_EMPTY;
extern const isc::log::MessageID FLEX_ID_EXPRESSION_EVALUATED;
extern const isc::log::MessageID FLEX_ID_EXPRESSION_EVALUATED_NP;
extern const isc::log::MessageID FLEX_ID_EXPRESSION_HEX;
extern const isc::log::MessageID FLEX_ID_EXPRESSION_INVALID_JSON_TYPE;
-extern const isc::log::MessageID FLEX_ID_EXPRESSION_NOT_DEFINED;
extern const isc::log::MessageID FLEX_ID_EXPRESSION_PARSE_FAILED;
extern const isc::log::MessageID FLEX_ID_IGNORE_IAID_APPLIED_ON_NA;
extern const isc::log::MessageID FLEX_ID_IGNORE_IAID_APPLIED_ON_PD;
extern const isc::log::MessageID FLEX_ID_IGNORE_IAID_NOT_APPLIED_ON_NA;
extern const isc::log::MessageID FLEX_ID_IGNORE_IAID_NOT_APPLIED_ON_PD;
extern const isc::log::MessageID FLEX_ID_LOAD_ERROR;
+extern const isc::log::MessageID FLEX_ID_NO_IDENTIFIER_EXPRESSION;
extern const isc::log::MessageID FLEX_ID_REPLACE_CLIENT_ID_JSON_TYPE;
extern const isc::log::MessageID FLEX_ID_RESTORE_CLIENT_ID;
extern const isc::log::MessageID FLEX_ID_RESTORE_DUID;
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-% FLEX_ID_EXPRESSION_EMPTY Specified identifier-expression is empty
-This warning message is printed when the flex-id library is being loaded,
-but the expression used to generate the identifier is empty. The library
-will load, but will not generate any identifiers. Please make sure that
-the identifier-expression parameter is specified.
+% FLEX_ID_NO_IDENTIFIER_EXPRESSION identifier-expression is either not specified or empty
+This debug message is printed when the flex-id library is being loaded,
+but the expression used to generate the identifier was either omitted or
+is empty. The library will load, but will neither generate nor replace
+client identifiers. Typically this occurs when users are only interested
+in using ignore-iaid, which operates independently of the expression.
% FLEX_ID_EXPRESSION_EVALUATED Expression evaluated for packet to "%1" (size: %2)
Logged at debug log level 40.
but the expression used to generate the identifier is malformed. It has
a different JSON type (e.g. is a map) rather than expected string.
-% FLEX_ID_EXPRESSION_NOT_DEFINED Expression (identifier-expression) is not defined.
-This warning message is printed when the flex-id library is loaded, but the
-expression used to generate the identifier is not specified. The library
-will load, but will not generate any identifiers. Please make sure that
-the identifier-expression parameter is specified for your library.
-
% FLEX_ID_EXPRESSION_PARSE_FAILED The identifier-expression is [%1], but fails to parse with error: %2
This error message is printed when the flex-id library is being loaded,
but the expression used to generate the identifier is malformed. It failed
invalidDaemonTest("bogus", AF_INET, valid_params_);
}
-// Simple test that checks the library fails to load on bad expressions.
-TEST_F(FlexIdLibLoadTest, badExpression) {
+// Simple test that checks the library still loads when identifier expression is
+// either omitted or empty.
+TEST_F(FlexIdLibLoadTest, emptyOrOmittedExpressionValid) {
// Prepare parameters for the callout parameters library.
ElementPtr params = Element::createMap();
params->set("replace-client-id", Element::create(true));
- invalidDaemonTest("kea-dhcp4", AF_INET, params);
+ params->set("ignore-iaid", Element::create(true));
+ validDaemonTest("kea-dhcp4", AF_INET, params);
// Empty expression.
params->set("identifier-expression", Element::create(string("")));
- // Warning (vs error)
validDaemonTest("kea-dhcp4", AF_INET, params);
+}
+
+// Simple test that checks the library fails to load on bad expressions.
+TEST_F(FlexIdLibLoadTest, badExpression) {
+ // Prepare parameters for the callout parameters library.
+ ElementPtr params = Element::createMap();
+ params->set("replace-client-id", Element::create(true));
// Bad expression.
params->set("identifier-expression", Element::create("foobar"));
using namespace isc::data;
using namespace isc::dhcp;
using namespace isc::process;
+using namespace isc::log;
namespace { // anonymous namespace.
<< ", expected " << expected_proc_name);
}
- // identifier-expression is mandatory
+ // identifier-expression is optional.
data::ConstElementPtr param = handle.getParameter("identifier-expression");
- if (!param) {
- LOG_ERROR(flex_id_logger, FLEX_ID_EXPRESSION_NOT_DEFINED);
- return (1);
- }
+ std::string expr;
+ if (param) {
+ // It must be a string...
+ if (param->getType() != Element::string) {
+ LOG_ERROR(flex_id_logger, FLEX_ID_EXPRESSION_INVALID_JSON_TYPE)
+ .arg(Element::typeToName(param->getType()));
+ return (1);
+ }
- // It must be a string...
- if (param->getType() != Element::string) {
- LOG_ERROR(flex_id_logger, FLEX_ID_EXPRESSION_INVALID_JSON_TYPE)
- .arg(Element::typeToName(param->getType()));
- return (1);
+ std::string expr = param->stringValue();
+ if (!expr.empty() && !checkExpression(v6, expr)) {
+ // The error was logged.
+ return (1);
+ }
}
- // ... and shouldn't be empty.
- std::string expr = param->stringValue();
if (expr.empty()) {
- // Ok, we can continue without the expression, but it's just useless
- // to have this lib loaded. Nevertheless, there may be cases when
- // user temporarily changes the expression to empty string to
- // troubleshoot something.
- LOG_WARN(flex_id_logger, FLEX_ID_EXPRESSION_EMPTY);
- } else if (!checkExpression(v6, expr)) {
- // The error was logged.
- return (1);
+ // Ok, we can continue without the expression. This is likely the
+ // case when users are only interested in ignore-iaid.
+ LOG_DEBUG(flex_id_logger, DBGLVL_TRACE_BASIC,
+ FLEX_ID_NO_IDENTIFIER_EXPRESSION);
}
// replace-client-id indicates if flexible identifier should be used to
}
ignore_iaid = param_ignore->boolValue();
+ if (ignore_iaid) {
+ LOG_WARN(flex_id_logger, FLEX_ID_IGNORE_IAID_ENABLED);
+ }
}
}
// Store specified expression.
storeConfiguration(v6, expr, replace_client_id, ignore_iaid);
-
- if (ignore_iaid) {
- LOG_WARN(flex_id_logger, FLEX_ID_IGNORE_IAID_ENABLED);
- }
} catch (const std::exception& ex) {
// Log the error and return failure.
LOG_ERROR(flex_id_logger, FLEX_ID_LOAD_ERROR)