]> git.proxmox.com Git - mirror_frr.git/commitdiff
zebra: mpls lsp async notifications
authorMark Stapp <mjs@voltanet.io>
Fri, 12 Apr 2019 19:34:12 +0000 (15:34 -0400)
committerMark Stapp <mjs@voltanet.io>
Tue, 28 May 2019 12:35:01 +0000 (08:35 -0400)
Add LSP notification event type; add a handler for LSP notifs;
dispatch to that handler.

Signed-off-by: Mark Stapp <mjs@voltanet.io>
zebra/zebra_dplane.c
zebra/zebra_dplane.h
zebra/zebra_mpls.c
zebra/zebra_mpls.h
zebra/zebra_rib.c

index df6188661b3098f56483b86e5bacbf29bd28700b..2509d908128c77ae9c94f336c9ce5025d0642be4 100644 (file)
@@ -421,6 +421,7 @@ static void dplane_ctx_free(struct zebra_dplane_ctx **pctx)
        case DPLANE_OP_LSP_INSTALL:
        case DPLANE_OP_LSP_UPDATE:
        case DPLANE_OP_LSP_DELETE:
+       case DPLANE_OP_LSP_NOTIFY:
        {
                zebra_nhlfe_t *nhlfe, *next;
 
@@ -596,6 +597,9 @@ const char *dplane_op2str(enum dplane_op_e op)
        case DPLANE_OP_LSP_DELETE:
                ret = "LSP_DELETE";
                break;
+       case DPLANE_OP_LSP_NOTIFY:
+               ret = "LSP_NOTIFY";
+               break;
 
        case DPLANE_OP_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);
                        break;
 
-               /* Ignore 'notifications' */
+               /* Ignore 'notifications' - no-op */
                case DPLANE_OP_SYS_ROUTE_ADD:
                case DPLANE_OP_SYS_ROUTE_DELETE:
                case DPLANE_OP_ROUTE_NOTIFY:
+               case DPLANE_OP_LSP_NOTIFY:
                        res = ZEBRA_DPLANE_REQUEST_SUCCESS;
                        break;
 
index 506dcb4996949dc94db5fbb29eaf0b51ea178784..a4c93cefd6b670c1f74cea96af9d4796ed35f4c9 100644 (file)
@@ -111,6 +111,7 @@ enum dplane_op_e {
        DPLANE_OP_LSP_INSTALL,
        DPLANE_OP_LSP_UPDATE,
        DPLANE_OP_LSP_DELETE,
+       DPLANE_OP_LSP_NOTIFY,
 
        /* Pseudowire update */
        DPLANE_OP_PW_INSTALL,
index 5356a7f498de3ef60fc82c2afde806e7b7ccd6ef..18b480bdf96eba27023eecfa21be9610d42a6758 100644 (file)
@@ -1809,6 +1809,130 @@ void zebra_mpls_lsp_dplane_result(struct zebra_dplane_ctx *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.
  */
index 3a131e1aaf1224ca637ef7573e1f4370c69ebbfd..d983221cb533fbda2019132e8a0558aefd7adbcd 100644 (file)
@@ -352,6 +352,9 @@ struct zebra_dplane_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.
  * Called upon changes that may affect one or more of them such as
index adf9f9900859556f185e8d67cce21d877b4bb50c..d1311dfdd2bdc15b3c7b3f6265563e71566ec4dc 100644 (file)
@@ -3738,6 +3738,10 @@ static int rib_process_dplane_results(struct thread *thread)
                                zebra_mpls_lsp_dplane_result(ctx);
                                break;
 
+                       case DPLANE_OP_LSP_NOTIFY:
+                               zebra_mpls_process_dplane_notify(ctx);
+                               break;
+
                        case DPLANE_OP_PW_INSTALL:
                        case DPLANE_OP_PW_UNINSTALL:
                                handle_pw_result(ctx);