From: Louis Scalbert Date: Tue, 6 Jun 2023 10:46:21 +0000 (+0200) Subject: bgpd: fix memory usage of vpn no retain X-Git-Tag: base_9.1~346^2~11 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=3cc70b02a9e19a364f3144031f27f3e50f128c0c;p=matthieu%2Ffrr.git 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 --- diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 447a21b5ea..c6c1ef82cd 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -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) diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h index 3922fbcb11..5d9c9f6b6b 100644 --- a/bgpd/bgp_mplsvpn.h +++ b/bgpd/bgp_mplsvpn.h @@ -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); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 155aebc5f9..5285a221e2 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -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. */