]> git.proxmox.com Git - mirror_frr.git/blobdiff - pathd/path_pcep_lib.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / pathd / path_pcep_lib.c
index 1d2f25889ea55cba576015e433499de05fd8513f..502f2336c75264ee3904451449a67975755c42fc 100644 (file)
@@ -1,48 +1,40 @@
+// 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>
 
+#include "memory.h"
+
 #include <debug.h>
 #include "pceplib/pcep_utils_counters.h"
 #include "pceplib/pcep_timers.h"
 #include "pathd/path_errors.h"
-#include "pathd/path_memory.h"
 #include "pathd/path_pcep.h"
 #include "pathd/path_pcep_lib.h"
 #include "pathd/path_pcep_debug.h"
-#include "pathd/path_pcep_memory.h"
+
+DEFINE_MTYPE_STATIC(PATHD, PCEPLIB_INFRA,    "PCEPlib Infrastructure");
+DEFINE_MTYPE_STATIC(PATHD, PCEPLIB_MESSAGES, "PCEPlib PCEP Messages");
 
 #define CLASS_TYPE(CLASS, TYPE) (((CLASS) << 16) | (TYPE))
 #define DEFAULT_LSAP_SETUP_PRIO 4
 #define DEFAULT_LSAP_HOLDING_PRIO 4
 #define DEFAULT_LSAP_LOCAL_PRETECTION false
+#define MAX_PATH_NAME_SIZE 255
 
 /* pceplib logging callback */
-static int pceplib_logging_cb(int level, const char *fmt, va_list args);
+static int pceplib_logging_cb(int level, const char *fmt, va_list args)
+       PRINTFRR(2, 0);
 
 /* Socket callbacks */
 static int pcep_lib_pceplib_socket_read_cb(void *fpt, void **thread, int fd,
                                           void *payload);
 static int pcep_lib_pceplib_socket_write_cb(void *fpt, void **thread, int fd,
                                            void *payload);
-static int pcep_lib_socket_read_ready(struct thread *thread);
-static int pcep_lib_socket_write_ready(struct thread *thread);
+static void pcep_lib_socket_read_ready(struct thread *thread);
+static void pcep_lib_socket_write_ready(struct thread *thread);
 
 /* pceplib pcep_event callbacks */
 static void pcep_lib_pceplib_event_cb(void *fpt, pcep_event *event);
@@ -73,8 +65,18 @@ static void pcep_lib_parse_srp(struct path *path, struct pcep_object_srp *srp);
 static void pcep_lib_parse_lsp(struct path *path, struct pcep_object_lsp *lsp);
 static void pcep_lib_parse_lspa(struct path *path,
                                struct pcep_object_lspa *lspa);
+static void pcep_lib_parse_lsp_symbolic_name(
+       struct path *path, struct pcep_object_tlv_symbolic_path_name *tlv);
 static void pcep_lib_parse_metric(struct path *path,
                                  struct pcep_object_metric *obj);
+static void
+pcep_lib_parse_endpoints_ipv4(struct path *path,
+                             struct pcep_object_endpoints_ipv4 *obj);
+static void
+pcep_lib_parse_endpoints_ipv6(struct path *path,
+                             struct pcep_object_endpoints_ipv6 *obj);
+static void pcep_lib_parse_vendor_info(struct path *path,
+                                      struct pcep_object_vendor_info *obj);
 static void pcep_lib_parse_ero(struct path *path, struct pcep_object_ro *ero);
 static struct path_hop *pcep_lib_parse_ero_sr(struct path_hop *next,
                                              struct pcep_ro_subobj_sr *sr);
@@ -157,7 +159,7 @@ pcep_lib_connect(struct ipaddr *src_addr, int src_port, struct ipaddr *dst_addr,
        }
 
        config->support_stateful_pce_lsp_update = true;
-       config->support_pce_lsp_instantiation = false;
+       config->support_pce_lsp_instantiation = pcep_options->pce_initiated;
        config->support_include_db_version = false;
        config->support_lsp_triggered_resync = false;
        config->support_lsp_delta_sync = false;
@@ -227,26 +229,22 @@ int pcep_lib_pceplib_socket_read_cb(void *fpt, void **thread, int fd,
 /* Callbacks called by path_pcep_controller when a socket is ready to read/write
  */
 
-int pcep_lib_socket_write_ready(struct thread *thread)
+void pcep_lib_socket_write_ready(struct thread *thread)
 {
        struct pcep_ctrl_socket_data *data = THREAD_ARG(thread);
        assert(data != NULL);
 
-       int retval = pceplib_external_socket_write(data->fd, data->payload);
+       pceplib_external_socket_write(data->fd, data->payload);
        XFREE(MTYPE_PCEP, data);
-
-       return retval;
 }
 
-int pcep_lib_socket_read_ready(struct thread *thread)
+void pcep_lib_socket_read_ready(struct thread *thread)
 {
        struct pcep_ctrl_socket_data *data = THREAD_ARG(thread);
        assert(data != NULL);
 
-       int retval = pceplib_external_socket_read(data->fd, data->payload);
+       pceplib_external_socket_read(data->fd, data->payload);
        XFREE(MTYPE_PCEP, data);
-
-       return retval;
 }
 
 /* Callback passed to pceplib when a pcep_event is ready */
@@ -378,9 +376,25 @@ struct pcep_message *pcep_lib_format_request(struct pcep_caps *caps,
        }
 }
 
-struct pcep_message *pcep_lib_format_error(int error_type, int error_value)
+struct pcep_message *pcep_lib_format_error(int error_type, int error_value,
+                                          struct path *path)
 {
-       return pcep_msg_create_error(error_type, error_value);
+       double_linked_list *objs, *srp_tlvs;
+       struct pcep_object_srp *srp;
+       struct pcep_object_tlv_header *tlv;
+
+       if ((path == NULL) || (path->srp_id == 0))
+               return pcep_msg_create_error(error_type, error_value);
+
+       objs = dll_initialize();
+       srp_tlvs = dll_initialize();
+       tlv = (struct pcep_object_tlv_header *)pcep_tlv_create_path_setup_type(
+               SR_TE_PST);
+       dll_append(srp_tlvs, tlv);
+       srp = pcep_obj_create_srp(path->do_remove, path->srp_id, srp_tlvs);
+       dll_append(objs, srp);
+       return pcep_msg_create_error_with_objects(error_type, error_value,
+                                                 objs);
 }
 
 struct pcep_message *pcep_lib_format_request_cancelled(uint32_t reqid)
@@ -414,6 +428,9 @@ struct path *pcep_lib_parse_path(struct pcep_message *msg)
        struct pcep_object_metric *metric = NULL;
        struct pcep_object_bandwidth *bandwidth = NULL;
        struct pcep_object_objective_function *of = NULL;
+       struct pcep_object_endpoints_ipv4 *epv4 = NULL;
+       struct pcep_object_endpoints_ipv6 *epv6 = NULL;
+       struct pcep_object_vendor_info *vendor_info = NULL;
 
        path = pcep_new_path();
 
@@ -467,6 +484,21 @@ struct path *pcep_lib_parse_path(struct pcep_message *msg)
                        path->has_pce_objfun = true;
                        path->pce_objfun = of->of_code;
                        break;
+               case CLASS_TYPE(PCEP_OBJ_CLASS_ENDPOINTS,
+                               PCEP_OBJ_TYPE_ENDPOINT_IPV4):
+                       epv4 = (struct pcep_object_endpoints_ipv4 *)obj;
+                       pcep_lib_parse_endpoints_ipv4(path, epv4);
+                       break;
+               case CLASS_TYPE(PCEP_OBJ_CLASS_ENDPOINTS,
+                               PCEP_OBJ_TYPE_ENDPOINT_IPV6):
+                       epv6 = (struct pcep_object_endpoints_ipv6 *)obj;
+                       pcep_lib_parse_endpoints_ipv6(path, epv6);
+                       break;
+               case CLASS_TYPE(PCEP_OBJ_CLASS_VENDOR_INFO,
+                               PCEP_OBJ_TYPE_VENDOR_INFO):
+                       vendor_info = (struct pcep_object_vendor_info *)obj;
+                       pcep_lib_parse_vendor_info(path, vendor_info);
+                       break;
                default:
                        flog_warn(EC_PATH_PCEP_UNEXPECTED_PCEP_OBJECT,
                                  "Unexpected PCEP object %s (%u) / %s (%u)",
@@ -629,7 +661,8 @@ double_linked_list *pcep_lib_format_path(struct pcep_caps *caps,
                tlv = (struct pcep_object_tlv_header *)
                        pcep_tlv_create_tlv_arbitrary(
                                binding_sid_lsp_tlv_data,
-                               sizeof(binding_sid_lsp_tlv_data), 65505);
+                               sizeof(binding_sid_lsp_tlv_data),
+                               PCEP_OBJ_TYPE_CISCO_BSID);
                assert(tlv != NULL);
                dll_append(lsp_tlvs, tlv);
        }
@@ -721,7 +754,9 @@ double_linked_list *pcep_lib_format_path(struct pcep_caps *caps,
                                                        .s_addr,
                                                hop->nai.remote_iface);
                                break;
-                       default:
+                       case PCEP_SR_SUBOBJ_NAI_ABSENT:
+                       case PCEP_SR_SUBOBJ_NAI_LINK_LOCAL_IPV6_ADJACENCY:
+                       case PCEP_SR_SUBOBJ_NAI_UNKNOWN:
                                break;
                        }
                }
@@ -808,7 +843,24 @@ void pcep_lib_parse_open(struct pcep_caps *caps, struct pcep_object_open *open)
                case PCEP_OBJ_TLV_TYPE_OBJECTIVE_FUNCTION_LIST:
                        pcep_lib_parse_open_objfun_list(caps, tlv_header);
                        break;
-               default:
+               case PCEP_OBJ_TLV_TYPE_NO_PATH_VECTOR:
+               case PCEP_OBJ_TLV_TYPE_VENDOR_INFO:
+               case PCEP_OBJ_TLV_TYPE_IPV4_LSP_IDENTIFIERS:
+               case PCEP_OBJ_TLV_TYPE_IPV6_LSP_IDENTIFIERS:
+               case PCEP_OBJ_TLV_TYPE_LSP_ERROR_CODE:
+               case PCEP_OBJ_TLV_TYPE_RSVP_ERROR_SPEC:
+               case PCEP_OBJ_TLV_TYPE_LSP_DB_VERSION:
+               case PCEP_OBJ_TLV_TYPE_SPEAKER_ENTITY_ID:
+               case PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE:
+               case PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE_CAPABILITY:
+               case PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_ID:
+               case PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_NAME:
+               case PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_ID:
+               case PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_PREFERENCE:
+               case PCEP_OBJ_TLV_TYPE_UNKNOWN:
+               case PCEP_OBJ_TLV_TYPE_ARBITRARY:
+               case PCEP_OBJ_TLV_TYPE_SYMBOLIC_PATH_NAME:
+               case PCEP_OBJ_TYPE_CISCO_BSID:
                        flog_warn(EC_PATH_PCEP_UNEXPECTED_PCEP_TLV,
                                  "Unexpected OPEN's TLV %s (%u)",
                                  pcep_tlv_type_name(tlv_header->type),
@@ -852,6 +904,12 @@ void pcep_lib_parse_rp(struct path *path, struct pcep_object_rp *rp)
        double_linked_list_node *node;
        struct pcep_object_tlv_header *tlv;
 
+       if (tlvs == NULL) {
+               flog_warn(EC_PATH_PCEP_UNEXPECTED_PCEP_TLV,
+                         "Unexpected Empty RP's TLV plsp-id:(%d)",
+                         path ? (int32_t)path->plsp_id : -1);
+               return;
+       }
        /* We ignore the other flags and priority for now */
        path->req_id = rp->request_id;
        path->has_pce_objfun = false;
@@ -863,7 +921,26 @@ void pcep_lib_parse_rp(struct path *path, struct pcep_object_rp *rp)
                case PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE:
                        // TODO: enforce the path setup type is SR_TE_PST
                        break;
-               default:
+               case PCEP_OBJ_TLV_TYPE_NO_PATH_VECTOR:
+               case PCEP_OBJ_TLV_TYPE_OBJECTIVE_FUNCTION_LIST:
+               case PCEP_OBJ_TLV_TYPE_VENDOR_INFO:
+               case PCEP_OBJ_TLV_TYPE_IPV4_LSP_IDENTIFIERS:
+               case PCEP_OBJ_TLV_TYPE_IPV6_LSP_IDENTIFIERS:
+               case PCEP_OBJ_TLV_TYPE_LSP_ERROR_CODE:
+               case PCEP_OBJ_TLV_TYPE_RSVP_ERROR_SPEC:
+               case PCEP_OBJ_TLV_TYPE_LSP_DB_VERSION:
+               case PCEP_OBJ_TLV_TYPE_SPEAKER_ENTITY_ID:
+               case PCEP_OBJ_TLV_TYPE_SR_PCE_CAPABILITY:
+               case PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_ID:
+               case PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_NAME:
+               case PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_ID:
+               case PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_PREFERENCE:
+               case PCEP_OBJ_TLV_TYPE_STATEFUL_PCE_CAPABILITY:
+               case PCEP_OBJ_TLV_TYPE_UNKNOWN:
+               case PCEP_OBJ_TLV_TYPE_ARBITRARY:
+               case PCEP_OBJ_TLV_TYPE_SYMBOLIC_PATH_NAME:
+               case PCEP_OBJ_TYPE_CISCO_BSID:
+               case PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE_CAPABILITY:
                        flog_warn(EC_PATH_PCEP_UNEXPECTED_PCEP_TLV,
                                  "Unexpected RP's TLV %s (%u)",
                                  pcep_tlv_type_name(tlv->type), tlv->type);
@@ -881,13 +958,38 @@ void pcep_lib_parse_srp(struct path *path, struct pcep_object_srp *srp)
        path->do_remove = srp->flag_lsp_remove;
        path->srp_id = srp->srp_id_number;
 
+       if (tlvs == NULL) {
+               flog_warn(EC_PATH_PCEP_UNEXPECTED_PCEP_TLV,
+                         "Unexpected Empty SRP's TLV plsp-id:(%d)",
+                         path ? (int32_t)path->plsp_id : -1);
+               return;
+       }
        for (node = tlvs->head; node != NULL; node = node->next_node) {
                tlv = (struct pcep_object_tlv_header *)node->data;
                switch (tlv->type) {
                case PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE:
                        // TODO: enforce the path setup type is SR_TE_PST
                        break;
-               default:
+               case PCEP_OBJ_TLV_TYPE_NO_PATH_VECTOR:
+               case PCEP_OBJ_TLV_TYPE_OBJECTIVE_FUNCTION_LIST:
+               case PCEP_OBJ_TLV_TYPE_VENDOR_INFO:
+               case PCEP_OBJ_TLV_TYPE_STATEFUL_PCE_CAPABILITY:
+               case PCEP_OBJ_TLV_TYPE_SYMBOLIC_PATH_NAME:
+               case PCEP_OBJ_TLV_TYPE_IPV4_LSP_IDENTIFIERS:
+               case PCEP_OBJ_TLV_TYPE_IPV6_LSP_IDENTIFIERS:
+               case PCEP_OBJ_TLV_TYPE_LSP_ERROR_CODE:
+               case PCEP_OBJ_TLV_TYPE_RSVP_ERROR_SPEC:
+               case PCEP_OBJ_TLV_TYPE_LSP_DB_VERSION:
+               case PCEP_OBJ_TLV_TYPE_SPEAKER_ENTITY_ID:
+               case PCEP_OBJ_TLV_TYPE_SR_PCE_CAPABILITY:
+               case PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE_CAPABILITY:
+               case PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_ID:
+               case PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_NAME:
+               case PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_ID:
+               case PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_PREFERENCE:
+               case PCEP_OBJ_TLV_TYPE_UNKNOWN:
+               case PCEP_OBJ_TYPE_CISCO_BSID:
+               case PCEP_OBJ_TLV_TYPE_ARBITRARY:
                        flog_warn(EC_PATH_PCEP_UNEXPECTED_PCEP_TLV,
                                  "Unexpected SRP's TLV %s (%u)",
                                  pcep_tlv_type_name(tlv->type), tlv->type);
@@ -901,6 +1003,8 @@ void pcep_lib_parse_lsp(struct path *path, struct pcep_object_lsp *lsp)
        double_linked_list *tlvs = lsp->header.tlv_list;
        double_linked_list_node *node;
        struct pcep_object_tlv_header *tlv;
+       struct pcep_object_tlv_symbolic_path_name *name;
+       struct pcep_object_tlv_arbitrary *arb_tlv;
 
        path->plsp_id = lsp->plsp_id;
        path->status = lsp->operational_status;
@@ -910,13 +1014,46 @@ void pcep_lib_parse_lsp(struct path *path, struct pcep_object_lsp *lsp)
        path->is_synching = lsp->flag_s;
        path->is_delegated = lsp->flag_d;
 
-       if (tlvs == NULL)
+       if (tlvs == NULL) {
+               flog_warn(EC_PATH_PCEP_UNEXPECTED_PCEP_TLV,
+                         "Unexpected Empty LSP's TLV plsp-id:(%d)",
+                         path ? (int32_t)path->plsp_id : -1);
                return;
+       }
 
        for (node = tlvs->head; node != NULL; node = node->next_node) {
                tlv = (struct pcep_object_tlv_header *)node->data;
                switch (tlv->type) {
-               default:
+               case PCEP_OBJ_TLV_TYPE_SYMBOLIC_PATH_NAME:
+                       name = (struct pcep_object_tlv_symbolic_path_name *)tlv;
+                       pcep_lib_parse_lsp_symbolic_name(path, name);
+                       break;
+               case PCEP_OBJ_TYPE_CISCO_BSID:
+                       arb_tlv = (struct pcep_object_tlv_arbitrary *)tlv;
+                       memcpy(&path->binding_sid, arb_tlv->data + 2,
+                              sizeof(path->binding_sid));
+                       path->binding_sid = ntohl(path->binding_sid);
+                       path->binding_sid = (path->binding_sid >> 12);
+                       break;
+               case PCEP_OBJ_TLV_TYPE_NO_PATH_VECTOR:
+               case PCEP_OBJ_TLV_TYPE_OBJECTIVE_FUNCTION_LIST:
+               case PCEP_OBJ_TLV_TYPE_VENDOR_INFO:
+               case PCEP_OBJ_TLV_TYPE_IPV4_LSP_IDENTIFIERS:
+               case PCEP_OBJ_TLV_TYPE_IPV6_LSP_IDENTIFIERS:
+               case PCEP_OBJ_TLV_TYPE_LSP_ERROR_CODE:
+               case PCEP_OBJ_TLV_TYPE_RSVP_ERROR_SPEC:
+               case PCEP_OBJ_TLV_TYPE_LSP_DB_VERSION:
+               case PCEP_OBJ_TLV_TYPE_SPEAKER_ENTITY_ID:
+               case PCEP_OBJ_TLV_TYPE_SR_PCE_CAPABILITY:
+               case PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE:
+               case PCEP_OBJ_TLV_TYPE_PATH_SETUP_TYPE_CAPABILITY:
+               case PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_ID:
+               case PCEP_OBJ_TLV_TYPE_SRPOLICY_POL_NAME:
+               case PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_ID:
+               case PCEP_OBJ_TLV_TYPE_SRPOLICY_CPATH_PREFERENCE:
+               case PCEP_OBJ_TLV_TYPE_STATEFUL_PCE_CAPABILITY:
+               case PCEP_OBJ_TLV_TYPE_UNKNOWN:
+               case PCEP_OBJ_TLV_TYPE_ARBITRARY:
                        flog_warn(EC_PATH_PCEP_UNEXPECTED_PCEP_TLV,
                                  "Unexpected LSP TLV %s (%u)",
                                  pcep_tlv_type_name(tlv->type), tlv->type);
@@ -925,6 +1062,16 @@ void pcep_lib_parse_lsp(struct path *path, struct pcep_object_lsp *lsp)
        }
 }
 
+void pcep_lib_parse_lsp_symbolic_name(
+       struct path *path, struct pcep_object_tlv_symbolic_path_name *tlv)
+{
+       uint16_t size = tlv->symbolic_path_name_length;
+       assert(path->name == NULL);
+       size = size > MAX_PATH_NAME_SIZE ? MAX_PATH_NAME_SIZE : size;
+       path->name = XCALLOC(MTYPE_PCEP, size);
+       strlcpy((char *)path->name, tlv->symbolic_path_name, size + 1);
+}
+
 void pcep_lib_parse_lspa(struct path *path, struct pcep_object_lspa *lspa)
 {
        path->has_affinity_filters = true;
@@ -949,6 +1096,34 @@ void pcep_lib_parse_metric(struct path *path, struct pcep_object_metric *obj)
        path->first_metric = metric;
 }
 
+void pcep_lib_parse_endpoints_ipv4(struct path *path,
+                                  struct pcep_object_endpoints_ipv4 *obj)
+{
+       SET_IPADDR_V4(&path->pcc_addr);
+       path->pcc_addr.ipaddr_v4 = obj->src_ipv4;
+       SET_IPADDR_V4(&path->nbkey.endpoint);
+       path->nbkey.endpoint.ipaddr_v4 = obj->dst_ipv4;
+}
+
+void pcep_lib_parse_endpoints_ipv6(struct path *path,
+                                  struct pcep_object_endpoints_ipv6 *obj)
+{
+       SET_IPADDR_V6(&path->pcc_addr);
+       path->pcc_addr.ipaddr_v6 = obj->src_ipv6;
+       SET_IPADDR_V6(&path->nbkey.endpoint);
+       path->nbkey.endpoint.ipaddr_v6 = obj->dst_ipv6;
+}
+
+void pcep_lib_parse_vendor_info(struct path *path,
+                               struct pcep_object_vendor_info *obj)
+{
+       if (obj->enterprise_number == ENTERPRISE_NUMBER_CISCO
+           && obj->enterprise_specific_info == ENTERPRISE_COLOR_CISCO)
+               path->nbkey.color = obj->enterprise_specific_info1;
+       else
+               path->nbkey.color = 0;
+}
+
 void pcep_lib_parse_ero(struct path *path, struct pcep_object_ro *ero)
 {
        struct path_hop *hop = NULL;
@@ -956,6 +1131,12 @@ void pcep_lib_parse_ero(struct path *path, struct pcep_object_ro *ero)
        double_linked_list_node *node;
        struct pcep_object_ro_subobj *obj;
 
+       if (objs == NULL) {
+               flog_warn(EC_PATH_PCEP_UNEXPECTED_PCEP_TLV,
+                         "Unexpected Empty ERO's sub_obj plsp-id:(%d)",
+                         path ? (int32_t)path->plsp_id : -1);
+               return;
+       }
        for (node = objs->tail; node != NULL; node = node->prev_node) {
                obj = (struct pcep_object_ro_subobj *)node->data;
                switch (obj->ro_subobj_type) {
@@ -963,7 +1144,12 @@ void pcep_lib_parse_ero(struct path *path, struct pcep_object_ro *ero)
                        hop = pcep_lib_parse_ero_sr(
                                hop, (struct pcep_ro_subobj_sr *)obj);
                        break;
-               default:
+               case RO_SUBOBJ_TYPE_IPV4:
+               case RO_SUBOBJ_TYPE_IPV6:
+               case RO_SUBOBJ_TYPE_LABEL:
+               case RO_SUBOBJ_TYPE_UNNUM:
+               case RO_SUBOBJ_TYPE_ASN:
+               case RO_SUBOBJ_UNKNOWN:
                        flog_warn(EC_PATH_PCEP_UNEXPECTED_PCEP_ERO_SUBOBJ,
                                  "Unexpected ERO sub-object %s (%u)",
                                  pcep_ro_type_name(obj->ro_subobj_type),
@@ -1062,7 +1248,9 @@ struct path_hop *pcep_lib_parse_ero_sr(struct path_hop *next,
                        assert(n->data != NULL);
                        hop->nai.remote_iface = *(uint32_t *)n->data;
                        break;
-               default:
+               case PCEP_SR_SUBOBJ_NAI_ABSENT:
+               case PCEP_SR_SUBOBJ_NAI_LINK_LOCAL_IPV6_ADJACENCY:
+               case PCEP_SR_SUBOBJ_NAI_UNKNOWN:
                        hop->has_nai = false;
                        flog_warn(EC_PATH_PCEP_UNEXPECTED_SR_NAI,
                                  "Unexpected SR segment NAI type %s (%u)",