summaryrefslogtreecommitdiff
path: root/bgpd
diff options
context:
space:
mode:
authorRuss White <russ@riw.us>2019-04-02 11:59:35 -0400
committerGitHub <noreply@github.com>2019-04-02 11:59:35 -0400
commitfebe440bc46fe0dfe38ba329fbfef318eef89710 (patch)
treea682be17dab8cbee9b633d821c558e3889bb6181 /bgpd
parentaee1decce237950bd75730c50d764bd70cfc962b (diff)
parent636f76088d1148711f3cdbffd2b1c807b773d664 (diff)
Merge pull request #3931 from chiragshah6/evpn_dev1
bgpd: vrf route-leak router-id change reflect to vpn auto rd rt
Diffstat (limited to 'bgpd')
-rw-r--r--bgpd/bgp_mplsvpn.c119
-rw-r--r--bgpd/bgp_mplsvpn.h1
-rw-r--r--bgpd/bgpd.c4
3 files changed, 124 insertions, 0 deletions
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index d211f1afff..4c4659ad54 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -1488,6 +1488,97 @@ 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)
+{
+ afi_t afi;
+ int debug;
+ char *vname;
+ const char *export_name;
+ char buf[RD_ADDRSTRLEN];
+ struct bgp *bgp_import;
+ struct listnode *node;
+ struct ecommunity *ecom;
+ vpn_policy_direction_t idir, edir;
+
+ 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;
+
+ for (afi = 0; afi < AFI_MAX; ++afi) {
+ if (!vpn_leak_to_vpn_active(bgp, afi, NULL))
+ continue;
+
+ if (withdraw) {
+ vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN,
+ afi, bgp_get_default(), bgp);
+ if (debug)
+ zlog_debug("%s: %s after to_vpn vpn_leak_prechange",
+ __func__, export_name);
+
+ /* Remove import RT from VRFs */
+ ecom = bgp->vpn_policy[afi].rtlist[edir];
+ for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].
+ export_vrf, node, vname)) {
+ bgp_import = bgp_lookup_by_name(vname);
+ if (!bgp_import)
+ continue;
+
+ ecommunity_del_val(bgp_import->vpn_policy[afi].
+ rtlist[idir],
+ (struct ecommunity_val *)ecom->val);
+
+ }
+ } else {
+ /* New router-id derive auto RD and RT and export
+ * to VPN
+ */
+ form_auto_rd(bgp->router_id, bgp->vrf_rd_id,
+ &bgp->vrf_prd_auto);
+ bgp->vpn_policy[afi].tovpn_rd = bgp->vrf_prd_auto;
+ prefix_rd2str(&bgp->vpn_policy[afi].tovpn_rd, buf,
+ sizeof(buf));
+ bgp->vpn_policy[afi].rtlist[edir] =
+ ecommunity_str2com(buf,
+ ECOMMUNITY_ROUTE_TARGET, 0);
+
+ /* Update import_vrf rt_list */
+ ecom = bgp->vpn_policy[afi].rtlist[edir];
+ for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].
+ export_vrf, node, vname)) {
+ bgp_import = bgp_lookup_by_name(vname);
+ if (!bgp_import)
+ continue;
+ if (bgp_import->vpn_policy[afi].rtlist[idir])
+ bgp_import->vpn_policy[afi].rtlist[idir]
+ = ecommunity_merge(
+ bgp_import->vpn_policy[afi]
+ .rtlist[idir], ecom);
+ else
+ bgp_import->vpn_policy[afi].rtlist[idir]
+ = ecommunity_dup(ecom);
+
+ }
+ /* Update routes to VPN */
+ vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN,
+ afi, bgp_get_default(),
+ bgp);
+ if (debug)
+ zlog_debug("%s: %s after to_vpn vpn_leak_postchange",
+ __func__, export_name);
+ }
+ }
+}
+
void vpn_policy_routemap_event(const char *rmap_name)
{
int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
@@ -1513,11 +1604,15 @@ void vrf_import_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
char buf[1000];
struct ecommunity *ecom;
bool first_export = false;
+ int debug;
export_name = to_bgp->name ? to_bgp->name : VRF_DEFAULT_NAME;
idir = BGP_VPN_POLICY_DIR_FROMVPN;
edir = BGP_VPN_POLICY_DIR_TOVPN;
+ debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
+ BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
+
/*
* Cross-ref both VRFs. Also, note if this is the first time
* any VRF is importing from "import_vrf".
@@ -1560,6 +1655,23 @@ void vrf_import_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
to_bgp->vpn_policy[afi].rtlist[idir] = ecommunity_dup(ecom);
SET_FLAG(to_bgp->af_flags[afi][safi], BGP_CONFIG_VRF_TO_VRF_IMPORT);
+ if (debug) {
+ const char *from_name;
+
+ from_name = from_bgp->name ? from_bgp->name :
+ VRF_DEFAULT_NAME;
+ zlog_debug("%s from %s to %s first_export %u import-rt %s export-rt %s",
+ __func__, from_name, export_name, first_export,
+ to_bgp->vpn_policy[afi].rtlist[idir] ?
+ (ecommunity_ecom2str(to_bgp->vpn_policy[afi].
+ rtlist[idir],
+ ECOMMUNITY_FORMAT_ROUTE_MAP, 0)) : " ",
+ to_bgp->vpn_policy[afi].rtlist[edir] ?
+ (ecommunity_ecom2str(to_bgp->vpn_policy[afi].
+ rtlist[edir],
+ ECOMMUNITY_FORMAT_ROUTE_MAP, 0)) : " ");
+ }
+
/* Does "import_vrf" first need to export its routes or that
* is already done and we just need to import those routes
* from the global table?
@@ -1578,12 +1690,16 @@ void vrf_unimport_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
char *vname;
struct ecommunity *ecom;
struct listnode *node;
+ int debug;
export_name = to_bgp->name ? to_bgp->name : VRF_DEFAULT_NAME;
tmp_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME;
idir = BGP_VPN_POLICY_DIR_FROMVPN;
edir = BGP_VPN_POLICY_DIR_TOVPN;
+ debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
+ BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
+
/* Were we importing from "import_vrf"? */
for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi].import_vrf, node,
vname)) {
@@ -1601,6 +1717,9 @@ void vrf_unimport_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
if (!vname)
return;
+ if (debug)
+ zlog_debug("%s from %s to %s", __func__, tmp_name, export_name);
+
/* Remove "import_vrf" from our import list. */
listnode_delete(to_bgp->vpn_policy[afi].import_vrf, vname);
XFREE(MTYPE_TMP, vname);
diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h
index 2ef9570aac..1526a8111e 100644
--- a/bgpd/bgp_mplsvpn.h
+++ b/bgpd/bgp_mplsvpn.h
@@ -264,5 +264,6 @@ 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);
#endif /* _QUAGGA_BGP_MPLSVPN_H */
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 54e8f5f369..298418b113 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -253,6 +253,8 @@ 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);
+
IPV4_ADDR_COPY(&bgp->router_id, id);
/* Set all peer's local identifier with this value. */
@@ -270,6 +272,8 @@ 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);
+
return 0;
}