Browse Source

[2404] Add method to get lease4 by hardware address & subnet ID

Stephen Morris 12 years ago
parent
commit
3eab2458f1

+ 33 - 5
src/lib/dhcpsrv/mysql_lease_mgr.cc

@@ -66,6 +66,11 @@ TaggedStatement tagged_statements[] = {
                         "valid_lifetime, expire, subnet_id "
                             "FROM lease4 "
                             "WHERE hwaddr = ?"},
+    {MySqlLeaseMgr::GET_LEASE4_HWADDR_SUBID,
+                    "SELECT address, hwaddr, client_id, "
+                        "valid_lifetime, expire, subnet_id "
+                            "FROM lease4 "
+                            "WHERE hwaddr = ? AND subnet_id = ?"},
     {MySqlLeaseMgr::GET_LEASE4_ADDR,
                     "SELECT address, hwaddr, client_id, "
                         "valid_lifetime, expire, subnet_id "
@@ -1104,14 +1109,37 @@ MySqlLeaseMgr::getLease4(const HWAddr& hwaddr) const {
 
 
 Lease4Ptr
-MySqlLeaseMgr::getLease4(const HWAddr& /* hwaddr */,
-                         SubnetID /* subnet_id */) const {
-    isc_throw(NotImplemented, "MySqlLeaseMgr::getLease4(const HWAddr&, SubnetID) "
-              "not implemented yet");
-    return (Lease4Ptr());
+MySqlLeaseMgr::getLease4(const HWAddr& hwaddr, SubnetID subnet_id) const {
+    // Set up the WHERE clause value
+    MYSQL_BIND inbind[2];
+    memset(inbind, 0, sizeof(inbind));
+
+    // As "buffer" is "char*" - even though the data is being read - we need
+    // to cast away the "const"ness as well as reinterpreting the data as
+    // a "char*". (We could avoid the "const_cast" by copying the data to a
+    // local variable, but as the data is only being read, this introduces
+    // an unnecessary copy).
+    unsigned long hwaddr_length = hwaddr.size();
+    uint8_t* data = const_cast<uint8_t*>(&hwaddr[0]);
+
+    inbind[0].buffer_type = MYSQL_TYPE_BLOB;
+    inbind[0].buffer = reinterpret_cast<char*>(data);
+    inbind[0].buffer_length = hwaddr_length;
+    inbind[0].length = &hwaddr_length;
+
+    inbind[1].buffer_type = MYSQL_TYPE_LONG;
+    inbind[1].buffer = reinterpret_cast<char*>(&subnet_id);
+    inbind[1].is_unsigned = my_bool(1);
+
+    // Get the data
+    Lease4Ptr result;
+    getLease(GET_LEASE4_HWADDR_SUBID, inbind, exchange4_, result);
+
+    return (result);
 }
 
 
+
 Lease4Collection
 MySqlLeaseMgr::getLease4(const ClientId& /* clientid */) const {
     isc_throw(NotImplemented, "MySqlLeaseMgr::getLease4(const ClientID&) "

+ 2 - 1
src/lib/dhcpsrv/mysql_lease_mgr.h

@@ -355,7 +355,8 @@ public:
         DELETE_LEASE4,              // Delete from lease4 by address
         DELETE_LEASE6,              // Delete from lease6 by address
         GET_LEASE4_ADDR,            // Get lease4 by address
-        GET_LEASE4_HWADDR,          // Get lease4 by hardward address
+        GET_LEASE4_HWADDR,          // Get lease4 by HW address
+        GET_LEASE4_HWADDR_SUBID,    // Get lease4 by HW address & subnet ID
         GET_LEASE6_ADDR,            // Get lease6 by address
         GET_LEASE6_DUID_IAID,       // Get lease6 by DUID and IAID
         GET_LEASE6_DUID_IAID_SUBID, // Get lease6 by DUID, IAID and Subnet ID

+ 42 - 2
src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc

@@ -299,7 +299,7 @@ public:
                 new ClientId(vector<uint8_t>(8, 0x42)));
             lease->valid_lft_ = 7736;      // Actual lifetime
             lease->cltt_ = 222456;         // Current time of day
-            lease->subnet_id_ = 75;        // Arbitrary number
+            lease->subnet_id_ = 85;        // Arbitrary number
 
         } else if (address == straddress4_[5]) {
             lease->hwaddr_ = vector<uint8_t>(6, 0x19);  // Same as lease 1
@@ -812,7 +812,7 @@ TEST_F(MySqlLeaseMgrTest, basicLease6) {
 // @brief Check GetLease4 methods - Access by Address and SubnetID
 //
 // Adds leases to the database and checks that they can be accessed via
-// a combination of Address, SubnetID
+// a the hardware address
 TEST_F(MySqlLeaseMgrTest, getLease4AddressSubnetId) {
     // Get the leases to be used for the test.
     vector<Lease4Ptr> leases = createLeases4();
@@ -840,6 +840,46 @@ TEST_F(MySqlLeaseMgrTest, getLease4AddressSubnetId) {
 
 
 
+// @brief Check GetLease4 methods - Access by Hardware Address & Subnet ID
+//
+// Adds leases to the database and checks that they can be accessed via
+// a combination of hardware address and subnet ID
+
+TEST_F(MySqlLeaseMgrTest, getLease4HwaddrSubnetId) {
+    // Get the leases to be used for the test and add to the database
+    vector<Lease4Ptr> leases = createLeases4();
+    for (int i = 0; i < leases.size(); ++i) {
+        EXPECT_TRUE(lmptr_->addLease(leases[i]));
+    }
+
+    // Get the leases matching the hardware address of lease 1 and
+    // subnet ID of lease 1.  Result should be a single lease - lease 1.
+    Lease4Ptr returned = lmptr_->getLease4(leases[1]->hwaddr_,
+                                           leases[1]->subnet_id_);
+    ASSERT_TRUE(returned);
+    detailCompareLease(leases[1], returned);
+
+    // Try for a match to the hardware address of lease 1 and the wrong
+    // subnet ID.
+    returned = lmptr_->getLease4(leases[1]->hwaddr_,
+                                 leases[1]->subnet_id_ + 1);
+    EXPECT_FALSE(returned);
+
+    // Try for a match to the subnet ID of lease 1 (and lease 4) but
+    // the wrong hardware address.
+    vector<uint8_t> invalid_hwaddr(15, 0x77);
+    returned = lmptr_->getLease4(invalid_hwaddr,
+                                 leases[1]->subnet_id_);
+    EXPECT_FALSE(returned);
+
+    // Try for a match to an unknown hardware address and an unknown
+    // subnet ID.
+    returned = lmptr_->getLease4(invalid_hwaddr,
+                                 leases[1]->subnet_id_ + 1);
+    EXPECT_FALSE(returned);
+}
+
+
 // @brief Check GetLease4 methods - Access by Hardware Address
 //
 // Adds leases to the database and checks that they can be accessed via