2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-30 05:27:55 +00:00

[3147] Implemented use of lease type in MySQL for IPv6 lease queries

Added support for lease type discrimination in IPv6 lease
operations in MySQL backend used by DHCP6, dhcpsrv/mysql_lease_mgr
This commit is contained in:
Thomas Markwalder 2013-09-13 10:05:28 -04:00
parent 928a9b6e56
commit 91c0c0605d
3 changed files with 144 additions and 35 deletions

View File

@ -252,7 +252,7 @@ recommended.
A debug message issued when the server is about to add an IPv4 lease A debug message issued when the server is about to add an IPv4 lease
with the specified address to the MySQL backend database. with the specified address to the MySQL backend database.
% DHCPSRV_MYSQL_ADD_ADDR6 adding IPv6 lease with address %1 % DHCPSRV_MYSQL_ADD_ADDR6 adding IPv6 lease with address %1, lease type %2
A debug message issued when the server is about to add an IPv6 lease A debug message issued when the server is about to add an IPv6 lease
with the specified address to the MySQL backend database. with the specified address to the MySQL backend database.
@ -275,7 +275,7 @@ the specified address from the MySQL database for the specified address.
A debug message issued when the server is attempting to obtain an IPv4 A debug message issued when the server is attempting to obtain an IPv4
lease from the MySQL database for the specified address. lease from the MySQL database for the specified address.
% DHCPSRV_MYSQL_GET_ADDR6 obtaining IPv6 lease for address %1 % DHCPSRV_MYSQL_GET_ADDR6 obtaining IPv6 lease for address %1, lease type %2
A debug message issued when the server is attempting to obtain an IPv6 A debug message issued when the server is attempting to obtain an IPv6
lease from the MySQL database for the specified address. lease from the MySQL database for the specified address.
@ -289,12 +289,12 @@ A debug message issued when the server is attempting to obtain a set
of IPv4 leases from the MySQL database for a client with the specified of IPv4 leases from the MySQL database for a client with the specified
hardware address. hardware address.
% DHCPSRV_MYSQL_GET_IAID_DUID obtaining IPv4 leases for IAID %1 and DUID %2 % DHCPSRV_MYSQL_GET_IAID_DUID obtaining IPv6 leases for IAID %1, DUID %2, and lease type %3
A debug message issued when the server is attempting to obtain a set of A debug message issued when the server is attempting to obtain a set of
IPv6 lease from the MySQL database for a client with the specified IAID IPv6 lease from the MySQL database for a client with the specified IAID
(Identity Association ID) and DUID (DHCP Unique Identifier). (Identity Association ID) and DUID (DHCP Unique Identifier).
% DHCPSRV_MYSQL_GET_IAID_SUBID_DUID obtaining IPv4 leases for IAID %1, Subnet ID %2 and DUID %3 % DHCPSRV_MYSQL_GET_IAID_SUBID_DUID obtaining IPv6 leases for IAID %1, Subnet ID %2, DUID %3, and lease type %4
A debug message issued when the server is attempting to obtain an IPv6 A debug message issued when the server is attempting to obtain an IPv6
lease from the MySQL database for a client with the specified IAID lease from the MySQL database for a client with the specified IAID
(Identity Association ID), Subnet ID and DUID (DHCP Unique Identifier). (Identity Association ID), Subnet ID and DUID (DHCP Unique Identifier).
@ -321,7 +321,7 @@ be rolled back and not committed to the database.
A debug message issued when the server is attempting to update IPv4 A debug message issued when the server is attempting to update IPv4
lease from the MySQL database for the specified address. lease from the MySQL database for the specified address.
% DHCPSRV_MYSQL_UPDATE_ADDR6 updating IPv6 lease for address %1 % DHCPSRV_MYSQL_UPDATE_ADDR6 updating IPv6 lease for address %1, lease type %2
A debug message issued when the server is attempting to update IPv6 A debug message issued when the server is attempting to update IPv6
lease from the MySQL database for the specified address. lease from the MySQL database for the specified address.

View File

@ -163,21 +163,22 @@ TaggedStatement tagged_statements[] = {
"lease_type, iaid, prefix_len, " "lease_type, iaid, prefix_len, "
"fqdn_fwd, fqdn_rev, hostname " "fqdn_fwd, fqdn_rev, hostname "
"FROM lease6 " "FROM lease6 "
"WHERE address = ?"}, "WHERE address = ? and lease_type = ?"},
{MySqlLeaseMgr::GET_LEASE6_DUID_IAID, {MySqlLeaseMgr::GET_LEASE6_DUID_IAID,
"SELECT address, duid, valid_lifetime, " "SELECT address, duid, valid_lifetime, "
"expire, subnet_id, pref_lifetime, " "expire, subnet_id, pref_lifetime, "
"lease_type, iaid, prefix_len, " "lease_type, iaid, prefix_len, "
"fqdn_fwd, fqdn_rev, hostname " "fqdn_fwd, fqdn_rev, hostname "
"FROM lease6 " "FROM lease6 "
"WHERE duid = ? AND iaid = ?"}, "WHERE duid = ? AND iaid = ? AND lease_type = ?"},
{MySqlLeaseMgr::GET_LEASE6_DUID_IAID_SUBID, {MySqlLeaseMgr::GET_LEASE6_DUID_IAID_SUBID,
"SELECT address, duid, valid_lifetime, " "SELECT address, duid, valid_lifetime, "
"expire, subnet_id, pref_lifetime, " "expire, subnet_id, pref_lifetime, "
"lease_type, iaid, prefix_len, " "lease_type, iaid, prefix_len, "
"fqdn_fwd, fqdn_rev, hostname " "fqdn_fwd, fqdn_rev, hostname "
"FROM lease6 " "FROM lease6 "
"WHERE duid = ? AND iaid = ? AND subnet_id = ?"}, "WHERE duid = ? AND iaid = ? AND subnet_id = ? "
"AND lease_type = ?"},
{MySqlLeaseMgr::GET_VERSION, {MySqlLeaseMgr::GET_VERSION,
"SELECT version, minor FROM schema_version"}, "SELECT version, minor FROM schema_version"},
{MySqlLeaseMgr::INSERT_LEASE4, {MySqlLeaseMgr::INSERT_LEASE4,
@ -1374,7 +1375,8 @@ MySqlLeaseMgr::addLease(const Lease4Ptr& lease) {
bool bool
MySqlLeaseMgr::addLease(const Lease6Ptr& lease) { MySqlLeaseMgr::addLease(const Lease6Ptr& lease) {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_MYSQL_ADD_ADDR6).arg(lease->addr_.toText()); DHCPSRV_MYSQL_ADD_ADDR6).arg(lease->addr_.toText())
.arg(lease->type_);
// Create the MYSQL_BIND array for the lease // Create the MYSQL_BIND array for the lease
std::vector<MYSQL_BIND> bind = exchange6_->createBindForSend(lease); std::vector<MYSQL_BIND> bind = exchange6_->createBindForSend(lease);
@ -1651,13 +1653,14 @@ MySqlLeaseMgr::getLease4(const ClientId& clientid, SubnetID subnet_id) const {
Lease6Ptr Lease6Ptr
MySqlLeaseMgr::getLease6(Lease6::LeaseType /* type - not used yet */, MySqlLeaseMgr::getLease6(Lease6::LeaseType lease_type,
const isc::asiolink::IOAddress& addr) const { const isc::asiolink::IOAddress& addr) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_MYSQL_GET_ADDR6).arg(addr.toText()); DHCPSRV_MYSQL_GET_ADDR6).arg(addr.toText())
.arg(lease_type);
// Set up the WHERE clause value // Set up the WHERE clause value
MYSQL_BIND inbind[1]; MYSQL_BIND inbind[2];
memset(inbind, 0, sizeof(inbind)); memset(inbind, 0, sizeof(inbind));
std::string addr6 = addr.toText(); std::string addr6 = addr.toText();
@ -1670,6 +1673,11 @@ MySqlLeaseMgr::getLease6(Lease6::LeaseType /* type - not used yet */,
inbind[0].buffer_length = addr6_length; inbind[0].buffer_length = addr6_length;
inbind[0].length = &addr6_length; inbind[0].length = &addr6_length;
// LEASE_TYPE
inbind[1].buffer_type = MYSQL_TYPE_TINY;
inbind[1].buffer = reinterpret_cast<char*>(&lease_type);
inbind[1].is_unsigned = MLM_TRUE;
Lease6Ptr result; Lease6Ptr result;
getLease(GET_LEASE6_ADDR, inbind, result); getLease(GET_LEASE6_ADDR, inbind, result);
@ -1678,13 +1686,14 @@ MySqlLeaseMgr::getLease6(Lease6::LeaseType /* type - not used yet */,
Lease6Collection Lease6Collection
MySqlLeaseMgr::getLeases6(Lease6::LeaseType /* type - not used yet */, MySqlLeaseMgr::getLeases6(Lease6::LeaseType lease_type,
const DUID& duid, uint32_t iaid) const { const DUID& duid, uint32_t iaid) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_MYSQL_GET_IAID_DUID).arg(iaid).arg(duid.toText()); DHCPSRV_MYSQL_GET_IAID_DUID).arg(iaid).arg(duid.toText())
.arg(lease_type);
// Set up the WHERE clause value // Set up the WHERE clause value
MYSQL_BIND inbind[2]; MYSQL_BIND inbind[3];
memset(inbind, 0, sizeof(inbind)); memset(inbind, 0, sizeof(inbind));
// In the following statement, the DUID is being read. However, the // In the following statement, the DUID is being read. However, the
@ -1712,6 +1721,11 @@ MySqlLeaseMgr::getLeases6(Lease6::LeaseType /* type - not used yet */,
inbind[1].buffer = reinterpret_cast<char*>(&iaid); inbind[1].buffer = reinterpret_cast<char*>(&iaid);
inbind[1].is_unsigned = MLM_TRUE; inbind[1].is_unsigned = MLM_TRUE;
// LEASE_TYPE
inbind[2].buffer_type = MYSQL_TYPE_TINY;
inbind[2].buffer = reinterpret_cast<char*>(&lease_type);
inbind[2].is_unsigned = MLM_TRUE;
// ... and get the data // ... and get the data
Lease6Collection result; Lease6Collection result;
getLeaseCollection(GET_LEASE6_DUID_IAID, inbind, result); getLeaseCollection(GET_LEASE6_DUID_IAID, inbind, result);
@ -1720,15 +1734,16 @@ MySqlLeaseMgr::getLeases6(Lease6::LeaseType /* type - not used yet */,
} }
Lease6Collection Lease6Collection
MySqlLeaseMgr::getLeases6(Lease6::LeaseType /* type - not used yet */, MySqlLeaseMgr::getLeases6(Lease6::LeaseType lease_type,
const DUID& duid, uint32_t iaid, const DUID& duid, uint32_t iaid,
SubnetID subnet_id) const { SubnetID subnet_id) const {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_MYSQL_GET_IAID_SUBID_DUID) DHCPSRV_MYSQL_GET_IAID_SUBID_DUID)
.arg(iaid).arg(subnet_id).arg(duid.toText()); .arg(iaid).arg(subnet_id).arg(duid.toText())
.arg(lease_type);
// Set up the WHERE clause value // Set up the WHERE clause value
MYSQL_BIND inbind[3]; MYSQL_BIND inbind[4];
memset(inbind, 0, sizeof(inbind)); memset(inbind, 0, sizeof(inbind));
// See the earlier description of the use of "const_cast" when accessing // See the earlier description of the use of "const_cast" when accessing
@ -1751,14 +1766,16 @@ MySqlLeaseMgr::getLeases6(Lease6::LeaseType /* type - not used yet */,
inbind[2].buffer = reinterpret_cast<char*>(&subnet_id); inbind[2].buffer = reinterpret_cast<char*>(&subnet_id);
inbind[2].is_unsigned = MLM_TRUE; inbind[2].is_unsigned = MLM_TRUE;
Lease6Ptr result; // LEASE_TYPE
getLease(GET_LEASE6_DUID_IAID_SUBID, inbind, result); inbind[3].buffer_type = MYSQL_TYPE_TINY;
inbind[3].buffer = reinterpret_cast<char*>(&lease_type);
inbind[3].is_unsigned = MLM_TRUE;
/// @todo: Implement getting one than more lease at the time // ... and get the data
Lease6Collection collection; Lease6Collection result;
collection.push_back(result); getLeaseCollection(GET_LEASE6_DUID_IAID_SUBID, inbind, result);
return (collection); return (result);
} }
// Update lease methods. These comprise common code that handles the actual // Update lease methods. These comprise common code that handles the actual
@ -1823,7 +1840,8 @@ MySqlLeaseMgr::updateLease6(const Lease6Ptr& lease) {
const StatementIndex stindex = UPDATE_LEASE6; const StatementIndex stindex = UPDATE_LEASE6;
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_MYSQL_UPDATE_ADDR6).arg(lease->addr_.toText()); DHCPSRV_MYSQL_UPDATE_ADDR6).arg(lease->addr_.toText())
.arg(lease->type_);
// Create the MYSQL_BIND array for the data being updated // Create the MYSQL_BIND array for the data being updated
std::vector<MYSQL_BIND> bind = exchange6_->createBindForSend(lease); std::vector<MYSQL_BIND> bind = exchange6_->createBindForSend(lease);

View File

@ -824,8 +824,7 @@ TEST_F(MySqlLeaseMgrTest, getLease4ClientIdSubnetId) {
/// ///
/// Adds leases to the database and checks that they can be accessed via /// Adds leases to the database and checks that they can be accessed via
/// a combination of DIUID and IAID. /// a combination of DIUID and IAID.
/// @todo: update this test once type checking/filtering is implemented TEST_F(MySqlLeaseMgrTest, getLeases6DuidIaid) {
TEST_F(MySqlLeaseMgrTest, getLease6DuidIaid) {
// Get the leases to be used for the test. // Get the leases to be used for the test.
vector<Lease6Ptr> leases = createLeases6(); vector<Lease6Ptr> leases = createLeases6();
ASSERT_LE(6, leases.size()); // Expect to access leases 0 through 5 ASSERT_LE(6, leases.size()); // Expect to access leases 0 through 5
@ -840,8 +839,8 @@ TEST_F(MySqlLeaseMgrTest, getLease6DuidIaid) {
*leases[1]->duid_, *leases[1]->duid_,
leases[1]->iaid_); leases[1]->iaid_);
// Should be three leases, matching leases[1], [4] and [5]. // Should be two leases, matching leases[1] and [4].
ASSERT_EQ(3, returned.size()); ASSERT_EQ(2, returned.size());
// Easiest way to check is to look at the addresses. // Easiest way to check is to look at the addresses.
vector<string> addresses; vector<string> addresses;
@ -852,7 +851,6 @@ TEST_F(MySqlLeaseMgrTest, getLease6DuidIaid) {
sort(addresses.begin(), addresses.end()); sort(addresses.begin(), addresses.end());
EXPECT_EQ(straddress6_[1], addresses[0]); EXPECT_EQ(straddress6_[1], addresses[0]);
EXPECT_EQ(straddress6_[4], addresses[1]); EXPECT_EQ(straddress6_[4], addresses[1]);
EXPECT_EQ(straddress6_[5], addresses[2]);
// Check that nothing is returned when either the IAID or DUID match // Check that nothing is returned when either the IAID or DUID match
// nothing. // nothing.
@ -871,8 +869,7 @@ TEST_F(MySqlLeaseMgrTest, getLease6DuidIaid) {
// @brief Get Lease4 by DUID and IAID (2) // @brief Get Lease4 by DUID and IAID (2)
// //
// Check that the system can cope with a DUID of any size. // Check that the system can cope with a DUID of any size.
/// @todo: update this test once type checking/filtering is implemented TEST_F(MySqlLeaseMgrTest, getLeases6DuidIaidSize) {
TEST_F(MySqlLeaseMgrTest, getLease6DuidIaidSize) {
// Create leases, although we need only one. // Create leases, although we need only one.
vector<Lease6Ptr> leases = createLeases6(); vector<Lease6Ptr> leases = createLeases6();
@ -902,6 +899,99 @@ TEST_F(MySqlLeaseMgrTest, getLease6DuidIaidSize) {
// tests. // tests.
} }
/// @brief Check that getLease6 methods discriminate by lease type.
///
/// Adds six leases, two per lease type all with the same duid and iad but
/// with alternating subnet_ids.
/// It then verifies that all of getLeases6() method variants correctly
/// discriminate between the leases based on lease type alone.
TEST_F(MySqlLeaseMgrTest, lease6LeaseTypeCheck) {
Lease6Ptr empty_lease(new Lease6());
DuidPtr duid(new DUID(vector<uint8_t>(8, 0x77)));
// Initialize unused fields.
empty_lease->t1_ = 0; // Not saved
empty_lease->t2_ = 0; // Not saved
empty_lease->fixed_ = false; // Unused
empty_lease->comments_ = std::string(""); // Unused
empty_lease->iaid_ = 142;
empty_lease->duid_ = DuidPtr(new DUID(*duid));
empty_lease->subnet_id_ = 23;
empty_lease->preferred_lft_ = 100;
empty_lease->valid_lft_ = 100;
empty_lease->cltt_ = 100;
empty_lease->fqdn_fwd_ = true;
empty_lease->fqdn_rev_ = true;
empty_lease->hostname_ = "myhost.example.com.";
empty_lease->prefixlen_ = 4;
// Make Two leases per lease type, all with the same duid, iad but
// alternate the subnet_ids.
vector<Lease6Ptr> leases;
int tick = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 2; j++) {
Lease6Ptr lease(new Lease6(*empty_lease));
lease->type_ = leasetype6_[i];
lease->addr_ = IOAddress(straddress6_[tick++]);
lease->subnet_id_ += j;
std::cout << "ok, subnet is: " << lease->subnet_id_
<< " tick is:" << tick << std::endl;
leases.push_back(lease);
EXPECT_TRUE(lmptr_->addLease(lease));
}
}
// Verify getting a single lease by type and address.
for (int i = 0; i < 3; i++) {
// Look for exact match for each lease type.
Lease6Ptr returned = lmptr_->getLease6(leasetype6_[i],
leases[i*2]->addr_);
// We should match one per lease type.
ASSERT_TRUE(returned);
EXPECT_TRUE(*returned == *leases[i*2]);
// Same address but wrong lease type, should not match.
returned = lmptr_->getLease6(leasetype6_[i+1], leases[i*2]->addr_);
ASSERT_FALSE(returned);
}
// Verify getting a collection of leases by type, duid, and iad.
// Iterate over the lease types, asking for leases based on
// lease type, duid, and iad.
tick = 0;
for (int i = 0; i < 3; i++) {
Lease6Collection returned = lmptr_->getLeases6(leasetype6_[i],
*duid, 142);
// We should match two per lease type.
ASSERT_EQ(2, returned.size());
EXPECT_TRUE(*(returned[0]) == *leases[tick++]);
EXPECT_TRUE(*(returned[1]) == *leases[tick++]);
}
// Verify getting a collection of leases by type, duid, iad, and subnet id.
// Iterate over the lease types, asking for leases based on
// lease type, duid, iad, and subnet_id.
for (int i = 0; i < 3; i++) {
Lease6Collection returned = lmptr_->getLeases6(leasetype6_[i],
*duid, 142, 23);
// We should match one per lease type.
ASSERT_EQ(1, returned.size());
EXPECT_TRUE(*(returned[0]) == *leases[i*2]);
}
// Verify getting a single lease by type, duid, iad, and subnet id.
for (int i = 0; i < 3; i++) {
Lease6Ptr returned = lmptr_->getLease6(leasetype6_[i],
*duid, 142, 23);
// We should match one per lease type.
ASSERT_TRUE(returned);
EXPECT_TRUE(*returned == *leases[i*2]);
}
}
/// @brief Check GetLease6 methods - access by DUID/IAID/SubnetID /// @brief Check GetLease6 methods - access by DUID/IAID/SubnetID
/// ///
/// Adds leases to the database and checks that they can be accessed via /// Adds leases to the database and checks that they can be accessed via
@ -939,6 +1029,7 @@ TEST_F(MySqlLeaseMgrTest, getLease6DuidIaidSubnetId) {
EXPECT_FALSE(returned); EXPECT_FALSE(returned);
} }
// @brief Get Lease4 by DUID, IAID & subnet ID (2) // @brief Get Lease4 by DUID, IAID & subnet ID (2)
// //
// Check that the system can cope with a DUID of any size. // Check that the system can cope with a DUID of any size.
@ -1051,7 +1142,7 @@ TEST_F(MySqlLeaseMgrTest, updateLease6) {
// ... and check what is returned is what is expected. // ... and check what is returned is what is expected.
l_returned.reset(); l_returned.reset();
l_returned = lmptr_->getLease6(leasetype6_[1], ioaddress6_[1]); l_returned = lmptr_->getLease6(Lease6::LEASE_IA_PD, ioaddress6_[1]);
ASSERT_TRUE(l_returned); ASSERT_TRUE(l_returned);
detailCompareLease(leases[1], l_returned); detailCompareLease(leases[1], l_returned);
@ -1063,14 +1154,14 @@ TEST_F(MySqlLeaseMgrTest, updateLease6) {
lmptr_->updateLease6(leases[1]); lmptr_->updateLease6(leases[1]);
l_returned.reset(); l_returned.reset();
l_returned = lmptr_->getLease6(leasetype6_[1], ioaddress6_[1]); l_returned = lmptr_->getLease6(Lease6::LEASE_IA_TA, ioaddress6_[1]);
ASSERT_TRUE(l_returned); ASSERT_TRUE(l_returned);
detailCompareLease(leases[1], l_returned); detailCompareLease(leases[1], l_returned);
// Check we can do an update without changing data. // Check we can do an update without changing data.
lmptr_->updateLease6(leases[1]); lmptr_->updateLease6(leases[1]);
l_returned.reset(); l_returned.reset();
l_returned = lmptr_->getLease6(leasetype6_[1], ioaddress6_[1]); l_returned = lmptr_->getLease6(Lease6::LEASE_IA_TA, ioaddress6_[1]);
ASSERT_TRUE(l_returned); ASSERT_TRUE(l_returned);
detailCompareLease(leases[1], l_returned); detailCompareLease(leases[1], l_returned);