diff options
Diffstat (limited to 'bgpd/bgp_evpn.c')
-rw-r--r-- | bgpd/bgp_evpn.c | 362 |
1 files changed, 191 insertions, 171 deletions
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 7af6ff7c..0a8ce615 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -117,7 +117,7 @@ int vni_list_cmp(void *p1, void *p2) static unsigned int vrf_import_rt_hash_key_make(const void *p) { const struct vrf_irt_node *irt = p; - const char *pnt = irt->rt.val; + const uint8_t *pnt = irt->rt.val; return jhash(pnt, 8, 0x5abc1234); } @@ -229,7 +229,7 @@ static int is_vrf_present_in_irt_vrfs(struct list *vrfs, struct bgp *bgp_vrf) static unsigned int import_rt_hash_key_make(const void *p) { const struct irt_node *irt = p; - const char *pnt = irt->rt.val; + const uint8_t *pnt = irt->rt.val; return jhash(pnt, 8, 0xdeadbeef); } @@ -621,7 +621,7 @@ static void form_auto_rt(struct bgp *bgp, vni_t vni, struct list *rtl, struct listnode *node; if (bgp->advertise_autort_rfc8365) - vni |= EVPN_AUTORT_VXLAN; + SET_FLAG(vni, EVPN_AUTORT_VXLAN); encode_route_target_as((bgp->as & 0xFFFF), vni, &eval, true); ecomadd = ecommunity_new(); @@ -1159,9 +1159,8 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr, } /* Add MAC mobility (sticky) if needed. */ - if (attr->sticky) { + if (CHECK_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_STICKY)) { seqnum = 0; - memset(&ecom_sticky, 0, sizeof(ecom_sticky)); encode_mac_mobility_extcomm(1, seqnum, &eval_sticky); ecom_sticky.size = 1; ecom_sticky.unit_size = ECOMMUNITY_SIZE; @@ -1179,8 +1178,7 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr, } /* Add default gateway, if needed. */ - if (attr->default_gw) { - memset(&ecom_default_gw, 0, sizeof(ecom_default_gw)); + if (CHECK_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_DEFAULT_GW)) { encode_default_gw_extcomm(&eval_default_gw); ecom_default_gw.size = 1; ecom_default_gw.unit_size = ECOMMUNITY_SIZE; @@ -1191,9 +1189,11 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr, } proxy = !!(attr->es_flags & ATTR_ES_PROXY_ADVERT); - if (attr->router_flag || proxy) { - memset(&ecom_na, 0, sizeof(ecom_na)); - encode_na_flag_extcomm(&eval_na, attr->router_flag, proxy); + if (CHECK_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_ROUTER) || proxy) { + encode_na_flag_extcomm(&eval_na, + CHECK_FLAG(attr->evpn_flags, + ATTR_EVPN_FLAG_ROUTER), + proxy); ecom_na.size = 1; ecom_na.unit_size = ECOMMUNITY_SIZE; ecom_na.val = (uint8_t *)eval_na.val; @@ -1278,12 +1278,15 @@ enum zclient_send_status evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn flags = 0; if (pi->sub_type == BGP_ROUTE_IMPORTED) { - if (pi->attr->sticky) + if (CHECK_FLAG(pi->attr->evpn_flags, + ATTR_EVPN_FLAG_STICKY)) SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY); - if (pi->attr->default_gw) + if (CHECK_FLAG(pi->attr->evpn_flags, + ATTR_EVPN_FLAG_DEFAULT_GW)) SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW); if (is_evpn_prefix_ipaddr_v6(p) && - pi->attr->router_flag) + CHECK_FLAG(pi->attr->evpn_flags, + ATTR_EVPN_FLAG_ROUTER)) SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG); seq = mac_mobility_seqnum(pi->attr); @@ -1311,12 +1314,11 @@ enum zclient_send_status evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn * flag set install the local entry as a router entry */ if (is_evpn_prefix_ipaddr_v6(p) && - (pi->attr->es_flags & - ATTR_ES_PEER_ROUTER)) + CHECK_FLAG(pi->attr->es_flags, ATTR_ES_PEER_ROUTER)) SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG); - if (!(pi->attr->es_flags & ATTR_ES_PEER_ACTIVE)) + if (!CHECK_FLAG(pi->attr->es_flags, ATTR_ES_PEER_ACTIVE)) SET_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT); } @@ -1608,12 +1610,16 @@ static int update_evpn_type5_route_entry(struct bgp *bgp_evpn, struct bgp_labels bgp_labels = {}; struct bgp_path_info *local_pi = NULL; struct bgp_path_info *tmp_pi = NULL; + struct aspath *new_aspath; + struct attr static_attr = { 0 }; *route_changed = 0; /* See if this is an update of an existing route, or a new add. */ local_pi = bgp_evpn_route_get_local_path(bgp_evpn, dest); + static_attr = *attr; + /* * create a new route entry if one doesn't exist. * Otherwise see if route attr has changed @@ -1623,8 +1629,19 @@ static int update_evpn_type5_route_entry(struct bgp *bgp_evpn, /* route has changed as this is the first entry */ *route_changed = 1; + /* + * if the asn values are different, copy the as of + * source vrf to the target entry + */ + if (bgp_vrf->as != bgp_evpn->as) { + new_aspath = aspath_dup(static_attr.aspath); + new_aspath = aspath_add_seq(new_aspath, bgp_vrf->as); + static_attr.aspath = new_aspath; + } + /* Add (or update) attribute to hash. */ - attr_new = bgp_attr_intern(attr); + attr_new = bgp_attr_intern(&static_attr); + bgp_attr_flush(&static_attr); /* create the route info from attribute */ pi = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, @@ -1738,20 +1755,30 @@ static int update_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp, BGP_L2VPN_EVPN_ADV_IPV6_UNICAST_GW_IP)) { if (src_attr && !IN6_IS_ADDR_UNSPECIFIED(&src_attr->mp_nexthop_global)) { - attr.evpn_overlay.type = OVERLAY_INDEX_GATEWAY_IP; - SET_IPADDR_V6(&attr.evpn_overlay.gw_ip); - memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v6, + struct bgp_route_evpn *bre = + XCALLOC(MTYPE_BGP_EVPN_OVERLAY, + sizeof(struct bgp_route_evpn)); + + bre->type = OVERLAY_INDEX_GATEWAY_IP; + SET_IPADDR_V6(&bre->gw_ip); + memcpy(&bre->gw_ip.ipaddr_v6, &src_attr->mp_nexthop_global, sizeof(struct in6_addr)); + bgp_attr_set_evpn_overlay(&attr, bre); } } else if (src_afi == AFI_IP && CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN], BGP_L2VPN_EVPN_ADV_IPV4_UNICAST_GW_IP)) { if (src_attr && src_attr->nexthop.s_addr != 0) { - attr.evpn_overlay.type = OVERLAY_INDEX_GATEWAY_IP; - SET_IPADDR_V4(&attr.evpn_overlay.gw_ip); - memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v4, - &src_attr->nexthop, sizeof(struct in_addr)); + struct bgp_route_evpn *bre = + XCALLOC(MTYPE_BGP_EVPN_OVERLAY, + sizeof(struct bgp_route_evpn)); + + bre->type = OVERLAY_INDEX_GATEWAY_IP; + SET_IPADDR_V4(&bre->gw_ip); + memcpy(&bre->gw_ip.ipaddr_v4, &src_attr->nexthop, + sizeof(struct in_addr)); + bgp_attr_set_evpn_overlay(&attr, bre); } } @@ -1840,7 +1867,8 @@ static void bgp_evpn_get_sync_info(struct bgp *bgp, esi_t *esi, *active_on_peer = true; } - if (second_best_path->attr->router_flag) + if (CHECK_FLAG(second_best_path->attr->evpn_flags, + ATTR_EVPN_FLAG_ROUTER)) *peer_router = true; /* we use both proxy and non-proxy imports to @@ -1883,42 +1911,44 @@ static void update_evpn_route_entry_sync_info(struct bgp *bgp, mac); attr->mm_sync_seqnum = max_sync_seq; if (active_on_peer) - attr->es_flags |= ATTR_ES_PEER_ACTIVE; + SET_FLAG(attr->es_flags, ATTR_ES_PEER_ACTIVE); else - attr->es_flags &= ~ATTR_ES_PEER_ACTIVE; + UNSET_FLAG(attr->es_flags, ATTR_ES_PEER_ACTIVE); if (proxy_from_peer) - attr->es_flags |= ATTR_ES_PEER_PROXY; + SET_FLAG(attr->es_flags, ATTR_ES_PEER_PROXY); else - attr->es_flags &= ~ATTR_ES_PEER_PROXY; + UNSET_FLAG(attr->es_flags, ATTR_ES_PEER_PROXY); if (peer_router) - attr->es_flags |= ATTR_ES_PEER_ROUTER; + SET_FLAG(attr->es_flags, ATTR_ES_PEER_ROUTER); else - attr->es_flags &= ~ATTR_ES_PEER_ROUTER; + UNSET_FLAG(attr->es_flags, ATTR_ES_PEER_ROUTER); if (BGP_DEBUG(evpn_mh, EVPN_MH_RT)) { char esi_buf[ESI_STR_LEN]; - zlog_debug( - "setup sync info for %pFX es %s max_seq %d %s%s%s", - evp, - esi_to_str(esi, esi_buf, - sizeof(esi_buf)), - max_sync_seq, - (attr->es_flags & ATTR_ES_PEER_ACTIVE) - ? "peer-active " - : "", - (attr->es_flags & ATTR_ES_PEER_PROXY) - ? "peer-proxy " - : "", - (attr->es_flags & ATTR_ES_PEER_ROUTER) - ? "peer-router " - : ""); + zlog_debug("setup sync info for %pFX es %s max_seq %d %s%s%s", + evp, + esi_to_str(esi, esi_buf, + sizeof(esi_buf)), + max_sync_seq, + CHECK_FLAG(attr->es_flags, + ATTR_ES_PEER_ACTIVE) + ? "peer-active " + : "", + CHECK_FLAG(attr->es_flags, + ATTR_ES_PEER_PROXY) + ? "peer-proxy " + : "", + CHECK_FLAG(attr->es_flags, + ATTR_ES_PEER_ROUTER) + ? "peer-router " + : ""); } } } else { attr->mm_sync_seqnum = 0; - attr->es_flags &= ~ATTR_ES_PEER_ACTIVE; - attr->es_flags &= ~ATTR_ES_PEER_PROXY; + UNSET_FLAG(attr->es_flags, ATTR_ES_PEER_ACTIVE); + UNSET_FLAG(attr->es_flags, ATTR_ES_PEER_PROXY); } } @@ -1940,7 +1970,6 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, struct attr local_attr; struct bgp_labels bgp_labels = {}; int route_change = 1; - uint8_t sticky = 0; const struct prefix_evpn *evp; *pi = NULL; @@ -1972,9 +2001,7 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, local_attr = *attr; /* Extract MAC mobility sequence number, if any. */ - local_attr.mm_seqnum = - bgp_attr_mac_mobility_seqnum(&local_attr, &sticky); - local_attr.sticky = sticky; + local_attr.mm_seqnum = bgp_attr_mac_mobility_seqnum(&local_attr); /* Add (or update) attribute to hash. */ attr_new = bgp_attr_intern(&local_attr); @@ -2069,9 +2096,8 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, BGP_PATH_ATTR_CHANGED); /* Extract MAC mobility sequence number, if any. */ - local_attr.mm_seqnum = bgp_attr_mac_mobility_seqnum( - &local_attr, &sticky); - local_attr.sticky = sticky; + local_attr.mm_seqnum = + bgp_attr_mac_mobility_seqnum(&local_attr); attr_new = bgp_attr_intern(&local_attr); @@ -2114,22 +2140,18 @@ static void evpn_zebra_reinstall_best_route(struct bgp *bgp, } } - if (curr_select && curr_select->type == ZEBRA_ROUTE_BGP - && (curr_select->sub_type == BGP_ROUTE_IMPORTED || - bgp_evpn_attr_is_sync(curr_select->attr))) - if (curr_select && curr_select->type == ZEBRA_ROUTE_BGP && - (curr_select->sub_type == BGP_ROUTE_IMPORTED || - bgp_evpn_attr_is_sync(curr_select->attr))) { - if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) - evpn_zebra_install(bgp, vpn, - (const struct prefix_evpn *) - bgp_dest_get_prefix( - dest), - curr_select); - else - bgp_zebra_route_install(dest, curr_select, bgp, - true, vpn, false); - } + if (curr_select && curr_select->type == ZEBRA_ROUTE_BGP && + (curr_select->sub_type == BGP_ROUTE_IMPORTED || + bgp_evpn_attr_is_sync(curr_select->attr))) { + if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS)) + evpn_zebra_install(bgp, vpn, + (const struct prefix_evpn *) + bgp_dest_get_prefix(dest), + curr_select); + else + bgp_zebra_route_install(dest, curr_select, bgp, true, + vpn, false); + } } /* @@ -2204,21 +2226,23 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn, attr.nexthop = vpn->originator_ip; attr.mp_nexthop_global_in = vpn->originator_ip; attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; - attr.sticky = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY) ? 1 : 0; - attr.default_gw = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW) ? 1 : 0; - attr.router_flag = CHECK_FLAG(flags, - ZEBRA_MACIP_TYPE_ROUTER_FLAG) ? 1 : 0; + if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY)) + SET_FLAG(attr.evpn_flags, ATTR_EVPN_FLAG_STICKY); + if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW)) + SET_FLAG(attr.evpn_flags, ATTR_EVPN_FLAG_DEFAULT_GW); + if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG)) + SET_FLAG(attr.evpn_flags, ATTR_EVPN_FLAG_ROUTER); if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT)) - attr.es_flags |= ATTR_ES_PROXY_ADVERT; + SET_FLAG(attr.es_flags, ATTR_ES_PROXY_ADVERT); if (esi && bgp_evpn_is_esi_valid(esi)) { memcpy(&attr.esi, esi, sizeof(esi_t)); - attr.es_flags |= ATTR_ES_IS_LOCAL; + SET_FLAG(attr.es_flags, ATTR_ES_IS_LOCAL); } /* PMSI is only needed for type-3 routes */ if (p->prefix.route_type == BGP_EVPN_IMET_ROUTE) { - attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL); + SET_FLAG(attr.flag, ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)); bgp_attr_set_pmsi_tnl_type(&attr, PMSI_TNLTYPE_INGR_REPL); } @@ -2250,8 +2274,12 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn, * IPv4 or IPv6 global addresses and we're advertising L3VNI with * these routes. */ - add_l3_ecomm = bgp_evpn_route_add_l3_ecomm_ok( - vpn, p, (attr.es_flags & ATTR_ES_IS_LOCAL) ? &attr.esi : NULL); + add_l3_ecomm = + bgp_evpn_route_add_l3_ecomm_ok(vpn, p, + CHECK_FLAG(attr.es_flags, + ATTR_ES_IS_LOCAL) + ? &attr.esi + : NULL); if (bgp->evpn_info) macvrf_soo = bgp->evpn_info->soo; @@ -2509,13 +2537,12 @@ void bgp_evpn_update_type2_route_entry(struct bgp *bgp, struct bgpevpn *vpn, attr.nexthop = vpn->originator_ip; attr.mp_nexthop_global_in = vpn->originator_ip; attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4; - attr.sticky = (local_pi->attr->sticky) ? 1 : 0; - attr.router_flag = (local_pi->attr->router_flag) ? 1 : 0; + attr.evpn_flags = local_pi->attr->evpn_flags; attr.es_flags = local_pi->attr->es_flags; - if (local_pi->attr->default_gw) { - attr.default_gw = 1; + if (CHECK_FLAG(local_pi->attr->evpn_flags, ATTR_EVPN_FLAG_DEFAULT_GW)) { + SET_FLAG(attr.evpn_flags, ATTR_EVPN_FLAG_DEFAULT_GW); if (is_evpn_prefix_ipaddr_v6(&evp)) - attr.router_flag = 1; + SET_FLAG(attr.evpn_flags, ATTR_EVPN_FLAG_ROUTER); } memcpy(&attr.esi, &local_pi->attr->esi, sizeof(esi_t)); bgp_evpn_get_rmac_nexthop(vpn, &evp, &attr, @@ -2524,9 +2551,12 @@ void bgp_evpn_update_type2_route_entry(struct bgp *bgp, struct bgpevpn *vpn, /* Add L3 VNI RTs and RMAC for non IPv6 link-local if * using L3 VNI for type-2 routes also. */ - add_l3_ecomm = bgp_evpn_route_add_l3_ecomm_ok( - vpn, &evp, - (attr.es_flags & ATTR_ES_IS_LOCAL) ? &attr.esi : NULL); + add_l3_ecomm = + bgp_evpn_route_add_l3_ecomm_ok(vpn, &evp, + CHECK_FLAG(attr.es_flags, + ATTR_ES_IS_LOCAL) + ? &attr.esi + : NULL); if (bgp->evpn_info) macvrf_soo = bgp->evpn_info->soo; @@ -3030,6 +3060,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, bool use_l3nhg = false; bool is_l3nhg_active = false; char buf1[INET6_ADDRSTRLEN]; + struct bgp_route_evpn *bre; memset(pp, 0, sizeof(struct prefix)); ip_prefix_from_evpn_prefix(evp, pp); @@ -3063,45 +3094,43 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, * make sure to set the flag for next hop attribute. */ attr = *parent_pi->attr; - if (attr.evpn_overlay.type != OVERLAY_INDEX_GATEWAY_IP) { - if (afi == AFI_IP6) - evpn_convert_nexthop_to_ipv6(&attr); - else { - attr.nexthop = attr.mp_nexthop_global_in; - attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP); - } - } else { - + bre = bgp_attr_get_evpn_overlay(&attr); + if (bre && bre->type == OVERLAY_INDEX_GATEWAY_IP) { /* * If gateway IP overlay index is specified in the NLRI of * EVPN RT-5, this gateway IP should be used as the nexthop * for the prefix in the VRF */ if (bgp_debug_zebra(NULL)) { - zlog_debug( - "Install gateway IP %s as nexthop for prefix %pFX in vrf %s", - inet_ntop(pp->family, &attr.evpn_overlay.gw_ip, - buf1, sizeof(buf1)), pp, - vrf_id_to_name(bgp_vrf->vrf_id)); + zlog_debug("Install gateway IP %s as nexthop for prefix %pFX in vrf %s", + inet_ntop(pp->family, &bre->gw_ip, buf1, + sizeof(buf1)), + pp, vrf_id_to_name(bgp_vrf->vrf_id)); } if (afi == AFI_IP6) { - memcpy(&attr.mp_nexthop_global, - &attr.evpn_overlay.gw_ip.ipaddr_v6, + memcpy(&attr.mp_nexthop_global, &bre->gw_ip.ipaddr_v6, sizeof(struct in6_addr)); attr.mp_nexthop_len = IPV6_MAX_BYTELEN; } else { - attr.nexthop = attr.evpn_overlay.gw_ip.ipaddr_v4; - attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP); + attr.nexthop = bre->gw_ip.ipaddr_v4; + SET_FLAG(attr.flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)); + } + } else { + if (afi == AFI_IP6) + evpn_convert_nexthop_to_ipv6(&attr); + else { + attr.nexthop = attr.mp_nexthop_global_in; + SET_FLAG(attr.flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)); } } bgp_evpn_es_vrf_use_nhg(bgp_vrf, &parent_pi->attr->esi, &use_l3nhg, &is_l3nhg_active, NULL); if (use_l3nhg) - attr.es_flags |= ATTR_ES_L3_NHG_USE; + SET_FLAG(attr.es_flags, ATTR_ES_L3_NHG_USE); if (is_l3nhg_active) - attr.es_flags |= ATTR_ES_L3_NHG_ACTIVE; + SET_FLAG(attr.es_flags, ATTR_ES_L3_NHG_ACTIVE); /* Check if route entry is already present. */ for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) @@ -3143,22 +3172,20 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, } /* Gateway IP nexthop should be resolved */ - if (attr.evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) { + if (bre && bre->type == OVERLAY_INDEX_GATEWAY_IP) { if (bgp_find_or_add_nexthop(bgp_vrf, bgp_vrf, afi, safi, pi, NULL, 0, NULL)) bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID); else { if (BGP_DEBUG(nht, NHT)) { - inet_ntop(pp->family, - &attr.evpn_overlay.gw_ip, - buf1, sizeof(buf1)); + inet_ntop(pp->family, &bre->gw_ip, buf1, + sizeof(buf1)); zlog_debug("%s: gateway IP NH unresolved", buf1); } bgp_path_info_unset_flag(dest, pi, BGP_PATH_VALID); } } else { - /* as it is an importation, change nexthop */ bgp_path_info_set_flag(dest, pi, BGP_PATH_ANNC_NH_SELF); } @@ -3267,8 +3294,7 @@ static int install_evpn_route_entry_in_vni_common( if (BGP_DEBUG(evpn_mh, EVPN_MH_RT)) zlog_debug("VNI %d path %pFX chg to %s es", vpn->vni, &pi->net->rn->p, - new_local_es ? "local" - : "non-local"); + new_local_es ? "local" : "non-local"); bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED); } @@ -3451,9 +3477,8 @@ uninstall_evpn_route_entry_in_vni_mac(struct bgp *bgp, struct bgpevpn *vpn, * Uninstall route entry from the VRF routing table and send message * to zebra, if appropriate. */ -static int uninstall_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, - const struct prefix_evpn *evp, - struct bgp_path_info *parent_pi) +int uninstall_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, const struct prefix_evpn *evp, + struct bgp_path_info *parent_pi) { struct bgp_dest *dest; struct bgp_path_info *pi; @@ -3631,7 +3656,7 @@ static int is_route_matching_for_vrf(struct bgp *bgp_vrf, assert(attr); /* Route should have valid RT to be even considered. */ - if (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) + if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) return 0; ecom = bgp_attr_get_ecommunity(attr); @@ -3698,7 +3723,7 @@ static int is_route_matching_for_vni(struct bgp *bgp, struct bgpevpn *vpn, assert(attr); /* Route should have valid RT to be even considered. */ - if (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) + if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) return 0; ecom = bgp_attr_get_ecommunity(attr); @@ -3820,10 +3845,8 @@ static int bgp_evpn_route_rmac_self_check(struct bgp *bgp_vrf, } /* don't import hosts that are locally attached */ -static inline bool -bgp_evpn_skip_vrf_import_of_local_es(struct bgp *bgp_vrf, - const struct prefix_evpn *evp, - struct bgp_path_info *pi, int install) +bool bgp_evpn_skip_vrf_import_of_local_es(struct bgp *bgp_vrf, const struct prefix_evpn *evp, + struct bgp_path_info *pi, int install) { esi_t *esi; @@ -4200,7 +4223,7 @@ static int bgp_evpn_install_uninstall_table(struct bgp *bgp, afi_t afi, return 0; /* If we don't have Route Target, nothing much to do. */ - if (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) + if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) return 0; /* EAD prefix in the global table doesn't include the VTEP-IP so @@ -4689,7 +4712,6 @@ static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi, { struct prefix_rd prd; struct prefix_evpn p = {}; - struct bgp_route_evpn evpn = {}; uint8_t ipaddr_len; uint8_t macaddr_len; /* holds the VNI(s) as in packet */ @@ -4731,9 +4753,9 @@ static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi, STREAM_GET(&attr->esi, pkt, sizeof(esi_t)); if (bgp_evpn_is_esi_local_and_non_bypass(&attr->esi)) - attr->es_flags |= ATTR_ES_IS_LOCAL; + SET_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL); else - attr->es_flags &= ~ATTR_ES_IS_LOCAL; + UNSET_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL); } else { STREAM_FORWARD_GETP(pkt, sizeof(esi_t)); } @@ -4791,11 +4813,11 @@ static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi, if (attr) bgp_update(peer, (struct prefix *)&p, addpath_id, attr, afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, - &label[0], num_labels, 0, &evpn); + &label[0], num_labels, 0, NULL); else bgp_withdraw(peer, (struct prefix *)&p, addpath_id, afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, &label[0], - num_labels, &evpn); + num_labels); goto done; fail: @@ -4835,8 +4857,7 @@ static int process_type3_route(struct peer *peer, afi_t afi, safi_t safi, * Note: We just simply ignore the values as it is not clear if * doing anything else is better. */ - if (attr && - (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL))) { + if (attr && CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL))) { enum pta_type pmsi_tnl_type = bgp_attr_get_pmsi_tnl_type(attr); if (pmsi_tnl_type != PMSI_TNLTYPE_INGR_REPL @@ -4885,8 +4906,7 @@ static int process_type3_route(struct peer *peer, afi_t afi, safi_t safi, 0, 0, NULL); else bgp_withdraw(peer, (struct prefix *)&p, addpath_id, afi, safi, - ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, NULL, 0, - NULL); + ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, NULL, 0); return 0; } @@ -4899,7 +4919,8 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi, { struct prefix_rd prd; struct prefix_evpn p; - struct bgp_route_evpn evpn; + struct bgp_route_evpn *evpn = XCALLOC(MTYPE_BGP_EVPN_OVERLAY, + sizeof(struct bgp_route_evpn)); uint8_t ippfx_len; uint32_t eth_tag; mpls_label_t label; /* holds the VNI as in the packet */ @@ -4914,6 +4935,7 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi, flog_err(EC_BGP_EVPN_ROUTE_INVALID, "%u:%s - Rx EVPN Type-5 NLRI with invalid length %d", peer->bgp->vrf_id, peer->host, psize); + evpn_overlay_free(evpn); return -1; } @@ -4929,12 +4951,9 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi, p.prefixlen = EVPN_ROUTE_PREFIXLEN; p.prefix.route_type = BGP_EVPN_IP_PREFIX_ROUTE; - /* Additional information outside of prefix - ESI and GW IP */ - memset(&evpn, 0, sizeof(evpn)); - /* Fetch ESI overlay index */ if (attr) - memcpy(&evpn.eth_s_id, pfx, sizeof(esi_t)); + memcpy(&evpn->eth_s_id, pfx, sizeof(esi_t)); pfx += ESI_BYTES; /* Fetch Ethernet Tag. */ @@ -4949,6 +4968,7 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi, EC_BGP_EVPN_ROUTE_INVALID, "%u:%s - Rx EVPN Type-5 NLRI with invalid IP Prefix length %d", peer->bgp->vrf_id, peer->host, ippfx_len); + evpn_overlay_free(evpn); return -1; } p.prefix.prefix_addr.ip_prefix_length = ippfx_len; @@ -4961,16 +4981,16 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi, SET_IPADDR_V4(&p.prefix.prefix_addr.ip); memcpy(&p.prefix.prefix_addr.ip.ipaddr_v4, pfx, 4); pfx += 4; - SET_IPADDR_V4(&evpn.gw_ip); - memcpy(&evpn.gw_ip.ipaddr_v4, pfx, 4); + SET_IPADDR_V4(&evpn->gw_ip); + memcpy(&evpn->gw_ip.ipaddr_v4, pfx, 4); pfx += 4; } else { SET_IPADDR_V6(&p.prefix.prefix_addr.ip); memcpy(&p.prefix.prefix_addr.ip.ipaddr_v6, pfx, IPV6_MAX_BYTELEN); pfx += IPV6_MAX_BYTELEN; - SET_IPADDR_V6(&evpn.gw_ip); - memcpy(&evpn.gw_ip.ipaddr_v6, pfx, IPV6_MAX_BYTELEN); + SET_IPADDR_V6(&evpn->gw_ip); + memcpy(&evpn->gw_ip.ipaddr_v6, pfx, IPV6_MAX_BYTELEN); pfx += IPV6_MAX_BYTELEN; } @@ -4988,20 +5008,20 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi, * An update containing a non-zero gateway IP and a non-zero ESI * at the same time is should be treated as withdraw */ - if (bgp_evpn_is_esi_valid(&evpn.eth_s_id) && - !ipaddr_is_zero(&evpn.gw_ip)) { + if (bgp_evpn_is_esi_valid(&evpn->eth_s_id) && + !ipaddr_is_zero(&evpn->gw_ip)) { flog_err(EC_BGP_EVPN_ROUTE_INVALID, "%s - Rx EVPN Type-5 ESI and gateway-IP both non-zero.", peer->host); is_valid_update = false; - } else if (bgp_evpn_is_esi_valid(&evpn.eth_s_id)) - evpn.type = OVERLAY_INDEX_ESI; - else if (!ipaddr_is_zero(&evpn.gw_ip)) - evpn.type = OVERLAY_INDEX_GATEWAY_IP; + } else if (bgp_evpn_is_esi_valid(&evpn->eth_s_id)) + evpn->type = OVERLAY_INDEX_ESI; + else if (!ipaddr_is_zero(&evpn->gw_ip)) + evpn->type = OVERLAY_INDEX_GATEWAY_IP; if (attr) { if (is_zero_mac(&attr->rmac) && - !bgp_evpn_is_esi_valid(&evpn.eth_s_id) && - ipaddr_is_zero(&evpn.gw_ip) && label == 0) { + !bgp_evpn_is_esi_valid(&evpn->eth_s_id) && + ipaddr_is_zero(&evpn->gw_ip) && label == 0) { flog_err(EC_BGP_EVPN_ROUTE_INVALID, "%s - Rx EVPN Type-5 ESI, gateway-IP, RMAC and label all zero", peer->host); @@ -5016,7 +5036,7 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi, if (attr && is_valid_update) bgp_update(peer, (struct prefix *)&p, addpath_id, attr, afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, - &label, 1, 0, &evpn); + &label, 1, 0, evpn); else { if (!is_valid_update) { char attr_str[BUFSIZ] = {0}; @@ -5028,8 +5048,8 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi, attr_str); } bgp_withdraw(peer, (struct prefix *)&p, addpath_id, afi, safi, - ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, &label, 1, - &evpn); + ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, &label, 1); + evpn_overlay_free(evpn); } return 0; @@ -5043,12 +5063,16 @@ static void evpn_mpattr_encode_type5(struct stream *s, const struct prefix *p, int len; char temp[16]; const struct evpn_addr *p_evpn_p; + struct bgp_route_evpn *bre = NULL; memset(&temp, 0, sizeof(temp)); if (p->family != AF_EVPN) return; p_evpn_p = &(p->u.prefix_evpn); + if (attr) + bre = bgp_attr_get_evpn_overlay(attr); + /* len denites the total len of IP and GW-IP in the route IP and GW-IP have to be both ipv4 or ipv6 */ @@ -5059,7 +5083,7 @@ static void evpn_mpattr_encode_type5(struct stream *s, const struct prefix *p, /* Prefix contains RD, ESI, EthTag, IP length, IP, GWIP and VNI */ stream_putc(s, 8 + 10 + 4 + 1 + len + 3); stream_put(s, prd->val, 8); - if (attr && attr->evpn_overlay.type == OVERLAY_INDEX_ESI) + if (attr && bre && bre->type == OVERLAY_INDEX_ESI) stream_put(s, &attr->esi, sizeof(esi_t)); else stream_put(s, 0, sizeof(esi_t)); @@ -5069,15 +5093,11 @@ static void evpn_mpattr_encode_type5(struct stream *s, const struct prefix *p, stream_put_ipv4(s, p_evpn_p->prefix_addr.ip.ipaddr_v4.s_addr); else stream_put(s, &p_evpn_p->prefix_addr.ip.ipaddr_v6, 16); - if (attr && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) { - const struct bgp_route_evpn *evpn_overlay = - bgp_attr_get_evpn_overlay(attr); - + if (attr && bre && bre->type == OVERLAY_INDEX_GATEWAY_IP) { if (IS_IPADDR_V4(&p_evpn_p->prefix_addr.ip)) - stream_put_ipv4(s, - evpn_overlay->gw_ip.ipaddr_v4.s_addr); + stream_put_ipv4(s, bre->gw_ip.ipaddr_v4.s_addr); else - stream_put(s, &(evpn_overlay->gw_ip.ipaddr_v6), 16); + stream_put(s, &(bre->gw_ip.ipaddr_v6), 16); } else { if (IS_IPADDR_V4(&p_evpn_p->prefix_addr.ip)) stream_put_ipv4(s, 0); @@ -5439,7 +5459,7 @@ void evpn_rt_delete_auto(struct bgp *bgp, vni_t vni, struct list *rtl, struct ecommunity_val eval; if (bgp->advertise_autort_rfc8365) - vni |= EVPN_AUTORT_VXLAN; + SET_FLAG(vni, EVPN_AUTORT_VXLAN); encode_route_target_as((bgp->as & 0xFFFF), vni, &eval, true); @@ -7717,18 +7737,18 @@ static void bgp_evpn_remote_ip_process_nexthops(struct bgpevpn *vpn, * MAC/IP route or SVI or tenant vrf being added to EVI. * Set nexthop as valid only if it is already L3 reachable */ - if (resolve && bnc->flags & BGP_NEXTHOP_EVPN_INCOMPLETE) { - bnc->flags &= ~BGP_NEXTHOP_EVPN_INCOMPLETE; - bnc->flags |= BGP_NEXTHOP_VALID; - bnc->change_flags |= BGP_NEXTHOP_MACIP_CHANGED; + if (resolve && CHECK_FLAG(bnc->flags, BGP_NEXTHOP_EVPN_INCOMPLETE)) { + UNSET_FLAG(bnc->flags, BGP_NEXTHOP_EVPN_INCOMPLETE); + SET_FLAG(bnc->flags, BGP_NEXTHOP_VALID); + SET_FLAG(bnc->change_flags, BGP_NEXTHOP_MACIP_CHANGED); evaluate_paths(bnc); } /* MAC/IP route or SVI or tenant vrf being deleted from EVI */ - if (!resolve && bnc->flags & BGP_NEXTHOP_VALID) { - bnc->flags &= ~BGP_NEXTHOP_VALID; - bnc->flags |= BGP_NEXTHOP_EVPN_INCOMPLETE; - bnc->change_flags |= BGP_NEXTHOP_MACIP_CHANGED; + if (!resolve && CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID)) { + UNSET_FLAG(bnc->flags, BGP_NEXTHOP_VALID); + SET_FLAG(bnc->flags, BGP_NEXTHOP_EVPN_INCOMPLETE); + SET_FLAG(bnc->change_flags, BGP_NEXTHOP_MACIP_CHANGED); evaluate_paths(bnc); } } |