]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#3140] [4157] Added pkt[46]-queue-full
authorFrancis Dupont <fdupont@isc.org>
Tue, 14 Oct 2025 09:45:01 +0000 (11:45 +0200)
committerFrancis Dupont <fdupont@isc.org>
Wed, 5 Nov 2025 21:46:16 +0000 (22:46 +0100)
16 files changed:
changelog_unreleased/4157-add-drop-stats-queue-full [new file with mode: 0644]
doc/sphinx/arm/dhcp4-srv.rst
doc/sphinx/arm/dhcp6-srv.rst
doc/sphinx/arm/stats.rst
src/bin/dhcp4/client_handler.cc
src/bin/dhcp4/dhcp4_srv.cc
src/bin/dhcp4/tests/client_handler_unittest.cc
src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc
src/bin/dhcp4/tests/hooks_unittest.cc
src/bin/dhcp4/tests/http_control_socket_unittest.cc
src/bin/dhcp6/client_handler.cc
src/bin/dhcp6/dhcp6_srv.cc
src/bin/dhcp6/tests/client_handler_unittest.cc
src/bin/dhcp6/tests/ctrl_dhcp6_srv_unittest.cc
src/bin/dhcp6/tests/hooks_unittest.cc
src/bin/dhcp6/tests/http_control_socket_unittest.cc

diff --git a/changelog_unreleased/4157-add-drop-stats-queue-full b/changelog_unreleased/4157-add-drop-stats-queue-full
new file mode 100644 (file)
index 0000000..b371dce
--- /dev/null
@@ -0,0 +1,5 @@
+[func]         fdupont
+       Added "pkt4-queue-full" and "pkt6-queue-full"
+       statistics which are increased when an incoming packet
+       was dropped because it was queued and the queue is full.
+       (Gitlab #4157)
index 6a9a3d860429dff8d7222368c65de239b1d79c7f..8fe7680cd1cff08dc481cce18d74a4cf4d261d91 100644 (file)
@@ -7403,6 +7403,10 @@ The DHCPv4 server supports the following statistics:
    |                                                    |                | network, faulty clients, or a bug  |
    |                                                    |                | in the server.                     |
    +----------------------------------------------------+----------------+------------------------------------+
+   | pkt4-queue-full                                    | integer        | Number of incoming packets that    |
+   |                                                    |                | were dropped when the queue they   |
+   |                                                    |                | were parked became full.           |
+   +----------------------------------------------------+----------------+------------------------------------+
    | pkt4-receive-drop                                  | integer        | Number of incoming packets that    |
    |                                                    |                | were dropped. The exact reason for |
    |                                                    |                | dropping packets is logged, but    |
@@ -7803,9 +7807,13 @@ The DHCPv4 server supports the following statistics:
 
 Dropped incoming packets can be counted in the ``pkt4-receive-drop`` and
 a second counter detailing the drop cause:
+
 - ``pkt4-service-disabled`` - DHCP service is disabled
+
 - ``pkt4-parse-failed`` - packet parsing raised a fatal error
 
+- ``pkt6-queue-full`` - parked packet in a queue which became full
+
 .. note::
 
    The pool ID can be configured on each pool by explicitly setting the ``pool-id``
index 55608e842f679b27fd05cb0603ca90a3562163c2..e220310da3d6ec2167a9a7758449ab2333cbc7df 100644 (file)
@@ -6978,6 +6978,10 @@ The DHCPv6 server supports the following statistics:
    |                                                   |                | relay agents, or a bug in the      |
    |                                                   |                | server.                            |
    +---------------------------------------------------+----------------+------------------------------------+
+   | pkt6-queue-full                                   | integer        | Number of incoming packets that    |
+   |                                                   |                | were dropped when the queue they   |
+   |                                                   |                | were parked became full.           |
+   +---------------------------------------------------+----------------+------------------------------------+
    | pkt6-solicit-received                             | integer        | Number of SOLICIT packets          |
    |                                                   |                | received. This statistic is        |
    |                                                   |                | expected to grow; its increase     |
@@ -7698,9 +7702,13 @@ The DHCPv6 server supports the following statistics:
 
 Dropped incoming packets can be counted in the ``pkt6-receive-drop`` and
 a second counter detailing the drop cause:
+
 - ``pkt6-service-disabled`` - DHCP service is disabled
+
 - ``pkt6-parse-failed`` - packet parsing raised a fatal error
 
+- ``pkt6-queue-full`` - parked packet in a queue which became full
+
 .. note::
 
    The pool ID can be configured on each pool by explicitly setting the ``pool-id``
index 40b5df58d05e103200111073be84596cad21b52c..ff8f538a1e625ba4ad9de8b3d05bbbdf4fc0f47b 100644 (file)
@@ -340,6 +340,12 @@ Here is an example response returning all collected statistics:
                    "2023-06-13 20:42:46.616351"
                ]
            ],
+           "pkt4-queue-full": [
+               [
+                   0,
+                   "2023-06-13 20:42:46.616352"
+               ]
+           ],
            "pkt4-unknown-received": [
                [
                    0,
@@ -657,6 +663,12 @@ or
                    "2023-06-13 21:28:57.177747"
                ]
            ],
+           "pkt6-queue-full": [
+               [
+                   0,
+                   "2023-06-13 21:28:57.177747"
+               ]
+           ],
            "pkt6-solicit-received": [
                [
                    0,
@@ -1074,6 +1086,12 @@ Here is an example response returning all collected statistics:
                    "2023-06-13 20:42:46.616351"
                ]
            ],
+           "pkt4-queue-full": [
+               [
+                   0,
+                   "2023-06-13 20:42:46.616352"
+               ]
+           ],
            "pkt4-unknown-received": [
                [
                    0,
@@ -1307,6 +1325,12 @@ or
                    "2023-06-13 21:28:57.177747"
                ]
            ],
+           "pkt6-queue-full": [
+               [
+                   0,
+                   "2023-06-13 21:28:57.177747"
+               ]
+           ],
            "pkt6-solicit-received": [
                [
                    0,
index 8fa4a55b2b67369094694f25c85e9794d3b9c5cd..f7585bcd063143d48c720574740116171f8d3355 100644 (file)
@@ -244,6 +244,8 @@ ClientHandler::tryLock(Pkt4Ptr query, ContinuationPtr cont) {
                     .arg(holder_id->query_->getHWAddrLabel())
                     .arg(holder_id->query_->toText())
                     .arg(holder_id->thread_);
+                stats::StatsMgr::instance().addValue("pkt4-queue-full",
+                                                     static_cast<int64_t>(1));
                 stats::StatsMgr::instance().addValue("pkt4-receive-drop",
                                                      static_cast<int64_t>(1));
             }
@@ -257,6 +259,8 @@ ClientHandler::tryLock(Pkt4Ptr query, ContinuationPtr cont) {
                 .arg(holder_id->query_->getHWAddrLabel())
                 .arg(holder_id->query_->toText())
                 .arg(holder_id->thread_);
+            stats::StatsMgr::instance().addValue("pkt4-queue-full",
+                                                 static_cast<int64_t>(1));
             stats::StatsMgr::instance().addValue("pkt4-receive-drop",
                                                  static_cast<int64_t>(1));
         }
@@ -273,6 +277,8 @@ ClientHandler::tryLock(Pkt4Ptr query, ContinuationPtr cont) {
                     .arg(holder_hw->query_->getHWAddrLabel())
                     .arg(holder_hw->query_->toText())
                     .arg(holder_hw->thread_);
+                stats::StatsMgr::instance().addValue("pkt4-queue-full",
+                                                     static_cast<int64_t>(1));
                 stats::StatsMgr::instance().addValue("pkt4-receive-drop",
                                                      static_cast<int64_t>(1));
             }
@@ -286,6 +292,8 @@ ClientHandler::tryLock(Pkt4Ptr query, ContinuationPtr cont) {
                 .arg(holder_hw->query_->getHWAddrLabel())
                 .arg(holder_hw->query_->toText())
                 .arg(holder_hw->thread_);
+            stats::StatsMgr::instance().addValue("pkt4-queue-full",
+                                                 static_cast<int64_t>(1));
             stats::StatsMgr::instance().addValue("pkt4-receive-drop",
                                                  static_cast<int64_t>(1));
         }
index cbec84c2f6f37a460f68ea5cb43025c2b11f8563..8609f1d215fc266fb3237a49c3018d714fa53124 100644 (file)
@@ -183,6 +183,7 @@ std::set<std::string> dhcp4_statistics = {
     "pkt4-nak-sent",
     "pkt4-service-disabled",
     "pkt4-parse-failed",
+    "pkt4-queue-full",
     "pkt4-receive-drop",
     "v4-allocation-fail",
     "v4-allocation-fail-shared-network",
@@ -818,6 +819,10 @@ Dhcpv4Srv::selectSubnet(const Pkt4Ptr& query, bool& drop, bool allow_answer_park
                       DHCP4_HOOK_SUBNET4_SELECT_PARKING_LOT_FULL)
                 .arg(limit)
                 .arg(query->getLabel());
+            isc::stats::StatsMgr::instance().addValue("pkt4-queue-full",
+                                                      static_cast<int64_t>(1));
+            isc::stats::StatsMgr::instance().addValue("pkt4-receive-drop",
+                                                      static_cast<int64_t>(1));
             return (ConstSubnet4Ptr());
         }
 
@@ -985,6 +990,10 @@ Dhcpv4Srv::selectSubnet4o6(const Pkt4Ptr& query, bool& drop,
                       DHCP4_HOOK_SUBNET4_SELECT_4O6_PARKING_LOT_FULL)
                 .arg(limit)
                 .arg(query->getLabel());
+            isc::stats::StatsMgr::instance().addValue("pkt4-queue-full",
+                                                      static_cast<int64_t>(1));
+            isc::stats::StatsMgr::instance().addValue("pkt4-receive-drop",
+                                                      static_cast<int64_t>(1));
             return (ConstSubnet4Ptr());
         }
 
@@ -1789,6 +1798,8 @@ Dhcpv4Srv::processLocalizedQuery4(AllocEngine::ClientContext4Ptr& ctx,
                     LOG_DEBUG(packet4_logger, DBGLVL_PKT_HANDLING, parking_lot_full_msg)
                         .arg(limit)
                         .arg(query->getLabel());
+                    isc::stats::StatsMgr::instance().addValue("pkt4-queue-full",
+                                                              static_cast<int64_t>(1));
                     isc::stats::StatsMgr::instance().addValue("pkt4-receive-drop",
                                                                 static_cast<int64_t>(1));
                     return (Pkt4Ptr());
index 50b3ba5e67aac52844afdec9def8594b440a4510..9c6119d6f3630c477b19f205f68b3e8595a674cc 100644 (file)
@@ -26,9 +26,10 @@ public:
 
     /// @brief Constructor.
     ///
-    /// Creates the pkt4-receive-drop statistic.
+    /// Creates the pkt4-queue-full and pkt4-receive-drop statistics.
     ClientHandleTest() : called1_(false), called2_(false), called3_(false) {
         MultiThreadingMgr::instance().apply(false, 0, 0);
+        StatsMgr::instance().setValue("pkt4-queue-full", static_cast<int64_t>(0));
         StatsMgr::instance().setValue("pkt4-receive-drop", static_cast<int64_t>(0));
     }
 
@@ -71,15 +72,21 @@ public:
 
     /// @brief Check statistics.
     ///
-    /// @param bumped True if pkt4-receive-drop should have been bumped by one,
+    /// @param bumped True if statistics should have been bumped by one,
     /// false otherwise.
     void checkStat(bool bumped) {
-        ObservationPtr obs = StatsMgr::instance().getObservation("pkt4-receive-drop");
-        ASSERT_TRUE(obs);
+        ObservationPtr obs_qf =
+            StatsMgr::instance().getObservation("pkt4-queue-full");
+        ObservationPtr obs_rd =
+            StatsMgr::instance().getObservation("pkt4-receive-drop");
+        ASSERT_TRUE(obs_qf);
+        ASSERT_TRUE(obs_rd);
         if (bumped) {
-            EXPECT_EQ(1, obs->getInteger().first);
+            EXPECT_EQ(1, obs_qf->getInteger().first);
+            EXPECT_EQ(1, obs_rd->getInteger().first);
         } else {
-            EXPECT_EQ(0, obs->getInteger().first);
+            EXPECT_EQ(0, obs_qf->getInteger().first);
+            EXPECT_EQ(0, obs_rd->getInteger().first);
         }
     }
 
index a5ba6e3f13a68002eb8ec427981f9d590819f5ad..de742efb5b9b028fb334b0c666885afaa606a8c1 100644 (file)
@@ -630,6 +630,7 @@ TEST_F(CtrlChannelDhcpv4SrvTest, controlChannelStats) {
         "pkt4-nak-sent",
         "pkt4-service-disabled",
         "pkt4-parse-failed",
+        "pkt4-queue-full",
         "pkt4-receive-drop",
         "v4-allocation-fail",
         "v4-allocation-fail-shared-network",
index f97ead2031b59ec0f05afb09ea8d432ea158a63b..2658626f4e925b3411cbe80e86eee24a67ff3095 100644 (file)
@@ -3586,6 +3586,7 @@ TEST_F(HooksDhcpv4SrvTest, leases4ParkedPacketLimit) {
                     "leases4_committed", leases4_committed_park_callout));
 
     // Statistic should not show any drops.
+    EXPECT_EQ(0, getStatistic("pkt4-queue-full"));
     EXPECT_EQ(0, getStatistic("pkt4-receive-drop"));
 
     // Create a client and initiate a DORA cycle for it.
@@ -3626,6 +3627,7 @@ TEST_F(HooksDhcpv4SrvTest, leases4ParkedPacketLimit) {
     ASSERT_EQ(1, parking_lot->size());
 
     // Statistic should show one drop.
+    EXPECT_EQ(1, getStatistic("pkt4-queue-full"));
     EXPECT_EQ(1, getStatistic("pkt4-receive-drop"));
 
     // Invoking poll should run the scheduled action only for
@@ -3670,6 +3672,7 @@ TEST_F(HooksDhcpv4SrvTest, leases4ParkedPacketLimit) {
     ASSERT_EQ(0, parking_lot->size());
 
     // Statistic should still show one drop.
+    EXPECT_EQ(1, getStatistic("pkt4-queue-full"));
     EXPECT_EQ(1, getStatistic("pkt4-receive-drop"));
 }
 
@@ -3950,6 +3953,7 @@ TEST_F(HooksDhcpv4SrvTest, lease4OfferParkedPacketLimit) {
         "lease4_offer", lease4_offer_park_callout));
 
     // Statistic should not show any drops.
+    EXPECT_EQ(0, getStatistic("pkt4-queue-full"));
     EXPECT_EQ(0, getStatistic("pkt4-receive-drop"));
 
     // Create a client and initiate a DORA cycle for it.
@@ -3990,6 +3994,7 @@ TEST_F(HooksDhcpv4SrvTest, lease4OfferParkedPacketLimit) {
     ASSERT_EQ(1, parking_lot->size());
 
     // Statistic should show one drop.
+    EXPECT_EQ(1, getStatistic("pkt4-queue-full"));
     EXPECT_EQ(1, getStatistic("pkt4-receive-drop"));
 
     // Invoking poll should run the scheduled action only for
@@ -4034,6 +4039,7 @@ TEST_F(HooksDhcpv4SrvTest, lease4OfferParkedPacketLimit) {
     ASSERT_EQ(0, parking_lot->size());
 
     // Statistic should still show one drop.
+    EXPECT_EQ(1, getStatistic("pkt4-queue-full"));
     EXPECT_EQ(1, getStatistic("pkt4-receive-drop"));
 }
 
index 9e9f453eef0663417bf14d932a71b8906e8e3045..12971db05bea8fd3af80812619ca868b4bdc7e47 100644 (file)
@@ -941,6 +941,7 @@ BaseCtrlChannelDhcpv4Test::testControlChannelStats() {
         "pkt4-nak-sent",
         "pkt4-service-disabled",
         "pkt4-parse-failed",
+        "pkt4-queue-full",
         "pkt4-receive-drop",
         "v4-allocation-fail",
         "v4-allocation-fail-shared-network",
index 54fc9d8de0f7f255549da9a09cf11d6e6da8bec8..b265021dd6d8bb84e431b409a364ab9ed24d5c9d 100644 (file)
@@ -134,6 +134,8 @@ ClientHandler::tryLock(Pkt6Ptr query, ContinuationPtr cont) {
                 .arg(holder->query_->makeLabel(holder->query_->getClientId(), nullptr))
                 .arg(holder->query_->toText())
                 .arg(holder->thread_);
+            stats::StatsMgr::instance().addValue("pkt6-queue-full",
+                                                 static_cast<int64_t>(1));
             stats::StatsMgr::instance().addValue("pkt6-receive-drop",
                                                  static_cast<int64_t>(1));
         }
@@ -147,6 +149,8 @@ ClientHandler::tryLock(Pkt6Ptr query, ContinuationPtr cont) {
             .arg(holder->query_->makeLabel(holder->query_->getClientId(), nullptr))
             .arg(holder->query_->toText())
             .arg(holder->thread_);
+        stats::StatsMgr::instance().addValue("pkt6-queue-full",
+                                             static_cast<int64_t>(1));
         stats::StatsMgr::instance().addValue("pkt6-receive-drop",
                                              static_cast<int64_t>(1));
     }
index 8083a4e17a96729ea4d494070c3ae80fb383f5ef..493a59ea8c8b09db4d290ea31c4bf1795020d72c 100644 (file)
@@ -243,6 +243,7 @@ std::set<std::string> dhcp6_statistics = {
     "pkt6-addr-reg-reply-sent",
     "pkt6-service-disabled",
     "pkt6-parse-failed",
+    "pkt6-queue-full",
     "pkt6-receive-drop",
     "v6-allocation-fail",
     "v6-allocation-fail-shared-network",
@@ -1316,6 +1317,8 @@ Dhcpv6Srv::processLocalizedQuery6(AllocEngine::ClientContext6& ctx) {
                           DHCP6_HOOK_LEASES6_PARKING_LOT_FULL)
                           .arg(parked_packet_limit)
                           .arg(query->getLabel());
+                isc::stats::StatsMgr::instance().addValue("pkt6-queue-full",
+                                                          static_cast<int64_t>(1));
                 isc::stats::StatsMgr::instance().addValue("pkt6-receive-drop",
                                                           static_cast<int64_t>(1));
                 rsp.reset();
@@ -2140,6 +2143,10 @@ Dhcpv6Srv::selectSubnet(const Pkt6Ptr& question, bool& drop) {
                       DHCP4_HOOK_SUBNET6_SELECT_PARKING_LOT_FULL)
                 .arg(limit)
                 .arg(question->getLabel());
+            isc::stats::StatsMgr::instance().addValue("pkt6-queue-full",
+                                                      static_cast<int64_t>(1));
+            isc::stats::StatsMgr::instance().addValue("pkt6-receive-drop",
+                                                      static_cast<int64_t>(1));
             return (ConstSubnet6Ptr());
         }
 
index 6eed4c4bbdfb1b13d77e6cf0b16556859ca1bff0..32991dba2f2de2441ca45b28530d2311bbf11652 100644 (file)
@@ -26,9 +26,10 @@ public:
 
     /// @brief Constructor.
     ///
-    /// Creates the pkt6-receive-drop statistic.
+    /// Creates the pkt6-queue-full and pkt6-receive-drop statistics.
     ClientHandleTest() : called1_(false), called2_(false), called3_(false) {
         MultiThreadingMgr::instance().apply(false, 0, 0);
+        StatsMgr::instance().setValue("pkt6-queue-full", static_cast<int64_t>(0));
         StatsMgr::instance().setValue("pkt6-receive-drop", static_cast<int64_t>(0));
     }
 
@@ -56,15 +57,21 @@ public:
 
     /// @brief Check statistics.
     ///
-    /// @param bumped True if pkt6-receive-drop should have been bumped by one,
+    /// @param bumped True if statistics should have been bumped by one,
     /// false otherwise.
     void checkStat(bool bumped) {
-        ObservationPtr obs = StatsMgr::instance().getObservation("pkt6-receive-drop");
-        ASSERT_TRUE(obs);
+        ObservationPtr obs_qf =
+            StatsMgr::instance().getObservation("pkt6-queue-full");
+        ObservationPtr obs_rd =
+            StatsMgr::instance().getObservation("pkt6-receive-drop");
+        ASSERT_TRUE(obs_qf);
+        ASSERT_TRUE(obs_rd);
         if (bumped) {
-            EXPECT_EQ(1, obs->getInteger().first);
+            EXPECT_EQ(1, obs_qf->getInteger().first);
+            EXPECT_EQ(1, obs_rd->getInteger().first);
         } else {
-            EXPECT_EQ(0, obs->getInteger().first);
+            EXPECT_EQ(0, obs_qf->getInteger().first);
+            EXPECT_EQ(0, obs_rd->getInteger().first);
         }
     }
 
index 59922cad0b34cedbe89af333b40ba23b01ab7eea..bb91daeef1ce780e39d64fc72e93ce1363d86e4e 100644 (file)
@@ -638,6 +638,7 @@ TEST_F(CtrlChannelDhcpv6SrvTest, controlChannelStats) {
         "pkt6-addr-reg-reply-sent",
         "pkt6-service-disabled",
         "pkt6-parse-failed",
+        "pkt6-queue-full",
         "pkt6-receive-drop",
         "v6-allocation-fail",
         "v6-allocation-fail-shared-network",
index 4e12ecf8d6a17b26b4d30fc2f32b20fdf9dab4f5..417649a286078e85fe0dd5c6a4b130770947f4e6 100644 (file)
@@ -5766,6 +5766,7 @@ TEST_F(HooksDhcpv6SrvTest, leases6ParkedPacketLimit) {
     ASSERT_EQ(0, parking_lot->size());
 
     // Statistic should not show any drops.
+    EXPECT_EQ(0, getStatistic("pkt6-queue-full"));
     EXPECT_EQ(0, getStatistic("pkt6-receive-drop"));
 
     // This callout uses provided IO service object to post a function
@@ -5790,6 +5791,7 @@ TEST_F(HooksDhcpv6SrvTest, leases6ParkedPacketLimit) {
 
     // Verify we have one parked packet and no drops.
     ASSERT_EQ(1, parking_lot->size());
+    EXPECT_EQ(0, getStatistic("pkt6-queue-full"));
     EXPECT_EQ(0, getStatistic("pkt6-receive-drop"));
 
     // Reset all indicators because we'll be now creating a second client.
@@ -5811,6 +5813,7 @@ TEST_F(HooksDhcpv6SrvTest, leases6ParkedPacketLimit) {
 
     // Verify we have one parked packet and one drop.
     ASSERT_EQ(1, parking_lot->size());
+    EXPECT_EQ(1, getStatistic("pkt6-queue-full"));
     EXPECT_EQ(1, getStatistic("pkt6-receive-drop"));
 
     // There should now be one action scheduled on our IO service
@@ -5827,6 +5830,7 @@ TEST_F(HooksDhcpv6SrvTest, leases6ParkedPacketLimit) {
 
     // Verify we have no parked packets and one drop.
     ASSERT_EQ(0, parking_lot->size());
+    EXPECT_EQ(1, getStatistic("pkt6-queue-full"));
     EXPECT_EQ(1, getStatistic("pkt6-receive-drop"));
 
     // Should not anything to receive for client2.
@@ -5850,6 +5854,7 @@ TEST_F(HooksDhcpv6SrvTest, leases6ParkedPacketLimit) {
 
     // Verify we again have one parked packet and one drop.
     ASSERT_EQ(1, parking_lot->size());
+    EXPECT_EQ(1, getStatistic("pkt6-queue-full"));
     EXPECT_EQ(1, getStatistic("pkt6-receive-drop"));
 
     // There should now be one action scheduled on our IO service
@@ -5866,6 +5871,7 @@ TEST_F(HooksDhcpv6SrvTest, leases6ParkedPacketLimit) {
 
     // Verify we no parked packets and one drop.
     ASSERT_EQ(0, parking_lot->size());
+    EXPECT_EQ(1, getStatistic("pkt6-queue-full"));
     EXPECT_EQ(1, getStatistic("pkt6-receive-drop"));
 }
 
index 7684a6946925190ea2d933d5c10425146174fdd0..5c9b4a7f439a478bd7a6a310713c03cc13f247a8 100644 (file)
@@ -956,6 +956,7 @@ BaseCtrlChannelDhcpv6Test::testControlChannelStats() {
         "pkt6-addr-reg-reply-sent",
         "pkt6-service-disabled",
         "pkt6-parse-failed",
+        "pkt6-queue-full",
         "pkt6-receive-drop",
         "v6-allocation-fail",
         "v6-allocation-fail-shared-network",