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))
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)) {
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:
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);
/* 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;
*/
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;
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;
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);
}
/*
* 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;
/* 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);
}
/* (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;