From: Marcin Siodelski Date: Wed, 26 Mar 2014 12:10:22 +0000 (+0100) Subject: [3281] DHCPv6 configuration parser sets the subnet id specified by user. X-Git-Tag: bind10-1.2.0rc1-release~25^2~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f4ba810511f61a1cefbeccd669f9c3cb40e07906;p=thirdparty%2Fkea.git [3281] DHCPv6 configuration parser sets the subnet id specified by user. --- diff --git a/src/bin/dhcp6/config_parser.cc b/src/bin/dhcp6/config_parser.cc index 2aa55134d1..9897f63c24 100644 --- a/src/bin/dhcp6/config_parser.cc +++ b/src/bin/dhcp6/config_parser.cc @@ -1,4 +1,4 @@ -// 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 t2 = getParam("rebind-timer"); Triplet pref = getParam("preferred-lifetime"); Triplet 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(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()) { diff --git a/src/bin/dhcp6/dhcp6.spec b/src/bin/dhcp6/dhcp6.spec index 7462daaaaf..5efc7403d7 100644 --- a/src/bin/dhcp6/dhcp6.spec +++ b/src/bin/dhcp6/dhcp6.spec @@ -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, diff --git a/src/bin/dhcp6/tests/config_parser_unittest.cc b/src/bin/dhcp6/tests/config_parser_unittest.cc index 3829609417..0476c88748 100644 --- a/src/bin/dhcp6/tests/config_parser_unittest.cc +++ b/src/bin/dhcp6/tests/config_parser_unittest.cc @@ -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 }