summaryrefslogtreecommitdiff
path: root/bgpd/bgp_evpn.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_evpn.c')
-rw-r--r--bgpd/bgp_evpn.c67
1 files changed, 41 insertions, 26 deletions
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index 2271aa1005..9a62c525bd 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -1754,8 +1754,10 @@ static int delete_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
}
/*
- * There is a tunnel endpoint IP address change for this VNI,
- * need to re-advertise routes with the new nexthop.
+ * There is a tunnel endpoint IP address change for this VNI, delete
+ * prior type-3 route (if needed) and update.
+ * Note: Route re-advertisement happens elsewhere after other processing
+ * other changes.
*/
static int handle_tunnel_ip_change(struct bgp *bgp, struct bgpevpn *vpn,
struct in_addr originator_ip)
@@ -1783,7 +1785,7 @@ static int handle_tunnel_ip_change(struct bgp *bgp, struct bgpevpn *vpn,
/* Update the tunnel IP and re-advertise all routes for this VNI. */
vpn->originator_ip = originator_ip;
- return update_routes_for_vni(bgp, vpn);
+ return 0;
}
/*
@@ -3253,15 +3255,25 @@ void bgp_evpn_withdraw_type5_routes(struct bgp *bgp_vrf,
{
struct bgp_table *table = NULL;
struct bgp_node *rn = NULL;
+ struct bgp_info *ri;
/* Bail out early if we don't have to advertise type-5 routes. */
if (!advertise_type5_routes(bgp_vrf, afi))
return;
table = bgp_vrf->rib[afi][safi];
- for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
- bgp_evpn_withdraw_type5_route(bgp_vrf, &rn->p, afi, safi);
-
+ for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
+ /* Only care about "selected" routes - non-imported. */
+ /* TODO: Support for AddPath for EVPN. */
+ for (ri = rn->info; ri; ri = ri->next) {
+ if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED) &&
+ (!ri->extra || !ri->extra->parent)) {
+ bgp_evpn_withdraw_type5_route(bgp_vrf, &rn->p,
+ afi, safi);
+ break;
+ }
+ }
+ }
}
/*
@@ -3282,10 +3294,6 @@ void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf, struct prefix *p,
if (!advertise_type5_routes(bgp_vrf, afi))
return;
- /* only advertise subnet routes as type-5 */
- if (is_host_route(p))
- return;
-
build_type5_prefix_from_ip_prefix(&evp, p);
ret = update_evpn_type5_route(bgp_vrf, &evp, src_attr);
if (ret)
@@ -3313,11 +3321,12 @@ void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf,
table = bgp_vrf->rib[afi][safi];
for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
/* Need to identify the "selected" route entry to use its
- * attribute.
+ * attribute. Also, we only consider "non-imported" routes.
* TODO: Support for AddPath for EVPN.
*/
for (ri = rn->info; ri; ri = ri->next) {
- if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)) {
+ if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED) &&
+ (!ri->extra || !ri->extra->parent)) {
/* apply the route-map */
if (bgp_vrf->adv_cmd_rmap[afi][safi].map) {
@@ -3330,7 +3339,6 @@ void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf,
if (ret == RMAP_DENYMATCH)
continue;
}
-
bgp_evpn_advertise_type5_route(bgp_vrf, &rn->p,
ri->attr,
afi, safi);
@@ -4457,8 +4465,8 @@ int bgp_evpn_local_vni_del(struct bgp *bgp, vni_t vni)
}
/*
- * Handle add (or update) of a local VNI. The only VNI change we care
- * about is change to local-tunnel-ip.
+ * Handle add (or update) of a local VNI. The VNI changes we care
+ * about are for the local-tunnel-ip and the (tenant) VRF.
*/
int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,
struct in_addr originator_ip,
@@ -4476,24 +4484,31 @@ int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,
vpn = bgp_evpn_lookup_vni(bgp, vni);
if (vpn) {
- /* update tenant_vrf_id if required */
+ if (is_vni_live(vpn)
+ && IPV4_ADDR_SAME(&vpn->originator_ip, &originator_ip)
+ && vpn->tenant_vrf_id == tenant_vrf_id)
+ /* Probably some other param has changed that we don't
+ * care about. */
+ return 0;
+
+ /* Update tenant_vrf_id if it has changed. */
if (vpn->tenant_vrf_id != tenant_vrf_id) {
bgpevpn_unlink_from_l3vni(vpn);
vpn->tenant_vrf_id = tenant_vrf_id;
bgpevpn_link_to_l3vni(vpn);
-
- /* update all routes with new export RT for VRFs */
- update_routes_for_vni(bgp, vpn);
}
- if (is_vni_live(vpn)
- && IPV4_ADDR_SAME(&vpn->originator_ip, &originator_ip))
- /* Probably some other param has changed that we don't
- * care about. */
- return 0;
+ /* If tunnel endpoint IP has changed, update (and delete prior
+ * type-3 route, if needed.)
+ */
+ if (!IPV4_ADDR_SAME(&vpn->originator_ip, &originator_ip))
+ handle_tunnel_ip_change(bgp, vpn, originator_ip);
- /* Local tunnel endpoint IP address has changed */
- handle_tunnel_ip_change(bgp, vpn, originator_ip);
+ /* Update all routes with new endpoint IP and/or export RT
+ * for VRFs
+ */
+ if (is_vni_live(vpn))
+ update_routes_for_vni(bgp, vpn);
}
/* Create or update as appropriate. */