]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_zebra.c
bgpd: send L3VNI as route labels to zebra
[mirror_frr.git] / bgpd / bgp_zebra.c
index 95e80ba1bb912611621dbaa8759694ea1a10e517..fc2df44ac69e5b67e5285800c2dc9da8790f2777 100644 (file)
@@ -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;
@@ -1404,6 +1406,7 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
        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;
@@ -1469,13 +1472,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 +1486,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 +1513,32 @@ 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;
+               }
 
-                       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
@@ -1529,27 +1549,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);
                        }