diff options
Diffstat (limited to 'zebra/zebra_mpls.c')
| -rw-r--r-- | zebra/zebra_mpls.c | 152 |
1 files changed, 112 insertions, 40 deletions
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index e741268ebb..03b8c8de1f 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -47,6 +47,7 @@ #include "zebra/zebra_memory.h" #include "zebra/zebra_vrf.h" #include "zebra/zebra_mpls.h" +#include "zebra/zebra_srte.h" #include "zebra/zebra_errors.h" DEFINE_MTYPE_STATIC(ZEBRA, LSP, "MPLS LSP object") @@ -120,7 +121,8 @@ static int mpls_lsp_uninstall_all(struct hash *lsp_table, zebra_lsp_t *lsp, enum lsp_types_t type); static int mpls_static_lsp_uninstall_all(struct zebra_vrf *zvrf, mpls_label_t in_label); -static void nhlfe_print(zebra_nhlfe_t *nhlfe, struct vty *vty); +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, @@ -232,8 +234,7 @@ static int lsp_install(struct zebra_vrf *zvrf, mpls_label_t label, if (IS_ZEBRA_DEBUG_MPLS) { nhlfe2str(nhlfe, buf, BUFSIZ); zlog_debug( - "LSP in-label %u type %d nexthop %s " - "out-label changed", + "LSP in-label %u type %d nexthop %s out-label changed", lsp->ile.in_label, lsp_type, buf); } @@ -254,8 +255,7 @@ static int lsp_install(struct zebra_vrf *zvrf, mpls_label_t label, if (IS_ZEBRA_DEBUG_MPLS) { nhlfe2str(nhlfe, buf, BUFSIZ); zlog_debug( - "Add LSP in-label %u type %d nexthop %s " - "out-label %u", + "Add LSP in-label %u type %d nexthop %s out-label %u", lsp->ile.in_label, lsp_type, buf, nexthop->nh_label->label[0]); } @@ -928,8 +928,7 @@ static wq_item_status lsp_process(struct work_queue *wq, void *data) if (newbest) nhlfe2str(newbest, buf2, sizeof(buf2)); zlog_debug( - "Process LSP in-label %u oldbest %s newbest %s " - "flags 0x%x ecmp# %d", + "Process LSP in-label %u oldbest %s newbest %s flags 0x%x ecmp# %d", lsp->ile.in_label, oldbest ? buf : "NULL", newbest ? buf2 : "NULL", lsp->flags, lsp->num_ecmp); } @@ -957,9 +956,6 @@ static wq_item_status lsp_process(struct work_queue *wq, void *data) case ZEBRA_DPLANE_REQUEST_SUCCESS: zvrf->lsp_installs++; break; - /* Should never happen */ - case ZEBRA_DPLANE_REQUEST_PENDING: - break; } } } else { @@ -985,10 +981,6 @@ static wq_item_status lsp_process(struct work_queue *wq, void *data) case ZEBRA_DPLANE_REQUEST_SUCCESS: zvrf->lsp_removals++; break; - - /* Should never happen */ - case ZEBRA_DPLANE_REQUEST_PENDING: - break; } } else if (CHECK_FLAG(lsp->flags, LSP_FLAG_CHANGED)) { zebra_nhlfe_t *nhlfe; @@ -1032,10 +1024,6 @@ static wq_item_status lsp_process(struct work_queue *wq, void *data) case ZEBRA_DPLANE_REQUEST_SUCCESS: zvrf->lsp_installs++; break; - - /* Should never happen */ - case ZEBRA_DPLANE_REQUEST_PENDING: - break; } } } @@ -1506,12 +1494,23 @@ static json_object *nhlfe_json(zebra_nhlfe_t *nhlfe) { char buf[BUFSIZ]; json_object *json_nhlfe = NULL; + json_object *json_backups = NULL; + json_object *json_label_stack; struct nexthop *nexthop = nhlfe->nexthop; + int i; json_nhlfe = json_object_new_object(); json_object_string_add(json_nhlfe, "type", nhlfe_type2str(nhlfe->type)); json_object_int_add(json_nhlfe, "outLabel", nexthop->nh_label->label[0]); + + json_label_stack = json_object_new_array(); + json_object_object_add(json_nhlfe, "outLabelStack", json_label_stack); + for (i = 0; i < nexthop->nh_label->num_labels; i++) + json_object_array_add( + json_label_stack, + json_object_new_int(nexthop->nh_label->label[i])); + json_object_int_add(json_nhlfe, "distance", nhlfe->distance); if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED)) @@ -1537,13 +1536,27 @@ static json_object *nhlfe_json(zebra_nhlfe_t *nhlfe) default: break; } + + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP)) { + json_backups = json_object_new_array(); + for (i = 0; i < nexthop->backup_num; i++) { + json_object_array_add( + json_backups, + json_object_new_int(nexthop->backup_idx[i])); + } + + json_object_object_add(json_nhlfe, "backupIndex", + json_backups); + } + return json_nhlfe; } /* * Print the NHLFE for a LSP forwarding entry. */ -static void nhlfe_print(zebra_nhlfe_t *nhlfe, struct vty *vty) +static void nhlfe_print(zebra_nhlfe_t *nhlfe, struct vty *vty, + const char *indent) { struct nexthop *nexthop; char buf[MPLS_LABEL_STRLEN]; @@ -1558,6 +1571,10 @@ static void nhlfe_print(zebra_nhlfe_t *nhlfe, struct vty *vty) nexthop->nh_label->label, buf, sizeof(buf), 0), nhlfe->distance); + + if (indent) + vty_out(vty, "%s", indent); + switch (nexthop->type) { case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: @@ -1595,31 +1612,34 @@ static void nhlfe_print(zebra_nhlfe_t *nhlfe, struct vty *vty) static void lsp_print(struct vty *vty, zebra_lsp_t *lsp) { zebra_nhlfe_t *nhlfe, *backup; - int i; + int i, j; vty_out(vty, "Local label: %u%s\n", lsp->ile.in_label, CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED) ? " (installed)" : ""); frr_each(nhlfe_list, &lsp->nhlfe_list, nhlfe) { - nhlfe_print(nhlfe, vty); + nhlfe_print(nhlfe, vty, NULL); - if (nhlfe->nexthop && - CHECK_FLAG(nhlfe->nexthop->flags, - NEXTHOP_FLAG_HAS_BACKUP)) { - /* Find backup in backup list */ + if (nhlfe->nexthop == NULL || + !CHECK_FLAG(nhlfe->nexthop->flags, + NEXTHOP_FLAG_HAS_BACKUP)) + continue; + /* Backup nhlfes: find backups in backup list */ + + for (j = 0; j < nhlfe->nexthop->backup_num; j++) { i = 0; backup = NULL; frr_each(nhlfe_list, &lsp->backup_nhlfe_list, backup) { - if (i == nhlfe->nexthop->backup_idx) + if (i == nhlfe->nexthop->backup_idx[j]) break; i++; } if (backup) { vty_out(vty, " [backup %d]", i); - nhlfe_print(backup, vty); + nhlfe_print(backup, vty, " "); } } } @@ -1643,6 +1663,19 @@ static json_object *lsp_json(zebra_lsp_t *lsp) json_object_array_add(json_nhlfe_list, nhlfe_json(nhlfe)); json_object_object_add(json, "nexthops", json_nhlfe_list); + json_nhlfe_list = NULL; + + + frr_each(nhlfe_list, &lsp->backup_nhlfe_list, nhlfe) { + if (json_nhlfe_list == NULL) + json_nhlfe_list = json_object_new_array(); + + json_object_array_add(json_nhlfe_list, nhlfe_json(nhlfe)); + } + + if (json_nhlfe_list) + json_object_object_add(json, "backupNexthops", json_nhlfe_list); + return json; } @@ -1882,14 +1915,13 @@ static int mpls_processq_init(void) } -/* Public functions */ - /* * Process LSP update results from zebra dataplane. */ void zebra_mpls_lsp_dplane_result(struct zebra_dplane_ctx *ctx) { struct zebra_vrf *zvrf; + mpls_label_t label; zebra_ile_t tmp_ile; struct hash *lsp_table; zebra_lsp_t *lsp; @@ -1897,6 +1929,7 @@ void zebra_mpls_lsp_dplane_result(struct zebra_dplane_ctx *ctx) struct nexthop *nexthop; enum dplane_op_e op; enum zebra_dplane_result status; + enum zebra_sr_policy_update_label_mode update_mode; op = dplane_ctx_get_op(ctx); status = dplane_ctx_get_status(ctx); @@ -1907,6 +1940,8 @@ void zebra_mpls_lsp_dplane_result(struct zebra_dplane_ctx *ctx) dplane_ctx_get_in_label(ctx), dplane_res2str(status)); + label = dplane_ctx_get_in_label(ctx); + switch (op) { case DPLANE_OP_LSP_INSTALL: case DPLANE_OP_LSP_UPDATE: @@ -1917,7 +1952,7 @@ void zebra_mpls_lsp_dplane_result(struct zebra_dplane_ctx *ctx) lsp_table = zvrf->lsp_table; - tmp_ile.in_label = dplane_ctx_get_in_label(ctx); + tmp_ile.in_label = label; lsp = hash_lookup(lsp_table, &tmp_ile); if (lsp == NULL) { if (IS_ZEBRA_DEBUG_DPLANE) @@ -1951,13 +1986,21 @@ void zebra_mpls_lsp_dplane_result(struct zebra_dplane_ctx *ctx) } } + update_mode = (op == DPLANE_OP_LSP_INSTALL) + ? ZEBRA_SR_POLICY_LABEL_CREATED + : ZEBRA_SR_POLICY_LABEL_UPDATED; + zebra_sr_policy_label_update(label, update_mode); break; case DPLANE_OP_LSP_DELETE: - if (status != ZEBRA_DPLANE_REQUEST_SUCCESS) + if (status != ZEBRA_DPLANE_REQUEST_SUCCESS) { flog_warn(EC_ZEBRA_LSP_DELETE_FAILURE, "LSP Deletion Failure: in-label %u", dplane_ctx_get_in_label(ctx)); + break; + } + zebra_sr_policy_label_update(label, + ZEBRA_SR_POLICY_LABEL_REMOVED); break; default: @@ -2112,6 +2155,7 @@ static int update_nhlfes_from_ctx(struct nhlfe_list_head *nhlfe_head, __func__, buf); SET_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED); + SET_FLAG(nhlfe->flags, NHLFE_FLAG_SELECTED); } else { if (is_debug) @@ -2119,6 +2163,7 @@ static int update_nhlfes_from_ctx(struct nhlfe_list_head *nhlfe_head, __func__, buf); UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED); + UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_SELECTED); } if (CHECK_FLAG(ctx_nhlfe->nexthop->flags, @@ -2140,6 +2185,7 @@ static int update_nhlfes_from_ctx(struct nhlfe_list_head *nhlfe_head, zlog_debug("%s: no match for lsp nhlfe %s", __func__, buf); UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED); + UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_SELECTED); UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); } @@ -3284,7 +3330,7 @@ lsp_add_nhlfe(zebra_lsp_t *lsp, enum lsp_types_t type, /* * Install an LSP and forwarding entry; used primarily - * from zapi message processing. + * from vrf zapi message processing. */ int mpls_lsp_install(struct zebra_vrf *zvrf, enum lsp_types_t type, mpls_label_t in_label, uint8_t num_out_labels, @@ -3335,8 +3381,19 @@ static int lsp_znh_install(zebra_lsp_t *lsp, enum lsp_types_t type, /* Update backup info if present */ if (CHECK_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP)) { - nhlfe->nexthop->backup_idx = znh->backup_idx; + if (znh->backup_num > NEXTHOP_MAX_BACKUPS) { + nhlfe_del(nhlfe); + return -1; + } + + nhlfe->nexthop->backup_num = znh->backup_num; + memcpy(nhlfe->nexthop->backup_idx, znh->backup_idx, + znh->backup_num); SET_FLAG(nhlfe->nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP); + } else { + /* Ensure there's no stale backup info */ + UNSET_FLAG(nhlfe->nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP); + nhlfe->nexthop->backup_num = 0; } /* Queue LSP for processing. */ @@ -3371,6 +3428,21 @@ static int lsp_backup_znh_install(zebra_lsp_t *lsp, enum lsp_types_t type, return 0; } +zebra_lsp_t *mpls_lsp_find(struct zebra_vrf *zvrf, mpls_label_t in_label) +{ + struct hash *lsp_table; + zebra_ile_t tmp_ile; + + /* Lookup table. */ + lsp_table = zvrf->lsp_table; + if (!lsp_table) + return NULL; + + /* If entry is not present, exit. */ + tmp_ile.in_label = in_label; + return hash_lookup(lsp_table, &tmp_ile); +} + /* * Uninstall a particular NHLFE in the forwarding table. If this is * the only NHLFE, the entire LSP forwarding entry has to be deleted. @@ -3408,7 +3480,7 @@ int mpls_lsp_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type, return 0; 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", in_label, type, buf, nhlfe->flags); } @@ -3639,10 +3711,9 @@ int zebra_mpls_static_lsp_add(struct zebra_vrf *zvrf, mpls_label_t in_label, return 0; if (IS_ZEBRA_DEBUG_MPLS) { - snhlfe2str(snhlfe, buf, BUFSIZ); + snhlfe2str(snhlfe, buf, sizeof(buf)); zlog_debug( - "Upd static LSP in-label %u nexthop %s " - "out-label %u (old %u)", + "Upd static LSP in-label %u nexthop %s out-label %u (old %u)", in_label, buf, out_label, snhlfe->out_label); } snhlfe->out_label = out_label; @@ -3653,7 +3724,7 @@ int zebra_mpls_static_lsp_add(struct zebra_vrf *zvrf, mpls_label_t in_label, return -1; if (IS_ZEBRA_DEBUG_MPLS) { - snhlfe2str(snhlfe, buf, BUFSIZ); + snhlfe2str(snhlfe, buf, sizeof(buf)); zlog_debug( "Add static LSP in-label %u nexthop %s out-label %u", in_label, buf, out_label); @@ -3798,7 +3869,8 @@ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf, for (ALL_LIST_ELEMENTS_RO(lsp_list, node, lsp)) json_object_object_add( - json, label2str(lsp->ile.in_label, buf, BUFSIZ), + json, label2str(lsp->ile.in_label, buf, + sizeof(buf)), lsp_json(lsp)); vty_out(vty, "%s\n", json_object_to_json_string_ext( @@ -3853,7 +3925,7 @@ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf, out_label_str = mpls_label2str( nexthop->nh_label->num_labels, &nexthop->nh_label->label[0], - buf, BUFSIZ, 1); + buf, sizeof(buf), 1); else out_label_str = "-"; |
