summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChirag Shah <chirag@cumulusnetworks.com>2019-06-10 17:19:26 -0700
committerChirag Shah <chirag@cumulusnetworks.com>2019-06-17 15:41:50 -0700
commit48381346d7d8daddfacdcdf1980e35a216957d1e (patch)
tree5e48f4cab60455d270832d97f24826e33739683c
parent9ecf931b13cfb9a5aa35253acbdfc66bd2346607 (diff)
bgpd: router bgp export leaked vpn routes
two bgp vrf instance has vrf route leak configured, when a source vrf x is deleted, its leaked routes are cleaned up from the destination and vpn table. With this change when a source bgp instance is reconfigured, export its routes back to destination vrfs where it is configured as leak. Ticket:CM-20534 CM-24484 Reviewed By: Testing Done: configure vrf leak between two vrf intances, delete and readd source vrf and checked its routes exported to vpn table and leaked vrfs table. Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
-rw-r--r--bgpd/bgp_mplsvpn.c72
-rw-r--r--bgpd/bgp_mplsvpn.h1
-rw-r--r--bgpd/bgp_vty.c2
3 files changed, 75 insertions, 0 deletions
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index e540815928..1156810510 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -2598,3 +2598,75 @@ int bgp_vpn_leak_unimport(struct bgp *from_bgp, struct vty *vty)
}
return 0;
}
+
+/* When a router bgp is configured, there could be a bgp vrf
+ * instance importing routes from this newly configured
+ * bgp vrf instance. Export routes from configured
+ * bgp vrf to VPN.
+ * VRF Y has import from bgp vrf x,
+ * when a bgp vrf x instance is created, export its routes
+ * to VRF Y instance.
+ */
+void bgp_vpn_leak_export(struct bgp *from_bgp)
+{
+ afi_t afi;
+ const char *export_name;
+ char *vname;
+ struct listnode *node, *next;
+ struct ecommunity *ecom;
+ vpn_policy_direction_t idir, edir;
+ safi_t safi = SAFI_UNICAST;
+ struct bgp *to_bgp;
+ int debug;
+
+ 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;
+
+ export_name = (from_bgp->name ? XSTRDUP(MTYPE_TMP, from_bgp->name)
+ : XSTRDUP(MTYPE_TMP, VRF_DEFAULT_NAME));
+
+ for (afi = 0; afi < AFI_MAX; ++afi) {
+ /* vrf leak is for IPv4 and IPv6 Unicast only */
+ if (afi != AFI_IP && afi != AFI_IP6)
+ continue;
+
+ for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, to_bgp)) {
+ if (from_bgp == to_bgp)
+ continue;
+
+ /* bgp instance has import list, check to see if newly
+ * configured bgp instance is the list.
+ */
+ struct vpn_policy *to_vpolicy;
+
+ to_vpolicy = &(to_bgp->vpn_policy[afi]);
+ for (ALL_LIST_ELEMENTS_RO(to_vpolicy->import_vrf,
+ node, vname)) {
+ if (strcmp(vname, export_name) != 0)
+ continue;
+
+ if (debug)
+ zlog_debug("%s: found from_bgp %s in to_bgp %s import list, import routes.",
+ __func__,
+ export_name, to_bgp->name_pretty);
+
+ ecom = from_bgp->vpn_policy[afi].rtlist[edir];
+ /* remove import rt, it will be readded
+ * as part of import from vrf.
+ */
+ if (ecom)
+ ecommunity_del_val(
+ to_vpolicy->rtlist[idir],
+ (struct ecommunity_val *)
+ ecom->val);
+ vrf_import_from_vrf(to_bgp, from_bgp,
+ afi, safi);
+ break;
+
+ }
+ }
+ }
+}
diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h
index 154eb2be06..3234f7fc9d 100644
--- a/bgpd/bgp_mplsvpn.h
+++ b/bgpd/bgp_mplsvpn.h
@@ -267,5 +267,6 @@ extern void vpn_leak_postchange_all(void);
extern void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw,
bool is_config);
extern int bgp_vpn_leak_unimport(struct bgp *from_bgp, struct vty *vty);
+extern void bgp_vpn_leak_export(struct bgp *from_bgp);
#endif /* _QUAGGA_BGP_MPLSVPN_H */
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 2e836fb40f..bde4b52af5 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -1003,6 +1003,8 @@ DEFUN_NOSH (router_bgp,
if (is_new_bgp && inst_type == BGP_INSTANCE_TYPE_DEFAULT)
vpn_leak_postchange_all();
+ if (inst_type == BGP_INSTANCE_TYPE_VRF)
+ bgp_vpn_leak_export(bgp);
/* Pending: handle when user tries to change a view to vrf n vv.
*/
}