mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-09 07:56:29 +00:00
Merge pull request #5442 from opensourcerouting/mpls-label-stacks
zebra: support LSPs with multiple outgoing labels
This commit is contained in:
commit
e25ca4514f
@ -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:
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user