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.