diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index b4adf47eb0..8b6bfd3254 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -863,6 +863,9 @@ unsigned int attrhash_key_make(const void *p) key = jhash(attr->mp_nexthop_local.s6_addr, IPV6_MAX_BYTELEN, key); MIX3(attr->nh_ifindex, attr->nh_lla_ifindex, attr->distance); MIX3(attr->bh_type, attr->otc, bgp_attr_get_aigp_metric(attr)); + MIX3(attr->mm_seqnum, attr->df_alg, attr->df_pref); + MIX(attr->encap_tunneltype); + key = jhash(&attr->rmac, sizeof(attr->rmac), key); return key; } @@ -912,6 +915,7 @@ bool attrhash_cmp(const void *p1, const void *p2) overlay_index_same(attr1, attr2) && !memcmp(&attr1->esi, &attr2->esi, sizeof(esi_t)) && attr1->es_flags == attr2->es_flags && + attr1->mm_seqnum == attr2->mm_seqnum && attr1->mm_sync_seqnum == attr2->mm_sync_seqnum && attr1->df_pref == attr2->df_pref && attr1->df_alg == attr2->df_alg && @@ -923,7 +927,9 @@ bool attrhash_cmp(const void *p1, const void *p2) srv6_vpn_same(attr1->srv6_vpn, attr2->srv6_vpn) && attr1->srte_color == attr2->srte_color && attr1->nh_type == attr2->nh_type && - attr1->bh_type == attr2->bh_type && attr1->otc == attr2->otc) + attr1->bh_type == attr2->bh_type && + attr1->otc == attr2->otc && + !memcmp(&attr1->rmac, &attr2->rmac, sizeof(struct ethaddr))) return true; } diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 0ebef2ecfe..9209be3ca9 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -3050,6 +3050,33 @@ bgp_create_evpn_bgp_path_info(struct bgp_path_info *parent_pi, return pi; } +/* + * According to draft-ietf-bess-evpn-ipvpn-interworking-13, strip the following + * extended communities for VRF routes imported from EVPN. + * + * a. BGP Encapsulation extended communities. + * b. Route Target extended communities. + * c. All the extended communities of type EVPN. + */ +static bool bgp_evpn_filter_ecommunity(uint8_t *val, uint8_t size, void *arg) +{ + switch (val[0]) { + case ECOMMUNITY_ENCODE_AS: + case ECOMMUNITY_ENCODE_IP: + case ECOMMUNITY_ENCODE_AS4: + if (val[1] == ECOMMUNITY_ROUTE_TARGET) + return false; + break; + case ECOMMUNITY_ENCODE_OPAQUE: + if (val[1] == ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP) + return false; + break; + case ECOMMUNITY_ENCODE_EVPN: + return false; + } + return true; +} + /* * Install route entry into the VRF routing table and invoke route selection. */ @@ -3071,6 +3098,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, bool is_l3nhg_active = false; char buf1[INET6_ADDRSTRLEN]; struct bgp_route_evpn *bre; + struct ecommunity *ecom; memset(pp, 0, sizeof(struct prefix)); ip_prefix_from_evpn_prefix(evp, pp); @@ -3142,6 +3170,9 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, if (is_l3nhg_active) SET_FLAG(attr.es_flags, ATTR_ES_L3_NHG_ACTIVE); + ecom = ecommunity_filter(bgp_attr_get_ecommunity(&attr), bgp_evpn_filter_ecommunity, NULL); + bgp_attr_set_ecommunity(&attr, ecom); + /* Check if route entry is already present. */ for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) if (pi->extra && pi->extra->vrfleak &&