From: Marcin Siodelski Date: Tue, 27 Sep 2016 17:43:42 +0000 (+0200) Subject: [github24] It is now possible to specify excluded prefix for a pool. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4709bf2d1ec53e13111436ea43c9d0106e81e142;p=thirdparty%2Fkea.git [github24] It is now possible to specify excluded prefix for a pool. This is to facilitate the use of Prefix Exclude option (RFC 6603). --- diff --git a/src/bin/dhcp6/dhcp6.spec b/src/bin/dhcp6/dhcp6.spec index 3571b8e2ac..6c0b169b93 100644 --- a/src/bin/dhcp6/dhcp6.spec +++ b/src/bin/dhcp6/dhcp6.spec @@ -500,6 +500,18 @@ "item_type": "integer", "item_optional": false, "item_default": 128 + }, + { + "item_name": "excluded-prefix", + "item_type": "string", + "item_optional": true, + "item_default": "" + }, + { + "item_name": "excluded-prefix-len", + "item_type": "integer", + "item_optional": true, + "item_default": 128 }] } }, diff --git a/src/bin/dhcp6/json_config_parser.cc b/src/bin/dhcp6/json_config_parser.cc index 4cf6bb6204..99f8bed7f4 100644 --- a/src/bin/dhcp6/json_config_parser.cc +++ b/src/bin/dhcp6/json_config_parser.cc @@ -172,11 +172,12 @@ public: BOOST_FOREACH(ConfigPair param, pd_pool_->mapValue()) { std::string entry(param.first); ParserPtr parser; - if (entry == "prefix") { + if (entry == "prefix" || entry =="excluded-prefix") { StringParserPtr str_parser(new StringParser(entry, string_values_)); parser = str_parser; - } else if (entry == "prefix-len" || entry == "delegated-len") { + } else if (entry == "prefix-len" || entry == "delegated-len" || + entry == "excluded-prefix-len") { Uint32ParserPtr code_parser(new Uint32Parser(entry, uint32_values_)); parser = code_parser; @@ -192,13 +193,18 @@ public: // Try to obtain the pool parameters. It will throw an exception if any // of the required parameters are not present or invalid. try { - std::string addr_str = string_values_->getParam("prefix"); - uint32_t prefix_len = uint32_values_->getParam("prefix-len"); - uint32_t delegated_len = uint32_values_->getParam("delegated-len"); + const std::string addr_str = string_values_->getParam("prefix"); + const uint32_t prefix_len = uint32_values_->getParam("prefix-len"); + const uint32_t delegated_len = uint32_values_->getParam("delegated-len"); + const std::string excluded_prefix_str = + string_values_->getOptionalParam("excluded-prefix", "::"); + const uint32_t excluded_prefix_len = + uint32_values_->getOptionalParam("excluded-prefix-len", 0); // Attempt to construct the local pool. - pool_.reset(new Pool6(Lease::TYPE_PD, IOAddress(addr_str), - prefix_len, delegated_len)); + pool_.reset(new Pool6(IOAddress(addr_str), prefix_len, + delegated_len, IOAddress(excluded_prefix_str), + excluded_prefix_len)); } catch (const std::exception& ex) { // Some parameters don't exist or are invalid. Since we are not // aware whether they don't exist or are invalid, let's append @@ -621,7 +627,8 @@ public: } if (!code) { - OptionDefinitionPtr def = LibDHCP::getOptionDef(Option::V6, option_str); + const OptionDefinitionPtr def = LibDHCP::getOptionDef(Option::V6, + option_str); if (def) { code = def->getCode(); } else { diff --git a/src/bin/dhcp6/tests/config_parser_unittest.cc b/src/bin/dhcp6/tests/config_parser_unittest.cc index cdee579cc1..92b2ee0bd6 100644 --- a/src/bin/dhcp6/tests/config_parser_unittest.cc +++ b/src/bin/dhcp6/tests/config_parser_unittest.cc @@ -1378,6 +1378,60 @@ TEST_F(Dhcp6ParserTest, pdPoolBasics) { EXPECT_EQ(lastAddrInPrefix(prefixAddress, 64), p6->getLastAddress()); } +// This test verifies that it is possible to specify a prefix pool with an +// excluded prefix (see RFC6603). +TEST_F(Dhcp6ParserTest, pdPoolPrefixExclude) { + + ConstElementPtr x; + + // Define a single valid pd pool. + string config = + "{ " + genIfaceConfig() + "," + "\"preferred-lifetime\": 3000," + "\"rebind-timer\": 2000, " + "\"renew-timer\": 1000, " + "\"subnet6\": [ { " + " \"subnet\": \"2001:db8:1::/64\"," + " \"pd-pools\": [" + " { \"prefix\": \"3000::\", " + " \"prefix-len\": 48, " + " \"delegated-len\": 64," + " \"excluded-prefix\": \"3000:1::\"," + " \"excluded-prefix-len\": 72" + " } ]," + "\"valid-lifetime\": 4000 }" + "] }"; + + // Convert the JSON string into Elements. + ElementPtr json; + ASSERT_NO_THROW(json = Element::fromJSON(config)); + + // Verify that DHCP6 configuration processing succeeds. + // Returned value must be non-empty ConstElementPtr to config result. + // rcode should be 0 which indicates successful configuration processing. + EXPECT_NO_THROW(x = configureDhcp6Server(srv_, json)); + checkResult(x, 0); + + // Test that we can retrieve the subnet. + Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()-> + selectSubnet(IOAddress("2001:db8:1::5"), classify_); + ASSERT_TRUE(subnet); + + // Fetch the collection of PD pools. It should have 1 entry. + PoolCollection pc; + ASSERT_NO_THROW(pc = subnet->getPools(Lease::TYPE_PD)); + EXPECT_EQ(1, pc.size()); + + // Get a pointer to the pd pool instance, and verify its contents. + Pool6Ptr p6; + ASSERT_NO_THROW(p6 = boost::dynamic_pointer_cast(pc[0])); + ASSERT_TRUE(p6); + EXPECT_EQ("3000::", p6->getFirstAddress().toText()); + EXPECT_EQ(64, p6->getLength()); + EXPECT_EQ("3000:1::", p6->getExcludedPrefix().toText()); + EXPECT_EQ(72, static_cast(p6->getExcludedPrefixLength())); +} + // Goal of this test is verify that a list of PD pools can be configured. // It also verifies that a subnet may be configured with both regular pools // and pd pools.