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

[3647] Allow for configuring pd pool which doesn't match the subnet.

parent 35be7340
...@@ -542,15 +542,19 @@ temporarily override a list of interface names and listen on all interfaces. ...@@ -542,15 +542,19 @@ temporarily override a list of interface names and listen on all interfaces.
<title>Subnet and Prefix Delegation Pools</title> <title>Subnet and Prefix Delegation Pools</title>
<para> <para>
Subnets may also be configured to delegate prefixes, as defined in Subnets may also be configured to delegate prefixes, as defined in
<ulink url="http://tools.ietf.org/html/rfc3633">RFC 3633</ulink>. <ulink url="http://tools.ietf.org/html/rfc3633">RFC 3633</ulink>.
A subnet may have one or more prefix delegation pools. Each pool has A subnet may have one or more prefix delegation pools. Each pool has
a prefixed address, which is specified as a prefix and a prefix length, a prefixed address, which is specified as a prefix and a prefix length,
as well as a delegated prefix length. <command>delegated-len</command> as well as a delegated prefix length. <command>delegated-len</command>
must not be shorter (that is it must be numerically greater or equal) must not be shorter (that is it must be numerically greater or equal)
than <command>prefix-len</command>. than <command>prefix-len</command>.
If both <command>delegated-len</command> If both <command>delegated-len</command>
and <command>prefix-len</command> are equal, the server will be able to and <command>prefix-len</command> are equal, the server will be able to
delegate only one prefix. A sample configuration is shown below: delegate only one prefix. The delegated <command>prefix</command> need
not match the <command>subnet</command> prefix.
</para>
<para> Below is a sample subnet configuration which enables prefix
delegation for the subnet:
<screen> <screen>
"Dhcp6": { "Dhcp6": {
"subnet6": [ "subnet6": [
...@@ -558,7 +562,7 @@ temporarily override a list of interface names and listen on all interfaces. ...@@ -558,7 +562,7 @@ temporarily override a list of interface names and listen on all interfaces.
"subnet": "2001:d8b:1::/64", "subnet": "2001:d8b:1::/64",
<userinput>"pd-pools": [ <userinput>"pd-pools": [
{ {
"prefix": "2001:db8:1::", "prefix": "3000:1::",
"prefix-len": 64, "prefix-len": 64,
"delegated-len": 96 "delegated-len": 96
} }
......
// Copyright (C) 2012-2014 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
// //
// Permission to use, copy, modify, and/or distribute this software for any // Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above // purpose with or without fee is hereby granted, provided that the above
...@@ -1259,10 +1259,13 @@ TEST_F(Dhcp6ParserTest, pdPoolList) { ...@@ -1259,10 +1259,13 @@ TEST_F(Dhcp6ParserTest, pdPoolList) {
ConstElementPtr x; ConstElementPtr x;
// We will configure three pools of prefixes for the subnet. Note that
// the 3rd prefix is out of the subnet prefix (the prefix doesn't match
// the subnet prefix).
const char* prefixes[] = { const char* prefixes[] = {
"2001:db8:1:1::", "2001:db8:1:1::",
"2001:db8:1:2::", "2001:db8:1:2::",
"2001:db8:1:3::" "3000:1:3::"
}; };
string config = string config =
...@@ -1282,7 +1285,7 @@ TEST_F(Dhcp6ParserTest, pdPoolList) { ...@@ -1282,7 +1285,7 @@ TEST_F(Dhcp6ParserTest, pdPoolList) {
" \"prefix-len\": 72, " " \"prefix-len\": 72, "
" \"delegated-len\": 88" " \"delegated-len\": 88"
" }," " },"
" { \"prefix\": \"2001:db8:1:03::\", " " { \"prefix\": \"3000:1:03::\", "
" \"prefix-len\": 72, " " \"prefix-len\": 72, "
" \"delegated-len\": 96" " \"delegated-len\": 96"
" }" " }"
...@@ -1443,20 +1446,6 @@ TEST_F(Dhcp6ParserTest, invalidPdPools) { ...@@ -1443,20 +1446,6 @@ TEST_F(Dhcp6ParserTest, invalidPdPools) {
" \"delegated-len\": 64" " \"delegated-len\": 64"
" } ]," " } ],"
"\"valid-lifetime\": 4000 }" "\"valid-lifetime\": 4000 }"
"] }",
// Pool is not within the subnet.
"{ \"interfaces\": [ \"*\" ],"
"\"preferred-lifetime\": 3000,"
"\"rebind-timer\": 2000, "
"\"renew-timer\": 1000, "
"\"subnet6\": [ { "
" \"subnet\": \"2001:db8:1::/64\","
" \"pd-pools\": ["
" { \"prefix\": \"2001:db8:77::\", "
" \"prefix-len\": 64, "
" \"delegated-len\": 128"
" } ],"
"\"valid-lifetime\": 4000 }"
"] }" "] }"
}; };
......
// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC")
// //
// Permission to use, copy, modify, and/or distribute this software for any // Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above // purpose with or without fee is hereby granted, provided that the above
...@@ -64,8 +64,17 @@ Dhcpv6MessageTest::requestLease(const std::string& config, ...@@ -64,8 +64,17 @@ Dhcpv6MessageTest::requestLease(const std::string& config,
// subnets. // subnets.
ASSERT_EQ(1, client.getLeaseNum()); ASSERT_EQ(1, client.getLeaseNum());
Lease6 lease_client = client.getLease(0); Lease6 lease_client = client.getLease(0);
ASSERT_TRUE(CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->
selectSubnet(lease_client.addr_, ClientClasses())); // Check if the lease belongs to one of the available pools.
bool pool_found = false;
for (int i = 0; i < subnets_num; ++i) {
if ((*subnets)[i]->getPool(lease_client.type_, lease_client.addr_)) {
pool_found = true;
break;
}
}
ASSERT_TRUE(pool_found);
// Check that the client's lease matches the information on the server // Check that the client's lease matches the information on the server
// side. // side.
Lease6Ptr lease_server = checkLease(lease_client); Lease6Ptr lease_server = checkLease(lease_client);
......
// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC")
// //
// Permission to use, copy, modify, and/or distribute this software for any // Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above // purpose with or without fee is hereby granted, provided that the above
...@@ -49,14 +49,14 @@ namespace { ...@@ -49,14 +49,14 @@ namespace {
/// - pools configured: 3000:3::/64 and 3000:4::/64 /// - pools configured: 3000:3::/64 and 3000:4::/64
/// - this specific configuration is used by tests using relays /// - this specific configuration is used by tests using relays
/// ///
/// - Configuration 5: /// - Configuration 4:
/// - only prefixes (no addresses) /// - only prefixes (no addresses)
/// - 2 subnets: 2001:db8:1::/40 and 2001:db8:2::/40 /// - 2 subnets: 2001:db8:1::/40 and 2001:db8:2::/40
/// - 2 prefix pools: 2001:db8:1::/72 and 2001:db8:2::/72 /// - 2 prefix pools: 3000::/72 and 2001:db8:2::/72
/// - 1 subnet for eth0 and 1 subnet for eth1 /// - 1 subnet for eth0 and 1 subnet for eth1
/// - this specific configuration is used by tests which don't use relays /// - this specific configuration is used by tests which don't use relays
/// ///
/// - Configuration 6: /// - Configuration 5:
/// - similar to Configuration 5 but with different subnets /// - similar to Configuration 5 but with different subnets
/// - 2 subnets: 2001:db8:3::/40 and 2001:db8:4::/40 /// - 2 subnets: 2001:db8:3::/40 and 2001:db8:4::/40
/// - 2 prefix pools: 2001:db8:3::/72 and 2001:db8:4::/72 /// - 2 prefix pools: 2001:db8:3::/72 and 2001:db8:4::/72
...@@ -146,7 +146,7 @@ const char* REBIND_CONFIGS[] = { ...@@ -146,7 +146,7 @@ const char* REBIND_CONFIGS[] = {
"\"renew-timer\": 1000, " "\"renew-timer\": 1000, "
"\"subnet6\": [ { " "\"subnet6\": [ { "
" \"pd-pools\": [" " \"pd-pools\": ["
" { \"prefix\": \"2001:db8:1:01::\", " " { \"prefix\": \"3000::\", "
" \"prefix-len\": 72, " " \"prefix-len\": 72, "
" \"delegated-len\": 80" " \"delegated-len\": 80"
" } ]," " } ],"
...@@ -156,7 +156,7 @@ const char* REBIND_CONFIGS[] = { ...@@ -156,7 +156,7 @@ const char* REBIND_CONFIGS[] = {
" }," " },"
" {" " {"
" \"pd-pools\": [" " \"pd-pools\": ["
" { \"prefix\": \"2001:db8:2:01::\", " " { \"prefix\": \"2001:db8:2::\", "
" \"prefix-len\": 72, " " \"prefix-len\": 72, "
" \"delegated-len\": 80" " \"delegated-len\": 80"
" } ]," " } ],"
...@@ -498,8 +498,6 @@ TEST_F(RebindTest, directClientPD) { ...@@ -498,8 +498,6 @@ TEST_F(RebindTest, directClientPD) {
// subnets. // subnets.
ASSERT_EQ(1, client.getLeaseNum()); ASSERT_EQ(1, client.getLeaseNum());
Lease6 lease_client2 = client.getLease(0); Lease6 lease_client2 = client.getLease(0);
ASSERT_TRUE(CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->
selectSubnet(lease_client2.addr_, ClientClasses()));
// The client's lease should have been extended. The client will // The client's lease should have been extended. The client will
// update the cltt to current time when the lease gets extended. // update the cltt to current time when the lease gets extended.
ASSERT_GE(lease_client2.cltt_ - lease_client.cltt_, 1000); ASSERT_GE(lease_client2.cltt_ - lease_client.cltt_, 1000);
......
// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC")
// //
// Permission to use, copy, modify, and/or distribute this software for any // Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above // purpose with or without fee is hereby granted, provided that the above
...@@ -27,8 +27,11 @@ namespace { ...@@ -27,8 +27,11 @@ namespace {
/// @brief Set of JSON configurations used by the SARR unit tests. /// @brief Set of JSON configurations used by the SARR unit tests.
/// ///
/// - Configuration 0: /// - Configuration 0:
/// - one subnet used on eth0 interface /// - one subnet 3000::/32 used on eth0 interface
/// - prefixes of length 64, delegated from the pool: 2001:db8:3::/48 /// - prefixes of length 64, delegated from the pool: 2001:db8:3::/48
/// - the delegated prefix was intentionally selected to not match the
/// subnet prefix, to test that the delegated prefix doesn't need to
/// match the subnet prefix
const char* CONFIGS[] = { const char* CONFIGS[] = {
// Configuration 0 // Configuration 0
"{ \"interfaces\": [ \"*\" ]," "{ \"interfaces\": [ \"*\" ],"
...@@ -41,7 +44,7 @@ const char* CONFIGS[] = { ...@@ -41,7 +44,7 @@ const char* CONFIGS[] = {
" \"prefix-len\": 48, " " \"prefix-len\": 48, "
" \"delegated-len\": 64" " \"delegated-len\": 64"
" } ]," " } ],"
" \"subnet\": \"2001:db8::/32\", " " \"subnet\": \"3000::/32\", "
" \"interface-id\": \"\"," " \"interface-id\": \"\","
" \"interface\": \"eth0\"" " \"interface\": \"eth0\""
" } ]," " } ],"
......
// Copyright (C) 2012-2014 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
// //
// Permission to use, copy, modify, and/or distribute this software for any // Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above // purpose with or without fee is hereby granted, provided that the above
...@@ -227,13 +227,21 @@ const PoolPtr Subnet::getPool(Lease::Type type, const isc::asiolink::IOAddress& ...@@ -227,13 +227,21 @@ const PoolPtr Subnet::getPool(Lease::Type type, const isc::asiolink::IOAddress&
void void
Subnet::addPool(const PoolPtr& pool) { Subnet::addPool(const PoolPtr& pool) {
IOAddress first_addr = pool->getFirstAddress(); // Check that the pool is in range with a subnet only if this is
IOAddress last_addr = pool->getLastAddress(); // not a pool of IPv6 prefixes. The IPv6 prefixes delegated for
// the particular subnet don't need to match the prefix of the
if (!inRange(first_addr) || !inRange(last_addr)) { // subnet.
isc_throw(BadValue, "Pool (" << first_addr << "-" << last_addr if (pool->getType() != Lease::TYPE_PD) {
<< " does not belong in this (" << prefix_ << "/" if (!inRange(pool->getFirstAddress()) || !inRange(pool->getLastAddress())) {
<< static_cast<int>(prefix_len_) << ") subnet"); isc_throw(BadValue, "a pool of type "
<< Lease::typeToText(pool->getType())
<< ", with the following address range: "
<< pool->getFirstAddress() << "-"
<< pool->getLastAddress() << " does not match "
<< " the prefix of a subnet: "
<< prefix_ << "/" << static_cast<int>(prefix_len_)
<< " to which it is being added");
}
} }
/// @todo: Check that pools do not overlap /// @todo: Check that pools do not overlap
......
// Copyright (C) 2012-2014 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
// //
// Permission to use, copy, modify, and/or distribute this software for any // Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above // purpose with or without fee is hereby granted, provided that the above
...@@ -150,8 +150,20 @@ public: ...@@ -150,8 +150,20 @@ public:
return (std::make_pair(prefix_, prefix_len_)); return (std::make_pair(prefix_, prefix_len_));
} }
/// @brief Adds a new pool. /// @brief Adds a new pool for the subnet.
///
/// This method checks that the address range represented by the pool
/// matches the subnet prefix, if the pool type is different than
/// IA_PD. The prefixes from the IA_PD pools don't need to match the
/// prefix from the subnet from which they are handed out to the
/// requesting router because the requesting router may use the
/// delegated prefixes in different networks (using different subnets).
///
/// @param pool pool to be added /// @param pool pool to be added
///
/// @throw isc::BadValue if the pool type is invalid or the pool
/// is not an IA_PD pool and the address range of this pool does not
/// match the subnet prefix.
void addPool(const PoolPtr& pool); void addPool(const PoolPtr& pool);
......
// Copyright (C) 2012-2014 Internet Systems Consortium, Inc. ("ISC") // Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
// //
// Permission to use, copy, modify, and/or distribute this software for any // Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above // purpose with or without fee is hereby granted, provided that the above
...@@ -464,14 +464,14 @@ TEST(Subnet6Test, Pool6InSubnet6) { ...@@ -464,14 +464,14 @@ TEST(Subnet6Test, Pool6InSubnet6) {
} }
// Check if Subnet6 supports different types of pools properly. // Check if Subnet6 supports different types of pools properly.
TEST(Subnet6Test, PoolTypes) { TEST(Subnet6Test, poolTypes) {
Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4)); Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));
PoolPtr pool1(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:1::"), 64)); PoolPtr pool1(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1:1::"), 64));
PoolPtr pool2(new Pool6(Lease::TYPE_TA, IOAddress("2001:db8:1:2::"), 64)); PoolPtr pool2(new Pool6(Lease::TYPE_TA, IOAddress("2001:db8:1:2::"), 64));
PoolPtr pool3(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8:1:3::"), 64)); PoolPtr pool3(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8:1:3::"), 64));
PoolPtr pool4(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8:1:4::"), 64)); PoolPtr pool4(new Pool6(Lease::TYPE_PD, IOAddress("3000:1::"), 64));
PoolPtr pool5(new Pool4(IOAddress("192.0.2.0"), 24)); PoolPtr pool5(new Pool4(IOAddress("192.0.2.0"), 24));
...@@ -525,7 +525,7 @@ TEST(Subnet6Test, PoolTypes) { ...@@ -525,7 +525,7 @@ TEST(Subnet6Test, PoolTypes) {
// With valid hint, it should return that hint // With valid hint, it should return that hint
EXPECT_EQ(pool3, subnet->getPool(Lease::TYPE_PD, IOAddress("2001:db8:1:3::1"))); EXPECT_EQ(pool3, subnet->getPool(Lease::TYPE_PD, IOAddress("2001:db8:1:3::1")));
EXPECT_EQ(pool4, subnet->getPool(Lease::TYPE_PD, IOAddress("2001:db8:1:4::1"))); EXPECT_EQ(pool4, subnet->getPool(Lease::TYPE_PD, IOAddress("3000:1::")));
// With invalid hint, it should return the first pool // With invalid hint, it should return the first pool
EXPECT_EQ(pool3, subnet->getPool(Lease::TYPE_PD, IOAddress("2001:db8::123"))); EXPECT_EQ(pool3, subnet->getPool(Lease::TYPE_PD, IOAddress("2001:db8::123")));
......
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