Commit 58f5cf41 authored by Marcin Siodelski's avatar Marcin Siodelski

[3562] Addressed review comments.

parent 0ed7f6f0
......@@ -62,6 +62,12 @@ public:
/// DUID and HW address belong to the same client, until the client sends
/// a DHCP message.
///
/// Specifying both hardware address and DUID is allowed for this method
/// and results in returning all objects that are associated with hardware
/// address OR duid. For example: if one host is associated with the
/// specified hardware address and another host is associated with the
/// specified DUID, two hosts will be returned.
///
/// @param hwaddr HW address of the client or NULL if no HW address
/// available.
/// @param duid client id or NULL if not available, e.g. DHCPv4 client case.
......@@ -72,6 +78,12 @@ public:
/// @brief Non-const version of the @c getAll const method.
///
/// Specifying both hardware address and DUID is allowed for this method
/// and results in returning all objects that are associated with hardware
/// address OR duid. For example: if one host is associated with the
/// specified hardware address and another host is associated with the
/// specified DUID, two hosts will be returned.
///
/// @param hwaddr HW address of the client or NULL if no HW address
/// available.
/// @param duid client id or NULL if not available, e.g. DHCPv4 client case.
......
......@@ -160,12 +160,17 @@ CfgHosts::getHostInternal(const SubnetID& subnet_id, const bool subnet6,
void
CfgHosts::add(const HostPtr& host) {
/// @todo This may need to be sanity-checked. For example, a duplicate
// Sanity check that the host is non-null.
if (!host) {
isc_throw(BadValue, "specified host object must not be NULL when it"
" is added to the configuration");
}
/// @todo This may need further sanity checks. For example, a duplicate
/// should be rejected.
HWAddrPtr hwaddr = host->getHWAddress();
DuidPtr duid = host->getDuid();
// Check for duplicates for the specified IPv4 subnet.
if (get4(host->getIPv4SubnetID(), host->getHWAddress(), host->getDuid())) {
if (get4(host->getIPv4SubnetID(), hwaddr, duid)) {
isc_throw(DuplicateHost, "failed to add new host using the HW"
" address '" << (hwaddr ? hwaddr->toText(false) : "(null)")
<< " and DUID '" << (duid ? duid->toText() : "(null)")
......@@ -173,8 +178,7 @@ CfgHosts::add(const HostPtr& host) {
<< "' as this host has already been added");
// Checek for duplicates for the specified IPv6 subnet.
} else if (get6(host->getIPv6SubnetID(), host->getDuid(),
host->getHWAddress())) {
} else if (get6(host->getIPv6SubnetID(), duid, hwaddr)) {
isc_throw(DuplicateHost, "failed to add new host using the HW"
" address '" << (hwaddr ? hwaddr->toText(false) : "(null)")
<< " and DUID '" << (duid ? duid->toText() : "(null)")
......
......@@ -80,7 +80,7 @@ public:
///
/// @param address IPv4 address for which the @c Host object is searched.
///
/// @throw isc::NotImplemented.
/// @throw isc::NotImplemented.
virtual ConstHostCollection
getAll4(const asiolink::IOAddress& address) const;
......@@ -91,11 +91,12 @@ public:
///
/// @param address IPv4 address for which the @c Host object is searched.
///
/// @throw isc::NotImplemented
/// @throw isc::NotImplemented
virtual HostCollection
getAll4(const asiolink::IOAddress& address);
/// @brief Returns a host connected to the IPv4 subnet.
/// @brief Returns a host connected to the IPv4 subnet and matching
/// specified identifiers.
///
/// @param subnet_id Subnet identifier.
/// @param hwaddr HW address of the client or NULL if no HW address
......@@ -109,7 +110,8 @@ public:
get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr,
const DuidPtr& duid = DuidPtr()) const;
/// @brief Returns a host connected to the IPv4 subnet.
/// @brief Returns a host connected to the IPv4 subnet and matching
/// specified identifiers.
///
/// @param subnet_id Subnet identifier.
/// @param hwaddr HW address of the client or NULL if no HW address
......@@ -123,7 +125,8 @@ public:
get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr,
const DuidPtr& duid = DuidPtr());
/// @brief Returns a host connected to the IPv6 subnet.
/// @brief Returns a host connected to the IPv6 subnet and matching
/// the specified identifiers.
///
/// @param subnet_id Subnet identifier.
/// @param hwaddr HW address of the client or NULL if no HW address
......@@ -137,7 +140,8 @@ public:
get6(const SubnetID& subnet_id, const DuidPtr& duid,
const HWAddrPtr& hwaddr = HWAddrPtr()) const;
/// @brief Returns a host connected to the IPv6 subnet.
/// @brief Returns a host connected to the IPv6 subnet and matching the
/// specified identifiers.
///
/// @param subnet_id Subnet identifier.
/// @param hwaddr HW address of the client or NULL if no HW address
......@@ -156,7 +160,7 @@ public:
/// @param prefix IPv6 prefix for which the @c Host object is searched.
/// @param prefix_len IPv6 prefix length.
///
/// @throw isc::NotImplemented.
/// @throw isc::NotImplemented
virtual ConstHostPtr
get6(const asiolink::IOAddress& prefix, const uint8_t prefix_len) const;
......@@ -165,7 +169,7 @@ public:
/// @param prefix IPv6 prefix for which the @c Host object is searched.
/// @param prefix_len IPv6 prefix length.
///
/// @throw isc::NotImplemented.
/// @throw isc::NotImplemented
virtual HostPtr
get6(const asiolink::IOAddress& prefix, const uint8_t prefix_len);
......
......@@ -20,15 +20,17 @@
namespace isc {
namespace dhcp {
IPv6Resrv::IPv6Resrv(const asiolink::IOAddress& prefix,
IPv6Resrv::IPv6Resrv(const Type& type,
const asiolink::IOAddress& prefix,
const uint8_t prefix_len)
: prefix_(asiolink::IOAddress("::")), prefix_len_(128) {
: type_(type), prefix_(asiolink::IOAddress("::")), prefix_len_(128) {
// Validate and set the actual values.
set(prefix, prefix_len);
set(type, prefix, prefix_len);
}
void
IPv6Resrv::set(const asiolink::IOAddress& prefix, const uint8_t prefix_len) {
IPv6Resrv::set(const Type& type, const asiolink::IOAddress& prefix,
const uint8_t prefix_len) {
if (!prefix.isV6() || prefix.isV6Multicast()) {
isc_throw(isc::BadValue, "invalid prefix '" << prefix
<< "' for new IPv6 reservation");
......@@ -37,8 +39,14 @@ IPv6Resrv::set(const asiolink::IOAddress& prefix, const uint8_t prefix_len) {
isc_throw(isc::BadValue, "invalid prefix length '"
<< static_cast<int>(prefix_len)
<< "' for new IPv6 reservation");
} else if ((type == TYPE_NA) && (prefix_len != 128)) {
isc_throw(isc::BadValue, "invalid prefix length '"
<< static_cast<int>(prefix_len)
<< "' for reserved IPv6 address, expected 128");
}
type_ = type;
prefix_ = prefix;
prefix_len_ = prefix_len;
}
......@@ -56,7 +64,8 @@ IPv6Resrv::toText() const {
bool
IPv6Resrv::operator==(const IPv6Resrv& other) const {
return (prefix_ == other.prefix_ &&
return (type_ == other.type_ &&
prefix_ == other.prefix_ &&
prefix_len_ == other.prefix_len_);
}
......
......@@ -55,12 +55,14 @@ public:
/// of 128 is used. This value indicates that the reservation is made
/// for an IPv6 address.
///
/// @param type Reservation type: NA or PD.
/// @param prefix Address or prefix to be reserved.
/// @param prefix_len Prefix length.
///
/// @throw isc::BadValue if prefix is not IPv6 prefix, is a
/// multicast address or the prefix length is greater than 128.
IPv6Resrv(const asiolink::IOAddress& prefix,
IPv6Resrv(const Type& type,
const asiolink::IOAddress& prefix,
const uint8_t prefix_len = 128);
/// @brief Returns prefix for the reservation.
......@@ -79,17 +81,19 @@ public:
///
/// @return NA for prefix length equal to 128, PD otherwise.
Type getType() const {
return (prefix_len_ == 128 ? TYPE_NA : TYPE_PD);
return (type_);
}
/// @brief Sets a new prefix and prefix length.
///
/// @param type Reservation type: NA or PD.
/// @param prefix New prefix.
/// @param prefix_len New prefix length.
///
/// @throw isc::BadValue if prefix is not IPv6 prefix, is a
/// multicast address or the prefix length is greater than 128.
void set(const asiolink::IOAddress& prefix, const uint8_t prefix_len);
void set(const Type& type, const asiolink::IOAddress& prefix,
const uint8_t prefix_len);
/// @brief Returns information about the reservation in the textual format.
std::string toText() const;
......@@ -105,6 +109,8 @@ public:
bool operator!=(const IPv6Resrv& other) const;
private:
Type type_; ///< Reservation type.
asiolink::IOAddress prefix_; ///< Prefix
uint8_t prefix_len_; ///< Prefix length.
......@@ -137,7 +143,10 @@ typedef std::pair<IPv6ResrvIterator, IPv6ResrvIterator> IPv6ResrvRange;
/// interfaces. For the MAC address based reservations, each interface on a
/// network device maps to a single @c Host object as each @c Host object
/// contains at most one MAC address. So, it is possible that a single
/// device is associated with multiple distinct @c Host objects.
/// device is associated with multiple distinct @c Host objects if the
/// device has multiple interfaces. Under normal circumstances, a non-mobile
/// dual stack device using one interface should be represented by a single
/// @c Host object.
///
/// A DHCPv6 DUID is common for all interfaces on a device. Therefore, for
/// DUID based reservations a @c Host object may represent a network device with
......
......@@ -69,6 +69,9 @@ typedef boost::multi_index_container<
> HostContainer;
/// @brief First index type in the @c HostContainer.
///
/// This index allows for searching for @c Host objects using an
/// identifier + identifier type tuple.
typedef HostContainer::nth_index<0>::type HostContainerIndex0;
/// @brief Results range returned using the @c HostContainerIndex0.
......
......@@ -132,6 +132,7 @@ HostReservationParser6::build(isc::data::ConstElementPtr reservation_data) {
try {
// For the IPv6 address the prefix length is 128 and the
// value specified in the list is a reserved address.
IPv6Resrv::Type resrv_type = IPv6Resrv::TYPE_NA;
std::string prefix = prefix_element->stringValue();
uint8_t prefix_len = 128;
......@@ -172,10 +173,14 @@ HostReservationParser6::build(isc::data::ConstElementPtr reservation_data) {
// Remove the slash character and the prefix length
// from the parsed value.
prefix.erase(len_pos);
// Finally, set the reservation type.
resrv_type = IPv6Resrv::TYPE_PD;
}
// Create a reservation for an address or prefix.
host_->addReservation(IPv6Resrv(IOAddress(prefix),
host_->addReservation(IPv6Resrv(resrv_type,
IOAddress(prefix),
prefix_len));
} catch (const std::exception& ex) {
......
......@@ -245,7 +245,8 @@ TEST_F(CfgHostsTest, get6) {
"hw-address",
SubnetID(10), SubnetID(1 + i % 2),
IOAddress("0.0.0.0")));
host->addReservation(IPv6Resrv(increase(IOAddress("2001:db8:1::1"),
host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_NA,
increase(IOAddress("2001:db8:1::1"),
i)));
cfg.add(host);
......@@ -253,7 +254,8 @@ TEST_F(CfgHostsTest, get6) {
host = HostPtr(new Host(duids_[i]->toText(), "duid",
SubnetID(10), SubnetID(1 + i % 2),
IOAddress("0.0.0.0")));
host->addReservation(IPv6Resrv(increase(IOAddress("2001:db8:2::1"),
host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_NA,
increase(IOAddress("2001:db8:2::1"),
i)));
cfg.add(host);
}
......
......@@ -206,17 +206,21 @@ TEST_F(HostReservationParserTest, dhcp6HWaddr) {
getIPv6Reservations(IPv6Resrv::TYPE_NA);
ASSERT_EQ(2, std::distance(addresses.first, addresses.second));
EXPECT_TRUE(reservationExists(IPv6Resrv(IOAddress("2001:db8:1::1")),
EXPECT_TRUE(reservationExists(IPv6Resrv(IPv6Resrv::TYPE_NA,
IOAddress("2001:db8:1::1")),
addresses));
EXPECT_TRUE(reservationExists(IPv6Resrv(IOAddress("2001:db8:1::2")),
EXPECT_TRUE(reservationExists(IPv6Resrv(IPv6Resrv::TYPE_NA,
IOAddress("2001:db8:1::2")),
addresses));
IPv6ResrvRange prefixes = hosts[0]->getIPv6Reservations(IPv6Resrv::TYPE_PD);
ASSERT_EQ(2, std::distance(prefixes.first, prefixes.second));
EXPECT_TRUE(reservationExists(IPv6Resrv(IOAddress("2001:db8:2000:0101::"),
EXPECT_TRUE(reservationExists(IPv6Resrv(IPv6Resrv::TYPE_PD,
IOAddress("2001:db8:2000:0101::"),
64),
prefixes));
EXPECT_TRUE(reservationExists(IPv6Resrv(IOAddress("2001:db8:2000:0102::"),
EXPECT_TRUE(reservationExists(IPv6Resrv(IPv6Resrv::TYPE_PD,
IOAddress("2001:db8:2000:0102::"),
64),
prefixes));
......@@ -249,9 +253,11 @@ TEST_F(HostReservationParserTest, dhcp6DUID) {
getIPv6Reservations(IPv6Resrv::TYPE_NA);
ASSERT_EQ(2, std::distance(addresses.first, addresses.second));
EXPECT_TRUE(reservationExists(IPv6Resrv(IOAddress("2001:db8:1::100")),
EXPECT_TRUE(reservationExists(IPv6Resrv(IPv6Resrv::TYPE_NA,
IOAddress("2001:db8:1::100")),
addresses));
EXPECT_TRUE(reservationExists(IPv6Resrv(IOAddress("2001:db8:1::200")),
EXPECT_TRUE(reservationExists(IPv6Resrv(IPv6Resrv::TYPE_NA,
IOAddress("2001:db8:1::200")),
addresses));
IPv6ResrvRange prefixes = hosts[0]->getIPv6Reservations(IPv6Resrv::TYPE_PD);
......
......@@ -27,7 +27,7 @@ namespace {
// This test verifies that it is possible to create IPv6 address
// reservation.
TEST(IPv6ResrvTest, constructorAddress) {
IPv6Resrv resrv(IOAddress("2001:db8:1::cafe"));
IPv6Resrv resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8:1::cafe"));
EXPECT_EQ("2001:db8:1::cafe", resrv.getPrefix().toText());
EXPECT_EQ(128, resrv.getPrefixLen());
EXPECT_EQ(IPv6Resrv::TYPE_NA, resrv.getType());
......@@ -36,7 +36,7 @@ TEST(IPv6ResrvTest, constructorAddress) {
// This test verifies that it is possible to create IPv6 prefix
// reservation.
TEST(IPv6ResrvTest, constructorPrefix) {
IPv6Resrv resrv(IOAddress("2001:db8:1::"), 64);
IPv6Resrv resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8:1::"), 64);
EXPECT_EQ("2001:db8:1::", resrv.getPrefix().toText());
EXPECT_EQ(64, resrv.getPrefixLen());
EXPECT_EQ(IPv6Resrv::TYPE_PD, resrv.getType());
......@@ -44,75 +44,88 @@ TEST(IPv6ResrvTest, constructorPrefix) {
// This test verifies that the toText() function prints correctly.
TEST(IPv6ResrvTest, toText) {
IPv6Resrv resrv_prefix(IOAddress("2001:db8:1::"), 64);
IPv6Resrv resrv_prefix(IPv6Resrv::TYPE_PD, IOAddress("2001:db8:1::"), 64);
EXPECT_EQ("2001:db8:1::/64", resrv_prefix.toText());
IPv6Resrv resrv_address(IOAddress("2001:db8:111::23"));
IPv6Resrv resrv_address(IPv6Resrv::TYPE_NA, IOAddress("2001:db8:111::23"));
EXPECT_EQ("2001:db8:111::23", resrv_address.toText());
}
// This test verifies that invalid prefix is rejected.
TEST(IPv6ResrvTest, constructorInvalidPrefix) {
// IPv4 address is invalid for IPv6 reservation.
EXPECT_THROW(IPv6Resrv(IOAddress("10.0.0.1"), 128), isc::BadValue);
EXPECT_THROW(IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("10.0.0.1"), 128),
isc::BadValue);
// Multicast address is invalid for IPv6 reservation.
EXPECT_THROW(IPv6Resrv(IOAddress("ff02:1::2"), 128), isc::BadValue);
EXPECT_THROW(IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("ff02:1::2"), 128),
isc::BadValue);
}
// This test verifies that invalid prefix length is rejected.
TEST(IPv6ResrvTest, constructiorInvalidPrefixLength) {
ASSERT_NO_THROW(IPv6Resrv(IOAddress("2001:db8:1::"), 128));
EXPECT_THROW(IPv6Resrv(IOAddress("2001:db8:1::"), 129), isc::BadValue);
EXPECT_THROW(IPv6Resrv(IOAddress("2001:db8:1::"), 244), isc::BadValue);
ASSERT_NO_THROW(IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8:1::"),
128));
EXPECT_THROW(IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8:1::"), 129),
isc::BadValue);
EXPECT_THROW(IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8:1::"), 244),
isc::BadValue);
EXPECT_THROW(IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8:1::"), 64),
isc::BadValue);
}
// This test verifies that it is possible to modify prefix and its
// length in an existing reservation.
TEST(IPv6ResrvTest, setPrefix) {
// Create a reservation using an address and prefix length 128.
IPv6Resrv resrv(IOAddress("2001:db8:1::1"));
IPv6Resrv resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8:1::1"));
ASSERT_EQ("2001:db8:1::1", resrv.getPrefix().toText());
ASSERT_EQ(128, resrv.getPrefixLen());
ASSERT_EQ(IPv6Resrv::TYPE_NA, resrv.getType());
// Modify the reservation to use a prefix having a length of 48.
ASSERT_NO_THROW(resrv.set(IOAddress("2001:db8::"), 48));
ASSERT_NO_THROW(resrv.set(IPv6Resrv::TYPE_PD, IOAddress("2001:db8::"), 48));
EXPECT_EQ("2001:db8::", resrv.getPrefix().toText());
EXPECT_EQ(48, resrv.getPrefixLen());
EXPECT_EQ(IPv6Resrv::TYPE_PD, resrv.getType());
// IPv4 address is invalid for IPv6 reservation.
EXPECT_THROW(resrv.set(IOAddress("10.0.0.1"), 128), isc::BadValue);
EXPECT_THROW(resrv.set(IPv6Resrv::TYPE_NA, IOAddress("10.0.0.1"), 128),
isc::BadValue);
// IPv6 multicast address is invalid for IPv6 reservation.
EXPECT_THROW(resrv.set(IOAddress("ff02::1:2"), 128), isc::BadValue);
EXPECT_THROW(resrv.set(IPv6Resrv::TYPE_NA, IOAddress("ff02::1:2"), 128),
isc::BadValue);
// Prefix length greater than 128 is invalid.
EXPECT_THROW(resrv.set(IOAddress("2001:db8:1::"), 129), isc::BadValue);
EXPECT_THROW(resrv.set(IPv6Resrv::TYPE_PD, IOAddress("2001:db8:1::"), 129),
isc::BadValue);
}
// This test checks that the equality operators work fine.
TEST(IPv6ResrvTest, equal) {
EXPECT_TRUE(IPv6Resrv(IOAddress("2001:db8::"), 64) ==
IPv6Resrv(IOAddress("2001:db8::"), 64));
EXPECT_FALSE(IPv6Resrv(IOAddress("2001:db8::"), 64) !=
IPv6Resrv(IOAddress("2001:db8::"), 64));
EXPECT_TRUE(IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8::"), 64) ==
IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8::"), 64));
EXPECT_FALSE(IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8::"), 64) !=
IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8::"), 64));
EXPECT_TRUE(IPv6Resrv(IOAddress("2001:db8::1")) ==
IPv6Resrv(IOAddress("2001:db8::1")));
EXPECT_FALSE(IPv6Resrv(IOAddress("2001:db8::1")) !=
IPv6Resrv(IOAddress("2001:db8::1")));
EXPECT_TRUE(IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::1")) ==
IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::1")));
EXPECT_FALSE(IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::1")) !=
IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::1")));
EXPECT_FALSE(IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::1")) ==
IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::2")));
EXPECT_TRUE(IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::1")) !=
IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::2")));
EXPECT_FALSE(IPv6Resrv(IOAddress("2001:db8::1")) ==
IPv6Resrv(IOAddress("2001:db8::2")));
EXPECT_TRUE(IPv6Resrv(IOAddress("2001:db8::1")) !=
IPv6Resrv(IOAddress("2001:db8::2")));
EXPECT_FALSE(IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8::"), 64) ==
IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8::"), 48));
EXPECT_TRUE(IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8::"), 64) !=
IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8::"), 48));
EXPECT_FALSE(IPv6Resrv(IOAddress("2001:db8::"), 64) ==
IPv6Resrv(IOAddress("2001:db8::"), 48));
EXPECT_TRUE(IPv6Resrv(IOAddress("2001:db8::"), 64) !=
IPv6Resrv(IOAddress("2001:db8::"), 48));
EXPECT_FALSE(IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::1"), 128) ==
IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8::1"), 128));
EXPECT_TRUE(IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::1"), 128) !=
IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8::1"), 128));
}
......@@ -342,35 +355,47 @@ TEST(HostTest, addReservations) {
// Add 4 reservations: 2 for NAs, 2 for PDs.
ASSERT_NO_THROW(
host->addReservation(IPv6Resrv(IOAddress("2001:db8:1::cafe")));
host->addReservation(IPv6Resrv(IOAddress("2001:db8:1:1::"), 64));
host->addReservation(IPv6Resrv(IOAddress("2001:db8:1:2::"), 64));
host->addReservation(IPv6Resrv(IOAddress("2001:db8:1::1")));
host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_NA,
IOAddress("2001:db8:1::cafe")));
host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_PD,
IOAddress("2001:db8:1:1::"), 64));
host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_PD,
IOAddress("2001:db8:1:2::"), 64));
host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_NA,
IOAddress("2001:db8:1::1")));
);
// Check that reservations exist.
EXPECT_TRUE(host->hasReservation(IPv6Resrv(IOAddress("2001:db8:1::cafe"))));
EXPECT_TRUE(host->hasReservation(IPv6Resrv(IOAddress("2001:db8:1:1::"),
EXPECT_TRUE(host->hasReservation(IPv6Resrv(IPv6Resrv::TYPE_NA,
IOAddress("2001:db8:1::cafe"))));
EXPECT_TRUE(host->hasReservation(IPv6Resrv(IPv6Resrv::TYPE_PD,
IOAddress("2001:db8:1:1::"),
64)));
EXPECT_TRUE(host->hasReservation(IPv6Resrv(IOAddress("2001:db8:1:2::"),
EXPECT_TRUE(host->hasReservation(IPv6Resrv(IPv6Resrv::TYPE_PD,
IOAddress("2001:db8:1:2::"),
64)));
EXPECT_TRUE(host->hasReservation(IPv6Resrv(IOAddress("2001:db8:1::1"))));
EXPECT_TRUE(host->hasReservation(IPv6Resrv(IPv6Resrv::TYPE_NA,
IOAddress("2001:db8:1::1"))));
// Get only NA reservations.
IPv6ResrvRange addresses = host->getIPv6Reservations(IPv6Resrv::TYPE_NA);
ASSERT_EQ(2, std::distance(addresses.first, addresses.second));
EXPECT_TRUE(reservationExists(IPv6Resrv(IOAddress("2001:db8:1::cafe")),
EXPECT_TRUE(reservationExists(IPv6Resrv(IPv6Resrv::TYPE_NA,
IOAddress("2001:db8:1::cafe")),
addresses));
EXPECT_TRUE(reservationExists(IPv6Resrv(IOAddress("2001:db8:1::1")),
EXPECT_TRUE(reservationExists(IPv6Resrv(IPv6Resrv::TYPE_NA,
IOAddress("2001:db8:1::1")),
addresses));
// Get only PD reservations.
IPv6ResrvRange prefixes = host->getIPv6Reservations(IPv6Resrv::TYPE_PD);
ASSERT_EQ(2, std::distance(prefixes.first, prefixes.second));
EXPECT_TRUE(reservationExists(IPv6Resrv(IOAddress("2001:db8:1:1::"), 64),
EXPECT_TRUE(reservationExists(IPv6Resrv(IPv6Resrv::TYPE_PD,
IOAddress("2001:db8:1:1::"), 64),
prefixes));
EXPECT_TRUE(reservationExists(IPv6Resrv(IOAddress("2001:db8:1:2::"), 64),
EXPECT_TRUE(reservationExists(IPv6Resrv(IPv6Resrv::TYPE_PD,
IOAddress("2001:db8:1:2::"), 64),
prefixes));
}
......
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