diff options
Diffstat (limited to 'bgpd/bgp_zebra.c')
| -rw-r--r-- | bgpd/bgp_zebra.c | 63 |
1 files changed, 40 insertions, 23 deletions
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 95e80ba1bb..3a61989900 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1310,8 +1310,10 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, struct bgp_path_info local_info; struct bgp_path_info *mpinfo_cp = &local_info; route_tag_t tag; - mpls_label_t label; struct bgp_sid_info *sid_info; + mpls_label_t *labels; + uint32_t num_labels = 0; + mpls_label_t nh_label; int nh_othervrf = 0; bool nh_updated = false; bool do_wt_ecmp; @@ -1402,8 +1404,11 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, } for (; mpinfo; mpinfo = bgp_path_info_mpath_next(mpinfo)) { + labels = NULL; + num_labels = 0; uint32_t nh_weight; bool is_evpn; + bool is_parent_evpn; if (valid_nh_count >= multipath_num) break; @@ -1469,13 +1474,13 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, BGP_ORIGINAL_UPDATE(bgp_orig, mpinfo, bgp); - if (nh_family == AF_INET) { - is_evpn = is_route_parent_evpn(mpinfo); + is_parent_evpn = is_route_parent_evpn(mpinfo); + if (nh_family == AF_INET) { nh_updated = update_ipv4nh_for_route_install( nh_othervrf, bgp_orig, &mpinfo_cp->attr->nexthop, mpinfo_cp->attr, - is_evpn, api_nh); + is_parent_evpn, api_nh); } else { ifindex_t ifindex = IFINDEX_INTERNAL; struct in6_addr *nexthop; @@ -1483,19 +1488,20 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, nexthop = bgp_path_info_to_ipv6_nexthop(mpinfo_cp, &ifindex); - is_evpn = is_route_parent_evpn(mpinfo); - if (!nexthop) nh_updated = update_ipv4nh_for_route_install( nh_othervrf, bgp_orig, &mpinfo_cp->attr->nexthop, - mpinfo_cp->attr, is_evpn, api_nh); + mpinfo_cp->attr, is_parent_evpn, + api_nh); else nh_updated = update_ipv6nh_for_route_install( nh_othervrf, bgp_orig, nexthop, ifindex, - mpinfo, info, is_evpn, api_nh); + mpinfo, info, is_parent_evpn, api_nh); } + is_evpn = !!CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN); + /* Did we get proper nexthop info to update zebra? */ if (!nh_updated) continue; @@ -1509,16 +1515,28 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, || mpinfo->peer->sort == BGP_PEER_CONFED)) allow_recursion = true; - if (mpinfo->extra && - bgp_is_valid_label(&mpinfo->extra->label[0]) && - !CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN)) { - mpls_lse_decode(mpinfo->extra->label[0], &label, &ttl, - &exp, &bos); + if (mpinfo->extra) { + labels = mpinfo->extra->label; + num_labels = mpinfo->extra->num_labels; + } + + if (labels && (num_labels > 0) && + (is_evpn || bgp_is_valid_label(&labels[0]))) { + enum lsp_types_t nh_label_type = ZEBRA_LSP_NONE; - SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_LABEL); + if (is_evpn) { + nh_label = *bgp_evpn_path_info_labels_get_l3vni( + labels, num_labels); + nh_label_type = ZEBRA_LSP_EVPN; + } else { + mpls_lse_decode(labels[0], &nh_label, &ttl, + &exp, &bos); + } + SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_LABEL); api_nh->label_num = 1; - api_nh->labels[0] = label; + api_nh->label_type = nh_label_type; + api_nh->labels[0] = nh_label; } if (is_evpn @@ -1529,27 +1547,26 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, api_nh->weight = nh_weight; - if (mpinfo->extra && - bgp_is_valid_label(&mpinfo->extra->label[0]) && - !sid_zero(&mpinfo->extra->sid[0].sid) && - !CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN)) { + if (mpinfo->extra && !is_evpn && + bgp_is_valid_label(&labels[0]) && + !sid_zero(&mpinfo->extra->sid[0].sid)) { sid_info = &mpinfo->extra->sid[0]; memcpy(&api_nh->seg6_segs, &sid_info->sid, sizeof(api_nh->seg6_segs)); if (sid_info->transposition_len != 0) { - mpls_lse_decode(mpinfo->extra->label[0], &label, - &ttl, &exp, &bos); + mpls_lse_decode(labels[0], &nh_label, &ttl, + &exp, &bos); - if (label < MPLS_LABEL_UNRESERVED_MIN) { + if (nh_label < MPLS_LABEL_UNRESERVED_MIN) { if (bgp_debug_zebra(&api.prefix)) zlog_debug( "skip invalid SRv6 routes: transposition scheme is used, but label is too small"); continue; } - transpose_sid(&api_nh->seg6_segs, label, + transpose_sid(&api_nh->seg6_segs, nh_label, sid_info->transposition_offset, sid_info->transposition_len); } |
