]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: fix syncs suppressed prefixes in VPN environments
authorPhilippe Guibert <philippe.guibert@6wind.com>
Mon, 3 Mar 2025 16:11:33 +0000 (17:11 +0100)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Mon, 3 Mar 2025 19:43:11 +0000 (20:43 +0100)
By using the summary-only option for aggregated prefixes, the suppressed
prefixes are however exported as VPN prefixes, whereas they should not.

> r1# show bgp vrf vrf1 ipv4
> [..]
>  *>  172.31.1.0/24    0.0.0.0                  0         32768 ?
>  s>  172.31.1.1/32    0.0.0.0                  0         32768 ?
>  s>  172.31.1.2/32    0.0.0.0                  0         32768 ?
>  s>  172.31.1.3/32    0.0.0.0                  0         32768 ?
> [..]
> r1#
>
> r1# show bgp ipv4 vpn
> [..]
>  *>  172.31.1.0/24    0.0.0.0@4<               0         32768 ?
>     UN=0.0.0.0 EC{52:100} label=101 type=bgp, subtype=5
>  *>  172.31.1.1/32    0.0.0.0@4<               0         32768 ?
>     UN=0.0.0.0 EC{52:100} label=101 type=bgp, subtype=5
>  *>  172.31.1.2/32    0.0.0.0@4<               0         32768 ?
>     UN=0.0.0.0 EC{52:100} label=101 type=bgp, subtype=5
>  *>  172.31.1.3/32    0.0.0.0@4<               0         32768 ?
>     UN=0.0.0.0 EC{52:100} label=101 type=bgp, subtype=5
> [..]
> r1#

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
bgpd/bgp_mplsvpn.c
bgpd/bgp_route.c

index 8057b3d56a15616077cf7a5589265d74a7f637a6..d1d4c5af68c180ec101ed93a13d2a7dc3c0b7f9f 100644 (file)
@@ -1696,6 +1696,14 @@ void vpn_leak_from_vrf_update(struct bgp *to_bgp,             /* to */
                return;
        }
 
+       /* Aggregate-address suppress check. */
+       if (bgp_path_suppressed(path_vrf)) {
+               if (debug)
+                       zlog_debug("%s: %s skipping: suppressed path will not be exported",
+                                  __func__, from_bgp->name);
+               return;
+       }
+
        /* shallow copy */
        static_attr = *path_vrf->attr;
 
index 910fa97493d1997fc312356d86cda640c92ecbaf..f1a6ad8c94ccdfee22bd09067f1b09df0999e34f 100644 (file)
@@ -8135,14 +8135,25 @@ void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
                        /* We are toggling suppression back. */
                        if (suppress) {
                                /* Suppress route if not suppressed already. */
-                               if (aggr_suppress_path(aggregate, pi))
+                               if (aggr_suppress_path(aggregate, pi)) {
                                        bgp_process(bgp, dest, pi, afi, safi);
+                                       if (SAFI_UNICAST == safi &&
+                                           (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
+                                            bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT))
+                                               vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp,
+                                                                          pi);
+                               }
                                continue;
                        }
 
                        /* Install route if there is no more suppression. */
-                       if (aggr_unsuppress_path(aggregate, pi))
+                       if (aggr_unsuppress_path(aggregate, pi)) {
                                bgp_process(bgp, dest, pi, afi, safi);
+                               if (SAFI_UNICAST == safi &&
+                                   (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
+                                    bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT))
+                                       vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
+                       }
                }
        }
        bgp_dest_unlock_node(top);
@@ -8273,8 +8284,14 @@ bool bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
                         */
                        if (aggregate->summary_only
                            && AGGREGATE_MED_VALID(aggregate)) {
-                               if (aggr_suppress_path(aggregate, pi))
+                               if (aggr_suppress_path(aggregate, pi)) {
                                        bgp_process(bgp, dest, pi, afi, safi);
+                                       if (SAFI_UNICAST == safi &&
+                                           (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
+                                            bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT))
+                                               vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp,
+                                                                          pi);
+                               }
                        }
 
                        /*
@@ -8289,8 +8306,14 @@ bool bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
                        if (aggregate->suppress_map_name
                            && AGGREGATE_MED_VALID(aggregate)
                            && aggr_suppress_map_test(bgp, aggregate, pi)) {
-                               if (aggr_suppress_path(aggregate, pi))
+                               if (aggr_suppress_path(aggregate, pi)) {
                                        bgp_process(bgp, dest, pi, afi, safi);
+                                       if (SAFI_UNICAST == safi &&
+                                           (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
+                                            bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT))
+                                               vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp,
+                                                                          pi);
+                               }
                        }
 
                        aggregate->count++;
@@ -8438,8 +8461,13 @@ void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
                         */
                        if (pi->extra && pi->extra->aggr_suppressors &&
                            listcount(pi->extra->aggr_suppressors)) {
-                               if (aggr_unsuppress_path(aggregate, pi))
+                               if (aggr_unsuppress_path(aggregate, pi)) {
                                        bgp_process(bgp, dest, pi, afi, safi);
+                                       if (SAFI_UNICAST == safi &&
+                                           (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
+                                            bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT))
+                                               vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
+                               }
                        }
 
                        if (aggregate->count > 0)
@@ -8645,13 +8673,21 @@ static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
                return;
 
        if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
-               if (aggr_unsuppress_path(aggregate, pi))
+               if (aggr_unsuppress_path(aggregate, pi)) {
                        bgp_process(bgp, pi->net, pi, afi, safi);
+                       if (SAFI_UNICAST == safi && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
+                                                    bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT))
+                               vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
+               }
 
        if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
            && aggr_suppress_map_test(bgp, aggregate, pi))
-               if (aggr_unsuppress_path(aggregate, pi))
+               if (aggr_unsuppress_path(aggregate, pi)) {
                        bgp_process(bgp, pi->net, pi, afi, safi);
+                       if (SAFI_UNICAST == safi && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF ||
+                                                    bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT))
+                               vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi);
+               }
 
        /*
         * This must be called after `summary`, `suppress-map` check to avoid