// include it if the pool configuration specifies this option.
Pool6Ptr pool = boost::dynamic_pointer_cast<
Pool6>(subnet->getPool(Lease::TYPE_PD, (*l)->addr_));
- if (pool && pool->getExcludedPrefixLength() > 0) {
- OptionPtr opt(new Option6PDExclude((*l)->addr_,
- (*l)->prefixlen_,
- pool->getExcludedPrefix(),
- pool->getExcludedPrefixLength()));
- addr->addOption(opt);
+ if (pool) {
+ Option6PDExcludePtr pd_exclude_option = pool->getPrefixExcludeOption();
+ if (pd_exclude_option) {
+ addr->addOption(pd_exclude_option);
+ }
}
}
}
Pool6Ptr pool = boost::dynamic_pointer_cast<
Pool6>(subnet->getPool(Lease::TYPE_PD, (*l)->addr_));
- if (pool && pool->getExcludedPrefixLength() > 0) {
- OptionPtr opt(new Option6PDExclude((*l)->addr_,
- (*l)->prefixlen_,
- pool->getExcludedPrefix(),
- pool->getExcludedPrefixLength()));
- prf->addOption(opt);
+ if (pool) {
+ Option6PDExcludePtr pd_exclude_option = pool->getPrefixExcludeOption();
+ if (pd_exclude_option) {
+ prf->addOption(pd_exclude_option);
+ }
}
}
" { \"prefix\": \"3000::\", "
" \"prefix-len\": 48, "
" \"delegated-len\": 64,"
- " \"excluded-prefix\": \"3000:1::\","
+ " \"excluded-prefix\": \"3000:0:0:0:1000::\","
" \"excluded-prefix-len\": 72"
" } ],"
"\"valid-lifetime\": 4000 }"
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<unsigned>(p6->getExcludedPrefixLength()));
+
+ // This pool should have Prefix Exclude option associated.
+ Option6PDExcludePtr pd_exclude_option = p6->getPrefixExcludeOption();
+ ASSERT_TRUE(pd_exclude_option);
+
+ // Pick a delegated prefix of 3000:0:0:3:1000::/64 which belongs to our
+ // pool of 3000::/48. For this prefix obtain a Prefix Exclude option and
+ // verify that it is correct.
+ EXPECT_EQ("3000:0:0:3:1000::",
+ pd_exclude_option->getExcludedPrefix(IOAddress("3000:0:0:3::"), 64).toText());
+ EXPECT_EQ(72, static_cast<unsigned>(pd_exclude_option->getExcludedPrefixLength()));
}
// Goal of this test is verify that a list of PD pools can be configured.
Pool6::Pool6(Lease::Type type, const isc::asiolink::IOAddress& first,
const isc::asiolink::IOAddress& last)
- : Pool(type, first, last), prefix_len_(128),
- excluded_prefix_(IOAddress::IPV6_ZERO_ADDRESS()),
- excluded_prefix_len_(0) {
+ : Pool(type, first, last), prefix_len_(128), pd_exclude_option_() {
// check if specified address boundaries are sane
if (!first.isV6() || !last.isV6()) {
Pool6::Pool6(Lease::Type type, const isc::asiolink::IOAddress& prefix,
const uint8_t prefix_len, const uint8_t delegated_len /* = 128 */)
: Pool(type, prefix, IOAddress::IPV6_ZERO_ADDRESS()),
- prefix_len_(delegated_len),
- excluded_prefix_(IOAddress::IPV6_ZERO_ADDRESS()),
- excluded_prefix_len_(0) {
+ prefix_len_(delegated_len), pd_exclude_option_() {
init(type, prefix, prefix_len, delegated_len,
IOAddress::IPV6_ZERO_ADDRESS(), 0);
const asiolink::IOAddress& excluded_prefix,
const uint8_t excluded_prefix_len)
: Pool(Lease::TYPE_PD, prefix, IOAddress::IPV6_ZERO_ADDRESS()),
- prefix_len_(delegated_len),
- excluded_prefix_(excluded_prefix),
- excluded_prefix_len_(excluded_prefix_len) {
+ prefix_len_(delegated_len), pd_exclude_option_() {
init(Lease::TYPE_PD, prefix, prefix_len, delegated_len, excluded_prefix,
excluded_prefix_len);
// The excluded prefix can only be specified using this constructor.
// Therefore, the initialization of the excluded prefix is takes place
// here, rather than in the init(...) function.
- if (!excluded_prefix_.isV6()) {
+ if (!excluded_prefix.isV6()) {
isc_throw(BadValue, "excluded prefix must be an IPv6 prefix");
}
// An "unspecified" prefix should have both value and length equal to 0.
- if ((excluded_prefix_.isV6Zero() && (excluded_prefix_len_ != 0)) ||
- (!excluded_prefix_.isV6Zero() && (excluded_prefix_len_ == 0))) {
+ if ((excluded_prefix.isV6Zero() && (excluded_prefix_len != 0)) ||
+ (!excluded_prefix.isV6Zero() && (excluded_prefix_len == 0))) {
isc_throw(BadValue, "invalid excluded prefix "
- << excluded_prefix_ << "/"
- << static_cast<unsigned>(excluded_prefix_len_));
+ << excluded_prefix << "/"
+ << static_cast<unsigned>(excluded_prefix_len));
}
// If excluded prefix has been specified.
- if (!excluded_prefix_.isV6Zero() && (excluded_prefix_len_ != 0)) {
+ if (!excluded_prefix.isV6Zero() && (excluded_prefix_len != 0)) {
// Excluded prefix length must not be greater than 128.
- if (excluded_prefix_len_ > 128) {
+ if (excluded_prefix_len > 128) {
isc_throw(BadValue, "excluded prefix length "
- << static_cast<unsigned>(excluded_prefix_len_)
+ << static_cast<unsigned>(excluded_prefix_len)
<< " must not be greater than 128");
}
// Excluded prefix must be a sub-prefix of a delegated prefix. First
// check the prefix length as it is less involved.
- if (excluded_prefix_len_ <= prefix_len_) {
+ if (excluded_prefix_len <= prefix_len_) {
isc_throw(BadValue, "excluded prefix length "
- << static_cast<unsigned>(excluded_prefix_len_)
+ << static_cast<unsigned>(excluded_prefix_len)
<< " must be lower than the delegated prefix length "
<< static_cast<unsigned>(prefix_len_));
}
const asiolink::IOAddress& prefix,
const uint8_t prefix_len,
const uint8_t delegated_len,
- const asiolink::IOAddress& /*excluded_prefix*/,
+ const asiolink::IOAddress& excluded_prefix,
const uint8_t excluded_prefix_len) {
// Check if the prefix is sane
if (!prefix.isV6()) {
// For addresses, we could use addrsInRange(prefix, last_), but it's
// much faster to do calculations on prefix lengths.
capacity_ = prefixesInRange(prefix_len, delegated_len);
+
+ // If user specified an excluded prefix, create an option that will
+ // be sent to clients obtaining prefixes from this pool.
+ if (excluded_prefix_len > 0) {
+ pd_exclude_option_.reset(new Option6PDExclude(prefix, delegated_len,
+ excluded_prefix,
+ excluded_prefix_len));
+ }
}
std::string
std::ostringstream s;
s << "type=" << Lease::typeToText(type_) << ", " << first_
<< "-" << last_ << ", delegated_len="
- << static_cast<int>(prefix_len_);
+ << static_cast<unsigned>(prefix_len_);
- if (excluded_prefix_len_ > 0) {
- s << ", excluded_prefix=" << excluded_prefix_
- << ", excluded_prefix_len="
- << static_cast<unsigned>(excluded_prefix_len_);
+ if (pd_exclude_option_) {
+ s << ", excluded_prefix_len="
+ << static_cast<unsigned>(pd_exclude_option_->getExcludedPrefixLength());
}
return (s.str());
}
#define POOL_H
#include <asiolink/io_address.h>
-#include <boost/shared_ptr.hpp>
+#include <dhcp/option6_pdexclude.h>
#include <dhcpsrv/cfg_option.h>
#include <dhcpsrv/lease.h>
+#include <boost/shared_ptr.hpp>
#include <vector>
return (prefix_len_);
}
- /// @brief Returns an excluded prefix.
- ///
- /// An excluded prefix can be specified for a prefix pool as specified
- /// in RFC6603.
+ /// @brief Returns instance of the pool specific Prefix Exclude option.
///
- /// @return Reference to an IOAddress object representing an excluded
- /// prefix pool. A value of '::' if the excluded prefix is not specified.
- const isc::asiolink::IOAddress& getExcludedPrefix() const{
- return (excluded_prefix_);
- }
-
- /// @brief Returns an excluded prefix length.
- ///
- /// An excluded prefix can be specified for a prefix pool as specified
- /// in RFC6603.
- ///
- /// @return Excluded prefix length in the range of 2 to 128, if the
- /// excluded prefix is specified. A value of 0 if the excluded prefix
- /// is not specified.
- uint8_t getExcludedPrefixLength() const{
- return (excluded_prefix_len_);
+ /// @return An instance of the Prefix Exclude option (RFC 6603) or NULL
+ /// if such option hasn't been specified for the pool.
+ Option6PDExcludePtr getPrefixExcludeOption() const {
+ return (pd_exclude_option_);
}
/// @brief returns textual representation of the pool
/// @brief Defines prefix length (for TYPE_PD only)
uint8_t prefix_len_;
- /// @brief The excluded prefix (RFC6603).
- ///
- /// This prefix can only be specified for DHCPv6 prefix pools.
- /// An "unspecified" prefix has a value of '::'.
- isc::asiolink::IOAddress excluded_prefix_;
+ /// @brief A pointer to the Prefix Exclude option (RFC 6603).
+ Option6PDExcludePtr pd_exclude_option_;
- /// @brief The excluded prefix length (RFC6603).
- ///
- /// This value can only be specified for DHCPv6 prefix pool.
- /// An "unspecified" prefix has a length of 0.
- uint8_t excluded_prefix_len_;
};
/// @brief a pointer an IPv6 Pool
#include <config.h>
#include <asiolink/io_address.h>
+#include <dhcp/option6_pdexclude.h>
#include <dhcpsrv/pool.h>
#include <boost/scoped_ptr.hpp>
// Create a pool with a good excluded prefix. The good excluded prefix
// is the one for which is a sub-prefix of the main prefix.
ASSERT_NO_THROW(pool.reset(new Pool6(IOAddress("2001:db8:1::"), 96, 112,
- IOAddress("2001:db8:1:2::"), 120)));
+ IOAddress("2001:db8:1::2000"), 120)));
// Verify pool properties.
EXPECT_EQ(Lease::TYPE_PD, pool->getType());
EXPECT_EQ(112, pool->getLength());
EXPECT_EQ("2001:db8:1::", pool->getFirstAddress().toText());
EXPECT_EQ("2001:db8:1::ffff:ffff", pool->getLastAddress().toText());
- EXPECT_EQ("2001:db8:1:2::", pool->getExcludedPrefix().toText());
- EXPECT_EQ(120, static_cast<unsigned>(pool->getExcludedPrefixLength()));
+
+ // It should include Prefix Exclude option.
+ Option6PDExcludePtr pd_exclude_option = pool->getPrefixExcludeOption();
+ ASSERT_TRUE(pd_exclude_option);
+ EXPECT_EQ("2001:db8:1::2:2000", pd_exclude_option->
+ getExcludedPrefix(IOAddress("2001:db8:1:0:0:0:2::"), 112).toText());
+ EXPECT_EQ(120, static_cast<unsigned>(pd_exclude_option->getExcludedPrefixLength()));
// Create another pool instance, but with the excluded prefix being
// "unspecified".
EXPECT_EQ(112, pool->getLength());
EXPECT_EQ("2001:db8:1::", pool->getFirstAddress().toText());
EXPECT_EQ("2001:db8:1::ffff:ffff", pool->getLastAddress().toText());
- EXPECT_TRUE(pool->getExcludedPrefix().isV6Zero());
- EXPECT_EQ(0, static_cast<unsigned>(pool->getExcludedPrefixLength()));
+
+ ASSERT_FALSE(pool->getPrefixExcludeOption());
// Excluded prefix length must be greater than the main prefix length.
EXPECT_THROW(Pool6(IOAddress("2001:db8:1::"), 96, 112,
Pool6 pool3(IOAddress("2001:db8:1::"), 96, 112,
IOAddress("2001:db8:1::1000"), 120);
EXPECT_EQ("type=IA_PD, 2001:db8:1::-2001:db8:1::ffff:ffff, delegated_len=112,"
- " excluded_prefix=2001:db8:1::1000, excluded_prefix_len=120",
+ " excluded_prefix_len=120",
pool3.toText());
}