diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 6eddd0e1e3..355bc93320 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -1488,7 +1488,8 @@ static void vpn_policy_routemap_update(struct bgp *bgp, const char *rmap_name) /* This API is used during router-id change, reflect VPNs * auto RD and RT values and readvertise routes to VPN table. */ -void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw) +void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw, + bool is_config) { afi_t afi; int debug; @@ -1536,6 +1537,20 @@ void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw) } } 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 */ @@ -1565,6 +1580,8 @@ void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw) = ecommunity_dup(ecom); } + +postchange: /* Update routes to VPN */ vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(), diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h index 1526a8111e..2a6c0e1708 100644 --- a/bgpd/bgp_mplsvpn.h +++ b/bgpd/bgp_mplsvpn.h @@ -264,6 +264,7 @@ extern void vpn_policy_routemap_event(const char *rmap_name); extern vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey); extern void vpn_leak_postchange_all(void); -extern void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw); +extern void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw, + bool is_config); #endif /* _QUAGGA_BGP_MPLSVPN_H */ diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 181b3d7066..8be6cec0c8 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -234,8 +234,11 @@ static int bgp_config_check(struct bgp *bgp, int config) return CHECK_FLAG(bgp->config, config); } -/* Set BGP router identifier. */ -static int bgp_router_id_set(struct bgp *bgp, const struct in_addr *id) +/* Set BGP router identifier; distinguish between explicit config and other + * cases. + */ +static int bgp_router_id_set(struct bgp *bgp, const struct in_addr *id, + bool is_config) { struct peer *peer; struct listnode *node, *nnode; @@ -247,7 +250,7 @@ static int bgp_router_id_set(struct bgp *bgp, const struct in_addr *id) if (is_evpn_enabled()) bgp_evpn_handle_router_id_update(bgp, TRUE); - vpn_handle_router_id_update(bgp, TRUE); + vpn_handle_router_id_update(bgp, TRUE, is_config); IPV4_ADDR_COPY(&bgp->router_id, id); @@ -266,7 +269,7 @@ static int bgp_router_id_set(struct bgp *bgp, const struct in_addr *id) if (is_evpn_enabled()) bgp_evpn_handle_router_id_update(bgp, FALSE); - vpn_handle_router_id_update(bgp, FALSE); + vpn_handle_router_id_update(bgp, FALSE, is_config); return 0; } @@ -300,7 +303,7 @@ void bgp_router_id_zebra_bump(vrf_id_t vrf_id, const struct prefix *router_id) if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("RID change : vrf %u, RTR ID %s", bgp->vrf_id, inet_ntoa(*addr)); - bgp_router_id_set(bgp, addr); + bgp_router_id_set(bgp, addr, FALSE); } } } @@ -320,7 +323,7 @@ void bgp_router_id_zebra_bump(vrf_id_t vrf_id, const struct prefix *router_id) if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("RID change : vrf %u, RTR ID %s", bgp->vrf_id, inet_ntoa(*addr)); - bgp_router_id_set(bgp, addr); + bgp_router_id_set(bgp, addr, FALSE); } } @@ -331,7 +334,8 @@ void bgp_router_id_zebra_bump(vrf_id_t vrf_id, const struct prefix *router_id) int bgp_router_id_static_set(struct bgp *bgp, struct in_addr id) { bgp->router_id_static = id; - bgp_router_id_set(bgp, id.s_addr ? &id : &bgp->router_id_zebra); + bgp_router_id_set(bgp, id.s_addr ? &id : &bgp->router_id_zebra, + TRUE /* is config */); return 0; } @@ -3185,7 +3189,7 @@ int bgp_get(struct bgp **bgp_val, as_t *as, const char *name, bgp = bgp_create(as, name, inst_type); if (bgp_option_check(BGP_OPT_NO_ZEBRA) && name) bgp->vrf_id = vrf_generate_id(); - bgp_router_id_set(bgp, &bgp->router_id_zebra); + bgp_router_id_set(bgp, &bgp->router_id_zebra, TRUE); bgp_address_init(bgp); bgp_tip_hash_init(bgp); bgp_scan_init(bgp);