Commit b18d1e53dc for frr

commit b18d1e53dc5cfd6d7f5205b2063a4e2079b37bd6
Author: Rajasekar Raja <rajasekarr@nvidia.com>
Date:   Tue Oct 6 11:55:07 2026 -0700

    bgpd: do not allocate path extra for unlabeled received routes

    Since commit b80499339406 ("bgpd: get rid of has_valid_label in
    bgp_update()"), merged with PR #15434 and first released in 10.1,
    bgp_update() allocates a struct bgp_path_info_extra for every newly
    received path, only to hang the path's labels off it. Plain IPv4 and
    IPv6 unicast routes carry no labels, so bgp_labels_intern() returns
    NULL and each path pays for an extra structure that holds nothing.
    Before that change the allocation was guarded by has_valid_label, and
    an unlabeled path normally had no extra at all.

    The cost grows with the number of received paths, not with best paths
    or FIB size: close to 100 bytes per path once malloc overhead is
    counted, or roughly 90 MiB for every million paths.

    In our internal scale test, a router receiving million paths accounted
    for most of an observed 12% increase in bgpd memory after upgrading
    from 10.0.3.

    Only allocate the extra when the route carries labels. Code that
    reads path labels already copes with a missing extra, as it had to
    before 10.1.

    Fixes: b80499339406 ("bgpd: get rid of has_valid_label in bgp_update()")

    Signed-off-by: Rajasekar Raja <rajasekarr@nvidia.com>

diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index ea764b1e85..09af54aed3 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -6924,8 +6924,10 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
 	}

 	/* Update MPLS label */
-	bgp_path_info_extra_get(new);
-	new->extra->labels = bgp_labels_intern(&bgp_labels);
+	if (bgp_labels.num_labels) {
+		bgp_path_info_extra_get(new);
+		new->extra->labels = bgp_labels_intern(&bgp_labels);
+	}

 	/* Propagate fields written to the rmap-transient extra
 	 * (e.g. "set sr-te color") onto the real path.