diff options
author | Mark Stapp <mjs@voltanet.io> | 2019-04-14 23:16:11 +0200 |
---|---|---|
committer | Mark Stapp <mjs@voltanet.io> | 2019-05-28 19:41:37 +0200 |
commit | 188a00e014cba150f7e973394373f26709bc4054 (patch) | |
tree | c65f5ecde181dfb2d71cae7a86995864c813730c /zebra/zebra_mpls.c | |
parent | zebra: mpls lsp async notifications (diff) | |
download | frr-188a00e014cba150f7e973394373f26709bc4054.tar.xz frr-188a00e014cba150f7e973394373f26709bc4054.zip |
zebra: generate updates from notifications
If an async notification changes a route that's current,
generate an update to keep the kernel in sync.
Signed-off-by: Mark Stapp <mjs@voltanet.io>
Diffstat (limited to 'zebra/zebra_mpls.c')
-rw-r--r-- | zebra/zebra_mpls.c | 118 |
1 files changed, 101 insertions, 17 deletions
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 18b480bdf..48366417d 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -1823,6 +1823,7 @@ void zebra_mpls_process_dplane_notify(struct zebra_dplane_ctx *ctx) struct nexthop *nexthop; const struct nexthop *ctx_nexthop; int start_count = 0, end_count = 0; /* Installed counts */ + bool changed_p = false; bool is_debug = (IS_ZEBRA_DEBUG_DPLANE | IS_ZEBRA_DEBUG_MPLS); if (is_debug) @@ -1847,8 +1848,11 @@ void zebra_mpls_process_dplane_notify(struct zebra_dplane_ctx *ctx) /* * 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. + * of the nexthops associated with this LSP. First, we take a + * pre-scan pass to determine whether the LSP has transitioned + * from installed -> uninstalled. In that case, we need to have + * the existing state of the LSP objects available before making + * any changes. */ for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) { char buf[NEXTHOP_STRLEN]; @@ -1890,41 +1894,121 @@ void zebra_mpls_process_dplane_notify(struct zebra_dplane_ctx *ctx) buf, tstr); } - /* Bring zebra nhlfe install state into sync */ + /* Test zebra nhlfe install state */ if (CHECK_FLAG(ctx_nhlfe->flags, NHLFE_FLAG_INSTALLED)) { - SET_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED); + + if (!CHECK_FLAG(nhlfe->flags, + NHLFE_FLAG_INSTALLED)) + changed_p = true; /* Update counter */ end_count++; - } else + } else { + + if (CHECK_FLAG(nhlfe->flags, + NHLFE_FLAG_INSTALLED)) + changed_p = true; + } + + } else { + /* Not mentioned in lfib set -> uninstalled */ + if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED) || + CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE) || + CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) { + changed_p = true; + } + + 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%s", + start_count, end_count, + changed_p ? ", changed" : ""); + + /* + * Has the LSP become uninstalled? + */ + if (start_count > 0 && end_count == 0) { + /* Inform other lfibs */ + dplane_lsp_notif_update(lsp, DPLANE_OP_LSP_DELETE, ctx); + } + + /* + * Now we take a second pass and 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; + + 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) { + + /* Bring zebra nhlfe install state into sync */ + if (CHECK_FLAG(ctx_nhlfe->flags, + NHLFE_FLAG_INSTALLED)) { + + SET_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED); + + } else { + UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED); + } if (CHECK_FLAG(ctx_nhlfe->nexthop->flags, - NEXTHOP_FLAG_FIB)) + NEXTHOP_FLAG_FIB)) { + SET_FLAG(nhlfe->nexthop->flags, + NEXTHOP_FLAG_ACTIVE); SET_FLAG(nhlfe->nexthop->flags, NEXTHOP_FLAG_FIB); - else + } else { + UNSET_FLAG(nhlfe->nexthop->flags, + NEXTHOP_FLAG_ACTIVE); 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); + UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); } } - if (is_debug) - zlog_debug("LSP dplane notif: lfib start_count %d, end_count %d", - start_count, end_count); - - if (end_count > 0) + if (end_count > 0) { SET_FLAG(lsp->flags, LSP_FLAG_INSTALLED); - else { + + if (changed_p) + dplane_lsp_notif_update(lsp, DPLANE_OP_LSP_UPDATE, ctx); + + } else { UNSET_FLAG(lsp->flags, LSP_FLAG_INSTALLED); clear_nhlfe_installed(lsp); } |