]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: fix memory usage of vpn no retain
authorLouis Scalbert <louis.scalbert@6wind.com>
Tue, 6 Jun 2023 10:46:21 +0000 (12:46 +0200)
committerLouis Scalbert <louis.scalbert@6wind.com>
Fri, 16 Jun 2023 12:18:25 +0000 (14:18 +0200)
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>
bgpd/bgp_mplsvpn.c
bgpd/bgp_mplsvpn.h
bgpd/bgp_route.c

index 447a21b5eaf73a38c7b3270d35120e029cfe5360..c6c1ef82cd2a4dbce3d6cefcaae139c8695348a1 100644 (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)
index 3922fbcb116d5588149a782322d46fc05f57d51e..5d9c9f6b6b8d1c24a1a26880e51245197d8bf641 100644 (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);
index 155aebc5f94a1a03f93de6679c971bcd893952db..5285a221e2735aaef4da25c996fe97a407799251 100644 (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.
         */