2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-09-03 15:35:17 +00:00

[#2314] Checkpoint: added space

This commit is contained in:
Francis Dupont
2022-03-17 18:58:35 +01:00
committed by Razvan Becheriu
parent ebe3bdfb69
commit 196e60cf0e
3 changed files with 86 additions and 3 deletions

View File

@@ -1878,7 +1878,10 @@ a client class name, when not empty the entry is skipped if the query does
not belong to the class.
Since Kea 2.1.4, it is allowed to have multiple entries for the same option,
but each entry must have exactly one action.
but each entry must have exactly one action. If the option is not defined
in the ``dhcp4`` for DHCPv4 or ``dhcp6`` for DHCPv6 you can specify the
space where to find the option definition using its name with the new
``space`` parameter.
.. _host-cmds:

View File

@@ -73,6 +73,7 @@ namespace flex_option {
const SimpleKeywords FlexOptionImpl::OPTION_PARAMETERS = {
{ "code", Element::integer },
{ "name", Element::string },
{ "space", Element::string },
{ "csv-format", Element::boolean },
{ "add", Element::string },
{ "supersede", Element::string },
@@ -137,6 +138,7 @@ FlexOptionImpl::parseOptionConfig(ConstElementPtr option) {
}
ConstElementPtr code_elem = option->get("code");
ConstElementPtr name_elem = option->get("name");
ConstElementPtr space_elem = option->get("space");
ConstElementPtr csv_format_elem = option->get("csv-format");
ConstElementPtr class_elem = option->get("client-class");
OptionDefinitionPtr def;
@@ -153,6 +155,12 @@ FlexOptionImpl::parseOptionConfig(ConstElementPtr option) {
space = DHCP6_OPTION_SPACE;
universe = Option::V6;
}
if (space_elem) {
space = space_elem->stringValue();
if (!OptionSpace::validateName(space)) {
isc_throw(BadValue, "'" << space << "' is not a valid space name");
}
}
uint16_t code;
if (code_elem) {
int64_t value = code_elem->intValue();
@@ -166,7 +174,7 @@ FlexOptionImpl::parseOptionConfig(ConstElementPtr option) {
isc_throw(OutOfRange, "invalid 'code' value " << value
<< " not in [0.." << max_code << "]");
}
if (family == AF_INET) {
if (space == DHCP4_OPTION_SPACE) {
if (value == DHO_PAD) {
isc_throw(BadValue,
"invalid 'code' value 0: reserved for PAD");
@@ -174,7 +182,7 @@ FlexOptionImpl::parseOptionConfig(ConstElementPtr option) {
isc_throw(BadValue,
"invalid 'code' value 255: reserved for END");
}
} else {
} else if (space == DHCP6_OPTION_SPACE) {
if (value == 0) {
isc_throw(BadValue, "invalid 'code' value 0: reserved");
}

View File

@@ -228,6 +228,36 @@ TEST_F(FlexOptionTest, optionConfigBadCode6) {
EXPECT_TRUE(impl_->getErrMsg().empty());
}
// Verify that the space must be a string.
TEST_F(FlexOptionTest, optionConfigBadSpace) {
ElementPtr options = Element::createList();
ElementPtr option = Element::createMap();
options->add(option);
ElementPtr add = Element::create(string("'ab'"));
option->set("add", add);
ElementPtr code = Element::create(222);
option->set("code", code);
ElementPtr space = Element::create(true);
option->set("space", space);
EXPECT_THROW(impl_->testConfigure(options), BadValue);
EXPECT_EQ("'space' must be a string: true", impl_->getErrMsg());
}
// Verify that the space must be valid.
TEST_F(FlexOptionTest, optionConfigInvalidSpace) {
ElementPtr options = Element::createList();
ElementPtr option = Element::createMap();
options->add(option);
ElementPtr add = Element::create(string("'ab'"));
option->set("add", add);
ElementPtr code = Element::create(222);
option->set("code", code);
ElementPtr space = Element::create(string("-bad-"));
option->set("space", space);
EXPECT_THROW(impl_->testConfigure(options), BadValue);
EXPECT_EQ("'-bad-' is not a valid space name", impl_->getErrMsg());
}
// Verify that the name must be a string.
TEST_F(FlexOptionTest, optionConfigBadName) {
ElementPtr options = Element::createList();
@@ -267,6 +297,22 @@ TEST_F(FlexOptionTest, optionConfigUnknownName) {
EXPECT_EQ("no known 'foobar' option in 'dhcp4' space", impl_->getErrMsg());
}
// Verify that the space must be a known space.
TEST_F(FlexOptionTest, optionConfigUnknownSpace) {
ElementPtr options = Element::createList();
ElementPtr option = Element::createMap();
options->add(option);
ElementPtr add = Element::create(string("'ab'"));
option->set("add", add);
ElementPtr name = Element::create(string("host-name"));
option->set("name", name);
ElementPtr space = Element::create(string("foobar"));
option->set("space", space);
EXPECT_THROW(impl_->testConfigure(options), BadValue);
EXPECT_EQ("no known 'host-name' option in 'foobar' space",
impl_->getErrMsg());
}
// Verify that the definition is not required when csv-format is not specified.
TEST_F(FlexOptionTest, optionConfigUnknownCodeNoCSVFormat) {
ElementPtr options = Element::createList();
@@ -362,6 +408,32 @@ TEST_F(FlexOptionTest, optionConfigDefinedName) {
EXPECT_EQ(1, opt_lst.size());
}
// Verify that the name can be an user defined option in a custom space.
TEST_F(FlexOptionTest, optionConfigDefinedSpace) {
OptionDefSpaceContainer defs;
OptionDefinitionPtr def(new OptionDefinition("my-option", 222,
"my-space", "string"));
defs.addItem(def);
EXPECT_NO_THROW(LibDHCP::setRuntimeOptionDefs(defs));
ElementPtr options = Element::createList();
ElementPtr option = Element::createMap();
options->add(option);
ElementPtr add = Element::create(string("'ab'"));
option->set("add", add);
ElementPtr name = Element::create(string("my-option"));
option->set("name", name);
ElementPtr space = Element::create(string("my-space"));
option->set("space", space);
EXPECT_NO_THROW(impl_->testConfigure(options));
EXPECT_TRUE(impl_->getErrMsg().empty());
auto map = impl_->getOptionConfigMap();
EXPECT_EQ(1, map.count(222));
auto opt_lst = map[222];
EXPECT_EQ(1, opt_lst.size());
}
// Last resort is only option 43...
// Verify that the name must match the code.