mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-29 13:07:50 +00:00
[#1405] merged second pass
This commit is contained in:
parent
8d05ba02b2
commit
d26a72f560
@ -766,6 +766,52 @@ insert into hosts(dhcp_identifier, dhcp_identifier_type, dhcp4_subnet_id, ipv4_a
|
||||
ERRCODE=$?
|
||||
assert_eq 0 $ERRCODE "insert into hosts failed, expected exit code %d, actual %d"
|
||||
|
||||
# Schema upgrade from 9.4 to 9.5.
|
||||
|
||||
# table: dhcp4_shared_network (reservation_mode replaced by reservations flags)
|
||||
qry="select reservations_global, reservations_in_subnet, reservations_out_of_pool from dhcp4_shared_network"
|
||||
run_statement "dhcp4_shared_network" "$qry"
|
||||
|
||||
qry="show columns from dhcp4_shared_network like 'reservation_mode'";
|
||||
text=`mysql_execute "${qry}"`
|
||||
ERRCODE=$?
|
||||
assert_eq 0 $ERRCODE "show columns from dhcp4_shared_network like 'reservation_mode' failed. (expected status code %d, returned %d)"
|
||||
count=`echo $text | grep -ic reservation`
|
||||
assert_eq $count 0 "dhcp4_shared_network has still reservation_mode column. (returned count %d, expected %d)"
|
||||
|
||||
# table: dhcp4_subnet (reservation_mode replaced by reservations flags)
|
||||
qry="select reservations_global, reservations_in_subnet, reservations_out_of_pool from dhcp4_subnet"
|
||||
run_statement "dhcp4_subnet" "$qry"
|
||||
|
||||
qry="show columns from dhcp4_subnet like 'reservation_mode'";
|
||||
text=`mysql_execute "${qry}"`
|
||||
ERRCODE=$?
|
||||
assert_eq 0 $ERRCODE "show columns from dhcp4_subnet like 'reservation_mode' failed. (expected status code %d, returned %d)"
|
||||
count=`echo $text | grep -ic reservation`
|
||||
assert_eq $count 0 "dhcp4_subnet has still reservation_mode column. (returned count %d, expected %d)"
|
||||
|
||||
# table: dhcp6_shared_network (reservation_mode replaced by reservations flags)
|
||||
qry="select reservations_global, reservations_in_subnet, reservations_out_of_pool from dhcp6_shared_network"
|
||||
run_statement "dhcp6_shared_network" "$qry"
|
||||
|
||||
qry="show columns from dhcp6_shared_network like 'reservation_mode'";
|
||||
text=`mysql_execute "${qry}"`
|
||||
ERRCODE=$?
|
||||
assert_eq 0 $ERRCODE "show columns from dhcp6_shared_network like 'reservation_mode' failed. (expected status code %d, returned %d)"
|
||||
count=`echo $text | grep -ic reservation`
|
||||
assert_eq $count 0 "dhcp6_shared_network has still reservation_mode column. (returned count %d, expected %d)"
|
||||
|
||||
# table: dhcp6_subnet (reservation_mode replaced by reservations flags)
|
||||
qry="select reservations_global, reservations_in_subnet, reservations_out_of_pool from dhcp6_subnet"
|
||||
run_statement "dhcp6_subnet" "$qry"
|
||||
|
||||
qry="show columns from dhcp6_subnet like 'reservation_mode'";
|
||||
text=`mysql_execute "${qry}"`
|
||||
ERRCODE=$?
|
||||
assert_eq 0 $ERRCODE "show columns from dhcp6_subnet like 'reservation_mode' failed. (expected status code %d, returned %d)"
|
||||
count=`echo $text | grep -ic reservation`
|
||||
assert_eq $count 0 "dhcp6_subnet has still reservation_mode column. (returned count %d, expected %d)"
|
||||
|
||||
# Verify upgraded schema reports version 9.5
|
||||
version=$(${keaadmin} db-version mysql -u $db_user -p $db_password -n $db_name -d $db_scripts_dir)
|
||||
assert_str_eq "9.5" ${version} "Expected kea-admin to return %s, returned value was %s"
|
||||
@ -1352,7 +1398,7 @@ mysql_unused_subnet_id_test() {
|
||||
|
||||
# Verifies that you can upgrade from an earlier version and
|
||||
# that reservation_mode values in subnet and shared network tables are
|
||||
# converted to new values.
|
||||
# converted to new reservations flags.
|
||||
mysql_reservation_mode_upgrade_test() {
|
||||
test_start "mysql_reservation_mode_upgrade_test"
|
||||
|
||||
@ -1422,68 +1468,68 @@ mysql_reservation_mode_upgrade_test() {
|
||||
# Upgrade to schema 9.5.
|
||||
mysql_upgrade_schema_to_version 9.5
|
||||
|
||||
# Test DISABLED (0) -> 0
|
||||
qry="select count(id) from dhcp4_shared_network where reservation_mode = 0 and name = 'test0';"
|
||||
# Test DISABLED (0) -> false, false, false
|
||||
qry="select count(id) from dhcp4_shared_network where reservations_global = false and reservations_in_subnet = false and reservations_out_of_pool = false and name = 'test0';"
|
||||
run_statement "#4_shared_disabled" "$qry" 1
|
||||
|
||||
# Test OUT_OF_POOL (1) -> 3
|
||||
qry="select count(id) from dhcp4_shared_network where reservation_mode = 3 and name = 'test1';"
|
||||
# Test OUT_OF_POOL (1) -> false, true, true
|
||||
qry="select count(id) from dhcp4_shared_network where reservations_global = false and reservations_in_subnet = true and reservations_out_of_pool = true and name = 'test1';"
|
||||
run_statement "#4_shared_out_of_pool" "$qry" 1
|
||||
|
||||
# Test GLOBAL (2) -> 4
|
||||
qry="select count(id) from dhcp4_shared_network where reservation_mode = 4 and name = 'test2';"
|
||||
# Test GLOBAL (2) -> true, false, false
|
||||
qry="select count(id) from dhcp4_shared_network where reservations_global = true and reservations_in_subnet = false and reservations_out_of_pool = false and name = 'test2';"
|
||||
run_statement "#4_shared_global" "$qry" 1
|
||||
|
||||
# Test ALL (3) -> 2
|
||||
qry="select count(id) from dhcp4_shared_network where reservation_mode = 2 and name = 'test3';"
|
||||
# Test ALL (3) -> false, true, false
|
||||
qry="select count(id) from dhcp4_shared_network where reservation_global = false and reservations_in_subnet = true and reservations_out_of_pool = false name = 'test3';"
|
||||
run_statement "#4_shared_all" "$qry" 1
|
||||
|
||||
# Test DISABLED (0) -> 0
|
||||
qry="select count(subnet_id) from dhcp4_subnet where reservation_mode = 0 and subnet_prefix = '192.0.0.0/24'"
|
||||
# Test DISABLED (0) -> false, false, false
|
||||
qry="select count(subnet_id) from dhcp4_subnet where reservations_global = false and reservations_in_subnet = false and reservations_out_of_pool = false and subnet_prefix = '192.0.0.0/24'"
|
||||
run_statement "#4_subnet_disabled" "$qry" 1
|
||||
|
||||
# Test OUT_OF_POOL (1) -> 3
|
||||
qry="select count(subnet_id) from dhcp4_subnet where reservation_mode = 3 and subnet_prefix = '192.0.1.0/24'"
|
||||
# Test OUT_OF_POOL (1) -> false, true, true
|
||||
qry="select count(subnet_id) from dhcp4_subnet where reservations_global = false and reservations_in_subnet = true and reservations_out_of_pool = true and subnet_prefix = '192.0.1.0/24'"
|
||||
run_statement "#4_subnet_out_of_pool" "$qry" 1
|
||||
|
||||
# Test GLOBAL (2) -> 4
|
||||
qry="select count(subnet_id) from dhcp4_subnet where reservation_mode = 4 and subnet_prefix = '192.0.2.0/24'"
|
||||
# Test GLOBAL (2) -> true, false, false
|
||||
qry="select count(subnet_id) from dhcp4_subnet where reservations_global = true and reservations_in_subnet = false and reservations_out_of_pool = false and subnet_prefix = '192.0.2.0/24'"
|
||||
run_statement "#4_subnet_global" "$qry" 1
|
||||
|
||||
# Test ALL (3) -> 2
|
||||
qry="select count(subnet_id) from dhcp4_subnet where reservation_mode = 2 and subnet_prefix = '192.0.3.0/24'"
|
||||
# Test ALL (3) -> false, true, false
|
||||
qry="select count(subnet_id) from dhcp4_subnet where reservations_global = false and reservations_in_subnet = true and reservations_out_of_pool = false and subnet_prefix = '192.0.3.0/24'"
|
||||
run_statement "#4_subnet_all" "$qry" 1
|
||||
|
||||
# Test DISABLED (0) -> 0
|
||||
qry="select count(id) from dhcp6_shared_network where reservation_mode = 0 and name = 'test0';"
|
||||
# Test DISABLED (0) -> false, false, false
|
||||
qry="select count(id) from dhcp6_shared_network where reservations_global = false and reservations_in_subnet = false and reservations_out_of_pool = false and name = 'test0';"
|
||||
run_statement "#6_shared_disabled" "$qry" 1
|
||||
|
||||
# Test OUT_OF_POOL (1) -> 3
|
||||
qry="select count(id) from dhcp6_shared_network where reservation_mode = 3 and name = 'test1';"
|
||||
# Test OUT_OF_POOL (1) -> false, true, true
|
||||
qry="select count(id) from dhcp6_shared_network where reservations_global = false and reservations_in_subnet = true and reservations_out_of_pool = true and name = 'test1';"
|
||||
run_statement "#6_shared_out_of_pool" "$qry" 1
|
||||
|
||||
# Test GLOBAL (2) -> 4
|
||||
qry="select count(id) from dhcp6_shared_network where reservation_mode = 4 and name = 'test2';"
|
||||
# Test GLOBAL (2) -> true, false, false
|
||||
qry="select count(id) from dhcp6_shared_network where reservations_global = true and reservations_in_subnet = false and reservations_out_of_pool = false and name = 'test2';"
|
||||
run_statement "#6_shared_global" "$qry" 1
|
||||
|
||||
# Test ALL (3) -> 2
|
||||
qry="select count(id) from dhcp6_shared_network where reservation_mode = 2 and name = 'test3';"
|
||||
# Test ALL (3) -> false, true, false
|
||||
qry="select count(id) from dhcp6_shared_network where reservations_global = false and reservations_in_subnet = true and reservations_out_of_pool = false and name = 'test3';"
|
||||
run_statement "#6_shared_all" "$qry" 1
|
||||
|
||||
# Test DISABLED (0) -> 0
|
||||
qry="select count(subnet_id) from dhcp6_subnet where reservation_mode = 0 and subnet_prefix = '2001:db8::/64'"
|
||||
# Test DISABLED (0) -> false, false, false
|
||||
qry="select count(subnet_id) from dhcp6_subnet where reservations_global = false and reservations_in_subnet = false and reservations_out_of_pool = false and subnet_prefix = '2001:db8::/64'"
|
||||
run_statement "#6_subnet_disabled" "$qry" 1
|
||||
|
||||
# Test OUT_OF_POOL (1) -> 3
|
||||
qry="select count(subnet_id) from dhcp6_subnet where reservation_mode = 3 and subnet_prefix = '2001:db8:1::/64'"
|
||||
# Test OUT_OF_POOL (1) -> false, true, true
|
||||
qry="select count(subnet_id) from dhcp6_subnet where reservations_global = false and reservations_in_subnet = true and reservations_out_of_pool = true and subnet_prefix = '2001:db8:1::/64'"
|
||||
run_statement "#6_subnet_out_of_pool" "$qry" 1
|
||||
|
||||
# Test GLOBAL (2) -> 4
|
||||
qry="select count(subnet_id) from dhcp6_subnet where reservation_mode = 4 and subnet_prefix = '2001:db8:2::/64'"
|
||||
# Test GLOBAL (2) -> true, false, false
|
||||
qry="select count(subnet_id) from dhcp6_subnet where reservations_global = true and reservations_in_subnet = false and reservations_out_of_pool = false and subnet_prefix = '2001:db8:2::/64'"
|
||||
run_statement "#6_subnet_global" "$qry" 1
|
||||
|
||||
# Test ALL (3) -> 2
|
||||
qry="select count(subnet_id) from dhcp6_subnet where reservation_mode = 2 and subnet_prefix = '2001:db8:3::/64'"
|
||||
# Test ALL (3) -> false, true, false
|
||||
qry="select count(subnet_id) from dhcp6_subnet where reservations_global = false and reservations_in_subnet = true and reservations_out_of_pool = false and subnet_prefix = '2001:db8:3::/64'"
|
||||
run_statement "#6_subnet_all" "$qry" 1
|
||||
|
||||
qry="select count(*) from dhcp4_shared_network;"
|
||||
|
@ -948,39 +948,6 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu]
|
||||
}
|
||||
}
|
||||
|
||||
\"reservations-out-of-pool\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser4Context::DHCP4:
|
||||
case isc::dhcp::Parser4Context::SUBNET4:
|
||||
case isc::dhcp::Parser4Context::SHARED_NETWORK:
|
||||
return isc::dhcp::Dhcp4Parser::make_RESERVATIONS_OUT_OF_POOL(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp4Parser::make_STRING("reservations-out-of-pool", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"reservations-in-subnet\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser4Context::DHCP4:
|
||||
case isc::dhcp::Parser4Context::SUBNET4:
|
||||
case isc::dhcp::Parser4Context::SHARED_NETWORK:
|
||||
return isc::dhcp::Dhcp4Parser::make_RESERVATIONS_IN_SUBNET(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp4Parser::make_STRING("reservations-in-subnet", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"reservations-global\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser4Context::DHCP4:
|
||||
case isc::dhcp::Parser4Context::SUBNET4:
|
||||
case isc::dhcp::Parser4Context::SHARED_NETWORK:
|
||||
return isc::dhcp::Dhcp4Parser::make_RESERVATIONS_GLOBAL(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp4Parser::make_STRING("reservations-global", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"reservation-mode\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser4Context::DHCP4:
|
||||
@ -1037,6 +1004,39 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu]
|
||||
}
|
||||
}
|
||||
|
||||
\"reservations-global\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser4Context::DHCP4:
|
||||
case isc::dhcp::Parser4Context::SUBNET4:
|
||||
case isc::dhcp::Parser4Context::SHARED_NETWORK:
|
||||
return isc::dhcp::Dhcp4Parser::make_RESERVATIONS_GLOBAL(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp4Parser::make_STRING("reservations-global", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"reservations-in-subnet\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser4Context::DHCP4:
|
||||
case isc::dhcp::Parser4Context::SUBNET4:
|
||||
case isc::dhcp::Parser4Context::SHARED_NETWORK:
|
||||
return isc::dhcp::Dhcp4Parser::make_RESERVATIONS_IN_SUBNET(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp4Parser::make_STRING("reservations-in-subnet", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"reservations-out-of-pool\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser4Context::DHCP4:
|
||||
case isc::dhcp::Parser4Context::SUBNET4:
|
||||
case isc::dhcp::Parser4Context::SHARED_NETWORK:
|
||||
return isc::dhcp::Dhcp4Parser::make_RESERVATIONS_OUT_OF_POOL(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp4Parser::make_STRING("reservations-out-of-pool", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"code\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser4Context::OPTION_DEF:
|
||||
|
@ -152,13 +152,13 @@ using namespace std;
|
||||
INTERFACE "interface"
|
||||
ID "id"
|
||||
RESERVATION_MODE "reservation-mode"
|
||||
RESERVATIONS_OUT_OF_POOL "reservations-out-of-pool"
|
||||
RESERVATIONS_IN_SUBNET "reservations-in-subnet"
|
||||
RESERVATIONS_GLOBAL "reservations-global"
|
||||
DISABLED "disabled"
|
||||
OUT_OF_POOL "out-of-pool"
|
||||
GLOBAL "global"
|
||||
ALL "all"
|
||||
RESERVATIONS_GLOBAL "reservations-global"
|
||||
RESERVATIONS_IN_SUBNET "reservations-in-subnet"
|
||||
RESERVATIONS_OUT_OF_POOL "reservations-out-of-pool"
|
||||
|
||||
HOST_RESERVATION_IDENTIFIERS "host-reservation-identifiers"
|
||||
|
||||
@ -486,9 +486,9 @@ global_param: valid_lifetime
|
||||
| config_control
|
||||
| server_tag
|
||||
| reservation_mode
|
||||
| reservations_out_of_pool
|
||||
| reservations_in_subnet
|
||||
| reservations_global
|
||||
| reservations_in_subnet
|
||||
| reservations_out_of_pool
|
||||
| calculate_tee_times
|
||||
| t1_percent
|
||||
| t2_percent
|
||||
@ -1374,9 +1374,9 @@ subnet4_param: valid_lifetime
|
||||
| require_client_classes
|
||||
| reservations
|
||||
| reservation_mode
|
||||
| reservations_out_of_pool
|
||||
| reservations_in_subnet
|
||||
| reservations_global
|
||||
| reservations_in_subnet
|
||||
| reservations_out_of_pool
|
||||
| relay
|
||||
| match_client_id
|
||||
| authoritative
|
||||
@ -1472,10 +1472,10 @@ require_client_classes: REQUIRE_CLIENT_CLASSES {
|
||||
ctx.leave();
|
||||
};
|
||||
|
||||
reservations_out_of_pool: RESERVATIONS_OUT_OF_POOL COLON BOOLEAN {
|
||||
ctx.unique("reservations-out-of-pool", ctx.loc2pos(@1));
|
||||
reservations_global: RESERVATIONS_GLOBAL COLON BOOLEAN {
|
||||
ctx.unique("reservations-global", ctx.loc2pos(@1));
|
||||
ElementPtr b(new BoolElement($3, ctx.loc2pos(@3)));
|
||||
ctx.stack_.back()->set("reservations-out-of-pool", b);
|
||||
ctx.stack_.back()->set("reservations-global", b);
|
||||
};
|
||||
|
||||
reservations_in_subnet: RESERVATIONS_IN_SUBNET COLON BOOLEAN {
|
||||
@ -1484,10 +1484,10 @@ reservations_in_subnet: RESERVATIONS_IN_SUBNET COLON BOOLEAN {
|
||||
ctx.stack_.back()->set("reservations-in-subnet", b);
|
||||
};
|
||||
|
||||
reservations_global: RESERVATIONS_GLOBAL COLON BOOLEAN {
|
||||
ctx.unique("reservations-global", ctx.loc2pos(@1));
|
||||
reservations_out_of_pool: RESERVATIONS_OUT_OF_POOL COLON BOOLEAN {
|
||||
ctx.unique("reservations-out-of-pool", ctx.loc2pos(@1));
|
||||
ElementPtr b(new BoolElement($3, ctx.loc2pos(@3)));
|
||||
ctx.stack_.back()->set("reservations-global", b);
|
||||
ctx.stack_.back()->set("reservations-out-of-pool", b);
|
||||
};
|
||||
|
||||
reservation_mode: RESERVATION_MODE {
|
||||
@ -1558,9 +1558,9 @@ shared_network_param: name
|
||||
| boot_file_name
|
||||
| relay
|
||||
| reservation_mode
|
||||
| reservations_out_of_pool
|
||||
| reservations_in_subnet
|
||||
| reservations_global
|
||||
| reservations_in_subnet
|
||||
| reservations_out_of_pool
|
||||
| client_class
|
||||
| require_client_classes
|
||||
| valid_lifetime
|
||||
|
@ -180,7 +180,9 @@ Dhcpv4Exchange::Dhcpv4Exchange(const AllocEnginePtr& alloc_engine,
|
||||
}
|
||||
|
||||
// Find static reservations if not disabled for our subnet.
|
||||
if (subnet->getHostReservationMode() != Network::HR_DISABLED) {
|
||||
if (subnet->getReservationsGlobal() ||
|
||||
subnet->getReservationsInSubnet() ||
|
||||
subnet->getReservationsOutOfPool()) {
|
||||
// Before we can check for static reservations, we need to prepare a set
|
||||
// of identifiers to be used for this.
|
||||
setHostIdentifiers();
|
||||
@ -493,8 +495,11 @@ Dhcpv4Exchange::conditionallySetReservedClientClasses() {
|
||||
if (context_->subnet_) {
|
||||
SharedNetwork4Ptr shared_network;
|
||||
context_->subnet_->getSharedNetwork(shared_network);
|
||||
if (shared_network && !context_->globalHost()) {
|
||||
setReservedClientClasses(context_);
|
||||
if (shared_network) {
|
||||
ConstHostPtr host = context_->currentHost();
|
||||
if (host && (host->getIPv4SubnetID() != SUBNET_ID_GLOBAL)) {
|
||||
setReservedClientClasses(context_);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -367,53 +367,17 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
|
||||
// default values and will insert derived values as well.
|
||||
mutable_cfg = boost::const_pointer_cast<Element>(config_set);
|
||||
|
||||
bool found = false;
|
||||
ConstElementPtr reservations_out_of_pool = mutable_cfg->get("reservations-out-of-pool");
|
||||
ConstElementPtr reservations_in_subnet = mutable_cfg->get("reservations-in-subnet");
|
||||
ConstElementPtr reservations_global = mutable_cfg->get("reservations-global");
|
||||
if (reservations_out_of_pool || reservations_in_subnet || reservations_global) {
|
||||
found = true;
|
||||
}
|
||||
ConstElementPtr reservation_mode = mutable_cfg->get("reservation-mode");
|
||||
if (reservation_mode) {
|
||||
LOG_WARN(dhcp4_logger, DHCP4_DEPRECATED_RESERVATION_MODE);
|
||||
if (found) {
|
||||
isc_throw(DhcpConfigError, "invalid use of both 'reservation-mode'"
|
||||
" and one of 'reservations-out-of-pool'"
|
||||
" , 'reservations-in-subnet' or"
|
||||
" 'reservations-global' parameters");
|
||||
}
|
||||
}
|
||||
|
||||
// reset all other reservation flags to overwrite default values.
|
||||
if (found) {
|
||||
bool force_true = false;
|
||||
if (!reservations_out_of_pool) {
|
||||
mutable_cfg->set("reservations-out-of-pool", Element::create(false));
|
||||
} else {
|
||||
force_true = reservations_out_of_pool->boolValue();
|
||||
}
|
||||
if (!reservations_in_subnet) {
|
||||
if (force_true) {
|
||||
mutable_cfg->set("reservations-in-subnet", Element::create(true));
|
||||
} else {
|
||||
mutable_cfg->set("reservations-in-subnet", Element::create(false));
|
||||
}
|
||||
} else if (force_true && !reservations_in_subnet->boolValue()) {
|
||||
isc_throw(DhcpConfigError, "invalid use of disabled 'reservations-in-subnet'"
|
||||
" when enabled 'reservations-out-of-pool'");
|
||||
}
|
||||
if (!reservations_global) {
|
||||
mutable_cfg->set("reservations-global", Element::create(false));
|
||||
}
|
||||
}
|
||||
|
||||
// Relocate dhcp-ddns parameters that have moved to global scope.
|
||||
// Rule is that a global value overrides the dhcp-ddns value, so
|
||||
// we need to do this before we apply global defaults.
|
||||
// Note this is done for backward compatibility.
|
||||
srv_cfg->moveDdnsParams(mutable_cfg);
|
||||
|
||||
// Move from reservation mode to new reservations flags.
|
||||
if (BaseNetworkParser::moveReservationMode(mutable_cfg)) {
|
||||
LOG_WARN(dhcp4_logger, DHCP4_DEPRECATED_RESERVATION_MODE);
|
||||
}
|
||||
|
||||
// Set all default values if not specified by the user.
|
||||
SimpleParser4::setAllDefaults(mutable_cfg);
|
||||
|
||||
@ -432,14 +396,6 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
|
||||
// Apply global options in the staging config, e.g. ip-reservations-unique
|
||||
global_parser.parseEarly(srv_cfg, mutable_cfg);
|
||||
|
||||
// If using deprecated reservation-mode, remove defaults for new parameters
|
||||
// reservations-out-of-pool, reservations-in-subnet and reservations-global.
|
||||
if (reservation_mode) {
|
||||
mutable_cfg->remove("reservations-out-of-pool");
|
||||
mutable_cfg->remove("reservations-in-subnet");
|
||||
mutable_cfg->remove("reservations-global");
|
||||
}
|
||||
|
||||
// We need definitions first
|
||||
ConstElementPtr option_defs = mutable_cfg->get("option-def");
|
||||
if (option_defs) {
|
||||
@ -678,9 +634,9 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
|
||||
(config_pair.first == "boot-file-name") ||
|
||||
(config_pair.first == "server-tag") ||
|
||||
(config_pair.first == "reservation-mode") ||
|
||||
(config_pair.first == "reservations-out-of-pool") ||
|
||||
(config_pair.first == "reservations-in-subnet") ||
|
||||
(config_pair.first == "reservations-global") ||
|
||||
(config_pair.first == "reservations-in-subnet") ||
|
||||
(config_pair.first == "reservations-out-of-pool") ||
|
||||
(config_pair.first == "calculate-tee-times") ||
|
||||
(config_pair.first == "t1-percent") ||
|
||||
(config_pair.first == "t2-percent") ||
|
||||
|
@ -5280,96 +5280,10 @@ TEST_F(Dhcp4ParserTest, reservationBogus) {
|
||||
checkResult(x, 1);
|
||||
}
|
||||
|
||||
/// The goal of this test is to verify that Host Reservation modes can be
|
||||
/// The goal of this test is to verify that Host Reservation flags can be
|
||||
/// specified on a per-subnet basis.
|
||||
TEST_F(Dhcp4ParserTest, hostReservationPerSubnet) {
|
||||
|
||||
/// - Configuration:
|
||||
/// - only addresses (no prefixes)
|
||||
/// - 5 subnets with:
|
||||
/// - 192.0.1.0/24 (all reservations enabled)
|
||||
/// - 192.0.2.0/24 (out-of-pool reservations)
|
||||
/// - 192.0.3.0/24 (reservations disabled)
|
||||
/// - 192.0.4.0/24 (global reservations)
|
||||
/// - 192.0.5.0/24 (reservations not specified)
|
||||
const char* hr_config =
|
||||
"{ "
|
||||
"\"rebind-timer\": 2000, "
|
||||
"\"renew-timer\": 1000, "
|
||||
"\"subnet4\": [ { "
|
||||
" \"pools\": [ { \"pool\": \"192.0.1.0/24\" } ],"
|
||||
" \"subnet\": \"192.0.1.0/24\", "
|
||||
" \"reservation-mode\": \"all\""
|
||||
" },"
|
||||
" {"
|
||||
" \"pools\": [ { \"pool\": \"192.0.2.0/24\" } ],"
|
||||
" \"subnet\": \"192.0.2.0/24\", "
|
||||
" \"reservation-mode\": \"out-of-pool\""
|
||||
" },"
|
||||
" {"
|
||||
" \"pools\": [ { \"pool\": \"192.0.3.0/24\" } ],"
|
||||
" \"subnet\": \"192.0.3.0/24\", "
|
||||
" \"reservation-mode\": \"disabled\""
|
||||
" },"
|
||||
" {"
|
||||
" \"pools\": [ { \"pool\": \"192.0.4.0/24\" } ],"
|
||||
" \"subnet\": \"192.0.4.0/24\", "
|
||||
" \"reservation-mode\": \"global\""
|
||||
" },"
|
||||
" {"
|
||||
" \"pools\": [ { \"pool\": \"192.0.5.0/24\" } ],"
|
||||
" \"subnet\": \"192.0.5.0/24\""
|
||||
" } ],"
|
||||
"\"valid-lifetime\": 4000 }";
|
||||
|
||||
ConstElementPtr json;
|
||||
ASSERT_NO_THROW(json = parseDHCP4(hr_config));
|
||||
extractConfig(hr_config);
|
||||
ConstElementPtr result;
|
||||
EXPECT_NO_THROW(result = configureDhcp4Server(*srv_, json));
|
||||
|
||||
// returned value should be 0 (success)
|
||||
checkResult(result, 0);
|
||||
|
||||
// Let's get all subnets and check that there are 5 of them.
|
||||
ConstCfgSubnets4Ptr subnets = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
|
||||
ASSERT_TRUE(subnets);
|
||||
const Subnet4Collection* subnet_col = subnets->getAll();
|
||||
ASSERT_EQ(5, subnet_col->size()); // We expect 5 subnets
|
||||
|
||||
// Let's check if the parsed subnets have correct HR modes.
|
||||
|
||||
// Subnet 1
|
||||
Subnet4Ptr subnet;
|
||||
subnet = subnets->selectSubnet(IOAddress("192.0.1.1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_ALL, subnet->getHostReservationMode());
|
||||
|
||||
// Subnet 2
|
||||
subnet = subnets->selectSubnet(IOAddress("192.0.2.1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_OUT_OF_POOL, subnet->getHostReservationMode());
|
||||
|
||||
// Subnet 3
|
||||
subnet = subnets->selectSubnet(IOAddress("192.0.3.1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_DISABLED, subnet->getHostReservationMode());
|
||||
|
||||
// Subnet 4
|
||||
subnet = subnets->selectSubnet(IOAddress("192.0.4.1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_GLOBAL, subnet->getHostReservationMode());
|
||||
|
||||
// Subnet 5
|
||||
subnet = subnets->selectSubnet(IOAddress("192.0.5.1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_ALL, subnet->getHostReservationMode());
|
||||
}
|
||||
|
||||
/// The goal of this test is to verify that Host Reservation modes can be
|
||||
/// specified on a per-subnet basis.
|
||||
TEST_F(Dhcp4ParserTest, hostReservationModesPerSubnet) {
|
||||
|
||||
/// - Configuration:
|
||||
/// - only addresses (no prefixes)
|
||||
/// - 7 subnets with:
|
||||
@ -5387,24 +5301,30 @@ TEST_F(Dhcp4ParserTest, hostReservationModesPerSubnet) {
|
||||
"\"subnet4\": [ { "
|
||||
" \"pools\": [ { \"pool\": \"192.0.1.0/24\" } ],"
|
||||
" \"subnet\": \"192.0.1.0/24\", "
|
||||
" \"reservations-in-subnet\": true"
|
||||
" \"reservations-global\": false,"
|
||||
" \"reservations-in-subnet\": true,"
|
||||
" \"reservations-out-of-pool\": false"
|
||||
" },"
|
||||
" {"
|
||||
" \"pools\": [ { \"pool\": \"192.0.2.0/24\" } ],"
|
||||
" \"subnet\": \"192.0.2.0/24\", "
|
||||
" \"reservations-global\": false,"
|
||||
" \"reservations-in-subnet\": true,"
|
||||
" \"reservations-out-of-pool\": true"
|
||||
" },"
|
||||
" {"
|
||||
" \"pools\": [ { \"pool\": \"192.0.3.0/24\" } ],"
|
||||
" \"subnet\": \"192.0.3.0/24\", "
|
||||
" \"reservations-out-of-pool\": false,"
|
||||
" \"reservations-global\": false,"
|
||||
" \"reservations-in-subnet\": false,"
|
||||
" \"reservations-global\": false"
|
||||
" \"reservations-out-of-pool\": false"
|
||||
" },"
|
||||
" {"
|
||||
" \"pools\": [ { \"pool\": \"192.0.4.0/24\" } ],"
|
||||
" \"subnet\": \"192.0.4.0/24\", "
|
||||
" \"reservations-global\": true"
|
||||
" \"reservations-global\": true,"
|
||||
" \"reservations-in-subnet\": false,"
|
||||
" \"reservations-out-of-pool\": false"
|
||||
" },"
|
||||
" {"
|
||||
" \"pools\": [ { \"pool\": \"192.0.5.0/24\" } ],"
|
||||
@ -5413,16 +5333,16 @@ TEST_F(Dhcp4ParserTest, hostReservationModesPerSubnet) {
|
||||
" {"
|
||||
" \"pools\": [ { \"pool\": \"192.0.6.0/24\" } ],"
|
||||
" \"subnet\": \"192.0.6.0/24\", "
|
||||
" \"reservations-out-of-pool\": false,"
|
||||
" \"reservations-global\": true,"
|
||||
" \"reservations-in-subnet\": true,"
|
||||
" \"reservations-global\": true"
|
||||
" \"reservations-out-of-pool\": false"
|
||||
" },"
|
||||
" {"
|
||||
" \"pools\": [ { \"pool\": \"192.0.7.0/24\" } ],"
|
||||
" \"subnet\": \"192.0.7.0/24\", "
|
||||
" \"reservations-out-of-pool\": true,"
|
||||
" \"reservations-global\": true,"
|
||||
" \"reservations-in-subnet\": true,"
|
||||
" \"reservations-global\": true"
|
||||
" \"reservations-out-of-pool\": true"
|
||||
" } ],"
|
||||
"\"valid-lifetime\": 4000 }";
|
||||
|
||||
@ -5447,41 +5367,54 @@ TEST_F(Dhcp4ParserTest, hostReservationModesPerSubnet) {
|
||||
Subnet4Ptr subnet;
|
||||
subnet = subnets->selectSubnet(IOAddress("192.0.1.1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_ALL, subnet->getHostReservationMode());
|
||||
EXPECT_FALSE(subnet->getReservationsGlobal());
|
||||
EXPECT_TRUE(subnet->getReservationsInSubnet());
|
||||
EXPECT_FALSE(subnet->getReservationsOutOfPool());
|
||||
|
||||
// Subnet 2
|
||||
subnet = subnets->selectSubnet(IOAddress("192.0.2.1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_OUT_OF_POOL, subnet->getHostReservationMode());
|
||||
EXPECT_FALSE(subnet->getReservationsGlobal());
|
||||
EXPECT_TRUE(subnet->getReservationsInSubnet());
|
||||
EXPECT_TRUE(subnet->getReservationsOutOfPool());
|
||||
|
||||
// Subnet 3
|
||||
subnet = subnets->selectSubnet(IOAddress("192.0.3.1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_DISABLED, subnet->getHostReservationMode());
|
||||
EXPECT_FALSE(subnet->getReservationsGlobal());
|
||||
EXPECT_FALSE(subnet->getReservationsInSubnet());
|
||||
EXPECT_FALSE(subnet->getReservationsOutOfPool());
|
||||
|
||||
// Subnet 4
|
||||
subnet = subnets->selectSubnet(IOAddress("192.0.4.1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_GLOBAL, subnet->getHostReservationMode());
|
||||
EXPECT_TRUE(subnet->getReservationsGlobal());
|
||||
EXPECT_FALSE(subnet->getReservationsInSubnet());
|
||||
EXPECT_FALSE(subnet->getReservationsOutOfPool());
|
||||
|
||||
// Subnet 5
|
||||
subnet = subnets->selectSubnet(IOAddress("192.0.5.1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_ALL, subnet->getHostReservationMode());
|
||||
EXPECT_FALSE(subnet->getReservationsGlobal());
|
||||
EXPECT_TRUE(subnet->getReservationsInSubnet());
|
||||
EXPECT_FALSE(subnet->getReservationsOutOfPool());
|
||||
|
||||
// Subnet 6
|
||||
subnet = subnets->selectSubnet(IOAddress("192.0.6.1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_ALL|Network::HR_GLOBAL, subnet->getHostReservationMode());
|
||||
EXPECT_TRUE(subnet->getReservationsGlobal());
|
||||
EXPECT_TRUE(subnet->getReservationsInSubnet());
|
||||
EXPECT_FALSE(subnet->getReservationsOutOfPool());
|
||||
|
||||
// Subnet 7
|
||||
subnet = subnets->selectSubnet(IOAddress("192.0.7.1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_OUT_OF_POOL|Network::HR_GLOBAL,
|
||||
subnet->getHostReservationMode());
|
||||
EXPECT_TRUE(subnet->getReservationsGlobal());
|
||||
EXPECT_TRUE(subnet->getReservationsInSubnet());
|
||||
EXPECT_TRUE(subnet->getReservationsOutOfPool());
|
||||
}
|
||||
|
||||
/// The goal of this test is to verify that Host Reservation modes can be
|
||||
/// The goal of this test is to verify that Host Reservation flags can be
|
||||
/// specified globally.
|
||||
TEST_F(Dhcp4ParserTest, hostReservationGlobal) {
|
||||
|
||||
@ -5494,73 +5427,15 @@ TEST_F(Dhcp4ParserTest, hostReservationGlobal) {
|
||||
"{ "
|
||||
"\"rebind-timer\": 2000, "
|
||||
"\"renew-timer\": 1000, "
|
||||
"\"reservation-mode\": \"out-of-pool\", "
|
||||
"\"subnet4\": [ { "
|
||||
" \"pools\": [ { \"pool\": \"192.0.2.0/24\" } ],"
|
||||
" \"subnet\": \"192.0.2.0/24\", "
|
||||
" \"reservation-mode\": \"all\""
|
||||
" },"
|
||||
" {"
|
||||
" \"pools\": [ { \"pool\": \"192.0.3.0/24\" } ],"
|
||||
" \"subnet\": \"192.0.3.0/24\""
|
||||
" } ],"
|
||||
"\"valid-lifetime\": 4000 }";
|
||||
|
||||
ConstElementPtr json;
|
||||
ASSERT_NO_THROW(json = parseDHCP4(hr_config));
|
||||
extractConfig(hr_config);
|
||||
ConstElementPtr result;
|
||||
EXPECT_NO_THROW(result = configureDhcp4Server(*srv_, json));
|
||||
|
||||
// returned value should be 0 (success)
|
||||
checkResult(result, 0);
|
||||
|
||||
// Let's get all subnets and check that there are 4 of them.
|
||||
ConstCfgSubnets4Ptr subnets = CfgMgr::instance().getStagingCfg()->getCfgSubnets4();
|
||||
ASSERT_TRUE(subnets);
|
||||
const Subnet4Collection* subnet_col = subnets->getAll();
|
||||
ASSERT_EQ(2, subnet_col->size()); // We expect 2 subnets
|
||||
|
||||
// Let's check if the parsed subnets have correct HR modes.
|
||||
|
||||
// Subnet 1
|
||||
Subnet4Ptr subnet;
|
||||
subnet = subnets->selectSubnet(IOAddress("192.0.2.1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
// Reset the fetch global function to staging (vs current) config.
|
||||
subnet->setFetchGlobalsFn([]() -> ConstElementPtr {
|
||||
return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
|
||||
});
|
||||
EXPECT_EQ(Network::HR_ALL, subnet->getHostReservationMode());
|
||||
|
||||
// Subnet 2
|
||||
subnet = subnets->selectSubnet(IOAddress("192.0.3.1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
// Reset the fetch global function to staging (vs current) config.
|
||||
subnet->setFetchGlobalsFn([]() -> ConstElementPtr {
|
||||
return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
|
||||
});
|
||||
EXPECT_EQ(Network::HR_OUT_OF_POOL, subnet->getHostReservationMode());
|
||||
}
|
||||
|
||||
/// The goal of this test is to verify that Host Reservation modes can be
|
||||
/// specified globally.
|
||||
TEST_F(Dhcp4ParserTest, hostReservationModesGlobal) {
|
||||
|
||||
/// - Configuration:
|
||||
/// - only addresses (no prefixes)
|
||||
/// - 2 subnets with :
|
||||
/// - 192.0.2.0/24 (all reservations enabled)
|
||||
/// - 192.0.3.0/24 (reservations not specified)
|
||||
const char* hr_config =
|
||||
"{ "
|
||||
"\"rebind-timer\": 2000, "
|
||||
"\"renew-timer\": 1000, "
|
||||
"\"reservations-global\": false,"
|
||||
"\"reservations-in-subnet\": true,"
|
||||
"\"reservations-out-of-pool\": true,"
|
||||
"\"subnet4\": [ { "
|
||||
" \"pools\": [ { \"pool\": \"192.0.2.0/24\" } ],"
|
||||
" \"subnet\": \"192.0.2.0/24\", "
|
||||
" \"reservations-in-subnet\": true"
|
||||
" \"reservations-global\": false,"
|
||||
" \"reservations-in-subnet\": true,"
|
||||
" \"reservations-out-of-pool\": false"
|
||||
" },"
|
||||
" {"
|
||||
" \"pools\": [ { \"pool\": \"192.0.3.0/24\" } ],"
|
||||
@ -5593,7 +5468,9 @@ TEST_F(Dhcp4ParserTest, hostReservationModesGlobal) {
|
||||
subnet->setFetchGlobalsFn([]() -> ConstElementPtr {
|
||||
return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
|
||||
});
|
||||
EXPECT_EQ(Network::HR_ALL, subnet->getHostReservationMode());
|
||||
EXPECT_FALSE(subnet->getReservationsGlobal());
|
||||
EXPECT_TRUE(subnet->getReservationsInSubnet());
|
||||
EXPECT_FALSE(subnet->getReservationsOutOfPool());
|
||||
|
||||
// Subnet 2
|
||||
subnet = subnets->selectSubnet(IOAddress("192.0.3.1"));
|
||||
@ -5602,7 +5479,9 @@ TEST_F(Dhcp4ParserTest, hostReservationModesGlobal) {
|
||||
subnet->setFetchGlobalsFn([]() -> ConstElementPtr {
|
||||
return (CfgMgr::instance().getStagingCfg()->getConfiguredGlobals());
|
||||
});
|
||||
EXPECT_EQ(Network::HR_OUT_OF_POOL, subnet->getHostReservationMode());
|
||||
EXPECT_FALSE(subnet->getReservationsGlobal());
|
||||
EXPECT_TRUE(subnet->getReservationsInSubnet());
|
||||
EXPECT_TRUE(subnet->getReservationsOutOfPool());
|
||||
}
|
||||
|
||||
/// Check that the decline-probation-period has a default value when not
|
||||
@ -6459,7 +6338,9 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDerive) {
|
||||
" \"relay\": {\n"
|
||||
" \"ip-address\": \"5.6.7.8\"\n"
|
||||
" },\n"
|
||||
" \"reservations-out-of-pool\": true,"
|
||||
" \"reservations-global\": false,\n"
|
||||
" \"reservations-in-subnet\": true,\n"
|
||||
" \"reservations-out-of-pool\": true,\n"
|
||||
" \"renew-timer\": 10,\n"
|
||||
" \"rebind-timer\": 20,\n"
|
||||
" \"valid-lifetime\": 40,\n"
|
||||
@ -6485,7 +6366,9 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDerive) {
|
||||
" \"relay\": {\n"
|
||||
" \"ip-address\": \"55.66.77.88\"\n"
|
||||
" },\n"
|
||||
" \"reservations-global\": false"
|
||||
" \"reservations-global\": false,\n"
|
||||
" \"reservations-in-subnet\": false,\n"
|
||||
" \"reservations-out-of-pool\": false\n"
|
||||
" }\n"
|
||||
" ]\n"
|
||||
" },\n"
|
||||
@ -6536,7 +6419,9 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDerive) {
|
||||
EXPECT_EQ("foo", s->getSname().get());
|
||||
EXPECT_EQ("bar", s->getFilename().get());
|
||||
EXPECT_TRUE(s->hasRelayAddress(IOAddress("5.6.7.8")));
|
||||
EXPECT_EQ(Network::HR_OUT_OF_POOL, s->getHostReservationMode());
|
||||
EXPECT_FALSE(s->getReservationsGlobal());
|
||||
EXPECT_TRUE(s->getReservationsInSubnet());
|
||||
EXPECT_TRUE(s->getReservationsOutOfPool());
|
||||
|
||||
// For the second subnet, the renew-timer should be 100, because it
|
||||
// was specified explicitly. Other parameters a derived
|
||||
@ -6553,7 +6438,9 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDerive) {
|
||||
EXPECT_EQ("some-name.example.org", s->getSname().get());
|
||||
EXPECT_EQ("bootfile.efi", s->getFilename().get());
|
||||
EXPECT_TRUE(s->hasRelayAddress(IOAddress("55.66.77.88")));
|
||||
EXPECT_EQ(Network::HR_DISABLED, s->getHostReservationMode());
|
||||
EXPECT_FALSE(s->getReservationsGlobal());
|
||||
EXPECT_FALSE(s->getReservationsInSubnet());
|
||||
EXPECT_FALSE(s->getReservationsOutOfPool());
|
||||
|
||||
// Ok, now check the second shared subnet.
|
||||
net = nets->at(1);
|
||||
@ -6574,7 +6461,9 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDerive) {
|
||||
EXPECT_TRUE(s->getSname().empty());
|
||||
EXPECT_TRUE(s->getFilename().empty());
|
||||
EXPECT_FALSE(s->hasRelays());
|
||||
EXPECT_EQ(Network::HR_ALL, s->getHostReservationMode());
|
||||
EXPECT_FALSE(s->getReservationsGlobal());
|
||||
EXPECT_TRUE(s->getReservationsInSubnet());
|
||||
EXPECT_FALSE(s->getReservationsOutOfPool());
|
||||
}
|
||||
|
||||
// This test checks if client-class is derived properly.
|
||||
|
@ -1809,7 +1809,7 @@ TEST_F(DORATest, reservationModeDisabled) {
|
||||
// Set explicit HW address so as it matches the reservation in the
|
||||
// configuration used below.
|
||||
client.setHWAddress("aa:bb:cc:dd:ee:ff");
|
||||
// Configure DHCP server. In this configuration the reservation flags are
|
||||
// Configure DHCP server. In this configuration the reservations flags are
|
||||
// set to false. Thus, the server should ignore the reservation for
|
||||
// this client.
|
||||
configure(DORA_CONFIGS[13], *client.getServer());
|
||||
|
@ -1258,39 +1258,6 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu]
|
||||
}
|
||||
}
|
||||
|
||||
\"reservations-out-of-pool\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser6Context::DHCP6:
|
||||
case isc::dhcp::Parser6Context::SUBNET6:
|
||||
case isc::dhcp::Parser6Context::SHARED_NETWORK:
|
||||
return isc::dhcp::Dhcp6Parser::make_RESERVATIONS_OUT_OF_POOL(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp6Parser::make_STRING("reservations-out-of-pool", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"reservations-in-subnet\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser6Context::DHCP6:
|
||||
case isc::dhcp::Parser6Context::SUBNET6:
|
||||
case isc::dhcp::Parser6Context::SHARED_NETWORK:
|
||||
return isc::dhcp::Dhcp6Parser::make_RESERVATIONS_IN_SUBNET(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp6Parser::make_STRING("reservations-in-subnet", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"reservations-global\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser6Context::DHCP6:
|
||||
case isc::dhcp::Parser6Context::SUBNET6:
|
||||
case isc::dhcp::Parser6Context::SHARED_NETWORK:
|
||||
return isc::dhcp::Dhcp6Parser::make_RESERVATIONS_GLOBAL(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp6Parser::make_STRING("reservations-global", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"reservation-mode\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser6Context::DHCP6:
|
||||
@ -1347,6 +1314,39 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu]
|
||||
}
|
||||
}
|
||||
|
||||
\"reservations-global\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser6Context::DHCP6:
|
||||
case isc::dhcp::Parser6Context::SUBNET6:
|
||||
case isc::dhcp::Parser6Context::SHARED_NETWORK:
|
||||
return isc::dhcp::Dhcp6Parser::make_RESERVATIONS_GLOBAL(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp6Parser::make_STRING("reservations-global", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"reservations-in-subnet\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser6Context::DHCP6:
|
||||
case isc::dhcp::Parser6Context::SUBNET6:
|
||||
case isc::dhcp::Parser6Context::SHARED_NETWORK:
|
||||
return isc::dhcp::Dhcp6Parser::make_RESERVATIONS_IN_SUBNET(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp6Parser::make_STRING("reservations-in-subnet", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"reservations-out-of-pool\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser6Context::DHCP6:
|
||||
case isc::dhcp::Parser6Context::SUBNET6:
|
||||
case isc::dhcp::Parser6Context::SHARED_NETWORK:
|
||||
return isc::dhcp::Dhcp6Parser::make_RESERVATIONS_OUT_OF_POOL(driver.loc_);
|
||||
default:
|
||||
return isc::dhcp::Dhcp6Parser::make_STRING("reservations-out-of-pool", driver.loc_);
|
||||
}
|
||||
}
|
||||
|
||||
\"code\" {
|
||||
switch(driver.ctx_) {
|
||||
case isc::dhcp::Parser6Context::OPTION_DEF:
|
||||
|
@ -145,13 +145,13 @@ using namespace std;
|
||||
ID "id"
|
||||
RAPID_COMMIT "rapid-commit"
|
||||
RESERVATION_MODE "reservation-mode"
|
||||
RESERVATIONS_OUT_OF_POOL "reservations-out-of-pool"
|
||||
RESERVATIONS_IN_SUBNET "reservations-in-subnet"
|
||||
RESERVATIONS_GLOBAL "reservations-global"
|
||||
DISABLED "disabled"
|
||||
OUT_OF_POOL "out-of-pool"
|
||||
GLOBAL "global"
|
||||
ALL "all"
|
||||
RESERVATIONS_GLOBAL "reservations-global"
|
||||
RESERVATIONS_IN_SUBNET "reservations-in-subnet"
|
||||
RESERVATIONS_OUT_OF_POOL "reservations-out-of-pool"
|
||||
|
||||
MAC_SOURCES "mac-sources"
|
||||
RELAY_SUPPLIED_OPTIONS "relay-supplied-options"
|
||||
@ -495,9 +495,9 @@ global_param: data_directory
|
||||
| config_control
|
||||
| server_tag
|
||||
| reservation_mode
|
||||
| reservations_out_of_pool
|
||||
| reservations_in_subnet
|
||||
| reservations_global
|
||||
| reservations_in_subnet
|
||||
| reservations_out_of_pool
|
||||
| calculate_tee_times
|
||||
| t1_percent
|
||||
| t2_percent
|
||||
@ -1393,9 +1393,9 @@ subnet6_param: preferred_lifetime
|
||||
| require_client_classes
|
||||
| reservations
|
||||
| reservation_mode
|
||||
| reservations_out_of_pool
|
||||
| reservations_in_subnet
|
||||
| reservations_global
|
||||
| reservations_in_subnet
|
||||
| reservations_out_of_pool
|
||||
| relay
|
||||
| user_context
|
||||
| comment
|
||||
@ -1465,10 +1465,10 @@ require_client_classes: REQUIRE_CLIENT_CLASSES {
|
||||
ctx.leave();
|
||||
};
|
||||
|
||||
reservations_out_of_pool: RESERVATIONS_OUT_OF_POOL COLON BOOLEAN {
|
||||
ctx.unique("reservations-out-of-pool", ctx.loc2pos(@1));
|
||||
reservations_global: RESERVATIONS_GLOBAL COLON BOOLEAN {
|
||||
ctx.unique("reservations-global", ctx.loc2pos(@1));
|
||||
ElementPtr b(new BoolElement($3, ctx.loc2pos(@3)));
|
||||
ctx.stack_.back()->set("reservations-out-of-pool", b);
|
||||
ctx.stack_.back()->set("reservations-global", b);
|
||||
};
|
||||
|
||||
reservations_in_subnet: RESERVATIONS_IN_SUBNET COLON BOOLEAN {
|
||||
@ -1477,10 +1477,10 @@ reservations_in_subnet: RESERVATIONS_IN_SUBNET COLON BOOLEAN {
|
||||
ctx.stack_.back()->set("reservations-in-subnet", b);
|
||||
};
|
||||
|
||||
reservations_global: RESERVATIONS_GLOBAL COLON BOOLEAN {
|
||||
ctx.unique("reservations-global", ctx.loc2pos(@1));
|
||||
reservations_out_of_pool: RESERVATIONS_OUT_OF_POOL COLON BOOLEAN {
|
||||
ctx.unique("reservations-out-of-pool", ctx.loc2pos(@1));
|
||||
ElementPtr b(new BoolElement($3, ctx.loc2pos(@3)));
|
||||
ctx.stack_.back()->set("reservations-global", b);
|
||||
ctx.stack_.back()->set("reservations-out-of-pool", b);
|
||||
};
|
||||
|
||||
reservation_mode: RESERVATION_MODE {
|
||||
@ -1553,9 +1553,9 @@ shared_network_param: name
|
||||
| option_data_list
|
||||
| relay
|
||||
| reservation_mode
|
||||
| reservations_out_of_pool
|
||||
| reservations_in_subnet
|
||||
| reservations_global
|
||||
| reservations_in_subnet
|
||||
| reservations_out_of_pool
|
||||
| client_class
|
||||
| require_client_classes
|
||||
| preferred_lifetime
|
||||
|
@ -3774,8 +3774,11 @@ Dhcpv6Srv::conditionallySetReservedClientClasses(const Pkt6Ptr& pkt,
|
||||
if (ctx.subnet_) {
|
||||
SharedNetwork6Ptr shared_network;
|
||||
ctx.subnet_->getSharedNetwork(shared_network);
|
||||
if (shared_network && !ctx.globalHost()) {
|
||||
setReservedClientClasses(pkt, ctx);
|
||||
if (shared_network) {
|
||||
ConstHostPtr host = ctx.currentHost();
|
||||
if (host && (host->getIPv6SubnetID() != SUBNET_ID_GLOBAL)) {
|
||||
setReservedClientClasses(pkt, ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -450,7 +450,12 @@ configureDhcp6Server(Dhcpv6Srv& server, isc::data::ConstElementPtr config_set,
|
||||
// Print the list of known backends.
|
||||
HostDataSourceFactory::printRegistered();
|
||||
|
||||
// Answer will hold the result.
|
||||
// This is a way to convert ConstElementPtr to ElementPtr.
|
||||
// We need a config that can be edited, because we will insert
|
||||
// default values and will insert derived values as well.
|
||||
ElementPtr mutable_cfg = boost::const_pointer_cast<Element>(config_set);
|
||||
|
||||
// answer will hold the result.
|
||||
ConstElementPtr answer;
|
||||
// Rollback informs whether error occurred and original data
|
||||
// have to be restored to global storages.
|
||||
@ -468,53 +473,17 @@ configureDhcp6Server(Dhcpv6Srv& server, isc::data::ConstElementPtr config_set,
|
||||
// default values and will insert derived values as well.
|
||||
mutable_cfg = boost::const_pointer_cast<Element>(config_set);
|
||||
|
||||
bool found = false;
|
||||
ConstElementPtr reservations_out_of_pool = mutable_cfg->get("reservations-out-of-pool");
|
||||
ConstElementPtr reservations_in_subnet = mutable_cfg->get("reservations-in-subnet");
|
||||
ConstElementPtr reservations_global = mutable_cfg->get("reservations-global");
|
||||
if (reservations_out_of_pool || reservations_in_subnet || reservations_global) {
|
||||
found = true;
|
||||
}
|
||||
ConstElementPtr reservation_mode = mutable_cfg->get("reservation-mode");
|
||||
if (reservation_mode) {
|
||||
LOG_WARN(dhcp6_logger, DHCP6_DEPRECATED_RESERVATION_MODE);
|
||||
if (found) {
|
||||
isc_throw(DhcpConfigError, "invalid use of both 'reservation-mode'"
|
||||
" and one of 'reservations-out-of-pool'"
|
||||
" , 'reservations-in-subnet' or"
|
||||
" 'reservations-global' parameters");
|
||||
}
|
||||
}
|
||||
|
||||
// reset all other reservation flags to overwrite default values.
|
||||
if (found) {
|
||||
bool force_true = false;
|
||||
if (!reservations_out_of_pool) {
|
||||
mutable_cfg->set("reservations-out-of-pool", Element::create(false));
|
||||
} else {
|
||||
force_true = reservations_out_of_pool->boolValue();
|
||||
}
|
||||
if (!reservations_in_subnet) {
|
||||
if (force_true) {
|
||||
mutable_cfg->set("reservations-in-subnet", Element::create(true));
|
||||
} else {
|
||||
mutable_cfg->set("reservations-in-subnet", Element::create(false));
|
||||
}
|
||||
} else if (force_true && !reservations_in_subnet->boolValue()) {
|
||||
isc_throw(DhcpConfigError, "invalid use of disabled 'reservations-in-subnet'"
|
||||
" when enabled 'reservations-out-of-pool'");
|
||||
}
|
||||
if (!reservations_global) {
|
||||
mutable_cfg->set("reservations-global", Element::create(false));
|
||||
}
|
||||
}
|
||||
|
||||
// Relocate dhcp-ddns parameters that have moved to global scope.
|
||||
// Rule is that a global value overrides the dhcp-ddns value, so
|
||||
// we need to do this before we apply global defaults.
|
||||
// Note this is done for backward compatibility.
|
||||
srv_config->moveDdnsParams(mutable_cfg);
|
||||
|
||||
// Move from reservation mode to new reservations flags.
|
||||
if (BaseNetworkParser::moveReservationMode(mutable_cfg)) {
|
||||
LOG_WARN(dhcp6_logger, DHCP6_DEPRECATED_RESERVATION_MODE);
|
||||
}
|
||||
|
||||
// Set all default values if not specified by the user.
|
||||
SimpleParser6::setAllDefaults(mutable_cfg);
|
||||
|
||||
@ -533,14 +502,6 @@ configureDhcp6Server(Dhcpv6Srv& server, isc::data::ConstElementPtr config_set,
|
||||
// Apply global options in the staging config, e.g. ip-reservations-unique
|
||||
global_parser.parseEarly(srv_config, mutable_cfg);
|
||||
|
||||
// If using deprecated reservation-mode, remove defaults for new parameters
|
||||
// reservations-out-of-pool, reservations-in-subnet and reservations-global.
|
||||
if (reservation_mode) {
|
||||
mutable_cfg->remove("reservations-out-of-pool");
|
||||
mutable_cfg->remove("reservations-in-subnet");
|
||||
mutable_cfg->remove("reservations-global");
|
||||
}
|
||||
|
||||
// Specific check for this global parameter.
|
||||
ConstElementPtr data_directory = mutable_cfg->get("data-directory");
|
||||
if (data_directory) {
|
||||
@ -810,9 +771,9 @@ configureDhcp6Server(Dhcpv6Srv& server, isc::data::ConstElementPtr config_set,
|
||||
(config_pair.first == "dhcp4o6-port") ||
|
||||
(config_pair.first == "server-tag") ||
|
||||
(config_pair.first == "reservation-mode") ||
|
||||
(config_pair.first == "reservations-out-of-pool") ||
|
||||
(config_pair.first == "reservations-in-subnet") ||
|
||||
(config_pair.first == "reservations-global") ||
|
||||
(config_pair.first == "reservations-in-subnet") ||
|
||||
(config_pair.first == "reservations-out-of-pool") ||
|
||||
(config_pair.first == "calculate-tee-times") ||
|
||||
(config_pair.first == "t1-percent") ||
|
||||
(config_pair.first == "t2-percent") ||
|
||||
|
@ -5649,99 +5649,10 @@ TEST_F(Dhcp6ParserTest, macSourcesBogus) {
|
||||
checkResult(status, 1);
|
||||
}
|
||||
|
||||
/// The goal of this test is to verify that Host Reservation modes can be
|
||||
/// The goal of this test is to verify that Host Reservation flags can be
|
||||
/// specified on a per-subnet basis.
|
||||
TEST_F(Dhcp6ParserTest, hostReservationPerSubnet) {
|
||||
|
||||
/// - Configuration:
|
||||
/// - only addresses (no prefixes)
|
||||
/// - 5 subnets with:
|
||||
/// - 2001:db8:1::/64 (all reservations enabled)
|
||||
/// - 2001:db8:2::/64 (out-of-pool reservations)
|
||||
/// - 2001:db8:3::/64 (reservations disabled)
|
||||
/// - 2001:db8:4::/64 (global reservations)
|
||||
/// - 2001:db8:5::/64 (reservations not specified)
|
||||
const char* hr_config =
|
||||
"{"
|
||||
"\"preferred-lifetime\": 3000,"
|
||||
"\"rebind-timer\": 2000, "
|
||||
"\"renew-timer\": 1000, "
|
||||
"\"subnet6\": [ { "
|
||||
" \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ],"
|
||||
" \"subnet\": \"2001:db8:1::/48\", "
|
||||
" \"reservation-mode\": \"all\""
|
||||
" },"
|
||||
" {"
|
||||
" \"pools\": [ { \"pool\": \"2001:db8:2::/64\" } ],"
|
||||
" \"subnet\": \"2001:db8:2::/48\", "
|
||||
" \"reservation-mode\": \"out-of-pool\""
|
||||
" },"
|
||||
" {"
|
||||
" \"pools\": [ { \"pool\": \"2001:db8:3::/64\" } ],"
|
||||
" \"subnet\": \"2001:db8:3::/48\", "
|
||||
" \"reservation-mode\": \"disabled\""
|
||||
" },"
|
||||
" {"
|
||||
" \"pools\": [ { \"pool\": \"2001:db8:4::/64\" } ],"
|
||||
" \"subnet\": \"2001:db8:4::/48\", "
|
||||
" \"reservation-mode\": \"global\""
|
||||
" },"
|
||||
" {"
|
||||
" \"pools\": [ { \"pool\": \"2001:db8:5::/64\" } ],"
|
||||
" \"subnet\": \"2001:db8:5::/48\" "
|
||||
" } ],"
|
||||
"\"valid-lifetime\": 4000 }";
|
||||
|
||||
ConstElementPtr json;
|
||||
ASSERT_NO_THROW(json = parseDHCP6(hr_config));
|
||||
extractConfig(hr_config);
|
||||
|
||||
ConstElementPtr status;
|
||||
EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
|
||||
|
||||
// returned value should be 0 (success)
|
||||
checkResult(status, 0);
|
||||
CfgMgr::instance().commit();
|
||||
|
||||
// Let's get all subnets and check that there are 5 of them.
|
||||
ConstCfgSubnets6Ptr subnets = CfgMgr::instance().getCurrentCfg()->getCfgSubnets6();
|
||||
ASSERT_TRUE(subnets);
|
||||
const Subnet6Collection* subnet_col = subnets->getAll();
|
||||
ASSERT_EQ(5, subnet_col->size()); // We expect 5 subnets
|
||||
|
||||
// Let's check if the parsed subnets have correct HR modes.
|
||||
|
||||
// Subnet 1
|
||||
Subnet6Ptr subnet;
|
||||
subnet = subnets->selectSubnet(IOAddress("2001:db8:1::1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_ALL, subnet->getHostReservationMode());
|
||||
|
||||
// Subnet 2
|
||||
subnet = subnets->selectSubnet(IOAddress("2001:db8:2::1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_OUT_OF_POOL, subnet->getHostReservationMode());
|
||||
|
||||
// Subnet 3
|
||||
subnet = subnets->selectSubnet(IOAddress("2001:db8:3::1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_DISABLED, subnet->getHostReservationMode());
|
||||
|
||||
// Subnet 4
|
||||
subnet = subnets->selectSubnet(IOAddress("2001:db8:4::1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_GLOBAL, subnet->getHostReservationMode());
|
||||
|
||||
// Subnet 5
|
||||
subnet = subnets->selectSubnet(IOAddress("2001:db8:5::1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_ALL, subnet->getHostReservationMode());
|
||||
}
|
||||
|
||||
/// The goal of this test is to verify that Host Reservation modes can be
|
||||
/// specified on a per-subnet basis.
|
||||
TEST_F(Dhcp6ParserTest, hostReservationModesPerSubnet) {
|
||||
|
||||
/// - Configuration:
|
||||
/// - only addresses (no prefixes)
|
||||
/// - 7 subnets with:
|
||||
@ -5760,24 +5671,30 @@ TEST_F(Dhcp6ParserTest, hostReservationModesPerSubnet) {
|
||||
"\"subnet6\": [ { "
|
||||
" \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ],"
|
||||
" \"subnet\": \"2001:db8:1::/48\", "
|
||||
" \"reservations-in-subnet\": true"
|
||||
" \"reservations-global\": false,"
|
||||
" \"reservations-in-subnet\": true,"
|
||||
" \"reservations-out-of-pool\": false"
|
||||
" },"
|
||||
" {"
|
||||
" \"pools\": [ { \"pool\": \"2001:db8:2::/64\" } ],"
|
||||
" \"subnet\": \"2001:db8:2::/48\", "
|
||||
" \"reservations-global\": false,"
|
||||
" \"reservations-in-subnet\": true,"
|
||||
" \"reservations-out-of-pool\": true"
|
||||
" },"
|
||||
" {"
|
||||
" \"pools\": [ { \"pool\": \"2001:db8:3::/64\" } ],"
|
||||
" \"subnet\": \"2001:db8:3::/48\", "
|
||||
" \"reservations-out-of-pool\": false,"
|
||||
" \"reservations-global\": false,"
|
||||
" \"reservations-in-subnet\": false,"
|
||||
" \"reservations-global\": false"
|
||||
" \"reservations-out-of-pool\": false"
|
||||
" },"
|
||||
" {"
|
||||
" \"pools\": [ { \"pool\": \"2001:db8:4::/64\" } ],"
|
||||
" \"subnet\": \"2001:db8:4::/48\", "
|
||||
" \"reservations-global\": true"
|
||||
" \"reservations-global\": true,"
|
||||
" \"reservations-in-subnet\": false,"
|
||||
" \"reservations-out-of-pool\": false"
|
||||
" },"
|
||||
" {"
|
||||
" \"pools\": [ { \"pool\": \"2001:db8:5::/64\" } ],"
|
||||
@ -5786,16 +5703,16 @@ TEST_F(Dhcp6ParserTest, hostReservationModesPerSubnet) {
|
||||
" {"
|
||||
" \"pools\": [ { \"pool\": \"2001:db8:6::/64\" } ],"
|
||||
" \"subnet\": \"2001:db8:6::/48\", "
|
||||
" \"reservations-out-of-pool\": false,"
|
||||
" \"reservations-global\": true,"
|
||||
" \"reservations-in-subnet\": true,"
|
||||
" \"reservations-global\": true"
|
||||
" \"reservations-out-of-pool\": false"
|
||||
" },"
|
||||
" {"
|
||||
" \"pools\": [ { \"pool\": \"2001:db8:7::/64\" } ],"
|
||||
" \"subnet\": \"2001:db8:7::/48\", "
|
||||
" \"reservations-out-of-pool\": true,"
|
||||
" \"reservations-global\": true,"
|
||||
" \"reservations-in-subnet\": true,"
|
||||
" \"reservations-global\": true"
|
||||
" \"reservations-out-of-pool\": true"
|
||||
" } ],"
|
||||
"\"valid-lifetime\": 4000 }";
|
||||
|
||||
@ -5822,41 +5739,55 @@ TEST_F(Dhcp6ParserTest, hostReservationModesPerSubnet) {
|
||||
Subnet6Ptr subnet;
|
||||
subnet = subnets->selectSubnet(IOAddress("2001:db8:1::1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_ALL, subnet->getHostReservationMode());
|
||||
EXPECT_FALSE(subnet->getReservationsGlobal());
|
||||
EXPECT_TRUE(subnet->getReservationsInSubnet());
|
||||
EXPECT_FALSE(subnet->getReservationsOutOfPool());
|
||||
|
||||
// Subnet 2
|
||||
subnet = subnets->selectSubnet(IOAddress("2001:db8:2::1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_OUT_OF_POOL, subnet->getHostReservationMode());
|
||||
EXPECT_FALSE(subnet->getReservationsGlobal());
|
||||
EXPECT_TRUE(subnet->getReservationsInSubnet());
|
||||
EXPECT_TRUE(subnet->getReservationsOutOfPool());
|
||||
|
||||
// Subnet 3
|
||||
subnet = subnets->selectSubnet(IOAddress("2001:db8:3::1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_DISABLED, subnet->getHostReservationMode());
|
||||
EXPECT_FALSE(subnet->getReservationsGlobal());
|
||||
EXPECT_FALSE(subnet->getReservationsInSubnet());
|
||||
EXPECT_FALSE(subnet->getReservationsOutOfPool());
|
||||
|
||||
// Subnet 4
|
||||
subnet = subnets->selectSubnet(IOAddress("2001:db8:4::1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_GLOBAL, subnet->getHostReservationMode());
|
||||
EXPECT_TRUE(subnet->getReservationsGlobal());
|
||||
EXPECT_FALSE(subnet->getReservationsInSubnet());
|
||||
EXPECT_FALSE(subnet->getReservationsOutOfPool());
|
||||
|
||||
// Subnet 5
|
||||
subnet = subnets->selectSubnet(IOAddress("2001:db8:5::1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_ALL, subnet->getHostReservationMode());
|
||||
EXPECT_FALSE(subnet->getReservationsGlobal());
|
||||
EXPECT_TRUE(subnet->getReservationsInSubnet());
|
||||
EXPECT_FALSE(subnet->getReservationsOutOfPool());
|
||||
|
||||
// Subnet 6
|
||||
subnet = subnets->selectSubnet(IOAddress("2001:db8:6::1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_ALL|Network::HR_GLOBAL, subnet->getHostReservationMode());
|
||||
EXPECT_TRUE(subnet->getReservationsGlobal());
|
||||
EXPECT_TRUE(subnet->getReservationsInSubnet());
|
||||
EXPECT_FALSE(subnet->getReservationsOutOfPool());
|
||||
|
||||
// Subnet 7
|
||||
subnet = subnets->selectSubnet(IOAddress("2001:db8:7::1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_OUT_OF_POOL|Network::HR_GLOBAL,
|
||||
subnet->getHostReservationMode());
|
||||
EXPECT_TRUE(subnet->getReservationsGlobal());
|
||||
EXPECT_TRUE(subnet->getReservationsInSubnet());
|
||||
EXPECT_TRUE(subnet->getReservationsOutOfPool());
|
||||
|
||||
}
|
||||
|
||||
/// The goal of this test is to verify that Host Reservation modes can be
|
||||
/// The goal of this test is to verify that Host Reservation flags can be
|
||||
/// specified globally.
|
||||
TEST_F(Dhcp6ParserTest, hostReservationGlobal) {
|
||||
|
||||
@ -5870,68 +5801,15 @@ TEST_F(Dhcp6ParserTest, hostReservationGlobal) {
|
||||
"\"preferred-lifetime\": 3000,"
|
||||
"\"rebind-timer\": 2000, "
|
||||
"\"renew-timer\": 1000, "
|
||||
"\"reservation-mode\": \"out-of-pool\", "
|
||||
"\"subnet6\": [ { "
|
||||
" \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ],"
|
||||
" \"subnet\": \"2001:db8:1::/48\", "
|
||||
" \"reservation-mode\": \"all\""
|
||||
" },"
|
||||
" {"
|
||||
" \"pools\": [ { \"pool\": \"2001:db8:2::/64\" } ],"
|
||||
" \"subnet\": \"2001:db8:2::/48\" "
|
||||
" } ],"
|
||||
"\"valid-lifetime\": 4000 }";
|
||||
|
||||
ConstElementPtr json;
|
||||
ASSERT_NO_THROW(json = parseDHCP6(hr_config));
|
||||
extractConfig(hr_config);
|
||||
|
||||
ConstElementPtr status;
|
||||
EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json));
|
||||
|
||||
// returned value should be 0 (success)
|
||||
checkResult(status, 0);
|
||||
CfgMgr::instance().commit();
|
||||
|
||||
// Let's get all subnets and check that there are 2 of them.
|
||||
ConstCfgSubnets6Ptr subnets = CfgMgr::instance().getCurrentCfg()->getCfgSubnets6();
|
||||
ASSERT_TRUE(subnets);
|
||||
const Subnet6Collection* subnet_col = subnets->getAll();
|
||||
ASSERT_EQ(2, subnet_col->size()); // We expect 2 subnets
|
||||
|
||||
// Let's check if the parsed subnets have correct HR modes.
|
||||
|
||||
// Subnet 1
|
||||
Subnet6Ptr subnet;
|
||||
subnet = subnets->selectSubnet(IOAddress("2001:db8:1::1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_ALL, subnet->getHostReservationMode());
|
||||
|
||||
// Subnet 2
|
||||
subnet = subnets->selectSubnet(IOAddress("2001:db8:2::1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_OUT_OF_POOL, subnet->getHostReservationMode());
|
||||
}
|
||||
|
||||
/// The goal of this test is to verify that Host Reservation modes can be
|
||||
/// specified globally.
|
||||
TEST_F(Dhcp6ParserTest, hostReservationModesGlobal) {
|
||||
|
||||
/// - Configuration:
|
||||
/// - only addresses (no prefixes)
|
||||
/// - 2 subnets with:
|
||||
/// - 2001:db8:1::/64 (all reservations enabled)
|
||||
/// - 2001:db8:2::/64 (reservations not specified)
|
||||
const char* hr_config =
|
||||
"{"
|
||||
"\"preferred-lifetime\": 3000,"
|
||||
"\"rebind-timer\": 2000, "
|
||||
"\"renew-timer\": 1000, "
|
||||
"\"reservations-global\": false,"
|
||||
"\"reservations-in-subnet\": true,"
|
||||
"\"reservations-out-of-pool\": true,"
|
||||
"\"subnet6\": [ { "
|
||||
" \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ],"
|
||||
" \"subnet\": \"2001:db8:1::/48\", "
|
||||
" \"reservations-in-subnet\": true"
|
||||
" \"reservations-global\": false,"
|
||||
" \"reservations-in-subnet\": true,"
|
||||
" \"reservations-out-of-pool\": false"
|
||||
" },"
|
||||
" {"
|
||||
" \"pools\": [ { \"pool\": \"2001:db8:2::/64\" } ],"
|
||||
@ -5962,12 +5840,16 @@ TEST_F(Dhcp6ParserTest, hostReservationModesGlobal) {
|
||||
Subnet6Ptr subnet;
|
||||
subnet = subnets->selectSubnet(IOAddress("2001:db8:1::1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_ALL, subnet->getHostReservationMode());
|
||||
EXPECT_FALSE(subnet->getReservationsGlobal());
|
||||
EXPECT_TRUE(subnet->getReservationsInSubnet());
|
||||
EXPECT_FALSE(subnet->getReservationsOutOfPool());
|
||||
|
||||
// Subnet 2
|
||||
subnet = subnets->selectSubnet(IOAddress("2001:db8:2::1"));
|
||||
ASSERT_TRUE(subnet);
|
||||
EXPECT_EQ(Network::HR_OUT_OF_POOL, subnet->getHostReservationMode());
|
||||
EXPECT_FALSE(subnet->getReservationsGlobal());
|
||||
EXPECT_TRUE(subnet->getReservationsInSubnet());
|
||||
EXPECT_TRUE(subnet->getReservationsOutOfPool());
|
||||
}
|
||||
|
||||
/// The goal of this test is to verify that configuration can include
|
||||
@ -6889,7 +6771,9 @@ TEST_F(Dhcp6ParserTest, sharedNetworksDerive) {
|
||||
" \"ip-address\": \"1111::1\"\n"
|
||||
" },\n"
|
||||
" \"rapid-commit\": true,\n"
|
||||
" \"reservations-global\": false,"
|
||||
" \"reservations-global\": false,\n"
|
||||
" \"reservations-in-subnet\": false,\n"
|
||||
" \"reservations-out-of-pool\": false,\n"
|
||||
" \"subnet6\": [\n"
|
||||
" { \n"
|
||||
" \"subnet\": \"2001:db1::/48\",\n"
|
||||
@ -6911,7 +6795,9 @@ TEST_F(Dhcp6ParserTest, sharedNetworksDerive) {
|
||||
" \"max-valid-lifetime\": 500, \n"
|
||||
" \"interface-id\": \"twotwo\",\n"
|
||||
" \"rapid-commit\": true,\n"
|
||||
" \"reservations-out-of-pool\": true"
|
||||
" \"reservations-global\": false,\n"
|
||||
" \"reservations-in-subnet\": true,\n"
|
||||
" \"reservations-out-of-pool\": true\n"
|
||||
" }\n"
|
||||
" ]\n"
|
||||
" },\n"
|
||||
@ -6957,7 +6843,9 @@ TEST_F(Dhcp6ParserTest, sharedNetworksDerive) {
|
||||
EXPECT_TRUE(iface_id1.equals(s->getInterfaceId()));
|
||||
EXPECT_TRUE(s->hasRelayAddress(IOAddress("1111::1")));
|
||||
EXPECT_TRUE(s->getRapidCommit());
|
||||
EXPECT_EQ(Network::HR_DISABLED, s->getHostReservationMode());
|
||||
EXPECT_FALSE(s->getReservationsGlobal());
|
||||
EXPECT_FALSE(s->getReservationsInSubnet());
|
||||
EXPECT_FALSE(s->getReservationsOutOfPool());
|
||||
EXPECT_TRUE(s->getStoreExtendedInfo());
|
||||
|
||||
// For the second subnet, the renew-timer should be 100, because it
|
||||
@ -6970,7 +6858,9 @@ TEST_F(Dhcp6ParserTest, sharedNetworksDerive) {
|
||||
EXPECT_TRUE(iface_id2.equals(s->getInterfaceId()));
|
||||
EXPECT_TRUE(s->hasRelayAddress(IOAddress("2222::2")));
|
||||
EXPECT_TRUE(s->getRapidCommit());
|
||||
EXPECT_EQ(Network::HR_OUT_OF_POOL, s->getHostReservationMode());
|
||||
EXPECT_FALSE(s->getReservationsGlobal());
|
||||
EXPECT_TRUE(s->getReservationsInSubnet());
|
||||
EXPECT_TRUE(s->getReservationsOutOfPool());
|
||||
EXPECT_TRUE(s->getStoreExtendedInfo());
|
||||
|
||||
// Ok, now check the second shared subnet.
|
||||
@ -6986,7 +6876,9 @@ TEST_F(Dhcp6ParserTest, sharedNetworksDerive) {
|
||||
EXPECT_FALSE(s->getInterfaceId());
|
||||
EXPECT_FALSE(s->hasRelays());
|
||||
EXPECT_FALSE(s->getRapidCommit());
|
||||
EXPECT_EQ(Network::HR_ALL, s->getHostReservationMode());
|
||||
EXPECT_FALSE(s->getReservationsGlobal());
|
||||
EXPECT_TRUE(s->getReservationsInSubnet());
|
||||
EXPECT_FALSE(s->getReservationsOutOfPool());
|
||||
EXPECT_FALSE(s->getStoreExtendedInfo());
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,9 @@ const char* CONFIGS[] = {
|
||||
" \"pools\": [ { \"pool\": \"2001:db8:1::1 - 2001:db8:1::10\" } ],"
|
||||
" \"subnet\": \"2001:db8:1::/48\", "
|
||||
" \"interface\": \"eth0\", "
|
||||
" \"reservation-mode\": \"out-of-pool\","
|
||||
" \"reservations-global\": false,"
|
||||
" \"reservations-in-subnet\": true,"
|
||||
" \"reservations-out-of-pool\": true,"
|
||||
" \"reservations\": [ "
|
||||
" {"
|
||||
" \"duid\": \"aa:bb:cc:dd:ee:ff\","
|
||||
|
@ -267,7 +267,7 @@ public:
|
||||
MySqlBinding::createString(RELAY_BUF_LENGTH), // relay
|
||||
MySqlBinding::createInteger<uint32_t>(), // renew_timer
|
||||
MySqlBinding::createString(REQUIRE_CLIENT_CLASSES_BUF_LENGTH), // require_client_classes
|
||||
MySqlBinding::createInteger<uint8_t>(), // reservation_mode
|
||||
MySqlBinding::createInteger<uint8_t>(), // reservations_global
|
||||
MySqlBinding::createString(SERVER_HOSTNAME_BUF_LENGTH), // server_hostname
|
||||
MySqlBinding::createString(SHARED_NETWORK_NAME_BUF_LENGTH), // shared_network_name
|
||||
MySqlBinding::createString(USER_CONTEXT_BUF_LENGTH), // user_context
|
||||
@ -316,6 +316,8 @@ public:
|
||||
MySqlBinding::createInteger<uint8_t>(), // ddns_replace_client_name
|
||||
MySqlBinding::createString(DNS_NAME_BUF_LENGTH), // ddns_generated_prefix
|
||||
MySqlBinding::createString(DNS_NAME_BUF_LENGTH), // ddns_qualifying_suffix
|
||||
MySqlBinding::createInteger<uint8_t>(), // reservations_in_subnet
|
||||
MySqlBinding::createInteger<uint8_t>(), // reservations_out_of_pool
|
||||
MySqlBinding::createString(SERVER_TAG_BUF_LENGTH) // server_tag
|
||||
};
|
||||
|
||||
@ -353,13 +355,17 @@ public:
|
||||
|
||||
// subnet_id
|
||||
SubnetID subnet_id(out_bindings[0]->getInteger<uint32_t>());
|
||||
|
||||
// subnet_prefix
|
||||
std::string subnet_prefix = out_bindings[1]->getString();
|
||||
auto prefix_pair = Subnet4::parsePrefix(subnet_prefix);
|
||||
|
||||
// renew_timer
|
||||
auto renew_timer = createTriplet(out_bindings[13]);
|
||||
|
||||
// rebind_timer
|
||||
auto rebind_timer = createTriplet(out_bindings[11]);
|
||||
|
||||
// valid_lifetime (and {min,max)_valid_lifetime)
|
||||
auto valid_lifetime = createTriplet(out_bindings[19],
|
||||
out_bindings[53],
|
||||
@ -374,6 +380,7 @@ public:
|
||||
if (!out_bindings[2]->amNull()) {
|
||||
last_subnet->get4o6().setIface4o6(out_bindings[2]->getString());
|
||||
}
|
||||
|
||||
// 4o6_interface_id
|
||||
if (!out_bindings[3]->amNull()) {
|
||||
std::string dhcp4o6_interface_id = out_bindings[3]->getString();
|
||||
@ -383,6 +390,7 @@ public:
|
||||
Option::create(Option::V6, D6O_INTERFACE_ID, dhcp4o6_interface_id_buf);
|
||||
last_subnet->get4o6().setInterfaceId(option_dhcp4o6_interface_id);
|
||||
}
|
||||
|
||||
// 4o6_subnet
|
||||
if (!out_bindings[4]->amNull()) {
|
||||
std::pair<IOAddress, uint8_t> dhcp4o6_subnet_prefix_pair =
|
||||
@ -390,6 +398,7 @@ public:
|
||||
last_subnet->get4o6().setSubnet4o6(dhcp4o6_subnet_prefix_pair.first,
|
||||
dhcp4o6_subnet_prefix_pair.second);
|
||||
}
|
||||
|
||||
// boot_file_name
|
||||
if (!out_bindings[5]->amNull()) {
|
||||
last_subnet->setFilename(out_bindings[5]->getString());
|
||||
@ -399,6 +408,7 @@ public:
|
||||
if (!out_bindings[6]->amNull()) {
|
||||
last_subnet->allowClientClass(out_bindings[6]->getString());
|
||||
}
|
||||
|
||||
// interface
|
||||
if (!out_bindings[7]->amNull()) {
|
||||
last_subnet->setIface(out_bindings[7]->getString());
|
||||
@ -450,10 +460,9 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// reservation_mode
|
||||
// reservations_global
|
||||
if (!out_bindings[15]->amNull()) {
|
||||
last_subnet->setHostReservationMode(static_cast<Network::HRMode>
|
||||
(out_bindings[15]->getInteger<uint8_t>()));
|
||||
last_subnet->setReservationsGlobal(out_bindings[15]->getBool());
|
||||
}
|
||||
|
||||
// server_hostname
|
||||
@ -492,42 +501,46 @@ public:
|
||||
last_subnet->setAuthoritative(out_bindings[52]->getBool());
|
||||
}
|
||||
|
||||
// {min,max}_valid_lifetime
|
||||
|
||||
// pool client_class, require_client_classes and user_context
|
||||
|
||||
// ddns_send_updates at 58
|
||||
// ddns_send_updates
|
||||
if (!out_bindings[58]->amNull()) {
|
||||
last_subnet->setDdnsSendUpdates(out_bindings[58]->getBool());
|
||||
}
|
||||
|
||||
// ddns_override_no_update at 59
|
||||
// ddns_override_no_update
|
||||
if (!out_bindings[59]->amNull()) {
|
||||
last_subnet->setDdnsOverrideNoUpdate(out_bindings[59]->getBool());
|
||||
}
|
||||
|
||||
// ddns_override_client_update at 60
|
||||
// ddns_override_client_update
|
||||
if (!out_bindings[60]->amNull()) {
|
||||
last_subnet->setDdnsOverrideClientUpdate(out_bindings[60]->getBool());
|
||||
}
|
||||
|
||||
// ddns_replace_client_name at 61
|
||||
// ddns_replace_client_name
|
||||
if (!out_bindings[61]->amNull()) {
|
||||
last_subnet->setDdnsReplaceClientNameMode(static_cast<D2ClientConfig::ReplaceClientNameMode>
|
||||
(out_bindings[61]->getInteger<uint8_t>()));
|
||||
}
|
||||
|
||||
// ddns_generated_prefix at 62
|
||||
// ddns_generated_prefix
|
||||
if (!out_bindings[62]->amNull()) {
|
||||
last_subnet->setDdnsGeneratedPrefix(out_bindings[62]->getString());
|
||||
}
|
||||
|
||||
// ddns_qualifying_suffix at 63
|
||||
// ddns_qualifying_suffix
|
||||
if (!out_bindings[63]->amNull()) {
|
||||
last_subnet->setDdnsQualifyingSuffix(out_bindings[63]->getString());
|
||||
}
|
||||
|
||||
// server_tag at 64
|
||||
// reservations_in_subnet
|
||||
if (!out_bindings[64]->amNull()) {
|
||||
last_subnet->setReservationsInSubnet(out_bindings[64]->getBool());
|
||||
}
|
||||
|
||||
// reservations_out_of_pool
|
||||
if (!out_bindings[65]->amNull()) {
|
||||
last_subnet->setReservationsOutOfPool(out_bindings[65]->getBool());
|
||||
}
|
||||
|
||||
// Subnet ready. Add it to the list.
|
||||
auto ret = subnets.insert(last_subnet);
|
||||
@ -541,14 +554,16 @@ public:
|
||||
}
|
||||
|
||||
// Check for new server tags.
|
||||
if (!out_bindings[64]->amNull() &&
|
||||
(last_tag != out_bindings[64]->getString())) {
|
||||
last_tag = out_bindings[64]->getString();
|
||||
if (!out_bindings[66]->amNull() &&
|
||||
(last_tag != out_bindings[66]->getString())) {
|
||||
last_tag = out_bindings[66]->getString();
|
||||
if (!last_tag.empty() && !last_subnet->hasServerTag(ServerTag(last_tag))) {
|
||||
last_subnet->setServerTag(last_tag);
|
||||
}
|
||||
}
|
||||
|
||||
// Pool is between 20 and 25 with extra between 55 and 57
|
||||
|
||||
// If the row contains information about the pool and it appears to be
|
||||
// new pool entry (checked by comparing pool id), let's create the new
|
||||
// pool and add it to the subnet.
|
||||
@ -591,7 +606,7 @@ public:
|
||||
last_subnet->addPool(last_pool);
|
||||
}
|
||||
|
||||
// Parse pool specific option.
|
||||
// Parse pool specific option between 25 and 36
|
||||
if (last_pool && !out_bindings[25]->amNull() &&
|
||||
(last_pool_option_id < out_bindings[25]->getInteger<uint64_t>())) {
|
||||
last_pool_option_id = out_bindings[25]->getInteger<uint64_t>();
|
||||
@ -602,7 +617,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Parse subnet specific option.
|
||||
// Parse subnet specific option between 37 and 48
|
||||
if (!out_bindings[37]->amNull() &&
|
||||
(last_option_id < out_bindings[37]->getInteger<uint64_t>())) {
|
||||
last_option_id = out_bindings[37]->getInteger<uint64_t>();
|
||||
@ -797,12 +812,12 @@ public:
|
||||
|
||||
last_pool = Pool4::create(IOAddress(out_bindings[1]->getInteger<uint32_t>()),
|
||||
IOAddress(out_bindings[2]->getInteger<uint32_t>()));
|
||||
// pool client_class (4)
|
||||
// pool client_class
|
||||
if (!out_bindings[4]->amNull()) {
|
||||
last_pool->allowClientClass(out_bindings[4]->getString());
|
||||
}
|
||||
|
||||
// pool require_client_classes (5)
|
||||
// pool require_client_classes
|
||||
ElementPtr require_element = out_bindings[5]->getJSON();
|
||||
if (require_element) {
|
||||
if (require_element->getType() != Element::list) {
|
||||
@ -819,19 +834,17 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// pool user_context (6)
|
||||
// pool user_context
|
||||
ElementPtr user_context = out_bindings[6]->getJSON();
|
||||
if (user_context) {
|
||||
last_pool->setContext(user_context);
|
||||
}
|
||||
|
||||
// pool: modification_ts (7)
|
||||
|
||||
pools.push_back(last_pool);
|
||||
pool_ids.push_back(last_pool_id);
|
||||
}
|
||||
|
||||
// Parse pool specific option (8).
|
||||
// Parse pool specific option between 8 and 19
|
||||
if (last_pool && !out_bindings[8]->amNull() &&
|
||||
(last_pool_option_id < out_bindings[8]->getInteger<uint64_t>())) {
|
||||
last_pool_option_id = out_bindings[8]->getInteger<uint64_t>();
|
||||
@ -937,16 +950,6 @@ public:
|
||||
required_classes_element->add(Element::create(*required_class));
|
||||
}
|
||||
|
||||
// Create binding for host reservation mode.
|
||||
MySqlBindingPtr hr_mode_binding;
|
||||
auto hr_mode = subnet->getHostReservationMode(Network::Inheritance::NONE);
|
||||
if (!hr_mode.unspecified()) {
|
||||
hr_mode_binding = MySqlBinding::createInteger<uint8_t>(static_cast<uint8_t>
|
||||
(hr_mode.get()));
|
||||
} else {
|
||||
hr_mode_binding = MySqlBinding::createNull();
|
||||
}
|
||||
|
||||
// Create binding for DDNS replace client name mode.
|
||||
MySqlBindingPtr ddns_rcn_mode_binding;
|
||||
auto ddns_rcn_mode = subnet->getDdnsReplaceClientNameMode(Network::Inheritance::NONE);
|
||||
@ -1001,7 +1004,7 @@ public:
|
||||
createInputRelayBinding(subnet),
|
||||
createBinding(subnet->getT1(Network::Inheritance::NONE)),
|
||||
createInputRequiredClassesBinding(subnet),
|
||||
hr_mode_binding,
|
||||
MySqlBinding::condCreateBool(subnet->getReservationsGlobal(Network::Inheritance::NONE)),
|
||||
MySqlBinding::condCreateString(subnet->getSname(Network::Inheritance::NONE)),
|
||||
shared_network_binding,
|
||||
createInputContextBinding(subnet),
|
||||
@ -1017,7 +1020,9 @@ public:
|
||||
MySqlBinding::condCreateBool(subnet->getDdnsOverrideClientUpdate(Network::Inheritance::NONE)),
|
||||
ddns_rcn_mode_binding,
|
||||
MySqlBinding::condCreateString(subnet->getDdnsGeneratedPrefix(Network::Inheritance::NONE)),
|
||||
MySqlBinding::condCreateString(subnet->getDdnsQualifyingSuffix(Network::Inheritance::NONE))
|
||||
MySqlBinding::condCreateString(subnet->getDdnsQualifyingSuffix(Network::Inheritance::NONE)),
|
||||
MySqlBinding::condCreateBool(subnet->getReservationsInSubnet(Network::Inheritance::NONE)),
|
||||
MySqlBinding::condCreateBool(subnet->getReservationsOutOfPool(Network::Inheritance::NONE))
|
||||
};
|
||||
|
||||
MySqlTransaction transaction(conn_);
|
||||
@ -1231,7 +1236,7 @@ public:
|
||||
MySqlBinding::createString(RELAY_BUF_LENGTH), // relay
|
||||
MySqlBinding::createInteger<uint32_t>(), // renew_timer
|
||||
MySqlBinding::createString(REQUIRE_CLIENT_CLASSES_BUF_LENGTH), // require_client_classes
|
||||
MySqlBinding::createInteger<uint8_t>(), // reservation_mode
|
||||
MySqlBinding::createInteger<uint8_t>(), // reservations_global
|
||||
MySqlBinding::createString(USER_CONTEXT_BUF_LENGTH), // user_context
|
||||
MySqlBinding::createInteger<uint32_t>(), // valid_lifetime
|
||||
MySqlBinding::createInteger<uint64_t>(), // option: option_id
|
||||
@ -1261,6 +1266,8 @@ public:
|
||||
MySqlBinding::createInteger<uint8_t>(), // ddns_replace_client_name
|
||||
MySqlBinding::createString(DNS_NAME_BUF_LENGTH), // ddns_generated_prefix
|
||||
MySqlBinding::createString(DNS_NAME_BUF_LENGTH), // ddns_qualifying_suffix
|
||||
MySqlBinding::createInteger<uint8_t>(), // reservations_in_subnet
|
||||
MySqlBinding::createInteger<uint8_t>(), // reservations_out_of_pool
|
||||
MySqlBinding::createString(SERVER_TAG_BUF_LENGTH) // server_tag
|
||||
};
|
||||
|
||||
@ -1352,10 +1359,9 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// reservation_mode
|
||||
// reservations_global
|
||||
if (!out_bindings[10]->amNull()) {
|
||||
last_network->setHostReservationMode(static_cast<Network::HRMode>
|
||||
(out_bindings[10]->getIntegerOrDefault<uint8_t>(Network::HR_ALL)));
|
||||
last_network->setReservationsGlobal(out_bindings[10]->getBool());
|
||||
}
|
||||
|
||||
// user_context
|
||||
@ -1408,37 +1414,47 @@ public:
|
||||
|
||||
// {min,max}_valid_lifetime
|
||||
|
||||
// ddns_send_updates at 34
|
||||
// ddns_send_updates
|
||||
if (!out_bindings[34]->amNull()) {
|
||||
last_network->setDdnsSendUpdates(out_bindings[34]->getBool());
|
||||
}
|
||||
|
||||
// ddns_override_no_update at 35
|
||||
// ddns_override_no_update
|
||||
if (!out_bindings[35]->amNull()) {
|
||||
last_network->setDdnsOverrideNoUpdate(out_bindings[35]->getBool());
|
||||
}
|
||||
|
||||
// ddns_override_client_update at 36
|
||||
// ddns_override_client_update
|
||||
if (!out_bindings[36]->amNull()) {
|
||||
last_network->setDdnsOverrideClientUpdate(out_bindings[36]->getBool());
|
||||
}
|
||||
|
||||
// ddns_replace_client_name at 37
|
||||
// ddns_replace_client_name
|
||||
if (!out_bindings[37]->amNull()) {
|
||||
last_network->setDdnsReplaceClientNameMode(static_cast<D2ClientConfig::ReplaceClientNameMode>
|
||||
(out_bindings[37]->getInteger<uint8_t>()));
|
||||
}
|
||||
|
||||
// ddns_generated_prefix at 38
|
||||
// ddns_generated_prefix
|
||||
if (!out_bindings[38]->amNull()) {
|
||||
last_network->setDdnsGeneratedPrefix(out_bindings[38]->getString());
|
||||
}
|
||||
|
||||
// ddns_qualifying_suffix at 39
|
||||
// ddns_qualifying_suffix
|
||||
if (!out_bindings[39]->amNull()) {
|
||||
last_network->setDdnsQualifyingSuffix(out_bindings[39]->getString());
|
||||
}
|
||||
|
||||
// reservations_in_subnet
|
||||
if (!out_bindings[40]->amNull()) {
|
||||
last_network->setReservationsInSubnet(out_bindings[40]->getBool());
|
||||
}
|
||||
|
||||
// reservations_out_of_pool
|
||||
if (!out_bindings[41]->amNull()) {
|
||||
last_network->setReservationsOutOfPool(out_bindings[41]->getBool());
|
||||
}
|
||||
|
||||
// Add the shared network.
|
||||
auto ret = shared_networks.push_back(last_network);
|
||||
|
||||
@ -1451,15 +1467,15 @@ public:
|
||||
}
|
||||
|
||||
// Check for new server tags.
|
||||
if (!out_bindings[40]->amNull() &&
|
||||
(last_tag != out_bindings[40]->getString())) {
|
||||
last_tag = out_bindings[40]->getString();
|
||||
if (!out_bindings[42]->amNull() &&
|
||||
(last_tag != out_bindings[42]->getString())) {
|
||||
last_tag = out_bindings[42]->getString();
|
||||
if (!last_tag.empty() && !last_network->hasServerTag(ServerTag(last_tag))) {
|
||||
last_network->setServerTag(last_tag);
|
||||
}
|
||||
}
|
||||
|
||||
// Parse option.
|
||||
// Parse option from 13 to 24
|
||||
if (!out_bindings[13]->amNull() &&
|
||||
(last_option_id < out_bindings[13]->getInteger<uint64_t>())) {
|
||||
last_option_id = out_bindings[13]->getInteger<uint64_t>();
|
||||
@ -1569,16 +1585,6 @@ public:
|
||||
" assigning it to a server or all servers is not supported");
|
||||
}
|
||||
|
||||
// Create binding for host reservation mode.
|
||||
MySqlBindingPtr hr_mode_binding;
|
||||
auto hr_mode = shared_network->getHostReservationMode(Network::Inheritance::NONE);
|
||||
if (!hr_mode.unspecified()) {
|
||||
hr_mode_binding = MySqlBinding::createInteger<uint8_t>(static_cast<uint8_t>
|
||||
(hr_mode.get()));
|
||||
} else {
|
||||
hr_mode_binding = MySqlBinding::createNull();
|
||||
}
|
||||
|
||||
// Create binding for DDNS replace client name mode.
|
||||
MySqlBindingPtr ddns_rcn_mode_binding;
|
||||
auto ddns_rcn_mode = shared_network->getDdnsReplaceClientNameMode(Network::Inheritance::NONE);
|
||||
@ -1599,7 +1605,7 @@ public:
|
||||
createInputRelayBinding(shared_network),
|
||||
createBinding(shared_network->getT1(Network::Inheritance::NONE)),
|
||||
createInputRequiredClassesBinding(shared_network),
|
||||
hr_mode_binding,
|
||||
MySqlBinding::condCreateBool(shared_network->getReservationsGlobal(Network::Inheritance::NONE)),
|
||||
createInputContextBinding(shared_network),
|
||||
createBinding(shared_network->getValid(Network::Inheritance::NONE)),
|
||||
createMinBinding(shared_network->getValid(Network::Inheritance::NONE)),
|
||||
@ -1616,7 +1622,9 @@ public:
|
||||
MySqlBinding::condCreateBool(shared_network->getDdnsOverrideClientUpdate(Network::Inheritance::NONE)),
|
||||
ddns_rcn_mode_binding,
|
||||
MySqlBinding::condCreateString(shared_network->getDdnsGeneratedPrefix(Network::Inheritance::NONE)),
|
||||
MySqlBinding::condCreateString(shared_network->getDdnsQualifyingSuffix(Network::Inheritance::NONE))
|
||||
MySqlBinding::condCreateString(shared_network->getDdnsQualifyingSuffix(Network::Inheritance::NONE)),
|
||||
MySqlBinding::condCreateBool(shared_network->getReservationsInSubnet(Network::Inheritance::NONE)),
|
||||
MySqlBinding::condCreateBool(shared_network->getReservationsOutOfPool(Network::Inheritance::NONE))
|
||||
};
|
||||
|
||||
MySqlTransaction transaction(conn_);
|
||||
@ -2448,7 +2456,7 @@ TaggedStatementArray tagged_statements = { {
|
||||
" relay,"
|
||||
" renew_timer,"
|
||||
" require_client_classes,"
|
||||
" reservation_mode,"
|
||||
" reservations_global,"
|
||||
" server_hostname,"
|
||||
" shared_network_name,"
|
||||
" user_context,"
|
||||
@ -2464,9 +2472,11 @@ TaggedStatementArray tagged_statements = { {
|
||||
" ddns_override_client_update,"
|
||||
" ddns_replace_client_name,"
|
||||
" ddns_generated_prefix,"
|
||||
" ddns_qualifying_suffix"
|
||||
" ddns_qualifying_suffix,"
|
||||
" reservations_in_subnet,"
|
||||
" reservations_out_of_pool"
|
||||
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,"
|
||||
"?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" },
|
||||
"?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" },
|
||||
|
||||
// Insert association of the subnet with a server.
|
||||
{ MySqlConfigBackendDHCPv4Impl::INSERT_SUBNET4_SERVER,
|
||||
@ -2490,7 +2500,7 @@ TaggedStatementArray tagged_statements = { {
|
||||
" relay,"
|
||||
" renew_timer,"
|
||||
" require_client_classes,"
|
||||
" reservation_mode,"
|
||||
" reservations_global,"
|
||||
" user_context,"
|
||||
" valid_lifetime,"
|
||||
" min_valid_lifetime,"
|
||||
@ -2507,9 +2517,11 @@ TaggedStatementArray tagged_statements = { {
|
||||
" ddns_override_client_update,"
|
||||
" ddns_replace_client_name,"
|
||||
" ddns_generated_prefix,"
|
||||
" ddns_qualifying_suffix"
|
||||
" ddns_qualifying_suffix,"
|
||||
" reservations_in_subnet,"
|
||||
" reservations_out_of_pool"
|
||||
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,"
|
||||
" ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" },
|
||||
" ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" },
|
||||
|
||||
// Insert association of the shared network with a server.
|
||||
{ MySqlConfigBackendDHCPv4Impl::INSERT_SHARED_NETWORK4_SERVER,
|
||||
@ -2564,7 +2576,7 @@ TaggedStatementArray tagged_statements = { {
|
||||
" relay = ?,"
|
||||
" renew_timer = ?,"
|
||||
" require_client_classes = ?,"
|
||||
" reservation_mode = ?,"
|
||||
" reservations_global = ?,"
|
||||
" server_hostname = ?,"
|
||||
" shared_network_name = ?,"
|
||||
" user_context = ?,"
|
||||
@ -2580,7 +2592,9 @@ TaggedStatementArray tagged_statements = { {
|
||||
" ddns_override_client_update = ?,"
|
||||
" ddns_replace_client_name = ?,"
|
||||
" ddns_generated_prefix = ?,"
|
||||
" ddns_qualifying_suffix = ? "
|
||||
" ddns_qualifying_suffix = ?,"
|
||||
" reservations_in_subnet = ?,"
|
||||
" reservations_out_of_pool = ? "
|
||||
"WHERE subnet_id = ? OR subnet_prefix = ?" },
|
||||
|
||||
// Update existing shared network.
|
||||
@ -2595,7 +2609,7 @@ TaggedStatementArray tagged_statements = { {
|
||||
" relay = ?,"
|
||||
" renew_timer = ?,"
|
||||
" require_client_classes = ?,"
|
||||
" reservation_mode = ?,"
|
||||
" reservations_global = ?,"
|
||||
" user_context = ?,"
|
||||
" valid_lifetime = ?,"
|
||||
" min_valid_lifetime = ?,"
|
||||
@ -2612,7 +2626,9 @@ TaggedStatementArray tagged_statements = { {
|
||||
" ddns_override_client_update = ?,"
|
||||
" ddns_replace_client_name = ?,"
|
||||
" ddns_generated_prefix = ?,"
|
||||
" ddns_qualifying_suffix = ? "
|
||||
" ddns_qualifying_suffix = ?,"
|
||||
" reservations_in_subnet = ?,"
|
||||
" reservations_out_of_pool = ? "
|
||||
"WHERE name = ?" },
|
||||
|
||||
// Update existing option definition.
|
||||
|
@ -274,7 +274,7 @@ public:
|
||||
MySqlBinding::createString(RELAY_BUF_LENGTH), // relay
|
||||
MySqlBinding::createInteger<uint32_t>(), // renew_timer
|
||||
MySqlBinding::createString(REQUIRE_CLIENT_CLASSES_BUF_LENGTH), // require_client_classes
|
||||
MySqlBinding::createInteger<uint8_t>(), // reservation_mode
|
||||
MySqlBinding::createInteger<uint8_t>(), // reservations_global
|
||||
MySqlBinding::createString(SHARED_NETWORK_NAME_BUF_LENGTH), // shared_network_name
|
||||
MySqlBinding::createString(USER_CONTEXT_BUF_LENGTH), // user_context
|
||||
MySqlBinding::createInteger<uint32_t>(), // valid_lifetime
|
||||
@ -350,6 +350,8 @@ public:
|
||||
MySqlBinding::createInteger<uint8_t>(), // ddns_replace_client_name
|
||||
MySqlBinding::createString(DNS_NAME_BUF_LENGTH), // ddns_generated_prefix
|
||||
MySqlBinding::createString(DNS_NAME_BUF_LENGTH), // ddns_qualifying_suffix
|
||||
MySqlBinding::createInteger<uint8_t>(), // reservations_in_subnet
|
||||
MySqlBinding::createInteger<uint8_t>(), // reservations_out_of_pool
|
||||
MySqlBinding::createString(SERVER_TAG_BUF_LENGTH) // server_tag
|
||||
};
|
||||
|
||||
@ -392,10 +394,10 @@ public:
|
||||
last_pd_pool.reset();
|
||||
last_tag.clear();
|
||||
|
||||
// subnet_id (0)
|
||||
// subnet_id
|
||||
SubnetID subnet_id(out_bindings[0]->getInteger<uint32_t>());
|
||||
|
||||
// subnet_prefix (1)
|
||||
// subnet_prefix
|
||||
std::string subnet_prefix = out_bindings[1]->getString();
|
||||
auto prefix_pair = Subnet6::parsePrefix(subnet_prefix);
|
||||
|
||||
@ -404,10 +406,10 @@ public:
|
||||
out_bindings[69],
|
||||
out_bindings[70]);
|
||||
|
||||
// renew_timer (9)
|
||||
// renew_timer
|
||||
auto renew_timer = createTriplet(out_bindings[9]);
|
||||
|
||||
// rebind_timer (7)
|
||||
// rebind_timer
|
||||
auto rebind_timer = createTriplet(out_bindings[7]);
|
||||
|
||||
// valid_lifetime (and {min,max)_valid_lifetime)
|
||||
@ -421,28 +423,25 @@ public:
|
||||
preferred_lifetime,
|
||||
valid_lifetime, subnet_id);
|
||||
|
||||
// client_class (2)
|
||||
// client_class
|
||||
if (!out_bindings[2]->amNull()) {
|
||||
last_subnet->allowClientClass(out_bindings[2]->getString());
|
||||
}
|
||||
|
||||
// interface (3)
|
||||
// interface
|
||||
if (!out_bindings[3]->amNull()) {
|
||||
last_subnet->setIface(out_bindings[3]->getString());
|
||||
}
|
||||
|
||||
// modification_ts (4)
|
||||
// modification_ts
|
||||
last_subnet->setModificationTime(out_bindings[4]->getTimestamp());
|
||||
// 5 is preferred_lifetime
|
||||
|
||||
// rapid_commit (6)
|
||||
// rapid_commit
|
||||
if (!out_bindings[6]->amNull()) {
|
||||
last_subnet->setRapidCommit(out_bindings[6]->getBool());
|
||||
}
|
||||
|
||||
// 7 is rebind_timer
|
||||
|
||||
// relay (8)
|
||||
// relay
|
||||
ElementPtr relay_element = out_bindings[8]->getJSON();
|
||||
if (relay_element) {
|
||||
if (relay_element->getType() != Element::list) {
|
||||
@ -458,9 +457,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// 9 is renew_timer
|
||||
|
||||
// require_client_classes (10)
|
||||
// require_client_classes
|
||||
ElementPtr require_element = out_bindings[10]->getJSON();
|
||||
if (require_element) {
|
||||
if (require_element->getType() != Element::list) {
|
||||
@ -477,41 +474,38 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// reservation_mode (11)
|
||||
// reservations_global
|
||||
if (!out_bindings[11]->amNull()) {
|
||||
last_subnet->setHostReservationMode(static_cast<Network::HRMode>
|
||||
(out_bindings[11]->getInteger<uint8_t>()));
|
||||
last_subnet->setReservationsGlobal(out_bindings[11]->getBool());
|
||||
}
|
||||
|
||||
// shared_network_name (12)
|
||||
// shared_network_name
|
||||
if (!out_bindings[12]->amNull()) {
|
||||
last_subnet->setSharedNetworkName(out_bindings[12]->getString());
|
||||
}
|
||||
|
||||
// user_context (13)
|
||||
// user_context
|
||||
ElementPtr user_context = out_bindings[13]->getJSON();
|
||||
if (user_context) {
|
||||
last_subnet->setContext(user_context);
|
||||
}
|
||||
|
||||
// 14 is valid_lifetime
|
||||
|
||||
// calculate_tee_times (65)
|
||||
// calculate_tee_times
|
||||
if (!out_bindings[65]->amNull()) {
|
||||
last_subnet->setCalculateTeeTimes(out_bindings[65]->getBool());
|
||||
}
|
||||
|
||||
// t1_percent (66)
|
||||
// t1_percent
|
||||
if (!out_bindings[66]->amNull()) {
|
||||
last_subnet->setT1Percent(out_bindings[66]->getFloat());
|
||||
}
|
||||
|
||||
// t2_percent (67)
|
||||
// t2_percent
|
||||
if (!out_bindings[67]->amNull()) {
|
||||
last_subnet->setT2Percent(out_bindings[67]->getFloat());
|
||||
}
|
||||
|
||||
// interface_id (68)
|
||||
// interface_id
|
||||
if (!out_bindings[68]->amNull()) {
|
||||
auto iface_id_data = out_bindings[68]->getBlob();
|
||||
if (!iface_id_data.empty()) {
|
||||
@ -521,51 +515,46 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// 69 and 70 are {min,max}_preferred_lifetime
|
||||
|
||||
// 71 and 72 are {min,max}_valid_lifetime
|
||||
|
||||
// 73 is pool client_class
|
||||
// 74 is pool require_client_classes
|
||||
// 75 is pool user_context
|
||||
// 76 is pd pool excluded_prefix
|
||||
// 77 is pd pool excluded_prefix_length
|
||||
// 78 is pd pool client_class
|
||||
// 79 is pd pool require_client_classes
|
||||
// 80 is pd pool user_context
|
||||
|
||||
// ddns_send_updates (81)
|
||||
// ddns_send_updates
|
||||
if (!out_bindings[81]->amNull()) {
|
||||
last_subnet->setDdnsSendUpdates(out_bindings[81]->getBool());
|
||||
}
|
||||
|
||||
// ddns_override_no_update (82)
|
||||
// ddns_override_no_update
|
||||
if (!out_bindings[82]->amNull()) {
|
||||
last_subnet->setDdnsOverrideNoUpdate(out_bindings[82]->getBool());
|
||||
}
|
||||
|
||||
// ddns_override_client_update (83)
|
||||
// ddns_override_client_update
|
||||
if (!out_bindings[83]->amNull()) {
|
||||
last_subnet->setDdnsOverrideClientUpdate(out_bindings[83]->getBool());
|
||||
}
|
||||
|
||||
// ddns_replace_client_name (84)
|
||||
// ddns_replace_client_name
|
||||
if (!out_bindings[84]->amNull()) {
|
||||
last_subnet->setDdnsReplaceClientNameMode(static_cast<D2ClientConfig::ReplaceClientNameMode>
|
||||
(out_bindings[84]->getInteger<uint8_t>()));
|
||||
}
|
||||
|
||||
// ddns_generated_prefix (85)
|
||||
// ddns_generated_prefix
|
||||
if (!out_bindings[85]->amNull()) {
|
||||
last_subnet->setDdnsGeneratedPrefix(out_bindings[85]->getString());
|
||||
}
|
||||
|
||||
// ddns_qualifying_suffix (86)
|
||||
// ddns_qualifying_suffix
|
||||
if (!out_bindings[86]->amNull()) {
|
||||
last_subnet->setDdnsQualifyingSuffix(out_bindings[86]->getString());
|
||||
}
|
||||
|
||||
// server_tag (87 / last)
|
||||
// reservations_in_subnet
|
||||
if (!out_bindings[87]->amNull()) {
|
||||
last_subnet->setReservationsInSubnet(out_bindings[87]->getBool());
|
||||
}
|
||||
|
||||
// reservations_out_of_pool
|
||||
if (!out_bindings[88]->amNull()) {
|
||||
last_subnet->setReservationsOutOfPool(out_bindings[88]->getBool());
|
||||
}
|
||||
|
||||
// Subnet ready. Add it to the list.
|
||||
auto ret = subnets.insert(last_subnet);
|
||||
@ -579,9 +568,9 @@ public:
|
||||
}
|
||||
|
||||
// Check for new server tags.
|
||||
if (!out_bindings[87]->amNull() &&
|
||||
(last_tag != out_bindings[87]->getString())) {
|
||||
last_tag = out_bindings[87]->getString();
|
||||
if (!out_bindings[89]->amNull() &&
|
||||
(last_tag != out_bindings[89]->getString())) {
|
||||
last_tag = out_bindings[89]->getString();
|
||||
if (!last_tag.empty() && !last_subnet->hasServerTag(ServerTag(last_tag))) {
|
||||
last_subnet->setServerTag(last_tag);
|
||||
}
|
||||
@ -601,12 +590,12 @@ public:
|
||||
last_pool = Pool6::create(Lease::TYPE_NA,
|
||||
IOAddress(out_bindings[16]->getString()),
|
||||
IOAddress(out_bindings[17]->getString()));
|
||||
// pool client_class (73)
|
||||
// pool client_class
|
||||
if (!out_bindings[73]->amNull()) {
|
||||
last_pool->allowClientClass(out_bindings[73]->getString());
|
||||
}
|
||||
|
||||
// pool require_client_classes (74)
|
||||
// pool require_client_classes
|
||||
ElementPtr require_element = out_bindings[74]->getJSON();
|
||||
if (require_element) {
|
||||
if (require_element->getType() != Element::list) {
|
||||
@ -623,7 +612,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// pool user_context (75)
|
||||
// pool user_context
|
||||
ElementPtr user_context = out_bindings[75]->getJSON();
|
||||
if (user_context) {
|
||||
last_pool->setContext(user_context);
|
||||
@ -645,7 +634,7 @@ public:
|
||||
(out_bindings[20]->getInteger<uint64_t>() > last_pd_pool_id)) {
|
||||
last_pd_pool_id = out_bindings[20]->getInteger<uint64_t>();
|
||||
|
||||
// excluded_prefix (76) and excluded_prefix_length (77)
|
||||
// excluded_prefix and excluded_prefix_length
|
||||
IOAddress excluded_prefix = IOAddress::IPV6_ZERO_ADDRESS();
|
||||
if (!out_bindings[76]->amNull()) {
|
||||
excluded_prefix = IOAddress(out_bindings[76]->getString());
|
||||
@ -655,12 +644,12 @@ public:
|
||||
out_bindings[23]->getInteger<uint8_t>(),
|
||||
excluded_prefix,
|
||||
out_bindings[77]->getInteger<uint8_t>());
|
||||
// pd pool client_class (78)
|
||||
// pd pool client_class
|
||||
if (!out_bindings[78]->amNull()) {
|
||||
last_pd_pool->allowClientClass(out_bindings[78]->getString());
|
||||
}
|
||||
|
||||
// pd pool require_client_classes (79)
|
||||
// pd pool require_client_classes
|
||||
ElementPtr require_element = out_bindings[79]->getJSON();
|
||||
if (require_element) {
|
||||
if (require_element->getType() != Element::list) {
|
||||
@ -677,7 +666,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// pd pool user_context (80)
|
||||
// pd pool user_context
|
||||
ElementPtr user_context = out_bindings[80]->getJSON();
|
||||
if (user_context) {
|
||||
last_pd_pool->setContext(user_context);
|
||||
@ -904,12 +893,12 @@ public:
|
||||
last_pool = Pool6::create(Lease::TYPE_NA,
|
||||
IOAddress(out_bindings[1]->getString()),
|
||||
IOAddress(out_bindings[2]->getString()));
|
||||
// pool client_class (4)
|
||||
// pool client_class
|
||||
if (!out_bindings[4]->amNull()) {
|
||||
last_pool->allowClientClass(out_bindings[4]->getString());
|
||||
}
|
||||
|
||||
// pool require_client_classes (5)
|
||||
// pool require_client_classes
|
||||
ElementPtr require_element = out_bindings[5]->getJSON();
|
||||
if (require_element) {
|
||||
if (require_element->getType() != Element::list) {
|
||||
@ -926,19 +915,17 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// pool user_context (6)
|
||||
// pool user_context
|
||||
ElementPtr user_context = out_bindings[6]->getJSON();
|
||||
if (user_context) {
|
||||
last_pool->setContext(user_context);
|
||||
}
|
||||
|
||||
// pool: modification_ts (7)
|
||||
|
||||
pools.push_back(last_pool);
|
||||
pool_ids.push_back(last_pool_id);
|
||||
}
|
||||
|
||||
// Parse pool specific option (8).
|
||||
// Parse pool specific option between 8 and 20
|
||||
if (last_pool && !out_bindings[8]->amNull() &&
|
||||
(last_pool_option_id < out_bindings[8]->getInteger<uint64_t>())) {
|
||||
last_pool_option_id = out_bindings[8]->getInteger<uint64_t>();
|
||||
@ -1007,7 +994,7 @@ public:
|
||||
|
||||
last_pd_pool_id = out_bindings[0]->getInteger<uint64_t>();
|
||||
|
||||
// excluded_prefix (5) and excluded_prefix_length (6)
|
||||
// excluded_prefix and excluded_prefix_length
|
||||
IOAddress excluded_prefix = IOAddress::IPV6_ZERO_ADDRESS();
|
||||
if (!out_bindings[5]->amNull()) {
|
||||
excluded_prefix = IOAddress(out_bindings[5]->getString());
|
||||
@ -1019,12 +1006,12 @@ public:
|
||||
excluded_prefix,
|
||||
out_bindings[6]->getInteger<uint8_t>());
|
||||
|
||||
// pd pool client_class (7)
|
||||
// pd pool client_class
|
||||
if (!out_bindings[7]->amNull()) {
|
||||
last_pd_pool->allowClientClass(out_bindings[7]->getString());
|
||||
}
|
||||
|
||||
// pd pool require_client_classes (8)
|
||||
// pd pool require_client_classes
|
||||
ElementPtr require_element = out_bindings[8]->getJSON();
|
||||
if (require_element) {
|
||||
if (require_element->getType() != Element::list) {
|
||||
@ -1041,19 +1028,17 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// pd pool user_context (9)
|
||||
// pd pool user_context
|
||||
ElementPtr user_context = out_bindings[9]->getJSON();
|
||||
if (user_context) {
|
||||
last_pd_pool->setContext(user_context);
|
||||
}
|
||||
|
||||
// pd pool modification_ts (10)
|
||||
|
||||
pd_pools.push_back(last_pd_pool);
|
||||
pd_pool_ids.push_back(last_pd_pool_id);
|
||||
}
|
||||
|
||||
// Parse pd pool specific option between 11 and 24
|
||||
// Parse pd pool specific option between 11 and 23
|
||||
if (last_pd_pool && !out_bindings[11]->amNull() &&
|
||||
(last_pd_pool_option_id < out_bindings[11]->getInteger<uint64_t>())) {
|
||||
last_pd_pool_option_id = out_bindings[11]->getInteger<uint64_t>();
|
||||
@ -1178,16 +1163,6 @@ public:
|
||||
required_classes_element->add(Element::create(*required_class));
|
||||
}
|
||||
|
||||
// Create binding for host reservation mode.
|
||||
MySqlBindingPtr hr_mode_binding;
|
||||
auto hr_mode = subnet->getHostReservationMode(Network::Inheritance::NONE);
|
||||
if (!hr_mode.unspecified()) {
|
||||
hr_mode_binding = MySqlBinding::createInteger<uint8_t>(static_cast<uint8_t>
|
||||
(hr_mode.get()));
|
||||
} else {
|
||||
hr_mode_binding = MySqlBinding::createNull();
|
||||
}
|
||||
|
||||
// Create binding for DDNS replace client name mode.
|
||||
MySqlBindingPtr ddns_rcn_mode_binding;
|
||||
auto ddns_rcn_mode = subnet->getDdnsReplaceClientNameMode(Network::Inheritance::NONE);
|
||||
@ -1251,7 +1226,7 @@ public:
|
||||
createInputRelayBinding(subnet),
|
||||
createBinding(subnet->getT1(Network::Inheritance::NONE)),
|
||||
createInputRequiredClassesBinding(subnet),
|
||||
hr_mode_binding,
|
||||
MySqlBinding::condCreateBool(subnet->getReservationsGlobal(Network::Inheritance::NONE)),
|
||||
shared_network_binding,
|
||||
createInputContextBinding(subnet),
|
||||
createBinding(subnet->getValid(Network::Inheritance::NONE)),
|
||||
@ -1266,7 +1241,9 @@ public:
|
||||
MySqlBinding::condCreateBool(subnet->getDdnsOverrideClientUpdate(Network::Inheritance::NONE)),
|
||||
ddns_rcn_mode_binding,
|
||||
MySqlBinding::condCreateString(subnet->getDdnsGeneratedPrefix(Network::Inheritance::NONE)),
|
||||
MySqlBinding::condCreateString(subnet->getDdnsQualifyingSuffix(Network::Inheritance::NONE))
|
||||
MySqlBinding::condCreateString(subnet->getDdnsQualifyingSuffix(Network::Inheritance::NONE)),
|
||||
MySqlBinding::condCreateBool(subnet->getReservationsInSubnet(Network::Inheritance::NONE)),
|
||||
MySqlBinding::condCreateBool(subnet->getReservationsOutOfPool(Network::Inheritance::NONE))
|
||||
};
|
||||
|
||||
MySqlTransaction transaction(conn_);
|
||||
@ -1556,7 +1533,7 @@ public:
|
||||
MySqlBinding::createString(RELAY_BUF_LENGTH), // relay
|
||||
MySqlBinding::createInteger<uint32_t>(), // renew_timer
|
||||
MySqlBinding::createString(REQUIRE_CLIENT_CLASSES_BUF_LENGTH), // require_client_classes
|
||||
MySqlBinding::createInteger<uint8_t>(), // reservation_mode
|
||||
MySqlBinding::createInteger<uint8_t>(), // reservations_global
|
||||
MySqlBinding::createString(USER_CONTEXT_BUF_LENGTH), // user_context
|
||||
MySqlBinding::createInteger<uint32_t>(), // valid_lifetime
|
||||
MySqlBinding::createInteger<uint64_t>(), // option: option_id
|
||||
@ -1586,6 +1563,8 @@ public:
|
||||
MySqlBinding::createInteger<uint8_t>(), // ddns_replace_client_name
|
||||
MySqlBinding::createString(DNS_NAME_BUF_LENGTH), // ddns_generated_prefix
|
||||
MySqlBinding::createString(DNS_NAME_BUF_LENGTH), // ddns_qualifying_suffix
|
||||
MySqlBinding::createInteger<uint8_t>(), // reservations_in_subnet
|
||||
MySqlBinding::createInteger<uint8_t>(), // reservations_out_of_pool
|
||||
MySqlBinding::createString(SERVER_TAG_BUF_LENGTH) // server_tag
|
||||
};
|
||||
|
||||
@ -1684,10 +1663,9 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// reservation_mode
|
||||
// reservations_global
|
||||
if (!out_bindings[11]->amNull()) {
|
||||
last_network->setHostReservationMode(static_cast<Network::HRMode>
|
||||
(out_bindings[11]->getIntegerOrDefault<uint8_t>(Network::HR_ALL)));
|
||||
last_network->setReservationsGlobal(out_bindings[11]->getBool());
|
||||
}
|
||||
|
||||
// user_context
|
||||
@ -1732,38 +1710,46 @@ public:
|
||||
|
||||
// {min,max)_valid_lifetime
|
||||
|
||||
// ddns_send_updates at 35
|
||||
// ddns_send_updates
|
||||
if (!out_bindings[35]->amNull()) {
|
||||
last_network->setDdnsSendUpdates(out_bindings[35]->getBool());
|
||||
}
|
||||
|
||||
// ddns_override_no_update at 36
|
||||
// ddns_override_no_update
|
||||
if (!out_bindings[36]->amNull()) {
|
||||
last_network->setDdnsOverrideNoUpdate(out_bindings[36]->getBool());
|
||||
}
|
||||
|
||||
// ddns_override_client_update at 37
|
||||
// ddns_override_client_update
|
||||
if (!out_bindings[37]->amNull()) {
|
||||
last_network->setDdnsOverrideClientUpdate(out_bindings[37]->getBool());
|
||||
}
|
||||
|
||||
// ddns_replace_client_name at 38
|
||||
// ddns_replace_client_name
|
||||
if (!out_bindings[38]->amNull()) {
|
||||
last_network->setDdnsReplaceClientNameMode(static_cast<D2ClientConfig::ReplaceClientNameMode>
|
||||
(out_bindings[38]->getInteger<uint8_t>()));
|
||||
}
|
||||
|
||||
// ddns_generated_prefix at 39
|
||||
// ddns_generated_prefix
|
||||
if (!out_bindings[39]->amNull()) {
|
||||
last_network->setDdnsGeneratedPrefix(out_bindings[39]->getString());
|
||||
}
|
||||
|
||||
// ddns_qualifying_suffix at 40
|
||||
// ddns_qualifying_suffix
|
||||
if (!out_bindings[40]->amNull()) {
|
||||
last_network->setDdnsQualifyingSuffix(out_bindings[40]->getString());
|
||||
}
|
||||
|
||||
// server_tag at 41
|
||||
// reservations_in_subnet
|
||||
if (!out_bindings[41]->amNull()) {
|
||||
last_network->setReservationsInSubnet(out_bindings[41]->getBool());
|
||||
}
|
||||
|
||||
// reservations_out_of_pool
|
||||
if (!out_bindings[42]->amNull()) {
|
||||
last_network->setReservationsOutOfPool(out_bindings[42]->getBool());
|
||||
}
|
||||
|
||||
// Add the shared network.
|
||||
auto ret = shared_networks.push_back(last_network);
|
||||
@ -1788,9 +1774,9 @@ public:
|
||||
}
|
||||
|
||||
// Check for new server tags.
|
||||
if (!out_bindings[41]->amNull() &&
|
||||
(last_tag != out_bindings[41]->getString())) {
|
||||
last_tag = out_bindings[41]->getString();
|
||||
if (!out_bindings[43]->amNull() &&
|
||||
(last_tag != out_bindings[43]->getString())) {
|
||||
last_tag = out_bindings[43]->getString();
|
||||
if (!last_tag.empty() && !last_network->hasServerTag(ServerTag(last_tag))) {
|
||||
last_network->setServerTag(last_tag);
|
||||
}
|
||||
@ -1895,16 +1881,6 @@ public:
|
||||
" (unassigned) is unsupported at the moment");
|
||||
}
|
||||
|
||||
// Create binding for host reservation mode.
|
||||
MySqlBindingPtr hr_mode_binding;
|
||||
auto hr_mode = shared_network->getHostReservationMode(Network::Inheritance::NONE);
|
||||
if (!hr_mode.unspecified()) {
|
||||
hr_mode_binding = MySqlBinding::createInteger<uint8_t>(static_cast<uint8_t>
|
||||
(hr_mode.get()));
|
||||
} else {
|
||||
hr_mode_binding = MySqlBinding::createNull();
|
||||
}
|
||||
|
||||
// Create the binding holding interface_id.
|
||||
MySqlBindingPtr interface_id_binding = MySqlBinding::createNull();
|
||||
auto opt_iface_id = shared_network->getInterfaceId();
|
||||
@ -1939,7 +1915,7 @@ public:
|
||||
createInputRelayBinding(shared_network),
|
||||
createBinding(shared_network->getT1(Network::Inheritance::NONE)),
|
||||
createInputRequiredClassesBinding(shared_network),
|
||||
hr_mode_binding,
|
||||
MySqlBinding::condCreateBool(shared_network->getReservationsGlobal(Network::Inheritance::NONE)),
|
||||
createInputContextBinding(shared_network),
|
||||
createBinding(shared_network->getValid(Network::Inheritance::NONE)),
|
||||
createMinBinding(shared_network->getValid(Network::Inheritance::NONE)),
|
||||
@ -1953,7 +1929,9 @@ public:
|
||||
MySqlBinding::condCreateBool(shared_network->getDdnsOverrideClientUpdate(Network::Inheritance::NONE)),
|
||||
ddns_rcn_mode_binding,
|
||||
MySqlBinding::condCreateString(shared_network->getDdnsGeneratedPrefix(Network::Inheritance::NONE)),
|
||||
MySqlBinding::condCreateString(shared_network->getDdnsQualifyingSuffix(Network::Inheritance::NONE))
|
||||
MySqlBinding::condCreateString(shared_network->getDdnsQualifyingSuffix(Network::Inheritance::NONE)),
|
||||
MySqlBinding::condCreateBool(shared_network->getReservationsInSubnet(Network::Inheritance::NONE)),
|
||||
MySqlBinding::condCreateBool(shared_network->getReservationsOutOfPool(Network::Inheritance::NONE))
|
||||
};
|
||||
|
||||
MySqlTransaction transaction(conn_);
|
||||
@ -2911,7 +2889,7 @@ TaggedStatementArray tagged_statements = { {
|
||||
" relay,"
|
||||
" renew_timer,"
|
||||
" require_client_classes,"
|
||||
" reservation_mode,"
|
||||
" reservations_global,"
|
||||
" shared_network_name,"
|
||||
" user_context,"
|
||||
" valid_lifetime,"
|
||||
@ -2926,9 +2904,11 @@ TaggedStatementArray tagged_statements = { {
|
||||
" ddns_override_client_update,"
|
||||
" ddns_replace_client_name,"
|
||||
" ddns_generated_prefix,"
|
||||
" ddns_qualifying_suffix"
|
||||
" ddns_qualifying_suffix,"
|
||||
" reservations_in_subnet,"
|
||||
" reservations_out_of_pool"
|
||||
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,"
|
||||
" ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" },
|
||||
" ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" },
|
||||
|
||||
// Insert association of the subnet with a server.
|
||||
{ MySqlConfigBackendDHCPv6Impl::INSERT_SUBNET6_SERVER,
|
||||
@ -2960,7 +2940,7 @@ TaggedStatementArray tagged_statements = { {
|
||||
" relay,"
|
||||
" renew_timer,"
|
||||
" require_client_classes,"
|
||||
" reservation_mode,"
|
||||
" reservations_global,"
|
||||
" user_context,"
|
||||
" valid_lifetime,"
|
||||
" min_valid_lifetime,"
|
||||
@ -2974,9 +2954,11 @@ TaggedStatementArray tagged_statements = { {
|
||||
" ddns_override_client_update,"
|
||||
" ddns_replace_client_name,"
|
||||
" ddns_generated_prefix,"
|
||||
" ddns_qualifying_suffix"
|
||||
" ddns_qualifying_suffix,"
|
||||
" reservations_in_subnet,"
|
||||
" reservations_out_of_pool"
|
||||
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,"
|
||||
" ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" },
|
||||
" ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" },
|
||||
|
||||
// Insert association of the shared network with a server.
|
||||
{ MySqlConfigBackendDHCPv6Impl::INSERT_SHARED_NETWORK6_SERVER,
|
||||
@ -3029,7 +3011,7 @@ TaggedStatementArray tagged_statements = { {
|
||||
" relay = ?,"
|
||||
" renew_timer = ?,"
|
||||
" require_client_classes = ?,"
|
||||
" reservation_mode = ?,"
|
||||
" reservations_global = ?,"
|
||||
" shared_network_name = ?,"
|
||||
" user_context = ?,"
|
||||
" valid_lifetime = ?,"
|
||||
@ -3044,7 +3026,9 @@ TaggedStatementArray tagged_statements = { {
|
||||
" ddns_override_client_update = ?,"
|
||||
" ddns_replace_client_name = ?,"
|
||||
" ddns_generated_prefix = ?,"
|
||||
" ddns_qualifying_suffix = ? "
|
||||
" ddns_qualifying_suffix = ?,"
|
||||
" reservations_in_subnet = ?,"
|
||||
" reservations_out_of_pool = ? "
|
||||
"WHERE subnet_id = ? OR subnet_prefix = ?" },
|
||||
|
||||
// Update existing shared network.
|
||||
@ -3062,7 +3046,7 @@ TaggedStatementArray tagged_statements = { {
|
||||
" relay = ?,"
|
||||
" renew_timer = ?,"
|
||||
" require_client_classes = ?,"
|
||||
" reservation_mode = ?,"
|
||||
" reservations_global = ?,"
|
||||
" user_context = ?,"
|
||||
" valid_lifetime = ?,"
|
||||
" min_valid_lifetime = ?,"
|
||||
@ -3076,7 +3060,9 @@ TaggedStatementArray tagged_statements = { {
|
||||
" ddns_override_client_update = ?,"
|
||||
" ddns_replace_client_name = ?,"
|
||||
" ddns_generated_prefix = ?,"
|
||||
" ddns_qualifying_suffix = ? "
|
||||
" ddns_qualifying_suffix = ?,"
|
||||
" reservations_in_subnet = ?,"
|
||||
" reservations_out_of_pool = ? "
|
||||
"WHERE name = ?" },
|
||||
|
||||
// Update existing option definition.
|
||||
|
@ -66,7 +66,7 @@ namespace {
|
||||
" s.relay," \
|
||||
" s.renew_timer," \
|
||||
" s.require_client_classes," \
|
||||
" s.reservation_mode," \
|
||||
" s.reservations_global," \
|
||||
" s.server_hostname," \
|
||||
" s.shared_network_name," \
|
||||
" s.user_context," \
|
||||
@ -115,6 +115,8 @@ namespace {
|
||||
" s.ddns_replace_client_name," \
|
||||
" s.ddns_generated_prefix," \
|
||||
" s.ddns_qualifying_suffix," \
|
||||
" s.reservations_in_subnet," \
|
||||
" s.reservations_out_of_pool," \
|
||||
" srv.tag " \
|
||||
"FROM dhcp4_subnet AS s " \
|
||||
server_join \
|
||||
@ -164,7 +166,7 @@ namespace {
|
||||
" s.relay," \
|
||||
" s.renew_timer," \
|
||||
" s.require_client_classes," \
|
||||
" s.reservation_mode," \
|
||||
" s.reservations_global," \
|
||||
" s.shared_network_name," \
|
||||
" s.user_context," \
|
||||
" s.valid_lifetime," \
|
||||
@ -240,6 +242,8 @@ namespace {
|
||||
" s.ddns_replace_client_name," \
|
||||
" s.ddns_generated_prefix," \
|
||||
" s.ddns_qualifying_suffix," \
|
||||
" s.reservations_in_subnet," \
|
||||
" s.reservations_out_of_pool," \
|
||||
" srv.tag " \
|
||||
"FROM dhcp6_subnet AS s " \
|
||||
server_join \
|
||||
@ -415,7 +419,7 @@ namespace {
|
||||
" n.relay," \
|
||||
" n.renew_timer," \
|
||||
" n.require_client_classes," \
|
||||
" n.reservation_mode," \
|
||||
" n.reservations_global," \
|
||||
" n.user_context," \
|
||||
" n.valid_lifetime," \
|
||||
" o.option_id," \
|
||||
@ -445,6 +449,8 @@ namespace {
|
||||
" n.ddns_replace_client_name," \
|
||||
" n.ddns_generated_prefix," \
|
||||
" n.ddns_qualifying_suffix," \
|
||||
" n.reservations_in_subnet," \
|
||||
" n.reservations_out_of_pool," \
|
||||
" s.tag " \
|
||||
"FROM dhcp4_shared_network AS n " \
|
||||
server_join \
|
||||
@ -492,7 +498,7 @@ namespace {
|
||||
" n.relay," \
|
||||
" n.renew_timer," \
|
||||
" n.require_client_classes," \
|
||||
" n.reservation_mode," \
|
||||
" n.reservations_global," \
|
||||
" n.user_context," \
|
||||
" n.valid_lifetime," \
|
||||
" o.option_id," \
|
||||
@ -522,6 +528,8 @@ namespace {
|
||||
" n.ddns_replace_client_name," \
|
||||
" n.ddns_generated_prefix," \
|
||||
" n.ddns_qualifying_suffix," \
|
||||
" n.reservations_in_subnet," \
|
||||
" n.reservations_out_of_pool," \
|
||||
" s.tag " \
|
||||
"FROM dhcp6_shared_network AS n " \
|
||||
server_join \
|
||||
|
@ -161,7 +161,9 @@ public:
|
||||
subnet->setT1(1234);
|
||||
subnet->requireClientClass("required-class1");
|
||||
subnet->requireClientClass("required-class2");
|
||||
subnet->setHostReservationMode(Subnet4::HR_DISABLED);
|
||||
subnet->setReservationsGlobal(false);
|
||||
subnet->setReservationsInSubnet(false);
|
||||
subnet->setReservationsOutOfPool(false);
|
||||
subnet->setSname("server-hostname");
|
||||
subnet->setContext(user_context);
|
||||
subnet->setValid(555555);
|
||||
@ -260,7 +262,9 @@ public:
|
||||
shared_network->setT1(1234);
|
||||
shared_network->requireClientClass("required-class1");
|
||||
shared_network->requireClientClass("required-class2");
|
||||
shared_network->setHostReservationMode(Subnet4::HR_DISABLED);
|
||||
shared_network->setReservationsGlobal(false);
|
||||
shared_network->setReservationsInSubnet(false);
|
||||
shared_network->setReservationsOutOfPool(false);
|
||||
shared_network->setContext(user_context);
|
||||
shared_network->setValid(5555);
|
||||
shared_network->setCalculateTeeTimes(true);
|
||||
@ -1319,8 +1323,14 @@ TEST_F(MySqlConfigBackendDHCPv4Test, getSubnet4WithOptionalUnspecified) {
|
||||
EXPECT_TRUE(returned_subnet->getT2().unspecified());
|
||||
EXPECT_EQ(0, returned_subnet->getT2().get());
|
||||
|
||||
EXPECT_TRUE(returned_subnet->getHostReservationMode().unspecified());
|
||||
EXPECT_EQ(Network::HR_ALL, returned_subnet->getHostReservationMode().get());
|
||||
EXPECT_TRUE(returned_subnet->getReservationsGlobal().unspecified());
|
||||
EXPECT_FALSE(returned_subnet->getReservationsGlobal().get());
|
||||
|
||||
EXPECT_TRUE(returned_subnet->getReservationsInSubnet().unspecified());
|
||||
EXPECT_TRUE(returned_subnet->getReservationsInSubnet().get());
|
||||
|
||||
EXPECT_TRUE(returned_subnet->getReservationsOutOfPool().unspecified());
|
||||
EXPECT_FALSE(returned_subnet->getReservationsOutOfPool().get());
|
||||
|
||||
EXPECT_TRUE(returned_subnet->getCalculateTeeTimes().unspecified());
|
||||
EXPECT_FALSE(returned_subnet->getCalculateTeeTimes().get());
|
||||
@ -2338,8 +2348,14 @@ TEST_F(MySqlConfigBackendDHCPv4Test, getSharedNetwork4WithOptionalUnspecified) {
|
||||
EXPECT_TRUE(returned_network->getT2().unspecified());
|
||||
EXPECT_EQ(0, returned_network->getT2().get());
|
||||
|
||||
EXPECT_TRUE(returned_network->getHostReservationMode().unspecified());
|
||||
EXPECT_EQ(Network::HR_ALL, returned_network->getHostReservationMode().get());
|
||||
EXPECT_TRUE(returned_network->getReservationsGlobal().unspecified());
|
||||
EXPECT_FALSE(returned_network->getReservationsGlobal().get());
|
||||
|
||||
EXPECT_TRUE(returned_network->getReservationsInSubnet().unspecified());
|
||||
EXPECT_TRUE(returned_network->getReservationsInSubnet().get());
|
||||
|
||||
EXPECT_TRUE(returned_network->getReservationsOutOfPool().unspecified());
|
||||
EXPECT_FALSE(returned_network->getReservationsOutOfPool().get());
|
||||
|
||||
EXPECT_TRUE(returned_network->getCalculateTeeTimes().unspecified());
|
||||
EXPECT_FALSE(returned_network->getCalculateTeeTimes().get());
|
||||
|
@ -157,7 +157,9 @@ public:
|
||||
subnet->setT1(1234);
|
||||
subnet->requireClientClass("required-class1");
|
||||
subnet->requireClientClass("required-class2");
|
||||
subnet->setHostReservationMode(Subnet4::HR_DISABLED);
|
||||
subnet->setReservationsGlobal(false);
|
||||
subnet->setReservationsInSubnet(false);
|
||||
subnet->setReservationsOutOfPool(false);
|
||||
subnet->setContext(user_context);
|
||||
subnet->setValid(555555);
|
||||
subnet->setPreferred(4444444);
|
||||
@ -307,7 +309,9 @@ public:
|
||||
shared_network->setT1(1234);
|
||||
shared_network->requireClientClass("required-class1");
|
||||
shared_network->requireClientClass("required-class2");
|
||||
shared_network->setHostReservationMode(Subnet6::HR_DISABLED);
|
||||
shared_network->setReservationsGlobal(false);
|
||||
shared_network->setReservationsInSubnet(false);
|
||||
subnet->setReservationsOutOfPool(false);
|
||||
shared_network->setContext(user_context);
|
||||
shared_network->setValid(5555);
|
||||
shared_network->setPreferred(4444);
|
||||
@ -1367,8 +1371,14 @@ TEST_F(MySqlConfigBackendDHCPv6Test, getSubnet6WithOptionalUnspecified) {
|
||||
EXPECT_TRUE(returned_subnet->getT2().unspecified());
|
||||
EXPECT_EQ(0, returned_subnet->getT2().get());
|
||||
|
||||
EXPECT_TRUE(returned_subnet->getHostReservationMode().unspecified());
|
||||
EXPECT_EQ(Network::HR_ALL, returned_subnet->getHostReservationMode().get());
|
||||
EXPECT_TRUE(returned_subnet->getReservationsGlobal().unspecified());
|
||||
EXPECT_FALSE(returned_subnet->getReservationsGlobal().get());
|
||||
|
||||
EXPECT_TRUE(returned_subnet->getReservationsInSubnet().unspecified());
|
||||
EXPECT_TRUE(returned_subnet->getReservationsInSubnet().get());
|
||||
|
||||
EXPECT_TRUE(returned_subnet->getReservationsOutOfPool().unspecified());
|
||||
EXPECT_FALSE(returned_subnet->getReservationsOutOfPool().get());
|
||||
|
||||
EXPECT_TRUE(returned_subnet->getCalculateTeeTimes().unspecified());
|
||||
EXPECT_FALSE(returned_subnet->getCalculateTeeTimes().get());
|
||||
@ -2376,8 +2386,14 @@ TEST_F(MySqlConfigBackendDHCPv6Test, getSharedNetwork6WithOptionalUnspecified) {
|
||||
EXPECT_TRUE(returned_network->getT2().unspecified());
|
||||
EXPECT_EQ(0, returned_network->getT2().get());
|
||||
|
||||
EXPECT_TRUE(returned_network->getHostReservationMode().unspecified());
|
||||
EXPECT_EQ(Network::HR_ALL, returned_network->getHostReservationMode().get());
|
||||
EXPECT_TRUE(returned_network->getReservationsGlobal().unspecified());
|
||||
EXPECT_FALSE(returned_network->getReservationsGlobal().get());
|
||||
|
||||
EXPECT_TRUE(returned_network->getReservationsInSubnet().unspecified());
|
||||
EXPECT_TRUE(returned_network->getReservationsInSubnet().get());
|
||||
|
||||
EXPECT_TRUE(returned_network->getReservationsOutOfPool().unspecified());
|
||||
EXPECT_FALSE(returned_network->getReservationsOutOfPool().get());
|
||||
|
||||
EXPECT_TRUE(returned_network->getCalculateTeeTimes().unspecified());
|
||||
EXPECT_FALSE(returned_network->getCalculateTeeTimes().get());
|
||||
|
@ -535,7 +535,7 @@ isAllocated(const asiolink::IOAddress& prefix, const uint8_t prefix_len) const {
|
||||
ConstHostPtr
|
||||
AllocEngine::ClientContext6::currentHost() const {
|
||||
Subnet6Ptr subnet = host_subnet_ ? host_subnet_ : subnet_;
|
||||
if (subnet && (subnet_->getHostReservationMode() & Network::HR_IN_SUBNET_FLAG)) {
|
||||
if (subnet && subnet->getReservationsInSubnet()) {
|
||||
auto host = hosts_.find(subnet->getID());
|
||||
if (host != hosts_.cend()) {
|
||||
return (host->second);
|
||||
@ -548,7 +548,7 @@ AllocEngine::ClientContext6::currentHost() const {
|
||||
ConstHostPtr
|
||||
AllocEngine::ClientContext6::globalHost() const {
|
||||
Subnet6Ptr subnet = host_subnet_ ? host_subnet_ : subnet_;
|
||||
if (subnet && (subnet_->getHostReservationMode() & Network::HR_GLOBAL_FLAG)) {
|
||||
if (subnet && subnet_->getReservationsGlobal()) {
|
||||
auto host = hosts_.find(SUBNET_ID_GLOBAL);
|
||||
if (host != hosts_.cend()) {
|
||||
return (host->second);
|
||||
@ -597,14 +597,14 @@ AllocEngine::findReservation(ClientContext6& ctx) {
|
||||
SharedNetwork6Ptr network;
|
||||
subnet->getSharedNetwork(network);
|
||||
|
||||
if (subnet->getHostReservationMode() & Network::HR_GLOBAL_FLAG) {
|
||||
if (subnet->getReservationsGlobal()) {
|
||||
ConstHostPtr ghost = findGlobalReservation(ctx);
|
||||
if (ghost) {
|
||||
ctx.hosts_[SUBNET_ID_GLOBAL] = ghost;
|
||||
|
||||
// @todo In theory, to support global as part of HR_ALL,
|
||||
// we would just keep going, instead of returning.
|
||||
if (subnet->getHostReservationMode() == Network::HR_GLOBAL) {
|
||||
// If we had only to fetch global reservations it is done.
|
||||
if (!subnet->getReservationsInSubnet() &&
|
||||
!subnet->getReservationsOutOfPool()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -641,9 +641,9 @@ AllocEngine::findReservation(ClientContext6& ctx) {
|
||||
while (subnet) {
|
||||
|
||||
// Only makes sense to get reservations if the client has access
|
||||
// to the class and host reservations are enabled.
|
||||
// to the class and host reservations are enabled for this subnet.
|
||||
if (subnet->clientSupported(ctx.query_->getClasses()) &&
|
||||
(subnet->getHostReservationMode() != Network::HR_DISABLED)) {
|
||||
(subnet->getReservationsInSubnet() || subnet->getReservationsOutOfPool())) {
|
||||
// Iterate over configured identifiers in the order of preference
|
||||
// and try to use each of them to search for the reservations.
|
||||
for (auto id_pair : ctx.host_identifiers_) {
|
||||
@ -916,9 +916,6 @@ AllocEngine::allocateUnreservedLeases6(ClientContext6& ctx) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check which host reservation mode is supported in this subnet.
|
||||
Network::HRMode hr_mode = subnet->getHostReservationMode();
|
||||
|
||||
/// @todo: We support only one hint for now
|
||||
Lease6Ptr lease =
|
||||
LeaseMgrFactory::instance().getLease6(ctx.currentIA().type_, hint);
|
||||
@ -929,9 +926,9 @@ AllocEngine::allocateUnreservedLeases6(ClientContext6& ctx) {
|
||||
// it has been reserved for us we would have already allocated a lease.
|
||||
|
||||
ConstHostCollection hosts;
|
||||
bool in_subnet = (hr_mode & Network::HR_IN_SUBNET_FLAG);
|
||||
bool out_of_pool = (hr_mode & Network::HR_OUT_OF_POOL_FLAG);
|
||||
// The HR_OUT_OF_POOL_FLAG indicates that no client should be assigned reservations
|
||||
bool in_subnet = subnet->getReservationsInSubnet();
|
||||
bool out_of_pool = subnet->getReservationsOutOfPool();
|
||||
// The out-of-pool flag indicates that no client should be assigned reservations
|
||||
// from within the dynamic pool, and for that reason we only look at reservations that
|
||||
// are outside the pools, hence the inPool check.
|
||||
if ((in_subnet && !out_of_pool) ||
|
||||
@ -969,9 +966,9 @@ AllocEngine::allocateUnreservedLeases6(ClientContext6& ctx) {
|
||||
|
||||
// If the lease is expired, we may likely reuse it, but...
|
||||
ConstHostCollection hosts;
|
||||
bool in_subnet = (hr_mode & Network::HR_IN_SUBNET_FLAG);
|
||||
bool out_of_pool = (hr_mode & Network::HR_OUT_OF_POOL_FLAG);
|
||||
// The HR_OUT_OF_POOL_FLAG indicates that no client should be assigned reservations
|
||||
bool in_subnet = subnet->getReservationsInSubnet();
|
||||
bool out_of_pool = subnet->getReservationsOutOfPool();
|
||||
// The out-of-pool flag indicates that no client should be assigned reservations
|
||||
// from within the dynamic pool, and for that reason we only look at reservations that
|
||||
// are outside the pools, hence the inPool check.
|
||||
if ((in_subnet && !out_of_pool) ||
|
||||
@ -1053,7 +1050,8 @@ AllocEngine::allocateUnreservedLeases6(ClientContext6& ctx) {
|
||||
continue;
|
||||
}
|
||||
uint64_t max_attempts = (attempts_ > 0 ? attempts_ : possible_attempts);
|
||||
Network::HRMode hr_mode = subnet->getHostReservationMode();
|
||||
bool in_subnet = subnet->getReservationsInSubnet();
|
||||
bool out_of_pool = subnet->getReservationsOutOfPool();
|
||||
|
||||
// Set the default status code in case the lease6_select callouts
|
||||
// do not exist and the callout handle has a status returned by
|
||||
@ -1084,8 +1082,7 @@ AllocEngine::allocateUnreservedLeases6(ClientContext6& ctx) {
|
||||
}
|
||||
|
||||
// First check for reservation when it is the choice.
|
||||
if (check_reservation_first && ((hr_mode & Network::HR_IN_SUBNET_FLAG) &&
|
||||
!(hr_mode & Network::HR_OUT_OF_POOL_FLAG))) {
|
||||
if (check_reservation_first && in_subnet && !out_of_pool) {
|
||||
auto hosts = getIPv6Resrv(subnet->getID(), candidate);
|
||||
if (!hosts.empty()) {
|
||||
// Don't allocate.
|
||||
@ -1110,8 +1107,7 @@ AllocEngine::allocateUnreservedLeases6(ClientContext6& ctx) {
|
||||
/// In-pool reservations: Check if this address is reserved for someone
|
||||
/// else. There is no need to check for whom it is reserved, because if
|
||||
/// it has been reserved for us we would have already allocated a lease.
|
||||
if (!check_reservation_first && (hr_mode & Network::HR_IN_SUBNET_FLAG) &&
|
||||
!(hr_mode & Network::HR_OUT_OF_POOL_FLAG)) {
|
||||
if (!check_reservation_first && in_subnet && !out_of_pool) {
|
||||
auto hosts = getIPv6Resrv(subnet->getID(), candidate);
|
||||
if (!hosts.empty()) {
|
||||
// Don't allocate.
|
||||
@ -1143,8 +1139,7 @@ AllocEngine::allocateUnreservedLeases6(ClientContext6& ctx) {
|
||||
// allocation attempts.
|
||||
} else if (existing->expired()) {
|
||||
// Make sure it's not reserved.
|
||||
if (!check_reservation_first && (hr_mode & Network::HR_IN_SUBNET_FLAG) &&
|
||||
!(hr_mode & Network::HR_OUT_OF_POOL_FLAG)) {
|
||||
if (!check_reservation_first && in_subnet && !out_of_pool) {
|
||||
auto hosts = getIPv6Resrv(subnet->getID(), candidate);
|
||||
if (!hosts.empty()) {
|
||||
// Don't allocate.
|
||||
@ -1265,11 +1260,8 @@ AllocEngine::allocateReservedLeases6(ClientContext6& ctx,
|
||||
|
||||
ConstHostPtr host = ctx.hosts_[subnet_id];
|
||||
|
||||
// Check which host reservation mode is supported in this subnet.
|
||||
Network::HRMode hr_mode = subnet->getHostReservationMode();
|
||||
|
||||
bool in_subnet = (hr_mode & Network::HR_IN_SUBNET_FLAG);
|
||||
bool out_of_pool = (hr_mode & Network::HR_OUT_OF_POOL_FLAG);
|
||||
bool in_subnet = subnet->getReservationsInSubnet();
|
||||
bool out_of_pool = subnet->getReservationsOutOfPool();
|
||||
|
||||
// Get the IPv6 reservations of specified type.
|
||||
const IPv6ResrvRange& reservs = host->getIPv6Reservations(type);
|
||||
@ -1284,7 +1276,7 @@ AllocEngine::allocateReservedLeases6(ClientContext6& ctx,
|
||||
continue;
|
||||
}
|
||||
|
||||
// The HR_OUT_OF_POOL_FLAG indicates that no client should be assigned reservations
|
||||
// The out-of-pool flag indicates that no client should be assigned reservations
|
||||
// from within the dynamic pool, and for that reason we only look at reservations that
|
||||
// are outside the pools, hence the inPool check.
|
||||
if ((in_subnet && !out_of_pool) ||
|
||||
@ -1490,7 +1482,9 @@ AllocEngine::removeNonmatchingReservedLeases6(ClientContext6& ctx,
|
||||
}
|
||||
// If host reservation is disabled (so there are no reserved leases)
|
||||
// use the simplified version.
|
||||
if (ctx.subnet_->getHostReservationMode() == Network::HR_DISABLED) {
|
||||
if (!ctx.subnet_->getReservationsGlobal() &&
|
||||
!ctx.subnet_->getReservationsInSubnet() &&
|
||||
!ctx.subnet_->getReservationsOutOfPool()) {
|
||||
removeNonmatchingReservedNoHostLeases6(ctx, existing_leases);
|
||||
return;
|
||||
}
|
||||
@ -2978,11 +2972,9 @@ addressReserved(const IOAddress& address, const AllocEngine::ClientContext4& ctx
|
||||
if (!ctx.subnet_) {
|
||||
return false;
|
||||
}
|
||||
// Check which host reservation mode is supported in this subnet.
|
||||
Network::HRMode hr_mode = ctx.subnet_->getHostReservationMode();
|
||||
bool in_subnet = (hr_mode & Network::HR_IN_SUBNET_FLAG);
|
||||
bool out_of_pool = (hr_mode & Network::HR_OUT_OF_POOL_FLAG);
|
||||
// The HR_OUT_OF_POOL_FLAG indicates that no client should be assigned reservations
|
||||
bool in_subnet = ctx.subnet_->getReservationsInSubnet();
|
||||
bool out_of_pool = ctx.subnet_->getReservationsOutOfPool();
|
||||
// The out-of-pool flag indicates that no client should be assigned reservations
|
||||
// from within the dynamic pool, and for that reason we only look at reservations that
|
||||
// are outside the pools, hence the inPool check.
|
||||
if ((in_subnet && !out_of_pool) ||
|
||||
@ -3048,13 +3040,14 @@ hasAddressReservation(AllocEngine::ClientContext4& ctx) {
|
||||
|
||||
Subnet4Ptr subnet = ctx.subnet_;
|
||||
while (subnet) {
|
||||
if (subnet->getHostReservationMode() & Network::HR_GLOBAL_FLAG) {
|
||||
if (subnet->getReservationsGlobal()) {
|
||||
auto host = ctx.hosts_.find(SUBNET_ID_GLOBAL);
|
||||
bool found = (host != ctx.hosts_.end() &&
|
||||
!(host->second->getIPv4Reservation().isV4Zero()));
|
||||
// if we want global + other modes we would need to
|
||||
// return only if true, else continue
|
||||
if (subnet->getHostReservationMode() == Network::HR_GLOBAL) {
|
||||
if (!subnet->getReservationsInSubnet() &&
|
||||
!subnet->getReservationsOutOfPool()) {
|
||||
return (found);
|
||||
} else {
|
||||
if (found) {
|
||||
@ -3064,11 +3057,9 @@ hasAddressReservation(AllocEngine::ClientContext4& ctx) {
|
||||
}
|
||||
|
||||
auto host = ctx.hosts_.find(subnet->getID());
|
||||
// Check which host reservation mode is supported in this subnet.
|
||||
Network::HRMode hr_mode = subnet->getHostReservationMode();
|
||||
bool in_subnet = (hr_mode & Network::HR_IN_SUBNET_FLAG);
|
||||
bool out_of_pool = (hr_mode & Network::HR_OUT_OF_POOL_FLAG);
|
||||
// The HR_OUT_OF_POOL_FLAG indicates that no client should be assigned reservations
|
||||
bool in_subnet = subnet->getReservationsInSubnet();
|
||||
bool out_of_pool = subnet->getReservationsOutOfPool();
|
||||
// The out-of-pool flag indicates that no client should be assigned reservations
|
||||
// from within the dynamic pool, and for that reason we only look at reservations that
|
||||
// are outside the pools, hence the inPool check.
|
||||
if (host != ctx.hosts_.end()) {
|
||||
@ -3252,7 +3243,7 @@ AllocEngine::ClientContext4::ClientContext4(const Subnet4Ptr& subnet,
|
||||
|
||||
ConstHostPtr
|
||||
AllocEngine::ClientContext4::currentHost() const {
|
||||
if (subnet_ && (subnet_->getHostReservationMode() & Network::HR_IN_SUBNET_FLAG)) {
|
||||
if (subnet_ && subnet_->getReservationsInSubnet()) {
|
||||
auto host = hosts_.find(subnet_->getID());
|
||||
if (host != hosts_.cend()) {
|
||||
return (host->second);
|
||||
@ -3264,7 +3255,7 @@ AllocEngine::ClientContext4::currentHost() const {
|
||||
|
||||
ConstHostPtr
|
||||
AllocEngine::ClientContext4::globalHost() const {
|
||||
if (subnet_ && (subnet_->getHostReservationMode() & Network::HR_GLOBAL_FLAG)) {
|
||||
if (subnet_ && subnet_->getReservationsGlobal()) {
|
||||
auto host = hosts_.find(SUBNET_ID_GLOBAL);
|
||||
if (host != hosts_.cend()) {
|
||||
return (host->second);
|
||||
@ -3351,14 +3342,14 @@ AllocEngine::findReservation(ClientContext4& ctx) {
|
||||
SharedNetwork4Ptr network;
|
||||
subnet->getSharedNetwork(network);
|
||||
|
||||
if (subnet->getHostReservationMode() & Network::HR_GLOBAL_FLAG) {
|
||||
if (subnet->getReservationsGlobal()) {
|
||||
ConstHostPtr ghost = findGlobalReservation(ctx);
|
||||
if (ghost) {
|
||||
ctx.hosts_[SUBNET_ID_GLOBAL] = ghost;
|
||||
|
||||
// @todo In theory, to support global as part of HR_ALL,
|
||||
// we would just keep going, instead of returning.
|
||||
if (subnet->getHostReservationMode() == Network::HR_GLOBAL) {
|
||||
// If we had only to fetch global reservations it is done.
|
||||
if (!subnet->getReservationsInSubnet() &&
|
||||
!subnet->getReservationsOutOfPool()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -3399,7 +3390,7 @@ AllocEngine::findReservation(ClientContext4& ctx) {
|
||||
// Only makes sense to get reservations if the client has access
|
||||
// to the class.
|
||||
if (subnet->clientSupported(ctx.query_->getClasses()) &&
|
||||
(subnet->getHostReservationMode() != Network::HR_DISABLED)) {
|
||||
(subnet->getReservationsInSubnet() || subnet->getReservationsOutOfPool())) {
|
||||
// Iterate over configured identifiers in the order of preference
|
||||
// and try to use each of them to search for the reservations.
|
||||
BOOST_FOREACH(const IdentifierPair& id_pair, ctx.host_identifiers_) {
|
||||
|
@ -7,7 +7,6 @@
|
||||
#include <config.h>
|
||||
#include <dhcpsrv/triplet.h>
|
||||
#include <dhcpsrv/parsers/base_network_parser.h>
|
||||
#include <dhcpsrv/parsers/reservation_modes_parser.h>
|
||||
#include <util/optional.h>
|
||||
#include <util/strutil.h>
|
||||
|
||||
@ -17,6 +16,44 @@ using namespace isc::util;
|
||||
namespace isc {
|
||||
namespace dhcp {
|
||||
|
||||
bool
|
||||
BaseNetworkParser::moveReservationMode(ElementPtr config) {
|
||||
if (!config->contains("reservation-mode")) {
|
||||
return (false);
|
||||
}
|
||||
if (config->contains("reservations-global") ||
|
||||
config->contains("reservations-in-subnet") ||
|
||||
config->contains("reservations-out-of-pool")) {
|
||||
isc_throw(DhcpConfigError, "invalid use of both 'reservation-mode'"
|
||||
" one of 'reservations-global', 'reservations-in-subnet'"
|
||||
" or 'reservations-out-of-pool' parameters");
|
||||
}
|
||||
std::string hr_mode = getString(config, "reservation-mode");
|
||||
if ((hr_mode == "disabled") || (hr_mode == "off")) {
|
||||
config->set("reservations-global", Element::create(false));
|
||||
config->set("reservations-in-subnet", Element::create(false));
|
||||
config->set("reservations-out-of-pool", Element::create(false));
|
||||
} else if (hr_mode == "out-of-pool") {
|
||||
config->set("reservations-global", Element::create(false));
|
||||
config->set("reservations-in-subnet", Element::create(true));
|
||||
config->set("reservations-out-of-pool", Element::create(true));
|
||||
} else if (hr_mode == "global") {
|
||||
config->set("reservations-global", Element::create(true));
|
||||
config->set("reservations-in-subnet", Element::create(false));
|
||||
config->set("reservations-out-of-pool", Element::create(false));
|
||||
} else if (hr_mode == "all") {
|
||||
config->set("reservations-global", Element::create(false));
|
||||
config->set("reservations-in-subnet", Element::create(true));
|
||||
config->set("reservations-out-of-pool", Element::create(false));
|
||||
} else {
|
||||
isc_throw(DhcpConfigError, "invalid reservation-mode parameter: '"
|
||||
<< hr_mode << "' ("
|
||||
<< getPosition("reservation-mode", config) << ")");
|
||||
}
|
||||
config->remove("reservation-mode");
|
||||
return (true);
|
||||
}
|
||||
|
||||
const Triplet<uint32_t>
|
||||
BaseNetworkParser::parseLifetime(const ConstElementPtr& scope,
|
||||
const std::string& name) {
|
||||
@ -136,6 +173,21 @@ BaseNetworkParser::parseCommon(const ConstElementPtr& network_data,
|
||||
network->setStoreExtendedInfo(getBoolean(network_data,
|
||||
"store-extended-info"));
|
||||
}
|
||||
|
||||
if (network_data->contains("reservations-global")) {
|
||||
network->setReservationsGlobal(getBoolean(network_data,
|
||||
"reservations-global"));
|
||||
}
|
||||
|
||||
if (network_data->contains("reservations-in-subnet")) {
|
||||
network->setReservationsInSubnet(getBoolean(network_data,
|
||||
"reservations-in-subnet"));
|
||||
}
|
||||
|
||||
if (network_data->contains("reservations-out-of-pool")) {
|
||||
network->setReservationsOutOfPool(getBoolean(network_data,
|
||||
"reservations-out-of-pool"));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -198,61 +250,6 @@ BaseNetworkParser::parseCacheParams(const ConstElementPtr& network_data,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BaseNetworkParser::parseHostReservationMode(const data::ConstElementPtr& network_data,
|
||||
NetworkPtr& network) {
|
||||
if (network_data->contains("reservation-mode")) {
|
||||
bool found = false;
|
||||
if (network_data->contains("reservations-out-of-pool") ||
|
||||
network_data->contains("reservations-in-subnet") ||
|
||||
network_data->contains("reservations-global")) {
|
||||
found = true;
|
||||
}
|
||||
if (found) {
|
||||
isc_throw(DhcpConfigError, "invalid use of both 'reservation-mode'"
|
||||
" and one of 'reservations-out-of-pool'"
|
||||
" , 'reservations-in-subnet' or"
|
||||
" 'reservations-global' parameters");
|
||||
}
|
||||
try {
|
||||
std::string hr_mode = getString(network_data, "reservation-mode");
|
||||
network->setHostReservationMode(Network::hrModeFromString(hr_mode));
|
||||
} catch (const BadValue& ex) {
|
||||
isc_throw(DhcpConfigError, "invalid reservation-mode parameter: "
|
||||
<< ex.what() << " (" << getPosition("reservation-mode",
|
||||
network_data) << ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BaseNetworkParser::parseHostReservationModes(const data::ConstElementPtr& network_data,
|
||||
NetworkPtr& network) {
|
||||
bool found = false;
|
||||
if (network_data->contains("reservations-out-of-pool") ||
|
||||
network_data->contains("reservations-in-subnet") ||
|
||||
network_data->contains("reservations-global")) {
|
||||
found = true;
|
||||
}
|
||||
if (found) {
|
||||
if (network_data->contains("reservation-mode")) {
|
||||
isc_throw(DhcpConfigError, "invalid use of both 'reservation-mode'"
|
||||
" and one of 'reservations-out-of-pool'"
|
||||
" , 'reservations-in-subnet' or"
|
||||
" 'reservations-global' parameters");
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
HostReservationModesParser parser;
|
||||
Network::HRMode flags = parser.parse(network_data);
|
||||
network->setHostReservationMode(flags);
|
||||
} catch (const BadValue& ex) {
|
||||
isc_throw(DhcpConfigError, "invalid parameter: " << ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BaseNetworkParser::parseDdnsParams(const data::ConstElementPtr& network_data,
|
||||
NetworkPtr& network) {
|
||||
|
@ -17,6 +17,19 @@ namespace dhcp {
|
||||
/// @brief Common configuration parser for shared networks
|
||||
/// and subnets.
|
||||
class BaseNetworkParser : public data::SimpleParser {
|
||||
public:
|
||||
|
||||
/// @brief Moves deprecated reservation-mode parameter to
|
||||
/// new reservations flags.
|
||||
///
|
||||
/// @param config [in/out] configuration to alter.
|
||||
/// @throw DhcpConfigError on error e.g. when both reservation-mode
|
||||
/// and a flag are specified.
|
||||
/// @return true if reservation-mode parameter has been replaces with
|
||||
/// new reservations-global, reservations-in-subnet and
|
||||
/// reservations-out-of-pool parameters, false otherwise.
|
||||
static bool moveReservationMode(isc::data::ElementPtr config);
|
||||
|
||||
protected:
|
||||
|
||||
/// @brief Parses DHCP lifetime.
|
||||
@ -37,6 +50,9 @@ protected:
|
||||
/// - rebind-timer,
|
||||
/// - valid-lifetime,
|
||||
/// - store-extended-info
|
||||
/// - reservations-global
|
||||
/// - reservations-in-subnet
|
||||
/// - reservations-out-of-pool
|
||||
///
|
||||
/// @param network_data Data element holding shared network
|
||||
/// configuration to be parsed.
|
||||
@ -78,28 +94,6 @@ protected:
|
||||
void parseCacheParams(const data::ConstElementPtr& network_data,
|
||||
NetworkPtr& network);
|
||||
|
||||
/// @brief Parses host reservation mode.
|
||||
///
|
||||
/// @note Configuring 'reservation-mode' is deprecated. The new
|
||||
/// 'reservations-out-of-pool', 'reservations-in-subnet' and
|
||||
/// 'reservations-global' parameters should be used.
|
||||
///
|
||||
/// @param network_data Data element holding shared network
|
||||
/// configuration to be parsed.
|
||||
/// @param [out] network Pointer to a network in which parsed data is
|
||||
/// to be stored.
|
||||
void parseHostReservationMode(const data::ConstElementPtr& network_data,
|
||||
NetworkPtr& network);
|
||||
|
||||
/// @brief Parses host reservation modes.
|
||||
///
|
||||
/// @param network_data Data element holding shared network
|
||||
/// configuration to be parsed.
|
||||
/// @param [out] network Pointer to a network in which parsed data is
|
||||
/// to be stored.
|
||||
void parseHostReservationModes(const data::ConstElementPtr& network_data,
|
||||
NetworkPtr& network);
|
||||
|
||||
/// @brief Parses parameters pertaining to DDNS behavior.
|
||||
///
|
||||
/// The parsed parameters are:
|
||||
|
@ -743,9 +743,14 @@ Subnet4ConfigParser::initSubnet(data::ConstElementPtr params,
|
||||
subnet_id));
|
||||
subnet_ = subnet4;
|
||||
|
||||
// Move from reservation mode to new reservations flags.
|
||||
ElementPtr mutable_params;
|
||||
mutable_params = boost::const_pointer_cast<Element>(params);
|
||||
BaseNetworkParser::moveReservationMode(mutable_params);
|
||||
|
||||
// Parse parameters common to all Network derivations.
|
||||
NetworkPtr network = boost::dynamic_pointer_cast<Network>(subnet4);
|
||||
parseCommon(params, network);
|
||||
parseCommon(mutable_params, network);
|
||||
|
||||
std::ostringstream output;
|
||||
output << addr << "/" << static_cast<int>(len) << " with params: ";
|
||||
@ -859,13 +864,6 @@ Subnet4ConfigParser::initSubnet(data::ConstElementPtr params,
|
||||
}
|
||||
}
|
||||
|
||||
// reservation modes
|
||||
parseHostReservationModes(params, network);
|
||||
|
||||
// Let's set host reservation mode. If not specified, the default value of
|
||||
// all will be used.
|
||||
parseHostReservationMode(params, network);
|
||||
|
||||
// Try setting up client class.
|
||||
if (params->contains("client-class")) {
|
||||
string client_class = getString(params, "client-class");
|
||||
@ -1241,9 +1239,14 @@ Subnet6ConfigParser::initSubnet(data::ConstElementPtr params,
|
||||
subnet_id);
|
||||
subnet_.reset(subnet6);
|
||||
|
||||
// Move from reservation mode to new reservations flags.
|
||||
ElementPtr mutable_params;
|
||||
mutable_params = boost::const_pointer_cast<Element>(params);
|
||||
BaseNetworkParser::moveReservationMode(mutable_params);
|
||||
|
||||
// Parse parameters common to all Network derivations.
|
||||
NetworkPtr network = boost::dynamic_pointer_cast<Network>(subnet_);
|
||||
parseCommon(params, network);
|
||||
parseCommon(mutable_params, network);
|
||||
|
||||
// Enable or disable Rapid Commit option support for the subnet.
|
||||
if (!rapid_commit.unspecified()) {
|
||||
@ -1334,13 +1337,6 @@ Subnet6ConfigParser::initSubnet(data::ConstElementPtr params,
|
||||
subnet6->setIface(iface);
|
||||
}
|
||||
|
||||
// reservation modes
|
||||
parseHostReservationModes(params, network);
|
||||
|
||||
// Let's set host reservation mode. If not specified, the default value of
|
||||
// all will be used.
|
||||
parseHostReservationMode(params, network);
|
||||
|
||||
// Try setting up client class.
|
||||
if (params->contains("client-class")) {
|
||||
string client_class = getString(params, "client-class");
|
||||
|
@ -44,9 +44,14 @@ SharedNetwork4Parser::parse(const data::ConstElementPtr& shared_network_data) {
|
||||
std::string name = getString(shared_network_data, "name");
|
||||
shared_network.reset(new SharedNetwork4(name));
|
||||
|
||||
// Move from reservation mode to new reservations flags.
|
||||
ElementPtr mutable_params;
|
||||
mutable_params = boost::const_pointer_cast<Element>(shared_network_data);
|
||||
BaseNetworkParser::moveReservationMode(mutable_params);
|
||||
|
||||
// Parse parameters common to all Network derivations.
|
||||
NetworkPtr network = boost::dynamic_pointer_cast<Network>(shared_network);
|
||||
parseCommon(shared_network_data, network);
|
||||
parseCommon(mutable_params, network);
|
||||
|
||||
// interface is an optional parameter
|
||||
if (shared_network_data->contains("interface")) {
|
||||
@ -185,12 +190,6 @@ SharedNetwork4Parser::parse(const data::ConstElementPtr& shared_network_data) {
|
||||
}
|
||||
}
|
||||
|
||||
// reservation modes
|
||||
parseHostReservationModes(shared_network_data, network);
|
||||
|
||||
// reservation-mode
|
||||
parseHostReservationMode(shared_network_data, network);
|
||||
|
||||
parseTeePercents(shared_network_data, network);
|
||||
|
||||
// Parse DDNS parameters
|
||||
@ -234,9 +233,14 @@ SharedNetwork6Parser::parse(const data::ConstElementPtr& shared_network_data) {
|
||||
std::string name = getString(shared_network_data, "name");
|
||||
shared_network.reset(new SharedNetwork6(name));
|
||||
|
||||
// Move from reservation mode to new reservations flags.
|
||||
ElementPtr mutable_params;
|
||||
mutable_params = boost::const_pointer_cast<Element>(shared_network_data);
|
||||
BaseNetworkParser::moveReservationMode(mutable_params);
|
||||
|
||||
// Parse parameters common to all Network derivations.
|
||||
NetworkPtr network = boost::dynamic_pointer_cast<Network>(shared_network);
|
||||
parseCommon(shared_network_data, network);
|
||||
parseCommon(mutable_params, network);
|
||||
|
||||
// preferred-lifetime
|
||||
shared_network->setPreferred(parseLifetime(shared_network_data,
|
||||
@ -354,12 +358,6 @@ SharedNetwork6Parser::parse(const data::ConstElementPtr& shared_network_data) {
|
||||
}
|
||||
}
|
||||
|
||||
// reservation modes
|
||||
parseHostReservationModes(shared_network_data, network);
|
||||
|
||||
// reservation-mode
|
||||
parseHostReservationMode(shared_network_data, network);
|
||||
|
||||
parseTeePercents(shared_network_data, network);
|
||||
|
||||
// Parse DDNS parameters
|
||||
|
@ -2905,6 +2905,7 @@ TEST_F(AllocEngine4Test, findReservation) {
|
||||
EXPECT_FALSE(ctx.currentHost());
|
||||
|
||||
// Check the out of the pool reservation mode.
|
||||
subnet_->setReservationsInSubnet(true);
|
||||
subnet_->setReservationsOutOfPool(true);
|
||||
ASSERT_NO_THROW(engine.findReservation(ctx));
|
||||
EXPECT_TRUE(ctx.currentHost());
|
||||
|
@ -3719,6 +3719,7 @@ TEST_F(AllocEngine6Test, mixedHostReservedAddress) {
|
||||
|
||||
subnet_->setReservationsGlobal(true);
|
||||
subnet_->setReservationsInSubnet(true);
|
||||
subnet_->setReservationsOutOfPool(false);
|
||||
|
||||
// Create context which will be used to try to allocate leases
|
||||
Pkt6Ptr query(new Pkt6(DHCPV6_REQUEST, 1234));
|
||||
@ -3862,6 +3863,7 @@ TEST_F(AllocEngine6Test, bothHostReservedAddress) {
|
||||
|
||||
subnet_->setReservationsGlobal(true);
|
||||
subnet_->setReservationsInSubnet(true);
|
||||
subnet_->setReservationsOutOfPool(false);
|
||||
|
||||
// Create context which will be used to try to allocate leases
|
||||
Pkt6Ptr query(new Pkt6(DHCPV6_REQUEST, 1234));
|
||||
|
@ -6,9 +6,12 @@
|
||||
|
||||
#include <config.h>
|
||||
#include <asiolink/io_address.h>
|
||||
#include <cc/data.h>
|
||||
#include <dhcp/dhcp6.h>
|
||||
#include <dhcp/option.h>
|
||||
#include <dhcpsrv/network.h>
|
||||
#include <dhcpsrv/parsers/base_network_parser.h>
|
||||
#include <testutils/gtest_utils.h>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <functional>
|
||||
#include <gtest/gtest.h>
|
||||
@ -17,6 +20,7 @@ using namespace isc::asiolink;
|
||||
using namespace isc::data;
|
||||
using namespace isc::dhcp;
|
||||
using namespace isc::util;
|
||||
using namespace isc::test;
|
||||
|
||||
namespace {
|
||||
|
||||
@ -586,4 +590,155 @@ TEST_F(NetworkTest, getSiaddrNeverFail) {
|
||||
EXPECT_NO_THROW(net4_child->getSiaddr());
|
||||
}
|
||||
|
||||
/// @brief Test fixture class for testing @c moveReservationMode.
|
||||
class NetworkReservationTest : public ::testing::Test {
|
||||
public:
|
||||
|
||||
/// @brief Move test error case.
|
||||
///
|
||||
/// Error cases of @ref BaseNetworkParser::moveReservationMode.
|
||||
///
|
||||
/// @param config String with the config to test.
|
||||
/// @param expected String with the expected error message.
|
||||
void TestError(const std::string& config, const std::string& expected) {
|
||||
ElementPtr cfg;
|
||||
ASSERT_NO_THROW(cfg = Element::fromJSON(config))
|
||||
<< "bad config, test broken";
|
||||
|
||||
ElementPtr copy = isc::data::copy(cfg);
|
||||
|
||||
EXPECT_THROW_MSG(BaseNetworkParser::moveReservationMode(cfg),
|
||||
DhcpConfigError, expected);
|
||||
|
||||
ASSERT_TRUE(copy->equals(*cfg));
|
||||
}
|
||||
|
||||
/// @brief Move test case.
|
||||
///
|
||||
/// Test cases of @ref BaseNetworkParser::moveReservationMode.
|
||||
///
|
||||
/// @param config String with the config to test.
|
||||
/// @param expected String with the config after move.
|
||||
void TestMove(const std::string& config, const std::string& expected) {
|
||||
ElementPtr cfg;
|
||||
ASSERT_NO_THROW(cfg = Element::fromJSON(config))
|
||||
<< "bad config, test broken";
|
||||
|
||||
EXPECT_NO_THROW(BaseNetworkParser::moveReservationMode(cfg));
|
||||
|
||||
EXPECT_EQ(expected, cfg->str());
|
||||
}
|
||||
};
|
||||
|
||||
/// @brief Test @ref BaseNetworkParser::moveReservationMode error cases.
|
||||
TEST_F(NetworkReservationTest, errors) {
|
||||
// Conflicts.
|
||||
std::string config = "{\n"
|
||||
"\"reservation-mode\": \"all\",\n"
|
||||
"\"reservations-global\": true\n"
|
||||
"}";
|
||||
std::string expected = "invalid use of both 'reservation-mode'"
|
||||
" one of 'reservations-global', 'reservations-in-subnet'"
|
||||
" or 'reservations-out-of-pool' parameters";
|
||||
TestError(config, expected);
|
||||
|
||||
config = "{\n"
|
||||
"\"reservation-mode\": \"all\",\n"
|
||||
"\"reservations-in-subnet\": true\n"
|
||||
"}";
|
||||
TestError(config, expected);
|
||||
|
||||
config = "{\n"
|
||||
"\"reservation-mode\": \"all\",\n"
|
||||
"\"reservations-out-of-pool\": false\n"
|
||||
"}";
|
||||
TestError(config, expected);
|
||||
|
||||
// Unknown mode.
|
||||
config = "{\n"
|
||||
"\"reservation-mode\": \"foo\"\n"
|
||||
"}";
|
||||
expected = "invalid reservation-mode parameter: 'foo' (<string>:2:21)";
|
||||
TestError(config, expected);
|
||||
}
|
||||
|
||||
/// @brief Test @ref BaseNetworkParser::moveReservationMode.
|
||||
TEST_F(NetworkReservationTest, move) {
|
||||
// No-ops.
|
||||
std::string config = "{\n"
|
||||
"}";
|
||||
std::string expected = "{ "
|
||||
" }";
|
||||
TestMove(config, expected);
|
||||
|
||||
config = "{\n"
|
||||
"\"reservations-global\": true\n"
|
||||
"}";
|
||||
expected = "{"
|
||||
" \"reservations-global\": true"
|
||||
" }";
|
||||
TestMove(config, expected);
|
||||
|
||||
// Disabled.
|
||||
config = "{\n"
|
||||
"\"reservation-mode\": \"disabled\"\n"
|
||||
"}";
|
||||
expected = "{"
|
||||
" \"reservations-global\": false,"
|
||||
" \"reservations-in-subnet\": false,"
|
||||
" \"reservations-out-of-pool\": false"
|
||||
" }";
|
||||
TestMove(config, expected);
|
||||
|
||||
config = "{\n"
|
||||
"\"reservation-mode\": \"off\"\n"
|
||||
"}";
|
||||
TestMove(config, expected);
|
||||
|
||||
// Out-of-pool.
|
||||
config = "{\n"
|
||||
"\"reservation-mode\": \"out-of-pool\"\n"
|
||||
"}";
|
||||
expected = "{"
|
||||
" \"reservations-global\": false,"
|
||||
" \"reservations-in-subnet\": true,"
|
||||
" \"reservations-out-of-pool\": true"
|
||||
" }";
|
||||
TestMove(config, expected);
|
||||
|
||||
// Global.
|
||||
config = "{\n"
|
||||
"\"reservation-mode\": \"global\"\n"
|
||||
"}";
|
||||
expected = "{"
|
||||
" \"reservations-global\": true,"
|
||||
" \"reservations-in-subnet\": false,"
|
||||
" \"reservations-out-of-pool\": false"
|
||||
" }";
|
||||
TestMove(config, expected);
|
||||
|
||||
// All.
|
||||
config = "{\n"
|
||||
"\"reservation-mode\": \"all\"\n"
|
||||
"}";
|
||||
expected = "{"
|
||||
" \"reservations-global\": false,"
|
||||
" \"reservations-in-subnet\": true,"
|
||||
" \"reservations-out-of-pool\": false"
|
||||
" }";
|
||||
TestMove(config, expected);
|
||||
|
||||
config = "{\n"
|
||||
"\"foobar\": 1234,\n"
|
||||
"\"reservation-mode\": \"all\"\n"
|
||||
"}";
|
||||
expected = "{"
|
||||
" \"foobar\": 1234,"
|
||||
" \"reservations-global\": false,"
|
||||
" \"reservations-in-subnet\": true,"
|
||||
" \"reservations-out-of-pool\": false"
|
||||
" }";
|
||||
TestMove(config, expected);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user