summaryrefslogtreecommitdiff
path: root/zebra/zebra_mpls.c
diff options
context:
space:
mode:
authorRenato Westphal <renato@opensourcerouting.org>2019-03-02 15:00:46 -0300
committerRenato Westphal <renatowestphal@gmail.com>2019-03-29 11:32:21 -0300
commit8f88441d717c0ded412543cceabf0ddd93ee9f09 (patch)
tree0a460d2da46a5b910535529c92e8db2fa5ff2a74 /zebra/zebra_mpls.c
parent6a534dcafcb623f1b85b5ee2a13c74faab227ced (diff)
parent700e9faa28bbdc3460e1d7aa109b6e4acaf347b3 (diff)
Merge remote-tracking branch 'frr/master' into rip-vrf
Merge commit to solve a bunch of conflicts with other PRs that were merged in the previous weeks. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Diffstat (limited to 'zebra/zebra_mpls.c')
-rw-r--r--zebra/zebra_mpls.c216
1 files changed, 149 insertions, 67 deletions
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c
index c0764cd4b8..a06e15d90d 100644
--- a/zebra/zebra_mpls.c
+++ b/zebra/zebra_mpls.c
@@ -40,6 +40,7 @@
#include "zebra/rt.h"
#include "zebra/interface.h"
#include "zebra/zserv.h"
+#include "zebra/zebra_router.h"
#include "zebra/redistribute.h"
#include "zebra/debug.h"
#include "zebra/zebra_memory.h"
@@ -56,9 +57,6 @@ DEFINE_MTYPE_STATIC(ZEBRA, SNHLFE_IFNAME, "MPLS static nexthop ifname")
int mpls_enabled;
-/* Default rtm_table for all clients */
-extern struct zebra_t zebrad;
-
/* static function declarations */
static void fec_evaluate(struct zebra_vrf *zvrf);
@@ -87,8 +85,8 @@ static int nhlfe_nexthop_active_ipv6(zebra_nhlfe_t *nhlfe,
static int nhlfe_nexthop_active(zebra_nhlfe_t *nhlfe);
static void lsp_select_best_nhlfe(zebra_lsp_t *lsp);
-static void lsp_uninstall_from_kernel(struct hash_backet *backet, void *ctxt);
-static void lsp_schedule(struct hash_backet *backet, void *ctxt);
+static void lsp_uninstall_from_kernel(struct hash_bucket *bucket, void *ctxt);
+static void lsp_schedule(struct hash_bucket *bucket, void *ctxt);
static wq_item_status lsp_process(struct work_queue *wq, void *data);
static void lsp_processq_del(struct work_queue *wq, void *data);
static void lsp_processq_complete(struct work_queue *wq);
@@ -126,7 +124,6 @@ static zebra_snhlfe_t *snhlfe_add(zebra_slsp_t *slsp,
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 int mpls_processq_init(struct zebra_t *zebra);
/* Static functions */
@@ -856,24 +853,24 @@ static void lsp_select_best_nhlfe(zebra_lsp_t *lsp)
* Delete LSP forwarding entry from kernel, if installed. Called upon
* process exit.
*/
-static void lsp_uninstall_from_kernel(struct hash_backet *backet, void *ctxt)
+static void lsp_uninstall_from_kernel(struct hash_bucket *bucket, void *ctxt)
{
zebra_lsp_t *lsp;
- lsp = (zebra_lsp_t *)backet->data;
+ lsp = (zebra_lsp_t *)bucket->data;
if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED))
- (void)kernel_del_lsp(lsp);
+ (void)dplane_lsp_delete(lsp);
}
/*
* Schedule LSP forwarding entry for processing. Called upon changes
* that may impact LSPs such as nexthop / connected route changes.
*/
-static void lsp_schedule(struct hash_backet *backet, void *ctxt)
+static void lsp_schedule(struct hash_bucket *bucket, void *ctxt)
{
zebra_lsp_t *lsp;
- lsp = (zebra_lsp_t *)backet->data;
+ lsp = (zebra_lsp_t *)bucket->data;
(void)lsp_processq_add(lsp);
}
@@ -887,6 +884,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 +914,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 +937,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 +963,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 +989,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++;
@@ -1054,13 +1071,13 @@ static int lsp_processq_add(zebra_lsp_t *lsp)
if (CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED))
return 0;
- if (zebrad.lsp_process_q == NULL) {
+ if (zrouter.lsp_process_q == NULL) {
flog_err(EC_ZEBRA_WQ_NONEXISTENT,
"%s: work_queue does not exist!", __func__);
return -1;
}
- work_queue_add(zebrad.lsp_process_q, lsp);
+ work_queue_add(zrouter.lsp_process_q, lsp);
SET_FLAG(lsp->flags, LSP_FLAG_SCHEDULED);
return 0;
}
@@ -1475,7 +1492,7 @@ static json_object *lsp_json(zebra_lsp_t *lsp)
static struct list *hash_get_sorted_list(struct hash *hash, void *cmp)
{
unsigned int i;
- struct hash_backet *hb;
+ struct hash_bucket *hb;
struct list *sorted_list = list_new();
sorted_list->cmp = (int (*)(void *, void *))cmp;
@@ -1694,21 +1711,21 @@ static char *snhlfe2str(zebra_snhlfe_t *snhlfe, char *buf, int size)
/*
* Initialize work queue for processing changed LSPs.
*/
-static int mpls_processq_init(struct zebra_t *zebra)
+static int mpls_processq_init(void)
{
- zebra->lsp_process_q = work_queue_new(zebra->master, "LSP processing");
- if (!zebra->lsp_process_q) {
+ zrouter.lsp_process_q = work_queue_new(zrouter.master, "LSP processing");
+ if (!zrouter.lsp_process_q) {
flog_err(EC_ZEBRA_WQ_NONEXISTENT,
"%s: could not initialise work queue!", __func__);
return -1;
}
- zebra->lsp_process_q->spec.workfunc = &lsp_process;
- zebra->lsp_process_q->spec.del_item_data = &lsp_processq_del;
- zebra->lsp_process_q->spec.errorfunc = NULL;
- zebra->lsp_process_q->spec.completion_func = &lsp_processq_complete;
- zebra->lsp_process_q->spec.max_retries = 0;
- zebra->lsp_process_q->spec.hold = 10;
+ zrouter.lsp_process_q->spec.workfunc = &lsp_process;
+ zrouter.lsp_process_q->spec.del_item_data = &lsp_processq_del;
+ zrouter.lsp_process_q->spec.errorfunc = NULL;
+ zrouter.lsp_process_q->spec.completion_func = &lsp_processq_complete;
+ zrouter.lsp_process_q->spec.max_retries = 0;
+ zrouter.lsp_process_q->spec.hold = 10;
return 0;
}
@@ -1716,43 +1733,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_result 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;
+ }
+
+ /* TODO -- Confirm that this result is still 'current' */
+
+ if (status == 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);
+ 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:
- flog_warn(EC_ZEBRA_LSP_DELETE_FAILURE,
- "LSP Deletion Failure: %u", lsp->ile.in_label);
+
+ case DPLANE_OP_LSP_DELETE:
+ 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;
- case ZEBRA_DPLANE_STATUS_NONE:
+
+ default:
break;
- }
+
+ } /* Switch */
+
+ dplane_ctx_fini(&ctx);
}
/*
@@ -1808,6 +1867,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.
@@ -2468,12 +2550,12 @@ int mpls_lsp_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
* Uninstall all LDP NHLFEs for a particular LSP forwarding entry.
* If no other NHLFEs exist, the entry would be deleted.
*/
-void mpls_ldp_lsp_uninstall_all(struct hash_backet *backet, void *ctxt)
+void mpls_ldp_lsp_uninstall_all(struct hash_bucket *bucket, void *ctxt)
{
zebra_lsp_t *lsp;
struct hash *lsp_table;
- lsp = (zebra_lsp_t *)backet->data;
+ lsp = (zebra_lsp_t *)bucket->data;
if (!lsp->nhlfe_list)
return;
@@ -2978,7 +3060,7 @@ void zebra_mpls_init(void)
return;
}
- if (!mpls_processq_init(&zebrad))
+ if (!mpls_processq_init())
mpls_enabled = 1;
hook_register(zserv_client_close, zebra_mpls_cleanup_fecs_for_client);