diff options
| author | Russ White <russ@riw.us> | 2019-04-02 11:59:35 -0400 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-04-02 11:59:35 -0400 | 
| commit | febe440bc46fe0dfe38ba329fbfef318eef89710 (patch) | |
| tree | a682be17dab8cbee9b633d821c558e3889bb6181 /bgpd | |
| parent | aee1decce237950bd75730c50d764bd70cfc962b (diff) | |
| parent | 636f76088d1148711f3cdbffd2b1c807b773d664 (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.c | 119 | ||||
| -rw-r--r-- | bgpd/bgp_mplsvpn.h | 1 | ||||
| -rw-r--r-- | bgpd/bgpd.c | 4 | 
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;  }  | 
