diff --git a/ChangeLog b/ChangeLog index bf16306aab..28f43add5f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2109. [bug] fdupont + Compatibility flags e.g. lenient-option-parsing were not + saved by config-get and similar commands. + (Gitlab #2790) + 2108. [func] fdupont Added a new exclude-first-last-24 DHCPv4 compatibility flag which when set to true (default is false) skips addresses diff --git a/src/bin/dhcp4/json_config_parser.cc b/src/bin/dhcp4/json_config_parser.cc index 9538a081ae..c2244d5da1 100644 --- a/src/bin/dhcp4/json_config_parser.cc +++ b/src/bin/dhcp4/json_config_parser.cc @@ -594,6 +594,12 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set, ConstElementPtr compatibility = mutable_cfg->get("compatibility"); if (compatibility) { for (auto kv : compatibility->mapValue()) { + if (!kv.second || (kv.second->getType() != Element::boolean)) { + isc_throw(DhcpConfigError, + "compatibility parameter values must be " + << "boolean (" << kv.first << " at " + << kv.second->getPosition() << ")"); + } if (kv.first == "lenient-option-parsing") { CfgMgr::instance().getStagingCfg()->setLenientOptionParsing( kv.second->boolValue()); diff --git a/src/bin/dhcp4/tests/config_parser_unittest.cc b/src/bin/dhcp4/tests/config_parser_unittest.cc index d0afeab884..d04c3f7e3f 100644 --- a/src/bin/dhcp4/tests/config_parser_unittest.cc +++ b/src/bin/dhcp4/tests/config_parser_unittest.cc @@ -1680,18 +1680,106 @@ TEST_F(Dhcp4ParserTest, echoClientId) { // Now check that "false" configuration is really applied. ConstElementPtr status; EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json_false)); + checkResult(status, 0); ASSERT_FALSE(CfgMgr::instance().getStagingCfg()->getEchoClientId()); CfgMgr::instance().clear(); // Now check that "true" configuration is really applied. EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json_true)); + checkResult(status, 0); ASSERT_TRUE(CfgMgr::instance().getStagingCfg()->getEchoClientId()); // In any case revert back to the default value (true) CfgMgr::instance().getStagingCfg()->setEchoClientId(true); } +// Check whether it is possible to configure compatibility flags. +TEST_F(Dhcp4ParserTest, compatibility) { + string config = "{ " + genIfaceConfig() + "," + + "\"rebind-timer\": 2000, " + "\"renew-timer\": 1000, " + "\"compatibility\": { " + " \"lenient-option-parsing\": true," + " \"ignore-rai-link-selection\": true," + " \"exclude-first-last-24\": true" + "}," + "\"subnet4\": [ { " + " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ]," + " \"subnet\": \"192.0.2.0/24\" } ]," + "\"valid-lifetime\": 4000 }"; + + ConstElementPtr json; + ASSERT_NO_THROW(json = parseDHCP4(config)) << "bad config: " << config; + extractConfig(config); + + // Check defaults: they should be false. + EXPECT_FALSE(CfgMgr::instance().getStagingCfg()->getLenientOptionParsing()); + EXPECT_FALSE(CfgMgr::instance().getStagingCfg()->getIgnoreRAILinkSelection()); + EXPECT_FALSE(CfgMgr::instance().getStagingCfg()->getExcludeFirstLast24()); + + // Check the configuration was really applied. + ConstElementPtr status; + EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json)); + checkResult(status, 0); + + EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getLenientOptionParsing()); + EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getIgnoreRAILinkSelection()); + EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getExcludeFirstLast24()); +} + +// Check that unknown compatibility flag raises error. +TEST_F(Dhcp4ParserTest, compatibilityUnknown) { + string config = "{ " + genIfaceConfig() + "," + + "\"rebind-timer\": 2000, " + "\"renew-timer\": 1000, " + "\"compatibility\": { " + " \"foo-bar\": true" + "}," + "\"subnet4\": [ { " + " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ]," + " \"subnet\": \"192.0.2.0/24\" } ]," + "\"valid-lifetime\": 4000 }"; + + // Syntax is incorrect. + EXPECT_THROW(parseDHCP4(config), Dhcp4ParseError); + ConstElementPtr json; + EXPECT_NO_THROW(json = parseJSON(config)); + + // Unknown keyword is detected. + ConstElementPtr status; + EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json)); + string expected = "unsupported compatibility parameter: "; + expected += "foo-bar (:1:127)"; + checkResult(status, 1, expected); +} + +// Check that not boolean compatibility flag value raises error. +TEST_F(Dhcp4ParserTest, compatibilityNotBool) { + string config = "{ " + genIfaceConfig() + "," + + "\"rebind-timer\": 2000, " + "\"renew-timer\": 1000, " + "\"compatibility\": { " + " \"lenient-option-parsing\": 1" + "}," + "\"subnet4\": [ { " + " \"pools\": [ { \"pool\": \"192.0.2.1 - 192.0.2.100\" } ]," + " \"subnet\": \"192.0.2.0/24\" } ]," + "\"valid-lifetime\": 4000 }"; + + // Syntax is incorrect. + EXPECT_THROW(parseDHCP4(config), Dhcp4ParseError); + ConstElementPtr json; + EXPECT_NO_THROW(json = parseJSON(config)); + + // Bad value type is detected. + ConstElementPtr status; + EXPECT_NO_THROW(status = Dhcpv4SrvTest::configure(*srv_, json)); + string expected = "compatibility parameter values must be boolean "; + expected += "(lenient-option-parsing at :1:142)"; + checkResult(status, 1, expected); +} + // This test checks that the global match-client-id parameter is optional // and that values under the subnet are used. TEST_F(Dhcp4ParserTest, matchClientIdNoGlobal) { @@ -7626,5 +7714,4 @@ TEST_F(Dhcp4ParserTest, parkedPacketLimit) { ASSERT_THROW(parseDHCP4(bad_limit), std::exception); } - } // namespace diff --git a/src/bin/dhcp4/tests/get_config_unittest.cc b/src/bin/dhcp4/tests/get_config_unittest.cc index 9168c2cdbe..11e722e4dc 100644 --- a/src/bin/dhcp4/tests/get_config_unittest.cc +++ b/src/bin/dhcp4/tests/get_config_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2017-2023 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2017-2022 Internet Systems Consortium, Inc. ("ISC") // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -350,6 +349,31 @@ const char* EXTRACTED_CONFIGS[] = { " }\n", // CONFIGURATION 11 "{\n" +" \"compatibility\": {\n" +" \"exclude-first-last-24\": true,\n" +" \"ignore-rai-link-selection\": true,\n" +" \"lenient-option-parsing\": true\n" +" },\n" +" \"interfaces-config\": {\n" +" \"interfaces\": [ \"*\" ],\n" +" \"re-detect\": false\n" +" },\n" +" \"rebind-timer\": 2000,\n" +" \"renew-timer\": 1000,\n" +" \"subnet4\": [\n" +" {\n" +" \"pools\": [\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 12 +"{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" " \"re-detect\": false\n" @@ -378,7 +402,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 12 + // CONFIGURATION 13 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -408,7 +432,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 13 + // CONFIGURATION 14 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -438,7 +462,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 14 + // CONFIGURATION 15 "{\n" " \"authoritative\": true,\n" " \"interfaces-config\": {\n" @@ -468,7 +492,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 15 + // CONFIGURATION 16 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -495,7 +519,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 16 + // CONFIGURATION 17 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -529,7 +553,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 17 + // CONFIGURATION 18 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -549,7 +573,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 18 + // CONFIGURATION 19 "{\n" " \"option-def\": [\n" " {\n" @@ -560,7 +584,7 @@ const char* EXTRACTED_CONFIGS[] = { " }\n" " ]\n" " }\n", - // CONFIGURATION 19 + // CONFIGURATION 20 "{\n" " \"option-def\": [\n" " {\n" @@ -572,7 +596,7 @@ const char* EXTRACTED_CONFIGS[] = { " }\n" " ]\n" " }\n", - // CONFIGURATION 20 + // CONFIGURATION 21 "{\n" " \"option-def\": [\n" " {\n" @@ -589,7 +613,7 @@ const char* EXTRACTED_CONFIGS[] = { " }\n" " ]\n" " }\n", - // CONFIGURATION 21 + // CONFIGURATION 22 "{\n" " \"option-def\": [\n" " {\n" @@ -601,7 +625,7 @@ const char* EXTRACTED_CONFIGS[] = { " }\n" " ]\n" " }\n", - // CONFIGURATION 22 + // CONFIGURATION 23 "{\n" " \"option-def\": [\n" " {\n" @@ -613,7 +637,7 @@ const char* EXTRACTED_CONFIGS[] = { " }\n" " ]\n" " }\n", - // CONFIGURATION 23 + // CONFIGURATION 24 "{\n" " \"option-def\": [\n" " {\n" @@ -624,7 +648,7 @@ const char* EXTRACTED_CONFIGS[] = { " }\n" " ]\n" " }\n", - // CONFIGURATION 24 + // CONFIGURATION 25 "{\n" " \"option-def\": [\n" " {\n" @@ -635,7 +659,7 @@ const char* EXTRACTED_CONFIGS[] = { " }\n" " ]\n" " }\n", - // CONFIGURATION 25 + // CONFIGURATION 26 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -667,7 +691,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 26 + // CONFIGURATION 27 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -699,7 +723,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 27 + // CONFIGURATION 28 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -739,7 +763,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 28 + // CONFIGURATION 29 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -775,7 +799,7 @@ const char* EXTRACTED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 29 + // CONFIGURATION 30 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -832,7 +856,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 3000\n" " }\n", - // CONFIGURATION 30 + // CONFIGURATION 31 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -871,7 +895,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 31 + // CONFIGURATION 32 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -913,7 +937,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 32 + // CONFIGURATION 33 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -945,7 +969,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 33 + // CONFIGURATION 34 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -982,7 +1006,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 34 + // CONFIGURATION 35 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -1012,7 +1036,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 35 + // CONFIGURATION 36 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -1048,7 +1072,7 @@ const char* EXTRACTED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 36 + // CONFIGURATION 37 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -1100,7 +1124,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 3000\n" " }\n", - // CONFIGURATION 37 + // CONFIGURATION 38 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -1136,7 +1160,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 38 + // CONFIGURATION 39 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -1172,7 +1196,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 39 + // CONFIGURATION 40 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"eth0\", \"eth1\" ],\n" @@ -1182,7 +1206,7 @@ const char* EXTRACTED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 40 + // CONFIGURATION 41 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"eth0\", \"*\", \"eth1\" ],\n" @@ -1192,7 +1216,7 @@ const char* EXTRACTED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 41 + // CONFIGURATION 42 "{\n" " \"dhcp-ddns\": {\n" " \"enable-updates\": true,\n" @@ -1222,7 +1246,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 42 + // CONFIGURATION 43 "{\n" " \"dhcp-ddns\": {\n" " \"enable-updates\": true,\n" @@ -1259,7 +1283,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 43 + // CONFIGURATION 44 "{\n" " \"ddns-generated-prefix\": \"global.prefix\",\n" " \"ddns-override-client-update\": true,\n" @@ -1304,7 +1328,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 44 + // CONFIGURATION 45 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -1330,7 +1354,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 45 + // CONFIGURATION 46 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -1356,7 +1380,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 46 + // CONFIGURATION 47 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -1403,7 +1427,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 47 + // CONFIGURATION 48 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -1435,7 +1459,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 48 + // CONFIGURATION 49 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -1534,7 +1558,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 49 + // CONFIGURATION 50 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -1576,7 +1600,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 50 + // CONFIGURATION 51 "{\n" " \"rebind-timer\": 2000,\n" " \"renew-timer\": 1000,\n" @@ -1656,7 +1680,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 51 + // CONFIGURATION 52 "{\n" " \"rebind-timer\": 2000,\n" " \"renew-timer\": 1000,\n" @@ -1685,14 +1709,6 @@ const char* EXTRACTED_CONFIGS[] = { " }\n" " ],\n" " \"valid-lifetime\": 4000\n" -" }\n", - // CONFIGURATION 52 -"{\n" -" \"interfaces-config\": {\n" -" \"interfaces\": [ \"*\" ],\n" -" \"re-detect\": false\n" -" },\n" -" \"subnet4\": [ ]\n" " }\n", // CONFIGURATION 53 "{\n" @@ -1704,7 +1720,6 @@ const char* EXTRACTED_CONFIGS[] = { " }\n", // CONFIGURATION 54 "{\n" -" \"decline-probation-period\": 12345,\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" " \"re-detect\": false\n" @@ -1713,6 +1728,15 @@ const char* EXTRACTED_CONFIGS[] = { " }\n", // CONFIGURATION 55 "{\n" +" \"decline-probation-period\": 12345,\n" +" \"interfaces-config\": {\n" +" \"interfaces\": [ \"*\" ],\n" +" \"re-detect\": false\n" +" },\n" +" \"subnet4\": [ ]\n" +" }\n", + // CONFIGURATION 56 +"{\n" " \"expired-leases-processing\": {\n" " \"flush-reclaimed-timer-wait-time\": 35,\n" " \"hold-reclaimed-time\": 1800,\n" @@ -1726,26 +1750,6 @@ const char* EXTRACTED_CONFIGS[] = { " \"re-detect\": false\n" " },\n" " \"subnet4\": [ ]\n" -" }\n", - // CONFIGURATION 56 -"{\n" -" \"interfaces-config\": {\n" -" \"interfaces\": [ \"*\" ],\n" -" \"re-detect\": false\n" -" },\n" -" \"rebind-timer\": 2000,\n" -" \"renew-timer\": 1000,\n" -" \"subnet4\": [\n" -" {\n" -" \"pools\": [\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 57 "{\n" @@ -1757,7 +1761,6 @@ const char* EXTRACTED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"subnet4\": [\n" " {\n" -" \"4o6-subnet\": \"2001:db8::123/45\",\n" " \"pools\": [\n" " {\n" " \"pool\": \"192.0.2.1 - 192.0.2.100\"\n" @@ -1778,7 +1781,7 @@ const char* EXTRACTED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"subnet4\": [\n" " {\n" -" \"4o6-interface\": \"ethX\",\n" +" \"4o6-subnet\": \"2001:db8::123/45\",\n" " \"pools\": [\n" " {\n" " \"pool\": \"192.0.2.1 - 192.0.2.100\"\n" @@ -1800,7 +1803,6 @@ const char* EXTRACTED_CONFIGS[] = { " \"subnet4\": [\n" " {\n" " \"4o6-interface\": \"ethX\",\n" -" \"4o6-subnet\": \"2001:db8::543/21\",\n" " \"pools\": [\n" " {\n" " \"pool\": \"192.0.2.1 - 192.0.2.100\"\n" @@ -1821,7 +1823,8 @@ const char* EXTRACTED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"subnet4\": [\n" " {\n" -" \"4o6-interface-id\": \"vlan123\",\n" +" \"4o6-interface\": \"ethX\",\n" +" \"4o6-subnet\": \"2001:db8::543/21\",\n" " \"pools\": [\n" " {\n" " \"pool\": \"192.0.2.1 - 192.0.2.100\"\n" @@ -1834,6 +1837,27 @@ const char* EXTRACTED_CONFIGS[] = { " }\n", // CONFIGURATION 61 "{\n" +" \"interfaces-config\": {\n" +" \"interfaces\": [ \"*\" ],\n" +" \"re-detect\": false\n" +" },\n" +" \"rebind-timer\": 2000,\n" +" \"renew-timer\": 1000,\n" +" \"subnet4\": [\n" +" {\n" +" \"4o6-interface-id\": \"vlan123\",\n" +" \"pools\": [\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 62 +"{\n" " \"client-classes\": [\n" " {\n" " \"name\": \"one\"\n" @@ -1863,7 +1887,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 62 + // CONFIGURATION 63 "{\n" " \"client-classes\": [\n" " {\n" @@ -1891,7 +1915,7 @@ const char* EXTRACTED_CONFIGS[] = { " }\n" " ]\n" " }\n", - // CONFIGURATION 63 + // CONFIGURATION 64 "{\n" " \"client-classes\": [\n" " {\n" @@ -1921,7 +1945,7 @@ const char* EXTRACTED_CONFIGS[] = { " }\n" " ]\n" " }\n", - // CONFIGURATION 64 + // CONFIGURATION 65 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -1941,7 +1965,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 65 + // CONFIGURATION 66 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -1962,7 +1986,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 66 + // CONFIGURATION 67 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -1987,7 +2011,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 67 + // CONFIGURATION 68 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -2012,7 +2036,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 68 + // CONFIGURATION 69 "{\n" " \"hosts-databases\": [\n" " {\n" @@ -2036,7 +2060,7 @@ const char* EXTRACTED_CONFIGS[] = { " \"renew-timer\": 1000,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 69 + // CONFIGURATION 70 "{\n" " \"client-classes\": [\n" " {\n" @@ -2145,7 +2169,7 @@ const char* EXTRACTED_CONFIGS[] = { " \"comment\": \"A DHCPv4 server\"\n" " }\n" " }\n", - // CONFIGURATION 70 + // CONFIGURATION 71 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -2207,7 +2231,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 71 + // CONFIGURATION 72 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -2257,7 +2281,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 72 + // CONFIGURATION 73 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -2287,7 +2311,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 73 + // CONFIGURATION 74 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -2317,7 +2341,7 @@ const char* EXTRACTED_CONFIGS[] = { " ],\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 74 + // CONFIGURATION 75 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -2329,7 +2353,7 @@ const char* EXTRACTED_CONFIGS[] = { " \"statistic-default-sample-count\": 10,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 75 + // CONFIGURATION 76 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" @@ -2337,14 +2361,14 @@ const char* EXTRACTED_CONFIGS[] = { " },\n" " \"subnet4\": [ ]\n" " }\n", - // CONFIGURATION 76 + // CONFIGURATION 77 "{\n" " \"interfaces-config\": {\n" " \"interfaces\": [ \"*\" ],\n" " \"re-detect\": false\n" " },\n" " \"multi-threading\": {\n" -" \"enable-multi-threading\": false,\n" +" \"enable-multi-threading\": true,\n" " \"packet-queue-size\": 1024,\n" " \"thread-pool-size\": 48\n" " },\n" @@ -3746,6 +3770,124 @@ const char* UNPARSED_CONFIGS[] = { " \"authoritative\": false,\n" " \"boot-file-name\": \"\",\n" " \"calculate-tee-times\": false,\n" +" \"compatibility\": {\n" +" \"exclude-first-last-24\": true,\n" +" \"ignore-rai-link-selection\": true,\n" +" \"lenient-option-parsing\": true\n" +" },\n" +" \"ddns-generated-prefix\": \"myhost\",\n" +" \"ddns-override-client-update\": false,\n" +" \"ddns-override-no-update\": false,\n" +" \"ddns-qualifying-suffix\": \"\",\n" +" \"ddns-replace-client-name\": \"never\",\n" +" \"ddns-send-updates\": true,\n" +" \"ddns-update-on-renew\": false,\n" +" \"ddns-use-conflict-resolution\": true,\n" +" \"decline-probation-period\": 86400,\n" +" \"dhcp-ddns\": {\n" +" \"enable-updates\": false,\n" +" \"max-queue-size\": 1024,\n" +" \"ncr-format\": \"JSON\",\n" +" \"ncr-protocol\": \"UDP\",\n" +" \"sender-ip\": \"0.0.0.0\",\n" +" \"sender-port\": 0,\n" +" \"server-ip\": \"127.0.0.1\",\n" +" \"server-port\": 53001\n" +" },\n" +" \"dhcp-queue-control\": {\n" +" \"capacity\": 64,\n" +" \"enable-queue\": false,\n" +" \"queue-type\": \"kea-ring4\"\n" +" },\n" +" \"dhcp4o6-port\": 0,\n" +" \"early-global-reservations-lookup\": false,\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" +" \"hostname-char-replacement\": \"\",\n" +" \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n" +" \"interfaces-config\": {\n" +" \"interfaces\": [ \"*\" ],\n" +" \"re-detect\": false\n" +" },\n" +" \"ip-reservations-unique\": true,\n" +" \"lease-database\": {\n" +" \"type\": \"memfile\"\n" +" },\n" +" \"match-client-id\": true,\n" +" \"multi-threading\": {\n" +" \"enable-multi-threading\": true,\n" +" \"packet-queue-size\": 64,\n" +" \"thread-pool-size\": 0\n" +" },\n" +" \"next-server\": \"0.0.0.0\",\n" +" \"option-data\": [ ],\n" +" \"option-def\": [ ],\n" +" \"parked-packet-limit\": 256,\n" +" \"rebind-timer\": 2000,\n" +" \"renew-timer\": 1000,\n" +" \"reservations-global\": false,\n" +" \"reservations-in-subnet\": true,\n" +" \"reservations-lookup-first\": false,\n" +" \"reservations-out-of-pool\": false,\n" +" \"sanity-checks\": {\n" +" \"extended-info-checks\": \"fix\",\n" +" \"lease-checks\": \"warn\"\n" +" },\n" +" \"server-hostname\": \"\",\n" +" \"server-tag\": \"\",\n" +" \"shared-networks\": [ ],\n" +" \"statistic-default-sample-age\": 0,\n" +" \"statistic-default-sample-count\": 20,\n" +" \"store-extended-info\": false,\n" +" \"subnet4\": [\n" +" {\n" +" \"4o6-interface\": \"\",\n" +" \"4o6-interface-id\": \"\",\n" +" \"4o6-subnet\": \"\",\n" +" \"allocator\": \"iterative\",\n" +" \"calculate-tee-times\": false,\n" +" \"id\": 1,\n" +" \"max-valid-lifetime\": 4000,\n" +" \"min-valid-lifetime\": 4000,\n" +" \"option-data\": [ ],\n" +" \"pools\": [\n" +" {\n" +" \"option-data\": [ ],\n" +" \"pool\": \"192.0.2.1-192.0.2.100\"\n" +" }\n" +" ],\n" +" \"rebind-timer\": 2000,\n" +" \"relay\": {\n" +" \"ip-addresses\": [ ]\n" +" },\n" +" \"renew-timer\": 1000,\n" +" \"reservations\": [ ],\n" +" \"store-extended-info\": false,\n" +" \"subnet\": \"192.0.2.0/24\",\n" +" \"t1-percent\": 0.5,\n" +" \"t2-percent\": 0.875,\n" +" \"valid-lifetime\": 4000\n" +" }\n" +" ],\n" +" \"t1-percent\": 0.5,\n" +" \"t2-percent\": 0.875,\n" +" \"valid-lifetime\": 4000\n" +" }\n", + // CONFIGURATION 12 +"{\n" +" \"allocator\": \"iterative\",\n" +" \"authoritative\": false,\n" +" \"boot-file-name\": \"\",\n" +" \"calculate-tee-times\": false,\n" " \"ddns-generated-prefix\": \"myhost\",\n" " \"ddns-override-client-update\": false,\n" " \"ddns-override-no-update\": false,\n" @@ -3883,7 +4025,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 12 + // CONFIGURATION 13 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -4025,7 +4167,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 13 + // CONFIGURATION 14 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -4168,7 +4310,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 14 + // CONFIGURATION 15 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": true,\n" @@ -4310,7 +4452,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 15 + // CONFIGURATION 16 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -4425,7 +4567,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 16 + // CONFIGURATION 17 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -4574,7 +4716,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 17 + // CONFIGURATION 18 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -4687,7 +4829,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 18 + // CONFIGURATION 19 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -4779,7 +4921,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 7200\n" " }\n", - // CONFIGURATION 19 + // CONFIGURATION 20 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -4871,7 +5013,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 7200\n" " }\n", - // CONFIGURATION 20 + // CONFIGURATION 21 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -4972,7 +5114,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 7200\n" " }\n", - // CONFIGURATION 21 + // CONFIGURATION 22 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -5064,7 +5206,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 7200\n" " }\n", - // CONFIGURATION 22 + // CONFIGURATION 23 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -5156,7 +5298,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 7200\n" " }\n", - // CONFIGURATION 23 + // CONFIGURATION 24 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -5248,7 +5390,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 7200\n" " }\n", - // CONFIGURATION 24 + // CONFIGURATION 25 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -5340,7 +5482,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 7200\n" " }\n", - // CONFIGURATION 25 + // CONFIGURATION 26 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -5470,7 +5612,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 26 + // CONFIGURATION 27 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -5600,7 +5742,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 27 + // CONFIGURATION 28 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -5740,7 +5882,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 28 + // CONFIGURATION 29 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -5860,7 +6002,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 29 + // CONFIGURATION 30 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -6026,7 +6168,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 3000\n" " }\n", - // CONFIGURATION 30 + // CONFIGURATION 31 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -6165,7 +6307,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 31 + // CONFIGURATION 32 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -6324,7 +6466,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 32 + // CONFIGURATION 33 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -6454,7 +6596,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 33 + // CONFIGURATION 34 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -6589,7 +6731,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 34 + // CONFIGURATION 35 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -6719,7 +6861,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 35 + // CONFIGURATION 36 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -6839,7 +6981,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 36 + // CONFIGURATION 37 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -6996,7 +7138,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 3000\n" " }\n", - // CONFIGURATION 37 + // CONFIGURATION 38 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -7124,7 +7266,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 38 + // CONFIGURATION 39 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -7256,7 +7398,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 39 + // CONFIGURATION 40 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -7340,7 +7482,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 40 + // CONFIGURATION 41 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -7424,7 +7566,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 41 + // CONFIGURATION 42 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -7537,7 +7679,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 42 + // CONFIGURATION 43 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -7650,7 +7792,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 43 + // CONFIGURATION 44 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -7763,7 +7905,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 44 + // CONFIGURATION 45 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -7876,7 +8018,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 45 + // CONFIGURATION 46 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -7989,7 +8131,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 46 + // CONFIGURATION 47 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -8189,7 +8331,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 47 + // CONFIGURATION 48 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -8317,7 +8459,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 48 + // CONFIGURATION 49 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -8589,7 +8731,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 49 + // CONFIGURATION 50 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -8732,7 +8874,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 50 + // CONFIGURATION 51 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -9029,7 +9171,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 51 + // CONFIGURATION 52 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -9172,88 +9314,6 @@ const char* UNPARSED_CONFIGS[] = { " \"t1-percent\": 0.5,\n" " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" -" }\n", - // CONFIGURATION 52 -"{\n" -" \"allocator\": \"iterative\",\n" -" \"authoritative\": false,\n" -" \"boot-file-name\": \"\",\n" -" \"calculate-tee-times\": false,\n" -" \"ddns-generated-prefix\": \"myhost\",\n" -" \"ddns-override-client-update\": false,\n" -" \"ddns-override-no-update\": false,\n" -" \"ddns-qualifying-suffix\": \"\",\n" -" \"ddns-replace-client-name\": \"never\",\n" -" \"ddns-send-updates\": true,\n" -" \"ddns-update-on-renew\": false,\n" -" \"ddns-use-conflict-resolution\": true,\n" -" \"decline-probation-period\": 86400,\n" -" \"dhcp-ddns\": {\n" -" \"enable-updates\": false,\n" -" \"max-queue-size\": 1024,\n" -" \"ncr-format\": \"JSON\",\n" -" \"ncr-protocol\": \"UDP\",\n" -" \"sender-ip\": \"0.0.0.0\",\n" -" \"sender-port\": 0,\n" -" \"server-ip\": \"127.0.0.1\",\n" -" \"server-port\": 53001\n" -" },\n" -" \"dhcp-queue-control\": {\n" -" \"capacity\": 64,\n" -" \"enable-queue\": false,\n" -" \"queue-type\": \"kea-ring4\"\n" -" },\n" -" \"dhcp4o6-port\": 0,\n" -" \"early-global-reservations-lookup\": false,\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" -" \"hostname-char-replacement\": \"\",\n" -" \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n" -" \"interfaces-config\": {\n" -" \"interfaces\": [ \"*\" ],\n" -" \"re-detect\": false\n" -" },\n" -" \"ip-reservations-unique\": true,\n" -" \"lease-database\": {\n" -" \"type\": \"memfile\"\n" -" },\n" -" \"match-client-id\": true,\n" -" \"multi-threading\": {\n" -" \"enable-multi-threading\": true,\n" -" \"packet-queue-size\": 64,\n" -" \"thread-pool-size\": 0\n" -" },\n" -" \"next-server\": \"0.0.0.0\",\n" -" \"option-data\": [ ],\n" -" \"option-def\": [ ],\n" -" \"parked-packet-limit\": 256,\n" -" \"reservations-global\": false,\n" -" \"reservations-in-subnet\": true,\n" -" \"reservations-lookup-first\": false,\n" -" \"reservations-out-of-pool\": false,\n" -" \"sanity-checks\": {\n" -" \"extended-info-checks\": \"fix\",\n" -" \"lease-checks\": \"warn\"\n" -" },\n" -" \"server-hostname\": \"\",\n" -" \"server-tag\": \"\",\n" -" \"shared-networks\": [ ],\n" -" \"statistic-default-sample-age\": 0,\n" -" \"statistic-default-sample-count\": 20,\n" -" \"store-extended-info\": false,\n" -" \"subnet4\": [ ],\n" -" \"t1-percent\": 0.5,\n" -" \"t2-percent\": 0.875,\n" -" \"valid-lifetime\": 7200\n" " }\n", // CONFIGURATION 53 "{\n" @@ -9351,7 +9411,7 @@ const char* UNPARSED_CONFIGS[] = { " \"ddns-send-updates\": true,\n" " \"ddns-update-on-renew\": false,\n" " \"ddns-use-conflict-resolution\": true,\n" -" \"decline-probation-period\": 12345,\n" +" \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" " \"enable-updates\": false,\n" " \"max-queue-size\": 1024,\n" @@ -9433,6 +9493,88 @@ const char* UNPARSED_CONFIGS[] = { " \"ddns-send-updates\": true,\n" " \"ddns-update-on-renew\": false,\n" " \"ddns-use-conflict-resolution\": true,\n" +" \"decline-probation-period\": 12345,\n" +" \"dhcp-ddns\": {\n" +" \"enable-updates\": false,\n" +" \"max-queue-size\": 1024,\n" +" \"ncr-format\": \"JSON\",\n" +" \"ncr-protocol\": \"UDP\",\n" +" \"sender-ip\": \"0.0.0.0\",\n" +" \"sender-port\": 0,\n" +" \"server-ip\": \"127.0.0.1\",\n" +" \"server-port\": 53001\n" +" },\n" +" \"dhcp-queue-control\": {\n" +" \"capacity\": 64,\n" +" \"enable-queue\": false,\n" +" \"queue-type\": \"kea-ring4\"\n" +" },\n" +" \"dhcp4o6-port\": 0,\n" +" \"early-global-reservations-lookup\": false,\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" +" \"hostname-char-replacement\": \"\",\n" +" \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n" +" \"interfaces-config\": {\n" +" \"interfaces\": [ \"*\" ],\n" +" \"re-detect\": false\n" +" },\n" +" \"ip-reservations-unique\": true,\n" +" \"lease-database\": {\n" +" \"type\": \"memfile\"\n" +" },\n" +" \"match-client-id\": true,\n" +" \"multi-threading\": {\n" +" \"enable-multi-threading\": true,\n" +" \"packet-queue-size\": 64,\n" +" \"thread-pool-size\": 0\n" +" },\n" +" \"next-server\": \"0.0.0.0\",\n" +" \"option-data\": [ ],\n" +" \"option-def\": [ ],\n" +" \"parked-packet-limit\": 256,\n" +" \"reservations-global\": false,\n" +" \"reservations-in-subnet\": true,\n" +" \"reservations-lookup-first\": false,\n" +" \"reservations-out-of-pool\": false,\n" +" \"sanity-checks\": {\n" +" \"extended-info-checks\": \"fix\",\n" +" \"lease-checks\": \"warn\"\n" +" },\n" +" \"server-hostname\": \"\",\n" +" \"server-tag\": \"\",\n" +" \"shared-networks\": [ ],\n" +" \"statistic-default-sample-age\": 0,\n" +" \"statistic-default-sample-count\": 20,\n" +" \"store-extended-info\": false,\n" +" \"subnet4\": [ ],\n" +" \"t1-percent\": 0.5,\n" +" \"t2-percent\": 0.875,\n" +" \"valid-lifetime\": 7200\n" +" }\n", + // CONFIGURATION 56 +"{\n" +" \"allocator\": \"iterative\",\n" +" \"authoritative\": false,\n" +" \"boot-file-name\": \"\",\n" +" \"calculate-tee-times\": false,\n" +" \"ddns-generated-prefix\": \"myhost\",\n" +" \"ddns-override-client-update\": false,\n" +" \"ddns-override-no-update\": false,\n" +" \"ddns-qualifying-suffix\": \"\",\n" +" \"ddns-replace-client-name\": \"never\",\n" +" \"ddns-send-updates\": true,\n" +" \"ddns-update-on-renew\": false,\n" +" \"ddns-use-conflict-resolution\": true,\n" " \"decline-probation-period\": 86400,\n" " \"dhcp-ddns\": {\n" " \"enable-updates\": false,\n" @@ -9501,7 +9643,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 7200\n" " }\n", - // CONFIGURATION 56 + // CONFIGURATION 57 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -9614,7 +9756,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 57 + // CONFIGURATION 58 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -9727,7 +9869,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 58 + // CONFIGURATION 59 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -9840,7 +9982,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 59 + // CONFIGURATION 60 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -9953,7 +10095,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 60 + // CONFIGURATION 61 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -10066,7 +10208,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 61 + // CONFIGURATION 62 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -10205,7 +10347,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 62 + // CONFIGURATION 63 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -10335,7 +10477,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 7200\n" " }\n", - // CONFIGURATION 63 + // CONFIGURATION 64 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -10466,119 +10608,6 @@ const char* UNPARSED_CONFIGS[] = { " \"t1-percent\": 0.5,\n" " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 7200\n" -" }\n", - // CONFIGURATION 64 -"{\n" -" \"allocator\": \"iterative\",\n" -" \"authoritative\": false,\n" -" \"boot-file-name\": \"\",\n" -" \"calculate-tee-times\": false,\n" -" \"ddns-generated-prefix\": \"myhost\",\n" -" \"ddns-override-client-update\": false,\n" -" \"ddns-override-no-update\": false,\n" -" \"ddns-qualifying-suffix\": \"\",\n" -" \"ddns-replace-client-name\": \"never\",\n" -" \"ddns-send-updates\": true,\n" -" \"ddns-update-on-renew\": false,\n" -" \"ddns-use-conflict-resolution\": true,\n" -" \"decline-probation-period\": 86400,\n" -" \"dhcp-ddns\": {\n" -" \"enable-updates\": false,\n" -" \"max-queue-size\": 1024,\n" -" \"ncr-format\": \"JSON\",\n" -" \"ncr-protocol\": \"UDP\",\n" -" \"sender-ip\": \"0.0.0.0\",\n" -" \"sender-port\": 0,\n" -" \"server-ip\": \"127.0.0.1\",\n" -" \"server-port\": 53001\n" -" },\n" -" \"dhcp-queue-control\": {\n" -" \"capacity\": 64,\n" -" \"enable-queue\": false,\n" -" \"queue-type\": \"kea-ring4\"\n" -" },\n" -" \"dhcp4o6-port\": 0,\n" -" \"early-global-reservations-lookup\": false,\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" -" \"hostname-char-replacement\": \"\",\n" -" \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n" -" \"interfaces-config\": {\n" -" \"interfaces\": [ \"*\" ],\n" -" \"re-detect\": false\n" -" },\n" -" \"ip-reservations-unique\": true,\n" -" \"lease-database\": {\n" -" \"type\": \"memfile\"\n" -" },\n" -" \"match-client-id\": true,\n" -" \"multi-threading\": {\n" -" \"enable-multi-threading\": true,\n" -" \"packet-queue-size\": 64,\n" -" \"thread-pool-size\": 0\n" -" },\n" -" \"next-server\": \"0.0.0.0\",\n" -" \"option-data\": [ ],\n" -" \"option-def\": [ ],\n" -" \"parked-packet-limit\": 256,\n" -" \"rebind-timer\": 2000,\n" -" \"renew-timer\": 1000,\n" -" \"reservations-global\": false,\n" -" \"reservations-in-subnet\": true,\n" -" \"reservations-lookup-first\": false,\n" -" \"reservations-out-of-pool\": false,\n" -" \"sanity-checks\": {\n" -" \"extended-info-checks\": \"fix\",\n" -" \"lease-checks\": \"warn\"\n" -" },\n" -" \"server-hostname\": \"\",\n" -" \"server-tag\": \"\",\n" -" \"shared-networks\": [ ],\n" -" \"statistic-default-sample-age\": 0,\n" -" \"statistic-default-sample-count\": 20,\n" -" \"store-extended-info\": false,\n" -" \"subnet4\": [\n" -" {\n" -" \"4o6-interface\": \"\",\n" -" \"4o6-interface-id\": \"\",\n" -" \"4o6-subnet\": \"\",\n" -" \"allocator\": \"iterative\",\n" -" \"calculate-tee-times\": false,\n" -" \"id\": 1,\n" -" \"max-valid-lifetime\": 4000,\n" -" \"min-valid-lifetime\": 4000,\n" -" \"option-data\": [ ],\n" -" \"pools\": [\n" -" {\n" -" \"option-data\": [ ],\n" -" \"pool\": \"192.0.2.0/28\"\n" -" }\n" -" ],\n" -" \"rebind-timer\": 2000,\n" -" \"relay\": {\n" -" \"ip-addresses\": [ ]\n" -" },\n" -" \"renew-timer\": 1000,\n" -" \"reservations\": [ ],\n" -" \"store-extended-info\": false,\n" -" \"subnet\": \"192.0.2.0/24\",\n" -" \"t1-percent\": 0.5,\n" -" \"t2-percent\": 0.875,\n" -" \"valid-lifetime\": 4000\n" -" }\n" -" ],\n" -" \"t1-percent\": 0.5,\n" -" \"t2-percent\": 0.875,\n" -" \"valid-lifetime\": 4000\n" " }\n", // CONFIGURATION 65 "{\n" @@ -10673,8 +10702,7 @@ const char* UNPARSED_CONFIGS[] = { " \"pools\": [\n" " {\n" " \"option-data\": [ ],\n" -" \"pool\": \"192.0.2.0/28\",\n" -" \"user-context\": { }\n" +" \"pool\": \"192.0.2.0/28\"\n" " }\n" " ],\n" " \"rebind-timer\": 2000,\n" @@ -10788,11 +10816,7 @@ const char* UNPARSED_CONFIGS[] = { " {\n" " \"option-data\": [ ],\n" " \"pool\": \"192.0.2.0/28\",\n" -" \"user-context\": {\n" -" \"bool-param\": true,\n" -" \"integer-param\": 42,\n" -" \"string-param\": \"Sagittarius\"\n" -" }\n" +" \"user-context\": { }\n" " }\n" " ],\n" " \"rebind-timer\": 2000,\n" @@ -10975,6 +10999,124 @@ const char* UNPARSED_CONFIGS[] = { " \"host-reservation-identifiers\": [ \"hw-address\", \"duid\", \"circuit-id\", \"client-id\" ],\n" " \"hostname-char-replacement\": \"\",\n" " \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n" +" \"interfaces-config\": {\n" +" \"interfaces\": [ \"*\" ],\n" +" \"re-detect\": false\n" +" },\n" +" \"ip-reservations-unique\": true,\n" +" \"lease-database\": {\n" +" \"type\": \"memfile\"\n" +" },\n" +" \"match-client-id\": true,\n" +" \"multi-threading\": {\n" +" \"enable-multi-threading\": true,\n" +" \"packet-queue-size\": 64,\n" +" \"thread-pool-size\": 0\n" +" },\n" +" \"next-server\": \"0.0.0.0\",\n" +" \"option-data\": [ ],\n" +" \"option-def\": [ ],\n" +" \"parked-packet-limit\": 256,\n" +" \"rebind-timer\": 2000,\n" +" \"renew-timer\": 1000,\n" +" \"reservations-global\": false,\n" +" \"reservations-in-subnet\": true,\n" +" \"reservations-lookup-first\": false,\n" +" \"reservations-out-of-pool\": false,\n" +" \"sanity-checks\": {\n" +" \"extended-info-checks\": \"fix\",\n" +" \"lease-checks\": \"warn\"\n" +" },\n" +" \"server-hostname\": \"\",\n" +" \"server-tag\": \"\",\n" +" \"shared-networks\": [ ],\n" +" \"statistic-default-sample-age\": 0,\n" +" \"statistic-default-sample-count\": 20,\n" +" \"store-extended-info\": false,\n" +" \"subnet4\": [\n" +" {\n" +" \"4o6-interface\": \"\",\n" +" \"4o6-interface-id\": \"\",\n" +" \"4o6-subnet\": \"\",\n" +" \"allocator\": \"iterative\",\n" +" \"calculate-tee-times\": false,\n" +" \"id\": 1,\n" +" \"max-valid-lifetime\": 4000,\n" +" \"min-valid-lifetime\": 4000,\n" +" \"option-data\": [ ],\n" +" \"pools\": [\n" +" {\n" +" \"option-data\": [ ],\n" +" \"pool\": \"192.0.2.0/28\",\n" +" \"user-context\": {\n" +" \"bool-param\": true,\n" +" \"integer-param\": 42,\n" +" \"string-param\": \"Sagittarius\"\n" +" }\n" +" }\n" +" ],\n" +" \"rebind-timer\": 2000,\n" +" \"relay\": {\n" +" \"ip-addresses\": [ ]\n" +" },\n" +" \"renew-timer\": 1000,\n" +" \"reservations\": [ ],\n" +" \"store-extended-info\": false,\n" +" \"subnet\": \"192.0.2.0/24\",\n" +" \"t1-percent\": 0.5,\n" +" \"t2-percent\": 0.875,\n" +" \"valid-lifetime\": 4000\n" +" }\n" +" ],\n" +" \"t1-percent\": 0.5,\n" +" \"t2-percent\": 0.875,\n" +" \"valid-lifetime\": 4000\n" +" }\n", + // CONFIGURATION 69 +"{\n" +" \"allocator\": \"iterative\",\n" +" \"authoritative\": false,\n" +" \"boot-file-name\": \"\",\n" +" \"calculate-tee-times\": false,\n" +" \"ddns-generated-prefix\": \"myhost\",\n" +" \"ddns-override-client-update\": false,\n" +" \"ddns-override-no-update\": false,\n" +" \"ddns-qualifying-suffix\": \"\",\n" +" \"ddns-replace-client-name\": \"never\",\n" +" \"ddns-send-updates\": true,\n" +" \"ddns-update-on-renew\": false,\n" +" \"ddns-use-conflict-resolution\": true,\n" +" \"decline-probation-period\": 86400,\n" +" \"dhcp-ddns\": {\n" +" \"enable-updates\": false,\n" +" \"max-queue-size\": 1024,\n" +" \"ncr-format\": \"JSON\",\n" +" \"ncr-protocol\": \"UDP\",\n" +" \"sender-ip\": \"0.0.0.0\",\n" +" \"sender-port\": 0,\n" +" \"server-ip\": \"127.0.0.1\",\n" +" \"server-port\": 53001\n" +" },\n" +" \"dhcp-queue-control\": {\n" +" \"capacity\": 64,\n" +" \"enable-queue\": false,\n" +" \"queue-type\": \"kea-ring4\"\n" +" },\n" +" \"dhcp4o6-port\": 0,\n" +" \"early-global-reservations-lookup\": false,\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" +" \"hostname-char-replacement\": \"\",\n" +" \"hostname-char-set\": \"[^A-Za-z0-9.-]\",\n" " \"hosts-databases\": [\n" " {\n" " \"name\": \"keatest1\",\n" @@ -11028,7 +11170,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 69 + // CONFIGURATION 70 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -11263,7 +11405,7 @@ const char* UNPARSED_CONFIGS[] = { " },\n" " \"valid-lifetime\": 7200\n" " }\n", - // CONFIGURATION 70 + // CONFIGURATION 71 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -11459,7 +11601,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 71 + // CONFIGURATION 72 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -11638,7 +11780,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 72 + // CONFIGURATION 73 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -11779,7 +11921,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 73 + // CONFIGURATION 74 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -11920,7 +12062,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 74 + // CONFIGURATION 75 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -12004,7 +12146,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 4000\n" " }\n", - // CONFIGURATION 75 + // CONFIGURATION 76 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -12086,7 +12228,7 @@ const char* UNPARSED_CONFIGS[] = { " \"t2-percent\": 0.875,\n" " \"valid-lifetime\": 7200\n" " }\n", - // CONFIGURATION 76 + // CONFIGURATION 77 "{\n" " \"allocator\": \"iterative\",\n" " \"authoritative\": false,\n" @@ -12141,7 +12283,7 @@ const char* UNPARSED_CONFIGS[] = { " },\n" " \"match-client-id\": true,\n" " \"multi-threading\": {\n" -" \"enable-multi-threading\": false,\n" +" \"enable-multi-threading\": true,\n" " \"packet-queue-size\": 1024,\n" " \"thread-pool-size\": 48\n" " },\n" @@ -12419,17 +12561,9 @@ TEST_P(Dhcp4GetConfigTest, run) { // get the expected config using the generic JSON syntax parser ASSERT_NO_THROW_LOG(jsonj = parseJSON(expected)); // the generic JSON parser does not handle comments - EXPECT_TRUE(isEquivalent(jsond, moveComments(jsonj))) -#ifdef HAVE_CREATE_UNIFIED_DIFF - << "\nDiff:\n" << generateDiff(prettyPrint(jsond), prettyPrint(jsonj)) << "\n" -#endif - ; + EXPECT_TRUE(isEquivalent(jsond, moveComments(jsonj))); // check that unparsed and expected values match - EXPECT_TRUE(isEquivalent(dhcp, jsonj)) -#ifdef HAVE_CREATE_UNIFIED_DIFF - << "\nDiff:\n" << generateDiff(prettyPrint(dhcp), prettyPrint(jsonj)) << "\n" -#endif - ; + EXPECT_TRUE(isEquivalent(dhcp, jsonj)); // check on pretty prints too std::string current = prettyPrint(dhcp, 4, 4) + "\n"; EXPECT_EQ(expected, current); @@ -12448,11 +12582,7 @@ TEST_P(Dhcp4GetConfigTest, run) { ConstElementPtr unparsed2; ASSERT_NO_THROW_LOG(unparsed2 = extracted2->toElement()); ASSERT_TRUE(unparsed2); - EXPECT_TRUE(isEquivalent(unparsed, unparsed2)) -#ifdef HAVE_CREATE_UNIFIED_DIFF - << "\nDiff:\n" << generateDiff(prettyPrint(unparsed), prettyPrint(unparsed2)) << "\n" -#endif - ; + EXPECT_TRUE(isEquivalent(unparsed, unparsed2)); } class IntToString { diff --git a/src/bin/dhcp6/json_config_parser.cc b/src/bin/dhcp6/json_config_parser.cc index 02487cfc2d..91a3d68873 100644 --- a/src/bin/dhcp6/json_config_parser.cc +++ b/src/bin/dhcp6/json_config_parser.cc @@ -727,9 +727,20 @@ configureDhcp6Server(Dhcpv6Srv& server, isc::data::ConstElementPtr config_set, ConstElementPtr compatibility = mutable_cfg->get("compatibility"); if (compatibility) { for (auto kv : compatibility->mapValue()) { + if (!kv.second || (kv.second->getType() != Element::boolean)) { + isc_throw(DhcpConfigError, + "compatibility parameter values must be " + << "boolean (" << kv.first << " at " + << kv.second->getPosition() << ")"); + } if (kv.first == "lenient-option-parsing") { CfgMgr::instance().getStagingCfg()->setLenientOptionParsing( kv.second->boolValue()); + } else { + isc_throw(DhcpConfigError, + "unsupported compatibility parameter: " + << kv.first << " (" << kv.second->getPosition() + << ")"); } } } diff --git a/src/bin/dhcp6/tests/config_parser_unittest.cc b/src/bin/dhcp6/tests/config_parser_unittest.cc index a48589547d..4dab6a13b7 100644 --- a/src/bin/dhcp6/tests/config_parser_unittest.cc +++ b/src/bin/dhcp6/tests/config_parser_unittest.cc @@ -1688,6 +1688,89 @@ TEST_F(Dhcp6ParserTest, reconfigureRemoveSubnet) { EXPECT_EQ(4, (*++subnet)->getID()); } +// Check whether it is possible to configure compatibility flags. +TEST_F(Dhcp6ParserTest, compatibility) { + string config = "{ " + genIfaceConfig() + "," + + "\"preferred-lifetime\": 3000," + "\"rebind-timer\": 2000, " + "\"renew-timer\": 1000, " + "\"compatibility\": { " + " \"lenient-option-parsing\": true" + "}," + "\"subnet6\": [ { " + " \"pools\": [ { \"pool\": \"2001:db8:1::1 - 2001:db8:1::ffff\" } ]," + " \"subnet\": \"2001:db8:1::/64\" } ]," + "\"valid-lifetime\": 4000 }"; + + ConstElementPtr json; + ASSERT_NO_THROW(json = parseDHCP6(config)) << "bad config: " << config; + extractConfig(config); + + // Check defaults: they should be false. + EXPECT_FALSE(CfgMgr::instance().getStagingCfg()->getLenientOptionParsing()); + + // Check the configuration was really applied. + ConstElementPtr status; + EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json)); + checkResult(status, 0); + + EXPECT_TRUE(CfgMgr::instance().getStagingCfg()->getLenientOptionParsing()); +} + +// Check that unknown compatibility flag raises error. +TEST_F(Dhcp6ParserTest, compatibilityUnknown) { + string config = "{ " + genIfaceConfig() + "," + + "\"preferred-lifetime\": 3000," + "\"rebind-timer\": 2000, " + "\"renew-timer\": 1000, " + "\"compatibility\": { " + " \"foo-bar\": true" + "}," + "\"subnet6\": [ { " + " \"pools\": [ { \"pool\": \"2001:db8:1::1 - 2001:db8:1::ffff\" } ]," + " \"subnet\": \"2001:db8:1::/64\" } ]," + "\"valid-lifetime\": 4000 }"; + + // Syntax is incorrect. + EXPECT_THROW(parseDHCP6(config), Dhcp6ParseError); + ConstElementPtr json; + EXPECT_NO_THROW(json = parseJSON(config)); + + // Unknown keyword is detected. + ConstElementPtr status; + EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json)); + string expected = "unsupported compatibility parameter: "; + expected += "foo-bar (:1:154)"; + checkResult(status, 1, expected); +} + +// Check that not boolean compatibility flag value raises error. +TEST_F(Dhcp6ParserTest, compatibilityNotBool) { + string config = "{ " + genIfaceConfig() + "," + + "\"preferred-lifetime\": 3000," + "\"rebind-timer\": 2000, " + "\"renew-timer\": 1000, " + "\"compatibility\": { " + " \"lenient-option-parsing\": 1" + "}," + "\"subnet6\": [ { " + " \"pools\": [ { \"pool\": \"2001:db8:1::1 - 2001:db8:1::ffff\" } ]," + " \"subnet\": \"2001:db8:1::/64\" } ]," + "\"valid-lifetime\": 4000 }"; + + // Syntax is incorrect. + EXPECT_THROW(parseDHCP6(config), Dhcp6ParseError); + ConstElementPtr json; + EXPECT_NO_THROW(json = parseJSON(config)); + + // Bad value type is detected. + ConstElementPtr status; + EXPECT_NO_THROW(status = Dhcpv6SrvTest::configure(srv_, json)); + string expected = "compatibility parameter values must be boolean "; + expected += "(lenient-option-parsing at :1:169)"; + checkResult(status, 1, expected); +} + // This test checks if it is possible to override global values // on a per subnet basis. TEST_F(Dhcp6ParserTest, subnetLocal) { diff --git a/src/lib/dhcpsrv/srv_config.cc b/src/lib/dhcpsrv/srv_config.cc index 50e4e7891a..6d1df21612 100644 --- a/src/lib/dhcpsrv/srv_config.cc +++ b/src/lib/dhcpsrv/srv_config.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2022 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2014-2023 Internet Systems Consortium, Inc. ("ISC") // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -48,7 +48,7 @@ SrvConfig::SrvConfig() d2_client_config_(new D2ClientConfig()), configured_globals_(new CfgGlobals()), cfg_consist_(new CfgConsistency()), lenient_option_parsing_(false), ignore_rai_link_selection_(false), - reservations_lookup_first_(false) { + exclude_first_last_24_(false), reservations_lookup_first_(false) { } SrvConfig::SrvConfig(const uint32_t sequence) @@ -67,7 +67,7 @@ SrvConfig::SrvConfig(const uint32_t sequence) d2_client_config_(new D2ClientConfig()), configured_globals_(new CfgGlobals()), cfg_consist_(new CfgConsistency()), lenient_option_parsing_(false), ignore_rai_link_selection_(false), - reservations_lookup_first_(false) { + exclude_first_last_24_(false), reservations_lookup_first_(false) { } std::string @@ -632,6 +632,21 @@ SrvConfig::toElement() const { } } + // Set compatibility flags. + ElementPtr compatibility = Element::createMap(); + if (getLenientOptionParsing()) { + compatibility->set("lenient-option-parsing", Element::create(true)); + } + if (getIgnoreRAILinkSelection()) { + compatibility->set("ignore-rai-link-selection", Element::create(true)); + } + if (getExcludeFirstLast24()) { + compatibility->set("exclude-first-last-24", Element::create(true)); + } + if (compatibility->size() > 0) { + dhcp->set("compatibility", compatibility); + } + // Set decline-probation-period dhcp->set("decline-probation-period", Element::create(static_cast(decline_timer_))); diff --git a/src/lib/dhcpsrv/tests/srv_config_unittest.cc b/src/lib/dhcpsrv/tests/srv_config_unittest.cc index ac330ef9eb..4b21f27383 100644 --- a/src/lib/dhcpsrv/tests/srv_config_unittest.cc +++ b/src/lib/dhcpsrv/tests/srv_config_unittest.cc @@ -309,6 +309,38 @@ TEST_F(SrvConfigTest, echoClientId) { EXPECT_TRUE(conf1.getEchoClientId()); } +// This test verifies that compatibility flags are correctly managed. +TEST_F(SrvConfigTest, compatibility) { + SrvConfig conf; + + // Check that defaults are false. + EXPECT_FALSE(conf.getLenientOptionParsing()); + EXPECT_FALSE(conf.getIgnoreRAILinkSelection()); + EXPECT_FALSE(conf.getExcludeFirstLast24()); + + // Check that they can be modified to true. + conf.setLenientOptionParsing(true); + conf.setIgnoreRAILinkSelection(true); + conf.setExcludeFirstLast24(true); + EXPECT_TRUE(conf.getLenientOptionParsing()); + EXPECT_TRUE(conf.getIgnoreRAILinkSelection()); + EXPECT_TRUE(conf.getExcludeFirstLast24()); + + // Check that default values can be restored. + conf.setLenientOptionParsing(false); + conf.setIgnoreRAILinkSelection(false); + conf.setExcludeFirstLast24(false); + EXPECT_FALSE(conf.getLenientOptionParsing()); + EXPECT_FALSE(conf.getIgnoreRAILinkSelection()); + EXPECT_FALSE(conf.getExcludeFirstLast24()); + + // Check the other constructor has the same default. + SrvConfig conf1(1); + EXPECT_FALSE(conf1.getLenientOptionParsing()); + EXPECT_FALSE(conf1.getIgnoreRAILinkSelection()); + EXPECT_FALSE(conf1.getExcludeFirstLast24()); +} + // This test verifies that host reservations lookup first flag can be configured. TEST_F(SrvConfigTest, reservationsLookupFirst) { SrvConfig conf; @@ -600,10 +632,19 @@ TEST_F(SrvConfigTest, unparse) { CfgMgr::instance().setFamily(AF_INET); conf.setEchoClientId(false); conf.setDhcp4o6Port(6767); + // Add compatibility flags. + conf.setLenientOptionParsing(true); + conf.setIgnoreRAILinkSelection(true); + conf.setExcludeFirstLast24(true); + params = "\"compatibility\": {\n"; + params += " \"lenient-option-parsing\": true,\n"; + params += " \"ignore-rai-link-selection\": true,\n"; + params += " \"exclude-first-last-24\": true\n"; + params += "},\n"; // Add "configured globals" conf.addConfiguredGlobal("renew-timer", Element::create(777)); conf.addConfiguredGlobal("comment", Element::create("bar")); - params = "\"echo-client-id\": false,\n"; + params += "\"echo-client-id\": false,\n"; params += "\"dhcp4o6-port\": 6767,\n"; params += "\"renew-timer\": 777,\n"; params += "\"comment\": \"bar\"\n"; @@ -612,7 +653,14 @@ TEST_F(SrvConfigTest, unparse) { // Verify direct non-default parameters and configured globals CfgMgr::instance().setFamily(AF_INET6); - params = ",\"dhcp4o6-port\": 6767,\n"; + // Add compatibility flag. + conf.setIgnoreRAILinkSelection(false); + conf.setExcludeFirstLast24(false); + params = ",\"compatibility\": {\n"; + params += " \"lenient-option-parsing\": true\n"; + params += "},\n"; + // Add "configured globals" + params += "\"dhcp4o6-port\": 6767,\n"; params += "\"renew-timer\": 777,\n"; params += "\"comment\": \"bar\"\n"; isc::test::runToElementTest