summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis Scalbert <louis.scalbert@6wind.com>2023-06-07 12:46:30 +0200
committerLouis Scalbert <louis.scalbert@6wind.com>2023-06-16 14:18:25 +0200
commitaf79038c4be1b5cec7da9f67b81280d6f14e2479 (patch)
treebac4d8b0738cc10c4cad83e8c8f073420f4b2335
parent3cc70b02a9e19a364f3144031f27f3e50f128c0c (diff)
bgpd: cleanup un-imported vpn prefix if no retain set
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>
-rw-r--r--bgpd/bgp_mplsvpn.c57
-rw-r--r--bgpd/bgp_mplsvpn.h3
-rw-r--r--bgpd/bgp_vty.c9
3 files changed, 67 insertions, 2 deletions
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index c6c1ef82cd..ea82591ced 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -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;
}
diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h
index 5d9c9f6b6b..23458caf53 100644
--- a/bgpd/bgp_mplsvpn.h
+++ b/bgpd/bgp_mplsvpn.h
@@ -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);
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 6d7b745713..7b75c96e2f 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -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);