if (bpi) {
bool labelssame = labels_same(bpi, label, num_labels);
+ if (CHECK_FLAG(source_bpi->flags, BGP_PATH_REMOVED)
+ && CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
+ if (debug) {
+ zlog_debug(
+ "%s: ->%s(s_flags: 0x%x b_flags: 0x%x): %pFX: Found route, being removed, not leaking",
+ __func__, bgp->name_pretty,
+ source_bpi->flags, bpi->flags, p);
+ }
+ return NULL;
+ }
+
if (attrhash_cmp(bpi->attr, new_attr) && labelssame
&& !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
return bpi;
}
+ if (CHECK_FLAG(source_bpi->flags, BGP_PATH_REMOVED)) {
+ if (debug) {
+ zlog_debug(
+ "%s: ->%s(s_flags: 0x%x): %pFX: New route, being removed, not leaking",
+ __func__, bgp->name_pretty,
+ source_bpi->flags, p);
+ }
+ return NULL;
+ }
+
new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_IMPORTED, 0,
bgp->peer_self, new_attr, bn);
if (debug)
zlog_debug("%s: deleting it",
__func__);
+ /* withdraw from leak-to vrfs as well */
+ vpn_leak_to_vrf_withdraw(bgp_vpn, bpi);
bgp_aggregate_decrement(
bgp_vpn,
bgp_dest_get_prefix(bn), bpi,
if (!ecom_intersect(
bgp_vrf->vpn_policy[afi].rtlist[BGP_VPN_POLICY_DIR_FROMVPN],
path_vpn->attr->ecommunity)) {
-
+ if (debug)
+ zlog_debug(
+ "from vpn to vrf %s, skipping after no intersection of route targets",
+ bgp_vrf->name_pretty);
return;
}
struct bgp *bgp_vpn, /* from */
afi_t afi)
{
- struct prefix_rd prd;
struct bgp_dest *pdest;
safi_t safi = SAFI_MPLS_VPN;
*/
for (pdest = bgp_table_top(bgp_vpn->rib[afi][safi]); pdest;
pdest = bgp_route_next(pdest)) {
- const struct prefix *p = bgp_dest_get_prefix(pdest);
struct bgp_table *table;
struct bgp_dest *bn;
struct bgp_path_info *bpi;
- memset(&prd, 0, sizeof(prd));
- prd.family = AF_UNSPEC;
- prd.prefixlen = 64;
- memcpy(prd.val, &p->u.val, 8);
-
/* This is the per-RD table of prefixes */
table = bgp_dest_get_bgp_table_info(pdest);
bool is_config)
{
afi_t afi;
- int debug;
+ int debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF)
+ | BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
char *vname;
const char *export_name;
char buf[RD_ADDRSTRLEN];
struct ecommunity *ecom;
vpn_policy_direction_t idir, edir;
+ /*
+ * Router-id change that is not explicitly configured
+ * (a change from zebra, frr restart for example)
+ * should not replace a configured vpn RD/RT.
+ */
+ if (!is_config) {
+ if (debug)
+ zlog_debug("%s: skipping non explicit router-id change",
+ __func__);
+ return;
+ }
+
if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
&& bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
return;
export_name = bgp->name ? bgp->name : VRF_DEFAULT_NAME;
- debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
- BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
-
idir = BGP_VPN_POLICY_DIR_FROMVPN;
edir = BGP_VPN_POLICY_DIR_TOVPN;
if (!bgp_import)
continue;
- ecommunity_del_val(bgp_import->vpn_policy[afi].
- rtlist[idir],
+ ecommunity_del_val(
+ bgp_import->vpn_policy[afi]
+ .rtlist[idir],
(struct ecommunity_val *)ecom->val);
-
}
} else {
- /*
- * Router-id changes that are not explicit config
- * changes should not replace configured RD/RT.
- */
- if (!is_config) {
- if (CHECK_FLAG(bgp->vpn_policy[afi].flags,
- BGP_VPN_POLICY_TOVPN_RD_SET)) {
- if (debug)
- zlog_debug("%s: auto router-id change skipped",
- __func__);
- goto postchange;
- }
- }
-
/* New router-id derive auto RD and RT and export
* to VPN
*/
else
bgp_import->vpn_policy[afi].rtlist[idir]
= ecommunity_dup(ecom);
-
}
- postchange:
/* Update routes to VPN */
vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN,
afi, bgp_get_default(),