<title>Configuring Classes</title>
<para>
A class contains five items: a name, a test expression, option data,
- option definition and eval on-demand flag.
+ option definition and only-if-required flag.
The name must exist and must be unique amongst all classes. The test
- expression, option data and definition, and eval on-demand flag are
+ expression, option data and definition, and only-if-required flag are
optional.
</para>
Usually the test expression is evaluated before subnet selection
but in some cases it is useful to evaluate it later when the
subnet, shared-network or pools are known but output option
- processing not yet done. The eval-on-demand flag, false by default,
- allows to defer and make only on-demand the evaluation of the
- test expression.
+ processing not yet done. The only-if-required flag, false by default,
+ allows to perform the evaluation of the test expression only
+ when it was required, i.e. in a required-client-classes list.
</para>
<para>
- The eval-client-classes list which is valid for shared-network,
+ The required-client-classes list which is valid for shared-network,
subnet and pool scope specifies the classes which are evaluated
in the second pass before output option processing.
The list is built in the reversed precedence order of option
data, i.e. an option data in a subnet takes precedence on one
- in a shared-network but an on-demand class in a subnet is added
+ in a shared-network but required class in a subnet is added
after one in a shared-network.
- The mechanism is related to the eval-on-demand flag but it is
- not required that the flag was set to true.
+ The mechanism is related to the only-if-required flag but it is
+ not mandatory that the flag was set to true.
</para>
<para>
is to assess an incoming packet and assign it to zero or more classes. The
second step is to choose a subnet, possibly based on the class information.
The third step is to assign classes from host reservations.
- The forth step is to build the list of on-demand classes and perform
- deferred evaluation for each class of the list.
+ The forth step is to build the list of required classes and perform
+ the evaluation for each class of the list.
The last step is to assign options, again possibly based on the class
information.
</para>
</para>
</section>
- <section id="dhcp4-on-demand-class">
- <title>On-demand classification</title>
+ <section id="dhcp4-required-class">
+ <title>Required classification</title>
<para>
In some cases it is useful to limit the scope of class.
Two devices are available to perform evaluation of test
- expressions so assignment when it returns true only on-demand.
+ expressions so assignment when it was required.
</para>
<para>
- The first one is the per-class <command>eval-on-demand</command>
+ The first one is the per-class <command>only-if-required</command>
flag which is false by default. When it is set to
<command>true</command> the test expression of the class is not
evaluated at the reception of a new incoming ticket.
</para>
<para>
- The second is the <command>eval-client-classes</command> which
+ The second is the <command>required-client-classes</command> which
takes a list of class names and is valid in shared-network,
subnet and pool scope. Classes in these lists are evaluated
after resource assignment and before output option processing.
{<userinput>
"name": "Client_foo",
"test": "'' == ''",
- "eval-on-demand": true</userinput>
+ "only-if-required": true</userinput>
},
...
],
{
"subnet": "192.0.2.0/24",
"pools": [ { "pool": "192.0.2.10 - 192.0.2.20" } ],
- <userinput>"eval-client-classes": [ "Client_foo" ],</userinput>
+ <userinput>"required-client-classes": [ "Client_foo" ],</userinput>
...
},
...
is to assess an incoming packet and assign it to zero or more classes. The
second step is to choose a subnet, possibly based on the class information.
The third step is to assign classes from host reservations.
- The forth step is to build the list of on-demand classes and perform
- deferred evaluation for each class of the list.
+ The forth step is to build the list of required classes and perform
+ the evaluation for each class of the list.
The last step is to assign options again possibly based on the class
information.
</para>
</para>
</section>
- <section id="dhcp6-on-demand-class">
- <title>On-demand classification</title>
+ <section id="dhcp6-required-class">
+ <title>Required classification</title>
<para>
In some cases it is useful to limit the scope of class.
Two devices are available to perform evaluation of test
- expressions so assignment when it returns true only on-demand.
+ expressions so assignment when it was required.
</para>
<para>
- The first one is the per-class <command>eval-on-demand</command>
+ The first one is the per-class <command>only-if-required</command>
flag which is false by default. When it is set to
<command>true</command> the test expression of the class is not
evaluated at the reception of a new incoming ticket.
</para>
<para>
- The second is the <command>eval-client-classes</command> which
+ The second is the <command>required-client-classes</command> which
takes a list of class names and is valid in shared-network,
subnet and pool scope. Classes in these lists are evaluated
after resource assignment and before output option processing.
{<userinput>
"name": "Client_foo",
"test": "'' == ''",
- "eval-on-demand": true</userinput>
+ "only-if-required": true</userinput>
},
...
],
"pool": "2001:db8:1::-2001:db8:1::ffff"
}
],
- <userinput>"eval-client-classes": [ "Client_foo" ],</userinput>
+ <userinput>"required-client-classes": [ "Client_foo" ],</userinput>
...
},
...
}
}
-\"eval-client-classes\" {
+\"required-client-classes\" {
switch(driver.ctx_) {
case isc::dhcp::Parser4Context::SUBNET4:
case isc::dhcp::Parser4Context::POOLS:
case isc::dhcp::Parser4Context::SHARED_NETWORK:
- return isc::dhcp::Dhcp4Parser::make_EVAL_CLIENT_CLASSES(driver.loc_);
+ return isc::dhcp::Dhcp4Parser::make_REQUIRED_CLIENT_CLASSES(driver.loc_);
default:
- return isc::dhcp::Dhcp4Parser::make_STRING("eval-client-classes", driver.loc_);
+ return isc::dhcp::Dhcp4Parser::make_STRING("required-client-classes", driver.loc_);
}
}
}
}
-\"eval-on-demand\" {
+\"only-if-required\" {
switch(driver.ctx_) {
case isc::dhcp::Parser4Context::CLIENT_CLASSES:
- return isc::dhcp::Dhcp4Parser::make_EVAL_ON_DEMAND(driver.loc_);
+ return isc::dhcp::Dhcp4Parser::make_ONLY_IF_REQUIRED(driver.loc_);
default:
- return isc::dhcp::Dhcp4Parser::make_STRING("eval-on-demand", driver.loc_);
+ return isc::dhcp::Dhcp4Parser::make_STRING("only-if-required", driver.loc_);
}
}
-# Copyright (C) 2012-2017 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2012-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
before the classification was added to Kea is used, or class naming is
inconsistent.
-% DHCP4_CLASS_UNKNOWN on-demand class %1 has no definition
-This debug message informs that a class is listed for late evaluation but
+% DHCP4_CLASS_UNDEFINED required class %1 has no definition
+This debug message informs that a class is listed for required evaluation but
has no definition.
-% DHCP4_CLASS_UNTESTABLE on-demand class %1 has no test expression
-This debug message informs that a class was listed for late evaluation but
+% DHCP4_CLASS_UNTESTABLE required class %1 has no test expression
+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
HOST_RESERVATION_IDENTIFIERS "host-reservation-identifiers"
CLIENT_CLASSES "client-classes"
- EVAL_CLIENT_CLASSES "eval-client-classes"
+ REQUIRED_CLIENT_CLASSES "required-client-classes"
TEST "test"
- EVAL_ON_DEMAND "eval-on-demand"
+ ONLY_IF_REQUIRED "only-if-required"
CLIENT_CLASS "client-class"
RESERVATIONS "reservations"
| id
| rapid_commit
| client_class
- | eval_client_classes
+ | required_client_classes
| reservations
| reservation_mode
| relay
ctx.leave();
};
-eval_client_classes: EVAL_CLIENT_CLASSES {
+required_client_classes: REQUIRED_CLIENT_CLASSES {
ElementPtr c(new ListElement(ctx.loc2pos(@1)));
- ctx.stack_.back()->set("eval-client-classes", c);
+ ctx.stack_.back()->set("required-client-classes", c);
ctx.stack_.push_back(c);
ctx.enter(ctx.NO_KEYWORD);
} COLON list_strings {
| relay
| reservation_mode
| client_class
- | eval_client_classes
+ | required_client_classes
| valid_lifetime
| unknown_map_entry
;
pool_param: pool_entry
| option_data_list
| client_class
- | eval_client_classes
+ | required_client_classes
| user_context
| unknown_map_entry
;
client_class_param: client_class_name
| client_class_test
- | eval_on_demand
+ | only_if_required
| option_def_list
| option_data_list
| next_server
ctx.leave();
};
-eval_on_demand: EVAL_ON_DEMAND COLON BOOLEAN {
+only_if_required: ONLY_IF_REQUIRED COLON BOOLEAN {
ElementPtr b(new BoolElement($3, ctx.loc2pos(@3)));
- ctx.stack_.back()->set("eval-on-demand", b);
+ ctx.stack_.back()->set("only-if-required", b);
};
// --- end of client classes ---------------------------------
-// Copyright (C) 2011-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-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
if (!ex.getResponse()->getYiaddr().isV4Zero()) {
// Assign reserved classes.
ex.setReservedClientClasses();
- // Late classification
- lateClassify(ex);
+ // Required classification
+ requiredClassify(ex);
buildCfgOptionList(ex);
appendRequestedOptions(ex);
if (!ex.getResponse()->getYiaddr().isV4Zero()) {
// Assign reserved classes.
ex.setReservedClientClasses();
- // Late classification
- lateClassify(ex);
+ // Required classification
+ requiredClassify(ex);
buildCfgOptionList(ex);
appendRequestedOptions(ex);
Pkt4Ptr ack = ex.getResponse();
ex.setReservedClientClasses();
- lateClassify(ex);
+ requiredClassify(ex);
buildCfgOptionList(ex);
appendRequestedOptions(ex);
if (!expr_ptr) {
continue;
}
- // Not the right time if on demand
- if ((*it)->getOnDemand()) {
+ // Not the right time if only when required
+ if ((*it)->getRequired()) {
continue;
}
// Evaluate the expression which can return false (no match),
}
}
-void Dhcpv4Srv::lateClassify(Dhcpv4Exchange& ex) {
- // First collect on-demand classes
+void Dhcpv4Srv::requiredClassify(Dhcpv4Exchange& ex) {
+ // First collect required classes
Pkt4Ptr query = ex.getQuery();
ClientClasses classes = query->getClasses(true);
Subnet4Ptr subnet = ex.getContext()->subnet_;
SharedNetwork4Ptr network;
subnet->getSharedNetwork(network);
if (network) {
- const ClientClasses& to_add = network->getOnDemandClasses();
+ const ClientClasses& to_add = network->getRequiredClasses();
for (ClientClasses::const_iterator cclass = to_add.cbegin();
cclass != to_add.cend(); ++cclass) {
classes.insert(*cclass);
}
// Followed by the subnet
- const ClientClasses& to_add = subnet->getOnDemandClasses();
+ const ClientClasses& to_add = subnet->getRequiredClasses();
for(ClientClasses::const_iterator cclass = to_add.cbegin();
cclass != to_add.cend(); ++cclass) {
classes.insert(*cclass);
if (!addr.isV4Zero()) {
PoolPtr pool = subnet->getPool(Lease::TYPE_V4, addr, false);
if (pool) {
- const ClientClasses& to_add = pool->getOnDemandClasses();
+ const ClientClasses& to_add = pool->getRequiredClasses();
for (ClientClasses::const_iterator cclass = to_add.cbegin();
cclass != to_add.cend(); ++cclass) {
classes.insert(*cclass);
cclass != classes.cend(); ++cclass) {
const ClientClassDefPtr class_def = dict->findClass(*cclass);
if (!class_def) {
- LOG_DEBUG(dhcp4_logger, DBG_DHCP4_BASIC, DHCP4_CLASS_UNKNOWN)
+ LOG_DEBUG(dhcp4_logger, DBG_DHCP4_BASIC, DHCP4_CLASS_UNDEFINED)
.arg(*cclass);
continue;
}
-// Copyright (C) 2011-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-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 pkt packet to be classified
void classifyPacket(const Pkt4Ptr& pkt);
- /// @brief Assigns incoming packet to zero or more classes (late pass).
+ /// @brief Assigns incoming packet to zero or more classes (required pass).
///
- /// @note This late classification evaluates all classes which
- /// were marked for this deferred/on-demand pass. Classes are
- /// collected in the reversed order than output option processing.
+ /// @note This required classification evaluates all classes which
+ /// were marked for required evaluation. Classes are collected so
+ /// evaluated in the reversed order than output option processing.
///
- /// @note The eval-on-demand flag is related because it avoids
+ /// @note The only-if-required flag is related because it avoids
/// double evaluation (which is not forbidden).
///
/// @param ex The exchange holding needed informations.
- void lateClassify(Dhcpv4Exchange& ex);
+ void requiredClassify(Dhcpv4Exchange& ex);
/// @brief Perform deferred option unpacking.
///
-// Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-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
/// or member(<last two>), set boot-file-name to pxelinux.0
///
/// - Configuration 3:
-/// - Used for late/on-demand classification
+/// - Used for required classification
/// - 1 subnet: 10.0.0.0/24
/// - 1 pool: 10.0.0.10-10.0.0.100
/// - the following classes defined:
"{"
" \"name\": \"pxe1\","
" \"test\": \"option[93].hex == 0x0009\","
- " \"eval-on-demand\": true,"
+ " \"only-if-required\": true,"
" \"next-server\": \"1.2.3.4\""
"},"
"{"
" \"name\": \"pxe2\","
" \"test\": \"option[93].hex == 0x0007\","
- " \"eval-on-demand\": true,"
+ " \"only-if-required\": true,"
" \"server-hostname\": \"deneb\""
"},"
"{"
" \"name\": \"pxe3\","
" \"test\": \"option[93].hex == 0x0006\","
- " \"eval-on-demand\": false,"
+ " \"only-if-required\": false,"
" \"boot-file-name\": \"pxelinux.0\""
"},"
"{"
" \"subnet\": \"10.0.0.0/24\", "
" \"id\": 1,"
" \"pools\": [ { \"pool\": \"10.0.0.10-10.0.0.100\" } ],"
- " \"eval-client-classes\": [ \"pxe2\" ]"
+ " \"required-client-classes\": [ \"pxe2\" ]"
" } ]"
"}"
testFixedFields(CONFIGS[3], DHCPINFORM, OptionPtr(), "0.0.0.0", "", "");
}
-// Class 'pxe1' is on-demand and not subject to late evaluation
+// Class 'pxe1' is only-if-required and not subject to required evaluation
TEST_F(ClassifyTest, fixedFieldsDiscoverNextServer3) {
OptionPtr pxe(new OptionInt<uint16_t>(Option::V4, 93, 0x0009));
}
-// Class pxe2 is on-demand but the subnet requests its late evaluation
+// Class pxe2 is only-if-required but the subnet requires its evaluation
TEST_F(ClassifyTest, fixedFieldsDiscoverHostname3) {
OptionPtr pxe(new OptionInt<uint16_t>(Option::V4, 93, 0x0007));
testFixedFields(CONFIGS[3], DHCPINFORM, pxe, "0.0.0.0", "", "ipxe.efi");
}
-// This test checks the precedence order in requested late evaluation.
+// This test checks the precedence order in required evaluation.
// This order is: shared-network > subnet > pools
TEST_F(ClassifyTest, precedenceNone) {
std::string config =
" {"
" \"name\": \"for-pool\","
" \"test\": \"member('all')\","
- " \"eval-on-demand\": true,"
+ " \"only-if-required\": true,"
" \"option-data\": [ {"
" \"name\": \"domain-name-servers\","
" \"data\": \"10.0.0.1\""
" {"
" \"name\": \"for-subnet\","
" \"test\": \"member('all')\","
- " \"eval-on-demand\": true,"
+ " \"only-if-required\": true,"
" \"option-data\": [ {"
" \"name\": \"domain-name-servers\","
" \"data\": \"10.0.0.2\""
" {"
" \"name\": \"for-network\","
" \"test\": \"member('all')\","
- " \"eval-on-demand\": true,"
+ " \"only-if-required\": true,"
" \"option-data\": [ {"
" \"name\": \"domain-name-servers\","
" \"data\": \"10.0.0.3\""
EXPECT_FALSE(opt);
}
-// This test checks the precedence order in requested late evaluation.
+// This test checks the precedence order in required evaluation.
// This order is: shared-network > subnet > pools
TEST_F(ClassifyTest, precedencePool) {
std::string config =
" {"
" \"name\": \"for-pool\","
" \"test\": \"member('all')\","
- " \"eval-on-demand\": true,"
+ " \"only-if-required\": true,"
" \"option-data\": [ {"
" \"name\": \"domain-name-servers\","
" \"data\": \"10.0.0.1\""
" {"
" \"name\": \"for-subnet\","
" \"test\": \"member('all')\","
- " \"eval-on-demand\": true,"
+ " \"only-if-required\": true,"
" \"option-data\": [ {"
" \"name\": \"domain-name-servers\","
" \"data\": \"10.0.0.2\""
" {"
" \"name\": \"for-network\","
" \"test\": \"member('all')\","
- " \"eval-on-demand\": true,"
+ " \"only-if-required\": true,"
" \"option-data\": [ {"
" \"name\": \"domain-name-servers\","
" \"data\": \"10.0.0.3\""
" \"id\": 1,"
" \"pools\": [ { "
" \"pool\": \"10.0.0.10-10.0.0.100\","
- " \"eval-client-classes\": [ \"for-pool\" ]"
+ " \"required-client-classes\": [ \"for-pool\" ]"
" } ]"
" } ]"
"} ]"
EXPECT_EQ("10.0.0.1", addrs[0].toText());
}
-// This test checks the precedence order in requested late evaluation.
+// This test checks the precedence order in required evaluation.
// This order is: shared-network > subnet > pools
TEST_F(ClassifyTest, precedenceSubnet) {
std::string config =
" {"
" \"name\": \"for-pool\","
" \"test\": \"member('all')\","
- " \"eval-on-demand\": true,"
+ " \"only-if-required\": true,"
" \"option-data\": [ {"
" \"name\": \"domain-name-servers\","
" \"data\": \"10.0.0.1\""
" {"
" \"name\": \"for-subnet\","
" \"test\": \"member('all')\","
- " \"eval-on-demand\": true,"
+ " \"only-if-required\": true,"
" \"option-data\": [ {"
" \"name\": \"domain-name-servers\","
" \"data\": \"10.0.0.2\""
" {"
" \"name\": \"for-network\","
" \"test\": \"member('all')\","
- " \"eval-on-demand\": true,"
+ " \"only-if-required\": true,"
" \"option-data\": [ {"
" \"name\": \"domain-name-servers\","
" \"data\": \"10.0.0.3\""
" \"subnet4\": [ { "
" \"subnet\": \"10.0.0.0/24\","
" \"id\": 1,"
- " \"eval-client-classes\": [ \"for-subnet\" ],"
+ " \"required-client-classes\": [ \"for-subnet\" ],"
" \"pools\": [ { "
" \"pool\": \"10.0.0.10-10.0.0.100\","
- " \"eval-client-classes\": [ \"for-pool\" ]"
+ " \"required-client-classes\": [ \"for-pool\" ]"
" } ]"
" } ]"
"} ]"
EXPECT_EQ("10.0.0.2", addrs[0].toText());
}
-// This test checks the precedence order in requested late evaluation.
+// This test checks the precedence order in required evaluation.
// This order is: shared-network > subnet > pools
TEST_F(ClassifyTest, precedenceNetwork) {
std::string config =
" {"
" \"name\": \"for-pool\","
" \"test\": \"member('all')\","
- " \"eval-on-demand\": true,"
+ " \"only-if-required\": true,"
" \"option-data\": [ {"
" \"name\": \"domain-name-servers\","
" \"data\": \"10.0.0.1\""
" {"
" \"name\": \"for-subnet\","
" \"test\": \"member('all')\","
- " \"eval-on-demand\": true,"
+ " \"only-if-required\": true,"
" \"option-data\": [ {"
" \"name\": \"domain-name-servers\","
" \"data\": \"10.0.0.2\""
" {"
" \"name\": \"for-network\","
" \"test\": \"member('all')\","
- " \"eval-on-demand\": true,"
+ " \"only-if-required\": true,"
" \"option-data\": [ {"
" \"name\": \"domain-name-servers\","
" \"data\": \"10.0.0.3\""
"],"
"\"shared-networks\": [ {"
" \"name\": \"frog\","
- " \"eval-client-classes\": [ \"for-network\" ],"
+ " \"required-client-classes\": [ \"for-network\" ],"
" \"subnet4\": [ { "
" \"subnet\": \"10.0.0.0/24\","
" \"id\": 1,"
- " \"eval-client-classes\": [ \"for-subnet\" ],"
+ " \"required-client-classes\": [ \"for-subnet\" ],"
" \"pools\": [ { "
" \"pool\": \"10.0.0.10-10.0.0.100\","
- " \"eval-client-classes\": [ \"for-pool\" ]"
+ " \"required-client-classes\": [ \"for-pool\" ]"
" } ]"
" } ]"
"} ]"
}
}
-\"eval-client-classes\" {
+\"required-client-classes\" {
switch(driver.ctx_) {
case isc::dhcp::Parser6Context::SUBNET6:
case isc::dhcp::Parser6Context::POOLS:
case isc::dhcp::Parser6Context::PD_POOLS:
case isc::dhcp::Parser6Context::SHARED_NETWORK:
- return isc::dhcp::Dhcp6Parser::make_EVAL_CLIENT_CLASSES(driver.loc_);
+ return isc::dhcp::Dhcp6Parser::make_REQUIRED_CLIENT_CLASSES(driver.loc_);
default:
- return isc::dhcp::Dhcp6Parser::make_STRING("eval-client-classes", driver.loc_);
+ return isc::dhcp::Dhcp6Parser::make_STRING("required-client-classes", driver.loc_);
}
}
}
}
-\"eval-on-demand\" {
+\"only-if-required\" {
switch(driver.ctx_) {
case isc::dhcp::Parser6Context::CLIENT_CLASSES:
- return isc::dhcp::Dhcp6Parser::make_EVAL_ON_DEMAND(driver.loc_);
+ return isc::dhcp::Dhcp6Parser::make_ONLY_IF_REQUIRED(driver.loc_);
default:
- return isc::dhcp::Dhcp6Parser::make_STRING("eval-on-demand", driver.loc_);
+ return isc::dhcp::Dhcp6Parser::make_STRING("only-if-required", driver.loc_);
}
}
-# Copyright (C) 2012-2017 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2012-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
before the classification was added to Kea is used, or class naming is
inconsistent.
-% DHCP6_CLASS_UNKNOWN on-demand class %1 has no definition
-This debug message informs that a class is listed for late evaluation but
+% DHCP6_CLASS_UNDEFINED required class %1 has no definition
+This debug message informs that a class is listed for required evaluation but
has no definition.
-% DHCP6_CLASS_UNTESTABLE on-demand class %1 has no test expression
-This debug message informs that a class was listed for late evaluation but
+% DHCP6_CLASS_UNTESTABLE required class %1 has no test expression
+This debug message informs that a class was listed for required evaluation but
its definition does not include a test expression to evaluate.
% DHCP6_COMMAND_RECEIVED received command %1, arguments: %2
HOST_RESERVATION_IDENTIFIERS "host-reservation-identifiers"
CLIENT_CLASSES "client-classes"
- EVAL_CLIENT_CLASSES "eval-client-classes"
+ REQUIRED_CLIENT_CLASSES "required-client-classes"
TEST "test"
- EVAL_ON_DEMAND "eval-on-demand"
+ ONLY_IF_REQUIRED "only-if-required"
CLIENT_CLASS "client-class"
RESERVATIONS "reservations"
| id
| rapid_commit
| client_class
- | eval_client_classes
+ | required_client_classes
| reservations
| reservation_mode
| relay
ctx.leave();
};
-eval_client_classes: EVAL_CLIENT_CLASSES {
+required_client_classes: REQUIRED_CLIENT_CLASSES {
ElementPtr c(new ListElement(ctx.loc2pos(@1)));
- ctx.stack_.back()->set("eval-client-classes", c);
+ ctx.stack_.back()->set("required-client-classes", c);
ctx.stack_.push_back(c);
ctx.enter(ctx.NO_KEYWORD);
} COLON list_strings {
| relay
| reservation_mode
| client_class
- | eval_client_classes
+ | required_client_classes
| preferred_lifetime
| rapid_commit
| valid_lifetime
pool_param: pool_entry
| option_data_list
| client_class
- | eval_client_classes
+ | required_client_classes
| user_context
| unknown_map_entry
;
| pd_delegated_len
| option_data_list
| client_class
- | eval_client_classes
+ | required_client_classes
| excluded_prefix
| excluded_prefix_len
| user_context
client_class_param: client_class_name
| client_class_test
- | eval_on_demand
+ | only_if_required
| option_data_list
| unknown_map_entry
;
ctx.leave();
};
-eval_on_demand: EVAL_ON_DEMAND COLON BOOLEAN {
+only_if_required: ONLY_IF_REQUIRED COLON BOOLEAN {
ElementPtr b(new BoolElement($3, ctx.loc2pos(@3)));
- ctx.stack_.back()->set("eval-on-demand", b);
+ ctx.stack_.back()->set("only-if-required", b);
};
// --- end of client classes ---------------------------------
-// Copyright (C) 2011-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-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
assignLeases(solicit, response, ctx);
setReservedClientClasses(solicit, ctx);
- lateClassify(solicit, ctx);
+ requiredClassify(solicit, ctx);
copyClientOptions(solicit, response);
CfgOptionList co_list;
assignLeases(request, reply, ctx);
setReservedClientClasses(request, ctx);
- lateClassify(request, ctx);
+ requiredClassify(request, ctx);
copyClientOptions(request, reply);
CfgOptionList co_list;
extendLeases(renew, reply, ctx);
setReservedClientClasses(renew, ctx);
- lateClassify(renew, ctx);
+ requiredClassify(renew, ctx);
copyClientOptions(renew, reply);
CfgOptionList co_list;
extendLeases(rebind, reply, ctx);
setReservedClientClasses(rebind, ctx);
- lateClassify(rebind, ctx);
+ requiredClassify(rebind, ctx);
copyClientOptions(rebind, reply);
CfgOptionList co_list;
AllocEngine::ClientContext6 ctx;
initContext(confirm, ctx);
setReservedClientClasses(confirm, ctx);
- lateClassify(confirm, ctx);
+ requiredClassify(confirm, ctx);
// Get IA_NAs from the Confirm. If there are none, the message is
// invalid and must be discarded. There is nothing more to do.
AllocEngine::ClientContext6 ctx;
initContext(release, ctx);
setReservedClientClasses(release, ctx);
- lateClassify(release, ctx);
+ requiredClassify(release, ctx);
Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, release->getTransid()));
AllocEngine::ClientContext6 ctx;
initContext(decline, ctx);
setReservedClientClasses(decline, ctx);
- lateClassify(decline, ctx);
+ requiredClassify(decline, ctx);
// Copy client options (client-id, also relay information if present)
copyClientOptions(decline, reply);
AllocEngine::ClientContext6 ctx;
initContext(inf_request, ctx);
setReservedClientClasses(inf_request, ctx);
- lateClassify(inf_request, ctx);
+ requiredClassify(inf_request, ctx);
// Create a Reply packet, with the same trans-id as the client's.
Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, inf_request->getTransid()));
if (!expr_ptr) {
continue;
}
- // Not the right time if on demand
- if ((*it)->getOnDemand()) {
+ // Not the right time if only when required
+ if ((*it)->getRequired()) {
continue;
}
// Evaluate the expression which can return false (no match),
}
void
-Dhcpv6Srv::lateClassify(const Pkt6Ptr& pkt, AllocEngine::ClientContext6& ctx) {
- // First collect on-demand classes
+Dhcpv6Srv::requiredClassify(const Pkt6Ptr& pkt, AllocEngine::ClientContext6& ctx) {
+ // First collect required classes
ClientClasses classes = pkt->getClasses(true);
Subnet6Ptr subnet = ctx.subnet_;
SharedNetwork6Ptr network;
subnet->getSharedNetwork(network);
if (network) {
- const ClientClasses& to_add = network->getOnDemandClasses();
+ const ClientClasses& to_add = network->getRequiredClasses();
for (ClientClasses::const_iterator cclass = to_add.cbegin();
cclass != to_add.cend(); ++cclass) {
classes.insert(*cclass);
}
// Followed by the subnet
- const ClientClasses& to_add = subnet->getOnDemandClasses();
+ const ClientClasses& to_add = subnet->getRequiredClasses();
for(ClientClasses::const_iterator cclass = to_add.cbegin();
cclass != to_add.cend(); ++cclass) {
classes.insert(*cclass);
resource.first,
false);
if (pool) {
- const ClientClasses& to_add = pool->getOnDemandClasses();
+ const ClientClasses& to_add = pool->getRequiredClasses();
for (ClientClasses::const_iterator cclass = to_add.cbegin();
cclass != to_add.cend(); ++cclass) {
classes.insert(*cclass);
cclass != classes.cend(); ++cclass) {
const ClientClassDefPtr class_def = dict->findClass(*cclass);
if (!class_def) {
- LOG_DEBUG(dhcp6_logger, DBG_DHCP6_BASIC, DHCP6_CLASS_UNKNOWN)
+ LOG_DEBUG(dhcp6_logger, DBG_DHCP6_BASIC, DHCP6_CLASS_UNDEFINED)
.arg(*cclass);
continue;
}
-// Copyright (C) 2011-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-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
void setReservedClientClasses(const Pkt6Ptr& pkt,
const AllocEngine::ClientContext6& ctx);
- /// @brief Assigns incoming packet to zero or more classes (late pass).
+ /// @brief Assigns incoming packet to zero or more classes (required pass).
///
- /// @note This late classification evaluates all classes which
- /// were marked for this deferred/on-demand pass. Classes are
- /// collected in the reversed order than output option processing.
+ /// @note This required classification evaluates all classes which
+ /// were marked for required evaluation. Classes are collected so
+ /// evaluated in the reversed order than output option processing.
///
- /// @note The eval-on-demand flag is related because it avoids
+ /// @note The only-if-required flag is related because it avoids
/// double evaluation (which is not forbidden).
///
/// @param pkt packet to be classified
/// @param ctx allocation context where to get informations
- void lateClassify(const Pkt6Ptr& pkt, AllocEngine::ClientContext6& ctx);
+ void requiredClassify(const Pkt6Ptr& pkt, AllocEngine::ClientContext6& ctx);
/// @brief Attempts to get a MAC/hardware address using configured sources
///
-// Copyright (C) 2016-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-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
EXPECT_FALSE(opt3);
}
-// Check that on-demand classes are not evaluated by classifyPacket
-TEST_F(ClassifyTest, onDemand) {
+// Check that only-if-required classes are not evaluated by classifyPacket
+TEST_F(ClassifyTest, required) {
IfaceMgrTestConfig test_config(true);
NakedDhcpv6Srv srv(0);
" \"interface\": \"eth1\" } ],"
"\"client-classes\": [ "
"{ \"name\": \"router\", "
- " \"eval-on-demand\": true, "
+ " \"only-if-required\": true, "
" \"option-data\": ["
" { \"name\": \"ipv6-forwarding\", "
" \"data\": \"true\" } ], "
EXPECT_FALSE(opt3);
}
-// Checks that when requested on-demand classes are still (but late) evaluated
-TEST_F(ClassifyTest, lateClassification) {
+// Checks that when only-if-required classes are still evaluated
+TEST_F(ClassifyTest, requiredClassification) {
IfaceMgrTestConfig test_config(true);
NakedDhcpv6Srv srv(0);
"\"subnet6\": [ "
"{ \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ], "
" \"subnet\": \"2001:db8:1::/48\", "
- " \"eval-client-classes\": [ \"router\" ], "
+ " \"require-client-classes\": [ \"router\" ], "
" \"interface\": \"eth1\" } ],"
"\"client-classes\": [ "
"{ \"name\": \"router\", "
- " \"eval-on-demand\": true, "
+ " \"only-if-required\": true, "
" \"option-data\": ["
" { \"name\": \"ipv6-forwarding\", "
" \"data\": \"true\" } ], "
EXPECT_FALSE(ipf3->readBoolean());
}
-// This test checks the precedence order in requested late evaluation.
+// This test checks the precedence order in required evaluation.
// This order is: shared-network > subnet > pools
TEST_F(ClassifyTest, precedenceNone) {
std::string config =
" {"
" \"name\": \"for-pool\","
" \"test\": \"member('all')\","
- " \"eval-on-demand\": true,"
+ " \"only-if-required\": true,"
" \"option-data\": [ {"
" \"name\": \"dns-servers\","
" \"data\": \"2001:db8:1::1\""
" {"
" \"name\": \"for-subnet\","
" \"test\": \"member('all')\","
- " \"eval-on-demand\": true,"
+ " \"only-if-required\": true,"
" \"option-data\": [ {"
" \"name\": \"dns-servers\","
" \"data\": \"2001:db8:1::2\""
" {"
" \"name\": \"for-network\","
" \"test\": \"member('all')\","
- " \"eval-on-demand\": true,"
+ " \"only-if-required\": true,"
" \"option-data\": [ {"
" \"name\": \"dns-servers\","
" \"data\": \"2001:db8:1::3\""
EXPECT_FALSE(opt);
}
-// This test checks the precedence order in requested late evaluation.
+// This test checks the precedence order in required evaluation.
// This order is: shared-network > subnet > pools
TEST_F(ClassifyTest, precedencePool) {
std::string config =
" {"
" \"name\": \"for-pool\","
" \"test\": \"member('all')\","
- " \"eval-on-demand\": true,"
+ " \"only-if-required\": true,"
" \"option-data\": [ {"
" \"name\": \"dns-servers\","
" \"data\": \"2001:db8:1::1\""
" {"
" \"name\": \"for-subnet\","
" \"test\": \"member('all')\","
- " \"eval-on-demand\": true,"
+ " \"only-if-required\": true,"
" \"option-data\": [ {"
" \"name\": \"dns-servers\","
" \"data\": \"2001:db8:1::2\""
" {"
" \"name\": \"for-network\","
" \"test\": \"member('all')\","
- " \"eval-on-demand\": true,"
+ " \"only-if-required\": true,"
" \"option-data\": [ {"
" \"name\": \"dns-servers\","
" \"data\": \"2001:db8:1::3\""
" \"id\": 1,"
" \"pools\": [ { "
" \"pool\": \"2001:db8:1::1 - 2001:db8:1::64\","
- " \"eval-client-classes\": [ \"for-pool\" ]"
+ " \"require-client-classes\": [ \"for-pool\" ]"
" } ]"
" } ]"
"} ],"
EXPECT_EQ("2001:db8:1::1", addrs[0].toText());
}
-// This test checks the precedence order in requested late evaluation.
+// This test checks the precedence order in required evaluation.
// This order is: shared-network > subnet > pools
TEST_F(ClassifyTest, precedenceSubnet) {
std::string config =
" {"
" \"name\": \"for-pool\","
" \"test\": \"member('all')\","
- " \"eval-on-demand\": true,"
+ " \"only-if-required\": true,"
" \"option-data\": [ {"
" \"name\": \"dns-servers\","
" \"data\": \"2001:db8:1::1\""
" {"
" \"name\": \"for-subnet\","
" \"test\": \"member('all')\","
- " \"eval-on-demand\": true,"
+ " \"only-if-required\": true,"
" \"option-data\": [ {"
" \"name\": \"dns-servers\","
" \"data\": \"2001:db8:1::2\""
" {"
" \"name\": \"for-network\","
" \"test\": \"member('all')\","
- " \"eval-on-demand\": true,"
+ " \"only-if-required\": true,"
" \"option-data\": [ {"
" \"name\": \"dns-servers\","
" \"data\": \"2001:db8:1::3\""
" \"subnet6\": [ { "
" \"subnet\": \"2001:db8:1::/64\","
" \"id\": 1,"
- " \"eval-client-classes\": [ \"for-subnet\" ],"
+ " \"require-client-classes\": [ \"for-subnet\" ],"
" \"pools\": [ { "
" \"pool\": \"2001:db8:1::1 - 2001:db8:1::64\","
- " \"eval-client-classes\": [ \"for-pool\" ]"
+ " \"require-client-classes\": [ \"for-pool\" ]"
" } ]"
" } ]"
"} ],"
EXPECT_EQ("2001:db8:1::2", addrs[0].toText());
}
-// This test checks the precedence order in requested late evaluation.
+// This test checks the precedence order in required evaluation.
// This order is: shared-network > subnet > pools
TEST_F(ClassifyTest, precedenceNetwork) {
std::string config =
" {"
" \"name\": \"for-pool\","
" \"test\": \"member('all')\","
- " \"eval-on-demand\": true,"
+ " \"only-if-required\": true,"
" \"option-data\": [ {"
" \"name\": \"dns-servers\","
" \"data\": \"2001:db8:1::1\""
" {"
" \"name\": \"for-subnet\","
" \"test\": \"member('all')\","
- " \"eval-on-demand\": true,"
+ " \"only-if-required\": true,"
" \"option-data\": [ {"
" \"name\": \"dns-servers\","
" \"data\": \"2001:db8:1::2\""
" {"
" \"name\": \"for-network\","
" \"test\": \"member('all')\","
- " \"eval-on-demand\": true,"
+ " \"only-if-required\": true,"
" \"option-data\": [ {"
" \"name\": \"dns-servers\","
" \"data\": \"2001:db8:1::3\""
"\"shared-networks\": [ {"
" \"name\": \"frog\","
" \"interface\": \"eth1\","
- " \"eval-client-classes\": [ \"for-network\" ],"
+ " \"require-client-classes\": [ \"for-network\" ],"
" \"subnet6\": [ { "
" \"subnet\": \"2001:db8:1::/64\","
" \"id\": 1,"
- " \"eval-client-classes\": [ \"for-subnet\" ],"
+ " \"require-client-classes\": [ \"for-subnet\" ],"
" \"pools\": [ { "
" \"pool\": \"2001:db8:1::1 - 2001:db8:1::64\","
- " \"eval-client-classes\": [ \"for-pool\" ]"
+ " \"require-client-classes\": [ \"for-pool\" ]"
" } ]"
" } ]"
"} ],"
-// Copyright (C) 2014-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-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
}
void
-Pkt::addClass(const std::string& client_class, bool deferred) {
- ClientClasses& classes = !deferred ? classes_ : on_demand_classes_;
+Pkt::addClass(const std::string& client_class, bool required) {
+ ClientClasses& classes = !required ? classes_ : required_classes_;
if (!classes.contains(client_class)) {
classes.insert(client_class);
}
-// Copyright (C) 2014-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-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
/// so I decided to stick with addClass().
///
/// @param client_class name of the class to be added
- /// @param deferred the class is marked for late evaluation
+ /// @param required the class is marked for required evaluation
void addClass(const isc::dhcp::ClientClass& client_class,
- bool deferred = false);
+ bool required = false);
/// @brief Returns the class set
///
/// @note This should be used only to iterate over the class set.
- /// @param deferred return classes or to be evaluated classes.
- /// @return if deferred is false (the default) the claases the
- /// packet belongs to else the classes which will be evaluated later.
- const ClientClasses& getClasses(bool deferred = false) const {
- return (!deferred ? classes_ : on_demand_classes_);
+ /// @param required return classes or required to be evaluated classes.
+ /// @return if required is false (the default) the classes the
+ /// packet belongs to else the classes which are required to be
+ /// evaluated.
+ const ClientClasses& getClasses(bool required = false) const {
+ return (!required ? classes_ : required_classes_);
}
/// @brief Unparsed data (in received packets).
/// @ref addClass should be used to operate on this field.
ClientClasses classes_;
- /// @brief Classes which will be evaluated later.
+ /// @brief Classes which are required to be evaluated.
///
/// The comment on @ref classes_ applies here.
///
/// Before output option processing these classes will be evaluated
/// and if evaluation status is true added to the previous collection.
- ClientClasses on_demand_classes_;
+ ClientClasses required_classes_;
/// @brief Collection of options present in this message.
///
-// 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
ClientClassDef::ClientClassDef(const std::string& name,
const ExpressionPtr& match_expr,
const CfgOptionPtr& cfg_option)
- : name_(name), match_expr_(match_expr), on_demand_(false),
+ : name_(name), match_expr_(match_expr), required_(false),
cfg_option_(cfg_option),
next_server_(asiolink::IOAddress::IPV4_ZERO_ADDRESS()) {
ClientClassDef::ClientClassDef(const ClientClassDef& rhs)
: name_(rhs.name_), match_expr_(ExpressionPtr()),
- on_demand_(false), cfg_option_(new CfgOption()),
+ required_(false), cfg_option_(new CfgOption()),
next_server_(asiolink::IOAddress::IPV4_ZERO_ADDRESS()) {
if (rhs.match_expr_) {
rhs.cfg_option_->copyTo(*cfg_option_);
}
- on_demand_ = rhs.on_demand_;
+ required_ = rhs.required_;
next_server_ = rhs.next_server_;
sname_ = rhs.sname_;
filename_ = rhs.filename_;
}
bool
-ClientClassDef::getOnDemand() const {
- return (on_demand_);
+ClientClassDef::getRequired() const {
+ return (required_);
}
void
-ClientClassDef::setOnDemand(bool on_demand) {
- on_demand_ = on_demand;
+ClientClassDef::setRequired(bool required) {
+ required_ = required;
}
const CfgOptionDefPtr&
((!cfg_option_def_ && !other.cfg_option_def_) ||
(cfg_option_def_ && other.cfg_option_def_ &&
(*cfg_option_def_ == *other.cfg_option_def_))) &&
- (on_demand_ == other.on_demand_) &&
+ (required_ == other.required_) &&
(next_server_ == other.next_server_) &&
(sname_ == other.sname_) &&
(filename_ == other.filename_));
if (!test_.empty()) {
result->set("test", Element::create(test_));
}
- // Set eval-on-demand
- if (on_demand_) {
- result->set("eval-on-demand", Element::create(on_demand_));
+ // Set only-if-required
+ if (required_) {
+ result->set("only-if-required", Element::create(required_));
}
// Set option-def (used only by DHCPv4)
if (cfg_option_def_ && (family == AF_INET)) {
ClientClassDictionary::addClass(const std::string& name,
const ExpressionPtr& match_expr,
const std::string& test,
- bool on_demand,
+ bool required,
const CfgOptionPtr& cfg_option,
CfgOptionDefPtr cfg_option_def,
asiolink::IOAddress next_server,
const std::string& filename) {
ClientClassDefPtr cclass(new ClientClassDef(name, match_expr, cfg_option));
cclass->setTest(test);
- cclass->setOnDemand(on_demand);
+ cclass->setRequired(required);
cclass->setCfgOptionDef(cfg_option_def);
cclass->setNextServer(next_server);
cclass->setSname(sname);
-// 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 test the original expression to assign the class
void setTest(const std::string& test);
- /// @brief Fetches the on demand flag
- bool getOnDemand() const;
+ /// @brief Fetches the only if required flag
+ bool getRequired() const;
- /// @brief Sets the on demand flag
- void setOnDemand(bool on_demand);
+ /// @brief Sets the only if required flag
+ void setRequired(bool required);
/// @brief Fetches the class's option definitions
const CfgOptionDefPtr& getCfgOptionDef() const;
/// this class.
std::string test_;
- /// @brief The on demand flag: when false (the defaul) membership
+ /// @brief The only if required flag: when false (the defaul) membership
/// is determined during classification so is for instance
/// available for subnet selection, when true membership is evaluated
- /// only if asked for and is usable only for option configuration.
- bool on_demand_;
+ /// only when required for and is usable only for option configuration.
+ bool required_;
/// @brief The option definition configuration for this class
CfgOptionDefPtr cfg_option_def_;
/// @param name Name to assign to this class
/// @param match_expr Expression the class will use to determine membership
/// @param test Original version of match_expr
- /// @param on_demand Original value of the on demand flag
+ /// @param required Original value of the only if required flag
/// @param options Collection of options members should be given
/// @param defs Option definitions (optional)
/// @param next_server next-server value for this class (optional)
/// dictionary. See @ref dhcp::ClientClassDef::ClientClassDef() for
/// others.
void addClass(const std::string& name, const ExpressionPtr& match_expr,
- const std::string& test, bool on_demand,
+ const std::string& test, bool required,
const CfgOptionPtr& options,
CfgOptionDefPtr defs = CfgOptionDefPtr(),
asiolink::IOAddress next_server = asiolink::IOAddress("0.0.0.0"),
-// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2017-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
}
void
-Network::deferClientClass(const isc::dhcp::ClientClass& class_name) {
- if (!on_demand_classes_.contains(class_name)) {
- on_demand_classes_.insert(class_name);
+Network::requireClientClass(const isc::dhcp::ClientClass& class_name) {
+ if (!required_classes_.contains(class_name)) {
+ required_classes_.insert(class_name);
}
}
const ClientClasses&
-Network::getOnDemandClasses() const {
- return (on_demand_classes_);
+Network::getRequiredClasses() const {
+ return (required_classes_);
}
ElementPtr
map->set("client-class", Element::create(cclass));
}
- // Set eval-client-classes
- const ClientClasses& classes = getOnDemandClasses();
+ // Set required-client-classes
+ const ClientClasses& classes = getRequiredClasses();
if (!classes.empty()) {
ElementPtr class_list = Element::createList();
for (ClientClasses::const_iterator it = classes.cbegin();
it != classes.cend(); ++it) {
class_list->add(Element::create(*it));
}
- map->set("eval-client-classes", class_list);
+ map->set("required-client-classes", class_list);
}
// Set renew-timer
-// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2017-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 class_name client class to be supported by this network
void allowClientClass(const isc::dhcp::ClientClass& class_name);
- /// @brief Adds class class_name to classes to be evaluated later
+ /// @brief Adds class class_name to classes required to be evaluated.
///
- /// @param class_name client class to be evaluated later
- void deferClientClass(const isc::dhcp::ClientClass& class_name);
+ /// @param class_name client class required to be evaluated
+ void requireClientClass(const isc::dhcp::ClientClass& class_name);
- /// @brief Returns classes which will be evaluated later
- const isc::dhcp::ClientClasses& getOnDemandClasses() const;
+ /// @brief Returns classes which are required to be evaluated
+ const isc::dhcp::ClientClasses& getRequiredClasses() const;
/// @brief returns the client class
///
/// which means that any client is allowed, regardless of its class.
ClientClass client_class_;
- /// @brief On demand classes
+ /// @brief Required classes
///
/// If the network is selected these classes will be added to the
- /// incoming packet and evaluated later.
- ClientClasses on_demand_classes_;
+ /// incoming packet and their evaluation will be required.
+ ClientClasses required_classes_;
/// @brief a Triplet (min/default/max) holding allowed renew timer values
Triplet<uint32_t> t1_;
-// 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
opts_parser.parse(options, option_data);
}
- // Let's try to parse the eval-on-demand flag
- bool on_demand = false;
- if (class_def_cfg->contains("eval-on-demand")) {
- on_demand = getBoolean(class_def_cfg, "eval-on-demand");
+ // Let's try to parse the only-if-required flag
+ bool required = false;
+ if (class_def_cfg->contains("only-if-required")) {
+ required = getBoolean(class_def_cfg, "only-if-required");
}
// Let's try to parse the next-server field
// Add the client class definition
try {
- class_dictionary->addClass(name, match_expr, test, on_demand, options,
+ class_dictionary->addClass(name, match_expr, test, required, options,
defs, next_server, sname, filename);
} catch (const std::exception& ex) {
isc_throw(DhcpConfigError, "Can't add class: " << ex.what()
}
}
- // Try setting up on demand client classes.
- ConstElementPtr class_list = pool_structure->get("eval-client-classes");
+ // Try setting up required client classes.
+ ConstElementPtr class_list = pool_structure->get("required-client-classes");
if (class_list) {
const std::vector<data::ElementPtr>& classes = class_list->listValue();
for (auto cclass = classes.cbegin();
isc_throw(DhcpConfigError, "invalid class name ("
<< (*cclass)->getPosition() << ")");
}
- pool->deferClientClass((*cclass)->stringValue());
+ pool->requireClientClass((*cclass)->stringValue());
}
}
}
subnet4->allowClientClass(client_class);
}
- // Try setting up on demand client classes.
- ConstElementPtr class_list = params->get("eval-client-classes");
+ // Try setting up required client classes.
+ ConstElementPtr class_list = params->get("required-client-classes");
if (class_list) {
const std::vector<data::ElementPtr>& classes = class_list->listValue();
for (auto cclass = classes.cbegin();
isc_throw(DhcpConfigError, "invalid class name ("
<< (*cclass)->getPosition() << ")");
}
- subnet4->deferClientClass((*cclass)->stringValue());
+ subnet4->requireClientClass((*cclass)->stringValue());
}
}
client_class_ = client_class;
}
- ConstElementPtr class_list = pd_pool_->get("eval-client-classes");
+ ConstElementPtr class_list = pd_pool_->get("required-client-classes");
// Check the pool parameters. It will throw an exception if any
// of the required parameters are invalid.
isc_throw(DhcpConfigError, "invalid class name ("
<< (*cclass)->getPosition() << ")");
}
- pool_->deferClientClass((*cclass)->stringValue());
+ pool_->requireClientClass((*cclass)->stringValue());
}
}
subnet6->allowClientClass(client_class);
}
- // Try setting up on demand client classes.
- ConstElementPtr class_list = params->get("eval-client-classes");
+ // Try setting up required client classes.
+ ConstElementPtr class_list = params->get("required-client-classes");
if (class_list) {
const std::vector<data::ElementPtr>& classes = class_list->listValue();
for (auto cclass = classes.cbegin();
isc_throw(DhcpConfigError, "invalid class name ("
<< (*cclass)->getPosition() << ")");
}
- subnet6->deferClientClass((*cclass)->stringValue());
+ subnet6->requireClientClass((*cclass)->stringValue());
}
}
-// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2017-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
}
}
- if (shared_network_data->contains("eval-client-classes")) {
+ if (shared_network_data->contains("required-client-classes")) {
const std::vector<data::ElementPtr>& class_list =
- shared_network_data->get("eval-client-classes")->listValue();
+ shared_network_data->get("required-client-classes")->listValue();
for (auto cclass = class_list.cbegin();
cclass != class_list.cend(); ++cclass) {
if (((*cclass)->getType() != Element::string) ||
isc_throw(DhcpConfigError, "invalid class name ("
<< (*cclass)->getPosition() << ")");
}
- shared_network->deferClientClass((*cclass)->stringValue());
+ shared_network->requireClientClass((*cclass)->stringValue());
}
}
}
}
- if (shared_network_data->contains("eval-client-classes")) {
+ if (shared_network_data->contains("required-client-classes")) {
const std::vector<data::ElementPtr>& class_list =
- shared_network_data->get("eval-client-classes")->listValue();
+ shared_network_data->get("required-client-classes")->listValue();
for (auto cclass = class_list.cbegin();
cclass != class_list.cend(); ++cclass) {
if (((*cclass)->getType() != Element::string) ||
isc_throw(DhcpConfigError, "invalid class name ("
<< (*cclass)->getPosition() << ")");
}
- shared_network->deferClientClass((*cclass)->stringValue());
+ shared_network->requireClientClass((*cclass)->stringValue());
}
}
map->set("client-class", Element::create(cclass));
}
- // Set eval-client-classes
- const ClientClasses& classes = getOnDemandClasses();
+ // Set required-client-classes
+ const ClientClasses& classes = getRequiredClasses();
if (!classes.empty()) {
ElementPtr class_list =Element::createList();
for (ClientClasses::const_iterator it = classes.cbegin();
it != classes.cend(); ++it) {
class_list->add(Element::create(*it));
}
- map->set("eval-client-classes", class_list);
+ map->set("required-client-classes", class_list);
}
return (map);
return (client_class_);
}
- /// @brief Adds class class_name to classes to be evaluated later
+ /// @brief Adds class class_name to classes required to be evaluated
///
- /// @param class_name client class to be evaluated later
- void deferClientClass(const ClientClass& class_name) {
- if (!on_demand_classes_.contains(class_name)) {
- on_demand_classes_.insert(class_name);
+ /// @param class_name client class required to be evaluated
+ void requireClientClass(const ClientClass& class_name) {
+ if (!required_classes_.contains(class_name)) {
+ required_classes_.insert(class_name);
}
}
- /// @brief Returns classes which will be evaluated later
- const ClientClasses& getOnDemandClasses() const {
- return (on_demand_classes_);
+ /// @brief Returns classes which are required to be evaluated
+ const ClientClasses& getRequiredClasses() const {
+ return (required_classes_);
}
/// @brief returns the last address that was tried from this pool
/// @ref Network::client_class_
ClientClass client_class_;
- /// @brief On demand classes
+ /// @brief Required classes
///
- /// @ref isc::dhcp::Network::on_demand_classes
- ClientClasses on_demand_classes_;
+ /// @ref isc::dhcp::Network::required_classes
+ ClientClasses required_classes_;
/// @brief Pointer to the user context (may be NULL)
data::ConstElementPtr user_context_;
subnet2->setIface("lo");
subnet2->setRelayInfo(IOAddress("10.0.0.1"));
subnet3->setIface("eth1");
- subnet3->deferClientClass("foo");
- subnet3->deferClientClass("bar");
+ subnet3->requireClientClass("foo");
+ subnet3->requireClientClass("bar");
cfg.add(subnet1);
cfg.add(subnet2);
" \"reservation-mode\": \"all\",\n"
" \"option-data\": [ ],\n"
" \"pools\": [ ]\n,"
- " \"eval-client-classes\": [ \"foo\", \"bar\" ]\n"
+ " \"required-client-classes\": [ \"foo\", \"bar\" ]\n"
"} ]\n";
runToElementTest<CfgSubnets4>(expected, cfg);
}
Pool4Ptr pool1(new Pool4(IOAddress("192.0.2.1"), IOAddress("192.0.2.10")));
Pool4Ptr pool2(new Pool4(IOAddress("192.0.2.64"), 26));
pool2->allowClientClass("bar");
- pool2->deferClientClass("foo");
+ pool2->requireClientClass("foo");
subnet->addPool(pool1);
subnet->addPool(pool2);
" \"option-data\": [ ],\n"
" \"pool\": \"192.0.2.64/26\",\n"
" \"client-class\": \"bar\",\n"
- " \"eval-client-classes\": [ \"foo\" ]\n"
+ " \"required-client-classes\": [ \"foo\" ]\n"
" }\n"
" ]\n"
"} ]\n";
-// Copyright (C) 2014-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-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
subnet2->setIface("lo");
subnet2->setRelayInfo(IOAddress("2001:db8:ff::2"));
subnet3->setIface("eth1");
- subnet3->deferClientClass("foo");
- subnet3->deferClientClass("bar");
+ subnet3->requireClientClass("foo");
+ subnet3->requireClientClass("bar");
cfg.add(subnet1);
cfg.add(subnet2);
" \"pools\": [ ],\n"
" \"pd-pools\": [ ],\n"
" \"option-data\": [ ],\n"
- " \"eval-client-classes\": [ \"foo\", \"bar\" ]\n"
+ " \"required-client-classes\": [ \"foo\", \"bar\" ]\n"
"} ]\n";
runToElementTest<CfgSubnets6>(expected, cfg);
}
IOAddress("2001:db8:1::199")));
Pool6Ptr pool2(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:1::"), 64));
pool2->allowClientClass("bar");
- pool2->deferClientClass("foo");
+ pool2->requireClientClass("foo");
subnet->addPool(pool1);
subnet->addPool(pool2);
" \"pool\": \"2001:db8:1:1::/64\",\n"
" \"option-data\": [ ],\n"
" \"client-class\": \"bar\",\n"
- " \"eval-client-classes\": [ \"foo\" ]\n"
+ " \"required-client-classes\": [ \"foo\" ]\n"
" }\n"
" ],\n"
" \"pd-pools\": [ ],\n"
IOAddress("2001:db8:2::"), 48, 64));
Pool6Ptr pdpool2(new Pool6(IOAddress("2001:db8:3::"), 48, 56,
IOAddress("2001:db8:3::"), 64));
- pdpool1->deferClientClass("bar");
+ pdpool1->requireClientClass("bar");
pdpool2->allowClientClass("bar");
subnet->addPool(pdpool1);
" \"prefix-len\": 48,\n"
" \"delegated-len\": 64,\n"
" \"option-data\": [ ],\n"
- " \"eval-client-classes\": [ \"bar\" ]\n"
+ " \"required-client-classes\": [ \"bar\" ]\n"
" },{\n"
" \"prefix\": \"2001:db8:3::\",\n"
" \"prefix-len\": 48,\n"
-// 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
EXPECT_TRUE(*cclass == *cclass2);
EXPECT_FALSE(*cclass != *cclass2);
- // Verify the on_demand flag is enough to make classes not equal.
- EXPECT_FALSE(cclass->getOnDemand());
- cclass2->setOnDemand(true);
- EXPECT_TRUE(cclass2->getOnDemand());
+ // Verify the required flag is enough to make classes not equal.
+ EXPECT_FALSE(cclass->getRequired());
+ cclass2->setRequired(true);
+ EXPECT_TRUE(cclass2->getRequired());
EXPECT_FALSE(*cclass == *cclass2);
EXPECT_TRUE(*cclass != *cclass2);
ASSERT_NO_THROW(cclass.reset(new ClientClassDef(name, expr)));
// Let's checks that it doesn't return any nonsense
- EXPECT_FALSE(cclass->getOnDemand());
+ EXPECT_FALSE(cclass->getRequired());
EXPECT_FALSE(cclass->getCfgOptionDef());
string empty;
ASSERT_EQ(IOAddress("0.0.0.0"), cclass->getNextServer());
// Verify we can create a class with a name, expression, and no cfg_option
ASSERT_NO_THROW(cclass.reset(new ClientClassDef(name, expr)));
- cclass->setOnDemand(true);
+ cclass->setRequired(true);
string sname = "This is a very long string that can be a server name";
string filename = "this-is-a-slightly-longish-name-of-a-file.txt";
cclass->setFilename(filename);
// Let's checks that it doesn't return any nonsense
- EXPECT_TRUE(cclass->getOnDemand());
+ EXPECT_TRUE(cclass->getRequired());
EXPECT_EQ(IOAddress("1.2.3.4"), cclass->getNextServer());
EXPECT_EQ(sname, cclass->getSname());
EXPECT_EQ(filename, cclass->getFilename());
ASSERT_NO_THROW(cclass.reset(new ClientClassDef(name, expr)));
std::string test = "option[12].text == 'foo'";
cclass->setTest(test);
- cclass->setOnDemand(true);
+ cclass->setRequired(true);
std::string next_server = "1.2.3.4";
cclass->setNextServer(IOAddress(next_server));
std::string sname = "my-server.example.com";
std::string expected = "{\n"
"\"name\": \"" + name + "\",\n"
"\"test\": \"" + test + "\",\n"
- "\"eval-on-demand\": true,\n"
+ "\"only-if-required\": true,\n"
"\"next-server\": \"" + next_server + "\",\n"
"\"server-hostname\": \"" + sname + "\",\n"
"\"boot-file-name\": \"" + filename + "\",\n"
EXPECT_TRUE(pool->clientSupported(three_classes));
}
-// This test checks that handling for eval-client-classes is valid.
-TEST(Pool4Test, onDemandClasses) {
+// This test checks that handling for required-client-classes is valid.
+TEST(Pool4Test, requiredClasses) {
// Create a pool.
Pool4Ptr pool(new Pool4(IOAddress("192.0.2.0"),
IOAddress("192.0.2.255")));
- // This client starts with no deferred classes.
- EXPECT_TRUE(pool->getOnDemandClasses().empty());
+ // This client starts with no required classes.
+ EXPECT_TRUE(pool->getRequiredClasses().empty());
// Add the first class
- pool->deferClientClass("router");
- EXPECT_EQ(1, pool->getOnDemandClasses().size());
+ pool->requireClientClass("router");
+ EXPECT_EQ(1, pool->getRequiredClasses().size());
// Add a second class
- pool->deferClientClass("modem");
- EXPECT_EQ(2, pool->getOnDemandClasses().size());
- EXPECT_TRUE(pool->getOnDemandClasses().contains("router"));
- EXPECT_TRUE(pool->getOnDemandClasses().contains("modem"));
- EXPECT_FALSE(pool->getOnDemandClasses().contains("foo"));
+ pool->requireClientClass("modem");
+ EXPECT_EQ(2, pool->getRequiredClasses().size());
+ EXPECT_TRUE(pool->getRequiredClasses().contains("router"));
+ EXPECT_TRUE(pool->getRequiredClasses().contains("modem"));
+ EXPECT_FALSE(pool->getRequiredClasses().contains("foo"));
// Check that it's ok to add the same class repeatedly
- EXPECT_NO_THROW(pool->deferClientClass("foo"));
- EXPECT_NO_THROW(pool->deferClientClass("foo"));
- EXPECT_NO_THROW(pool->deferClientClass("foo"));
+ EXPECT_NO_THROW(pool->requireClientClass("foo"));
+ EXPECT_NO_THROW(pool->requireClientClass("foo"));
+ EXPECT_NO_THROW(pool->requireClientClass("foo"));
- // Check that 'foo' is marked for late evaluation
- EXPECT_TRUE(pool->getOnDemandClasses().contains("foo"));
+ // Check that 'foo' is marked for required evaluation
+ EXPECT_TRUE(pool->getRequiredClasses().contains("foo"));
}
// This test checks that handling for last allocated address/prefix is valid.
EXPECT_TRUE(pool.clientSupported(three_classes));
}
-// This test checks that handling for eval-client-classes is valid.
-TEST(Pool6Test, onDemandClasses) {
+// This test checks that handling for required-client-classes is valid.
+TEST(Pool6Test, requiredClasses) {
// Create a pool.
Pool6 pool(Lease::TYPE_NA, IOAddress("2001:db8::1"),
IOAddress("2001:db8::2"));
- // This client starts with no deferred classes.
- EXPECT_TRUE(pool.getOnDemandClasses().empty());
+ // This client starts with no required classes.
+ EXPECT_TRUE(pool.getRequiredClasses().empty());
// Add the first class
- pool.deferClientClass("router");
- EXPECT_EQ(1, pool.getOnDemandClasses().size());
+ pool.requireClientClass("router");
+ EXPECT_EQ(1, pool.getRequiredClasses().size());
// Add a second class
- pool.deferClientClass("modem");
- EXPECT_EQ(2, pool.getOnDemandClasses().size());
- EXPECT_TRUE(pool.getOnDemandClasses().contains("router"));
- EXPECT_TRUE(pool.getOnDemandClasses().contains("modem"));
- EXPECT_FALSE(pool.getOnDemandClasses().contains("foo"));
+ pool.requireClientClass("modem");
+ EXPECT_EQ(2, pool.getRequiredClasses().size());
+ EXPECT_TRUE(pool.getRequiredClasses().contains("router"));
+ EXPECT_TRUE(pool.getRequiredClasses().contains("modem"));
+ EXPECT_FALSE(pool.getRequiredClasses().contains("foo"));
// Check that it's ok to add the same class repeatedly
- EXPECT_NO_THROW(pool.deferClientClass("foo"));
- EXPECT_NO_THROW(pool.deferClientClass("foo"));
- EXPECT_NO_THROW(pool.deferClientClass("foo"));
+ EXPECT_NO_THROW(pool.requireClientClass("foo"));
+ EXPECT_NO_THROW(pool.requireClientClass("foo"));
+ EXPECT_NO_THROW(pool.requireClientClass("foo"));
- // Check that 'foo' is marked for late evaluation
- EXPECT_TRUE(pool.getOnDemandClasses().contains("foo"));
+ // Check that 'foo' is marked for required evaluation
+ EXPECT_TRUE(pool.getRequiredClasses().contains("foo"));
}
// This test checks that handling for last allocated address/prefix is valid.
-// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2017-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
" \"server-hostname\": \"\","
" \"boot-file-name\": \"\","
" \"client-class\": \"\","
- " \"eval-client-classes\": []\n,"
+ " \"required-client-classes\": []\n,"
" \"reservation-mode\": \"all\","
" \"4o6-interface\": \"\","
" \"4o6-interface-id\": \"\","
" \"server-hostname\": \"\","
" \"boot-file-name\": \"\","
" \"client-class\": \"\","
- " \"eval-client-classes\": []\n,"
+ " \"required-client-classes\": []\n,"
" \"reservation-mode\": \"all\","
" \"4o6-interface\": \"\","
" \"4o6-interface-id\": \"\","
" \"preferred-lifetime\": 300,"
" \"valid-lifetime\": 400,"
" \"client-class\": \"\","
- " \"eval-client-classes\": []\n,"
+ " \"required-client-classes\": []\n,"
" \"reservation-mode\": \"all\","
" \"decline-probation-period\": 86400,"
" \"dhcp4o6-port\": 0,"
" \"preferred-lifetime\": 30,"
" \"valid-lifetime\": 40,"
" \"client-class\": \"\","
- " \"eval-client-classes\": []\n,"
+ " \"required-client-classes\": []\n,"
" \"reservation-mode\": \"all\","
" \"decline-probation-period\": 86400,"
" \"dhcp4o6-port\": 0,"
EXPECT_EQ("alpha", network->getClientClass());
}
-// This test verifies that it's possible to specify eval-client-classes
+// This test verifies that it's possible to specify required-client-classes
// on shared-network level.
TEST_F(SharedNetwork6ParserTest, evalClientClasses) {
std::string config = getWorkingConfig();
ElementPtr class_list = Element::createList();
class_list->add(Element::create("alpha"));
class_list->add(Element::create("beta"));
- config_element->set("eval-client-classes", class_list);
+ config_element->set("required-client-classes", class_list);
// Parse configuration specified above.
SharedNetwork6Parser parser;
network = parser.parse(config_element);
ASSERT_TRUE(network);
- const ClientClasses& classes = network->getOnDemandClasses();
+ const ClientClasses& classes = network->getRequiredClasses();
EXPECT_EQ(2, classes.size());
EXPECT_EQ("alpha, beta", classes.toText());
}
-// This test verifies that bad eval-client-classes configs raise
+// This test verifies that bad required-client-classes configs raise
// expected errors.
TEST_F(SharedNetwork6ParserTest, badEvalClientClasses) {
std::string config = getWorkingConfig();
ElementPtr class_list = Element::createList();
class_list->add(Element::create("alpha"));
class_list->add(Element::create(1234));
- config_element->set("eval-client-classes", class_list);
+ config_element->set("required-client-classes", class_list);
// Parse configuration specified above.
SharedNetwork6Parser parser;
-// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2017-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
network->setValid(200);
network->setMatchClientId(false);
- network->deferClientClass("foo");
+ network->requireClientClass("foo");
// Add several subnets.
Subnet4Ptr subnet1(new Subnet4(IOAddress("10.0.0.0"), 8, 10, 20, 30,
" \"valid-lifetime\": 30\n"
" }\n"
" ],\n"
- " \"eval-client-classes\": [ \"foo\" ],\n"
+ " \"required-client-classes\": [ \"foo\" ],\n"
" \"valid-lifetime\": 200\n"
"}\n";
network->setPreferred(200);
network->setValid(300);
network->setRapidCommit(true);
- network->deferClientClass("foo");
+ network->requireClientClass("foo");
// Add several subnets.
Subnet6Ptr subnet1(new Subnet6(IOAddress("2001:db8:1::"), 64, 10, 20, 30,
" \"valid-lifetime\": 40\n"
" }\n"
" ],\n"
- " \"eval-client-classes\": [ \"foo\" ],\n"
+ " \"required-client-classes\": [ \"foo\" ],\n"
" \"valid-lifetime\": 300\n"
"}\n";