]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[5469] checkpoint (copied with 4 -> 6)
authorFrancis Dupont <fdupont@isc.org>
Fri, 12 Jan 2018 23:24:41 +0000 (00:24 +0100)
committerFrancis Dupont <fdupont@isc.org>
Fri, 12 Jan 2018 23:24:41 +0000 (00:24 +0100)
25 files changed:
doc/guide/hooks.xml
src/hooks/dhcp/lease_cmds/lease_cmds.cc
src/hooks/dhcp/lease_cmds/lease_cmds.h
src/hooks/dhcp/lease_cmds/lease_cmds_callouts.cc
src/hooks/dhcp/lease_cmds/tests/lease_cmds_unittest.cc
src/lib/dhcpsrv/cql_lease_mgr.cc
src/lib/dhcpsrv/cql_lease_mgr.h
src/lib/dhcpsrv/dhcpsrv_messages.mes
src/lib/dhcpsrv/lease_mgr.h
src/lib/dhcpsrv/memfile_lease_mgr.cc
src/lib/dhcpsrv/memfile_lease_mgr.h
src/lib/dhcpsrv/mysql_lease_mgr.cc
src/lib/dhcpsrv/mysql_lease_mgr.h
src/lib/dhcpsrv/pgsql_lease_mgr.cc
src/lib/dhcpsrv/pgsql_lease_mgr.h
src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc
src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.h
src/lib/dhcpsrv/tests/lease_mgr_unittest.cc
src/lib/dhcpsrv/tests/memfile_lease_mgr_unittest.cc
src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc
src/lib/dhcpsrv/tests/pgsql_lease_mgr_unittest.cc
src/share/database/scripts/mysql/dhcpdb_create.mysql
src/share/database/scripts/mysql/upgrade_5.1_to_6.0.sh.in
src/share/database/scripts/pgsql/dhcpdb_create.pgsql
src/share/database/scripts/pgsql/upgrade_3.2_to_4.0.sh.in

index 645f749a3cde614784517e72e20836074ff4cda9..d68a018091386aca40f408a3a093b4de1fe745d6 100644 (file)
@@ -1340,13 +1340,17 @@ An example deletion by (subnet-id, identifier-type, identifier) looks as follows
               <para><command>lease4-get</command> - checks if an IPv4 lease with
               the specified parameters exists and returns it if it does;</para>
             </listitem>
+            <listitem>
+              <para><command>lease6-get</command> - checks if an IPv6 lease with
+              the specified parameters exists and returns it if it does;</para>
+            </listitem>
             <listitem>
               <para><command>lease4-get-all</command> - returns all IPv4 leases
               or IPv4 leases for specified subnets;</para>
             </listitem>
             <listitem>
-              <para><command>lease6-get</command> - checks if an IPv6 lease with
-              the specified parameters exists and returns it if it does;</para>
+              <para><command>lease6-get-all</command> - returns all IPv6 leases
+              or IPv6 leases for specified subnets;</para>
             </listitem>
             <listitem>
               <para><command>lease4-del</command> - attempts to delete an IPv4
@@ -1663,11 +1667,12 @@ An example result returned when the host was found:
         </section>
 
         <section>
-          <title>lease4-get-all command</title>
-          <para><command>lease4-get-all</command> is used to retrieve all IPv4
-          leases or all leases for the specified set of subnets. All leases are
-          returned when there are no arguments specified with the command as
-          in the following example:
+          <title>lease4-get-all, lease6-get-all commands</title>
+          <para><command>lease4-get-all</command> or
+          <command>lease6-get-all</command> is used to retrieve all
+          IPv4 or IPv6 leases or all leases for the specified set of
+          subnets. All leases are returned when there are no arguments
+          specified with the command as in the following example:
 <screen>
 {
     "command": "lease4-get-all"
@@ -1680,7 +1685,7 @@ An example result returned when the host was found:
           leases should be returned, e.g.:
 <screen>
 {
-    "command": "lease4-get-all",
+    "command": "lease6-get-all",
     "arguments": {
         "subnets": [ 1, 2, 3, 4 ]
     }
@@ -1695,38 +1700,45 @@ An example result returned when the host was found:
     "arguments": {
         "leases": [
             {
-                "client-id": "42:42:42:42:42:42:42:42",
                 "cltt": 12345678,
+                "duid": "42:42:42:42:42:42:42:42",
                 "fqdn-fwd": false,
                 "fqdn-rev": true,
                 "hostname": "myhost.example.com.",
                 "hw-address": "08:08:08:08:08:08",
-                "ip-address": "192.0.2.1",
+                "iaid": 1,
+                "ip-address": "2001:db8:2::1",
+                "preferred-lft": 500,
                 "state": 0,
                 "subnet-id": 44,
+                "type": "IA_NA",
                 "valid-lft": 3600
             },
             {
-                "client-id": "21:21:21:21:21:21:21:21",
                 "cltt": 12345678,
+                "duid": "21:21:21:21:21:21:21:21",
                 "fqdn-fwd": false,
                 "fqdn-rev": true,
                 "hostname": "",
-                "hw-address": "10:10:10:10:10:10",
-                "ip-address": "192.0.2.2",
+                "iaid": 1,
+                "ip-address": "2001:db8:0:0:2::",
+                "preferred-lft": 500,
+                "prefix-len": 80,
                 "state": 0,
                 "subnet-id": 44,
+                "type": "IA_PD",
                 "valid-lft": 3600
             }
         ]
     },
     "result": 0,
-    "text": "2 IPv4 lease(s) found."
+    "text": "2 IPv6 lease(s) found."
 }</screen>
           </para>
 
           <warning>
-            <para>The <command>lease4-get-command</command> may result in very
+            <para>The <command>lease4-get-command</command> or
+            <command>lease6-get-command</command> may result in very
             large responses. This may have negative impact on the DHCP server
             responsiveness while the response is generated and transmitted
             over the control channel, as the server imposes no restriction
index 3eb38797d70d9b7dc8c308dda67632ac160e57a5..0c48e2046de43991e1779fa86785b24d5eed87a7 100644 (file)
@@ -130,17 +130,18 @@ public:
     int
     leaseGetHandler(CalloutHandle& handle);
 
-    /// @brief lease4-get-all command handler
+    /// @brief lease4-get-all, lease6-get-all command handler
     ///
-    /// This command attempts to retrieve all IPv4 leases or all IPv4 leases
-    /// belonging to the particular subnets. If no subnet identifiers are
-    /// provided, it returns all IPv4 leases from the database.
+    /// This command attempts to retrieve all IPv4 or IPv6 leases,
+    /// or all IPv4 or all IPv6 leases belonging to the particular
+    /// subnets. If no subnet identifiers are provided, it returns all
+    /// IPv4 or IPv6 leases from the database.
     ///
     /// @param handle Callout context - which is expected to contain the
     /// get command JSON text in the "command" argument
     /// @return 0 upon success, non-zero otherwise.
     int
-    lease4GetAllHandler(CalloutHandle& handle);
+    leaseGetAllHandler(CalloutHandle& handle);
 
     /// @brief lease4-del command handler
     ///
@@ -469,9 +470,11 @@ LeaseCmdsImpl::leaseGetHandler(CalloutHandle& handle) {
 }
 
 int
-LeaseCmdsImpl::lease4GetAllHandler(CalloutHandle& handle) {
+LeaseCmdsImpl::leaseGetAllHandler(CalloutHandle& handle) {
+    bool v4 = true;
     try {
         extractCommand(handle);
+        v4 = (cmd_name_ == "lease4-get-all");
 
         ElementPtr leases_json = Element::createList();
 
@@ -491,11 +494,20 @@ LeaseCmdsImpl::lease4GetAllHandler(CalloutHandle& handle) {
                         isc_throw(BadValue, "listed subnet identifiers must be numbers");
                     }
 
-                    Lease4Collection leases =
-                        LeaseMgrFactory::instance().getLeases4((*subnet_id)->intValue());
-                    for (auto lease = leases.begin(); lease != leases.end(); ++lease) {
-                        ElementPtr lease_json = (*lease)->toElement();
-                        leases_json->add(lease_json);
+                    if (v4) {
+                        Lease4Collection leases =
+                            LeaseMgrFactory::instance().getLeases4((*subnet_id)->intValue());
+                        for (auto lease = leases.begin(); lease != leases.end(); ++lease) {
+                            ElementPtr lease_json = (*lease)->toElement();
+                            leases_json->add(lease_json);
+                        }
+                    } else {
+                        Lease6Collection leases =
+                            LeaseMgrFactory::instance().getLeases6((*subnet_id)->intValue());
+                        for (auto lease = leases.begin(); lease != leases.end(); ++lease) {
+                            ElementPtr lease_json = (*lease)->toElement();
+                            leases_json->add(lease_json);
+                        }
                     }
                 }
 
@@ -505,19 +517,32 @@ LeaseCmdsImpl::lease4GetAllHandler(CalloutHandle& handle) {
 
         } else {
             // There is no 'subnets' argument so let's return all leases.
-            Lease4Collection leases = LeaseMgrFactory::instance().getLeases4();
-            for (auto lease = leases.begin(); lease != leases.end(); ++lease) {
-                ElementPtr lease_json = (*lease)->toElement();
-                leases_json->add(lease_json);
+            if (v4) {
+                Lease4Collection leases = LeaseMgrFactory::instance().getLeases4();
+                for (auto lease = leases.begin(); lease != leases.end(); ++lease) {
+                    ElementPtr lease_json = (*lease)->toElement();
+                    leases_json->add(lease_json);
+                }
+            } else {
+                Lease6Collection leases = LeaseMgrFactory::instance().getLeases6();
+                for (auto lease = leases.begin(); lease != leases.end(); ++lease) {
+                    ElementPtr lease_json = (*lease)->toElement();
+                    leases_json->add(lease_json);
+                }
             }
         }
 
         std::ostringstream s;
-        s << leases_json->size() << " IPv4 lease(s) found.";
+        s << leases_json->size()
+          << " IPv" << (v4 ? "4" : "6")
+          << " lease(s) found.";
         ElementPtr args = Element::createMap();
         args->set("leases", leases_json);
-        ConstElementPtr response = createAnswer(CONTROL_RESULT_SUCCESS,
-                                                s.str(), args);
+        ConstElementPtr response =
+            createAnswer(leases_json->size() > 0 ?
+                         CONTROL_RESULT_SUCCESS :
+                         CONTROL_RESULT_EMPTY,
+                         s.str(), args);
         setResponse(handle, response);
 
 
@@ -782,8 +807,8 @@ LeaseCmds::leaseGetHandler(CalloutHandle& handle) {
 }
 
 int
-LeaseCmds::lease4GetAllHandler(hooks::CalloutHandle& handle) {
-    return (impl_->lease4GetAllHandler(handle));
+LeaseCmds::leaseGetAllHandler(hooks::CalloutHandle& handle) {
+    return (impl_->leaseGetAllHandler(handle));
 }
 
 int
index 106ff92642e0f59226bc3a3d51762e2ce5075e10..33d90106a6a1e3094547097c8cec468b5bfcc4ac 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2017-2018 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -131,13 +131,14 @@ public:
     int
     leaseGetHandler(hooks::CalloutHandle& handle);
 
-    /// @brief lease4-get-all command handler
+    /// @brief lease4-get-all, lease6-get-all command handler
     ///
-    /// This command attempts to retrieve all IPv4 leases or all IPv4 leases
-    /// belonging to the particular subnets. If no subnet identifiers are
-    /// provided, it returns all IPv4 leases from the database.
+    /// This command attempts to retrieve all IPv4 or IPv6 leases,
+    /// or all IPv4 or all IPv6 leases belonging to the particular
+    /// subnets. If no subnet identifiers are provided, it returns all
+    /// IPv4 or IPv6 leases from the database.
     ///
-    /// Example command for query by (subnet-ids):
+    /// Example command for IPv4 query by (subnet-ids):
     /// {
     ///     "command": "lease4-get-all",
     ///     "arguments": {
@@ -145,16 +146,16 @@ public:
     ///     }
     /// }
     ///
-    /// Example command for retrieving all leases:
+    /// Example command for retrieving all IPv6 leases:
     /// {
-    ///     "command": "lease4-get-all",
+    ///     "command": "lease6-get-all",
     /// }
     ///
     /// @param handle Callout context - which is expected to contain the
     /// get command JSON text in the "command" argument
     /// @return result of the operation.
     int
-    lease4GetAllHandler(hooks::CalloutHandle& handle);
+    leaseGetAllHandler(hooks::CalloutHandle& handle);
 
     /// @brief lease4-del command handler
     ///
index 809c46d83ea8b7ed95d77bf6e0e4c29c02efe2c5..2853ba55cefa18105491deb0cf5a3e84f4158d41 100644 (file)
@@ -53,26 +53,37 @@ int lease4_get(CalloutHandle& handle) {
     return(lease_cmds.leaseGetHandler(handle));
 }
 
-/// @brief This is a command callout for 'lease4-get-all' command.
+/// @brief This is a command callout for 'lease6-get' command.
 ///
 /// @param handle Callout handle used to retrieve a command and
 /// provide a response.
 /// @return 0 if this callout has been invoked successfully,
 /// 1 otherwise.
+int lease6_get(CalloutHandle& handle) {
+    LeaseCmds lease_cmds;
+    return(lease_cmds.leaseGetHandler(handle));
+}
+
+/// @brief This is a command callout for 'lease4-get-all' command.
+///
+/// @param handle Callout handle used to retrieve a command and
+/// provide a response.
+/// @return 0 if this callout has been invoked successfully,
+/// 1 if an error occurs, 2 if empty.
 int lease4_get_all(CalloutHandle& handle) {
     LeaseCmds lease_cmds;
-    return (lease_cmds.lease4GetAllHandler(handle));
+    return (lease_cmds.leaseGetAllHandler(handle));
 }
 
-/// @brief This is a command callout for 'lease6-get' command.
+/// @brief This is a command callout for 'lease6-get-all' command.
 ///
 /// @param handle Callout handle used to retrieve a command and
 /// provide a response.
 /// @return 0 if this callout has been invoked successfully,
-/// 1 otherwise.
-int lease6_get(CalloutHandle& handle) {
+/// 1 if an error occurs, 2 if empty.
+int lease6_get_all(CalloutHandle& handle) {
     LeaseCmds lease_cmds;
-    return(lease_cmds.leaseGetHandler(handle));
+    return (lease_cmds.leaseGetAllHandler(handle));
 }
 
 /// @brief This is a command callout for 'lease4-del' command.
@@ -151,6 +162,7 @@ int load(LibraryHandle& handle) {
     handle.registerCommandCallout("lease4-get", lease4_get);
     handle.registerCommandCallout("lease4-get-all", lease4_get_all);
     handle.registerCommandCallout("lease6-get", lease6_get);
+    handle.registerCommandCallout("lease6-get-all", lease6_get_all);
     handle.registerCommandCallout("lease4-del", lease4_del);
     handle.registerCommandCallout("lease6-del", lease6_del);
     handle.registerCommandCallout("lease4-update", lease4_update);
index d60ebe8d4a32052c930c176122e494759ff2452b..b593042c83ac6d152a1677ad59795f1129016104 100644 (file)
@@ -255,9 +255,11 @@ public:
 
         CfgMgr& cfg_mgr = CfgMgr::instance();
         if (v6) {
-            Subnet6Ptr subnet6(new Subnet6(IOAddress("2001:db8::"), 48, 1, 2, 3, 4, 66));
+            Subnet6Ptr subnet66(new Subnet6(IOAddress("2001:db8:1::"), 48, 1, 2, 3, 4, 66));
+            Subnet6Ptr subnet99(new Subnet6(IOAddress("2001:db8:2::"), 48, 1, 2, 3, 4, 99));
             CfgSubnets6Ptr subnets = cfg_mgr.getStagingCfg()->getCfgSubnets6();
-            subnets->add(subnet6);
+            subnets->add(subnet66);
+            subnets->add(subnet99);
             cfg_mgr.commit();
         } else {
             Subnet4Ptr subnet44(new Subnet4(IOAddress("192.0.2.0"), 24, 1, 2, 3, 44));
@@ -270,7 +272,10 @@ public:
 
         if (insert_lease) {
             if (v6) {
-                lmptr_->addLease(createLease6());
+                lmptr_->addLease(createLease6("2001:db8:1::1", 66, 0x42));
+                lmptr_->addLease(createLease6("2001:db8:1::2", 66, 0x56));
+                lmptr_->addLease(createLease6("2001:db8:2::1", 99, 0x42));
+                lmptr_->addLease(createLease6("2001:db8:2::2", 99, 0x56));
             } else {
                 lmptr_->addLease(createLease4("192.0.2.1", 44, 0x08, 0x42));
                 lmptr_->addLease(createLease4("192.0.2.2", 44, 0x09, 0x56));
@@ -287,7 +292,7 @@ public:
     ///
     /// @param ip_address IP address for the lease.
     /// @param subnet_id subnet identifier
-    /// @param hw_address_pattern value to be used for generating HW address by repating
+    /// @param hw_address_pattern value to be used for generating HW address by repeating
     /// it 6 times.
     /// @param client_id_pattern value to be used for generating client identifier by
     /// repeating it 8 times.
@@ -318,24 +323,28 @@ public:
 
     /// @brief Creates an IPv6 lease
     ///
-    /// Lease parameters: ip-address = 2001:db8::1, duid = 77:77:77:77:77:77:77:77,
-    /// cltt = 12345678, subnet-id = 66, fqdn-fwd = false, fqdn-rev = true,
-    /// hostname = myhost.example.com preferred lifetime = 1800,
+    /// Lease parameters: cltt = 12345678, fqdn-fwd = false, fqdn-rev = true,
+    /// hostname = myhost.example.com, preferred lifetime = 1800,
     /// valid lifetime = 3600
     ///
+    /// @param ip_address IP address for the lease.
+    /// @param subnet_id subnet identifier
+    /// @param duid_address_pattern value to be used for generating DUID by
+    /// repeating it 8 times
     /// @return Returns the lease created
-    Lease6Ptr createLease6() {
+    Lease6Ptr createLease6(const std::string& ip_address, const SubnetID& subnet_id,
+                           const uint8_t duid_pattern) {
         Lease6Ptr lease(new Lease6());
 
-        lease->addr_ = IOAddress("2001:db8::1");
+        lease->addr_ = IOAddress(ip_address);
         lease->type_ = Lease::TYPE_NA;
         lease->prefixlen_ = 128;
         lease->iaid_ = 42;
-        lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x77)));
+        lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, duid_pattern)));
         lease->preferred_lft_ = 1800;
         lease->valid_lft_ = 3600;
         lease->cltt_ = 12345678;
-        lease->subnet_id_ = 66;
+        lease->subnet_id_ = subnet_id;;
         lease->fqdn_fwd_ = true;
         lease->fqdn_rev_ = true;
         lease->hostname_ = "myhost.example.com.";
@@ -415,6 +424,21 @@ public:
 
         ASSERT_TRUE(l);
 
+        // If the element is a list we need to retrieve the lease that
+        // we're interested in.
+        if (l->getType() == Element::list) {
+            std::vector<ElementPtr> e = l->listValue();
+            for (auto it = e.begin(); it != e.end(); ++it) {
+                ConstElementPtr ip_address = (*it)->get("ip-address");
+                if (ip_address && ip_address->stringValue() == ip) {
+                    l = (*it);
+                    break;
+                }
+            }
+
+            ASSERT_TRUE(l);
+        }
+
         ASSERT_TRUE(l->contains("ip-address"));
         EXPECT_EQ(ip, l->get("ip-address")->stringValue());
         if (prefixlen != 0) {
@@ -564,11 +588,11 @@ TEST_F(LeaseCmdsTest, Lease4AddBadParams) {
         "    \"command\": \"lease4-add\",\n"
         "    \"arguments\": {"
         "        \"subnet-id\": 44,\n"
-        "        \"ip-address\": \"2001:db8::1\",\n"
+        "        \"ip-address\": \"2001:db8:1::1\",\n"
         "        \"hw-address\": \"1a:1b:1c:1d:1e:1f\"\n"
         "    }\n"
         "}";
-    exp_rsp = "Non-IPv4 address specified: 2001:db8::1";
+    exp_rsp = "Non-IPv4 address specified: 2001:db8:1::1";
     testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
 
     // currently defined states are 0,1 and 2. 123 is junk.
@@ -695,7 +719,7 @@ TEST_F(LeaseCmdsTest, Lease6AddMissingParams) {
         "{\n"
         "    \"command\": \"lease6-add\",\n"
         "    \"arguments\": {"
-        "        \"ip-address\": \"2001:db8::3\"\n"
+        "        \"ip-address\": \"2001:db8:1::3\"\n"
         "    }\n"
         "}";
     exp_rsp = "missing parameter 'subnet-id' (<string>:3:19)";
@@ -707,7 +731,7 @@ TEST_F(LeaseCmdsTest, Lease6AddMissingParams) {
         "    \"command\": \"lease6-add\",\n"
         "    \"arguments\": {"
         "        \"subnet-id\": 66,\n"
-        "        \"ip-address\": \"2001:db8::3\"\n"
+        "        \"ip-address\": \"2001:db8:1::3\"\n"
         "    }\n"
         "}";
     exp_rsp = "missing parameter 'duid' (<string>:3:19)";
@@ -745,7 +769,7 @@ TEST_F(LeaseCmdsTest, Lease6AddMissingParams) {
         "    \"arguments\": {"
         "        \"subnet-id\": 66,\n"
         "        \"duid\": \"1a:1b:1c:1d:1e:1f\",\n"
-        "        \"ip-address\": \"2001:db8::3\"\n"
+        "        \"ip-address\": \"2001:db8:1::3\"\n"
         "    }\n"
         "}";
     exp_rsp = "missing parameter 'iaid' (<string>:3:19)";
@@ -768,7 +792,7 @@ TEST_F(LeaseCmdsTest, Lease6AddBadParams) {
         "    \"command\": \"lease6-add\",\n"
         "    \"arguments\": {"
         "        \"subnet-id\": 123,\n"
-        "        \"ip-address\": \"2001:db8::3\",\n"
+        "        \"ip-address\": \"2001:db8:1::3\",\n"
         "        \"duid\": \"1a:1b:1c:1d:1e:1f\",\n"
         "        \"iaid\": 1234\n"
         "    }\n"
@@ -787,7 +811,7 @@ TEST_F(LeaseCmdsTest, Lease6AddBadParams) {
         "        \"iaid\": 1234\n"
         "    }\n"
         "}";
-    exp_rsp = "The address 3000::3 does not belong to subnet 2001:db8::/48, subnet-id=66";
+    exp_rsp = "The address 3000::3 does not belong to subnet 2001:db8:1::/48, subnet-id=66";
     testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
 
     // v4? You're a time traveler from early 80s or what?
@@ -810,7 +834,7 @@ TEST_F(LeaseCmdsTest, Lease6AddBadParams) {
         "    \"command\": \"lease6-add\",\n"
         "    \"arguments\": {"
         "        \"subnet-id\": 66,\n"
-        "        \"ip-address\": \"2001:db8::1\",\n"
+        "        \"ip-address\": \"2001:db8:1::1\",\n"
         "        \"duid\": \"1a:1b:1c:1d:1e:1f\",\n"
         "        \"iaid\": 1234\n,"
         "        \"state\": 123\n"
@@ -836,7 +860,7 @@ TEST_F(LeaseCmdsTest, Lease6Add) {
         "    \"command\": \"lease6-add\",\n"
         "    \"arguments\": {"
         "        \"subnet-id\": 66,\n"
-        "        \"ip-address\": \"2001:db8::3\",\n"
+        "        \"ip-address\": \"2001:db8:1::3\",\n"
         "        \"duid\": \"1a:1b:1c:1d:1e:1f\",\n"
         "        \"iaid\": 1234\n"
         "    }\n"
@@ -845,7 +869,7 @@ TEST_F(LeaseCmdsTest, Lease6Add) {
     testCommand(txt, CONTROL_RESULT_SUCCESS, exp_rsp);
 
     // Now check that the lease is really there.
-    EXPECT_TRUE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8::3")));
+    EXPECT_TRUE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::3")));
 }
 
 // Check that a simple, well formed prefix lease can be added.
@@ -895,7 +919,7 @@ TEST_F(LeaseCmdsTest, Lease6AddFullAddr) {
         "    \"command\": \"lease6-add\",\n"
         "    \"arguments\": {"
         "        \"subnet-id\": 66,\n"
-        "        \"ip-address\": \"2001:db8::3\",\n"
+        "        \"ip-address\": \"2001:db8:1::3\",\n"
         "        \"duid\": \"01:02:03:04:05:06:07:08\",\n"
         "        \"iaid\": 1234,\n"
         "        \"hw-address\": \"1a:1b:1c:1d:1e:1f\",\n"
@@ -911,10 +935,10 @@ TEST_F(LeaseCmdsTest, Lease6AddFullAddr) {
     testCommand(txt, CONTROL_RESULT_SUCCESS, exp_rsp);
 
     // Now check that the lease is really there.
-    Lease6Ptr l = lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8::3"));
+    Lease6Ptr l = lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::3"));
     ASSERT_TRUE(l);
     EXPECT_EQ(Lease::TYPE_NA, l->type_);
-    EXPECT_EQ("2001:db8::3", l->addr_.toText());
+    EXPECT_EQ("2001:db8:1::3", l->addr_.toText());
     ASSERT_TRUE(l->hwaddr_);
     EXPECT_EQ("1a:1b:1c:1d:1e:1f", l->hwaddr_->toText(false));
     ASSERT_TRUE(l->duid_);
@@ -1013,10 +1037,10 @@ TEST_F(LeaseCmdsTest, Lease4GetByAddrBadParam) {
         "{\n"
         "    \"command\": \"lease4-get\",\n"
         "    \"arguments\": {"
-        "        \"ip-address\": \"2001:db8::1\""
+        "        \"ip-address\": \"2001:db8:1::1\""
         "    }\n"
         "}";
-    string exp_rsp = "Invalid IPv4 address specified: 2001:db8::1";
+    string exp_rsp = "Invalid IPv4 address specified: 2001:db8:1::1";
     testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 
     // This is way off
@@ -1126,6 +1150,241 @@ TEST_F(LeaseCmdsTest, Lease4GetByHWAddr) {
     checkLease4(lease, "192.0.2.1", 44, "08:08:08:08:08:08", false);
 }
 
+// Checks that lease6-get(addr) can handle a situation when
+// the query is correctly formed, but the lease is not there.
+TEST_F(LeaseCmdsTest, Lease6GetByAddr6NotFound) {
+
+    // Initialize lease manager (true = v6, true = add a lease)
+    initLeaseMgr(true, true);
+
+    // Now send the command.
+    string cmd =
+        "{\n"
+        "    \"command\": \"lease6-get\",\n"
+        "    \"arguments\": {"
+        "        \"subnet-id\": 1,\n"
+        "        \"ip-address\": \"2001:db8:1::10\"\n"
+        "    }\n"
+        "}";
+    string exp_rsp = "Lease not found.";
+
+    // Note the status expected is empty. The query completed correctly,
+    // just didn't found the lease.
+    testCommand(cmd, CONTROL_RESULT_EMPTY, exp_rsp);
+}
+
+// Checks that lease4-get can handle a situation when the query is
+// well formed, but the lease is not there.
+TEST_F(LeaseCmdsTest, Lease4GetByClientIdNotFound) {
+
+    // Initialize lease manager (false = v4, false = don't add a lease)
+    initLeaseMgr(false, false);
+
+    // No such lease.
+    string cmd =
+        "{\n"
+        "    \"command\": \"lease4-get\",\n"
+        "    \"arguments\": {"
+        "        \"identifier-type\": \"client-id\","
+        "        \"identifier\": \"01:02:03:04\","
+        "        \"subnet-id\": 44"
+        "    }\n"
+        "}";
+    string exp_rsp = "Lease not found.";
+    ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_EMPTY, exp_rsp);
+}
+
+// Check that lease4-get can find a lease by client identifier.
+TEST_F(LeaseCmdsTest, Lease4GetByClientId) {
+    // Initialize lease manager (false = v4, true = add a lease)
+    initLeaseMgr(false, true);
+
+    string cmd =
+        "{\n"
+        "    \"command\": \"lease4-get\",\n"
+        "    \"arguments\": {"
+        "        \"identifier-type\": \"client-id\","
+        "        \"identifier\": \"42:42:42:42:42:42:42:42\","
+        "        \"subnet-id\": 44"
+        "    }\n"
+        "}";
+    string exp_rsp = "IPv4 lease found.";
+    ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_SUCCESS, exp_rsp);
+
+    // Now check that the lease parameters were indeed returned.
+    ASSERT_TRUE(rsp);
+    ConstElementPtr lease = rsp->get("arguments");
+    ASSERT_TRUE(lease);
+
+    // Let's check if the response makes any sense.
+    checkLease4(lease, "192.0.2.1", 44, "08:08:08:08:08:08", false);
+}
+
+// Checks that lease6-get rejects queries by client-id.
+TEST_F(LeaseCmdsTest, Lease6GetByClientIdInvalidType) {
+
+    // Initialize lease manager (true = v6, true = add a lease)
+    initLeaseMgr(true, true);
+
+    // client-id query is allowed in v4 only.
+    string cmd =
+        "{\n"
+        "    \"command\": \"lease6-get\",\n"
+        "    \"arguments\": {"
+        "        \"identifier-type\": \"client-id\","
+        "        \"identifier\": \"01:02:03:04\","
+        "        \"subnet-id\": 44"
+        "    }\n"
+        "}";
+    string exp_rsp = "Query by client-id is not allowed in v6.";
+    ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
+}
+
+// Checks that lease6-get(subnet-id, addr) can handle a situation when
+// the query is correctly formed, but the lease is not there.
+TEST_F(LeaseCmdsTest, Lease6GetByDuidNotFound) {
+    // Initialize lease manager (true = v6, true = add a lease)
+    initLeaseMgr(true, true);
+
+    // Now send the command.
+    string cmd =
+        "{\n"
+        "    \"command\": \"lease6-get\",\n"
+        "    \"arguments\": {"
+        "        \"subnet-id\": 1,\n"
+        "        \"identifier-type\": \"duid\","
+        "        \"identifier\": \"00:01:02:03:04:05:06:07\"\n"
+        "    }\n"
+        "}";
+    string exp_rsp = "Lease not found.";
+
+    // Note the status expected is empty. The query completed correctly,
+    // just didn't found the lease.
+    testCommand(cmd, CONTROL_RESULT_EMPTY, exp_rsp);
+}
+
+// Checks that lease6-get(subnet-id, addr6) can handle a situation when
+// the query is correctly formed and the lease is returned.
+TEST_F(LeaseCmdsTest, Lease6GetByAddr) {
+
+    initLeaseMgr(true, true); // (true = v6, true = create a lease)
+
+    // Now send the command.
+    string cmd =
+        "{\n"
+        "    \"command\": \"lease6-get\",\n"
+        "    \"arguments\": {\n"
+        "        \"ip-address\": \"2001:db8:1::1\"\n"
+        "    }\n"
+        "}";
+    string exp_rsp = "IPv6 lease found.";
+
+    // The status expected is success. The lease should be returned.
+    ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_SUCCESS, exp_rsp);
+    ASSERT_TRUE(rsp);
+
+    ConstElementPtr lease = rsp->get("arguments");
+    ASSERT_TRUE(lease);
+
+    // Now check that the lease was indeed returned.
+    checkLease6(lease, "2001:db8:1::1", 0, 66, "42:42:42:42:42:42:42:42", false);
+}
+
+// Checks that lease6-get sanitizes its input.
+TEST_F(LeaseCmdsTest, Lease6GetByAddrBadParam) {
+
+    // Initialize lease manager (true = v6, true = add a lease)
+    initLeaseMgr(true, true);
+
+    // Invalid family
+    string cmd =
+        "{\n"
+        "    \"command\": \"lease6-get\",\n"
+        "    \"arguments\": {"
+        "        \"ip-address\": \"192.0.2.1\""
+        "    }\n"
+        "}";
+    string exp_rsp = "Invalid IPv6 address specified: 192.0.2.1";
+    testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
+
+    // This is way off
+    cmd =
+        "{\n"
+        "    \"command\": \"lease6-get\",\n"
+        "    \"arguments\": {"
+        "        \"ip-address\": \"221B Baker St.\""
+        "    }\n"
+        "}";
+    exp_rsp = "Failed to convert string to address '221B Baker St.': Invalid argument";
+    testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
+}
+
+// Checks that lease6-get(subnet-id, type, addr6) can handle a situation when
+// the query is correctly formed and the lease is returned.
+TEST_F(LeaseCmdsTest, Lease6GetByAddrPrefix) {
+
+    // We need to get a prefix lease. We need to create it by hand.
+    initLeaseMgr(true, false); // (true = v6, true = create a lease)
+
+    // Let's start with regular address lease and make it a prefix lease.
+    Lease6Ptr l = createLease6("2001:db8:1::1", 66, 0x77);
+    l->addr_ = IOAddress("2001:db8:1234:ab::");
+    l->type_ = Lease::TYPE_PD;
+    l->prefixlen_ = 56;
+    lmptr_->addLease(l);
+
+    // Now send the command.
+    string cmd =
+        "{\n"
+        "    \"command\": \"lease6-get\",\n"
+        "    \"arguments\": {"
+        "        \"type\": \"IA_PD\","
+        "        \"ip-address\": \"2001:db8:1234:ab::\""
+        "    }\n"
+        "}";
+    string exp_rsp = "IPv6 lease found.";
+
+    // The status expected is success. The lease should be returned.
+    ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_SUCCESS, exp_rsp);
+    ASSERT_TRUE(rsp);
+
+    ConstElementPtr lease = rsp->get("arguments");
+    ASSERT_TRUE(lease);
+
+    // Now check that the lease was indeed returned.
+    checkLease6(lease, "2001:db8:1234:ab::", 56, 66, "77:77:77:77:77:77:77:77", false);
+}
+
+// Checks that lease6-get(subnet-id, iaid, identifier-type, identifier) can handle
+// a situation when the query returns a lease.
+TEST_F(LeaseCmdsTest, Lease6GetByDUID) {
+
+    initLeaseMgr(true, true); // (true = v6, true = create a lease)
+
+    // Now send the command.
+    string cmd =
+        "{\n"
+        "    \"command\": \"lease6-get\",\n"
+        "    \"arguments\": {"
+        "        \"subnet-id\": 66,\n"
+        "        \"iaid\": 42,"
+        "        \"identifier-type\": \"duid\","
+        "        \"identifier\": \"42:42:42:42:42:42:42:42\"\n"
+        "    }\n"
+        "}";
+    string exp_rsp = "IPv6 lease found.";
+
+    // The status expected is success. The lease should be returned.
+    ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_SUCCESS, exp_rsp);
+    ASSERT_TRUE(rsp);
+
+    ConstElementPtr lease = rsp->get("arguments");
+    ASSERT_TRUE(lease);
+
+    // Now check that the lease was indeed returned.
+    checkLease6(lease, "2001:db8:1::1", 0, 66, "42:42:42:42:42:42:42:42", false);
+}
+
 // Checks that lease4-get-all returns all leases.
 TEST_F(LeaseCmdsTest, Lease4GetAll) {
 
@@ -1170,7 +1429,7 @@ TEST_F(LeaseCmdsTest, Lease4GetAllNoLeases) {
         "    \"command\": \"lease4-get-all\"\n"
         "}";
     string exp_rsp = "0 IPv4 lease(s) found.";
-    ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_SUCCESS, exp_rsp);
+    ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_EMPTY, exp_rsp);
 
     // Now check that the lease parameters were indeed returned.
     ASSERT_TRUE(rsp);
@@ -1237,7 +1496,7 @@ TEST_F(LeaseCmdsTest, Lease4GetAllBySubnetIdNoLeases) {
         "    }\n"
         "}";
     string exp_rsp = "0 IPv4 lease(s) found.";
-    ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_SUCCESS, exp_rsp);
+    ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_EMPTY, exp_rsp);
 
     // Now check that the lease parameters were indeed returned.
     ASSERT_TRUE(rsp);
@@ -1328,239 +1587,206 @@ TEST_F(LeaseCmdsTest, Lease4GetBySubnetIdInvalidArguments) {
     testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
-// Checks that lease6-get(addr) can handle a situation when
-// the query is correctly formed, but the lease is not there.
-TEST_F(LeaseCmdsTest, Lease6GetByAddr6NotFound) {
+// Checks that lease6-get-all returns all leases.
+TEST_F(LeaseCmdsTest, Lease6GetAll) {
 
     // Initialize lease manager (true = v6, true = add a lease)
     initLeaseMgr(true, true);
 
-    // Now send the command.
+    // Query for all leases.
     string cmd =
         "{\n"
-        "    \"command\": \"lease6-get\",\n"
-        "    \"arguments\": {"
-        "        \"subnet-id\": 1,\n"
-        "        \"ip-address\": \"2001:db8::2\"\n"
-        "    }\n"
+        "    \"command\": \"lease6-get-all\"\n"
         "}";
-    string exp_rsp = "Lease not found.";
+    string exp_rsp = "4 IPv6 lease(s) found.";
+    ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_SUCCESS, exp_rsp);
 
-    // Note the status expected is empty. The query completed correctly,
-    // just didn't found the lease.
-    testCommand(cmd, CONTROL_RESULT_EMPTY, exp_rsp);
+    // Now check that the lease parameters were indeed returned.
+    ASSERT_TRUE(rsp);
+
+    ConstElementPtr args = rsp->get("arguments");
+    ASSERT_TRUE(args);
+    ASSERT_EQ(Element::map, args->getType());
+
+    ConstElementPtr leases = args->get("leases");
+    ASSERT_TRUE(leases);
+    ASSERT_EQ(Element::list, leases->getType());
+
+    // Let's check if the response contains desired leases.
+    checkLease6(leases, "2001:db8:1::1", 0, 66, "42:42:42:42:42:42:42:42", false);
+    checkLease6(leases, "2001:db8:1::2", 0, 66, "56:56:56:56:56:56:56:56", false);
+    checkLease6(leases, "2001:db8:2::1", 0, 99, "42:42:42:42:42:42:42:42", false);
+    checkLease6(leases, "2001:db8:2::2", 0, 99, "56:56:56:56:56:56:56:56", false);
 }
 
-// Checks that lease4-get can handle a situation when the query is
-// well formed, but the lease is not there.
-TEST_F(LeaseCmdsTest, Lease4GetByClientIdNotFound) {
+// Checks that lease6-get-all returns empty set if no leases are found.
+TEST_F(LeaseCmdsTest, Lease6GetAllNoLeases) {
 
-    // Initialize lease manager (false = v4, false = don't add a lease)
-    initLeaseMgr(false, false);
+    // Initialize lease manager (true = v6, false = do not add leasesxs)
+    initLeaseMgr(true, false);
 
-    // No such lease.
+    // Query for all leases.
     string cmd =
         "{\n"
-        "    \"command\": \"lease4-get\",\n"
-        "    \"arguments\": {"
-        "        \"identifier-type\": \"client-id\","
-        "        \"identifier\": \"01:02:03:04\","
-        "        \"subnet-id\": 44"
-        "    }\n"
+        "    \"command\": \"lease6-get-all\"\n"
         "}";
-    string exp_rsp = "Lease not found.";
+    string exp_rsp = "0 IPv6 lease(s) found.";
     ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_EMPTY, exp_rsp);
+
+    // Now check that the lease parameters were indeed returned.
+    ASSERT_TRUE(rsp);
+
+    ConstElementPtr args = rsp->get("arguments");
+    ASSERT_TRUE(args);
+    ASSERT_EQ(Element::map, args->getType());
+
+    ConstElementPtr leases = args->get("leases");
+    ASSERT_TRUE(leases);
+    ASSERT_EQ(Element::list, leases->getType());
+
+    EXPECT_EQ(0, leases->size());
 }
 
-// Check that lease4-get can find a lease by client identifier.
-TEST_F(LeaseCmdsTest, Lease4GetByClientId) {
-    // Initialize lease manager (false = v4, true = add a lease)
-    initLeaseMgr(false, true);
 
+// Checks that lease6-get-all returns all leases for a subnet.
+TEST_F(LeaseCmdsTest, Lease6GetAllBySubnetId) {
+
+    // Initialize lease manager (true = v6, true = add leases)
+    initLeaseMgr(true, true);
+
+    // Query for leases from subnet 66. Subnet 127 will be ignored because
+    // it doesn't contain any leases.
     string cmd =
         "{\n"
-        "    \"command\": \"lease4-get\",\n"
-        "    \"arguments\": {"
-        "        \"identifier-type\": \"client-id\","
-        "        \"identifier\": \"42:42:42:42:42:42:42:42\","
-        "        \"subnet-id\": 44"
+        "    \"command\": \"lease6-get-all\",\n"
+        "    \"arguments\": {\n"
+        "        \"subnets\": [ 66, 127 ]"
         "    }\n"
         "}";
-    string exp_rsp = "IPv4 lease found.";
+    string exp_rsp = "2 IPv6 lease(s) found.";
     ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_SUCCESS, exp_rsp);
 
     // Now check that the lease parameters were indeed returned.
     ASSERT_TRUE(rsp);
-    ConstElementPtr lease = rsp->get("arguments");
-    ASSERT_TRUE(lease);
 
-    // Let's check if the response makes any sense.
-    checkLease4(lease, "192.0.2.1", 44, "08:08:08:08:08:08", false);
+    ConstElementPtr args = rsp->get("arguments");
+    ASSERT_TRUE(args);
+    ASSERT_EQ(Element::map, args->getType());
+
+    ConstElementPtr leases = args->get("leases");
+    ASSERT_TRUE(leases);
+    ASSERT_EQ(Element::list, leases->getType());
+
+    // Let's check if the response contains desired leases.
+    checkLease6(leases, "2001:db8:1::1", 0, 66, "42:42:42:42:42:42:42:42", false);
+    checkLease6(leases, "2001:db8:1::2", 0, 66, "56:56:56:56:56:56:56:56", false);
 }
 
-// Checks that lease6-get rejects queries by client-id.
-TEST_F(LeaseCmdsTest, Lease6GetByClientIdInvalidType) {
+// Checks that lease6-get-all returns empty set when no leases are found.
+TEST_F(LeaseCmdsTest, Lease6GetAllBySubnetIdNoLeases) {
 
-    // Initialize lease manager (true = v6, true = add a lease)
-    initLeaseMgr(true, true);
+    // Initialize lease manager (true = v6, true = do not add leases)
+    initLeaseMgr(true, false);
 
-    // client-id query is allowed in v4 only.
+    // Query for leases from subnet 66. Subnet 127 will be ignored because
+    // it doesn't contain any leases.
     string cmd =
         "{\n"
-        "    \"command\": \"lease6-get\",\n"
-        "    \"arguments\": {"
-        "        \"identifier-type\": \"client-id\","
-        "        \"identifier\": \"01:02:03:04\","
-        "        \"subnet-id\": 44"
+        "    \"command\": \"lease6-get-all\",\n"
+        "    \"arguments\": {\n"
+        "        \"subnets\": [ 66, 127 ]"
         "    }\n"
         "}";
-    string exp_rsp = "Query by client-id is not allowed in v6.";
-    ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
-}
+    string exp_rsp = "0 IPv6 lease(s) found.";
+    ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_EMPTY, exp_rsp);
 
-// Checks that lease6-get(subnet-id, addr) can handle a situation when
-// the query is correctly formed, but the lease is not there.
-TEST_F(LeaseCmdsTest, Lease6GetByDuidNotFound) {
-    // Initialize lease manager (true = v6, true = add a lease)
-    initLeaseMgr(true, true);
+    // Now check that the lease parameters were indeed returned.
+    ASSERT_TRUE(rsp);
 
-    // Now send the command.
-    string cmd =
-        "{\n"
-        "    \"command\": \"lease6-get\",\n"
-        "    \"arguments\": {"
-        "        \"subnet-id\": 1,\n"
-        "        \"identifier-type\": \"duid\","
-        "        \"identifier\": \"00:01:02:03:04:05:06:07\"\n"
-        "    }\n"
-        "}";
-    string exp_rsp = "Lease not found.";
+    ConstElementPtr args = rsp->get("arguments");
+    ASSERT_TRUE(args);
+    ASSERT_EQ(Element::map, args->getType());
 
-    // Note the status expected is empty. The query completed correctly,
-    // just didn't found the lease.
-    testCommand(cmd, CONTROL_RESULT_EMPTY, exp_rsp);
+    ConstElementPtr leases = args->get("leases");
+    ASSERT_TRUE(leases);
+    ASSERT_EQ(Element::list, leases->getType());
+
+    EXPECT_EQ(0, leases->size());
 }
 
-// Checks that lease6-get(subnet-id, addr6) can handle a situation when
-// the query is correctly formed and the lease is returned.
-TEST_F(LeaseCmdsTest, Lease6GetByAddr) {
+// Checks that lease6-get-all returns leases from multiple subnets.
+TEST_F(LeaseCmdsTest, Lease6GetAllByMultipleSubnetIds) {
 
-    initLeaseMgr(true, true); // (true = v6, true = create a lease)
+    // Initialize lease manager (true = v6, true = add a lease)
+    initLeaseMgr(true, true);
 
-    // Now send the command.
+    // Query for leases from subnet 66 and 99.
     string cmd =
         "{\n"
-        "    \"command\": \"lease6-get\",\n"
+        "    \"command\": \"lease6-get-all\",\n"
         "    \"arguments\": {\n"
-        "        \"ip-address\": \"2001:db8::1\"\n"
+        "        \"subnets\": [ 66, 99 ]"
         "    }\n"
         "}";
-    string exp_rsp = "IPv6 lease found.";
-
-    // The status expected is success. The lease should be returned.
+    string exp_rsp = "4 IPv6 lease(s) found.";
     ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_SUCCESS, exp_rsp);
+
+    // Now check that the lease parameters were indeed returned.
     ASSERT_TRUE(rsp);
 
-    ConstElementPtr lease = rsp->get("arguments");
-    ASSERT_TRUE(lease);
+    ConstElementPtr args = rsp->get("arguments");
+    ASSERT_TRUE(args);
+    ASSERT_EQ(Element::map, args->getType());
 
-    // Now check that the lease was indeed returned.
-    checkLease6(lease, "2001:db8::1", 0, 66, "77:77:77:77:77:77:77:77", false);
+    ConstElementPtr leases = args->get("leases");
+    ASSERT_TRUE(leases);
+    ASSERT_EQ(Element::list, leases->getType());
+
+    // Let's check if the response contains desired leases.
+    checkLease6(leases, "2001:db8:1::1", 0, 66, "42:42:42:42:42:42:42:42", false);
+    checkLease6(leases, "2001:db8:1::2", 0, 66, "56:56:56:56:56:56:56:56", false);
+    checkLease6(leases, "2001:db8:2::1", 0, 99, "42:42:42:42:42:42:42:42", false);
+    checkLease6(leases, "2001:db8:2::2", 0, 99, "56:56:56:56:56:56:56:56", false);
 }
 
-// Checks that lease6-get sanitizes its input.
-TEST_F(LeaseCmdsTest, Lease6GetByAddrBadParam) {
+// Checks that lease6-get-all checks its input arguments.
+TEST_F(LeaseCmdsTest, Lease6GetBySubnetIdInvalidArguments) {
 
     // Initialize lease manager (true = v6, true = add a lease)
     initLeaseMgr(true, true);
 
-    // Invalid family
+    // Subnets not specified in arguments.
     string cmd =
         "{\n"
-        "    \"command\": \"lease6-get\",\n"
+        "    \"command\": \"lease6-get-all\",\n"
         "    \"arguments\": {"
-        "        \"ip-address\": \"192.0.2.1\""
+        "        \"foo\": 1\n"
         "    }\n"
         "}";
-    string exp_rsp = "Invalid IPv6 address specified: 192.0.2.1";
+    string exp_rsp = "'subnets' parameter not specified";
     testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 
-    // This is way off
+    // Subnets are not a list.
     cmd =
         "{\n"
-        "    \"command\": \"lease6-get\",\n"
+        "    \"command\": \"lease6-get-all\",\n"
         "    \"arguments\": {"
-        "        \"ip-address\": \"221B Baker St.\""
+        "        \"subnets\": 1\n"
         "    }\n"
         "}";
-    exp_rsp = "Failed to convert string to address '221B Baker St.': Invalid argument";
+    exp_rsp = "'subnets' parameter must be a list";
     testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
-}
-
-// Checks that lease6-get(subnet-id, type, addr6) can handle a situation when
-// the query is correctly formed and the lease is returned.
-TEST_F(LeaseCmdsTest, Lease6GetByAddrPrefix) {
-
-    // We need to get a prefix lease. We need to create it by hand.
-    initLeaseMgr(true, false); // (true = v6, true = create a lease)
-
-    // Let's start with regular address lease and make it a prefix lease.
-    Lease6Ptr l = createLease6();
-    l->addr_ = IOAddress("2001:db8:1234:ab::");
-    l->type_ = Lease::TYPE_PD;
-    l->prefixlen_ = 56;
-    lmptr_->addLease(l);
-
-    // Now send the command.
-    string cmd =
-        "{\n"
-        "    \"command\": \"lease6-get\",\n"
-        "    \"arguments\": {"
-        "        \"type\": \"IA_PD\","
-        "        \"ip-address\": \"2001:db8:1234:ab::\""
-        "    }\n"
-        "}";
-    string exp_rsp = "IPv6 lease found.";
-
-    // The status expected is success. The lease should be returned.
-    ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_SUCCESS, exp_rsp);
-    ASSERT_TRUE(rsp);
-
-    ConstElementPtr lease = rsp->get("arguments");
-    ASSERT_TRUE(lease);
-
-    // Now check that the lease was indeed returned.
-    checkLease6(lease, "2001:db8:1234:ab::", 56, 66, "77:77:77:77:77:77:77:77", false);
-}
-
-// Checks that lease6-get(subnet-id, iaid, identifier-type, identifier) can handle
-// a situation when the query returns a lease.
-TEST_F(LeaseCmdsTest, Lease6GetByDUID) {
 
-    initLeaseMgr(true, true); // (true = v6, true = create a lease)
-
-    // Now send the command.
-    string cmd =
+    // Subnets list must contain numbers.
+    cmd =
         "{\n"
-        "    \"command\": \"lease6-get\",\n"
+        "    \"command\": \"lease6-get-all\",\n"
         "    \"arguments\": {"
-        "        \"subnet-id\": 66,\n"
-        "        \"iaid\": 42,"
-        "        \"identifier-type\": \"duid\","
-        "        \"identifier\": \"77:77:77:77:77:77:77:77\"\n"
+        "        \"subnets\": [ \"x\", \"y\" ]\n"
         "    }\n"
         "}";
-    string exp_rsp = "IPv6 lease found.";
-
-    // The status expected is success. The lease should be returned.
-    ConstElementPtr rsp = testCommand(cmd, CONTROL_RESULT_SUCCESS, exp_rsp);
-    ASSERT_TRUE(rsp);
-
-    ConstElementPtr lease = rsp->get("arguments");
-    ASSERT_TRUE(lease);
-
-    // Now check that the lease was indeed returned.
-    checkLease6(lease, "2001:db8::1", 0, 66, "77:77:77:77:77:77:77:77", false);
+    exp_rsp = "listed subnet identifiers must be numbers";
+    testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
 // Test checks if lease4-update handler refuses calls with missing parameters.
@@ -1660,11 +1886,11 @@ TEST_F(LeaseCmdsTest, Lease4UpdateBadParams) {
         "    \"command\": \"lease4-update\",\n"
         "    \"arguments\": {"
         "        \"subnet-id\": 44,\n"
-        "        \"ip-address\": \"2001:db8::1\",\n"
+        "        \"ip-address\": \"2001:db8:1::1\",\n"
         "        \"hw-address\": \"1a:1b:1c:1d:1e:1f\"\n"
         "    }\n"
         "}";
-    exp_rsp = "Non-IPv4 address specified: 2001:db8::1";
+    exp_rsp = "Non-IPv4 address specified: 2001:db8:1::1";
     testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
@@ -1750,7 +1976,7 @@ TEST_F(LeaseCmdsTest, Lease6UpdateMissingParams) {
         "{\n"
         "    \"command\": \"lease6-update\",\n"
         "    \"arguments\": {"
-        "            \"ip-address\": \"2001:db8::1\"\n"
+        "            \"ip-address\": \"2001:db8:1::1\"\n"
         "    }\n"
         "}";
     exp_rsp = "missing parameter 'subnet-id' (<string>:3:19)";
@@ -1762,7 +1988,7 @@ TEST_F(LeaseCmdsTest, Lease6UpdateMissingParams) {
         "    \"command\": \"lease6-update\",\n"
         "    \"arguments\": {"
         "            \"subnet-id\": 44,\n"
-        "            \"ip-address\": \"2001:db8::1\"\n"
+        "            \"ip-address\": \"2001:db8:1::1\"\n"
         "    }\n"
         "}";
     exp_rsp = "missing parameter 'duid' (<string>:3:19)";
@@ -1798,7 +2024,7 @@ TEST_F(LeaseCmdsTest, Lease6UpdateBadParams) {
         "    \"command\": \"lease6-update\",\n"
         "    \"arguments\": {"
         "        \"subnet-id\": 123,\n"
-        "        \"ip-address\": \"2001:db8::1\",\n"
+        "        \"ip-address\": \"2001:db8:1::1\",\n"
         "        \"duid\": \"88:88:88:88:88:88:88:88\"\n"
         "    }\n"
         "}";
@@ -1815,7 +2041,7 @@ TEST_F(LeaseCmdsTest, Lease6UpdateBadParams) {
         "        \"duid\": \"88:88:88:88:88:88:88:88\"\n"
         "    }\n"
         "}";
-    exp_rsp = "The address 3000::1 does not belong to subnet 2001:db8::/48, subnet-id=66";
+    exp_rsp = "The address 3000::1 does not belong to subnet 2001:db8:1::/48, subnet-id=66";
     testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
 
     // Nope, can't do v4 address in v6 lease.
@@ -1848,7 +2074,7 @@ TEST_F(LeaseCmdsTest, Lease6Update) {
         "    \"command\": \"lease6-update\",\n"
         "    \"arguments\": {"
         "        \"subnet-id\": 66,\n"
-        "        \"ip-address\": \"2001:db8::1\",\n"
+        "        \"ip-address\": \"2001:db8:1::1\",\n"
         "        \"iaid\": 7654321,\n"
         "        \"duid\": \"88:88:88:88:88:88:88:88\",\n"
         "        \"hostname\": \"newhostname.example.org\""
@@ -1858,7 +2084,7 @@ TEST_F(LeaseCmdsTest, Lease6Update) {
     testCommand(txt, CONTROL_RESULT_SUCCESS, exp_rsp);
 
     // Now check that the lease is really there.
-    Lease6Ptr l = lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8::1"));
+    Lease6Ptr l = lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::1"));
     ASSERT_TRUE(l);
 
     // Make sure the lease has been updated.
@@ -1885,13 +2111,13 @@ TEST_F(LeaseCmdsTest, Lease6UpdateNoLease) {
         "    \"command\": \"lease6-update\",\n"
         "    \"arguments\": {"
         "        \"subnet-id\": 66,\n"
-        "        \"ip-address\": \"2001:db8::1\",\n"
+        "        \"ip-address\": \"2001:db8:1::1\",\n"
         "        \"iaid\": 7654321,\n"
         "        \"duid\": \"88:88:88:88:88:88:88:88\",\n"
         "        \"hostname\": \"newhostname.example.org\""
         "    }\n"
         "}";
-    string exp_rsp = "failed to update the lease with address 2001:db8::1 - no such lease";
+    string exp_rsp = "failed to update the lease with address 2001:db8:1::1 - no such lease";
     testCommand(txt, CONTROL_RESULT_ERROR, exp_rsp);
 }
 
@@ -2025,10 +2251,10 @@ TEST_F(LeaseCmdsTest, Lease4DelByAddrBadParam) {
         "{\n"
         "    \"command\": \"lease4-del\",\n"
         "    \"arguments\": {"
-        "        \"ip-address\": \"2001:db8::1\""
+        "        \"ip-address\": \"2001:db8:1::1\""
         "    }\n"
         "}";
-    string exp_rsp = "Invalid IPv4 address specified: 2001:db8::1";
+    string exp_rsp = "Invalid IPv4 address specified: 2001:db8:1::1";
     testCommand(cmd, CONTROL_RESULT_ERROR, exp_rsp);
 
     // This is way off
@@ -2149,7 +2375,7 @@ TEST_F(LeaseCmdsTest, Lease6DelByAddr6NotFound) {
         "    \"command\": \"lease6-del\",\n"
         "    \"arguments\": {"
         "        \"subnet-id\": 1,\n"
-        "        \"ip-address\": \"2001:db8::2\"\n"
+        "        \"ip-address\": \"2001:db8:1::10\"\n"
         "    }\n"
         "}";
     string exp_rsp = "IPv6 lease not found.";
@@ -2183,7 +2409,7 @@ TEST_F(LeaseCmdsTest, Lease6DelByDuidNotFound) {
     testCommand(cmd, CONTROL_RESULT_EMPTY, exp_rsp);
 
     // Make sure the lease is still there.
-    EXPECT_TRUE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8::1")));
+    EXPECT_TRUE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::1")));
 }
 
 // Checks that lease6-del(subnet-id, addr6) can handle a situation when
@@ -2198,7 +2424,7 @@ TEST_F(LeaseCmdsTest, Lease6DelByAddr) {
         "    \"command\": \"lease6-del\",\n"
         "    \"arguments\": {"
         "        \"subnet-id\": 66,\n"
-        "        \"ip-address\": \"2001:db8::1\""
+        "        \"ip-address\": \"2001:db8:1::1\""
         "    }\n"
         "}";
     string exp_rsp = "IPv6 lease deleted.";
@@ -2207,7 +2433,7 @@ TEST_F(LeaseCmdsTest, Lease6DelByAddr) {
     testCommand(cmd, CONTROL_RESULT_SUCCESS, exp_rsp);
 
     // Make sure the lease is really gone.
-    EXPECT_FALSE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8::1")));
+    EXPECT_FALSE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::1")));
 }
 
 // Checks that lease6-del sanitizes its input.
@@ -2246,7 +2472,7 @@ TEST_F(LeaseCmdsTest, Lease6DelByAddrPrefix) {
     initLeaseMgr(true, false); // (true = v6, false = don't add any leases)
 
     // Let's start with regular address lease and make it a prefix lease.
-    Lease6Ptr l = createLease6();
+    Lease6Ptr l = createLease6("2001:db8:1::1", 66, 0x77);
     l->addr_ = IOAddress("2001:db8:1234:ab::");
     l->type_ = Lease::TYPE_PD;
     l->prefixlen_ = 56;
@@ -2284,7 +2510,7 @@ TEST_F(LeaseCmdsTest, Lease6DelByDUID) {
         "        \"subnet-id\": 66,\n"
         "        \"iaid\": 42,"
         "        \"identifier-type\": \"duid\","
-        "        \"identifier\": \"77:77:77:77:77:77:77:77\"\n"
+        "        \"identifier\": \"42:42:42:42:42:42:42:42\"\n"
         "    }\n"
         "}";
     string exp_rsp = "IPv6 lease deleted.";
@@ -2293,7 +2519,7 @@ TEST_F(LeaseCmdsTest, Lease6DelByDUID) {
     testCommand(cmd, CONTROL_RESULT_SUCCESS, exp_rsp);
 
     // Make sure the lease is really gone.
-    EXPECT_FALSE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8::1")));
+    EXPECT_FALSE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::1")));
 }
 
 // Checks that lease4-wipe detects missing parmameter properly.
@@ -2382,13 +2608,13 @@ TEST_F(LeaseCmdsTest, Lease6Wipe) {
         "        \"subnet-id\": 66\n"
         "    }\n"
         "}";
-    string exp_rsp = "Deleted 1 IPv6 lease(s).";
+    string exp_rsp = "Deleted 2 IPv6 lease(s).";
 
     // The status expected is success. The lease should be deleted.
     testCommand(cmd, CONTROL_RESULT_SUCCESS, exp_rsp);
 
     // Make sure the lease is really gone.
-    EXPECT_FALSE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8::1")));
+    EXPECT_FALSE(lmptr_->getLease6(Lease::TYPE_NA, IOAddress("2001:db8:1::1")));
 }
 
 // Checks that lease4-wipe properly reports when no leases were deleted.
index 5036044b75b5d7cf4abb65eed106e6f1c03d8985..5dcdfd8f9b4b56910ef23737834fb2dc073c376d 100644 (file)
@@ -1718,6 +1718,16 @@ CqlLeaseMgr::getLeases6(Lease::Type lease_type, const DUID &duid, uint32_t iaid,
     return (result);
 }
 
+Lease6Collection
+CqlLeaseMgr::getLeases6(SubnetID) const {
+    isc_throw(NotImplemented, "getLeases6(subnet_id) is not implemented");
+}
+
+Lease6Collection
+CqlLeaseMgr::getLeases6() const {
+    isc_throw(NotImplemented, "getLeases6() is not implemented");
+}
+
 void
 CqlLeaseMgr::getExpiredLeases4(Lease4Collection &expired_leases,
                                const size_t max_leases) const {
index f8ffd82d68807983cc1a2e029f637d6db8efccb7..af0097289cae4b86de4034416b3d55453734c763 100644 (file)
@@ -267,6 +267,19 @@ public:
                                         const DUID& duid,
                                         uint32_t iaid,
                                         SubnetID subnet_id) const override;
+
+    /// @brief Returns all IPv6 leases for the particular subnet identifier.
+    ///
+    /// @param subnet_id subnet identifier.
+    ///
+    /// @return Lease collection (may be empty if no IPv6 lease found).
+    virtual Lease6Collection getLeases6(SubnetID subnet_id) const;
+
+    /// @brief Returns all IPv6 leases.
+    ///
+    /// @return Lease collection (may be empty if no IPv6 lease found).
+    virtual Lease6Collection getLeases6() const;
+
     /// @brief Returns a collection of expired DHCPv6 leases.
     ///
     /// This method returns at most @c max_leases expired leases. The leases
@@ -316,7 +329,7 @@ public:
     /// @param lease6 The lease to be updated.
     ///
     /// @throw isc::dhcp::NoSuchLease Attempt to update a lease that did not
-    ///        exist.
+
     /// @throw isc::dhcp::DbOperationError An operation on the open database has
     ///        failed.
     virtual void updateLease6(const Lease6Ptr& lease6) override;
index ad5a7d40f3ea46a6cbf0fb77475b05c26e5030f3..8e3c7cfebd765cdbf24ae285ead2cda05627efe1 100644 (file)
@@ -463,6 +463,10 @@ in the message.
 A debug message issued when the server is attempting to obtain all IPv4
 leases from the memory file database.
 
+% DHCPSRV_MEMFILE_GET6 obtaining all IPv6 leases
+A debug message issued when the server is attempting to obtain all IPv6
+leases from the memory file database.
+
 % DHCPSRV_MEMFILE_GET_ADDR4 obtaining IPv4 lease for address %1
 A debug message issued when the server is attempting to obtain an IPv4
 lease from the memory file database for the specified address.
@@ -510,6 +514,10 @@ lease from the memory file database for a client with the specified IAID
 A debug message issued when the server is attempting to obtain all IPv4
 leases for a given subnet identifier from the memory file database.
 
+% DHCPSRV_MEMFILE_GET_SUBID6 obtaining IPv6 leases for subnet ID %1
+A debug message issued when the server is attempting to obtain all IPv6
+leases for a given subnet identifier from the memory file database.
+
 % DHCPSRV_MEMFILE_GET_SUBID_CLIENTID obtaining IPv4 lease for subnet ID %1 and client ID %2
 A debug message issued when the server is attempting to obtain an IPv4
 lease from the memory file database for a client with the specified
@@ -697,6 +705,10 @@ exit code.  This is most likely due to a network issue.
 A debug message issued when the server is attempting to obtain all IPv4
 leases from the MySQL database.
 
+% DHCPSRV_MYSQL_GET6 obtaining all IPv6 leases
+A debug message issued when the server is attempting to obtain all IPv6
+leases from the MySQL database.
+
 % DHCPSRV_MYSQL_GET_ADDR4 obtaining IPv4 lease for address %1
 A debug message issued when the server is attempting to obtain an IPv4
 lease from the MySQL database for the specified address.
@@ -739,6 +751,10 @@ lease from the MySQL database for a client with the specified IAID
 A debug message issued when the server is attempting to obtain all IPv4
 leases for a given subnet identifier from the MySQL database.
 
+% DHCPSRV_MYSQL_GET_SUBID6 obtaining IPv6 leases for subnet ID %1
+A debug message issued when the server is attempting to obtain all IPv6
+leases for a given subnet identifier from the MySQL database.
+
 % DHCPSRV_MYSQL_GET_SUBID_CLIENTID obtaining IPv4 lease for subnet ID %1 and client ID %2
 A debug message issued when the server is attempting to obtain an IPv4
 lease from the MySQL database for a client with the specified subnet ID
@@ -859,6 +875,10 @@ exit code.  This is most likely due to a network issue.
 A debug message issued when the server is attempting to obtain all IPv4
 leases from the PostgreSQL database.
 
+% DHCPSRV_PGSQL_GET6 obtaining all IPv6 leases
+A debug message issued when the server is attempting to obtain all IPv6
+leases from the PostgreSQL database.
+
 % DHCPSRV_PGSQL_GET_ADDR4 obtaining IPv4 lease for address %1
 A debug message issued when the server is attempting to obtain an IPv4
 lease from the PostgreSQL database for the specified address.
@@ -901,6 +921,10 @@ lease from the PostgreSQL database for a client with the specified IAID
 A debug message issued when the server is attempting to obtain all IPv4
 leases for a given subnet identifier from the PostgreSQL database.
 
+% DHCPSRV_PGSQL_GET_SUBID6 obtaining IPv6 leases for subnet ID %1
+A debug message issued when the server is attempting to obtain all IPv6
+leases for a given subnet identifier from the PostgreSQL database.
+
 % DHCPSRV_PGSQL_GET_SUBID_CLIENTID obtaining IPv4 lease for subnet ID %1 and client ID %2
 A debug message issued when the server is attempting to obtain an IPv4
 lease from the PostgreSQL database for a client with the specified subnet ID
index 9bac9e6fc3078b2f64a08855faac6c0205728309..f7775845bd80467cf1d50d03fe6caff4e7f93231 100644 (file)
@@ -341,6 +341,18 @@ public:
     Lease6Ptr getLease6(Lease::Type type, const DUID& duid,
                         uint32_t iaid, SubnetID subnet_id) const;
 
+    /// @brief Returns all IPv6 leases for the particular subnet identifier.
+    ///
+    /// @param subnet_id subnet identifier.
+    ///
+    /// @return Lease collection (may be empty if no IPv6 lease found).
+    virtual Lease6Collection getLeases6(SubnetID subnet_id) const = 0;
+
+    /// @brief Returns all IPv6 leases.
+    ///
+    /// @return Lease collection (may be empty if no IPv6 lease found).
+    virtual Lease6Collection getLeases6() const = 0;
+
     /// @brief Returns a collection of expired DHCPv6 leases.
     ///
     /// This method returns at most @c max_leases expired leases. The leases
index 1a26b44668b2a6c9e97f056eb5e1cb14196c9ba5..61aaf577b1f73c1de33f054c3ad65524b1b38468 100644 (file)
@@ -831,6 +831,36 @@ Memfile_LeaseMgr::getLeases6(Lease::Type type,
     return (collection);
 }
 
+Lease6Collection
+Memfile_LeaseMgr::getLeases6(SubnetID subnet_id) const {
+    LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MEMFILE_GET_SUBID6)
+        .arg(subnet_id);
+
+    Lease6Collection collection;
+    const Lease6StorageSubnetIdIndex& idx = storage6_.get<SubnetIdIndexTag>();
+    std::pair<Lease6StorageSubnetIdIndex::const_iterator,
+              Lease6StorageSubnetIdIndex::const_iterator> l =
+        idx.equal_range(subnet_id);
+
+    for (auto lease = l.first; lease != l.second; ++lease) {
+        collection.push_back(Lease6Ptr(new Lease6(**lease)));
+    }
+
+    return (collection);
+}
+
+Lease6Collection
+Memfile_LeaseMgr::getLeases6() const {
+   LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MEMFILE_GET6);
+
+   Lease6Collection collection;
+   for (auto lease = storage6_.begin(); lease != storage6_.end(); ++lease ) {
+       collection.push_back(Lease6Ptr(new Lease6(**lease)));
+   }
+
+   return (collection);
+}
+
 void
 Memfile_LeaseMgr::getExpiredLeases6(Lease6Collection& expired_leases,
                                     const size_t max_leases) const {
index a82fa3cd5b98f37c0d829201d0b61b98eb75547f..0cb5bc829b42a2d3bb3cc074c5b83f7ab34519fe 100644 (file)
@@ -271,6 +271,18 @@ public:
                                         uint32_t iaid,
                                         SubnetID subnet_id) const;
 
+    /// @brief Returns all IPv6 leases for the particular subnet identifier.
+    ///
+    /// @param subnet_id subnet identifier.
+    ///
+    /// @return Lease collection (may be empty if no IPv6 lease found).
+    virtual Lease6Collection getLeases6(SubnetID subnet_id) const;
+
+    /// @brief Returns all IPv6 leases.
+    ///
+    /// @return Lease collection (may be empty if no IPv6 lease found).
+    virtual Lease6Collection getLeases6() const;
+
     /// @brief Returns a collection of expired DHCPv6 leases.
     ///
     /// This method returns at most @c max_leases expired leases. The leases
index 8c70a60afa2530484766f99a997cdc7954ead948..9f035564886677a2ae2b813b204fbb8dedef28a9 100644 (file)
@@ -153,6 +153,14 @@ tagged_statements = { {
                             "WHERE state != ? AND expire < ? "
                             "ORDER BY expire ASC "
                             "LIMIT ?"},
+    {MySqlLeaseMgr::GET_LEASE6,
+                    "SELECT address, duid, valid_lifetime, "
+                        "expire, subnet_id, pref_lifetime, "
+                        "lease_type, iaid, prefix_len, "
+                        "fqdn_fwd, fqdn_rev, hostname, "
+                        "hwaddr, hwtype, hwaddr_source, "
+                        "state "
+                            "FROM lease6"},
     {MySqlLeaseMgr::GET_LEASE6_ADDR,
                     "SELECT address, duid, valid_lifetime, "
                         "expire, subnet_id, pref_lifetime, "
@@ -181,6 +189,15 @@ tagged_statements = { {
                             "FROM lease6 "
                             "WHERE duid = ? AND iaid = ? AND subnet_id = ? "
                             "AND lease_type = ?"},
+    {MySqlLeaseMgr::GET_LEASE6_SUBID,
+                    "SELECT address, duid, valid_lifetime, "
+                        "expire, subnet_id, pref_lifetime, "
+                        "lease_type, iaid, prefix_len, "
+                        "fqdn_fwd, fqdn_rev, hostname, "
+                        "hwaddr, hwtype, hwaddr_source, "
+                        "state "
+                            "FROM lease6 "
+                            "WHERE subnet_id = ?"},
     {MySqlLeaseMgr::GET_LEASE6_EXPIRE,
                     "SELECT address, duid, valid_lifetime, "
                         "expire, subnet_id, pref_lifetime, "
@@ -1909,6 +1926,37 @@ MySqlLeaseMgr::getLeases6(Lease::Type lease_type,
     return (result);
 }
 
+Lease6Collection
+MySqlLeaseMgr::getLeases6(SubnetID subnet_id) const {
+    LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MYSQL_GET_SUBID6)
+        .arg(subnet_id);
+
+    // Set up the WHERE clause value
+    MYSQL_BIND inbind[1];
+    memset(inbind, 0, sizeof(inbind));
+
+    // Subnet ID
+    inbind[0].buffer_type = MYSQL_TYPE_LONG;
+    inbind[0].buffer = reinterpret_cast<char*>(&subnet_id);
+    inbind[0].is_unsigned = MLM_TRUE;
+
+    // ... and get the data
+    Lease6Collection result;
+    getLeaseCollection(GET_LEASE6_SUBID, inbind, result);
+
+    return (result);
+}
+
+Lease6Collection
+MySqlLeaseMgr::getLeases6() const {
+   LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MYSQL_GET6);
+
+    Lease6Collection result;
+    getLeaseCollection(GET_LEASE6, 0, result);
+
+    return (result);
+}
+
 void
 MySqlLeaseMgr::getExpiredLeases6(Lease6Collection& expired_leases,
                                  const size_t max_leases) const {
index 0c274a46ed67b75dc0276165ea4c7d43b03bc034..91265cc72ba5ca12e6d0cad356ddfb3f80e42c58 100644 (file)
@@ -268,6 +268,18 @@ public:
     virtual Lease6Collection getLeases6(Lease::Type type, const DUID& duid,
                                         uint32_t iaid, SubnetID subnet_id) const;
 
+    /// @brief Returns all IPv6 leases for the particular subnet identifier.
+    ///
+    /// @param subnet_id subnet identifier.
+    ///
+    /// @return Lease collection (may be empty if no IPv6 lease found).
+    virtual Lease6Collection getLeases6(SubnetID subnet_id) const;
+
+    /// @brief Returns all IPv6 leases.
+    ///
+    /// @return Lease collection (may be empty if no IPv6 lease found).
+    virtual Lease6Collection getLeases6() const;
+
     /// @brief Returns a collection of expired DHCPv6 leases.
     ///
     /// This method returns at most @c max_leases expired leases. The leases
@@ -436,9 +448,11 @@ public:
         GET_LEASE4_HWADDR_SUBID,     // Get lease4 by HW address & subnet ID
         GET_LEASE4_SUBID,            // Get IPv4 leases by subnet ID
         GET_LEASE4_EXPIRE,           // Get lease4 by expiration.
+        GET_LEASE6,                  // Get all IPv6 leases
         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
+        GET_LEASE6_SUBID,            // Get IPv6 leases by subnet ID
         GET_LEASE6_EXPIRE,           // Get lease6 by expiration.
         GET_VERSION,                 // Obtain version number
         INSERT_LEASE4,               // Add entry to lease4 table
index 3d8c30cfdcaa452cb927ebfb772c16d1dcebe0f5..c9e68499dd31682490bb554aedbc475d7fd141fa 100644 (file)
@@ -128,6 +128,15 @@ PgSqlTaggedStatement tagged_statements[] = {
               "ORDER BY expire "
               "LIMIT $3"},
 
+    // GET_LEASE6
+    { 0, { OID_NONE },
+      "get_lease6",
+      "SELECT address, duid, valid_lifetime, "
+        "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
+        "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
+        "state "
+      "FROM lease6"},
+
     // GET_LEASE6_ADDR
     { 2, { OID_VARCHAR, OID_INT2 },
       "get_lease6_addr",
@@ -159,6 +168,16 @@ PgSqlTaggedStatement tagged_statements[] = {
       "WHERE lease_type = $1 "
         "AND duid = $2 AND iaid = $3 AND subnet_id = $4"},
 
+    // GET_LEASE6_SUBID
+    { 1, { OID_INT8 },
+      "get_lease6_subid",
+      "SELECT address, duid, valid_lifetime, "
+        "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
+        "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
+        "state "
+      "FROM lease6 "
+      "WHERE subnet_id = $1"},
+
     // GET_LEASE6_EXPIRE
     { 3, { OID_INT8, OID_TIMESTAMP, OID_INT8 },
       "get_lease6_expire",
@@ -1205,6 +1224,38 @@ PgSqlLeaseMgr::getLeases6(Lease::Type lease_type, const DUID& duid,
     return (result);
 }
 
+Lease6Collection
+PgSqlLeaseMgr::getLeases6(SubnetID subnet_id) const {
+    LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_PGSQL_GET_SUBID6)
+        .arg(subnet_id);
+
+    // Set up the WHERE clause value
+    PsqlBindArray bind_array;
+
+    // SUBNET_ID
+    std::string subnet_id_str = boost::lexical_cast<std::string>(subnet_id);
+    bind_array.add(subnet_id_str);
+
+    // ... and get the data
+    Lease6Collection result;
+    getLeaseCollection(GET_LEASE6_SUBID, bind_array, result);
+
+    return (result);
+}
+
+Lease6Collection
+PgSqlLeaseMgr::getLeases6() const {
+    LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_PGSQL_GET6);
+
+    // Provide empty binding array because our query has no parameters in
+    // WHERE clause.
+    PsqlBindArray bind_array;
+    Lease6Collection result;
+    getLeaseCollection(GET_LEASE6, bind_array, result);
+
+    return (result);
+}
+
 void
 PgSqlLeaseMgr::getExpiredLeases6(Lease6Collection& expired_leases,
                                  const size_t max_leases) const {
index 8599d523795a85843e206e032a5210e41b080ad4..54ca6df8ecbe585cc4115cedfd9b7e36e54caaeb 100644 (file)
@@ -161,18 +161,6 @@ public:
     virtual Lease4Ptr getLease4(const ClientId& client_id, const HWAddr& hwaddr,
                                 SubnetID subnet_id) const;
 
-    /// @brief Returns all IPv4 leases for the particular subnet identifier.
-    ///
-    /// @param subnet_id subnet identifier.
-    ///
-    /// @return Lease collection (may be empty if no IPv4 lease found).
-    virtual Lease4Collection getLeases4(SubnetID subnet_id) const;
-
-    /// @brief Returns all IPv4 leases.
-    ///
-    /// @return Lease collection (may be empty if no IPv4 lease found).
-    virtual Lease4Collection getLeases4() const;
-
     /// @brief Returns existing IPv4 lease for specified client-id
     ///
     /// There can be at most one lease for a given HW address in a single
@@ -188,6 +176,18 @@ public:
     virtual Lease4Ptr getLease4(const ClientId& clientid,
                                 SubnetID subnet_id) const;
 
+    /// @brief Returns all IPv4 leases for the particular subnet identifier.
+    ///
+    /// @param subnet_id subnet identifier.
+    ///
+    /// @return Lease collection (may be empty if no IPv4 lease found).
+    virtual Lease4Collection getLeases4(SubnetID subnet_id) const;
+
+    /// @brief Returns all IPv4 leases.
+    ///
+    /// @return Lease collection (may be empty if no IPv4 lease found).
+    virtual Lease4Collection getLeases4() const;
+
     /// @brief Returns existing IPv6 lease for a given IPv6 address.
     ///
     /// For a given address, we assume that there will be only one lease.
@@ -242,6 +242,18 @@ public:
     virtual Lease6Collection getLeases6(Lease::Type type, const DUID& duid,
                                         uint32_t iaid, SubnetID subnet_id) const;
 
+    /// @brief Returns all IPv6 leases for the particular subnet identifier.
+    ///
+    /// @param subnet_id subnet identifier.
+    ///
+    /// @return Lease collection (may be empty if no IPv6 lease found).
+    virtual Lease6Collection getLeases6(SubnetID subnet_id) const;
+
+    /// @brief Returns all IPv6 leases.
+    ///
+    /// @return Lease collection (may be empty if no IPv6 lease found).
+    virtual Lease6Collection getLeases6() const;
+
     /// @brief Returns a collection of expired DHCPv6 leases.
     ///
     /// This method returns at most @c max_leases expired leases. The leases
@@ -427,9 +439,11 @@ public:
         GET_LEASE4_HWADDR_SUBID,    // Get lease4 by HW address & subnet ID
         GET_LEASE4_SUBID,           // Get IPv4 leases by subnet ID
         GET_LEASE4_EXPIRE,          // Get expired lease4
+        GET_LEASE6,                 // Get all IPv6 leases
         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
+        GET_LEASE6_SUBID,           // Get IPv6 leases by subnet ID
         GET_LEASE6_EXPIRE,          // Get expired lease6
         GET_VERSION,                // Obtain version number
         INSERT_LEASE4,              // Add entry to lease4 table
index e9cdcbf94210a2e131e878a632e702fe38a8e2b7..3b1850d5275d86f91684d74c9333b4e2d38ad9e3 100644 (file)
@@ -1246,6 +1246,33 @@ GenericLeaseMgrTest::testGetLeases4() {
     ASSERT_EQ(leases.size(), returned.size());
 }
 
+void
+GenericLeaseMgrTest::testGetLeases6SubnetId() {
+    // Get the leases to be used for the test and add to the database.
+    vector<Lease6Ptr> leases = createLeases6();
+    for (size_t i = 0; i < leases.size(); ++i) {
+        EXPECT_TRUE(lmptr_->addLease(leases[i]));
+    }
+
+    // There should be exactly two leases for the subnet id that the second
+    // lease belongs to.
+    Lease6Collection returned = lmptr_->getLeases6(leases[1]->subnet_id_);
+    ASSERT_EQ(2, returned.size());
+}
+
+void
+GenericLeaseMgrTest::testGetLeases6() {
+    // Get the leases to be used for the test and add to the database
+    vector<Lease6Ptr> leases = createLeases6();
+    for (size_t i = 0; i < leases.size(); ++i) {
+        EXPECT_TRUE(lmptr_->addLease(leases[i]));
+    }
+
+    // All leases should be returned.
+    Lease6Collection returned = lmptr_->getLeases6();
+    ASSERT_EQ(leases.size(), returned.size());
+}
+
 void
 GenericLeaseMgrTest::testGetLeases6DuidIaid() {
     // Get the leases to be used for the test.
index 07b7948cc3bec89b91b7824dace13ee42fa26b14..b6e275d57ff507563851a64465a36eeaa62e4296 100644 (file)
@@ -206,6 +206,12 @@ public:
     /// @brief Test method which returns all IPv4 leases.
     void testGetLeases4();
 
+    /// @brief Test method which returns all IPv6 leases for Subnet ID.
+    void testGetLeases6SubnetId();
+
+    /// @brief Test method which returns all IPv6 leases.
+    void testGetLeases6();
+
     /// @brief Basic Lease4 Checks
     ///
     /// Checks that the addLease, getLease4(by address), getLease4(hwaddr,subnet_id),
index 373eb1a0b9321d27039d606b92fe0e55a7e07de8..88ea5a064a38d16f06c6ed3cf91a4cc85ff31bd9 100644 (file)
@@ -178,6 +178,22 @@ public:
         return (leases6_);
     }
 
+    /// @brief Returns all IPv6 leases for the particular subnet identifier.
+    ///
+    /// @param subnet_id subnet identifier.
+    ///
+    /// @return Lease collection (may be empty if no IPv6 lease found).
+    virtual Lease6Collection getLeases6(SubnetID) const {
+        return (Lease6Collection());
+    }
+
+    /// @brief Returns all IPv6 leases.
+    ///
+    /// @return Lease collection (may be empty if no IPv6 lease found).
+    virtual Lease6Collection getLeases6() const {
+        return (Lease6Collection());
+    }
+
 
     /// @brief Returns expired DHCPv6 leases.
     ///
index df4d586c3bd2a0be54c07062dd1badd822f9adb4..c438f0807c197734f22b6c2de46e8c3fa7e76873 100644 (file)
@@ -929,6 +929,18 @@ TEST_F(MemfileLeaseMgrTest, getLeases4) {
     testGetLeases4();
 }
 
+// This test checks that all IPv6 leases for a specified subnet id are returned.
+TEST_F(MemfileLeaseMgrTest, getLeases6SubnetId) {
+    startBackend(V6);
+    testGetLeases6SubnetId();
+}
+
+// This test checks that all IPv6 leases are returned.
+TEST_F(MemfileLeaseMgrTest, getLeases6) {
+    startBackend(V6);
+    testGetLeases6();
+}
+
 /// @brief Basic Lease6 Checks
 ///
 /// Checks that the addLease, getLease6 (by address) and deleteLease (with an
index 609ddabe6e748ec05e7940b92b7e4ef5b84e697c..974d7d79512025543ae0714f4bbbacc0d11f2e40 100644 (file)
@@ -331,6 +331,16 @@ TEST_F(MySqlLeaseMgrTest, getLeases4) {
     testGetLeases4();
 }
 
+// This test checks that all IPv6 leases for a specified subnet id are returned.
+TEST_F(MySqlLeaseMgrTest, getLeases6SubnetId) {
+    testGetLeases6SubnetId();
+}
+
+// This test checks that all IPv6 leases are returned.
+TEST_F(MySqlLeaseMgrTest, getLeases6) {
+    testGetLeases6();
+}
+
 /// @brief Basic Lease4 Checks
 ///
 /// Checks that the addLease, getLease4(by address), getLease4(hwaddr,subnet_id),
index fa84bbb99b20003858679a8f2041a494be1050ba..2087d46a18c376d22877f595a88f87f7ab6246d7 100644 (file)
@@ -290,6 +290,16 @@ TEST_F(PgSqlLeaseMgrTest, getLeases4) {
     testGetLeases4();
 }
 
+// This test checks that all IPv6 leases for a specified subnet id are returned.
+TEST_F(PgSqlLeaseMgrTest, getLeases6SubnetId) {
+    testGetLeases6SubnetId();
+}
+
+// This test checks that all IPv6 leases are returned.
+TEST_F(PgSqlLeaseMgrTest, getLeases6) {
+    testGetLeases6();
+}
+
 /// @brief Basic Lease4 Checks
 ///
 /// Checks that the addLease, getLease4(by address), getLease4(hwaddr,subnet_id),
index b1cdd1d05883f60f2ee61d97db4bda20691afa3c..921e4670f77bfd4bfc234cd756c6ae6ba298ef7d 100644 (file)
@@ -514,7 +514,9 @@ ALTER TABLE dhcp6_options ADD COLUMN user_context TEXT NULL;
 CREATE INDEX lease4_by_subnet_id ON lease4 (subnet_id);
 
 # Create for searching leases by subnet identifier and lease type.
-CREATE INDEX lease6_by_subnet_id_lease_type ON lease6 (subnet_id, lease_type);
+#CREATE INDEX lease6_by_subnet_id_lease_type ON lease6 (subnet_id, lease_type);
+# Create for searching leases by subnet identifier.
+CREATE INDEX lease6_by_subnet_id ON lease6 (subnet_id);
 
 # Update the schema version number
 UPDATE schema_version
index c4e78091289abf4d3bffdbfb66c9e4f163fa5857..96af0278843df1666b980f38a723b0a6a36d75a1 100644 (file)
@@ -28,7 +28,9 @@ ALTER TABLE dhcp6_options ADD COLUMN user_context TEXT NULL;
 CREATE INDEX lease4_by_subnet_id ON lease4 (subnet_id);
 
 # Create for searching leases by subnet identifier and lease type.
-CREATE INDEX lease6_by_subnet_id_lease_type ON lease6 (subnet_id, lease_type);
+#CREATE INDEX lease6_by_subnet_id_lease_type ON lease6 (subnet_id, lease_type);
+# Create for searching leases by subnet identifier.
+CREATE INDEX lease6_by_subnet_id ON lease6 (subnet_id);
 
 # Update the schema version number
 UPDATE schema_version
index 90d1aed7da55cc0eb40bc9b00fe514009d4d0213..4414bd6a039d46213193014b958f249ed31ce777 100644 (file)
@@ -541,7 +541,9 @@ ALTER TABLE dhcp6_options ADD COLUMN user_context TEXT;
 CREATE INDEX lease4_by_subnet_id ON lease4 (subnet_id);
 
 -- Create for searching leases by subnet identifier and lease type.
-CREATE INDEX lease6_by_subnet_id_lease_type ON lease6 (subnet_id, lease_type);
+-- CREATE INDEX lease6_by_subnet_id_lease_type ON lease6 (subnet_id, lease_type);
+-- Create for searching leases by subnet identifier.
+CREATE INDEX lease6_by_subnet_id ON lease6 (subnet_id);
 
 -- Set 4.0 schema version.
 UPDATE schema_version
index c20e114f2a344cef067ff9a27b80439c4557d793..236f8e312e4796aa764abee89135ad1c02b246d1 100644 (file)
@@ -30,7 +30,9 @@ ALTER TABLE dhcp6_options ADD COLUMN user_context TEXT;
 CREATE INDEX lease4_by_subnet_id ON lease4 (subnet_id);
 
 -- Create for searching leases by subnet identifier and lease type.
-CREATE INDEX lease6_by_subnet_id_lease_type ON lease6 (subnet_id, lease_type);
+-- CREATE INDEX lease6_by_subnet_id_lease_type ON lease6 (subnet_id, lease_type);
+-- Create for searching leases by subnet identifier.
+CREATE INDEX lease6_by_subnet_id ON lease6 (subnet_id);
 
 -- Set 4.0 schema version.
 UPDATE schema_version