Skip to content

Commit 5b60e5f

Browse files
committed
[#2961] Checkpoint: updated code, tests and doc
1 parent 5bee75d commit 5b60e5f

14 files changed

+177
-215
lines changed

doc/sphinx/arm/dhcp4-srv.rst

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,26 +1207,8 @@ IPv4 Subnet Identifier
12071207

12081208
The subnet identifier (subnet ID) is a unique number associated with a particular
12091209
subnet. In principle, it is used to associate clients' leases with their
1210-
respective subnets. The server configuration should contain unique and stable
1211-
identifiers for all subnets. When a subnet identifier is not specified for a
1212-
subnet, it is automatically assigned by the configuration mechanism. The identifiers
1213-
are assigned starting at 1 and are monotonically increased for each subsequent
1214-
subnet: 1, 2, 3, ....
1215-
1216-
If there are multiple subnets configured with auto-generated identifiers
1217-
and one of them is removed, the subnet identifiers may be renumbered.
1218-
For example: if there are four subnets and the third is removed, the
1219-
last subnet will be assigned the identifier that the third subnet had
1220-
before removal. As a result, the leases stored in the lease database for
1221-
subnet 3 are now associated with subnet 4, something that may have
1222-
unexpected consequences. It is one of the reasons why auto-generated subnet
1223-
identifiers are deprecated starting from Kea version 2.4.0.
1224-
1225-
.. note::
1226-
1227-
The auto-generation of the subnet identifiers will be removed in a future
1228-
release. Starting from Kea 2.4.0, a subnet without an ``id`` entry
1229-
or with the zero value raises a warning at the configuration time.
1210+
respective subnets. The server configuration must contain unique and stable
1211+
identifiers for all subnets.
12301212

12311213
.. note::
12321214

@@ -1247,10 +1229,6 @@ to a newly configured subnet:
12471229
]
12481230
}
12491231

1250-
This identifier will not change for this subnet unless the ``id``
1251-
parameter is removed or set to 0. The value of 0 forces auto-generation
1252-
of the subnet identifier.
1253-
12541232
.. _ipv4-subnet-prefix:
12551233

12561234
IPv4 Subnet Prefix

doc/sphinx/arm/dhcp6-srv.rst

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -988,26 +988,8 @@ IPv6 Subnet Identifier
988988

989989
The subnet identifier (subnet ID) is a unique number associated with a particular
990990
subnet. In principle, it is used to associate clients' leases with their
991-
respective subnets. The server configuration should contain unique and stable
992-
identifiers for all subnets. When a subnet identifier is not specified for a
993-
subnet, it is automatically assigned by the configuration mechanism. The identifiers
994-
are assigned starting at 1 and are monotonically increased for each subsequent
995-
subnet: 1, 2, 3, ....
996-
997-
If there are multiple subnets configured with auto-generated identifiers
998-
and one of them is removed, the subnet identifiers may be renumbered.
999-
For example: if there are four subnets and the third is removed, the
1000-
last subnet will be assigned the identifier that the third subnet had
1001-
before removal. As a result, the leases stored in the lease database for
1002-
subnet 3 are now associated with subnet 4, something that may have
1003-
unexpected consequences. It is one of the reasons why auto-generated subnet
1004-
identifiers are deprecated starting from Kea version 2.4.0.
1005-
1006-
.. note::
1007-
1008-
The auto-generation of the subnet identifiers will be removed in a future
1009-
release. Starting from Kea 2.4.0, a subnet without an ``id`` entry
1010-
or with the zero value raises a warning at the configuration time.
991+
respective subnets. The server configuration must contain unique and stable
992+
identifiers for all subnets.
1011993

1012994
.. note::
1013995

@@ -1028,10 +1010,6 @@ to a newly configured subnet:
10281010
]
10291011
}
10301012

1031-
This identifier will not change for this subnet unless the ``id``
1032-
parameter is removed or set to 0. The value of 0 forces auto-generation
1033-
of the subnet identifier.
1034-
10351013
.. _ipv6-subnet-prefix:
10361014

10371015
IPv6 Subnet Prefix

src/bin/dhcp4/json_config_parser.cc

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -327,10 +327,6 @@ void configureCommandChannel() {
327327
/// @param config_set the configuration being processed
328328
isc::data::ConstElementPtr
329329
processDhcp4Config(isc::data::ConstElementPtr config_set) {
330-
// Before starting any subnet operations, let's reset the subnet-id counter,
331-
// so newly recreated configuration starts with first subnet-id equal 1.
332-
Subnet::resetSubnetID();
333-
334330
// Revert any runtime option definitions configured so far and not committed.
335331
LibDHCP::revertRuntimeOptionDefs();
336332
// Let's set empty container in case a user hasn't specified any configuration

src/bin/dhcp6/json_config_parser.cc

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -429,10 +429,6 @@ void configureCommandChannel() {
429429
/// @param config_set the configuration being processed
430430
isc::data::ConstElementPtr
431431
processDhcp6Config(isc::data::ConstElementPtr config_set) {
432-
// Before starting any subnet operations, let's reset the subnet-id counter,
433-
// so newly recreated configuration starts with first subnet-id equal 1.
434-
Subnet::resetSubnetID();
435-
436432
// Revert any runtime option definitions configured so far and not committed.
437433
LibDHCP::revertRuntimeOptionDefs();
438434
// Let's set empty container in case a user hasn't specified any configuration

src/lib/dhcpsrv/parsers/dhcp_parsers.cc

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -730,11 +730,9 @@ Subnet4ConfigParser::parse(ConstElementPtr subnet, bool encapsulate_options) {
730730
void
731731
Subnet4ConfigParser::initSubnet(data::ConstElementPtr params,
732732
asiolink::IOAddress addr, uint8_t len) {
733-
// Subnet ID is optional. If it is not supplied the value of 0 is used,
734-
// which means autogenerate. The value was inserted earlier by calling
735-
// SimpleParser4::setAllDefaults.
733+
// Subnet ID is required and must be in 1..SUBNET_ID_MAX.
736734
int64_t subnet_id_max = static_cast<int64_t>(SUBNET_ID_MAX);
737-
SubnetID subnet_id = static_cast<SubnetID>(getInteger(params, "id", 0,
735+
SubnetID subnet_id = static_cast<SubnetID>(getInteger(params, "id", 1,
738736
subnet_id_max));
739737

740738
auto subnet4 = Subnet4::create(addr, len, Triplet<uint32_t>(),
@@ -1259,11 +1257,9 @@ Subnet6ConfigParser::duplicateOptionWarning(uint32_t code,
12591257
void
12601258
Subnet6ConfigParser::initSubnet(data::ConstElementPtr params,
12611259
asiolink::IOAddress addr, uint8_t len) {
1262-
// Subnet ID is optional. If it is not supplied the value of 0 is used,
1263-
// which means autogenerate. The value was inserted earlier by calling
1264-
// SimpleParser6::setAllDefaults.
1260+
// Subnet ID is required and must be in 1..SUBNET_ID_MAX.
12651261
int64_t subnet_id_max = static_cast<int64_t>(SUBNET_ID_MAX);
1266-
SubnetID subnet_id = static_cast<SubnetID>(getInteger(params, "id", 0,
1262+
SubnetID subnet_id = static_cast<SubnetID>(getInteger(params, "id", 1,
12671263
subnet_id_max));
12681264

12691265
// We want to log whether rapid-commit is enabled, so we get this

src/lib/dhcpsrv/parsers/simple_parser4.cc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,6 @@ const SimpleKeywords SimpleParser4::SUBNET4_PARAMETERS = {
270270
/// defined on global level. Currently there are two such parameters:
271271
/// interface and reservation-mode
272272
const SimpleDefaults SimpleParser4::SUBNET4_DEFAULTS = {
273-
{ "id", Element::integer, "0" }, // 0 means autogenerate
274273
{ "interface", Element::string, "" },
275274
{ "client-class", Element::string, "" },
276275
{ "4o6-interface", Element::string, "" },
@@ -285,7 +284,6 @@ const SimpleDefaults SimpleParser4::SUBNET4_DEFAULTS = {
285284
/// that can be derived from shared-network, but cannot from global scope.
286285
/// Those are: interface and reservation-mode.
287286
const SimpleDefaults SimpleParser4::SHARED_SUBNET4_DEFAULTS = {
288-
{ "id", Element::integer, "0" }, // 0 means autogenerate
289287
{ "4o6-interface", Element::string, "" },
290288
{ "4o6-interface-id", Element::string, "" },
291289
{ "4o6-subnet", Element::string, "" },

src/lib/dhcpsrv/parsers/simple_parser6.cc

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,6 @@ const SimpleKeywords SimpleParser6::SUBNET6_PARAMETERS = {
261261
/// where a parameter can be derived from shared-networks, but is not
262262
/// defined on global level.
263263
const SimpleDefaults SimpleParser6::SUBNET6_DEFAULTS = {
264-
{ "id", Element::integer, "0" }, // 0 means autogenerate
265264
{ "interface", Element::string, "" },
266265
{ "client-class", Element::string, "" },
267266
{ "rapid-commit", Element::boolean, "false" }, // rapid-commit disabled by default
@@ -274,7 +273,6 @@ const SimpleDefaults SimpleParser6::SUBNET6_DEFAULTS = {
274273
/// This is mostly the same as @ref SUBNET6_DEFAULTS, except the parameters
275274
/// that can be derived from shared-network, but cannot from global scope.
276275
const SimpleDefaults SimpleParser6::SHARED_SUBNET6_DEFAULTS = {
277-
{ "id", Element::integer, "0" } // 0 means autogenerate
278276
};
279277

280278
/// @brief This table defines default values for each IPv6 shared network.

src/lib/dhcpsrv/subnet.cc

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,21 +65,14 @@ comparePoolFirstAddress(const PoolPtr& pool1,
6565
namespace isc {
6666
namespace dhcp {
6767

68-
// This is an initial value of subnet-id. See comments in subnet.h for details.
69-
SubnetID Subnet::static_id_ = 1;
70-
7168
Subnet::Subnet(const isc::asiolink::IOAddress& prefix, uint8_t len,
7269
const SubnetID id)
73-
: id_(id == 0 ? generateNextID() : id), prefix_(prefix),
74-
prefix_len_(len),
75-
shared_network_name_() {
76-
if ((id == 0) && (id_ == 1)) {
77-
// Emit a warning on the first auto-numbered subnet.
78-
LOG_WARN(dhcpsrv_logger, DHCPSRV_CONFIGURED_SUBNET_WITHOUT_ID)
79-
.arg(toText());
80-
}
81-
if ((prefix.isV6() && len > 128) ||
82-
(prefix.isV4() && len > 32)) {
70+
: id_(id), prefix_(prefix), prefix_len_(len), shared_network_name_() {
71+
if ((id == SUBNET_ID_GLOBAL) || (id == SUBNET_ID_UNUSED)) {
72+
isc_throw(BadValue,
73+
"Invalid id specified for subnet: " << id);
74+
}
75+
if ((prefix.isV6() && len > 128) || (prefix.isV4() && len > 32)) {
8376
isc_throw(BadValue,
8477
"Invalid prefix length specified for subnet: " << len);
8578
}

src/lib/dhcpsrv/subnet.h

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -211,15 +211,6 @@ class Subnet : public virtual Network {
211211
/// @return textual representation
212212
virtual std::string toText() const;
213213

214-
/// @brief Resets subnet-id counter to its initial value (1).
215-
///
216-
/// This should be called during reconfiguration, before any new
217-
/// subnet objects are created. It will ensure that the subnet_id will
218-
/// be consistent between reconfigures.
219-
static void resetSubnetID() {
220-
static_id_ = 1;
221-
}
222-
223214
/// @brief Retrieves pointer to a shared network associated with a subnet.
224215
///
225216
/// By implementing it as a template function we overcome a need to
@@ -338,15 +329,9 @@ class Subnet : public virtual Network {
338329
/// By making the constructor protected, we make sure that no one will
339330
/// ever instantiate that class. Subnet4 and Subnet6 should be used instead.
340331
///
341-
/// This constructor assigns a new subnet-id (see @ref generateNextID).
342-
/// This subnet-id has unique value that is strictly monotonously increasing
343-
/// for each subnet, until it is explicitly reset back to 1 during
344-
/// reconfiguration process.
345-
///
346332
/// @param prefix subnet prefix
347333
/// @param len prefix length for the subnet
348-
/// @param id arbitrary subnet id, value of 0 triggers autogeneration
349-
/// of subnet id
334+
/// @param id arbitrary subnet id between 0 and 2^32-1 excluded.
350335
Subnet(const isc::asiolink::IOAddress& prefix, uint8_t len,
351336
const SubnetID id);
352337

@@ -356,31 +341,6 @@ class Subnet : public virtual Network {
356341
/// derive from this class.
357342
virtual ~Subnet() { };
358343

359-
/// @brief keeps the subnet-id value.
360-
///
361-
/// It is incremented every time a new Subnet object is created. It is reset
362-
/// (@ref resetSubnetID) every time reconfiguration
363-
/// occurs.
364-
///
365-
/// Static value initialized in subnet.cc.
366-
static SubnetID static_id_;
367-
368-
/// @brief returns the next unique Subnet-ID.
369-
///
370-
/// This method generates and returns the next unique subnet-id.
371-
/// It is a strictly monotonously increasing value (1,2,3,...) for
372-
/// each new Subnet object created. It can be explicitly reset
373-
/// back to 1 during reconfiguration (@ref resetSubnetID).
374-
///
375-
/// @return the next unique Subnet-ID
376-
static SubnetID generateNextID() {
377-
if (static_id_ == SUBNET_ID_MAX) {
378-
resetSubnetID();
379-
}
380-
381-
return (static_id_++);
382-
}
383-
384344
/// @brief Checks if used pool type is valid.
385345
///
386346
/// Allowed type for Subnet4 is Pool::TYPE_V4.

src/lib/dhcpsrv/tests/alloc_engine_utils.cc

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,6 @@ AllocEngine4Test::generateDeclinedLease(const std::string& addr,
171171
}
172172

173173
AllocEngine6Test::AllocEngine6Test() {
174-
// No longer used but this means too that tests relied far too much on it.
175-
//Subnet::resetSubnetID();
176-
177174
CfgMgr::instance().clear();
178175

179176
// This lease mgr needs to exist to before configuration commits.
@@ -649,9 +646,6 @@ AllocEngine4Test::initSubnet(const asiolink::IOAddress& pool_start,
649646
}
650647

651648
AllocEngine4Test::AllocEngine4Test() {
652-
// No longer used but this means too that tests relied far too much on it.
653-
//Subnet::resetSubnetID();
654-
655649
CfgMgr::instance().clear();
656650

657651
// This lease mgr needs to exist to before configuration commits.

src/lib/dhcpsrv/tests/cfg_subnets4_unittest.cc

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,6 +1298,78 @@ TEST(CfgSubnets4Test, hasSubnetWithServerId) {
12981298
EXPECT_FALSE(cfg.hasSubnetWithServerId(IOAddress("2.3.4.5")));
12991299
}
13001300

1301+
// This test verifies the Subnet4 parser's validation logic for id parameter.
1302+
TEST(CfgSubnets4Test, idValidation) {
1303+
{
1304+
// id 0.
1305+
SCOPED_TRACE("id 0");
1306+
std::string json =
1307+
" {\n"
1308+
" \"id\": 0,\n"
1309+
" \"subnet\": \"10.1.2.0/24\"\n"
1310+
" }\n";
1311+
data::ElementPtr elems;
1312+
ASSERT_NO_THROW(elems = data::Element::fromJSON(json))
1313+
<< "invalid JSON:" << json << "\n test is broken";
1314+
std::string expected = "subnet configuration failed: ";
1315+
expected += "The 'id' value (0) is not within ";
1316+
expected += "expected range: (1 - 4294967294)";
1317+
try {
1318+
// Attempt to parse the configuration.
1319+
Subnet4ConfigParser parser;
1320+
Subnet4Ptr subnet = parser.parse(elems);
1321+
ADD_FAILURE() << "expected exception";
1322+
} catch (const std::exception& ex) {
1323+
EXPECT_EQ(expected, ex.what());
1324+
}
1325+
}
1326+
1327+
{
1328+
// id 4294967295.
1329+
SCOPED_TRACE("id 4294967295");
1330+
std::string json =
1331+
" {\n"
1332+
" \"id\": 4294967295,\n"
1333+
" \"subnet\": \"10.1.2.0/24\"\n"
1334+
" }\n";
1335+
data::ElementPtr elems;
1336+
ASSERT_NO_THROW(elems = data::Element::fromJSON(json))
1337+
<< "invalid JSON:" << json << "\n test is broken";
1338+
std::string expected = "subnet configuration failed: ";
1339+
expected += "The 'id' value (4294967295) is not within ";
1340+
expected += "expected range: (1 - 4294967294)";
1341+
try {
1342+
// Attempt to parse the configuration.
1343+
Subnet4ConfigParser parser;
1344+
Subnet4Ptr subnet = parser.parse(elems);
1345+
ADD_FAILURE() << "expected exception";
1346+
} catch (const std::exception& ex) {
1347+
EXPECT_EQ(expected, ex.what());
1348+
}
1349+
}
1350+
1351+
{
1352+
// id 1 (valid).
1353+
SCOPED_TRACE("id 1");
1354+
std::string json =
1355+
" {\n"
1356+
" \"id\": 1,\n"
1357+
" \"subnet\": \"10.1.2.0/24\"\n"
1358+
" }\n";
1359+
data::ElementPtr elems;
1360+
ASSERT_NO_THROW(elems = data::Element::fromJSON(json))
1361+
<< "invalid JSON:" << json << "\n test is broken";
1362+
try {
1363+
// Attempt to parse the configuration.
1364+
Subnet4ConfigParser parser;
1365+
Subnet4Ptr subnet = parser.parse(elems);
1366+
EXPECT_TRUE(subnet);
1367+
} catch (const std::exception& ex) {
1368+
ADD_FAILURE() << "unexpected failure " << ex.what();
1369+
}
1370+
}
1371+
}
1372+
13011373
// This test verifies the Subnet4 parser's validation logic for
13021374
// t1-percent and t2-percent parameters.
13031375
TEST(CfgSubnets4Test, teeTimePercentValidation) {

0 commit comments

Comments
 (0)