extern const isc::log::MessageID MYSQL_LB_SFLQ_CREATE_POOL6 = "MYSQL_LB_SFLQ_CREATE_POOL6";
extern const isc::log::MessageID MYSQL_LB_SFLQ_PICK_LEASE4 = "MYSQL_LB_SFLQ_PICK_LEASE4";
extern const isc::log::MessageID MYSQL_LB_SFLQ_PICK_LEASE6 = "MYSQL_LB_SFLQ_PICK_LEASE6";
+extern const isc::log::MessageID MYSQL_LB_SFLQ_POOL4_DELETE = "MYSQL_LB_SFLQ_POOL4_DELETE";
+extern const isc::log::MessageID MYSQL_LB_SFLQ_POOL4_GET_ALL = "MYSQL_LB_SFLQ_POOL4_GET_ALL";
+extern const isc::log::MessageID MYSQL_LB_SFLQ_POOL4_GET_BY_RANGE = "MYSQL_LB_SFLQ_POOL4_GET_BY_RANGE";
+extern const isc::log::MessageID MYSQL_LB_SFLQ_POOL4_GET_BY_SUBNET = "MYSQL_LB_SFLQ_POOL4_GET_BY_SUBNET";
+extern const isc::log::MessageID MYSQL_LB_SFLQ_POOL6_DELETE = "MYSQL_LB_SFLQ_POOL6_DELETE";
+extern const isc::log::MessageID MYSQL_LB_SFLQ_POOL6_GET_ALL = "MYSQL_LB_SFLQ_POOL6_GET_ALL";
+extern const isc::log::MessageID MYSQL_LB_SFLQ_POOL6_GET_BY_RANGE = "MYSQL_LB_SFLQ_POOL6_GET_BY_RANGE";
+extern const isc::log::MessageID MYSQL_LB_SFLQ_POOL6_GET_BY_SUBNET = "MYSQL_LB_SFLQ_POOL6_GET_BY_SUBNET";
extern const isc::log::MessageID MYSQL_LB_TLS_CIPHER = "MYSQL_LB_TLS_CIPHER";
extern const isc::log::MessageID MYSQL_LB_UPDATE_ADDR4 = "MYSQL_LB_UPDATE_ADDR4";
extern const isc::log::MessageID MYSQL_LB_UPDATE_ADDR6 = "MYSQL_LB_UPDATE_ADDR6";
"MYSQL_LB_SFLQ_CREATE_POOL6", "creating shared-flq pool for address range %1 - %2, type %3, delegated length: %4, subnet id %5, recreate %6, capacity %7",
"MYSQL_LB_SFLQ_PICK_LEASE4", "picking a free lease from address range %1 - %2",
"MYSQL_LB_SFLQ_PICK_LEASE6", "picking a free lease from address range %1 - %2",
+ "MYSQL_LB_SFLQ_POOL4_DELETE", "delete the V4 SFLQ pool with start address %1 and end address %2, forece = %3",
+ "MYSQL_LB_SFLQ_POOL4_GET_ALL", "fetch all V4 SFLQ pools",
+ "MYSQL_LB_SFLQ_POOL4_GET_BY_RANGE", "fetch all V4 SFLQ pools that overlap the range %1 and %2",
+ "MYSQL_LB_SFLQ_POOL4_GET_BY_SUBNET", "fetch all V4 SFLQ pools for subnet-id %1",
+ "MYSQL_LB_SFLQ_POOL6_DELETE", "delete the V6 SFLQ pool with start address %1 and end address %2, forece = %3",
+ "MYSQL_LB_SFLQ_POOL6_GET_ALL", "fetch all V6 SFLQ pools",
+ "MYSQL_LB_SFLQ_POOL6_GET_BY_RANGE", "fetch all V6 SFLQ pools that overlap the range %1 and %2",
+ "MYSQL_LB_SFLQ_POOL6_GET_BY_SUBNET", "fetch all V6 SFLQ pools for subnet-id %1",
"MYSQL_LB_TLS_CIPHER", "TLS cipher: %1",
"MYSQL_LB_UPDATE_ADDR4", "updating IPv4 lease for address %1",
"MYSQL_LB_UPDATE_ADDR6", "updating IPv6 lease for address %1, lease type %2",
extern const isc::log::MessageID MYSQL_LB_SFLQ_CREATE_POOL6;
extern const isc::log::MessageID MYSQL_LB_SFLQ_PICK_LEASE4;
extern const isc::log::MessageID MYSQL_LB_SFLQ_PICK_LEASE6;
+extern const isc::log::MessageID MYSQL_LB_SFLQ_POOL4_DELETE;
+extern const isc::log::MessageID MYSQL_LB_SFLQ_POOL4_GET_ALL;
+extern const isc::log::MessageID MYSQL_LB_SFLQ_POOL4_GET_BY_RANGE;
+extern const isc::log::MessageID MYSQL_LB_SFLQ_POOL4_GET_BY_SUBNET;
+extern const isc::log::MessageID MYSQL_LB_SFLQ_POOL6_DELETE;
+extern const isc::log::MessageID MYSQL_LB_SFLQ_POOL6_GET_ALL;
+extern const isc::log::MessageID MYSQL_LB_SFLQ_POOL6_GET_BY_RANGE;
+extern const isc::log::MessageID MYSQL_LB_SFLQ_POOL6_GET_BY_SUBNET;
extern const isc::log::MessageID MYSQL_LB_TLS_CIPHER;
extern const isc::log::MessageID MYSQL_LB_UPDATE_ADDR4;
extern const isc::log::MessageID MYSQL_LB_UPDATE_ADDR6;
This debug message is issued when the server upgrades IPv6 lease extended info.
The page number and started address, and the count of already updated leases
are displayed.
+
+% MYSQL_LB_SFLQ_CREATE_POOL4 creating shared-flq pool for address range %1 - %2, subnet id %3, recreate %4, capacity %5
+Logged at debug log level 50.
+This debug message is issued when the server asks the lease back end to
+(re)create the shared free lease data for the pool described in the arguments.
+
+% MYSQL_LB_SFLQ_PICK_LEASE4 picking a free lease from address range %1 - %2
+Logged at debug log level 50.
+This debug message is issued when the server asks the lease back end for
+a free address from the pool described in the arguments.
+
+% MYSQL_LB_SFLQ_CREATE_POOL6 creating shared-flq pool for address range %1 - %2, type %3, delegated length: %4, subnet id %5, recreate %6, capacity %7
+Logged at debug log level 50.
+This debug message is issued when the server asks the lease back end to
+(re)create the shared free lease data for the pool described in the arguments.
+
+% MYSQL_LB_SFLQ_PICK_LEASE6 picking a free lease from address range %1 - %2
+Logged at debug log level 50.
+This debug message is issued when the server asks the lease back end for
+a free lease from the pool described in the arguments.
+
+% MYSQL_LB_SFLQ_POOL4_GET_ALL fetch all V4 SFLQ pools
+Logged at debug log level 50.
+This debug message is issued when the server asks the lease back end for a list of all v4 SFLQ pools.
+
+% MYSQL_LB_SFLQ_POOL4_GET_BY_SUBNET fetch all V4 SFLQ pools for subnet-id %1
+Logged at debug log level 50.
+This debug message is issued when the server asks the lease back end for
+a list of all v4 SFLQ pools belonging to a subnet.
+
+% MYSQL_LB_SFLQ_POOL4_GET_BY_RANGE fetch all V4 SFLQ pools that overlap the range %1 and %2
+Logged at debug log level 50.
+This debug message is issued when the server asks the lease back end for
+the v4 SFLQ pool that overlap the given address range.
+
+% MYSQL_LB_SFLQ_POOL4_DELETE delete the V4 SFLQ pool with start address %1 and end address %2, forece = %3
+Logged at debug log level 50.
+This debug message is issued when the server asks the lease back to delete
+the v4 SFLQ pool (and it's free lease data) that match the given start and end
+addresses.
+
+% MYSQL_LB_SFLQ_POOL6_GET_ALL fetch all V6 SFLQ pools
+Logged at debug log level 50.
+This debug message is issued when the server asks the lease back end for
+a list of all v6 SFLQ pools.
+
+% MYSQL_LB_SFLQ_POOL6_GET_BY_SUBNET fetch all V6 SFLQ pools for subnet-id %1
+Logged at debug log level 50.
+This debug message is issued when the server asks the lease back end for
+a list of all v6 SFLQ pools belonging to a subnet.
+
+% MYSQL_LB_SFLQ_POOL6_GET_BY_RANGE fetch all V6 SFLQ pools that overlap the range %1 and %2
+Logged at debug log level 50.
+This debug message is issued when the server asks the lease back end for
+the v6 SFLQ pool that overlap the given address range.
+
+% MYSQL_LB_SFLQ_POOL6_DELETE delete the V6 SFLQ pool with start address %1 and end address %2, forece = %3
+Logged at debug log level 50.
+This debug message is issued when the server asks the lease back to delete
+the v6 SFLQ pool (and it's free lease data) that match the given start and end
+addresses.
/// @brief Maximum length of the text returned by the limit checking functions.
const size_t LIMITS_TEXT_MAX_LEN = 512;
+/// @brief Maximum string length of a V6 address.
+const size_t POOL_ADDRESS6_BUF_LENGTH = 45;
+
boost::array<TaggedStatement, MySqlLeaseMgr::NUM_STATEMENTS>
tagged_statements = { {
{MySqlLeaseMgr::DELETE_LEASE4,
"?, ?, ?, ?, ?, ?, ?, ?, ?)"},
{MySqlLeaseMgr::SFLQ_DELETE_LEASE6,
"SELECT sflqDeleteLease6(?, ?)"},
+
+ {MySqlLeaseMgr::SFLQ_POOL4_GET_ALL,
+ "SELECT q.id, q.subnet_id, 3 as lease_type, "
+ " q.start_address, q.end_address, 128 as delegated_len, "
+ " q.created_ts, q.modification_ts, count(f.address) as free_leases "
+ " FROM flq_pool4 AS q "
+ " LEFT JOIN free_lease4 AS f "
+ " ON f.address >= q.start_address AND f.address <= q.end_address "
+ " GROUP BY q.id "
+ " ORDER BY q.subnet_id, q.start_address"},
+
+ {MySqlLeaseMgr::SFLQ_POOL4_GET_BY_SUBNET,
+ "SELECT q.id, q.subnet_id, 3 as lease_type, "
+ " q.start_address, q.end_address, 128 as delegated_len, "
+ " q.created_ts, q.modification_ts, count(f.address) as free_leases "
+ " FROM flq_pool4 AS q "
+ " LEFT JOIN free_lease4 AS f "
+ " ON f.address >= q.start_address AND f.address <= q.end_address "
+ " WHERE q.subnet_id = ? "
+ " GROUP BY q.id "
+ " ORDER BY q.subnet_id ASC, q.start_address ASC"},
+
+ {MySqlLeaseMgr::SFLQ_POOL4_GET_BY_RANGE,
+ "SELECT q.id, q.subnet_id, 3 as lease_type, "
+ " q.start_address, q.end_address, 128 as delegated_len, "
+ " q.created_ts, q.modification_ts, count(f.address) as free_leases "
+ " FROM flq_pool4 AS q "
+ " LEFT JOIN free_lease4 AS f "
+ " ON f.address >= q.start_address AND f.address <= q.end_address "
+ // WHERE ((q.start <= p_start AND p_start <= q.end) OR "
+ // (q.start <= p_end AND p_pend <= q.end) OR "
+ // (p_start < q.start AND q.end < p_end))
+ " WHERE ((q.start_address <= ? AND ? <= q.end_address) OR "
+ " (q.start_address <= ? AND ? <= q.end_address) OR "
+ " (? < q.start_address AND q.end_address < ?)) "
+ " GROUP BY q.id "
+ " ORDER BY q.subnet_id ASC, q.start_address ASC"},
+
+ {MySqlLeaseMgr::SFLQ_POOL4_DELETE,
+ "DELETE flq_pool4, free_lease4 "
+ " FROM flq_pool4 "
+ " INNER JOIN free_lease4 "
+ " ON free_lease4.address >= start_address "
+ " AND free_lease4.address <= end_address "
+ " WHERE flq_pool4.start_address = ? AND flq_pool4.end_address = ?"},
+
+ {MySqlLeaseMgr::SFLQ_POOL6_GET_ALL,
+ "SELECT q.id, q.subnet_id, q.lease_type, "
+ " q.start_address, q.end_address, q.delegated_len, "
+ " q.created_ts, q.modification_ts, count(f.address) as free_leases "
+ " FROM flq_pool6 AS q "
+ " LEFT JOIN free_lease6 AS f "
+ " ON f.bin_address >= inet6_aton(q.start_address) AND "
+ " f.bin_address <= inet6_aton(q.end_address)"
+ " GROUP BY q.id "
+ " ORDER BY q.subnet_id ASC, inet6_aton(q.start_address) ASC"},
+
+ {MySqlLeaseMgr::SFLQ_POOL6_GET_BY_SUBNET,
+ "SELECT q.id, q.subnet_id, q.lease_type, "
+ " q.start_address, q.end_address, q.delegated_len, "
+ " q.created_ts, q.modification_ts, count(f.address) as free_leases "
+ " FROM flq_pool6 AS q "
+ " LEFT JOIN free_lease6 AS f "
+ " ON f.bin_address >= inet6_aton(q.start_address) AND "
+ " f.bin_address <= inet6_aton(q.end_address)"
+
+ " WHERE q.subnet_id = ? "
+ " GROUP BY q.id "
+ " ORDER BY q.subnet_id ASC, inet6_aton(q.start_address) ASC"},
+ {MySqlLeaseMgr::SFLQ_POOL6_GET_BY_RANGE,
+ "SELECT q.id, q.subnet_id, q.lease_type,"
+ " q.start_address, q.end_address, q.delegated_len, "
+ " q.created_ts, q.modification_ts, count(f.address) as free_leases "
+ " FROM flq_pool6 AS q "
+ " LEFT JOIN free_lease6 AS f "
+ " ON f.bin_address >= inet6_aton(q.start_address) AND "
+ " f.bin_address <= inet6_aton(q.end_address)"
+ " WHERE ((inet6_aton(q.start_address) <= inet6_aton(?) AND "
+ " inet6_aton(?) <= inet6_aton(q.end_address)) OR "
+ " (inet6_aton(q.start_address) <= inet6_aton(?) AND "
+ " inet6_aton(?) <= inet6_aton(q.end_address)) OR "
+ " (inet6_aton(?) < inet6_aton(q.start_address) AND "
+ " inet6_aton(q.end_address) < inet6_aton(?))) "
+ " GROUP BY q.id "
+ " ORDER BY q.subnet_id ASC, inet6_aton(q.start_address) ASC"},
+
+ {MySqlLeaseMgr::SFLQ_POOL6_DELETE,
+ "DELETE flq_pool6, free_lease6 "
+ " FROM flq_pool6 "
+ " INNER JOIN free_lease6 "
+ " ON free_lease6.address >= start_address "
+ " AND free_lease6.address <= end_address "
+ " WHERE flq_pool6.start_address = ? AND flq_pool6.end_address = ?"}
} }; // tagged_statements
} // namespace
bool
MySqlLeaseMgr::sflqCreateFlqPool4(IOAddress start_address, IOAddress end_address,
SubnetID subnet_id, bool recreate) {
- auto capacity = addrsInRange(start_address, end_address);
- LOG_DEBUG(mysql_lb_logger, MYSQL_LB_DBG_TRACE_DETAIL, MYSQL_LB_SFLQ_CREATE_POOL4)
- .arg(start_address.toText())
- .arg(end_address.toText())
- .arg(subnet_id)
- .arg(recreate)
- .arg(capacity);
-
- if (capacity > SharedFlqAllocator::MAX_V4_POOL_SIZE) {
- isc_throw(BadValue, "MySqlLeasMgr::sflqCreateFlqPool4 pool capacity "
- << capacity << " exceeds limit of "
+ // This is clunky but it allows us to log the capacity.
+ try {
+ validateV4Range(start_address, end_address);
+ auto capacity = addrsInRange(start_address, end_address);
+ if (capacity > SharedFlqAllocator::MAX_V4_POOL_SIZE) {
+ isc_throw(BadValue, "pool capacity " << capacity << " exceeds limit of "
<< SharedFlqAllocator::MAX_V4_POOL_SIZE
<< " for shared-flq allocator on V4 pool ");
+ }
+
+ LOG_DEBUG(mysql_lb_logger, MYSQL_LB_DBG_TRACE_DETAIL, MYSQL_LB_SFLQ_CREATE_POOL4)
+ .arg(start_address.toText())
+ .arg(end_address.toText())
+ .arg(subnet_id)
+ .arg(recreate)
+ .arg(capacity);
+ } catch (const std::exception& ex) {
+ isc_throw(BadValue, "MySqlLeasMgr::sflqCreateFlqPool4 " << ex.what());
}
// Get a context.
.arg(start_address.toText())
.arg(end_address.toText());
+ validateV4Range(start_address, end_address);
+
// Get a context.
MySqlLeaseContextAlloc get_context(*this);
MySqlLeaseContextPtr ctx = get_context.ctx_;
MySqlLeaseMgr::sflqCreateFlqPool6(IOAddress start_address, IOAddress end_address,
Lease::Type lease_type, uint8_t delegated_len,
SubnetID subnet_id, bool recreate) {
- uint128_t capacity;
- if (lease_type == Lease::TYPE_PD) {
- auto prefix_len = prefixLengthFromRange(start_address, end_address);
- capacity = prefixesInRange(prefix_len, delegated_len);
- } else {
- capacity = addrsInRange(start_address, end_address);
- }
+ // This is clunky but it allows us to log the capacity.
+ try {
+ validateV6Range(start_address, end_address);
+ uint128_t capacity;
+ if (lease_type == Lease::TYPE_PD) {
+ auto prefix_len = prefixLengthFromRange(start_address, end_address);
+ capacity = prefixesInRange(prefix_len, delegated_len);
+ } else {
+ capacity = addrsInRange(start_address, end_address);
+ }
- LOG_DEBUG(mysql_lb_logger, MYSQL_LB_DBG_TRACE_DETAIL, MYSQL_LB_SFLQ_CREATE_POOL6)
- .arg(start_address.toText())
- .arg(end_address.toText())
- .arg(lease_type)
- .arg(static_cast<uint16_t>(delegated_len))
- .arg(subnet_id)
- .arg(recreate)
- .arg(capacity);
-
- if (capacity > SharedFlqAllocator::MAX_V6_POOL_SIZE) {
- isc_throw(BadValue, "MySqlLeasMgr::sflqCreateFlqPool6 pool capacity "
- << capacity << " exceeds limit of "
- << SharedFlqAllocator::MAX_V6_POOL_SIZE
- << " for shared-flq allocator on V6 pool ");
+ LOG_DEBUG(mysql_lb_logger, MYSQL_LB_DBG_TRACE_DETAIL, MYSQL_LB_SFLQ_CREATE_POOL6)
+ .arg(start_address.toText())
+ .arg(end_address.toText())
+ .arg(lease_type)
+ .arg(static_cast<uint16_t>(delegated_len))
+ .arg(subnet_id)
+ .arg(recreate)
+ .arg(capacity);
+ } catch (const std::exception& ex) {
+ isc_throw(BadValue, "MySqlLeasMgr::sflqCreateFlqPool6 " << ex.what());
}
// Get a context.
.arg(start_address.toText())
.arg(end_address.toText());
+ validateV6Range(start_address, end_address);
+
// Get a context.
MySqlLeaseContextAlloc get_context(*this);
MySqlLeaseContextPtr ctx = get_context.ctx_;
return (IOAddress(tmp));
}
+SflqPoolInfoCollectionPtr
+MySqlLeaseMgr::sflqPool4GetAll() {
+ LOG_DEBUG(mysql_lb_logger, MYSQL_LB_DBG_TRACE_DETAIL, MYSQL_LB_SFLQ_POOL4_GET_ALL);
+
+ // No input parameters.
+ MySqlBindingCollection in_bindings = {};
+
+ return (sflqPoolGetCommon(SFLQ_POOL4_GET_ALL, in_bindings));
+}
+
+SflqPoolInfoCollectionPtr
+MySqlLeaseMgr::sflqPool4Get(SubnetID subnet_id) {
+ LOG_DEBUG(mysql_lb_logger, MYSQL_LB_DBG_TRACE_DETAIL,
+ MYSQL_LB_SFLQ_POOL4_GET_BY_SUBNET)
+ .arg(subnet_id);
+
+ MySqlBindingCollection in_bindings = {
+ MySqlBinding::createInteger<int64_t>(subnet_id)
+ };
+
+ return (sflqPoolGetCommon(SFLQ_POOL4_GET_BY_SUBNET, in_bindings));
+}
+
+SflqPoolInfoCollectionPtr
+MySqlLeaseMgr::sflqPool4Get(IOAddress start_address, IOAddress end_address) {
+ LOG_DEBUG(mysql_lb_logger, MYSQL_LB_DBG_TRACE_DETAIL,
+ MYSQL_LB_SFLQ_POOL4_GET_BY_RANGE)
+ .arg(start_address.toText())
+ .arg(end_address.toText());
+
+ validateV4Range(start_address, end_address);
+
+ MySqlBindingCollection in_bindings = {
+ // SQL needs both addresses three times.
+ MySqlBinding::createInteger<uint32_t>(start_address.toUint32()),
+ MySqlBinding::createInteger<uint32_t>(start_address.toUint32()),
+ MySqlBinding::createInteger<uint32_t>(end_address.toUint32()),
+ MySqlBinding::createInteger<uint32_t>(end_address.toUint32()),
+ MySqlBinding::createInteger<uint32_t>(start_address.toUint32()),
+ MySqlBinding::createInteger<uint32_t>(end_address.toUint32())
+ };
+
+ return (sflqPoolGetCommon(SFLQ_POOL4_GET_BY_RANGE, in_bindings));
+}
+
+bool
+MySqlLeaseMgr::sflqPool4Del(IOAddress start_address, IOAddress end_address,
+ bool force /* = false */) {
+ LOG_DEBUG(mysql_lb_logger, MYSQL_LB_DBG_TRACE_DETAIL,
+ MYSQL_LB_SFLQ_POOL4_DELETE)
+ .arg(start_address.toText())
+ .arg(end_address.toText())
+ .arg(force ? "true" : "false");
+
+ validateV4Range(start_address, end_address);
+
+ return (sflqPoolDelCommon(start_address, end_address, force, AF_INET));
+}
+
+SflqPoolInfoCollectionPtr
+MySqlLeaseMgr::sflqPool6GetAll() {
+ LOG_DEBUG(mysql_lb_logger, MYSQL_LB_DBG_TRACE_DETAIL, MYSQL_LB_SFLQ_POOL6_GET_ALL);
+
+ // No input parameters.
+ MySqlBindingCollection in_bindings = {};
+
+ return (sflqPoolGetCommon(SFLQ_POOL6_GET_ALL, in_bindings, AF_INET6));
+}
+
+SflqPoolInfoCollectionPtr
+MySqlLeaseMgr::sflqPool6Get(SubnetID subnet_id) {
+ LOG_DEBUG(mysql_lb_logger, MYSQL_LB_DBG_TRACE_DETAIL,
+ MYSQL_LB_SFLQ_POOL6_GET_BY_SUBNET)
+ .arg(subnet_id);
+
+ MySqlBindingCollection in_bindings = {
+ MySqlBinding::createInteger<int64_t>(subnet_id)
+ };
+
+ return (sflqPoolGetCommon(SFLQ_POOL6_GET_BY_SUBNET, in_bindings, AF_INET6));
+}
+
+SflqPoolInfoCollectionPtr
+MySqlLeaseMgr::sflqPool6Get(IOAddress start_address, IOAddress end_address) {
+ LOG_DEBUG(mysql_lb_logger, MYSQL_LB_DBG_TRACE_DETAIL,
+ MYSQL_LB_SFLQ_POOL6_GET_BY_RANGE)
+ .arg(start_address.toText())
+ .arg(end_address.toText());
+
+ validateV6Range(start_address, end_address);
+
+ MySqlBindingCollection in_bindings = {
+ // SQL needs both addresses three times.
+ MySqlBinding::createString(start_address.toText()),
+ MySqlBinding::createString(start_address.toText()),
+ MySqlBinding::createString(end_address.toText()),
+ MySqlBinding::createString(end_address.toText()),
+ MySqlBinding::createString(start_address.toText()),
+ MySqlBinding::createString(end_address.toText())
+ };
+
+ return (sflqPoolGetCommon(SFLQ_POOL6_GET_BY_RANGE, in_bindings, AF_INET6));
+}
+
+bool
+MySqlLeaseMgr::sflqPool6Del(IOAddress start_address, IOAddress end_address,
+ bool force /* = false */) {
+ LOG_DEBUG(mysql_lb_logger, MYSQL_LB_DBG_TRACE_DETAIL,
+ MYSQL_LB_SFLQ_POOL6_DELETE)
+ .arg(start_address.toText())
+ .arg(end_address.toText())
+ .arg(force ? "true" : "false");
+
+ validateV6Range(start_address, end_address);
+
+ return (sflqPoolDelCommon(start_address, end_address, force, AF_INET6));
+}
+
+SflqPoolInfoCollectionPtr
+MySqlLeaseMgr::sflqPoolGetCommon(StatementIndex stindex,
+ MySqlBindingCollection& where_bindings,
+ uint16_t family /* = AF_INET*/ ) {
+ // Get a context.
+ MySqlLeaseContextAlloc get_context(*this);
+ MySqlLeaseContextPtr ctx = get_context.ctx_;
+
+ // Create the output bindings. Start with common columns.
+ MySqlBindingCollection out_bindings = {
+ MySqlBinding::createInteger<uint64_t>(), // db pool id
+ MySqlBinding::createInteger<uint32_t>(), // subnet_id
+ MySqlBinding::createInteger<uint32_t>(), // lease_type
+ };
+
+ // Type specific start and end address.
+ if (family == AF_INET) {
+ out_bindings.push_back(MySqlBinding::createInteger<uint32_t>());
+ out_bindings.push_back(MySqlBinding::createInteger<uint32_t>());
+ } else {
+ out_bindings.push_back(MySqlBinding::createString(POOL_ADDRESS6_BUF_LENGTH));
+ out_bindings.push_back(MySqlBinding::createString(POOL_ADDRESS6_BUF_LENGTH));
+ }
+
+ // Add in remaining common columns.
+ out_bindings.push_back(MySqlBinding::createInteger<uint32_t>()); // delegated_len
+ out_bindings.push_back(MySqlBinding::createTimestamp()); // created_ts
+ out_bindings.push_back(MySqlBinding::createTimestamp()); // modification_ts
+ out_bindings.push_back(MySqlBinding::createInteger<uint64_t>()); // free leases
+
+ SflqPoolInfoCollectionPtr pools(new SflqPoolInfoCollection());
+
+ ctx->conn_.selectQuery(stindex, where_bindings, out_bindings,
+ [this, &pools]
+ (MySqlBindingCollection& out_bindings) {
+
+ SflqPoolInfoPtr info(new SflqPoolInfo());
+ // db pool id is 0, we skip it
+ info->subnet_id_ = out_bindings[1]->getInteger<uint32_t>();
+ auto lease_type_ = out_bindings[2]->getInteger<uint32_t>();
+ switch(lease_type_) {
+ case Lease::TYPE_V4:
+ info->lease_type_ = Lease::TYPE_V4;
+ break;
+ case Lease::TYPE_NA:
+ info->lease_type_ = Lease::TYPE_NA;
+ break;
+ case Lease::TYPE_PD:
+ info->lease_type_ = Lease::TYPE_PD;
+ break;
+ default:
+ isc_throw(BadValue, "invalid pool lease type returned " <<
+ static_cast<int>(lease_type_));
+ }
+
+ if (lease_type_ == Lease::TYPE_V4) {
+ info->start_address_ = IOAddress(out_bindings[3]->getInteger<uint32_t>());
+ info->end_address_ = IOAddress(out_bindings[4]->getInteger<uint32_t>());
+ } else {
+ info->start_address_ = IOAddress(out_bindings[3]->getString());
+ info->end_address_ = IOAddress(out_bindings[4]->getString());
+ }
+
+ info->delegated_len_ = out_bindings[5]->getInteger<uint32_t>();
+ info->created_ts_ = out_bindings[6]->getTimestamp();
+ info->modified_ts_ = out_bindings[7]->getTimestamp();
+ info->free_leases_ = out_bindings[8]->getInteger<uint64_t>();
+ pools->push_back(info);
+ });
+
+ return (pools);
+}
+
+bool
+MySqlLeaseMgr::sflqPoolDelCommon(IOAddress start_address, IOAddress end_address,
+ bool force, uint16_t family ) {
+ // If force is false check for overlapping pools.
+ if (!force) {
+ auto pools_in_range = (family == AF_INET ? sflqPool4Get(start_address, end_address)
+ : sflqPool6Get(start_address, end_address));
+ auto count = pools_in_range->size();
+ if (count == 0) {
+ // Nothing to do.
+ return (false);
+ }
+
+ if (count > 1) {
+ // Overlapping pools, warn and bail.
+ isc_throw(InvalidOperation, "Delete would affect "
+ << count << " overlapping pools");
+ }
+ }
+
+ // Get a context.
+ MySqlLeaseContextAlloc get_context(*this);
+ MySqlLeaseContextPtr ctx = get_context.ctx_;
+
+ // Make where clause bindings.
+ MySqlBindingCollection in_bindings;
+ StatementIndex stindex;
+ if (family == AF_INET) {
+ in_bindings.push_back(MySqlBinding::createInteger<uint32_t>(start_address.toUint32()));
+ in_bindings.push_back(MySqlBinding::createInteger<uint32_t>(end_address.toUint32()));
+ stindex = SFLQ_POOL4_DELETE;
+ } else {
+ in_bindings.push_back(MySqlBinding::createString(start_address.toText()));
+ in_bindings.push_back(MySqlBinding::createString(end_address.toText()));
+ stindex = SFLQ_POOL6_DELETE;
+ }
+
+ ScopedMySqlTransactionPtr trans(new MySqlTransaction(ctx->conn_));
+ auto affected_rows = ctx->conn_.updateDeleteQuery(stindex, in_bindings);
+ trans->commit();
+
+ return(affected_rows > 0);
+}
+
TrackingLeaseMgrPtr
MySqlLeaseMgr::factory(const isc::db::DatabaseConnection::ParameterMap& parameters) {
LOG_INFO(mysql_lb_logger, MYSQL_LB_DB)
SFLQ_INSERT_LEASE6, // SFLQ Alternate for inserting v6 lease
SFLQ_UPDATE_LEASE6, // SFLQ Alternate for updating v6 lease
SFLQ_DELETE_LEASE6, // SFLQ Alternate for deleting v6 lease
+ SFLQ_POOL4_GET_ALL, // SFLQ Fetch all v4 shared flq pools
+ SFLQ_POOL4_GET_BY_SUBNET, // SFLQ Fetch all v4 shared flq pools for a subnet
+ SFLQ_POOL4_GET_BY_RANGE, // SFLQ Fetch v4 shared flq pools that overlap the given range
+ SFLQ_POOL4_DELETE, // SFLQ Delete v4 shared flq pool for an address range
+ SFLQ_POOL6_GET_ALL, // SFLQ Fetch all v6 shared flq pools
+ SFLQ_POOL6_GET_BY_SUBNET, // SFLQ Fetch all v6 shared flq pools for a subnet
+ SFLQ_POOL6_GET_BY_RANGE, // SFLQ Fetch v4 shared flq pool that overlap the address range
+ SFLQ_POOL6_DELETE, // SFLQ Delete v4 shared flq pool for an address range
NUM_STATEMENTS // Number of statements
};
/// @return A free V6 address/prefix or IOAddress::IPV6_ZERO_ADDRESS().
virtual asiolink::IOAddress sflqPickFreeLease6(asiolink::IOAddress start_address,
asiolink::IOAddress end_address) override;
+ /// @brief Fetch all SFLQ V4 pools.
+ ///
+ /// @return A collection of the SFLQ V4 pools.
+ virtual SflqPoolInfoCollectionPtr sflqPool4GetAll() override;
+
+ /// @brief Fetch all SFLQ V4 pools belonging to a subnet.
+ ///
+ /// @param subnet_id id of the desired subnet.
+ ///
+ /// @return A collection of the SFLQ V4 pools.
+ virtual SflqPoolInfoCollectionPtr sflqPool4Get(SubnetID subnet_id) override;
+
+ /// @brief Fetch all SFLQ V4 pools that overlap an address range.
+ ///
+ /// Since overlapping pools are supported, this function returns all V4
+ /// SFLQ pools whose range overlaps the given range.
+ ///
+ /// @param start_address range start address
+ /// @param end_address range end address
+ ///
+ /// @return A collection of the SFLQ V4 pools.
+ virtual SflqPoolInfoCollectionPtr sflqPool4Get(asiolink::IOAddress start_address,
+ asiolink::IOAddress end_address)
+ override;
+
+ /// @brief Delete the SFLQ V4 pool that matches a start and end address.
+ ///
+ /// Deletes the flq_pool4 entry along with its free_lease4 data.
+ /// Fails If there are multiple pools that overalap the given range
+ /// unless force is true.
+ ///
+ /// @param start_address start address of the pool to delete.
+ /// @param end_address end address of the pool to delete.
+ /// @param force overrides check for overlapping pools when true. Defaults
+ /// to false.
+ ///
+ /// @return True a pool was deleted.
+ /// @throw InvalidOperation if force is false and overlapping pools are
+ /// detected.
+ virtual bool sflqPool4Del(asiolink::IOAddress start_address,
+ asiolink::IOAddress end_address,
+ bool force = false) override;
+
+ /// @brief Fetch all SFLQ V6 pools.
+ ///
+ /// @return A collection of the SFLQ V6 pools.
+ virtual SflqPoolInfoCollectionPtr sflqPool6GetAll() override;
+
+ /// @brief Fetch all SFLQ V6 pools belonging to a subnet.
+ ///
+ /// @param subnet_id id of the desired subnet.
+ ///
+ /// @return A collection of the SFLQ V6 pools.
+ virtual SflqPoolInfoCollectionPtr sflqPool6Get(SubnetID subnet_id) override;
+
+ /// @brief Fetch all SFLQ V6 pools that overlap an address range.
+ ///
+ /// Since overlapping pools are supported, this function returns all V4
+ /// SFLQ pools whose range overlaps the given range.
+ ///
+ /// @param start_address range start address
+ /// @param end_address range end address
+ ///
+ /// @return A collection of the SFLQ V6 pools.
+ virtual SflqPoolInfoCollectionPtr sflqPool6Get(asiolink::IOAddress start_address,
+ asiolink::IOAddress end_address)
+ override;
+ /// @brief Delete the SFLQ V6 pool that matches a start and end address.
+ ///
+ /// Deletes the flq_pool6 entry along with its free_lease6 data.
+ /// Fails If there are multiple pools that overalap the given range
+ /// unless force is true.
+ ///
+ /// @param start_address start address of the pool to delete.
+ /// @param end_address end address of the pool to delete.
+ /// @param force overrides check for overlapping pools when true. Defaults
+ /// to false.
+ ///
+ /// @return True a pool was deleted.
+ /// @throw InvalidOperation if force is false and overlapping pools are
+ /// detected.
+ virtual bool sflqPool6Del(asiolink::IOAddress start_address,
+ asiolink::IOAddress end_address,
+ bool force = false) override;
+
+
private:
+ /// @brief Fetch SFLQ pools based on statement index and option where clause.
+ ///
+ /// Common function used for all variants. Requires that all selects return
+ /// values for all the columns and in the same order.
+ ///
+ /// @param stindex index of the SQL statement to execute.
+ /// @param where_bindings input bindings holding the where clause parameter
+ /// values (if any)
+ /// @param family protocl family AF_INET or AF_INET6
+ ///
+ /// @return A collection of the SFLQ V4 pools.
+ SflqPoolInfoCollectionPtr sflqPoolGetCommon(StatementIndex stindex,
+ db::MySqlBindingCollection& where_bindings,
+ uint16_t family = AF_INET);
+
+ /// @brief Delete the SFLQ pool that matches a start and end address.
+ ///
+ /// Deletes the flq_poolX entry along with its free_leaseX data.
+ /// Fails If there are multiple pools that overalap the given range
+ /// unless force is true.
+ ///
+ /// @param start_address start address of the pool to delete.
+ /// @param end_address end address of the pool to delete.
+ /// @param force overrides check for overlapping pools when true.
+ /// @param family protocl family AF_INET or AF_INET6
+ ///
+ /// @return True a pool was deleted.
+ /// @throw InvalidOperation if force is false and overlapping pools are
+ /// detected.
+ bool sflqPoolDelCommon(asiolink::IOAddress start_address, asiolink::IOAddress end_address,
+ bool force, uint16_t family);
+
/// @brief Context RAII allocator.
class MySqlLeaseContextAlloc {
public:
testSflqLeaseOps6(Lease::TYPE_PD);
}
+TEST_F(MySqlLeaseMgrTest, testSflqAPIFuncs4) {
+ testSflqAPIFuncs4();
+}
+
+TEST_F(MySqlLeaseMgrTest, testSflqAPIFuncs6NA) {
+ testSflqAPIFuncs6(Lease::TYPE_NA);
+}
+
+TEST_F(MySqlLeaseMgrTest, testSflqAPIFuncs6PD) {
+ testSflqAPIFuncs6(Lease::TYPE_PD);
+}
+
+TEST_F(MySqlLeaseMgrTest, testSflqAPIOverlappingPools4) {
+ testSflqAPIOverlappingPools4();
+}
+
+TEST_F(MySqlLeaseMgrTest, testSflqAPIOverlappingPools6NA) {
+ testSflqAPIOverlappingPools6(Lease::TYPE_NA);
+}
+
+TEST_F(MySqlLeaseMgrTest, testSflqAPIOverlappingPools6PD) {
+ testSflqAPIOverlappingPools6(Lease::TYPE_PD);
+}
+
/// @brief Test fixture class for testing @ref CfgDbAccessTest using MySQL
/// backend.
class CfgMySqlLbDbAccessTest : public ::testing::Test {
testSflqLeaseOps6(Lease::TYPE_PD);
}
+TEST_F(PgSqlLeaseMgrTest, testSflqAPIFuncs4) {
+ testSflqAPIFuncs4();
+}
+
+TEST_F(PgSqlLeaseMgrTest, testSflqAPIFuncs6NA) {
+ testSflqAPIFuncs6(Lease::TYPE_NA);
+}
+
+TEST_F(PgSqlLeaseMgrTest, testSflqAPIFuncs6PD) {
+ testSflqAPIFuncs6(Lease::TYPE_PD);
+}
+
+TEST_F(PgSqlLeaseMgrTest, testSflqAPIOverlappingPools4) {
+ testSflqAPIOverlappingPools4();
+}
+
+TEST_F(PgSqlLeaseMgrTest, testSflqAPIOverlappingPools6NA) {
+ testSflqAPIOverlappingPools6(Lease::TYPE_NA);
+}
+
+TEST_F(PgSqlLeaseMgrTest, testSflqAPIOverlappingPools6PD) {
+ testSflqAPIOverlappingPools6(Lease::TYPE_PD);
+}
+
/// @brief Test fixture class for testing @ref CfgDbAccessTest using PostgreSQL
/// backend.
class CfgPgSqlLbDbAccessTest : public ::testing::Test {
return (IOAddress::fromBytes(AF_INET6, &addr_bytes[0]));
}
+void validateV4Range(const IOAddress& start, const IOAddress& end) {
+ if (!start.isV4() || !end.isV4() || end < start) {
+ isc_throw (BadValue, "invalid V4 range - start_address "
+ << start.toText() << "r, end_address " << end.toText()
+ << ", must be V4 addresses where start <= end");
+ }
+}
+
+void validateV6Range(const IOAddress& start, const IOAddress& end) {
+ if (!start.isV6() || !end.isV6() || end < start) {
+ isc_throw (BadValue, "invalid V6 range - start_address "
+ << start.toText() << "r, end_address " << end.toText()
+ << ", must be V6 addresses where start <= end");
+ }
+}
+
}
}
/// @return address being offset greater than the input address
IOAddress offsetAddress(const IOAddress& addr, isc::util::uint128_t offset);
+/// @brief Ensures address pair are both v4 and start <= end
+///
+/// @param addr input address
+/// @param addr input address
+///
+/// @throw BadValue if either address is not v4 or start > end
+void validateV4Range(const IOAddress& start, const IOAddress& end);
+
+/// @brief Ensures address pair are both v6 and start <= end
+///
+/// @param addr input address
+/// @param addr input address
+///
+/// @throw BadValue if either address is not v6 or start > end
+void validateV6Range(const IOAddress& start, const IOAddress& end);
+
} // namespace asiolink
} // namespace isc
#include <stats/stats_mgr.h>
#include <util/encode/encode.h>
#include <util/str.h>
+#include <util/boost_time_utils.h>
#include <boost/algorithm/string.hpp>
}
}
+SflqPoolInfo::SflqPoolInfo():
+ lease_type_(Lease::TYPE_V4),
+ start_address_(IOAddress::IPV4_ZERO_ADDRESS()),
+ end_address_(IOAddress::IPV4_ZERO_ADDRESS()),
+ delegated_len_(128),
+ subnet_id_(0),
+ free_leases_(0),
+ created_ts_(),
+ modified_ts_() {
+}
+
+
+data::ConstElementPtr
+SflqPoolInfo::toElement() const {
+ ElementPtr info = Element::createMap();
+ info->set("lease-type", Element::create(Lease::typeToText(lease_type_)));
+ info->set("start-address", Element::create(start_address_.toText()));
+ info->set("end-address", Element::create(end_address_.toText()));
+ info->set("delegated-len", Element::create(delegated_len_));
+ info->set("subnet-id", Element::create(subnet_id_));
+ info->set("free-leases", ElementPtr(new IntElement(free_leases_)));
+ info->set("created-ts", Element::create(isc::util::ptimeToText(created_ts_)));
+ info->set("modified-ts", Element::create(isc::util::ptimeToText(modified_ts_)));
+ return(info);
+}
bool
LeaseMgr::sflqCreateFlqPool4(IOAddress, IOAddress, SubnetID, bool) {
isc_throw(NotImplemented, "LeaseMgr::sflqPickFreeLease6() called");
}
+SflqPoolInfoCollectionPtr
+LeaseMgr::sflqPool4GetAll() {
+ isc_throw(NotImplemented, "LeaseMgr::sflqPool4GetAll() called");
+}
+
+SflqPoolInfoCollectionPtr
+LeaseMgr::sflqPool4Get(SubnetID /* subnet_id */) {
+ isc_throw(NotImplemented, "LeaseMgr::sflqPool4Get(SubnetID) called");
+}
+
+SflqPoolInfoCollectionPtr
+LeaseMgr::sflqPool4Get(asiolink::IOAddress, asiolink::IOAddress) {
+ isc_throw(NotImplemented, "LeaseMgr::sflqPool4Get(IOAddress,IOAddress) called");
+}
+
+bool
+LeaseMgr::sflqPool4Del(asiolink::IOAddress, asiolink::IOAddress, bool) {
+ isc_throw(NotImplemented, "LeaseMgr::sflqPool4Del() called");
+}
+
+SflqPoolInfoCollectionPtr
+LeaseMgr::sflqPool6GetAll() {
+ isc_throw(NotImplemented, "LeaseMgr::sflqPool6GetAll() called");
+}
+
+SflqPoolInfoCollectionPtr
+LeaseMgr::sflqPool6Get(SubnetID) {
+ isc_throw(NotImplemented, "LeaseMgr::sflqPool6Get(SubnetID) called");
+}
+
+SflqPoolInfoCollectionPtr
+LeaseMgr::sflqPool6Get(asiolink::IOAddress, asiolink::IOAddress) {
+ isc_throw(NotImplemented, "LeaseMgr::sflqPool6Get(IOAdress,IOAddress) called");
+}
+
+bool
+LeaseMgr::sflqPool6Del(asiolink::IOAddress, asiolink::IOAddress, bool) {
+ isc_throw(NotImplemented, "LeaseMgr::sflqPool6Del() called");
+}
+
bool
LeaseMgr::useSharedFlqStatement(Lease4Ptr lease) {
// Only check the subnet if SFLQ is in-use in this config.
/// @brief Defines a pointer to a LeaseStatsRow.
typedef boost::shared_ptr<LeaseStatsRow> LeaseStatsRowPtr;
+/// @brief Describes a SFLQ pool.
+class SflqPoolInfo {
+public:
+ SflqPoolInfo();
+
+ ~SflqPoolInfo(){};
+
+ Lease::Type lease_type_;
+ asiolink::IOAddress start_address_;
+ asiolink::IOAddress end_address_;
+ uint8_t delegated_len_;
+ SubnetID subnet_id_;
+ uint64_t free_leases_;
+ boost::posix_time::ptime created_ts_;
+ boost::posix_time::ptime modified_ts_;
+
+ data::ConstElementPtr toElement() const;
+};
+
+/// @brief A pointer to a SFLQPoolInfo instance.
+typedef boost::shared_ptr<SflqPoolInfo> SflqPoolInfoPtr;
+
+/// @brief A collection of SFLQPoolInfo structures.
+typedef std::vector<SflqPoolInfoPtr> SflqPoolInfoCollection;
+typedef boost::shared_ptr<SflqPoolInfoCollection> SflqPoolInfoCollectionPtr;
+
+
/// @brief Abstract Lease Manager
///
/// This is an abstract API for lease database backends. It provides unified
virtual asiolink::IOAddress sflqPickFreeLease6(asiolink::IOAddress start_address,
asiolink::IOAddress end_address);
+ /// @brief Fetch all SFLQ V4 pools.
+ ///
+ /// @return A collection of the SFLQ V4 pools.
+ virtual SflqPoolInfoCollectionPtr sflqPool4GetAll();
+
+ /// @brief Fetch all SFLQ V4 pools belonging to a subnet.
+ ///
+ /// @param subnet_id id of the desired subnet.
+ ///
+ /// @return A collection of the SFLQ V4 pools.
+ virtual SflqPoolInfoCollectionPtr sflqPool4Get(SubnetID subnet_id);
+
+ /// @brief Fetch all SFLQ V4 pools that overlap an address range.
+ ///
+ /// Since overlapping pools are supported, this function returns all V4
+ /// SFLQ pools whose range overlaps the given range.
+ ///
+ /// @param start_address range start address
+ /// @param end_address range end address
+ ///
+ /// @return A collection of the SFLQ V4 pools.
+ virtual SflqPoolInfoCollectionPtr sflqPool4Get(asiolink::IOAddress start_address,
+ asiolink::IOAddress end_address);
+
+ /// @brief Delete the SFLQ V4 pool that matches a start and end address.
+ ///
+ /// Deletes the flq_pool4 entry along with its free_lease4 data.
+ /// Fails If there are multiple pools that overalap the given range
+ /// unless force is true.
+ ///
+ /// @param start_address start address of the pool to delete.
+ /// @param end_address end address of the pool to delete.
+ /// @param force overrides check for overlapping pools when true. Defaults
+ /// to false.
+ ///
+ /// @return True a pool was deleted.
+ /// @throw InvalidOperation if force is false and overlapping pools are
+ /// detected.
+ virtual bool sflqPool4Del(asiolink::IOAddress start_address,
+ asiolink::IOAddress end_address,
+ bool force = false);
+
+ /// @brief Fetch all SFLQ V6 pools.
+ ///
+ /// @return A collection of the SFLQ V6 pools.
+ virtual SflqPoolInfoCollectionPtr sflqPool6GetAll();
+
+ /// @brief Fetch all SFLQ V6 pools belonging to a subnet.
+ ///
+ /// @param subnet_id id of the desired subnet.
+ ///
+ /// @return A collection of the SFLQ V6 pools.
+ virtual SflqPoolInfoCollectionPtr sflqPool6Get(SubnetID subnet_id);
+
+ /// @brief Fetch all SFLQ V6 pools that overlap an address range.
+ ///
+ /// Since overlapping pools are supported, this function returns all V6
+ /// SFLQ pools whose range overlaps the given range.
+ ///
+ /// @param start_address range start address
+ /// @param end_address range end address
+ ///
+ /// @return A collection of the SFLQ V6 pools.
+ virtual SflqPoolInfoCollectionPtr sflqPool6Get(asiolink::IOAddress start_address,
+ asiolink::IOAddress end_address);
+
+ /// @brief Delete the SFLQ V6 pool that matches a start and end address.
+ ///
+ /// Deletes the flq_pool6 entry along with its free_lease6 data.
+ /// Fails If there are multiple pools that overalap the given range
+ /// unless force is true.
+ ///
+ /// @param start_address start address of the pool to delete.
+ /// @param end_address end address of the pool to delete.
+ /// @param force overrides check for overlapping pools when true. Defaults
+ /// to false.
+ ///
+ /// @return True a pool was deleted.
+ /// @throw InvalidOperation if force is false and overlapping pools are
+ /// detected.
+ virtual bool sflqPool6Del(asiolink::IOAddress start_address,
+ asiolink::IOAddress end_address,
+ bool force = false);
+
/// @brief Determine if SFLQ alternate SQL statements should be used
/// for a given v4 lease
///
#include <dhcpsrv/testutils/concrete_lease_mgr.h>
#include <dhcpsrv/testutils/generic_lease_mgr_unittest.h>
#include <testutils/gtest_utils.h>
+#include <util/boost_time_utils.h>
#include <iostream>
#include <list>
EXPECT_EQ(exp_remote_id, remote_id);
}
+// Verifies SfqlPoolInfo::toElement() function.
+TEST(SflqPoolInfo, toElement) {
+ SflqPoolInfo info;
+ info.lease_type_ = Lease::TYPE_V4;
+ info.start_address_ = IOAddress("1.2.3.4");
+ info.end_address_ = IOAddress("1.2.3.5");
+ info.delegated_len_ = 128;
+ info.subnet_id_ = 77;
+ info.free_leases_ = 245;
+ auto now = boost::posix_time::second_clock::local_time();
+ info.created_ts_ = now;
+ info.modified_ts_ = now;
+
+ auto info_elem = info.toElement();
+
+ ElementPtr expected = Element::createMap();
+ expected->set("lease-type", Element::create(Lease::typeToText(info.lease_type_)));
+ expected->set("start-address", Element::create(info.start_address_.toText()));
+ expected->set("end-address", Element::create(info.end_address_.toText()));
+ expected->set("delegated-len", Element::create(info.delegated_len_));
+ expected->set("subnet-id", Element::create(info.subnet_id_));
+ expected->set("free-leases", ElementPtr(new IntElement(info.free_leases_)));
+ expected->set("created-ts", Element::create(isc::util::ptimeToText(info.created_ts_)));
+ expected->set("modified-ts", Element::create(isc::util::ptimeToText(info.modified_ts_)));
+
+ EXPECT_TRUE(info_elem->equals(*expected));
+}
+
// There's no point in calling any other methods in LeaseMgr, as they
// are purely virtual, so we would only call ConcreteLeaseMgr methods.
// Those methods are just stubs that do not return anything.
return (leases);
}
+void
+GenericLeaseMgrTest::checkPoolInfos(const SflqPoolInfo& lhs,
+ const SflqPoolInfo& rhs,
+ int lineno) {
+
+ ASSERT_TRUE(lhs.lease_type_ == rhs.lease_type_ &&
+ lhs.start_address_ == rhs.start_address_ &&
+ lhs.end_address_ == rhs.end_address_ &&
+ lhs.delegated_len_ == rhs.delegated_len_ &&
+ lhs.subnet_id_ == rhs.subnet_id_ &&
+ lhs.free_leases_ == rhs.free_leases_ &&
+ lhs.created_ts_ >= rhs.created_ts_ &&
+ lhs.modified_ts_ >= rhs.modified_ts_)
+ << "Pools don't match at line " << lineno << std::endl
+ << "lhs: " << *lhs.toElement() << std::endl
+ << "rhs: " << *rhs.toElement() << std::endl;
+}
+
void
GenericLeaseMgrTest::testGetLease4ClientId() {
// Let's initialize a specific lease ...
}
}
+void
+GenericLeaseMgrTest::testSflqAPIFuncs4() {
+ SflqPoolInfoCollectionPtr pool_infos;
+
+ // Fetching all pools should find none.
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool4GetAll());
+ ASSERT_EQ(0, pool_infos->size());
+
+ auto test_start = boost::posix_time::second_clock::local_time();
+
+ // Create three test pools.
+ SflqPoolInfoCollection test_pools;
+ SflqPoolInfoPtr pi;
+ pi.reset(new SflqPoolInfo());
+ pi->start_address_ = IOAddress("192.0.3.0");
+ pi->end_address_ = IOAddress("192.0.3.2");
+ pi->subnet_id_ = 1;
+ pi->created_ts_ = test_start;
+ pi->modified_ts_ = test_start;
+ pi->free_leases_ = 3;
+ test_pools.push_back(pi);
+
+ pi.reset(new SflqPoolInfo());
+ pi->start_address_ = IOAddress("192.0.2.0");
+ pi->end_address_ = IOAddress("192.0.2.2");
+ pi->subnet_id_ = 2;
+ pi->created_ts_ = test_start;
+ pi->modified_ts_ = test_start;
+ pi->free_leases_ = 3;
+ test_pools.push_back(pi);
+
+ pi.reset(new SflqPoolInfo());
+ pi->start_address_ = IOAddress("192.0.1.0");
+ pi->end_address_ = IOAddress("192.0.1.2");
+ pi->subnet_id_ = 1;
+ pi->created_ts_ = test_start;
+ pi->modified_ts_ = test_start;
+ pi->free_leases_ = 3;
+ test_pools.push_back(pi);
+
+ for ( auto const& test_pool : test_pools) {
+ ASSERT_NO_THROW_LOG(
+ lmptr_->sflqCreateFlqPool4(test_pool->start_address_,
+ test_pool->end_address_,
+ test_pool->subnet_id_, false));
+ }
+
+ // Fetching all pools should find none.
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool4GetAll());
+ ASSERT_TRUE(pool_infos);
+ ASSERT_EQ(3, pool_infos->size());
+
+ // Should get them back ordered by subnet and start address.
+ checkPoolInfos(*(*pool_infos)[0], *test_pools[2], __LINE__);
+ checkPoolInfos(*(*pool_infos)[1], *test_pools[0], __LINE__);
+ checkPoolInfos(*(*pool_infos)[2], *test_pools[1], __LINE__);
+
+ // Fetch by subnet id for subnet_id = 1.
+ pool_infos.reset();
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool4Get(1));
+ ASSERT_TRUE(pool_infos);
+ ASSERT_EQ(2, pool_infos->size());
+ checkPoolInfos(*(*pool_infos)[0], *test_pools[2], __LINE__);
+ checkPoolInfos(*(*pool_infos)[1], *test_pools[0], __LINE__);
+
+ // Fetch by subnet id for subnet_id = 2.
+ pool_infos.reset();
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool4Get(2));
+ ASSERT_TRUE(pool_infos);
+ ASSERT_EQ(1, pool_infos->size());
+ checkPoolInfos(*(*pool_infos)[0], *test_pools[1], __LINE__);
+
+ // Fetch by subnet id for subnet_id = 99
+ pool_infos.reset();
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool4Get(99));
+ ASSERT_TRUE(pool_infos);
+ ASSERT_EQ(0, pool_infos->size());
+
+ // Fetch by a range that excludes them all.
+ pool_infos.reset();
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool4Get(IOAddress("1.2.3.4"),
+ IOAddress("1.2.3.4")));
+ ASSERT_TRUE(pool_infos);
+ ASSERT_EQ(0, pool_infos->size());
+
+ // Fetch by a range that includes them all.
+ pool_infos.reset();
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool4Get(IOAddress("192.0.0.0"),
+ IOAddress("192.0.4.0")));
+ ASSERT_TRUE(pool_infos);
+ ASSERT_EQ(3, pool_infos->size());
+ checkPoolInfos(*(*pool_infos)[0], *test_pools[2], __LINE__);
+ checkPoolInfos(*(*pool_infos)[1], *test_pools[0], __LINE__);
+ checkPoolInfos(*(*pool_infos)[2], *test_pools[1], __LINE__);
+
+ // Fetch each by exact range match.
+ for ( auto const& test_pool : test_pools) {
+ pool_infos.reset();
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool4Get(test_pool->start_address_,
+ test_pool->end_address_));
+ ASSERT_TRUE(pool_infos);
+ ASSERT_EQ(1, pool_infos->size());
+ checkPoolInfos(*(*pool_infos)[0], *test_pool, __LINE__);
+ }
+
+ // Fetch each by overlapping the pool end.
+ for ( auto const& test_pool : test_pools) {
+ pool_infos.reset();
+ auto start_address = IOAddress::increase(test_pool->start_address_);
+ auto end_address = IOAddress::increase(test_pool->end_address_);
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool4Get(start_address, end_address));
+ ASSERT_TRUE(pool_infos);
+ ASSERT_EQ(1, pool_infos->size());
+ checkPoolInfos(*(*pool_infos)[0], *test_pool, __LINE__);
+ }
+
+ // Fetch each by overlapping pool start.
+ for ( auto const& test_pool : test_pools) {
+ pool_infos.reset();
+
+ auto start_address = IOAddress(test_pool->start_address_.toUint32() - 1);
+ auto end_address = IOAddress(test_pool->end_address_.toUint32() - 1);
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool4Get(start_address, end_address));
+ ASSERT_TRUE(pool_infos);
+ ASSERT_EQ(1, pool_infos->size());
+ checkPoolInfos(*(*pool_infos)[0], *test_pool, __LINE__);
+ }
+
+ // No match, no delete.
+ bool deleted;
+ ASSERT_NO_THROW_LOG(deleted = lmptr_->sflqPool4Del(IOAddress("1.2.3.4"),
+ IOAddress("1.2.3.4")));
+ ASSERT_FALSE(deleted);
+
+ // Delete each pool.
+ for ( auto const& test_pool : test_pools) {
+ // Delete the pool.
+ ASSERT_NO_THROW_LOG(deleted = lmptr_->sflqPool4Del(test_pool->start_address_,
+ test_pool->end_address_));
+ ASSERT_TRUE(deleted);
+
+ // Verify it's no longer there.
+ pool_infos.reset();
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool4Get(test_pool->start_address_,
+ test_pool->end_address_));
+ ASSERT_TRUE(pool_infos);
+ ASSERT_EQ(0, pool_infos->size());
+ }
+}
+
+void
+GenericLeaseMgrTest::testSflqAPIFuncs6(Lease::Type lease_type) {
+ SflqPoolInfoCollectionPtr pool_infos;
+
+ // Fetching all pools should find none.
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool6GetAll());
+ ASSERT_EQ(0, pool_infos->size());
+
+ auto test_start = boost::posix_time::second_clock::local_time();
+
+ // Create three test pools.
+ SflqPoolInfoCollection test_pools;
+ SflqPoolInfoPtr pi;
+ pi.reset(new SflqPoolInfo());
+ pi->start_address_ = IOAddress("3001::30");
+ pi->end_address_ = IOAddress("3001::32");
+ pi->subnet_id_ = 1;
+ pi->lease_type_ = lease_type;
+ pi->created_ts_ = test_start;
+ pi->modified_ts_ = test_start;
+ pi->free_leases_ = 3;
+ test_pools.push_back(pi);
+
+ pi.reset(new SflqPoolInfo());
+ pi->start_address_ = IOAddress("3001::20");
+ pi->end_address_ = IOAddress("3001::22");
+ pi->subnet_id_ = 2;
+ pi->lease_type_ = lease_type;
+ pi->created_ts_ = test_start;
+ pi->modified_ts_ = test_start;
+ pi->free_leases_ = 3;
+ test_pools.push_back(pi);
+
+ pi.reset(new SflqPoolInfo());
+ pi->start_address_ = IOAddress("3001::10");
+ pi->end_address_ = IOAddress("3001::12");
+ pi->subnet_id_ = 1;
+ pi->lease_type_ = lease_type;
+ pi->created_ts_ = test_start;
+ pi->modified_ts_ = test_start;
+ pi->free_leases_ = 3;
+ test_pools.push_back(pi);
+
+ for ( auto const& test_pool : test_pools) {
+ ASSERT_NO_THROW_LOG(
+ lmptr_->sflqCreateFlqPool6(test_pool->start_address_,
+ test_pool->end_address_,
+ test_pool->lease_type_,
+ test_pool->delegated_len_,
+ test_pool->subnet_id_, false));
+ }
+
+ // Fetching all pools should find none.
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool6GetAll());
+ ASSERT_TRUE(pool_infos);
+ ASSERT_EQ(3, pool_infos->size());
+
+ // Should get them back ordered by subnet and start address.
+ checkPoolInfos(*(*pool_infos)[0], *test_pools[2], __LINE__);
+ checkPoolInfos(*(*pool_infos)[1], *test_pools[0], __LINE__);
+ checkPoolInfos(*(*pool_infos)[2], *test_pools[1], __LINE__);
+
+ // Fetch by subnet id for subnet_id = 1.
+ pool_infos.reset();
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool6Get(1));
+ ASSERT_TRUE(pool_infos);
+ ASSERT_EQ(2, pool_infos->size());
+ checkPoolInfos(*(*pool_infos)[0], *test_pools[2], __LINE__);
+ checkPoolInfos(*(*pool_infos)[1], *test_pools[0], __LINE__);
+
+ // Fetch by subnet id for subnet_id = 2.
+ pool_infos.reset();
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool6Get(2));
+ ASSERT_TRUE(pool_infos);
+ ASSERT_EQ(1, pool_infos->size());
+ checkPoolInfos(*(*pool_infos)[0], *test_pools[1], __LINE__);
+
+ // Fetch by subnet id for subnet_id = 99
+ pool_infos.reset();
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool6Get(99));
+ ASSERT_TRUE(pool_infos);
+ ASSERT_EQ(0, pool_infos->size());
+
+ // Fetch by a range that excludes them all.
+ pool_infos.reset();
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool6Get(IOAddress("2001::1"),
+ IOAddress("2001::2")));
+ ASSERT_TRUE(pool_infos);
+ ASSERT_EQ(0, pool_infos->size());
+
+ // Fetch by a range that includes them all.
+ pool_infos.reset();
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool6Get(IOAddress("3001::"),
+ IOAddress("3001::FF")));
+ ASSERT_TRUE(pool_infos);
+ ASSERT_EQ(3, pool_infos->size());
+ checkPoolInfos(*(*pool_infos)[0], *test_pools[2], __LINE__);
+ checkPoolInfos(*(*pool_infos)[1], *test_pools[0], __LINE__);
+ checkPoolInfos(*(*pool_infos)[2], *test_pools[1], __LINE__);
+
+ // Fetch each by exact range match.
+ for ( auto const& test_pool : test_pools) {
+ pool_infos.reset();
+ auto start_address = test_pool->start_address_;
+ auto end_address = test_pool->end_address_;
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool6Get(start_address.toText(),
+ end_address.toText()));
+ ASSERT_TRUE(pool_infos);
+ ASSERT_EQ(1, pool_infos->size()) << start_address.toText() << " - " << end_address.toText();
+ checkPoolInfos(*(*pool_infos)[0], *test_pool, __LINE__);
+ }
+
+ // Fetch each by overlapping the pool end.
+ for ( auto const& test_pool : test_pools) {
+ pool_infos.reset();
+ auto start_address = IOAddress::increase(test_pool->start_address_);
+ auto end_address = IOAddress::increase(test_pool->end_address_);
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool6Get(start_address, end_address));
+ ASSERT_TRUE(pool_infos);
+ ASSERT_EQ(1, pool_infos->size());
+ checkPoolInfos(*(*pool_infos)[0], *test_pool, __LINE__);
+ }
+
+ // Fetch each by overlapping pool start.
+ for ( auto const& test_pool : test_pools) {
+ pool_infos.reset();
+
+ IOAddress one("::1");
+ auto start_address = IOAddress::subtract(test_pool->start_address_, one);
+ auto end_address = IOAddress::subtract(test_pool->end_address_, one);
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool6Get(start_address, end_address));
+ ASSERT_TRUE(pool_infos);
+ ASSERT_EQ(1, pool_infos->size());
+ checkPoolInfos(*(*pool_infos)[0], *test_pool, __LINE__);
+ }
+
+ // No match, no delete.
+ bool deleted;
+ ASSERT_NO_THROW_LOG(deleted = lmptr_->sflqPool6Del(IOAddress("2001::1"),
+ IOAddress("2001::2")));
+ ASSERT_FALSE(deleted);
+
+ // Delete each pool.
+ for ( auto const& test_pool : test_pools) {
+ // Delete the pool.
+ ASSERT_NO_THROW_LOG(deleted = lmptr_->sflqPool6Del(test_pool->start_address_,
+ test_pool->end_address_));
+ ASSERT_TRUE(deleted);
+
+ // Verify it's no longer there.
+ pool_infos.reset();
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool6Get(test_pool->start_address_,
+ test_pool->end_address_));
+ ASSERT_TRUE(pool_infos);
+ ASSERT_EQ(0, pool_infos->size());
+ }
+}
+
+void
+GenericLeaseMgrTest::testSflqAPIOverlappingPools4() {
+ SflqPoolInfoCollectionPtr pool_infos;
+
+ // Fetching all pools should find none.
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool4GetAll());
+ ASSERT_EQ(0, pool_infos->size());
+
+ auto test_start = boost::posix_time::second_clock::local_time();
+
+ // Create three test pools.
+ SflqPoolInfoCollection test_pools;
+ SflqPoolInfoPtr pi;
+ pi.reset(new SflqPoolInfo());
+ pi->start_address_ = IOAddress("192.0.1.10");
+ pi->end_address_ = IOAddress("192.0.1.20");
+ pi->subnet_id_ = 1;
+ pi->created_ts_ = test_start;
+ pi->modified_ts_ = test_start;
+ pi->free_leases_ = 11;
+ test_pools.push_back(pi);
+
+ pi.reset(new SflqPoolInfo());
+ pi->start_address_ = IOAddress("192.0.1.15");
+ pi->end_address_ = IOAddress("192.0.1.25");
+ pi->subnet_id_ = 1;
+ pi->created_ts_ = test_start;
+ pi->modified_ts_ = test_start;
+ pi->free_leases_ = 11;
+ test_pools.push_back(pi);
+
+ pi.reset(new SflqPoolInfo());
+ pi->start_address_ = IOAddress("192.0.1.20");
+ pi->end_address_ = IOAddress("192.0.1.30");
+ pi->subnet_id_ = 1;
+ pi->created_ts_ = test_start;
+ pi->modified_ts_ = test_start;
+ pi->free_leases_ = 11;
+ test_pools.push_back(pi);
+
+ for ( auto const& test_pool : test_pools) {
+ ASSERT_NO_THROW_LOG(
+ lmptr_->sflqCreateFlqPool4(test_pool->start_address_,
+ test_pool->end_address_,
+ test_pool->subnet_id_, false));
+ }
+
+ // Fetch by middle pool's range should return all three.
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool4Get(test_pools[1]->start_address_,
+ test_pools[1]->end_address_));
+ ASSERT_TRUE(pool_infos);
+ ASSERT_EQ(3, pool_infos->size());
+ checkPoolInfos(*(*pool_infos)[0], *test_pools[0], __LINE__);
+ checkPoolInfos(*(*pool_infos)[1], *test_pools[1], __LINE__);
+ checkPoolInfos(*(*pool_infos)[2], *test_pools[2], __LINE__);
+
+ // Attempting to delete middle pool should return false.
+ ASSERT_THROW_MSG(lmptr_->sflqPool4Del(test_pools[1]->start_address_,
+ test_pools[1]->end_address_),
+ InvalidOperation, "Delete would affect 3 overlapping pools");
+ bool deleted;
+ ASSERT_NO_THROW_LOG(deleted = lmptr_->sflqPool4Del(test_pools[1]->start_address_,
+ test_pools[1]->end_address_, true));
+ ASSERT_TRUE(deleted);
+
+ // Fetch by middle pool's range should the remaining two.
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool4Get(test_pools[1]->start_address_,
+ test_pools[1]->end_address_));
+ ASSERT_TRUE(pool_infos);
+ ASSERT_EQ(2, pool_infos->size());
+ // Deleting the middle pool affects free_lease count for the other two.
+ // Users would need to fix them by calling create with recreate = true.
+ test_pools[0]->free_leases_ = 5;
+ test_pools[2]->free_leases_ = 5;
+ checkPoolInfos(*(*pool_infos)[0], *test_pools[0], __LINE__);
+ checkPoolInfos(*(*pool_infos)[1], *test_pools[2], __LINE__);
+}
+
+void
+GenericLeaseMgrTest::testSflqAPIOverlappingPools6(Lease::Type lease_type) {
+ SflqPoolInfoCollectionPtr pool_infos;
+
+ // Fetching all pools should find none.
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool6GetAll());
+ ASSERT_EQ(0, pool_infos->size());
+
+ auto test_start = boost::posix_time::second_clock::local_time();
+
+ // Create three test pools.
+ SflqPoolInfoCollection test_pools;
+ SflqPoolInfoPtr pi;
+ pi.reset(new SflqPoolInfo());
+ pi->start_address_ = IOAddress("3001::10");
+ pi->end_address_ = IOAddress("3001::20");
+ pi->subnet_id_ = 1;
+ pi->lease_type_ = lease_type;
+ pi->created_ts_ = test_start;
+ pi->modified_ts_ = test_start;
+ pi->free_leases_ = 17;
+ test_pools.push_back(pi);
+
+ pi.reset(new SflqPoolInfo());
+ pi->start_address_ = IOAddress("3001::15");
+ pi->end_address_ = IOAddress("3001::25");
+ pi->subnet_id_ = 1;
+ pi->lease_type_ = lease_type;
+ pi->created_ts_ = test_start;
+ pi->modified_ts_ = test_start;
+ pi->free_leases_ = 17;
+ test_pools.push_back(pi);
+
+ pi.reset(new SflqPoolInfo());
+ pi->start_address_ = IOAddress("3001::20");
+ pi->end_address_ = IOAddress("3001::30");
+ pi->subnet_id_ = 1;
+ pi->lease_type_ = lease_type;
+ pi->created_ts_ = test_start;
+ pi->modified_ts_ = test_start;
+ pi->free_leases_ = 17;
+ test_pools.push_back(pi);
+
+ for ( auto const& test_pool : test_pools) {
+ ASSERT_NO_THROW_LOG(
+ lmptr_->sflqCreateFlqPool6(test_pool->start_address_,
+ test_pool->end_address_,
+ test_pool->lease_type_,
+ test_pool->delegated_len_,
+ test_pool->subnet_id_, false));
+ }
+
+ // Fetch by middle pool's range should return all three.
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool6Get(test_pools[1]->start_address_,
+ test_pools[1]->end_address_));
+ ASSERT_TRUE(pool_infos);
+ ASSERT_EQ(3, pool_infos->size());
+ checkPoolInfos(*(*pool_infos)[0], *test_pools[0], __LINE__);
+ checkPoolInfos(*(*pool_infos)[1], *test_pools[1], __LINE__);
+ checkPoolInfos(*(*pool_infos)[2], *test_pools[2], __LINE__);
+
+ // Attempting to delete middle pool should return false.
+ ASSERT_THROW_MSG(lmptr_->sflqPool6Del(test_pools[1]->start_address_,
+ test_pools[1]->end_address_),
+ InvalidOperation, "Delete would affect 3 overlapping pools");
+ bool deleted;
+ ASSERT_NO_THROW_LOG(deleted = lmptr_->sflqPool6Del(test_pools[1]->start_address_,
+ test_pools[1]->end_address_, true));
+ ASSERT_TRUE(deleted);
+
+ // Fetch by middle pool's range should the remaining two.
+ ASSERT_NO_THROW_LOG(pool_infos = lmptr_->sflqPool6Get(test_pools[1]->start_address_,
+ test_pools[1]->end_address_));
+ ASSERT_TRUE(pool_infos);
+ ASSERT_EQ(2, pool_infos->size());
+ // Deleting the middle pool affects free_lease count for the other two.
+ // Users would need to fix them by calling create with recreate = true.
+ test_pools[0]->free_leases_ = 5;
+ test_pools[2]->free_leases_ = 11;
+ checkPoolInfos(*(*pool_infos)[0], *test_pools[0], __LINE__);
+ checkPoolInfos(*(*pool_infos)[1], *test_pools[2], __LINE__);
+}
} // namespace test
} // namespace dhcp
int countLogs(TrackingLeaseMgr::CallbackType type, SubnetID subnet_id,
Lease::Type lease_type) const;
+ /// Compare two SflqPoolInfo structures for equality.
+ ///
+ /// All members are compared for equality except the timestamps. Those
+ /// are considered correct if the lhs timestamps are greater than or
+ /// equal to their rhs counterparts. Asserts if they are not "equal".
+ ///
+ /// @param lhs left-side instance to compare
+ /// @param rhs reft-side instance to compare
+ /// @param lineno source line of invocation (pass in __LINE__)
+ void checkPoolInfos(const SflqPoolInfo& lhs, const SflqPoolInfo& rhs, int lineno);
+
/// @brief checks that addLease, getLease4(addr) and deleteLease() works
void testBasicLease4();
/// @param lease_type lease type to test (TYPE_NA or TYPE_PD)
void testSflqLeaseOps6(Lease::Type lease_type);
+ /// @brief Checks V4 SFLQ API sflqPool4Get*, sflqPool4Del
+ void testSflqAPIFuncs4();
+
+ /// @brief Checks V4 SFLQ API behavior with overlapping pools.
+ void testSflqAPIOverlappingPools4();
+
+ /// @brief Checks V6 SFLQ API sflqPool6Get*, sflqPool6Del
+ ///
+ /// @param lease_type lease type to test (TYPE_NA or TYPE_PD)
+ void testSflqAPIFuncs6(Lease::Type lease_type);
+
+ /// @brief Checks V6 SFLQ API behavior with overlapping pools.
+ ///
+ /// @param lease_type lease type to test (TYPE_NA or TYPE_PD)
+ void testSflqAPIOverlappingPools6(Lease::Type lease_type);
+
/// @brief String forms of IPv4 addresses
std::vector<std::string> straddress4_;