]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: support LSPs with multiple outgoing labels
authorRenato Westphal <renato@opensourcerouting.org>
Fri, 29 Nov 2019 14:50:07 +0000 (11:50 -0300)
committerRenato Westphal <renato@opensourcerouting.org>
Fri, 29 Nov 2019 14:50:07 +0000 (11:50 -0300)
For SR-TE we'll need to create Binding-SIDs which are essentially
LSPs that can push multiple outgoing labels. This commit sets the
groundwork for that. Luckily the netlink code didn't need to be
changed since it already supports pushing label stacks.

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
zebra/zapi_msg.c
zebra/zebra_dplane.c
zebra/zebra_dplane.h
zebra/zebra_mpls.c
zebra/zebra_mpls.h

index e809d2ad3dc93d2ce6e1a3ed1b806729061e6cfc..9e65e67a6e019e69a34951d8673e7b725d43da0b 100644 (file)
@@ -1782,7 +1782,7 @@ static void zread_mpls_labels_add(ZAPI_HANDLER_ARGS)
                struct zapi_nexthop_label *znh;
 
                znh = &zl.nexthops[i];
-               mpls_lsp_install(zvrf, zl.type, zl.local_label, znh->label,
+               mpls_lsp_install(zvrf, zl.type, zl.local_label, 1, &znh->label,
                                 znh->type, &znh->address, znh->ifindex);
 
                if (CHECK_FLAG(zl.message, ZAPI_LABELS_FTN))
@@ -1883,7 +1883,7 @@ static void zread_mpls_labels_replace(ZAPI_HANDLER_ARGS)
                struct zapi_nexthop_label *znh;
 
                znh = &zl.nexthops[i];
-               mpls_lsp_install(zvrf, zl.type, zl.local_label, znh->label,
+               mpls_lsp_install(zvrf, zl.type, zl.local_label, 1, &znh->label,
                                 znh->type, &znh->address, znh->ifindex);
 
                if (CHECK_FLAG(zl.message, ZAPI_LABELS_FTN)) {
@@ -2282,10 +2282,11 @@ static void zread_vrf_label(ZAPI_HANDLER_ARGS)
                                           ifp->ifindex);
        }
 
-       if (nlabel != MPLS_LABEL_NONE)
-               mpls_lsp_install(def_zvrf, ltype, nlabel,
-                                MPLS_LABEL_IMPLICIT_NULL, NEXTHOP_TYPE_IFINDEX,
-                                NULL, ifp->ifindex);
+       if (nlabel != MPLS_LABEL_NONE) {
+               mpls_label_t out_label = MPLS_LABEL_IMPLICIT_NULL;
+               mpls_lsp_install(def_zvrf, ltype, nlabel, 1, &out_label,
+                                NEXTHOP_TYPE_IFINDEX, NULL, ifp->ifindex);
+       }
 
        zvrf->label[afi] = nlabel;
 stream_failure:
index 7f993442a624b0bdfe67cd9ddcab6ad14f4cdf61..aecadfadf8ff5a67b2d4eea3fcc2fdf80c09ed23 100644 (file)
@@ -1161,7 +1161,8 @@ zebra_nhlfe_t *dplane_ctx_add_nhlfe(struct zebra_dplane_ctx *ctx,
                                    enum nexthop_types_t nh_type,
                                    union g_addr *gate,
                                    ifindex_t ifindex,
-                                   mpls_label_t out_label)
+                                   uint8_t num_labels,
+                                   mpls_label_t out_labels[])
 {
        zebra_nhlfe_t *nhlfe;
 
@@ -1169,7 +1170,7 @@ zebra_nhlfe_t *dplane_ctx_add_nhlfe(struct zebra_dplane_ctx *ctx,
 
        nhlfe = zebra_mpls_lsp_add_nhlfe(&(ctx->u.lsp),
                                         lsp_type, nh_type, gate,
-                                        ifindex, out_label);
+                                        ifindex, num_labels, out_labels);
 
        return nhlfe;
 }
@@ -1660,7 +1661,8 @@ static int dplane_ctx_lsp_init(struct zebra_dplane_ctx *ctx,
                                nhlfe->nexthop->type,
                                &(nhlfe->nexthop->gate),
                                nhlfe->nexthop->ifindex,
-                               nhlfe->nexthop->nh_label->label[0]);
+                               nhlfe->nexthop->nh_label->num_labels,
+                               nhlfe->nexthop->nh_label->label);
 
                if (new_nhlfe == NULL || new_nhlfe->nexthop == NULL) {
                        ret = ENOMEM;
index fede3bfcca4e9e9140e9dd6d958c357cd59db76b..c0b04e71b0af1b21a7c95ee68ac7d70992c38f3c 100644 (file)
@@ -302,7 +302,8 @@ zebra_nhlfe_t *dplane_ctx_add_nhlfe(struct zebra_dplane_ctx *ctx,
                                    enum nexthop_types_t nh_type,
                                    union g_addr *gate,
                                    ifindex_t ifindex,
-                                   mpls_label_t out_label);
+                                   uint8_t num_labels,
+                                   mpls_label_t out_labels[]);
 
 const zebra_nhlfe_t *dplane_ctx_get_best_nhlfe(
        const struct zebra_dplane_ctx *ctx);
index 6942a379894b1180173cf1e6086a896ad4065f91..5146311c6aed1893b937e14d0d4fa671430935b0 100644 (file)
@@ -102,7 +102,8 @@ static zebra_nhlfe_t *nhlfe_find(zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
                                 ifindex_t ifindex);
 static zebra_nhlfe_t *nhlfe_add(zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
                                enum nexthop_types_t gtype, union g_addr *gate,
-                               ifindex_t ifindex, mpls_label_t out_label);
+                               ifindex_t ifindex, uint8_t num_labels,
+                               mpls_label_t *labels);
 static int nhlfe_del(zebra_nhlfe_t *snhlfe);
 static void nhlfe_out_label_update(zebra_nhlfe_t *nhlfe,
                                   struct mpls_label_stack *nh_label);
@@ -218,7 +219,8 @@ static int lsp_install(struct zebra_vrf *zvrf, mpls_label_t label,
                        /* Add LSP entry to this nexthop */
                        nhlfe = nhlfe_add(lsp, lsp_type, nexthop->type,
                                          &nexthop->gate, nexthop->ifindex,
-                                         nexthop->nh_label->label[0]);
+                                         nexthop->nh_label->num_labels,
+                                         nexthop->nh_label->label);
                        if (!nhlfe)
                                return -1;
 
@@ -1197,7 +1199,8 @@ static zebra_nhlfe_t *nhlfe_find(zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
  */
 static zebra_nhlfe_t *nhlfe_add(zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
                                enum nexthop_types_t gtype, union g_addr *gate,
-                               ifindex_t ifindex, mpls_label_t out_label)
+                               ifindex_t ifindex, uint8_t num_labels,
+                               mpls_label_t labels[])
 {
        zebra_nhlfe_t *nhlfe;
        struct nexthop *nexthop;
@@ -1216,7 +1219,7 @@ static zebra_nhlfe_t *nhlfe_add(zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
                XFREE(MTYPE_NHLFE, nhlfe);
                return NULL;
        }
-       nexthop_add_labels(nexthop, lsp_type, 1, &out_label);
+       nexthop_add_labels(nexthop, lsp_type, num_labels, labels);
 
        nexthop->vrf_id = VRF_DEFAULT;
        nexthop->type = gtype;
@@ -2083,10 +2086,12 @@ zebra_nhlfe_t *zebra_mpls_lsp_add_nhlfe(zebra_lsp_t *lsp,
                                        enum nexthop_types_t gtype,
                                        union g_addr *gate,
                                        ifindex_t ifindex,
-                                       mpls_label_t out_label)
+                                       uint8_t num_labels,
+                                       mpls_label_t out_labels[])
 {
        /* Just a public pass-through to the internal implementation */
-       return nhlfe_add(lsp, lsp_type, gtype, gate, ifindex, out_label);
+       return nhlfe_add(lsp, lsp_type, gtype, gate, ifindex, num_labels,
+                        out_labels);
 }
 
 /*
@@ -2730,9 +2735,9 @@ int mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
  * the out-label for an existing NHLFE (update case).
  */
 int mpls_lsp_install(struct zebra_vrf *zvrf, enum lsp_types_t type,
-                    mpls_label_t in_label, mpls_label_t out_label,
-                    enum nexthop_types_t gtype, union g_addr *gate,
-                    ifindex_t ifindex)
+                    mpls_label_t in_label, uint8_t num_out_labels,
+                    mpls_label_t out_labels[], enum nexthop_types_t gtype,
+                    union g_addr *gate, ifindex_t ifindex)
 {
        struct hash *lsp_table;
        zebra_ile_t tmp_ile;
@@ -2759,33 +2764,56 @@ int mpls_lsp_install(struct zebra_vrf *zvrf, enum lsp_types_t type,
 
                /* Clear deleted flag (in case it was set) */
                UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED);
-               if (nh->nh_label->label[0] == out_label)
+               if (nh->nh_label->num_labels == num_out_labels
+                   && !memcmp(nh->nh_label->label, out_labels,
+                              sizeof(mpls_label_t) * num_out_labels))
                        /* No change */
                        return 0;
 
                if (IS_ZEBRA_DEBUG_MPLS) {
+                       char buf2[BUFSIZ];
+                       char buf3[BUFSIZ];
+
                        nhlfe2str(nhlfe, buf, BUFSIZ);
+                       mpls_label2str(num_out_labels, out_labels, buf2,
+                                      sizeof(buf2), 0);
+                       mpls_label2str(nh->nh_label->num_labels,
+                                      nh->nh_label->label, buf3, sizeof(buf3),
+                                      0);
+
                        zlog_debug(
                                "LSP in-label %u type %d nexthop %s "
-                               "out-label changed to %u (old %u)",
-                               in_label, type, buf, out_label,
-                               nh->nh_label->label[0]);
+                               "out-label(s) changed to %s (old %s)",
+                               in_label, type, buf, buf2, buf3);
                }
 
-               /* Update out label, trigger processing. */
-               nh->nh_label->label[0] = out_label;
+               /* Update out label(s), trigger processing. */
+               if (nh->nh_label->num_labels == num_out_labels)
+                       memcpy(nh->nh_label->label, out_labels,
+                              sizeof(mpls_label_t) * num_out_labels);
+               else {
+                       nexthop_del_labels(nh);
+                       nexthop_add_labels(nh, type, num_out_labels,
+                                          out_labels);
+               }
        } else {
                /* Add LSP entry to this nexthop */
-               nhlfe = nhlfe_add(lsp, type, gtype, gate, ifindex, out_label);
+               nhlfe = nhlfe_add(lsp, type, gtype, gate, ifindex,
+                                 num_out_labels, out_labels);
                if (!nhlfe)
                        return -1;
 
                if (IS_ZEBRA_DEBUG_MPLS) {
+                       char buf2[BUFSIZ];
+
                        nhlfe2str(nhlfe, buf, BUFSIZ);
+                       mpls_label2str(num_out_labels, out_labels, buf2,
+                                      sizeof(buf2), 0);
+
                        zlog_debug(
                                "Add LSP in-label %u type %d nexthop %s "
-                               "out-label %u",
-                               in_label, type, buf, out_label);
+                               "out-label(s) %s",
+                               in_label, type, buf, buf2);
                }
 
                lsp->addr_family = NHLFE_FAMILY(nhlfe);
@@ -3058,8 +3086,8 @@ int zebra_mpls_static_lsp_add(struct zebra_vrf *zvrf, mpls_label_t in_label,
        }
 
        /* (Re)Install LSP in the main table. */
-       if (mpls_lsp_install(zvrf, ZEBRA_LSP_STATIC, in_label, out_label, gtype,
-                            gate, ifindex))
+       if (mpls_lsp_install(zvrf, ZEBRA_LSP_STATIC, in_label, 1, &out_label,
+                            gtype, gate, ifindex))
                return -1;
 
        return 0;
index 157f43ca9879031e3f82f43dc304b68576f6ebdc..2489e8e51038ff3d3134a50a3b6620b607c02fa5 100644 (file)
@@ -200,7 +200,8 @@ zebra_nhlfe_t *zebra_mpls_lsp_add_nhlfe(zebra_lsp_t *lsp,
                                        enum nexthop_types_t gtype,
                                        union g_addr *gate,
                                        ifindex_t ifindex,
-                                       mpls_label_t out_label);
+                                       uint8_t num_labels,
+                                       mpls_label_t out_labels[]);
 
 /* Free an allocated NHLFE */
 void zebra_mpls_nhlfe_del(zebra_nhlfe_t *nhlfe);
@@ -282,12 +283,12 @@ int mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
 /*
  * Install/update a NHLFE for an LSP in the forwarding table. This may be
  * a new LSP entry or a new NHLFE for an existing in-label or an update of
- * the out-label for an existing NHLFE (update case).
+ * the out-label(s) for an existing NHLFE (update case).
  */
 int mpls_lsp_install(struct zebra_vrf *zvrf, enum lsp_types_t type,
-                    mpls_label_t in_label, mpls_label_t out_label,
-                    enum nexthop_types_t gtype, union g_addr *gate,
-                    ifindex_t ifindex);
+                    mpls_label_t in_label, uint8_t num_out_labels,
+                    mpls_label_t out_labels[], enum nexthop_types_t gtype,
+                    union g_addr *gate, ifindex_t ifindex);
 
 /*
  * Uninstall a particular NHLFE in the forwarding table. If this is