Commit 55a639a9f3 for frr

commit 55a639a9f3ddaff97d266b63d4b7eec2a023e022
Author: Chenlang Li <Cc1580155hsg@163.com>
Date:   Fri Oct 23 22:32:11 2026 +0800

    eigrpd: fix uint32_t overflow in eigrp_calculate_total_metrics

    When an inbound distribute-list denies a route, eigrp_update_receive()
    and eigrp_update_send_GR_part() set the route's delay field to
    EIGRP_MAX_METRIC (0xffffffff).  eigrp_calculate_total_metrics() then
    adds the interface delay to that value; because both operands are
    uint32_t the addition wraps in 32-bit arithmetic before the result is
    widened into the uint64_t temp_delay.  The wrapped value falls just
    below the feasibility-condition threshold, so eigrp_topology_update_
    node_flags() classifies the route as neither a successor nor a feasible
    successor.  eigrp_get_fsm_event() then dispatches EIGRP_FSM_EVENT_NQ_FCN
    and eigrp_fsm_event_nq_fcn() asserts because eigrp_topology_get_
    successor() returns NULL.

    Fix by returning EIGRP_METRIC_MAX early when the reported delay is
    already EIGRP_MAX_METRIC, matching the identical guard that already
    exists in eigrp_calculate_metrics().

    Fixes: #23836
    Signed-off-by: Chenlang Li <Cc1580155hsg@163.com>

diff --git a/eigrpd/eigrp_metric.c b/eigrpd/eigrp_metric.c
index 20470825a8..2ef877a42e 100644
--- a/eigrpd/eigrp_metric.c
+++ b/eigrpd/eigrp_metric.c
@@ -105,6 +105,19 @@ eigrp_calculate_total_metrics(struct eigrp *eigrp,
 	eigrp_bandwidth_t bw;

 	entry->total_metric = entry->reported_metric;
+
+	/*
+	 * An inbound filter marks a route unreachable by setting delay to
+	 * EIGRP_MAX_METRIC (0xffffffff).  Both fields are uint32_t, so adding
+	 * the interface delay wraps in 32-bit arithmetic before the result is
+	 * widened into temp_delay, placing the total metric just below the
+	 * feasibility-condition threshold and causing DUAL to assert when it
+	 * finds no successor.  Short-circuit here to match the same guard in
+	 * eigrp_calculate_metrics().
+	 */
+	if (entry->total_metric.delay == EIGRP_MAX_METRIC)
+		return EIGRP_METRIC_MAX;
+
 	temp_delay = entry->total_metric.delay
 		     + eigrp_delay_to_scaled(ei->params->delay);