summaryrefslogtreecommitdiff
path: root/zebra/zebra_mpls.c
diff options
context:
space:
mode:
authorRenato Westphal <renato@opensourcerouting.org>2019-11-29 11:50:07 -0300
committerRenato Westphal <renato@opensourcerouting.org>2019-11-29 11:50:07 -0300
commit5065db0aa63137daebf96f8f6c0d9a0fe2ddf594 (patch)
tree630b216689492c024b600b6999602ef037ed8274 /zebra/zebra_mpls.c
parent6fc3fed23c95da21887acb57a92c474e4d0ca3a4 (diff)
zebra: support LSPs with multiple outgoing labels
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>
Diffstat (limited to 'zebra/zebra_mpls.c')
-rw-r--r--zebra/zebra_mpls.c68
1 files changed, 48 insertions, 20 deletions
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c
index 6942a37989..5146311c6a 100644
--- a/zebra/zebra_mpls.c
+++ b/zebra/zebra_mpls.c
@@ -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;