diff --git a/src/bin/dhcp4/dhcp4_messages.cc b/src/bin/dhcp4/dhcp4_messages.cc index 6219337257..c8966d74b2 100644 --- a/src/bin/dhcp4/dhcp4_messages.cc +++ b/src/bin/dhcp4/dhcp4_messages.cc @@ -75,6 +75,7 @@ extern const isc::log::MessageID DHCP4_HOOK_DECLINE_SKIP = "DHCP4_HOOK_DECLINE_S extern const isc::log::MessageID DHCP4_HOOK_LEASE4_RELEASE_SKIP = "DHCP4_HOOK_LEASE4_RELEASE_SKIP"; extern const isc::log::MessageID DHCP4_HOOK_LEASES4_COMMITTED_DROP = "DHCP4_HOOK_LEASES4_COMMITTED_DROP"; extern const isc::log::MessageID DHCP4_HOOK_LEASES4_COMMITTED_PARK = "DHCP4_HOOK_LEASES4_COMMITTED_PARK"; +extern const isc::log::MessageID DHCP4_HOOK_LEASES4_PARKING_LOT_FULL = "DHCP4_HOOK_LEASES4_PARKING_LOT_FULL"; extern const isc::log::MessageID DHCP4_HOOK_PACKET_RCVD_SKIP = "DHCP4_HOOK_PACKET_RCVD_SKIP"; extern const isc::log::MessageID DHCP4_HOOK_PACKET_SEND_DROP = "DHCP4_HOOK_PACKET_SEND_DROP"; extern const isc::log::MessageID DHCP4_HOOK_PACKET_SEND_SKIP = "DHCP4_HOOK_PACKET_SEND_SKIP"; @@ -230,6 +231,7 @@ const char* values[] = { "DHCP4_HOOK_LEASE4_RELEASE_SKIP", "%1: lease was not released because a callout set the next step to SKIP", "DHCP4_HOOK_LEASES4_COMMITTED_DROP", "%1: packet is dropped, because a callout set the next step to DROP", "DHCP4_HOOK_LEASES4_COMMITTED_PARK", "%1: packet is parked, because a callout set the next step to PARK", + "DHCP4_HOOK_LEASES4_PARKING_LOT_FULL", "The parked-packet-limit %1, has been reached, dropping query: %2", "DHCP4_HOOK_PACKET_RCVD_SKIP", "%1: packet is dropped, because a callout set the next step to SKIP", "DHCP4_HOOK_PACKET_SEND_DROP", "%1: prepared DHCPv4 response was not sent because a callout set the next ste to DROP", "DHCP4_HOOK_PACKET_SEND_SKIP", "%1: prepared response is not sent, because a callout set the next stp to SKIP", diff --git a/src/bin/dhcp4/dhcp4_messages.h b/src/bin/dhcp4/dhcp4_messages.h index f03c12a8e5..a52e733fde 100644 --- a/src/bin/dhcp4/dhcp4_messages.h +++ b/src/bin/dhcp4/dhcp4_messages.h @@ -76,6 +76,7 @@ extern const isc::log::MessageID DHCP4_HOOK_DECLINE_SKIP; extern const isc::log::MessageID DHCP4_HOOK_LEASE4_RELEASE_SKIP; extern const isc::log::MessageID DHCP4_HOOK_LEASES4_COMMITTED_DROP; extern const isc::log::MessageID DHCP4_HOOK_LEASES4_COMMITTED_PARK; +extern const isc::log::MessageID DHCP4_HOOK_LEASES4_PARKING_LOT_FULL; extern const isc::log::MessageID DHCP4_HOOK_PACKET_RCVD_SKIP; extern const isc::log::MessageID DHCP4_HOOK_PACKET_SEND_DROP; extern const isc::log::MessageID DHCP4_HOOK_PACKET_SEND_SKIP; diff --git a/src/bin/dhcp4/dhcp4_messages.mes b/src/bin/dhcp4/dhcp4_messages.mes index 19aa3581ff..c98c43bc38 100644 --- a/src/bin/dhcp4/dhcp4_messages.mes +++ b/src/bin/dhcp4/dhcp4_messages.mes @@ -391,6 +391,14 @@ hook point sets the next step to DROP. This debug message is printed when a callout installed on the leases4_committed hook point sets the next step to PARK. +% DHCP4_HOOK_LEASES4_PARKING_LOT_FULL The parked-packet-limit %1, has been reached, dropping query: %2 +This debug message occurs when the parking lot used to hold client queries +while hook library work for them completes has reached or exceeded the +limit set by the parked-packet-limit global parameter. This can occur when +kea-dhcp4 is using hook libraries (e.g. HA) that implement the +"leases4-committed" callout and client queries are arriving faster than +those callouts can fulfill them. + % DHCP4_HOOK_PACKET_RCVD_SKIP %1: packet is dropped, because a callout set the next step to SKIP This debug message is printed when a callout installed on the pkt4_receive hook point sets the next step to SKIP. For this particular hook point, the diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc index 8af64f9856..4d732a2c07 100644 --- a/src/bin/dhcp4/dhcp4_srv.cc +++ b/src/bin/dhcp4/dhcp4_srv.cc @@ -1356,6 +1356,31 @@ Dhcpv4Srv::processDhcp4Query(Pkt4Ptr& query, Pkt4Ptr& rsp, callout_handle->setArgument("deleted_leases4", deleted_leases); if (allow_packet_park) { + // Get the parking limit. Parsing should ensure the value is present. + uint32_t parked_packet_limit = 0; + data::ConstElementPtr ppl = CfgMgr::instance(). + getCurrentCfg()->getConfiguredGlobal("parked-packet-limit"); + if (ppl) { + parked_packet_limit = ppl->intValue(); + } + + if (parked_packet_limit) { + const auto& parking_lot = ServerHooks::getServerHooks(). + getParkingLotPtr("leases4_committed"); + + if (parking_lot && (parking_lot->size() >= parked_packet_limit)) { + // We can't park it so we're going to throw it on the floor. + LOG_DEBUG(packet4_logger, DBGLVL_PKT_HANDLING, + DHCP4_HOOK_LEASES4_PARKING_LOT_FULL) + .arg(parked_packet_limit) + .arg(query->getLabel()); + isc::stats::StatsMgr::instance().addValue("pkt4-receive-drop", + static_cast(1)); + rsp.reset(); + return; + } + } + // We proactively park the packet. We'll unpark it without invoking // the callback (i.e. drop) unless the callout status is set to // NEXT_STEP_PARK. Otherwise the callback we bind here will be