2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-28 12:37:55 +00:00

[5288] Added option-data in DHCPv4 pools

This commit is contained in:
Francis Dupont 2017-07-03 23:09:12 +02:00
parent f5e88bca80
commit 556f6591be
8 changed files with 675 additions and 213 deletions

View File

@ -32,9 +32,11 @@
// clients connected to this subnet. The first two options are
// identified by the name. The third option is identified by the
// option code.
// There is an address pool defined within this subnet. Pool
// specific value for option domain-name-servers is defined
// for the pool.
"subnet4": [
{
"pools": [ { "pool": "192.0.2.10 - 192.0.2.200" } ],
"subnet": "192.0.2.0/24",
"interface": "ethX",
"option-data": [
@ -124,9 +126,17 @@
"name": "default-ip-ttl",
"data": "0xf0"
}
]
}
]
],
"pools": [ {
"pool": "192.0.2.10 - 192.0.2.200",
"option-data": [
{
"name": "domain-name-servers",
"data": "192.0.2.3, 192.0.2.4"
}
]
} ]
} ]
},
// The following configures logging. It assumes that messages with at

View File

@ -1057,6 +1057,57 @@ temporarily override a list of interface names and listen on all interfaces.
</screen>
</para>
<para>
In some cases it is useful to associate some options with an
address pool from which a client is assigned a lease. Pool
specific option values override subnet specific and global
option values. If the client is assigned multiple leases from
different pools, the server will assign options from all pools
from which the leases have been obtained. However, if the
particular option is specified in multiple pools from which
the client obtains the leases, only one instance of this
option will be handed out to the client. The server's
administrator must not try to prioritize assignment of pool
specific options by trying to order pools declarations in the
server configuration. Future Kea releases may change the order
in which options are assigned from the pools without any
notice.
</para>
<para>
The following configuration snippet demonstrates how to specify the
DNS servers option, which will be assigned to a client only if the
client obtains an address from the given pool:
<screen>
"Dhcp4": {
"subnet4": [
{
"pools": [
{
"pool": "192.0.2.1 - 192.0.2.200",
<userinput>"option-data": [
{
"name": "domain-name-servers",
"code": 6,
"space": "dhcp4",
"csv-format": true,
"data": "192.0.2.3"
},
...
]</userinput>,
...
},
...
],
...
},
...
],
...
}
</screen>
</para>
<para>
The currently supported standard DHCPv4 options are
listed in <xref linkend="dhcp4-std-options-list"/>.

View File

@ -2739,6 +2739,157 @@ TEST_F(Dhcp4ParserTest, optionDataInMultipleSubnets) {
testOption(*range2.first, 23, foo2_expected, sizeof(foo2_expected));
}
// This test verifies that it is possible to specify options on
// pool levels.
TEST_F(Dhcp4ParserTest, optionDataSinglePool) {
ConstElementPtr x;
string config = "{ " + genIfaceConfig() + ","
"\"rebind-timer\": 2000, "
"\"renew-timer\": 1000, "
"\"subnet4\": [ { "
" \"pools\": [ { "
" \"pool\": \"192.0.2.1 - 192.0.2.100\","
" \"option-data\": [ {"
" \"name\": \"dhcp-message\","
" \"data\": \"ABCDEF0105\","
" \"csv-format\": false"
" },"
" {"
" \"name\": \"default-ip-ttl\","
" \"data\": \"01\","
" \"csv-format\": false"
" } ]"
" } ],"
" \"subnet\": \"192.0.2.0/24\""
" } ],"
"\"valid-lifetime\": 4000 }";
ConstElementPtr json;
ASSERT_NO_THROW(json = parseDHCP4(config));
extractConfig(config);
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
checkResult(x, 0);
Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->
selectSubnet(IOAddress("192.0.2.24"), classify_);
ASSERT_TRUE(subnet);
PoolPtr pool = subnet->getPool(Lease::TYPE_V4, IOAddress("192.0.2.24"), false);
ASSERT_TRUE(pool);
Pool4Ptr pool4 = boost::dynamic_pointer_cast<Pool4>(pool);
ASSERT_TRUE(pool4);
OptionContainerPtr options = pool4->getCfgOption()->getAll("dhcp4");
ASSERT_EQ(2, options->size());
// Get the search index. Index #1 is to search using option code.
const OptionContainerTypeIndex& idx = options->get<1>();
// Get the options for specified index. Expecting one option to be
// returned but in theory we may have multiple options with the same
// code so we get the range.
std::pair<OptionContainerTypeIndex::const_iterator,
OptionContainerTypeIndex::const_iterator> range =
idx.equal_range(56);
// Expect a single option with the code equal to 100.
ASSERT_EQ(1, std::distance(range.first, range.second));
const uint8_t foo_expected[] = {
0xAB, 0xCD, 0xEF, 0x01, 0x05
};
// Check if option is valid in terms of code and carried data.
testOption(*range.first, 56, foo_expected, sizeof(foo_expected));
range = idx.equal_range(23);
ASSERT_EQ(1, std::distance(range.first, range.second));
// Do another round of testing with second option.
const uint8_t foo2_expected[] = {
0x01
};
testOption(*range.first, 23, foo2_expected, sizeof(foo2_expected));
}
TEST_F(Dhcp4ParserTest, optionDataMultiplePools) {
ConstElementPtr x;
string config = "{ " + genIfaceConfig() + ","
"\"rebind-timer\": 2000, "
"\"renew-timer\": 1000, "
"\"subnet4\": [ { "
" \"pools\": [ { "
" \"pool\": \"192.0.2.1 - 192.0.2.100\","
" \"option-data\": [ {"
" \"name\": \"dhcp-message\","
" \"data\": \"ABCDEF0105\","
" \"csv-format\": false"
" } ]"
" },"
" {"
" \"pool\": \"192.0.2.200 - 192.0.2.250\","
" \"option-data\": [ {"
" \"name\": \"default-ip-ttl\","
" \"data\": \"01\","
" \"csv-format\": false"
" } ]"
" } ],"
" \"subnet\": \"192.0.2.0/24\""
" } ],"
"\"valid-lifetime\": 4000 }";
ConstElementPtr json;
ASSERT_NO_THROW(json = parseDHCP4(config));
extractConfig(config);
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
checkResult(x, 0);
Subnet4Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->
selectSubnet(IOAddress("192.0.2.24"), classify_);
ASSERT_TRUE(subnet);
PoolPtr pool1 = subnet->getPool(Lease::TYPE_V4, IOAddress("192.0.2.24"), false);
ASSERT_TRUE(pool1);
Pool4Ptr pool41 = boost::dynamic_pointer_cast<Pool4>(pool1);
ASSERT_TRUE(pool41);
OptionContainerPtr options1 = pool41->getCfgOption()->getAll("dhcp4");
ASSERT_EQ(1, options1->size());
// Get the search index. Index #1 is to search using option code.
const OptionContainerTypeIndex& idx1 = options1->get<1>();
// Get the options for specified index. Expecting one option to be
// returned but in theory we may have multiple options with the same
// code so we get the range.
std::pair<OptionContainerTypeIndex::const_iterator,
OptionContainerTypeIndex::const_iterator> range1 =
idx1.equal_range(56);
// Expect a single option with the code equal to 100.
ASSERT_EQ(1, std::distance(range1.first, range1.second));
const uint8_t foo_expected[] = {
0xAB, 0xCD, 0xEF, 0x01, 0x05
};
// Check if option is valid in terms of code and carried data.
testOption(*range1.first, 56, foo_expected, sizeof(foo_expected));
// Test another pool in the same way.
PoolPtr pool2 = subnet->getPool(Lease::TYPE_V4, IOAddress("192.0.2.240"), false);
ASSERT_TRUE(pool2);
Pool4Ptr pool42 = boost::dynamic_pointer_cast<Pool4>(pool2);
ASSERT_TRUE(pool42);
OptionContainerPtr options2 = pool42->getCfgOption()->getAll("dhcp4");
ASSERT_EQ(1, options2->size());
const OptionContainerTypeIndex& idx2 = options2->get<1>();
std::pair<OptionContainerTypeIndex::const_iterator,
OptionContainerTypeIndex::const_iterator> range2 =
idx2.equal_range(23);
ASSERT_EQ(1, std::distance(range2.first, range2.second));
const uint8_t foo2_expected[] = {
0x01
};
testOption(*range2.first, 23, foo2_expected, sizeof(foo2_expected));
}
// Verify that empty option name is rejected in the configuration.

View File

@ -816,6 +816,73 @@ const char* EXTRACTED_CONFIGS[] = {
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
" },\n"
" \"rebind-timer\": 2000,\n"
" \"renew-timer\": 1000,\n"
" \"subnet4\": [\n"
" {\n"
" \"pools\": [\n"
" {\n"
" \"option-data\": [\n"
" {\n"
" \"csv-format\": false,\n"
" \"data\": \"ABCDEF0105\",\n"
" \"name\": \"dhcp-message\"\n"
" },\n"
" {\n"
" \"csv-format\": false,\n"
" \"data\": \"01\",\n"
" \"name\": \"default-ip-ttl\"\n"
" }\n"
" ],\n"
" \"pool\": \"192.0.2.1 - 192.0.2.100\"\n"
" }\n"
" ],\n"
" \"subnet\": \"192.0.2.0/24\"\n"
" }\n"
" ],\n"
" \"valid-lifetime\": 4000\n"
" }\n",
// CONFIGURATION 31
"{\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
" },\n"
" \"rebind-timer\": 2000,\n"
" \"renew-timer\": 1000,\n"
" \"subnet4\": [\n"
" {\n"
" \"pools\": [\n"
" {\n"
" \"option-data\": [\n"
" {\n"
" \"csv-format\": false,\n"
" \"data\": \"ABCDEF0105\",\n"
" \"name\": \"dhcp-message\"\n"
" }\n"
" ],\n"
" \"pool\": \"192.0.2.1 - 192.0.2.100\"\n"
" },\n"
" {\n"
" \"option-data\": [\n"
" {\n"
" \"csv-format\": false,\n"
" \"data\": \"01\",\n"
" \"name\": \"default-ip-ttl\"\n"
" }\n"
" ],\n"
" \"pool\": \"192.0.2.200 - 192.0.2.250\"\n"
" }\n"
" ],\n"
" \"subnet\": \"192.0.2.0/24\"\n"
" }\n"
" ],\n"
" \"valid-lifetime\": 4000\n"
" }\n",
// CONFIGURATION 32
"{\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
" },\n"
" \"option-data\": [\n"
" {\n"
" \"data\": \"1234\",\n"
@ -846,7 +913,7 @@ const char* EXTRACTED_CONFIGS[] = {
" \"renew-timer\": 1000,\n"
" \"valid-lifetime\": 4000\n"
" }\n",
// CONFIGURATION 31
// CONFIGURATION 33
"{\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
@ -897,7 +964,7 @@ const char* EXTRACTED_CONFIGS[] = {
" ],\n"
" \"valid-lifetime\": 3000\n"
" }\n",
// CONFIGURATION 32
// CONFIGURATION 34
"{\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
@ -932,7 +999,7 @@ const char* EXTRACTED_CONFIGS[] = {
" ],\n"
" \"valid-lifetime\": 4000\n"
" }\n",
// CONFIGURATION 33
// CONFIGURATION 35
"{\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
@ -967,7 +1034,7 @@ const char* EXTRACTED_CONFIGS[] = {
" ],\n"
" \"valid-lifetime\": 4000\n"
" }\n",
// CONFIGURATION 34
// CONFIGURATION 36
"{\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"eth0\", \"eth1\" ]\n"
@ -976,7 +1043,7 @@ const char* EXTRACTED_CONFIGS[] = {
" \"renew-timer\": 1000,\n"
" \"valid-lifetime\": 4000\n"
" }\n",
// CONFIGURATION 35
// CONFIGURATION 37
"{\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"eth0\", \"*\", \"eth1\" ]\n"
@ -985,7 +1052,7 @@ const char* EXTRACTED_CONFIGS[] = {
" \"renew-timer\": 1000,\n"
" \"valid-lifetime\": 4000\n"
" }\n",
// CONFIGURATION 36
// CONFIGURATION 38
"{\n"
" \"dhcp-ddns\": {\n"
" \"always-include-fqdn\": true,\n"
@ -1020,7 +1087,7 @@ const char* EXTRACTED_CONFIGS[] = {
" ],\n"
" \"valid-lifetime\": 4000\n"
" }\n",
// CONFIGURATION 37
// CONFIGURATION 39
"{\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
@ -1045,7 +1112,7 @@ const char* EXTRACTED_CONFIGS[] = {
" ],\n"
" \"valid-lifetime\": 4000\n"
" }\n",
// CONFIGURATION 38
// CONFIGURATION 40
"{\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
@ -1143,7 +1210,7 @@ const char* EXTRACTED_CONFIGS[] = {
" ],\n"
" \"valid-lifetime\": 4000\n"
" }\n",
// CONFIGURATION 39
// CONFIGURATION 41
"{\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
@ -1184,7 +1251,7 @@ const char* EXTRACTED_CONFIGS[] = {
" ],\n"
" \"valid-lifetime\": 4000\n"
" }\n",
// CONFIGURATION 40
// CONFIGURATION 42
"{\n"
" \"rebind-timer\": 2000,\n"
" \"renew-timer\": 1000,\n"
@ -1226,30 +1293,30 @@ const char* EXTRACTED_CONFIGS[] = {
" }\n"
" ],\n"
" \"valid-lifetime\": 4000\n"
" }\n",
// CONFIGURATION 41
"{\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
" },\n"
" \"subnet4\": [ ]\n"
" }\n",
// CONFIGURATION 42
"{\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
" },\n"
" \"subnet4\": [ ]\n"
" }\n",
// CONFIGURATION 43
"{\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
" },\n"
" \"subnet4\": [ ]\n"
" }\n",
// CONFIGURATION 44
"{\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
" },\n"
" \"subnet4\": [ ]\n"
" }\n",
// CONFIGURATION 45
"{\n"
" \"decline-probation-period\": 12345,\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
" },\n"
" \"subnet4\": [ ]\n"
" }\n",
// CONFIGURATION 44
// CONFIGURATION 46
"{\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 35,\n"
@ -1264,7 +1331,7 @@ const char* EXTRACTED_CONFIGS[] = {
" },\n"
" \"subnet4\": [ ]\n"
" }\n",
// CONFIGURATION 45
// CONFIGURATION 47
"{\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
@ -1283,7 +1350,7 @@ const char* EXTRACTED_CONFIGS[] = {
" ],\n"
" \"valid-lifetime\": 4000\n"
" }\n",
// CONFIGURATION 46
// CONFIGURATION 48
"{\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
@ -1303,7 +1370,7 @@ const char* EXTRACTED_CONFIGS[] = {
" ],\n"
" \"valid-lifetime\": 4000\n"
" }\n",
// CONFIGURATION 47
// CONFIGURATION 49
"{\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
@ -1323,7 +1390,7 @@ const char* EXTRACTED_CONFIGS[] = {
" ],\n"
" \"valid-lifetime\": 4000\n"
" }\n",
// CONFIGURATION 48
// CONFIGURATION 50
"{\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
@ -1344,7 +1411,7 @@ const char* EXTRACTED_CONFIGS[] = {
" ],\n"
" \"valid-lifetime\": 4000\n"
" }\n",
// CONFIGURATION 49
// CONFIGURATION 51
"{\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
@ -1364,7 +1431,7 @@ const char* EXTRACTED_CONFIGS[] = {
" ],\n"
" \"valid-lifetime\": 4000\n"
" }\n",
// CONFIGURATION 50
// CONFIGURATION 52
"{\n"
" \"client-classes\": [\n"
" {\n"
@ -1394,7 +1461,7 @@ const char* EXTRACTED_CONFIGS[] = {
" ],\n"
" \"valid-lifetime\": 4000\n"
" }\n",
// CONFIGURATION 51
// CONFIGURATION 53
"{\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
@ -1413,7 +1480,7 @@ const char* EXTRACTED_CONFIGS[] = {
" ],\n"
" \"valid-lifetime\": 4000\n"
" }\n",
// CONFIGURATION 52
// CONFIGURATION 54
"{\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
@ -1433,7 +1500,7 @@ const char* EXTRACTED_CONFIGS[] = {
" ],\n"
" \"valid-lifetime\": 4000\n"
" }\n",
// CONFIGURATION 53
// CONFIGURATION 55
"{\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
@ -1457,7 +1524,7 @@ const char* EXTRACTED_CONFIGS[] = {
" ],\n"
" \"valid-lifetime\": 4000\n"
" }\n",
// CONFIGURATION 54
// CONFIGURATION 56
"{\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
@ -3780,6 +3847,141 @@ const char* UNPARSED_CONFIGS[] = {
" \"lease-database\": {\n"
" \"type\": \"memfile\"\n"
" },\n"
" \"option-data\": [ ],\n"
" \"option-def\": [ ],\n"
" \"subnet4\": [\n"
" {\n"
" \"4o6-interface\": \"\",\n"
" \"4o6-interface-id\": \"\",\n"
" \"4o6-subnet\": \"\",\n"
" \"id\": 1,\n"
" \"interface\": \"\",\n"
" \"match-client-id\": true,\n"
" \"next-server\": \"0.0.0.0\",\n"
" \"option-data\": [ ],\n"
" \"pools\": [\n"
" {\n"
" \"pool\": \"192.0.2.1-192.0.2.100\"\n"
" }\n"
" ],\n"
" \"rebind-timer\": 2000,\n"
" \"relay\": {\n"
" \"ip-address\": \"0.0.0.0\"\n"
" },\n"
" \"renew-timer\": 1000,\n"
" \"reservation-mode\": \"all\",\n"
" \"reservations\": [ ],\n"
" \"subnet\": \"192.0.2.0/24\",\n"
" \"valid-lifetime\": 4000\n"
" }\n"
" ]\n"
" }\n",
// CONFIGURATION 31
"{\n"
" \"decline-probation-period\": 86400,\n"
" \"dhcp-ddns\": {\n"
" \"always-include-fqdn\": false,\n"
" \"enable-updates\": false,\n"
" \"generated-prefix\": \"myhost\",\n"
" \"max-queue-size\": 1024,\n"
" \"ncr-format\": \"JSON\",\n"
" \"ncr-protocol\": \"UDP\",\n"
" \"override-client-update\": false,\n"
" \"override-no-update\": false,\n"
" \"qualifying-suffix\": \"\",\n"
" \"replace-client-name\": \"never\",\n"
" \"sender-ip\": \"0.0.0.0\",\n"
" \"sender-port\": 0,\n"
" \"server-ip\": \"127.0.0.1\",\n"
" \"server-port\": 53001\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
" \"max-reclaim-leases\": 100,\n"
" \"max-reclaim-time\": 250,\n"
" \"reclaim-timer-wait-time\": 10,\n"
" \"unwarned-reclaim-cycles\": 5\n"
" },\n"
" \"hooks-libraries\": [ ],\n"
" \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
" },\n"
" \"lease-database\": {\n"
" \"type\": \"memfile\"\n"
" },\n"
" \"option-data\": [ ],\n"
" \"option-def\": [ ],\n"
" \"subnet4\": [\n"
" {\n"
" \"4o6-interface\": \"\",\n"
" \"4o6-interface-id\": \"\",\n"
" \"4o6-subnet\": \"\",\n"
" \"id\": 1,\n"
" \"interface\": \"\",\n"
" \"match-client-id\": true,\n"
" \"next-server\": \"0.0.0.0\",\n"
" \"option-data\": [ ],\n"
" \"pools\": [\n"
" {\n"
" \"pool\": \"192.0.2.1-192.0.2.100\"\n"
" },\n"
" {\n"
" \"pool\": \"192.0.2.200-192.0.2.250\"\n"
" }\n"
" ],\n"
" \"rebind-timer\": 2000,\n"
" \"relay\": {\n"
" \"ip-address\": \"0.0.0.0\"\n"
" },\n"
" \"renew-timer\": 1000,\n"
" \"reservation-mode\": \"all\",\n"
" \"reservations\": [ ],\n"
" \"subnet\": \"192.0.2.0/24\",\n"
" \"valid-lifetime\": 4000\n"
" }\n"
" ]\n"
" }\n",
// CONFIGURATION 32
"{\n"
" \"decline-probation-period\": 86400,\n"
" \"dhcp-ddns\": {\n"
" \"always-include-fqdn\": false,\n"
" \"enable-updates\": false,\n"
" \"generated-prefix\": \"myhost\",\n"
" \"max-queue-size\": 1024,\n"
" \"ncr-format\": \"JSON\",\n"
" \"ncr-protocol\": \"UDP\",\n"
" \"override-client-update\": false,\n"
" \"override-no-update\": false,\n"
" \"qualifying-suffix\": \"\",\n"
" \"replace-client-name\": \"never\",\n"
" \"sender-ip\": \"0.0.0.0\",\n"
" \"sender-port\": 0,\n"
" \"server-ip\": \"127.0.0.1\",\n"
" \"server-port\": 53001\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
" \"max-reclaim-leases\": 100,\n"
" \"max-reclaim-time\": 250,\n"
" \"reclaim-timer-wait-time\": 10,\n"
" \"unwarned-reclaim-cycles\": 5\n"
" },\n"
" \"hooks-libraries\": [ ],\n"
" \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
" },\n"
" \"lease-database\": {\n"
" \"type\": \"memfile\"\n"
" },\n"
" \"option-data\": [\n"
" {\n"
" \"code\": 1,\n"
@ -3818,7 +4020,7 @@ const char* UNPARSED_CONFIGS[] = {
" ],\n"
" \"subnet4\": [ ]\n"
" }\n",
// CONFIGURATION 31
// CONFIGURATION 33
"{\n"
" \"decline-probation-period\": 86400,\n"
" \"dhcp-ddns\": {\n"
@ -3925,7 +4127,7 @@ const char* UNPARSED_CONFIGS[] = {
" }\n"
" ]\n"
" }\n",
// CONFIGURATION 32
// CONFIGURATION 34
"{\n"
" \"decline-probation-period\": 86400,\n"
" \"dhcp-ddns\": {\n"
@ -4004,7 +4206,7 @@ const char* UNPARSED_CONFIGS[] = {
" }\n"
" ]\n"
" }\n",
// CONFIGURATION 33
// CONFIGURATION 35
"{\n"
" \"decline-probation-period\": 86400,\n"
" \"dhcp-ddns\": {\n"
@ -4088,7 +4290,7 @@ const char* UNPARSED_CONFIGS[] = {
" }\n"
" ]\n"
" }\n",
// CONFIGURATION 34
// CONFIGURATION 36
"{\n"
" \"decline-probation-period\": 86400,\n"
" \"dhcp-ddns\": {\n"
@ -4129,7 +4331,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"option-def\": [ ],\n"
" \"subnet4\": [ ]\n"
" }\n",
// CONFIGURATION 35
// CONFIGURATION 37
"{\n"
" \"decline-probation-period\": 86400,\n"
" \"dhcp-ddns\": {\n"
@ -4170,7 +4372,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"option-def\": [ ],\n"
" \"subnet4\": [ ]\n"
" }\n",
// CONFIGURATION 36
// CONFIGURATION 38
"{\n"
" \"decline-probation-period\": 86400,\n"
" \"dhcp-ddns\": {\n"
@ -4236,7 +4438,7 @@ const char* UNPARSED_CONFIGS[] = {
" }\n"
" ]\n"
" }\n",
// CONFIGURATION 37
// CONFIGURATION 39
"{\n"
" \"decline-probation-period\": 86400,\n"
" \"dhcp-ddns\": {\n"
@ -4302,7 +4504,7 @@ const char* UNPARSED_CONFIGS[] = {
" }\n"
" ]\n"
" }\n",
// CONFIGURATION 38
// CONFIGURATION 40
"{\n"
" \"decline-probation-period\": 86400,\n"
" \"dhcp-ddns\": {\n"
@ -4513,7 +4715,7 @@ const char* UNPARSED_CONFIGS[] = {
" }\n"
" ]\n"
" }\n",
// CONFIGURATION 39
// CONFIGURATION 41
"{\n"
" \"decline-probation-period\": 86400,\n"
" \"dhcp-ddns\": {\n"
@ -4608,7 +4810,7 @@ const char* UNPARSED_CONFIGS[] = {
" }\n"
" ]\n"
" }\n",
// CONFIGURATION 40
// CONFIGURATION 42
"{\n"
" \"decline-probation-period\": 86400,\n"
" \"dhcp-ddns\": {\n"
@ -4745,92 +4947,10 @@ const char* UNPARSED_CONFIGS[] = {
" \"valid-lifetime\": 4000\n"
" }\n"
" ]\n"
" }\n",
// CONFIGURATION 41
"{\n"
" \"decline-probation-period\": 86400,\n"
" \"dhcp-ddns\": {\n"
" \"always-include-fqdn\": false,\n"
" \"enable-updates\": false,\n"
" \"generated-prefix\": \"myhost\",\n"
" \"max-queue-size\": 1024,\n"
" \"ncr-format\": \"JSON\",\n"
" \"ncr-protocol\": \"UDP\",\n"
" \"override-client-update\": false,\n"
" \"override-no-update\": false,\n"
" \"qualifying-suffix\": \"\",\n"
" \"replace-client-name\": \"never\",\n"
" \"sender-ip\": \"0.0.0.0\",\n"
" \"sender-port\": 0,\n"
" \"server-ip\": \"127.0.0.1\",\n"
" \"server-port\": 53001\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
" \"max-reclaim-leases\": 100,\n"
" \"max-reclaim-time\": 250,\n"
" \"reclaim-timer-wait-time\": 10,\n"
" \"unwarned-reclaim-cycles\": 5\n"
" },\n"
" \"hooks-libraries\": [ ],\n"
" \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
" },\n"
" \"lease-database\": {\n"
" \"type\": \"memfile\"\n"
" },\n"
" \"option-data\": [ ],\n"
" \"option-def\": [ ],\n"
" \"subnet4\": [ ]\n"
" }\n",
// CONFIGURATION 42
"{\n"
" \"decline-probation-period\": 86400,\n"
" \"dhcp-ddns\": {\n"
" \"always-include-fqdn\": false,\n"
" \"enable-updates\": false,\n"
" \"generated-prefix\": \"myhost\",\n"
" \"max-queue-size\": 1024,\n"
" \"ncr-format\": \"JSON\",\n"
" \"ncr-protocol\": \"UDP\",\n"
" \"override-client-update\": false,\n"
" \"override-no-update\": false,\n"
" \"qualifying-suffix\": \"\",\n"
" \"replace-client-name\": \"never\",\n"
" \"sender-ip\": \"0.0.0.0\",\n"
" \"sender-port\": 0,\n"
" \"server-ip\": \"127.0.0.1\",\n"
" \"server-port\": 53001\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
" \"max-reclaim-leases\": 100,\n"
" \"max-reclaim-time\": 250,\n"
" \"reclaim-timer-wait-time\": 10,\n"
" \"unwarned-reclaim-cycles\": 5\n"
" },\n"
" \"hooks-libraries\": [ ],\n"
" \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
" },\n"
" \"lease-database\": {\n"
" \"type\": \"memfile\"\n"
" },\n"
" \"option-data\": [ ],\n"
" \"option-def\": [ ],\n"
" \"subnet4\": [ ]\n"
" }\n",
// CONFIGURATION 43
"{\n"
" \"decline-probation-period\": 12345,\n"
" \"decline-probation-period\": 86400,\n"
" \"dhcp-ddns\": {\n"
" \"always-include-fqdn\": false,\n"
" \"enable-updates\": false,\n"
@ -4891,12 +5011,12 @@ const char* UNPARSED_CONFIGS[] = {
" \"dhcp4o6-port\": 0,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 35,\n"
" \"hold-reclaimed-time\": 1800,\n"
" \"max-reclaim-leases\": 50,\n"
" \"max-reclaim-time\": 100,\n"
" \"reclaim-timer-wait-time\": 20,\n"
" \"unwarned-reclaim-cycles\": 10\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
" \"max-reclaim-leases\": 100,\n"
" \"max-reclaim-time\": 250,\n"
" \"reclaim-timer-wait-time\": 10,\n"
" \"unwarned-reclaim-cycles\": 5\n"
" },\n"
" \"hooks-libraries\": [ ],\n"
" \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
@ -4912,7 +5032,7 @@ const char* UNPARSED_CONFIGS[] = {
" }\n",
// CONFIGURATION 45
"{\n"
" \"decline-probation-period\": 86400,\n"
" \"decline-probation-period\": 12345,\n"
" \"dhcp-ddns\": {\n"
" \"always-include-fqdn\": false,\n"
" \"enable-updates\": false,\n"
@ -4949,32 +5069,7 @@ const char* UNPARSED_CONFIGS[] = {
" },\n"
" \"option-data\": [ ],\n"
" \"option-def\": [ ],\n"
" \"subnet4\": [\n"
" {\n"
" \"4o6-interface\": \"\",\n"
" \"4o6-interface-id\": \"\",\n"
" \"4o6-subnet\": \"\",\n"
" \"id\": 1,\n"
" \"interface\": \"\",\n"
" \"match-client-id\": true,\n"
" \"next-server\": \"0.0.0.0\",\n"
" \"option-data\": [ ],\n"
" \"pools\": [\n"
" {\n"
" \"pool\": \"192.0.2.1-192.0.2.100\"\n"
" }\n"
" ],\n"
" \"rebind-timer\": 2000,\n"
" \"relay\": {\n"
" \"ip-address\": \"0.0.0.0\"\n"
" },\n"
" \"renew-timer\": 1000,\n"
" \"reservation-mode\": \"all\",\n"
" \"reservations\": [ ],\n"
" \"subnet\": \"192.0.2.0/24\",\n"
" \"valid-lifetime\": 4000\n"
" }\n"
" ]\n"
" \"subnet4\": [ ]\n"
" }\n",
// CONFIGURATION 46
"{\n"
@ -4998,12 +5093,12 @@ const char* UNPARSED_CONFIGS[] = {
" \"dhcp4o6-port\": 0,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
" \"max-reclaim-leases\": 100,\n"
" \"max-reclaim-time\": 250,\n"
" \"reclaim-timer-wait-time\": 10,\n"
" \"unwarned-reclaim-cycles\": 5\n"
" \"flush-reclaimed-timer-wait-time\": 35,\n"
" \"hold-reclaimed-time\": 1800,\n"
" \"max-reclaim-leases\": 50,\n"
" \"max-reclaim-time\": 100,\n"
" \"reclaim-timer-wait-time\": 20,\n"
" \"unwarned-reclaim-cycles\": 10\n"
" },\n"
" \"hooks-libraries\": [ ],\n"
" \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
@ -5015,32 +5110,7 @@ const char* UNPARSED_CONFIGS[] = {
" },\n"
" \"option-data\": [ ],\n"
" \"option-def\": [ ],\n"
" \"subnet4\": [\n"
" {\n"
" \"4o6-interface\": \"\",\n"
" \"4o6-interface-id\": \"\",\n"
" \"4o6-subnet\": \"2001:db8::123/45\",\n"
" \"id\": 1,\n"
" \"interface\": \"\",\n"
" \"match-client-id\": true,\n"
" \"next-server\": \"0.0.0.0\",\n"
" \"option-data\": [ ],\n"
" \"pools\": [\n"
" {\n"
" \"pool\": \"192.0.2.1-192.0.2.100\"\n"
" }\n"
" ],\n"
" \"rebind-timer\": 2000,\n"
" \"relay\": {\n"
" \"ip-address\": \"0.0.0.0\"\n"
" },\n"
" \"renew-timer\": 1000,\n"
" \"reservation-mode\": \"all\",\n"
" \"reservations\": [ ],\n"
" \"subnet\": \"192.0.2.0/24\",\n"
" \"valid-lifetime\": 4000\n"
" }\n"
" ]\n"
" \"subnet4\": [ ]\n"
" }\n",
// CONFIGURATION 47
"{\n"
@ -5083,7 +5153,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"option-def\": [ ],\n"
" \"subnet4\": [\n"
" {\n"
" \"4o6-interface\": \"ethX\",\n"
" \"4o6-interface\": \"\",\n"
" \"4o6-interface-id\": \"\",\n"
" \"4o6-subnet\": \"\",\n"
" \"id\": 1,\n"
@ -5149,6 +5219,138 @@ const char* UNPARSED_CONFIGS[] = {
" \"option-def\": [ ],\n"
" \"subnet4\": [\n"
" {\n"
" \"4o6-interface\": \"\",\n"
" \"4o6-interface-id\": \"\",\n"
" \"4o6-subnet\": \"2001:db8::123/45\",\n"
" \"id\": 1,\n"
" \"interface\": \"\",\n"
" \"match-client-id\": true,\n"
" \"next-server\": \"0.0.0.0\",\n"
" \"option-data\": [ ],\n"
" \"pools\": [\n"
" {\n"
" \"pool\": \"192.0.2.1-192.0.2.100\"\n"
" }\n"
" ],\n"
" \"rebind-timer\": 2000,\n"
" \"relay\": {\n"
" \"ip-address\": \"0.0.0.0\"\n"
" },\n"
" \"renew-timer\": 1000,\n"
" \"reservation-mode\": \"all\",\n"
" \"reservations\": [ ],\n"
" \"subnet\": \"192.0.2.0/24\",\n"
" \"valid-lifetime\": 4000\n"
" }\n"
" ]\n"
" }\n",
// CONFIGURATION 49
"{\n"
" \"decline-probation-period\": 86400,\n"
" \"dhcp-ddns\": {\n"
" \"always-include-fqdn\": false,\n"
" \"enable-updates\": false,\n"
" \"generated-prefix\": \"myhost\",\n"
" \"max-queue-size\": 1024,\n"
" \"ncr-format\": \"JSON\",\n"
" \"ncr-protocol\": \"UDP\",\n"
" \"override-client-update\": false,\n"
" \"override-no-update\": false,\n"
" \"qualifying-suffix\": \"\",\n"
" \"replace-client-name\": \"never\",\n"
" \"sender-ip\": \"0.0.0.0\",\n"
" \"sender-port\": 0,\n"
" \"server-ip\": \"127.0.0.1\",\n"
" \"server-port\": 53001\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
" \"max-reclaim-leases\": 100,\n"
" \"max-reclaim-time\": 250,\n"
" \"reclaim-timer-wait-time\": 10,\n"
" \"unwarned-reclaim-cycles\": 5\n"
" },\n"
" \"hooks-libraries\": [ ],\n"
" \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
" },\n"
" \"lease-database\": {\n"
" \"type\": \"memfile\"\n"
" },\n"
" \"option-data\": [ ],\n"
" \"option-def\": [ ],\n"
" \"subnet4\": [\n"
" {\n"
" \"4o6-interface\": \"ethX\",\n"
" \"4o6-interface-id\": \"\",\n"
" \"4o6-subnet\": \"\",\n"
" \"id\": 1,\n"
" \"interface\": \"\",\n"
" \"match-client-id\": true,\n"
" \"next-server\": \"0.0.0.0\",\n"
" \"option-data\": [ ],\n"
" \"pools\": [\n"
" {\n"
" \"pool\": \"192.0.2.1-192.0.2.100\"\n"
" }\n"
" ],\n"
" \"rebind-timer\": 2000,\n"
" \"relay\": {\n"
" \"ip-address\": \"0.0.0.0\"\n"
" },\n"
" \"renew-timer\": 1000,\n"
" \"reservation-mode\": \"all\",\n"
" \"reservations\": [ ],\n"
" \"subnet\": \"192.0.2.0/24\",\n"
" \"valid-lifetime\": 4000\n"
" }\n"
" ]\n"
" }\n",
// CONFIGURATION 50
"{\n"
" \"decline-probation-period\": 86400,\n"
" \"dhcp-ddns\": {\n"
" \"always-include-fqdn\": false,\n"
" \"enable-updates\": false,\n"
" \"generated-prefix\": \"myhost\",\n"
" \"max-queue-size\": 1024,\n"
" \"ncr-format\": \"JSON\",\n"
" \"ncr-protocol\": \"UDP\",\n"
" \"override-client-update\": false,\n"
" \"override-no-update\": false,\n"
" \"qualifying-suffix\": \"\",\n"
" \"replace-client-name\": \"never\",\n"
" \"sender-ip\": \"0.0.0.0\",\n"
" \"sender-port\": 0,\n"
" \"server-ip\": \"127.0.0.1\",\n"
" \"server-port\": 53001\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
" \"max-reclaim-leases\": 100,\n"
" \"max-reclaim-time\": 250,\n"
" \"reclaim-timer-wait-time\": 10,\n"
" \"unwarned-reclaim-cycles\": 5\n"
" },\n"
" \"hooks-libraries\": [ ],\n"
" \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n"
" \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
" },\n"
" \"lease-database\": {\n"
" \"type\": \"memfile\"\n"
" },\n"
" \"option-data\": [ ],\n"
" \"option-def\": [ ],\n"
" \"subnet4\": [\n"
" {\n"
" \"4o6-interface\": \"ethX\",\n"
" \"4o6-interface-id\": \"\",\n"
" \"4o6-subnet\": \"2001:db8::543/21\",\n"
@ -5174,7 +5376,7 @@ const char* UNPARSED_CONFIGS[] = {
" }\n"
" ]\n"
" }\n",
// CONFIGURATION 49
// CONFIGURATION 51
"{\n"
" \"decline-probation-period\": 86400,\n"
" \"dhcp-ddns\": {\n"
@ -5240,7 +5442,7 @@ const char* UNPARSED_CONFIGS[] = {
" }\n"
" ]\n"
" }\n",
// CONFIGURATION 50
// CONFIGURATION 52
"{\n"
" \"client-classes\": [\n"
" {\n"
@ -5329,7 +5531,7 @@ const char* UNPARSED_CONFIGS[] = {
" }\n"
" ]\n"
" }\n",
// CONFIGURATION 51
// CONFIGURATION 53
"{\n"
" \"decline-probation-period\": 86400,\n"
" \"dhcp-ddns\": {\n"
@ -5395,7 +5597,7 @@ const char* UNPARSED_CONFIGS[] = {
" }\n"
" ]\n"
" }\n",
// CONFIGURATION 52
// CONFIGURATION 54
"{\n"
" \"decline-probation-period\": 86400,\n"
" \"dhcp-ddns\": {\n"
@ -5462,7 +5664,7 @@ const char* UNPARSED_CONFIGS[] = {
" }\n"
" ]\n"
" }\n",
// CONFIGURATION 53
// CONFIGURATION 55
"{\n"
" \"decline-probation-period\": 86400,\n"
" \"dhcp-ddns\": {\n"
@ -5533,7 +5735,7 @@ const char* UNPARSED_CONFIGS[] = {
" }\n"
" ]\n"
" }\n",
// CONFIGURATION 54
// CONFIGURATION 56
"{\n"
" \"decline-probation-period\": 86400,\n"
" \"dhcp-ddns\": {\n"

View File

@ -340,6 +340,6 @@ TEST_P(Dhcp4GetConfigTest, run) {
/// Define the parametrized test loop
INSTANTIATE_TEST_CASE_P(Dhcp4GetConfigTest, Dhcp4GetConfigTest,
::testing::Range(0UL, max_config_counter));
::testing::Range(static_cast<size_t>(0), max_config_counter));
};

View File

@ -335,7 +335,9 @@ CfgSubnets4::toElement() const {
if (!isNull(context)) {
pool_map->set("user-context", context);
}
// Set pool options (not yet supported)
// Set pool options
ConstCfgOptionPtr opts = (*pool)->getCfgOption();
pool_map->set("option-data", opts->toElement());
// Push on the pool list
pool_list->add(pool_map);
}

View File

@ -749,12 +749,6 @@ PoolParser::parse(PoolStoragePtr pools,
ConstElementPtr option_data = pool_structure->get("option-data");
if (option_data) {
try {
// Currently we don't support specifying options for the DHCPv4 server.
if (address_family == AF_INET) {
isc_throw(DhcpConfigError, "option-data is not supported for DHCPv4"
" address pools");
}
CfgOptionPtr cfg = pool->getCfgOption();
OptionDataListParser option_parser(address_family);
option_parser.parse(cfg, option_data);

View File

@ -120,6 +120,58 @@ TEST(Pool4Test, toText) {
EXPECT_EQ("type=V4, 192.0.2.128-192.0.2.143", pool2.toText());
}
// This test checks that it is possible to specify pool specific options.
TEST(Pool4Test, addOptions) {
// Create a pool to add options to it.
Pool4Ptr pool(new Pool4(IOAddress("192.0.2.0"),
IOAddress("192.0.2.255")));
// Differentiate options by their codes (100-109)
for (uint16_t code = 100; code < 110; ++code) {
OptionPtr option(new Option(Option::V4, code, OptionBuffer(10, 0xFF)));
ASSERT_NO_THROW(pool->getCfgOption()->add(option, false, "dhcp4"));
}
// Add 7 options to another option space. The option codes partially overlap
// with option codes that we have added to dhcp4 option space.
for (uint16_t code = 105; code < 112; ++code) {
OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
ASSERT_NO_THROW(pool->getCfgOption()->add(option, false, "isc"));
}
// Get options from the pool and check if all 10 are there.
OptionContainerPtr options = pool->getCfgOption()->getAll("dhcp4");
ASSERT_TRUE(options);
ASSERT_EQ(10, options->size());
// Validate codes of options added to dhcp4 option space.
uint16_t expected_code = 100;
for (OptionContainer::const_iterator option_desc = options->begin();
option_desc != options->end(); ++option_desc) {
ASSERT_TRUE(option_desc->option_);
EXPECT_EQ(expected_code, option_desc->option_->getType());
++expected_code;
}
options = pool->getCfgOption()->getAll("isc");
ASSERT_TRUE(options);
ASSERT_EQ(7, options->size());
// Validate codes of options added to isc option space.
expected_code = 105;
for (OptionContainer::const_iterator option_desc = options->begin();
option_desc != options->end(); ++option_desc) {
ASSERT_TRUE(option_desc->option_);
EXPECT_EQ(expected_code, option_desc->option_->getType());
++expected_code;
}
// Try to get options from a non-existing option space.
options = pool->getCfgOption()->getAll("abcd");
ASSERT_TRUE(options);
EXPECT_TRUE(options->empty());
}
TEST(Pool6Test, constructor_first_last) {
// let's construct 2001:db8:1:: - 2001:db8:1::ffff:ffff:ffff:ffff pool
@ -329,7 +381,7 @@ TEST(Pool6Test, unique_id) {
}
// Simple check if toText returns reasonable values
TEST(Pool6Test,toText) {
TEST(Pool6Test, toText) {
Pool6 pool1(Lease::TYPE_NA, IOAddress("2001:db8::1"),
IOAddress("2001:db8::2"));
EXPECT_EQ("type=IA_NA, 2001:db8::1-2001:db8::2, delegated_len=128",