zebra: mpls lsp async notifications

Add LSP notification event type; add a handler for LSP notifs;
dispatch to that handler.

Signed-off-by: Mark Stapp <mjs@voltanet.io>
This commit is contained in:
Mark Stapp 2019-04-12 15:34:12 -04:00
parent 3ab54059be
commit 104e3ad95e
5 changed files with 138 additions and 1 deletions

View File

@ -421,6 +421,7 @@ static void dplane_ctx_free(struct zebra_dplane_ctx **pctx)
case DPLANE_OP_LSP_INSTALL: case DPLANE_OP_LSP_INSTALL:
case DPLANE_OP_LSP_UPDATE: case DPLANE_OP_LSP_UPDATE:
case DPLANE_OP_LSP_DELETE: case DPLANE_OP_LSP_DELETE:
case DPLANE_OP_LSP_NOTIFY:
{ {
zebra_nhlfe_t *nhlfe, *next; zebra_nhlfe_t *nhlfe, *next;
@ -596,6 +597,9 @@ const char *dplane_op2str(enum dplane_op_e op)
case DPLANE_OP_LSP_DELETE: case DPLANE_OP_LSP_DELETE:
ret = "LSP_DELETE"; ret = "LSP_DELETE";
break; break;
case DPLANE_OP_LSP_NOTIFY:
ret = "LSP_NOTIFY";
break;
case DPLANE_OP_PW_INSTALL: case DPLANE_OP_PW_INSTALL:
ret = "PW_INSTALL"; ret = "PW_INSTALL";
@ -2377,10 +2381,11 @@ static int kernel_dplane_process_func(struct zebra_dplane_provider *prov)
res = kernel_dplane_address_update(ctx); res = kernel_dplane_address_update(ctx);
break; break;
/* Ignore 'notifications' */ /* Ignore 'notifications' - no-op */
case DPLANE_OP_SYS_ROUTE_ADD: case DPLANE_OP_SYS_ROUTE_ADD:
case DPLANE_OP_SYS_ROUTE_DELETE: case DPLANE_OP_SYS_ROUTE_DELETE:
case DPLANE_OP_ROUTE_NOTIFY: case DPLANE_OP_ROUTE_NOTIFY:
case DPLANE_OP_LSP_NOTIFY:
res = ZEBRA_DPLANE_REQUEST_SUCCESS; res = ZEBRA_DPLANE_REQUEST_SUCCESS;
break; break;

View File

@ -111,6 +111,7 @@ enum dplane_op_e {
DPLANE_OP_LSP_INSTALL, DPLANE_OP_LSP_INSTALL,
DPLANE_OP_LSP_UPDATE, DPLANE_OP_LSP_UPDATE,
DPLANE_OP_LSP_DELETE, DPLANE_OP_LSP_DELETE,
DPLANE_OP_LSP_NOTIFY,
/* Pseudowire update */ /* Pseudowire update */
DPLANE_OP_PW_INSTALL, DPLANE_OP_PW_INSTALL,

View File

@ -1809,6 +1809,130 @@ void zebra_mpls_lsp_dplane_result(struct zebra_dplane_ctx *ctx)
dplane_ctx_fini(&ctx); dplane_ctx_fini(&ctx);
} }
/*
* Process async dplane notifications.
*/
void zebra_mpls_process_dplane_notify(struct zebra_dplane_ctx *ctx)
{
struct zebra_vrf *zvrf;
zebra_ile_t tmp_ile;
struct hash *lsp_table;
zebra_lsp_t *lsp;
zebra_nhlfe_t *nhlfe;
const zebra_nhlfe_t *ctx_nhlfe;
struct nexthop *nexthop;
const struct nexthop *ctx_nexthop;
int start_count = 0, end_count = 0; /* Installed counts */
bool is_debug = (IS_ZEBRA_DEBUG_DPLANE | IS_ZEBRA_DEBUG_MPLS);
if (is_debug)
zlog_debug("LSP dplane notif, in-label %u",
dplane_ctx_get_in_label(ctx));
/* Look for zebra LSP object */
zvrf = vrf_info_lookup(VRF_DEFAULT);
if (zvrf == NULL)
goto done;
lsp_table = zvrf->lsp_table;
tmp_ile.in_label = dplane_ctx_get_in_label(ctx);
lsp = hash_lookup(lsp_table, &tmp_ile);
if (lsp == NULL) {
if (is_debug)
zlog_debug("dplane LSP notif: in-label %u not found",
dplane_ctx_get_in_label(ctx));
goto done;
}
/*
* The dataplane/forwarding plane is notifying zebra about the state
* of the nexthops associated with this LSP. We bring the zebra
* nexthop state into sync with the forwarding-plane state.
*/
for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) {
char buf[NEXTHOP_STRLEN];
nexthop = nhlfe->nexthop;
if (!nexthop)
continue;
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
start_count++;
ctx_nexthop = NULL;
for (ctx_nhlfe = dplane_ctx_get_nhlfe(ctx);
ctx_nhlfe; ctx_nhlfe = ctx_nhlfe->next) {
ctx_nexthop = ctx_nhlfe->nexthop;
if (!ctx_nexthop)
continue;
if ((ctx_nexthop->type == nexthop->type) &&
nexthop_same(ctx_nexthop, nexthop)) {
/* Matched */
break;
}
}
if (is_debug)
nexthop2str(nexthop, buf, sizeof(buf));
if (ctx_nhlfe && ctx_nexthop) {
if (is_debug) {
const char *tstr = "";
if (!CHECK_FLAG(ctx_nhlfe->flags,
NHLFE_FLAG_INSTALLED))
tstr = "not ";
zlog_debug("LSP dplane notif: matched nh %s (%sinstalled)",
buf, tstr);
}
/* Bring zebra nhlfe install state into sync */
if (CHECK_FLAG(ctx_nhlfe->flags,
NHLFE_FLAG_INSTALLED)) {
SET_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED);
/* Update counter */
end_count++;
} else
UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED);
if (CHECK_FLAG(ctx_nhlfe->nexthop->flags,
NEXTHOP_FLAG_FIB))
SET_FLAG(nhlfe->nexthop->flags,
NEXTHOP_FLAG_FIB);
else
UNSET_FLAG(nhlfe->nexthop->flags,
NEXTHOP_FLAG_FIB);
} else {
/* Not mentioned in lfib set -> uninstalled */
UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED);
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
if (is_debug)
zlog_debug("LSP dplane notif: no match, nh %s",
buf);
}
}
if (is_debug)
zlog_debug("LSP dplane notif: lfib start_count %d, end_count %d",
start_count, end_count);
if (end_count > 0)
SET_FLAG(lsp->flags, LSP_FLAG_INSTALLED);
else {
UNSET_FLAG(lsp->flags, LSP_FLAG_INSTALLED);
clear_nhlfe_installed(lsp);
}
done:
dplane_ctx_fini(&ctx);
}
/* /*
* Install dynamic LSP entry. * Install dynamic LSP entry.
*/ */

View File

@ -352,6 +352,9 @@ struct zebra_dplane_ctx;
void zebra_mpls_lsp_dplane_result(struct zebra_dplane_ctx *ctx); void zebra_mpls_lsp_dplane_result(struct zebra_dplane_ctx *ctx);
/* Process async dplane notifications. */
void zebra_mpls_process_dplane_notify(struct zebra_dplane_ctx *ctx);
/* /*
* Schedule all MPLS label forwarding entries for processing. * Schedule all MPLS label forwarding entries for processing.
* Called upon changes that may affect one or more of them such as * Called upon changes that may affect one or more of them such as

View File

@ -3738,6 +3738,10 @@ static int rib_process_dplane_results(struct thread *thread)
zebra_mpls_lsp_dplane_result(ctx); zebra_mpls_lsp_dplane_result(ctx);
break; break;
case DPLANE_OP_LSP_NOTIFY:
zebra_mpls_process_dplane_notify(ctx);
break;
case DPLANE_OP_PW_INSTALL: case DPLANE_OP_PW_INSTALL:
case DPLANE_OP_PW_UNINSTALL: case DPLANE_OP_PW_UNINSTALL:
handle_pw_result(ctx); handle_pw_result(ctx);