bgpd: fix memory usage of vpn no retain

By default, bgpd stores all MPLS VPN SAFI prefixes unless the "no bgp
retain route-target all" option is used to store only prefixes that are
imported into local VRFs. The "no retain" option temporarily uses too
much memory, as all prefixes are stored in memory before the deletion of
non-imported prefixes is done.

Filter out non-imported prefixes before they are set into the BGP adj
RIB out.

Fixes: a486300b26 ("bgpd: implement retain route-target all behaviour")
Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
This commit is contained in:
Louis Scalbert 2023-06-06 12:46:21 +02:00
parent 59bbe85d4b
commit 3cc70b02a9
3 changed files with 60 additions and 0 deletions

View File

@ -2365,6 +2365,52 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */
bgp_dest_unlock_node(bn);
}
bool vpn_leak_to_vrf_no_retain_filter_check(struct bgp *from_bgp,
struct attr *attr, afi_t afi)
{
struct ecommunity *ecom_route_target = bgp_attr_get_ecommunity(attr);
int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
struct listnode *node;
const char *debugmsg;
struct bgp *to_bgp;
/* Loop over BGP instances */
for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, to_bgp)) {
if (!vpn_leak_from_vpn_active(to_bgp, afi, &debugmsg)) {
if (debug)
zlog_debug(
"%s: from vpn (%s) to vrf (%s) afi %s, skipping: %s",
__func__, from_bgp->name_pretty,
to_bgp->name_pretty, afi2str(afi),
debugmsg);
continue;
}
/* Check for intersection of route targets */
if (!ecommunity_include(
to_bgp->vpn_policy[afi]
.rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
ecom_route_target)) {
if (debug)
zlog_debug(
"%s: from vpn (%s) to vrf (%s) afi %s %s, skipping after no intersection of route targets",
__func__, from_bgp->name_pretty,
to_bgp->name_pretty, afi2str(afi),
ecommunity_str(ecom_route_target));
continue;
}
return false;
}
if (debug)
zlog_debug(
"%s: from vpn (%s) afi %s %s, no import - must be filtered",
__func__, from_bgp->name_pretty, afi2str(afi),
ecommunity_str(ecom_route_target));
return true;
}
void vpn_leak_to_vrf_update(struct bgp *from_bgp,
struct bgp_path_info *path_vpn,
struct prefix_rd *prd)

View File

@ -59,6 +59,10 @@ extern void vpn_leak_to_vrf_withdraw_all(struct bgp *to_bgp, afi_t afi);
extern void vpn_leak_to_vrf_update_all(struct bgp *to_bgp, struct bgp *from_bgp,
afi_t afi);
extern bool vpn_leak_to_vrf_no_retain_filter_check(struct bgp *from_bgp,
struct attr *attr,
afi_t afi);
extern void vpn_leak_to_vrf_update(struct bgp *from_bgp,
struct bgp_path_info *path_vpn,
struct prefix_rd *prd);

View File

@ -4169,6 +4169,16 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
goto filtered;
}
if ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_MPLS_VPN &&
bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT &&
!CHECK_FLAG(bgp->af_flags[afi][safi],
BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL) &&
vpn_leak_to_vrf_no_retain_filter_check(bgp, attr, afi)) {
reason =
"no import. Filtered by no bgp retain route-target all";
goto filtered;
}
/* If the route has Node Target Extended Communities, check
* if it's allowed to be installed locally.
*/