diff options
| author | Chirag Shah <chirag@cumulusnetworks.com> | 2019-06-10 17:19:26 -0700 |
|---|---|---|
| committer | Chirag Shah <chirag@cumulusnetworks.com> | 2019-06-17 15:41:50 -0700 |
| commit | 48381346d7d8daddfacdcdf1980e35a216957d1e (patch) | |
| tree | 5e48f4cab60455d270832d97f24826e33739683c | |
| parent | 9ecf931b13cfb9a5aa35253acbdfc66bd2346607 (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.c | 72 | ||||
| -rw-r--r-- | bgpd/bgp_mplsvpn.h | 1 | ||||
| -rw-r--r-- | bgpd/bgp_vty.c | 2 |
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. */ } |
