]> git.proxmox.com Git - mirror_frr.git/blobdiff - pathd/path_pcep.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / pathd / path_pcep.c
index 1c650737b2e4c3f4c56034026bda26e0f5c7397f..0c5e495044d12f36054d9c7b47a867cb0a2d1f2e 100644 (file)
@@ -1,19 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Copyright (C) 2020  NetDEF, Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <zebra.h>
@@ -37,6 +24,7 @@
 #include "pathd/path_pcep_controller.h"
 #include "pathd/path_pcep_lib.h"
 #include "pathd/path_pcep_config.h"
+#include "pathd/path_pcep_debug.h"
 
 DEFINE_MTYPE(PATHD, PCEP, "PCEP module");
 
@@ -51,6 +39,7 @@ static int pcep_main_event_handler(enum pcep_main_event_type type, int pcc_id,
                                   void *payload);
 static int pcep_main_event_start_sync(int pcc_id);
 static int pcep_main_event_start_sync_cb(struct path *path, void *arg);
+static int pcep_main_event_initiate_candidate(struct path *path);
 static int pcep_main_event_update_candidate(struct path *path);
 static int pcep_main_event_remove_candidate_segments(const char *originator,
                                                     bool force);
@@ -64,6 +53,9 @@ static int pathd_candidate_removed_handler(struct srte_candidate *candidate);
 static struct path_metric *pcep_copy_metrics(struct path_metric *metric);
 static struct path_hop *pcep_copy_hops(struct path_hop *hop);
 
+/* Other static functions */
+static void notify_status(struct path *path, bool not_changed);
+
 /* Module Functions */
 static int pcep_module_finish(void);
 static int pcep_module_late_init(struct thread_master *tm);
@@ -165,6 +157,21 @@ void pcep_free_path(struct path *path)
        XFREE(MTYPE_PCEP, path);
 }
 
+/* ------------ Other Static Functions ------------ */
+
+void notify_status(struct path *path, bool not_changed)
+{
+       struct path *resp = NULL;
+
+       if ((resp = path_pcep_config_get_path(&path->nbkey))) {
+               resp->srp_id = path->srp_id;
+               flog_warn(EC_PATH_PCEP_RECOVERABLE_INTERNAL_ERROR,
+                         "(%s) Send report for candidate path %s", __func__,
+                         path->name);
+               pcep_ctrl_send_report(pcep_g->fpt, path->pcc_id, resp,
+                                     not_changed);
+       }
+}
 
 /* ------------ Main Thread Even Handler ------------ */
 
@@ -177,6 +184,11 @@ int pcep_main_event_handler(enum pcep_main_event_type type, int pcc_id,
        case PCEP_MAIN_EVENT_START_SYNC:
                ret = pcep_main_event_start_sync(pcc_id);
                break;
+       case PCEP_MAIN_EVENT_INITIATE_CANDIDATE:
+               assert(payload != NULL);
+               ret = pcep_main_event_initiate_candidate(
+                       (struct path *)payload);
+               break;
        case PCEP_MAIN_EVENT_UPDATE_CANDIDATE:
                assert(payload != NULL);
                ret = pcep_main_event_update_candidate((struct path *)payload);
@@ -185,7 +197,7 @@ int pcep_main_event_handler(enum pcep_main_event_type type, int pcc_id,
                ret = pcep_main_event_remove_candidate_segments(
                        (const char *)payload, true);
                break;
-       default:
+       case PCEP_MAIN_EVENT_UNDEFINED:
                flog_warn(EC_PATH_PCEP_RECOVERABLE_INTERNAL_ERROR,
                          "Unexpected event received in the main thread: %u",
                          type);
@@ -209,19 +221,49 @@ int pcep_main_event_start_sync_cb(struct path *path, void *arg)
        return 1;
 }
 
+int pcep_main_event_initiate_candidate(struct path *path)
+{
+       int ret = 0;
+
+       ret = path_pcep_config_initiate_path(path);
+       if (path->do_remove) {
+               struct pcep_error *error;
+               error = XCALLOC(MTYPE_PCEP, sizeof(*error));
+               error->path = path;
+               error->error_type = PCEP_ERRT_INVALID_OPERATION;
+               switch (ret) {
+               case ERROR_19_1:
+                       error->error_value =
+                               PCEP_ERRV_LSP_UPDATE_FOR_NON_DELEGATED_LSP;
+                       break;
+               case ERROR_19_3:
+                       error->error_value =
+                               PCEP_ERRV_LSP_UPDATE_UNKNOWN_PLSP_ID;
+                       break;
+               case ERROR_19_9:
+                       error->error_value = PCEP_ERRV_LSP_NOT_PCE_INITIATED;
+                       break;
+               default:
+                       zlog_warn("(%s)PCE tried to REMOVE unknown error!",
+                                 __func__);
+                       XFREE(MTYPE_PCEP, error);
+                       pcep_free_path(path);
+                       return ret;
+                       break;
+               }
+               pcep_ctrl_send_error(pcep_g->fpt, path->pcc_id, error);
+       } else if (ret != PATH_NB_ERR && path->srp_id != 0)
+               notify_status(path, ret == PATH_NB_NO_CHANGE);
+       return ret;
+}
+
 int pcep_main_event_update_candidate(struct path *path)
 {
-       struct path *resp = NULL;
        int ret = 0;
 
        ret = path_pcep_config_update_path(path);
-       if (ret != PATH_NB_ERR && path->srp_id != 0) {
-               if ((resp = path_pcep_config_get_path(&path->nbkey))) {
-                       resp->srp_id = path->srp_id;
-                       pcep_ctrl_send_report(pcep_g->fpt, path->pcc_id, resp,
-                                             ret == PATH_NB_NO_CHANGE);
-               }
-       }
+       if (ret != PATH_NB_ERR && path->srp_id != 0)
+               notify_status(path, ret == PATH_NB_NO_CHANGE);
        return ret;
 }
 
@@ -264,7 +306,11 @@ int pathd_candidate_removed_handler(struct srte_candidate *candidate)
 
 /* ------------ Module Functions ------------ */
 
-int pcep_module_late_init(struct thread_master *tm)
+/* this creates threads, therefore must run after fork().  but it must also
+ * run before config load, so the CLI commands don't try to touch things that
+ * aren't set up yet...
+ */
+static int pcep_module_config_pre(struct thread_master *tm)
 {
        assert(pcep_g->fpt == NULL);
        assert(pcep_g->master == NULL);
@@ -280,10 +326,16 @@ int pcep_module_late_init(struct thread_master *tm)
        pcep_g->master = tm;
        pcep_g->fpt = fpt;
 
+       return 0;
+}
+
+static int pcep_module_late_init(struct thread_master *tm)
+{
        hook_register(pathd_candidate_created, pathd_candidate_created_handler);
        hook_register(pathd_candidate_updated, pathd_candidate_updated_handler);
        hook_register(pathd_candidate_removed, pathd_candidate_removed_handler);
 
+       hook_register(frr_config_pre, pcep_module_config_pre);
        hook_register(frr_fini, pcep_module_finish);
 
        pcep_cli_init();