]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: cleanup un-imported vpn prefix if no retain set
authorLouis Scalbert <louis.scalbert@6wind.com>
Wed, 7 Jun 2023 10:46:30 +0000 (12:46 +0200)
committerLouis Scalbert <louis.scalbert@6wind.com>
Fri, 16 Jun 2023 12:18:25 +0000 (14:18 +0200)
After some VRF imports are removed and "no bgp retain route-target all"
is set, prefixes that are not imported anymore remain in the BGP table.

Parse the BGP table and remove un-imported prefixes in such a case.

Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
bgpd/bgp_mplsvpn.c
bgpd/bgp_mplsvpn.h
bgpd/bgp_vty.c

index c6c1ef82cd2a4dbce3d6cefcaae139c8695348a1..ea82591cedbcdb97cdbf2160883348031d559a41 100644 (file)
@@ -2551,6 +2551,51 @@ void vpn_leak_to_vrf_withdraw_all(struct bgp *to_bgp, afi_t afi)
        }
 }
 
+void vpn_leak_no_retain(struct bgp *to_bgp, struct bgp *vpn_from, afi_t afi)
+{
+       struct bgp_dest *pdest;
+       safi_t safi = SAFI_MPLS_VPN;
+
+       assert(vpn_from);
+
+       /*
+        * Walk vpn table
+        */
+       for (pdest = bgp_table_top(vpn_from->rib[afi][safi]); pdest;
+            pdest = bgp_route_next(pdest)) {
+               struct bgp_table *table;
+               struct bgp_dest *bn;
+               struct bgp_path_info *bpi;
+
+               /* This is the per-RD table of prefixes */
+               table = bgp_dest_get_bgp_table_info(pdest);
+
+               if (!table)
+                       continue;
+
+               for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
+                       for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;
+                            bpi = bpi->next) {
+
+                               if (bpi->extra &&
+                                   bpi->extra->bgp_orig == to_bgp)
+                                       continue;
+
+                               if (bpi->sub_type != BGP_ROUTE_NORMAL)
+                                       continue;
+
+                               if (!vpn_leak_to_vrf_no_retain_filter_check(
+                                           vpn_from, bpi->attr, afi))
+                                       /* do not filter */
+                                       continue;
+
+                               bgp_unlink_nexthop(bpi);
+                               bgp_rib_remove(bn, bpi, bpi->peer, afi, safi);
+                       }
+               }
+       }
+}
+
 void vpn_leak_to_vrf_update_all(struct bgp *to_bgp, struct bgp *vpn_from,
                                afi_t afi)
 {
@@ -3755,6 +3800,7 @@ void vpn_leak_postchange_all(void)
  */
 void bgp_vpn_leak_unimport(struct bgp *from_bgp)
 {
+       struct bgp *bgp_default = bgp_get_default();
        struct bgp *to_bgp;
        const char *tmp_name;
        char *vname;
@@ -3833,6 +3879,17 @@ void bgp_vpn_leak_unimport(struct bgp *from_bgp)
                                }
                        }
                }
+
+               if (bgp_default &&
+                   !CHECK_FLAG(bgp_default->af_flags[afi][SAFI_MPLS_VPN],
+                               BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL)) {
+                       /* 'from_bgp' instance will be deleted
+                        * so force to unset importation to update VPN labels
+                        */
+                       UNSET_FLAG(from_bgp->af_flags[afi][SAFI_UNICAST],
+                                  BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT);
+                       vpn_leak_no_retain(from_bgp, bgp_default, afi);
+               }
        }
        return;
 }
index 5d9c9f6b6b8d1c24a1a26880e51245197d8bf641..23458caf5313d3c7f5ab7a6fd28f393fa0e64f29 100644 (file)
@@ -56,6 +56,9 @@ extern void vpn_leak_from_vrf_update_all(struct bgp *to_bgp,
 
 extern void vpn_leak_to_vrf_withdraw_all(struct bgp *to_bgp, afi_t afi);
 
+extern void vpn_leak_no_retain(struct bgp *to_bgp, struct bgp *vpn_from,
+                              afi_t afi);
+
 extern void vpn_leak_to_vrf_update_all(struct bgp *to_bgp, struct bgp *from_bgp,
                                       afi_t afi);
 
index 6d7b745713a3d424bcd790c2f98f6f8e97dd3935..7b75c96e2f890234e860919784e319046f8615c8 100644 (file)
@@ -9954,6 +9954,7 @@ DEFPY (bgp_imexport_vpn,
        bool yes = true;
        int flag;
        enum vpn_policy_direction dir;
+       struct bgp *bgp_default = bgp_get_default();
 
        if (argv_find(argv, argc, "no", &idx))
                yes = false;
@@ -9989,14 +9990,18 @@ DEFPY (bgp_imexport_vpn,
                SET_FLAG(bgp->af_flags[afi][safi], flag);
                if (!previous_state) {
                        /* trigger export current vrf */
-                       vpn_leak_postchange(dir, afi, bgp_get_default(), bgp);
+                       vpn_leak_postchange(dir, afi, bgp_default, bgp);
                }
        } else {
                if (previous_state) {
                        /* trigger un-export current vrf */
-                       vpn_leak_prechange(dir, afi, bgp_get_default(), bgp);
+                       vpn_leak_prechange(dir, afi, bgp_default, bgp);
                }
                UNSET_FLAG(bgp->af_flags[afi][safi], flag);
+               if (previous_state && bgp_default &&
+                   !CHECK_FLAG(bgp_default->af_flags[afi][SAFI_MPLS_VPN],
+                               BGP_VPNVX_RETAIN_ROUTE_TARGET_ALL))
+                       vpn_leak_no_retain(bgp, bgp_default, afi);
        }
 
        hook_call(bgp_snmp_init_stats, bgp);