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;
for (; mpinfo; mpinfo = bgp_path_info_mpath_next(mpinfo)) {
uint32_t nh_weight;
bool is_evpn;
+ bool is_parent_evpn;
if (valid_nh_count >= multipath_num)
break;
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;
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;
|| 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;
+ }
- SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_LABEL);
+ if (labels && (num_labels > 0) &&
+ (is_evpn || bgp_is_valid_label(&labels[0]))) {
+ enum lsp_types_t nh_label_type = ZEBRA_LSP_NONE;
+ if (is_evpn) {
+ /*
+ * L3VNI is always last label. Type5 will only
+ * have one label, Type2 will have two.
+ */
+ nh_label = labels[num_labels - 1];
+ nh_label_type = ZEBRA_LSP_EVPN;
+
+ } else if (bgp_is_valid_label(&labels[0])) {
+ 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
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);
}