diff options
Diffstat (limited to 'zebra/zebra_mpls.c')
| -rw-r--r-- | zebra/zebra_mpls.c | 167 |
1 files changed, 126 insertions, 41 deletions
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index c0764cd4b8..4ea7f32446 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -862,7 +862,7 @@ static void lsp_uninstall_from_kernel(struct hash_backet *backet, void *ctxt) lsp = (zebra_lsp_t *)backet->data; if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED)) - (void)kernel_del_lsp(lsp); + (void)dplane_lsp_delete(lsp); } /* @@ -887,6 +887,7 @@ static wq_item_status lsp_process(struct work_queue *wq, void *data) zebra_nhlfe_t *oldbest, *newbest; char buf[BUFSIZ], buf2[BUFSIZ]; struct zebra_vrf *zvrf = vrf_info_lookup(VRF_DEFAULT); + enum zebra_dplane_result res; lsp = (zebra_lsp_t *)data; if (!lsp) // unexpected @@ -916,13 +917,20 @@ static wq_item_status lsp_process(struct work_queue *wq, void *data) if (newbest) { UNSET_FLAG(lsp->flags, LSP_FLAG_CHANGED); - switch (kernel_add_lsp(lsp)) { + + switch (dplane_lsp_add(lsp)) { case ZEBRA_DPLANE_REQUEST_QUEUED: - flog_err( - EC_ZEBRA_DP_INVALID_RC, - "No current DataPlane interfaces can return this, please fix"); + /* Set 'installed' flag so we will know + * that an install is in-flight. + */ + SET_FLAG(lsp->flags, LSP_FLAG_INSTALLED); + + zvrf->lsp_installs_queued++; break; case ZEBRA_DPLANE_REQUEST_FAILURE: + flog_warn(EC_ZEBRA_LSP_INSTALL_FAILURE, + "LSP Install Failure: %u", + lsp->ile.in_label); break; case ZEBRA_DPLANE_REQUEST_SUCCESS: zvrf->lsp_installs++; @@ -932,14 +940,22 @@ static wq_item_status lsp_process(struct work_queue *wq, void *data) } else { /* Installed, may need an update and/or delete. */ if (!newbest) { + res = dplane_lsp_delete(lsp); - switch (kernel_del_lsp(lsp)) { + /* We do some of the lsp cleanup immediately for + * deletes. + */ + UNSET_FLAG(lsp->flags, LSP_FLAG_INSTALLED); + clear_nhlfe_installed(lsp); + + switch (res) { case ZEBRA_DPLANE_REQUEST_QUEUED: - flog_err( - EC_ZEBRA_DP_INVALID_RC, - "No current DataPlane interfaces can return this, please fix"); + zvrf->lsp_removals_queued++; break; case ZEBRA_DPLANE_REQUEST_FAILURE: + flog_warn(EC_ZEBRA_LSP_DELETE_FAILURE, + "LSP Deletion Failure: %u", + lsp->ile.in_label); break; case ZEBRA_DPLANE_REQUEST_SUCCESS: zvrf->lsp_removals++; @@ -950,7 +966,10 @@ static wq_item_status lsp_process(struct work_queue *wq, void *data) struct nexthop *nexthop; UNSET_FLAG(lsp->flags, LSP_FLAG_CHANGED); - UNSET_FLAG(lsp->flags, LSP_FLAG_INSTALLED); + + /* We leave the INSTALLED flag set here + * so we know an update in in-flight. + */ /* * Any NHLFE that was installed but is not @@ -973,13 +992,14 @@ static wq_item_status lsp_process(struct work_queue *wq, void *data) } } - switch (kernel_upd_lsp(lsp)) { + switch (dplane_lsp_update(lsp)) { case ZEBRA_DPLANE_REQUEST_QUEUED: - flog_err( - EC_ZEBRA_DP_INVALID_RC, - "No current DataPlane interfaces can return this, please fix"); + zvrf->lsp_installs_queued++; break; case ZEBRA_DPLANE_REQUEST_FAILURE: + flog_warn(EC_ZEBRA_LSP_INSTALL_FAILURE, + "LSP Update Failure: %u", + lsp->ile.in_label); break; case ZEBRA_DPLANE_REQUEST_SUCCESS: zvrf->lsp_installs++; @@ -1716,43 +1736,85 @@ static int mpls_processq_init(struct zebra_t *zebra) /* Public functions */ -void kernel_lsp_pass_fail(zebra_lsp_t *lsp, enum zebra_dplane_status res) +/* + * Process LSP update results from zebra dataplane. + */ +void zebra_mpls_lsp_dplane_result(struct zebra_dplane_ctx *ctx) { - struct nexthop *nexthop; + struct zebra_vrf *zvrf; + zebra_ile_t tmp_ile; + struct hash *lsp_table; + zebra_lsp_t *lsp; zebra_nhlfe_t *nhlfe; + struct nexthop *nexthop; + enum dplane_op_e op; + enum zebra_dplane_status status; + + op = dplane_ctx_get_op(ctx); + status = dplane_ctx_get_status(ctx); + + if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) + zlog_debug("LSP dplane ctx %p, op %s, in-label %u, result %s", + ctx, dplane_op2str(op), + dplane_ctx_get_in_label(ctx), + dplane_res2str(status)); + + switch (op) { + case DPLANE_OP_LSP_INSTALL: + case DPLANE_OP_LSP_UPDATE: + /* Look for zebra LSP object */ + zvrf = vrf_info_lookup(VRF_DEFAULT); + if (zvrf == NULL) + break; - if (!lsp) - return; + lsp_table = zvrf->lsp_table; - switch (res) { - case ZEBRA_DPLANE_INSTALL_FAILURE: - UNSET_FLAG(lsp->flags, LSP_FLAG_INSTALLED); - clear_nhlfe_installed(lsp); - flog_warn(EC_ZEBRA_LSP_INSTALL_FAILURE, - "LSP Install Failure: %u", lsp->ile.in_label); - break; - case ZEBRA_DPLANE_INSTALL_SUCCESS: - SET_FLAG(lsp->flags, LSP_FLAG_INSTALLED); - for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) { - nexthop = nhlfe->nexthop; - if (!nexthop) - continue; + tmp_ile.in_label = dplane_ctx_get_in_label(ctx); + lsp = hash_lookup(lsp_table, &tmp_ile); + if (lsp == NULL) { + if (IS_ZEBRA_DEBUG_DPLANE) + zlog_debug("LSP ctx %p: in-label %u not found", + ctx, dplane_ctx_get_in_label(ctx)); + break; + } - SET_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED); - SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); + /* TODO -- Confirm that this result is still 'current' */ + + if (dplane_ctx_get_status(ctx) == + ZEBRA_DPLANE_REQUEST_SUCCESS) { + /* Update zebra object */ + SET_FLAG(lsp->flags, LSP_FLAG_INSTALLED); + for (nhlfe = lsp->nhlfe_list; nhlfe; + nhlfe = nhlfe->next) { + nexthop = nhlfe->nexthop; + if (!nexthop) + continue; + + SET_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED); + SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); + } + } else { + UNSET_FLAG(lsp->flags, LSP_FLAG_INSTALLED); + clear_nhlfe_installed(lsp); + flog_warn(EC_ZEBRA_LSP_INSTALL_FAILURE, + "LSP Install Failure: in-label %u", + lsp->ile.in_label); } + break; - case ZEBRA_DPLANE_DELETE_SUCCESS: - UNSET_FLAG(lsp->flags, LSP_FLAG_INSTALLED); - clear_nhlfe_installed(lsp); - break; - case ZEBRA_DPLANE_DELETE_FAILURE: + + case DPLANE_OP_LSP_DELETE: flog_warn(EC_ZEBRA_LSP_DELETE_FAILURE, - "LSP Deletion Failure: %u", lsp->ile.in_label); + "LSP Deletion Failure: in-label %u", + dplane_ctx_get_in_label(ctx)); break; - case ZEBRA_DPLANE_STATUS_NONE: + + default: break; - } + + } /* Switch */ + + dplane_ctx_fini(&ctx); } /* @@ -1808,6 +1870,29 @@ int zebra_mpls_lsp_uninstall(struct zebra_vrf *zvrf, struct route_node *rn, } /* + * Add an NHLFE to an LSP, return the newly-added object + */ +zebra_nhlfe_t *zebra_mpls_lsp_add_nhlfe(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) +{ + /* Just a public pass-through to the internal implementation */ + return nhlfe_add(lsp, lsp_type, gtype, gate, ifindex, out_label); +} + +/* + * Free an allocated NHLFE + */ +void zebra_mpls_nhlfe_del(zebra_nhlfe_t *nhlfe) +{ + /* Just a pass-through to the internal implementation */ + nhlfe_del(nhlfe); +} + +/* * Registration from a client for the label binding for a FEC. If a binding * already exists, it is informed to the client. * NOTE: If there is a manually configured label binding, that is used. |
