Commit 8f4fff6e19 for frr

commit 8f4fff6e19f2cf99f9f5b8ba4e6fe93b6a165541
Author: Donald Sharp <sharpd@nvidia.com>
Date:   Tue Oct 6 12:21:39 2026 -0400

    zebra: Add hidden `zebra test disable install`

    This is a corollary to the `zebra test distable result` command.
    Stop dplane contexts from being sent to dplane providers.  When
    the no form of the command is entered turn it back on.

    Signed-off-by: Donald Sharp <sharpd@nvidia.com>

diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c
index 73b9b874be..4e2112b87e 100644
--- a/zebra/zebra_dplane.c
+++ b/zebra/zebra_dplane.c
@@ -8310,6 +8310,27 @@ void zebra_dplane_finish(void)
 			NULL, 0, &zdplane_info.dg_t_shutdown_check);
 }

+#ifdef DEV_BUILD
+/*
+ * When set, dplane_thread_loop leaves new contexts on the incoming queue
+ * instead of handing them to the first provider.
+ */
+static _Atomic bool dplane_install_plugged;
+
+void zebra_dplane_install_plug(void)
+{
+	atomic_store_explicit(&dplane_install_plugged, true, memory_order_relaxed);
+}
+
+void zebra_dplane_install_unplug(void)
+{
+	atomic_store_explicit(&dplane_install_plugged, false, memory_order_relaxed);
+
+	/* Wake the dplane thread so queued contexts are sent. */
+	dplane_provider_work_ready();
+}
+#endif
+
 /*
  * Main dataplane pthread event loop. The thread takes new incoming work
  * and offers it to the first provider. It then iterates through the
@@ -8330,6 +8351,9 @@ static void dplane_thread_loop(struct event *event)
 	int limit, counter, error_counter;
 	uint64_t curr, out_curr, high;
 	bool reschedule = false;
+#ifdef DEV_BUILD
+	bool install_plugged = false;
+#endif

 	/* Capture work limit per cycle */
 	limit = zdplane_info.dg_updates_per_cycle;
@@ -8344,6 +8368,19 @@ static void dplane_thread_loop(struct event *event)
 	if (!zdplane_info.dg_run)
 		return;

+#ifdef DEV_BUILD
+	/*
+	 * Test plug: hold new contexts on the incoming queue instead of
+	 * sending them to the first provider.
+	 */
+	install_plugged = atomic_load_explicit(&dplane_install_plugged, memory_order_relaxed);
+	if (install_plugged) {
+		if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
+			zlog_debug("%s: dplane install plugged, holding off new work", __func__);
+		return;
+	}
+#endif
+
 	/* Dequeue some incoming work from zebra (if any) onto the temporary
 	 * working list.
 	 */
diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h
index 5a2391d13d..d198e132b4 100644
--- a/zebra/zebra_dplane.h
+++ b/zebra/zebra_dplane.h
@@ -1427,6 +1427,12 @@ void zebra_dplane_pre_finish(void);
 void zebra_dplane_finish(void);
 void zebra_dplane_shutdown(void);

+#ifdef DEV_BUILD
+/* Test hooks: hold or release sending new contexts in dplane_thread_loop. */
+void zebra_dplane_install_plug(void);
+void zebra_dplane_install_unplug(void);
+#endif
+
 void zebra_dplane_startup_stage(ns_id_t ns_id,
 				enum zebra_dplane_startup_notifications spot);

diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index d8195a770d..44d3992cfe 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -4132,6 +4132,24 @@ DEFPY_HIDDEN(zebra_test_dplane_results_plug,

 	return CMD_SUCCESS;
 }
+
+DEFPY_HIDDEN(zebra_test_dplane_install_plug,
+	     zebra_test_dplane_install_plug_cmd,
+	     "[no] zebra test dplane disable install",
+	     NO_STR
+	     ZEBRA_STR
+	     "Test command\n"
+	     "Dataplane\n"
+	     "Plug dplane processing (prevent processing)\n"
+	     "Plug sending contexts to the dplane (prevent install)\n")
+{
+	if (no)
+		zebra_dplane_install_unplug();
+	else
+		zebra_dplane_install_plug();
+
+	return CMD_SUCCESS;
+}
 #endif

 /* Display Zebra MetaQ counters */
@@ -4408,6 +4426,7 @@ void zebra_vty_init(void)
 	install_element(VIEW_NODE, &zebra_test_metaq_plug_cmd);
 #ifdef DEV_BUILD
 	install_element(VIEW_NODE, &zebra_test_dplane_results_plug_cmd);
+	install_element(VIEW_NODE, &zebra_test_dplane_install_plug_cmd);
 #endif

 #ifdef HAVE_NETLINK