Commit 14597ebb3f for frr

commit 14597ebb3fefe2d1b9738f02d03840d086015362
Author: Minghan Chan <mhchann082@gmail.com>
Date:   Fri Nov 6 08:22:23 2026 +0800

    bfdd: walk the reflectors when no sbfd reflector deletes a range

    "no sbfd reflector START END" looked up every value from START to END
    with an int32_t counter, which cannot reach an END above 2147483647.
    Incrementing it past that is undefined behavior. Built with -O0 the
    loop never ends; gcc 11 at -O2 widens the counter and stops after 2^32
    lookups, which kept bfdd busy for 30 seconds in testing. Either way
    bfdd serves neither vty nor BFD packets meanwhile, and even a range
    that ends lower costs one hash lookup per value.

    Walk the configured reflectors and free those in the range instead.
    hash_iterate() saves the next bucket before calling back, so freeing
    the current one is safe, as sbfd_reflector_flush() already relies on.

    Fixes #24202

    Signed-off-by: Minghan Chan <mhchann082@gmail.com>

diff --git a/bfdd/bfdd_cli.c b/bfdd/bfdd_cli.c
index d2b50f5c55..e0d5283877 100644
--- a/bfdd/bfdd_cli.c
+++ b/bfdd/bfdd_cli.c
@@ -1386,6 +1386,24 @@ DEFPY(
 	return CMD_SUCCESS;
 }

+struct sbfd_reflector_range {
+	uint32_t from;
+	uint32_t to;
+};
+
+static void _sbfd_reflector_free_range(struct hash_bucket *hb, void *arg)
+{
+	struct sbfd_reflector *sr = hb->data;
+	struct sbfd_reflector_range *range = arg;
+
+	if (sr->discr < range->from || sr->discr > range->to)
+		return;
+
+	// notify bfdsyncd
+	//bfd_fpm_sbfd_reflector_sendmsg(sr, false);
+	sbfd_reflector_free(sr->discr);
+}
+
 DEFPY(
 	no_sbfd_reflector, no_sbfd_reflector_cmd,
 	"no sbfd reflector (0-4294967295)$start_discr [(0-4294967295)$end_discr]",
@@ -1396,7 +1414,7 @@ DEFPY(
 	"end discriminator\n")
 {
 	struct sbfd_reflector *sr;
-	int32_t i;
+	struct sbfd_reflector_range range;

 	if (end_discr == 0) {
 		if (start_discr == 0) {
@@ -1420,14 +1438,10 @@ DEFPY(
 			return CMD_WARNING_CONFIG_FAILED;
 		}

-		for (i = start_discr; i <= end_discr; i++) {
-			sr = sbfd_discr_lookup(i);
-			if (sr) {
-				// notify bfdsyncd
-				//bfd_fpm_sbfd_reflector_sendmsg(sr, false);
-				sbfd_reflector_free(i);
-			}
-		}
+		/* Walk the reflectors, not the range, which can span 2^32 values. */
+		range.from = start_discr;
+		range.to = end_discr;
+		sbfd_discr_iterate(_sbfd_reflector_free_range, &range);
 	}

 	return CMD_SUCCESS;