Merge pull request #5442 from opensourcerouting/mpls-label-stacks

zebra: support LSPs with multiple outgoing labels
This commit is contained in:
Russ White 2019-12-03 11:25:53 -05:00 committed by GitHub
commit e25ca4514f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 68 additions and 35 deletions

View File

@ -1782,7 +1782,7 @@ static void zread_mpls_labels_add(ZAPI_HANDLER_ARGS)
struct zapi_nexthop_label *znh; struct zapi_nexthop_label *znh;
znh = &zl.nexthops[i]; 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); znh->type, &znh->address, znh->ifindex);
if (CHECK_FLAG(zl.message, ZAPI_LABELS_FTN)) 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; struct zapi_nexthop_label *znh;
znh = &zl.nexthops[i]; 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); znh->type, &znh->address, znh->ifindex);
if (CHECK_FLAG(zl.message, ZAPI_LABELS_FTN)) { if (CHECK_FLAG(zl.message, ZAPI_LABELS_FTN)) {
@ -2282,10 +2282,11 @@ static void zread_vrf_label(ZAPI_HANDLER_ARGS)
ifp->ifindex); ifp->ifindex);
} }
if (nlabel != MPLS_LABEL_NONE) if (nlabel != MPLS_LABEL_NONE) {
mpls_lsp_install(def_zvrf, ltype, nlabel, mpls_label_t out_label = MPLS_LABEL_IMPLICIT_NULL;
MPLS_LABEL_IMPLICIT_NULL, NEXTHOP_TYPE_IFINDEX, mpls_lsp_install(def_zvrf, ltype, nlabel, 1, &out_label,
NULL, ifp->ifindex); NEXTHOP_TYPE_IFINDEX, NULL, ifp->ifindex);
}
zvrf->label[afi] = nlabel; zvrf->label[afi] = nlabel;
stream_failure: stream_failure:

View File

@ -1161,7 +1161,8 @@ zebra_nhlfe_t *dplane_ctx_add_nhlfe(struct zebra_dplane_ctx *ctx,
enum nexthop_types_t nh_type, enum nexthop_types_t nh_type,
union g_addr *gate, union g_addr *gate,
ifindex_t ifindex, ifindex_t ifindex,
mpls_label_t out_label) uint8_t num_labels,
mpls_label_t out_labels[])
{ {
zebra_nhlfe_t *nhlfe; 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), nhlfe = zebra_mpls_lsp_add_nhlfe(&(ctx->u.lsp),
lsp_type, nh_type, gate, lsp_type, nh_type, gate,
ifindex, out_label); ifindex, num_labels, out_labels);
return nhlfe; return nhlfe;
} }
@ -1660,7 +1661,8 @@ static int dplane_ctx_lsp_init(struct zebra_dplane_ctx *ctx,
nhlfe->nexthop->type, nhlfe->nexthop->type,
&(nhlfe->nexthop->gate), &(nhlfe->nexthop->gate),
nhlfe->nexthop->ifindex, 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) { if (new_nhlfe == NULL || new_nhlfe->nexthop == NULL) {
ret = ENOMEM; ret = ENOMEM;

View File

@ -302,7 +302,8 @@ zebra_nhlfe_t *dplane_ctx_add_nhlfe(struct zebra_dplane_ctx *ctx,
enum nexthop_types_t nh_type, enum nexthop_types_t nh_type,
union g_addr *gate, union g_addr *gate,
ifindex_t ifindex, 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 zebra_nhlfe_t *dplane_ctx_get_best_nhlfe(
const struct zebra_dplane_ctx *ctx); const struct zebra_dplane_ctx *ctx);

View File

@ -102,7 +102,8 @@ static zebra_nhlfe_t *nhlfe_find(zebra_lsp_t *lsp, enum lsp_types_t lsp_type,
ifindex_t ifindex); ifindex_t ifindex);
static zebra_nhlfe_t *nhlfe_add(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, 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 int nhlfe_del(zebra_nhlfe_t *snhlfe);
static void nhlfe_out_label_update(zebra_nhlfe_t *nhlfe, static void nhlfe_out_label_update(zebra_nhlfe_t *nhlfe,
struct mpls_label_stack *nh_label); 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 */ /* Add LSP entry to this nexthop */
nhlfe = nhlfe_add(lsp, lsp_type, nexthop->type, nhlfe = nhlfe_add(lsp, lsp_type, nexthop->type,
&nexthop->gate, nexthop->ifindex, &nexthop->gate, nexthop->ifindex,
nexthop->nh_label->label[0]); nexthop->nh_label->num_labels,
nexthop->nh_label->label);
if (!nhlfe) if (!nhlfe)
return -1; 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, 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, 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; zebra_nhlfe_t *nhlfe;
struct nexthop *nexthop; 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); XFREE(MTYPE_NHLFE, nhlfe);
return NULL; 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->vrf_id = VRF_DEFAULT;
nexthop->type = gtype; nexthop->type = gtype;
@ -2083,10 +2086,12 @@ zebra_nhlfe_t *zebra_mpls_lsp_add_nhlfe(zebra_lsp_t *lsp,
enum nexthop_types_t gtype, enum nexthop_types_t gtype,
union g_addr *gate, union g_addr *gate,
ifindex_t ifindex, 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 */ /* 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). * the out-label for an existing NHLFE (update case).
*/ */
int mpls_lsp_install(struct zebra_vrf *zvrf, enum lsp_types_t type, int mpls_lsp_install(struct zebra_vrf *zvrf, enum lsp_types_t type,
mpls_label_t in_label, mpls_label_t out_label, mpls_label_t in_label, uint8_t num_out_labels,
enum nexthop_types_t gtype, union g_addr *gate, mpls_label_t out_labels[], enum nexthop_types_t gtype,
ifindex_t ifindex) union g_addr *gate, ifindex_t ifindex)
{ {
struct hash *lsp_table; struct hash *lsp_table;
zebra_ile_t tmp_ile; 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) */ /* Clear deleted flag (in case it was set) */
UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_DELETED); 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 */ /* No change */
return 0; return 0;
if (IS_ZEBRA_DEBUG_MPLS) { if (IS_ZEBRA_DEBUG_MPLS) {
char buf2[BUFSIZ];
char buf3[BUFSIZ];
nhlfe2str(nhlfe, buf, 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( zlog_debug(
"LSP in-label %u type %d nexthop %s " "LSP in-label %u type %d nexthop %s "
"out-label changed to %u (old %u)", "out-label(s) changed to %s (old %s)",
in_label, type, buf, out_label, in_label, type, buf, buf2, buf3);
nh->nh_label->label[0]);
} }
/* Update out label, trigger processing. */ /* Update out label(s), trigger processing. */
nh->nh_label->label[0] = out_label; 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 { } else {
/* Add LSP entry to this nexthop */ /* 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) if (!nhlfe)
return -1; return -1;
if (IS_ZEBRA_DEBUG_MPLS) { if (IS_ZEBRA_DEBUG_MPLS) {
char buf2[BUFSIZ];
nhlfe2str(nhlfe, buf, BUFSIZ); nhlfe2str(nhlfe, buf, BUFSIZ);
mpls_label2str(num_out_labels, out_labels, buf2,
sizeof(buf2), 0);
zlog_debug( zlog_debug(
"Add LSP in-label %u type %d nexthop %s " "Add LSP in-label %u type %d nexthop %s "
"out-label %u", "out-label(s) %s",
in_label, type, buf, out_label); in_label, type, buf, buf2);
} }
lsp->addr_family = NHLFE_FAMILY(nhlfe); 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. */ /* (Re)Install LSP in the main table. */
if (mpls_lsp_install(zvrf, ZEBRA_LSP_STATIC, in_label, out_label, gtype, if (mpls_lsp_install(zvrf, ZEBRA_LSP_STATIC, in_label, 1, &out_label,
gate, ifindex)) gtype, gate, ifindex))
return -1; return -1;
return 0; return 0;

View File

@ -200,7 +200,8 @@ zebra_nhlfe_t *zebra_mpls_lsp_add_nhlfe(zebra_lsp_t *lsp,
enum nexthop_types_t gtype, enum nexthop_types_t gtype,
union g_addr *gate, union g_addr *gate,
ifindex_t ifindex, ifindex_t ifindex,
mpls_label_t out_label); uint8_t num_labels,
mpls_label_t out_labels[]);
/* Free an allocated NHLFE */ /* Free an allocated NHLFE */
void zebra_mpls_nhlfe_del(zebra_nhlfe_t *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 * 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 * 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, int mpls_lsp_install(struct zebra_vrf *zvrf, enum lsp_types_t type,
mpls_label_t in_label, mpls_label_t out_label, mpls_label_t in_label, uint8_t num_out_labels,
enum nexthop_types_t gtype, union g_addr *gate, mpls_label_t out_labels[], enum nexthop_types_t gtype,
ifindex_t ifindex); union g_addr *gate, ifindex_t ifindex);
/* /*
* Uninstall a particular NHLFE in the forwarding table. If this is * Uninstall a particular NHLFE in the forwarding table. If this is