summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Stapp <mjs@voltanet.io>2019-06-11 13:47:15 -0400
committerMark Stapp <mjs@voltanet.io>2019-06-12 11:37:05 -0400
commite65fe398f6ba1a47a04793f7e25d6557ee705b7f (patch)
treed3d4ab2b74687c150852bc2d3c8dceebbdc8d91c
parentafbdfbb69bcf1d50cc07e59e91829866d766618f (diff)
bgpd: auto router-id should not change configured vpn RD/RT
A router-id change that isn't explicitly configured (a change from zebra, for example) should not replace a configured vpn RD/RT. Signed-off-by: Mark Stapp <mjs@voltanet.io>
-rw-r--r--bgpd/bgp_mplsvpn.c19
-rw-r--r--bgpd/bgp_mplsvpn.h3
-rw-r--r--bgpd/bgpd.c20
3 files changed, 32 insertions, 10 deletions
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 02eda7a430..65f1b64820 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);