Merge pull request #8406 from adharkar/frr-es_rd

bgpd: Handle EAD/EVI local route updates on VNI RD change
This commit is contained in:
Russ White 2021-05-11 06:51:41 -04:00 committed by GitHub
commit 41e4b0c0ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 81 additions and 12 deletions

View File

@ -3562,8 +3562,12 @@ static int update_advertise_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
const struct prefix_evpn *evp = const struct prefix_evpn *evp =
(const struct prefix_evpn *)bgp_dest_get_prefix(dest); (const struct prefix_evpn *)bgp_dest_get_prefix(dest);
/* Identify MAC-IP local routes. */ /*
if (evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE) * We have already processed type-3 routes.
* Process only type-1 and type-2 routes here.
*/
if (evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE
&& evp->prefix.route_type != BGP_EVPN_AD_ROUTE)
continue; continue;
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
@ -3581,10 +3585,23 @@ static int update_advertise_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
global_dest = bgp_global_evpn_node_get(bgp->rib[afi][safi], afi, safi, global_dest = bgp_global_evpn_node_get(bgp->rib[afi][safi], afi, safi,
evp, &vpn->prd); evp, &vpn->prd);
assert(global_dest); assert(global_dest);
update_evpn_route_entry(bgp, vpn, afi, safi, global_dest, attr, 1,
&global_pi, 0, if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) {
mac_mobility_seqnum(attr), /* Type-2 route */
update_evpn_route_entry(
bgp, vpn, afi, safi, global_dest, attr, 1,
&global_pi, 0, mac_mobility_seqnum(attr),
false /* setup_sync */, NULL /* old_is_sync */); false /* setup_sync */, NULL /* old_is_sync */);
} else {
/* Type-1 route */
struct bgp_evpn_es *es;
int route_changed = 0;
es = bgp_evpn_es_find(&evp->prefix.ead_addr.esi);
bgp_evpn_mh_route_update(bgp, es, vpn, afi, safi,
global_dest, attr, 1,
&global_pi, &route_changed);
}
/* Schedule for processing and unlock node. */ /* Schedule for processing and unlock node. */
bgp_process(bgp, global_dest, afi, safi); bgp_process(bgp, global_dest, afi, safi);
@ -3630,6 +3647,8 @@ static int delete_withdraw_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
bgp_dest_unlock_node(global_dest); bgp_dest_unlock_node(global_dest);
} }
delete_global_ead_evi_routes(bgp, vpn);
return 0; return 0;
} }

View File

@ -347,11 +347,10 @@ static void bgp_evpn_es_route_del_all(struct bgp *bgp, struct bgp_evpn_es *es)
* Note: vpn is applicable only to EAD-EVI routes (NULL for EAD-ES and * Note: vpn is applicable only to EAD-EVI routes (NULL for EAD-ES and
* ESR). * ESR).
*/ */
static int bgp_evpn_mh_route_update(struct bgp *bgp, struct bgp_evpn_es *es, int bgp_evpn_mh_route_update(struct bgp *bgp, struct bgp_evpn_es *es,
struct bgpevpn *vpn, afi_t afi, safi_t safi, struct bgpevpn *vpn, afi_t afi, safi_t safi,
struct bgp_dest *dest, struct attr *attr, struct bgp_dest *dest, struct attr *attr, int add,
int add, struct bgp_path_info **ri, struct bgp_path_info **ri, int *route_changed)
int *route_changed)
{ {
struct bgp_path_info *tmp_pi = NULL; struct bgp_path_info *tmp_pi = NULL;
struct bgp_path_info *local_pi = NULL; /* local route entry if any */ struct bgp_path_info *local_pi = NULL; /* local route entry if any */
@ -384,7 +383,8 @@ static int bgp_evpn_mh_route_update(struct bgp *bgp, struct bgp_evpn_es *es,
flog_err( flog_err(
EC_BGP_ES_INVALID, EC_BGP_ES_INVALID,
"%u ERROR: local es route for ESI: %s Vtep %pI4 also learnt from remote", "%u ERROR: local es route for ESI: %s Vtep %pI4 also learnt from remote",
bgp->vrf_id, es->esi_str, &es->originator_ip); bgp->vrf_id, es ? es->esi_str : "Null",
&es->originator_ip);
return -1; return -1;
} }
@ -441,7 +441,7 @@ static int bgp_evpn_mh_route_update(struct bgp *bgp, struct bgp_evpn_es *es,
if (BGP_DEBUG(evpn_mh, EVPN_MH_RT)) if (BGP_DEBUG(evpn_mh, EVPN_MH_RT))
zlog_debug( zlog_debug(
"local ES %s vni %u route-type %s nexthop %pI4 updated", "local ES %s vni %u route-type %s nexthop %pI4 updated",
es->esi_str, vpn ? vpn->vni : 0, es ? es->esi_str : "Null", vpn ? vpn->vni : 0,
evp->prefix.route_type == BGP_EVPN_ES_ROUTE evp->prefix.route_type == BGP_EVPN_ES_ROUTE
? "esr" ? "esr"
: (vpn ? "ead-evi" : "ead-es"), : (vpn ? "ead-evi" : "ead-es"),
@ -524,6 +524,50 @@ static int bgp_evpn_mh_route_delete(struct bgp *bgp, struct bgp_evpn_es *es,
return 0; return 0;
} }
/*
* This function is called when the VNI RD changes.
* Delete all EAD/EVI local routes for this VNI from the global routing table.
* These routes are scheduled for withdraw from peers.
*/
int delete_global_ead_evi_routes(struct bgp *bgp, struct bgpevpn *vpn)
{
afi_t afi;
safi_t safi;
struct bgp_dest *rdrn, *rn;
struct bgp_table *table;
struct bgp_path_info *pi;
afi = AFI_L2VPN;
safi = SAFI_EVPN;
/* Find the RD node for the VNI in the global table */
rdrn = bgp_node_lookup(bgp->rib[afi][safi], (struct prefix *)&vpn->prd);
if (rdrn && bgp_dest_has_bgp_path_info_data(rdrn)) {
table = bgp_dest_get_bgp_table_info(rdrn);
/*
* Iterate over all the routes in this table and delete EAD/EVI
* routes
*/
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
if (evp->prefix.route_type != BGP_EVPN_AD_ROUTE)
continue;
delete_evpn_route_entry(bgp, afi, safi, rn, &pi);
if (pi)
bgp_process(bgp, rn, afi, safi);
}
}
/* Unlock RD node. */
if (rdrn)
bgp_dest_unlock_node(rdrn);
return 0;
}
/***************************************************************************** /*****************************************************************************
* Ethernet Segment (Type-4) Routes * Ethernet Segment (Type-4) Routes
* ESRs are used for DF election. Currently service-carving described in * ESRs are used for DF election. Currently service-carving described in

View File

@ -377,6 +377,12 @@ extern int bgp_evpn_es_route_install_uninstall(struct bgp *bgp,
struct prefix_evpn *evp, struct bgp_path_info *pi, struct prefix_evpn *evp, struct bgp_path_info *pi,
int install); int install);
extern void update_type1_routes_for_evi(struct bgp *bgp, struct bgpevpn *vpn); extern void update_type1_routes_for_evi(struct bgp *bgp, struct bgpevpn *vpn);
extern int delete_global_ead_evi_routes(struct bgp *bgp, struct bgpevpn *vpn);
extern int bgp_evpn_mh_route_update(struct bgp *bgp, struct bgp_evpn_es *es,
struct bgpevpn *vpn, afi_t afi, safi_t safi,
struct bgp_dest *dest, struct attr *attr,
int add, struct bgp_path_info **ri,
int *route_changed);
int bgp_evpn_type1_route_process(struct peer *peer, afi_t afi, safi_t safi, int bgp_evpn_type1_route_process(struct peer *peer, afi_t afi, safi_t safi,
struct attr *attr, uint8_t *pfx, int psize, struct attr *attr, uint8_t *pfx, int psize,
uint32_t addpath_id); uint32_t addpath_id);