Commit 1e2bfcdc authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[3747] Update configuration parsers to support ignore-client-id.

parent 5e5ca323
......@@ -194,6 +194,8 @@ protected:
parser = new RelayInfoParser(config_id, relay_info_, Option::V4);
} else if (config_id.compare("option-data") == 0) {
parser = new OptionDataListParser(config_id, options_, AF_INET);
} else if (config_id.compare("ignore-client-id") == 0) {
parser = new BooleanParser(config_id, boolean_values_);
} else {
isc_throw(NotImplemented, "unsupported parameter: " << config_id);
}
......@@ -250,7 +252,28 @@ protected:
Subnet4Ptr subnet4(new Subnet4(addr, len, t1, t2, valid, subnet_id));
subnet_ = subnet4;
// Try global value first
// ignore-client-id
isc::util::OptionalValue<bool> ignore_client_id;
try {
ignore_client_id = boolean_values_->getParam("ignore-client-id");
} catch (...) {
// Ignore because this parameter is optional and it may be specified
// in the global scope.
}
// If the ignore-client-id wasn't specified as a subnet specific parameter
// check if there is global value specified.
if (!ignore_client_id.isSpecified()) {
// If not specified, use false.
ignore_client_id.specify(globalContext()->boolean_values_->
getOptionalParam("ignore-client-id", false));
}
// Set the ignore-client-id value for the subnet.
subnet4->setIgnoreClientId(ignore_client_id.get());
// next-server
try {
string next_server = globalContext()->string_values_->getParam("next-server");
if (!next_server.empty()) {
......@@ -374,6 +397,8 @@ namespace dhcp {
parser = new BooleanParser(config_id, globalContext()->boolean_values_);
} else if (config_id.compare("dhcp-ddns") == 0) {
parser = new D2ClientConfigParser(config_id);
} else if (config_id.compare("ignore-client-id") == 0) {
parser = new BooleanParser(config_id, globalContext()->boolean_values_);
} else {
isc_throw(DhcpConfigError,
"unsupported global configuration parameter: "
......
......@@ -1102,6 +1102,77 @@ TEST_F(Dhcp4ParserTest, echoClientId) {
CfgMgr::instance().echoClientId(true);
}
// This test checks that the global ignore-client-id parameter is optional
// and that values under the subnet are used.
TEST_F(Dhcp4ParserTest, ignoreClientIdNoGlobal) {
ConstElementPtr status;
std::string config = "{ " + genIfaceConfig() + "," +
"\"rebind-timer\": 2000, "
"\"renew-timer\": 1000, "
"\"subnet4\": [ "
"{"
" \"ignore-client-id\": true,"
" \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
" \"subnet\": \"192.0.2.0/24\""
"},"
"{"
" \"ignore-client-id\": false,"
" \"pools\": [ { \"pool\": \"192.0.3.1 - 192.0.3.100\" } ],"
" \"subnet\": \"192.0.3.0/24\""
"} ],"
"\"valid-lifetime\": 4000 }";
ElementPtr json = Element::fromJSON(config);
ASSERT_NO_THROW(status = configureDhcp4Server(*srv_, json));
checkResult(status, 0);
CfgSubnets4Ptr cfg = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
Subnet4Ptr subnet1 = cfg->selectSubnet(IOAddress("192.0.2.1"));
ASSERT_TRUE(subnet1);
EXPECT_TRUE(subnet1->getIgnoreClientId());
Subnet4Ptr subnet2 = cfg->selectSubnet(IOAddress("192.0.3.1"));
ASSERT_TRUE(subnet2);
EXPECT_FALSE(subnet2->getIgnoreClientId());
}
// This test checks that the global ignore-client-id parameter is used
// when there is no such parameter under subnet and that the parameter
// specified for a subnet overrides the global setting.
TEST_F(Dhcp4ParserTest, ignoreClientIdGlobal) {
ConstElementPtr status;
std::string config = "{ " + genIfaceConfig() + "," +
"\"rebind-timer\": 2000, "
"\"renew-timer\": 1000, "
"\"ignore-client-id\": true,"
"\"subnet4\": [ "
"{"
" \"ignore-client-id\": false,"
" \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ],"
" \"subnet\": \"192.0.2.0/24\""
"},"
"{"
" \"pools\": [ { \"pool\": \"192.0.3.1 - 192.0.3.100\" } ],"
" \"subnet\": \"192.0.3.0/24\""
"} ],"
"\"valid-lifetime\": 4000 }";
ElementPtr json = Element::fromJSON(config);
ASSERT_NO_THROW(status = configureDhcp4Server(*srv_, json));
checkResult(status, 0);
CfgSubnets4Ptr cfg = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
Subnet4Ptr subnet1 = cfg->selectSubnet(IOAddress("192.0.2.1"));
ASSERT_TRUE(subnet1);
EXPECT_FALSE(subnet1->getIgnoreClientId());
Subnet4Ptr subnet2 = cfg->selectSubnet(IOAddress("192.0.3.1"));
ASSERT_TRUE(subnet2);
EXPECT_TRUE(subnet2->getIgnoreClientId());
}
// This test checks if it is possible to override global values
// on a per subnet basis.
TEST_F(Dhcp4ParserTest, subnetLocal) {
......
......@@ -238,7 +238,7 @@ Iface::setActive(const IOAddress& address, const bool active) {
for (AddressCollection::iterator addr_it = addrs_.begin();
addr_it != addrs_.end(); ++addr_it) {
if (address == addr_it->get()) {
addr_it->specify(active);
addr_it->specify(OptionalValueState(active));
return;
}
}
......@@ -250,7 +250,7 @@ void
Iface::setActive(const bool active) {
for (AddressCollection::iterator addr_it = addrs_.begin();
addr_it != addrs_.end(); ++addr_it) {
addr_it->specify(active);
addr_it->specify(OptionalValueState(active));
}
}
......
......@@ -1030,7 +1030,9 @@ PoolParser::commit() {
SubnetConfigParser::SubnetConfigParser(const std::string&,
ParserContextPtr global_context,
const isc::asiolink::IOAddress& default_addr)
: uint32_values_(new Uint32Storage()), string_values_(new StringStorage()),
: uint32_values_(new Uint32Storage()),
string_values_(new StringStorage()),
boolean_values_(new BooleanStorage()),
pools_(new PoolStorage()), global_context_(global_context),
relay_info_(new isc::dhcp::Subnet::RelayInfo(default_addr)),
options_(new CfgOption()) {
......
......@@ -1063,6 +1063,9 @@ protected:
/// Storage for subnet-specific string values.
StringStoragePtr string_values_;
/// Storage for subnet-specific boolean values.
BooleanStoragePtr boolean_values_;
/// Storage for pools belonging to this subnet.
PoolStoragePtr pools_;
......
......@@ -100,11 +100,7 @@ public:
/// @param value New actual value.
void specify(const T& value) {
set(value);
specify(true);
}
void specify(const OptionalValueState& state) {
specified_ = state.specified_;
specify(OptionalValueState(true));
}
/// @brief Sets the value to "specified" or "unspecified".
......@@ -112,8 +108,8 @@ public:
/// It does not alter the actual value. It only marks it "specified" or
/// "unspecified".
/// @param specified boolean that determined if a value is specified or not
void specify(const bool specified) {
specified_ = specified;
void specify(const OptionalValueState& state) {
specified_ = state.specified_;
}
/// @brief Checks if the value is specified or unspecified.
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment