Commit f4ba8105 authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[3281] DHCPv6 configuration parser sets the subnet id specified by user.

parent 30a20ce2
// Copyright (C) 2012-2013 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2012-2014 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
......@@ -406,7 +406,8 @@ protected:
if ((config_id.compare("preferred-lifetime") == 0) ||
(config_id.compare("valid-lifetime") == 0) ||
(config_id.compare("renew-timer") == 0) ||
(config_id.compare("rebind-timer") == 0)) {
(config_id.compare("rebind-timer") == 0) ||
(config_id.compare("id") == 0)) {
parser = new Uint32Parser(config_id, uint32_values_);
} else if ((config_id.compare("subnet") == 0) ||
(config_id.compare("interface") == 0) ||
......@@ -480,6 +481,10 @@ protected:
Triplet<uint32_t> t2 = getParam("rebind-timer");
Triplet<uint32_t> pref = getParam("preferred-lifetime");
Triplet<uint32_t> valid = getParam("valid-lifetime");
// Subnet ID is optional. If it is not supplied the value of 0 is used,
// which means autogenerate.
SubnetID subnet_id =
static_cast<SubnetID>(uint32_values_->getOptionalParam("id", 0));
// Get interface-id option content. For now we support string
// represenation only
......@@ -518,7 +523,8 @@ protected:
LOG_INFO(dhcp6_logger, DHCP6_CONFIG_NEW_SUBNET).arg(tmp.str());
// Create a new subnet.
Subnet6* subnet6 = new Subnet6(addr, len, t1, t2, pref, valid);
Subnet6* subnet6 = new Subnet6(addr, len, t1, t2, pref, valid,
subnet_id);
// Configure interface-id for remote interfaces, if defined
if (!ifaceid.empty()) {
......
......@@ -207,6 +207,12 @@
"item_default": ""
},
{ "item_name": "id",
"item_type": "integer",
"item_optional": false,
"item_default": 0
},
{ "item_name": "interface",
"item_type": "string",
"item_optional": false,
......
......@@ -569,11 +569,10 @@ TEST_F(Dhcp6ParserTest, subnetGlobalDefaults) {
EXPECT_EQ(1, subnet->getID());
}
// Goal of this test is to verify that multiple subnets get unique
// subnet-ids. Also, test checks that it's possible to do reconfiguration
// multiple times.
TEST_F(Dhcp6ParserTest, multipleSubnets) {
ConstElementPtr x;
// Collection of four subnets for which ids should be autogenerated
// - ids are unspecified or set to 0.
string config = "{ \"interfaces\": [ \"*\" ],"
"\"preferred-lifetime\": 3000,"
"\"rebind-timer\": 2000, "
......@@ -584,7 +583,8 @@ TEST_F(Dhcp6ParserTest, multipleSubnets) {
" },"
" {"
" \"pool\": [ \"2001:db8:2::/80\" ],"
" \"subnet\": \"2001:db8:2::/64\" "
" \"subnet\": \"2001:db8:2::/64\", "
" \"id\": 0"
" },"
" {"
" \"pool\": [ \"2001:db8:3::/80\" ],"
......@@ -623,6 +623,101 @@ TEST_F(Dhcp6ParserTest, multipleSubnets) {
} while (++cnt < 10);
}
// This checks that it is possible to assign arbitrary ids for subnets.
TEST_F(Dhcp6ParserTest, multipleSubnetsExplicitIDs) {
ConstElementPtr x;
// Collection of four subnets for which ids should be autogenerated
// - ids are unspecified or set to 0.
string config = "{ \"interfaces\": [ \"*\" ],"
"\"preferred-lifetime\": 3000,"
"\"rebind-timer\": 2000, "
"\"renew-timer\": 1000, "
"\"subnet6\": [ { "
" \"pool\": [ \"2001:db8:1::/80\" ],"
" \"subnet\": \"2001:db8:1::/64\", "
" \"id\": 1024"
" },"
" {"
" \"pool\": [ \"2001:db8:2::/80\" ],"
" \"subnet\": \"2001:db8:2::/64\", "
" \"id\": 100"
" },"
" {"
" \"pool\": [ \"2001:db8:3::/80\" ],"
" \"subnet\": \"2001:db8:3::/64\", "
" \"id\": 1"
" },"
" {"
" \"pool\": [ \"2001:db8:4::/80\" ],"
" \"subnet\": \"2001:db8:4::/64\", "
" \"id\": 34"
" } ],"
"\"valid-lifetime\": 4000 }";
int cnt = 0; // Number of reconfigurations
do {
ElementPtr json = Element::fromJSON(config);
EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
ASSERT_TRUE(x);
comment_ = parseAnswer(rcode_, x);
ASSERT_EQ(0, rcode_);
const Subnet6Collection* subnets = CfgMgr::instance().getSubnets6();
ASSERT_TRUE(subnets);
ASSERT_EQ(4, subnets->size()); // We expect 4 subnets
// Check that subnet ids are as expected.
EXPECT_EQ(1024, subnets->at(0)->getID());
EXPECT_EQ(100, subnets->at(1)->getID());
EXPECT_EQ(1, subnets->at(2)->getID());
EXPECT_EQ(34, subnets->at(3)->getID());
// Repeat reconfiguration process 10 times and check that the subnet-id
// is set to the same value.
} while (++cnt < 10);
}
// CHeck that the configuration with two subnets having the same id is rejected.
TEST_F(Dhcp6ParserTest, multipleSubnetsOverlapingIDs) {
ConstElementPtr x;
// Four subnets, two of them have the same id.
string config = "{ \"interfaces\": [ \"*\" ],"
"\"preferred-lifetime\": 3000,"
"\"rebind-timer\": 2000, "
"\"renew-timer\": 1000, "
"\"subnet6\": [ { "
" \"pool\": [ \"2001:db8:1::/80\" ],"
" \"subnet\": \"2001:db8:1::/64\", "
" \"id\": 1024"
" },"
" {"
" \"pool\": [ \"2001:db8:2::/80\" ],"
" \"subnet\": \"2001:db8:2::/64\", "
" \"id\": 100"
" },"
" {"
" \"pool\": [ \"2001:db8:3::/80\" ],"
" \"subnet\": \"2001:db8:3::/64\", "
" \"id\": 1024"
" },"
" {"
" \"pool\": [ \"2001:db8:4::/80\" ],"
" \"subnet\": \"2001:db8:4::/64\", "
" \"id\": 34"
" } ],"
"\"valid-lifetime\": 4000 }";
ElementPtr json = Element::fromJSON(config);
EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
ASSERT_TRUE(x);
comment_ = parseAnswer(rcode_, x);
ASSERT_NE(rcode_, 0);
}
// Goal of this test is to verify that a previously configured subnet can be
// deleted in subsequent reconfiguration.
TEST_F(Dhcp6ParserTest, reconfigureRemoveSubnet) {
......@@ -635,19 +730,23 @@ TEST_F(Dhcp6ParserTest, reconfigureRemoveSubnet) {
"\"renew-timer\": 1000, "
"\"subnet6\": [ { "
" \"pool\": [ \"2001:db8:1::/80\" ],"
" \"subnet\": \"2001:db8:1::/64\" "
" \"subnet\": \"2001:db8:1::/64\", "
" \"id\": 1"
" },"
" {"
" \"pool\": [ \"2001:db8:2::/80\" ],"
" \"subnet\": \"2001:db8:2::/64\" "
" \"subnet\": \"2001:db8:2::/64\", "
" \"id\": 2"
" },"
" {"
" \"pool\": [ \"2001:db8:3::/80\" ],"
" \"subnet\": \"2001:db8:3::/64\" "
" \"subnet\": \"2001:db8:3::/64\", "
" \"id\": 3"
" },"
" {"
" \"pool\": [ \"2001:db8:4::/80\" ],"
" \"subnet\": \"2001:db8:4::/64\" "
" \"subnet\": \"2001:db8:4::/64\", "
" \"id\": 4"
" } ],"
"\"valid-lifetime\": 4000 }";
......@@ -658,15 +757,18 @@ TEST_F(Dhcp6ParserTest, reconfigureRemoveSubnet) {
"\"renew-timer\": 1000, "
"\"subnet6\": [ { "
" \"pool\": [ \"2001:db8:1::/80\" ],"
" \"subnet\": \"2001:db8:1::/64\" "
" \"subnet\": \"2001:db8:1::/64\", "
" \"id\": 1"
" },"
" {"
" \"pool\": [ \"2001:db8:2::/80\" ],"
" \"subnet\": \"2001:db8:2::/64\" "
" \"subnet\": \"2001:db8:2::/64\", "
" \"id\": 2"
" },"
" {"
" \"pool\": [ \"2001:db8:3::/80\" ],"
" \"subnet\": \"2001:db8:3::/64\" "
" \"subnet\": \"2001:db8:3::/64\", "
" \"id\": 3"
" } ],"
"\"valid-lifetime\": 4000 }";
......@@ -677,15 +779,18 @@ TEST_F(Dhcp6ParserTest, reconfigureRemoveSubnet) {
"\"renew-timer\": 1000, "
"\"subnet6\": [ { "
" \"pool\": [ \"2001:db8:1::/80\" ],"
" \"subnet\": \"2001:db8:1::/64\" "
" \"subnet\": \"2001:db8:1::/64\", "
" \"id\": 1"
" },"
" {"
" \"pool\": [ \"2001:db8:3::/80\" ],"
" \"subnet\": \"2001:db8:3::/64\" "
" \"subnet\": \"2001:db8:3::/64\", "
" \"id\": 3"
" },"
" {"
" \"pool\": [ \"2001:db8:4::/80\" ],"
" \"subnet\": \"2001:db8:4::/64\" "
" \"subnet\": \"2001:db8:4::/64\", "
" \"id\": 4"
" } ],"
"\"valid-lifetime\": 4000 }";
......@@ -720,7 +825,6 @@ TEST_F(Dhcp6ParserTest, reconfigureRemoveSubnet) {
/// CASE 2: Configure 4 subnets, then reconfigure and remove one
/// from in between (not first, not last)
#if 0
/// @todo: Uncomment subnet removal test as part of #3281.
json = Element::fromJSON(config4);
EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json));
......@@ -743,7 +847,6 @@ TEST_F(Dhcp6ParserTest, reconfigureRemoveSubnet) {
// The second subnet (with subnet-id = 2) is no longer there
EXPECT_EQ(3, subnets->at(1)->getID());
EXPECT_EQ(4, subnets->at(2)->getID());
#endif
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment