mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-29 13:07:50 +00:00
[#3587] Updated kea-dhcp6 parser
Changes to be committed: doc/examples/kea6/all-keys.json doc/examples/kea6/classify2.json src/bin/admin/tests/mysql_tests.sh.in src/bin/dhcp6/dhcp6_lexer.cc src/bin/dhcp6/dhcp6_lexer.ll src/bin/dhcp6/dhcp6_parser.cc src/bin/dhcp6/dhcp6_parser.h src/bin/dhcp6/dhcp6_parser.yy src/bin/dhcp6/tests/config_parser_unittest.cc
This commit is contained in:
parent
3328540c76
commit
9acfe8732f
@ -67,10 +67,10 @@
|
||||
|
||||
// Boolean flag indicating whether the class expression is only evaluated
|
||||
// when the class is required, e.g. the selected address pool configuration
|
||||
// includes this class name in its "require-client-classes" list. The
|
||||
// includes this class name in its "evaluate-additional-classes" list. The
|
||||
// default value false means that the class test expression must
|
||||
// always be evaluated.
|
||||
"only-if-required": true,
|
||||
"only-in-additional-list": true,
|
||||
|
||||
// Class selection expression.
|
||||
"test": "member('ALL')"
|
||||
@ -901,7 +901,7 @@
|
||||
|
||||
// List of client classes which must be evaluated when this shared
|
||||
// network is selected for client assignments.
|
||||
"require-client-classes": [ "late" ],
|
||||
"evaluate-additional-classes": [ "late" ],
|
||||
|
||||
// Turn off storage of extended information (e.g. relay agent
|
||||
// information) with each lease for this shared network.
|
||||
@ -1043,7 +1043,7 @@
|
||||
|
||||
// List of client classes which must be evaluated
|
||||
// when this prefix pool is selected for client assignments.
|
||||
"require-client-classes": [],
|
||||
"evaluate-additional-classes": [],
|
||||
|
||||
// PD-pool identifier used to enable statistics for this pd-pool.
|
||||
// The pd-pool ID does not need to be unique within the subnet
|
||||
@ -1080,7 +1080,7 @@
|
||||
|
||||
// List of client classes which must be evaluated when this pool
|
||||
// is selected for client assignments.
|
||||
"require-client-classes": [ "late" ]
|
||||
"evaluate-additional-classes": [ "late" ]
|
||||
},
|
||||
{
|
||||
// Restricts this pool to only be used for client
|
||||
@ -1095,7 +1095,7 @@
|
||||
|
||||
// List of client classes which must be evaluated when this pool
|
||||
// is selected for client assignments.
|
||||
"require-client-classes": [],
|
||||
"evaluate-additional-classes": [],
|
||||
|
||||
// Pool identifier used to enable statistics for this pool.
|
||||
// The pool ID does not need to be unique within the subnet
|
||||
@ -1195,7 +1195,7 @@
|
||||
|
||||
// List of client classes which must be evaluated when this subnet
|
||||
// is selected for client assignments.
|
||||
"require-client-classes": [ "late" ],
|
||||
"evaluate-additional-classes": [ "late" ],
|
||||
|
||||
// Subnet prefix.
|
||||
"subnet": "2001:db8::/32",
|
||||
|
@ -30,7 +30,7 @@
|
||||
// is not yet defined.
|
||||
{
|
||||
"name": "second_subnet",
|
||||
"only-if-required": true,
|
||||
"only-in-additional-list": true,
|
||||
"test": "member('ALL')",
|
||||
"option-data": [{
|
||||
"name": "dns-servers",
|
||||
@ -86,7 +86,7 @@
|
||||
"client-classes": [ "cable-modems" ]
|
||||
} ],
|
||||
"interface": "eth0",
|
||||
"require-client-classes": [ "second_subnet" ]
|
||||
"evaluate-additional-classes": [ "second_subnet" ]
|
||||
},
|
||||
// The following subnet contains a pool with a class constraint: only
|
||||
// clients which belong to the class are allowed to use this pool.
|
||||
|
@ -961,10 +961,10 @@ mysql_upgrade_24_to_25_test() {
|
||||
mysql_upgrade_25_to_26_test() {
|
||||
|
||||
# client_classes been added to dhcp4_options
|
||||
check_table_column client_classes dhcp4_options;
|
||||
check_table_column client_classes dhcp4_options
|
||||
|
||||
# client_classes been added to dhcp6_options
|
||||
check_table_column client_classes dhcp6_options;
|
||||
check_table_column client_classes dhcp6_options
|
||||
|
||||
# check rename of require_client_classes to evaluate_additaionl_classes.
|
||||
check_table_column evaluate_additional_classes dhcp4_shared_network
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1625,6 +1625,18 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu]
|
||||
}
|
||||
}
|
||||
|
||||
\"evaluate-additional-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_EVALUATE_ADDITIONAL_CLASSES(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp6Parser::make_STRING("evaluate-additional-classes", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"client-class\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser6Context::SUBNET6:
|
||||
@ -1665,6 +1677,15 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu]
|
||||
}
|
||||
}
|
||||
|
||||
\"only-in-additional-list\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser6Context::CLIENT_CLASSES:
|
||||
return isc::dhcp::Dhcp6Parser::make_ONLY_IN_ADDITIONAL_LIST(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp6Parser::make_STRING("only-in-additional-list", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"reservations\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser6Context::DHCP6:
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -177,9 +177,11 @@ using namespace std;
|
||||
|
||||
CLIENT_CLASSES "client-classes"
|
||||
REQUIRE_CLIENT_CLASSES "require-client-classes"
|
||||
EVALUATE_ADDITIONAL_CLASSES "evaluate-additional-classes"
|
||||
TEST "test"
|
||||
TEMPLATE_TEST "template-test"
|
||||
ONLY_IF_REQUIRED "only-if-required"
|
||||
ONLY_IN_ADDITIONAL_LIST "only-in-additional-list"
|
||||
CLIENT_CLASS "client-class"
|
||||
POOL_ID "pool-id"
|
||||
|
||||
@ -1617,6 +1619,7 @@ subnet6_param: preferred_lifetime
|
||||
| rapid_commit
|
||||
| client_class
|
||||
| require_client_classes
|
||||
| evaluate_additional_classes
|
||||
| reservations
|
||||
| reservations_global
|
||||
| reservations_in_subnet
|
||||
@ -1683,6 +1686,7 @@ client_class: CLIENT_CLASS {
|
||||
ctx.leave();
|
||||
};
|
||||
|
||||
// Deprecated.
|
||||
require_client_classes: REQUIRE_CLIENT_CLASSES {
|
||||
ctx.unique("require-client-classes", ctx.loc2pos(@1));
|
||||
ElementPtr c(new ListElement(ctx.loc2pos(@1)));
|
||||
@ -1694,6 +1698,18 @@ require_client_classes: REQUIRE_CLIENT_CLASSES {
|
||||
ctx.leave();
|
||||
};
|
||||
|
||||
evaluate_additional_classes: EVALUATE_ADDITIONAL_CLASSES {
|
||||
ctx.unique("evaluate-additional-classes", ctx.loc2pos(@1));
|
||||
ElementPtr c(new ListElement(ctx.loc2pos(@1)));
|
||||
ctx.stack_.back()->set("evaluate-additional-classes", c);
|
||||
ctx.stack_.push_back(c);
|
||||
ctx.enter(ctx.NO_KEYWORD);
|
||||
} COLON list_strings {
|
||||
ctx.stack_.pop_back();
|
||||
ctx.leave();
|
||||
};
|
||||
|
||||
|
||||
reservations_global: RESERVATIONS_GLOBAL COLON BOOLEAN {
|
||||
ctx.unique("reservations-global", ctx.loc2pos(@1));
|
||||
ElementPtr b(new BoolElement($3, ctx.loc2pos(@3)));
|
||||
@ -1778,6 +1794,7 @@ shared_network_param: name
|
||||
| reservations_out_of_pool
|
||||
| client_class
|
||||
| require_client_classes
|
||||
| evaluate_additional_classes
|
||||
| preferred_lifetime
|
||||
| min_preferred_lifetime
|
||||
| max_preferred_lifetime
|
||||
@ -2143,6 +2160,7 @@ pool_param: pool_entry
|
||||
| option_data_list
|
||||
| client_class
|
||||
| require_client_classes
|
||||
| evaluate_additional_classes
|
||||
| user_context
|
||||
| comment
|
||||
| unknown_map_entry
|
||||
@ -2280,6 +2298,7 @@ pd_pool_param: pd_prefix
|
||||
| option_data_list
|
||||
| client_class
|
||||
| require_client_classes
|
||||
| evaluate_additional_classes
|
||||
| excluded_prefix
|
||||
| excluded_prefix_len
|
||||
| user_context
|
||||
@ -2535,6 +2554,7 @@ client_class_param: client_class_name
|
||||
| client_class_test
|
||||
| client_class_template_test
|
||||
| only_if_required
|
||||
| only_in_additional_list
|
||||
| option_data_list
|
||||
| user_context
|
||||
| comment
|
||||
@ -2567,12 +2587,19 @@ client_class_template_test: TEMPLATE_TEST {
|
||||
ctx.leave();
|
||||
};
|
||||
|
||||
// Deprecated
|
||||
only_if_required: ONLY_IF_REQUIRED COLON BOOLEAN {
|
||||
ctx.unique("only-if-required", ctx.loc2pos(@1));
|
||||
ElementPtr b(new BoolElement($3, ctx.loc2pos(@3)));
|
||||
ctx.stack_.back()->set("only-if-required", b);
|
||||
};
|
||||
|
||||
only_in_additional_list: ONLY_IN_ADDITIONAL_LIST COLON BOOLEAN {
|
||||
ctx.unique("only-in-additional-list", ctx.loc2pos(@1));
|
||||
ElementPtr b(new BoolElement($3, ctx.loc2pos(@3)));
|
||||
ctx.stack_.back()->set("only-in-additional-list", b);
|
||||
};
|
||||
|
||||
// --- end of client classes ---------------------------------
|
||||
|
||||
// --- server-id ---------------------------------------------
|
||||
|
@ -9096,4 +9096,126 @@ TEST_F(Dhcp6ParserTest, optionClientClassesDuplicateCheck) {
|
||||
EXPECT_EQ(*cclasses, "bar");
|
||||
}
|
||||
|
||||
// This test verifies that require-client-classes gets translated
|
||||
// to evaluate-additional-classes.
|
||||
TEST_F(Dhcp6ParserTest, deprecatedRequireClientClassesCheck) {
|
||||
std::string config = "{ " + genIfaceConfig() + ","
|
||||
R"^(
|
||||
"rebind-timer": 2000,
|
||||
"renew-timer": 1000,
|
||||
"subnet6": [{
|
||||
"require-client-classes": [ "foo" ],
|
||||
"pools": [{ "pool": "2001:db8::/64" }],
|
||||
"id": 1,
|
||||
"subnet": "2001:db8::/64"
|
||||
}],
|
||||
"valid-lifetime": 400
|
||||
})^";
|
||||
|
||||
ConstElementPtr json;
|
||||
ASSERT_NO_THROW(json = parseDHCP6(config));
|
||||
extractConfig(config);
|
||||
|
||||
ConstElementPtr status;
|
||||
ASSERT_NO_THROW(status = configureDhcp6Server(srv_, json));
|
||||
checkResult(status, 0);
|
||||
|
||||
Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->
|
||||
getCfgSubnets6()->selectSubnet(IOAddress("2001:db8::"));
|
||||
ASSERT_TRUE(subnet);
|
||||
|
||||
const auto& cclass_list = subnet->getAdditionalClasses();
|
||||
EXPECT_EQ(1, cclass_list.size());
|
||||
auto cclasses = cclass_list.begin();
|
||||
EXPECT_EQ(*cclasses, "foo");
|
||||
}
|
||||
|
||||
// This test verifies that users cannot specify both
|
||||
// require-client-classes and evaluate-addtional-classes.
|
||||
TEST_F(Dhcp6ParserTest, deprecatedRequireClientClassesCheck2) {
|
||||
std::string config = "{ " + genIfaceConfig() + ","
|
||||
R"^(
|
||||
"rebind-timer": 2000,
|
||||
"renew-timer": 1000,
|
||||
"subnet6": [{
|
||||
"require-client-classes": [ "foo" ],
|
||||
"evaluate-additional-classes": [ "foo" ],
|
||||
"pools": [{ "pool": "2001:db8::/64" }],
|
||||
"id": 1,
|
||||
"subnet": "2001:db8::/64"
|
||||
}],
|
||||
"valid-lifetime": 400
|
||||
})^";
|
||||
|
||||
|
||||
ConstElementPtr json;
|
||||
ASSERT_NO_THROW(json = parseDHCP6(config));
|
||||
extractConfig(config);
|
||||
|
||||
ConstElementPtr status;
|
||||
ASSERT_NO_THROW(status = configureDhcp6Server(srv_, json));
|
||||
checkResult(status, 1,
|
||||
"subnet configuration failed: cannot specify both 'require-client-classes'"
|
||||
" and 'evaluate-additional-classes'. Use only the latter.");
|
||||
}
|
||||
|
||||
// This test verifies that only-if-required gets translated
|
||||
// to only-in-additional-list.
|
||||
TEST_F(Dhcp6ParserTest, deprecatedOnlyIfRequiredCheck) {
|
||||
std::string config = "{ " + genIfaceConfig() + ","
|
||||
R"^(
|
||||
"rebind-timer": 2000,
|
||||
"renew-timer": 1000,
|
||||
"client-classes": [{
|
||||
"name": "foo",
|
||||
"only-if-required": true
|
||||
}],
|
||||
"subnet6": [ ],
|
||||
"valid-lifetime": 400
|
||||
})^";
|
||||
|
||||
ConstElementPtr json;
|
||||
ASSERT_NO_THROW(json = parseDHCP6(config));
|
||||
extractConfig(config);
|
||||
|
||||
ConstElementPtr status;
|
||||
ASSERT_NO_THROW(status = configureDhcp6Server(srv_, json));
|
||||
checkResult(status, 0);
|
||||
|
||||
auto dictionary = CfgMgr::instance().getStagingCfg()->getClientClassDictionary();
|
||||
ASSERT_TRUE(dictionary);
|
||||
EXPECT_EQ(1, dictionary->getClasses()->size());
|
||||
|
||||
ClientClassDefPtr class_def = dictionary->findClass("foo");
|
||||
ASSERT_TRUE(class_def);
|
||||
EXPECT_TRUE(class_def->getAdditional());
|
||||
}
|
||||
|
||||
// This test verifies that users cannot specify both
|
||||
// only-if-required and only-in-additional-list.
|
||||
TEST_F(Dhcp6ParserTest, deprecatedOnlyIfRequiredCheck2) {
|
||||
std::string config = "{ " + genIfaceConfig() + ","
|
||||
R"^(
|
||||
"rebind-timer": 2000,
|
||||
"renew-timer": 1000,
|
||||
"client-classes": [{
|
||||
"name": "foo",
|
||||
"only-if-required": true,
|
||||
"only-in-additional-list": true
|
||||
}],
|
||||
"subnet6": [ ],
|
||||
"valid-lifetime": 400
|
||||
})^";
|
||||
|
||||
ConstElementPtr json;
|
||||
ASSERT_NO_THROW(json = parseDHCP6(config));
|
||||
extractConfig(config);
|
||||
|
||||
ConstElementPtr status;
|
||||
ASSERT_NO_THROW(status = configureDhcp6Server(srv_, json));
|
||||
checkResult(status, 1,
|
||||
"cannot specify both 'only-if-required' and"
|
||||
" 'only-in-additional-list'. Use only the latter.");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
Loading…
x
Reference in New Issue
Block a user