summaryrefslogtreecommitdiff
path: root/zebra/zebra_mpls.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/zebra_mpls.c')
-rw-r--r--zebra/zebra_mpls.c460
1 files changed, 151 insertions, 309 deletions
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c
index 03b8c8de1f..dc49695019 100644
--- a/zebra/zebra_mpls.c
+++ b/zebra/zebra_mpls.c
@@ -52,10 +52,7 @@
DEFINE_MTYPE_STATIC(ZEBRA, LSP, "MPLS LSP object")
DEFINE_MTYPE_STATIC(ZEBRA, FEC, "MPLS FEC object")
-DEFINE_MTYPE_STATIC(ZEBRA, SLSP, "MPLS static LSP config")
DEFINE_MTYPE_STATIC(ZEBRA, NHLFE, "MPLS nexthop object")
-DEFINE_MTYPE_STATIC(ZEBRA, SNHLFE, "MPLS static nexthop object")
-DEFINE_MTYPE_STATIC(ZEBRA, SNHLFE_IFNAME, "MPLS static nexthop ifname")
int mpls_enabled;
@@ -101,7 +98,8 @@ static void lsp_check_free(struct hash *lsp_table, zebra_lsp_t **plsp);
/* Free lsp; sets caller's pointer to NULL */
static void lsp_free(struct hash *lsp_table, zebra_lsp_t **plsp);
-static char *nhlfe2str(zebra_nhlfe_t *nhlfe, char *buf, int size);
+static char *nhlfe2str(const zebra_nhlfe_t *nhlfe, char *buf, int size);
+static char *nhlfe_config_str(const zebra_nhlfe_t *nhlfe, char *buf, int size);
static int nhlfe_nhop_match(zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype,
const union g_addr *gate, ifindex_t ifindex);
static zebra_nhlfe_t *nhlfe_find(struct nhlfe_list_head *list,
@@ -124,19 +122,6 @@ static int mpls_static_lsp_uninstall_all(struct zebra_vrf *zvrf,
static void nhlfe_print(zebra_nhlfe_t *nhlfe, struct vty *vty,
const char *indent);
static void lsp_print(struct vty *vty, zebra_lsp_t *lsp);
-static void *slsp_alloc(void *p);
-static int snhlfe_match(zebra_snhlfe_t *snhlfe, enum nexthop_types_t gtype,
- const union g_addr *gate, ifindex_t ifindex);
-static zebra_snhlfe_t *snhlfe_find(zebra_slsp_t *slsp,
- enum nexthop_types_t gtype,
- const union g_addr *gate, ifindex_t ifindex);
-static zebra_snhlfe_t *snhlfe_add(zebra_slsp_t *slsp,
- enum nexthop_types_t gtype,
- const union g_addr *gate, ifindex_t ifindex,
- mpls_label_t out_label);
-static int snhlfe_del(zebra_snhlfe_t *snhlfe);
-static int snhlfe_del_all(zebra_slsp_t *slsp);
-static char *snhlfe2str(zebra_snhlfe_t *snhlfe, char *buf, int size);
static void mpls_lsp_uninstall_all_type(struct hash_bucket *bucket, void *ctxt);
static void mpls_ftn_uninstall_all(struct zebra_vrf *zvrf,
int afi, enum lsp_types_t lsp_type);
@@ -145,9 +130,6 @@ static int lsp_znh_install(zebra_lsp_t *lsp, enum lsp_types_t type,
static int lsp_backup_znh_install(zebra_lsp_t *lsp, enum lsp_types_t type,
const struct zapi_nexthop *znh);
-/* List implementations - declare internal linkage */
-DECLARE_DLIST(snhlfe_list, struct zebra_snhlfe_t_, list);
-
/* Static functions */
/*
@@ -349,7 +331,6 @@ static void fec_evaluate(struct zebra_vrf *zvrf)
zebra_fec_t *fec;
uint32_t old_label, new_label;
int af;
- char buf[BUFSIZ];
for (af = AFI_IP; af < AFI_MAX; af++) {
if (zvrf->fec_table[af] == NULL)
@@ -366,9 +347,6 @@ static void fec_evaluate(struct zebra_vrf *zvrf)
|| fec->label_index == MPLS_INVALID_LABEL_INDEX)
continue;
- if (IS_ZEBRA_DEBUG_MPLS)
- prefix2str(&rn->p, buf, BUFSIZ);
-
/* Save old label, determine new label. */
old_label = fec->label;
new_label =
@@ -382,8 +360,8 @@ static void fec_evaluate(struct zebra_vrf *zvrf)
if (IS_ZEBRA_DEBUG_MPLS)
zlog_debug(
- "Update fec %s new label %u upon label block",
- buf, new_label);
+ "Update fec %pRN new label %u upon label block",
+ rn, new_label);
fec->label = new_label;
fec_update_clients(fec);
@@ -512,8 +490,7 @@ static void fec_print(zebra_fec_t *fec, struct vty *vty)
char buf[BUFSIZ];
rn = fec->rn;
- prefix2str(&rn->p, buf, BUFSIZ);
- vty_out(vty, "%s\n", buf);
+ vty_out(vty, "%pRN\n", rn);
vty_out(vty, " Label: %s", label2str(fec->label, buf, BUFSIZ));
if (fec->label_index != MPLS_INVALID_LABEL_INDEX)
vty_out(vty, ", Label Index: %u", fec->label_index);
@@ -1173,9 +1150,9 @@ static void lsp_free(struct hash *lsp_table, zebra_lsp_t **plsp)
/*
* Create printable string for NHLFE entry.
*/
-static char *nhlfe2str(zebra_nhlfe_t *nhlfe, char *buf, int size)
+static char *nhlfe2str(const zebra_nhlfe_t *nhlfe, char *buf, int size)
{
- struct nexthop *nexthop;
+ const struct nexthop *nexthop;
buf[0] = '\0';
nexthop = nhlfe->nexthop;
@@ -1414,7 +1391,7 @@ static int mpls_lsp_uninstall_all(struct hash *lsp_table, zebra_lsp_t *lsp,
continue;
if (IS_ZEBRA_DEBUG_MPLS) {
- nhlfe2str(nhlfe, buf, BUFSIZ);
+ nhlfe2str(nhlfe, buf, sizeof(buf));
zlog_debug(
"Del LSP in-label %u type %d nexthop %s flags 0x%x",
lsp->ile.in_label, type, buf, nhlfe->flags);
@@ -1435,7 +1412,7 @@ static int mpls_lsp_uninstall_all(struct hash *lsp_table, zebra_lsp_t *lsp,
continue;
if (IS_ZEBRA_DEBUG_MPLS) {
- nhlfe2str(nhlfe, buf, BUFSIZ);
+ nhlfe2str(nhlfe, buf, sizeof(buf));
zlog_debug(
"Del backup LSP in-label %u type %d nexthop %s flags 0x%x",
lsp->ile.in_label, type, buf, nhlfe->flags);
@@ -1520,7 +1497,8 @@ static json_object *nhlfe_json(zebra_nhlfe_t *nhlfe)
case NEXTHOP_TYPE_IPV4:
case NEXTHOP_TYPE_IPV4_IFINDEX:
json_object_string_add(json_nhlfe, "nexthop",
- inet_ntoa(nexthop->gate.ipv4));
+ inet_ntop(AF_INET, &nexthop->gate.ipv4,
+ buf, sizeof(buf)));
break;
case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX:
@@ -1578,7 +1556,7 @@ static void nhlfe_print(zebra_nhlfe_t *nhlfe, struct vty *vty,
switch (nexthop->type) {
case NEXTHOP_TYPE_IPV4:
case NEXTHOP_TYPE_IPV4_IFINDEX:
- vty_out(vty, " via %s", inet_ntoa(nexthop->gate.ipv4));
+ vty_out(vty, " via %pI4", &nexthop->gate.ipv4);
if (nexthop->ifindex)
vty_out(vty, " dev %s",
ifindex2ifname(nexthop->ifindex,
@@ -1711,188 +1689,6 @@ static int lsp_cmp(const zebra_lsp_t *lsp1, const zebra_lsp_t *lsp2)
}
/*
- * Callback to allocate static LSP.
- */
-static void *slsp_alloc(void *p)
-{
- const zebra_ile_t *ile = p;
- zebra_slsp_t *slsp;
-
- slsp = XCALLOC(MTYPE_SLSP, sizeof(zebra_slsp_t));
- slsp->ile = *ile;
- snhlfe_list_init(&slsp->snhlfe_list);
-
- return ((void *)slsp);
-}
-
-/*
- * Compare two static LSPs based on their label values.
- */
-static int slsp_cmp(const zebra_slsp_t *slsp1, const zebra_slsp_t *slsp2)
-{
- if (slsp1->ile.in_label < slsp2->ile.in_label)
- return -1;
-
- if (slsp1->ile.in_label > slsp2->ile.in_label)
- return 1;
-
- return 0;
-}
-
-/*
- * Check if static NHLFE matches with search info passed.
- */
-static int snhlfe_match(zebra_snhlfe_t *snhlfe, enum nexthop_types_t gtype,
- const union g_addr *gate, ifindex_t ifindex)
-{
- int cmp = 1;
-
- if (snhlfe->gtype != gtype)
- return 1;
-
- switch (snhlfe->gtype) {
- case NEXTHOP_TYPE_IPV4:
- cmp = memcmp(&(snhlfe->gate.ipv4), &(gate->ipv4),
- sizeof(struct in_addr));
- break;
- case NEXTHOP_TYPE_IPV6:
- case NEXTHOP_TYPE_IPV6_IFINDEX:
- cmp = memcmp(&(snhlfe->gate.ipv6), &(gate->ipv6),
- sizeof(struct in6_addr));
- if (!cmp && snhlfe->gtype == NEXTHOP_TYPE_IPV6_IFINDEX)
- cmp = !(snhlfe->ifindex == ifindex);
- break;
- default:
- break;
- }
-
- return cmp;
-}
-
-/*
- * Locate static NHLFE that matches with passed info.
- */
-static zebra_snhlfe_t *snhlfe_find(zebra_slsp_t *slsp,
- enum nexthop_types_t gtype,
- const union g_addr *gate, ifindex_t ifindex)
-{
- zebra_snhlfe_t *snhlfe;
-
- if (!slsp)
- return NULL;
-
- frr_each_safe(snhlfe_list, &slsp->snhlfe_list, snhlfe) {
- if (!snhlfe_match(snhlfe, gtype, gate, ifindex))
- break;
- }
-
- return snhlfe;
-}
-
-
-/*
- * Add static NHLFE. Base LSP config entry must have been created
- * and duplicate check done.
- */
-static zebra_snhlfe_t *snhlfe_add(zebra_slsp_t *slsp,
- enum nexthop_types_t gtype,
- const union g_addr *gate, ifindex_t ifindex,
- mpls_label_t out_label)
-{
- zebra_snhlfe_t *snhlfe;
-
- if (!slsp)
- return NULL;
-
- snhlfe = XCALLOC(MTYPE_SNHLFE, sizeof(zebra_snhlfe_t));
- snhlfe->slsp = slsp;
- snhlfe->out_label = out_label;
- snhlfe->gtype = gtype;
- switch (gtype) {
- case NEXTHOP_TYPE_IPV4:
- snhlfe->gate.ipv4 = gate->ipv4;
- break;
- case NEXTHOP_TYPE_IPV6:
- case NEXTHOP_TYPE_IPV6_IFINDEX:
- snhlfe->gate.ipv6 = gate->ipv6;
- if (ifindex)
- snhlfe->ifindex = ifindex;
- break;
- default:
- XFREE(MTYPE_SNHLFE, snhlfe);
- return NULL;
- }
-
- snhlfe_list_add_head(&slsp->snhlfe_list, snhlfe);
-
- return snhlfe;
-}
-
-/*
- * Delete static NHLFE. Entry must be present on list.
- */
-static int snhlfe_del(zebra_snhlfe_t *snhlfe)
-{
- zebra_slsp_t *slsp;
-
- if (!snhlfe)
- return -1;
-
- slsp = snhlfe->slsp;
- if (!slsp)
- return -1;
-
- snhlfe_list_del(&slsp->snhlfe_list, snhlfe);
-
- XFREE(MTYPE_SNHLFE_IFNAME, snhlfe->ifname);
- XFREE(MTYPE_SNHLFE, snhlfe);
-
- return 0;
-}
-
-/*
- * Delete all static NHLFE entries for this LSP (in label).
- */
-static int snhlfe_del_all(zebra_slsp_t *slsp)
-{
- zebra_snhlfe_t *snhlfe;
-
- if (!slsp)
- return -1;
-
- frr_each_safe(snhlfe_list, &slsp->snhlfe_list, snhlfe) {
- snhlfe_del(snhlfe);
- }
-
- return 0;
-}
-
-/*
- * Create printable string for NHLFE configuration.
- */
-static char *snhlfe2str(zebra_snhlfe_t *snhlfe, char *buf, int size)
-{
- buf[0] = '\0';
- switch (snhlfe->gtype) {
- case NEXTHOP_TYPE_IPV4:
- inet_ntop(AF_INET, &snhlfe->gate.ipv4, buf, size);
- break;
- case NEXTHOP_TYPE_IPV6:
- case NEXTHOP_TYPE_IPV6_IFINDEX:
- inet_ntop(AF_INET6, &snhlfe->gate.ipv6, buf, size);
- if (snhlfe->ifindex)
- strlcat(buf,
- ifindex2ifname(snhlfe->ifindex, VRF_DEFAULT),
- size);
- break;
- default:
- break;
- }
-
- return buf;
-}
-
-/*
* Initialize work queue for processing changed LSPs.
*/
static int mpls_processq_init(void)
@@ -2443,7 +2239,6 @@ int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p,
{
struct route_table *table;
zebra_fec_t *fec;
- char buf[BUFSIZ];
bool new_client;
bool label_change = false;
uint32_t old_label;
@@ -2454,14 +2249,11 @@ int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p,
if (!table)
return -1;
- if (IS_ZEBRA_DEBUG_MPLS)
- prefix2str(p, buf, BUFSIZ);
-
if (label != MPLS_INVALID_LABEL && have_label_index) {
flog_err(
EC_ZEBRA_FEC_LABEL_INDEX_LABEL_CONFLICT,
- "Rejecting FEC register for %s with both label %u and Label Index %u specified, client %s",
- buf, label, label_index,
+ "Rejecting FEC register for %pFX with both label %u and Label Index %u specified, client %s",
+ p, label, label_index,
zebra_route_string(client->proto));
return -1;
}
@@ -2473,8 +2265,8 @@ int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p,
if (!fec) {
flog_err(
EC_ZEBRA_FEC_ADD_FAILED,
- "Failed to add FEC %s upon register, client %s",
- buf, zebra_route_string(client->proto));
+ "Failed to add FEC %pFX upon register, client %s",
+ p, zebra_route_string(client->proto));
return -1;
}
@@ -2500,7 +2292,7 @@ int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p,
listnode_add(fec->client_list, client);
if (IS_ZEBRA_DEBUG_MPLS)
- zlog_debug("FEC %s label%s %u %s by client %s%s", buf,
+ zlog_debug("FEC %pFX label%s %u %s by client %s%s", p,
have_label_index ? " index" : "",
have_label_index ? label_index : label,
new_client ? "registered" : "updated",
@@ -2551,28 +2343,23 @@ int zebra_mpls_fec_unregister(struct zebra_vrf *zvrf, struct prefix *p,
{
struct route_table *table;
zebra_fec_t *fec;
- char buf[BUFSIZ];
table = zvrf->fec_table[family2afi(PREFIX_FAMILY(p))];
if (!table)
return -1;
- if (IS_ZEBRA_DEBUG_MPLS)
- prefix2str(p, buf, BUFSIZ);
-
fec = fec_find(table, p);
if (!fec) {
- prefix2str(p, buf, BUFSIZ);
flog_err(EC_ZEBRA_FEC_RM_FAILED,
- "Failed to find FEC %s upon unregister, client %s",
- buf, zebra_route_string(client->proto));
+ "Failed to find FEC %pFX upon unregister, client %s",
+ p, zebra_route_string(client->proto));
return -1;
}
listnode_delete(fec->client_list, client);
if (IS_ZEBRA_DEBUG_MPLS)
- zlog_debug("FEC %s unregistered by client %s", buf,
+ zlog_debug("FEC %pFX unregistered by client %s", p,
zebra_route_string(client->proto));
/* If not a configured entry, delete the FEC if no other clients. Before
@@ -2713,7 +2500,6 @@ int zebra_mpls_static_fec_add(struct zebra_vrf *zvrf, struct prefix *p,
{
struct route_table *table;
zebra_fec_t *fec;
- char buf[BUFSIZ];
mpls_label_t old_label;
int ret = 0;
@@ -2721,23 +2507,19 @@ int zebra_mpls_static_fec_add(struct zebra_vrf *zvrf, struct prefix *p,
if (!table)
return -1;
- if (IS_ZEBRA_DEBUG_MPLS)
- prefix2str(p, buf, BUFSIZ);
-
/* Update existing FEC or create a new one. */
fec = fec_find(table, p);
if (!fec) {
fec = fec_add(table, p, in_label, FEC_FLAG_CONFIGURED,
MPLS_INVALID_LABEL_INDEX);
if (!fec) {
- prefix2str(p, buf, BUFSIZ);
flog_err(EC_ZEBRA_FEC_ADD_FAILED,
- "Failed to add FEC %s upon config", buf);
+ "Failed to add FEC %pFX upon config", p);
return -1;
}
if (IS_ZEBRA_DEBUG_MPLS)
- zlog_debug("Add fec %s label %u", buf, in_label);
+ zlog_debug("Add fec %pFX label %u", p, in_label);
} else {
fec->flags |= FEC_FLAG_CONFIGURED;
if (fec->label == in_label)
@@ -2747,7 +2529,7 @@ int zebra_mpls_static_fec_add(struct zebra_vrf *zvrf, struct prefix *p,
/* Label change, update clients. */
old_label = fec->label;
if (IS_ZEBRA_DEBUG_MPLS)
- zlog_debug("Update fec %s new label %u", buf, in_label);
+ zlog_debug("Update fec %pFX new label %u", p, in_label);
fec->label = in_label;
fec_update_clients(fec);
@@ -2770,7 +2552,6 @@ int zebra_mpls_static_fec_del(struct zebra_vrf *zvrf, struct prefix *p)
struct route_table *table;
zebra_fec_t *fec;
mpls_label_t old_label;
- char buf[BUFSIZ];
table = zvrf->fec_table[family2afi(PREFIX_FAMILY(p))];
if (!table)
@@ -2778,15 +2559,13 @@ int zebra_mpls_static_fec_del(struct zebra_vrf *zvrf, struct prefix *p)
fec = fec_find(table, p);
if (!fec) {
- prefix2str(p, buf, BUFSIZ);
flog_err(EC_ZEBRA_FEC_RM_FAILED,
- "Failed to find FEC %s upon delete", buf);
+ "Failed to find FEC %pFX upon delete", p);
return -1;
}
if (IS_ZEBRA_DEBUG_MPLS) {
- prefix2str(p, buf, BUFSIZ);
- zlog_debug("Delete fec %s label %u label index %u", buf,
+ zlog_debug("Delete fec %pFX label %u label index %u", p,
fec->label, fec->label_index);
}
@@ -2820,7 +2599,6 @@ int zebra_mpls_write_fec_config(struct vty *vty, struct zebra_vrf *zvrf)
struct route_node *rn;
int af;
zebra_fec_t *fec;
- char buf[BUFSIZ];
int write = 0;
for (af = AFI_IP; af < AFI_MAX; af++) {
@@ -2839,8 +2617,7 @@ int zebra_mpls_write_fec_config(struct vty *vty, struct zebra_vrf *zvrf)
continue;
write = 1;
- prefix2str(&rn->p, buf, BUFSIZ);
- vty_out(vty, "mpls label bind %s %s\n", buf,
+ vty_out(vty, "mpls label bind %pFX %s\n", &rn->p,
label2str(fec->label, lstr, BUFSIZ));
}
}
@@ -3046,7 +2823,7 @@ int mpls_zapi_labels_process(bool add_p, struct zebra_vrf *zvrf,
const struct zapi_labels *zl)
{
int i, counter, ret = 0;
- char buf[NEXTHOP_STRLEN], prefix_buf[PREFIX_STRLEN];
+ char buf[NEXTHOP_STRLEN];
const struct zapi_nexthop *znh;
struct route_table *table;
struct route_node *rn = NULL;
@@ -3110,12 +2887,10 @@ int mpls_zapi_labels_process(bool add_p, struct zebra_vrf *zvrf,
* attempted to manage LSPs before trying to
* find a route/FEC, so we'll continue that way.
*/
- if (IS_ZEBRA_DEBUG_RECV || IS_ZEBRA_DEBUG_MPLS) {
- prefix2str(prefix, prefix_buf,
- sizeof(prefix_buf));
- zlog_debug("%s: FTN update requested: no route for prefix %s",
- __func__, prefix_buf);
- }
+ if (IS_ZEBRA_DEBUG_RECV || IS_ZEBRA_DEBUG_MPLS)
+ zlog_debug(
+ "%s: FTN update requested: no route for prefix %pFX",
+ __func__, prefix);
}
}
@@ -3157,9 +2932,9 @@ int mpls_zapi_labels_process(bool add_p, struct zebra_vrf *zvrf,
counter++;
} else if (IS_ZEBRA_DEBUG_RECV | IS_ZEBRA_DEBUG_MPLS) {
zapi_nexthop2str(znh, buf, sizeof(buf));
- prefix2str(prefix, prefix_buf, sizeof(prefix_buf));
- zlog_debug("%s: Unable to update FEC: prefix %s, label %u, znh %s",
- __func__, prefix_buf, zl->local_label, buf);
+ zlog_debug(
+ "%s: Unable to update FEC: prefix %pFX, label %u, znh %s",
+ __func__, prefix, zl->local_label, buf);
}
}
@@ -3207,9 +2982,9 @@ int mpls_zapi_labels_process(bool add_p, struct zebra_vrf *zvrf,
counter++;
} else if (IS_ZEBRA_DEBUG_RECV | IS_ZEBRA_DEBUG_MPLS) {
zapi_nexthop2str(znh, buf, sizeof(buf));
- prefix2str(prefix, prefix_buf, sizeof(prefix_buf));
- zlog_debug("%s: Unable to update backup FEC: prefix %s, label %u, znh %s",
- __func__, prefix_buf, zl->local_label, buf);
+ zlog_debug(
+ "%s: Unable to update backup FEC: prefix %pFX, label %u, znh %s",
+ __func__, prefix, zl->local_label, buf);
}
}
@@ -3633,8 +3408,9 @@ int zebra_mpls_lsp_label_consistent(struct zebra_vrf *zvrf,
{
struct hash *slsp_table;
zebra_ile_t tmp_ile;
- zebra_slsp_t *slsp;
- zebra_snhlfe_t *snhlfe;
+ zebra_lsp_t *lsp;
+ zebra_nhlfe_t *nhlfe;
+ const struct nexthop *nh;
/* Lookup table. */
slsp_table = zvrf->slsp_table;
@@ -3643,26 +3419,37 @@ int zebra_mpls_lsp_label_consistent(struct zebra_vrf *zvrf,
/* If entry is not present, exit. */
tmp_ile.in_label = in_label;
- slsp = hash_lookup(slsp_table, &tmp_ile);
- if (!slsp)
+ lsp = hash_lookup(slsp_table, &tmp_ile);
+ if (!lsp)
return 1;
- snhlfe = snhlfe_find(slsp, gtype, gate, ifindex);
- if (snhlfe) {
- if (snhlfe->out_label == out_label)
+ nhlfe = nhlfe_find(&lsp->nhlfe_list, ZEBRA_LSP_STATIC,
+ gtype, gate, ifindex);
+ if (nhlfe) {
+ nh = nhlfe->nexthop;
+
+ if (nh == NULL || nh->nh_label == NULL)
+ return 0;
+
+ if (nh->nh_label->label[0] == out_label)
return 1;
/* If not only NHLFE, cannot allow label change. */
- if (snhlfe != snhlfe_list_first(&slsp->snhlfe_list) ||
- snhlfe_list_next(&slsp->snhlfe_list, snhlfe) != NULL)
+ if (nhlfe != nhlfe_list_first(&lsp->nhlfe_list) ||
+ nhlfe_list_next(&lsp->nhlfe_list, nhlfe) != NULL)
return 0;
} else {
/* If other NHLFEs exist, label operation must match. */
- snhlfe = snhlfe_list_first(&slsp->snhlfe_list);
- if (snhlfe != NULL) {
+ nhlfe = nhlfe_list_first(&lsp->nhlfe_list);
+ if (nhlfe != NULL) {
int cur_op, new_op;
- cur_op = (snhlfe->out_label ==
+ nh = nhlfe->nexthop;
+
+ if (nh == NULL || nh->nh_label == NULL)
+ return 0;
+
+ cur_op = (nh->nh_label->label[0] ==
MPLS_LABEL_IMPLICIT_NULL);
new_op = (out_label == MPLS_LABEL_IMPLICIT_NULL);
if (cur_op != new_op)
@@ -3689,8 +3476,8 @@ int zebra_mpls_static_lsp_add(struct zebra_vrf *zvrf, mpls_label_t in_label,
{
struct hash *slsp_table;
zebra_ile_t tmp_ile;
- zebra_slsp_t *slsp;
- zebra_snhlfe_t *snhlfe;
+ zebra_lsp_t *lsp;
+ zebra_nhlfe_t *nhlfe;
char buf[BUFSIZ];
/* Lookup table. */
@@ -3700,31 +3487,47 @@ int zebra_mpls_static_lsp_add(struct zebra_vrf *zvrf, mpls_label_t in_label,
/* Find or create LSP. */
tmp_ile.in_label = in_label;
- slsp = hash_get(slsp_table, &tmp_ile, slsp_alloc);
- if (!slsp)
+ lsp = hash_get(slsp_table, &tmp_ile, lsp_alloc);
+ if (!lsp)
return -1;
- snhlfe = snhlfe_find(slsp, gtype, gate, ifindex);
- if (snhlfe) {
- if (snhlfe->out_label == out_label)
+ nhlfe = nhlfe_find(&lsp->nhlfe_list, ZEBRA_LSP_STATIC, gtype, gate,
+ ifindex);
+ if (nhlfe) {
+ struct nexthop *nh = nhlfe->nexthop;
+
+ assert(nh);
+ assert(nh->nh_label);
+
+ /* Compare existing nexthop */
+ if (nh->nh_label->num_labels == 1 &&
+ nh->nh_label->label[0] == out_label)
/* No change */
return 0;
if (IS_ZEBRA_DEBUG_MPLS) {
- snhlfe2str(snhlfe, buf, sizeof(buf));
+ nhlfe2str(nhlfe, buf, sizeof(buf));
zlog_debug(
"Upd static LSP in-label %u nexthop %s out-label %u (old %u)",
- in_label, buf, out_label, snhlfe->out_label);
+ in_label, buf, out_label,
+ nh->nh_label->label[0]);
+ }
+ if (nh->nh_label->num_labels == 1)
+ nh->nh_label->label[0] = out_label;
+ else {
+ nexthop_del_labels(nh);
+ nexthop_add_labels(nh, ZEBRA_LSP_STATIC, 1, &out_label);
}
- snhlfe->out_label = out_label;
+
} else {
/* Add static LSP entry to this nexthop */
- snhlfe = snhlfe_add(slsp, gtype, gate, ifindex, out_label);
- if (!snhlfe)
+ nhlfe = nhlfe_add(lsp, ZEBRA_LSP_STATIC, gtype, gate,
+ ifindex, 1, &out_label, false /*backup*/);
+ if (!nhlfe)
return -1;
if (IS_ZEBRA_DEBUG_MPLS) {
- snhlfe2str(snhlfe, buf, sizeof(buf));
+ nhlfe2str(nhlfe, buf, sizeof(buf));
zlog_debug(
"Add static LSP in-label %u nexthop %s out-label %u",
in_label, buf, out_label);
@@ -3752,8 +3555,8 @@ int zebra_mpls_static_lsp_del(struct zebra_vrf *zvrf, mpls_label_t in_label,
{
struct hash *slsp_table;
zebra_ile_t tmp_ile;
- zebra_slsp_t *slsp;
- zebra_snhlfe_t *snhlfe;
+ zebra_lsp_t *lsp;
+ zebra_nhlfe_t *nhlfe;
/* Lookup table. */
slsp_table = zvrf->slsp_table;
@@ -3762,8 +3565,8 @@ int zebra_mpls_static_lsp_del(struct zebra_vrf *zvrf, mpls_label_t in_label,
/* If entry is not present, exit. */
tmp_ile.in_label = in_label;
- slsp = hash_lookup(slsp_table, &tmp_ile);
- if (!slsp)
+ lsp = hash_lookup(slsp_table, &tmp_ile);
+ if (!lsp)
return 0;
/* Is it delete of entire LSP or a specific NHLFE? */
@@ -3775,16 +3578,19 @@ int zebra_mpls_static_lsp_del(struct zebra_vrf *zvrf, mpls_label_t in_label,
mpls_static_lsp_uninstall_all(zvrf, in_label);
/* Delete all static NHLFEs */
- snhlfe_del_all(slsp);
+ frr_each_safe(nhlfe_list, &lsp->nhlfe_list, nhlfe) {
+ nhlfe_del(nhlfe);
+ }
} else {
/* Find specific NHLFE, exit if not found. */
- snhlfe = snhlfe_find(slsp, gtype, gate, ifindex);
- if (!snhlfe)
+ nhlfe = nhlfe_find(&lsp->nhlfe_list, ZEBRA_LSP_STATIC,
+ gtype, gate, ifindex);
+ if (!nhlfe)
return 0;
if (IS_ZEBRA_DEBUG_MPLS) {
char buf[BUFSIZ];
- snhlfe2str(snhlfe, buf, BUFSIZ);
+ nhlfe2str(nhlfe, buf, sizeof(buf));
zlog_debug("Del static LSP in-label %u nexthop %s",
in_label, buf);
}
@@ -3794,14 +3600,15 @@ int zebra_mpls_static_lsp_del(struct zebra_vrf *zvrf, mpls_label_t in_label,
gate, ifindex, false);
/* Delete static LSP NHLFE */
- snhlfe_del(snhlfe);
+ nhlfe_del(nhlfe);
}
/* Remove entire static LSP entry if no NHLFE - valid in either case
- * above. */
- if (snhlfe_list_first(&slsp->snhlfe_list) == NULL) {
- slsp = hash_release(slsp_table, &tmp_ile);
- XFREE(MTYPE_SLSP, slsp);
+ * above.
+ */
+ if (nhlfe_list_first(&lsp->nhlfe_list) == NULL) {
+ lsp = hash_release(slsp_table, &tmp_ile);
+ XFREE(MTYPE_LSP, lsp);
}
return 0;
@@ -3949,23 +3756,58 @@ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf,
}
/*
+ * Create printable string for static LSP configuration.
+ */
+static char *nhlfe_config_str(const zebra_nhlfe_t *nhlfe, char *buf, int size)
+{
+ const struct nexthop *nh;
+
+ nh = nhlfe->nexthop;
+
+ buf[0] = '\0';
+ switch (nh->type) {
+ case NEXTHOP_TYPE_IPV4:
+ inet_ntop(AF_INET, &nh->gate.ipv4, buf, size);
+ break;
+ case NEXTHOP_TYPE_IPV6:
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ inet_ntop(AF_INET6, &nh->gate.ipv6, buf, size);
+ if (nh->ifindex)
+ strlcat(buf,
+ ifindex2ifname(nh->ifindex, VRF_DEFAULT),
+ size);
+ break;
+ default:
+ break;
+ }
+
+ return buf;
+}
+
+/*
* Display MPLS LSP configuration of all static LSPs (VTY command handler).
*/
int zebra_mpls_write_lsp_config(struct vty *vty, struct zebra_vrf *zvrf)
{
- zebra_slsp_t *slsp;
- zebra_snhlfe_t *snhlfe;
+ zebra_lsp_t *lsp;
+ zebra_nhlfe_t *nhlfe;
+ struct nexthop *nh;
struct listnode *node;
struct list *slsp_list =
- hash_get_sorted_list(zvrf->slsp_table, slsp_cmp);
+ hash_get_sorted_list(zvrf->slsp_table, lsp_cmp);
- for (ALL_LIST_ELEMENTS_RO(slsp_list, node, slsp)) {
- frr_each(snhlfe_list, &slsp->snhlfe_list, snhlfe) {
+ for (ALL_LIST_ELEMENTS_RO(slsp_list, node, lsp)) {
+ frr_each(nhlfe_list, &lsp->nhlfe_list, nhlfe) {
char buf[BUFSIZ];
char lstr[30];
- snhlfe2str(snhlfe, buf, sizeof(buf));
- switch (snhlfe->out_label) {
+ nh = nhlfe->nexthop;
+ if (nh == NULL || nh->nh_label == NULL)
+ continue;
+
+ nhlfe_config_str(nhlfe, buf, sizeof(buf));
+
+ switch (nh->nh_label->label[0]) {
case MPLS_LABEL_IPV4_EXPLICIT_NULL:
case MPLS_LABEL_IPV6_EXPLICIT_NULL:
strlcpy(lstr, "explicit-null", sizeof(lstr));
@@ -3975,11 +3817,11 @@ int zebra_mpls_write_lsp_config(struct vty *vty, struct zebra_vrf *zvrf)
break;
default:
snprintf(lstr, sizeof(lstr), "%u",
- snhlfe->out_label);
+ nh->nh_label->label[0]);
break;
}
- vty_out(vty, "mpls lsp %u %s %s\n", slsp->ile.in_label,
+ vty_out(vty, "mpls lsp %u %s %s\n", lsp->ile.in_label,
buf, lstr);
}
}