mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-14 22:10:19 +00:00
Merge pull request #3931 from chiragshah6/evpn_dev1
bgpd: vrf route-leak router-id change reflect to vpn auto rd rt
This commit is contained in:
commit
febe440bc4
@ -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)
|
void vpn_policy_routemap_event(const char *rmap_name)
|
||||||
{
|
{
|
||||||
int debug = BGP_DEBUG(vpn, VPN_LEAK_RMAP_EVENT);
|
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];
|
char buf[1000];
|
||||||
struct ecommunity *ecom;
|
struct ecommunity *ecom;
|
||||||
bool first_export = false;
|
bool first_export = false;
|
||||||
|
int debug;
|
||||||
|
|
||||||
export_name = to_bgp->name ? to_bgp->name : VRF_DEFAULT_NAME;
|
export_name = to_bgp->name ? to_bgp->name : VRF_DEFAULT_NAME;
|
||||||
idir = BGP_VPN_POLICY_DIR_FROMVPN;
|
idir = BGP_VPN_POLICY_DIR_FROMVPN;
|
||||||
edir = BGP_VPN_POLICY_DIR_TOVPN;
|
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
|
* Cross-ref both VRFs. Also, note if this is the first time
|
||||||
* any VRF is importing from "import_vrf".
|
* 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);
|
to_bgp->vpn_policy[afi].rtlist[idir] = ecommunity_dup(ecom);
|
||||||
SET_FLAG(to_bgp->af_flags[afi][safi], BGP_CONFIG_VRF_TO_VRF_IMPORT);
|
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
|
/* Does "import_vrf" first need to export its routes or that
|
||||||
* is already done and we just need to import those routes
|
* is already done and we just need to import those routes
|
||||||
* from the global table?
|
* from the global table?
|
||||||
@ -1578,12 +1690,16 @@ void vrf_unimport_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
|
|||||||
char *vname;
|
char *vname;
|
||||||
struct ecommunity *ecom;
|
struct ecommunity *ecom;
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
|
int debug;
|
||||||
|
|
||||||
export_name = to_bgp->name ? to_bgp->name : VRF_DEFAULT_NAME;
|
export_name = to_bgp->name ? to_bgp->name : VRF_DEFAULT_NAME;
|
||||||
tmp_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME;
|
tmp_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME;
|
||||||
idir = BGP_VPN_POLICY_DIR_FROMVPN;
|
idir = BGP_VPN_POLICY_DIR_FROMVPN;
|
||||||
edir = BGP_VPN_POLICY_DIR_TOVPN;
|
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"? */
|
/* Were we importing from "import_vrf"? */
|
||||||
for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi].import_vrf, node,
|
for (ALL_LIST_ELEMENTS_RO(to_bgp->vpn_policy[afi].import_vrf, node,
|
||||||
vname)) {
|
vname)) {
|
||||||
@ -1601,6 +1717,9 @@ void vrf_unimport_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
|
|||||||
if (!vname)
|
if (!vname)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
zlog_debug("%s from %s to %s", __func__, tmp_name, export_name);
|
||||||
|
|
||||||
/* Remove "import_vrf" from our import list. */
|
/* Remove "import_vrf" from our import list. */
|
||||||
listnode_delete(to_bgp->vpn_policy[afi].import_vrf, vname);
|
listnode_delete(to_bgp->vpn_policy[afi].import_vrf, vname);
|
||||||
XFREE(MTYPE_TMP, vname);
|
XFREE(MTYPE_TMP, vname);
|
||||||
|
@ -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 vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey);
|
||||||
|
|
||||||
extern void vpn_leak_postchange_all(void);
|
extern void vpn_leak_postchange_all(void);
|
||||||
|
extern void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw);
|
||||||
|
|
||||||
#endif /* _QUAGGA_BGP_MPLSVPN_H */
|
#endif /* _QUAGGA_BGP_MPLSVPN_H */
|
||||||
|
@ -253,6 +253,8 @@ static int bgp_router_id_set(struct bgp *bgp, const struct in_addr *id)
|
|||||||
if (is_evpn_enabled())
|
if (is_evpn_enabled())
|
||||||
bgp_evpn_handle_router_id_update(bgp, TRUE);
|
bgp_evpn_handle_router_id_update(bgp, TRUE);
|
||||||
|
|
||||||
|
vpn_handle_router_id_update(bgp, TRUE);
|
||||||
|
|
||||||
IPV4_ADDR_COPY(&bgp->router_id, id);
|
IPV4_ADDR_COPY(&bgp->router_id, id);
|
||||||
|
|
||||||
/* Set all peer's local identifier with this value. */
|
/* 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())
|
if (is_evpn_enabled())
|
||||||
bgp_evpn_handle_router_id_update(bgp, FALSE);
|
bgp_evpn_handle_router_id_update(bgp, FALSE);
|
||||||
|
|
||||||
|
vpn_handle_router_id_update(bgp, FALSE);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user